Example #1
0
func Measure(r io.RuneReader, f font.Face) (size fixed.Point26_6, err error) {
	var char rune
	var prev rune

	w := fixed.Int26_6(0)
	m := f.Metrics()
	size.Y = m.Height + m.Descent

	for {
		if char, _, err = r.ReadRune(); err != nil {
			if err == io.EOF {
				err = nil
			}
			size.X = maxInt26_6(size.X, w)
			return
		}

		if char == '\n' {
			size.X = maxInt26_6(size.X, w)
			size.Y += m.Height
			w, prev = 0, 0
			continue
		}

		if prev != 0 {
			w += f.Kern(prev, char)
		}

		w += advance(f, char)
		prev = char
	}
}
Example #2
0
func advance(face font.Face, char rune) (x fixed.Int26_6) {
	if x, ok := face.GlyphAdvance(char); ok {
		return x
	} else {
		x, _ = face.GlyphAdvance(utf8.RuneError)
		return x
	}
}
Example #3
0
func glyph(face font.Face, char rune, dot fixed.Point26_6) (dr image.Rectangle, mask image.Image, maskp image.Point) {
	var ok bool

	if dr, mask, maskp, _, ok = face.Glyph(dot, char); !ok {
		dr, mask, maskp, _, _ = face.Glyph(dot, utf8.RuneError)
	}

	return
}
Example #4
0
func fromString(s string, fc font.Face) []*glyph {
	var gs []*glyph
	for _, r := range s {
		if b, a, ok := fc.GlyphBounds(r); ok {
			gs = append(gs, &glyph{r: r, b: b, a: a})
		}
	}
	return gs
}
Example #5
0
// enumerate returns all glyphs with a valid index.
func enumerate(f *truetype.Font, fc font.Face) []*glyph {
	var gs []*glyph
	for r := rune(1); r < (1<<16)-1; r++ {
		if r == '\uFEFF' {
			continue // ignore BOM
		}
		if f.Index(r) != 0 {
			b, a, _ := fc.GlyphBounds(r)
			gs = append(gs, &glyph{r: r, b: b, a: a})
		}
	}
	return gs
}
Example #6
0
func (self rightToLeft) Advance(face font.Face, origin fixed.Point26_6, dot fixed.Point26_6, prev rune, char rune) (begin fixed.Point26_6, end fixed.Point26_6) {
	if char == '\n' {
		dot.X = origin.X
		dot.Y += face.Metrics().Height
		return dot, dot
	}

	if prev != 0 {
		dot.X -= face.Kern(prev, char)
	}

	dot.X -= advance(face, char)
	return dot, dot
}
Example #7
0
func newGlyphPage(face fnt.Face, r rune) *glyphPage {
	// Start the page big enough to hold the initial rune.
	b, _, _ := face.GlyphBounds(r)
	bounds := rectangle26_6toRect(b)
	size := math.Size{W: glyphPageWidth, H: glyphPageHeight}.Max(bounds.Size())
	size.W = align(size.W, glyphSizeAlignment)
	size.H = align(size.H, glyphSizeAlignment)

	page := &glyphPage{
		image:     image.NewAlpha(image.Rect(0, 0, size.W, size.H)),
		size:      size,
		entries:   make(map[rune]glyphEntry),
		rowHeight: 0,
	}
	page.add(face, r)
	return page
}
Example #8
0
func (p *glyphPage) add(face fnt.Face, r rune) bool {
	if _, found := p.entries[r]; found {
		panic("Glyph already added to glyph page")
	}

	b, mask, maskp, _, _ := face.Glyph(fixed.Point26_6{}, r)
	bounds := math.CreateRect(b.Min.X, b.Min.Y, b.Max.X, b.Max.Y)

	w, h := bounds.Size().WH()
	x, y := p.nextPoint.X, p.nextPoint.Y

	if x+w > p.size.W {
		// Row full, start new line
		x = 0
		y += p.rowHeight + glyphPadding
		p.rowHeight = 0
	}

	if y+h > p.size.H {
		return false // Page full
	}

	draw.Draw(p.image, image.Rect(x, y, x+w, y+h), mask, maskp, draw.Src)

	p.entries[r] = glyphEntry{
		offset: math.Point{X: x, Y: y}.Sub(bounds.Min),
		bounds: bounds,
	}
	p.nextPoint = math.Point{X: x + w + glyphPadding, Y: y}
	if h > p.rowHeight {
		p.rowHeight = h
	}
	p.tex = nil

	return true
}
Example #9
0
func (self rightToLeft) Origin(face font.Face, bounds fixed.Rectangle26_6) fixed.Point26_6 {
	return fixed.Point26_6{
		X: bounds.Max.X,
		Y: bounds.Min.Y + face.Metrics().Ascent,
	}
}
Example #10
0
// MeasureString returns the rendered width and height of the specified text
// given the current font face.
func MeasureString(ff font.Face, s string) (w float64, h float64) {
	d := &font.Drawer{Face: ff}
	return float64(d.MeasureString(s) >> 6),
		float64(ff.Metrics().Height>>6) * 96.0 / 72.0
}