[API] Make get_glyph() callback return a boolean

We need to know whether the glyph exists, so we can fallback to
composing / decomposing.  Assuming that glyph==0 means "doesn't exist"
wouldn't work for applications like Pango that want to use different
"doesn't exist" glyph codes for different characters.  An explicit
return value fixes that.
This commit is contained in:
Behdad Esfahbod 2011-05-12 15:14:13 -04:00
parent 8e07f93ab4
commit 0fd8c2f1be
6 changed files with 43 additions and 26 deletions

View File

@ -99,17 +99,19 @@ hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
extents->width = extents->height = 0; extents->width = extents->height = 0;
} }
static hb_codepoint_t static hb_bool_t
hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED, hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED, void *font_data HB_UNUSED,
hb_codepoint_t unicode, hb_codepoint_t unicode,
hb_codepoint_t variation_selector, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph,
void *user_data HB_UNUSED) void *user_data HB_UNUSED)
{ {
if (font->parent) if (font->parent)
return hb_font_get_glyph (font->parent, unicode, variation_selector); return hb_font_get_glyph (font->parent, unicode, variation_selector, glyph);
return 0; *glyph = 0;
return FALSE;
} }
static void static void
@ -287,12 +289,13 @@ hb_font_get_glyph_extents (hb_font_t *font,
font->klass->user_data.glyph_extents); font->klass->user_data.glyph_extents);
} }
hb_codepoint_t hb_bool_t
hb_font_get_glyph (hb_font_t *font, hb_font_get_glyph (hb_font_t *font,
hb_codepoint_t unicode, hb_codepoint_t variation_selector) hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph)
{ {
return font->klass->get.glyph (font, font->user_data, return font->klass->get.glyph (font, font->user_data,
unicode, variation_selector, unicode, variation_selector, glyph,
font->klass->user_data.glyph); font->klass->user_data.glyph);
} }

View File

@ -140,9 +140,10 @@ typedef void (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_da
hb_codepoint_t glyph, hb_codepoint_t glyph,
hb_glyph_extents_t *extents, hb_glyph_extents_t *extents,
void *user_data); void *user_data);
typedef hb_codepoint_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data, typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t unicode, hb_codepoint_t variation_selector, hb_codepoint_t unicode, hb_codepoint_t variation_selector,
void *user_data); hb_codepoint_t *glyph,
void *user_data);
typedef void (*hb_font_get_kerning_func_t) (hb_font_t *font, void *font_data, typedef void (*hb_font_get_kerning_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph, hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
hb_position_t *x_kern, hb_position_t *y_kern, hb_position_t *x_kern, hb_position_t *y_kern,
@ -190,9 +191,10 @@ hb_font_get_glyph_extents (hb_font_t *font,
hb_codepoint_t glyph, hb_codepoint_t glyph,
hb_glyph_extents_t *extents); hb_glyph_extents_t *extents);
hb_codepoint_t hb_bool_t
hb_font_get_glyph (hb_font_t *font, hb_font_get_glyph (hb_font_t *font,
hb_codepoint_t unicode, hb_codepoint_t variation_selector); hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph);
void void
hb_font_get_kerning (hb_font_t *font, hb_font_get_kerning (hb_font_t *font,

View File

@ -107,11 +107,12 @@ hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
} }
} }
static hb_codepoint_t static hb_bool_t
hb_ft_get_glyph (hb_font_t *font HB_UNUSED, hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
void *font_data, void *font_data,
hb_codepoint_t unicode, hb_codepoint_t unicode,
hb_codepoint_t variation_selector, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph,
void *user_data HB_UNUSED) void *user_data HB_UNUSED)
{ {
@ -119,13 +120,14 @@ hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
#ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX #ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX
if (unlikely (variation_selector)) { if (unlikely (variation_selector)) {
hb_codepoint_t glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector); *glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
if (glyph) if (*glyph)
return glyph; return TRUE;
} }
#endif #endif
return FT_Get_Char_Index (ft_face, unicode); *glyph = FT_Get_Char_Index (ft_face, unicode);
return *glyph != 0;
} }
static void static void

View File

@ -216,18 +216,23 @@ hb_map_glyphs (hb_font_t *font,
if (unlikely (!buffer->len)) if (unlikely (!buffer->len))
return; return;
hb_codepoint_t glyph;
buffer->clear_output (); buffer->clear_output ();
unsigned int count = buffer->len - 1; unsigned int count = buffer->len - 1;
for (buffer->i = 0; buffer->i < count;) { for (buffer->i = 0; buffer->i < count;) {
if (unlikely (is_variation_selector (buffer->info[buffer->i + 1].codepoint))) { if (unlikely (is_variation_selector (buffer->info[buffer->i + 1].codepoint))) {
buffer->replace_glyph (hb_font_get_glyph (font, buffer->info[buffer->i].codepoint, buffer->info[buffer->i + 1].codepoint)); hb_font_get_glyph (font, buffer->info[buffer->i].codepoint, buffer->info[buffer->i + 1].codepoint, &glyph);
buffer->replace_glyph (glyph);
buffer->i++; buffer->i++;
} else { } else {
buffer->replace_glyph (hb_font_get_glyph (font, buffer->info[buffer->i].codepoint, 0)); hb_font_get_glyph (font, buffer->info[buffer->i].codepoint, 0, &glyph);
buffer->replace_glyph (glyph);
} }
} }
if (likely (buffer->i < buffer->len)) if (likely (buffer->i < buffer->len)) {
buffer->replace_glyph (hb_font_get_glyph (font, buffer->info[buffer->i].codepoint, 0)); hb_font_get_glyph (font, buffer->info[buffer->i].codepoint, 0, &glyph);
buffer->replace_glyph (glyph);
}
buffer->swap (); buffer->swap ();
} }

View File

@ -112,6 +112,7 @@ test_face_createfortables (void)
static void static void
_test_font_nil_funcs (hb_font_t *font) _test_font_nil_funcs (hb_font_t *font)
{ {
hb_codepoint_t glyph;
hb_position_t x, y; hb_position_t x, y;
hb_glyph_extents_t extents; hb_glyph_extents_t extents;
@ -133,7 +134,9 @@ _test_font_nil_funcs (hb_font_t *font)
g_assert_cmpint (extents.width, ==, 0); g_assert_cmpint (extents.width, ==, 0);
g_assert_cmpint (extents.height, ==, 0); g_assert_cmpint (extents.height, ==, 0);
g_assert (0 == hb_font_get_glyph (font, 17, 2)); glyph = 3;
g_assert (!hb_font_get_glyph (font, 17, 2, &glyph));
g_assert_cmpint (glyph, ==, 0);
x = y = 13; x = y = 13;
hb_font_get_kerning (font, 17, 19, &x, &y); hb_font_get_kerning (font, 17, 19, &x, &y);

View File

@ -44,17 +44,19 @@ glyph_advance_func (hb_font_t *font, void *font_data,
} }
} }
static hb_codepoint_t static hb_bool_t
glyph_func (hb_font_t *font, void *font_data, glyph_func (hb_font_t *font, void *font_data,
hb_codepoint_t unicode, hb_codepoint_t variant_selector, hb_codepoint_t unicode, hb_codepoint_t variant_selector,
hb_codepoint_t *glyph,
void *user_data) void *user_data)
{ {
switch (unicode) { switch (unicode) {
case 'T': return 1; case 'T': *glyph = 1; return TRUE;
case 'e': return 2; case 'e': *glyph = 2; return TRUE;
case 's': return 3; case 's': *glyph = 3; return TRUE;
default: return 0;
} }
return FALSE;
} }
static void static void