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 <unordered_set>
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
);
34 FontFeaturesDialog::~FontFeaturesDialog() {}
36 static sal_Int32
makeEnumComboBox(weld::ComboBox
& rNameBox
,
37 vcl::font::FeatureDefinition
const& rFeatureDefinition
,
42 for (vcl::font::FeatureParameter
const& rParameter
: rFeatureDefinition
.getEnumParameters())
44 rNameBox
.append(OUString::number(rParameter
.getCode()), rParameter
.getDescription());
45 if (rParameter
.getCode() == nDefault
)
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
))
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
)
75 rFilteredFontFeatures
.push_back(rFontFeature
);
78 fillGrid(rFilteredFontFeatures
);
83 void FontFeaturesDialog::fillGrid(std::vector
<vcl::font::Feature
> const& rFontFeatures
)
85 vcl::font::FeatureParser
aParser(m_sFontName
);
86 auto aExistingFeatures
= aParser
.getFeaturesMap();
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
;
97 aDefinition
= { nFontFeatureCode
, nullptr };
99 m_aFeatureItems
.emplace_back(m_xContentGrid
.get());
102 if (aExistingFeatures
.find(nFontFeatureCode
) != aExistingFeatures
.end())
103 nValue
= aExistingFeatures
.at(nFontFeatureCode
);
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();
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();
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)
164 IMPL_LINK_NOARG(FontFeaturesDialog
, ComboBoxSelectedHdl
, weld::ComboBox
&, void)
169 OUString
FontFeaturesDialog::createFontNameWithFeatures()
171 OUString sResultFontName
;
172 OUStringBuffer sNameSuffix
;
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
)
182 sNameSuffix
.append(OUString(vcl::font::FeatureSeparator
));
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
))
197 sNameSuffix
.append(OUString(vcl::font::FeatureSeparator
));
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())
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();
224 } // end svx namespace
226 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */