diff options
Diffstat (limited to 'vcl/source/font/OpenTypeFeatureDefinitionList.cxx')
-rw-r--r-- | vcl/source/font/OpenTypeFeatureDefinitionList.cxx | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/vcl/source/font/OpenTypeFeatureDefinitionList.cxx b/vcl/source/font/OpenTypeFeatureDefinitionList.cxx new file mode 100644 index 000000000..f49837cce --- /dev/null +++ b/vcl/source/font/OpenTypeFeatureDefinitionList.cxx @@ -0,0 +1,200 @@ +/* -*- 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 <font/OpenTypeFeatureDefinitionList.hxx> +#include <font/OpenTypeFeatureStrings.hrc> + +#include <rtl/character.hxx> + +#include <algorithm> + +namespace vcl::font +{ +OpenTypeFeatureDefinitionListPrivate& OpenTypeFeatureDefinitionList() +{ + static OpenTypeFeatureDefinitionListPrivate SINGLETON; + return SINGLETON; +}; + +OpenTypeFeatureDefinitionListPrivate::OpenTypeFeatureDefinitionListPrivate() { init(); } + +void OpenTypeFeatureDefinitionListPrivate::init() +{ + m_aFeatureDefinition.assign({ + { featureCode("aalt"), STR_FONT_FEATURE_ID_AALT }, + { featureCode("afrc"), STR_FONT_FEATURE_ID_AFRC }, + { featureCode("alig"), STR_FONT_FEATURE_ID_ALIG }, + { featureCode("c2pc"), STR_FONT_FEATURE_ID_C2PC }, + { featureCode("c2sc"), STR_FONT_FEATURE_ID_C2SC }, + { featureCode("calt"), STR_FONT_FEATURE_ID_CALT }, + { featureCode("case"), STR_FONT_FEATURE_ID_CASE }, + { featureCode("clig"), STR_FONT_FEATURE_ID_CLIG }, + { featureCode("cpct"), STR_FONT_FEATURE_ID_CPCT }, + { featureCode("cpsp"), STR_FONT_FEATURE_ID_CPSP }, + { featureCode("cswh"), STR_FONT_FEATURE_ID_CSWH }, + { featureCode("dcap"), STR_FONT_FEATURE_ID_DCAP }, + { featureCode("dlig"), STR_FONT_FEATURE_ID_DLIG }, + { featureCode("dnom"), STR_FONT_FEATURE_ID_DNOM }, + { featureCode("dpng"), STR_FONT_FEATURE_ID_DPNG }, + { featureCode("expt"), STR_FONT_FEATURE_ID_EXPT }, + { featureCode("falt"), STR_FONT_FEATURE_ID_FALT }, + { featureCode("frac"), STR_FONT_FEATURE_ID_FRAC }, + { featureCode("fwid"), STR_FONT_FEATURE_ID_FWID }, + { featureCode("halt"), STR_FONT_FEATURE_ID_HALT }, + { featureCode("hist"), STR_FONT_FEATURE_ID_HIST }, + { featureCode("hkna"), STR_FONT_FEATURE_ID_HKNA }, + { featureCode("hlig"), STR_FONT_FEATURE_ID_HLIG }, + { featureCode("hngl"), STR_FONT_FEATURE_ID_HNGL }, + { featureCode("hojo"), STR_FONT_FEATURE_ID_HOJO }, + { featureCode("hwid"), STR_FONT_FEATURE_ID_HWID }, + { featureCode("ital"), STR_FONT_FEATURE_ID_ITAL }, + { featureCode("jalt"), STR_FONT_FEATURE_ID_JALT }, + { featureCode("jp78"), STR_FONT_FEATURE_ID_JP78 }, + { featureCode("jp83"), STR_FONT_FEATURE_ID_JP83 }, + { featureCode("jp90"), STR_FONT_FEATURE_ID_JP90 }, + { featureCode("jp04"), STR_FONT_FEATURE_ID_JP04 }, + { featureCode("kern"), STR_FONT_FEATURE_ID_KERN }, + { featureCode("lfbd"), STR_FONT_FEATURE_ID_LFBD }, + { featureCode("liga"), STR_FONT_FEATURE_ID_LIGA }, + { featureCode("lnum"), STR_FONT_FEATURE_ID_LNUM }, + { featureCode("mgrk"), STR_FONT_FEATURE_ID_MGRK }, + { featureCode("nalt"), STR_FONT_FEATURE_ID_NALT }, + { featureCode("nlck"), STR_FONT_FEATURE_ID_NLCK }, + { featureCode("numr"), STR_FONT_FEATURE_ID_NUMR }, + { featureCode("onum"), STR_FONT_FEATURE_ID_ONUM }, + { featureCode("opbd"), STR_FONT_FEATURE_ID_OPBD }, + { featureCode("ordn"), STR_FONT_FEATURE_ID_ORDN }, + { featureCode("ornm"), STR_FONT_FEATURE_ID_ORNM }, + { featureCode("palt"), STR_FONT_FEATURE_ID_PALT }, + { featureCode("pcap"), STR_FONT_FEATURE_ID_PCAP }, + { featureCode("pkna"), STR_FONT_FEATURE_ID_PKNA }, + { featureCode("pnum"), STR_FONT_FEATURE_ID_PNUM }, + { featureCode("pwid"), STR_FONT_FEATURE_ID_PWID }, + { featureCode("qwid"), STR_FONT_FEATURE_ID_QWID }, + { featureCode("rtbd"), STR_FONT_FEATURE_ID_RTBD }, + { featureCode("ruby"), STR_FONT_FEATURE_ID_RUBY }, + { featureCode("salt"), STR_FONT_FEATURE_ID_SALT }, + { featureCode("sinf"), STR_FONT_FEATURE_ID_SINF }, + { featureCode("smcp"), STR_FONT_FEATURE_ID_SMCP }, + { featureCode("smpl"), STR_FONT_FEATURE_ID_SMPL }, + { featureCode("subs"), STR_FONT_FEATURE_ID_SUBS }, + { featureCode("sups"), STR_FONT_FEATURE_ID_SUPS }, + { featureCode("swsh"), STR_FONT_FEATURE_ID_SWSH }, + { featureCode("titl"), STR_FONT_FEATURE_ID_TITL }, + { featureCode("tnam"), STR_FONT_FEATURE_ID_TNAM }, + { featureCode("tnum"), STR_FONT_FEATURE_ID_TNUM }, + { featureCode("trad"), STR_FONT_FEATURE_ID_TRAD }, + { featureCode("twid"), STR_FONT_FEATURE_ID_TWID }, + { featureCode("unic"), STR_FONT_FEATURE_ID_UNIC }, + { featureCode("valt"), STR_FONT_FEATURE_ID_VALT }, + { featureCode("vhal"), STR_FONT_FEATURE_ID_VHAL }, + { featureCode("vkna"), STR_FONT_FEATURE_ID_VKNA }, + { featureCode("vkrn"), STR_FONT_FEATURE_ID_VKRN }, + { featureCode("vpal"), STR_FONT_FEATURE_ID_VPAL }, + { featureCode("vrt2"), STR_FONT_FEATURE_ID_VRT2 }, + { 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"), + }); +} + +namespace +{ +bool isCharacterVariantCode(sal_uInt32 nFeatureCode) +{ + return ((sal_uInt32(nFeatureCode) >> 24) & 0xFF) == 'c' + && ((sal_uInt32(nFeatureCode) >> 16) & 0xFF) == 'v'; +} + +bool isStylisticSetCode(sal_uInt32 nFeatureCode) +{ + return ((sal_uInt32(nFeatureCode) >> 24) & 0xFF) == 's' + && ((sal_uInt32(nFeatureCode) >> 16) & 0xFF) == 's'; +} + +OUString getNumericLowerPart(sal_uInt32 nFeatureCode) +{ + char cChar1((sal_uInt32(nFeatureCode) >> 8) & 0xFF); + char cChar2((sal_uInt32(nFeatureCode) >> 0) & 0xFF); + + if (rtl::isAsciiDigit(static_cast<unsigned char>(cChar1)) + && rtl::isAsciiDigit(static_cast<unsigned char>(cChar2))) + { + return OUStringChar(cChar1) + OUStringChar(cChar2); + } + return OUString(); +} + +} // end anonymous namespace + +bool OpenTypeFeatureDefinitionListPrivate::isSpecialFeatureCode(sal_uInt32 nFeatureCode) +{ + return isCharacterVariantCode(nFeatureCode) || isStylisticSetCode(nFeatureCode); +} + +FeatureDefinition +OpenTypeFeatureDefinitionListPrivate::handleSpecialFeatureCode(sal_uInt32 nFeatureCode) +{ + FeatureDefinition aFeatureDefinition; + OUString sNumericPart = getNumericLowerPart(nFeatureCode); + if (!sNumericPart.isEmpty()) + { + if (isCharacterVariantCode(nFeatureCode)) + aFeatureDefinition = { nFeatureCode, STR_FONT_FEATURE_ID_CVXX, sNumericPart }; + else if (isStylisticSetCode(nFeatureCode)) + aFeatureDefinition = { nFeatureCode, STR_FONT_FEATURE_ID_SSXX, sNumericPart }; + } + return aFeatureDefinition; +} + +FeatureDefinition OpenTypeFeatureDefinitionListPrivate::getDefinition(sal_uInt32 nFeatureCode) +{ + if (isSpecialFeatureCode(nFeatureCode)) + { + return handleSpecialFeatureCode(nFeatureCode); + } + + if (m_aCodeToIndex.find(nFeatureCode) != m_aCodeToIndex.end()) + { + size_t nIndex = m_aCodeToIndex.at(nFeatureCode); + return m_aFeatureDefinition[nIndex]; + } + return FeatureDefinition(); +} + +bool OpenTypeFeatureDefinitionListPrivate::isRequired(sal_uInt32 nFeatureCode) +{ + return std::find(m_aRequiredFeatures.begin(), m_aRequiredFeatures.end(), nFeatureCode) + != m_aRequiredFeatures.end(); +} + +} // end vcl::font namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |