summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gui/text/freetype/qfontengine_ft.cpp44
-rw-r--r--src/gui/text/freetype/qfontengine_ft_p.h2
-rw-r--r--src/gui/text/unix/qfontconfigdatabase.cpp59
3 files changed, 83 insertions, 22 deletions
diff --git a/src/gui/text/freetype/qfontengine_ft.cpp b/src/gui/text/freetype/qfontengine_ft.cpp
index 66a46d18cd9..3d41cfda0aa 100644
--- a/src/gui/text/freetype/qfontengine_ft.cpp
+++ b/src/gui/text/freetype/qfontengine_ft.cpp
@@ -278,6 +278,13 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id,
}
#endif
newFreetype->face = face;
+ newFreetype->mm_var = nullptr;
+ if (FT_IS_NAMED_INSTANCE(newFreetype->face)) {
+ FT_Error ftresult;
+ ftresult = FT_Get_MM_Var(face, &newFreetype->mm_var);
+ if (ftresult != FT_Err_Ok)
+ newFreetype->mm_var = nullptr;
+ }
newFreetype->ref.storeRelaxed(1);
newFreetype->xsize = 0;
@@ -351,6 +358,9 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id,
void QFreetypeFace::cleanup()
{
hbFace.reset();
+ if (mm_var && face && face->glyph)
+ FT_Done_MM_Var(face->glyph->library, mm_var);
+ mm_var = nullptr;
FT_Done_Face(face);
face = nullptr;
}
@@ -818,16 +828,13 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
static void dont_delete(void*) {}
-static FT_UShort calculateActualWeight(FT_Face face, QFontEngine::FaceId faceId)
+static FT_UShort calculateActualWeight(QFreetypeFace *freetypeFace, FT_Face face, QFontEngine::FaceId faceId)
{
- if (faceId.instanceIndex >= 0) {
- FT_MM_Var *var = nullptr;
- FT_Get_MM_Var(face, &var);
- if (var != nullptr && FT_UInt(faceId.instanceIndex) < var->num_namedstyles) {
- for (FT_UInt axis = 0; axis < var->num_axis; ++axis) {
- if (var->axis[axis].tag == QFont::Tag("wght").value()) {
- return var->namedstyle[faceId.instanceIndex].coords[axis] >> 16;
- }
+ FT_MM_Var *var = freetypeFace->mm_var;
+ if (var != nullptr && faceId.instanceIndex >= 0 && FT_UInt(faceId.instanceIndex) < var->num_namedstyles) {
+ for (FT_UInt axis = 0; axis < var->num_axis; ++axis) {
+ if (var->axis[axis].tag == QFont::Tag("wght").value()) {
+ return var->namedstyle[faceId.instanceIndex].coords[axis] >> 16;
}
}
}
@@ -838,16 +845,13 @@ static FT_UShort calculateActualWeight(FT_Face face, QFontEngine::FaceId faceId)
return 700;
}
-static bool calculateActualItalic(FT_Face face, QFontEngine::FaceId faceId)
+static bool calculateActualItalic(QFreetypeFace *freetypeFace, FT_Face face, QFontEngine::FaceId faceId)
{
- if (faceId.instanceIndex >= 0) {
- FT_MM_Var *var = nullptr;
- FT_Get_MM_Var(face, &var);
- if (var != nullptr && FT_UInt(faceId.instanceIndex) < var->num_namedstyles) {
- for (FT_UInt axis = 0; axis < var->num_axis; ++axis) {
- if (var->axis[axis].tag == QFont::Tag("ital").value()) {
- return (var->namedstyle[faceId.instanceIndex].coords[axis] >> 16) == 1;
- }
+ FT_MM_Var *var = freetypeFace->mm_var;
+ if (var != nullptr && faceId.instanceIndex >= 0 && FT_UInt(faceId.instanceIndex) < var->num_namedstyles) {
+ for (FT_UInt axis = 0; axis < var->num_axis; ++axis) {
+ if (var->axis[axis].tag == QFont::Tag("ital").value()) {
+ return (var->namedstyle[faceId.instanceIndex].coords[axis] >> 16) == 1;
}
}
}
@@ -886,7 +890,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
FT_Face face = lockFace();
if (FT_IS_SCALABLE(face)) {
- bool isItalic = calculateActualItalic(face, faceId);
+ bool isItalic = calculateActualItalic(freetype, face, faceId);
bool fake_oblique = (fontDef.style != QFont::StyleNormal) && !isItalic && !qEnvironmentVariableIsSet("QT_NO_SYNTHESIZED_ITALIC");
if (fake_oblique)
obliquen = true;
@@ -894,7 +898,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
freetype->matrix = matrix;
// fake bold
if ((fontDef.weight >= QFont::Bold) && !(face->style_flags & FT_STYLE_FLAG_BOLD) && !FT_IS_FIXED_WIDTH(face) && !qEnvironmentVariableIsSet("QT_NO_SYNTHESIZED_BOLD")) {
- FT_UShort actualWeight = calculateActualWeight(face, faceId);
+ FT_UShort actualWeight = calculateActualWeight(freetype, face, faceId);
if (actualWeight < 700 &&
(fontDef.pixelSize < 64 || qEnvironmentVariableIsSet("QT_NO_SYNTHESIZED_BOLD_LIMIT"))) {
embolden = true;
diff --git a/src/gui/text/freetype/qfontengine_ft_p.h b/src/gui/text/freetype/qfontengine_ft_p.h
index b6315a37d3e..9245a271adc 100644
--- a/src/gui/text/freetype/qfontengine_ft_p.h
+++ b/src/gui/text/freetype/qfontengine_ft_p.h
@@ -19,6 +19,7 @@
#include <ft2build.h>
#include FT_FREETYPE_H
+#include FT_MULTIPLE_MASTERS_H
#ifndef Q_OS_WIN
@@ -62,6 +63,7 @@ public:
}
FT_Face face;
+ FT_MM_Var *mm_var;
int xsize; // 26.6
int ysize; // 26.6
FT_Matrix matrix;
diff --git a/src/gui/text/unix/qfontconfigdatabase.cpp b/src/gui/text/unix/qfontconfigdatabase.cpp
index a0b1abd14a9..46e8f5724aa 100644
--- a/src/gui/text/unix/qfontconfigdatabase.cpp
+++ b/src/gui/text/unix/qfontconfigdatabase.cpp
@@ -575,6 +575,12 @@ void QFontconfigDatabase::populateFontDatabase()
FcObjectSetAdd(os, *p);
++p;
}
+
+#ifdef FC_VARIABLE
+ /* Support the named instance of Variable Fonts. */
+ FcPatternAddBool(pattern, FC_VARIABLE, FcFalse);
+#endif
+
fonts = FcFontList(nullptr, pattern, os);
FcObjectSetDestroy(os);
FcPatternDestroy(pattern);
@@ -974,6 +980,7 @@ void QFontconfigDatabase::setupFontEngine(QFontEngineFT *engine, const QFontDef
QFontEngine::GlyphFormat format;
// try and get the pattern
FcPattern *pattern = FcPatternCreate();
+ FcPattern *match = nullptr;
FcValue value;
value.type = FcTypeString;
@@ -992,7 +999,7 @@ void QFontconfigDatabase::setupFontEngine(QFontEngineFT *engine, const QFontDef
FcPatternAdd(pattern,FC_INDEX,value,true);
}
- if (fontDef.pixelSize > 0.1)
+ if (!qFuzzyIsNull(fontDef.pixelSize))
FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontDef.pixelSize);
FcResult result;
@@ -1000,7 +1007,55 @@ void QFontconfigDatabase::setupFontEngine(QFontEngineFT *engine, const QFontDef
FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
FcDefaultSubstitute(pattern);
- FcPattern *match = FcFontMatch(nullptr, pattern, &result);
+#ifdef FC_VARIABLE
+ if (!fid.filename.isEmpty()) {
+ // FC_INDEX is ignored during processing in FcFontMatch.
+ // So iterate FcPatterns directly and find it out.
+ FcFontSet *fcsets[2], *fcfs;
+
+ fcsets[0] = FcConfigGetFonts(nullptr, FcSetSystem);
+ fcsets[1] = FcConfigGetFonts(nullptr, FcSetApplication);
+ for (int nset = 0; nset < 2; nset++) {
+ fcfs = fcsets[nset];
+ if (fcfs == nullptr)
+ continue;
+ for (int fnum = 0; fnum < fcfs->nfont; fnum++) {
+ FcPattern *fcpat = fcfs->fonts[fnum];
+ FcChar8 *fcfile;
+ FcBool variable;
+ double fcpixelsize;
+ int fcindex;
+
+ // Skip the variable font itself, only to use the named instances and normal fonts here
+ if (FcPatternGetBool(fcpat, FC_VARIABLE, 0, &variable) == FcResultMatch &&
+ variable == FcTrue)
+ continue;
+
+ if (!qFuzzyIsNull(fontDef.pixelSize)) {
+ if (FcPatternGetDouble(fcpat, FC_PIXEL_SIZE, 0, &fcpixelsize) == FcResultMatch &&
+ fontDef.pixelSize != fcpixelsize)
+ continue;
+ }
+
+ if (FcPatternGetString(fcpat, FC_FILE, 0, &fcfile) == FcResultMatch &&
+ FcPatternGetInteger(fcpat, FC_INDEX, 0, &fcindex) == FcResultMatch) {
+ QByteArray f = QByteArray::fromRawData((const char *)fcfile,
+ qstrlen((const char *)fcfile));
+ if (f == fid.filename && fcindex == fid.index) {
+ // We found it.
+ match = FcFontRenderPrepare(nullptr, pattern, fcpat);
+ goto bail;
+ }
+ }
+ }
+ }
+ }
+bail:
+#endif
+
+ if (!match)
+ match = FcFontMatch(nullptr, pattern, &result);
+
if (match) {
engine->setDefaultHintStyle(defaultHintStyleFromMatch((QFont::HintingPreference)fontDef.hintingPreference, match, useXftConf));