Beispiel #1
0
func (ig *ImageGraphics) TextLen(s string, font chart.Font) int {
	c := freetype.NewContext()
	c.SetDPI(dpi)
	c.SetFont(ig.font)
	fontsize := ig.relFontsizeToPixel(font.Size)
	c.SetFontSize(fontsize)
	scale := int32(fontsize * dpi * (64.0 / 72.0))
	var p raster.Point
	prev, hasPrev := truetype.Index(0), false
	for _, rune := range s {
		index := ig.font.Index(rune)
		if hasPrev {
			p.X += raster.Fix32(ig.font.Kerning(scale, prev, index)) << 2
		}
		p.X += raster.Fix32(ig.font.HMetric(scale, index).AdvanceWidth) << 2
		prev, hasPrev = index, true
	}
	return int((p.X + 127) / 256)
}
Beispiel #2
0
// textBox renders t into a tight fitting image
func (ig *ImageGraphics) textBox(t string, font chart.Font) image.Image {
	// Initialize the context.
	fg := image.NewUniform(color.Alpha{0xff})
	bg := image.NewUniform(color.Alpha{0x00})
	width := ig.TextLen(t, font)
	size := ig.relFontsizeToPixel(font.Size)
	bb := ig.font.Bounds(int32(size))
	// TODO: Ugly, manual, heuristic hack to get "nicer" text for common latin characters
	bb.YMin++
	if size >= 15 {
		bb.YMin++
		bb.YMax--
	}
	if size >= 20 {
		bb.YMax--
	}
	if size >= 25 {
		bb.YMin++
		bb.YMax--
	}

	dy := int(bb.YMax - bb.YMin)
	canvas := image.NewAlpha(image.Rect(0, 0, width, dy))
	draw.Draw(canvas, canvas.Bounds(), bg, image.ZP, draw.Src)

	c := freetype.NewContext()
	c.SetDPI(dpi)
	c.SetFont(ig.font)
	c.SetFontSize(size)
	c.SetClip(canvas.Bounds())
	c.SetDst(canvas)
	c.SetSrc(fg)

	// Draw the text.
	pt := freetype.Pt(0, dy+int(bb.YMin)-1)
	extent, err := c.DrawString(t, pt)
	if err != nil {
		log.Println(err)
		return nil
	}
	// log.Printf("text %q, extent: %v", t, extent)
	return canvas.SubImage(image.Rect(0, 0, int((extent.X+127)/256), dy))
}