summaryrefslogtreecommitdiffstats
path: root/src/platformsupport/fontdatabases
diff options
context:
space:
mode:
Diffstat (limited to 'src/platformsupport/fontdatabases')
-rw-r--r--src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp11
-rw-r--r--src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h4
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp144
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h6
-rw-r--r--src/platformsupport/fontdatabases/mac/coretext.pri8
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm211
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h7
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm90
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h12
9 files changed, 319 insertions, 174 deletions
diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
index a74516214b..f17eff4dd7 100644
--- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
+++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
@@ -217,8 +217,8 @@ QSupportedWritingSystems QBasicFontDatabase::determineWritingSystemsFromTrueType
static inline bool scriptRequiresOpenType(int script)
{
- return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
- || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
+ return ((script >= QChar::Script_Syriac && script <= QChar::Script_Sinhala)
+ || script == QChar::Script_Khmer || script == QChar::Script_Nko);
}
void QBasicFontDatabase::populateFontDatabase()
@@ -242,7 +242,7 @@ void QBasicFontDatabase::populateFontDatabase()
}
}
-QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *usrPtr)
+QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, QChar::Script script, void *usrPtr)
{
QFontEngineFT *engine;
FontFile *fontfile = static_cast<FontFile *> (usrPtr);
@@ -262,8 +262,7 @@ QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTab
delete engine;
engine = 0;
} else if (scriptRequiresOpenType(script)) {
- HB_Face hbFace = engine->initializedHarfbuzzFace();
- if (!hbFace || !hbFace->supported_scripts[script]) {
+ if (!engine->supportsScript(script)) {
delete engine;
engine = 0;
}
@@ -337,7 +336,7 @@ QFontEngine *QBasicFontDatabase::fontEngine(const QByteArray &fontData, qreal pi
return fe;
}
-QStringList QBasicFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
+QStringList QBasicFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
{
Q_UNUSED(family);
Q_UNUSED(style);
diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h
index 23f60fc611..8bb574f335 100644
--- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h
@@ -58,9 +58,9 @@ class QBasicFontDatabase : public QPlatformFontDatabase
{
public:
void populateFontDatabase();
- QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle);
+ QFontEngine *fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle);
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
- QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const;
+ QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
void releaseHandle(void *handle);
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index 84eb6613a3..329268395e 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -75,10 +75,11 @@ static inline bool requiresOpenType(int writingSystem)
return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
|| writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
}
+
static inline bool scriptRequiresOpenType(int script)
{
- return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
- || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
+ return ((script >= QChar::Script_Syriac && script <= QChar::Script_Sinhala)
+ || script == QChar::Script_Khmer || script == QChar::Script_Nko);
}
static int getFCWeight(int fc_weight)
@@ -97,14 +98,17 @@ static int getFCWeight(int fc_weight)
}
static const char *specialLanguages[] = {
- "en", // Common
+ "", // Unknown
+ "", // Inherited
+ "", // Common
+ "en", // Latin
"el", // Greek
"ru", // Cyrillic
"hy", // Armenian
"he", // Hebrew
"ar", // Arabic
"syr", // Syriac
- "div", // Thaana
+ "dv", // Thaana
"hi", // Devanagari
"bn", // Bengali
"pa", // Gurmukhi
@@ -121,45 +125,85 @@ static const char *specialLanguages[] = {
"my", // Myanmar
"ka", // Georgian
"ko", // Hangul
- "", // Ogham
- "", // Runic
+ "am", // Ethiopic
+ "chr", // Cherokee
+ "cr", // CanadianAboriginal
+ "sga", // Ogham
+ "non", // Runic
"km", // Khmer
- "" // N'Ko
+ "mn", // Mongolian
+ "ja", // Hiragana
+ "ja", // Katakana
+ "zh", // Bopomofo
+ "zh", // Han
+ "ii", // Yi
+ "ett", // OldItalic
+ "got", // Gothic
+ "en", // Deseret
+ "fil", // Tagalog
+ "hnn", // Hanunoo
+ "bku", // Buhid
+ "tbw", // Tagbanwa
+ "cop", // Coptic
+ "lif", // Limbu
+ "tdd", // TaiLe
+ "grc", // LinearB
+ "uga", // Ugaritic
+ "en", // Shavian
+ "so", // Osmanya
+ "grc", // Cypriot
+ "", // Braille
+ "bug", // Buginese
+ "khb", // NewTaiLue
+ "cu", // Glagolitic
+ "shi", // Tifinagh
+ "syl", // SylotiNagri
+ "peo", // OldPersian
+ "pra", // Kharoshthi
+ "ban", // Balinese
+ "akk", // Cuneiform
+ "phn", // Phoenician
+ "lzh", // PhagsPa
+ "man", // Nko
+ "su", // Sundanese
+ "lep", // Lepcha
+ "sat", // OlChiki
+ "vai", // Vai
+ "saz", // Saurashtra
+ "eky", // KayahLi
+ "rej", // Rejang
+ "xlc", // Lycian
+ "xcr", // Carian
+ "xld", // Lydian
+ "cjm", // Cham
+ "nod", // TaiTham
+ "blt", // TaiViet
+ "ae", // Avestan
+ "egy", // EgyptianHieroglyphs
+ "smp", // Samaritan
+ "lis", // Lisu
+ "bax", // Bamum
+ "jv", // Javanese
+ "mni", // MeeteiMayek
+ "arc", // ImperialAramaic
+ "xsa", // OldSouthArabian
+ "xpr", // InscriptionalParthian
+ "pal", // InscriptionalPahlavi
+ "otk", // OldTurkic
+ "bh", // Kaithi
+ "bbc", // Batak
+ "pra", // Brahmi
+ "myz", // Mandaic
+ "ccp", // Chakma
+ "xmr", // MeroiticCursive
+ "xmr", // MeroiticHieroglyphs
+ "hmd", // Miao
+ "sa", // Sharada
+ "srb", // SoraSompeng
+ "doi" // Takri
};
enum { SpecialLanguageCount = sizeof(specialLanguages) / sizeof(const char *) };
-static const ushort specialChars[] = {
- 0, // English
- 0, // Greek
- 0, // Cyrillic
- 0, // Armenian
- 0, // Hebrew
- 0, // Arabic
- 0, // Syriac
- 0, // Thaana
- 0, // Devanagari
- 0, // Bengali
- 0, // Gurmukhi
- 0, // Gujarati
- 0, // Oriya
- 0, // Tamil
- 0xc15, // Telugu
- 0xc95, // Kannada
- 0xd15, // Malayalam
- 0xd9a, // Sinhala
- 0, // Thai
- 0, // Lao
- 0, // Tibetan
- 0x1000, // Myanmar
- 0, // Georgian
- 0, // Hangul
- 0x1681, // Ogham
- 0x16a0, // Runic
- 0, // Khmer
- 0x7ca // N'Ko
-};
-enum { SpecialCharCount = sizeof(specialChars) / sizeof(ushort) };
-
// this could become a list of all languages used for each writing
// system, instead of using the single most common language.
static const char *languageForWritingSystem[] = {
@@ -194,9 +238,9 @@ static const char *languageForWritingSystem[] = {
"ko", // Korean
"vi", // Vietnamese
0, // Symbol
- 0, // Ogham
- 0, // Runic
- 0 // N'Ko
+ "sga", // Ogham
+ "non", // Runic
+ "man" // N'Ko
};
enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) };
@@ -402,7 +446,7 @@ void QFontconfigDatabase::populateFontDatabase()
// some languages are not supported by FontConfig, we rather check the
// charset to detect these
for (int i = 1; i < SampleCharCount; ++i) {
- if (!sampleCharForWritingSystem[i])
+ if (!sampleCharForWritingSystem[i] || writingSystems.supported(QFontDatabase::WritingSystem(i)))
continue;
if (FcCharSetHasChar(cs, sampleCharForWritingSystem[i]))
writingSystems.setSupported(QFontDatabase::WritingSystem(i));
@@ -481,13 +525,12 @@ void QFontconfigDatabase::populateFontDatabase()
// QApplication::setFont(font);
}
-QFontEngineMulti *QFontconfigDatabase::fontEngineMulti(QFontEngine *fontEngine,
- QUnicodeTables::Script script)
+QFontEngineMulti *QFontconfigDatabase::fontEngineMulti(QFontEngine *fontEngine, QChar::Script script)
{
return new QFontEngineMultiFontConfig(fontEngine, script);
}
-QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QUnicodeTables::Script script, void *usrPtr)
+QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QChar::Script script, void *usrPtr)
{
if (!usrPtr)
return 0;
@@ -595,8 +638,7 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QUnicodeTables::
delete engine;
engine = 0;
} else if (scriptRequiresOpenType(script)) {
- HB_Face hbFace = engine->initializedHarfbuzzFace();
- if (!hbFace || !hbFace->supported_scripts[script]) {
+ if (!engine->supportsScript(script)) {
delete engine;
engine = 0;
}
@@ -605,7 +647,7 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QUnicodeTables::
return engine;
}
-QStringList QFontconfigDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
+QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
{
QStringList fallbackFamilies;
FcPattern *pattern = FcPatternCreate();
@@ -625,8 +667,8 @@ QStringList QFontconfigDatabase::fallbacksForFamily(const QString family, const
slant_value = FC_SLANT_OBLIQUE;
FcPatternAddInteger(pattern, FC_SLANT, slant_value);
- if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') {
- Q_ASSERT(script < QUnicodeTables::ScriptCount);
+ Q_ASSERT(uint(script) < SpecialLanguageCount);
+ if (*specialLanguages[script] != '\0') {
FcLangSet *ls = FcLangSetCreate();
FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
FcPatternAddLangSet(pattern, FC_LANG, ls);
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
index cb05ef4722..6d6dae680e 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
@@ -51,9 +51,9 @@ class QFontconfigDatabase : public QBasicFontDatabase
{
public:
void populateFontDatabase();
- QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QUnicodeTables::Script script);
- QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle);
- QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const;
+ QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script);
+ QFontEngine *fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle);
+ QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
QString resolveFontFamilyAlias(const QString &family) const;
QFont defaultFont() const;
diff --git a/src/platformsupport/fontdatabases/mac/coretext.pri b/src/platformsupport/fontdatabases/mac/coretext.pri
index f7977964fe..d1abf123aa 100644
--- a/src/platformsupport/fontdatabases/mac/coretext.pri
+++ b/src/platformsupport/fontdatabases/mac/coretext.pri
@@ -1,2 +1,10 @@
HEADERS += $$PWD/qcoretextfontdatabase_p.h $$PWD/qfontengine_coretext_p.h
OBJECTIVE_SOURCES += $$PWD/qfontengine_coretext.mm $$PWD/qcoretextfontdatabase.mm
+
+ios: \
+ # On iOS CoreText and CoreGraphics are stand-alone frameworks
+ LIBS += -framework CoreText -framework CoreGraphics
+else: \
+ # On Mac OS they are part of the ApplicationServices umbrella framework,
+ # even in 10.8 where they were also made available stand-alone.
+ LIBS += -framework ApplicationServices
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index d59bd5f116..fbd836f763 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include "qglobal.h"
+
#ifndef Q_OS_IOS
#import <Cocoa/Cocoa.h>
#import <IOKit/graphics/IOGraphicsLib.h>
@@ -85,28 +87,12 @@ static const char *languageForWritingSystem[] = {
"ko", // Korean
"vi", // Vietnamese
0, // Symbol
- 0, // Ogham
- 0, // Runic
- 0 // N'Ko
+ "sga", // Ogham
+ "non", // Runic
+ "man" // N'Ko
};
enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) };
-QFont::StyleHint styleHintFromNSString(NSString *style)
-{
- if ([style isEqual: @"sans-serif"])
- return QFont::SansSerif;
- else if ([style isEqual: @"monospace"])
- return QFont::Monospace;
- else if ([style isEqual: @"cursive"])
- return QFont::Cursive;
- else if ([style isEqual: @"serif"])
- return QFont::Serif;
- else if ([style isEqual: @"fantasy"])
- return QFont::Fantasy;
- else // if ([style isEqual: @"default"])
- return QFont::AnyStyle;
-}
-
static NSInteger languageMapSort(id obj1, id obj2, void *context)
{
NSArray *map1 = (NSArray *) obj1;
@@ -188,27 +174,6 @@ QCoreTextFontDatabase::~QCoreTextFontDatabase()
{
}
-static QString familyNameFromPostScriptName(QHash<QString, QString> &psNameToFamily,
- 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;
- }
-}
-
void QCoreTextFontDatabase::populateFontDatabase()
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@@ -223,7 +188,6 @@ void QCoreTextFontDatabase::populateFontDatabase()
QString foundryName = QLatin1String("CoreText");
const int numFonts = CFArrayGetCount(fonts);
- QHash<QString, QString> psNameToFamily;
for (int i = 0; i < numFonts; ++i) {
CTFontDescriptorRef font = (CTFontDescriptorRef) CFArrayGetValueAtIndex(fonts, i);
QCFString familyName = (CFStringRef) CTFontDescriptorCopyLocalizedAttribute(font, kCTFontFamilyNameAttribute, NULL);
@@ -289,35 +253,14 @@ void QCoreTextFontDatabase::populateFontDatabase()
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);
- // we need PostScript Name to family name mapping for fallback list construction
psNameToFamily[QCFString::toQString((NSString *) psName)] = familyName;
+ familyNameToPsName[familyName] = QCFString::toQString((NSString *) psName);
CFRelease(psName);
}
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- NSArray *languages = [defaults stringArrayForKey: @"AppleLanguages"];
-
- NSDictionary *fallbackDict = [NSDictionary dictionaryWithContentsOfFile: @"/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/Resources/DefaultFontFallbacks.plist"];
-
- for (NSString *style in [fallbackDict allKeys]) {
- NSArray *list = [fallbackDict valueForKey: style];
- QFont::StyleHint styleHint = styleHintFromNSString(style);
- QStringList fallbackList;
- for (id item in list) {
- // sort the array based on system language preferences
- if ([item isKindOfClass: [NSArray class]]) {
- NSArray *langs = [(NSArray *) item sortedArrayUsingFunction: languageMapSort
- context: languages];
- for (NSArray *map in langs)
- fallbackList.append(familyNameFromPostScriptName(psNameToFamily, [map objectAtIndex: 1]));
- }
- else if ([item isKindOfClass: [NSString class]])
- fallbackList.append(familyNameFromPostScriptName(psNameToFamily, item));
- }
- fallbackLists[styleHint] = fallbackList;
- }
-
[pool release];
}
@@ -326,7 +269,7 @@ void QCoreTextFontDatabase::releaseHandle(void *handle)
CFRelease(CTFontDescriptorRef(handle));
}
-QFontEngine *QCoreTextFontDatabase::fontEngine(const QFontDef &f, QUnicodeTables::Script script, void *usrPtr)
+QFontEngine *QCoreTextFontDatabase::fontEngine(const QFontDef &f, QChar::Script script, void *usrPtr)
{
Q_UNUSED(script);
@@ -376,14 +319,142 @@ QFontEngine *QCoreTextFontDatabase::fontEngine(const QByteArray &fontData, qreal
return fontEngine;
}
-QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
+QFont::StyleHint styleHintFromNSString(NSString *style)
+{
+ if ([style isEqual: @"sans-serif"])
+ return QFont::SansSerif;
+ else if ([style isEqual: @"monospace"])
+ return QFont::Monospace;
+ else if ([style isEqual: @"cursive"])
+ return QFont::Cursive;
+ else if ([style isEqual: @"serif"])
+ return QFont::Serif;
+ else if ([style isEqual: @"fantasy"])
+ return QFont::Fantasy;
+ else // if ([style isEqual: @"default"])
+ return QFont::AnyStyle;
+}
+
+static QString familyNameFromPostScriptName(QHash<QString, QString> &psNameToFamily,
+ 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;
+ }
+}
+
+QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
{
- Q_UNUSED(family);
Q_UNUSED(style);
Q_UNUSED(script);
- if (fallbackLists.isEmpty())
+
+ static QHash<QString, QStringList> fallbackLists;
+
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_8, __IPHONE_6_0)
+ // CTFontCopyDefaultCascadeListForLanguages is available in the SDK
+ #if QT_MAC_DEPLOYMENT_TARGET_BELOW(__MAC_10_8, __IPHONE_6_0)
+ // But we have to feature check at runtime
+ if (&CTFontCopyDefaultCascadeListForLanguages)
+ #endif
+ {
+ 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));
+ }
+ fallbackLists[family] = fallbackList;
+ }
+ }
+
+ if (fallbackLists.contains(family))
+ return fallbackLists.value(family);
+ }
+#else
+ Q_UNUSED(family);
+#endif
+
+ // We were not able to find a fallback for the specific family,
+ // so we fall back to the stylehint.
+
+ static const QString styleLookupKey = QString::fromLatin1(".QFontStyleHint_%1");
+
+ static bool didPopulateStyleFallbacks = false;
+ if (!didPopulateStyleFallbacks) {
+#if !defined(Q_OS_IOS)
+ // Ensure we have the psNameToFamily mapping set up
const_cast<QCoreTextFontDatabase*>(this)->populateFontDatabase();
- return fallbackLists[styleHint];
+
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ NSArray *languages = [defaults stringArrayForKey: @"AppleLanguages"];
+
+ NSDictionary *fallbackDict = [NSDictionary dictionaryWithContentsOfFile: @"/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/Resources/DefaultFontFallbacks.plist"];
+
+ for (NSString *style in [fallbackDict allKeys]) {
+ NSArray *list = [fallbackDict valueForKey: style];
+ QFont::StyleHint fallbackStyleHint = styleHintFromNSString(style);
+ QStringList fallbackList;
+ for (id item in list) {
+ // sort the array based on system language preferences
+ if ([item isKindOfClass: [NSArray class]]) {
+ NSArray *langs = [(NSArray *) item sortedArrayUsingFunction: languageMapSort
+ context: languages];
+ for (NSArray *map in langs)
+ fallbackList.append(familyNameFromPostScriptName(psNameToFamily, [map objectAtIndex: 1]));
+ }
+ else if ([item isKindOfClass: [NSString class]])
+ fallbackList.append(familyNameFromPostScriptName(psNameToFamily, item));
+ }
+
+ if (QCoreTextFontEngine::supportsColorGlyphs())
+ fallbackList.append(QLatin1String("Apple Color Emoji"));
+
+ fallbackLists[styleLookupKey.arg(fallbackStyleHint)] = fallbackList;
+ }
+#else
+ QStringList staticFallbackList;
+ staticFallbackList << QString::fromLatin1("Helvetica,Apple Color Emoji,Geeza Pro,Arial Hebrew,Thonburi,Kailasa"
+ "Hiragino Kaku Gothic ProN,.Heiti J,Apple SD Gothic Neo,.Heiti K,Heiti SC,Heiti TC"
+ "Bangla Sangam MN,Devanagari Sangam MN,Gujarati Sangam MN,Gurmukhi MN,Kannada Sangam MN"
+ "Malayalam Sangam MN,Oriya Sangam MN,Sinhala Sangam MN,Tamil Sangam MN,Telugu Sangam MN"
+ "Euphemia UCAS,.PhoneFallback").split(QLatin1String(","));
+
+ for (int i = QFont::Helvetica; i <= QFont::Fantasy; ++i)
+ fallbackLists[styleLookupKey.arg(i)] = staticFallbackList;
+#endif
+
+ didPopulateStyleFallbacks = true;
+ }
+
+ Q_ASSERT(!fallbackLists.isEmpty());
+ return fallbackLists[styleLookupKey.arg(styleHint)];
}
#ifndef Q_OS_IOS
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
index dcec738598..5b9b8e2329 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
@@ -52,9 +52,9 @@ public:
QCoreTextFontDatabase();
~QCoreTextFontDatabase();
void populateFontDatabase();
- QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle);
+ QFontEngine *fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle);
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
- QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const;
+ QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const;
#ifndef Q_OS_IOS
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
#endif
@@ -64,7 +64,8 @@ public:
private:
mutable QString defaultFontName;
- QHash<QFont::StyleHint, QStringList> fallbackLists;
+ mutable QHash<QString, QString> psNameToFamily;
+ mutable QHash<QString, QString> familyNameToPsName;
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 5c46907bc5..3e553acd0a 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -46,8 +46,6 @@
#include <private/qimage_p.h>
-#if !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
-
QT_BEGIN_NAMESPACE
static float SYNTHETIC_ITALIC_SKEW = tanf(14 * acosf(0) / 90);
@@ -158,7 +156,7 @@ void QCoreTextFontEngine::init()
synthesisFlags = 0;
CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont);
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+#if defined(Q_OS_IOS) || MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
if (supportsColorGlyphs() && (traits & kCTFontColorGlyphsTrait))
glyphFormat = QFontEngineGlyphCache::Raster_ARGB;
else
@@ -457,7 +455,9 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition
br.y = QFixed::fromReal(br.y.toReal() * vscale);
}
- QImage im(qAbs(qRound(br.width))+2, qAbs(qRound(br.height))+2, QImage::Format_RGB32);
+ bool isColorGlyph = glyphFormat == QFontEngineGlyphCache::Raster_ARGB;
+ QImage::Format format = isColorGlyph ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
+ QImage im(qAbs(qRound(br.width)) + 2, qAbs(qRound(br.height)) + 2, format);
im.fill(0);
#ifndef Q_OS_IOS
@@ -465,7 +465,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition
#else
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
#endif
- uint cgflags = kCGImageAlphaNoneSkipFirst;
+ uint cgflags = isColorGlyph ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst;
#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
cgflags |= kCGBitmapByteOrder32Host;
#endif
@@ -476,38 +476,49 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition
CGContextSetShouldAntialias(ctx, (aa || fontDef.pointSize > antialiasingThreshold)
&& !(fontDef.styleStrategy & QFont::NoAntialias));
CGContextSetShouldSmoothFonts(ctx, aa);
- CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
- CGAffineTransform cgMatrix = CGAffineTransformIdentity;
- CGAffineTransformConcat(cgMatrix, oldTextMatrix);
+ CGAffineTransform cgMatrix = CGAffineTransformIdentity;
if (synthesisFlags & QFontEngine::SynthesizedItalic)
cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, SYNTHETIC_ITALIC_SKEW, 1, 0, 0));
- cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
+ if (!isColorGlyph) // CTFontDrawGlyphs incorporates the font's matrix already
+ cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
+
if (m.isScaling())
cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMakeScale(m.m11(), m.m22()));
- CGContextSetTextMatrix(ctx, cgMatrix);
- CGContextSetRGBFillColor(ctx, 1, 1, 1, 1);
- CGContextSetTextDrawingMode(ctx, kCGTextFill);
-
- CGContextSetFont(ctx, cgFont);
-
+ CGGlyph cgGlyph = glyph;
qreal pos_x = -br.x.truncate() + subPixelPosition.toReal();
qreal pos_y = im.height() + br.y.toReal();
- CGContextSetTextPosition(ctx, pos_x, pos_y);
- CGSize advance;
- advance.width = 0;
- advance.height = 0;
- CGGlyph cgGlyph = glyph;
- CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1);
+ if (!isColorGlyph) {
+ CGContextSetTextMatrix(ctx, cgMatrix);
+ CGContextSetRGBFillColor(ctx, 1, 1, 1, 1);
+ CGContextSetTextDrawingMode(ctx, kCGTextFill);
+ CGContextSetFont(ctx, cgFont);
+ CGContextSetTextPosition(ctx, pos_x, pos_y);
- if (synthesisFlags & QFontEngine::SynthesizedBold) {
- CGContextSetTextPosition(ctx, pos_x + 0.5 * lineThickness().toReal(), pos_y);
- CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1);
+ CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &CGSizeZero, 1);
+
+ if (synthesisFlags & QFontEngine::SynthesizedBold) {
+ CGContextSetTextPosition(ctx, pos_x + 0.5 * lineThickness().toReal(), pos_y);
+ CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &CGSizeZero, 1);
+ }
}
+#if defined(Q_OS_IOS) || MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+ else if (supportsColorGlyphs()) {
+ // CGContextSetTextMatrix does not work with color glyphs, so we use
+ // the CTM instead. This means we must translate the CTM as well, to
+ // set the glyph position, instead of using CGContextSetTextPosition.
+ CGContextTranslateCTM(ctx, pos_x, pos_y);
+ CGContextConcatCTM(ctx, cgMatrix);
+
+ // CGContextShowGlyphsWithAdvances does not support the 'sbix' color-bitmap
+ // glyphs in the Apple Color Emoji font, so we use CTFontDrawGlyphs instead.
+ CTFontDrawGlyphs(ctfont, &cgGlyph, &CGPointZero, 1, ctx);
+ }
+#endif
CGContextRelease(ctx);
CGColorSpaceRelease(colorspace);
@@ -517,7 +528,15 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition
QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition)
{
- QImage im = imageForGlyph(glyph, subPixelPosition, false, QTransform());
+ return alphaMapForGlyph(glyph, subPixelPosition, QTransform());
+}
+
+QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &x)
+{
+ if (x.type() > QTransform::TxScale)
+ return QFontEngine::alphaMapForGlyph(glyph, subPixelPosition, x);
+
+ QImage im = imageForGlyph(glyph, subPixelPosition, false, x);
QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
QVector<QRgb> colors(256);
@@ -548,6 +567,14 @@ QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPo
return im;
}
+QImage QCoreTextFontEngine::bitmapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t)
+{
+ if (t.type() > QTransform::TxScale)
+ return QFontEngine::bitmapForGlyph(glyph, subPixelPosition, t);
+
+ return imageForGlyph(glyph, subPixelPosition, true, t);
+}
+
void QCoreTextFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags) const
{
int i, numGlyphs = glyphs->numGlyphs;
@@ -609,12 +636,15 @@ QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const
return new QCoreTextFontEngine(cgFont, newFontDef);
}
-bool QCoreTextFontEngine::supportsTransformations(const QTransform &transform) const
+bool QCoreTextFontEngine::supportsTransformation(const QTransform &transform) const
{
- return transform.type() > QTransform::TxTranslate;
+ if (transform.type() < QTransform::TxScale)
+ return true;
+ else if (transform.type() == QTransform::TxScale &&
+ transform.m11() >= 0 && transform.m22() >= 0)
+ return true;
+ else
+ return false;
}
QT_END_NAMESPACE
-
-#endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
-
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
index dc73d38522..a9b1960491 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
@@ -52,10 +52,6 @@
#include <CoreGraphics/CoreGraphics.h>
#endif
-#if !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
-
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class QRawFontPrivate;
@@ -98,12 +94,14 @@ public:
virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const;
virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition);
+ virtual QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t);
virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
+ virtual QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
virtual qreal minRightBearing() const;
virtual qreal minLeftBearing() const;
virtual QFixed emSquareSize() const;
- bool supportsTransformations(const QTransform &transform) const;
+ bool supportsTransformation(const QTransform &transform) const;
virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
virtual int glyphMargin(QFontEngineGlyphCache::Type type) { Q_UNUSED(type); return 0; }
@@ -142,8 +140,4 @@ CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef);
QT_END_NAMESPACE
-QT_END_HEADER
-
-#endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
-
#endif // QFONTENGINE_CORETEXT_P_H