Another ugly hack to make bidi cursor work with Core Text

If the text is wrapped with LRE/LRO/RLE/RLO override/embed marks,
Core Text in Mac OS X 10.5 doesn't produce an empty glyph at the
beginning of the glyphs (while it does in Mac OS X 10.6), thus
we need to prepend an empty glyph here, otherwise cursor position
calculation will consider the first two characters as a ligature
of the same glyph.

Reviewed-by: Eskil
(cherry picked from commit a36ac6c34bafa801c2c30d76f59e4a3594efc4d5)
This commit is contained in:
Jiang Jiang 2011-04-27 11:39:09 +02:00
parent d64460fffb
commit bbbfc9b0eb
2 changed files with 25 additions and 3 deletions

View File

@ -180,6 +180,8 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
&kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
typeSetter = CTTypesetterCreateWithAttributedStringAndOptions(attributedString, options);
} else
#else
Q_UNUSED(flags);
#endif
typeSetter = CTTypesetterCreateWithAttributedString(attributedString);
@ -219,6 +221,25 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
Q_ASSERT((CTRunGetStatus(run) & kCTRunStatusRightToLeft) == rtl);
CFRange stringRange = CTRunGetStringRange(run);
int prepend = 0;
#if MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5
UniChar beginGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location);
QChar dir = QChar::direction(beginGlyph);
bool beginWithOverride = dir == QChar::DirLRO || dir == QChar::DirRLO || dir == QChar::DirLRE || dir == QChar::DirRLE;
if (beginWithOverride) {
logClusters[stringRange.location] = 0;
outGlyphs[0] = 0xFFFF;
outAdvances_x[0] = 0;
outAdvances_y[0] = 0;
outAttributes[0].clusterStart = true;
outAttributes[0].dontPrint = true;
outGlyphs++;
outAdvances_x++;
outAdvances_y++;
outAttributes++;
prepend = 1;
}
#endif
UniChar endGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location + stringRange.length - 1);
bool endWithPDF = QChar::direction(endGlyph) == QChar::DirPDF;
if (endWithPDF)
@ -271,9 +292,9 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
CFIndex k = 0;
CFIndex i = 0;
for (i = stringRange.location;
for (i = stringRange.location + prepend;
(i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) {
if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location) {
if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location + prepend) {
logClusters[i] = k + firstGlyphIndex;
outAttributes[k].clusterStart = true;
++k;
@ -308,7 +329,7 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
: QFixed::fromReal(lastGlyphAdvance.width);
if (endWithPDF) {
logClusters[stringRange.location + stringRange.length - 1] = glyphCount;
logClusters[stringRange.location + stringRange.length - 1] = glyphCount + prepend;
outGlyphs[glyphCount] = 0xFFFF;
outAdvances_x[glyphCount] = 0;
outAdvances_y[glyphCount] = 0;

View File

@ -214,6 +214,7 @@ void tst_QComplexText::bidiCursorMovement()
QTextOption option = layout.textOption();
option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft);
layout.setTextOption(option);
layout.setCursorMoveStyle(QTextCursor::Visual);
bool moved;
int oldPos, newPos = 0;
qreal x, newX;