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