Add hb_font_glyph_from/to_string
diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh index 56c5913..6bbf8d8 100644 --- a/src/hb-font-private.hh +++ b/src/hb-font-private.hh
@@ -254,6 +254,7 @@ inline hb_bool_t get_glyph_name (hb_codepoint_t glyph, char *name, unsigned int size) { + if (size) *name = '\0'; return klass->get.glyph_name (this, user_data, glyph, name, size, @@ -263,6 +264,8 @@ inline hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */ hb_codepoint_t *glyph) { + *glyph = 0; + if (len == -1) len = strlen (name); return klass->get.glyph_from_name (this, user_data, name, len, glyph, @@ -377,6 +380,46 @@ return ret; } + /* Generates gidDDD if glyph has no name. */ + inline void + glyph_to_string (hb_codepoint_t glyph, + char *s, unsigned int size) + { + if (get_glyph_name (glyph, s, size)) return; + + snprintf (s, size, "gid%u", glyph); + } + + /* Parses gidDDD and uniUUUU strings automatically. */ + inline hb_bool_t + glyph_from_string (const char *s, int len, /* -1 means nul-terminated */ + hb_codepoint_t *glyph) + { + if (get_glyph_from_name (s, len, glyph)) return true; + + if (len == -1) len = strlen (s); + + /* Straight glyph index. */ + if (hb_codepoint_parse (s, len, 10, glyph)) + return true; + + if (len > 3) + { + /* gidDDD syntax for glyph indices. */ + if (0 == strncmp (s, "gid", 3) && + hb_codepoint_parse (s + 3, len - 3, 10, glyph)) + return true; + + /* uniUUUU and other Unicode character indices. */ + hb_codepoint_t unichar; + if (0 == strncmp (s, "uni", 3) && + hb_codepoint_parse (s + 3, len - 3, 16, &unichar) && + get_glyph (unichar, 0, glyph)) + return true; + } + + return false; + } private: inline hb_position_t em_scale (int16_t v, int scale) { return v * (int64_t) scale / hb_face_get_upem (this->face); }
diff --git a/src/hb-font.cc b/src/hb-font.cc index 409b9e8..e5e4af7 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc
@@ -200,6 +200,7 @@ if (font->parent) return hb_font_get_glyph_name (font->parent, glyph, name, size); + if (size) *name = '\0'; return false; } @@ -410,10 +411,7 @@ hb_codepoint_t glyph, char *name, unsigned int size) { - hb_bool_t ret = font->get_glyph_name (glyph, name, size); - if (!ret) - snprintf (name, size, "gid%u", glyph); - return ret; + return font->get_glyph_name (glyph, name, size); } hb_bool_t @@ -490,6 +488,24 @@ return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y); } +/* Generates gidDDD if glyph has no name. */ +void +hb_font_glyph_to_string (hb_font_t *font, + hb_codepoint_t glyph, + char *s, unsigned int size) +{ + font->glyph_to_string (glyph, s, size); +} + +/* Parses gidDDD and uniUUUU strings automatically. */ +hb_bool_t +hb_font_glyph_from_string (hb_font_t *font, + const char *s, int len, /* -1 means nul-terminated */ + hb_codepoint_t *glyph) +{ + return font->glyph_from_string (s, len, glyph); +} + /* * hb_face_t
diff --git a/src/hb-font.h b/src/hb-font.h index ae4fc9b..0fde258 100644 --- a/src/hb-font.h +++ b/src/hb-font.h
@@ -346,6 +346,17 @@ hb_direction_t direction, hb_position_t *x, hb_position_t *y); +/* Generates gidDDD if glyph has no name. */ +void +hb_font_glyph_to_string (hb_font_t *font, + hb_codepoint_t glyph, + char *s, unsigned int size); +/* Parses gidDDD and uniUUUU strings automatically. */ +hb_bool_t +hb_font_glyph_from_string (hb_font_t *font, + const char *s, int len, /* -1 means nul-terminated */ + hb_codepoint_t *glyph); + /* * hb_font_t
diff --git a/src/hb-private.hh b/src/hb-private.hh index 0f1e5ce..8655020 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh
@@ -791,6 +791,22 @@ hb_bubble_sort (array, len, compar, (int *) NULL); } +static inline hb_bool_t +hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out) +{ + /* Pain because we don't know whether s is nul-terminated. */ + char buf[64]; + strncpy (buf, s, MIN (ARRAY_LENGTH (buf) - 1, len)); + buf[MIN (ARRAY_LENGTH (buf) - 1, len)] = '\0'; + + char *end; + errno = 0; + unsigned long v = strtoul (buf, &end, base); + if (errno) return false; + if (*end) return false; + *out = v; + return true; +} #endif /* HB_PRIVATE_HH */
diff --git a/src/test-would-substitute.cc b/src/test-would-substitute.cc index bf64a29..95626ed 100644 --- a/src/test-would-substitute.cc +++ b/src/test-would-substitute.cc
@@ -88,7 +88,16 @@ hb_blob_destroy (blob); blob = NULL; + hb_font_t *font = hb_font_create (face); +#ifdef HAVE_FREETYPE + hb_ft_font_set_funcs (font); +#endif + unsigned int len = argc - 3; - hb_codepoint_t glyphs[2] = {strtol (argv[3], NULL, 0), argc > 4 ? strtol (argv[4], NULL, 0) : (hb_codepoint_t) -1}; + hb_codepoint_t glyphs[2]; + if (!hb_font_glyph_from_string (font, argv[3], -1, &glyphs[0]) || + (argc > 4 && + !hb_font_glyph_from_string (font, argv[4], -1, &glyphs[1]))) + return 2; return !hb_ot_layout_would_substitute_lookup (face, glyphs, len, strtol (argv[2], NULL, 0)); }