Bump version to 6.4.7.2.M8
[LibreOffice.git] / cui / source / dialogs / FontFeaturesDialog.cxx
blob20ac4b67e3c83e0ae9b86102f033e6ae6704d05a
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/.
9 */
11 #include <FontFeaturesDialog.hxx>
12 #include <vcl/font/FeatureParser.hxx>
13 #include <vcl/virdev.hxx>
14 #include <svtools/colorcfg.hxx>
15 #include <unordered_set>
17 using namespace css;
19 namespace cui
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))
28 svtools::ColorConfig aColorConfig;
29 Color aFillColor(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
30 m_aPreviewWindow.SetBackColor(aFillColor);
31 initialize();
34 FontFeaturesDialog::~FontFeaturesDialog() {}
36 static sal_Int32 makeEnumComboBox(weld::ComboBox& rNameBox,
37 vcl::font::FeatureDefinition const& rFeatureDefinition,
38 uint32_t nDefault)
40 sal_Int32 nRes = 0;
41 int count = 0;
42 for (vcl::font::FeatureParameter const& rParameter : rFeatureDefinition.getEnumParameters())
44 rNameBox.append(OUString::number(rParameter.getCode()), rParameter.getDescription());
45 if (rParameter.getCode() == nDefault)
46 nRes = count;
47 ++count;
49 return nRes;
52 void FontFeaturesDialog::initialize()
54 ScopedVclPtrInstance<VirtualDevice> aVDev(*Application::GetDefaultDevice(),
55 DeviceFormat::DEFAULT, DeviceFormat::DEFAULT);
56 aVDev->SetOutputSizePixel(Size(10, 10));
58 vcl::Font aFont = aVDev->GetFont();
59 aFont.SetFamilyName(m_sFontName);
60 aVDev->SetFont(aFont);
62 std::vector<vcl::font::Feature> rFontFeatures;
64 if (!aVDev->GetFontFeatures(rFontFeatures))
65 return;
67 std::unordered_set<sal_uInt32> aDoneFeatures;
68 std::vector<vcl::font::Feature> rFilteredFontFeatures;
70 for (vcl::font::Feature const& rFontFeature : rFontFeatures)
72 sal_uInt32 nFontFeatureCode = rFontFeature.m_aID.m_aFeatureCode;
73 if (!aDoneFeatures.insert(nFontFeatureCode).second)
74 continue;
75 rFilteredFontFeatures.push_back(rFontFeature);
78 fillGrid(rFilteredFontFeatures);
80 updateFontPreview();
83 void FontFeaturesDialog::fillGrid(std::vector<vcl::font::Feature> const& rFontFeatures)
85 vcl::font::FeatureParser aParser(m_sFontName);
86 auto aExistingFeatures = aParser.getFeaturesMap();
88 sal_Int32 i = 0;
89 for (vcl::font::Feature const& rFontFeature : rFontFeatures)
91 sal_uInt32 nFontFeatureCode = rFontFeature.m_aID.m_aFeatureCode;
93 vcl::font::FeatureDefinition aDefinition;
94 if (rFontFeature.m_aDefinition)
95 aDefinition = rFontFeature.m_aDefinition;
96 if (!aDefinition)
97 aDefinition = { nFontFeatureCode, nullptr };
99 m_aFeatureItems.emplace_back(m_xContentGrid.get());
101 uint32_t nValue = 0;
102 if (aExistingFeatures.find(nFontFeatureCode) != aExistingFeatures.end())
103 nValue = aExistingFeatures.at(nFontFeatureCode);
104 else
105 nValue = aDefinition.getDefault();
107 FontFeatureItem& aCurrentItem = m_aFeatureItems.back();
108 aCurrentItem.m_aFeatureCode = nFontFeatureCode;
109 aCurrentItem.m_nDefault = aDefinition.getDefault();
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);
116 Link<weld::ComboBox&, void> aComboBoxSelectHandler
117 = LINK(this, FontFeaturesDialog, ComboBoxSelectedHdl);
118 Link<weld::ToggleButton&, void> aCheckBoxToggleHandler
119 = LINK(this, FontFeaturesDialog, CheckBoxToggledHdl);
121 if (aDefinition.getType() == vcl::font::FeatureParameterType::ENUM)
123 aCurrentItem.m_xText->set_label(aDefinition.getDescription());
124 aCurrentItem.m_xText->show();
126 sal_Int32 nInit = makeEnumComboBox(*aCurrentItem.m_xCombo, aDefinition, nValue);
128 aCurrentItem.m_xCombo->set_active(nInit);
129 aCurrentItem.m_xCombo->connect_changed(aComboBoxSelectHandler);
130 aCurrentItem.m_xCombo->show();
132 else
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();
140 i++;
144 void FontFeaturesDialog::updateFontPreview()
146 vcl::Font rPreviewFont = m_aPreviewWindow.GetFont();
147 vcl::Font rPreviewFontCJK = m_aPreviewWindow.GetCJKFont();
148 vcl::Font rPreviewFontCTL = m_aPreviewWindow.GetCTLFont();
150 OUString sNewFontName = createFontNameWithFeatures();
152 rPreviewFont.SetFamilyName(sNewFontName);
153 rPreviewFontCJK.SetFamilyName(sNewFontName);
154 rPreviewFontCTL.SetFamilyName(sNewFontName);
156 m_aPreviewWindow.SetFont(rPreviewFont, rPreviewFontCJK, rPreviewFontCTL);
159 IMPL_LINK_NOARG(FontFeaturesDialog, CheckBoxToggledHdl, weld::ToggleButton&, void)
161 updateFontPreview();
164 IMPL_LINK_NOARG(FontFeaturesDialog, ComboBoxSelectedHdl, weld::ComboBox&, void)
166 updateFontPreview();
169 OUString FontFeaturesDialog::createFontNameWithFeatures()
171 OUString sResultFontName;
172 OUStringBuffer sNameSuffix;
173 bool bFirst = true;
175 for (const FontFeatureItem& rItem : m_aFeatureItems)
177 if (rItem.m_xCheck->get_visible())
179 if (sal_uInt32(rItem.m_xCheck->get_active()) != rItem.m_nDefault)
181 if (!bFirst)
182 sNameSuffix.append(OUString(vcl::font::FeatureSeparator));
183 else
184 bFirst = false;
186 sNameSuffix.append(vcl::font::featureCodeAsString(rItem.m_aFeatureCode));
187 if (!rItem.m_xCheck->get_active())
188 sNameSuffix.append("=0");
191 else if (rItem.m_xCombo->get_visible() && rItem.m_xText->get_visible())
193 sal_Int32 nSelection = rItem.m_xCombo->get_active_id().toInt32();
194 if (nSelection != int(rItem.m_nDefault))
196 if (!bFirst)
197 sNameSuffix.append(OUString(vcl::font::FeatureSeparator));
198 else
199 bFirst = false;
201 sNameSuffix.append(vcl::font::featureCodeAsString(rItem.m_aFeatureCode));
202 sNameSuffix.append("=");
203 sNameSuffix.append(OUString::number(nSelection));
207 sResultFontName = vcl::font::trimFontNameFeatures(m_sFontName);
208 if (!sNameSuffix.isEmpty())
209 sResultFontName
210 += OUStringChar(vcl::font::FeaturePrefix) + sNameSuffix.makeStringAndClear();
211 return sResultFontName;
214 short FontFeaturesDialog::run()
216 short nResult = GenericDialogController::run();
217 if (nResult == RET_OK)
219 m_sResultFontName = createFontNameWithFeatures();
221 return nResult;
224 } // end svx namespace
226 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */