Fix surrogate pair handling in QCoreTextFontEngine

The number of glyphs returned should take surrogate pairs into account.
The glyphs array and advances array as well. This follows the approach
in QFontEngineFT in general.

Change-Id: Ic53faa5e38c2219b987d76aec434558dad92015a
Reviewed-by: Zeno Albisser <zeno.albisser@nokia.com>
This commit is contained in:
Jiang Jiang 2012-05-18 16:00:55 +02:00 committed by Qt by Nokia
parent 9149aebac9
commit b4aa5d970d

View File

@ -190,20 +190,46 @@ void QCoreTextFontEngine::init()
bool QCoreTextFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, bool QCoreTextFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
int *nglyphs, QTextEngine::ShaperFlags flags) const int *nglyphs, QTextEngine::ShaperFlags flags) const
{ {
*nglyphs = len;
QCFType<CFStringRef> cfstring; QCFType<CFStringRef> cfstring;
QVarLengthArray<CGGlyph> cgGlyphs(len); QVarLengthArray<CGGlyph> cgGlyphs(len);
CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len); CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len);
for (int i = 0; i < len; ++i) int glyph_pos = 0;
if (cgGlyphs[i]) for (int i = 0; i < len; ++i) {
glyphs->glyphs[i] = cgGlyphs[i]; if (cgGlyphs[i]) {
glyphs->glyphs[glyph_pos] = cgGlyphs[i];
if (glyph_pos < i)
cgGlyphs[glyph_pos] = cgGlyphs[i];
}
glyph_pos++;
// If it's a non-BMP char, skip the lower part of surrogate pair and go
// directly to the next char without increasing glyph_pos
if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate())
++i;
}
*nglyphs = glyph_pos;
if (flags & QTextEngine::GlyphIndicesOnly) if (flags & QTextEngine::GlyphIndicesOnly)
return true; return true;
loadAdvancesForGlyphs(ctfont, cgGlyphs, glyphs, len, flags, fontDef); QVarLengthArray<CGSize> advances(glyph_pos);
CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, cgGlyphs.data(), advances.data(), glyph_pos);
for (int i = 0; i < glyph_pos; ++i) {
if (glyphs->glyphs[i] & 0xff000000)
continue;
glyphs->advances_x[i] = QFixed::fromReal(advances[i].width);
glyphs->advances_y[i] = QFixed::fromReal(advances[i].height);
}
if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
for (int i = 0; i < glyph_pos; ++i) {
glyphs->advances_x[i] = glyphs->advances_x[i].round();
glyphs->advances_y[i] = glyphs->advances_y[i].round();
}
}
return true; return true;
} }