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>
13 #include <vcl/virdev.hxx>
14 #include <svtools/colorcfg.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  svtools::ColorConfig aColorConfig;
29  Color aFillColor(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
30  m_aPreviewWindow.SetBackColor(aFillColor);
31  initialize();
32 }
33 
35 
36 static sal_Int32 makeEnumComboBox(weld::ComboBox& rNameBox,
37  vcl::font::FeatureDefinition const& rFeatureDefinition,
38  uint32_t nDefault)
39 {
40  sal_Int32 nRes = 0;
41  int count = 0;
42  for (vcl::font::FeatureParameter const& rParameter : rFeatureDefinition.getEnumParameters())
43  {
44  rNameBox.append(OUString::number(rParameter.getCode()), rParameter.getDescription());
45  if (rParameter.getCode() == nDefault)
46  nRes = count;
47  ++count;
48  }
49  return nRes;
50 }
51 
53 {
55  DeviceFormat::DEFAULT, DeviceFormat::DEFAULT);
56  aVDev->SetOutputSizePixel(Size(10, 10));
57 
58  vcl::Font aFont = aVDev->GetFont();
60  aVDev->SetFont(aFont);
61 
62  std::vector<vcl::font::Feature> rFontFeatures;
63 
64  if (!aVDev->GetFontFeatures(rFontFeatures))
65  return;
66 
67  std::unordered_set<sal_uInt32> aDoneFeatures;
68  std::vector<vcl::font::Feature> rFilteredFontFeatures;
69 
70  for (vcl::font::Feature const& rFontFeature : rFontFeatures)
71  {
72  sal_uInt32 nFontFeatureCode = rFontFeature.m_aID.m_aFeatureCode;
73  if (!aDoneFeatures.insert(nFontFeatureCode).second)
74  continue;
75  rFilteredFontFeatures.push_back(rFontFeature);
76  }
77 
78  fillGrid(rFilteredFontFeatures);
79 
81 }
82 
83 void FontFeaturesDialog::fillGrid(std::vector<vcl::font::Feature> const& rFontFeatures)
84 {
86  auto aExistingFeatures = aParser.getFeaturesMap();
87 
88  sal_Int32 i = 0;
89  for (vcl::font::Feature const& rFontFeature : rFontFeatures)
90  {
91  sal_uInt32 nFontFeatureCode = rFontFeature.m_aID.m_aFeatureCode;
92 
93  vcl::font::FeatureDefinition aDefinition;
94  if (rFontFeature.m_aDefinition)
95  aDefinition = rFontFeature.m_aDefinition;
96  if (!aDefinition)
97  aDefinition = { nFontFeatureCode, nullptr };
98 
99  m_aFeatureItems.emplace_back(m_xContentGrid.get());
100 
101  uint32_t nValue = 0;
102  if (aExistingFeatures.find(nFontFeatureCode) != aExistingFeatures.end())
103  nValue = aExistingFeatures.at(nFontFeatureCode);
104  else
105  nValue = aDefinition.getDefault();
106 
107  FontFeatureItem& aCurrentItem = m_aFeatureItems.back();
108  aCurrentItem.m_aFeatureCode = nFontFeatureCode;
109  aCurrentItem.m_nDefault = aDefinition.getDefault();
110 
111  sal_Int32 nGridPositionX = (i % 2) * 2;
112  sal_Int32 nGridPositionY = i / 2;
113  aCurrentItem.m_xContainer->set_grid_left_attach(nGridPositionX);
114  aCurrentItem.m_xContainer->set_grid_top_attach(nGridPositionY);
115 
116  Link<weld::ComboBox&, void> aComboBoxSelectHandler
117  = LINK(this, FontFeaturesDialog, ComboBoxSelectedHdl);
118  Link<weld::ToggleButton&, void> aCheckBoxToggleHandler
119  = LINK(this, FontFeaturesDialog, CheckBoxToggledHdl);
120 
121  if (aDefinition.getType() == vcl::font::FeatureParameterType::ENUM)
122  {
123  aCurrentItem.m_xText->set_label(aDefinition.getDescription());
124  aCurrentItem.m_xText->show();
125 
126  sal_Int32 nInit = makeEnumComboBox(*aCurrentItem.m_xCombo, aDefinition, nValue);
127 
128  aCurrentItem.m_xCombo->set_active(nInit);
129  aCurrentItem.m_xCombo->connect_changed(aComboBoxSelectHandler);
130  aCurrentItem.m_xCombo->show();
131  }
132  else
133  {
134  aCurrentItem.m_xCheck->set_active(nValue > 0);
135  aCurrentItem.m_xCheck->set_label(aDefinition.getDescription());
136  aCurrentItem.m_xCheck->connect_toggled(aCheckBoxToggleHandler);
137  aCurrentItem.m_xCheck->show();
138  }
139 
140  i++;
141  }
142 }
143 
145 {
146  vcl::Font rPreviewFont = m_aPreviewWindow.GetFont();
147  vcl::Font rPreviewFontCJK = m_aPreviewWindow.GetCJKFont();
148  vcl::Font rPreviewFontCTL = m_aPreviewWindow.GetCTLFont();
149 
150  OUString sNewFontName = createFontNameWithFeatures();
151 
152  rPreviewFont.SetFamilyName(sNewFontName);
153  rPreviewFontCJK.SetFamilyName(sNewFontName);
154  rPreviewFontCTL.SetFamilyName(sNewFontName);
155 
156  m_aPreviewWindow.SetFont(rPreviewFont, rPreviewFontCJK, rPreviewFontCTL);
157 }
158 
160 {
161  updateFontPreview();
162 }
163 
164 IMPL_LINK_NOARG(FontFeaturesDialog, ComboBoxSelectedHdl, weld::ComboBox&, void)
165 {
166  updateFontPreview();
167 }
168 
170 {
171  OUString sResultFontName;
172  OUStringBuffer sNameSuffix;
173  bool bFirst = true;
174 
175  for (const FontFeatureItem& rItem : m_aFeatureItems)
176  {
177  if (rItem.m_xCheck->get_visible())
178  {
179  if (sal_uInt32(rItem.m_xCheck->get_active()) != rItem.m_nDefault)
180  {
181  if (!bFirst)
182  sNameSuffix.append(OUString(vcl::font::FeatureSeparator));
183  else
184  bFirst = false;
185 
186  sNameSuffix.append(vcl::font::featureCodeAsString(rItem.m_aFeatureCode));
187  if (!rItem.m_xCheck->get_active())
188  sNameSuffix.append("=0");
189  }
190  }
191  else if (rItem.m_xCombo->get_visible() && rItem.m_xText->get_visible())
192  {
193  sal_Int32 nSelection = rItem.m_xCombo->get_active_id().toInt32();
194  if (nSelection != int(rItem.m_nDefault))
195  {
196  if (!bFirst)
197  sNameSuffix.append(OUString(vcl::font::FeatureSeparator));
198  else
199  bFirst = false;
200 
201  sNameSuffix.append(vcl::font::featureCodeAsString(rItem.m_aFeatureCode));
202  sNameSuffix.append("=");
203  sNameSuffix.append(OUString::number(nSelection));
204  }
205  }
206  }
207  sResultFontName = vcl::font::trimFontNameFeatures(m_sFontName);
208  if (!sNameSuffix.isEmpty())
209  sResultFontName
210  += OUStringChar(vcl::font::FeaturePrefix) + sNameSuffix.makeStringAndClear();
211  return sResultFontName;
212 }
213 
215 {
216  short nResult = GenericDialogController::run();
217  if (nResult == RET_OK)
218  {
220  }
221  return nResult;
222 }
223 
224 } // end svx namespace
225 
226 /* 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())
void SetBackColor(const Color &rColor)
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
void SetFamilyName(const OUString &rFamilyName)
std::unique_ptr< weld::Widget > m_xContainer
int i
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
ColorConfigValue GetColorValue(ColorConfigEntry eEntry, bool bSmart=true) const
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