1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
11 #include <FontFeaturesDialog.hxx>
12 #include <vcl/font/FeatureParser.hxx>
13 #include <vcl/virdev.hxx>
14 #include <svtools/colorcfg.hxx>
15 #include <svx/dialmgr.hxx>
16 #include <unordered_set>
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
))
29 svtools::ColorConfig aColorConfig
;
30 Color
aFillColor(aColorConfig
.GetColorValue(svtools::DOCCOLOR
).nColor
);
31 m_aPreviewWindow
.SetBackColor(aFillColor
);
35 FontFeaturesDialog::~FontFeaturesDialog() {}
37 static sal_Int32
makeEnumComboBox(weld::ComboBox
& rNameBox
,
38 vcl::font::FeatureDefinition
const& rFeatureDefinition
,
43 for (vcl::font::FeatureParameter
const& rParameter
: rFeatureDefinition
.getEnumParameters())
45 rNameBox
.append(OUString::number(rParameter
.getCode()), rParameter
.getDescription());
46 if (rParameter
.getCode() == nDefault
)
53 void FontFeaturesDialog::initialize()
55 ScopedVclPtrInstance
<VirtualDevice
> aVDev(*Application::GetDefaultDevice(),
56 DeviceFormat::DEFAULT
, DeviceFormat::DEFAULT
);
57 aVDev
->SetOutputSizePixel(Size(10, 10));
59 vcl::Font aFont
= aVDev
->GetFont();
60 aFont
.SetFamilyName(m_sFontName
);
61 aVDev
->SetFont(aFont
);
63 std::vector
<vcl::font::Feature
> rFontFeatures
;
65 if (!aVDev
->GetFontFeatures(rFontFeatures
))
68 std::unordered_set
<sal_uInt32
> aDoneFeatures
;
69 std::vector
<vcl::font::Feature
> rFilteredFontFeatures
;
71 for (vcl::font::Feature
const& rFontFeature
: rFontFeatures
)
73 sal_uInt32 nFontFeatureCode
= rFontFeature
.m_aID
.m_aFeatureCode
;
74 if (!aDoneFeatures
.insert(nFontFeatureCode
).second
)
76 rFilteredFontFeatures
.push_back(rFontFeature
);
79 fillGrid(rFilteredFontFeatures
);
84 void FontFeaturesDialog::fillGrid(std::vector
<vcl::font::Feature
> const& rFontFeatures
)
86 vcl::font::FeatureParser
aParser(m_sFontName
);
87 auto aExistingFeatures
= aParser
.getFeaturesMap();
90 for (vcl::font::Feature
const& rFontFeature
: rFontFeatures
)
92 sal_uInt32 nFontFeatureCode
= rFontFeature
.m_aID
.m_aFeatureCode
;
94 vcl::font::FeatureDefinition aDefinition
;
95 if (rFontFeature
.m_aDefinition
)
96 aDefinition
= rFontFeature
.m_aDefinition
;
98 aDefinition
= { nFontFeatureCode
, nullptr };
100 m_aFeatureItems
.emplace_back(m_xContentGrid
.get());
103 if (aExistingFeatures
.find(nFontFeatureCode
) != aExistingFeatures
.end())
104 nValue
= aExistingFeatures
.at(nFontFeatureCode
);
106 nValue
= aDefinition
.getDefault();
108 FontFeatureItem
& aCurrentItem
= m_aFeatureItems
.back();
109 aCurrentItem
.m_aFeatureCode
= nFontFeatureCode
;
110 aCurrentItem
.m_nDefault
= aDefinition
.getDefault();
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
);
117 Link
<weld::ComboBox
&, void> aComboBoxSelectHandler
118 = LINK(this, FontFeaturesDialog
, ComboBoxSelectedHdl
);
119 Link
<weld::ToggleButton
&, void> aCheckBoxToggleHandler
120 = LINK(this, FontFeaturesDialog
, CheckBoxToggledHdl
);
122 if (aDefinition
.getType() == vcl::font::FeatureParameterType::ENUM
)
124 aCurrentItem
.m_xText
->set_label(aDefinition
.getDescription());
125 aCurrentItem
.m_xText
->show();
127 sal_Int32 nInit
= makeEnumComboBox(*aCurrentItem
.m_xCombo
, aDefinition
, nValue
);
129 aCurrentItem
.m_xCombo
->set_active(nInit
);
130 aCurrentItem
.m_xCombo
->connect_changed(aComboBoxSelectHandler
);
131 aCurrentItem
.m_xCombo
->show();
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();
145 void FontFeaturesDialog::updateFontPreview()
147 vcl::Font rPreviewFont
= m_aPreviewWindow
.GetFont();
148 vcl::Font rPreviewFontCJK
= m_aPreviewWindow
.GetCJKFont();
149 vcl::Font rPreviewFontCTL
= m_aPreviewWindow
.GetCTLFont();
151 OUString sNewFontName
= createFontNameWithFeatures();
153 rPreviewFont
.SetFamilyName(sNewFontName
);
154 rPreviewFontCJK
.SetFamilyName(sNewFontName
);
155 rPreviewFontCTL
.SetFamilyName(sNewFontName
);
157 m_aPreviewWindow
.SetFont(rPreviewFont
, rPreviewFontCJK
, rPreviewFontCTL
);
160 IMPL_LINK_NOARG(FontFeaturesDialog
, CheckBoxToggledHdl
, weld::ToggleButton
&, void)
165 IMPL_LINK_NOARG(FontFeaturesDialog
, ComboBoxSelectedHdl
, weld::ComboBox
&, void)
170 OUString
FontFeaturesDialog::createFontNameWithFeatures()
172 OUString sResultFontName
;
173 OUStringBuffer sNameSuffix
;
176 for (FontFeatureItem
& rItem
: m_aFeatureItems
)
178 if (rItem
.m_xCheck
->get_visible())
180 if (sal_uInt32(rItem
.m_xCheck
->get_active()) != rItem
.m_nDefault
)
183 sNameSuffix
.append(OUString(vcl::font::FeatureSeparator
));
187 sNameSuffix
.append(vcl::font::featureCodeAsString(rItem
.m_aFeatureCode
));
188 if (!rItem
.m_xCheck
->get_active())
189 sNameSuffix
.append("=0");
192 else if (rItem
.m_xCombo
->get_visible() && rItem
.m_xText
->get_visible())
194 sal_Int32 nSelection
= rItem
.m_xCombo
->get_active_id().toInt32();
195 if (nSelection
!= int(rItem
.m_nDefault
))
198 sNameSuffix
.append(OUString(vcl::font::FeatureSeparator
));
202 sNameSuffix
.append(vcl::font::featureCodeAsString(rItem
.m_aFeatureCode
));
203 sNameSuffix
.append("=");
204 sNameSuffix
.append(OUString::number(nSelection
));
208 sResultFontName
= vcl::font::trimFontNameFeatures(m_sFontName
);
209 if (!sNameSuffix
.isEmpty())
210 sResultFontName
+= OUString(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();
224 } // end svx namespace
226 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */