Skip to content

Commit 676dd1b

Browse files
committed
Parse features once
1 parent 50a732f commit 676dd1b

2 files changed

Lines changed: 47 additions & 47 deletions

File tree

Lib/alifTools/sample/__init__.py

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def union(self, other: "Rect") -> "Rect":
5252

5353
class TextRun(NamedTuple):
5454
font: "Font"
55-
features: str
55+
features: Features
5656
location: str
5757
string: str
5858

@@ -216,54 +216,13 @@ def _make_glyphs(
216216
)
217217
return GlyphRun(font=self, location=location, glyphs=glyphs)
218218

219-
@staticmethod
220-
def _parse_features(text: str) -> Features:
221-
if not text:
222-
return {}
223-
features = {}
224-
for feature in text.split(","):
225-
value = None
226-
start = None
227-
end = None
228-
229-
feature = feature.strip()
230-
if feature[0] == "-":
231-
value = 0
232-
if feature[0] in ("+", "-"):
233-
feature = feature[1:]
234-
tag = feature
235-
if "[" in tag:
236-
assert "]" in tag, f"Invalid feature tag: {tag}"
237-
tag, extra = tag.split("[")
238-
extra, tag2 = extra.split("]")
239-
tag += tag2
240-
start = end = extra
241-
if ":" in extra:
242-
start, end = extra.split(":")
243-
if "=" in tag:
244-
tag, value = tag.split("=")
245-
if value is None:
246-
value = 1
247-
if start is None or start == "":
248-
start = 0
249-
if end is None or end == "":
250-
end = 0xFFFFFFFF
251-
features.setdefault(tag, []).append([int(start), int(end), int(value)])
252-
for tag, value in features.items():
253-
if len(value) != 1:
254-
continue
255-
if value[0][:2] == [0, 0xFFFFFFFF]:
256-
features[tag] = value[0][2]
257-
return features
258-
259219
def shape(
260220
self,
261221
text: str,
262222
location: Location,
263-
features: str,
223+
features: Features,
264224
) -> Tuple[GlyphRun, float]:
265225
buf = hb.Buffer()
266-
features = self._parse_features(features)
267226
width = self._shape(buf, text, location, features)
268227
glyphs = self._make_glyphs(buf, location)
269228
return glyphs, width
@@ -272,11 +231,10 @@ def shape_justify(
272231
self,
273232
text: str,
274233
location: Location,
275-
features: str,
234+
features: Features,
276235
target_width: float,
277236
) -> Tuple[GlyphRun, float]:
278237
buf = hb.Buffer()
279-
features = self._parse_features(features)
280238

281239
width = self._shape(buf, text, location, features)
282240
if width >= target_width:
@@ -524,6 +482,8 @@ def draw(
524482
x = 0
525483
fonts = [Font(font_path) for font_path in font_paths]
526484

485+
features: Features = parseFeatures(features)
486+
527487
fonts_locations = []
528488
if len(fonts) == 1:
529489
fonts_locations = [(fonts[0], location) for location in fonts[0].locations]
@@ -581,6 +541,46 @@ def parseColor(color):
581541
return tuple(int(color[i : i + 2], 16) / 255 for i in (0, 2, 4)) + (1,)
582542

583543

544+
def parseFeatures(text: str) -> Features:
545+
if not text:
546+
return {}
547+
features = {}
548+
for feature in text.split(","):
549+
value = None
550+
start = None
551+
end = None
552+
553+
feature = feature.strip()
554+
if feature[0] == "-":
555+
value = 0
556+
if feature[0] in ("+", "-"):
557+
feature = feature[1:]
558+
tag = feature
559+
if "[" in tag:
560+
assert "]" in tag, f"Invalid feature tag: {tag}"
561+
tag, extra = tag.split("[")
562+
extra, tag2 = extra.split("]")
563+
tag += tag2
564+
start = end = extra
565+
if ":" in extra:
566+
start, end = extra.split(":")
567+
if "=" in tag:
568+
tag, value = tag.split("=")
569+
if value is None:
570+
value = 1
571+
if start is None or start == "":
572+
start = 0
573+
if end is None or end == "":
574+
end = 0xFFFFFFFF
575+
features.setdefault(tag, []).append([int(start), int(end), int(value)])
576+
for tag, value in features.items():
577+
if len(value) != 1:
578+
continue
579+
if value[0][:2] == [0, 0xFFFFFFFF]:
580+
features[tag] = value[0][2]
581+
return features
582+
583+
584584
def main(argv=None):
585585
parser = argparse.ArgumentParser(description="Create SVG sample.")
586586
parser.add_argument("fonts", help="input font", nargs="+", type=pathlib.Path)

tests/sample_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import pytest
2-
from alifTools.sample import Font
2+
from alifTools.sample import parseFeatures
33

44

55
HHB_FEATURE_GLOBAL_END = 0xFFFFFFFF
@@ -29,4 +29,4 @@
2929
],
3030
)
3131
def test_parse_feature(text, features):
32-
assert Font._parse_features(text) == features
32+
assert parseFeatures(text) == features

0 commit comments

Comments
 (0)