Advanced text rendering, typography, and Unicode support.
// Load font from file
dc.LoadFontFace("fonts/arial.ttf", 24)
// Load font from bytes
fontData, err := ioutil.ReadFile("fonts/custom.ttf")
if err == nil {
dc.LoadFontFaceFromBytes(fontData, 24)
}
// Load system fonts (platform-specific)
dc.LoadSystemFont("Arial", 24)
dc.LoadSystemFont("Times New Roman", 18)
// Set font size for existing font
dc.SetFontSize(32)
// Get font metrics
metrics := dc.GetFontMetrics()
fmt.Printf("Ascent: %f\n", metrics.Ascent)
fmt.Printf("Descent: %f\n", metrics.Descent)
fmt.Printf("Height: %f\n", metrics.Height)
// Check if font supports character
supported := dc.FontSupportsChar('€')
fmt.Printf("Euro symbol supported: %v\n", supported)
// Get available font families
families := advancegg.GetSystemFontFamilies()
for _, family := range families {
fmt.Println("Available font:", family)
}
// Draw text at position
dc.DrawString("Hello World", 100, 100)
// Draw text with anchor positioning
dc.DrawStringAnchored("Centered Text", 400, 300, 0.5, 0.5)
// ax, ay: 0=left/top, 0.5=center, 1=right/bottom
// Draw text with rotation
dc.Push()
dc.Translate(200, 200)
dc.Rotate(math.Pi / 4) // 45 degrees
dc.DrawString("Rotated Text", 0, 0)
dc.Pop()
// Measure text dimensions
width, height := dc.MeasureString("Sample Text")
fmt.Printf("Text size: %fx%f\n", width, height)
// Get text bounds (more detailed)
bounds := dc.GetStringBounds("Sample Text")
fmt.Printf("Bounds: %v\n", bounds)
// Measure multiline text
lines := []string{"Line 1", "Line 2", "Line 3"}
totalHeight := dc.MeasureMultilineString(lines, 1.2) // 1.2 = line spacing
// Wrap text to fit width
text := "This is a long text that needs to be wrapped to fit within a specific width."
lines := dc.WordWrap(text, 300) // 300 pixels wide
// Draw wrapped text
lineHeight := 1.2
for i, line := range lines {
y := 100 + float64(i)*dc.FontHeight()*lineHeight
dc.DrawString(line, 50, y)
}
// Advanced word wrapping with alignment
dc.DrawStringWrapped(text, 50, 100, 0, 0, 300, lineHeight, advancegg.AlignLeft)
dc.DrawStringWrapped(text, 50, 200, 0, 0, 300, lineHeight, advancegg.AlignCenter)
dc.DrawStringWrapped(text, 50, 300, 0, 0, 300, lineHeight, advancegg.AlignRight)
dc.DrawStringWrapped(text, 50, 400, 0, 0, 300, lineHeight, advancegg.AlignJustify)
// Text alignment constants
const (
AlignLeft = advancegg.AlignLeft
AlignCenter = advancegg.AlignCenter
AlignRight = advancegg.AlignRight
AlignJustify = advancegg.AlignJustify
)
// Draw aligned text in a box
boxX, boxY := 100.0, 100.0
boxWidth, boxHeight := 300.0, 200.0
// Draw box outline
dc.SetRGB(0.8, 0.8, 0.8)
dc.DrawRectangle(boxX, boxY, boxWidth, boxHeight)
dc.Stroke()
// Draw text with different alignments
dc.SetRGB(0, 0, 0)
dc.DrawStringInBox("Left aligned text", boxX, boxY, boxWidth, boxHeight, AlignLeft)
dc.DrawStringInBox("Center aligned text", boxX, boxY+50, boxWidth, boxHeight, AlignCenter)
dc.DrawStringInBox("Right aligned text", boxX, boxY+100, boxWidth, boxHeight, AlignRight)
// Unicode text rendering
dc.DrawString("Hello 世界", 100, 100) // Chinese
dc.DrawString("مرحبا بالعالم", 100, 130) // Arabic
dc.DrawString("Здравствуй мир", 100, 160) // Russian
dc.DrawString("नमस्ते दुनिया", 100, 190) // Hindi
dc.DrawString("こんにちは世界", 100, 220) // Japanese
// Complex script shaping (automatic)
dc.EnableTextShaping(true) // Enable for complex scripts
dc.DrawString("مرحبا بالعالم", 100, 250) // Properly shaped Arabic
// Color emoji support
dc.DrawString("Hello 👋 World 🌍", 100, 100)
dc.DrawString("🎨 Graphics 📊 Charts 🎮 Games", 100, 130)
// Emoji with fallback
dc.SetEmojiFont("fonts/NotoColorEmoji.ttf")
dc.DrawString("Emoji: 😀 🎉 🚀 ⭐ 💖", 100, 160)
// Check emoji support
if dc.SupportsEmoji() {
dc.DrawString("Emoji supported! 🎉", 100, 190)
} else {
dc.DrawString("Emoji not supported", 100, 190)
}
// Set text direction
dc.SetTextDirection(advancegg.TextDirectionLTR) // Left-to-right (default)
dc.SetTextDirection(advancegg.TextDirectionRTL) // Right-to-left
dc.SetTextDirection(advancegg.TextDirectionTTB) // Top-to-bottom
// Bidirectional text (automatic detection)
dc.EnableBidirectionalText(true)
dc.DrawString("English النص العربي English", 100, 100)
// Simple shadow
dc.SetTextShadow(2, 2, 0, color.RGBA{0, 0, 0, 128})
dc.SetRGB(1, 1, 1)
dc.DrawString("Text with Shadow", 100, 100)
// Blur shadow
dc.SetTextShadow(3, 3, 5, color.RGBA{0, 0, 0, 100})
dc.DrawString("Blurred Shadow", 100, 150)
// Multiple shadows
shadows := []advancegg.TextShadow{
{OffsetX: 1, OffsetY: 1, Blur: 0, Color: color.RGBA{255, 0, 0, 128}},
{OffsetX: -1, OffsetY: -1, Blur: 0, Color: color.RGBA{0, 0, 255, 128}},
}
dc.SetTextShadows(shadows)
dc.DrawString("Multiple Shadows", 100, 200)
// Clear shadows
dc.ClearTextShadow()
// Text with outline
dc.SetTextOutline(2, color.RGBA{0, 0, 0, 255})
dc.SetRGB(1, 1, 1)
dc.DrawString("Outlined Text", 100, 100)
// Gradient outline
outlineGradient := advancegg.NewLinearGradient(0, 0, 100, 0)
outlineGradient.AddColorStop(0, color.RGBA{255, 0, 0, 255})
outlineGradient.AddColorStop(1, color.RGBA{0, 0, 255, 255})
dc.SetTextOutlineGradient(3, outlineGradient)
dc.DrawString("Gradient Outline", 100, 150)
// Gradient text fill
gradient := advancegg.NewLinearGradient(0, 0, 200, 0)
gradient.AddColorStop(0, color.RGBA{255, 0, 0, 255})
gradient.AddColorStop(0.5, color.RGBA{255, 255, 0, 255})
gradient.AddColorStop(1, color.RGBA{0, 255, 0, 255})
dc.SetTextFillGradient(gradient)
dc.DrawString("Gradient Text", 100, 100)
// Radial gradient text
radialGradient := advancegg.NewRadialGradient(100, 50, 0, 100, 50, 50)
radialGradient.AddColorStop(0, color.RGBA{255, 255, 255, 255})
radialGradient.AddColorStop(1, color.RGBA{0, 0, 0, 255})
dc.SetTextFillGradient(radialGradient)
dc.DrawString("Radial Gradient", 100, 150)
// Text following a circle
advancegg.DrawTextOnCircle(dc, "Circular Text Example", 400, 300, 150)
// Text on arc
advancegg.DrawTextOnArc(dc, "Arc Text", 400, 300, 150, 0, math.Pi)
// Upside-down circular text
advancegg.DrawTextOnCircle(dc, "Upside Down Text", 400, 300, 120, true)
// Create a custom path
path := advancegg.NewPath2D()
path.MoveTo(100, 200)
path.CubicTo(200, 100, 400, 100, 500, 200)
path.CubicTo(600, 300, 400, 300, 300, 200)
// Draw text along the path
advancegg.DrawTextOnPath(dc, "Text following custom path", path)
// Text with offset along path
advancegg.DrawTextOnPathWithOffset(dc, "Offset text", path, 50) // 50 pixels offset
// Text following a sine wave
advancegg.DrawTextOnWave(dc, "Wavy Text Example", 100, 200, 400, 30, 3)
// Parameters: text, startX, startY, width, amplitude, frequency
// Text on custom wave function
waveFunc := func(x float64) float64 {
return 30 * math.Sin(x*0.02) + 20 * math.Cos(x*0.03)
}
advancegg.DrawTextOnCustomWave(dc, "Custom Wave", 100, 300, 400, waveFunc)
// Enable/disable kerning
dc.SetKerning(true) // Enable kerning (default)
dc.SetKerning(false) // Disable kerning
// Letter spacing
dc.SetLetterSpacing(2.0) // 2 pixels between letters
dc.DrawString("Spaced Text", 100, 100)
// Word spacing
dc.SetWordSpacing(10.0) // 10 pixels between words
dc.DrawString("Word Spaced Text", 100, 150)
// Line height
dc.SetLineHeight(1.5) // 1.5x font size
multilineText := "Line 1\nLine 2\nLine 3"
dc.DrawString(multilineText, 100, 200)
// Underline
dc.SetTextDecoration(advancegg.TextDecorationUnderline)
dc.DrawString("Underlined Text", 100, 100)
// Strikethrough
dc.SetTextDecoration(advancegg.TextDecorationStrikethrough)
dc.DrawString("Strikethrough Text", 100, 150)
// Overline
dc.SetTextDecoration(advancegg.TextDecorationOverline)
dc.DrawString("Overlined Text", 100, 200)
// Multiple decorations
dc.SetTextDecoration(advancegg.TextDecorationUnderline | advancegg.TextDecorationStrikethrough)
dc.DrawString("Multiple Decorations", 100, 250)
// Custom decoration style
dc.SetUnderlineStyle(advancegg.UnderlineStyleDotted, 2.0, color.RGBA{255, 0, 0, 255})
dc.DrawString("Custom Underline", 100, 300)
// Small caps
dc.SetFontVariant(advancegg.FontVariantSmallCaps)
dc.DrawString("Small Caps Text", 100, 100)
// Subscript and superscript
dc.SetFontVariant(advancegg.FontVariantSubscript)
dc.DrawString("H₂O", 100, 150)
dc.SetFontVariant(advancegg.FontVariantSuperscript)
dc.DrawString("E=mc²", 150, 150)
// Reset to normal
dc.SetFontVariant(advancegg.FontVariantNormal)
package main
import (
"image/color"
"math"
"github.com/GrandpaEJ/advancegg"
)
func main() {
dc := advancegg.NewContext(1200, 800)
// Background
dc.SetRGB(0.95, 0.95, 0.98)
dc.Clear()
// Title with gradient
dc.LoadFontFace("fonts/arial-bold.ttf", 48)
gradient := advancegg.NewLinearGradient(0, 0, 400, 0)
gradient.AddColorStop(0, color.RGBA{255, 0, 100, 255})
gradient.AddColorStop(1, color.RGBA{100, 0, 255, 255})
dc.SetTextFillGradient(gradient)
dc.DrawStringAnchored("Typography Showcase", 600, 80, 0.5, 0.5)
// Subtitle with shadow
dc.LoadFontFace("fonts/arial.ttf", 24)
dc.SetTextShadow(2, 2, 3, color.RGBA{0, 0, 0, 100})
dc.SetRGB(0.2, 0.2, 0.4)
dc.DrawStringAnchored("Advanced Text Rendering with AdvanceGG", 600, 130, 0.5, 0.5)
dc.ClearTextShadow()
// International text
dc.LoadFontFace("fonts/noto-sans.ttf", 20)
dc.SetRGB(0.1, 0.1, 0.2)
texts := []struct {
text string
lang string
}{
{"Hello World", "English"},
{"Bonjour le monde", "French"},
{"Hola Mundo", "Spanish"},
{"Hallo Welt", "German"},
{"Ciao Mondo", "Italian"},
{"Olá Mundo", "Portuguese"},
{"Привет мир", "Russian"},
{"你好世界", "Chinese"},
{"こんにちは世界", "Japanese"},
{"안녕하세요 세계", "Korean"},
}
for i, item := range texts {
x := 100 + float64(i%5)*220
y := 200 + float64(i/5)*40
dc.DrawString(item.text, x, y)
// Language label
dc.LoadFontFace("fonts/arial.ttf", 12)
dc.SetRGB(0.5, 0.5, 0.5)
dc.DrawString(item.lang, x, y+20)
dc.LoadFontFace("fonts/noto-sans.ttf", 20)
dc.SetRGB(0.1, 0.1, 0.2)
}
// Text effects demonstration
y := 350.0
// Outlined text
dc.LoadFontFace("fonts/arial-bold.ttf", 32)
dc.SetTextOutline(3, color.RGBA{0, 0, 0, 255})
dc.SetRGB(1, 1, 1)
dc.DrawString("Outlined Text", 100, y)
// Gradient text
textGradient := advancegg.NewLinearGradient(0, 0, 200, 0)
textGradient.AddColorStop(0, color.RGBA{255, 100, 0, 255})
textGradient.AddColorStop(1, color.RGBA{255, 200, 0, 255})
dc.SetTextFillGradient(textGradient)
dc.ClearTextOutline()
dc.DrawString("Gradient Text", 400, y)
// Text on circle
dc.SetRGB(0.2, 0.4, 0.8)
dc.LoadFontFace("fonts/arial.ttf", 18)
advancegg.DrawTextOnCircle(dc, "Text following a circular path around the center", 600, 550, 120)
// Emoji text
dc.LoadFontFace("fonts/noto-emoji.ttf", 24)
dc.SetRGB(0.1, 0.1, 0.2)
dc.DrawString("Emoji support: 🎨 📊 🎮 🚀 ⭐ 💖 🌍", 100, 650)
// Word wrapped text
dc.LoadFontFace("fonts/arial.ttf", 16)
longText := "This is a demonstration of word wrapping functionality. The text will automatically wrap to fit within the specified width, maintaining proper spacing and alignment."
dc.DrawStringWrapped(longText, 100, 700, 0, 0, 400, 1.3, advancegg.AlignJustify)
dc.SavePNG("typography-showcase.png")
}