Skip to content

Commit

Permalink
Implement issue 36 (#38)
Browse files Browse the repository at this point in the history
* added post table format 2.0, so we have glyph names

* implement a issue #36: adding font.get_glyph_name(gid) method

* also expose hb_font_glyph_to_string() via font.glyph_to_string()
  • Loading branch information
justvanrossum authored Mar 27, 2020
1 parent 79775b9 commit 541174d
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/uharfbuzz/_harfbuzz.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,23 @@ cdef class Font:
finally:
free(hb_variations)

def get_glyph_name(self, gid: int):
cdef char name[64]
cdef bytes packed
success = hb_font_get_glyph_name(self._hb_font, gid, name, 64)
if success:
packed = name
return packed.decode()
else:
return None

def glyph_to_string(self, gid: int):
cdef char name[64]
cdef bytes packed
hb_font_glyph_to_string(self._hb_font, gid, name, 64)
packed = name
return packed.decode()


cdef hb_position_t _glyph_h_advance_func(hb_font_t* font, void* font_data,
hb_codepoint_t glyph,
Expand Down
10 changes: 10 additions & 0 deletions src/uharfbuzz/charfbuzz.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,16 @@ cdef extern from "hb.h":
hb_font_t* font,
const hb_variation_t* variations,
unsigned int variations_length)
hb_bool_t hb_font_get_glyph_name(
hb_font_t* font,
hb_codepoint_t glyph,
char* name,
unsigned int size)
void hb_font_glyph_to_string(
hb_font_t* font,
hb_codepoint_t glyph,
char* name,
unsigned int size)
void hb_font_destroy(hb_font_t* font)

# hb-shape.h
Expand Down
Binary file modified tests/data/AdobeBlank.subset.ttf
Binary file not shown.
26 changes: 26 additions & 0 deletions tests/test_uharfbuzz.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,32 @@ def test_gid_and_cluster_no_features(self, blankfont, string, expected):
infos = [(g.codepoint, g.cluster) for g in buf.glyph_infos]
assert infos == expected

@pytest.mark.parametrize(
"string, expected",
[
("abcde", ["a", "b", "c", "d", "e"]),
("abçde", ["a", "b", "ccedilla", "d", "e"]),
("aбcde", ["a", "uni0431", "c", "d", "e"]),
("abc💩e", ["a", "b", "c", "u1F4A9", "e"]),
],
ids=["ascii", "latin1", "ucs2", "ucs4"],
)
def test_glyh_name_no_features(self, blankfont, string, expected):
buf = hb.Buffer()
buf.add_str(string)
buf.guess_segment_properties()
hb.shape(blankfont, buf)
# font.get_glyph_name() returns None if the font does not contain glyph names
# or if the glyph ID does not exist.
glyph_names = [blankfont.get_glyph_name(g.codepoint) for g in buf.glyph_infos]
assert glyph_names == expected
assert blankfont.get_glyph_name(1000) is None
# font.glyph_to_string() return "gidN" if the font does not contain glyph names
# or if the glyph ID does not exist.
glyph_names = [blankfont.glyph_to_string(g.codepoint) for g in buf.glyph_infos]
assert glyph_names == expected
assert blankfont.glyph_to_string(1000) == 'gid1000'


class TestCallbacks:
def test_nominal_glyph_func(self, blankfont):
Expand Down

0 comments on commit 541174d

Please sign in to comment.