LibreOffice Module vcl (master)  1
FeatureCollector.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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  */
9 
12 
13 #include <hb-ot.h>
14 #include <hb-graphite2.h>
15 
16 namespace vcl
17 {
18 namespace font
19 {
21 {
22  gr_face* grFace = hb_graphite2_face_get_gr_face(m_pHbFace);
23 
24  if (grFace == nullptr)
25  return false;
26 
27  gr_uint16 nUILanguage = gr_uint16(m_eLanguageType);
28 
29  gr_uint16 nNumberOfFeatures = gr_face_n_fref(grFace);
30  gr_feature_val* pfeatureValues
31  = gr_face_featureval_for_lang(grFace, 0); // shame we don't know which lang
32 
33  for (gr_uint16 i = 0; i < nNumberOfFeatures; ++i)
34  {
35  const gr_feature_ref* pFeatureRef = gr_face_fref(grFace, i);
36  gr_uint32 nFeatureCode = gr_fref_id(pFeatureRef);
37 
38  if (nFeatureCode == 0) // illegal feature code - skip
39  continue;
40 
41  gr_uint16 nValue = gr_fref_feature_value(pFeatureRef, pfeatureValues);
42  gr_uint32 nLabelLength = 0;
43  void* pLabel = gr_fref_label(pFeatureRef, &nUILanguage, gr_utf8, &nLabelLength);
44  OUString sLabel(OUString::createFromAscii(static_cast<char*>(pLabel)));
45  gr_label_destroy(pLabel);
46 
47  std::vector<vcl::font::FeatureParameter> aParameters;
48  gr_uint16 nNumberOfValues = gr_fref_n_values(pFeatureRef);
49 
50  if (nNumberOfValues > 0)
51  {
52  for (gr_uint16 j = 0; j < nNumberOfValues; ++j)
53  {
54  gr_uint32 nValueLabelLength = 0;
55  void* pValueLabel = gr_fref_value_label(pFeatureRef, j, &nUILanguage, gr_utf8,
56  &nValueLabelLength);
57  OUString sValueLabel(OUString::createFromAscii(static_cast<char*>(pValueLabel)));
58  gr_uint16 nParamValue = gr_fref_value(pFeatureRef, j);
59  aParameters.emplace_back(sal_uInt32(nParamValue), sValueLabel);
60  gr_label_destroy(pValueLabel);
61  }
62 
63  auto eFeatureParameterType = vcl::font::FeatureParameterType::ENUM;
64 
65  // Check if the parameters are boolean
66  if (aParameters.size() == 2
67  && (aParameters[0].getDescription() == "True"
68  || aParameters[0].getDescription() == "False"))
69  {
70  eFeatureParameterType = vcl::font::FeatureParameterType::BOOL;
71  aParameters.clear();
72  }
73 
74  m_rFontFeatures.emplace_back(
75  FeatureID{ nFeatureCode, HB_OT_TAG_DEFAULT_SCRIPT, HB_OT_TAG_DEFAULT_LANGUAGE },
77  vcl::font::Feature& rFeature = m_rFontFeatures.back();
79  nFeatureCode, sLabel, eFeatureParameterType, aParameters, sal_uInt32(nValue));
80  }
81  }
82  return true;
83 }
84 
85 void FeatureCollector::collectForLanguage(hb_tag_t aTableTag, sal_uInt32 nScript,
86  hb_tag_t aScriptTag, sal_uInt32 nLanguage,
87  hb_tag_t aLanguageTag)
88 {
89  unsigned int nFeatureCount = hb_ot_layout_language_get_feature_tags(
90  m_pHbFace, aTableTag, nScript, nLanguage, 0, nullptr, nullptr);
91  std::vector<hb_tag_t> aFeatureTags(nFeatureCount);
92  hb_ot_layout_language_get_feature_tags(m_pHbFace, aTableTag, nScript, nLanguage, 0,
93  &nFeatureCount, aFeatureTags.data());
94  aFeatureTags.resize(nFeatureCount);
95 
96  for (hb_tag_t aFeatureTag : aFeatureTags)
97  {
98  if (OpenTypeFeatureDefinitonList::get().isRequired(aFeatureTag))
99  continue;
100 
101  m_rFontFeatures.emplace_back();
102  vcl::font::Feature& rFeature = m_rFontFeatures.back();
103  rFeature.m_aID = { aFeatureTag, aScriptTag, aLanguageTag };
104 
105  FeatureDefinition aDefinition
106  = OpenTypeFeatureDefinitonList::get().getDefinition(aFeatureTag);
107  if (aDefinition)
108  {
109  rFeature.m_aDefinition = aDefinition;
110  }
111  }
112 }
113 
114 void FeatureCollector::collectForScript(hb_tag_t aTableTag, sal_uInt32 nScript, hb_tag_t aScriptTag)
115 {
116  collectForLanguage(aTableTag, nScript, aScriptTag, HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX,
117  HB_OT_TAG_DEFAULT_LANGUAGE);
118 
119  unsigned int nLanguageCount
120  = hb_ot_layout_script_get_language_tags(m_pHbFace, aTableTag, nScript, 0, nullptr, nullptr);
121  std::vector<hb_tag_t> aLanguageTags(nLanguageCount);
122  hb_ot_layout_script_get_language_tags(m_pHbFace, aTableTag, nScript, 0, &nLanguageCount,
123  aLanguageTags.data());
124  aLanguageTags.resize(nLanguageCount);
125  for (sal_uInt32 nLanguage = 0; nLanguage < sal_uInt32(nLanguageCount); ++nLanguage)
126  collectForLanguage(aTableTag, nScript, aScriptTag, nLanguage, aLanguageTags[nLanguage]);
127 }
128 
129 void FeatureCollector::collectForTable(hb_tag_t aTableTag)
130 {
131  unsigned int nScriptCount
132  = hb_ot_layout_table_get_script_tags(m_pHbFace, aTableTag, 0, nullptr, nullptr);
133  std::vector<hb_tag_t> aScriptTags(nScriptCount);
134  hb_ot_layout_table_get_script_tags(m_pHbFace, aTableTag, 0, &nScriptCount, aScriptTags.data());
135  aScriptTags.resize(nScriptCount);
136 
137  for (sal_uInt32 nScript = 0; nScript < sal_uInt32(nScriptCount); ++nScript)
138  collectForScript(aTableTag, nScript, aScriptTags[nScript]);
139 }
140 
142 {
143  gr_face* grFace = hb_graphite2_face_get_gr_face(m_pHbFace);
144 
145  if (grFace)
146  {
147  return collectGraphite();
148  }
149  else
150  {
151  collectForTable(HB_OT_TAG_GSUB); // substitution
152  collectForTable(HB_OT_TAG_GPOS); // positioning
153  return true;
154  }
155 }
156 
157 } // end namespace font
158 } // end namespace vcl
159 
160 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
FeatureID m_aID
Definition: Feature.hxx:101
std::vector< vcl::font::Feature > & m_rFontFeatures
LanguageType const m_eLanguageType
void collectForLanguage(hb_tag_t aTableTag, sal_uInt32 nScript, hb_tag_t aScriptTag, sal_uInt32 nLanguage, hb_tag_t aLanguageTag)
int i
void collectForTable(hb_tag_t aTableTag)
void collectForScript(hb_tag_t aTableTag, sal_uInt32 nScript, hb_tag_t aScriptTag)
FeatureDefinition m_aDefinition
Definition: Feature.hxx:103