Kaydet (Commit) dc9ee533 authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl Kaydeden (comit) Tomaž Vajngerl

vcl: parser of font features included in the font name

Change-Id: I7347410b4eb5e940d94c34aac4fdf344869541fa
Reviewed-on: https://gerrit.libreoffice.org/55893
Tested-by: Jenkins
Reviewed-by: 's avatarTomaž Vajngerl <quikee@gmail.com>
üst 099eef24
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef INCLUDED_VCL_FONT_FEATUREPASER_HXX
#define INCLUDED_VCL_FONT_FEATUREPASER_HXX
#include <vcl/dllapi.h>
#include <rtl/ustring.hxx>
#include <rtl/string.hxx>
#include <memory>
#include <vector>
#include <unordered_map>
#include <vcl/font/Feature.hxx>
namespace vcl
{
namespace font
{
// These must not conflict with font name lists which use ; and ,
constexpr const char FeaturePrefix = ':';
constexpr const char FeatureSeparator = '&';
VCL_DLLPUBLIC OUString trimFontNameFeatures(OUString const& rFontName);
class VCL_DLLPUBLIC FeatureParser
{
private:
OUString m_sLanguage;
std::vector<std::pair<sal_uInt32, sal_uInt32>> m_aFeatures;
public:
FeatureParser(OUString const& sFontName);
OUString getLanguage() const { return m_sLanguage; }
std::vector<std::pair<sal_uInt32, sal_uInt32>> getFeatures() const { return m_aFeatures; }
std::unordered_map<sal_uInt32, sal_uInt32> getFeaturesMap();
};
} // end font namespace
} // end vcl namespace
#endif // INCLUDED_VCL_FONT_FEATUREPASER_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -405,6 +405,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/filter/wmf/wmfwr \
vcl/source/font/Feature \
vcl/source/font/FeatureCollector \
vcl/source/font/FeatureParser \
vcl/source/font/OpenTypeFeatureDefinitonList \
vcl/source/font/PhysicalFontCollection \
vcl/source/font/PhysicalFontFace \
......
......@@ -10,8 +10,9 @@
#include <test/bootstrapfixture.hxx>
#include <cppunit/TestAssert.h>
#include <cppunit/TestFixture.h>
#include <vcl/font/Feature.hxx>
#include <vcl/font/Feature.hxx>
#include <vcl/font/FeatureParser.hxx>
#include <vcl/virdev.hxx>
#include <vcl/svapp.hxx>
......@@ -24,9 +25,11 @@ public:
}
void testGetFontFeatures();
void testParseFeature();
CPPUNIT_TEST_SUITE(FontFeatureTest);
CPPUNIT_TEST(testGetFontFeatures);
CPPUNIT_TEST(testParseFeature);
CPPUNIT_TEST_SUITE_END();
};
......@@ -103,6 +106,70 @@ void FontFeatureTest::testGetFontFeatures()
}
}
void FontFeatureTest::testParseFeature()
{
{ // No font features specified
vcl::font::FeatureParser aParser("Font name with no features");
CPPUNIT_ASSERT_EQUAL(size_t(0), aParser.getFeatures().size());
}
{ // One feature specified, no value
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].first);
CPPUNIT_ASSERT_EQUAL(sal_uInt32(1), aFeatures[0].second);
}
{ // 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);
}
{ // 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("bcde"), aFeatures[1].first);
CPPUNIT_ASSERT_EQUAL(sal_uInt32(1), aFeatures[1].second);
CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("efgh"), aFeatures[2].first);
CPPUNIT_ASSERT_EQUAL(sal_uInt32(1), aFeatures[2].second);
}
{
// Multiple features specified, explicit values
// Only 4 char parameter names supported - "toolong" is too long and igoned
// 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());
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("cdef"), aFeatures[1].first);
CPPUNIT_ASSERT_EQUAL(sal_uInt32(3), aFeatures[1].second);
}
{
// Special case - "lang" is parsed specially and access separately not as a feature.
vcl::font::FeatureParser aParser("Font name:abcd=1&lang=slo");
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(OUString("slo"), aParser.getLanguage());
}
}
CPPUNIT_TEST_SUITE_REGISTRATION(FontFeatureTest);
CPPUNIT_PLUGIN_IMPLEMENT();
......
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#include <vcl/font/FeatureParser.hxx>
namespace vcl
{
namespace font
{
OUString trimFontNameFeatures(OUString const& rFontName)
{
OUString sResultName(rFontName);
if (sResultName.indexOf(vcl::font::FeaturePrefix) < 0)
return sResultName;
return sResultName.getToken(0, vcl::font::FeaturePrefix);
}
FeatureParser::FeatureParser(OUString const& rFontName)
{
if (rFontName.indexOf(vcl::font::FeaturePrefix) < 0)
return;
OUString sName = rFontName.getToken(1, vcl::font::FeaturePrefix);
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")
{
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);
}
}
} while (nIndex >= 0);
}
std::unordered_map<sal_uInt32, sal_uInt32> FeatureParser::getFeaturesMap()
{
std::unordered_map<sal_uInt32, sal_uInt32> aResultMap;
for (auto const& rPair : m_aFeatures)
{
aResultMap.emplace(rPair);
}
return aResultMap;
}
} // end font namespace
} // end vcl namespace
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -25,6 +25,8 @@
#include <unotools/configmgr.hxx>
#include <vcl/unohelp.hxx>
#include <vcl/font/Feature.hxx>
#include <vcl/font/FeatureParser.hxx>
#include <scrptrun.h>
#include <com/sun/star/i18n/CharacterIteratorMode.hpp>
#include <i18nlangtag/mslangid.hxx>
......@@ -66,27 +68,16 @@ GenericSalLayout::~GenericSalLayout()
void GenericSalLayout::ParseFeatures(const OUString& aName)
{
if (aName.indexOf(FontSelectPatternAttributes::FEAT_PREFIX) < 0)
return;
vcl::font::FeatureParser aParser(aName);
OUString sLanguage = aParser.getLanguage();
if (!sLanguage.isEmpty())
msLanguage = OUStringToOString(sLanguage, RTL_TEXTENCODING_ASCII_US);
OString sName = OUStringToOString(aName, RTL_TEXTENCODING_ASCII_US);
sName = sName.getToken(1, FontSelectPatternAttributes::FEAT_PREFIX);
sal_Int32 nIndex = 0;
do
for (std::pair<sal_uInt32, sal_uInt32> const & rPair : aParser.getFeatures())
{
OString sToken = sName.getToken(0, FontSelectPatternAttributes::FEAT_SEPARATOR, nIndex);
if (sToken.startsWith("lang="))
{
msLanguage = sToken.getToken(1, '=');
}
else
{
hb_feature_t aFeature;
if (hb_feature_from_string(sToken.getStr(), sToken.getLength(), &aFeature))
maFeatures.push_back(aFeature);
}
hb_feature_t aFeature { rPair.first, rPair.second, 0, SAL_MAX_UINT32 };
maFeatures.push_back(aFeature);
}
while (nIndex >= 0);
}
struct SubRun
......
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