freetype/truetype: WCVTP, RCVT opcodes.
R=bsiegert CC=golang-dev https://codereview.appspot.com/14802046
This commit is contained in:
parent
bb775957cb
commit
b821f16356
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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},
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user