Ejemplo n.º 1
0
// MeasureString returns the width and height of the string in s, in terms of
// raster.Fix32 units.
//
// BUG(burntsushi): I don't think negative x-coordinates are handled at all, so
// that the bounding box could be smaller than what it actually is. (i.e., the
// first letter is an italic 'J'.)
func (c *Context) MeasureString(s string) (raster.Fix32, raster.Fix32, error) {
	if c.font == nil {
		return 0, 0, errors.New("freetype: DrawText called with a nil font")
	}

	var width, height, heightMax raster.Fix32
	oneLine := c.PointToFix32(c.fontSize) & 0xff
	height = c.PointToFix32(c.fontSize)
	prev, hasPrev := truetype.Index(0), false
	for _, rune := range s {
		index := c.font.Index(rune)
		if hasPrev {
			width += raster.Fix32(c.font.Kerning(c.scale, prev, index)) << 2
		}

		if err := c.glyphBuf.Load(c.font, c.scale, index, truetype.Hinting(c.hinting)); err != nil {
			return 0, 0, err
		}
		ymax := oneLine - raster.Fix32(c.glyphBuf.B.YMin<<2) + 0xff
		heightMax = max(heightMax, ymax)

		width += raster.Fix32(c.font.HMetric(c.scale, index).AdvanceWidth) << 2
		prev, hasPrev = index, true
	}

	if heightMax > 0 {
		height += heightMax
	}
	return width, height, nil
}
Ejemplo n.º 2
0
// rasterize returns the advance width, glyph mask and integer-pixel offset
// to render the given glyph at the given sub-pixel offsets.
// The 24.8 fixed point arguments fx and fy must be in the range [0, 1).
func (c *Context) rasterize(glyph truetype.Index, fx, fy raster.Fix32) (
	raster.Fix32, *image.Alpha, image.Point, error) {

	if err := c.glyphBuf.Load(c.font, c.scale, glyph, truetype.Hinting(c.hinting)); err != nil {
		return 0, nil, image.Point{}, err
	}
	// Calculate the integer-pixel bounds for the glyph.
	xmin := int(fx+raster.Fix32(c.glyphBuf.B.XMin<<2)) >> 8
	ymin := int(fy-raster.Fix32(c.glyphBuf.B.YMax<<2)) >> 8
	xmax := int(fx+raster.Fix32(c.glyphBuf.B.XMax<<2)+0xff) >> 8
	ymax := int(fy-raster.Fix32(c.glyphBuf.B.YMin<<2)+0xff) >> 8
	if xmin > xmax || ymin > ymax {
		return 0, nil, image.Point{}, errors.New("freetype: negative sized glyph")
	}
	// A TrueType's glyph's nodes can have negative co-ordinates, but the
	// rasterizer clips anything left of x=0 or above y=0. xmin and ymin
	// are the pixel offsets, based on the font's FUnit metrics, that let
	// a negative co-ordinate in TrueType space be non-negative in
	// rasterizer space. xmin and ymin are typically <= 0.
	fx += raster.Fix32(-xmin << 8)
	fy += raster.Fix32(-ymin << 8)
	// Rasterize the glyph's vectors.
	c.r.Clear()
	e0 := 0
	for _, e1 := range c.glyphBuf.End {
		c.drawContour(c.glyphBuf.Point[e0:e1], fx, fy)
		e0 = e1
	}
	a := image.NewAlpha(image.Rect(0, 0, xmax-xmin, ymax-ymin))
	c.r.Rasterize(raster.NewAlphaSrcPainter(a))
	return raster.Fix32(c.glyphBuf.AdvanceWidth << 2), a, image.Point{xmin, ymin}, nil
}