freetype/truetype: fix rounding for negative numbers to match the C
Freetype implementation. The spec is the "Order of rounding operations" part of https://developer.apple.com/fonts/TTRefMan/RM02/Chap2.html#rounding but it wasn't exactly clear to me what "the negative round value closest to zero" was: if the phase is 1/4, was that value -1/4 or -3/4? Anyway, the Go code now follows the C code, and code trumps documentation. R=bsiegert CC=golang-dev https://codereview.appspot.com/14092044
This commit is contained in:
parent
c661e372c6
commit
3490800cec
3 changed files with 27 additions and 33 deletions
|
@ -1237,27 +1237,21 @@ func dotProduct(x, y f26dot6, q [2]f2dot14) f26dot6 {
|
|||
// https://developer.apple.com/fonts/TTRefMan/RM02/Chap2.html#rounding
|
||||
func (h *Hinter) round(x f26dot6) f26dot6 {
|
||||
if h.gs.roundPeriod == 0 {
|
||||
// Rounding is off.
|
||||
return x
|
||||
}
|
||||
neg := x < 0
|
||||
x -= h.gs.roundPhase
|
||||
x += h.gs.roundThreshold
|
||||
if x >= 0 {
|
||||
x = (x / h.gs.roundPeriod) * h.gs.roundPeriod
|
||||
} else {
|
||||
x -= h.gs.roundPeriod
|
||||
x += 1
|
||||
x = (x / h.gs.roundPeriod) * h.gs.roundPeriod
|
||||
}
|
||||
x += h.gs.roundPhase
|
||||
if neg {
|
||||
if x >= 0 {
|
||||
x = h.gs.roundPhase - h.gs.roundPeriod
|
||||
ret := (x - h.gs.roundPhase + h.gs.roundThreshold) & -h.gs.roundPeriod
|
||||
if x != 0 && ret < 0 {
|
||||
ret = 0
|
||||
}
|
||||
} else if x < 0 {
|
||||
x = h.gs.roundPhase
|
||||
return ret + h.gs.roundPhase
|
||||
}
|
||||
return x
|
||||
ret := -((-x - h.gs.roundPhase + h.gs.roundThreshold) & -h.gs.roundPeriod)
|
||||
if ret > 0 {
|
||||
ret = 0
|
||||
}
|
||||
return ret - h.gs.roundPhase
|
||||
}
|
||||
|
||||
func bool2int32(b bool) int32 {
|
||||
|
|
|
@ -445,33 +445,33 @@ func TestBytecode(t *testing.T) {
|
|||
opPUSHW000, // [-81]
|
||||
0xff,
|
||||
0xaf,
|
||||
opROUND00, // [-112]
|
||||
opPUSHW000, // [-112, -80]
|
||||
opROUND00, // [-80]
|
||||
opPUSHW000, // [-80, -80]
|
||||
0xff,
|
||||
0xb0,
|
||||
opROUND00, // [-112, -48]
|
||||
opPUSHW000, // [-112, -48, -17]
|
||||
opROUND00, // [-80, -80]
|
||||
opPUSHW000, // [-80, -80, -17]
|
||||
0xff,
|
||||
0xef,
|
||||
opROUND00, // [-112, -48, -48]
|
||||
opPUSHW000, // [-112, -48, -48, -16]
|
||||
opROUND00, // [-80, -80, -16]
|
||||
opPUSHW000, // [-80, -80, -16, -16]
|
||||
0xff,
|
||||
0xf0,
|
||||
opROUND00, // [-112, -48, -48, -48]
|
||||
opPUSHB000, // [-112, -48, -48, -48, 0]
|
||||
opROUND00, // [-80, -80, -16, -16]
|
||||
opPUSHB000, // [-80, -80, -16, -16, 0]
|
||||
0,
|
||||
opROUND00, // [-112, -48, -48, -48, 16]
|
||||
opPUSHB000, // [-112, -48, -48, -48, 16, 16]
|
||||
opROUND00, // [-80, -80, -16, -16, 16]
|
||||
opPUSHB000, // [-80, -80, -16, -16, 16, 16]
|
||||
16,
|
||||
opROUND00, // [-112, -48, -48, -48, 16, 16]
|
||||
opPUSHB000, // [-112, -48, -48, -48, 16, 16, 47]
|
||||
opROUND00, // [-80, -80, -16, -16, 16, 16]
|
||||
opPUSHB000, // [-80, -80, -16, -16, 16, 16, 47]
|
||||
47,
|
||||
opROUND00, // [-112, -48, -48, -48, 16, 16, 16]
|
||||
opPUSHB000, // [-112, -48, -48, -48, 16, 16, 16, 48]
|
||||
opROUND00, // [-80, -80, -16, -16, 16, 16, 16]
|
||||
opPUSHB000, // [-80, -80, -16, -16, 16, 16, 16, 48]
|
||||
48,
|
||||
opROUND00, // [-112, -48, -48, -48, 16, 16, 16, 80]
|
||||
opROUND00, // [-80, -80, -16, -16, 16, 16, 16, 80]
|
||||
},
|
||||
[]int32{-112, -48, -48, -48, 16, 16, 16, 80},
|
||||
[]int32{-80, -80, -16, -16, 16, 16, 16, 80},
|
||||
"",
|
||||
},
|
||||
{
|
||||
|
|
|
@ -116,7 +116,7 @@ func testScaling(t *testing.T, filename string, hinter *Hinter) {
|
|||
for i, want := range wants {
|
||||
// TODO: completely implement hinting. For now, only the first N glyphs
|
||||
// of luxisr.ttf are correctly hinted.
|
||||
const N = 8
|
||||
const N = 9
|
||||
if hinter != nil && i == N {
|
||||
break
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue