include/vcl/font/Feature.hxx | 24 ++++-- vcl/inc/font/OpenTypeFeatureDefinitionList.hxx | 23 +----- vcl/source/font/FeatureCollector.cxx | 4 - vcl/source/font/OpenTypeFeatureDefinitionList.cxx | 76 +++++++++------------- 4 files changed, 54 insertions(+), 73 deletions(-)
New commits: commit f8406dd0bfcfd9e72d420900bbd9cfb3ca880b53 Author: Tomaž Vajngerl <[email protected]> AuthorDate: Mon Dec 29 11:07:30 2025 +0900 Commit: Tomaž Vajngerl <[email protected]> CommitDate: Mon Dec 29 12:09:34 2025 +0100 vcl: use frozen in OpenType feature definition list We can now simplify this list and use frozen containers as there is no more parameters for OpenType features. If we will add parameters, we can still add those as exceptions, no need to add them in the list itself. Singleton OpenTypeFeatureDefinitionListPrivate now doesn't make much sense as the methods became static, so the whole class was removed and only functions are used. Change-Id: Icc66cdf0a5eb4bd0997b4815421c044372dfd395 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196273 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <[email protected]> diff --git a/include/vcl/font/Feature.hxx b/include/vcl/font/Feature.hxx index 2696fc2c077a..e80a0899de01 100644 --- a/include/vcl/font/Feature.hxx +++ b/include/vcl/font/Feature.hxx @@ -7,8 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef INCLUDED_VCL_FONT_FEATURE_HXX -#define INCLUDED_VCL_FONT_FEATURE_HXX +#pragma once #include <vcl/dllapi.h> #include <rtl/character.hxx> @@ -92,18 +91,29 @@ struct Feature Feature(); Feature(uint32_t const nCode, FeatureType eType); + bool hasCodeNumericPart() const + { + return rtl::isAsciiDigit((m_nCode >> 8) & 0xFF) && rtl::isAsciiDigit((m_nCode >> 0) & 0xFF); + } + bool isCharacterVariant() const { return ((m_nCode >> 24) & 0xFF) == 'c' && ((m_nCode >> 16) & 0xFF) == 'v' - && rtl::isAsciiDigit((m_nCode >> 8) & 0xFF) - && rtl::isAsciiDigit((m_nCode >> 0) & 0xFF); + && hasCodeNumericPart(); } bool isStylisticSet() const { return ((m_nCode >> 24) & 0xFF) == 's' && ((m_nCode >> 16) & 0xFF) == 's' - && rtl::isAsciiDigit((m_nCode >> 8) & 0xFF) - && rtl::isAsciiDigit((m_nCode >> 0) & 0xFF); + && hasCodeNumericPart(); + } + + OUString getCodeNumericPart() const + { + if (hasCodeNumericPart()) + return OUStringChar(char((m_nCode >> 8) & 0xFF)) + + OUStringChar(char((m_nCode >> 0) & 0xFF)); + return OUString(); } uint32_t m_nCode; @@ -125,6 +135,4 @@ struct FeatureSetting } // namespace vcl::font -#endif // INCLUDED_VCL_FONT_FEATURE_HXX - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/font/OpenTypeFeatureDefinitionList.hxx b/vcl/inc/font/OpenTypeFeatureDefinitionList.hxx index 56409d59152e..a6bd5e8fe22f 100644 --- a/vcl/inc/font/OpenTypeFeatureDefinitionList.hxx +++ b/vcl/inc/font/OpenTypeFeatureDefinitionList.hxx @@ -14,25 +14,10 @@ #include <vector> #include <unordered_map> -namespace vcl::font +namespace vcl::font::feature { -class OpenTypeFeatureDefinitionListPrivate -{ -private: - std::vector<FeatureDefinition> m_aFeatureDefinition; - std::unordered_map<sal_uInt32, size_t> m_aCodeToIndex; - std::vector<sal_uInt32> m_aRequiredFeatures; - - void init(); - -public: - OpenTypeFeatureDefinitionListPrivate(); - FeatureDefinition getDefinition(const vcl::font::Feature& rFeature); - bool isRequired(sal_uInt32 nFeatureCode); -}; - -VCL_DLLPUBLIC OpenTypeFeatureDefinitionListPrivate& OpenTypeFeatureDefinitionList(); - -} // namespace vcl::font +FeatureDefinition getDefinition(const vcl::font::Feature& rFeature); +bool isRequired(sal_uInt32 nFeatureCode); +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/font/FeatureCollector.cxx b/vcl/source/font/FeatureCollector.cxx index 767d8c39aa73..ca7d98b12779 100644 --- a/vcl/source/font/FeatureCollector.cxx +++ b/vcl/source/font/FeatureCollector.cxx @@ -96,14 +96,14 @@ void FeatureCollector::collectForTable(hb_tag_t aTableTag) for (hb_tag_t aFeatureTag : aFeatureTags) { - if (OpenTypeFeatureDefinitionList().isRequired(aFeatureTag)) + if (vcl::font::feature::isRequired(aFeatureTag)) continue; m_rFontFeatures.emplace_back(); vcl::font::Feature& rFeature = m_rFontFeatures.back(); rFeature.m_nCode = aFeatureTag; - FeatureDefinition aDefinition = OpenTypeFeatureDefinitionList().getDefinition(rFeature); + FeatureDefinition aDefinition = vcl::font::feature::getDefinition(rFeature); std::vector<vcl::font::FeatureParameter> aParameters{ { 0, VclResId(STR_FONT_FEATURE_PARAM_NONE) } }; diff --git a/vcl/source/font/OpenTypeFeatureDefinitionList.cxx b/vcl/source/font/OpenTypeFeatureDefinitionList.cxx index 1018790d29ce..0fd7a9dc1a8a 100644 --- a/vcl/source/font/OpenTypeFeatureDefinitionList.cxx +++ b/vcl/source/font/OpenTypeFeatureDefinitionList.cxx @@ -11,23 +11,36 @@ #include <font/OpenTypeFeatureDefinitionList.hxx> #include <font/OpenTypeFeatureStrings.hrc> -#include <rtl/character.hxx> +#include <frozen/bits/defines.h> +#include <frozen/bits/elsa_std.h> +#include <frozen/unordered_map.h> +#include <frozen/unordered_set.h> +#include <rtl/character.hxx> #include <algorithm> -namespace vcl::font +namespace vcl::font::feature { -OpenTypeFeatureDefinitionListPrivate& OpenTypeFeatureDefinitionList() +namespace { - static OpenTypeFeatureDefinitionListPrivate SINGLETON; - return SINGLETON; -}; - -OpenTypeFeatureDefinitionListPrivate::OpenTypeFeatureDefinitionListPrivate() { init(); } +constexpr auto constRequiredFeatures = frozen::make_unordered_set<sal_uInt32>({ + featureCode("abvf"), featureCode("abvm"), featureCode("abvs"), featureCode("akhn"), + featureCode("blwf"), featureCode("blwm"), featureCode("blws"), featureCode("ccmp"), + featureCode("cfar"), featureCode("cjct"), featureCode("curs"), featureCode("dist"), + featureCode("dtls"), featureCode("fin2"), featureCode("fin3"), featureCode("fina"), + featureCode("flac"), featureCode("half"), featureCode("haln"), featureCode("init"), + featureCode("isol"), featureCode("ljmo"), featureCode("locl"), featureCode("ltra"), + featureCode("ltrm"), featureCode("mark"), featureCode("med2"), featureCode("medi"), + featureCode("mkmk"), featureCode("mset"), featureCode("nukt"), featureCode("pref"), + featureCode("pres"), featureCode("pstf"), featureCode("psts"), featureCode("rand"), + featureCode("rclt"), featureCode("rkrf"), featureCode("rlig"), featureCode("rphf"), + featureCode("rtla"), featureCode("rtlm"), featureCode("rvrn"), featureCode("size"), + featureCode("ssty"), featureCode("stch"), featureCode("tjmo"), featureCode("vatu"), + featureCode("vert"), featureCode("vjmo"), +}); -void OpenTypeFeatureDefinitionListPrivate::init() -{ - m_aFeatureDefinition.assign({ +constexpr auto constFeatureCodeToTranslationID + = frozen::make_unordered_map<sal_uInt32, TranslateId>({ { featureCode("aalt"), STR_FONT_FEATURE_ID_AALT }, { featureCode("afrc"), STR_FONT_FEATURE_ID_AFRC }, { featureCode("alig"), STR_FONT_FEATURE_ID_ALIG }, @@ -102,37 +115,14 @@ void OpenTypeFeatureDefinitionListPrivate::init() { featureCode("vrtr"), STR_FONT_FEATURE_ID_VRTR }, { featureCode("zero"), STR_FONT_FEATURE_ID_ZERO }, }); - - for (size_t i = 0; i < m_aFeatureDefinition.size(); ++i) - { - m_aCodeToIndex.emplace(m_aFeatureDefinition[i].getCode(), i); - } - - m_aRequiredFeatures.assign({ - featureCode("abvf"), featureCode("abvm"), featureCode("abvs"), featureCode("akhn"), - featureCode("blwf"), featureCode("blwm"), featureCode("blws"), featureCode("ccmp"), - featureCode("cfar"), featureCode("cjct"), featureCode("curs"), featureCode("dist"), - featureCode("dtls"), featureCode("fin2"), featureCode("fin3"), featureCode("fina"), - featureCode("flac"), featureCode("half"), featureCode("haln"), featureCode("init"), - featureCode("isol"), featureCode("ljmo"), featureCode("locl"), featureCode("ltra"), - featureCode("ltrm"), featureCode("mark"), featureCode("med2"), featureCode("medi"), - featureCode("mkmk"), featureCode("mset"), featureCode("nukt"), featureCode("pref"), - featureCode("pres"), featureCode("pstf"), featureCode("psts"), featureCode("rand"), - featureCode("rclt"), featureCode("rkrf"), featureCode("rlig"), featureCode("rphf"), - featureCode("rtla"), featureCode("rtlm"), featureCode("rvrn"), featureCode("size"), - featureCode("ssty"), featureCode("stch"), featureCode("tjmo"), featureCode("vatu"), - featureCode("vert"), featureCode("vjmo"), - }); } -FeatureDefinition -OpenTypeFeatureDefinitionListPrivate::getDefinition(const vcl::font::Feature& rFeature) +FeatureDefinition getDefinition(const vcl::font::Feature& rFeature) { if (rFeature.isCharacterVariant() || rFeature.isStylisticSet()) { FeatureDefinition aFeatureDefinition; - OUString sNumericPart = OUStringChar(char((rFeature.m_nCode >> 8) & 0xFF)) - + OUStringChar(char((rFeature.m_nCode >> 0) & 0xFF)); + OUString sNumericPart = rFeature.getCodeNumericPart(); if (rFeature.isCharacterVariant()) aFeatureDefinition = { rFeature.m_nCode, STR_FONT_FEATURE_ID_CVXX, sNumericPart }; else if (rFeature.isStylisticSet()) @@ -141,18 +131,16 @@ OpenTypeFeatureDefinitionListPrivate::getDefinition(const vcl::font::Feature& rF } auto nFeatureCode = rFeature.m_nCode; - if (m_aCodeToIndex.find(nFeatureCode) != m_aCodeToIndex.end()) - { - size_t nIndex = m_aCodeToIndex.at(nFeatureCode); - return m_aFeatureDefinition[nIndex]; - } + + auto iterator = constFeatureCodeToTranslationID.find(nFeatureCode); + if (iterator != constFeatureCodeToTranslationID.end()) + return FeatureDefinition(iterator->first, iterator->second); return FeatureDefinition(); } -bool OpenTypeFeatureDefinitionListPrivate::isRequired(sal_uInt32 nFeatureCode) +bool isRequired(sal_uInt32 nFeatureCode) { - return std::find(m_aRequiredFeatures.begin(), m_aRequiredFeatures.end(), nFeatureCode) - != m_aRequiredFeatures.end(); + return constRequiredFeatures.find(nFeatureCode) != constRequiredFeatures.end(); } } // end vcl::font namespace
