diff options
-rw-r--r-- | vcl/inc/font/FeatureCollector.hxx | 8 | ||||
-rw-r--r-- | vcl/inc/font/PhysicalFontFace.hxx | 36 | ||||
-rw-r--r-- | vcl/source/font/FeatureCollector.cxx | 28 | ||||
-rw-r--r-- | vcl/source/font/LogicalFontInstance.cxx | 20 | ||||
-rw-r--r-- | vcl/source/font/PhysicalFontFace.cxx | 30 | ||||
-rw-r--r-- | vcl/source/outdev/font.cxx | 10 |
6 files changed, 80 insertions, 52 deletions
diff --git a/vcl/inc/font/FeatureCollector.hxx b/vcl/inc/font/FeatureCollector.hxx index ae784474e06d..0ffb5f9d424c 100644 --- a/vcl/inc/font/FeatureCollector.hxx +++ b/vcl/inc/font/FeatureCollector.hxx @@ -15,19 +15,23 @@ #include <hb.h> #include <i18nlangtag/lang.h> +#include <font/PhysicalFontFace.hxx> + namespace vcl::font { class FeatureCollector { private: + const PhysicalFontFace* m_pFace; hb_face_t* m_pHbFace; std::vector<vcl::font::Feature>& m_rFontFeatures; const LanguageTag& m_rLanguageTag; public: - FeatureCollector(hb_face_t* pHbFace, std::vector<vcl::font::Feature>& rFontFeatures, + FeatureCollector(const PhysicalFontFace* pFace, std::vector<vcl::font::Feature>& rFontFeatures, const LanguageTag& rLanguageTag) - : m_pHbFace(pHbFace) + : m_pFace(pFace) + , m_pHbFace(pFace->GetHbFace()) , m_rFontFeatures(rFontFeatures) , m_rLanguageTag(rLanguageTag) { diff --git a/vcl/inc/font/PhysicalFontFace.hxx b/vcl/inc/font/PhysicalFontFace.hxx index 303976c59776..5cdf88bd3ac9 100644 --- a/vcl/inc/font/PhysicalFontFace.hxx +++ b/vcl/inc/font/PhysicalFontFace.hxx @@ -21,8 +21,9 @@ #include <sal/config.h> -#include <salhelper/simplereferenceobject.hxx> +#include <i18nlangtag/languagetag.hxx> #include <rtl/ref.hxx> +#include <salhelper/simplereferenceobject.hxx> #include <tools/color.hxx> #include <tools/long.hxx> #include <vcl/dllapi.h> @@ -93,6 +94,36 @@ struct ColorLayer typedef std::vector<Color> ColorPalette; +// https://learn.microsoft.com/en-us/typography/opentype/spec/name#name-ids +typedef enum { + NAME_ID_COPYRIGHT = 0, + NAME_ID_FONT_FAMILY = 1, + NAME_ID_FONT_SUBFAMILY = 2, + NAME_ID_UNIQUE_ID = 3, + NAME_ID_FULL_NAME = 4, + NAME_ID_VERSION_STRING = 5, + NAME_ID_POSTSCRIPT_NAME = 6, + NAME_ID_TRADEMARK = 7, + NAME_ID_MANUFACTURER = 8, + NAME_ID_DESIGNER = 9, + NAME_ID_DESCRIPTION = 10, + NAME_ID_VENDOR_URL = 11, + NAME_ID_DESIGNER_URL = 12, + NAME_ID_LICENSE = 13, + NAME_ID_LICENSE_URL = 14, + //NAME_ID_RESERVED = 15, + NAME_ID_TYPOGRAPHIC_FAMILY = 16, + NAME_ID_TYPOGRAPHIC_SUBFAMILY = 17, + NAME_ID_MAC_FULL_NAME = 18, + NAME_ID_SAMPLE_TEXT = 19, + NAME_ID_CID_FINDFONT_NAME = 20, + NAME_ID_WWS_FAMILY = 21, + NAME_ID_WWS_SUBFAMILY = 22, + NAME_ID_LIGHT_BACKGROUND = 23, + NAME_ID_DARK_BACKGROUND = 24, + NAME_ID_VARIATIONS_PS_PREFIX = 25, +} NameID; + // TODO: no more direct access to members // TODO: get rid of height/width for scalable fonts // TODO: make cloning cheaper @@ -140,6 +171,9 @@ public: uint32_t UnitsPerEm() const { return hb_face_get_upem(GetHbFace()); } + OUString GetName(NameID, const LanguageTag&) const; + OUString GetName(NameID aNameID) const { return GetName(aNameID, LanguageTag(LANGUAGE_NONE)); } + virtual hb_face_t* GetHbFace() const; virtual hb_blob_t* GetHbTable(hb_tag_t) const { diff --git a/vcl/source/font/FeatureCollector.cxx b/vcl/source/font/FeatureCollector.cxx index 134462e0ed44..a97988ca46ce 100644 --- a/vcl/source/font/FeatureCollector.cxx +++ b/vcl/source/font/FeatureCollector.cxx @@ -84,29 +84,6 @@ bool FeatureCollector::collectGraphite() return true; } -static OUString getName(hb_face_t* pHbFace, hb_ot_name_id_t aNameID, OString& rLanguage) -{ - auto aHbLang = hb_language_from_string(rLanguage.getStr(), rLanguage.getLength()); - auto nName = hb_ot_name_get_utf16(pHbFace, aNameID, aHbLang, nullptr, nullptr); - - if (!nName) - { - // Fallback to English if localized name is missing. - aHbLang = hb_language_from_string("en", 2); - nName = hb_ot_name_get_utf16(pHbFace, aNameID, aHbLang, nullptr, nullptr); - } - - OUString sName; - if (nName) - { - std::vector<uint16_t> aBuf(++nName); // make space for terminating NUL. - hb_ot_name_get_utf16(pHbFace, aNameID, aHbLang, &nName, aBuf.data()); - sName = OUString(reinterpret_cast<sal_Unicode*>(aBuf.data()), nName); - } - - return sName; -} - void FeatureCollector::collectForTable(hb_tag_t aTableTag) { unsigned int nFeatureCount @@ -144,8 +121,7 @@ void FeatureCollector::collectForTable(hb_tag_t aTableTag) nullptr, nullptr, &nNamedParameters, &aFirstParameterID)) { - OString sLanguage = m_rLanguageTag.getBcp47().toUtf8(); - OUString sLabel = getName(m_pHbFace, aLabelID, sLanguage); + OUString sLabel = m_pFace->GetName(NameID(aLabelID), m_rLanguageTag); if (!sLabel.isEmpty()) aDefinition = vcl::font::FeatureDefinition(aFeatureTag, sLabel); @@ -154,7 +130,7 @@ void FeatureCollector::collectForTable(hb_tag_t aTableTag) for (unsigned i = 0; i < nNamedParameters; i++) { hb_ot_name_id_t aNameID = aFirstParameterID + i; - OUString sName = getName(m_pHbFace, aNameID, sLanguage); + OUString sName = m_pFace->GetName(NameID(aNameID), m_rLanguageTag); if (!sName.isEmpty()) aParameters.emplace_back(uint32_t(i + 1), sName); else diff --git a/vcl/source/font/LogicalFontInstance.cxx b/vcl/source/font/LogicalFontInstance.cxx index 6124d41b3dba..b5d36afb2e56 100644 --- a/vcl/source/font/LogicalFontInstance.cxx +++ b/vcl/source/font/LogicalFontInstance.cxx @@ -181,22 +181,14 @@ bool LogicalFontInstance::NeedOffsetCorrection(sal_Int32 nYOffset) { if (!m_xeFontFamilyEnum) { - char familyname[10]; - unsigned int familyname_size = 10; - m_xeFontFamilyEnum = FontFamilyEnum::Unclassified; - if (hb_ot_name_get_utf8(hb_font_get_face(GetHbFont()), HB_OT_NAME_ID_FONT_FAMILY, - HB_LANGUAGE_INVALID, &familyname_size, familyname) - == 8) - { - // DFKai-SB (ukai.ttf) is a built-in font under traditional Chinese - // Windows. It has wrong extent values in glyf table. The problem results - // in wrong positioning of glyphs in vertical writing. - // Check https://github.com/harfbuzz/harfbuzz/issues/3521 for reference. - if (!strncmp("DFKai-SB", familyname, 8)) - m_xeFontFamilyEnum = FontFamilyEnum::DFKaiSB; - } + // DFKai-SB (ukai.ttf) is a built-in font under traditional Chinese + // Windows. It has wrong extent values in glyf table. The problem results + // in wrong positioning of glyphs in vertical writing. + // Check https://github.com/harfbuzz/harfbuzz/issues/3521 for reference. + if (GetFontFace()->GetName(vcl::font::NAME_ID_FONT_FAMILY) == "DFKai-SB") + m_xeFontFamilyEnum = FontFamilyEnum::DFKaiSB; } bool bRet = true; diff --git a/vcl/source/font/PhysicalFontFace.cxx b/vcl/source/font/PhysicalFontFace.cxx index 4a459ae8cee3..d210304f5b47 100644 --- a/vcl/source/font/PhysicalFontFace.cxx +++ b/vcl/source/font/PhysicalFontFace.cxx @@ -360,6 +360,36 @@ std::vector<ColorLayer> PhysicalFontFace::GetGlyphColorLayers(sal_GlyphId nGlyph return aLayers; } + +OUString PhysicalFontFace::GetName(NameID aNameID, const LanguageTag& rLanguageTag) const +{ + auto pHbFace = GetHbFace(); + + auto aHbLang = HB_LANGUAGE_INVALID; + if (rLanguageTag.getLanguageType() != LANGUAGE_NONE) + { + auto aLanguage(rLanguageTag.getBcp47().toUtf8()); + aHbLang = hb_language_from_string(aLanguage.getStr(), aLanguage.getLength()); + } + + auto nName = hb_ot_name_get_utf16(pHbFace, aNameID, aHbLang, nullptr, nullptr); + if (!nName && aHbLang == HB_LANGUAGE_INVALID) + { + // Fallback to English if localized name is missing. + aHbLang = hb_language_from_string("en", 2); + nName = hb_ot_name_get_utf16(pHbFace, aNameID, aHbLang, nullptr, nullptr); + } + + OUString sName; + if (nName) + { + std::vector<uint16_t> aBuf(++nName); // make space for terminating NUL. + hb_ot_name_get_utf16(pHbFace, aNameID, aHbLang, &nName, aBuf.data()); + sName = OUString(reinterpret_cast<sal_Unicode*>(aBuf.data()), nName); + } + + return sName; +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx index ba3076ac272b..a10ba5f29d36 100644 --- a/vcl/source/outdev/font.cxx +++ b/vcl/source/outdev/font.cxx @@ -163,17 +163,9 @@ bool OutputDevice::GetFontFeatures(std::vector<vcl::font::Feature>& rFontFeature if (!pFontInstance) return false; - hb_font_t* pHbFont = pFontInstance->GetHbFont(); - if (!pHbFont) - return false; - - hb_face_t* pHbFace = hb_font_get_face(pHbFont); - if (!pHbFace) - return false; - const LanguageTag& rOfficeLanguage = Application::GetSettings().GetUILanguageTag(); - vcl::font::FeatureCollector aFeatureCollector(pHbFace, rFontFeatures, rOfficeLanguage); + vcl::font::FeatureCollector aFeatureCollector(pFontInstance->GetFontFace(), rFontFeatures, rOfficeLanguage); aFeatureCollector.collect(); return true; |