diff options
author | Konstantin Ritt <ritt.ks@gmail.com> | 2015-11-02 08:26:39 +0400 |
---|---|---|
committer | Konstantin Ritt <ritt.ks@gmail.com> | 2015-11-03 16:20:57 +0000 |
commit | 4f8c75acbd7598ee5664b558293fb542817e0091 (patch) | |
tree | 62a978ea497f6f3da731043cee6f0db1d5b1d4d2 /src/3rdparty/harfbuzz-ng/src/hb-coretext.cc | |
parent | dbb013d98429f9eed399392da979e42759875db3 (diff) |
Update bundled HarfBuzz-NG to 1.0.6
- Unicode 8.0 support
- Universal Shaping Engine
- Various fixes, improvements, optimizations, etc.
Change-Id: Ib6f8c92fa275c2a6575b9ae09068c92aecac7b4e
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-coretext.cc')
-rw-r--r-- | src/3rdparty/harfbuzz-ng/src/hb-coretext.cc | 106 |
1 files changed, 43 insertions, 63 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc index ab9e1d4a93..13ba5d94ef 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc @@ -38,19 +38,6 @@ #endif -typedef bool (*qt_get_font_table_func_t) (void *user_data, unsigned int tag, unsigned char *buffer, unsigned int *length); - -struct FontEngineFaceData { - void *user_data; - qt_get_font_table_func_t get_font_table; -}; - -struct CoreTextFontEngineData { - CTFontRef ctFont; - CGFontRef cgFont; -}; - - static void release_table_data (void *user_data) { @@ -104,7 +91,7 @@ hb_coretext_shaper_face_data_t * _hb_coretext_shaper_face_data_create (hb_face_t *face) { hb_coretext_shaper_face_data_t *data = NULL; -#if 0 + if (face->destroy == (hb_destroy_func_t) CGFontRelease) { data = CGFontRetain ((CGFontRef) face->user_data); @@ -124,11 +111,7 @@ _hb_coretext_shaper_face_data_create (hb_face_t *face) CGDataProviderRelease (provider); } } -#else - FontEngineFaceData *fontEngineFaceData = (FontEngineFaceData *) face->user_data; - CoreTextFontEngineData *coreTextFontEngineData = (CoreTextFontEngineData *) fontEngineFaceData->user_data; - data = CGFontRetain (coreTextFontEngineData->cgFont); -#endif + if (unlikely (!data)) { DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed"); } @@ -142,6 +125,9 @@ _hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data) CFRelease (data); } +/* + * Since: 0.9.10 + */ CGFontRef hb_coretext_face_get_cg_font (hb_face_t *face) { @@ -170,10 +156,10 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) return NULL; hb_face_t *face = font->face; -#if 0 hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); /* Choose a CoreText font size and calculate multipliers to convert to HarfBuzz space. */ + /* TODO: use upem instead of 36? */ CGFloat font_size = 36.; /* Default... */ /* No idea if the following is even a good idea. */ if (font->y_ppem) @@ -184,12 +170,6 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) data->x_mult = (CGFloat) font->x_scale / font_size; data->y_mult = (CGFloat) font->y_scale / font_size; data->ct_font = CTFontCreateWithGraphicsFont (face_data, font_size, NULL, NULL); -#else - data->x_mult = data->y_mult = (CGFloat) 64.0f; - FontEngineFaceData *fontEngineFaceData = (FontEngineFaceData *) face->user_data; - CoreTextFontEngineData *coreTextFontEngineData = (CoreTextFontEngineData *) fontEngineFaceData->user_data; - data->ct_font = (CTFontRef) CFRetain (coreTextFontEngineData->ctFont); -#endif if (unlikely (!data->ct_font)) { DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed"); free (data); @@ -812,6 +792,17 @@ retry: buffer->len = 0; uint32_t status_and = ~0, status_or = 0; double advances_so_far = 0; + /* For right-to-left runs, CoreText returns the glyphs positioned such that + * any trailing whitespace is to the left of (0,0). Adjust coordinate system + * to fix for that. Test with any RTL string with trailing spaces. + * https://code.google.com/p/chromium/issues/detail?id=469028 + */ + if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) + { + advances_so_far -= CTLineGetTrailingWhitespaceWidth (line); + if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction)) + advances_so_far = -advances_so_far; + } const CFRange range_all = CFRangeMake (0, 0); @@ -827,8 +818,6 @@ retry: run_advance = -run_advance; DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance); - CFRange range = CTRunGetStringRange (run); - /* CoreText does automatic font fallback (AKA "cascading") for characters * not supported by the requested font, and provides no way to turn it off, * so we must detect if the returned run uses a font other than the requested @@ -895,6 +884,7 @@ retry: } if (!matched) { + CFRange range = CTRunGetStringRange (run); DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld", range.location, range.location + range.length); if (!buffer->ensure_inplace (buffer->len + range.length)) @@ -929,8 +919,8 @@ retry: info->cluster = log_clusters[j]; info->mask = advance; - info->var1.u32 = x_offset; - info->var2.u32 = y_offset; + info->var1.i32 = x_offset; + info->var2.i32 = y_offset; info++; buffer->len++; @@ -946,13 +936,7 @@ retry: if (num_glyphs == 0) continue; - /* ### temporary fix for QTBUG-38113 */ - /* CoreText throws away the PDF token, while the OpenType backend will add a zero-advance - * glyph for this. We need to make sure the two produce the same output. */ - UniChar endGlyph = CFStringGetCharacterAtIndex (string_ref, range.location + range.length - 1); - bool endsWithPDF = endGlyph == 0x202c; - - if (!buffer->ensure_inplace (buffer->len + num_glyphs + (endsWithPDF ? 1 : 0))) + if (!buffer->ensure_inplace (buffer->len + num_glyphs)) goto resize_and_retry; hb_glyph_info_t *run_info = buffer->info + buffer->len; @@ -1022,8 +1006,8 @@ retry: else /* last glyph */ advance = run_advance - (positions[j].x - positions[0].x); info->mask = advance * x_mult; - info->var1.u32 = x_offset; - info->var2.u32 = positions[j].y * y_mult; + info->var1.i32 = x_offset; + info->var2.i32 = positions[j].y * y_mult; info++; } } @@ -1038,25 +1022,11 @@ retry: else /* last glyph */ advance = run_advance - (positions[j].y - positions[0].y); info->mask = advance * y_mult; - info->var1.u32 = positions[j].x * x_mult; - info->var2.u32 = y_offset; + info->var1.i32 = positions[j].x * x_mult; + info->var2.i32 = y_offset; info++; } } - if (endsWithPDF) { - /* Ensure a zero-advance glyph the PDF token */ - if (unlikely (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))) { - memmove (run_info + 1, run_info, num_glyphs * sizeof (hb_glyph_info_t)); - info = run_info; - } - info->codepoint = 0xffff; - info->cluster = log_clusters[range.location + range.length - 1]; - info->mask = 0; - info->var1.u32 = 0; - info->var2.u32 = 0; - - buffer->len++; - } SCRATCH_RESTORE(); advances_so_far += run_advance; } @@ -1068,10 +1038,20 @@ retry: buffer->len += num_glyphs; } - /* Make sure all runs had the expected direction. */ - bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); - assert (bool (status_and & kCTRunStatusRightToLeft) == backward); - assert (bool (status_or & kCTRunStatusRightToLeft) == backward); + /* Mac OS 10.6 doesn't have kCTTypesetterOptionForcedEmbeddingLevel, + * or if it does, it doesn't resepct it. So we get runs with wrong + * directions. As such, disable the assert... It wouldn't crash, but + * cursoring will be off... + * + * http://crbug.com/419769 + */ + if (0) + { + /* Make sure all runs had the expected direction. */ + bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); + assert (bool (status_and & kCTRunStatusRightToLeft) == backward); + assert (bool (status_or & kCTRunStatusRightToLeft) == backward); + } buffer->clear_positions (); @@ -1082,16 +1062,16 @@ retry: for (unsigned int i = 0; i < count; i++) { pos->x_advance = info->mask; - pos->x_offset = info->var1.u32; - pos->y_offset = info->var2.u32; + pos->x_offset = info->var1.i32; + pos->y_offset = info->var2.i32; info++, pos++; } else for (unsigned int i = 0; i < count; i++) { pos->y_advance = info->mask; - pos->x_offset = info->var1.u32; - pos->y_offset = info->var2.u32; + pos->x_offset = info->var1.i32; + pos->y_offset = info->var2.i32; info++, pos++; } |