diff options
author | David Boddie <david.boddie@nokia.com> | 2011-06-17 11:54:16 (GMT) |
---|---|---|
committer | David Boddie <david.boddie@nokia.com> | 2011-06-17 11:54:16 (GMT) |
commit | 2b39081bf101e53a70ff056d527dc3dfb8208bf0 (patch) | |
tree | a8e57489e18dbdd620b8880eda5c8e2d77049a07 /src/gui/text | |
parent | 5e1112ec04dcef671700e326186ca56b790f7e08 (diff) | |
parent | c390312f8fbea14ac4df0c5185ca814054f448d8 (diff) | |
download | Qt-2b39081bf101e53a70ff056d527dc3dfb8208bf0.zip Qt-2b39081bf101e53a70ff056d527dc3dfb8208bf0.tar.gz Qt-2b39081bf101e53a70ff056d527dc3dfb8208bf0.tar.bz2 |
Merge branch '4.8' of scm.dev.nokia.troll.no:qt/qt
Conflicts:
doc/src/declarative/righttoleft.qdoc
examples/draganddrop/fridgemagnets/main.cpp
examples/script/context2d/main.cpp
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/qfont.cpp | 50 | ||||
-rw-r--r-- | src/gui/text/qfont.h | 6 | ||||
-rw-r--r-- | src/gui/text/qfont_p.h | 1 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase.cpp | 4 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase_mac.cpp | 142 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase_x11.cpp | 63 | ||||
-rw-r--r-- | src/gui/text/qfontengine_coretext.mm | 42 | ||||
-rw-r--r-- | src/gui/text/qfontengine_coretext_p.h | 4 | ||||
-rw-r--r-- | src/gui/text/qfontengine_ft.cpp | 8 | ||||
-rw-r--r-- | src/gui/text/qfontengine_x11.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qfontinfo.h | 1 | ||||
-rw-r--r-- | src/gui/text/qglyphrun.cpp | 108 | ||||
-rw-r--r-- | src/gui/text/qglyphrun.h | 4 | ||||
-rw-r--r-- | src/gui/text/qglyphrun_p.h | 19 | ||||
-rw-r--r-- | src/gui/text/qrawfont.cpp | 13 | ||||
-rw-r--r-- | src/gui/text/qrawfont.h | 1 | ||||
-rw-r--r-- | src/gui/text/qrawfont_ft.cpp | 6 | ||||
-rw-r--r-- | src/gui/text/qtextdocument.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 71 | ||||
-rw-r--r-- | src/gui/text/qtextengine_p.h | 2 | ||||
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 38 | ||||
-rw-r--r-- | src/gui/text/qtextodfwriter.cpp | 1 |
22 files changed, 417 insertions, 171 deletions
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 90dd029..d4c81b9 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -348,6 +348,9 @@ void QFontPrivate::resolve(uint mask, const QFontPrivate *other) if (! (mask & QFont::FamilyResolved)) request.family = other->request.family; + if (! (mask & QFont::StyleNameResolved)) + request.styleName = other->request.styleName; + if (! (mask & QFont::SizeResolved)) { request.pointSize = other->request.pointSize; request.pixelSize = other->request.pixelSize; @@ -897,6 +900,38 @@ void QFont::setFamily(const QString &family) } /*! + \since 4.8 + + Returns the requested font style name, it will be used to match the + font with irregular styles (that can't be normalized in other style + properties). It depends on system font support, thus only works for + Mac OS X and X11 so far. On Windows irregular styles will be added + as separate font families so there is no need for this. + + \sa setFamily() setStyle() +*/ +QString QFont::styleName() const +{ + return d->request.styleName; +} + +/*! + \since 4.8 + + Sets the style name of the font. When set, other style properties + like \a style() and \a weight() will be ignored for font matching. + + \sa styleName() +*/ +void QFont::setStyleName(const QString &styleName) +{ + detach(); + + d->request.styleName = styleName; + resolve_mask |= QFont::StyleNameResolved; +} + +/*! Returns the point size of the font. Returns -1 if the font size was specified in pixels. @@ -2509,6 +2544,21 @@ QString QFontInfo::family() const } /*! + \since 4.8 + + Returns the style name of the matched window system font on + system that supports it. + + \sa QFont::styleName() +*/ +QString QFontInfo::styleName() const +{ + QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + return engine->fontDef.styleName; +} + +/*! Returns the point size of the matched window system font. \sa pointSizeF() QFont::pointSize() diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h index 7636ecf..14f290c 100644 --- a/src/gui/text/qfont.h +++ b/src/gui/text/qfont.h @@ -156,7 +156,8 @@ public: LetterSpacingResolved = 0x2000, WordSpacingResolved = 0x4000, HintingPreferenceResolved = 0x8000, - AllPropertiesResolved = 0xffff + StyleNameResolved = 0x10000, + AllPropertiesResolved = 0x1ffff }; QFont(); @@ -168,6 +169,9 @@ public: QString family() const; void setFamily(const QString &); + QString styleName() const; + void setStyleName(const QString &); + int pointSize() const; void setPointSize(int); qreal pointSizeF() const; diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h index d36518e..8eeae6f 100644 --- a/src/gui/text/qfont_p.h +++ b/src/gui/text/qfont_p.h @@ -80,6 +80,7 @@ struct QFontDef } QString family; + QString styleName; #ifdef Q_WS_X11 QString addStyle; diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 7a8a912..98186df 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -879,10 +879,10 @@ QStringList QFontDatabasePrivate::addTTFile(const QByteArray &file, const QByteA TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2); if (os2) { quint32 unicodeRange[4] = { - os2->ulUnicodeRange1, os2->ulUnicodeRange2, os2->ulUnicodeRange3, os2->ulUnicodeRange4 + static_cast<quint32>(os2->ulUnicodeRange1), static_cast<quint32>(os2->ulUnicodeRange2), static_cast<quint32>(os2->ulUnicodeRange3), static_cast<quint32>(os2->ulUnicodeRange4) }; quint32 codePageRange[2] = { - os2->ulCodePageRange1, os2->ulCodePageRange2 + static_cast<quint32>(os2->ulCodePageRange1), static_cast<quint32>(os2->ulCodePageRange2) }; writingSystems = qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange); diff --git a/src/gui/text/qfontdatabase_mac.cpp b/src/gui/text/qfontdatabase_mac.cpp index 6fdaf06..724dbf6 100644 --- a/src/gui/text/qfontdatabase_mac.cpp +++ b/src/gui/text/qfontdatabase_mac.cpp @@ -249,6 +249,63 @@ static inline float weightToFloat(unsigned int weight) return (weight - 50) / 100.0; } +static QFontEngine *loadFromDatabase(const QFontDef &req, const QFontPrivate *d) +{ +#if defined(QT_MAC_USE_COCOA) + QCFString fontName = NULL; +#else + ATSFontFamilyRef familyRef = 0; + ATSFontRef fontRef = 0; +#endif + + QStringList family_list = familyList(req); + + const char *stylehint = styleHint(req); + if (stylehint) + family_list << QLatin1String(stylehint); + + // add QFont::defaultFamily() to the list, for compatibility with previous versions + family_list << QApplication::font().defaultFamily(); + + QMutexLocker locker(fontDatabaseMutex()); + QFontDatabasePrivate *db = privateDb(); + if (!db->count) + initializeDb(); + for (int i = 0; i < family_list.size(); ++i) { + for (int k = 0; k < db->count; ++k) { + if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) { + QByteArray family_name = db->families[k]->name.toUtf8(); +#if defined(QT_MAC_USE_COCOA) + QCFType<CTFontRef> ctFont = CTFontCreateWithName(QCFString(db->families[k]->name), 12, NULL); + if (ctFont) { + fontName = CTFontCopyFullName(ctFont); + goto found; + } +#else + familyRef = ATSFontFamilyFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault); + if (familyRef) { + fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault); + goto found; + } +#endif + } + } + } +found: +#ifdef QT_MAC_USE_COCOA + if (fontName) + return new QCoreTextFontEngineMulti(fontName, req, d->kerning); +#else + if (familyRef) { + QCFString actualName; + if (ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr) + req.family = actualName; + return new QFontEngineMacMulti(familyRef, req, fontDef, d->kerning); + } +#endif + return NULL; +} + void QFontDatabase::load(const QFontPrivate *d, int script) { // sanity checks @@ -289,69 +346,38 @@ void QFontDatabase::load(const QFontPrivate *d, int script) return; // the font info and fontdef should already be filled } - //find the font - QStringList family_list = familyList(req); - - const char *stylehint = styleHint(req); - if (stylehint) - family_list << QLatin1String(stylehint); - - // add QFont::defaultFamily() to the list, for compatibility with - // previous versions - family_list << QApplication::font().defaultFamily(); - + QFontEngine *engine = NULL; #if defined(QT_MAC_USE_COCOA) - QCFString fontName = NULL, familyName = NULL; -#else - ATSFontFamilyRef familyRef = 0; - ATSFontRef fontRef = 0; -#endif - - QMutexLocker locker(fontDatabaseMutex()); - QFontDatabasePrivate *db = privateDb(); - if (!db->count) - initializeDb(); - for(int i = 0; i < family_list.size(); ++i) { - for (int k = 0; k < db->count; ++k) { - if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) { - QByteArray family_name = db->families[k]->name.toUtf8(); -#if defined(QT_MAC_USE_COCOA) - QCFType<CTFontRef> ctFont = CTFontCreateWithName(QCFString(db->families[k]->name), 12, NULL); - if (ctFont) { - fontName = CTFontCopyFullName(ctFont); - familyName = CTFontCopyFamilyName(ctFont); - goto FamilyFound; - } -#else - familyRef = ATSFontFamilyFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault); - if (familyRef) { - fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault); - goto FamilyFound; - } -#endif + // Shortcut to get the font directly without going through the font database + if (!req.family.isEmpty() && !req.styleName.isEmpty()) { + QCFString expectedFamily = QCFString(req.family); + QCFString expectedStyle = QCFString(req.styleName); + + QCFType<CFMutableDictionaryRef> attributes = CFDictionaryCreateMutable(NULL, 0, + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, expectedFamily); + CFDictionaryAddValue(attributes, kCTFontStyleNameAttribute, expectedStyle); + + QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithAttributes(attributes); + CGAffineTransform transform = qt_transform_from_fontdef(req); + QCFType<CTFontRef> ctFont = CTFontCreateWithFontDescriptor(descriptor, req.pixelSize, &transform); + if (ctFont) { + QCFString familyName = CTFontCopyFamilyName(ctFont); + // Only accept the font if the family name is exactly the same as we specified + if (CFEqual(expectedFamily, familyName)) { + engine = new QCoreTextFontEngineMulti(ctFont, req, d->kerning); } } } -FamilyFound: - //fill in the engine's font definition - QFontDef fontDef = d->request; //copy.. - if(fontDef.pointSize < 0) - fontDef.pointSize = qt_mac_pointsize(fontDef, d->dpi); - else - fontDef.pixelSize = qt_mac_pixelsize(fontDef, d->dpi); - -#ifdef QT_MAC_USE_COCOA - fontDef.family = familyName; - QFontEngine *engine = new QCoreTextFontEngineMulti(fontName, fontDef, d->kerning); -#else - QCFString actualName; - if (ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr) - fontDef.family = actualName; - QFontEngine *engine = new QFontEngineMacMulti(familyRef, fontRef, fontDef, d->kerning); #endif - d->engineData->engine = engine; - engine->ref.ref(); //a ref for the engineData->engine - QFontCache::instance()->insertEngine(key, engine); + if (!engine) + engine = loadFromDatabase(req, d); + + if (engine) { + d->engineData->engine = engine; + engine->ref.ref(); + QFontCache::instance()->insertEngine(key, engine); + } } static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp index 8a13d91..754334c 100644 --- a/src/gui/text/qfontdatabase_x11.cpp +++ b/src/gui/text/qfontdatabase_x11.cpp @@ -1452,6 +1452,35 @@ static const char *styleHint(const QFontDef &request) void qt_addPatternProps(FcPattern *pattern, int screen, int script, const QFontDef &request) { + double size_value = qMax(qreal(1.), request.pixelSize); + FcPatternDel(pattern, FC_PIXEL_SIZE); + FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size_value); + + if (X11->display && QX11Info::appDepth(screen) <= 8) { + FcPatternDel(pattern, FC_ANTIALIAS); + // can't do antialiasing on 8bpp + FcPatternAddBool(pattern, FC_ANTIALIAS, false); + } else if (request.styleStrategy & (QFont::PreferAntialias|QFont::NoAntialias)) { + FcPatternDel(pattern, FC_ANTIALIAS); + FcPatternAddBool(pattern, FC_ANTIALIAS, + !(request.styleStrategy & QFont::NoAntialias)); + } + + if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') { + Q_ASSERT(script < QUnicodeTables::ScriptCount); + FcLangSet *ls = FcLangSetCreate(); + FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]); + FcPatternDel(pattern, FC_LANG); + FcPatternAddLangSet(pattern, FC_LANG, ls); + FcLangSetDestroy(ls); + } + + if (!request.styleName.isEmpty()) { + QByteArray cs = request.styleName.toUtf8(); + FcPatternAddString(pattern, FC_STYLE, (const FcChar8 *) cs.constData()); + return; + } + int weight_value = FC_WEIGHT_BLACK; if (request.weight == 0) weight_value = FC_WEIGHT_MEDIUM; @@ -1474,34 +1503,11 @@ void qt_addPatternProps(FcPattern *pattern, int screen, int script, const QFontD FcPatternDel(pattern, FC_SLANT); FcPatternAddInteger(pattern, FC_SLANT, slant_value); - double size_value = qMax(qreal(1.), request.pixelSize); - FcPatternDel(pattern, FC_PIXEL_SIZE); - FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size_value); - int stretch = request.stretch; if (!stretch) stretch = 100; FcPatternDel(pattern, FC_WIDTH); FcPatternAddInteger(pattern, FC_WIDTH, stretch); - - if (X11->display && QX11Info::appDepth(screen) <= 8) { - FcPatternDel(pattern, FC_ANTIALIAS); - // can't do antialiasing on 8bpp - FcPatternAddBool(pattern, FC_ANTIALIAS, false); - } else if (request.styleStrategy & (QFont::PreferAntialias|QFont::NoAntialias)) { - FcPatternDel(pattern, FC_ANTIALIAS); - FcPatternAddBool(pattern, FC_ANTIALIAS, - !(request.styleStrategy & QFont::NoAntialias)); - } - - if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') { - Q_ASSERT(script < QUnicodeTables::ScriptCount); - FcLangSet *ls = FcLangSetCreate(); - FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]); - FcPatternDel(pattern, FC_LANG); - FcPatternAddLangSet(pattern, FC_LANG, ls); - FcLangSetDestroy(ls); - } } static bool preferScalable(const QFontDef &request) @@ -1996,6 +2002,11 @@ void QFontDatabase::load(const QFontPrivate *d, int script) QFontCache::instance()->insertEngine(key, fe); } +// Needed for fontconfig version < 2.2.97 +#ifndef FC_FAMILYLANG +#define FC_FAMILYLANG "familylang" +#endif + static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) { #if defined(QT_NO_FONTCONFIG) @@ -2044,7 +2055,8 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) return; FcPatternDel(pattern, FC_FILE); - FcPatternAddString(pattern, FC_FILE, (const FcChar8 *)fnt->fileName.toUtf8().constData()); + QByteArray cs = fnt->fileName.toUtf8(); + FcPatternAddString(pattern, FC_FILE, (const FcChar8 *) cs.constData()); FcChar8 *fam = 0, *familylang = 0; int i, n = 0; @@ -2130,7 +2142,8 @@ QString QFontDatabase::resolveFontFamilyAlias(const QString &family) if (!pattern) return family; - FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *) family.toUtf8().data()); + QByteArray cs = family.toUtf8(); + FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *) cs.constData()); FcConfigSubstitute(0, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm index 24bd750..64b8682 100644 --- a/src/gui/text/qfontengine_coretext.mm +++ b/src/gui/text/qfontengine_coretext.mm @@ -100,7 +100,12 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize); QCFType<CTFontRef> baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, &transform); - ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, &transform, symbolicTraits, symbolicTraits); + ctfont = NULL; + // There is a side effect in Core Text: if we apply 0 as symbolic traits to a font in normal weight, + // we will get the light version of that font (while the way supposed to work doesn't: + // setting kCTFontWeightTrait to some value between -1.0 to 0.0 has no effect on font selection) + if (fontDef.weight != QFont::Normal || symbolicTraits) + ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, &transform, symbolicTraits, symbolicTraits); // CTFontCreateCopyWithSymbolicTraits returns NULL if we ask for a trait that does // not exist for the given font. (for example italic) @@ -111,17 +116,11 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const init(kerning); } -QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(CGFontRef cgFontRef, const QFontDef &fontDef, bool kerning) +QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(CTFontRef ctFontRef, const QFontDef &fontDef, bool kerning) : QFontEngineMulti(0) { this->fontDef = fontDef; - - transform = CGAffineTransformIdentity; - if (fontDef.stretch != 100) { - transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1); - } - - ctfont = CTFontCreateWithGraphicsFont(cgFontRef, fontDef.pixelSize, &transform, NULL); + ctfont = (CTFontRef) CFRetain(ctFontRef); init(kerning); } @@ -144,6 +143,9 @@ void QCoreTextFontEngineMulti::init(bool kerning) } QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef); + fontDef.family = fe->fontDef.family; + fontDef.styleName = fe->fontDef.styleName; + transform = fe->transform; fe->ref.ref(); engines.append(fe); } @@ -400,7 +402,7 @@ void QCoreTextFontEngineMulti::loadEngine(int) extern int qt_antialiasing_threshold; // from qapplication.cpp -static inline CGAffineTransform transformFromFontDef(const QFontDef &fontDef) +CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef) { CGAffineTransform transform = CGAffineTransformIdentity; if (fontDef.stretch != 100) @@ -411,7 +413,7 @@ static inline CGAffineTransform transformFromFontDef(const QFontDef &fontDef) QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def) { fontDef = def; - transform = transformFromFontDef(fontDef); + transform = qt_transform_from_fontdef(fontDef); ctfont = font; CFRetain(ctfont); cgFont = CTFontCopyGraphicsFont(font, NULL); @@ -421,7 +423,7 @@ QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def) QCoreTextFontEngine::QCoreTextFontEngine(CGFontRef font, const QFontDef &def) { fontDef = def; - transform = transformFromFontDef(fontDef); + transform = qt_transform_from_fontdef(fontDef); cgFont = font; // Keep reference count balanced CFRetain(cgFont); @@ -459,6 +461,9 @@ void QCoreTextFontEngine::init() QCFString family = CTFontCopyFamilyName(ctfont); fontDef.family = family; + QCFString styleName = (CFStringRef) CTFontCopyAttribute(ctfont, kCTFontStyleNameAttribute); + fontDef.styleName = styleName; + synthesisFlags = 0; CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont); if (traits & kCTFontItalicTrait) @@ -725,10 +730,10 @@ void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *position } } -QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int /*margin*/, bool aa) +QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int margin, bool aa) { const glyph_metrics_t br = boundingBox(glyph); - QImage im(qRound(br.width)+2, qRound(br.height)+2, QImage::Format_RGB32); + QImage im(qRound(br.width) + margin * 2, qRound(br.height) + margin * 2, QImage::Format_RGB32); im.fill(0); CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); @@ -740,9 +745,8 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition 8, im.bytesPerLine(), colorspace, cgflags); CGContextSetFontSize(ctx, fontDef.pixelSize); - CGContextSetShouldAntialias(ctx, aa || - (fontDef.pointSize > qt_antialiasing_threshold - && !(fontDef.styleStrategy & QFont::NoAntialias))); + CGContextSetShouldAntialias(ctx, (aa || fontDef.pointSize > qt_antialiasing_threshold) + && !(fontDef.styleStrategy & QFont::NoAntialias)); CGContextSetShouldSmoothFonts(ctx, aa); CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0); @@ -760,8 +764,8 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition CGContextSetFont(ctx, cgFont); - qreal pos_x = -br.x.toReal() + subPixelPosition.toReal(); - qreal pos_y = im.height() + br.y.toReal() - 1; + qreal pos_x = -br.x.toReal() + subPixelPosition.toReal() + margin; + qreal pos_y = im.height() + br.y.toReal() - margin; CGContextSetTextPosition(ctx, pos_x, pos_y); CGSize advance; diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h index 98d3b50..3ca8a0a 100644 --- a/src/gui/text/qfontengine_coretext_p.h +++ b/src/gui/text/qfontengine_coretext_p.h @@ -113,7 +113,7 @@ class QCoreTextFontEngineMulti : public QFontEngineMulti { public: QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning); - QCoreTextFontEngineMulti(CGFontRef cgFontRef, const QFontDef &fontDef, bool kerning); + QCoreTextFontEngineMulti(CTFontRef ctFontRef, const QFontDef &fontDef, bool kerning); ~QCoreTextFontEngineMulti(); virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, @@ -141,6 +141,8 @@ private: friend class QFontDialogPrivate; }; +CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef); + #endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) #endif // QFONTENGINE_CORETEXT_P_H diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index f514942..9a5d9d6 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -758,6 +758,8 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format, } #endif + fontDef.styleName = QString::fromUtf8(face->style_name); + unlockFace(); fsType = freetype->fsType(); @@ -795,7 +797,7 @@ int QFontEngineFT::loadFlags(QGlyphSet *set, GlyphFormat format, int flags, if (set && set->outline_drawing) load_flags = FT_LOAD_NO_BITMAP; - if (default_hint_style == HintNone || (flags & HB_ShaperFlag_UseDesignMetrics)) + if (default_hint_style == HintNone || (flags & HB_ShaperFlag_UseDesignMetrics) || set->outline_drawing) load_flags |= FT_LOAD_NO_HINTING; else load_flags |= load_target; @@ -1751,7 +1753,6 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe } else { glyphSet = &defaultGlyphSet; } - bool needsDelete = false; Glyph * g = glyphSet->getGlyph(glyph); if (!g || g->format != format) { face = lockFace(); @@ -1759,7 +1760,6 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe FT_Matrix_Multiply(&glyphSet->transformationMatrix, &m); freetype->matrix = m; g = loadGlyph(glyphSet, glyph, subPixelPosition, format); - needsDelete = true; } if (g) { @@ -1768,8 +1768,6 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe overall.width = g->width; overall.height = g->height; overall.xoff = g->advance; - if (needsDelete) - delete g; } else { int left = FLOOR(face->glyph->metrics.horiBearingX); int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width); diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp index 0997048..e3bfa5d 100644 --- a/src/gui/text/qfontengine_x11.cpp +++ b/src/gui/text/qfontengine_x11.cpp @@ -1205,7 +1205,9 @@ QFontEngine *QFontEngineX11FT::cloneWithSize(qreal pixelSize) const delete fe; return 0; } else { +#ifndef QT_NO_XRENDER fe->xglyph_format = xglyph_format; +#endif return fe; } } diff --git a/src/gui/text/qfontinfo.h b/src/gui/text/qfontinfo.h index 1238cba..37a724e 100644 --- a/src/gui/text/qfontinfo.h +++ b/src/gui/text/qfontinfo.h @@ -61,6 +61,7 @@ public: QFontInfo &operator=(const QFontInfo &); QString family() const; + QString styleName() const; int pixelSize() const; int pointSize() const; qreal pointSizeF() const; diff --git a/src/gui/text/qglyphrun.cpp b/src/gui/text/qglyphrun.cpp index 05e3b6b..2865d91 100644 --- a/src/gui/text/qglyphrun.cpp +++ b/src/gui/text/qglyphrun.cpp @@ -132,13 +132,27 @@ QGlyphRun &QGlyphRun::operator=(const QGlyphRun &other) */ bool QGlyphRun::operator==(const QGlyphRun &other) const { - return ((d == other.d) - || (d->glyphIndexes == other.d->glyphIndexes - && d->glyphPositions == other.d->glyphPositions - && d->overline == other.d->overline - && d->underline == other.d->underline - && d->strikeOut == other.d->strikeOut - && d->rawFont == other.d->rawFont)); + if (d == other.d) + return true; + + if ((d->glyphIndexDataSize != other.d->glyphIndexDataSize) + || (d->glyphPositionDataSize != other.d->glyphPositionDataSize)) { + return false; + } + + for (int i=0; i<qMax(d->glyphIndexDataSize, d->glyphPositionDataSize); ++i) { + if (i < d->glyphIndexDataSize && d->glyphIndexData[i] != other.d->glyphIndexData[i]) + return false; + + if (i < d->glyphPositionDataSize && d->glyphPositionData[i] != other.d->glyphPositionData[i]) + return false; + } + + + return (d->overline == other.d->overline + && d->underline == other.d->underline + && d->strikeOut == other.d->strikeOut + && d->rawFont == other.d->rawFont); } /*! @@ -151,36 +165,6 @@ bool QGlyphRun::operator!=(const QGlyphRun &other) const } /*! - \internal - - Adds together the lists of glyph indexes and positions in \a other and this QGlyphRun - object and returns the result. The font in the returned QGlyphRun will be the same as in - this QGlyphRun object. -*/ -QGlyphRun QGlyphRun::operator+(const QGlyphRun &other) const -{ - QGlyphRun ret(*this); - ret += other; - return ret; -} - -/*! - \internal - - Appends the glyph indexes and positions in \a other to this QGlyphRun object and returns - a reference to the current object. -*/ -QGlyphRun &QGlyphRun::operator+=(const QGlyphRun &other) -{ - detach(); - - d->glyphIndexes += other.d->glyphIndexes; - d->glyphPositions += other.d->glyphPositions; - - return *this; -} - -/*! Returns the font selected for this QGlyphRun object. \sa setRawFont() @@ -208,7 +192,13 @@ void QGlyphRun::setRawFont(const QRawFont &rawFont) */ QVector<quint32> QGlyphRun::glyphIndexes() const { - return d->glyphIndexes; + if (d->glyphIndexes.constData() == d->glyphIndexData) { + return d->glyphIndexes; + } else { + QVector<quint32> indexes(d->glyphIndexDataSize); + qMemCopy(indexes.data(), d->glyphIndexData, d->glyphIndexDataSize * sizeof(quint32)); + return indexes; + } } /*! @@ -218,7 +208,9 @@ QVector<quint32> QGlyphRun::glyphIndexes() const void QGlyphRun::setGlyphIndexes(const QVector<quint32> &glyphIndexes) { detach(); - d->glyphIndexes = glyphIndexes; + d->glyphIndexes = glyphIndexes; // Keep a reference to the QVector to avoid copying + d->glyphIndexData = glyphIndexes.constData(); + d->glyphIndexDataSize = glyphIndexes.size(); } /*! @@ -226,7 +218,14 @@ void QGlyphRun::setGlyphIndexes(const QVector<quint32> &glyphIndexes) */ QVector<QPointF> QGlyphRun::positions() const { - return d->glyphPositions; + if (d->glyphPositions.constData() == d->glyphPositionData) { + return d->glyphPositions; + } else { + QVector<QPointF> glyphPositions(d->glyphPositionDataSize); + qMemCopy(glyphPositions.data(), d->glyphPositionData, + d->glyphPositionDataSize * sizeof(QPointF)); + return glyphPositions; + } } /*! @@ -236,7 +235,9 @@ QVector<QPointF> QGlyphRun::positions() const void QGlyphRun::setPositions(const QVector<QPointF> &positions) { detach(); - d->glyphPositions = positions; + d->glyphPositions = positions; // Keep a reference to the vector to avoid copying + d->glyphPositionData = positions.constData(); + d->glyphPositionDataSize = positions.size(); } /*! @@ -245,12 +246,33 @@ void QGlyphRun::setPositions(const QVector<QPointF> &positions) void QGlyphRun::clear() { detach(); - d->glyphPositions = QVector<QPointF>(); - d->glyphIndexes = QVector<quint32>(); d->rawFont = QRawFont(); d->strikeOut = false; d->overline = false; d->underline = false; + + setPositions(QVector<QPointF>()); + setGlyphIndexes(QVector<quint32>()); +} + +/*! + Sets the glyph indexes and positions of this QGlyphRun to use the first \a size + elements in the arrays \a glyphIndexArray and \a glyphPositionArray. The data is + \e not copied. The caller must guarantee that the arrays are not deleted as long + as this QGlyphRun and any copies of it exists. + + \sa setGlyphIndexes(), setPositions() +*/ +void QGlyphRun::setRawData(const quint32 *glyphIndexArray, const QPointF *glyphPositionArray, + int size) +{ + detach(); + d->glyphIndexes.clear(); + d->glyphPositions.clear(); + + d->glyphIndexData = glyphIndexArray; + d->glyphPositionData = glyphPositionArray; + d->glyphIndexDataSize = d->glyphPositionDataSize = size; } /*! diff --git a/src/gui/text/qglyphrun.h b/src/gui/text/qglyphrun.h index e43f1ef..cf407a8 100644 --- a/src/gui/text/qglyphrun.h +++ b/src/gui/text/qglyphrun.h @@ -66,6 +66,10 @@ public: QRawFont rawFont() const; void setRawFont(const QRawFont &rawFont); + void setRawData(const quint32 *glyphIndexArray, + const QPointF *glyphPositionArray, + int size); + QVector<quint32> glyphIndexes() const; void setGlyphIndexes(const QVector<quint32> &glyphIndexes); diff --git a/src/gui/text/qglyphrun_p.h b/src/gui/text/qglyphrun_p.h index 533679d..a7745e6 100644 --- a/src/gui/text/qglyphrun_p.h +++ b/src/gui/text/qglyphrun_p.h @@ -71,6 +71,10 @@ public: : overline(false) , underline(false) , strikeOut(false) + , glyphIndexData(glyphIndexes.constData()) + , glyphIndexDataSize(0) + , glyphPositionData(glyphPositions.constData()) + , glyphPositionDataSize(0) { } @@ -82,6 +86,10 @@ public: , overline(other.overline) , underline(other.underline) , strikeOut(other.strikeOut) + , glyphIndexData(other.glyphIndexData) + , glyphIndexDataSize(other.glyphIndexDataSize) + , glyphPositionData(other.glyphPositionData) + , glyphPositionDataSize(other.glyphPositionDataSize) { } @@ -92,6 +100,17 @@ public: uint overline : 1; uint underline : 1; uint strikeOut : 1; + + const quint32 *glyphIndexData; + int glyphIndexDataSize; + + const QPointF *glyphPositionData; + int glyphPositionDataSize; + + static QGlyphRunPrivate *get(const QGlyphRun &glyphRun) + { + return glyphRun.d.data(); + } }; QT_END_NAMESPACE diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 3f8f225..ec5cc18 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -404,6 +404,19 @@ QString QRawFont::familyName() const } /*! + Returns the style name of this QRawFont. + + \sa QFont::styleName() +*/ +QString QRawFont::styleName() const +{ + if (!isValid()) + return QString(); + + return d->fontEngine->fontDef.styleName; +} + +/*! Returns the style of this QRawFont. \sa QFont::style() diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h index da56d3d..99e0837 100644 --- a/src/gui/text/qrawfont.h +++ b/src/gui/text/qrawfont.h @@ -84,6 +84,7 @@ public: bool operator==(const QRawFont &other) const; QString familyName() const; + QString styleName() const; QFont::Style style() const; int weight() const; diff --git a/src/gui/text/qrawfont_ft.cpp b/src/gui/text/qrawfont_ft.cpp index e8c10a5..db60459 100644 --- a/src/gui/text/qrawfont_ft.cpp +++ b/src/gui/text/qrawfont_ft.cpp @@ -46,7 +46,7 @@ #include "qrawfont_p.h" #include "qfontengine_ft_p.h" -#if defined(Q_WS_X11) +#if defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG) # include "qfontengine_x11_p.h" #endif @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE class QFontEngineFTRawFont -#if defined(Q_WS_X11) +#if defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG) : public QFontEngineX11FT #else : public QFontEngineFT @@ -63,7 +63,7 @@ class QFontEngineFTRawFont { public: QFontEngineFTRawFont(const QFontDef &fontDef) -#if defined(Q_WS_X11) +#if defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG) : QFontEngineX11FT(fontDef) #else : QFontEngineFT(fontDef) diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index cfe4aee..41b6fe2 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -2553,7 +2553,7 @@ void QTextHtmlExporter::emitBlockAttributes(const QTextBlock &block) const bool emptyBlock = block.begin().atEnd(); if (emptyBlock) { - html += QLatin1String("-qt-paragraph-type:empty;"); + html += QLatin1String("-qt-paragraph-type:empty; height:1em;"); } emitMargins(QString::number(format.topMargin()), diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index b43c8f4..e8e6c98 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -856,7 +856,7 @@ void QTextEngine::shapeLine(const QScriptLine &line) } } -#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC) +#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC) && defined(Q_WS_MAC) static bool enableHarfBuzz() { static enum { Yes, No, Unknown } status = Unknown; @@ -2825,6 +2825,75 @@ QFixed QTextEngine::offsetInLigature(const QScriptItem *si, int pos, int max, in return 0; } +// Scan in logClusters[from..to-1] for glyph_pos +int QTextEngine::getClusterLength(unsigned short *logClusters, + const HB_CharAttributes *attributes, + int from, int to, int glyph_pos, int *start) +{ + int clusterLength = 0; + for (int i = from; i < to; i++) { + if (logClusters[i] == glyph_pos && attributes[i].charStop) { + if (*start < 0) + *start = i; + clusterLength++; + } + else if (clusterLength) + break; + } + return clusterLength; +} + +int QTextEngine::positionInLigature(const QScriptItem *si, int end, + QFixed x, QFixed edge, int glyph_pos, + bool cursorOnCharacter) +{ + unsigned short *logClusters = this->logClusters(si); + int clusterStart = -1; + int clusterLength = 0; + + if (si->analysis.script != QUnicodeTables::Common && + si->analysis.script != QUnicodeTables::Greek) { + if (glyph_pos == -1) + return si->position + end; + else { + int i; + for (i = 0; i < end; i++) + if (logClusters[i] == glyph_pos) + break; + return si->position + i; + } + } + + if (glyph_pos == -1 && end > 0) + glyph_pos = logClusters[end - 1]; + else { + if (x <= edge) + glyph_pos--; + } + + const HB_CharAttributes *attrs = attributes(); + clusterLength = getClusterLength(logClusters, attrs, 0, end, glyph_pos, &clusterStart); + + if (clusterLength) { + const QGlyphLayout &glyphs = shapedGlyphs(si); + QFixed glyphWidth = glyphs.effectiveAdvance(glyph_pos); + // the approximate width of each individual element of the ligature + QFixed perItemWidth = glyphWidth / clusterLength; + QFixed left = x > edge ? edge : edge - glyphWidth; + int n = ((x - left) / perItemWidth).floor().toInt(); + QFixed dist = x - left - n * perItemWidth; + int closestItem = dist > (perItemWidth / 2) ? n + 1 : n; + if (cursorOnCharacter && closestItem > 0) + closestItem--; + int pos = si->position + clusterStart + closestItem; + // Jump to the next charStop + while (!attrs[pos].charStop && pos < end) + pos++; + return pos; + } + return si->position + end; +} + int QTextEngine::previousLogicalPosition(int oldPos) const { const HB_CharAttributes *attrs = attributes(); diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index ed24d59..055974a 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -620,6 +620,7 @@ public: QFixed leadingSpaceWidth(const QScriptLine &line); QFixed offsetInLigature(const QScriptItem *si, int pos, int max, int glyph_pos); + int positionInLigature(const QScriptItem *si, int end, QFixed x, QFixed edge, int glyph_pos, bool cursorOnCharacter); int previousLogicalPosition(int oldPos) const; int nextLogicalPosition(int oldPos) const; int lineNumberForTextPosition(int pos); @@ -642,6 +643,7 @@ private: void resolveAdditionalFormats() const; int endOfLine(int lineNum); int beginningOfLine(int lineNum); + int getClusterLength(unsigned short *logClusters, const HB_CharAttributes *attributes, int from, int to, int glyph_pos, int *start); }; class QStackTextEngine : public QTextEngine { diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 8e12aad..c1bc846 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2233,10 +2233,20 @@ QList<QGlyphRun> QTextLine::glyphs(int from, int length) const glyphIndexes.setRawFont(font); QPair<QFontEngine *, int> key(fontEngine, int(flags)); - if (!glyphsHash.contains(key)) + if (!glyphsHash.contains(key)) { glyphsHash.insert(key, glyphIndexes); - else - glyphsHash[key] += glyphIndexes; + } else { + QGlyphRun &glyphRun = glyphsHash[key]; + + QVector<quint32> indexes = glyphRun.glyphIndexes(); + QVector<QPointF> positions = glyphRun.positions(); + + indexes += glyphIndexes.glyphIndexes(); + positions += glyphIndexes.positions(); + + glyphRun.setGlyphIndexes(indexes); + glyphRun.setPositions(positions); + } } } @@ -2559,8 +2569,8 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const } else { bool rtl = eng->isRightToLeft(); bool visual = eng->visualCursorMovement(); + int end = qMin(lineEnd, si->position + l) - si->position; if (reverse) { - int end = qMin(lineEnd, si->position + l) - si->position; int glyph_end = end == l ? si->num_glyphs : logClusters[end]; int glyph_start = glyph_pos; if (visual && !rtl && !(lastLine && itm == (visualOrder[nItems - 1] + firstItem))) @@ -2576,7 +2586,7 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const for (int i = glyph_start; i <= glyph_end; i++) x += glyphs.effectiveAdvance(i); } - x += eng->offsetInLigature(si, pos, line.length, glyph_pos); + x += eng->offsetInLigature(si, pos, end, glyph_pos); } *cursorPos = pos + si->position; @@ -2691,6 +2701,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const } int glyph_pos = -1; + QFixed edge; // has to be inside run if (cpos == QTextLine::CursorOnCharacter) { if (si.analysis.bidiLevel % 2) { @@ -2701,6 +2712,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const if (pos < x) break; glyph_pos = gs; + edge = pos; break; } pos -= glyphs.effectiveAdvance(gs); @@ -2713,6 +2725,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const if (pos > x) break; glyph_pos = gs; + edge = pos; } pos += glyphs.effectiveAdvance(gs); ++gs; @@ -2726,6 +2739,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const while (gs <= ge) { if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) { glyph_pos = gs; + edge = pos; dist = qAbs(x-pos); } pos -= glyphs.effectiveAdvance(gs); @@ -2735,6 +2749,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const while (ge >= gs) { if (glyphs.attributes[ge].clusterStart && qAbs(x-pos) < dist) { glyph_pos = ge; + edge = pos; dist = qAbs(x-pos); } pos += glyphs.effectiveAdvance(ge); @@ -2746,6 +2761,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const while (gs <= ge) { if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) { glyph_pos = gs; + edge = pos; dist = qAbs(x-pos); } pos += glyphs.effectiveAdvance(gs); @@ -2757,6 +2773,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const pos += glyphs.effectiveAdvance(gs); if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) { glyph_pos = gs; + edge = pos; dist = qAbs(x-pos); } ++gs; @@ -2773,16 +2790,13 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const if (rtl && nchars > 0) return insertionPoints[lastLine ? nchars : nchars - 1]; } - return si.position + end; + return eng->positionInLigature(&si, end, x, pos, -1, + cpos == QTextLine::CursorOnCharacter); } } Q_ASSERT(glyph_pos != -1); - int j; - for (j = 0; j < eng->length(item); ++j) - if (logClusters[j] == glyph_pos) - break; -// qDebug("at pos %d (in run: %d)", si.position + j, j); - return si.position + j; + return eng->positionInLigature(&si, end, x, edge, glyph_pos, + cpos == QTextLine::CursorOnCharacter); } } // right of last item diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp index 1619c9c..2addc0f 100644 --- a/src/gui/text/qtextodfwriter.cpp +++ b/src/gui/text/qtextodfwriter.cpp @@ -591,6 +591,7 @@ void QTextOdfWriter::writeCharacterFormat(QXmlStreamWriter &writer, QTextCharFor QString value; switch (format.verticalAlignment()) { case QTextCharFormat::AlignMiddle: + case QTextCharFormat::AlignBaseline: case QTextCharFormat::AlignNormal: value = QString::fromLatin1("0%"); break; case QTextCharFormat::AlignSuperScript: value = QString::fromLatin1("super"); break; case QTextCharFormat::AlignSubScript: value = QString::fromLatin1("sub"); break; |