font/sfnt: implement rcurveline and rlinecurve.

Change-Id: I563f9e4a76a5c91d2ef2b6ffccc78550ab582d08
Reviewed-on: https://go-review.googlesource.com/38110
Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
Nigel Tao 2017-03-12 12:07:09 +11:00
parent 793f3be7da
commit c1a19c11c3
2 changed files with 74 additions and 10 deletions

View File

@ -564,8 +564,8 @@ var psOperators = [...][2][]psOperator{
21: {-1, "rmoveto", t2CRmoveto},
22: {-1, "hmoveto", t2CHmoveto},
23: {-1, "vstemhm", t2CStem},
24: {}, // rcurveline.
25: {}, // rlinecurve.
24: {-1, "rcurveline", t2CRcurveline},
25: {-1, "rlinecurve", t2CRlinecurve},
26: {-1, "vvcurveto", t2CVvcurveto},
27: {-1, "hhcurveto", t2CHhcurveto},
28: {}, // shortint.
@ -736,10 +736,7 @@ func t2CHlineto(p *psInterpreter) error { return t2CLineto(p, false) }
func t2CVlineto(p *psInterpreter) error { return t2CLineto(p, true) }
func t2CLineto(p *psInterpreter, vertical bool) error {
if !p.type2Charstrings.seenWidth {
return errInvalidCFFTable
}
if p.stack.top < 1 {
if !p.type2Charstrings.seenWidth || p.stack.top < 1 {
return errInvalidCFFTable
}
for i := int32(0); i < p.stack.top; i, vertical = i+1, !vertical {
@ -754,10 +751,7 @@ func t2CLineto(p *psInterpreter, vertical bool) error {
}
func t2CRlineto(p *psInterpreter) error {
if !p.type2Charstrings.seenWidth {
return errInvalidCFFTable
}
if p.stack.top < 2 || p.stack.top%2 != 0 {
if !p.type2Charstrings.seenWidth || p.stack.top < 2 || p.stack.top%2 != 0 {
return errInvalidCFFTable
}
for i := int32(0); i < p.stack.top; i += 2 {
@ -768,6 +762,56 @@ func t2CRlineto(p *psInterpreter) error {
return nil
}
// As per 5177.Type2.pdf section 4.1 "Path Construction Operators",
//
// rcurveline is:
// - {dxa dya dxb dyb dxc dyc}+ dxd dyd
//
// rlinecurve is:
// - {dxa dya}+ dxb dyb dxc dyc dxd dyd
func t2CRcurveline(p *psInterpreter) error {
if !p.type2Charstrings.seenWidth || p.stack.top < 8 || p.stack.top%6 != 2 {
return errInvalidCFFTable
}
i := int32(0)
for iMax := p.stack.top - 2; i < iMax; i += 6 {
t2CAppendCubeto(p,
p.stack.a[i+0],
p.stack.a[i+1],
p.stack.a[i+2],
p.stack.a[i+3],
p.stack.a[i+4],
p.stack.a[i+5],
)
}
p.type2Charstrings.x += p.stack.a[i+0]
p.type2Charstrings.y += p.stack.a[i+1]
t2CAppendLineto(p)
return nil
}
func t2CRlinecurve(p *psInterpreter) error {
if !p.type2Charstrings.seenWidth || p.stack.top < 8 || p.stack.top%2 != 0 {
return errInvalidCFFTable
}
i := int32(0)
for iMax := p.stack.top - 6; i < iMax; i += 2 {
p.type2Charstrings.x += p.stack.a[i+0]
p.type2Charstrings.y += p.stack.a[i+1]
t2CAppendLineto(p)
}
t2CAppendCubeto(p,
p.stack.a[i+0],
p.stack.a[i+1],
p.stack.a[i+2],
p.stack.a[i+3],
p.stack.a[i+4],
p.stack.a[i+5],
)
return nil
}
// As per 5177.Type2.pdf section 4.1 "Path Construction Operators",
//
// hhcurveto is:

View File

@ -380,6 +380,26 @@ var proprietaryGlyphTestCases = map[string]map[rune][]Segment{
// -90 38 83 -66 121 hhcurveto
cubeTo(329, -99, 412, -165, 533, -165),
},
'Λ': { // U+039B GREEK CAPITAL LETTER LAMDA
// 0 vmoveto
moveTo(0, 0),
// 85 hlineto
lineTo(85, 0),
// 105 355 23 77 16 63 24 77 rlinecurve
lineTo(190, 355),
cubeTo(213, 432, 229, 495, 253, 572),
// 4 hlineto
lineTo(257, 572),
// 25 -77 16 -63 23 -77 106 -355 rcurveline
cubeTo(282, 495, 298, 432, 321, 355),
lineTo(427, 0),
// 88 hlineto
lineTo(515, 0),
// -210 656 rlineto
lineTo(305, 656),
// -96 hlineto
lineTo(209, 656),
},
},
"microsoft/Arial.ttf": {