summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/text/qfontengine.cpp42
-rw-r--r--src/gui/text/qfontengine_ft.cpp3
-rw-r--r--src/gui/text/qfontengine_p.h1
-rw-r--r--src/gui/text/qfontengine_qpa.cpp5
-rw-r--r--src/gui/text/qtextengine.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.cpp39
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp9
8 files changed, 44 insertions, 63 deletions
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index a3fce197ce..32225750e4 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -89,18 +89,48 @@ static HB_Bool hb_stringToGlyphs(HB_Font font, const HB_UChar16 *string, hb_uint
{
QFontEngine *fe = (QFontEngine *)font->userData;
+ const QChar *str = reinterpret_cast<const QChar *>(string);
+
QGlyphLayout qglyphs;
qglyphs.numGlyphs = *numGlyphs;
qglyphs.glyphs = glyphs;
-
- QFontEngine::ShaperFlags shaperFlags(QFontEngine::GlyphIndicesOnly);
- if (rightToLeft)
- shaperFlags |= QFontEngine::RightToLeft;
-
int nGlyphs = *numGlyphs;
- bool result = fe->stringToCMap(reinterpret_cast<const QChar *>(string), length, &qglyphs, &nGlyphs, shaperFlags);
+ bool result = fe->stringToCMap(str, length, &qglyphs, &nGlyphs, QFontEngine::GlyphIndicesOnly);
*numGlyphs = nGlyphs;
+ if (rightToLeft && result && !fe->symbol) {
+ uint glyph_pos = 0;
+ for (uint i = 0; i < length; ++i, ++glyph_pos) {
+ uint ucs4 = str[i].unicode();
+ if (Q_UNLIKELY(QChar::isHighSurrogate(ucs4) && i + 1 < length)) {
+ uint low = str[i + 1].unicode();
+ if (Q_LIKELY(QChar::isLowSurrogate(low))) {
+ ucs4 = QChar::surrogateToUcs4(ucs4, low);
+ ++i;
+ }
+ }
+
+ uint mirrored = QChar::mirroredChar(ucs4);
+ if (Q_UNLIKELY(mirrored != ucs4)) {
+ QChar chars[2];
+ uint numChars = 0;
+ if (Q_UNLIKELY(QChar::requiresSurrogates(mirrored))) {
+ chars[numChars++] = QChar(QChar::highSurrogate(mirrored));
+ chars[numChars++] = QChar(QChar::lowSurrogate(mirrored));
+ } else {
+ chars[numChars++] = QChar(mirrored);
+ }
+
+ qglyphs.numGlyphs = numChars;
+ qglyphs.glyphs = glyphs + glyph_pos;
+ nGlyphs = numChars;
+ if (!fe->stringToCMap(chars, numChars, &qglyphs, &nGlyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nGlyphs == 1);
+ }
+ }
+ }
+
return result;
}
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 630ba78477..438c7b2141 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -1516,7 +1516,6 @@ bool QFontEngineFT::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs
return false;
}
- bool mirrored = flags & QFontEngine::RightToLeft;
int glyph_pos = 0;
if (freetype->symbol_map) {
FT_Face face = freetype->face;
@@ -1552,8 +1551,6 @@ bool QFontEngineFT::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs
FT_Face face = freetype->face;
for (int i = 0; i < len; ++i) {
unsigned int uc = getChar(str, i, len);
- if (mirrored)
- uc = QChar::mirroredChar(uc);
glyphs->glyphs[glyph_pos] = uc < QFreetypeFace::cmapCacheSize ? freetype->cmapCache[uc] : 0;
if (!glyphs->glyphs[glyph_pos]) {
{
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index c181d61d73..9bc1900b99 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -120,7 +120,6 @@ public:
};
enum ShaperFlag {
- RightToLeft = 0x0001,
DesignMetrics = 0x0002,
GlyphIndicesOnly = 0x0004
};
diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpa.cpp
index 46f9071f07..cb40a5388a 100644
--- a/src/gui/text/qfontengine_qpa.cpp
+++ b/src/gui/text/qfontengine_qpa.cpp
@@ -353,13 +353,10 @@ bool QFontEngineQPA::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
const uchar *cmap = externalCMap ? externalCMap : (fontData + cmapOffset);
- bool mirrored = flags & QFontEngine::RightToLeft;
int glyph_pos = 0;
if (symbol) {
for (int i = 0; i < len; ++i) {
unsigned int uc = getChar(str, i, len);
- if (mirrored)
- uc = QChar::mirroredChar(uc);
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
@@ -368,8 +365,6 @@ bool QFontEngineQPA::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
} else {
for (int i = 0; i < len; ++i) {
unsigned int uc = getChar(str, i, len);
- if (mirrored)
- uc = QChar::mirroredChar(uc);
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
#if 0 && defined(DEBUG_FONTENGINE)
QChar c(uc);
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 739935fdd5..14bdc3167e 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -932,9 +932,6 @@ void QTextEngine::shapeText(int item) const
int nGlyphs = initialGlyphs.numGlyphs;
QFontEngine::ShaperFlags shaperFlags(QFontEngine::GlyphIndicesOnly);
- if (si.analysis.bidiLevel % 2)
- shaperFlags |= QFontEngine::RightToLeft;
-
if (!fontEngine->stringToCMap(reinterpret_cast<const QChar *>(string), itemLength, &initialGlyphs, &nGlyphs, shaperFlags)) {
nGlyphs = qMax(nGlyphs, itemLength); // ### needed for QFontEngine::stringToCMap() to not fail twice
if (!ensureSpace(nGlyphs)) {
@@ -1274,7 +1271,8 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri
engineIdx = uint(availableGlyphs(&si).glyphs[glyph_pos] >> 24);
actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
- shaper_item.glyphIndicesPresent = true;
+ if ((si.analysis.bidiLevel % 2) == 0)
+ shaper_item.glyphIndicesPresent = true;
}
shaper_item.font = (HB_Font)actualFontEngine->harfbuzzFont();
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp
index 35346e5b45..1676b73658 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp
@@ -219,44 +219,11 @@ inline unsigned int getChar(const QChar *str, int &i, const int len)
return uc;
}
-int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs, bool mirrored) const
+int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs) const
{
int i = 0;
int glyph_pos = 0;
- if (mirrored) {
-#if defined(Q_OS_WINCE)
- {
-#else
- if (symbol) {
- for (; i < numChars; ++i, ++glyph_pos) {
- unsigned int uc = getChar(str, i, numChars);
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
- if (!glyphs->glyphs[glyph_pos] && uc < 0x100)
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
- }
- } else if (ttf) {
- for (; i < numChars; ++i, ++glyph_pos) {
- unsigned int uc = getChar(str, i, numChars);
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, QChar::mirroredChar(uc));
- }
- } else {
-#endif
- wchar_t first = tm.tmFirstChar;
- wchar_t last = tm.tmLastChar;
-
- for (; i < numChars; ++i, ++glyph_pos) {
- uint ucs = QChar::mirroredChar(getChar(str, i, numChars));
- if (
-#ifdef Q_WS_WINCE
- tm.tmFirstChar > 60000 ||
-#endif
- ucs >= first && ucs <= last)
- glyphs->glyphs[glyph_pos] = ucs;
- else
- glyphs->glyphs[glyph_pos] = 0;
- }
- }
- } else {
+ {
#if defined(Q_OS_WINCE)
{
#else
@@ -390,7 +357,7 @@ bool QWindowsFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *g
}
glyphs->numGlyphs = *nglyphs;
- *nglyphs = getGlyphIndexes(str, len, glyphs, flags & RightToLeft);
+ *nglyphs = getGlyphIndexes(str, len, glyphs);
if (!(flags & GlyphIndicesOnly))
recalcAdvances(glyphs, flags);
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h
index acf84d270c..e3fb3281a3 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.h
+++ b/src/plugins/platforms/windows/qwindowsfontengine.h
@@ -127,7 +127,7 @@ public:
virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
#endif
- int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs, bool mirrored) const;
+ int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs) const;
void getCMap();
bool getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const;
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
index f603dd5c53..ce5ea8167f 100644
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
@@ -325,13 +325,8 @@ bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGly
QVarLengthArray<UINT32> codePoints(len);
int actualLength = 0;
- if (flags & QFontEngine::RightToLeft) {
- for (int i = 0; i < len; ++i)
- codePoints[actualLength++] = QChar::mirroredChar(getChar(str, i, len));
- } else {
- for (int i = 0; i < len; ++i)
- codePoints[actualLength++] = getChar(str, i, len);
- }
+ for (int i = 0; i < len; ++i)
+ codePoints[actualLength++] = getChar(str, i, len);
QVarLengthArray<UINT16> glyphIndices(actualLength);
HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(), actualLength,