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
|
@ -1237,27 +1237,21 @@ func dotProduct(x, y f26dot6, q [2]f2dot14) f26dot6 {
|
||||||
// https://developer.apple.com/fonts/TTRefMan/RM02/Chap2.html#rounding
|
// https://developer.apple.com/fonts/TTRefMan/RM02/Chap2.html#rounding
|
||||||
func (h *Hinter) round(x f26dot6) f26dot6 {
|
func (h *Hinter) round(x f26dot6) f26dot6 {
|
||||||
if h.gs.roundPeriod == 0 {
|
if h.gs.roundPeriod == 0 {
|
||||||
|
// Rounding is off.
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
neg := x < 0
|
|
||||||
x -= h.gs.roundPhase
|
|
||||||
x += h.gs.roundThreshold
|
|
||||||
if x >= 0 {
|
if x >= 0 {
|
||||||
x = (x / h.gs.roundPeriod) * h.gs.roundPeriod
|
ret := (x - h.gs.roundPhase + h.gs.roundThreshold) & -h.gs.roundPeriod
|
||||||
} else {
|
if x != 0 && ret < 0 {
|
||||||
x -= h.gs.roundPeriod
|
ret = 0
|
||||||
x += 1
|
|
||||||
x = (x / h.gs.roundPeriod) * h.gs.roundPeriod
|
|
||||||
}
|
}
|
||||||
x += h.gs.roundPhase
|
return ret + h.gs.roundPhase
|
||||||
if neg {
|
|
||||||
if x >= 0 {
|
|
||||||
x = h.gs.roundPhase - h.gs.roundPeriod
|
|
||||||
}
|
}
|
||||||
} else if x < 0 {
|
ret := -((-x - h.gs.roundPhase + h.gs.roundThreshold) & -h.gs.roundPeriod)
|
||||||
x = h.gs.roundPhase
|
if ret > 0 {
|
||||||
|
ret = 0
|
||||||
}
|
}
|
||||||
return x
|
return ret - h.gs.roundPhase
|
||||||
}
|
}
|
||||||
|
|
||||||
func bool2int32(b bool) int32 {
|
func bool2int32(b bool) int32 {
|
||||||
|
|
|
@ -445,33 +445,33 @@ func TestBytecode(t *testing.T) {
|
||||||
opPUSHW000, // [-81]
|
opPUSHW000, // [-81]
|
||||||
0xff,
|
0xff,
|
||||||
0xaf,
|
0xaf,
|
||||||
opROUND00, // [-112]
|
opROUND00, // [-80]
|
||||||
opPUSHW000, // [-112, -80]
|
opPUSHW000, // [-80, -80]
|
||||||
0xff,
|
0xff,
|
||||||
0xb0,
|
0xb0,
|
||||||
opROUND00, // [-112, -48]
|
opROUND00, // [-80, -80]
|
||||||
opPUSHW000, // [-112, -48, -17]
|
opPUSHW000, // [-80, -80, -17]
|
||||||
0xff,
|
0xff,
|
||||||
0xef,
|
0xef,
|
||||||
opROUND00, // [-112, -48, -48]
|
opROUND00, // [-80, -80, -16]
|
||||||
opPUSHW000, // [-112, -48, -48, -16]
|
opPUSHW000, // [-80, -80, -16, -16]
|
||||||
0xff,
|
0xff,
|
||||||
0xf0,
|
0xf0,
|
||||||
opROUND00, // [-112, -48, -48, -48]
|
opROUND00, // [-80, -80, -16, -16]
|
||||||
opPUSHB000, // [-112, -48, -48, -48, 0]
|
opPUSHB000, // [-80, -80, -16, -16, 0]
|
||||||
0,
|
0,
|
||||||
opROUND00, // [-112, -48, -48, -48, 16]
|
opROUND00, // [-80, -80, -16, -16, 16]
|
||||||
opPUSHB000, // [-112, -48, -48, -48, 16, 16]
|
opPUSHB000, // [-80, -80, -16, -16, 16, 16]
|
||||||
16,
|
16,
|
||||||
opROUND00, // [-112, -48, -48, -48, 16, 16]
|
opROUND00, // [-80, -80, -16, -16, 16, 16]
|
||||||
opPUSHB000, // [-112, -48, -48, -48, 16, 16, 47]
|
opPUSHB000, // [-80, -80, -16, -16, 16, 16, 47]
|
||||||
47,
|
47,
|
||||||
opROUND00, // [-112, -48, -48, -48, 16, 16, 16]
|
opROUND00, // [-80, -80, -16, -16, 16, 16, 16]
|
||||||
opPUSHB000, // [-112, -48, -48, -48, 16, 16, 16, 48]
|
opPUSHB000, // [-80, -80, -16, -16, 16, 16, 16, 48]
|
||||||
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 {
|
for i, want := range wants {
|
||||||
// TODO: completely implement hinting. For now, only the first N glyphs
|
// TODO: completely implement hinting. For now, only the first N glyphs
|
||||||
// of luxisr.ttf are correctly hinted.
|
// of luxisr.ttf are correctly hinted.
|
||||||
const N = 8
|
const N = 9
|
||||||
if hinter != nil && i == N {
|
if hinter != nil && i == N {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue