diff options
author | Liang Qi <liang.qi@qt.io> | 2017-02-10 21:10:21 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-02-10 22:35:04 +0100 |
commit | 364b161122b567e3a6f7343d438fb540b9fb7e5c (patch) | |
tree | 3d49953be9a58295a8c956cf5fdb00f581020605 /src/gui/text | |
parent | e58401a75b29beb38d37a40072106d5ef7cb0336 (diff) | |
parent | 8a410f60ae39b06555d807581caf7cb8bfab4fac (diff) |
Merge remote-tracking branch 'origin/5.9' into dev
Conflicts:
src/widgets/widgets/qmainwindowlayout_p.h
Change-Id: Id406a67606b885052ed405b0fbc8eea7d9d03224
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/qfontmetrics.cpp | 6 | ||||
-rw-r--r-- | src/gui/text/qharfbuzzng.cpp | 117 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 28 |
3 files changed, 83 insertions, 68 deletions
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index aca59d0288..8067969f56 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -556,7 +556,6 @@ int QFontMetrics::width(const QString &text, int len, int flags) const } QStackTextEngine layout(text, QFont(d.data())); - layout.ignoreBidi = true; return qRound(layout.width(0, len)); } @@ -692,7 +691,6 @@ QRect QFontMetrics::boundingRect(const QString &text) const return QRect(); QStackTextEngine layout(text, QFont(d.data())); - layout.ignoreBidi = true; layout.itemize(); glyph_metrics_t gm = layout.boundingBox(0, text.length()); return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height)); @@ -861,7 +859,6 @@ QRect QFontMetrics::tightBoundingRect(const QString &text) const return QRect(); QStackTextEngine layout(text, QFont(d.data())); - layout.ignoreBidi = true; layout.itemize(); glyph_metrics_t gm = layout.tightBoundingBox(0, text.length()); return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height)); @@ -1413,7 +1410,6 @@ qreal QFontMetricsF::width(const QString &text) const int len = (pos != -1) ? pos : text.length(); QStackTextEngine layout(text, QFont(d.data())); - layout.ignoreBidi = true; layout.itemize(); return layout.width(0, len).toReal(); } @@ -1496,7 +1492,6 @@ QRectF QFontMetricsF::boundingRect(const QString &text) const return QRectF(); QStackTextEngine layout(text, QFont(d.data())); - layout.ignoreBidi = true; layout.itemize(); glyph_metrics_t gm = layout.boundingBox(0, len); return QRectF(gm.x.toReal(), gm.y.toReal(), @@ -1668,7 +1663,6 @@ QRectF QFontMetricsF::tightBoundingRect(const QString &text) const return QRect(); QStackTextEngine layout(text, QFont(d.data())); - layout.ignoreBidi = true; layout.itemize(); glyph_metrics_t gm = layout.tightBoundingBox(0, text.length()); return QRectF(gm.x.toReal(), gm.y.toReal(), gm.width.toReal(), gm.height.toReal()); diff --git a/src/gui/text/qharfbuzzng.cpp b/src/gui/text/qharfbuzzng.cpp index 55ef9f0d15..6aca660205 100644 --- a/src/gui/text/qharfbuzzng.cpp +++ b/src/gui/text/qharfbuzzng.cpp @@ -422,19 +422,53 @@ hb_unicode_funcs_t *hb_qt_get_unicode_funcs() // Font routines +#if HB_VERSION_ATLEAST(1, 1, 3) static hb_bool_t -_hb_qt_font_get_glyph(hb_font_t * /*font*/, void *font_data, - hb_codepoint_t unicode, hb_codepoint_t /*variation_selector*/, - hb_codepoint_t *glyph, - void * /*user_data*/) +_hb_qt_get_font_h_extents(hb_font_t * /*font*/, void *font_data, + hb_font_extents_t *metrics, + void * /*user_data*/) { QFontEngine *fe = static_cast<QFontEngine *>(font_data); Q_ASSERT(fe); - *glyph = fe->glyphIndex(unicode); + metrics->ascender = fe->ascent().value(); + metrics->descender = fe->descent().value(); + metrics->line_gap = fe->leading().value(); return true; } +#endif + +#if HB_VERSION_ATLEAST(1, 2, 3) +static hb_bool_t +_hb_qt_font_get_nominal_glyph(hb_font_t * /*font*/, void *font_data, + hb_codepoint_t unicode, + hb_codepoint_t *glyph, + void * /*user_data*/) +{ + QFontEngine *fe = static_cast<QFontEngine *>(font_data); + Q_ASSERT(fe); + + *glyph = fe->glyphIndex(unicode); + + return *glyph != 0; +} +#endif + +static hb_bool_t +_hb_qt_font_get_variation_glyph(hb_font_t * /*font*/, void *font_data, + hb_codepoint_t unicode, hb_codepoint_t /*variation_selector*/, + hb_codepoint_t *glyph, + void * /*user_data*/) +{ + QFontEngine *fe = static_cast<QFontEngine *>(font_data); + Q_ASSERT(fe); + + // ### TODO add support for variation selectors + *glyph = fe->glyphIndex(unicode); + + return *glyph != 0; +} static hb_position_t _hb_qt_font_get_glyph_h_advance(hb_font_t *font, void *font_data, @@ -456,15 +490,7 @@ _hb_qt_font_get_glyph_h_advance(hb_font_t *font, void *font_data, return advance.value(); } -static hb_position_t -_hb_qt_font_get_glyph_v_advance(hb_font_t * /*font*/, void * /*font_data*/, - hb_codepoint_t /*glyph*/, - void * /*user_data*/) -{ - qCritical("hb_qt_font_get_glyph_v_advance: vertical writing isn't supported!"); - return 0; -} - +#if !HB_VERSION_ATLEAST(1, 1, 2) static hb_bool_t _hb_qt_font_get_glyph_h_origin(hb_font_t * /*font*/, void * /*font_data*/, hb_codepoint_t /*glyph*/, @@ -473,16 +499,7 @@ _hb_qt_font_get_glyph_h_origin(hb_font_t * /*font*/, void * /*font_data*/, { return true; // we always work in the horizontal coordinates } - -static hb_bool_t -_hb_qt_font_get_glyph_v_origin(hb_font_t * /*font*/, void * /*font_data*/, - hb_codepoint_t /*glyph*/, - hb_position_t * /*x*/, hb_position_t * /*y*/, - void * /*user_data*/) -{ - qCritical("hb_qt_get_glyph_v_origin: vertical writing isn't supported!"); - return false; -} +#endif static hb_position_t _hb_qt_font_get_glyph_h_kerning(hb_font_t *font, void *font_data, @@ -505,15 +522,6 @@ _hb_qt_font_get_glyph_h_kerning(hb_font_t *font, void *font_data, return advance.value(); } -static hb_position_t -_hb_qt_font_get_glyph_v_kerning(hb_font_t * /*font*/, void * /*font_data*/, - hb_codepoint_t /*first_glyph*/, hb_codepoint_t /*second_glyph*/, - void * /*user_data*/) -{ - qCritical("hb_qt_get_glyph_v_kerning: vertical writing isn't supported!"); - return 0; -} - static hb_bool_t _hb_qt_font_get_glyph_extents(hb_font_t * /*font*/, void *font_data, hb_codepoint_t glyph, @@ -554,29 +562,6 @@ _hb_qt_font_get_glyph_contour_point(hb_font_t * /*font*/, void *font_data, return false; } -static hb_bool_t -_hb_qt_font_get_glyph_name(hb_font_t * /*font*/, void * /*font_data*/, - hb_codepoint_t /*glyph*/, - char *name, unsigned int size, - void * /*user_data*/) -{ - qCritical("hb_qt_font_get_glyph_name: not implemented!"); - if (size) - *name = '\0'; - return false; -} - -static hb_bool_t -_hb_qt_font_get_glyph_from_name(hb_font_t * /*font*/, void * /*font_data*/, - const char * /*name*/, int /*len*/, - hb_codepoint_t *glyph, - void * /*user_data*/) -{ - qCritical("hb_qt_font_get_glyph_from_name: not implemented!"); - *glyph = 0; - return false; -} - static hb_user_data_key_t _useDesignMetricsKey; @@ -595,17 +580,25 @@ struct _hb_qt_font_funcs_t { _hb_qt_font_funcs_t() { funcs = hb_font_funcs_create(); - hb_font_funcs_set_glyph_func(funcs, _hb_qt_font_get_glyph, NULL, NULL); + +#if HB_VERSION_ATLEAST(1, 1, 3) + hb_font_funcs_set_font_h_extents_func(funcs, _hb_qt_get_font_h_extents, NULL, NULL); +#endif +#if HB_VERSION_ATLEAST(1, 2, 3) + hb_font_funcs_set_nominal_glyph_func(funcs, _hb_qt_font_get_nominal_glyph, NULL, NULL); + hb_font_funcs_set_variation_glyph_func(funcs, _hb_qt_font_get_variation_glyph, NULL, NULL); +#else + hb_font_funcs_set_glyph_func(funcs, _hb_qt_font_get_variation_glyph, NULL, NULL); +#endif hb_font_funcs_set_glyph_h_advance_func(funcs, _hb_qt_font_get_glyph_h_advance, NULL, NULL); - hb_font_funcs_set_glyph_v_advance_func(funcs, _hb_qt_font_get_glyph_v_advance, NULL, NULL); +#if !HB_VERSION_ATLEAST(1, 1, 2) hb_font_funcs_set_glyph_h_origin_func(funcs, _hb_qt_font_get_glyph_h_origin, NULL, NULL); - hb_font_funcs_set_glyph_v_origin_func(funcs, _hb_qt_font_get_glyph_v_origin, NULL, NULL); +#endif hb_font_funcs_set_glyph_h_kerning_func(funcs, _hb_qt_font_get_glyph_h_kerning, NULL, NULL); - hb_font_funcs_set_glyph_v_kerning_func(funcs, _hb_qt_font_get_glyph_v_kerning, NULL, NULL); hb_font_funcs_set_glyph_extents_func(funcs, _hb_qt_font_get_glyph_extents, NULL, NULL); hb_font_funcs_set_glyph_contour_point_func(funcs, _hb_qt_font_get_glyph_contour_point, NULL, NULL); - hb_font_funcs_set_glyph_name_func(funcs, _hb_qt_font_get_glyph_name, NULL, NULL); - hb_font_funcs_set_glyph_from_name_func(funcs, _hb_qt_font_get_glyph_from_name, NULL, NULL); + + hb_font_funcs_make_immutable(funcs); } ~_hb_qt_font_funcs_t() { diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 67cafa53fe..f3ed8ef63a 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1165,6 +1165,20 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, hb_buffer_clear_contents(buffer); hb_buffer_add_utf16(buffer, reinterpret_cast<const uint16_t *>(string) + item_pos, item_length, 0, item_length); +#if defined(Q_OS_DARWIN) + // ### temporary workaround for QTBUG-38113 + // CoreText throws away the PDF token, while the OpenType backend will replace it with + // a zero-advance glyph. This becomes a real issue when PDF is the last character, + // since it gets treated like if it were a grapheme extender, so we + // temporarily replace it with some visible grapheme starter. + bool endsWithPDF = actualFontEngine->type() == QFontEngine::Mac && string[item_pos + item_length - 1] == 0x202c; + if (Q_UNLIKELY(endsWithPDF)) { + uint num_glyphs; + hb_glyph_info_t *infos = hb_buffer_get_glyph_infos(buffer, &num_glyphs); + infos[num_glyphs - 1].codepoint = '.'; + } +#endif + hb_buffer_set_segment_properties(buffer, &props); hb_buffer_guess_segment_properties(buffer); @@ -1286,6 +1300,20 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, while (str_pos < item_length) log_clusters[str_pos++] = last_glyph_pos; +#if defined(Q_OS_DARWIN) + if (Q_UNLIKELY(endsWithPDF)) { + int last_glyph_idx = num_glyphs - 1; + g.glyphs[last_glyph_idx] = 0xffff; + g.advances[last_glyph_idx] = QFixed(); + g.offsets[last_glyph_idx].x = QFixed(); + g.offsets[last_glyph_idx].y = QFixed(); + g.attributes[last_glyph_idx].clusterStart = true; + g.attributes[last_glyph_idx].dontPrint = true; + + log_clusters[item_length - 1] = glyphs_shaped + last_glyph_idx; + } +#endif + if (Q_UNLIKELY(engineIdx != 0)) { for (quint32 i = 0; i < num_glyphs; ++i) g.glyphs[i] |= (engineIdx << 24); |