freetype/truetype: load vertical metrics from the OS/2 table.

R=bsiegert
CC=golang-dev, remyoudompheng
https://codereview.appspot.com/34700043
This commit is contained in:
Nigel Tao 2013-11-29 10:33:11 +11:00
parent 1c0c5a1f9a
commit 114d43ecfe
3 changed files with 23 additions and 28 deletions

View File

@ -377,12 +377,12 @@ func (g *GlyphBuf) loadCompound(recursion int32, b Bounds, uhm HMetric, i Index,
func (g *GlyphBuf) addPhantomsAndScale(b Bounds, uhm HMetric, i Index, np0 int, simple bool) {
// Add the four phantom points.
uvm := g.font.unscaledVMetric(i)
uvm := g.font.unscaledVMetric(i, b.YMax)
g.Point = append(g.Point,
Point{X: b.XMin - uhm.LeftSideBearing},
Point{X: b.XMin - uhm.LeftSideBearing + uhm.AdvanceWidth},
Point{Y: b.YMax + uvm.TopSideBearing},
Point{Y: b.YMax + uvm.TopSideBearing - uvm.AdvanceHeight},
Point{X: uhm.AdvanceWidth / 2, Y: b.YMax + uvm.TopSideBearing},
Point{X: uhm.AdvanceWidth / 2, Y: b.YMax + uvm.TopSideBearing - uvm.AdvanceHeight},
)
// Scale the points.
if simple && g.hinter != nil {

View File

@ -98,7 +98,7 @@ type cm struct {
type Font struct {
// Tables sliced from the TTF data. The different tables are documented
// at http://developer.apple.com/fonts/TTRefMan/RM06/Chap6.html
cmap, cvt, fpgm, glyf, head, hhea, hmtx, kern, loca, maxp, prep, vmtx []byte
cmap, cvt, fpgm, glyf, head, hhea, hmtx, kern, loca, maxp, os2, prep, vmtx []byte
cmapIndexes []byte
@ -373,8 +373,8 @@ func (f *Font) HMetric(scale int32, i Index) HMetric {
}
// unscaledVMetric returns the unscaled vertical metrics for the glyph with
// the given index.
func (f *Font) unscaledVMetric(i Index) (v VMetric) {
// the given index. yMax is the top of the glyph's bounding box.
func (f *Font) unscaledVMetric(i Index, yMax int32) (v VMetric) {
j := int(i)
if j < 0 || f.nGlyph <= j {
return VMetric{}
@ -385,6 +385,19 @@ func (f *Font) unscaledVMetric(i Index) (v VMetric) {
TopSideBearing: int32(int16(u16(f.vmtx, 4*j+2))),
}
}
// The OS/2 table has grown over time.
// https://developer.apple.com/fonts/TTRefMan/RM06/Chap6OS2.html
// says that it was originally 68 bytes. Optional fields, including
// the ascender and descender, are described at
// http://www.microsoft.com/typography/otspec/os2.htm
if len(f.os2) >= 72 {
sTypoAscender := int32(int16(u16(f.os2, 68)))
sTypoDescender := int32(int16(u16(f.os2, 70)))
return VMetric{
AdvanceHeight: sTypoAscender - sTypoDescender,
TopSideBearing: sTypoAscender - yMax,
}
}
return VMetric{
AdvanceHeight: f.fUnitsPerEm,
TopSideBearing: 0,
@ -393,7 +406,8 @@ func (f *Font) unscaledVMetric(i Index) (v VMetric) {
// VMetric returns the vertical metrics for the glyph with the given index.
func (f *Font) VMetric(scale int32, i Index) VMetric {
v := f.unscaledVMetric(i)
// TODO: should 0 be bounds.YMax?
v := f.unscaledVMetric(i, 0)
v.AdvanceHeight = f.scale(scale * v.AdvanceHeight)
v.TopSideBearing = f.scale(scale * v.TopSideBearing)
return v
@ -500,6 +514,8 @@ func parse(ttf []byte, offset int) (font *Font, err error) {
f.loca, err = readTable(ttf, ttf[x+8:x+16])
case "maxp":
f.maxp, err = readTable(ttf, ttf[x+8:x+16])
case "OS/2":
f.os2, err = readTable(ttf, ttf[x+8:x+16])
case "prep":
f.prep, err = readTable(ttf, ttf[x+8:x+16])
case "vmtx":

View File

@ -261,22 +261,6 @@ var scalingTestCases = []struct {
{"x-times-new-roman", 13, 0},
}
var scalingExceptions = map[string]map[int]bool{
// TODO: fix these exceptions now that 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{
269: true,
733: true,
734: true,
2071: true,
2072: true,
2077: true,
2078: true,
2171: true,
2172: true,
},
}
// TODO: also test bounding boxes, not just points.
func testScaling(t *testing.T, hinter *Hinter) {
@ -329,7 +313,6 @@ 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
@ -338,10 +321,6 @@ 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