LibreOffice Module cui (master)  1
FontFeaturesDialog.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  */
10 
11 #include <FontFeaturesDialog.hxx>
12 #include <rtl/ustrbuf.hxx>
14 #include <FontFeatures.hxx>
15 #include <unordered_set>
16 
17 using namespace css;
18 
19 namespace cui
20 {
21 FontFeaturesDialog::FontFeaturesDialog(weld::Window* pParent, OUString const& rFontName)
22  : GenericDialogController(pParent, "cui/ui/fontfeaturesdialog.ui", "FontFeaturesDialog")
23  , m_sFontName(rFontName)
24  , m_xContentWindow(m_xBuilder->weld_scrolled_window("contentWindow"))
25  , m_xContentGrid(m_xBuilder->weld_container("contentGrid"))
26  , m_xPreviewWindow(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWindow))
27 {
28  initialize();
29 }
30 
32 
33 static sal_Int32 makeEnumComboBox(weld::ComboBox& rNameBox,
34  vcl::font::FeatureDefinition const& rFeatureDefinition,
35  uint32_t nDefault)
36 {
37  sal_Int32 nRes = 0;
38  int count = 0;
39  for (vcl::font::FeatureParameter const& rParameter : rFeatureDefinition.getEnumParameters())
40  {
41  rNameBox.append(OUString::number(rParameter.getCode()), rParameter.getDescription());
42  if (rParameter.getCode() == nDefault)
43  nRes = count;
44  ++count;
45  }
46  return nRes;
47 }
48 
50 {
52  DeviceFormat::DEFAULT, DeviceFormat::DEFAULT);
53  std::vector<vcl::font::Feature> rFontFeatures = getFontFeatureList(m_sFontName, *aVDev);
54 
55  std::unordered_set<sal_uInt32> aDoneFeatures;
56  std::vector<vcl::font::Feature> rFilteredFontFeatures;
57 
58  for (vcl::font::Feature const& rFontFeature : rFontFeatures)
59  {
60  sal_uInt32 nFontFeatureCode = rFontFeature.m_aID.m_aFeatureCode;
61  if (!aDoneFeatures.insert(nFontFeatureCode).second)
62  continue;
63  rFilteredFontFeatures.push_back(rFontFeature);
64  }
65 
66  int nRowHeight = fillGrid(rFilteredFontFeatures);
67 
68  m_xContentWindow->set_size_request(
69  -1, std::min(std::max(m_xContentWindow->get_preferred_size().Height(),
70  m_xContentGrid->get_preferred_size().Height()),
71  static_cast<tools::Long>(300L)));
72 
73  if (nRowHeight)
74  {
75  // tdf#141333 use row height + the 6 px spacing of contentGrid
76  m_xContentWindow->vadjustment_set_step_increment(nRowHeight + 6);
77  }
78 
80 }
81 
82 int FontFeaturesDialog::fillGrid(std::vector<vcl::font::Feature> const& rFontFeatures)
83 {
84  int nRowHeight(0);
85 
87  auto aExistingFeatures = aParser.getFeaturesMap();
88 
89  sal_Int32 i = 0;
90  for (vcl::font::Feature const& rFontFeature : rFontFeatures)
91  {
92  sal_uInt32 nFontFeatureCode = rFontFeature.m_aID.m_aFeatureCode;
93 
94  vcl::font::FeatureDefinition aDefinition;
95  if (rFontFeature.m_aDefinition)
96  aDefinition = rFontFeature.m_aDefinition;
97  if (!aDefinition)
98  aDefinition = { nFontFeatureCode, "" };
99 
100  m_aFeatureItems.emplace_back(m_xContentGrid.get());
101 
102  uint32_t nValue = 0;
103  if (aExistingFeatures.find(nFontFeatureCode) != aExistingFeatures.end())
104  nValue = aExistingFeatures.at(nFontFeatureCode);
105  else
106  nValue = aDefinition.getDefault();
107 
108  FontFeatureItem& aCurrentItem = m_aFeatureItems.back();
109  aCurrentItem.m_aFeatureCode = nFontFeatureCode;
110  aCurrentItem.m_nDefault = aDefinition.getDefault();
111 
112  sal_Int32 nGridPositionX = (i % 2) * 2;
113  sal_Int32 nGridPositionY = i / 2;
114  aCurrentItem.m_xContainer->set_grid_left_attach(nGridPositionX);
115  aCurrentItem.m_xContainer->set_grid_top_attach(nGridPositionY);
116 
117  Link<weld::ComboBox&, void> aComboBoxSelectHandler
118  = LINK(this, FontFeaturesDialog, ComboBoxSelectedHdl);
119  Link<weld::Toggleable&, void> aCheckBoxToggleHandler
120  = LINK(this, FontFeaturesDialog, CheckBoxToggledHdl);
121 
122  if (aDefinition.getType() == vcl::font::FeatureParameterType::ENUM)
123  {
124  aCurrentItem.m_xText->set_label(aDefinition.getDescription());
125  aCurrentItem.m_xText->show();
126 
127  sal_Int32 nInit = makeEnumComboBox(*aCurrentItem.m_xCombo, aDefinition, nValue);
128 
129  aCurrentItem.m_xCombo->set_active(nInit);
130  aCurrentItem.m_xCombo->connect_changed(aComboBoxSelectHandler);
131  aCurrentItem.m_xCombo->show();
132  }
133  else
134  {
135  aCurrentItem.m_xCheck->set_active(nValue > 0);
136  aCurrentItem.m_xCheck->set_label(aDefinition.getDescription());
137  aCurrentItem.m_xCheck->connect_toggled(aCheckBoxToggleHandler);
138  aCurrentItem.m_xCheck->show();
139  }
140 
141  nRowHeight
142  = std::max<int>(nRowHeight, aCurrentItem.m_xContainer->get_preferred_size().Height());
143 
144  i++;
145  }
146 
147  return nRowHeight;
148 }
149 
151 {
152  vcl::Font rPreviewFont = m_aPreviewWindow.GetFont();
153  vcl::Font rPreviewFontCJK = m_aPreviewWindow.GetCJKFont();
154  vcl::Font rPreviewFontCTL = m_aPreviewWindow.GetCTLFont();
155 
156  OUString sNewFontName = createFontNameWithFeatures();
157 
158  rPreviewFont.SetFamilyName(sNewFontName);
159  rPreviewFontCJK.SetFamilyName(sNewFontName);
160  rPreviewFontCTL.SetFamilyName(sNewFontName);
161 
162  m_aPreviewWindow.SetFont(rPreviewFont, rPreviewFontCJK, rPreviewFontCTL);
163 }
164 
166 {
167  updateFontPreview();
168 }
169 
170 IMPL_LINK_NOARG(FontFeaturesDialog, ComboBoxSelectedHdl, weld::ComboBox&, void)
171 {
172  updateFontPreview();
173 }
174 
176 {
177  OUString sResultFontName;
178  OUStringBuffer sNameSuffix;
179  bool bFirst = true;
180 
181  for (const FontFeatureItem& rItem : m_aFeatureItems)
182  {
183  if (rItem.m_xCheck->get_visible())
184  {
185  if (sal_uInt32(rItem.m_xCheck->get_active()) != rItem.m_nDefault)
186  {
187  if (!bFirst)
188  sNameSuffix.append(vcl::font::FeatureSeparator);
189  else
190  bFirst = false;
191 
192  sNameSuffix.append(vcl::font::featureCodeAsString(rItem.m_aFeatureCode));
193  if (!rItem.m_xCheck->get_active())
194  sNameSuffix.append("=0");
195  }
196  }
197  else if (rItem.m_xCombo->get_visible() && rItem.m_xText->get_visible())
198  {
199  sal_Int32 nSelection = rItem.m_xCombo->get_active_id().toInt32();
200  if (nSelection != int(rItem.m_nDefault))
201  {
202  if (!bFirst)
203  sNameSuffix.append(vcl::font::FeatureSeparator);
204  else
205  bFirst = false;
206 
207  sNameSuffix.append(vcl::font::featureCodeAsString(rItem.m_aFeatureCode));
208  sNameSuffix.append("=");
209  sNameSuffix.append(OUString::number(nSelection));
210  }
211  }
212  }
213  sResultFontName = vcl::font::trimFontNameFeatures(m_sFontName);
214  if (!sNameSuffix.isEmpty())
215  sResultFontName
216  += OUStringChar(vcl::font::FeaturePrefix) + sNameSuffix.makeStringAndClear();
217  return sResultFontName;
218 }
219 
221 {
222  short nResult = GenericDialogController::run();
223  if (nResult == RET_OK)
224  {
226  }
227  return nResult;
228 }
229 
230 } // end svx namespace
231 
232 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr const char FeaturePrefix
OUString getDescription() const
SvxFont & GetCTLFont()
IMPL_LINK_NOARG(ColorPickerDialog, ColorFieldControlModifydl, ColorFieldControl &, void)
OUString featureCodeAsString(uint32_t nFeature)
virtual short run() override
const std::vector< FeatureParameter > & getEnumParameters() const
SvxFont & GetCJKFont()
void append(const OUString &rId, const OUString &rStr)
uint32_t getDefault() const
std::unordered_map< uint32_t, uint32_t > getFeaturesMap() const
OUString trimFontNameFeatures(OUString const &rFontName)
static OutputDevice * GetDefaultDevice()
void SetFont(const SvxFont &rNormalFont, const SvxFont &rCJKFont, const SvxFont &rCTLFont)
std::vector< vcl::font::Feature > getFontFeatureList(OUString const &rFontName, VirtualDevice &rVDev)
SvxFont & GetFont()
constexpr const char FeatureSeparator
std::unique_ptr< weld::ScrolledWindow > m_xContentWindow
void SetFamilyName(const OUString &rFamilyName)
int i
std::unique_ptr< weld::Widget > m_xContainer
static sal_Int32 makeEnumComboBox(weld::ComboBox &rNameBox, vcl::font::FeatureDefinition const &rFeatureDefinition, uint32_t nDefault)
FeatureParameterType getType() const
int fillGrid(std::vector< vcl::font::Feature > const &rFontFeatures)
std::vector< FontFeatureItem > m_aFeatureItems
std::unique_ptr< weld::Label > m_xText
std::unique_ptr< weld::ComboBox > m_xCombo
RET_OK
SvxFontPrevWindow m_aPreviewWindow
std::unique_ptr< weld::Container > m_xContentGrid
std::unique_ptr< weld::CheckButton > m_xCheck
sal_Int16 nValue