From b14683a5523c4dd25d71ed97ab263799c64114c4 Mon Sep 17 00:00:00 2001 From: Laurent Le Goff Date: Thu, 30 Apr 2015 18:06:25 +0200 Subject: [PATCH] Start working on text --- draw2dimg/ftgc.go | 46 +-------------------------- draw2dimg/text.go | 80 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 45 deletions(-) create mode 100644 draw2dimg/text.go diff --git a/draw2dimg/ftgc.go b/draw2dimg/ftgc.go index 2e0da66..d7f668e 100644 --- a/draw2dimg/ftgc.go +++ b/draw2dimg/ftgc.go @@ -113,53 +113,9 @@ func (gc *GraphicContext) loadCurrentFont() (*truetype.Font, error) { return font, nil } -func fUnitsToFloat64(x int32) float64 { - scaled := x << 2 - return float64(scaled/256) + float64(scaled%256)/256.0 -} - // p is a truetype.Point measured in FUnits and positive Y going upwards. // The returned value is the same thing measured in floating point and positive Y // going downwards. -func pointToF64Point(p truetype.Point) (x, y float64) { - return fUnitsToFloat64(p.X), -fUnitsToFloat64(p.Y) -} - -// drawContour draws the given closed contour at the given sub-pixel offset. -func (gc *GraphicContext) drawContour(ps []truetype.Point, dx, dy float64) { - if len(ps) == 0 { - return - } - startX, startY := pointToF64Point(ps[0]) - gc.MoveTo(startX+dx, startY+dy) - q0X, q0Y, on0 := startX, startY, true - for _, p := range ps[1:] { - qX, qY := pointToF64Point(p) - on := p.Flags&0x01 != 0 - if on { - if on0 { - gc.LineTo(qX+dx, qY+dy) - } else { - gc.QuadCurveTo(q0X+dx, q0Y+dy, qX+dx, qY+dy) - } - } else { - if on0 { - // No-op. - } else { - midX := (q0X + qX) / 2 - midY := (q0Y + qY) / 2 - gc.QuadCurveTo(q0X+dx, q0Y+dy, midX+dx, midY+dy) - } - } - q0X, q0Y, on0 = qX, qY, on - } - // Close the curve. - if on0 { - gc.LineTo(startX+dx, startY+dy) - } else { - gc.QuadCurveTo(q0X+dx, q0Y+dy, startX+dx, startY+dy) - } -} func (gc *GraphicContext) drawGlyph(glyph truetype.Index, dx, dy float64) error { if err := gc.glyphBuf.Load(gc.Current.Font, gc.Current.Scale, glyph, truetype.NoHinting); err != nil { @@ -167,7 +123,7 @@ func (gc *GraphicContext) drawGlyph(glyph truetype.Index, dx, dy float64) error } e0 := 0 for _, e1 := range gc.glyphBuf.End { - gc.drawContour(gc.glyphBuf.Point[e0:e1], dx, dy) + DrawContour(gc, gc.glyphBuf.Point[e0:e1], dx, dy) e0 = e1 } return nil diff --git a/draw2dimg/text.go b/draw2dimg/text.go new file mode 100644 index 0000000..c858c1d --- /dev/null +++ b/draw2dimg/text.go @@ -0,0 +1,80 @@ +package draw2dimg + +import ( + "code.google.com/p/freetype-go/freetype/truetype" + "github.com/llgcode/draw2d" +) + +// drawContour draws the given closed contour at the given sub-pixel offset. +func DrawContour(path draw2d.PathBuilder, ps []truetype.Point, dx, dy float64) { + if len(ps) == 0 { + return + } + startX, startY := pointToF64Point(ps[0]) + path.MoveTo(startX+dx, startY+dy) + q0X, q0Y, on0 := startX, startY, true + for _, p := range ps[1:] { + qX, qY := pointToF64Point(p) + on := p.Flags&0x01 != 0 + if on { + if on0 { + path.LineTo(qX+dx, qY+dy) + } else { + path.QuadCurveTo(q0X+dx, q0Y+dy, qX+dx, qY+dy) + } + } else { + if on0 { + // No-op. + } else { + midX := (q0X + qX) / 2 + midY := (q0Y + qY) / 2 + path.QuadCurveTo(q0X+dx, q0Y+dy, midX+dx, midY+dy) + } + } + q0X, q0Y, on0 = qX, qY, on + } + // Close the curve. + if on0 { + path.LineTo(startX+dx, startY+dy) + } else { + path.QuadCurveTo(q0X+dx, q0Y+dy, startX+dx, startY+dy) + } +} + +func pointToF64Point(p truetype.Point) (x, y float64) { + return fUnitsToFloat64(p.X), -fUnitsToFloat64(p.Y) +} + +func fUnitsToFloat64(x int32) float64 { + scaled := x << 2 + return float64(scaled/256) + float64(scaled%256)/256.0 +} + +// FontExtents contains font metric information. +type FontExtents struct { + // Ascent is the distance that the text + // extends above the baseline. + Ascent float64 + + // Descent is the distance that the text + // extends below the baseline. The descent + // is given as a negative value. + Descent float64 + + // Height is the distance from the lowest + // descending point to the highest ascending + // point. + Height float64 +} + +// TODO needs to read this https://developer.apple.com/fonts/TrueType-Reference-Manual/RM02/Chap2.html#intro +// Extents returns the FontExtents for a font. +func Extents(font *truetype.Font, size float64) FontExtents { + bounds := font.Bounds(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, + } +}