Kaydet (Commit) 45deb5b7 authored tarafından Khaled Hosny's avatar Khaled Hosny

tdf#123304: Allow the full feature syntax as pre 6.2

Fix regression from:

commit dc9ee533
Author: Tomaž Vajngerl <tomaz.vajngerl@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)

Change-Id: I613190a677d24183e8c718fcfcaf9cf9b37a1e8f
Reviewed-on: https://gerrit.libreoffice.org/69062Reviewed-by: 's avatarKhaled Hosny <khaledhosny@eglug.org>
Tested-by: 's avatarKhaled Hosny <khaledhosny@eglug.org>
üst 212a40aa
...@@ -76,7 +76,7 @@ void FontFeaturesDialog::initialize() ...@@ -76,7 +76,7 @@ void FontFeaturesDialog::initialize()
void FontFeaturesDialog::fillGrid(std::vector<vcl::font::Feature> const& rFontFeatures) void FontFeaturesDialog::fillGrid(std::vector<vcl::font::Feature> const& rFontFeatures)
{ {
vcl::font::FeatureParser aParser(m_sFontName); vcl::font::FeatureParser aParser(m_sFontName);
std::unordered_map<sal_uInt32, sal_uInt32> aExistingFeatures = aParser.getFeaturesMap(); auto aExistingFeatures = aParser.getFeaturesMap();
sal_Int32 i = 0; sal_Int32 i = 0;
for (vcl::font::Feature const& rFontFeature : rFontFeatures) for (vcl::font::Feature const& rFontFeature : rFontFeatures)
...@@ -91,7 +91,7 @@ void FontFeaturesDialog::fillGrid(std::vector<vcl::font::Feature> const& rFontFe ...@@ -91,7 +91,7 @@ void FontFeaturesDialog::fillGrid(std::vector<vcl::font::Feature> const& rFontFe
m_aFeatureItems.emplace_back(m_xContentGrid.get()); m_aFeatureItems.emplace_back(m_xContentGrid.get());
sal_uInt32 nValue = 0; uint32_t nValue = 0;
if (aExistingFeatures.find(nFontFeatureCode) != aExistingFeatures.end()) if (aExistingFeatures.find(nFontFeatureCode) != aExistingFeatures.end())
nValue = aExistingFeatures.at(nFontFeatureCode); nValue = aExistingFeatures.at(nFontFeatureCode);
......
...@@ -18,13 +18,13 @@ namespace vcl ...@@ -18,13 +18,13 @@ namespace vcl
{ {
namespace font 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 return static_cast<uint32_t>(sFeature[0]) << 24U | static_cast<uint32_t>(sFeature[1]) << 16U
| static_cast<sal_uInt32>(sFeature[2]) << 8U | static_cast<sal_uInt32>(sFeature[3]); | 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 enum class FeatureParameterType
{ {
...@@ -41,22 +41,22 @@ enum class FeatureType ...@@ -41,22 +41,22 @@ enum class FeatureType
struct VCL_DLLPUBLIC FeatureParameter struct VCL_DLLPUBLIC FeatureParameter
{ {
private: private:
sal_uInt32 m_nCode; uint32_t m_nCode;
OUString m_sDescription; OUString m_sDescription;
const char* m_pDescriptionID; const char* m_pDescriptionID;
public: public:
FeatureParameter(sal_uInt32 nCode, OUString aDescription); FeatureParameter(uint32_t nCode, OUString aDescription);
FeatureParameter(sal_uInt32 nCode, const char* pDescriptionID); FeatureParameter(uint32_t nCode, const char* pDescriptionID);
sal_uInt32 getCode() const; uint32_t getCode() const;
OUString getDescription() const; OUString getDescription() const;
}; };
class VCL_DLLPUBLIC FeatureDefinition class VCL_DLLPUBLIC FeatureDefinition
{ {
private: private:
sal_uInt32 m_nCode; uint32_t m_nCode;
OUString m_sDescription; OUString m_sDescription;
const char* m_pDescriptionID; const char* m_pDescriptionID;
OUString m_sNumericPart; OUString m_sNumericPart;
...@@ -66,18 +66,18 @@ private: ...@@ -66,18 +66,18 @@ private:
public: public:
FeatureDefinition(); FeatureDefinition();
FeatureDefinition(sal_uInt32 nCode, OUString const& rDescription, FeatureDefinition(uint32_t nCode, OUString const& rDescription,
FeatureParameterType eType = FeatureParameterType::BOOL, FeatureParameterType eType = FeatureParameterType::BOOL,
std::vector<FeatureParameter> const& rEnumParameters std::vector<FeatureParameter> const& rEnumParameters
= std::vector<FeatureParameter>{}); = std::vector<FeatureParameter>{});
FeatureDefinition(sal_uInt32 nCode, const char* pDescriptionID, FeatureDefinition(uint32_t nCode, const char* pDescriptionID,
OUString const& rNumericPart = OUString()); OUString const& rNumericPart = OUString());
FeatureDefinition(sal_uInt32 nCode, const char* pDescriptionID, FeatureDefinition(uint32_t nCode, const char* pDescriptionID,
std::vector<FeatureParameter> aEnumParameters); std::vector<FeatureParameter> aEnumParameters);
const std::vector<FeatureParameter>& getEnumParameters() const; const std::vector<FeatureParameter>& getEnumParameters() const;
OUString getDescription() const; OUString getDescription() const;
sal_uInt32 getCode() const; uint32_t getCode() const;
FeatureParameterType getType() const; FeatureParameterType getType() const;
operator bool() const; operator bool() const;
...@@ -85,9 +85,9 @@ public: ...@@ -85,9 +85,9 @@ public:
struct VCL_DLLPUBLIC FeatureID struct VCL_DLLPUBLIC FeatureID
{ {
sal_uInt32 m_aFeatureCode; uint32_t m_aFeatureCode;
sal_uInt32 m_aScriptCode; uint32_t m_aScriptCode;
sal_uInt32 m_aLanguageCode; uint32_t m_aLanguageCode;
}; };
struct VCL_DLLPUBLIC Feature struct VCL_DLLPUBLIC Feature
...@@ -100,6 +100,18 @@ struct VCL_DLLPUBLIC Feature ...@@ -100,6 +100,18 @@ struct VCL_DLLPUBLIC Feature
FeatureDefinition m_aDefinition; 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 font namespace
} // end vcl namespace } // end vcl namespace
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include <vector> #include <vector>
#include <unordered_map> #include <unordered_map>
#include <vcl/font/Feature.hxx>
namespace vcl namespace vcl
{ {
namespace font namespace font
...@@ -29,19 +31,16 @@ class VCL_DLLPUBLIC FeatureParser ...@@ -29,19 +31,16 @@ class VCL_DLLPUBLIC FeatureParser
{ {
private: private:
OUString m_sLanguage; OUString m_sLanguage;
std::vector<std::pair<sal_uInt32, sal_uInt32>> m_aFeatures; std::vector<FeatureSetting> m_aFeatures;
public: public:
FeatureParser(OUString const& sFontName); FeatureParser(OUString const& sFontName);
OUString const& getLanguage() const { return m_sLanguage; } OUString const& getLanguage() const { return m_sLanguage; }
std::vector<std::pair<sal_uInt32, sal_uInt32>> const& getFeatures() const std::vector<FeatureSetting> const& getFeatures() const { return m_aFeatures; }
{
return m_aFeatures;
}
std::unordered_map<sal_uInt32, sal_uInt32> getFeaturesMap() const; std::unordered_map<uint32_t, uint32_t> getFeaturesMap() const;
}; };
} // end font namespace } // end font namespace
......
...@@ -13,11 +13,13 @@ ...@@ -13,11 +13,13 @@
#include <strings.hrc> #include <strings.hrc>
#include <svdata.hxx> #include <svdata.hxx>
#include <hb.h>
namespace vcl namespace vcl
{ {
namespace font namespace font
{ {
OUString featureCodeAsString(sal_uInt32 nFeature) OUString featureCodeAsString(uint32_t nFeature)
{ {
std::vector<sal_Char> aString(5, 0); std::vector<sal_Char> aString(5, 0);
aString[0] = sal_Char(nFeature >> 24 & 0xff); aString[0] = sal_Char(nFeature >> 24 & 0xff);
...@@ -41,16 +43,33 @@ Feature::Feature(FeatureID const& rID, FeatureType eType) ...@@ -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::FeatureParameter(sal_uInt32 nCode, OUString aDescription) FeatureParameter::FeatureParameter(uint32_t nCode, OUString aDescription)
: m_nCode(nCode) : m_nCode(nCode)
, m_sDescription(std::move(aDescription)) , m_sDescription(std::move(aDescription))
, m_pDescriptionID(nullptr) , m_pDescriptionID(nullptr)
{ {
} }
FeatureParameter::FeatureParameter(sal_uInt32 nCode, const char* pDescriptionID) FeatureParameter::FeatureParameter(uint32_t nCode, const char* pDescriptionID)
: m_nCode(nCode) : m_nCode(nCode)
, m_pDescriptionID(pDescriptionID) , m_pDescriptionID(pDescriptionID)
{ {
...@@ -68,7 +87,7 @@ OUString FeatureParameter::getDescription() const ...@@ -68,7 +87,7 @@ OUString FeatureParameter::getDescription() const
return aReturnString; return aReturnString;
} }
sal_uInt32 FeatureParameter::getCode() const { return m_nCode; } uint32_t FeatureParameter::getCode() const { return m_nCode; }
// FeatureDefinition // FeatureDefinition
...@@ -79,7 +98,7 @@ FeatureDefinition::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, FeatureParameterType eType,
std::vector<FeatureParameter> const& rEnumParameters) std::vector<FeatureParameter> const& rEnumParameters)
: m_nCode(nCode) : m_nCode(nCode)
...@@ -90,7 +109,7 @@ FeatureDefinition::FeatureDefinition(sal_uInt32 nCode, OUString const& rDescript ...@@ -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) OUString const& rNumericPart)
: m_nCode(nCode) : m_nCode(nCode)
, m_pDescriptionID(pDescriptionID) , m_pDescriptionID(pDescriptionID)
...@@ -99,7 +118,7 @@ FeatureDefinition::FeatureDefinition(sal_uInt32 nCode, const char* pDescriptionI ...@@ -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) std::vector<FeatureParameter> aEnumParameters)
: m_nCode(nCode) : m_nCode(nCode)
, m_pDescriptionID(pDescriptionID) , m_pDescriptionID(pDescriptionID)
...@@ -132,7 +151,7 @@ OUString FeatureDefinition::getDescription() const ...@@ -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; } FeatureParameterType FeatureDefinition::getType() const { return m_eType; }
......
...@@ -32,7 +32,7 @@ FeatureParser::FeatureParser(OUString const& rFontName) ...@@ -32,7 +32,7 @@ FeatureParser::FeatureParser(OUString const& rFontName)
if (nPrefixIdx < 0) if (nPrefixIdx < 0)
return; return;
OUString sName = rFontName.getToken(0, vcl::font::FeaturePrefix, ++nPrefixIdx); OUString sName = rFontName.copy(++nPrefixIdx);
sal_Int32 nIndex = 0; sal_Int32 nIndex = 0;
do do
{ {
...@@ -40,33 +40,28 @@ FeatureParser::FeatureParser(OUString const& rFontName) ...@@ -40,33 +40,28 @@ FeatureParser::FeatureParser(OUString const& rFontName)
sal_Int32 nInnerIdx{ 0 }; sal_Int32 nInnerIdx{ 0 };
OUString sID = sToken.getToken(0, '=', nInnerIdx); OUString sID = sToken.getToken(0, '=', nInnerIdx);
OUString sValue = sToken.getToken(0, '=', nInnerIdx);
if (sID.getLength() == 4 && sValue != "0") if (sID == "lang")
{ {
if (sID == "lang") m_sLanguage = sToken.getToken(0, '=', nInnerIdx);
{ }
m_sLanguage = sValue; else
} {
else OString sFeature = OUStringToOString(sToken, RTL_TEXTENCODING_ASCII_US);
{ FeatureSetting aFeature(sFeature);
OString sFeatureCodeAscii = OUStringToOString(sID, RTL_TEXTENCODING_ASCII_US); if (aFeature.m_nTag != 0)
sal_uInt32 nCode = vcl::font::featureCode(sFeatureCodeAscii.getStr()); m_aFeatures.push_back(aFeature);
sal_uInt32 nValue = sValue.isEmpty() ? 1 : sValue.toUInt32();
if (nValue != 0)
m_aFeatures.emplace_back(nCode, nValue);
}
} }
} while (nIndex >= 0); } 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; std::unordered_map<uint32_t, uint32_t> aResultMap;
for (auto const& rPair : m_aFeatures) for (auto const& rFeat : m_aFeatures)
{ {
aResultMap.emplace(rPair); if (rFeat.m_nValue != 0)
aResultMap.emplace(rFeat.m_nTag, rFeat.m_nValue);
} }
return aResultMap; return aResultMap;
} }
......
...@@ -74,9 +74,9 @@ void GenericSalLayout::ParseFeatures(const OUString& aName) ...@@ -74,9 +74,9 @@ void GenericSalLayout::ParseFeatures(const OUString& aName)
if (!sLanguage.isEmpty()) if (!sLanguage.isEmpty())
msLanguage = OUStringToOString(sLanguage, RTL_TEXTENCODING_ASCII_US); 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); maFeatures.push_back(aFeature);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment