freetype/truetype: implement SHP and DELTAP opcodes.
R=bsiegert CC=golang-dev, remyoudompheng https://codereview.appspot.com/16500043
This commit is contained in:
parent
486e1683dd
commit
ab80f5823d
|
@ -480,6 +480,24 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
prevEnd = end
|
||||
}
|
||||
|
||||
case opSHP0, opSHP1:
|
||||
if top < int(h.gs.loop) {
|
||||
return errors.New("truetype: hinting: stack underflow")
|
||||
}
|
||||
_, _, d, ok := h.displacement(opcode&1 == 0)
|
||||
if !ok {
|
||||
return errors.New("truetype: hinting: point out of range")
|
||||
}
|
||||
for ; h.gs.loop != 0; h.gs.loop-- {
|
||||
top--
|
||||
p := h.point(2, current, h.stack[top])
|
||||
if p == nil {
|
||||
return errors.New("truetype: hinting: point out of range")
|
||||
}
|
||||
h.move(p, d, true)
|
||||
}
|
||||
h.gs.loop = 1
|
||||
|
||||
case opSHZ0, opSHZ1:
|
||||
top--
|
||||
zonePointer, i, d, ok := h.displacement(opcode&1 == 0)
|
||||
|
@ -740,6 +758,9 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
case opNOT:
|
||||
h.stack[top-1] = bool2int32(h.stack[top-1] == 0)
|
||||
|
||||
case opDELTAP1:
|
||||
goto deltap
|
||||
|
||||
case opSDB:
|
||||
top--
|
||||
h.gs.deltaBase = h.stack[top]
|
||||
|
@ -794,6 +815,9 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
// This code does not implement engine compensation, as we don't expect to
|
||||
// be used to output on dot-matrix printers.
|
||||
|
||||
case opDELTAP2, opDELTAP3:
|
||||
goto deltap
|
||||
|
||||
case opSROUND, opS45ROUND:
|
||||
top--
|
||||
switch (h.stack[top] >> 6) & 0x03 {
|
||||
|
@ -1130,6 +1154,40 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
}
|
||||
continue
|
||||
}
|
||||
|
||||
deltap:
|
||||
top--
|
||||
n := f26dot6(h.stack[top])
|
||||
if top < 2*int(h.gs.loop) {
|
||||
return errors.New("truetype: hinting: stack underflow")
|
||||
}
|
||||
for ; n > 0; n-- {
|
||||
top -= 2
|
||||
p := h.point(0, current, h.stack[top+1])
|
||||
if p == nil {
|
||||
return errors.New("truetype: hinting: point out of range")
|
||||
}
|
||||
b := h.stack[top]
|
||||
c := (b & 0xf0) >> 4
|
||||
switch opcode {
|
||||
case opDELTAP2:
|
||||
c += 16
|
||||
case opDELTAP3:
|
||||
c += 32
|
||||
}
|
||||
c += h.gs.deltaBase
|
||||
if ppem := (h.scale + 1<<5) >> 6; ppem != c {
|
||||
continue
|
||||
}
|
||||
b = (b & 0x0f) - 8
|
||||
if b >= 0 {
|
||||
b++
|
||||
}
|
||||
b = b * 64 / (1 << uint32(h.gs.deltaShift))
|
||||
h.move(p, f26dot6(b), true)
|
||||
}
|
||||
pc++
|
||||
continue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -60,8 +60,8 @@ const (
|
|||
opMDAP1 = 0x2f // .
|
||||
opIUP0 = 0x30 // Interpolate Untouched Points through the outline
|
||||
opIUP1 = 0x31 // .
|
||||
opSHP0 = 0x32
|
||||
opSHP1 = 0x33
|
||||
opSHP0 = 0x32 // SHift Point using reference point
|
||||
opSHP1 = 0x33 // .
|
||||
opSHC0 = 0x34
|
||||
opSHC1 = 0x35
|
||||
opSHZ0 = 0x36 // SHift Zone using reference point
|
||||
|
@ -103,7 +103,7 @@ const (
|
|||
opAND = 0x5a // logical AND
|
||||
opOR = 0x5b // logical OR
|
||||
opNOT = 0x5c // logical NOT
|
||||
opDELTAP1 = 0x5d
|
||||
opDELTAP1 = 0x5d // DELTA exception P1
|
||||
opSDB = 0x5e // Set Delta Base in the graphics state
|
||||
opSDS = 0x5f // Set Delta Shift in the graphics state
|
||||
opADD = 0x60 // ADD
|
||||
|
@ -123,8 +123,8 @@ const (
|
|||
opNROUND10 = 0x6e // .
|
||||
opNROUND11 = 0x6f // .
|
||||
opWCVTF = 0x70
|
||||
opDELTAP2 = 0x71
|
||||
opDELTAP3 = 0x72
|
||||
opDELTAP2 = 0x71 // DELTA exception P2
|
||||
opDELTAP3 = 0x72 // DELTA exception P3
|
||||
opDELTAC1 = 0x73
|
||||
opDELTAC2 = 0x74
|
||||
opDELTAC3 = 0x75
|
||||
|
@ -274,11 +274,11 @@ var popCount = [256]uint8{
|
|||
0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, q, // 0x00 - 0x0f
|
||||
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, 1, 1, 1, 0, 2, 2, 0, 0, 2, 2, // 0x30 - 0x3f
|
||||
0, 0, 0, 0, q, q, 1, 1, 1, 0, 2, 2, 0, 0, 2, 2, // 0x30 - 0x3f
|
||||
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, 1, 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
|
||||
q, 1, 1, q, q, q, 1, 1, 2, 2, 0, q, 0, 0, 1, 1, // 0x70 - 0x7f
|
||||
q, q, q, q, q, 1, q, q, 1, 1, 3, 2, 2, 1, q, q, // 0x80 - 0x8f
|
||||
q, q, q, q, q, q, q, q, q, q, q, q, q, q, q, q, // 0x90 - 0x9f
|
||||
q, q, q, q, q, q, q, q, q, q, q, q, q, q, q, q, // 0xa0 - 0xaf
|
||||
|
|
|
@ -253,7 +253,7 @@ var scalingTestCases = []struct {
|
|||
}{
|
||||
{"luxisr", 12, -1},
|
||||
{"x-arial-bold", 11, 0},
|
||||
{"x-deja-vu-sans-oblique", 17, 5},
|
||||
{"x-deja-vu-sans-oblique", 17, 14},
|
||||
{"x-droid-sans-japanese", 9, 0},
|
||||
{"x-times-new-roman", 13, 0},
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user