summaryrefslogtreecommitdiffstats
path: root/src/gui/text
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>2016-02-05 13:25:13 +0100
committerFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2016-02-19 10:47:54 +0000
commitfef629cd9191bb73f22c5efb6f943e6b672953c1 (patch)
tree750cbffd984ebd384d2ebca9bf2e1dda14269ee9 /src/gui/text
parent67ced1d9c443011f1d1e332be2ed1abb2ef22456 (diff)
Disable unneeded ligatures when letter spacing is set
For writing systems where glyph substitutions are purely cosmetic, we should disable them when letter spacing is set, otherwise we get ligatures where the spacing is not applied. To avoid changing Harfbuzz-NG upstream, we detect this case when fetching the GSUB table and return an empty blob instead. Task-number: QTBUG-44393 Change-Id: Ie5f6b2d795d7fecbba0ece3941fb70ba7f04c395 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com> Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src/gui/text')
-rw-r--r--src/gui/text/qharfbuzzng.cpp15
-rw-r--r--src/gui/text/qharfbuzzng_p.h3
-rw-r--r--src/gui/text/qtextengine.cpp19
-rw-r--r--src/gui/text/qtextengine_p.h8
4 files changed, 40 insertions, 5 deletions
diff --git a/src/gui/text/qharfbuzzng.cpp b/src/gui/text/qharfbuzzng.cpp
index b2edfc00a0..6437465da8 100644
--- a/src/gui/text/qharfbuzzng.cpp
+++ b/src/gui/text/qharfbuzzng.cpp
@@ -573,17 +573,27 @@ _hb_qt_font_get_glyph_from_name(hb_font_t * /*font*/, void * /*font_data*/,
static hb_user_data_key_t _useDesignMetricsKey;
+static hb_user_data_key_t _ignoreGSUB;
void hb_qt_font_set_use_design_metrics(hb_font_t *font, uint value)
{
hb_font_set_user_data(font, &_useDesignMetricsKey, (void *)quintptr(value), NULL, true);
}
+void hb_qt_face_set_ignore_gsub(hb_face_t *face, uint value)
+{
+ hb_face_set_user_data(face, &_ignoreGSUB, (void *)quintptr(value), NULL, true);
+}
+
uint hb_qt_font_get_use_design_metrics(hb_font_t *font)
{
return quintptr(hb_font_get_user_data(font, &_useDesignMetricsKey));
}
+uint hb_qt_face_get_ignore_gsub(hb_face_t *face)
+{
+ return quintptr(hb_face_get_user_data(face, &_ignoreGSUB));
+}
struct _hb_qt_font_funcs_t {
_hb_qt_font_funcs_t()
@@ -618,11 +628,14 @@ hb_font_funcs_t *hb_qt_get_font_funcs()
static hb_blob_t *
-_hb_qt_reference_table(hb_face_t * /*face*/, hb_tag_t tag, void *user_data)
+_hb_qt_reference_table(hb_face_t *face, hb_tag_t tag, void *user_data)
{
QFontEngine::FaceData *data = static_cast<QFontEngine::FaceData *>(user_data);
Q_ASSERT(data);
+ if (hb_qt_face_get_ignore_gsub(face) && tag == HB_TAG('G','S','U','B'))
+ return hb_blob_get_empty();
+
qt_get_font_table_func_t get_font_table = data->get_font_table;
Q_ASSERT(get_font_table);
diff --git a/src/gui/text/qharfbuzzng_p.h b/src/gui/text/qharfbuzzng_p.h
index d5e11e6264..8beadbc72c 100644
--- a/src/gui/text/qharfbuzzng_p.h
+++ b/src/gui/text/qharfbuzzng_p.h
@@ -72,6 +72,9 @@ Q_GUI_EXPORT hb_font_t *hb_qt_font_get_for_engine(QFontEngine *fe);
Q_GUI_EXPORT void hb_qt_font_set_use_design_metrics(hb_font_t *font, uint value);
Q_GUI_EXPORT uint hb_qt_font_get_use_design_metrics(hb_font_t *font);
+Q_GUI_EXPORT void hb_qt_face_set_ignore_gsub(hb_face_t *font, uint value);
+Q_GUI_EXPORT uint hb_qt_face_get_ignore_gsub(hb_face_t *font);
+
QT_END_NAMESPACE
#endif // QHARFBUZZNG_P_H
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 1c924175e2..7dc8e8fadb 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1059,7 +1059,7 @@ void QTextEngine::shapeText(int item) const
#ifdef QT_ENABLE_HARFBUZZ_NG
if (Q_LIKELY(qt_useHarfbuzzNG()))
- si.num_glyphs = shapeTextWithHarfbuzzNG(si, string, itemLength, fontEngine, itemBoundaries, kerningEnabled);
+ si.num_glyphs = shapeTextWithHarfbuzzNG(si, string, itemLength, fontEngine, itemBoundaries, kerningEnabled, letterSpacing != 0);
else
#endif
si.num_glyphs = shapeTextWithHarfbuzz(si, string, itemLength, fontEngine, itemBoundaries, kerningEnabled);
@@ -1121,7 +1121,13 @@ QT_BEGIN_INCLUDE_NAMESPACE
QT_END_INCLUDE_NAMESPACE
-int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector<uint> &itemBoundaries, bool kerningEnabled) const
+int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si,
+ const ushort *string,
+ int itemLength,
+ QFontEngine *fontEngine,
+ const QVector<uint> &itemBoundaries,
+ bool kerningEnabled,
+ bool hasLetterSpacing) const
{
uint glyphs_shaped = 0;
@@ -1135,7 +1141,8 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
hb_segment_properties_t props = HB_SEGMENT_PROPERTIES_DEFAULT;
props.direction = si.analysis.bidiLevel % 2 ? HB_DIRECTION_RTL : HB_DIRECTION_LTR;
- props.script = hb_qt_script_to_script(QChar::Script(si.analysis.script));
+ QChar::Script script = QChar::Script(si.analysis.script);
+ props.script = hb_qt_script_to_script(script);
// ### props.language = hb_language_get_default_for_script(props.script);
for (int k = 0; k < itemBoundaries.size(); k += 3) {
@@ -1168,6 +1175,12 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
Q_ASSERT(hb_font);
hb_qt_font_set_use_design_metrics(hb_font, option.useDesignMetrics() ? uint(QFontEngine::DesignMetrics) : 0); // ###
+ bool scriptRequiresOpenType = ((script >= QChar::Script_Syriac && script <= QChar::Script_Sinhala)
+ || script == QChar::Script_Khmer || script == QChar::Script_Nko);
+ hb_face_t *hb_face = hb_font_get_face(hb_font);
+ Q_ASSERT(hb_face);
+ hb_qt_face_set_ignore_gsub(hb_face, hasLetterSpacing && !scriptRequiresOpenType);
+
const hb_feature_t features[1] = {
{ HB_TAG('k','e','r','n'), !!kerningEnabled, 0, uint(-1) }
};
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index 39c228fd52..7e507bba2d 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -643,7 +643,13 @@ private:
void addRequiredBoundaries() const;
void shapeText(int item) const;
#ifdef QT_ENABLE_HARFBUZZ_NG
- int shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector<uint> &itemBoundaries, bool kerningEnabled) const;
+ int shapeTextWithHarfbuzzNG(const QScriptItem &si,
+ const ushort *string,
+ int itemLength,
+ QFontEngine *fontEngine,
+ const QVector<uint> &itemBoundaries,
+ bool kerningEnabled,
+ bool hasLetterSpacing) const;
#endif
int shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector<uint> &itemBoundaries, bool kerningEnabled) const;