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 <svx/dialmgr.hxx>
15 #include <svx/strings.hrc>
16 #include <docmodel/theme/ColorSet.hxx>
17 #include <docmodel/color/ComplexColorJSON.hxx>
18 #include <tools/json_writer.hxx>
24 constexpr const std::array
<const std::array
<sal_Int16
, 6>, 5> g_aLumMods
= {
25 std::array
<sal_Int16
, 6>{ 10'000, 5'000, 6'500, 7'500, 8'500, 9'500 },
26 std::array
<sal_Int16
, 6>{ 10'000, 1'000, 2'500, 5'000, 7'500, 9'000 },
27 std::array
<sal_Int16
, 6>{ 10'000, 2'000, 4'000, 6'000, 7'500, 5'000 },
28 std::array
<sal_Int16
, 6>{ 10'000, 9'000, 7'500, 5'000, 2'500, 1'000 },
29 std::array
<sal_Int16
, 6>{ 10'000, 9'500, 8'500, 7'500, 6'500, 5'000 },
32 constexpr const std::array
<const std::array
<sal_Int16
, 6>, 5> g_aLumOffs
= {
33 std::array
<sal_Int16
, 6>{ 0, 5'000, 3'500, 2'500, 1'500, 0'500 },
34 std::array
<sal_Int16
, 6>{ 0, 9'000, 7'500, 5'000, 2'500, 1'000 },
35 std::array
<sal_Int16
, 6>{ 0, 8'000, 6'000, 4'000, 0, 0 },
36 std::array
<sal_Int16
, 6>{ 0, 0, 0, 0, 0, 0 },
37 std::array
<sal_Int16
, 6>{ 0, 0, 0, 0, 0, 0 },
40 } // end anonymous namespace
44 ThemeColorPaletteManager::ThemeColorPaletteManager(
45 std::shared_ptr
<model::ColorSet
> const& pColorSet
)
46 : m_pColorSet(pColorSet
)
50 svx::ThemePaletteCollection
ThemeColorPaletteManager::generate()
52 svx::ThemePaletteCollection aThemePaletteCollection
;
54 const std::array
<OUString
, 12> aColorNames
= {
55 SvxResId(RID_SVXSTR_THEME_COLOR1
), SvxResId(RID_SVXSTR_THEME_COLOR2
),
56 SvxResId(RID_SVXSTR_THEME_COLOR3
), SvxResId(RID_SVXSTR_THEME_COLOR4
),
57 SvxResId(RID_SVXSTR_THEME_COLOR5
), SvxResId(RID_SVXSTR_THEME_COLOR6
),
58 SvxResId(RID_SVXSTR_THEME_COLOR7
), SvxResId(RID_SVXSTR_THEME_COLOR8
),
59 SvxResId(RID_SVXSTR_THEME_COLOR9
), SvxResId(RID_SVXSTR_THEME_COLOR10
),
60 SvxResId(RID_SVXSTR_THEME_COLOR11
), SvxResId(RID_SVXSTR_THEME_COLOR12
),
63 for (size_t nColor
= 0; nColor
< aColorNames
.size(); ++nColor
)
65 auto eThemeType
= model::convertToThemeColorType(nColor
);
66 if (eThemeType
== model::ThemeColorType::Unknown
)
69 auto& aThemeColorData
= aThemePaletteCollection
.maColors
[nColor
];
70 aThemeColorData
.meThemeColorType
= eThemeType
;
72 Color aThemeColor
= m_pColorSet
->getColor(eThemeType
);
73 aThemeColorData
.maBaseColor
= aThemeColor
;
75 basegfx::BColor aHSLColor
= basegfx::utils::rgb2hsl(aThemeColor
.getBColor());
76 double aLuminanceValue
= aHSLColor
.getBlue() * 255.0;
78 for (size_t nEffect
: { 0, 1, 2, 3, 4, 5 })
80 auto& rEffect
= aThemeColorData
.maEffects
[nEffect
];
83 if (aLuminanceValue
< 0.5)
85 else if (aLuminanceValue
> 254.5)
87 else if (aLuminanceValue
< 50.5)
89 else if (aLuminanceValue
> 203.5)
94 rEffect
.mnLumOff
= g_aLumOffs
[nIndex
][nEffect
];
95 rEffect
.mnLumMod
= g_aLumMods
[nIndex
][nEffect
];
97 rEffect
.maColor
= aThemeColor
;
98 rEffect
.maColor
.ApplyLumModOff(rEffect
.mnLumMod
, rEffect
.mnLumOff
);
101 sal_Int16 nPercent
= rEffect
.getPercentage();
106 aTemplate
= SvxResId(RID_SVXSTR_THEME_EFFECT_LIGHTER
);
108 else if (nPercent
< 0)
110 aTemplate
= SvxResId(RID_SVXSTR_THEME_EFFECT_DARKER
);
113 if (!aTemplate
.isEmpty())
115 aColorName
= aTemplate
.replaceAll("$THEME_NAME", aColorNames
[nColor
]);
117 = aColorName
.replaceAll("$PERCENTAGE", OUString::number(std::abs(nPercent
)));
121 aColorName
= aColorNames
[nColor
];
123 rEffect
.maColorName
= aColorName
;
126 return aThemePaletteCollection
;
129 void ThemeColorPaletteManager::generateJSON(tools::JsonWriter
& aTree
)
131 svx::ThemePaletteCollection aThemePaletteCollection
= generate();
133 auto aColorListTree
= aTree
.startArray("ThemeColors");
135 for (size_t nEffect
= 0; nEffect
< 6; ++nEffect
)
137 auto aColorRowTree
= aTree
.startAnonArray();
138 for (size_t nIndex
= 0; nIndex
< 12; ++nIndex
)
140 auto aColorTree
= aTree
.startStruct();
142 auto const& rColorData
= aThemePaletteCollection
.maColors
[nIndex
];
143 auto const& rEffectData
= rColorData
.maEffects
[nEffect
];
145 aTree
.put("Value", rEffectData
.maColor
.AsRGBHexString().toUtf8());
146 aTree
.put("Name", rEffectData
.maColorName
.toUtf8());
148 model::ComplexColor aComplexColor
;
149 aComplexColor
.setThemeColor(rColorData
.meThemeColorType
);
150 aComplexColor
.addTransformation(
151 { model::TransformationType::LumMod
, rEffectData
.mnLumMod
});
152 aComplexColor
.addTransformation(
153 { model::TransformationType::LumOff
, rEffectData
.mnLumOff
});
154 auto aDataTree
= aTree
.startNode("Data");
155 model::color::convertToJSONTree(aTree
, aComplexColor
);
160 } // end svx namespace
162 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */