freetype/truetype: implement compound glyph transforms.

R=bsiegert
CC=golang-dev
https://codereview.appspot.com/14425064
This commit is contained in:
Nigel Tao 2013-10-16 21:39:06 +11:00
parent c8094ec963
commit 8373bbf0e6
2 changed files with 32 additions and 11 deletions

View file

@ -286,7 +286,7 @@ func (g *GlyphBuf) loadCompound(recursion int32, glyf []byte) error {
for offset := loadOffset; ; {
flags := u16(glyf, offset)
component := Index(u16(glyf, offset+2))
dx, dy := int32(0), int32(0)
dx, dy, transform, hasTransform := int32(0), int32(0), [4]int32{}, false
if flags&flagArg1And2AreWords != 0 {
dx = int32(int16(u16(glyf, offset+4)))
dy = int32(int16(u16(glyf, offset+6)))
@ -300,12 +300,38 @@ func (g *GlyphBuf) loadCompound(recursion int32, glyf []byte) error {
return UnsupportedError("compound glyph transform vector")
}
if flags&(flagWeHaveAScale|flagWeHaveAnXAndYScale|flagWeHaveATwoByTwo) != 0 {
return UnsupportedError("compound glyph scale/transform")
hasTransform = true
switch {
case flags&flagWeHaveAScale != 0:
transform[0] = int32(int16(u16(glyf, offset+0)))
transform[3] = transform[0]
offset += 2
case flags&flagWeHaveAnXAndYScale != 0:
transform[0] = int32(int16(u16(glyf, offset+0)))
transform[3] = int32(int16(u16(glyf, offset+2)))
offset += 4
case flags&flagWeHaveATwoByTwo != 0:
transform[0] = int32(int16(u16(glyf, offset+0)))
transform[1] = int32(int16(u16(glyf, offset+2)))
transform[2] = int32(int16(u16(glyf, offset+4)))
transform[3] = int32(int16(u16(glyf, offset+6)))
offset += 8
}
}
np0 := len(g.Point)
if err := g.load(recursion+1, component, flags&flagUseMyMetrics != 0); err != nil {
return err
}
if hasTransform {
for i := np0; i < len(g.Point); i++ {
p := &g.Point[i]
newX := int32((int64(p.X)*int64(transform[0])+1<<13)>>14) +
int32((int64(p.Y)*int64(transform[2])+1<<13)>>14)
newY := int32((int64(p.X)*int64(transform[1])+1<<13)>>14) +
int32((int64(p.Y)*int64(transform[3])+1<<13)>>14)
p.X, p.Y = newX, newY
}
}
dx = g.font.scale(g.scale * dx)
dy = g.font.scale(g.scale * dy)
if flags&flagRoundXYToGrid != 0 {

View file

@ -263,7 +263,6 @@ var scalingTestCases = []struct {
// TODO: also test bounding boxes, not just points.
func testScaling(t *testing.T, hinter *Hinter) {
loop:
for _, tc := range scalingTestCases {
font, testdataIsOptional, err := parseTestdataFont(tc.name)
if err != nil {
@ -272,7 +271,7 @@ loop:
} else {
t.Error(err)
}
continue loop
continue
}
hinting := "sans"
if hinter != nil {
@ -282,7 +281,7 @@ loop:
"../../testdata/%s-%dpt-%s-hinting.txt", tc.name, tc.size, hinting))
if err != nil {
t.Errorf("%s: Open: %v", tc.name, err)
continue loop
continue
}
defer f.Close()
@ -293,7 +292,7 @@ loop:
}
if err := scanner.Err(); err != nil && err != io.EOF {
t.Errorf("%s: Scanner: %v", tc.name, err)
continue loop
continue
}
glyphBuf := NewGlyphBuf()
@ -305,12 +304,8 @@ loop:
}
if err = glyphBuf.Load(font, tc.size*64, Index(i), hinter); err != nil {
if ue, ok := err.(UnsupportedError); ok && ue == "compound glyph scale/transform" {
// TODO: implement compound glyph scale/transform.
continue loop
}
t.Errorf("%s: glyph #%d: Load: %v", tc.name, i, err)
continue loop
continue
}
got := glyphBuf.Point
for i := range got {