[coretext] Handle surrogate pairs when generating notdef glyphs

Fixes github.com/behdad/harfbuzz/pull/19
This commit is contained in:
Behdad Esfahbod 2014-01-28 17:29:42 -05:00
parent 748b2782e4
commit c29993a181
1 changed files with 14 additions and 4 deletions

View File

@ -591,7 +591,6 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
CFMutableAttributedStringRef attr_string = CFAttributedStringCreateMutable (NULL, chars_len); CFMutableAttributedStringRef attr_string = CFAttributedStringCreateMutable (NULL, chars_len);
CFAttributedStringReplaceString (attr_string, CFRangeMake (0, 0), string_ref); CFAttributedStringReplaceString (attr_string, CFRangeMake (0, 0), string_ref);
CFRelease (string_ref);
CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
kCTFontAttributeName, font_data->ct_font); kCTFontAttributeName, font_data->ct_font);
@ -671,23 +670,33 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
if (buffer->in_error) if (buffer->in_error)
FAIL ("Buffer resize failed"); FAIL ("Buffer resize failed");
hb_glyph_info_t *info = buffer->info + buffer->len; hb_glyph_info_t *info = buffer->info + buffer->len;
buffer->len += range.length;
CGGlyph notdef = 0; CGGlyph notdef = 0;
double advance = CTFontGetAdvancesForGlyphs (font_data->ct_font, kCTFontHorizontalOrientation, &notdef, NULL, 1); double advance = CTFontGetAdvancesForGlyphs (font_data->ct_font, kCTFontHorizontalOrientation, &notdef, NULL, 1);
for (CFIndex j = 0; j < range.length; j++) for (CFIndex j = range.location; j < range.location + range.length; j++)
{ {
UniChar ch = CFStringGetCharacterAtIndex (string_ref, j);
if (hb_in_range<UniChar> (ch, 0xDC00, 0xDFFF) && range.location < j)
{
ch = CFStringGetCharacterAtIndex (string_ref, j - 1);
if (hb_in_range<UniChar> (ch, 0xD800, 0xDBFF))
/* This is the second of a surrogate pair. Don't need .notdef
* for this one. */
continue;
}
info->codepoint = notdef; info->codepoint = notdef;
/* TODO We have to fixup clusters later. See vis_clusters in /* TODO We have to fixup clusters later. See vis_clusters in
* hb-uniscribe.cc for example. */ * hb-uniscribe.cc for example. */
info->cluster = range.location + j; info->cluster = j;
info->mask = advance; info->mask = advance;
info->var1.u32 = 0; info->var1.u32 = 0;
info->var2.u32 = 0; info->var2.u32 = 0;
info++; info++;
buffer->len++;
} }
continue; continue;
} }
@ -796,6 +805,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
} }
} }
CFRelease (string_ref);
CFRelease (line); CFRelease (line);
return true; return true;