func drawString(src image.Image, fontContext *freetype.Context, position raster.Point, text string) { fontContext.SetSrc(src) _, err := fontContext.DrawString(text, position) if err != nil { log.Println(err) } }
func drawFitCentered(c *freetype.Context, text string, img image.Image, bottom bool) { lines, longest := splitLines(text) // Calculate the font size that fits the longest line within the image width. // Simplistic approach -- calculate the width of the line at MaxFontSize, then divide it // down to get the appropriate font size. Not quite right, but close enough. size := MaxFontSize c.SetFontSize(MaxFontSize) fw, _, _ := c.MeasureString(lines[longest]) w := int(fw >> 8) ratio := float64(img.Bounds().Dx()-16) / float64(w) size *= ratio if size > MaxFontSize { size = MaxFontSize } else { w = int(float64(w) * ratio) } c.SetFontSize(size) pos := 0 for _, line := range lines { fw, _, _ = c.MeasureString(line) w := int(fw >> 8) lineHeight := int(size * 1.2) x := img.Bounds().Dx()/2 - w/2 y := 0 if bottom { y = img.Bounds().Max.Y - 8 - (len(lines)-1)*lineHeight + pos } else { y = int(size) + 8 + pos } pos += lineHeight drawBorderedText(c, line, x, y) } }
func drawBorderedText(c *freetype.Context, text string, x, y int) { // God-awful hack to add a 2px black border around the text. c.SetSrc(image.Black) c.DrawString(text, freetype.Pt(x-2, y-2)) c.DrawString(text, freetype.Pt(x, y-2)) c.DrawString(text, freetype.Pt(x+2, y-2)) c.DrawString(text, freetype.Pt(x-2, y)) c.DrawString(text, freetype.Pt(x+2, y)) c.DrawString(text, freetype.Pt(x-2, y+2)) c.DrawString(text, freetype.Pt(x, y+2)) c.DrawString(text, freetype.Pt(x+2, y+2)) c.SetSrc(image.White) c.DrawString(text, freetype.Pt(x, y)) }
func renderString(s string, c *freetype.Context) (*image.RGBA, int) { estWidth := 8 * len(s) dst := image.NewRGBA(image.Rect(0, 0, estWidth, h)) c.SetDst(dst) c.SetClip(dst.Bounds()) c.SetSrc(&image.Uniform{C: shadow}) pt := freetype.Pt(0, 13) c.DrawString(s, pt) c.SetSrc(image.White) pt = freetype.Pt(0, 12) pt, _ = c.DrawString(s, pt) return dst, getTextOffset(pt) }
func drawText(font *truetype.Font, c *freetype.Context, color color.Color, rgba *image.RGBA, text string) (int, int) { fg := image.NewUniform(color) bg := image.Transparent draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src) c.SetFont(font) c.SetDst(rgba) c.SetSrc(fg) c.SetClip(rgba.Bounds()) // height is the fraction of the font that is above the line, 1.0 would mean // that the font never falls below the line // TODO: wtf - this is all wrong! // fix fonts - we can't change the font size easily height := 1.3 pt := freetype.Pt(0, int(float64(c.PointToFix32(*size)>>8)*height)) adv, _ := c.DrawString(text, pt) pt.X += adv.X py := int(float64(pt.Y>>8)/height + 0.01) return int(pt.X >> 8), py }
func NextLine(c *freetype.Context, pt raster.Point) raster.Point { return raster.Point{inset, pt.Y - c.PointToFix32(size*1.5)} }