From d16d96568ef56266968ed8de90117a2aa91b0318 Mon Sep 17 00:00:00 2001 From: justvanrossum Date: Mon, 16 Mar 2020 16:08:20 +0100 Subject: [PATCH 1/2] don't hardcode a maximum number of tags, but loop until all tags are collected. Fixes #31 --- src/uharfbuzz/_harfbuzz.pyx | 69 +++++++++++++++++++++---------------- tests/test_uharfbuzz.py | 15 ++++++++ 2 files changed, 55 insertions(+), 29 deletions(-) diff --git a/src/uharfbuzz/_harfbuzz.pyx b/src/uharfbuzz/_harfbuzz.pyx index 92c52b8..05b8040 100644 --- a/src/uharfbuzz/_harfbuzz.pyx +++ b/src/uharfbuzz/_harfbuzz.pyx @@ -516,25 +516,30 @@ def shape(font: Font, buffer: Buffer, features: Dict[str, bool] = None) -> None: free(hb_features) +DEF STATIC_TAGS_ARRAY_SIZE = 128 + + def ot_layout_language_get_feature_tags( face: Face, tag: str, script_index: int = 0, language_index: int = 0xFFFF) -> List[str]: cdef bytes packed = tag.encode() cdef hb_tag_t hb_tag = hb_tag_from_string(packed, -1) - cdef unsigned int feature_count = 24 - # we could get count first and malloc the array like pango is doing - cdef hb_tag_t feature_tags[24] - hb_ot_layout_language_get_feature_tags( - face._hb_face, hb_tag, script_index, language_index, 0, &feature_count, - feature_tags) + cdef unsigned int feature_count = STATIC_TAGS_ARRAY_SIZE + cdef hb_tag_t feature_tags[STATIC_TAGS_ARRAY_SIZE] cdef list tags = [] cdef char cstr[5] cdef unsigned int i - for i in range(feature_count): - hb_tag_to_string(feature_tags[i], cstr) - cstr[4] = b'\0' - packed = cstr - tags.append(packed.decode()) + cdef unsigned int start_offset = 0 + while feature_count == STATIC_TAGS_ARRAY_SIZE: + hb_ot_layout_language_get_feature_tags( + face._hb_face, hb_tag, script_index, language_index, start_offset, &feature_count, + feature_tags) + for i in range(feature_count): + hb_tag_to_string(feature_tags[i], cstr) + cstr[4] = b'\0' + packed = cstr + tags.append(packed.decode()) + start_offset += feature_count return tags @@ -542,37 +547,43 @@ def ot_layout_script_get_language_tags( face: Face, tag: str, script_index: int = 0) -> List[str]: cdef bytes packed = tag.encode() cdef hb_tag_t hb_tag = hb_tag_from_string(packed, -1) - cdef unsigned int language_count = 24 + cdef unsigned int language_count = STATIC_TAGS_ARRAY_SIZE # we could get count first and malloc the array like pango is doing - cdef hb_tag_t language_tags[24] - hb_ot_layout_script_get_language_tags( - face._hb_face, hb_tag, script_index, 0, &language_count, language_tags) + cdef hb_tag_t language_tags[STATIC_TAGS_ARRAY_SIZE] cdef list tags = [] cdef char cstr[5] cdef unsigned int i - for i in range(language_count): - hb_tag_to_string(language_tags[i], cstr) - cstr[4] = b'\0' - packed = cstr - tags.append(packed.decode()) + cdef unsigned int start_offset = 0 + while language_count == STATIC_TAGS_ARRAY_SIZE: + hb_ot_layout_script_get_language_tags( + face._hb_face, hb_tag, script_index, start_offset, &language_count, language_tags) + for i in range(language_count): + hb_tag_to_string(language_tags[i], cstr) + cstr[4] = b'\0' + packed = cstr + tags.append(packed.decode()) + start_offset += language_count return tags def ot_layout_table_get_script_tags(face: Face, tag: str) -> List[str]: cdef bytes packed = tag.encode() cdef hb_tag_t hb_tag = hb_tag_from_string(packed, -1) - cdef unsigned int script_count = 24 + cdef unsigned int script_count = STATIC_TAGS_ARRAY_SIZE # we could get count first and malloc the array like pango is doing - cdef hb_tag_t script_tags[24] - hb_ot_layout_table_get_script_tags( - face._hb_face, hb_tag, 0, &script_count, script_tags) + cdef hb_tag_t script_tags[STATIC_TAGS_ARRAY_SIZE] cdef list tags = [] cdef char cstr[5] cdef unsigned int i - for i in range(script_count): - hb_tag_to_string(script_tags[i], cstr) - cstr[4] = b'\0' - packed = cstr - tags.append(packed.decode()) + cdef unsigned int start_offset = 0 + while script_count == STATIC_TAGS_ARRAY_SIZE: + hb_ot_layout_table_get_script_tags( + face._hb_face, hb_tag, start_offset, &script_count, script_tags) + for i in range(script_count): + hb_tag_to_string(script_tags[i], cstr) + cstr[4] = b'\0' + packed = cstr + tags.append(packed.decode()) + start_offset += script_count return tags def ot_layout_get_baseline(font: Font, diff --git a/tests/test_uharfbuzz.py b/tests/test_uharfbuzz.py index 2e9dc32..97b6959 100644 --- a/tests/test_uharfbuzz.py +++ b/tests/test_uharfbuzz.py @@ -236,3 +236,18 @@ def test_ot_layout_get_baseline_invalid_tag(self, blankfont): def test_ot_layout_get_baseline(self, blankfont, baseline_tag, script_tag, direction, expected_value): value = hb.ot_layout_get_baseline(blankfont, baseline_tag, direction, script_tag, "") assert value == expected_value + +class TestGetTags: + def test_ot_layout_language_get_feature_tags(self, blankfont): + tags = hb.ot_layout_language_get_feature_tags(blankfont.face, "GPOS") + assert tags == ['kern'] + tags = hb.ot_layout_language_get_feature_tags(blankfont.face, "GSUB") + assert tags == ['calt'] + + def test_ot_layout_table_get_script_tags(self, blankfont): + tags = hb.ot_layout_table_get_script_tags(blankfont.face, "GPOS") + assert tags == ['DFLT'] + + def test_ot_layout_script_get_language_tags(self, blankfont): + tags = hb.ot_layout_script_get_language_tags(blankfont.face, "GPOS", 0) + assert tags == [] From 2477085f24c60b8fe50fa84a2e0158e5d85153ea Mon Sep 17 00:00:00 2001 From: justvanrossum Date: Mon, 16 Mar 2020 16:09:54 +0100 Subject: [PATCH 2/2] deleted stale comments --- src/uharfbuzz/_harfbuzz.pyx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/uharfbuzz/_harfbuzz.pyx b/src/uharfbuzz/_harfbuzz.pyx index 05b8040..6a9e494 100644 --- a/src/uharfbuzz/_harfbuzz.pyx +++ b/src/uharfbuzz/_harfbuzz.pyx @@ -548,7 +548,6 @@ def ot_layout_script_get_language_tags( cdef bytes packed = tag.encode() cdef hb_tag_t hb_tag = hb_tag_from_string(packed, -1) cdef unsigned int language_count = STATIC_TAGS_ARRAY_SIZE - # we could get count first and malloc the array like pango is doing cdef hb_tag_t language_tags[STATIC_TAGS_ARRAY_SIZE] cdef list tags = [] cdef char cstr[5] @@ -569,7 +568,6 @@ def ot_layout_table_get_script_tags(face: Face, tag: str) -> List[str]: cdef bytes packed = tag.encode() cdef hb_tag_t hb_tag = hb_tag_from_string(packed, -1) cdef unsigned int script_count = STATIC_TAGS_ARRAY_SIZE - # we could get count first and malloc the array like pango is doing cdef hb_tag_t script_tags[STATIC_TAGS_ARRAY_SIZE] cdef list tags = [] cdef char cstr[5]