summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>2012-07-16 11:42:14 (GMT)
committerQt by Nokia <qt-info@nokia.com>2012-07-16 11:54:21 (GMT)
commitac10780c78444e8899b3ef965b6ffe56128e32be (patch)
tree38c5c1e9a664fa27c46fbf3bb0858be567a7af1a
parentee54ea88fa8e8aa73462d65e327f038753611cc1 (diff)
downloadQt-ac10780c78444e8899b3ef965b6ffe56128e32be.zip
Qt-ac10780c78444e8899b3ef965b6ffe56128e32be.tar.gz
Qt-ac10780c78444e8899b3ef965b6ffe56128e32be.tar.bz2
Support fallbacks fonts in UIKit plugin
Code is taken from the Qt 5 CoreText font database, but the hardcoded path for the plist has been modified for iOS. Change-Id: I71271600ec5dd085d469d5c42f9811a23948021f Reviewed-by: Jiang Jiang <jiang.jiang@nokia.com>
-rw-r--r--src/plugins/platforms/uikit/platform.pro6
-rw-r--r--src/plugins/platforms/uikit/qcoretextfontdatabase.h8
-rw-r--r--src/plugins/platforms/uikit/qcoretextfontdatabase.mm (renamed from src/plugins/platforms/uikit/qcoretextfontdatabase.cpp)118
3 files changed, 115 insertions, 17 deletions
diff --git a/src/plugins/platforms/uikit/platform.pro b/src/plugins/platforms/uikit/platform.pro
index b5ff62f..1b90f3e 100644
--- a/src/plugins/platforms/uikit/platform.pro
+++ b/src/plugins/platforms/uikit/platform.pro
@@ -9,7 +9,8 @@ OBJECTIVE_SOURCES = main.mm \
quikitwindow.mm \
quikitscreen.mm \
quikiteventloop.mm \
- quikitwindowsurface.mm
+ quikitwindowsurface.mm \
+ qcoretextfontdatabase.mm
OBJECTIVE_HEADERS = quikitintegration.h \
quikitwindow.h \
@@ -20,9 +21,6 @@ OBJECTIVE_HEADERS = quikitintegration.h \
HEADERS = quikitsoftwareinputhandler.h \
qcoretextfontdatabase.h
-SOURCES += \
- qcoretextfontdatabase.cpp
-
#needed for qcoretextfontengine even if it's not used
INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/harfbuzz/src
diff --git a/src/plugins/platforms/uikit/qcoretextfontdatabase.h b/src/plugins/platforms/uikit/qcoretextfontdatabase.h
index 05b9b09..77010c2 100644
--- a/src/plugins/platforms/uikit/qcoretextfontdatabase.h
+++ b/src/plugins/platforms/uikit/qcoretextfontdatabase.h
@@ -51,6 +51,14 @@ class QCoreTextFontDatabase : public QPlatformFontDatabase
public:
void populateFontDatabase();
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;
+
+private:
+ QHash<QFont::StyleHint, QStringList> fallbackLists;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/qcoretextfontdatabase.cpp b/src/plugins/platforms/uikit/qcoretextfontdatabase.mm
index 2854567..47bfba1 100644
--- a/src/plugins/platforms/uikit/qcoretextfontdatabase.cpp
+++ b/src/plugins/platforms/uikit/qcoretextfontdatabase.mm
@@ -42,28 +42,90 @@
#include "qcoretextfontdatabase.h"
#include <CoreText/CoreText.h>
+#include <Foundation/Foundation.h>
#include <private/qcore_mac_p.h>
#include <private/qfontengine_coretext_p.h>
-#include <QtDebug>
-
QT_BEGIN_NAMESPACE
+QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString family,
+ const QFont::Style &style,
+ const QFont::StyleHint &styleHint,
+ const QUnicodeTables::Script &script) const
+{
+ Q_UNUSED(family);
+ Q_UNUSED(style);
+ Q_UNUSED(script);
+ if (fallbackLists.isEmpty())
+ const_cast<QCoreTextFontDatabase *>(this)->populateFontDatabase();
+
+ return fallbackLists[styleHint];
+}
+
+static 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
+ return QFont::AnyStyle;
+}
+
+static NSInteger languageMapSort(id obj1, id obj2, void *context)
+{
+ NSArray *map1 = (NSArray *) obj1;
+ NSArray *map2 = (NSArray *) obj2;
+ NSArray *languages = (NSArray *) context;
+
+ NSString *lang1 = [map1 objectAtIndex: 0];
+ NSString *lang2 = [map2 objectAtIndex: 0];
+
+ return [languages indexOfObject: lang1] - [languages indexOfObject: lang2];
+}
+
+static QString familyNameFromPostScriptName(QHash<QString, QString> *psNameToFamily,
+ NSString *psName)
+{
+ QString name = QCFString::toQString((CFStringRef) psName);
+ if (psNameToFamily->contains(name)) {
+ return psNameToFamily->value(name);
+ } else {
+ 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];
+
QCFType<CTFontCollectionRef> collection = CTFontCollectionCreateFromAvailableFonts(0);
- if(!collection)
+ if (!collection)
return;
QCFType<CFArrayRef> fonts = CTFontCollectionCreateMatchingFontDescriptors(collection);
- if(!fonts)
+ if (!fonts)
return;
QSupportedWritingSystems supportedWritingSystems;
for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i)
supportedWritingSystems.setSupported((QFontDatabase::WritingSystem)i, true);
QString foundry_name = "CoreText";
const int numFonts = CFArrayGetCount(fonts);
- for(int i = 0; i < numFonts; ++i) {
+ QHash<QString, QString> psNameToFamily;
+ for (int i = 0; i < numFonts; ++i) {
CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fonts, i);
QCFString family_name = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
@@ -71,19 +133,19 @@ void QCoreTextFontDatabase::populateFontDatabase()
QFont::Weight fontWeight = QFont::Normal;
QFont::Style fontStyle = QFont::StyleNormal;
- if(QCFType<CFDictionaryRef> styles = (CFDictionaryRef)CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute)) {
- if(CFNumberRef weight = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
+ if (QCFType<CFDictionaryRef> styles = (CFDictionaryRef)CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute)) {
+ if (CFNumberRef weight = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
Q_ASSERT(CFNumberIsFloatType(weight));
double d;
- if(CFNumberGetValue(weight, kCFNumberDoubleType, &d)) {
+ if (CFNumberGetValue(weight, kCFNumberDoubleType, &d)) {
if (d > 0.0)
fontWeight = QFont::Bold;
}
}
- if(CFNumberRef italic = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontSlantTrait)) {
+ if (CFNumberRef italic = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontSlantTrait)) {
Q_ASSERT(CFNumberIsFloatType(italic));
double d;
- if(CFNumberGetValue(italic, kCFNumberDoubleType, &d)) {
+ if (CFNumberGetValue(italic, kCFNumberDoubleType, &d)) {
if (d > 0.0)
fontStyle = QFont::StyleItalic;
}
@@ -91,8 +153,8 @@ void QCoreTextFontDatabase::populateFontDatabase()
}
int pixelSize = 0;
- if(QCFType<CFNumberRef> size = (CFNumberRef)CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) {
- if(CFNumberIsFloatType(size)) {
+ if (QCFType<CFNumberRef> size = (CFNumberRef)CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) {
+ if (CFNumberIsFloatType(size)) {
double d;
CFNumberGetValue(size, kCFNumberDoubleType, &d);
pixelSize = d;
@@ -100,7 +162,8 @@ void QCoreTextFontDatabase::populateFontDatabase()
CFNumberGetValue(size, kCFNumberIntType, &pixelSize);
}
}
- registerFont(QString(family_name),
+ QString familyName = QCFString::toQString(family_name);
+ registerFont(familyName,
foundry_name,
fontWeight,
fontStyle,
@@ -110,7 +173,36 @@ void QCoreTextFontDatabase::populateFontDatabase()
pixelSize,
supportedWritingSystems,
0);
+
+ CFStringRef psName = (CFStringRef) CTFontDescriptorCopyAttribute(font,
+ kCTFontNameAttribute);
+ psNameToFamily[QCFString::toQString(psName)] = familyName;
+ CFRelease(psName);
}
+
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ NSArray *languages = [defaults stringArrayForKey: @"AppleLanguages"];
+
+ NSDictionary *fallbackDict = [NSDictionary dictionaryWithContentsOfFile: @"/System/Library/Frameworks/CoreText.framework/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) {
+ 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];
}
QFontEngine *QCoreTextFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle)