summaryrefslogtreecommitdiffstats
path: root/src/platformsupport/fontdatabases
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@digia.com>2014-02-19 10:06:25 +0100
committerOswald Buddenhagen <oswald.buddenhagen@digia.com>2014-02-19 10:06:25 +0100
commit30fd22b9574def54726e7b193127cc0c901c1b4c (patch)
tree96dfc923044db0515064ba39d052d9ed577e3e40 /src/platformsupport/fontdatabases
parentd7b0581c1c2ef60c08d238dae39298af6904918f (diff)
parent6aa09bbce59828d028f6d1e81d2bfc6ba537aae1 (diff)
Merge remote-tracking branch 'origin/dev' into stable
Diffstat (limited to 'src/platformsupport/fontdatabases')
-rw-r--r--src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp17
-rw-r--r--src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h2
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp310
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h2
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm204
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h25
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm20
7 files changed, 318 insertions, 262 deletions
diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
index 33f3601b97..1ed5ede3e8 100644
--- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
+++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
@@ -113,27 +113,18 @@ void QBasicFontDatabase::populateFontDatabase()
}
}
-QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, QChar::Script script, void *usrPtr)
+QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, void *usrPtr)
{
- QFontEngineFT *engine;
FontFile *fontfile = static_cast<FontFile *> (usrPtr);
QFontEngine::FaceId fid;
fid.filename = QFile::encodeName(fontfile->fileName);
fid.index = fontfile->indexValue;
- engine = new QFontEngineFT(fontDef);
bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
- if (!engine->init(fid,antialias,format)) {
- delete engine;
- engine = 0;
- return engine;
- }
- if (engine->invalid()) {
- delete engine;
- engine = 0;
- } else if (!engine->supportsScript(script)) {
- qWarning(" OpenType support missing for script %d", int(script));
+
+ QFontEngineFT *engine = new QFontEngineFT(fontDef);
+ if (!engine->init(fid, antialias, format) || engine->invalid()) {
delete engine;
engine = 0;
}
diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h
index 4d6fd2ceeb..45d7218ece 100644
--- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h
@@ -58,7 +58,7 @@ class QBasicFontDatabase : public QPlatformFontDatabase
{
public:
void populateFontDatabase();
- QFontEngine *fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle);
+ 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;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index 8c3ca2d229..8b16e7520a 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -69,21 +69,52 @@ static inline bool requiresOpenType(int writingSystem)
|| writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
}
-static int getFCWeight(int fc_weight)
+static inline int weightFromFcWeight(int fcweight)
{
- int qtweight = QFont::Black;
- if (fc_weight <= (FC_WEIGHT_LIGHT + FC_WEIGHT_REGULAR) / 2)
- qtweight = QFont::Light;
- else if (fc_weight <= (FC_WEIGHT_REGULAR + FC_WEIGHT_MEDIUM) / 2)
- qtweight = QFont::Normal;
- else if (fc_weight <= (FC_WEIGHT_MEDIUM + FC_WEIGHT_BOLD) / 2)
- qtweight = QFont::DemiBold;
- else if (fc_weight <= (FC_WEIGHT_BOLD + FC_WEIGHT_BLACK) / 2)
- qtweight = QFont::Bold;
+ // Font Config uses weights from 0 to 215 (the highest enum value) while QFont ranges from
+ // 0 to 99. The spacing between the values for the enums are uneven so a linear mapping from
+ // Font Config values to Qt would give surprising results. So, we do a piecewise linear
+ // mapping. This ensures that where there is a corresponding enum on both sides (for example
+ // FC_WEIGHT_DEMIBOLD and QFont::DemiBold) we map one to the other but other values map
+ // to intermediate Qt weights.
+ const int maxWeight = 99;
+ int qtweight;
+ if (fcweight < 0)
+ qtweight = 0;
+ else if (fcweight <= FC_WEIGHT_LIGHT)
+ qtweight = (fcweight * QFont::Light) / FC_WEIGHT_LIGHT;
+ else if (fcweight <= FC_WEIGHT_NORMAL)
+ qtweight = QFont::Light + ((fcweight - FC_WEIGHT_LIGHT) * (QFont::Normal - QFont::Light)) / (FC_WEIGHT_NORMAL - FC_WEIGHT_LIGHT);
+ else if (fcweight <= FC_WEIGHT_DEMIBOLD)
+ qtweight = QFont::Normal + ((fcweight - FC_WEIGHT_NORMAL) * (QFont::DemiBold - QFont::Normal)) / (FC_WEIGHT_DEMIBOLD - FC_WEIGHT_NORMAL);
+ else if (fcweight <= FC_WEIGHT_BOLD)
+ qtweight = QFont::DemiBold + ((fcweight - FC_WEIGHT_DEMIBOLD) * (QFont::Bold - QFont::DemiBold)) / (FC_WEIGHT_BOLD - FC_WEIGHT_DEMIBOLD);
+ else if (fcweight <= FC_WEIGHT_BLACK)
+ qtweight = QFont::Bold + ((fcweight - FC_WEIGHT_BOLD) * (QFont::Black - QFont::Bold)) / (FC_WEIGHT_BLACK - FC_WEIGHT_BOLD);
+ else if (fcweight <= FC_WEIGHT_ULTRABLACK)
+ qtweight = QFont::Black + ((fcweight - FC_WEIGHT_BLACK) * (maxWeight - QFont::Black)) / (FC_WEIGHT_ULTRABLACK - FC_WEIGHT_BLACK);
+ else
+ qtweight = maxWeight;
return qtweight;
}
+static inline int stretchFromFcWidth(int fcwidth)
+{
+ // Font Config enums for width match pretty closely with those used by Qt so just use
+ // Font Config values directly while enforcing the same limits imposed by QFont.
+ const int maxStretch = 4000;
+ int qtstretch;
+ if (fcwidth < 1)
+ qtstretch = 1;
+ else if (fcwidth > maxStretch)
+ qtstretch = maxStretch;
+ else
+ qtstretch = fcwidth;
+
+ return qtstretch;
+}
+
static const char *specialLanguages[] = {
"", // Unknown
"", // Inherited
@@ -300,15 +331,14 @@ static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
return stylehint;
}
-void QFontconfigDatabase::populateFontDatabase()
+static void populateFromPattern(FcPattern *pattern)
{
- FcFontSet *fonts;
-
QString familyName;
FcChar8 *value = 0;
int weight_value;
int slant_value;
int spacing_value;
+ int width_value;
FcChar8 *file_value;
int indexValue;
FcChar8 *foundry_value;
@@ -316,13 +346,117 @@ void QFontconfigDatabase::populateFontDatabase()
FcBool scalable;
FcBool antialias;
+ if (FcPatternGetString(pattern, FC_FAMILY, 0, &value) != FcResultMatch)
+ return;
+
+ familyName = QString::fromUtf8((const char *)value);
+
+ slant_value = FC_SLANT_ROMAN;
+ weight_value = FC_WEIGHT_REGULAR;
+ spacing_value = FC_PROPORTIONAL;
+ file_value = 0;
+ indexValue = 0;
+ scalable = FcTrue;
+
+
+ if (FcPatternGetInteger(pattern, FC_SLANT, 0, &slant_value) != FcResultMatch)
+ slant_value = FC_SLANT_ROMAN;
+ if (FcPatternGetInteger(pattern, FC_WEIGHT, 0, &weight_value) != FcResultMatch)
+ weight_value = FC_WEIGHT_REGULAR;
+ if (FcPatternGetInteger(pattern, FC_WIDTH, 0, &width_value) != FcResultMatch)
+ width_value = FC_WIDTH_NORMAL;
+ if (FcPatternGetInteger(pattern, FC_SPACING, 0, &spacing_value) != FcResultMatch)
+ spacing_value = FC_PROPORTIONAL;
+ if (FcPatternGetString(pattern, FC_FILE, 0, &file_value) != FcResultMatch)
+ file_value = 0;
+ if (FcPatternGetInteger(pattern, FC_INDEX, 0, &indexValue) != FcResultMatch)
+ indexValue = 0;
+ if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &scalable) != FcResultMatch)
+ scalable = FcTrue;
+ if (FcPatternGetString(pattern, FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
+ foundry_value = 0;
+ if (FcPatternGetString(pattern, FC_STYLE, 0, &style_value) != FcResultMatch)
+ style_value = 0;
+ if (FcPatternGetBool(pattern,FC_ANTIALIAS,0,&antialias) != FcResultMatch)
+ antialias = true;
+
+ QSupportedWritingSystems writingSystems;
+ FcLangSet *langset = 0;
+ FcResult res = FcPatternGetLangSet(pattern, FC_LANG, 0, &langset);
+ if (res == FcResultMatch) {
+ bool hasLang = false;
+ for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
+ const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[j];
+ if (lang) {
+ FcLangResult langRes = FcLangSetHasLang(langset, lang);
+ if (langRes != FcLangDifferentLang) {
+ writingSystems.setSupported(QFontDatabase::WritingSystem(j));
+ hasLang = true;
+ }
+ }
+ }
+ if (!hasLang)
+ // none of our known languages, add it to the other set
+ writingSystems.setSupported(QFontDatabase::Other);
+ } else {
+ // we set Other to supported for symbol fonts. It makes no
+ // sense to merge these with other ones, as they are
+ // special in a way.
+ writingSystems.setSupported(QFontDatabase::Other);
+ }
+
+#if FC_VERSION >= 20297
+ for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
+ if (writingSystems.supported(QFontDatabase::WritingSystem(j))
+ && requiresOpenType(j) && openType[j]) {
+ FcChar8 *cap;
+ res = FcPatternGetString (pattern, FC_CAPABILITY, 0, &cap);
+ if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
+ writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
+ }
+ }
+#endif
+
+ FontFile *fontFile = new FontFile;
+ fontFile->fileName = QLatin1String((const char *)file_value);
+ fontFile->indexValue = indexValue;
+
+ QFont::Style style = (slant_value == FC_SLANT_ITALIC)
+ ? QFont::StyleItalic
+ : ((slant_value == FC_SLANT_OBLIQUE)
+ ? QFont::StyleOblique
+ : QFont::StyleNormal);
+ // Note: weight should really be an int but registerFont incorrectly uses an enum
+ QFont::Weight weight = QFont::Weight(weightFromFcWeight(weight_value));
+
+ double pixel_size = 0;
+ if (!scalable)
+ FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &pixel_size);
+
+ bool fixedPitch = spacing_value >= FC_MONO;
+ // Note: stretch should really be an int but registerFont incorrectly uses an enum
+ QFont::Stretch stretch = QFont::Stretch(stretchFromFcWidth(width_value));
+ QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
+ QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile);
+// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
+
+ for (int k = 1; FcPatternGetString(pattern, FC_FAMILY, k, &value) == FcResultMatch; ++k)
+ QPlatformFontDatabase::registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value));
+
+}
+
+void QFontconfigDatabase::populateFontDatabase()
+{
+ FcInitReinitialize();
+ FcFontSet *fonts;
+
{
FcObjectSet *os = FcObjectSetCreate();
FcPattern *pattern = FcPatternCreate();
const char *properties [] = {
FC_FAMILY, FC_STYLE, FC_WEIGHT, FC_SLANT,
FC_SPACING, FC_FILE, FC_INDEX,
- FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE, FC_WEIGHT,
+ FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE,
FC_WIDTH,
#if FC_VERSION >= 20297
FC_CAPABILITY,
@@ -339,102 +473,8 @@ void QFontconfigDatabase::populateFontDatabase()
FcPatternDestroy(pattern);
}
- for (int i = 0; i < fonts->nfont; i++) {
- if (FcPatternGetString(fonts->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
- continue;
- // capitalize(value);
- familyName = QString::fromUtf8((const char *)value);
- slant_value = FC_SLANT_ROMAN;
- weight_value = FC_WEIGHT_REGULAR;
- spacing_value = FC_PROPORTIONAL;
- file_value = 0;
- indexValue = 0;
- scalable = FcTrue;
-
-
- if (FcPatternGetInteger (fonts->fonts[i], FC_SLANT, 0, &slant_value) != FcResultMatch)
- slant_value = FC_SLANT_ROMAN;
- if (FcPatternGetInteger (fonts->fonts[i], FC_WEIGHT, 0, &weight_value) != FcResultMatch)
- weight_value = FC_WEIGHT_REGULAR;
- if (FcPatternGetInteger (fonts->fonts[i], FC_SPACING, 0, &spacing_value) != FcResultMatch)
- spacing_value = FC_PROPORTIONAL;
- if (FcPatternGetString (fonts->fonts[i], FC_FILE, 0, &file_value) != FcResultMatch)
- file_value = 0;
- if (FcPatternGetInteger (fonts->fonts[i], FC_INDEX, 0, &indexValue) != FcResultMatch)
- indexValue = 0;
- if (FcPatternGetBool(fonts->fonts[i], FC_SCALABLE, 0, &scalable) != FcResultMatch)
- scalable = FcTrue;
- if (FcPatternGetString(fonts->fonts[i], FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
- foundry_value = 0;
- if (FcPatternGetString(fonts->fonts[i], FC_STYLE, 0, &style_value) != FcResultMatch)
- style_value = 0;
- if(FcPatternGetBool(fonts->fonts[i],FC_ANTIALIAS,0,&antialias) != FcResultMatch)
- antialias = true;
-
- QSupportedWritingSystems writingSystems;
- FcLangSet *langset = 0;
- FcResult res = FcPatternGetLangSet(fonts->fonts[i], FC_LANG, 0, &langset);
- if (res == FcResultMatch) {
- bool hasLang = false;
- for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
- const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[j];
- if (lang) {
- FcLangResult langRes = FcLangSetHasLang(langset, lang);
- if (langRes != FcLangDifferentLang) {
- writingSystems.setSupported(QFontDatabase::WritingSystem(j));
- hasLang = true;
- }
- }
- }
- if (!hasLang)
- // none of our known languages, add it to the other set
- writingSystems.setSupported(QFontDatabase::Other);
- } else {
- // we set Other to supported for symbol fonts. It makes no
- // sense to merge these with other ones, as they are
- // special in a way.
- writingSystems.setSupported(QFontDatabase::Other);
- }
-
-#if FC_VERSION >= 20297
- for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
- if (writingSystems.supported(QFontDatabase::WritingSystem(j))
- && requiresOpenType(j) && openType[j]) {
- FcChar8 *cap;
- res = FcPatternGetString (fonts->fonts[i], FC_CAPABILITY, 0, &cap);
- if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
- writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
- }
- }
-#endif
-
- FontFile *fontFile = new FontFile;
- fontFile->fileName = QLatin1String((const char *)file_value);
- fontFile->indexValue = indexValue;
-
- QFont::Style style = (slant_value == FC_SLANT_ITALIC)
- ? QFont::StyleItalic
- : ((slant_value == FC_SLANT_OBLIQUE)
- ? QFont::StyleOblique
- : QFont::StyleNormal);
- QFont::Weight weight = QFont::Weight(getFCWeight(weight_value));
-
- double pixel_size = 0;
- if (!scalable) {
- int width = 100;
- FcPatternGetInteger (fonts->fonts[i], FC_WIDTH, 0, &width);
- FcPatternGetDouble (fonts->fonts[i], FC_PIXEL_SIZE, 0, &pixel_size);
- }
-
- bool fixedPitch = spacing_value >= FC_MONO;
- QFont::Stretch stretch = QFont::Unstretched;
- QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
- QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile);
-// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
-
- for (int k = 1; FcPatternGetString(fonts->fonts[i], FC_FAMILY, k, &value) == FcResultMatch; ++k)
- QPlatformFontDatabase::registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value));
- }
+ for (int i = 0; i < fonts->nfont; i++)
+ populateFromPattern(fonts->fonts[i]);
FcFontSetDestroy (fonts);
@@ -476,20 +516,18 @@ QFontEngineMulti *QFontconfigDatabase::fontEngineMulti(QFontEngine *fontEngine,
return new QFontEngineMultiFontConfig(fontEngine, script);
}
-QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QChar::Script script, void *usrPtr)
+QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
{
if (!usrPtr)
return 0;
QFontDef fontDef = f;
- QFontEngineFT *engine;
FontFile *fontfile = static_cast<FontFile *> (usrPtr);
QFontEngine::FaceId fid;
fid.filename = QFile::encodeName(fontfile->fileName);
fid.index = fontfile->indexValue;
bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
- engine = new QFontEngineFT(fontDef);
QFontEngineFT::GlyphFormat format;
// try and get the pattern
@@ -509,8 +547,24 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QChar::Script sc
FcPatternAdd(pattern,FC_INDEX,value,true);
FcResult result;
+
+ FcConfigSubstitute(0, pattern, FcMatchPattern);
+ FcDefaultSubstitute(pattern);
+
FcPattern *match = FcFontMatch(0, pattern, &result);
+
+ QFontEngineFT *engine = new QFontEngineFT(fontDef);
+
if (match) {
+ //Respect the file and index of the font config match
+ FcChar8 *file_value;
+ int indexValue;
+
+ if (FcPatternGetString(match, FC_FILE, 0, &file_value) == FcResultMatch)
+ fid.filename = (const char *)file_value;
+ if (FcPatternGetInteger(match, FC_INDEX, 0, &indexValue) == FcResultMatch)
+ fid.index = indexValue;
+
QFontEngineFT::HintStyle default_hint_style;
if (f.hintingPreference != QFont::PreferDefaultHinting) {
switch (f.hintingPreference) {
@@ -587,25 +641,18 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QChar::Script sc
format = subpixelType == QFontEngineFT::Subpixel_None
? QFontEngineFT::Format_A8 : QFontEngineFT::Format_A32;
engine->subpixelType = subpixelType;
- } else
+ } else {
format = QFontEngineFT::Format_Mono;
+ }
FcPatternDestroy(match);
- } else
+ } else {
format = antialias ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
+ }
FcPatternDestroy(pattern);
- if (!engine->init(fid,antialias,format)) {
- delete engine;
- engine = 0;
- return engine;
- }
- if (engine->invalid()) {
- delete engine;
- engine = 0;
- } else if (!engine->supportsScript(script)) {
- qWarning(" OpenType support missing for script %d", int(script));
+ if (!engine->init(fid, antialias, format) || engine->invalid()) {
delete engine;
engine = 0;
}
@@ -715,6 +762,7 @@ static FcPattern *queryFont(const FcChar8 *file, const QByteArray &data, int id,
QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
{
QStringList families;
+
FcFontSet *set = FcConfigGetFonts(0, FcSetApplication);
if (!set) {
FcConfigAppFontAddFile(0, (const FcChar8 *)":/non-existent");
@@ -727,28 +775,24 @@ QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData,
FcBlanks *blanks = FcConfigGetBlanks(0);
int count = 0;
- FcPattern *pattern = 0;
+ FcPattern *pattern;
do {
pattern = queryFont((const FcChar8 *)QFile::encodeName(fileName).constData(),
fontData, id, blanks, &count);
if (!pattern)
return families;
- FcPatternDel(pattern, FC_FILE);
- QByteArray cs = fileName.toUtf8();
- FcPatternAddString(pattern, FC_FILE, (const FcChar8 *) cs.constData());
-
FcChar8 *fam = 0;
if (FcPatternGetString(pattern, FC_FAMILY, 0, &fam) == FcResultMatch) {
QString family = QString::fromUtf8(reinterpret_cast<const char *>(fam));
families << family;
}
+ populateFromPattern(pattern);
- if (!FcFontSetAdd(set, pattern))
- return families;
+ FcFontSetAdd(set, pattern);
++id;
- } while (pattern && id < count);
+ } while (id < count);
return families;
}
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
index 6d6dae680e..9f1fd28144 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
@@ -52,7 +52,7 @@ class QFontconfigDatabase : public QBasicFontDatabase
public:
void populateFontDatabase();
QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script);
- QFontEngine *fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle);
+ QFontEngine *fontEngine(const QFontDef &fontDef, 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;
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index 38c44e3f35..ab2e9c1f1a 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -278,10 +278,8 @@ void QCoreTextFontDatabase::releaseHandle(void *handle)
CFRelease(CTFontDescriptorRef(handle));
}
-QFontEngine *QCoreTextFontDatabase::fontEngine(const QFontDef &f, QChar::Script script, void *usrPtr)
+QFontEngine *QCoreTextFontDatabase::fontEngine(const QFontDef &f, void *usrPtr)
{
- Q_UNUSED(script);
-
qreal scaledPointSize = f.pixelSize;
// When 96 DPI is forced, the Mac plugin will use DPI 72 for some
@@ -474,104 +472,120 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
return fallbackLists[styleLookupKey.arg(styleHint)];
}
-#ifdef Q_OS_MACX
+#if HAVE_CORETEXT
+static CFArrayRef createDescriptorArrayForFont(CTFontRef font)
+{
+ CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+ CFArrayAppendValue(array, QCFType<CTFontDescriptorRef>(CTFontCopyFontDescriptor(font)));
+ return array;
+}
+#endif
+
QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
- if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
- CTFontRef font = NULL;
+ QCFType<CFArrayRef> fonts;
+ QStringList families;
+#if HAVE_CORETEXT
+ if (&CTFontManagerRegisterGraphicsFont) {
+ CFErrorRef error = 0;
if (!fontData.isEmpty()) {
QByteArray* fontDataCopy = new QByteArray(fontData);
QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(fontDataCopy,
fontDataCopy->constData(), fontDataCopy->size(), releaseFontData);
- CGFontRef cgFont = CGFontCreateWithDataProvider(dataProvider);
+ QCFType<CGFontRef> cgFont = CGFontCreateWithDataProvider(dataProvider);
if (cgFont) {
- CFErrorRef error;
- bool success = CTFontManagerRegisterGraphicsFont(cgFont, &error);
- if (success) {
- font = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL);
- m_applicationGraphicsFonts.append(QCFType<CGFontRef>::constructFromGet(cgFont));
- } else {
- NSLog(@"Unable to register font: %@", error);
- CFRelease(error);
+ if (CTFontManagerRegisterGraphicsFont(cgFont, &error)) {
+ QCFType<CTFontRef> font = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL);
+ fonts = createDescriptorArrayForFont(font);
+ m_applicationFonts.append(QVariant::fromValue(QCFType<CGFontRef>::constructFromGet(cgFont)));
}
- CGFontRelease(cgFont);
}
} else {
- CFErrorRef error;
QCFType<CFURLRef> fontURL = CFURLCreateWithFileSystemPath(NULL, QCFString(fileName), kCFURLPOSIXPathStyle, false);
- bool success = CTFontManagerRegisterFontsForURL(fontURL, kCTFontManagerScopeProcess, &error);
- if (success) {
- const void *keys[] = { kCTFontURLAttribute };
- const void *values[] = { fontURL };
- QCFType<CFDictionaryRef> attributes = CFDictionaryCreate(NULL, keys, values, 1,
- &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithAttributes(attributes);
- font = CTFontCreateWithFontDescriptor(descriptor, 0.0, NULL);
- m_applicationURLFonts.append(QCFType<CFURLRef>::constructFromGet(fontURL));
- } else {
- NSLog(@"Unable to register font: %@", error);
- CFRelease(error);
+ if (CTFontManagerRegisterFontsForURL(fontURL, kCTFontManagerScopeProcess, &error)) {
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_6, __IPHONE_7_0)
+ if (&CTFontManagerCreateFontDescriptorsFromURL)
+ fonts = CTFontManagerCreateFontDescriptorsFromURL(fontURL);
+ else
+#endif
+ {
+ // We're limited to a single font per file, unless we dive into the font tables
+ QCFType<CFMutableDictionaryRef> attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 1,
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionaryAddValue(attributes, kCTFontURLAttribute, fontURL);
+ QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithAttributes(attributes);
+ QCFType<CTFontRef> font = CTFontCreateWithFontDescriptor(descriptor, 0.0, NULL);
+ fonts = createDescriptorArrayForFont(font);
+ }
+
+ m_applicationFonts.append(QVariant::fromValue(QCFType<CFURLRef>::constructFromGet(fontURL)));
}
}
- if (font) {
- QStringList families;
- families.append(QCFString(CTFontCopyFamilyName(font)));
-
- QCFType<CTFontDescriptorRef> descriptor = CTFontCopyFontDescriptor(font);
- populateFromDescriptor(descriptor);
-
- CFRelease(font);
- return families;
+ if (error) {
+ NSLog(@"Unable to register font: %@", error);
+ CFRelease(error);
}
- } else
+ }
+#endif
+#if HAVE_CORETEXT && HAVE_ATS
+ else
#endif
+#if HAVE_ATS
{
- ATSFontContainerRef fontContainer;
- OSStatus e;
+ ATSFontContainerRef fontContainer;
+ OSStatus e;
- if (!fontData.isEmpty()) {
- e = ATSFontActivateFromMemory((void *) fontData.constData(), fontData.size(),
- kATSFontContextLocal, kATSFontFormatUnspecified, NULL,
- kATSOptionFlagsDefault, &fontContainer);
- } else {
- FSRef ref;
- OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref);
- if (qt_mac_create_fsref(fileName, &ref) != noErr)
- return QStringList();
- e = ATSFontActivateFromFileReference(&ref, kATSFontContextLocal, kATSFontFormatUnspecified, 0,
- kATSOptionFlagsDefault, &fontContainer);
- }
-
- if (e == noErr) {
- ItemCount fontCount = 0;
- e = ATSFontFindFromContainer(fontContainer, kATSOptionFlagsDefault, 0, 0, &fontCount);
- if (e != noErr)
- return QStringList();
-
- QVarLengthArray<ATSFontRef> containedFonts(fontCount);
- e = ATSFontFindFromContainer(fontContainer, kATSOptionFlagsDefault, fontCount, containedFonts.data(), &fontCount);
- if (e != noErr)
- return QStringList();
-
- QStringList families;
- for (int i = 0; i < containedFonts.size(); ++i) {
- QCFType<CTFontRef> font = CTFontCreateWithPlatformFont(containedFonts[i], 12.0, NULL, NULL);
- QCFType<CTFontDescriptorRef> descriptor = CTFontCopyFontDescriptor(font);
- populateFromDescriptor(descriptor);
- families.append(QCFString(CTFontCopyFamilyName(font)));
+ if (!fontData.isEmpty()) {
+ e = ATSFontActivateFromMemory((void *) fontData.constData(), fontData.size(),
+ kATSFontContextLocal, kATSFontFormatUnspecified, NULL,
+ kATSOptionFlagsDefault, &fontContainer);
+ } else {
+ FSRef ref;
+ OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref);
+ if (qt_mac_create_fsref(fileName, &ref) != noErr)
+ return QStringList();
+ e = ATSFontActivateFromFileReference(&ref, kATSFontContextLocal, kATSFontFormatUnspecified, 0,
+ kATSOptionFlagsDefault, &fontContainer);
}
- m_applicationFonts.append(fontContainer);
- return families;
+ if (e == noErr) {
+ ItemCount fontCount = 0;
+ e = ATSFontFindFromContainer(fontContainer, kATSOptionFlagsDefault, 0, 0, &fontCount);
+ if (e != noErr)
+ return QStringList();
+
+ QVarLengthArray<ATSFontRef> containedFonts(fontCount);
+ e = ATSFontFindFromContainer(fontContainer, kATSOptionFlagsDefault, fontCount, containedFonts.data(), &fontCount);
+ if (e != noErr)
+ return QStringList();
+
+ CFMutableArrayRef fontsArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ for (int i = 0; i < containedFonts.size(); ++i) {
+ QCFType<CTFontRef> font = CTFontCreateWithPlatformFont(containedFonts[i], 12.0, NULL, NULL);
+ CFArrayAppendValue(fontsArray, QCFType<CTFontDescriptorRef>(CTFontCopyFontDescriptor(font)));
+ }
+
+ fonts = fontsArray;
+
+ m_applicationFonts.append(QVariant::fromValue(fontContainer));
+ }
}
+#endif
+
+ if (fonts) {
+ const int numFonts = CFArrayGetCount(fonts);
+ for (int i = 0; i < numFonts; ++i) {
+ CTFontDescriptorRef fontDescriptor = CTFontDescriptorRef(CFArrayGetValueAtIndex(fonts, i));
+ populateFromDescriptor(fontDescriptor);
+ QCFType<CFStringRef> familyName = CFStringRef(CTFontDescriptorCopyLocalizedAttribute(fontDescriptor, kCTFontFamilyNameAttribute, NULL));
+ families.append(QCFString(familyName));
+ }
}
- return QStringList();
+ return families;
}
-#endif
QFont QCoreTextFontDatabase::defaultFont() const
{
@@ -596,25 +610,31 @@ QList<int> QCoreTextFontDatabase::standardSizes() const
void QCoreTextFontDatabase::removeApplicationFonts()
{
-#ifdef Q_OS_MACX
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
- if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
- CFErrorRef error;
- for (int i = 0; i < m_applicationGraphicsFonts.count(); ++i)
- CTFontManagerUnregisterGraphicsFont(m_applicationGraphicsFonts[i], &error);
- m_applicationGraphicsFonts.clear();
-
- for (int i = 0; i < m_applicationURLFonts.count(); ++i)
- CTFontManagerUnregisterFontsForURL(m_applicationURLFonts[i], kCTFontManagerScopeProcess, &error);
- m_applicationURLFonts.clear();
- } else
+ foreach (const QVariant &font, m_applicationFonts) {
+#if HAVE_CORETEXT
+ if (&CTFontManagerUnregisterGraphicsFont && &CTFontManagerUnregisterFontsForURL) {
+ CFErrorRef error;
+ if (font.canConvert(qMetaTypeId<QCFType<CGFontRef> >())) {
+ CTFontManagerUnregisterGraphicsFont(font.value<QCFType<CGFontRef> >(), &error);
+ } else if (font.canConvert(qMetaTypeId<QCFType<CFURLRef> >())) {
+ CTFontManagerUnregisterFontsForURL(font.value<QCFType<CFURLRef> >(), kCTFontManagerScopeProcess, &error);
+ }
+ }
#endif
- {
- for (int i = 0; i < m_applicationFonts.count(); ++i)
- ATSFontDeactivate(m_applicationFonts[i], 0, kATSOptionFlagsDoNotNotify);
+#if HAVE_CORETEXT && HAVE_ATS
+ else
+#endif
+#if HAVE_ATS
+ if (font.canConvert(qMetaTypeId<ATSFontContainerRef>())) {
+ ATSFontDeactivate(font.value<ATSFontContainerRef>(), 0, kATSOptionFlagsDoNotNotify);
+ }
+#endif
+ }
+
m_applicationFonts.clear();
+
+#if HAVE_ATS
ATSFontNotify(kATSFontNotifyActionFontsChanged, 0);
- }
#endif
}
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
index ee1016509b..1560d36644 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
@@ -42,6 +42,10 @@
#ifndef QCORETEXTFONTDATABASE_H
#define QCORETEXTFONTDATABASE_H
+#include <qglobal.h>
+#define HAVE_CORETEXT QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_8, __IPHONE_4_1)
+#define HAVE_ATS QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_5, __IPHONE_NA)
+
#include <qpa/qplatformfontdatabase.h>
#include <private/qcore_mac_p.h>
@@ -52,6 +56,14 @@
#include <CoreGraphics/CoreGraphics.h>
#endif
+#if HAVE_CORETEXT
+Q_DECLARE_METATYPE(QCFType<CGFontRef>);
+Q_DECLARE_METATYPE(QCFType<CFURLRef>);
+#endif
+#if HAVE_ATS
+Q_DECLARE_METATYPE(ATSFontContainerRef);
+#endif
+
QT_BEGIN_NAMESPACE
class QCoreTextFontDatabase : public QPlatformFontDatabase
@@ -60,12 +72,10 @@ public:
QCoreTextFontDatabase();
~QCoreTextFontDatabase();
void populateFontDatabase();
- QFontEngine *fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle);
+ 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;
-#ifdef Q_OS_MACX
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
-#endif
void releaseHandle(void *handle);
QFont defaultFont() const;
QList<int> standardSizes() const;
@@ -78,13 +88,8 @@ private:
mutable QHash<QString, QString> familyNameToPsName;
void removeApplicationFonts();
-#ifdef Q_OS_MACX
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
- QVector<QCFType<CGFontRef> > m_applicationGraphicsFonts;
- QVector<QCFType<CFURLRef> > m_applicationURLFonts;
-#endif
- QVector<ATSFontContainerRef> m_applicationFonts;
-#endif
+
+ QVector<QVariant> m_applicationFonts;
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 9b8f10f588..31a015ae9f 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -63,15 +63,12 @@ static void loadAdvancesForGlyphs(CTFontRef ctfont,
for (int i = 0; i < len; ++i) {
if (glyphs->glyphs[i] & 0xff000000)
continue;
- glyphs->advances_x[i] = QFixed::fromReal(advances[i].width);
- glyphs->advances_y[i] = QFixed::fromReal(advances[i].height);
+ glyphs->advances[i] = QFixed::fromReal(advances[i].width);
}
if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
- for (int i = 0; i < len; ++i) {
- glyphs->advances_x[i] = glyphs->advances_x[i].round();
- glyphs->advances_y[i] = glyphs->advances_y[i].round();
- }
+ for (int i = 0; i < len; ++i)
+ glyphs->advances[i] = glyphs->advances[i].round();
}
}
@@ -191,6 +188,8 @@ void QCoreTextFontEngine::init()
avgCharWidth = QFontEngine::averageCharWidth();
cache_cost = (CTFontGetAscent(ctfont) + CTFontGetDescent(ctfont)) * avgCharWidth.toInt() * 2000;
+
+ setUserData(QVariant::fromValue((void *)cgFont));
}
bool QCoreTextFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
@@ -228,15 +227,12 @@ bool QCoreTextFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *
for (int i = 0; i < glyph_pos; ++i) {
if (glyphs->glyphs[i] & 0xff000000)
continue;
- glyphs->advances_x[i] = QFixed::fromReal(advances[i].width);
- glyphs->advances_y[i] = QFixed::fromReal(advances[i].height);
+ glyphs->advances[i] = QFixed::fromReal(advances[i].width);
}
if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
- for (int i = 0; i < glyph_pos; ++i) {
- glyphs->advances_x[i] = glyphs->advances_x[i].round();
- glyphs->advances_y[i] = glyphs->advances_y[i].round();
- }
+ for (int i = 0; i < glyph_pos; ++i)
+ glyphs->advances[i] = glyphs->advances[i].round();
}
return true;
}