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