diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2018-06-15 18:50:00 +0200 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2018-06-16 14:28:40 +0200 |
commit | bda33ba2ce4d53214e1bd9ee62b05ced0525e8db (patch) | |
tree | 2668d78510ba316a40478b629d87009610d9e19c | |
parent | 8dacd42f3af903ac3daeef8f4dd444ffc7e1a99c (diff) |
tdf#58941 implement retrieving font features and structures
This adds the following:
- Retrieving of features using HarfBuzz
- Retrieving of feature definitions from graphite fonts
- Adds description texts of OpenType features
- Tests for retrieving features (Linux Libertine G graphite font)
and making sure the features and definitions are what we
expect.
Change-Id: I51573fe086e59c6228cb546bbfac95ac53824c47
Reviewed-on: https://gerrit.libreoffice.org/55892
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
-rw-r--r-- | include/vcl/font/Feature.hxx | 99 | ||||
-rw-r--r-- | include/vcl/outdev.hxx | 6 | ||||
-rw-r--r-- | vcl/CppunitTest_vcl_fontfeature.mk | 49 | ||||
-rw-r--r-- | vcl/Library_vcl.mk | 3 | ||||
-rw-r--r-- | vcl/Module_vcl.mk | 1 | ||||
-rw-r--r-- | vcl/inc/font/FeatureCollector.hxx | 52 | ||||
-rw-r--r-- | vcl/inc/font/OpenTypeFeatureDefinitonList.hxx | 47 | ||||
-rw-r--r-- | vcl/inc/font/OpenTypeFeatureStrings.hrc | 184 | ||||
-rw-r--r-- | vcl/qa/cppunit/FontFeatureTest.cxx | 110 | ||||
-rw-r--r-- | vcl/source/font/Feature.cxx | 119 | ||||
-rw-r--r-- | vcl/source/font/FeatureCollector.cxx | 141 | ||||
-rw-r--r-- | vcl/source/font/OpenTypeFeatureDefinitonList.cxx | 199 | ||||
-rw-r--r-- | vcl/source/outdev/font.cxx | 34 |
13 files changed, 1044 insertions, 0 deletions
diff --git a/include/vcl/font/Feature.hxx b/include/vcl/font/Feature.hxx new file mode 100644 index 000000000000..0fa8f6d5bb70 --- /dev/null +++ b/include/vcl/font/Feature.hxx @@ -0,0 +1,99 @@ +/* -*- 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_FEATURE_HXX +#define INCLUDED_VCL_FONT_FEATURE_HXX + +#include <vcl/dllapi.h> +#include <rtl/ustring.hxx> +#include <rtl/string.hxx> +#include <memory> +#include <vector> +#include <unordered_map> + +namespace vcl +{ +namespace font +{ +constexpr sal_uInt32 featureCode(const char sFeature[4]) +{ + return sFeature[0] << 24 | sFeature[1] << 16 | sFeature[2] << 8 | sFeature[3] << 0; +} + +VCL_DLLPUBLIC OUString featureCodeAsString(sal_uInt32 nFeature); + +enum class FeatureParameterType +{ + BOOL, + ENUM +}; + +struct VCL_DLLPUBLIC FeatureParameter +{ +private: + sal_uInt32 m_nCode; + OUString m_sDescription; + const char* m_pDescriptionID; + +public: + FeatureParameter(sal_uInt32 nCode, OUString aDescription); + FeatureParameter(sal_uInt32 nCode, const char* pDescriptionID); + + sal_uInt32 getCode() const; + OUString getDescription() const; +}; + +class VCL_DLLPUBLIC FeatureDefinition +{ +private: + sal_uInt32 m_nCode; + OUString m_sDescription; + const char* m_pDescriptionID; + FeatureParameterType m_eType; + // the index of the parameter defines the enum value, string is the description + std::vector<FeatureParameter> m_aEnumParameters; + +public: + FeatureDefinition(); + FeatureDefinition(sal_uInt32 nCode, OUString const& rDescription, + FeatureParameterType eType = FeatureParameterType::BOOL, + std::vector<FeatureParameter> const& rEnumParameters + = std::vector<FeatureParameter>{}); + FeatureDefinition(sal_uInt32 nCode, const char* pDescriptionID); + FeatureDefinition(sal_uInt32 nCode, const char* pDescriptionID, + std::vector<FeatureParameter> aEnumParameters); + + const std::vector<FeatureParameter>& getEnumParameters() const; + OUString getDescription() const; + sal_uInt32 getCode() const; + FeatureParameterType getType() const; + + operator bool() const; +}; + +struct VCL_DLLPUBLIC FeatureID +{ + sal_uInt32 m_aFeatureCode; + sal_uInt32 m_aScriptCode; + sal_uInt32 m_aLanguageCode; +}; + +struct VCL_DLLPUBLIC Feature +{ + FeatureID m_aID; + FeatureDefinition m_aDefinition; +}; + +} // end font namespace + +} // end vcl namespace + +#endif // INCLUDED_VCL_FONT_FEATURE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index 5cff1915b602..96fd4246a070 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -101,6 +101,9 @@ namespace vcl class TextLayoutCache; class Window; class FontInfo; + namespace font { + struct Feature; + } } namespace com { namespace sun { namespace star { namespace rendering { @@ -1218,6 +1221,9 @@ public: bool GetFontCharMap( FontCharMapRef& rxFontCharMap ) const; bool GetFontCapabilities( vcl::FontCapabilities& rFontCapabilities ) const; + bool GetFontFeatures(std::vector<vcl::font::Feature>& rFontFeatures) const; + + /** Retrieve detailed font information in platform independent structure @param nFallbacklevel Fallback font level (0 = best matching font) diff --git a/vcl/CppunitTest_vcl_fontfeature.mk b/vcl/CppunitTest_vcl_fontfeature.mk new file mode 100644 index 000000000000..bb3b97106de1 --- /dev/null +++ b/vcl/CppunitTest_vcl_fontfeature.mk @@ -0,0 +1,49 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# 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/. +# + +$(eval $(call gb_CppunitTest_CppunitTest,vcl_fontfeature)) + +$(eval $(call gb_CppunitTest_set_include,vcl_fontfeature,\ + $$(INCLUDE) \ + -I$(SRCDIR)/vcl/inc \ +)) + +$(eval $(call gb_CppunitTest_add_exception_objects,vcl_fontfeature, \ + vcl/qa/cppunit/FontFeatureTest \ +)) + +$(eval $(call gb_CppunitTest_use_externals,vcl_fontfeature,boost_headers)) + +$(eval $(call gb_CppunitTest_use_libraries,vcl_fontfeature, \ + comphelper \ + cppu \ + cppuhelper \ + sal \ + svt \ + test \ + tl \ + tk \ + unotest \ + vcl \ +)) + +$(eval $(call gb_CppunitTest_use_sdk_api,vcl_fontfeature)) + +$(eval $(call gb_CppunitTest_use_ure,vcl_fontfeature)) +$(eval $(call gb_CppunitTest_use_vcl,vcl_fontfeature)) + +$(eval $(call gb_CppunitTest_use_components,vcl_fontfeature,\ + configmgr/source/configmgr \ + i18npool/util/i18npool \ + ucb/source/core/ucb1 \ +)) + +$(eval $(call gb_CppunitTest_use_configuration,vcl_fontfeature)) + +# vim: set noet sw=4 ts=4: diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index fd99be295c98..58fbfaaa8b56 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -403,6 +403,9 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/filter/wmf/wmf \ vcl/source/filter/wmf/wmfexternal \ vcl/source/filter/wmf/wmfwr \ + vcl/source/font/Feature \ + vcl/source/font/FeatureCollector \ + vcl/source/font/OpenTypeFeatureDefinitonList \ vcl/source/font/PhysicalFontCollection \ vcl/source/font/PhysicalFontFace \ vcl/source/font/PhysicalFontFamily \ diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk index a739d5988716..f2dfff71d862 100644 --- a/vcl/Module_vcl.mk +++ b/vcl/Module_vcl.mk @@ -192,6 +192,7 @@ $(eval $(call gb_Module_add_check_targets,vcl,\ CppunitTest_vcl_graphic_test \ CppunitTest_vcl_fontcharmap \ CppunitTest_vcl_font \ + CppunitTest_vcl_fontfeature \ CppunitTest_vcl_fontmetric \ CppunitTest_vcl_complextext \ CppunitTest_vcl_filters_test \ diff --git a/vcl/inc/font/FeatureCollector.hxx b/vcl/inc/font/FeatureCollector.hxx new file mode 100644 index 000000000000..4e918c48e334 --- /dev/null +++ b/vcl/inc/font/FeatureCollector.hxx @@ -0,0 +1,52 @@ +/* -*- 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_INC_FONT_FEATURECOLLECTOR_HXX +#define INCLUDED_VCL_INC_FONT_FEATURECOLLECTOR_HXX + +#include <vcl/font/Feature.hxx> +#include <o3tl/make_unique.hxx> +#include <hb.h> + +namespace vcl +{ +namespace font +{ +class FeatureCollector +{ +private: + hb_face_t* m_pHbFace; + std::vector<vcl::font::Feature>& m_rFontFeatures; + +public: + FeatureCollector(hb_face_t* pHbFace, std::vector<vcl::font::Feature>& rFontFeatures) + : m_pHbFace(pHbFace) + , m_rFontFeatures(rFontFeatures) + { + } + +private: + bool collectGraphiteFeatureDefinition(vcl::font::Feature& rFeature); + + void collectForLanguage(hb_tag_t aTableTag, sal_uInt32 nScript, hb_tag_t aScriptTag, + sal_uInt32 nLanguage, hb_tag_t aLanguageTag); + + void collectForScript(hb_tag_t aTableTag, sal_uInt32 nScript, hb_tag_t aScriptTag); + +public: + void collectForTable(hb_tag_t aTableTag); +}; + +} // end namespace font +} // end namespace vcl + +#endif // INCLUDED_VCL_INC_FONT_FEATURECOLLECTOR_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/font/OpenTypeFeatureDefinitonList.hxx b/vcl/inc/font/OpenTypeFeatureDefinitonList.hxx new file mode 100644 index 000000000000..f606017d7412 --- /dev/null +++ b/vcl/inc/font/OpenTypeFeatureDefinitonList.hxx @@ -0,0 +1,47 @@ +/* -*- 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_INC_FONT_OPENTYPEFEATUREDEFINITONLIST_HXX +#define INCLUDED_VCL_INC_FONT_OPENTYPEFEATUREDEFINITONLIST_HXX + +#include <vcl/dllapi.h> +#include <vcl/font/Feature.hxx> +#include <rtl/instance.hxx> +#include <memory> +#include <vector> +#include <unordered_map> + +namespace vcl +{ +namespace font +{ +class VCL_DLLPUBLIC OpenTypeFeatureDefinitonListPrivate +{ +private: + std::vector<FeatureDefinition> m_aFeatureDefinition; + std::unordered_map<sal_uInt32, size_t> m_aCodeToIndex; + + void init(); + +public: + OpenTypeFeatureDefinitonListPrivate(); + FeatureDefinition getDefinition(sal_uInt32 nFeatureCode); +}; + +class VCL_DLLPUBLIC OpenTypeFeatureDefinitonList + : public rtl::Static<OpenTypeFeatureDefinitonListPrivate, OpenTypeFeatureDefinitonList> +{ +}; + +} // end font namespace +} // end vcl namespace + +#endif // INCLUDED_VCL_INC_FONT_OPENTYPEFEATUREDEFINITONLIST_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/font/OpenTypeFeatureStrings.hrc b/vcl/inc/font/OpenTypeFeatureStrings.hrc new file mode 100644 index 000000000000..379a013b9f89 --- /dev/null +++ b/vcl/inc/font/OpenTypeFeatureStrings.hrc @@ -0,0 +1,184 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_VCL_INC_FONT_OPENTYPEFEATRESTRINGS_HRC +#define INCLUDED_VCL_INC_FONT_OPENTYPEFEATRESTRINGS_HRC + +#define NC_(Context, String) (Context "\004" u8##String) + +#define STR_FONT_FEATURE_ID_AALT NC_("STR_FONT_FEATURE_ID_AALT", "Access All Alternates") +#define STR_FONT_FEATURE_ID_ABVF NC_("STR_FONT_FEATURE_ID_ABVF", "Above Base Forms") +#define STR_FONT_FEATURE_ID_ABVM NC_("STR_FONT_FEATURE_ID_ABVM", "Above Base Mark Positioning") +#define STR_FONT_FEATURE_ID_ABVS NC_("STR_FONT_FEATURE_ID_ABVS", "Above Base Substitutions") +#define STR_FONT_FEATURE_ID_AFRC NC_("STR_FONT_FEATURE_ID_AFRC", "Alternative (Vertical) Fractions") +#define STR_FONT_FEATURE_ID_AKHN NC_("STR_FONT_FEATURE_ID_AKHN", "Akhands") +#define STR_FONT_FEATURE_ID_ALIG NC_("STR_FONT_FEATURE_ID_ALIG", "Ancient Ligatures") +#define STR_FONT_FEATURE_ID_BLWF NC_("STR_FONT_FEATURE_ID_BLWF", "Below Base Forms") +#define STR_FONT_FEATURE_ID_BLWM NC_("STR_FONT_FEATURE_ID_BLWM", "Below Base Mark Positioning") +#define STR_FONT_FEATURE_ID_BLWS NC_("STR_FONT_FEATURE_ID_BLWS", "Below Base Substitutions") +#define STR_FONT_FEATURE_ID_C2PC NC_("STR_FONT_FEATURE_ID_C2PC", "Capitals to Petite Capitals") +#define STR_FONT_FEATURE_ID_C2SC NC_("STR_FONT_FEATURE_ID_C2SC", "Capitals to Small Capitals") +#define STR_FONT_FEATURE_ID_CALT NC_("STR_FONT_FEATURE_ID_CALT", "Contextual Alternates") +#define STR_FONT_FEATURE_ID_CASE NC_("STR_FONT_FEATURE_ID_CASE", "Case-Sensitive Forms") +#define STR_FONT_FEATURE_ID_CCMP NC_("STR_FONT_FEATURE_ID_CCMP", "Glyph Composition / Decomposition") +#define STR_FONT_FEATURE_ID_CFAR NC_("STR_FONT_FEATURE_ID_CFAR", "Conjunct Form After Ro") +#define STR_FONT_FEATURE_ID_CJCT NC_("STR_FONT_FEATURE_ID_CJCT", "Conjunct Forms") +#define STR_FONT_FEATURE_ID_CLIG NC_("STR_FONT_FEATURE_ID_CLIG", "Contextual Ligatures") +#define STR_FONT_FEATURE_ID_CPCT NC_("STR_FONT_FEATURE_ID_CPCT", "Centered CJK Punctuation") +#define STR_FONT_FEATURE_ID_CPSP NC_("STR_FONT_FEATURE_ID_CPSP", "Capital Spacing") +#define STR_FONT_FEATURE_ID_CSWH NC_("STR_FONT_FEATURE_ID_CSWH", "Contextual Swash") +#define STR_FONT_FEATURE_ID_CURS NC_("STR_FONT_FEATURE_ID_CURS", "Cursive Attachment") +#define STR_FONT_FEATURE_ID_CV01 NC_("STR_FONT_FEATURE_ID_CV01", "Character Variant 1") +#define STR_FONT_FEATURE_ID_CV02 NC_("STR_FONT_FEATURE_ID_CV02", "Character Variant 2") +#define STR_FONT_FEATURE_ID_CV03 NC_("STR_FONT_FEATURE_ID_CV03", "Character Variant 3") +#define STR_FONT_FEATURE_ID_CV04 NC_("STR_FONT_FEATURE_ID_CV04", "Character Variant 4") +#define STR_FONT_FEATURE_ID_CV05 NC_("STR_FONT_FEATURE_ID_CV05", "Character Variant 5") +#define STR_FONT_FEATURE_ID_CV06 NC_("STR_FONT_FEATURE_ID_CV06", "Character Variant 6") +#define STR_FONT_FEATURE_ID_CV07 NC_("STR_FONT_FEATURE_ID_CV07", "Character Variant 7") +#define STR_FONT_FEATURE_ID_CV08 NC_("STR_FONT_FEATURE_ID_CV08", "Character Variant 8") +#define STR_FONT_FEATURE_ID_CV09 NC_("STR_FONT_FEATURE_ID_CV09", "Character Variant 9") +#define STR_FONT_FEATURE_ID_CV10 NC_("STR_FONT_FEATURE_ID_CV10", "Character Variant 10") +#define STR_FONT_FEATURE_ID_CV11 NC_("STR_FONT_FEATURE_ID_CV11", "Character Variant 11") +#define STR_FONT_FEATURE_ID_DCAP NC_("STR_FONT_FEATURE_ID_DCAP", "Drop Caps") +#define STR_FONT_FEATURE_ID_DIST NC_("STR_FONT_FEATURE_ID_DIST", "Distances") +#define STR_FONT_FEATURE_ID_DLIG NC_("STR_FONT_FEATURE_ID_DLIG", "Discretionary Ligatures") +#define STR_FONT_FEATURE_ID_DNOM NC_("STR_FONT_FEATURE_ID_DNOM", "Denominators") +#define STR_FONT_FEATURE_ID_DPNG NC_("STR_FONT_FEATURE_ID_DPNG", "Dipthongs (Obsolete)") +#define STR_FONT_FEATURE_ID_DTLS NC_("STR_FONT_FEATURE_ID_DTLS", "Dotless Forms") +#define STR_FONT_FEATURE_ID_EXPT NC_("STR_FONT_FEATURE_ID_EXPT", "Expert Forms") +#define STR_FONT_FEATURE_ID_FALT NC_("STR_FONT_FEATURE_ID_FALT", "Final Glyph on Line Alternates") +#define STR_FONT_FEATURE_ID_FIN2 NC_("STR_FONT_FEATURE_ID_FIN2", "Terminal Forms #2") +#define STR_FONT_FEATURE_ID_FIN3 NC_("STR_FONT_FEATURE_ID_FIN3", "Terminal Forms #3") +#define STR_FONT_FEATURE_ID_FINA NC_("STR_FONT_FEATURE_ID_FINA", "Terminal Forms") +#define STR_FONT_FEATURE_ID_FLAC NC_("STR_FONT_FEATURE_ID_FLAC", "Flattened Accent Over Capitals") +#define STR_FONT_FEATURE_ID_FRAC NC_("STR_FONT_FEATURE_ID_FRAC", "DIagonal Fractions") +#define STR_FONT_FEATURE_ID_FRAC_PARAM_1 NC_("STR_FONT_FEATURE_ID_FRAC_PARAM_1", "Diagonal Fractions") +#define STR_FONT_FEATURE_ID_FRAC_PARAM_2 NC_("STR_FONT_FEATURE_ID_FRAC_PARAM_2", "Nut Fractions") +#define STR_FONT_FEATURE_ID_FWID NC_("STR_FONT_FEATURE_ID_FWID", "Full Widths") +#define STR_FONT_FEATURE_ID_HALF NC_("STR_FONT_FEATURE_ID_HALF", "Half Forms") +#define STR_FONT_FEATURE_ID_HALN NC_("STR_FONT_FEATURE_ID_HALN", "Halant Forms") +#define STR_FONT_FEATURE_ID_HALT NC_("STR_FONT_FEATURE_ID_HALT", "Alternate Half Widths") +#define STR_FONT_FEATURE_ID_HIST NC_("STR_FONT_FEATURE_ID_HIST", "Historical Forms") +#define STR_FONT_FEATURE_ID_HKNA NC_("STR_FONT_FEATURE_ID_HKNA", "Horizontal Kana Alternates") +#define STR_FONT_FEATURE_ID_HLIG NC_("STR_FONT_FEATURE_ID_HLIG", "Historical Ligatures") +#define STR_FONT_FEATURE_ID_HNGL NC_("STR_FONT_FEATURE_ID_HNGL", "Hanja to Hangul") +#define STR_FONT_FEATURE_ID_HOJO NC_("STR_FONT_FEATURE_ID_HOJO", "Hojo Kanji Forms (JIS X 0212-1990 Kanji Forms)") +#define STR_FONT_FEATURE_ID_HWID NC_("STR_FONT_FEATURE_ID_HWID", "Half Widths") +#define STR_FONT_FEATURE_ID_INIT NC_("STR_FONT_FEATURE_ID_INIT", "Initial Forms") +#define STR_FONT_FEATURE_ID_ISOL NC_("STR_FONT_FEATURE_ID_ISOL", "Isolated Forms") +#define STR_FONT_FEATURE_ID_ITAL NC_("STR_FONT_FEATURE_ID_ITAL", "Italics") +#define STR_FONT_FEATURE_ID_JALT NC_("STR_FONT_FEATURE_ID_JALT", "Justification Alternates") +#define STR_FONT_FEATURE_ID_JP04 NC_("STR_FONT_FEATURE_ID_JP04", "JIS2004 Forms") +#define STR_FONT_FEATURE_ID_JP78 NC_("STR_FONT_FEATURE_ID_JP78", "JIS78 Forms") +#define STR_FONT_FEATURE_ID_JP83 NC_("STR_FONT_FEATURE_ID_JP83", "JIS83 Forms") +#define STR_FONT_FEATURE_ID_JP90 NC_("STR_FONT_FEATURE_ID_JP90", "JIS90 Forms") +#define STR_FONT_FEATURE_ID_KERN NC_("STR_FONT_FEATURE_ID_KERN", "Horizontal Kerning") +#define STR_FONT_FEATURE_ID_LFBD NC_("STR_FONT_FEATURE_ID_LFBD", "Left Bounds") +#define STR_FONT_FEATURE_ID_LIGA NC_("STR_FONT_FEATURE_ID_LIGA", "Standard Ligatures") +#define STR_FONT_FEATURE_ID_LJMO NC_("STR_FONT_FEATURE_ID_LJMO", "Leading Jamo Forms") +#define STR_FONT_FEATURE_ID_LNUM NC_("STR_FONT_FEATURE_ID_LNUM", "Lining Figures") +#define STR_FONT_FEATURE_ID_LOCL NC_("STR_FONT_FEATURE_ID_LOCL", "Localized Forms") +#define STR_FONT_FEATURE_ID_LTRA NC_("STR_FONT_FEATURE_ID_LTRA", "Left to Right Alternates") +#define STR_FONT_FEATURE_ID_LTRM NC_("STR_FONT_FEATURE_ID_LTRM", "Left to Right Mirrored Forms") +#define STR_FONT_FEATURE_ID_MARK NC_("STR_FONT_FEATURE_ID_MARK", "Mark Positioning") +#define STR_FONT_FEATURE_ID_MED2 NC_("STR_FONT_FEATURE_ID_MED2", "Medial Forms #2") +#define STR_FONT_FEATURE_ID_MEDI NC_("STR_FONT_FEATURE_ID_MEDI", "Medial Forms") +#define STR_FONT_FEATURE_ID_MGRK NC_("STR_FONT_FEATURE_ID_MGRK", "Mathematical Greek") +#define STR_FONT_FEATURE_ID_MKMK NC_("STR_FONT_FEATURE_ID_MKMK", "Mark to Mark Positioning") +#define STR_FONT_FEATURE_ID_MSET NC_("STR_FONT_FEATURE_ID_MSET", "Mark Positioning via Substitution") +#define STR_FONT_FEATURE_ID_NALT NC_("STR_FONT_FEATURE_ID_NALT", "Alternate Annotation Forms") +#define STR_FONT_FEATURE_ID_NLCK NC_("STR_FONT_FEATURE_ID_NLCK", "NLC Kanji Forms") +#define STR_FONT_FEATURE_ID_NUKT NC_("STR_FONT_FEATURE_ID_NUKT", "Nukta Forms") +#define STR_FONT_FEATURE_ID_NUMR NC_("STR_FONT_FEATURE_ID_NUMR", "Numerators") +#define STR_FONT_FEATURE_ID_ONUM NC_("STR_FONT_FEATURE_ID_ONUM", "Oldstyle Figures") +#define STR_FONT_FEATURE_ID_OPBD NC_("STR_FONT_FEATURE_ID_OPBD", "Optical Bounds") +#define STR_FONT_FEATURE_ID_ORDN NC_("STR_FONT_FEATURE_ID_ORDN", "Ordinals") +#define STR_FONT_FEATURE_ID_ORNM NC_("STR_FONT_FEATURE_ID_ORNM", "Ornaments") +#define STR_FONT_FEATURE_ID_PALT NC_("STR_FONT_FEATURE_ID_PALT", "Proportional Alternate Metrics") +#define STR_FONT_FEATURE_ID_PCAP NC_("STR_FONT_FEATURE_ID_PCAP", "Lowercase to Petite Capitals") +#define STR_FONT_FEATURE_ID_PKNA NC_("STR_FONT_FEATURE_ID_PKNA", "Proportional Kana") +#define STR_FONT_FEATURE_ID_PNUM NC_("STR_FONT_FEATURE_ID_PNUM", "Proportional Numbers") +#define STR_FONT_FEATURE_ID_PREF NC_("STR_FONT_FEATURE_ID_PREF", "Pre Base Forms") +#define STR_FONT_FEATURE_ID_PRES NC_("STR_FONT_FEATURE_ID_PRES", "Pre Base Substitutions") +#define STR_FONT_FEATURE_ID_PSTF NC_("STR_FONT_FEATURE_ID_PSTF", "Post Base Forms") +#define STR_FONT_FEATURE_ID_PSTS NC_("STR_FONT_FEATURE_ID_PSTS", "Post Base Substitutions") +#define STR_FONT_FEATURE_ID_PWID NC_("STR_FONT_FEATURE_ID_PWID", "Proportional Widths") +#define STR_FONT_FEATURE_ID_QWID NC_("STR_FONT_FEATURE_ID_QWID", "Quarter Widths") +#define STR_FONT_FEATURE_ID_RAND NC_("STR_FONT_FEATURE_ID_RAND", "Randomize") +#define STR_FONT_FEATURE_ID_RCLT NC_("STR_FONT_FEATURE_ID_RCLT", "Required Contextual Alternates") +#define STR_FONT_FEATURE_ID_RKRF NC_("STR_FONT_FEATURE_ID_RKRF", "Rakar Forms") +#define STR_FONT_FEATURE_ID_RLIG NC_("STR_FONT_FEATURE_ID_RLIG", "Required Ligatures") +#define STR_FONT_FEATURE_ID_RPHF NC_("STR_FONT_FEATURE_ID_RPHF", "Reph Forms") +#define STR_FONT_FEATURE_ID_RTBD NC_("STR_FONT_FEATURE_ID_RTBD", "Right Bounds") +#define STR_FONT_FEATURE_ID_RTLA NC_("STR_FONT_FEATURE_ID_RTLA", "Right to Left Alternates") +#define STR_FONT_FEATURE_ID_RTLM NC_("STR_FONT_FEATURE_ID_RTLM", "Right to Left Mirrored Forms") +#define STR_FONT_FEATURE_ID_RUBY NC_("STR_FONT_FEATURE_ID_RUBY", "Ruby Notation Forms") +#define STR_FONT_FEATURE_ID_RVRN NC_("STR_FONT_FEATURE_ID_RVRN", "Required Variation Alternates") +#define STR_FONT_FEATURE_ID_SALT NC_("STR_FONT_FEATURE_ID_SALT", "Stylistic Alternates") +#define STR_FONT_FEATURE_ID_SINF NC_("STR_FONT_FEATURE_ID_SINF", "Scientific Inferiors") +#define STR_FONT_FEATURE_ID_SIZE NC_("STR_FONT_FEATURE_ID_SIZE", "Optical Size") +#define STR_FONT_FEATURE_ID_SMCP NC_("STR_FONT_FEATURE_ID_SMCP", "Lowercase to Small Capitals") +#define STR_FONT_FEATURE_ID_SMPL NC_("STR_FONT_FEATURE_ID_SMPL", "Simplified Forms") +#define STR_FONT_FEATURE_ID_SS01 NC_("STR_FONT_FEATURE_ID_SS01", "Stylistic Set 1") +#define STR_FONT_FEATURE_ID_SS02 NC_("STR_FONT_FEATURE_ID_SS02", "Stylistic Set 2") +#define STR_FONT_FEATURE_ID_SS03 NC_("STR_FONT_FEATURE_ID_SS03", "Stylistic Set 3") +#define STR_FONT_FEATURE_ID_SS04 NC_("STR_FONT_FEATURE_ID_SS04", "Stylistic Set 4") +#define STR_FONT_FEATURE_ID_SS05 NC_("STR_FONT_FEATURE_ID_SS05", "Stylistic Set 5") +#define STR_FONT_FEATURE_ID_SS06 NC_("STR_FONT_FEATURE_ID_SS06", "Stylistic Set 6") +#define STR_FONT_FEATURE_ID_SS07 NC_("STR_FONT_FEATURE_ID_SS07", "Stylistic Set 7") +#define STR_FONT_FEATURE_ID_SS08 NC_("STR_FONT_FEATURE_ID_SS08", "Stylistic Set 8") +#define STR_FONT_FEATURE_ID_SS09 NC_("STR_FONT_FEATURE_ID_SS09", "Stylistic Set 9") +#define STR_FONT_FEATURE_ID_SS10 NC_("STR_FONT_FEATURE_ID_SS10", "Stylistic Set 10") +#define STR_FONT_FEATURE_ID_SS11 NC_("STR_FONT_FEATURE_ID_SS11", "Stylistic Set 11") +#define STR_FONT_FEATURE_ID_SS12 NC_("STR_FONT_FEATURE_ID_SS12", "Stylistic Set 12") +#define STR_FONT_FEATURE_ID_SS13 NC_("STR_FONT_FEATURE_ID_SS13", "Stylistic Set 13") +#define STR_FONT_FEATURE_ID_SS14 NC_("STR_FONT_FEATURE_ID_SS14", "Stylistic Set 14") +#define STR_FONT_FEATURE_ID_SS15 NC_("STR_FONT_FEATURE_ID_SS15", "Stylistic Set 15") +#define STR_FONT_FEATURE_ID_SS16 NC_("STR_FONT_FEATURE_ID_SS16", "Stylistic Set 16") +#define STR_FONT_FEATURE_ID_SS17 NC_("STR_FONT_FEATURE_ID_SS17", "Stylistic Set 17") +#define STR_FONT_FEATURE_ID_SS18 NC_("STR_FONT_FEATURE_ID_SS18", "Stylistic Set 18") +#define STR_FONT_FEATURE_ID_SS19 NC_("STR_FONT_FEATURE_ID_SS19", "Stylistic Set 19") +#define STR_FONT_FEATURE_ID_SS20 NC_("STR_FONT_FEATURE_ID_SS20", "Stylistic Set 20") +#define STR_FONT_FEATURE_ID_SSTY NC_("STR_FONT_FEATURE_ID_SSTY", "Script Style") +#define STR_FONT_FEATURE_ID_STCH NC_("STR_FONT_FEATURE_ID_STCH", "Stretching Glyph Decomposition") +#define STR_FONT_FEATURE_ID_SUBS NC_("STR_FONT_FEATURE_ID_SUBS", "Subscript") +#define STR_FONT_FEATURE_ID_SUPS NC_("STR_FONT_FEATURE_ID_SUPS", "Superscript") +#define STR_FONT_FEATURE_ID_SWSH NC_("STR_FONT_FEATURE_ID_SWSH", "Swash") +#define STR_FONT_FEATURE_ID_TITL NC_("STR_FONT_FEATURE_ID_TITL", "Titling") +#define STR_FONT_FEATURE_ID_TJMO NC_("STR_FONT_FEATURE_ID_TJMO", "Trailing Jamo Forms") +#define STR_FONT_FEATURE_ID_TNAM NC_("STR_FONT_FEATURE_ID_TNAM", "Traditional Name Forms") +#define STR_FONT_FEATURE_ID_TNUM NC_("STR_FONT_FEATURE_ID_TNUM", "Tabular Numbers") +#define STR_FONT_FEATURE_ID_TRAD NC_("STR_FONT_FEATURE_ID_TRAD", "Traditional Forms") +#define STR_FONT_FEATURE_ID_TWID NC_("STR_FONT_FEATURE_ID_TWID", "Third Widths") +#define STR_FONT_FEATURE_ID_UNIC NC_("STR_FONT_FEATURE_ID_UNIC", "Unicase") +#define STR_FONT_FEATURE_ID_VALT NC_("STR_FONT_FEATURE_ID_VALT", "Alternate Vertical Metrics") +#define STR_FONT_FEATURE_ID_VATU NC_("STR_FONT_FEATURE_ID_VATU", "Vattu Variants") +#define STR_FONT_FEATURE_ID_VERT NC_("STR_FONT_FEATURE_ID_VERT", "Vertical Alternatives") +#define STR_FONT_FEATURE_ID_VHAL NC_("STR_FONT_FEATURE_ID_VHAL", "Alternate Vertical Half Metrics") +#define STR_FONT_FEATURE_ID_VJMO NC_("STR_FONT_FEATURE_ID_VJMO", "Vowel Jamo Forms") +#define STR_FONT_FEATURE_ID_VKNA NC_("STR_FONT_FEATURE_ID_VKNA", "Vertical Kana Alternates") +#define STR_FONT_FEATURE_ID_VKRN NC_("STR_FONT_FEATURE_ID_VKRN", "Vertical Kerning") +#define STR_FONT_FEATURE_ID_VPAL NC_("STR_FONT_FEATURE_ID_VPAL", "Proportional Alternate Vertical Metrics") +#define STR_FONT_FEATURE_ID_VRT2 NC_("STR_FONT_FEATURE_ID_VRT2", "Vertical Alternates and Rotation") +#define STR_FONT_FEATURE_ID_VRTR NC_("STR_FONT_FEATURE_ID_VRTR", "Vertical Alternates for Rotation") +#define STR_FONT_FEATURE_ID_ZERO NC_("STR_FONT_FEATURE_ID_ZERO", "Slashed Zero") + +#endif // INCLUDED_VCL_INC_STRINGS_HRC + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/qa/cppunit/FontFeatureTest.cxx b/vcl/qa/cppunit/FontFeatureTest.cxx new file mode 100644 index 000000000000..0bb28e306139 --- /dev/null +++ b/vcl/qa/cppunit/FontFeatureTest.cxx @@ -0,0 +1,110 @@ +/* -*- 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 <test/bootstrapfixture.hxx> +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <vcl/font/Feature.hxx> + +#include <vcl/virdev.hxx> +#include <vcl/svapp.hxx> + +class FontFeatureTest : public test::BootstrapFixture +{ +public: + FontFeatureTest() + : BootstrapFixture(true, false) + { + } + + void testGetFontFeatures(); + + CPPUNIT_TEST_SUITE(FontFeatureTest); + CPPUNIT_TEST(testGetFontFeatures); + CPPUNIT_TEST_SUITE_END(); +}; + +void FontFeatureTest::testGetFontFeatures() +{ + ScopedVclPtrInstance<VirtualDevice> aVDev(*Application::GetDefaultDevice(), + DeviceFormat::DEFAULT, DeviceFormat::DEFAULT); + aVDev->SetOutputSizePixel(Size(10, 10)); + + vcl::Font aFont = aVDev->GetFont(); + aFont.SetFamilyName("Linux Libertine G"); + aVDev->SetFont(aFont); + + std::vector<vcl::font::Feature> rFontFeatures; + CPPUNIT_ASSERT(aVDev->GetFontFeatures(rFontFeatures)); + + // We're interested only in defaults here + std::vector<vcl::font::Feature> rDefaultFontFeatures; + OUString aFeaturesString; + for (vcl::font::Feature const& rFeature : rFontFeatures) + { + if (rFeature.m_aID.m_aScriptCode == vcl::font::featureCode("DFLT") + && rFeature.m_aID.m_aLanguageCode == vcl::font::featureCode("dflt")) + { + rDefaultFontFeatures.push_back(rFeature); + aFeaturesString += vcl::font::featureCodeAsString(rFeature.m_aID.m_aFeatureCode) + " "; + } + } + + CPPUNIT_ASSERT_EQUAL(size_t(31), rDefaultFontFeatures.size()); + + OUString aExpectedFeaturesString = "aalt c2sc case ccmp dlig fina frac hlig " + "liga lnum nalt onum pnum salt sinf smcp " + "ss01 ss02 ss03 ss04 ss05 ss06 sups tnum " + "zero cpsp kern lfbd mark mkmk rtbd "; + CPPUNIT_ASSERT_EQUAL(aExpectedFeaturesString, aFeaturesString); + + // Check C2SC feature + { + vcl::font::Feature& rFeature = rDefaultFontFeatures[1]; + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("c2sc"), rFeature.m_aID.m_aFeatureCode); + + vcl::font::FeatureDefinition& rFracFeatureDefinition = rFeature.m_aDefinition; + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("c2sc"), rFracFeatureDefinition.getCode()); + CPPUNIT_ASSERT(!rFracFeatureDefinition.getDescription().isEmpty()); + CPPUNIT_ASSERT_EQUAL(vcl::font::FeatureParameterType::BOOL, + rFracFeatureDefinition.getType()); + + CPPUNIT_ASSERT_EQUAL(size_t(0), rFracFeatureDefinition.getEnumParameters().size()); + } + + // Check FRAC feature + { + vcl::font::Feature& rFeature = rDefaultFontFeatures[6]; + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("frac"), rFeature.m_aID.m_aFeatureCode); + + vcl::font::FeatureDefinition& rFracFeatureDefinition = rFeature.m_aDefinition; + CPPUNIT_ASSERT_EQUAL(vcl::font::featureCode("frac"), rFracFeatureDefinition.getCode()); + CPPUNIT_ASSERT(!rFracFeatureDefinition.getDescription().isEmpty()); + CPPUNIT_ASSERT_EQUAL(vcl::font::FeatureParameterType::ENUM, + rFracFeatureDefinition.getType()); + + CPPUNIT_ASSERT_EQUAL(size_t(2), rFracFeatureDefinition.getEnumParameters().size()); + + vcl::font::FeatureParameter const& rParameter1 + = rFracFeatureDefinition.getEnumParameters()[0]; + CPPUNIT_ASSERT_EQUAL(sal_uInt32(1), rParameter1.getCode()); + CPPUNIT_ASSERT(!rParameter1.getDescription().isEmpty()); + + vcl::font::FeatureParameter const& rParameter2 + = rFracFeatureDefinition.getEnumParameters()[1]; + CPPUNIT_ASSERT_EQUAL(sal_uInt32(2), rParameter2.getCode()); + CPPUNIT_ASSERT(!rParameter2.getDescription().isEmpty()); + } +} + +CPPUNIT_TEST_SUITE_REGISTRATION(FontFeatureTest); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/font/Feature.cxx b/vcl/source/font/Feature.cxx new file mode 100644 index 000000000000..1b7545b560b9 --- /dev/null +++ b/vcl/source/font/Feature.cxx @@ -0,0 +1,119 @@ +/* -*- 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/Feature.hxx> +#include <strings.hrc> +#include <svdata.hxx> + +namespace vcl +{ +namespace font +{ +OUString featureCodeAsString(sal_uInt32 nFeature) +{ + std::vector<sal_Char> aString(5, 0); + aString[0] = sal_Char(nFeature >> 24 & 0xff); + aString[1] = sal_Char(nFeature >> 16 & 0xff); + aString[2] = sal_Char(nFeature >> 8 & 0xff); + aString[3] = sal_Char(nFeature >> 0 & 0xff); + + return OStringToOUString(aString.data(), RTL_TEXTENCODING_ASCII_US); +} + +// FeatureParameter + +FeatureParameter::FeatureParameter(sal_uInt32 nCode, OUString aDescription) + : m_nCode(nCode) + , m_sDescription(aDescription) + , m_pDescriptionID(nullptr) +{ +} + +FeatureParameter::FeatureParameter(sal_uInt32 nCode, const char* pDescriptionID) + : m_nCode(nCode) + , m_pDescriptionID(pDescriptionID) +{ +} + +OUString FeatureParameter::getDescription() const +{ + OUString aReturnString; + + if (m_pDescriptionID) + aReturnString = VclResId(m_pDescriptionID); + else if (!m_sDescription.isEmpty()) + aReturnString = m_sDescription; + + return aReturnString; +} + +sal_uInt32 FeatureParameter::getCode() const { return m_nCode; } + +// FeatureDefinition + +FeatureDefinition::FeatureDefinition() + : m_nCode(0) + , m_pDescriptionID(nullptr) + , m_eType(FeatureParameterType::BOOL) +{ +} + +FeatureDefinition::FeatureDefinition(sal_uInt32 nCode, OUString const& rDescription, + FeatureParameterType eType, + std::vector<FeatureParameter> const& rEnumParameters) + : m_nCode(nCode) + , m_sDescription(rDescription) + , m_pDescriptionID(nullptr) + , m_eType(eType) + , m_aEnumParameters(rEnumParameters) +{ +} + +FeatureDefinition::FeatureDefinition(sal_uInt32 nCode, const char* pDescriptionID) + : m_nCode(nCode) + , m_pDescriptionID(pDescriptionID) + , m_eType(FeatureParameterType::BOOL) +{ +} + +FeatureDefinition::FeatureDefinition(sal_uInt32 nCode, const char* pDescriptionID, + std::vector<FeatureParameter> aEnumParameters) + : m_nCode(nCode) + , m_pDescriptionID(pDescriptionID) + , m_eType(FeatureParameterType::ENUM) + , m_aEnumParameters(aEnumParameters) +{ +} + +const std::vector<FeatureParameter>& FeatureDefinition::getEnumParameters() const +{ + return m_aEnumParameters; +} + +OUString FeatureDefinition::getDescription() const +{ + if (m_pDescriptionID) + return VclResId(m_pDescriptionID); + else if (!m_sDescription.isEmpty()) + return m_sDescription; + else + return vcl::font::featureCodeAsString(m_nCode); +} + +sal_uInt32 FeatureDefinition::getCode() const { return m_nCode; } + +FeatureParameterType FeatureDefinition::getType() const { return m_eType; } + +FeatureDefinition::operator bool() const { return m_nCode != 0; } + +} // end font namespace +} // end vcl namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/font/FeatureCollector.cxx b/vcl/source/font/FeatureCollector.cxx new file mode 100644 index 000000000000..1087a9311daf --- /dev/null +++ b/vcl/source/font/FeatureCollector.cxx @@ -0,0 +1,141 @@ +/* -*- 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/FeatureCollector.hxx> +#include <font/OpenTypeFeatureDefinitonList.hxx> +#include <o3tl/make_unique.hxx> + +#include <hb-ot.h> +#include <hb-graphite2.h> + +namespace vcl +{ +namespace font +{ +bool FeatureCollector::collectGraphiteFeatureDefinition(vcl::font::Feature& rFeature) +{ + gr_face* grFace = hb_graphite2_face_get_gr_face(m_pHbFace); + if (grFace == nullptr) + return false; + + bool bFound = false; + + gr_uint16 nUILanguage = 0x0409; + + gr_uint16 nNumberOfFeatures = gr_face_n_fref(grFace); + gr_feature_val* pFeatures = gr_face_featureval_for_lang(grFace, rFeature.m_aID.m_aLanguageCode); + + if (pFeatures) + { + for (gr_uint16 i = 0; i < nNumberOfFeatures; ++i) + { + const gr_feature_ref* pFeatureRef = gr_face_fref(grFace, i); + gr_uint32 nFeatureCode = gr_fref_id(pFeatureRef); + + if (nFeatureCode == rFeature.m_aID.m_aFeatureCode) + { + gr_uint32 nLabelLength = 0; + void* pLabel = gr_fref_label(pFeatureRef, &nUILanguage, gr_utf8, &nLabelLength); + OUString sLabel(OUString::createFromAscii(static_cast<char*>(pLabel))); + gr_label_destroy(pLabel); + + std::vector<vcl::font::FeatureParameter> aParameters; + gr_uint16 nNumberOfValues = gr_fref_n_values(pFeatureRef); + for (gr_uint16 j = 0; j < nNumberOfValues; ++j) + { + if (gr_fref_value(pFeatureRef, j)) + { + gr_uint32 nValueLabelLength = 0; + void* pValueLabel = gr_fref_value_label(pFeatureRef, j, &nUILanguage, + gr_utf8, &nValueLabelLength); + OUString sValueLabel( + OUString::createFromAscii(static_cast<char*>(pValueLabel))); + aParameters.emplace_back(sal_uInt32(j), sValueLabel); + gr_label_destroy(pValueLabel); + } + } + + auto eFeatureParameterType = vcl::font::FeatureParameterType::ENUM; + + // Check if the parameters are boolean + if (aParameters.size() == 1 && aParameters[0].getDescription() == "True") + { + eFeatureParameterType = vcl::font::FeatureParameterType::BOOL; + aParameters.clear(); + } + rFeature.m_aDefinition = vcl::font::FeatureDefinition( + rFeature.m_aID.m_aFeatureCode, sLabel, eFeatureParameterType, aParameters); + bFound = true; + } + } + } + gr_featureval_destroy(pFeatures); + return bFound; +} + +void FeatureCollector::collectForLanguage(hb_tag_t aTableTag, sal_uInt32 nScript, + hb_tag_t aScriptTag, sal_uInt32 nLanguage, + hb_tag_t aLanguageTag) +{ + unsigned int nFeatureCount = hb_ot_layout_language_get_feature_tags( + m_pHbFace, aTableTag, nScript, nLanguage, 0, nullptr, nullptr); + std::vector<hb_tag_t> aFeatureTags(nFeatureCount); + hb_ot_layout_language_get_feature_tags(m_pHbFace, aTableTag, nScript, nLanguage, 0, + &nFeatureCount, aFeatureTags.data()); + aFeatureTags.resize(nFeatureCount); + + for (hb_tag_t aFeatureTag : aFeatureTags) + { + m_rFontFeatures.emplace_back(); + vcl::font::Feature& rFeature = m_rFontFeatures.back(); + rFeature.m_aID = { aFeatureTag, aScriptTag, aLanguageTag }; + bool bResult = collectGraphiteFeatureDefinition(rFeature); + if (!bResult) + { + FeatureDefinition aDefinition + = OpenTypeFeatureDefinitonList::get().getDefinition(aFeatureTag); + if (aDefinition) + { + rFeature.m_aDefinition = vcl::font::FeatureDefinition(aDefinition); + } + } + } +} + +void FeatureCollector::collectForScript(hb_tag_t aTableTag, sal_uInt32 nScript, hb_tag_t aScriptTag) +{ + collectForLanguage(aTableTag, nScript, aScriptTag, HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, + HB_OT_TAG_DEFAULT_LANGUAGE); + + unsigned int nLanguageCount + = hb_ot_layout_script_get_language_tags(m_pHbFace, aTableTag, nScript, 0, nullptr, nullptr); + std::vector<hb_tag_t> aLanguageTags(nLanguageCount); + hb_ot_layout_script_get_language_tags(m_pHbFace, aTableTag, nScript, 0, &nLanguageCount, + aLanguageTags.data()); + aLanguageTags.resize(nLanguageCount); + for (sal_uInt32 nLanguage = 0; nLanguage < sal_uInt32(nLanguageCount); ++nLanguage) + collectForLanguage(aTableTag, nScript, aScriptTag, nLanguage, aLanguageTags[nLanguage]); +} + +void FeatureCollector::collectForTable(hb_tag_t aTableTag) +{ + unsigned int nScriptCount + = hb_ot_layout_table_get_script_tags(m_pHbFace, aTableTag, 0, nullptr, nullptr); + std::vector<hb_tag_t> aScriptTags(nScriptCount); + hb_ot_layout_table_get_script_tags(m_pHbFace, aTableTag, 0, &nScriptCount, aScriptTags.data()); + aScriptTags.resize(nScriptCount); + + for (sal_uInt32 nScript = 0; nScript < sal_uInt32(nScriptCount); ++nScript) + collectForScript(aTableTag, nScript, aScriptTags[nScript]); +} + +} // end namespace font +} // end namespace vcl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/font/OpenTypeFeatureDefinitonList.cxx b/vcl/source/font/OpenTypeFeatureDefinitonList.cxx new file mode 100644 index 000000000000..17ee8268c741 --- /dev/null +++ b/vcl/source/font/OpenTypeFeatureDefinitonList.cxx @@ -0,0 +1,199 @@ +/* -*- 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/OpenTypeFeatureDefinitonList.hxx> +#include <font/OpenTypeFeatureStrings.hrc> +#include <svdata.hxx> + +namespace vcl +{ +namespace font +{ +OpenTypeFeatureDefinitonListPrivate::OpenTypeFeatureDefinitonListPrivate() { init(); } + +void OpenTypeFeatureDefinitonListPrivate::init() +{ + m_aFeatureDefinition.assign({ + { featureCode("aalt"), STR_FONT_FEATURE_ID_AALT }, + { featureCode("abvf"), STR_FONT_FEATURE_ID_ABVF }, + { featureCode("abvm"), STR_FONT_FEATURE_ID_ABVM }, + { featureCode("abvs"), STR_FONT_FEATURE_ID_ABVS }, + { featureCode("afrc"), STR_FONT_FEATURE_ID_AFRC }, + { featureCode("akhn"), STR_FONT_FEATURE_ID_AKHN }, + { featureCode("alig"), STR_FONT_FEATURE_ID_ALIG }, + { featureCode("blwf"), STR_FONT_FEATURE_ID_BLWF }, + { featureCode("blwm"), STR_FONT_FEATURE_ID_BLWM }, + { featureCode("blws"), STR_FONT_FEATURE_ID_BLWS }, + { 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("ccmp"), STR_FONT_FEATURE_ID_CCMP }, + { featureCode("cfar"), STR_FONT_FEATURE_ID_CFAR }, + { featureCode("cjct"), STR_FONT_FEATURE_ID_CJCT }, + { 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("curs"), STR_FONT_FEATURE_ID_CURS }, + { featureCode("cv01"), STR_FONT_FEATURE_ID_CV01 }, + { featureCode("cv02"), STR_FONT_FEATURE_ID_CV02 }, + { featureCode("cv03"), STR_FONT_FEATURE_ID_CV03 }, + { featureCode("cv04"), STR_FONT_FEATURE_ID_CV04 }, + { featureCode("cv05"), STR_FONT_FEATURE_ID_CV05 }, + { featureCode("cv06"), STR_FONT_FEATURE_ID_CV06 }, + { featureCode("cv07"), STR_FONT_FEATURE_ID_CV07 }, + { featureCode("cv08"), STR_FONT_FEATURE_ID_CV08 }, + { featureCode("cv09"), STR_FONT_FEATURE_ID_CV09 }, + { featureCode("dcap"), STR_FONT_FEATURE_ID_DCAP }, + { featureCode("dist"), STR_FONT_FEATURE_ID_DIST }, + { featureCode("dlig"), STR_FONT_FEATURE_ID_DLIG }, + { featureCode("dnom"), STR_FONT_FEATURE_ID_DNOM }, + { featureCode("dpng"), STR_FONT_FEATURE_ID_DPNG }, + { featureCode("dtls"), STR_FONT_FEATURE_ID_DTLS }, + { featureCode("expt"), STR_FONT_FEATURE_ID_EXPT }, + { featureCode("falt"), STR_FONT_FEATURE_ID_FALT }, + { featureCode("fin2"), STR_FONT_FEATURE_ID_FIN2 }, + { featureCode("fin3"), STR_FONT_FEATURE_ID_FIN3 }, + { featureCode("fina"), STR_FONT_FEATURE_ID_FINA }, + { featureCode("flac"), STR_FONT_FEATURE_ID_FLAC }, + { featureCode("frac"), STR_FONT_FEATURE_ID_FRAC, + std::vector<FeatureParameter>{ { 1, STR_FONT_FEATURE_ID_FRAC_PARAM_1 }, + { 2, STR_FONT_FEATURE_ID_FRAC_PARAM_2 } } }, + { featureCode("fwid"), STR_FONT_FEATURE_ID_FWID }, + { featureCode("half"), STR_FONT_FEATURE_ID_HALF }, + { featureCode("haln"), STR_FONT_FEATURE_ID_HALN }, + { 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("init"), STR_FONT_FEATURE_ID_INIT }, + { featureCode("isol"), STR_FONT_FEATURE_ID_ISOL }, + { 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("ljmo"), STR_FONT_FEATURE_ID_LJMO }, + { featureCode("lnum"), STR_FONT_FEATURE_ID_LNUM }, + { featureCode("locl"), STR_FONT_FEATURE_ID_LOCL }, + { featureCode("ltra"), STR_FONT_FEATURE_ID_LTRA }, + { featureCode("ltrm"), STR_FONT_FEATURE_ID_LTRM }, + { featureCode("mark"), STR_FONT_FEATURE_ID_MARK }, + { featureCode("med2"), STR_FONT_FEATURE_ID_MED2 }, + { featureCode("medi"), STR_FONT_FEATURE_ID_MEDI }, + { featureCode("mgrk"), STR_FONT_FEATURE_ID_MGRK }, + { featureCode("mkmk"), STR_FONT_FEATURE_ID_MKMK }, + { featureCode("mset"), STR_FONT_FEATURE_ID_MSET }, + { featureCode("nalt"), STR_FONT_FEATURE_ID_NALT }, + { featureCode("nlck"), STR_FONT_FEATURE_ID_NLCK }, + { featureCode("nukt"), STR_FONT_FEATURE_ID_NUKT }, + { 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("pref"), STR_FONT_FEATURE_ID_PREF }, + { featureCode("pres"), STR_FONT_FEATURE_ID_PRES }, + { featureCode("pstf"), STR_FONT_FEATURE_ID_PSTF }, + { featureCode("psts"), STR_FONT_FEATURE_ID_PSTS }, + { featureCode("pwid"), STR_FONT_FEATURE_ID_PWID }, + { featureCode("qwid"), STR_FONT_FEATURE_ID_QWID }, + { featureCode("rand"), STR_FONT_FEATURE_ID_RAND }, + { featureCode("rclt"), STR_FONT_FEATURE_ID_RCLT }, + { featureCode("rkrf"), STR_FONT_FEATURE_ID_RKRF }, + { featureCode("rlig"), STR_FONT_FEATURE_ID_RLIG }, + { featureCode("rphf"), STR_FONT_FEATURE_ID_RPHF }, + { featureCode("rtbd"), STR_FONT_FEATURE_ID_RTBD }, + { featureCode("rtla"), STR_FONT_FEATURE_ID_RTLA }, + { featureCode("rtlm"), STR_FONT_FEATURE_ID_RTLM }, + { featureCode("ruby"), STR_FONT_FEATURE_ID_RUBY }, + { featureCode("rvrn"), STR_FONT_FEATURE_ID_RVRN }, + { featureCode("salt"), STR_FONT_FEATURE_ID_SALT }, + { featureCode("sinf"), STR_FONT_FEATURE_ID_SINF }, + { featureCode("size"), STR_FONT_FEATURE_ID_SIZE }, + { featureCode("smcp"), STR_FONT_FEATURE_ID_SMCP }, + { featureCode("smpl"), STR_FONT_FEATURE_ID_SMPL }, + { featureCode("ss01"), STR_FONT_FEATURE_ID_SS01 }, + { featureCode("ss02"), STR_FONT_FEATURE_ID_SS02 }, + { featureCode("ss03"), STR_FONT_FEATURE_ID_SS03 }, + { featureCode("ss04"), STR_FONT_FEATURE_ID_SS04 }, + { featureCode("ss05"), STR_FONT_FEATURE_ID_SS05 }, + { featureCode("ss06"), STR_FONT_FEATURE_ID_SS06 }, + { featureCode("ss07"), STR_FONT_FEATURE_ID_SS07 }, + { featureCode("ss08"), STR_FONT_FEATURE_ID_SS08 }, + { featureCode("ss09"), STR_FONT_FEATURE_ID_SS09 }, + { featureCode("ss10"), STR_FONT_FEATURE_ID_SS10 }, + { featureCode("ss11"), STR_FONT_FEATURE_ID_SS11 }, + { featureCode("ss12"), STR_FONT_FEATURE_ID_SS12 }, + { featureCode("ss13"), STR_FONT_FEATURE_ID_SS13 }, + { featureCode("ss14"), STR_FONT_FEATURE_ID_SS14 }, + { featureCode("ss15"), STR_FONT_FEATURE_ID_SS15 }, + { featureCode("ss16"), STR_FONT_FEATURE_ID_SS16 }, + { featureCode("ss17"), STR_FONT_FEATURE_ID_SS17 }, + { featureCode("ss18"), STR_FONT_FEATURE_ID_SS18 }, + { featureCode("ss19"), STR_FONT_FEATURE_ID_SS19 }, + { featureCode("ss20"), STR_FONT_FEATURE_ID_SS20 }, + { featureCode("ssty"), STR_FONT_FEATURE_ID_SSTY }, + { featureCode("stch"), STR_FONT_FEATURE_ID_STCH }, + { 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("tjmo"), STR_FONT_FEATURE_ID_TJMO }, + { 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("vatu"), STR_FONT_FEATURE_ID_VATU }, + { featureCode("vert"), STR_FONT_FEATURE_ID_VERT }, + { featureCode("vhal"), STR_FONT_FEATURE_ID_VHAL }, + { featureCode("vjmo"), STR_FONT_FEATURE_ID_VJMO }, + { 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); + } +} + +FeatureDefinition OpenTypeFeatureDefinitonListPrivate::getDefinition(sal_uInt32 nFeatureCode) +{ + if (m_aCodeToIndex.find(nFeatureCode) != m_aCodeToIndex.end()) + { + size_t nIndex = m_aCodeToIndex.at(nFeatureCode); + return m_aFeatureDefinition[nIndex]; + } + return FeatureDefinition(); +} + +} // end font namespace +} // end vcl namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx index 439a3df75c5b..2f9a7f7df570 100644 --- a/vcl/source/outdev/font.cxx +++ b/vcl/source/outdev/font.cxx @@ -24,6 +24,7 @@ #include <vcl/print.hxx> #include <vcl/sysdata.hxx> #include <vcl/fontcharmap.hxx> +#include <font/FeatureCollector.hxx> #include <sallayout.hxx> #include <salgdi.hxx> @@ -162,6 +163,39 @@ bool OutputDevice::AddTempDevFont( const OUString& rFileURL, const OUString& rFo return true; } +bool OutputDevice::GetFontFeatures(std::vector<vcl::font::Feature>& rFontFeatures) const +{ + if (mbNewFont) + ImplNewFont(); + + if (mbInitFont) + InitFont(); + + if (!mpFontInstance) + return false; + + LogicalFontInstance* pFontInstance = mpFontInstance; + + if (!pFontInstance) + return false; + + hb_font_t* pHbFont = pFontInstance->GetHbFont(); + + if (!pHbFont) + return false; + + hb_face_t* pHbFace = hb_font_get_face(pHbFont); + + if (!pHbFace) + return false; + + vcl::font::FeatureCollector aFeatureCollector(pHbFace, rFontFeatures); + aFeatureCollector.collectForTable(HB_OT_TAG_GSUB); // substitution + aFeatureCollector.collectForTable(HB_OT_TAG_GPOS); // positioning + + return true; +} + FontMetric OutputDevice::GetFontMetric() const { FontMetric aMetric; |