diff --git a/src/gui/text/coretext/qcoretextfontdatabase.mm b/src/gui/text/coretext/qcoretextfontdatabase.mm index baf2803d570..0301b2e61e0 100644 --- a/src/gui/text/coretext/qcoretextfontdatabase.mm +++ b/src/gui/text/coretext/qcoretextfontdatabase.mm @@ -361,7 +361,7 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd) fd->fixedPitch = false; if (QCFType tempFont = CTFontCreateWithFontDescriptor(font, 0.0, 0)) { - uint tag = MAKE_TAG('O', 'S', '/', '2'); + uint tag = QFont::Tag("OS/2").value(); CTFontRef tempFontRef = tempFont; void *userData = reinterpret_cast(&tempFontRef); uint length = 128; diff --git a/src/gui/text/coretext/qfontengine_coretext.mm b/src/gui/text/coretext/qfontengine_coretext.mm index 6cdba2609dc..1ba1c739762 100644 --- a/src/gui/text/coretext/qfontengine_coretext.mm +++ b/src/gui/text/coretext/qfontengine_coretext.mm @@ -232,7 +232,7 @@ void QCoreTextFontEngine::init() synthesisFlags |= SynthesizedItalic; avgCharWidth = 0; - QByteArray os2Table = getSfntTable(MAKE_TAG('O', 'S', '/', '2')); + QByteArray os2Table = getSfntTable(QFont::Tag("OS/2").value()); unsigned emSize = CTFontGetUnitsPerEm(ctfont); if (os2Table.size() >= 10) { fsType = qFromBigEndian(os2Table.constData() + 8); diff --git a/src/gui/text/freetype/qfontengine_ft.cpp b/src/gui/text/freetype/qfontengine_ft.cpp index f3a80d925d5..3c01392e46b 100644 --- a/src/gui/text/freetype/qfontengine_ft.cpp +++ b/src/gui/text/freetype/qfontengine_ft.cpp @@ -767,7 +767,7 @@ static FT_UShort calculateActualWeight(FT_Face face, QFontEngine::FaceId faceId) 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 == MAKE_TAG('w', 'g', 'h', 't')) { + if (var->axis[axis].tag == QFont::Tag("wght").value()) { return var->namedstyle[faceId.instanceIndex].coords[axis] >> 16; } } @@ -787,7 +787,7 @@ static bool calculateActualItalic(FT_Face face, QFontEngine::FaceId faceId) 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 == MAKE_TAG('i', 't', 'a', 'l')) { + if (var->axis[axis].tag == QFont::Tag("ital").value()) { return (var->namedstyle[faceId.instanceIndex].coords[axis] >> 16) == 1; } } diff --git a/src/gui/text/freetype/qfreetypefontdatabase.cpp b/src/gui/text/freetype/qfreetypefontdatabase.cpp index df64d2ce90f..f7d592a761c 100644 --- a/src/gui/text/freetype/qfreetypefontdatabase.cpp +++ b/src/gui/text/freetype/qfreetypefontdatabase.cpp @@ -114,11 +114,11 @@ void QFreeTypeFontDatabase::addNamedInstancesForFace(void *face_, QFont::Stretch instanceStretch = stretch; QFont::Style instanceStyle = style; for (FT_UInt axis = 0; axis < var->num_axis; ++axis) { - if (var->axis[axis].tag == MAKE_TAG('w', 'g', 'h', 't')) { + if (var->axis[axis].tag == QFont::Tag("wght").value()) { instanceWeight = QFont::Weight(var->namedstyle[i].coords[axis] >> 16); - } else if (var->axis[axis].tag == MAKE_TAG('w', 'd', 't', 'h')) { + } else if (var->axis[axis].tag == QFont::Tag("wdth").value()) { instanceStretch = QFont::Stretch(var->namedstyle[i].coords[axis] >> 16); - } else if (var->axis[axis].tag == MAKE_TAG('i', 't', 'a', 'l')) { + } else if (var->axis[axis].tag == QFont::Tag("ital").value()) { FT_UInt ital = var->namedstyle[i].coords[axis] >> 16; if (ital == 1) instanceStyle = QFont::StyleItalic; diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index d144a8d79a5..04ead4468ed 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -2508,12 +2508,9 @@ void QFont::clearFeatures() */ QByteArray QFont::tagToString(quint32 tag) { - char str[4] = - { char((tag & 0xff000000) >> 24), - char((tag & 0x00ff0000) >> 16), - char((tag & 0x0000ff00) >> 8), - char((tag & 0x000000ff)) }; - return QByteArray(str, 4); + if (auto maybeTag = QFont::Tag::fromValue(tag)) + return maybeTag->toString(); + return {}; } /*! @@ -2531,10 +2528,9 @@ QByteArray QFont::tagToString(quint32 tag) */ quint32 QFont::stringToTag(const char *name) { - if (qstrlen(name) != 4) - return 0; - - return MAKE_TAG(name[0], name[1], name[2], name[3]); + if (auto maybeTag = QFont::Tag::fromString(name)) + return maybeTag->value(); + return 0; } extern QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style, diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 8f2336f2ace..ca9dc6afc9d 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -182,8 +182,10 @@ bool QFontEngine::supportsScript(QChar::Script script) const #if QT_CONFIG(harfbuzz) // in AAT fonts, 'gsub' table is effectively replaced by 'mort'/'morx' table uint lenMort = 0, lenMorx = 0; - if (getSfntTableData(MAKE_TAG('m','o','r','t'), nullptr, &lenMort) || getSfntTableData(MAKE_TAG('m','o','r','x'), nullptr, &lenMorx)) + if (getSfntTableData(QFont::Tag("mort").value(), nullptr, &lenMort) + || getSfntTableData(QFont::Tag("morx").value(), nullptr, &lenMorx)) { return true; + } if (hb_face_t *face = hb_qt_face_get_for_engine(const_cast(this))) { unsigned int script_count = HB_OT_MAX_TAGS_PER_SCRIPT; @@ -381,7 +383,7 @@ void QFontEngine::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rig bool QFontEngine::processHheaTable() const { - QByteArray hhea = getSfntTable(MAKE_TAG('h', 'h', 'e', 'a')); + QByteArray hhea = getSfntTable(QFont::Tag("hhea").value()); if (hhea.size() >= 10) { auto ptr = hhea.constData(); qint16 ascent = qFromBigEndian(ptr + 4); @@ -407,9 +409,9 @@ bool QFontEngine::processHheaTable() const void QFontEngine::initializeHeightMetrics() const { bool hasEmbeddedBitmaps = - !getSfntTable(MAKE_TAG('E', 'B', 'L', 'C')).isEmpty() - || !getSfntTable(MAKE_TAG('C', 'B', 'L', 'C')).isEmpty() - || !getSfntTable(MAKE_TAG('b', 'd', 'a', 't')).isEmpty(); + !getSfntTable(QFont::Tag("EBLC").value()).isEmpty() + || !getSfntTable(QFont::Tag("CBLC").value()).isEmpty() + || !getSfntTable(QFont::Tag("bdat").value()).isEmpty(); if (!hasEmbeddedBitmaps) { // Get HHEA table values if available processHheaTable(); @@ -429,7 +431,7 @@ void QFontEngine::initializeHeightMetrics() const bool QFontEngine::processOS2Table() const { - QByteArray os2 = getSfntTable(MAKE_TAG('O', 'S', '/', '2')); + QByteArray os2 = getSfntTable(QFont::Tag("OS/2").value()); if (os2.size() >= 78) { auto ptr = os2.constData(); quint16 fsSelection = qFromBigEndian(ptr + 62); @@ -505,7 +507,7 @@ qreal QFontEngine::minRightBearing() const if (m_minRightBearing == kBearingNotInitialized) { // Try the 'hhea' font table first, which covers the entire font - QByteArray hheaTable = getSfntTable(MAKE_TAG('h', 'h', 'e', 'a')); + QByteArray hheaTable = getSfntTable(QFont::Tag("hhea").value()); if (hheaTable.size() >= int(kMinRightSideBearingOffset + sizeof(qint16))) { const uchar *tableData = reinterpret_cast(hheaTable.constData()); Q_ASSERT(q16Dot16ToFloat(qFromBigEndian(tableData)) == 1.0); @@ -1045,7 +1047,7 @@ void QFontEngine::loadKerningPairs(QFixed scalingFactor) { kerning_pairs.clear(); - QByteArray tab = getSfntTable(MAKE_TAG('k', 'e', 'r', 'n')); + QByteArray tab = getSfntTable(QFont::Tag("kern").value()); if (tab.isEmpty()) return; @@ -1134,7 +1136,7 @@ end: int QFontEngine::glyphCount() const { - QByteArray maxpTable = getSfntTable(MAKE_TAG('m', 'a', 'x', 'p')); + QByteArray maxpTable = getSfntTable(QFont::Tag("maxp").value()); if (maxpTable.size() < 6) return 0; diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index bf6514a0bdd..1b79ffd14a0 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -29,13 +29,6 @@ class QFontEngineGlyphCache; struct QGlyphLayout; -#define MAKE_TAG(ch1, ch2, ch3, ch4) (\ - (((quint32)(ch1)) << 24) | \ - (((quint32)(ch2)) << 16) | \ - (((quint32)(ch3)) << 8) | \ - ((quint32)(ch4)) \ - ) - // ### this only used in getPointInOutline(), refactor it and then remove these magic numbers enum HB_Compat_Error { Err_Ok = 0x0000, diff --git a/src/gui/text/qfontsubset.cpp b/src/gui/text/qfontsubset.cpp index a8efecce8c9..f6c973e5229 100644 --- a/src/gui/text/qfontsubset.cpp +++ b/src/gui/text/qfontsubset.cpp @@ -401,7 +401,7 @@ static QTtfTable generateHead(const qttf_head_table &head) { const int head_size = 54; QTtfTable t; - t.tag = MAKE_TAG('h', 'e', 'a', 'd'); + t.tag = QFont::Tag("head").value(); t.data.resize(head_size); QTtfStream s(t.data); @@ -472,7 +472,7 @@ static QTtfTable generateHhea(const qttf_hhea_table &hhea) { const int hhea_size = 36; QTtfTable t; - t.tag = MAKE_TAG('h', 'h', 'e', 'a'); + t.tag = QFont::Tag("hhea").value(); t.data.resize(hhea_size); QTtfStream s(t.data); @@ -523,7 +523,7 @@ static QTtfTable generateMaxp(const qttf_maxp_table &maxp) { const int maxp_size = 32; QTtfTable t; - t.tag = MAKE_TAG('m', 'a', 'x', 'p'); + t.tag = QFont::Tag("maxp").value(); t.data.resize(maxp_size); QTtfStream s(t.data); @@ -603,7 +603,7 @@ static QTtfTable generateName(const QList &name) const int char_size = 2; QTtfTable t; - t.tag = MAKE_TAG('n', 'a', 'm', 'e'); + t.tag = QFont::Tag("name").value(); const int name_size = 6 + 12*name.size(); int string_size = 0; @@ -958,15 +958,15 @@ static QList generateGlyphTables(qttf_font_tables &tables, const QLis tables.hhea.numberOfHMetrics = nGlyphs; QTtfTable glyf; - glyf.tag = MAKE_TAG('g', 'l', 'y', 'f'); + glyf.tag = QFont::Tag("glyf").value(); QTtfTable loca; - loca.tag = MAKE_TAG('l', 'o', 'c', 'a'); + loca.tag = QFont::Tag("loca").value(); loca.data.resize(glyf_size < max_size_small ? (nGlyphs+1)*sizeof(quint16) : (nGlyphs+1)*sizeof(quint32)); QTtfStream ls(loca.data); QTtfTable hmtx; - hmtx.tag = MAKE_TAG('h', 'm', 't', 'x'); + hmtx.tag = QFont::Tag("hmtx").value(); hmtx.data.resize(nGlyphs*4); QTtfStream hs(hmtx.data); @@ -1066,7 +1066,7 @@ static QByteArray bindFont(const QList& _tables) for (int i = 0; i < tables.size(); ++i) { const QTtfTable &t = tables.at(i); const quint32 size = (t.data.size() + 3) & ~3; - if (t.tag == MAKE_TAG('h', 'e', 'a', 'd')) + if (t.tag == QFont::Tag("head").value()) head_offset = table_offset; f << t.tag << checksum(t.data) @@ -1186,7 +1186,7 @@ QByteArray QFontSubset::toTruetype() const tables.append(generateMaxp(font.maxp)); // name QTtfTable name_table; - name_table.tag = MAKE_TAG('n', 'a', 'm', 'e'); + name_table.tag = QFont::Tag("name").value(); if (!noEmbed) name_table.data = fontEngine->getSfntTable(name_table.tag); if (name_table.data.isEmpty()) { @@ -1204,7 +1204,7 @@ QByteArray QFontSubset::toTruetype() const if (!noEmbed) { QTtfTable os2; - os2.tag = MAKE_TAG('O', 'S', '/', '2'); + os2.tag = QFont::Tag("OS/2").value(); os2.data = fontEngine->getSfntTable(os2.tag); if (!os2.data.isEmpty()) tables.append(os2); diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index e58f9187e9e..99cd87f1b27 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -642,7 +642,9 @@ QByteArray QRawFont::fontTable(const char *tagName) const if (!d->isValid()) return QByteArray(); - return d->fontEngine->getSfntTable(MAKE_TAG(tagName[0], tagName[1], tagName[2], tagName[3])); + if (auto maybeTag = QFont::Tag::fromString(tagName)) + return d->fontEngine->getSfntTable(maybeTag->value()); + return {}; } /*! diff --git a/src/gui/text/windows/qwindowsfontengine.cpp b/src/gui/text/windows/qwindowsfontengine.cpp index 1f24cc85c59..fe078973696 100644 --- a/src/gui/text/windows/qwindowsfontengine.cpp +++ b/src/gui/text/windows/qwindowsfontengine.cpp @@ -104,7 +104,7 @@ void QWindowsFontEngine::getCMap() SelectObject(hdc, hfont); bool symb = false; if (ttf) { - cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p')); + cmapTable = getSfntTable(QFont::Tag("cmap").value()); cmap = QFontEngine::getCMap(reinterpret_cast(cmapTable.constData()), cmapTable.size(), &symb, &cmapSize); } @@ -471,7 +471,7 @@ namespace { QFixed QWindowsFontEngine::capHeight() const { - const QByteArray tableData = getSfntTable(MAKE_TAG('O', 'S', '/', '2')); + const QByteArray tableData = getSfntTable(QFont::Tag("OS/2").value()); if (size_t(tableData.size()) >= sizeof(OS2Table)) { const OS2Table *table = reinterpret_cast(tableData.constData()); if (qFromBigEndian(table->version) >= 2) { diff --git a/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp b/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp index 9c4ca33f91c..a93cf16594f 100644 --- a/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp @@ -359,7 +359,7 @@ void QWindowsFontEngineDirectWrite::collectMetrics() fontFile->Release(); } - QByteArray table = getSfntTable(MAKE_TAG('h', 'h', 'e', 'a')); + QByteArray table = getSfntTable(QFont::Tag("hhea").value()); const int advanceWidthMaxLocation = 10; if (table.size() >= advanceWidthMaxLocation + int(sizeof(quint16))) { quint16 advanceWidthMax = qFromBigEndian(table.constData() + advanceWidthMaxLocation); diff --git a/tests/manual/fontfeatures/mainwindow.cpp b/tests/manual/fontfeatures/mainwindow.cpp index 534cee88c46..474e20de652 100644 --- a/tests/manual/fontfeatures/mainwindow.cpp +++ b/tests/manual/fontfeatures/mainwindow.cpp @@ -27,8 +27,8 @@ void MainWindow::updateSampleText() for (int i = 0; i < ui->lwFeatures->count(); ++i) { QListWidgetItem *it = ui->lwFeatures->item(i); if (it->checkState() != Qt::PartiallyChecked) { - QByteArray ba = it->text().toLatin1(); - font.setFeature(ba, !!it->checkState()); + if (const auto maybeTag = QFont::Tag::fromString(it->text().toLatin1())) + font.setFeature(*maybeTag, !!it->checkState()); } }