cui/source/dialogs/FontFeaturesDialog.cxx | 4 include/vcl/font/Feature.hxx | 44 ++++--- include/vcl/font/FeatureParser.hxx | 11 - vcl/qa/cppunit/FontFeatureTest.cxx | 182 ++++++++++++++++++++++++++---- vcl/source/font/Feature.cxx | 35 ++++- vcl/source/font/FeatureParser.cxx | 38 ++---- vcl/source/gdi/CommonSalLayout.cxx | 4 7 files changed, 242 insertions(+), 76 deletions(-)
New commits: commit 3450311c403af714d3fc0ba14b9f7673c717a6a2 Author: Khaled Hosny <khaledho...@eglug.org> AuthorDate: Mon Mar 11 20:55:24 2019 +0200 Commit: Khaled Hosny <khaledho...@eglug.org> CommitDate: Tue Mar 12 03:38:19 2019 +0100 tdf#123304: Allow the full feature syntax as pre 6.2 Fix regression from: commit dc9ee533dc707cc10b99d537eaccc3ee5aa555fe Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> Date: Fri Jun 15 19:32:15 2018 +0200 vcl: parser of font features included in the font name Where hb_feature_from_string() was replaced by a simple parser that supports avery limited subset of the syntax it supports (as documented in https://harfbuzz.github.io/harfbuzz-hb-common.html#hb-feature-from-string) Reviewed-on: https://gerrit.libreoffice.org/69062 Reviewed-by: Khaled Hosny <khaledho...@eglug.org> Tested-by: Khaled Hosny <khaledho...@eglug.org> (cherry picked from commit 45deb5b714d2d011eb2a5ad91721a9c2c508a426) Change-Id: I613190a677d24183e8c718fcfcaf9cf9b37a1e8f Reviewed-on: https://gerrit.libreoffice.org/69068 Reviewed-by: Khaled Hosny <khaledho...@eglug.org> Tested-by: Khaled Hosny <khaledho...@eglug.org> diff --git a/cui/source/dialogs/FontFeaturesDialog.cxx b/cui/source/dialogs/FontFeaturesDialog.cxx index 8da13eda49e6..f9276441c1a8 100644 --- a/cui/source/dialogs/FontFeaturesDialog.cxx +++ b/cui/source/dialogs/FontFeaturesDialog.cxx @@ -74,7 +74,7 @@ void FontFeaturesDialog::initialize() void FontFeaturesDialog::fillGrid(std::vector<vcl::font::Feature> const& rFontFeatures) { vcl::font::FeatureParser aParser(m_sFontName); - std::unordered_map<sal_uInt32, sal_uInt32> aExistingFeatures = aParser.getFeaturesMap(); + auto aExistingFeatures = aParser.getFeaturesMap(); sal_Int32 i = 0; for (vcl::font::Feature const& rFontFeature : rFontFeatures) @@ -89,7 +89,7 @@ void FontFeaturesDialog::fillGrid(std::vector<vcl::font::Feature> const& rFontFe m_aFeatureItems.emplace_back(m_xContentGrid.get()); - sal_uInt32 nValue = 0; + uint32_t nValue = 0; if (aExistingFeatures.find(nFontFeatureCode) != aExistingFeatures.end()) nValue = aExistingFeatures.at(nFontFeatureCode); diff --git a/include/vcl/font/Feature.hxx b/include/vcl/font/Feature.hxx index 299d0a55a9f2..76ba597b1ba2 100644 --- a/include/vcl/font/Feature.hxx +++ b/include/vcl/font/Feature.hxx @@ -21,13 +21,13 @@ namespace vcl { namespace font { -constexpr sal_uInt32 featureCode(const char sFeature[4]) +constexpr uint32_t featureCode(const char sFeature[4]) { - return static_cast<sal_uInt32>(sFeature[0]) << 24U | static_cast<sal_uInt32>(sFeature[1]) << 16U - | static_cast<sal_uInt32>(sFeature[2]) << 8U | static_cast<sal_uInt32>(sFeature[3]); + return static_cast<uint32_t>(sFeature[0]) << 24U | static_cast<uint32_t>(sFeature[1]) << 16U + | static_cast<uint32_t>(sFeature[2]) << 8U | static_cast<uint32_t>(sFeature[3]); } -VCL_DLLPUBLIC OUString featureCodeAsString(sal_uInt32 nFeature); +VCL_DLLPUBLIC OUString featureCodeAsString(uint32_t nFeature); enum class FeatureParameterType { @@ -44,22 +44,22 @@ enum class FeatureType struct VCL_DLLPUBLIC FeatureParameter { private: - sal_uInt32 m_nCode; + uint32_t m_nCode; OUString m_sDescription; const char* m_pDescriptionID; public: - FeatureParameter(sal_uInt32 nCode, OUString aDescription); - FeatureParameter(sal_uInt32 nCode, const char* pDescriptionID); + FeatureParameter(uint32_t nCode, OUString aDescription); + FeatureParameter(uint32_t nCode, const char* pDescriptionID); - sal_uInt32 getCode() const; + uint32_t getCode() const; OUString getDescription() const; }; class VCL_DLLPUBLIC FeatureDefinition { private: - sal_uInt32 m_nCode; + uint32_t m_nCode; OUString m_sDescription; const char* m_pDescriptionID; OUString m_sNumericPart; @@ -69,18 +69,18 @@ private: public: FeatureDefinition(); - FeatureDefinition(sal_uInt32 nCode, OUString const& rDescription, + FeatureDefinition(uint32_t nCode, OUString const& rDescription, FeatureParameterType eType = FeatureParameterType::BOOL, std::vector<FeatureParameter> const& rEnumParameters = std::vector<FeatureParameter>{}); - FeatureDefinition(sal_uInt32 nCode, const char* pDescriptionID, + FeatureDefinition(uint32_t nCode, const char* pDescriptionID, OUString const& rNumericPart = OUString()); - FeatureDefinition(sal_uInt32 nCode, const char* pDescriptionID, + FeatureDefinition(uint32_t nCode, const char* pDescriptionID, std::vector<FeatureParameter> aEnumParameters); const std::vector<FeatureParameter>& getEnumParameters() const; OUString getDescription() const; - sal_uInt32 getCode() const; + uint32_t getCode() const; FeatureParameterType getType() const; operator bool() const; @@ -88,9 +88,9 @@ public: struct VCL_DLLPUBLIC FeatureID { - sal_uInt32 m_aFeatureCode; - sal_uInt32 m_aScriptCode; - sal_uInt32 m_aLanguageCode; + uint32_t m_aFeatureCode; + uint32_t m_aScriptCode; + uint32_t m_aLanguageCode; }; struct VCL_DLLPUBLIC Feature @@ -103,6 +103,18 @@ struct VCL_DLLPUBLIC Feature FeatureDefinition m_aDefinition; }; +// This is basically duplicates hb_feature_t to avoid including HarfBuzz +// headers here, so the member types should remain compatible. +struct VCL_DLLPUBLIC FeatureSetting +{ + FeatureSetting(OString feature); + + uint32_t m_nTag; + uint32_t m_nValue; + unsigned int m_nStart; + unsigned int m_nEnd; +}; + } // end font namespace } // end vcl namespace diff --git a/include/vcl/font/FeatureParser.hxx b/include/vcl/font/FeatureParser.hxx old mode 100644 new mode 100755 index 3adc5fc0b0d0..65de3ea0b82e --- a/include/vcl/font/FeatureParser.hxx +++ b/include/vcl/font/FeatureParser.hxx @@ -18,6 +18,8 @@ #include <unordered_map> #include <vcl/font/Feature.hxx> +#include <vcl/font/Feature.hxx> + namespace vcl { namespace font @@ -32,19 +34,16 @@ class VCL_DLLPUBLIC FeatureParser { private: OUString m_sLanguage; - std::vector<std::pair<sal_uInt32, sal_uInt32>> m_aFeatures; + std::vector<FeatureSetting> m_aFeatures; public: FeatureParser(OUString const& sFontName); OUString const& getLanguage() const { return m_sLanguage; } - std::vector<std::pair<sal_uInt32, sal_uInt32>> const& getFeatures() const - { - return m_aFeatures; - } + std::vector<FeatureSetting> const& getFeatures() const { return m_aFeatures; } - std::unordered_map<sal_uInt32, sal_uInt32> getFeaturesMap() const; + std::unordered_map<uint32_t, uint32_t> getFeaturesMap() const; }; } // end font namespace diff --git a/vcl/qa/cppunit/FontFeatureTest.cxx b/vcl/qa/cppunit/FontFeatureTest.cxx index 6a66eb1c70b5..47e610f50018 100644 --- a/vcl/qa/cppunit/FontFeatureTest.cxx +++ b/vcl/qa/cppunit/FontFeatureTest.cxx @@ -119,17 +119,17 @@ void FontFeatureTest::testGetFontFeatures() vcl::font::FeatureParameter const& rParameter1 = rFracFeatureDefinition.getEnumParameters()[0]; - CPPUNIT_ASSERT_EQUAL(sal_uInt32(0), rParameter1.getCode()); + CPPUNIT_ASSERT_EQUAL(uint32_t(0), rParameter1.getCode()); CPPUNIT_ASSERT(!rParameter1.getDescription().isEmpty()); vcl::font::FeatureParameter const& rParameter2 = rFracFeatureDefinition.getEnumParameters()[1]; - CPPUNIT_ASSERT_EQUAL(sal_uInt32(1), rParameter2.getCode()); + CPPUNIT_ASSERT_EQUAL(uint32_t(1), rParameter2.getCode()); CPPUNIT_ASSERT(!rParameter2.getDescription().isEmpty()); vcl::font::FeatureParameter const& rParameter3 = rFracFeatureDefinition.getEnumParameters()[2]; - CPPUNIT_ASSERT_EQUAL(sal_uInt32(2), rParameter3.getCode()); + CPPUNIT_ASSERT_EQUAL(uint32_t(2), rParameter3.getCode()); CPPUNIT_ASSERT(!rParameter2.getDescription().isEmpty()); } #endif // HAVE_MORE_FONTS @@ -146,44 +146,184 @@ void FontFeatureTest::testParseFeature() CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); auto aFeatures = aParser.getFeatures(); - CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].first); - CPPUNIT_ASSERT_EQUAL(sal_uInt32(1), aFeatures[0].second); + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(1), aFeatures[0].m_nValue); } { // One feature specified, explicit value vcl::font::FeatureParser aParser("Font name:abcd=5"); CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); auto aFeatures = aParser.getFeatures(); - CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].first); - CPPUNIT_ASSERT_EQUAL(sal_uInt32(5), aFeatures[0].second); + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(5), aFeatures[0].m_nValue); + } + { // One feature specified, explicit zero value + vcl::font::FeatureParser aParser("Font name:abcd=0"); + CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); + auto aFeatures = aParser.getFeatures(); + + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(0), aFeatures[0].m_nValue); + } + { // One feature specified, using plus prefix + vcl::font::FeatureParser aParser("Font name:+abcd"); + CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); + auto aFeatures = aParser.getFeatures(); + + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(1), aFeatures[0].m_nValue); + } + { // One feature specified, using minus prefix + vcl::font::FeatureParser aParser("Font name:-abcd"); + CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); + auto aFeatures = aParser.getFeatures(); + + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(0), aFeatures[0].m_nValue); + } + { // One feature specified, with empty character range + vcl::font::FeatureParser aParser("Font name:abcd[]"); + CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); + auto aFeatures = aParser.getFeatures(); + + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(1), aFeatures[0].m_nValue); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(0), aFeatures[0].m_nStart); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(-1), aFeatures[0].m_nEnd); + } + { // One feature specified, with empty character range + vcl::font::FeatureParser aParser("Font name:abcd[:]"); + CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); + auto aFeatures = aParser.getFeatures(); + + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(1), aFeatures[0].m_nValue); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(0), aFeatures[0].m_nStart); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(-1), aFeatures[0].m_nEnd); + } + { // One feature specified, with start character range + vcl::font::FeatureParser aParser("Font name:abcd[3:]"); + CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); + auto aFeatures = aParser.getFeatures(); + + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(1), aFeatures[0].m_nValue); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(3), aFeatures[0].m_nStart); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(-1), aFeatures[0].m_nEnd); + } + { // One feature specified, with end character range + vcl::font::FeatureParser aParser("Font name:abcd[:3]"); + CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); + auto aFeatures = aParser.getFeatures(); + + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(1), aFeatures[0].m_nValue); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(0), aFeatures[0].m_nStart); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(3), aFeatures[0].m_nEnd); + } + { // One feature specified, with character range + vcl::font::FeatureParser aParser("Font name:abcd[3:6]"); + CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); + auto aFeatures = aParser.getFeatures(); + + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(1), aFeatures[0].m_nValue); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(3), aFeatures[0].m_nStart); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(6), aFeatures[0].m_nEnd); + } + { // One feature specified, with character range + vcl::font::FeatureParser aParser("Font name:abcd[3]"); + CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); + auto aFeatures = aParser.getFeatures(); + + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(1), aFeatures[0].m_nValue); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(3), aFeatures[0].m_nStart); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(4), aFeatures[0].m_nEnd); + } + { // One feature specified, with character range and value + vcl::font::FeatureParser aParser("Font name:abcd[3:6]=2"); + CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); + auto aFeatures = aParser.getFeatures(); + + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(2), aFeatures[0].m_nValue); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(3), aFeatures[0].m_nStart); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(6), aFeatures[0].m_nEnd); + } + { // One feature specified, with character range and 0 value + vcl::font::FeatureParser aParser("Font name:abcd[3:6]=0"); + CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); + auto aFeatures = aParser.getFeatures(); + + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(0), aFeatures[0].m_nValue); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(3), aFeatures[0].m_nStart); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(6), aFeatures[0].m_nEnd); + } + { // One feature specified, with character range and minus prefix + vcl::font::FeatureParser aParser("Font name:-abcd[3:6]"); + CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); + auto aFeatures = aParser.getFeatures(); + + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(0), aFeatures[0].m_nValue); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(3), aFeatures[0].m_nStart); + CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(6), aFeatures[0].m_nEnd); + } + { // One feature specified, with CSS on + vcl::font::FeatureParser aParser("Font name:\"abcd\" on"); + CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); + auto aFeatures = aParser.getFeatures(); + + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(1), aFeatures[0].m_nValue); + } + { // One feature specified, with CSS off + vcl::font::FeatureParser aParser("Font name:'abcd' off"); + CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); + auto aFeatures = aParser.getFeatures(); + + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(0), aFeatures[0].m_nValue); + } + { // One feature specified, with CSS value + vcl::font::FeatureParser aParser("Font name:\"abcd\" 2"); + CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); + auto aFeatures = aParser.getFeatures(); + + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(2), aFeatures[0].m_nValue); } { // Multiple features specified, no values vcl::font::FeatureParser aParser("Font name:abcd&bcde&efgh"); CPPUNIT_ASSERT_EQUAL(size_t(3), aParser.getFeatures().size()); auto aFeatures = aParser.getFeatures(); - CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].first); - CPPUNIT_ASSERT_EQUAL(sal_uInt32(1), aFeatures[0].second); + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(1), aFeatures[0].m_nValue); - CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("bcde"), aFeatures[1].first); - CPPUNIT_ASSERT_EQUAL(sal_uInt32(1), aFeatures[1].second); + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("bcde"), aFeatures[1].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(1), aFeatures[1].m_nValue); - CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("efgh"), aFeatures[2].first); - CPPUNIT_ASSERT_EQUAL(sal_uInt32(1), aFeatures[2].second); + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("efgh"), aFeatures[2].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(1), aFeatures[2].m_nValue); } { // Multiple features specified, explicit values // Only 4 char parameter names supported - "toolong" is too long and ignored - // If value is 0, it should be also ignored vcl::font::FeatureParser aParser("Font name:abcd=1&bcde=0&toolong=1&cdef=3"); - CPPUNIT_ASSERT_EQUAL(size_t(2), aParser.getFeatures().size()); + CPPUNIT_ASSERT_EQUAL(size_t(3), aParser.getFeatures().size()); auto aFeatures = aParser.getFeatures(); - CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].first); - CPPUNIT_ASSERT_EQUAL(sal_uInt32(1), aFeatures[0].second); + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(1), aFeatures[0].m_nValue); + + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("bcde"), aFeatures[1].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(0), aFeatures[1].m_nValue); - CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("cdef"), aFeatures[1].first); - CPPUNIT_ASSERT_EQUAL(sal_uInt32(3), aFeatures[1].second); + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("cdef"), aFeatures[2].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(3), aFeatures[2].m_nValue); } { // Special case - "lang" is parsed specially and access separately not as a feature. @@ -192,8 +332,8 @@ void FontFeatureTest::testParseFeature() CPPUNIT_ASSERT_EQUAL(size_t(1), aParser.getFeatures().size()); auto aFeatures = aParser.getFeatures(); - CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].first); - CPPUNIT_ASSERT_EQUAL(sal_uInt32(1), aFeatures[0].second); + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("abcd"), aFeatures[0].m_nTag); + CPPUNIT_ASSERT_EQUAL(uint32_t(1), aFeatures[0].m_nValue); CPPUNIT_ASSERT_EQUAL(OUString("slo"), aParser.getLanguage()); } diff --git a/vcl/source/font/Feature.cxx b/vcl/source/font/Feature.cxx index 07810c1b011b..3a809cb11e8a 100644 --- a/vcl/source/font/Feature.cxx +++ b/vcl/source/font/Feature.cxx @@ -13,11 +13,13 @@ #include <strings.hrc> #include <svdata.hxx> +#include <hb.h> + namespace vcl { namespace font { -OUString featureCodeAsString(sal_uInt32 nFeature) +OUString featureCodeAsString(uint32_t nFeature) { std::vector<sal_Char> aString(5, 0); aString[0] = sal_Char(nFeature >> 24 & 0xff); @@ -41,16 +43,33 @@ Feature::Feature(FeatureID const& rID, FeatureType eType) { } +// FeatureSetting +FeatureSetting::FeatureSetting(OString feature) + : m_nTag(0) + , m_nValue(0) + , m_nStart(0) + , m_nEnd(0) +{ + hb_feature_t aFeat; + if (hb_feature_from_string(feature.getStr(), feature.getLength(), &aFeat)) + { + m_nTag = aFeat.tag; + m_nValue = aFeat.value; + m_nStart = aFeat.start; + m_nEnd = aFeat.end; + } +} + // FeatureParameter -FeatureParameter::FeatureParameter(sal_uInt32 nCode, OUString aDescription) +FeatureParameter::FeatureParameter(uint32_t nCode, OUString aDescription) : m_nCode(nCode) , m_sDescription(std::move(aDescription)) , m_pDescriptionID(nullptr) { } -FeatureParameter::FeatureParameter(sal_uInt32 nCode, const char* pDescriptionID) +FeatureParameter::FeatureParameter(uint32_t nCode, const char* pDescriptionID) : m_nCode(nCode) , m_pDescriptionID(pDescriptionID) { @@ -68,7 +87,7 @@ OUString FeatureParameter::getDescription() const return aReturnString; } -sal_uInt32 FeatureParameter::getCode() const { return m_nCode; } +uint32_t FeatureParameter::getCode() const { return m_nCode; } // FeatureDefinition @@ -79,7 +98,7 @@ FeatureDefinition::FeatureDefinition() { } -FeatureDefinition::FeatureDefinition(sal_uInt32 nCode, OUString const& rDescription, +FeatureDefinition::FeatureDefinition(uint32_t nCode, OUString const& rDescription, FeatureParameterType eType, std::vector<FeatureParameter> const& rEnumParameters) : m_nCode(nCode) @@ -90,7 +109,7 @@ FeatureDefinition::FeatureDefinition(sal_uInt32 nCode, OUString const& rDescript { } -FeatureDefinition::FeatureDefinition(sal_uInt32 nCode, const char* pDescriptionID, +FeatureDefinition::FeatureDefinition(uint32_t nCode, const char* pDescriptionID, OUString const& rNumericPart) : m_nCode(nCode) , m_pDescriptionID(pDescriptionID) @@ -99,7 +118,7 @@ FeatureDefinition::FeatureDefinition(sal_uInt32 nCode, const char* pDescriptionI { } -FeatureDefinition::FeatureDefinition(sal_uInt32 nCode, const char* pDescriptionID, +FeatureDefinition::FeatureDefinition(uint32_t nCode, const char* pDescriptionID, std::vector<FeatureParameter> aEnumParameters) : m_nCode(nCode) , m_pDescriptionID(pDescriptionID) @@ -132,7 +151,7 @@ OUString FeatureDefinition::getDescription() const } } -sal_uInt32 FeatureDefinition::getCode() const { return m_nCode; } +uint32_t FeatureDefinition::getCode() const { return m_nCode; } FeatureParameterType FeatureDefinition::getType() const { return m_eType; } diff --git a/vcl/source/font/FeatureParser.cxx b/vcl/source/font/FeatureParser.cxx index 7085b94f19ef..adafbaa2e101 100644 --- a/vcl/source/font/FeatureParser.cxx +++ b/vcl/source/font/FeatureParser.cxx @@ -26,43 +26,39 @@ OUString trimFontNameFeatures(OUString const& rFontName) FeatureParser::FeatureParser(OUString const& rFontName) { - if (rFontName.indexOf(vcl::font::FeaturePrefix) < 0) + sal_Int32 nPrefixIdx{ rFontName.indexOf(vcl::font::FeaturePrefix) }; + if (nPrefixIdx < 0) return; - OUString sName = rFontName.getToken(1, vcl::font::FeaturePrefix); + OUString sName = rFontName.copy(++nPrefixIdx); sal_Int32 nIndex = 0; do { OUString sToken = sName.getToken(0, vcl::font::FeatureSeparator, nIndex); OUString sID = sToken.getToken(0, '='); - OUString sValue = sToken.getToken(1, '='); - if (sID.getLength() == 4 && sValue != "0") + if (sID == "lang") { - if (sID == "lang") - { - m_sLanguage = sValue; - } - else - { - OString sFeatureCodeAscii = OUStringToOString(sID, RTL_TEXTENCODING_ASCII_US); - sal_uInt32 nCode = vcl::font::featureCode(sFeatureCodeAscii.getStr()); - sal_uInt32 nValue = sValue.isEmpty() ? 1 : sValue.toUInt32(); - - if (nValue != 0) - m_aFeatures.emplace_back(nCode, nValue); - } + m_sLanguage = sToken.getToken(1, '='); + } + else + { + OString sFeature = OUStringToOString(sToken, RTL_TEXTENCODING_ASCII_US); + FeatureSetting aFeature(sFeature); + if (aFeature.m_nTag != 0) + m_aFeatures.push_back(aFeature); } } while (nIndex >= 0); } -std::unordered_map<sal_uInt32, sal_uInt32> FeatureParser::getFeaturesMap() const +std::unordered_map<uint32_t, uint32_t> FeatureParser::getFeaturesMap() const { - std::unordered_map<sal_uInt32, sal_uInt32> aResultMap; - for (auto const& rPair : m_aFeatures) + std::unordered_map<uint32_t, uint32_t> aResultMap; + for (auto const& rFeat : m_aFeatures) { - aResultMap.emplace(rPair); + if (rFeat.m_nValue != 0) + aResultMap.emplace(rFeat.m_nTag, rFeat.m_nValue); } return aResultMap; } diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index 21d4d1c22ad3..9a638663d1ca 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -74,9 +74,9 @@ void GenericSalLayout::ParseFeatures(const OUString& aName) if (!sLanguage.isEmpty()) msLanguage = OUStringToOString(sLanguage, RTL_TEXTENCODING_ASCII_US); - for (std::pair<sal_uInt32, sal_uInt32> const & rPair : aParser.getFeatures()) + for (auto const &rFeat : aParser.getFeatures()) { - hb_feature_t aFeature { rPair.first, rPair.second, 0, SAL_MAX_UINT32 }; + hb_feature_t aFeature { rFeat.m_nTag, rFeat.m_nValue, rFeat.m_nStart, rFeat.m_nEnd }; maFeatures.push_back(aFeature); } } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits