freetype/truetype: WCVTP, RCVT opcodes.

R=bsiegert
CC=golang-dev
https://codereview.appspot.com/14802046
This commit is contained in:
Nigel Tao 2013-10-19 10:04:03 +11:00
parent bb775957cb
commit b821f16356
3 changed files with 52 additions and 12 deletions

View file

@ -58,6 +58,10 @@ type Hinter struct {
// and glyph's contour boundaries.
points [numZone][numPointType][]Point
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
@ -169,6 +173,7 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
h.points[glyphZone][unhinted] = pUnhinted
h.points[glyphZone][inFontUnits] = pInFontUnits
h.ends = ends
h.scaledCVTInitialized = false
if len(program) > 50000 {
return errors.New("truetype: hinting: too many instructions")
@ -514,7 +519,7 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
case opMIAP0, opMIAP1:
top -= 2
i := h.stack[top]
distance := h.cvt(h.stack[top+1])
distance := h.getScaledCVT(h.stack[top+1])
if h.gs.zp[0] == 0 {
p := h.point(0, unhinted, i)
q := h.point(0, current, i)
@ -558,6 +563,13 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
}
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:
if top >= len(h.stack) {
return errors.New("truetype: hinting: stack overflow")
@ -867,7 +879,7 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
top -= 2
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 >= 0 {
cvtDist = +h.gs.singleWidth
@ -1011,14 +1023,42 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
return nil
}
// cvt returns the scaled value from the font's Control Value Table.
func (h *Hinter) cvt(i int32) f26dot6 {
i *= 2
if i < 0 || len(h.font.cvt) < int(i) {
func (h *Hinter) initializeScaledCVT() {
h.scaledCVTInitialized = true
if n := len(h.font.cvt) / 2; n <= cap(h.scaledCVT) {
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
}
cv := uint16(h.font.cvt[i])<<8 | uint16(h.font.cvt[i+1])
return f26dot6(h.font.scale(h.scale * int32(int16(cv))))
return h.scaledCVT[i]
}
// 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 {

View file

@ -78,8 +78,8 @@ const (
opNPUSHW = 0x41 // PUSH N Words
opWS = 0x42 // Write Store
opRS = 0x43 // Read Store
opWCVTP = 0x44
opRCVT = 0x45
opWCVTP = 0x44 // Write Control Value Table in Pixel units
opRCVT = 0x45 // Read Control Value Table entry
opGC0 = 0x46
opGC1 = 0x47
opSCFS = 0x48
@ -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, 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, 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, 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

View file

@ -253,7 +253,7 @@ var scalingTestCases = []struct {
}{
{"luxisr", 12, -1},
{"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-times-new-roman", 13, 0},
}