Delete the f26dot6 type in favor of fixed.Int26_6.
This commit is contained in:
parent
43fc220ebd
commit
7e2154db58
1 changed files with 64 additions and 67 deletions
131
truetype/hint.go
131
truetype/hint.go
|
@ -63,7 +63,7 @@ type hinter struct {
|
|||
|
||||
// scaledCVT is the lazily initialized scaled Control Value Table.
|
||||
scaledCVTInitialized bool
|
||||
scaledCVT []f26dot6
|
||||
scaledCVT []fixed.Int26_6
|
||||
}
|
||||
|
||||
// graphicsState is described at https://developer.apple.com/fonts/TTRefMan/RM04/Chap4.html
|
||||
|
@ -73,15 +73,15 @@ type graphicsState struct {
|
|||
// Reference points and zone pointers.
|
||||
rp, zp [3]int32
|
||||
// Control Value / Single Width Cut-In.
|
||||
controlValueCutIn, singleWidthCutIn, singleWidth f26dot6
|
||||
controlValueCutIn, singleWidthCutIn, singleWidth fixed.Int26_6
|
||||
// Delta base / shift.
|
||||
deltaBase, deltaShift int32
|
||||
// Minimum distance.
|
||||
minDist f26dot6
|
||||
minDist fixed.Int26_6
|
||||
// Loop count.
|
||||
loop int32
|
||||
// Rounding policy.
|
||||
roundPeriod, roundPhase, roundThreshold f26dot6
|
||||
roundPeriod, roundPhase, roundThreshold fixed.Int26_6
|
||||
roundSuper45 bool
|
||||
// Auto-flip.
|
||||
autoFlip bool
|
||||
|
@ -92,13 +92,13 @@ var globalDefaultGS = graphicsState{
|
|||
fv: [2]f2dot14{0x4000, 0},
|
||||
dv: [2]f2dot14{0x4000, 0},
|
||||
zp: [3]int32{1, 1, 1},
|
||||
controlValueCutIn: (17 << 6) / 16, // 17/16 as an f26dot6.
|
||||
controlValueCutIn: (17 << 6) / 16, // 17/16 as a fixed.Int26_6.
|
||||
deltaBase: 9,
|
||||
deltaShift: 3,
|
||||
minDist: 1 << 6, // 1 as an f26dot6.
|
||||
minDist: 1 << 6, // 1 as a fixed.Int26_6.
|
||||
loop: 1,
|
||||
roundPeriod: 1 << 6, // 1 as an f26dot6.
|
||||
roundThreshold: 1 << 5, // 1/2 as an f26dot6.
|
||||
roundPeriod: 1 << 6, // 1 as a fixed.Int26_6.
|
||||
roundThreshold: 1 << 5, // 1/2 as a fixed.Int26_6.
|
||||
roundSuper45: false,
|
||||
autoFlip: true,
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
|
||||
case opSMD:
|
||||
top--
|
||||
h.gs.minDist = f26dot6(h.stack[top])
|
||||
h.gs.minDist = fixed.Int26_6(h.stack[top])
|
||||
|
||||
case opELSE:
|
||||
opcode = 1
|
||||
|
@ -373,15 +373,15 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
|
||||
case opSCVTCI:
|
||||
top--
|
||||
h.gs.controlValueCutIn = f26dot6(h.stack[top])
|
||||
h.gs.controlValueCutIn = fixed.Int26_6(h.stack[top])
|
||||
|
||||
case opSSWCI:
|
||||
top--
|
||||
h.gs.singleWidthCutIn = f26dot6(h.stack[top])
|
||||
h.gs.singleWidthCutIn = fixed.Int26_6(h.stack[top])
|
||||
|
||||
case opSSW:
|
||||
top--
|
||||
h.gs.singleWidth = f26dot6(h.font.scale(h.scale * fixed.Int26_6(h.stack[top])))
|
||||
h.gs.singleWidth = h.font.scale(h.scale * fixed.Int26_6(h.stack[top]))
|
||||
|
||||
case opDUP:
|
||||
if top >= len(h.stack) {
|
||||
|
@ -424,7 +424,7 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
if p == nil || q == nil {
|
||||
return errors.New("truetype: hinting: point out of range")
|
||||
}
|
||||
d := dotProduct(f26dot6(q.X-p.X), f26dot6(q.Y-p.Y), h.gs.pv) / 2
|
||||
d := dotProduct(fixed.Int26_6(q.X-p.X), fixed.Int26_6(q.Y-p.Y), h.gs.pv) / 2
|
||||
h.move(p, +d, true)
|
||||
h.move(q, -d, true)
|
||||
|
||||
|
@ -502,9 +502,9 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
if p == nil {
|
||||
return errors.New("truetype: hinting: point out of range")
|
||||
}
|
||||
distance := f26dot6(0)
|
||||
distance := fixed.Int26_6(0)
|
||||
if opcode == opMDAP1 {
|
||||
distance = dotProduct(f26dot6(p.X), f26dot6(p.Y), h.gs.pv)
|
||||
distance = dotProduct(p.X, p.Y, h.gs.pv)
|
||||
// TODO: metrics compensation.
|
||||
distance = h.round(distance) - distance
|
||||
}
|
||||
|
@ -610,7 +610,7 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
|
||||
case opSHPIX:
|
||||
top--
|
||||
d := f26dot6(h.stack[top])
|
||||
d := fixed.Int26_6(h.stack[top])
|
||||
if top < int(h.gs.loop) {
|
||||
return errors.New("truetype: hinting: stack underflow")
|
||||
}
|
||||
|
@ -635,22 +635,22 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
}
|
||||
p := h.point(1, pointType, h.gs.rp[2])
|
||||
oldP := h.point(0, pointType, h.gs.rp[1])
|
||||
oldRange := dotProduct(f26dot6(p.X-oldP.X), f26dot6(p.Y-oldP.Y), h.gs.dv)
|
||||
oldRange := dotProduct(p.X-oldP.X, p.Y-oldP.Y, h.gs.dv)
|
||||
|
||||
p = h.point(1, current, h.gs.rp[2])
|
||||
curP := h.point(0, current, h.gs.rp[1])
|
||||
curRange := dotProduct(f26dot6(p.X-curP.X), f26dot6(p.Y-curP.Y), h.gs.pv)
|
||||
curRange := dotProduct(p.X-curP.X, p.Y-curP.Y, h.gs.pv)
|
||||
for ; h.gs.loop != 0; h.gs.loop-- {
|
||||
top--
|
||||
i := h.stack[top]
|
||||
p = h.point(2, pointType, i)
|
||||
oldDist := dotProduct(f26dot6(p.X-oldP.X), f26dot6(p.Y-oldP.Y), h.gs.dv)
|
||||
oldDist := dotProduct(p.X-oldP.X, p.Y-oldP.Y, h.gs.dv)
|
||||
p = h.point(2, current, i)
|
||||
curDist := dotProduct(f26dot6(p.X-curP.X), f26dot6(p.Y-curP.Y), h.gs.pv)
|
||||
newDist := f26dot6(0)
|
||||
curDist := dotProduct(p.X-curP.X, p.Y-curP.Y, h.gs.pv)
|
||||
newDist := fixed.Int26_6(0)
|
||||
if oldDist != 0 {
|
||||
if oldRange != 0 {
|
||||
newDist = f26dot6(mulDiv(int64(oldDist), int64(curRange), int64(oldRange)))
|
||||
newDist = fixed.Int26_6(mulDiv(int64(oldDist), int64(curRange), int64(oldRange)))
|
||||
} else {
|
||||
newDist = -oldDist
|
||||
}
|
||||
|
@ -662,7 +662,7 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
case opMSIRP0, opMSIRP1:
|
||||
top -= 2
|
||||
i := h.stack[top]
|
||||
distance := f26dot6(h.stack[top+1])
|
||||
distance := fixed.Int26_6(h.stack[top+1])
|
||||
|
||||
// TODO: special case h.gs.zp[1] == 0 in C Freetype.
|
||||
ref := h.point(0, current, h.gs.rp[0])
|
||||
|
@ -670,7 +670,7 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
if ref == nil || p == nil {
|
||||
return errors.New("truetype: hinting: point out of range")
|
||||
}
|
||||
curDist := dotProduct(f26dot6(p.X-ref.X), f26dot6(p.Y-ref.Y), h.gs.pv)
|
||||
curDist := dotProduct(p.X-ref.X, p.Y-ref.Y, h.gs.pv)
|
||||
|
||||
// Set-RP0 bit.
|
||||
if opcode == opMSIRP1 {
|
||||
|
@ -696,7 +696,7 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
if p == nil {
|
||||
return errors.New("truetype: hinting: point out of range")
|
||||
}
|
||||
h.move(p, -dotProduct(f26dot6(p.X-ref.X), f26dot6(p.Y-ref.Y), h.gs.pv), true)
|
||||
h.move(p, -dotProduct(p.X-ref.X, p.Y-ref.Y, h.gs.pv), true)
|
||||
}
|
||||
h.gs.loop = 1
|
||||
|
||||
|
@ -718,7 +718,7 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
*q = *p
|
||||
}
|
||||
p := h.point(0, current, i)
|
||||
oldDist := dotProduct(f26dot6(p.X), f26dot6(p.Y), h.gs.pv)
|
||||
oldDist := dotProduct(p.X, p.Y, h.gs.pv)
|
||||
if opcode == opMIAP1 {
|
||||
if fabs(distance-oldDist) > h.gs.controlValueCutIn {
|
||||
distance = oldDist
|
||||
|
@ -755,7 +755,7 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
|
||||
case opWCVTP:
|
||||
top -= 2
|
||||
h.setScaledCVT(h.stack[top], f26dot6(h.stack[top+1]))
|
||||
h.setScaledCVT(h.stack[top], fixed.Int26_6(h.stack[top+1]))
|
||||
|
||||
case opRCVT:
|
||||
h.stack[top-1] = int32(h.getScaledCVT(h.stack[top-1]))
|
||||
|
@ -764,11 +764,11 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
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))
|
||||
h.stack[top-1] = int32(dotProduct(p.X, 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))
|
||||
h.stack[top-1] = int32(dotProduct(p.X, p.Y, h.gs.dv))
|
||||
}
|
||||
|
||||
case opSCFS:
|
||||
|
@ -778,8 +778,8 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
if p == nil {
|
||||
return errors.New("truetype: hinting: point out of range")
|
||||
}
|
||||
c := dotProduct(f26dot6(p.X), f26dot6(p.Y), h.gs.pv)
|
||||
h.move(p, f26dot6(h.stack[top+1])-c, true)
|
||||
c := dotProduct(p.X, p.Y, h.gs.pv)
|
||||
h.move(p, fixed.Int26_6(h.stack[top+1])-c, true)
|
||||
if h.gs.zp[2] != 0 {
|
||||
break
|
||||
}
|
||||
|
@ -809,7 +809,7 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
if p == nil || q == nil {
|
||||
return errors.New("truetype: hinting: point out of range")
|
||||
}
|
||||
d := int32(dotProduct(f26dot6(p.X-q.X), f26dot6(p.Y-q.Y), v))
|
||||
d := int32(dotProduct(p.X-q.X, p.Y-q.Y, v))
|
||||
if scale {
|
||||
d = int32(int64(d*int32(h.scale)) / int64(h.font.fUnitsPerEm))
|
||||
}
|
||||
|
@ -854,7 +854,7 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
h.stack[top-1] = bool2int32(h.stack[top-1] != h.stack[top])
|
||||
|
||||
case opODD, opEVEN:
|
||||
i := h.round(f26dot6(h.stack[top-1])) >> 6
|
||||
i := h.round(fixed.Int26_6(h.stack[top-1])) >> 6
|
||||
h.stack[top-1] = int32(i&1) ^ int32(opcode-opODD)
|
||||
|
||||
case opIF:
|
||||
|
@ -902,11 +902,11 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
if h.stack[top] == 0 {
|
||||
return errors.New("truetype: hinting: division by zero")
|
||||
}
|
||||
h.stack[top-1] = int32(fdiv(f26dot6(h.stack[top-1]), f26dot6(h.stack[top])))
|
||||
h.stack[top-1] = int32(fdiv(fixed.Int26_6(h.stack[top-1]), fixed.Int26_6(h.stack[top])))
|
||||
|
||||
case opMUL:
|
||||
top--
|
||||
h.stack[top-1] = int32(fmul(f26dot6(h.stack[top-1]), f26dot6(h.stack[top])))
|
||||
h.stack[top-1] = int32(fmul(fixed.Int26_6(h.stack[top-1]), fixed.Int26_6(h.stack[top])))
|
||||
|
||||
case opABS:
|
||||
if h.stack[top-1] < 0 {
|
||||
|
@ -926,7 +926,7 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
case opROUND00, opROUND01, opROUND10, opROUND11:
|
||||
// The four flavors of opROUND are equivalent. See the comment below on
|
||||
// opNROUND for the rationale.
|
||||
h.stack[top-1] = int32(h.round(f26dot6(h.stack[top-1])))
|
||||
h.stack[top-1] = int32(h.round(fixed.Int26_6(h.stack[top-1])))
|
||||
|
||||
case opNROUND00, opNROUND01, opNROUND10, opNROUND11:
|
||||
// No-op. The spec says to add one of four "compensations for the engine
|
||||
|
@ -937,7 +937,7 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
|
||||
case opWCVTF:
|
||||
top -= 2
|
||||
h.setScaledCVT(h.stack[top], f26dot6(h.font.scale(h.scale*fixed.Int26_6(h.stack[top+1]))))
|
||||
h.setScaledCVT(h.stack[top], h.font.scale(h.scale*fixed.Int26_6(h.stack[top+1])))
|
||||
|
||||
case opDELTAP2, opDELTAP3, opDELTAC1, opDELTAC2, opDELTAC3:
|
||||
goto delta
|
||||
|
@ -959,9 +959,9 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
h.gs.roundPeriod *= 46341
|
||||
h.gs.roundPeriod /= 65536
|
||||
}
|
||||
h.gs.roundPhase = h.gs.roundPeriod * f26dot6((h.stack[top]>>4)&0x03) / 4
|
||||
h.gs.roundPhase = h.gs.roundPeriod * fixed.Int26_6((h.stack[top]>>4)&0x03) / 4
|
||||
if x := h.stack[top] & 0x0f; x != 0 {
|
||||
h.gs.roundThreshold = h.gs.roundPeriod * f26dot6(x-4) / 8
|
||||
h.gs.roundThreshold = h.gs.roundPeriod * fixed.Int26_6(x-4) / 8
|
||||
} else {
|
||||
h.gs.roundThreshold = h.gs.roundPeriod - 1
|
||||
}
|
||||
|
@ -1137,16 +1137,16 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
return errors.New("truetype: hinting: point out of range")
|
||||
}
|
||||
|
||||
oldDist := f26dot6(0)
|
||||
oldDist := fixed.Int26_6(0)
|
||||
if h.gs.zp[0] == 0 || h.gs.zp[1] == 0 {
|
||||
p0 := h.point(1, unhinted, i)
|
||||
p1 := h.point(0, unhinted, h.gs.rp[0])
|
||||
oldDist = dotProduct(f26dot6(p0.X-p1.X), f26dot6(p0.Y-p1.Y), h.gs.dv)
|
||||
oldDist = dotProduct(p0.X-p1.X, p0.Y-p1.Y, h.gs.dv)
|
||||
} else {
|
||||
p0 := h.point(1, inFontUnits, i)
|
||||
p1 := h.point(0, inFontUnits, h.gs.rp[0])
|
||||
oldDist = dotProduct(f26dot6(p0.X-p1.X), f26dot6(p0.Y-p1.Y), h.gs.dv)
|
||||
oldDist = f26dot6(h.font.scale(h.scale * fixed.Int26_6(oldDist)))
|
||||
oldDist = dotProduct(p0.X-p1.X, p0.Y-p1.Y, h.gs.dv)
|
||||
oldDist = h.font.scale(h.scale * oldDist)
|
||||
}
|
||||
|
||||
// Single-width cut-in test.
|
||||
|
@ -1186,7 +1186,7 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
}
|
||||
|
||||
// Move the point.
|
||||
oldDist = dotProduct(f26dot6(p.X-ref.X), f26dot6(p.Y-ref.Y), h.gs.pv)
|
||||
oldDist = dotProduct(p.X-ref.X, p.Y-ref.Y, h.gs.pv)
|
||||
h.move(p, distance-oldDist, true)
|
||||
|
||||
} else {
|
||||
|
@ -1214,14 +1214,14 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
if ref == nil || p == nil {
|
||||
return errors.New("truetype: hinting: point out of range")
|
||||
}
|
||||
oldDist := dotProduct(f26dot6(p.X-ref.X), f26dot6(p.Y-ref.Y), h.gs.dv)
|
||||
oldDist := dotProduct(p.X-ref.X, p.Y-ref.Y, h.gs.dv)
|
||||
|
||||
ref = h.point(0, current, h.gs.rp[0])
|
||||
p = h.point(1, current, i)
|
||||
if ref == nil || p == nil {
|
||||
return errors.New("truetype: hinting: point out of range")
|
||||
}
|
||||
curDist := dotProduct(f26dot6(p.X-ref.X), f26dot6(p.Y-ref.Y), h.gs.pv)
|
||||
curDist := dotProduct(p.X-ref.X, p.Y-ref.Y, h.gs.pv)
|
||||
|
||||
if h.gs.autoFlip && oldDist^cvtDist < 0 {
|
||||
cvtDist = -cvtDist
|
||||
|
@ -1373,13 +1373,13 @@ func (h *hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point,
|
|||
if a < 0 || len(h.scaledCVT) <= int(a) {
|
||||
return errors.New("truetype: hinting: index out of range")
|
||||
}
|
||||
h.scaledCVT[a] += f26dot6(b)
|
||||
h.scaledCVT[a] += fixed.Int26_6(b)
|
||||
} else {
|
||||
p := h.point(0, current, h.stack[top+1])
|
||||
if p == nil {
|
||||
return errors.New("truetype: hinting: point out of range")
|
||||
}
|
||||
h.move(p, f26dot6(b), true)
|
||||
h.move(p, fixed.Int26_6(b), true)
|
||||
}
|
||||
}
|
||||
pc++
|
||||
|
@ -1397,16 +1397,16 @@ func (h *hinter) initializeScaledCVT() {
|
|||
if n < 32 {
|
||||
n = 32
|
||||
}
|
||||
h.scaledCVT = make([]f26dot6, len(h.font.cvt)/2, n)
|
||||
h.scaledCVT = make([]fixed.Int26_6, 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 * fixed.Int26_6(int16(unscaled))))
|
||||
h.scaledCVT[i] = h.font.scale(h.scale * fixed.Int26_6(int16(unscaled)))
|
||||
}
|
||||
}
|
||||
|
||||
// getScaledCVT returns the scaled value from the font's Control Value Table.
|
||||
func (h *hinter) getScaledCVT(i int32) f26dot6 {
|
||||
func (h *hinter) getScaledCVT(i int32) fixed.Int26_6 {
|
||||
if !h.scaledCVTInitialized {
|
||||
h.initializeScaledCVT()
|
||||
}
|
||||
|
@ -1417,7 +1417,7 @@ func (h *hinter) getScaledCVT(i int32) f26dot6 {
|
|||
}
|
||||
|
||||
// setScaledCVT overrides the scaled value from the font's Control Value Table.
|
||||
func (h *hinter) setScaledCVT(i int32, v f26dot6) {
|
||||
func (h *hinter) setScaledCVT(i int32, v fixed.Int26_6) {
|
||||
if !h.scaledCVTInitialized {
|
||||
h.initializeScaledCVT()
|
||||
}
|
||||
|
@ -1435,7 +1435,7 @@ func (h *hinter) point(zonePointer uint32, pt pointType, i int32) *Point {
|
|||
return &points[i]
|
||||
}
|
||||
|
||||
func (h *hinter) move(p *Point, distance f26dot6, touch bool) {
|
||||
func (h *hinter) move(p *Point, distance fixed.Int26_6, touch bool) {
|
||||
fvx := int64(h.gs.fv[0])
|
||||
pvx := int64(h.gs.pv[0])
|
||||
if fvx == 0x4000 && pvx == 0x4000 {
|
||||
|
@ -1590,7 +1590,7 @@ func (h *hinter) iupShift(interpY bool, p1, p2, p int) {
|
|||
}
|
||||
}
|
||||
|
||||
func (h *hinter) displacement(useZP1 bool) (zonePointer uint32, i int32, d f26dot6, ok bool) {
|
||||
func (h *hinter) displacement(useZP1 bool) (zonePointer uint32, i int32, d fixed.Int26_6, ok bool) {
|
||||
zonePointer, i = uint32(0), h.gs.rp[1]
|
||||
if useZP1 {
|
||||
zonePointer, i = 1, h.gs.rp[2]
|
||||
|
@ -1600,7 +1600,7 @@ func (h *hinter) displacement(useZP1 bool) (zonePointer uint32, i int32, d f26do
|
|||
if p == nil || q == nil {
|
||||
return 0, 0, 0, false
|
||||
}
|
||||
d = dotProduct(f26dot6(p.X-q.X), f26dot6(p.Y-q.Y), h.gs.pv)
|
||||
d = dotProduct(p.X-q.X, p.Y-q.Y, h.gs.pv)
|
||||
return zonePointer, i, d, true
|
||||
}
|
||||
|
||||
|
@ -1651,11 +1651,8 @@ func normalize(x, y f2dot14) [2]f2dot14 {
|
|||
return [2]f2dot14{f2dot14(fx), f2dot14(fy)}
|
||||
}
|
||||
|
||||
// f26dot6 is a 26.6 fixed point number.
|
||||
type f26dot6 int32
|
||||
|
||||
// fabs returns abs(x) in 26.6 fixed point arithmetic.
|
||||
func fabs(x f26dot6) f26dot6 {
|
||||
func fabs(x fixed.Int26_6) fixed.Int26_6 {
|
||||
if x < 0 {
|
||||
return -x
|
||||
}
|
||||
|
@ -1663,13 +1660,13 @@ func fabs(x f26dot6) f26dot6 {
|
|||
}
|
||||
|
||||
// fdiv returns x/y in 26.6 fixed point arithmetic.
|
||||
func fdiv(x, y f26dot6) f26dot6 {
|
||||
return f26dot6((int64(x) << 6) / int64(y))
|
||||
func fdiv(x, y fixed.Int26_6) fixed.Int26_6 {
|
||||
return fixed.Int26_6((int64(x) << 6) / int64(y))
|
||||
}
|
||||
|
||||
// fmul returns x*y in 26.6 fixed point arithmetic.
|
||||
func fmul(x, y f26dot6) f26dot6 {
|
||||
return f26dot6((int64(x)*int64(y) + 1<<5) >> 6)
|
||||
func fmul(x, y fixed.Int26_6) fixed.Int26_6 {
|
||||
return fixed.Int26_6((int64(x)*int64(y) + 1<<5) >> 6)
|
||||
}
|
||||
|
||||
// dotProduct returns the dot product of [x, y] and q. It is almost the same as
|
||||
|
@ -1677,10 +1674,10 @@ func fmul(x, y f26dot6) f26dot6 {
|
|||
// py := int64(y)
|
||||
// qx := int64(q[0])
|
||||
// qy := int64(q[1])
|
||||
// return f26dot6((px*qx + py*qy + 1<<13) >> 14)
|
||||
// return fixed.Int26_6((px*qx + py*qy + 1<<13) >> 14)
|
||||
// except that the computation is done with 32-bit integers to produce exactly
|
||||
// the same rounding behavior as C Freetype.
|
||||
func dotProduct(x, y f26dot6, q [2]f2dot14) f26dot6 {
|
||||
func dotProduct(x, y fixed.Int26_6, q [2]f2dot14) fixed.Int26_6 {
|
||||
// Compute x*q[0] as 64-bit value.
|
||||
l := uint32((int32(x) & 0xFFFF) * int32(q[0]))
|
||||
m := (int32(x) >> 16) * int32(q[0])
|
||||
|
@ -1708,7 +1705,7 @@ func dotProduct(x, y f26dot6, q [2]f2dot14) f26dot6 {
|
|||
l = lo + 0x2000
|
||||
hi += bool2int32(l < lo)
|
||||
|
||||
return f26dot6((uint32(hi) << 18) | (l >> 14))
|
||||
return fixed.Int26_6((uint32(hi) << 18) | (l >> 14))
|
||||
}
|
||||
|
||||
// mulDiv returns x*y/z, rounded to the nearest integer.
|
||||
|
@ -1727,7 +1724,7 @@ func mulDiv(x, y, z int64) int64 {
|
|||
|
||||
// round rounds the given number. The rounding algorithm is described at
|
||||
// https://developer.apple.com/fonts/TTRefMan/RM02/Chap2.html#rounding
|
||||
func (h *hinter) round(x f26dot6) f26dot6 {
|
||||
func (h *hinter) round(x fixed.Int26_6) fixed.Int26_6 {
|
||||
if h.gs.roundPeriod == 0 {
|
||||
// Rounding is off.
|
||||
return x
|
||||
|
|
Loading…
Reference in a new issue