summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJiang Jiang <jiang.jiang@nokia.com>2012-05-18 16:00:55 +0200
committerQt by Nokia <qt-info@nokia.com>2012-05-23 14:18:34 +0200
commitb4aa5d970d7701174b15f50f032138e96b427915 (patch)
tree2d9c18c77af437a7f2ee66a4dc4f9b3106a0514c /src
parent9149aebac96fb6134bf567b3266bf67d706893cf (diff)
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>
Diffstat (limited to 'src')
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm36
1 files changed, 31 insertions, 5 deletions
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 746cba6762..846b657bb4 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -190,20 +190,46 @@ void QCoreTextFontEngine::init()
bool QCoreTextFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
int *nglyphs, QTextEngine::ShaperFlags flags) const
{
- *nglyphs = len;
QCFType<CFStringRef> cfstring;
QVarLengthArray<CGGlyph> cgGlyphs(len);
CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len);
- for (int i = 0; i < len; ++i)
- if (cgGlyphs[i])
- glyphs->glyphs[i] = cgGlyphs[i];
+ int glyph_pos = 0;
+ for (int i = 0; i < len; ++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)
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;
}