diff options
author | robot-piglet <robot-piglet@yandex-team.com> | 2024-06-08 08:51:43 +0300 |
---|---|---|
committer | robot-piglet <robot-piglet@yandex-team.com> | 2024-06-08 09:02:27 +0300 |
commit | c3763910c6f878b17102c94e0b62cab57c9954b8 (patch) | |
tree | 19de35706beeb1adc158f13ca87110e110f1a753 /contrib/python/fonttools/fontTools/misc | |
parent | 63965219325c32d9b72b466b89fc613295746336 (diff) | |
download | ydb-c3763910c6f878b17102c94e0b62cab57c9954b8.tar.gz |
Intermediate changes
Diffstat (limited to 'contrib/python/fonttools/fontTools/misc')
6 files changed, 107 insertions, 6 deletions
diff --git a/contrib/python/fonttools/fontTools/misc/bezierTools.py b/contrib/python/fonttools/fontTools/misc/bezierTools.py index a1a707b098..5411ff99fd 100644 --- a/contrib/python/fonttools/fontTools/misc/bezierTools.py +++ b/contrib/python/fonttools/fontTools/misc/bezierTools.py @@ -18,6 +18,9 @@ except (AttributeError, ImportError): COMPILED = False +EPSILON = 1e-9 + + Intersection = namedtuple("Intersection", ["pt", "t1", "t2"]) @@ -92,7 +95,7 @@ def _split_cubic_into_two(p0, p1, p2, p3): def _calcCubicArcLengthCRecurse(mult, p0, p1, p2, p3): arch = abs(p0 - p3) box = abs(p0 - p1) + abs(p1 - p2) + abs(p2 - p3) - if arch * mult >= box: + if arch * mult + EPSILON >= box: return (arch + box) * 0.5 else: one, two = _split_cubic_into_two(p0, p1, p2, p3) diff --git a/contrib/python/fonttools/fontTools/misc/iterTools.py b/contrib/python/fonttools/fontTools/misc/iterTools.py new file mode 100644 index 0000000000..d7b8305322 --- /dev/null +++ b/contrib/python/fonttools/fontTools/misc/iterTools.py @@ -0,0 +1,12 @@ +from itertools import * + +# Python 3.12: +if "batched" not in globals(): + # https://docs.python.org/3/library/itertools.html#itertools.batched + def batched(iterable, n): + # batched('ABCDEFG', 3) --> ABC DEF G + if n < 1: + raise ValueError("n must be at least one") + it = iter(iterable) + while batch := tuple(islice(it, n)): + yield batch diff --git a/contrib/python/fonttools/fontTools/misc/lazyTools.py b/contrib/python/fonttools/fontTools/misc/lazyTools.py new file mode 100644 index 0000000000..91cb80c992 --- /dev/null +++ b/contrib/python/fonttools/fontTools/misc/lazyTools.py @@ -0,0 +1,42 @@ +from collections import UserDict, UserList + +__all__ = ["LazyDict", "LazyList"] + + +class LazyDict(UserDict): + def __init__(self, data): + super().__init__() + self.data = data + + def __getitem__(self, k): + v = self.data[k] + if callable(v): + v = v(k) + self.data[k] = v + return v + + +class LazyList(UserList): + def __getitem__(self, k): + if isinstance(k, slice): + indices = range(*k.indices(len(self))) + return [self[i] for i in indices] + v = self.data[k] + if callable(v): + v = v(k) + self.data[k] = v + return v + + def __add__(self, other): + if isinstance(other, LazyList): + other = list(other) + elif isinstance(other, list): + pass + else: + return NotImplemented + return list(self) + other + + def __radd__(self, other): + if not isinstance(other, list): + return NotImplemented + return other + list(self) diff --git a/contrib/python/fonttools/fontTools/misc/psCharStrings.py b/contrib/python/fonttools/fontTools/misc/psCharStrings.py index cc9ca01c7f..5d881c5816 100644 --- a/contrib/python/fonttools/fontTools/misc/psCharStrings.py +++ b/contrib/python/fonttools/fontTools/misc/psCharStrings.py @@ -275,6 +275,24 @@ def encodeFloat(f): s = s[1:] elif s[:3] == "-0.": s = "-" + s[2:] + elif s.endswith("000"): + significantDigits = s.rstrip("0") + s = "%sE%d" % (significantDigits, len(s) - len(significantDigits)) + else: + dotIndex = s.find(".") + eIndex = s.find("E") + if dotIndex != -1 and eIndex != -1: + integerPart = s[:dotIndex] + fractionalPart = s[dotIndex + 1 : eIndex] + exponent = int(s[eIndex + 1 :]) + newExponent = exponent - len(fractionalPart) + if newExponent == 1: + s = "%s%s0" % (integerPart, fractionalPart) + else: + s = "%s%sE%d" % (integerPart, fractionalPart, newExponent) + if s.startswith((".0", "-.0")): + sign, s = s.split(".", 1) + s = "%s%sE-%d" % (sign, s.lstrip("0"), len(s)) nibbles = [] while s: c = s[0] @@ -286,6 +304,8 @@ def encodeFloat(f): c = "E-" elif c2 == "+": s = s[1:] + if s.startswith("0"): + s = s[1:] nibbles.append(realNibblesDict[c]) nibbles.append(0xF) if len(nibbles) % 2: diff --git a/contrib/python/fonttools/fontTools/misc/sstruct.py b/contrib/python/fonttools/fontTools/misc/sstruct.py index d35bc9a5c8..92be275b89 100644 --- a/contrib/python/fonttools/fontTools/misc/sstruct.py +++ b/contrib/python/fonttools/fontTools/misc/sstruct.py @@ -64,7 +64,10 @@ def pack(fmt, obj): elements = [] if not isinstance(obj, dict): obj = obj.__dict__ - for name in names: + string_index = formatstring + if formatstring.startswith(">"): + string_index = formatstring[1:] + for ix, name in enumerate(names.keys()): value = obj[name] if name in fixes: # fixed point conversion @@ -72,6 +75,13 @@ def pack(fmt, obj): elif isinstance(value, str): value = tobytes(value) elements.append(value) + # Check it fits + try: + struct.pack(names[name], value) + except Exception as e: + raise ValueError( + "Value %s does not fit in format %s for %s" % (value, names[name], name) + ) from e data = struct.pack(*(formatstring,) + tuple(elements)) return data @@ -87,7 +97,7 @@ def unpack(fmt, data, obj=None): d = obj.__dict__ elements = struct.unpack(formatstring, data) for i in range(len(names)): - name = names[i] + name = list(names.keys())[i] value = elements[i] if name in fixes: # fixed point conversion @@ -141,7 +151,7 @@ def getformat(fmt, keep_pad_byte=False): except KeyError: lines = re.split("[\n;]", fmt) formatstring = "" - names = [] + names = {} fixes = {} for line in lines: if _emptyRE.match(line): @@ -158,7 +168,7 @@ def getformat(fmt, keep_pad_byte=False): name = m.group(1) formatchar = m.group(2) if keep_pad_byte or formatchar != "x": - names.append(name) + names[name] = formatchar if m.group(3): # fixed point before = int(m.group(3)) @@ -167,9 +177,10 @@ def getformat(fmt, keep_pad_byte=False): if bits not in [8, 16, 32]: raise Error("fixed point must be 8, 16 or 32 bits long") formatchar = _fixedpointmappings[bits] + names[name] = formatchar assert m.group(5) == "F" fixes[name] = after - formatstring = formatstring + formatchar + formatstring += formatchar _formatcache[fmt] = formatstring, names, fixes return formatstring, names, fixes diff --git a/contrib/python/fonttools/fontTools/misc/transform.py b/contrib/python/fonttools/fontTools/misc/transform.py index 0f9f3a5d8b..9025b79ec1 100644 --- a/contrib/python/fonttools/fontTools/misc/transform.py +++ b/contrib/python/fonttools/fontTools/misc/transform.py @@ -422,6 +422,19 @@ class DecomposedTransform: tCenterX: float = 0 tCenterY: float = 0 + def __bool__(self): + return ( + self.translateX != 0 + or self.translateY != 0 + or self.rotation != 0 + or self.scaleX != 1 + or self.scaleY != 1 + or self.skewX != 0 + or self.skewY != 0 + or self.tCenterX != 0 + or self.tCenterY != 0 + ) + @classmethod def fromTransform(self, transform): # Adapted from an answer on |