diff options
Diffstat (limited to 'Lib/fontTools/misc/fixedTools.py')
-rw-r--r-- | Lib/fontTools/misc/fixedTools.py | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/Lib/fontTools/misc/fixedTools.py b/Lib/fontTools/misc/fixedTools.py index 6ec7d06e..f0474abf 100644 --- a/Lib/fontTools/misc/fixedTools.py +++ b/Lib/fontTools/misc/fixedTools.py @@ -17,7 +17,7 @@ functions for converting between fixed-point, float and string representations. The maximum value that can still fit in an F2Dot14. (1.99993896484375) """ -from .roundTools import otRound, nearestMultipleShortestRepr +from .roundTools import otRound import logging log = logging.getLogger(__name__) @@ -125,7 +125,6 @@ def fixedToStr(value, precisionBits): This is pretty slow compared to the simple division used in ``fixedToFloat``. Use sporadically when you need to serialize or print the fixed-point number in a human-readable form. - It uses nearestMultipleShortestRepr under the hood. Args: value (int): The fixed-point value to convert. @@ -134,8 +133,27 @@ def fixedToStr(value, precisionBits): Returns: str: A string representation of the value. """ + if not value: return "0.0" + scale = 1 << precisionBits - return nearestMultipleShortestRepr(value/scale, factor=1.0/scale) + value /= scale + eps = .5 / scale + lo = value - eps + hi = value + eps + # If the range of valid choices spans an integer, return the integer. + if int(lo) != int(hi): + return str(float(round(value))) + fmt = "%.8f" + lo = fmt % lo + hi = fmt % hi + assert len(lo) == len(hi) and lo != hi + for i in range(len(lo)): + if lo[i] != hi[i]: + break + period = lo.find('.') + assert period < i + fmt = "%%.%df" % (i - period) + return fmt % value def strToFixed(string, precisionBits): @@ -150,9 +168,9 @@ def strToFixed(string, precisionBits): Examples:: - >>> ## to convert a float string to a 2.14 fixed-point number: - >>> strToFixed('-0.61884', precisionBits=14) - -10139 + >>> ## to convert a float string to a 2.14 fixed-point number: + >>> strToFixed('-0.61884', precisionBits=14) + -10139 """ value = float(string) return otRound(value * (1 << precisionBits)) @@ -196,7 +214,7 @@ def floatToFixedToStr(value, precisionBits): This uses the shortest decimal representation (ie. the least number of fractional decimal digits) to represent the equivalent fixed-point number with ``precisionBits`` fractional binary digits. - It uses nearestMultipleShortestRepr under the hood. + It uses fixedToStr under the hood. >>> floatToFixedToStr(-0.61883544921875, precisionBits=14) '-0.61884' @@ -209,8 +227,8 @@ def floatToFixedToStr(value, precisionBits): str: A string representation of the value. """ - scale = 1 << precisionBits - return nearestMultipleShortestRepr(value, factor=1.0/scale) + fixed = otRound(value * (1 << precisionBits)) + return fixedToStr(fixed, precisionBits) def ensureVersionIsLong(value): |