diff --git a/draw2dimg/ftgc.go b/draw2dimg/ftgc.go index f3721c6..141ac63 100644 --- a/draw2dimg/ftgc.go +++ b/draw2dimg/ftgc.go @@ -35,10 +35,11 @@ type GraphicContext struct { painter Painter fillRasterizer *raster.Rasterizer strokeRasterizer *raster.Rasterizer - FontCache draw2d.FontCache + FontCache draw2d.FontCache glyphCache draw2dbase.GlyphCache glyphBuf *truetype.GlyphBuf DPI int + Emojis emoji.Table } // ImageFilter defines the type of filter to use @@ -79,6 +80,7 @@ func NewGraphicContextWithPainter(img draw.Image, painter Painter) *GraphicConte draw2dbase.NewGlyphCache(), &truetype.GlyphBuf{}, dpi, + make(emoji.Table), } return gc } @@ -124,6 +126,9 @@ func (gc *GraphicContext) FillString(text string) (width float64) { return gc.FillStringAt(text, 0, 0) } +const emojiSpacing = 10 +const emojiScale = 110 + // FillStringAt draws the text at the specified point (x, y) func (gc *GraphicContext) FillStringAt(text string, x, y float64) (width float64) { f, err := gc.loadCurrentFont() @@ -134,12 +139,25 @@ func (gc *GraphicContext) FillStringAt(text string, x, y float64) (width float64 startx := x prev, hasPrev := truetype.Index(0), false fontName := gc.GetFontName() - for _, r := range text { - index := f.Index(r) + for fragment := range gc.Emojis.Iterate(text) { + if fragment.IsEmoji { + img, err := LoadFromPngFile(fragment.Emoji.Path) + if err == nil { + gc.Save() + scale := gc.GetFontSize() / 100 + gc.Translate(x+scale*emojiSpacing, y-scale*emojiScale) + gc.Scale(scale, scale) + gc.DrawImage(img) + gc.Restore() + x += scale*float64(img.Bounds().Size().X) + scale*emojiSpacing*2 + } + continue + } + index := f.Index(fragment.Rune) if hasPrev { x += fUnitsToFloat64(f.Kern(fixed.Int26_6(gc.Current.Scale), prev, index)) } - glyph := gc.glyphCache.Fetch(gc, fontName, r) + glyph := gc.glyphCache.Fetch(gc, fontName, fragment.Rune) x += glyph.Fill(gc, x, y) prev, hasPrev = index, true }