freetype/truetype: implement GC and MD instructions.
These instructions are found in Adobe Source Sans Pro fonts. R=golang-dev, nigeltao, bsiegert CC=golang-dev https://codereview.appspot.com/16440043 Committer: Nigel Tao <nigeltao@golang.org>
This commit is contained in:
parent
ab106efa01
commit
7bee3b6fe0
|
@ -627,6 +627,33 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
||||||
case opRCVT:
|
case opRCVT:
|
||||||
h.stack[top-1] = int32(h.getScaledCVT(h.stack[top-1]))
|
h.stack[top-1] = int32(h.getScaledCVT(h.stack[top-1]))
|
||||||
|
|
||||||
|
case opGC0, opGC1:
|
||||||
|
i := h.stack[top-1]
|
||||||
|
if opcode == opGC0 {
|
||||||
|
p := h.point(2, current, i)
|
||||||
|
h.stack[top-1] = int32(dotProduct(f26dot6(p.X), f26dot6(p.Y), h.gs.pv))
|
||||||
|
} else {
|
||||||
|
p := h.point(2, unhinted, i)
|
||||||
|
// Using dv as per C Freetype.
|
||||||
|
h.stack[top-1] = int32(dotProduct(f26dot6(p.X), f26dot6(p.Y), h.gs.dv))
|
||||||
|
}
|
||||||
|
|
||||||
|
case opMD0, opMD1:
|
||||||
|
top--
|
||||||
|
i, j := h.stack[top-1], h.stack[top]
|
||||||
|
if opcode == opMD1 {
|
||||||
|
p := h.point(0, current, i)
|
||||||
|
q := h.point(1, current, j)
|
||||||
|
h.stack[top-1] = int32(dotProduct(f26dot6(p.X-q.X), f26dot6(p.Y-q.Y), h.gs.pv))
|
||||||
|
} else {
|
||||||
|
// TODO: do we need to check (h.gs.zp[0] == 0 || h.gs.zp[1] == 0)
|
||||||
|
// as C Freetype does, similar to the MDRP instructions?
|
||||||
|
p := h.point(0, unhinted, i)
|
||||||
|
q := h.point(1, unhinted, j)
|
||||||
|
// Use dv for MD0 as in C Freetype.
|
||||||
|
h.stack[top-1] = int32(dotProduct(f26dot6(p.X-q.X), f26dot6(p.Y-q.Y), h.gs.dv))
|
||||||
|
}
|
||||||
|
|
||||||
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")
|
||||||
|
|
|
@ -80,11 +80,11 @@ const (
|
||||||
opRS = 0x43 // Read Store
|
opRS = 0x43 // Read Store
|
||||||
opWCVTP = 0x44 // Write Control Value Table in Pixel units
|
opWCVTP = 0x44 // Write Control Value Table in Pixel units
|
||||||
opRCVT = 0x45 // Read Control Value Table entry
|
opRCVT = 0x45 // Read Control Value Table entry
|
||||||
opGC0 = 0x46
|
opGC0 = 0x46 // Get Coordinate projected onto the projection vector
|
||||||
opGC1 = 0x47
|
opGC1 = 0x47 // .
|
||||||
opSCFS = 0x48
|
opSCFS = 0x48
|
||||||
opMD0 = 0x49
|
opMD0 = 0x49 // Measure Distance
|
||||||
opMD1 = 0x4a
|
opMD1 = 0x4a // .
|
||||||
opMPPEM = 0x4b // Measure Pixels Per EM
|
opMPPEM = 0x4b // Measure Pixels Per EM
|
||||||
opMPS = 0x4c // Measure Point Size
|
opMPS = 0x4c // Measure Point Size
|
||||||
opFLIPON = 0x4d // set the auto FLIP Boolean to ON
|
opFLIPON = 0x4d // set the auto FLIP Boolean to ON
|
||||||
|
@ -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, 1, 1, 1, 0, q, q, 0, 0, 2, 2, // 0x30 - 0x3f
|
0, 0, q, q, q, q, 1, 1, 1, 0, q, q, 0, 0, 2, 2, // 0x30 - 0x3f
|
||||||
0, 0, 2, 1, 2, 1, q, q, q, q, q, 0, 0, 0, 0, 0, // 0x40 - 0x4f
|
0, 0, 2, 1, 2, 1, 1, 1, q, 2, 2, 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
|
||||||
|
|
Loading…
Reference in New Issue