summaryrefslogtreecommitdiffstats
path: root/src/platformsupport
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@digia.com>2014-03-31 17:45:37 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-31 17:45:37 +0200
commitbd822bedfea5126b12c32523a68c3a1ac7a8931d (patch)
tree0fafd5ac037e3b62ad45e8808989ec89155618b4 /src/platformsupport
parent84c10500b1730e8d947732728d190fde612fc840 (diff)
parent3b5c0bc0780f1749fed7c07bd8b691400a0282b7 (diff)
Merge "Merge remote-tracking branch 'origin/stable' into dev" into refs/staging/dev
Diffstat (limited to 'src/platformsupport')
-rw-r--r--src/platformsupport/cglconvenience/cglconvenience.mm11
-rw-r--r--src/platformsupport/eglconvenience/eglconvenience.pri37
-rw-r--r--src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp1
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp189
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h1
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm49
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h1
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm31
8 files changed, 215 insertions, 105 deletions
diff --git a/src/platformsupport/cglconvenience/cglconvenience.mm b/src/platformsupport/cglconvenience/cglconvenience.mm
index 50c39a12e0..d0b0de8ae8 100644
--- a/src/platformsupport/cglconvenience/cglconvenience.mm
+++ b/src/platformsupport/cglconvenience/cglconvenience.mm
@@ -114,6 +114,14 @@ void *qcgl_createNSOpenGLPixelFormat(const QSurfaceFormat &format)
attrs << NSOpenGLPFAStencilSize << format.stencilBufferSize();
if (format.alphaBufferSize() > 0)
attrs << NSOpenGLPFAAlphaSize << format.alphaBufferSize();
+ if ((format.redBufferSize() > 0) &&
+ (format.greenBufferSize() > 0) &&
+ (format.blueBufferSize() > 0)) {
+ const int colorSize = format.redBufferSize() +
+ format.greenBufferSize() +
+ format.blueBufferSize();
+ attrs << NSOpenGLPFAColorSize << colorSize << NSOpenGLPFAMinimumPolicy;
+ }
if (format.samples() > 0) {
attrs << NSOpenGLPFAMultisample
@@ -121,6 +129,9 @@ void *qcgl_createNSOpenGLPixelFormat(const QSurfaceFormat &format)
<< NSOpenGLPFASamples << (NSOpenGLPixelFormatAttribute) format.samples();
}
+ if (format.stereo())
+ attrs << NSOpenGLPFAStereo;
+
attrs << NSOpenGLPFAAllowOfflineRenderers;
attrs << 0;
diff --git a/src/platformsupport/eglconvenience/eglconvenience.pri b/src/platformsupport/eglconvenience/eglconvenience.pri
index c026ff5a4b..7600cc952b 100644
--- a/src/platformsupport/eglconvenience/eglconvenience.pri
+++ b/src/platformsupport/eglconvenience/eglconvenience.pri
@@ -1,30 +1,33 @@
contains(QT_CONFIG,egl) {
HEADERS += \
$$PWD/qeglconvenience_p.h \
- $$PWD/qeglplatformcontext_p.h \
$$PWD/qeglpbuffer_p.h
SOURCES += \
$$PWD/qeglconvenience.cpp \
- $$PWD/qeglplatformcontext.cpp \
$$PWD/qeglpbuffer.cpp
- unix {
- HEADERS += \
- $$PWD/qeglplatformcursor_p.h \
- $$PWD/qeglplatformwindow_p.h \
- $$PWD/qeglplatformscreen_p.h \
- $$PWD/qeglcompositor_p.h \
- $$PWD/qeglplatformbackingstore_p.h \
- $$PWD/qeglplatformintegration_p.h
+ contains(QT_CONFIG,opengl) {
+ HEADERS += $$PWD/qeglplatformcontext_p.h
+ SOURCES += $$PWD/qeglplatformcontext.cpp
- SOURCES += \
- $$PWD/qeglplatformcursor.cpp \
- $$PWD/qeglplatformwindow.cpp \
- $$PWD/qeglplatformscreen.cpp \
- $$PWD/qeglcompositor.cpp \
- $$PWD/qeglplatformbackingstore.cpp \
- $$PWD/qeglplatformintegration.cpp
+ unix {
+ HEADERS += \
+ $$PWD/qeglplatformcursor_p.h \
+ $$PWD/qeglplatformwindow_p.h \
+ $$PWD/qeglplatformscreen_p.h \
+ $$PWD/qeglcompositor_p.h \
+ $$PWD/qeglplatformbackingstore_p.h \
+ $$PWD/qeglplatformintegration_p.h
+
+ SOURCES += \
+ $$PWD/qeglplatformcursor.cpp \
+ $$PWD/qeglplatformwindow.cpp \
+ $$PWD/qeglplatformscreen.cpp \
+ $$PWD/qeglcompositor.cpp \
+ $$PWD/qeglplatformbackingstore.cpp \
+ $$PWD/qeglplatformintegration.cpp
+ }
}
# Avoid X11 header collision
diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
index 1ed5ede3e8..88814151b6 100644
--- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
+++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
@@ -170,6 +170,7 @@ QFontEngine *QBasicFontDatabase::fontEngine(const QByteArray &fontData, qreal pi
{
QFontDef fontDef;
fontDef.pixelSize = pixelSize;
+ fontDef.hintingPreference = hintingPreference;
QFontEngineFTRawData *fe = new QFontEngineFTRawData(fontDef);
if (!fe->initFromData(fontData)) {
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index a9a85f1316..1a31400ea5 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -509,6 +509,74 @@ QFontEngineMulti *QFontconfigDatabase::fontEngineMulti(QFontEngine *fontEngine,
return new QFontEngineMultiFontConfig(fontEngine, script);
}
+namespace {
+QFontEngineFT::HintStyle defaultHintStyleFromMatch(QFont::HintingPreference hintingPreference, FcPattern *match)
+{
+ switch (hintingPreference) {
+ case QFont::PreferNoHinting:
+ return QFontEngineFT::HintNone;
+ case QFont::PreferVerticalHinting:
+ return QFontEngineFT::HintLight;
+ case QFont::PreferFullHinting:
+ return QFontEngineFT::HintFull;
+ case QFont::PreferDefaultHinting:
+ break;
+ }
+
+ const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services();
+ if (services && (services->desktopEnvironment() == "GNOME" || services->desktopEnvironment() == "UNITY")) {
+ void *hintStyleResource =
+ QGuiApplication::platformNativeInterface()->nativeResourceForScreen("hintstyle",
+ QGuiApplication::primaryScreen());
+ int hintStyle = int(reinterpret_cast<qintptr>(hintStyleResource));
+ if (hintStyle > 0)
+ return QFontEngine::HintStyle(hintStyle - 1);
+ }
+
+ int hint_style = 0;
+ if (FcPatternGetInteger (match, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch)
+ hint_style = FC_HINT_FULL;
+ switch (hint_style) {
+ case FC_HINT_NONE:
+ return QFontEngineFT::HintNone;
+ case FC_HINT_SLIGHT:
+ return QFontEngineFT::HintLight;
+ case FC_HINT_MEDIUM:
+ return QFontEngineFT::HintMedium;
+ case FC_HINT_FULL:
+ return QFontEngineFT::HintFull;
+ default:
+ Q_UNREACHABLE();
+ break;
+ }
+ return QFontEngineFT::HintFull;
+}
+
+QFontEngineFT::SubpixelAntialiasingType subpixelTypeFromMatch(FcPattern *match)
+{
+ int subpixel = FC_RGBA_UNKNOWN;
+ FcPatternGetInteger(match, FC_RGBA, 0, &subpixel);
+
+ switch (subpixel) {
+ case FC_RGBA_UNKNOWN:
+ case FC_RGBA_NONE:
+ return QFontEngineFT::Subpixel_None;
+ case FC_RGBA_RGB:
+ return QFontEngineFT::Subpixel_RGB;
+ case FC_RGBA_BGR:
+ return QFontEngineFT::Subpixel_BGR;
+ case FC_RGBA_VRGB:
+ return QFontEngineFT::Subpixel_VRGB;
+ case FC_RGBA_VBGR:
+ return QFontEngineFT::Subpixel_VBGR;
+ default:
+ Q_UNREACHABLE();
+ break;
+ }
+ return QFontEngineFT::Subpixel_None;
+}
+} // namespace
+
QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
{
if (!usrPtr)
@@ -548,39 +616,7 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
FcPattern *match = FcFontMatch(0, pattern, &result);
if (match) {
- QFontEngineFT::HintStyle default_hint_style;
- if (f.hintingPreference != QFont::PreferDefaultHinting) {
- switch (f.hintingPreference) {
- case QFont::PreferNoHinting:
- default_hint_style = QFontEngineFT::HintNone;
- break;
- case QFont::PreferVerticalHinting:
- default_hint_style = QFontEngineFT::HintLight;
- break;
- case QFont::PreferFullHinting:
- default:
- default_hint_style = QFontEngineFT::HintFull;
- break;
- }
- } else {
- int hint_style = 0;
- if (FcPatternGetInteger (match, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch)
- hint_style = QFontEngineFT::HintFull;
- switch (hint_style) {
- case FC_HINT_NONE:
- default_hint_style = QFontEngineFT::HintNone;
- break;
- case FC_HINT_SLIGHT:
- default_hint_style = QFontEngineFT::HintLight;
- break;
- case FC_HINT_MEDIUM:
- default_hint_style = QFontEngineFT::HintMedium;
- break;
- default:
- default_hint_style = QFontEngineFT::HintFull;
- break;
- }
- }
+ engine->setDefaultHintStyle(defaultHintStyleFromMatch((QFont::HintingPreference)f.hintingPreference, match));
if (antialias) {
// If antialiasing is not fully disabled, fontconfig may still disable it on a font match basis.
@@ -590,40 +626,13 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
antialias = fc_antialias;
}
- if (f.hintingPreference == QFont::PreferDefaultHinting) {
- const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services();
- if (services && (services->desktopEnvironment() == "GNOME" || services->desktopEnvironment() == "UNITY")) {
- void *hintStyleResource =
- QGuiApplication::platformNativeInterface()->nativeResourceForScreen("hintstyle",
- QGuiApplication::primaryScreen());
- int hintStyle = int(reinterpret_cast<qintptr>(hintStyleResource));
- if (hintStyle > 0)
- default_hint_style = QFontEngine::HintStyle(hintStyle - 1);
- }
- }
-
- engine->setDefaultHintStyle(default_hint_style);
-
if (antialias) {
- QFontEngineFT::SubpixelAntialiasingType subpixelType = QFontEngineFT::Subpixel_None;
- int subpixel = FC_RGBA_NONE;
-
- FcPatternGetInteger(match, FC_RGBA, 0, &subpixel);
- if (subpixel == FC_RGBA_UNKNOWN)
- subpixel = FC_RGBA_NONE;
-
- switch (subpixel) {
- case FC_RGBA_NONE: subpixelType = QFontEngineFT::Subpixel_None; break;
- case FC_RGBA_RGB: subpixelType = QFontEngineFT::Subpixel_RGB; break;
- case FC_RGBA_BGR: subpixelType = QFontEngineFT::Subpixel_BGR; break;
- case FC_RGBA_VRGB: subpixelType = QFontEngineFT::Subpixel_VRGB; break;
- case FC_RGBA_VBGR: subpixelType = QFontEngineFT::Subpixel_VBGR; break;
- default: break;
- }
-
- format = subpixelType == QFontEngineFT::Subpixel_None
- ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_A32;
+ QFontEngineFT::SubpixelAntialiasingType subpixelType = subpixelTypeFromMatch(match);
engine->subpixelType = subpixelType;
+
+ format = (subpixelType == QFontEngineFT::Subpixel_None)
+ ? QFontEngineFT::Format_A8
+ : QFontEngineFT::Format_A32;
} else
format = QFontEngineFT::Format_Mono;
@@ -641,6 +650,56 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
return engine;
}
+QFontEngine *QFontconfigDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
+{
+ QFontEngineFT *engine = static_cast<QFontEngineFT*>(QBasicFontDatabase::fontEngine(fontData, pixelSize, hintingPreference));
+ QFontDef fontDef = engine->fontDef;
+
+ QFontEngineFT::GlyphFormat format;
+ // try and get the pattern
+ FcPattern *pattern = FcPatternCreate();
+
+ FcValue value;
+ value.type = FcTypeString;
+ QByteArray cs = fontDef.family.toUtf8();
+ value.u.s = (const FcChar8 *)cs.data();
+ FcPatternAdd(pattern,FC_FAMILY,value,true);
+
+ FcResult result;
+
+ FcConfigSubstitute(0, pattern, FcMatchPattern);
+ FcDefaultSubstitute(pattern);
+
+ FcPattern *match = FcFontMatch(0, pattern, &result);
+ if (match) {
+ engine->setDefaultHintStyle(defaultHintStyleFromMatch(hintingPreference, match));
+
+ FcBool fc_antialias;
+ if (FcPatternGetBool(match, FC_ANTIALIAS,0, &fc_antialias) != FcResultMatch)
+ fc_antialias = true;
+ engine->antialias = fc_antialias;
+
+ if (engine->antialias) {
+ QFontEngineFT::SubpixelAntialiasingType subpixelType = subpixelTypeFromMatch(match);
+ engine->subpixelType = subpixelType;
+
+ format = subpixelType == QFontEngineFT::Subpixel_None
+ ? QFontEngineFT::Format_A8
+ : QFontEngineFT::Format_A32;
+ } else
+ format = QFontEngineFT::Format_Mono;
+ FcPatternDestroy(match);
+ } else
+ format = QFontEngineFT::Format_A8;
+
+ FcPatternDestroy(pattern);
+
+ engine->defaultFormat = format;
+ engine->glyphFormat = format;
+
+ return engine;
+}
+
QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
{
QStringList fallbackFamilies;
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
index 9f1fd28144..ba706dc59e 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
@@ -53,6 +53,7 @@ public:
void populateFontDatabase();
QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script);
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);
QString resolveFontFamilyAlias(const QString &family) const;
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index afee68ebed..1c0e888758 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -41,9 +41,11 @@
#include "qglobal.h"
-#ifdef Q_OS_MACX
+#if defined(Q_OS_MACX)
#import <Cocoa/Cocoa.h>
#import <IOKit/graphics/IOGraphicsLib.h>
+#elif defined(Q_OS_IOS)
+#import <UIKit/UIFont.h>
#endif
#include "qcoretextfontdatabase_p.h"
@@ -176,29 +178,50 @@ QCoreTextFontDatabase::~QCoreTextFontDatabase()
{
}
+static CFArrayRef availableFamilyNames()
+{
+#if defined(Q_OS_OSX)
+ return CTFontManagerCopyAvailableFontFamilyNames();
+#elif defined(Q_OS_IOS)
+ return (CFArrayRef) [[UIFont familyNames] retain];
+#endif
+}
+
void QCoreTextFontDatabase::populateFontDatabase()
{
// The caller (QFontDB) expects the db to be populate only with system fonts, so we need
// to make sure that any previously registered app fonts become invisible.
removeApplicationFonts();
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ QCFType<CFArrayRef> familyNames = availableFamilyNames();
+ const int numberOfFamilies = CFArrayGetCount(familyNames);
+ for (int i = 0; i < numberOfFamilies; ++i) {
+ QString familyName = QCFString::toQString((CFStringRef) CFArrayGetValueAtIndex(familyNames, i));
- QCFType<CTFontCollectionRef> collection = CTFontCollectionCreateFromAvailableFonts(0);
- if (! collection)
- return;
+ // Don't populate internal fonts
+ if (familyName.startsWith(QLatin1Char('.')) || familyName == QStringLiteral("LastResort"))
+ continue;
- QCFType<CFArrayRef> fonts = CTFontCollectionCreateMatchingFontDescriptors(collection);
- if (! fonts)
- return;
+ QPlatformFontDatabase::registerFontFamily(familyName);
+ }
+}
- const int numFonts = CFArrayGetCount(fonts);
- for (int i = 0; i < numFonts; ++i) {
- CTFontDescriptorRef font = (CTFontDescriptorRef) CFArrayGetValueAtIndex(fonts, i);
- populateFromDescriptor(font);
+void QCoreTextFontDatabase::populateFamily(const QString &familyName)
+{
+ CFMutableDictionaryRef attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, QCFString(familyName));
+ CTFontDescriptorRef nameOnlyDescriptor = CTFontDescriptorCreateWithAttributes(attributes);
+
+ // A single family might match several different fonts with different styles eg.
+ QCFType<CFArrayRef> matchingFonts = (CFArrayRef) CTFontDescriptorCreateMatchingFontDescriptors(nameOnlyDescriptor, 0);
+ if (!matchingFonts) {
+ qWarning() << "QCoreTextFontDatabase: Found no matching fonts for family" << familyName;
+ return;
}
- [pool release];
+ const int numFonts = CFArrayGetCount(matchingFonts);
+ for (int i = 0; i < numFonts; ++i)
+ populateFromDescriptor(CTFontDescriptorRef(CFArrayGetValueAtIndex(matchingFonts, i)));
}
void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font)
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
index c6fc791503..c73f4a32ca 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();
+ void populateFamily(const QString &familyName) Q_DECL_OVERRIDE;
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle);
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 3c30df6efb..0460f11139 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -50,6 +50,22 @@ QT_BEGIN_NAMESPACE
static float SYNTHETIC_ITALIC_SKEW = tanf(14 * acosf(0) / 90);
+static bool ct_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *length)
+{
+ CTFontRef ctfont = *(CTFontRef *)user_data;
+
+ QCFType<CFDataRef> table = CTFontCopyTable(ctfont, tag, 0);
+ if (!table)
+ return false;
+
+ CFIndex tableLength = CFDataGetLength(table);
+ if (buffer && int(*length) >= tableLength)
+ CFDataGetBytes(table, CFRangeMake(0, tableLength), buffer);
+ *length = tableLength;
+ Q_ASSERT(int(*length) > 0);
+ return true;
+}
+
static void loadAdvancesForGlyphs(CTFontRef ctfont,
QVarLengthArray<CGGlyph> &cgGlyphs,
QGlyphLayout *glyphs, int len,
@@ -191,7 +207,10 @@ void QCoreTextFontEngine::init()
cache_cost = (CTFontGetAscent(ctfont) + CTFontGetDescent(ctfont)) * avgCharWidth.toInt() * 2000;
- setUserData(QVariant::fromValue((void *)cgFont));
+ // HACK hb_coretext requires both CTFont and CGFont but user_data is only void*
+ Q_ASSERT((void *)(&ctfont + 1) == (void *)&cgFont);
+ faceData.user_data = &ctfont;
+ faceData.get_font_table = ct_getSfntTable;
}
glyph_t QCoreTextFontEngine::glyphIndex(uint ucs4) const
@@ -683,15 +702,7 @@ bool QCoreTextFontEngine::canRender(const QChar *string, int len) const
bool QCoreTextFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const
{
- QCFType<CFDataRef> table = CTFontCopyTable(ctfont, tag, 0);
- if (!table)
- return false;
- CFIndex tableLength = CFDataGetLength(table);
- if (buffer && int(*length) >= tableLength)
- CFDataGetBytes(table, CFRangeMake(0, tableLength), buffer);
- *length = tableLength;
- Q_ASSERT(int(*length) > 0);
- return true;
+ return ct_getSfntTable((void *)&ctfont, tag, buffer, length);
}
void QCoreTextFontEngine::getUnscaledGlyph(glyph_t, QPainterPath *, glyph_metrics_t *)