summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/text/qfont.cpp50
-rw-r--r--src/gui/text/qfont.h6
-rw-r--r--src/gui/text/qfont_p.h1
-rw-r--r--src/gui/text/qfontdatabase_mac.cpp142
-rw-r--r--src/gui/text/qfontdatabase_x11.cpp58
-rw-r--r--src/gui/text/qfontengine_coretext.mm22
-rw-r--r--src/gui/text/qfontengine_coretext_p.h4
-rw-r--r--src/gui/text/qfontengine_ft.cpp2
-rw-r--r--src/gui/text/qfontinfo.h1
-rw-r--r--src/gui/text/qrawfont.cpp13
-rw-r--r--src/gui/text/qrawfont.h1
11 files changed, 204 insertions, 96 deletions
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 90dd0293fc..d4c81b90db 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -348,6 +348,9 @@ void QFontPrivate::resolve(uint mask, const QFontPrivate *other)
if (! (mask & QFont::FamilyResolved))
request.family = other->request.family;
+ if (! (mask & QFont::StyleNameResolved))
+ request.styleName = other->request.styleName;
+
if (! (mask & QFont::SizeResolved)) {
request.pointSize = other->request.pointSize;
request.pixelSize = other->request.pixelSize;
@@ -897,6 +900,38 @@ void QFont::setFamily(const QString &family)
}
/*!
+ \since 4.8
+
+ Returns the requested font style name, it will be used to match the
+ font with irregular styles (that can't be normalized in other style
+ properties). It depends on system font support, thus only works for
+ Mac OS X and X11 so far. On Windows irregular styles will be added
+ as separate font families so there is no need for this.
+
+ \sa setFamily() setStyle()
+*/
+QString QFont::styleName() const
+{
+ return d->request.styleName;
+}
+
+/*!
+ \since 4.8
+
+ Sets the style name of the font. When set, other style properties
+ like \a style() and \a weight() will be ignored for font matching.
+
+ \sa styleName()
+*/
+void QFont::setStyleName(const QString &styleName)
+{
+ detach();
+
+ d->request.styleName = styleName;
+ resolve_mask |= QFont::StyleNameResolved;
+}
+
+/*!
Returns the point size of the font. Returns -1 if the font size
was specified in pixels.
@@ -2509,6 +2544,21 @@ QString QFontInfo::family() const
}
/*!
+ \since 4.8
+
+ Returns the style name of the matched window system font on
+ system that supports it.
+
+ \sa QFont::styleName()
+*/
+QString QFontInfo::styleName() const
+{
+ QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
+ Q_ASSERT(engine != 0);
+ return engine->fontDef.styleName;
+}
+
+/*!
Returns the point size of the matched window system font.
\sa pointSizeF() QFont::pointSize()
diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h
index 7636ecf910..14f290ceb3 100644
--- a/src/gui/text/qfont.h
+++ b/src/gui/text/qfont.h
@@ -156,7 +156,8 @@ public:
LetterSpacingResolved = 0x2000,
WordSpacingResolved = 0x4000,
HintingPreferenceResolved = 0x8000,
- AllPropertiesResolved = 0xffff
+ StyleNameResolved = 0x10000,
+ AllPropertiesResolved = 0x1ffff
};
QFont();
@@ -168,6 +169,9 @@ public:
QString family() const;
void setFamily(const QString &);
+ QString styleName() const;
+ void setStyleName(const QString &);
+
int pointSize() const;
void setPointSize(int);
qreal pointSizeF() const;
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index d36518ee4b..8eeae6ffc1 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -80,6 +80,7 @@ struct QFontDef
}
QString family;
+ QString styleName;
#ifdef Q_WS_X11
QString addStyle;
diff --git a/src/gui/text/qfontdatabase_mac.cpp b/src/gui/text/qfontdatabase_mac.cpp
index 6fdaf06c8b..724dbf6c4a 100644
--- a/src/gui/text/qfontdatabase_mac.cpp
+++ b/src/gui/text/qfontdatabase_mac.cpp
@@ -249,6 +249,63 @@ static inline float weightToFloat(unsigned int weight)
return (weight - 50) / 100.0;
}
+static QFontEngine *loadFromDatabase(const QFontDef &req, const QFontPrivate *d)
+{
+#if defined(QT_MAC_USE_COCOA)
+ QCFString fontName = NULL;
+#else
+ ATSFontFamilyRef familyRef = 0;
+ ATSFontRef fontRef = 0;
+#endif
+
+ QStringList family_list = familyList(req);
+
+ const char *stylehint = styleHint(req);
+ if (stylehint)
+ family_list << QLatin1String(stylehint);
+
+ // add QFont::defaultFamily() to the list, for compatibility with previous versions
+ family_list << QApplication::font().defaultFamily();
+
+ QMutexLocker locker(fontDatabaseMutex());
+ QFontDatabasePrivate *db = privateDb();
+ if (!db->count)
+ initializeDb();
+ for (int i = 0; i < family_list.size(); ++i) {
+ for (int k = 0; k < db->count; ++k) {
+ if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) {
+ QByteArray family_name = db->families[k]->name.toUtf8();
+#if defined(QT_MAC_USE_COCOA)
+ QCFType<CTFontRef> ctFont = CTFontCreateWithName(QCFString(db->families[k]->name), 12, NULL);
+ if (ctFont) {
+ fontName = CTFontCopyFullName(ctFont);
+ goto found;
+ }
+#else
+ familyRef = ATSFontFamilyFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
+ if (familyRef) {
+ fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
+ goto found;
+ }
+#endif
+ }
+ }
+ }
+found:
+#ifdef QT_MAC_USE_COCOA
+ if (fontName)
+ return new QCoreTextFontEngineMulti(fontName, req, d->kerning);
+#else
+ if (familyRef) {
+ QCFString actualName;
+ if (ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr)
+ req.family = actualName;
+ return new QFontEngineMacMulti(familyRef, req, fontDef, d->kerning);
+ }
+#endif
+ return NULL;
+}
+
void QFontDatabase::load(const QFontPrivate *d, int script)
{
// sanity checks
@@ -289,69 +346,38 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
return; // the font info and fontdef should already be filled
}
- //find the font
- QStringList family_list = familyList(req);
-
- const char *stylehint = styleHint(req);
- if (stylehint)
- family_list << QLatin1String(stylehint);
-
- // add QFont::defaultFamily() to the list, for compatibility with
- // previous versions
- family_list << QApplication::font().defaultFamily();
-
+ QFontEngine *engine = NULL;
#if defined(QT_MAC_USE_COCOA)
- QCFString fontName = NULL, familyName = NULL;
-#else
- ATSFontFamilyRef familyRef = 0;
- ATSFontRef fontRef = 0;
-#endif
-
- QMutexLocker locker(fontDatabaseMutex());
- QFontDatabasePrivate *db = privateDb();
- if (!db->count)
- initializeDb();
- for(int i = 0; i < family_list.size(); ++i) {
- for (int k = 0; k < db->count; ++k) {
- if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) {
- QByteArray family_name = db->families[k]->name.toUtf8();
-#if defined(QT_MAC_USE_COCOA)
- QCFType<CTFontRef> ctFont = CTFontCreateWithName(QCFString(db->families[k]->name), 12, NULL);
- if (ctFont) {
- fontName = CTFontCopyFullName(ctFont);
- familyName = CTFontCopyFamilyName(ctFont);
- goto FamilyFound;
- }
-#else
- familyRef = ATSFontFamilyFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
- if (familyRef) {
- fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
- goto FamilyFound;
- }
-#endif
+ // Shortcut to get the font directly without going through the font database
+ if (!req.family.isEmpty() && !req.styleName.isEmpty()) {
+ QCFString expectedFamily = QCFString(req.family);
+ QCFString expectedStyle = QCFString(req.styleName);
+
+ QCFType<CFMutableDictionaryRef> attributes = CFDictionaryCreateMutable(NULL, 0,
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, expectedFamily);
+ CFDictionaryAddValue(attributes, kCTFontStyleNameAttribute, expectedStyle);
+
+ QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithAttributes(attributes);
+ CGAffineTransform transform = qt_transform_from_fontdef(req);
+ QCFType<CTFontRef> ctFont = CTFontCreateWithFontDescriptor(descriptor, req.pixelSize, &transform);
+ if (ctFont) {
+ QCFString familyName = CTFontCopyFamilyName(ctFont);
+ // Only accept the font if the family name is exactly the same as we specified
+ if (CFEqual(expectedFamily, familyName)) {
+ engine = new QCoreTextFontEngineMulti(ctFont, req, d->kerning);
}
}
}
-FamilyFound:
- //fill in the engine's font definition
- QFontDef fontDef = d->request; //copy..
- if(fontDef.pointSize < 0)
- fontDef.pointSize = qt_mac_pointsize(fontDef, d->dpi);
- else
- fontDef.pixelSize = qt_mac_pixelsize(fontDef, d->dpi);
-
-#ifdef QT_MAC_USE_COCOA
- fontDef.family = familyName;
- QFontEngine *engine = new QCoreTextFontEngineMulti(fontName, fontDef, d->kerning);
-#else
- QCFString actualName;
- if (ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr)
- fontDef.family = actualName;
- QFontEngine *engine = new QFontEngineMacMulti(familyRef, fontRef, fontDef, d->kerning);
#endif
- d->engineData->engine = engine;
- engine->ref.ref(); //a ref for the engineData->engine
- QFontCache::instance()->insertEngine(key, engine);
+ if (!engine)
+ engine = loadFromDatabase(req, d);
+
+ if (engine) {
+ d->engineData->engine = engine;
+ engine->ref.ref();
+ QFontCache::instance()->insertEngine(key, engine);
+ }
}
static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp
index a5fdcb5216..754334c0c4 100644
--- a/src/gui/text/qfontdatabase_x11.cpp
+++ b/src/gui/text/qfontdatabase_x11.cpp
@@ -1452,6 +1452,35 @@ static const char *styleHint(const QFontDef &request)
void qt_addPatternProps(FcPattern *pattern, int screen, int script, const QFontDef &request)
{
+ double size_value = qMax(qreal(1.), request.pixelSize);
+ FcPatternDel(pattern, FC_PIXEL_SIZE);
+ FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size_value);
+
+ if (X11->display && QX11Info::appDepth(screen) <= 8) {
+ FcPatternDel(pattern, FC_ANTIALIAS);
+ // can't do antialiasing on 8bpp
+ FcPatternAddBool(pattern, FC_ANTIALIAS, false);
+ } else if (request.styleStrategy & (QFont::PreferAntialias|QFont::NoAntialias)) {
+ FcPatternDel(pattern, FC_ANTIALIAS);
+ FcPatternAddBool(pattern, FC_ANTIALIAS,
+ !(request.styleStrategy & QFont::NoAntialias));
+ }
+
+ if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') {
+ Q_ASSERT(script < QUnicodeTables::ScriptCount);
+ FcLangSet *ls = FcLangSetCreate();
+ FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
+ FcPatternDel(pattern, FC_LANG);
+ FcPatternAddLangSet(pattern, FC_LANG, ls);
+ FcLangSetDestroy(ls);
+ }
+
+ if (!request.styleName.isEmpty()) {
+ QByteArray cs = request.styleName.toUtf8();
+ FcPatternAddString(pattern, FC_STYLE, (const FcChar8 *) cs.constData());
+ return;
+ }
+
int weight_value = FC_WEIGHT_BLACK;
if (request.weight == 0)
weight_value = FC_WEIGHT_MEDIUM;
@@ -1474,34 +1503,11 @@ void qt_addPatternProps(FcPattern *pattern, int screen, int script, const QFontD
FcPatternDel(pattern, FC_SLANT);
FcPatternAddInteger(pattern, FC_SLANT, slant_value);
- double size_value = qMax(qreal(1.), request.pixelSize);
- FcPatternDel(pattern, FC_PIXEL_SIZE);
- FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size_value);
-
int stretch = request.stretch;
if (!stretch)
stretch = 100;
FcPatternDel(pattern, FC_WIDTH);
FcPatternAddInteger(pattern, FC_WIDTH, stretch);
-
- if (X11->display && QX11Info::appDepth(screen) <= 8) {
- FcPatternDel(pattern, FC_ANTIALIAS);
- // can't do antialiasing on 8bpp
- FcPatternAddBool(pattern, FC_ANTIALIAS, false);
- } else if (request.styleStrategy & (QFont::PreferAntialias|QFont::NoAntialias)) {
- FcPatternDel(pattern, FC_ANTIALIAS);
- FcPatternAddBool(pattern, FC_ANTIALIAS,
- !(request.styleStrategy & QFont::NoAntialias));
- }
-
- if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') {
- Q_ASSERT(script < QUnicodeTables::ScriptCount);
- FcLangSet *ls = FcLangSetCreate();
- FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
- FcPatternDel(pattern, FC_LANG);
- FcPatternAddLangSet(pattern, FC_LANG, ls);
- FcLangSetDestroy(ls);
- }
}
static bool preferScalable(const QFontDef &request)
@@ -2049,7 +2055,8 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
return;
FcPatternDel(pattern, FC_FILE);
- FcPatternAddString(pattern, FC_FILE, (const FcChar8 *)fnt->fileName.toUtf8().constData());
+ QByteArray cs = fnt->fileName.toUtf8();
+ FcPatternAddString(pattern, FC_FILE, (const FcChar8 *) cs.constData());
FcChar8 *fam = 0, *familylang = 0;
int i, n = 0;
@@ -2135,7 +2142,8 @@ QString QFontDatabase::resolveFontFamilyAlias(const QString &family)
if (!pattern)
return family;
- FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *) family.toUtf8().data());
+ QByteArray cs = family.toUtf8();
+ FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *) cs.constData());
FcConfigSubstitute(0, pattern, FcMatchPattern);
FcDefaultSubstitute(pattern);
diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm
index eedcc69a81..a68a1551d9 100644
--- a/src/gui/text/qfontengine_coretext.mm
+++ b/src/gui/text/qfontengine_coretext.mm
@@ -116,17 +116,11 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const
init(kerning);
}
-QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(CGFontRef cgFontRef, const QFontDef &fontDef, bool kerning)
+QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(CTFontRef ctFontRef, const QFontDef &fontDef, bool kerning)
: QFontEngineMulti(0)
{
this->fontDef = fontDef;
-
- transform = CGAffineTransformIdentity;
- if (fontDef.stretch != 100) {
- transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1);
- }
-
- ctfont = CTFontCreateWithGraphicsFont(cgFontRef, fontDef.pixelSize, &transform, NULL);
+ ctfont = (CTFontRef) CFRetain(ctFontRef);
init(kerning);
}
@@ -149,6 +143,9 @@ void QCoreTextFontEngineMulti::init(bool kerning)
}
QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef);
+ fontDef.family = fe->fontDef.family;
+ fontDef.styleName = fe->fontDef.styleName;
+ transform = fe->transform;
fe->ref.ref();
engines.append(fe);
}
@@ -405,7 +402,7 @@ void QCoreTextFontEngineMulti::loadEngine(int)
extern int qt_antialiasing_threshold; // from qapplication.cpp
-static inline CGAffineTransform transformFromFontDef(const QFontDef &fontDef)
+CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef)
{
CGAffineTransform transform = CGAffineTransformIdentity;
if (fontDef.stretch != 100)
@@ -416,7 +413,7 @@ static inline CGAffineTransform transformFromFontDef(const QFontDef &fontDef)
QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def)
{
fontDef = def;
- transform = transformFromFontDef(fontDef);
+ transform = qt_transform_from_fontdef(fontDef);
ctfont = font;
CFRetain(ctfont);
cgFont = CTFontCopyGraphicsFont(font, NULL);
@@ -426,7 +423,7 @@ QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def)
QCoreTextFontEngine::QCoreTextFontEngine(CGFontRef font, const QFontDef &def)
{
fontDef = def;
- transform = transformFromFontDef(fontDef);
+ transform = qt_transform_from_fontdef(fontDef);
cgFont = font;
// Keep reference count balanced
CFRetain(cgFont);
@@ -464,6 +461,9 @@ void QCoreTextFontEngine::init()
QCFString family = CTFontCopyFamilyName(ctfont);
fontDef.family = family;
+ QCFString styleName = (CFStringRef) CTFontCopyAttribute(ctfont, kCTFontStyleNameAttribute);
+ fontDef.styleName = styleName;
+
synthesisFlags = 0;
CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont);
if (traits & kCTFontItalicTrait)
diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h
index 98d3b50c66..3ca8a0ad60 100644
--- a/src/gui/text/qfontengine_coretext_p.h
+++ b/src/gui/text/qfontengine_coretext_p.h
@@ -113,7 +113,7 @@ class QCoreTextFontEngineMulti : public QFontEngineMulti
{
public:
QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning);
- QCoreTextFontEngineMulti(CGFontRef cgFontRef, const QFontDef &fontDef, bool kerning);
+ QCoreTextFontEngineMulti(CTFontRef ctFontRef, const QFontDef &fontDef, bool kerning);
~QCoreTextFontEngineMulti();
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
@@ -141,6 +141,8 @@ private:
friend class QFontDialogPrivate;
};
+CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef);
+
#endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
#endif // QFONTENGINE_CORETEXT_P_H
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 39abbd6f58..9a5d9d6f2e 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -758,6 +758,8 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
}
#endif
+ fontDef.styleName = QString::fromUtf8(face->style_name);
+
unlockFace();
fsType = freetype->fsType();
diff --git a/src/gui/text/qfontinfo.h b/src/gui/text/qfontinfo.h
index 1238cba4da..37a724ec7c 100644
--- a/src/gui/text/qfontinfo.h
+++ b/src/gui/text/qfontinfo.h
@@ -61,6 +61,7 @@ public:
QFontInfo &operator=(const QFontInfo &);
QString family() const;
+ QString styleName() const;
int pixelSize() const;
int pointSize() const;
qreal pointSizeF() const;
diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp
index 481180ec78..71762df09f 100644
--- a/src/gui/text/qrawfont.cpp
+++ b/src/gui/text/qrawfont.cpp
@@ -404,6 +404,19 @@ QString QRawFont::familyName() const
}
/*!
+ Returns the style name of this QRawFont.
+
+ \sa QFont::styleName()
+*/
+QString QRawFont::styleName() const
+{
+ if (!isValid())
+ return QString();
+
+ return d->fontEngine->fontDef.styleName;
+}
+
+/*!
Returns the style of this QRawFont.
\sa QFont::style()
diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h
index 3857da35e0..aca33af127 100644
--- a/src/gui/text/qrawfont.h
+++ b/src/gui/text/qrawfont.h
@@ -84,6 +84,7 @@ public:
bool operator==(const QRawFont &other) const;
QString familyName() const;
+ QString styleName() const;
QFont::Style style() const;
int weight() const;