Пример #1
0
func NewFontFace(path string, pixels float32, fg, bg color.Color) (fontface *FontFace, err error) {
	var (
		font      *truetype.Font
		fontbytes []byte
		bounds    fixed.Rectangle26_6
		context   *freetype.Context
		points    float32
		dpi       float32 = 96
	)
	if fontbytes, err = ioutil.ReadFile(path); err != nil {
		return
	}
	if font, err = freetype.ParseFont(fontbytes); err != nil {
		return
	}
	points = pixels * 72 / dpi
	bounds = font.Bounds(fixed.I(int(pixels)))
	context = freetype.NewContext()
	context.SetFont(font)
	context.SetFontSize(float64(points))
	context.SetDPI(float64(dpi))
	fontface = &FontFace{
		font:    font,
		charw:   float32(bounds.Max.X-bounds.Min.X) / 64,
		charh:   float32(bounds.Max.Y-bounds.Min.Y) / 64,
		offy:    float32(bounds.Min.Y) / 64,
		fg:      fg,
		bg:      bg,
		context: context,
	}
	return
}
Пример #2
0
func NewFontFace(path string, size float64, fg, bg color.Color) (fontface *FontFace, err error) {
	var (
		font      *truetype.Font
		fontbytes []byte
		bounds    truetype.Bounds
		context   *freetype.Context
		scale     float32
	)
	if fontbytes, err = ioutil.ReadFile(path); err != nil {
		return
	}
	if font, err = freetype.ParseFont(fontbytes); err != nil {
		return
	}
	bounds = font.Bounds(1)
	fmt.Printf("bounds %v\n", bounds)
	context = freetype.NewContext()
	context.SetFont(font)
	context.SetFontSize(size)
	context.SetDPI(72)
	scale = float32(context.PointToFixed(size) / 64)
	fontface = &FontFace{
		font:    font,
		charw:   scale * float32(bounds.XMax-bounds.XMin),
		charh:   scale * float32(bounds.YMax-bounds.YMin),
		fg:      fg,
		bg:      bg,
		context: context,
	}
	return
}
Пример #3
0
// Extents returns the FontExtents for a font.
// TODO needs to read this https://developer.apple.com/fonts/TrueType-Reference-Manual/RM02/Chap2.html#intro
func Extents(font *truetype.Font, size float64) FontExtents {
	bounds := font.Bounds(fixed.Int26_6(font.FUnitsPerEm()))
	scale := size / float64(font.FUnitsPerEm())
	return FontExtents{
		Ascent:  float64(bounds.YMax) * scale,
		Descent: float64(bounds.YMin) * scale,
		Height:  float64(bounds.YMax-bounds.YMin) * scale,
	}
}
Пример #4
0
func createTextImage(text string, fontSize int, color color.Color, f *truetype.Font) (*image.RGBA, float32, float32, error) {
	// 1 pt = 1/72 in, 72 dpi = 1 in
	const dpi = 72

	fg, bg := image.NewUniform(color), image.Transparent

	c := freetype.NewContext()
	c.SetFont(f)
	c.SetDPI(dpi)
	c.SetFontSize(float64(fontSize)) // points
	c.SetSrc(fg)
	c.SetHinting(font.HintingFull)

	// 1. Figure out maximum height so all text lines are the same height.
	// 2. Draw within small bounds to figure out bounds.
	// 3. Draw within final bounds.

	scale := c.PointToFixed(float64(fontSize)) // point to pixels
	rect := f.Bounds(scale)                    // scale is pixels of 1 em
	maxHeight := int(rect.Max.Y>>6) - int(rect.Min.Y>>6)

	var rgba *image.RGBA
	w, h := 10, maxHeight
	for i := 0; i < 2; i++ {
		rgba = image.NewRGBA(image.Rect(0, 0, w, h))
		draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src)

		c.SetClip(rgba.Bounds())
		c.SetDst(rgba)

		pt := freetype.Pt(0, int(scale>>6))
		end, err := c.DrawString(text, pt)
		if err != nil {
			return nil, 0, 0, err
		}

		w = int(end.X >> 6)
	}

	return rgba, float32(w), float32(h), nil
}