Merge pull request #1230 from anthrotype/fix-coords-overflow
Fix GlyphCoordinates overflow
This commit is contained in:
commit
6bc44c8b05
@ -1220,6 +1220,9 @@ class GlyphCoordinates(object):
|
|||||||
def _checkFloat(self, p):
|
def _checkFloat(self, p):
|
||||||
if self.isFloat():
|
if self.isFloat():
|
||||||
return p
|
return p
|
||||||
|
if any(v > 0x7FFF or v < -0x8000 for v in p):
|
||||||
|
self._ensureFloat()
|
||||||
|
return p
|
||||||
if any(isinstance(v, float) for v in p):
|
if any(isinstance(v, float) for v in p):
|
||||||
p = [int(v) if int(v) == v else v for v in p]
|
p = [int(v) if int(v) == v else v for v in p]
|
||||||
if any(isinstance(v, float) for v in p):
|
if any(isinstance(v, float) for v in p):
|
||||||
@ -1259,7 +1262,6 @@ class GlyphCoordinates(object):
|
|||||||
del self._a[i]
|
del self._a[i]
|
||||||
del self._a[i]
|
del self._a[i]
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'GlyphCoordinates(['+','.join(str(c) for c in self)+'])'
|
return 'GlyphCoordinates(['+','.join(str(c) for c in self)+'])'
|
||||||
|
|
||||||
@ -1284,8 +1286,9 @@ class GlyphCoordinates(object):
|
|||||||
a = self._a
|
a = self._a
|
||||||
x,y = 0,0
|
x,y = 0,0
|
||||||
for i in range(len(a) // 2):
|
for i in range(len(a) // 2):
|
||||||
a[2*i ] = x = a[2*i ] + x
|
x = a[2*i ] + x
|
||||||
a[2*i+1] = y = a[2*i+1] + y
|
y = a[2*i+1] + y
|
||||||
|
self[i] = (x, y)
|
||||||
|
|
||||||
def absoluteToRelative(self):
|
def absoluteToRelative(self):
|
||||||
a = self._a
|
a = self._a
|
||||||
@ -1295,8 +1298,7 @@ class GlyphCoordinates(object):
|
|||||||
dy = a[2*i+1] - y
|
dy = a[2*i+1] - y
|
||||||
x = a[2*i ]
|
x = a[2*i ]
|
||||||
y = a[2*i+1]
|
y = a[2*i+1]
|
||||||
a[2*i ] = dx
|
self[i] = (dx, dy)
|
||||||
a[2*i+1] = dy
|
|
||||||
|
|
||||||
def translate(self, p):
|
def translate(self, p):
|
||||||
"""
|
"""
|
||||||
@ -1305,8 +1307,7 @@ class GlyphCoordinates(object):
|
|||||||
(x,y) = self._checkFloat(p)
|
(x,y) = self._checkFloat(p)
|
||||||
a = self._a
|
a = self._a
|
||||||
for i in range(len(a) // 2):
|
for i in range(len(a) // 2):
|
||||||
a[2*i ] += x
|
self[i] = (a[2*i] + x, a[2*i+1] + y)
|
||||||
a[2*i+1] += y
|
|
||||||
|
|
||||||
def scale(self, p):
|
def scale(self, p):
|
||||||
"""
|
"""
|
||||||
@ -1315,8 +1316,7 @@ class GlyphCoordinates(object):
|
|||||||
(x,y) = self._checkFloat(p)
|
(x,y) = self._checkFloat(p)
|
||||||
a = self._a
|
a = self._a
|
||||||
for i in range(len(a) // 2):
|
for i in range(len(a) // 2):
|
||||||
a[2*i ] *= x
|
self[i] = (a[2*i] * x, a[2*i+1] * y)
|
||||||
a[2*i+1] *= y
|
|
||||||
|
|
||||||
def transform(self, t):
|
def transform(self, t):
|
||||||
"""
|
"""
|
||||||
@ -1432,8 +1432,8 @@ class GlyphCoordinates(object):
|
|||||||
other = other._a
|
other = other._a
|
||||||
a = self._a
|
a = self._a
|
||||||
assert len(a) == len(other)
|
assert len(a) == len(other)
|
||||||
for i in range(len(a)):
|
for i in range(len(a) // 2):
|
||||||
a[i] += other[i]
|
self[i] = (a[2*i] + other[2*i], a[2*i+1] + other[2*i+1])
|
||||||
return self
|
return self
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
|
||||||
@ -1457,8 +1457,8 @@ class GlyphCoordinates(object):
|
|||||||
other = other._a
|
other = other._a
|
||||||
a = self._a
|
a = self._a
|
||||||
assert len(a) == len(other)
|
assert len(a) == len(other)
|
||||||
for i in range(len(a)):
|
for i in range(len(a) // 2):
|
||||||
a[i] -= other[i]
|
self[i] = (a[2*i] - other[2*i], a[2*i+1] - other[2*i+1])
|
||||||
return self
|
return self
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
|
||||||
|
@ -300,12 +300,7 @@ class VariationModel(object):
|
|||||||
for i,weights in enumerate(self.deltaWeights):
|
for i,weights in enumerate(self.deltaWeights):
|
||||||
delta = masterValues[mapping[i]]
|
delta = masterValues[mapping[i]]
|
||||||
for j,weight in weights.items():
|
for j,weight in weights.items():
|
||||||
try:
|
delta -= out[j] * weight
|
||||||
delta -= out[j] * weight
|
|
||||||
except OverflowError:
|
|
||||||
# if it doesn't fit signed shorts, retry with doubles
|
|
||||||
delta._ensureFloat()
|
|
||||||
delta -= out[j] * weight
|
|
||||||
out.append(delta)
|
out.append(delta)
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ from __future__ import print_function, division, absolute_import
|
|||||||
from fontTools.misc.py23 import *
|
from fontTools.misc.py23 import *
|
||||||
from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates
|
from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates
|
||||||
import sys
|
import sys
|
||||||
|
import array
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
@ -150,3 +151,9 @@ class GlyphCoordinatesTest(object):
|
|||||||
# since the Python float is truncated to a C float.
|
# since the Python float is truncated to a C float.
|
||||||
# when using typecode 'd' it should return the correct value 243
|
# when using typecode 'd' it should return the correct value 243
|
||||||
assert g[0][0] == round(afloat)
|
assert g[0][0] == round(afloat)
|
||||||
|
|
||||||
|
def test__checkFloat_overflow(self):
|
||||||
|
g = GlyphCoordinates([(1, 1)], typecode="h")
|
||||||
|
g.append((0x8000, 0))
|
||||||
|
assert g.array.typecode == "d"
|
||||||
|
assert g.array == array.array("d", [1.0, 1.0, 32768.0, 0.0])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user