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:
parent
1c0c5a1f9a
commit
114d43ecfe
3 changed files with 23 additions and 28 deletions
|
@ -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 {
|
||||
|
|
|
@ -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":
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue