From f6106a9f8b0485f8a527ea5096574f6923c98747 Mon Sep 17 00:00:00 2001 From: Nigel Tao Date: Thu, 7 Nov 2013 08:53:15 +1100 Subject: [PATCH] freetype/truetype: adjust ends slice when hinting a compound glyph. Successfully hint all of DejaVu Sans Oblique, barring 4 exceptions that are errors in the upstream C Freetype project. See http://lists.nongnu.org/archive/html/freetype/2013-11/msg00004.html for details. R=bsiegert CC=golang-dev, remyoudompheng https://codereview.appspot.com/21580044 --- freetype/truetype/glyph.go | 18 ++++++++++++++++-- freetype/truetype/truetype_test.go | 18 +++++++++++++++++- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/freetype/truetype/glyph.go b/freetype/truetype/glyph.go index adf6b79..265ce08 100644 --- a/freetype/truetype/glyph.go +++ b/freetype/truetype/glyph.go @@ -358,15 +358,29 @@ func (g *GlyphBuf) loadCompound(recursion int32, b Bounds, uhm HMetric, i Index, } program := glyf[offset : offset+instrLen] g.addPhantomsAndScale(b, uhm, i, len(g.Point), false) - points := g.Point[np0:] + points, ends := g.Point[np0:], g.End[ne0:] g.Point = g.Point[:len(g.Point)-4] for j := range points { points[j].Flags &^= flagTouchedX | flagTouchedY } + // Temporarily adjust the ends to be relative to this compound glyph. + if np0 != 0 { + for i := range ends { + ends[i] -= np0 + } + } // Hinting instructions of a composite glyph completely refer to the // (already) hinted subglyphs. g.tmp = append(g.tmp[:0], points...) - return g.hinter.run(program, points, g.tmp, g.tmp, g.End[ne0:]) + if err := g.hinter.run(program, points, g.tmp, g.tmp, ends); err != nil { + return err + } + if np0 != 0 { + for i := range ends { + ends[i] += np0 + } + } + return nil } func (g *GlyphBuf) addPhantomsAndScale(b Bounds, uhm HMetric, i Index, np0 int, appendOther bool) { diff --git a/freetype/truetype/truetype_test.go b/freetype/truetype/truetype_test.go index e791cdb..0a75c43 100644 --- a/freetype/truetype/truetype_test.go +++ b/freetype/truetype/truetype_test.go @@ -256,11 +256,22 @@ var scalingTestCases = []struct { }{ {"luxisr", 12, -1}, {"x-arial-bold", 11, 0}, - {"x-deja-vu-sans-oblique", 17, 2077}, + {"x-deja-vu-sans-oblique", 17, -1}, {"x-droid-sans-japanese", 9, 0}, {"x-times-new-roman", 13, 0}, } +var scalingExceptions = map[string]map[int]bool{ + // TODO: remove these exceptions when C Freetype version 2.5.1 is released: + // see http://lists.nongnu.org/archive/html/freetype/2013-11/msg00004.html + "x-deja-vu-sans-oblique": map[int]bool{ + 2077: true, + 2078: true, + 2171: true, + 2172: true, + }, +} + // TODO: also test bounding boxes, not just points. func testScaling(t *testing.T, hinter *Hinter) { @@ -296,6 +307,7 @@ func testScaling(t *testing.T, hinter *Hinter) { continue } + exceptions := scalingExceptions[tc.name] glyphBuf := NewGlyphBuf() for i, want := range wants { // TODO: completely implement hinting. For now, only the first @@ -304,6 +316,10 @@ func testScaling(t *testing.T, hinter *Hinter) { break } + if exceptions != nil && exceptions[i] { + continue + } + if err = glyphBuf.Load(font, tc.size*64, Index(i), hinter); err != nil { t.Errorf("%s: glyph #%d: Load: %v", tc.name, i, err) continue