From c29993a181c2139eaec97b5f6225824040ca3ac9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 28 Jan 2014 17:29:42 -0500 Subject: [PATCH] [coretext] Handle surrogate pairs when generating notdef glyphs Fixes github.com/behdad/harfbuzz/pull/19 --- src/hb-coretext.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc index f247c08f4..87dd77975 100644 --- a/src/hb-coretext.cc +++ b/src/hb-coretext.cc @@ -591,7 +591,6 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, CFMutableAttributedStringRef attr_string = CFAttributedStringCreateMutable (NULL, chars_len); CFAttributedStringReplaceString (attr_string, CFRangeMake (0, 0), string_ref); - CFRelease (string_ref); CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), kCTFontAttributeName, font_data->ct_font); @@ -671,23 +670,33 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, if (buffer->in_error) FAIL ("Buffer resize failed"); hb_glyph_info_t *info = buffer->info + buffer->len; - buffer->len += range.length; CGGlyph notdef = 0; double advance = CTFontGetAdvancesForGlyphs (font_data->ct_font, kCTFontHorizontalOrientation, ¬def, 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 (ch, 0xDC00, 0xDFFF) && range.location < j) + { + ch = CFStringGetCharacterAtIndex (string_ref, j - 1); + if (hb_in_range (ch, 0xD800, 0xDBFF)) + /* This is the second of a surrogate pair. Don't need .notdef + * for this one. */ + continue; + } + info->codepoint = notdef; /* TODO We have to fixup clusters later. See vis_clusters in * hb-uniscribe.cc for example. */ - info->cluster = range.location + j; + info->cluster = j; info->mask = advance; info->var1.u32 = 0; info->var2.u32 = 0; info++; + buffer->len++; } continue; } @@ -796,6 +805,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, } } + CFRelease (string_ref); CFRelease (line); return true;