提交 b821f163 编写于 作者: N Nigel Tao

freetype/truetype: WCVTP, RCVT opcodes.

R=bsiegert
CC=golang-dev
https://codereview.appspot.com/14802046
上级 bb775957
...@@ -58,6 +58,10 @@ type Hinter struct { ...@@ -58,6 +58,10 @@ type Hinter struct {
// and glyph's contour boundaries. // and glyph's contour boundaries.
points [numZone][numPointType][]Point points [numZone][numPointType][]Point
ends []int ends []int
// scaledCVT is the lazily initialized scaled Control Value Table.
scaledCVTInitialized bool
scaledCVT []f26dot6
} }
// graphicsState is described at https://developer.apple.com/fonts/TTRefMan/RM04/Chap4.html // graphicsState is described at https://developer.apple.com/fonts/TTRefMan/RM04/Chap4.html
...@@ -169,6 +173,7 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point, ...@@ -169,6 +173,7 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
h.points[glyphZone][unhinted] = pUnhinted h.points[glyphZone][unhinted] = pUnhinted
h.points[glyphZone][inFontUnits] = pInFontUnits h.points[glyphZone][inFontUnits] = pInFontUnits
h.ends = ends h.ends = ends
h.scaledCVTInitialized = false
if len(program) > 50000 { if len(program) > 50000 {
return errors.New("truetype: hinting: too many instructions") return errors.New("truetype: hinting: too many instructions")
...@@ -514,7 +519,7 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point, ...@@ -514,7 +519,7 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
case opMIAP0, opMIAP1: case opMIAP0, opMIAP1:
top -= 2 top -= 2
i := h.stack[top] i := h.stack[top]
distance := h.cvt(h.stack[top+1]) distance := h.getScaledCVT(h.stack[top+1])
if h.gs.zp[0] == 0 { if h.gs.zp[0] == 0 {
p := h.point(0, unhinted, i) p := h.point(0, unhinted, i)
q := h.point(0, current, i) q := h.point(0, current, i)
...@@ -558,6 +563,13 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point, ...@@ -558,6 +563,13 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
} }
h.stack[top-1] = h.store[i] h.stack[top-1] = h.store[i]
case opWCVTP:
top -= 2
h.setScaledCVT(h.stack[top], f26dot6(h.stack[top+1]))
case opRCVT:
h.stack[top-1] = int32(h.getScaledCVT(h.stack[top-1]))
case opMPPEM, opMPS: case opMPPEM, opMPS:
if top >= len(h.stack) { if top >= len(h.stack) {
return errors.New("truetype: hinting: stack overflow") return errors.New("truetype: hinting: stack overflow")
...@@ -867,7 +879,7 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point, ...@@ -867,7 +879,7 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
top -= 2 top -= 2
i := h.stack[top] i := h.stack[top]
cvtDist := h.cvt(h.stack[top+1]) cvtDist := h.getScaledCVT(h.stack[top+1])
if (cvtDist - h.gs.singleWidth).abs() < h.gs.singleWidthCutIn { if (cvtDist - h.gs.singleWidth).abs() < h.gs.singleWidthCutIn {
if cvtDist >= 0 { if cvtDist >= 0 {
cvtDist = +h.gs.singleWidth cvtDist = +h.gs.singleWidth
...@@ -1011,14 +1023,42 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point, ...@@ -1011,14 +1023,42 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
return nil return nil
} }
// cvt returns the scaled value from the font's Control Value Table. func (h *Hinter) initializeScaledCVT() {
func (h *Hinter) cvt(i int32) f26dot6 { h.scaledCVTInitialized = true
i *= 2 if n := len(h.font.cvt) / 2; n <= cap(h.scaledCVT) {
if i < 0 || len(h.font.cvt) < int(i) { h.scaledCVT = h.scaledCVT[:n]
} else {
if n < 32 {
n = 32
}
h.scaledCVT = make([]f26dot6, len(h.font.cvt)/2, n)
}
for i := range h.scaledCVT {
unscaled := uint16(h.font.cvt[2*i])<<8 | uint16(h.font.cvt[2*i+1])
h.scaledCVT[i] = f26dot6(h.font.scale(h.scale * int32(int16(unscaled))))
}
}
// getScaledCVT returns the scaled value from the font's Control Value Table.
func (h *Hinter) getScaledCVT(i int32) f26dot6 {
if !h.scaledCVTInitialized {
h.initializeScaledCVT()
}
if i < 0 || len(h.scaledCVT) <= int(i) {
return 0 return 0
} }
cv := uint16(h.font.cvt[i])<<8 | uint16(h.font.cvt[i+1]) return h.scaledCVT[i]
return f26dot6(h.font.scale(h.scale * int32(int16(cv)))) }
// setScaledCVT overrides the scaled value from the font's Control Value Table.
func (h *Hinter) setScaledCVT(i int32, v f26dot6) {
if !h.scaledCVTInitialized {
h.initializeScaledCVT()
}
if i < 0 || len(h.scaledCVT) <= int(i) {
return
}
h.scaledCVT[i] = v
} }
func (h *Hinter) point(zonePointer uint32, pt pointType, i int32) *Point { func (h *Hinter) point(zonePointer uint32, pt pointType, i int32) *Point {
......
...@@ -78,8 +78,8 @@ const ( ...@@ -78,8 +78,8 @@ const (
opNPUSHW = 0x41 // PUSH N Words opNPUSHW = 0x41 // PUSH N Words
opWS = 0x42 // Write Store opWS = 0x42 // Write Store
opRS = 0x43 // Read Store opRS = 0x43 // Read Store
opWCVTP = 0x44 opWCVTP = 0x44 // Write Control Value Table in Pixel units
opRCVT = 0x45 opRCVT = 0x45 // Read Control Value Table entry
opGC0 = 0x46 opGC0 = 0x46
opGC1 = 0x47 opGC1 = 0x47
opSCFS = 0x48 opSCFS = 0x48
...@@ -275,7 +275,7 @@ var popCount = [256]uint8{ ...@@ -275,7 +275,7 @@ var popCount = [256]uint8{
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, // 0x10 - 0x1f 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, // 0x10 - 0x1f
1, 1, 0, 2, 0, 1, 1, q, q, q, 2, 1, 1, 0, 1, 1, // 0x20 - 0x2f 1, 1, 0, 2, 0, 1, 1, q, q, q, 2, 1, 1, 0, 1, 1, // 0x20 - 0x2f
0, 0, q, q, q, q, q, q, q, 0, q, q, 0, 0, 2, 2, // 0x30 - 0x3f 0, 0, q, q, q, q, q, q, q, 0, q, q, 0, 0, 2, 2, // 0x30 - 0x3f
0, 0, 2, 1, q, q, q, q, q, q, q, 0, 0, 0, 0, 0, // 0x40 - 0x4f 0, 0, 2, 1, 2, 1, q, q, q, q, q, 0, 0, 0, 0, 0, // 0x40 - 0x4f
2, 2, 2, 2, 2, 2, 1, 1, 1, 0, 2, 2, 1, q, 1, 1, // 0x50 - 0x5f 2, 2, 2, 2, 2, 2, 1, 1, 1, 0, 2, 2, 1, q, 1, 1, // 0x50 - 0x5f
2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 0x6f 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 0x6f
q, q, q, q, q, q, 1, 1, 2, 2, 0, q, 0, 0, 1, 1, // 0x70 - 0x7f q, q, q, q, q, q, 1, 1, 2, 2, 0, q, 0, 0, 1, 1, // 0x70 - 0x7f
......
...@@ -253,7 +253,7 @@ var scalingTestCases = []struct { ...@@ -253,7 +253,7 @@ var scalingTestCases = []struct {
}{ }{
{"luxisr", 12, -1}, {"luxisr", 12, -1},
{"x-arial-bold", 11, 0}, {"x-arial-bold", 11, 0},
{"x-deja-vu-sans-oblique", 17, 0}, {"x-deja-vu-sans-oblique", 17, 1},
{"x-droid-sans-japanese", 9, 0}, {"x-droid-sans-japanese", 9, 0},
{"x-times-new-roman", 13, 0}, {"x-times-new-roman", 13, 0},
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册