diff options
Diffstat (limited to 'src/platformsupport/fontdatabases')
4 files changed, 71 insertions, 68 deletions
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 76506d12e9..afee68ebed 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -93,6 +93,7 @@ static const char *languageForWritingSystem[] = { }; enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) }; +#ifdef Q_OS_OSX static NSInteger languageMapSort(id obj1, id obj2, void *context) { NSArray *map1 = (NSArray *) obj1; @@ -104,6 +105,7 @@ static NSInteger languageMapSort(id obj1, id obj2, void *context) return [languages indexOfObject: lang1] - [languages indexOfObject: lang2]; } +#endif QCoreTextFontDatabase::QCoreTextFontDatabase() { @@ -202,8 +204,8 @@ void QCoreTextFontDatabase::populateFontDatabase() void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font) { QString foundryName = QStringLiteral("CoreText"); - QCFString familyName = (CFStringRef) CTFontDescriptorCopyLocalizedAttribute(font, kCTFontFamilyNameAttribute, NULL); - QCFString styleName = (CFStringRef)CTFontDescriptorCopyLocalizedAttribute(font, kCTFontStyleNameAttribute, NULL); + QCFString familyName = (CFStringRef) CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute); + QCFString styleName = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontStyleNameAttribute); QCFType<CFDictionaryRef> styles = (CFDictionaryRef) CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute); QFont::Weight weight = QFont::Normal; QFont::Style style = QFont::StyleNormal; @@ -265,12 +267,6 @@ void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font) QPlatformFontDatabase::registerFont(familyName, styleName, foundryName, weight, style, stretch, true /* antialiased */, true /* scalable */, pixelSize, fixedPitch, writingSystems, (void *) font); - - // We need to map back and forth between PostScript-names and family-names for fallback list construction - CFStringRef psName = (CFStringRef) CTFontDescriptorCopyAttribute(font, kCTFontNameAttribute); - psNameToFamily[QCFString::toQString((NSString *) psName)] = familyName; - familyNameToPsName[familyName] = QCFString::toQString((NSString *) psName); - CFRelease(psName); } void QCoreTextFontDatabase::releaseHandle(void *handle) @@ -350,26 +346,18 @@ QFont::StyleHint styleHintFromNSString(NSString *style) return QFont::AnyStyle; } -static QString familyNameFromPostScriptName(QHash<QString, QString> &psNameToFamily, - NSString *psName) +#ifdef Q_OS_OSX +static QString familyNameFromPostScriptName(NSString *psName) { - QString name = QCFString::toQString(psName); - if (psNameToFamily.contains(name)) - return psNameToFamily[name]; - else { - // Some of the font name in DefaultFontFallbacks.plist are hidden fonts like AquaHiraKaku, - // their family name begins with a dot, like ".AquaHiraKaku" or ".Apple Symbols Fallback", - // the only way (I've found) to get it are actually creating a CTFont with them. We only - // need to do it once though. - QCFType<CTFontRef> font = CTFontCreateWithName((CFStringRef) psName, 12.0, NULL); - if (font) { - QCFString family = CTFontCopyFamilyName(font); - psNameToFamily[name] = family; - return family; - } - return name; - } + QCFType<CTFontDescriptorRef> fontDescriptor = (CTFontDescriptorRef) CTFontDescriptorCreateWithNameAndSize((CFStringRef)psName, 12.0); + QCFString familyName = (CFStringRef) CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontFamilyNameAttribute); + QString name = QCFString::toQString(familyName); + if (name.isEmpty()) + qWarning() << "QCoreTextFontDatabase: Failed to resolve family name for PostScript name " << QCFString::toQString((CFStringRef)psName); + + return name; } +#endif QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const { @@ -389,29 +377,29 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo if (fallbackLists.contains(family)) return fallbackLists.value(family); - if (!familyNameToPsName.contains(family)) - const_cast<QCoreTextFontDatabase*>(this)->populateFontDatabase(); - - QCFType<CTFontRef> font = CTFontCreateWithName(QCFString(familyNameToPsName[family]), 12.0, NULL); - if (font) { - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - NSArray *languages = [defaults stringArrayForKey: @"AppleLanguages"]; - - QCFType<CFArrayRef> cascadeList = (CFArrayRef) CTFontCopyDefaultCascadeListForLanguages(font, (CFArrayRef) languages); - if (cascadeList) { - QStringList fallbackList; - const int numCascades = CFArrayGetCount(cascadeList); - for (int i = 0; i < numCascades; ++i) { - CTFontDescriptorRef fontFallback = (CTFontDescriptorRef) CFArrayGetValueAtIndex(cascadeList, i); - QCFString fallbackFamilyName = (CFStringRef) CTFontDescriptorCopyLocalizedAttribute(fontFallback, kCTFontFamilyNameAttribute, NULL); - fallbackList.append(QCFString::toQString(fallbackFamilyName)); + QCFType<CFMutableDictionaryRef> attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, QCFString(family)); + if (QCFType<CTFontDescriptorRef> fontDescriptor = CTFontDescriptorCreateWithAttributes(attributes)) { + if (QCFType<CTFontRef> font = CTFontCreateWithFontDescriptor(fontDescriptor, 12.0, 0)) { + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + NSArray *languages = [defaults stringArrayForKey: @"AppleLanguages"]; + + QCFType<CFArrayRef> cascadeList = (CFArrayRef) CTFontCopyDefaultCascadeListForLanguages(font, (CFArrayRef) languages); + if (cascadeList) { + QStringList fallbackList; + const int numCascades = CFArrayGetCount(cascadeList); + for (int i = 0; i < numCascades; ++i) { + CTFontDescriptorRef fontFallback = (CTFontDescriptorRef) CFArrayGetValueAtIndex(cascadeList, i); + QCFString fallbackFamilyName = (CFStringRef) CTFontDescriptorCopyAttribute(fontFallback, kCTFontFamilyNameAttribute); + fallbackList.append(QCFString::toQString(fallbackFamilyName)); + } + fallbackLists[family] = fallbackList; } - fallbackLists[family] = fallbackList; } - } - if (fallbackLists.contains(family)) - return fallbackLists.value(family); + if (fallbackLists.contains(family)) + return fallbackLists.value(family); + } } #endif } @@ -424,9 +412,6 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo static bool didPopulateStyleFallbacks = false; if (!didPopulateStyleFallbacks) { #if defined(Q_OS_MACX) - // Ensure we have the psNameToFamily mapping set up - const_cast<QCoreTextFontDatabase*>(this)->populateFontDatabase(); - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSArray *languages = [defaults stringArrayForKey: @"AppleLanguages"]; @@ -442,10 +427,10 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo NSArray *langs = [(NSArray *) item sortedArrayUsingFunction: languageMapSort context: languages]; for (NSArray *map in langs) - fallbackList.append(familyNameFromPostScriptName(psNameToFamily, [map objectAtIndex: 1])); + fallbackList.append(familyNameFromPostScriptName([map objectAtIndex: 1])); } else if ([item isKindOfClass: [NSString class]]) - fallbackList.append(familyNameFromPostScriptName(psNameToFamily, item)); + fallbackList.append(familyNameFromPostScriptName(item)); } if (QCoreTextFontEngine::supportsColorGlyphs()) @@ -579,7 +564,7 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData for (int i = 0; i < numFonts; ++i) { CTFontDescriptorRef fontDescriptor = CTFontDescriptorRef(CFArrayGetValueAtIndex(fonts, i)); populateFromDescriptor(fontDescriptor); - QCFType<CFStringRef> familyName = CFStringRef(CTFontDescriptorCopyLocalizedAttribute(fontDescriptor, kCTFontFamilyNameAttribute, NULL)); + QCFType<CFStringRef> familyName = CFStringRef(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontFamilyNameAttribute)); families.append(QCFString(familyName)); } } diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h index 1560d36644..c6fc791503 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h @@ -72,6 +72,7 @@ public: QCoreTextFontDatabase(); ~QCoreTextFontDatabase(); void populateFontDatabase(); + QFontEngine *fontEngine(const QFontDef &fontDef, void *handle); QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const; @@ -84,8 +85,6 @@ private: void populateFromDescriptor(CTFontDescriptorRef font); mutable QString defaultFontName; - mutable QHash<QString, QString> psNameToFamily; - mutable QHash<QString, QString> familyNameToPsName; void removeApplicationFonts(); diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 4fe78cb568..3c30df6efb 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -85,6 +85,7 @@ CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef) } QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def) + : QFontEngine(Mac) { fontDef = def; transform = qt_transform_from_fontdef(fontDef); @@ -95,6 +96,7 @@ QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def) } QCoreTextFontEngine::QCoreTextFontEngine(CGFontRef font, const QFontDef &def) + : QFontEngine(Mac) { fontDef = def; transform = qt_transform_from_fontdef(fontDef); @@ -192,10 +194,33 @@ void QCoreTextFontEngine::init() setUserData(QVariant::fromValue((void *)cgFont)); } +glyph_t QCoreTextFontEngine::glyphIndex(uint ucs4) const +{ + int len = 0; + + QChar str[2]; + if (Q_UNLIKELY(QChar::requiresSurrogates(ucs4))) { + str[len++] = QChar(QChar::highSurrogate(ucs4)); + str[len++] = QChar(QChar::lowSurrogate(ucs4)); + } else { + str[len++] = QChar(ucs4); + } + + CGGlyph glyphIndices[2]; + + CTFontGetGlyphsForCharacters(ctfont, (const UniChar *)str, glyphIndices, len); + + return glyphIndices[0]; +} + bool QCoreTextFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QFontEngine::ShaperFlags flags) const { - QCFType<CFStringRef> cfstring; + Q_ASSERT(glyphs->numGlyphs >= *nglyphs); + if (*nglyphs < len) { + *nglyphs = len; + return false; + } QVarLengthArray<CGGlyph> cgGlyphs(len); CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len); @@ -650,7 +675,7 @@ QFontEngine::FaceId QCoreTextFontEngine::faceId() const return QFontEngine::FaceId(); } -bool QCoreTextFontEngine::canRender(const QChar *string, int len) +bool QCoreTextFontEngine::canRender(const QChar *string, int len) const { QVarLengthArray<CGGlyph> cgGlyphs(len); return CTFontGetGlyphsForCharacters(ctfont, (const UniChar *) string, cgGlyphs.data(), len); @@ -659,16 +684,13 @@ bool QCoreTextFontEngine::canRender(const QChar *string, int len) bool QCoreTextFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const { QCFType<CFDataRef> table = CTFontCopyTable(ctfont, tag, 0); - if (!table || !length) + if (!table) return false; CFIndex tableLength = CFDataGetLength(table); - int availableLength = *length; - *length = tableLength; - if (buffer) { - if (tableLength > availableLength) - return false; + if (buffer && int(*length) >= tableLength) CFDataGetBytes(table, CFRangeMake(0, tableLength), buffer); - } + *length = tableLength; + Q_ASSERT(int(*length) > 0); return true; } diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h index 1cdac820b6..b9593b983e 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h @@ -62,6 +62,7 @@ public: QCoreTextFontEngine(CGFontRef font, const QFontDef &def); ~QCoreTextFontEngine(); + virtual glyph_t glyphIndex(uint ucs4) const; virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const; virtual void recalcAdvances(QGlyphLayout *, ShaperFlags) const; @@ -78,15 +79,11 @@ public: virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, QPainterPath *path, QTextItem::RenderFlags); - virtual const char *name() const { return "QCoreTextFontEngine"; } - - virtual bool canRender(const QChar *string, int len); + virtual bool canRender(const QChar *string, int len) const; virtual int synthesized() const { return synthesisFlags; } virtual bool supportsSubPixelPositions() const { return true; } - virtual Type type() const { return QFontEngine::Mac; } - void draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight); virtual FaceId faceId() const; |