freetype/truetype: variable sized bytecode interpreter stack/store.
R=bsiegert CC=golang-dev http://codereview.appspot.com/6343091
This commit is contained in:
parent
2bf22ccf6b
commit
20ce6ab4df
3 changed files with 24 additions and 5 deletions
|
@ -13,11 +13,7 @@ import (
|
|||
)
|
||||
|
||||
type hinter struct {
|
||||
// TODO: variable sized stack and store slices based on the maxp section?
|
||||
// Should the arrays for the stack and store be combined? For now, fixed
|
||||
// maximum sizes seem to work in practice.
|
||||
stack [800]int32
|
||||
store [128]int32
|
||||
stack, store []int32
|
||||
|
||||
// The fields below constitue the graphics state, which is described at
|
||||
// https://developer.apple.com/fonts/TTRefMan/RM04/Chap4.html
|
||||
|
@ -32,6 +28,19 @@ type hinter struct {
|
|||
roundPeriod, roundPhase, roundThreshold f26dot6
|
||||
}
|
||||
|
||||
func (h *hinter) init(f *Font) {
|
||||
if x := int(f.maxStackElements); x > len(h.stack) {
|
||||
x += 255
|
||||
x &^= 255
|
||||
h.stack = make([]int32, x)
|
||||
}
|
||||
if x := int(f.maxStorage); x > len(h.store) {
|
||||
x += 15
|
||||
x &^= 15
|
||||
h.store = make([]int32, x)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *hinter) run(program []byte) error {
|
||||
// The default vectors are along the X axis.
|
||||
h.pv = [2]f2dot14{0x4000, 0}
|
||||
|
|
|
@ -489,6 +489,10 @@ func TestBytecode(t *testing.T) {
|
|||
|
||||
for _, tc := range testCases {
|
||||
h := &hinter{}
|
||||
h.init(&Font{
|
||||
maxStorage: 32,
|
||||
maxStackElements: 100,
|
||||
})
|
||||
err, errStr := h.run(tc.prog), ""
|
||||
if err != nil {
|
||||
errStr = err.Error()
|
||||
|
|
|
@ -98,6 +98,8 @@ type Font struct {
|
|||
nGlyph, nHMetric, nKern int
|
||||
unitsPerEm int
|
||||
bounds Bounds
|
||||
// Values from the maxp section.
|
||||
maxTwilightPoints, maxStorage, maxFunctionDefs, maxStackElements uint16
|
||||
}
|
||||
|
||||
func (f *Font) parseCmap() error {
|
||||
|
@ -254,6 +256,10 @@ func (f *Font) parseMaxp() error {
|
|||
return FormatError(fmt.Sprintf("bad maxp length: %d", len(f.maxp)))
|
||||
}
|
||||
f.nGlyph = int(u16(f.maxp, 4))
|
||||
f.maxTwilightPoints = u16(f.maxp, 16)
|
||||
f.maxStorage = u16(f.maxp, 18)
|
||||
f.maxFunctionDefs = u16(f.maxp, 20)
|
||||
f.maxStackElements = u16(f.maxp, 24)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue