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
|
@ -13,11 +13,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type hinter struct {
|
type hinter struct {
|
||||||
// TODO: variable sized stack and store slices based on the maxp section?
|
stack, store []int32
|
||||||
// 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
|
|
||||||
|
|
||||||
// The fields below constitue the graphics state, which is described at
|
// The fields below constitue the graphics state, which is described at
|
||||||
// https://developer.apple.com/fonts/TTRefMan/RM04/Chap4.html
|
// https://developer.apple.com/fonts/TTRefMan/RM04/Chap4.html
|
||||||
|
@ -32,6 +28,19 @@ type hinter struct {
|
||||||
roundPeriod, roundPhase, roundThreshold f26dot6
|
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 {
|
func (h *hinter) run(program []byte) error {
|
||||||
// The default vectors are along the X axis.
|
// The default vectors are along the X axis.
|
||||||
h.pv = [2]f2dot14{0x4000, 0}
|
h.pv = [2]f2dot14{0x4000, 0}
|
||||||
|
|
|
@ -489,6 +489,10 @@ func TestBytecode(t *testing.T) {
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
h := &hinter{}
|
h := &hinter{}
|
||||||
|
h.init(&Font{
|
||||||
|
maxStorage: 32,
|
||||||
|
maxStackElements: 100,
|
||||||
|
})
|
||||||
err, errStr := h.run(tc.prog), ""
|
err, errStr := h.run(tc.prog), ""
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errStr = err.Error()
|
errStr = err.Error()
|
||||||
|
|
|
@ -98,6 +98,8 @@ type Font struct {
|
||||||
nGlyph, nHMetric, nKern int
|
nGlyph, nHMetric, nKern int
|
||||||
unitsPerEm int
|
unitsPerEm int
|
||||||
bounds Bounds
|
bounds Bounds
|
||||||
|
// Values from the maxp section.
|
||||||
|
maxTwilightPoints, maxStorage, maxFunctionDefs, maxStackElements uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Font) parseCmap() error {
|
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)))
|
return FormatError(fmt.Sprintf("bad maxp length: %d", len(f.maxp)))
|
||||||
}
|
}
|
||||||
f.nGlyph = int(u16(f.maxp, 4))
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue