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/.
10 #include <svx/theme/ThemeColorPaletteManager.hxx>
12 #include <basegfx/color/bcolortools.hxx>
13 #include <tools/color.hxx>
14 #include <unotools/resmgr.hxx>
15 #include <svx/dialmgr.hxx>
16 #include <svx/strings.hrc>
17 #include <docmodel/theme/ColorSet.hxx>
18 #include <docmodel/color/ComplexColorJSON.hxx>
19 #include <boost/property_tree/json_parser.hpp>
25 constexpr const std::array
<const std::array
<sal_Int16
, 6>, 5> g_aLumMods
= {
26 std::array
<sal_Int16
, 6>{ 10'000, 5'000, 6'500, 7'500, 8'500, 9'500 },
27 std::array
<sal_Int16
, 6>{ 10'000, 1'000, 2'500, 5'000, 7'500, 9'000 },
28 std::array
<sal_Int16
, 6>{ 10'000, 2'000, 4'000, 6'000, 7'500, 5'000 },
29 std::array
<sal_Int16
, 6>{ 10'000, 9'000, 7'500, 5'000, 2'500, 1'000 },
30 std::array
<sal_Int16
, 6>{ 10'000, 9'500, 8'500, 7'500, 6'500, 5'000 },
33 constexpr const std::array
<const std::array
<sal_Int16
, 6>, 5> g_aLumOffs
= {
34 std::array
<sal_Int16
, 6>{ 0, 5'000, 3'500, 2'500, 1'500, 0'500 },
35 std::array
<sal_Int16
, 6>{ 0, 9'000, 7'500, 5'000, 2'500, 1'000 },
36 std::array
<sal_Int16
, 6>{ 0, 8'000, 6'000, 4'000, 0, 0 },
37 std::array
<sal_Int16
, 6>{ 0, 0, 0, 0, 0, 0 },
38 std::array
<sal_Int16
, 6>{ 0, 0, 0, 0, 0, 0 },
41 } // end anonymous namespace
45 ThemeColorPaletteManager::ThemeColorPaletteManager(
46 std::shared_ptr
<model::ColorSet
> const& pColorSet
)
47 : m_pColorSet(pColorSet
)
51 svx::ThemePaletteCollection
ThemeColorPaletteManager::generate()
53 svx::ThemePaletteCollection aThemePaletteCollection
;
55 const std::array
<OUString
, 12> aColorNames
= {
56 SvxResId(RID_SVXSTR_THEME_COLOR1
), SvxResId(RID_SVXSTR_THEME_COLOR2
),
57 SvxResId(RID_SVXSTR_THEME_COLOR3
), SvxResId(RID_SVXSTR_THEME_COLOR4
),
58 SvxResId(RID_SVXSTR_THEME_COLOR5
), SvxResId(RID_SVXSTR_THEME_COLOR6
),
59 SvxResId(RID_SVXSTR_THEME_COLOR7
), SvxResId(RID_SVXSTR_THEME_COLOR8
),
60 SvxResId(RID_SVXSTR_THEME_COLOR9
), SvxResId(RID_SVXSTR_THEME_COLOR10
),
61 SvxResId(RID_SVXSTR_THEME_COLOR11
), SvxResId(RID_SVXSTR_THEME_COLOR12
),
64 for (size_t nColor
= 0; nColor
< aColorNames
.size(); ++nColor
)
66 auto eThemeType
= model::convertToThemeColorType(nColor
);
67 if (eThemeType
== model::ThemeColorType::Unknown
)
70 auto& aThemeColorData
= aThemePaletteCollection
.maColors
[nColor
];
71 aThemeColorData
.meThemeColorType
= eThemeType
;
73 Color aThemeColor
= m_pColorSet
->getColor(eThemeType
);
74 aThemeColorData
.maBaseColor
= aThemeColor
;
76 basegfx::BColor aHSLColor
= basegfx::utils::rgb2hsl(aThemeColor
.getBColor());
77 double aLuminanceValue
= aHSLColor
.getBlue() * 255.0;
79 for (size_t nEffect
: { 0, 1, 2, 3, 4, 5 })
81 auto& rEffect
= aThemeColorData
.maEffects
[nEffect
];
84 if (aLuminanceValue
< 0.5)
86 else if (aLuminanceValue
> 254.5)
88 else if (aLuminanceValue
< 50.5)
90 else if (aLuminanceValue
> 203.5)
95 rEffect
.mnLumOff
= g_aLumOffs
[nIndex
][nEffect
];
96 rEffect
.mnLumMod
= g_aLumMods
[nIndex
][nEffect
];
98 rEffect
.maColor
= aThemeColor
;
99 rEffect
.maColor
.ApplyLumModOff(rEffect
.mnLumMod
, rEffect
.mnLumOff
);
102 sal_Int16 nPercent
= rEffect
.getPercentage();
107 aTemplate
= SvxResId(RID_SVXSTR_THEME_EFFECT_LIGHTER
);
109 else if (nPercent
< 0)
111 aTemplate
= SvxResId(RID_SVXSTR_THEME_EFFECT_DARKER
);
114 if (!aTemplate
.isEmpty())
116 aColorName
= aTemplate
.replaceAll("$THEME_NAME", aColorNames
[nColor
]);
118 = aColorName
.replaceAll("$PERCENTAGE", OUString::number(std::abs(nPercent
)));
122 aColorName
= aColorNames
[nColor
];
124 rEffect
.maColorName
= aColorName
;
127 return aThemePaletteCollection
;
130 OString
ThemeColorPaletteManager::generateJSON()
132 svx::ThemePaletteCollection aThemePaletteCollection
= generate();
134 boost::property_tree::ptree aTree
;
135 boost::property_tree::ptree aColorListTree
;
137 for (size_t nEffect
= 0; nEffect
< 6; ++nEffect
)
139 boost::property_tree::ptree aColorRowTree
;
140 for (size_t nIndex
= 0; nIndex
< 12; ++nIndex
)
142 auto const& rColorData
= aThemePaletteCollection
.maColors
[nIndex
];
143 auto const& rEffectData
= rColorData
.maEffects
[nEffect
];
145 boost::property_tree::ptree aColorTree
;
146 aColorTree
.put("Value", rEffectData
.maColor
.AsRGBHexString().toUtf8());
147 aColorTree
.put("Name", rEffectData
.maColorName
.toUtf8());
149 model::ComplexColor aComplexColor
;
150 aComplexColor
.setSchemeColor(rColorData
.meThemeColorType
);
151 aComplexColor
.addTransformation(
152 { model::TransformationType::LumMod
, rEffectData
.mnLumMod
});
153 aComplexColor
.addTransformation(
154 { model::TransformationType::LumOff
, rEffectData
.mnLumOff
});
155 boost::property_tree::ptree aDataTree
;
156 model::color::convertToJSONTree(aDataTree
, aComplexColor
);
157 aColorTree
.add_child("Data", aDataTree
);
158 aColorRowTree
.push_back(std::make_pair("", aColorTree
));
160 aColorListTree
.push_back(std::make_pair("", aColorRowTree
));
163 aTree
.add_child("ThemeColors", aColorListTree
);
165 std::stringstream aStream
;
166 boost::property_tree::write_json(aStream
, aTree
);
168 return OString(aStream
.str());
171 } // end svx namespace
173 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */