bump product version to 7.2.5.1
[LibreOffice.git] / vcl / source / font / FeatureCollector.cxx
blobe8219b07c3285ac2ab331af510a67236a3883b18
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <font/FeatureCollector.hxx>
11 #include <font/OpenTypeFeatureDefinitionList.hxx>
13 #include <hb-ot.h>
14 #include <hb-graphite2.h>
16 namespace vcl::font
18 bool FeatureCollector::collectGraphite()
20 gr_face* grFace = hb_graphite2_face_get_gr_face(m_pHbFace);
22 if (grFace == nullptr)
23 return false;
25 gr_uint16 nUILanguage = gr_uint16(m_eLanguageType);
27 gr_uint16 nNumberOfFeatures = gr_face_n_fref(grFace);
28 gr_feature_val* pfeatureValues
29 = gr_face_featureval_for_lang(grFace, 0); // shame we don't know which lang
31 for (gr_uint16 i = 0; i < nNumberOfFeatures; ++i)
33 const gr_feature_ref* pFeatureRef = gr_face_fref(grFace, i);
34 gr_uint32 nFeatureCode = gr_fref_id(pFeatureRef);
36 if (nFeatureCode == 0) // illegal feature code - skip
37 continue;
39 gr_uint16 nValue = gr_fref_feature_value(pFeatureRef, pfeatureValues);
40 gr_uint32 nLabelLength = 0;
41 void* pLabel = gr_fref_label(pFeatureRef, &nUILanguage, gr_utf8, &nLabelLength);
42 OUString sLabel(OUString::createFromAscii(static_cast<char*>(pLabel)));
43 gr_label_destroy(pLabel);
45 std::vector<vcl::font::FeatureParameter> aParameters;
46 gr_uint16 nNumberOfValues = gr_fref_n_values(pFeatureRef);
48 if (nNumberOfValues > 0)
50 for (gr_uint16 j = 0; j < nNumberOfValues; ++j)
52 gr_uint32 nValueLabelLength = 0;
53 void* pValueLabel = gr_fref_value_label(pFeatureRef, j, &nUILanguage, gr_utf8,
54 &nValueLabelLength);
55 OUString sValueLabel(OUString::createFromAscii(static_cast<char*>(pValueLabel)));
56 gr_uint16 nParamValue = gr_fref_value(pFeatureRef, j);
57 aParameters.emplace_back(sal_uInt32(nParamValue), sValueLabel);
58 gr_label_destroy(pValueLabel);
61 auto eFeatureParameterType = vcl::font::FeatureParameterType::ENUM;
63 // Check if the parameters are boolean
64 if (aParameters.size() == 2
65 && (aParameters[0].getDescription() == "True"
66 || aParameters[0].getDescription() == "False"))
68 eFeatureParameterType = vcl::font::FeatureParameterType::BOOL;
69 aParameters.clear();
72 m_rFontFeatures.emplace_back(
73 FeatureID{ nFeatureCode, HB_OT_TAG_DEFAULT_SCRIPT, HB_OT_TAG_DEFAULT_LANGUAGE },
74 vcl::font::FeatureType::Graphite);
75 vcl::font::Feature& rFeature = m_rFontFeatures.back();
76 rFeature.m_aDefinition = vcl::font::FeatureDefinition(
77 nFeatureCode, sLabel, eFeatureParameterType, aParameters, sal_uInt32(nValue));
80 gr_featureval_destroy(pfeatureValues);
81 return true;
84 void FeatureCollector::collectForLanguage(hb_tag_t aTableTag, sal_uInt32 nScript,
85 hb_tag_t aScriptTag, sal_uInt32 nLanguage,
86 hb_tag_t aLanguageTag)
88 unsigned int nFeatureCount = hb_ot_layout_language_get_feature_tags(
89 m_pHbFace, aTableTag, nScript, nLanguage, 0, nullptr, nullptr);
90 std::vector<hb_tag_t> aFeatureTags(nFeatureCount);
91 hb_ot_layout_language_get_feature_tags(m_pHbFace, aTableTag, nScript, nLanguage, 0,
92 &nFeatureCount, aFeatureTags.data());
93 aFeatureTags.resize(nFeatureCount);
95 for (hb_tag_t aFeatureTag : aFeatureTags)
97 if (OpenTypeFeatureDefinitionList::get().isRequired(aFeatureTag))
98 continue;
100 m_rFontFeatures.emplace_back();
101 vcl::font::Feature& rFeature = m_rFontFeatures.back();
102 rFeature.m_aID = { aFeatureTag, aScriptTag, aLanguageTag };
104 FeatureDefinition aDefinition
105 = OpenTypeFeatureDefinitionList::get().getDefinition(aFeatureTag);
106 if (aDefinition)
108 rFeature.m_aDefinition = aDefinition;
113 void FeatureCollector::collectForScript(hb_tag_t aTableTag, sal_uInt32 nScript, hb_tag_t aScriptTag)
115 collectForLanguage(aTableTag, nScript, aScriptTag, HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX,
116 HB_OT_TAG_DEFAULT_LANGUAGE);
118 unsigned int nLanguageCount
119 = hb_ot_layout_script_get_language_tags(m_pHbFace, aTableTag, nScript, 0, nullptr, nullptr);
120 std::vector<hb_tag_t> aLanguageTags(nLanguageCount);
121 hb_ot_layout_script_get_language_tags(m_pHbFace, aTableTag, nScript, 0, &nLanguageCount,
122 aLanguageTags.data());
123 aLanguageTags.resize(nLanguageCount);
124 for (sal_uInt32 nLanguage = 0; nLanguage < sal_uInt32(nLanguageCount); ++nLanguage)
125 collectForLanguage(aTableTag, nScript, aScriptTag, nLanguage, aLanguageTags[nLanguage]);
128 void FeatureCollector::collectForTable(hb_tag_t aTableTag)
130 unsigned int nScriptCount
131 = hb_ot_layout_table_get_script_tags(m_pHbFace, aTableTag, 0, nullptr, nullptr);
132 std::vector<hb_tag_t> aScriptTags(nScriptCount);
133 hb_ot_layout_table_get_script_tags(m_pHbFace, aTableTag, 0, &nScriptCount, aScriptTags.data());
134 aScriptTags.resize(nScriptCount);
136 for (sal_uInt32 nScript = 0; nScript < sal_uInt32(nScriptCount); ++nScript)
137 collectForScript(aTableTag, nScript, aScriptTags[nScript]);
140 bool FeatureCollector::collect()
142 gr_face* grFace = hb_graphite2_face_get_gr_face(m_pHbFace);
144 if (grFace)
146 return collectGraphite();
148 else
150 collectForTable(HB_OT_TAG_GSUB); // substitution
151 collectForTable(HB_OT_TAG_GPOS); // positioning
152 return true;
156 } // end namespace vcl::font
158 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */