From cd38e8056d9b27bb2f265effa37fb0ea6b8a7f0f Mon Sep 17 00:00:00 2001 From: Nigel Tao Date: Fri, 16 Nov 2018 09:27:58 +1100 Subject: [PATCH] font/sfnt: make PostTable.ItalicAngle a float64 Previously, it was a float32, which obviously has 32 bits of state. Not all of that 32 bit state space is meaningful, since NaN has multiple bit representations. The underlying file format field (of type "Fixed" or 16.16 fixed point) is also 32 bits of state (https://docs.microsoft.com/en-us/typography/opentype/spec/post). Therefore, converting from 32 bit fixed point to 32 bit floating point can be lossy. Instead, use 64 bit floating point. 53 significand bits can losslessly represent all possible 16.16 fixed point values. Using float64 is also arguably more Go-like, as the default type for the ideal constant 0.5 is float64, not float32. Change-Id: I5abe7979a020af2ac4784d6c2723ab8e39e38e34 Reviewed-on: https://go-review.googlesource.com/c/149837 Reviewed-by: Denys Smirnov Reviewed-by: Nigel Tao --- font/sfnt/sfnt.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/font/sfnt/sfnt.go b/font/sfnt/sfnt.go index 0eb5cd5..e7125bf 100644 --- a/font/sfnt/sfnt.go +++ b/font/sfnt/sfnt.go @@ -1165,7 +1165,7 @@ type PostTable struct { Version uint32 // ItalicAngle in counter-clockwise degrees from the vertical. Zero for // upright text, negative for text that leans to the right (forward). - ItalicAngle float32 + ItalicAngle float64 // UnderlinePosition is the suggested distance of the top of the // underline from the baseline (negative values indicate below baseline). UnderlinePosition int16 @@ -1227,7 +1227,7 @@ func (f *Font) parsePost(buf []byte, numGlyphs int32) (buf1 []byte, post *PostTa } post = &PostTable{ Version: u, - ItalicAngle: float32(int16(ang>>16)) + float32(ang&0xffff)/0x10000, + ItalicAngle: float64(int32(ang)) / 0x10000, UnderlinePosition: int16(up), UnderlineThickness: int16(ut), IsFixedPitch: fp != 0,