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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <oox/drawingml/drawingmltypes.hxx>
21 #include <drawingml/colorchoicecontext.hxx>
22 #include <oox/helper/attributelist.hxx>
23 #include <oox/drawingml/color.hxx>
24 #include <oox/token/namespaces.hxx>
25 #include <oox/token/tokens.hxx>
26 #include <unordered_map>
27 #include <frozen/bits/defines.h>
28 #include <frozen/bits/elsa_std.h>
29 #include <frozen/unordered_map.h>
31 namespace oox::drawingml
{
36 constexpr frozen::unordered_map
<sal_Int32
, model::SystemColorType
, 30> constSystemColorMap
38 { XML_scrollBar
, model::SystemColorType::ScrollBar
},
39 { XML_background
, model::SystemColorType::Background
},
40 { XML_activeCaption
, model::SystemColorType::ActiveCaption
},
41 { XML_inactiveCaption
, model::SystemColorType::InactiveCaption
},
42 { XML_menu
, model::SystemColorType::Menu
},
43 { XML_window
, model::SystemColorType::Window
},
44 { XML_windowFrame
, model::SystemColorType::WindowFrame
},
45 { XML_menuText
, model::SystemColorType::MenuText
},
46 { XML_windowText
, model::SystemColorType::WindowText
},
47 { XML_captionText
, model::SystemColorType::CaptionText
},
48 { XML_activeBorder
, model::SystemColorType::ActiveBorder
},
49 { XML_inactiveBorder
, model::SystemColorType::InactiveBorder
},
50 { XML_appWorkspace
, model::SystemColorType::AppWorkspace
},
51 { XML_highlight
, model::SystemColorType::Highlight
},
52 { XML_highlightText
, model::SystemColorType::HighlightText
},
53 { XML_btnFace
, model::SystemColorType::ButtonFace
},
54 { XML_btnShadow
, model::SystemColorType::ButtonShadow
},
55 { XML_grayText
, model::SystemColorType::GrayText
},
56 { XML_btnText
, model::SystemColorType::ButtonText
},
57 { XML_inactiveCaptionText
, model::SystemColorType::InactiveCaptionText
},
58 { XML_btnHighlight
, model::SystemColorType::ButtonHighlight
},
59 { XML_3dDkShadow
, model::SystemColorType::DarkShadow3D
},
60 { XML_3dLight
, model::SystemColorType::Light3D
},
61 { XML_infoText
, model::SystemColorType::InfoText
},
62 { XML_infoBk
, model::SystemColorType::InfoBack
},
63 { XML_hotLight
, model::SystemColorType::HotLight
},
64 { XML_gradientActiveCaption
, model::SystemColorType::GradientActiveCaption
},
65 { XML_gradientInactiveCaption
, model::SystemColorType::GradientInactiveCaption
},
66 { XML_menuHighlight
, model::SystemColorType::MenuHighlight
},
67 { XML_menuBar
, model::SystemColorType::MenuBar
}
70 constexpr frozen::unordered_map
<sal_Int32
, model::TransformationType
, 28> constTransformTypeMap
72 { XML_alpha
, model::TransformationType::Alpha
},
73 { XML_alphaMod
, model::TransformationType::AlphaMod
},
74 { XML_alphaOff
, model::TransformationType::AlphaOff
},
75 { XML_blue
, model::TransformationType::Blue
},
76 { XML_blueMod
, model::TransformationType::BlueMod
},
77 { XML_blueOff
, model::TransformationType::BlueOff
},
78 { XML_hue
, model::TransformationType::Hue
},
79 { XML_hueMod
, model::TransformationType::HueMod
},
80 { XML_hueOff
, model::TransformationType::HueOff
},
81 { XML_lum
, model::TransformationType::Lum
},
82 { XML_lumMod
, model::TransformationType::LumMod
},
83 { XML_lumOff
, model::TransformationType::LumOff
},
84 { XML_green
, model::TransformationType::Green
},
85 { XML_greenMod
, model::TransformationType::GreenMod
},
86 { XML_greenOff
, model::TransformationType::GreenOff
},
87 { XML_red
, model::TransformationType::Red
},
88 { XML_redMod
, model::TransformationType::RedMod
},
89 { XML_redOff
, model::TransformationType::RedOff
},
90 { XML_sat
, model::TransformationType::Sat
},
91 { XML_satMod
, model::TransformationType::SatMod
},
92 { XML_satOff
, model::TransformationType::SatMod
},
93 { XML_shade
, model::TransformationType::Shade
},
94 { XML_tint
, model::TransformationType::Tint
},
95 { XML_comp
, model::TransformationType::Comp
},
96 { XML_gamma
, model::TransformationType::Gamma
},
97 { XML_gray
, model::TransformationType::Gray
},
98 { XML_inv
, model::TransformationType::Inv
},
99 { XML_invGamma
, model::TransformationType::InvGamma
}
104 ColorValueContext::ColorValueContext(ContextHandler2Helper
const & rParent
, Color
& rColor
, model::ComplexColor
* pComplexColor
)
105 : ContextHandler2(rParent
)
107 , mpComplexColor(pComplexColor
)
111 void ColorValueContext::onStartElement( const AttributeList
& rAttribs
)
113 switch( getCurrentElement() )
115 case A_TOKEN(scrgbClr
):
118 rAttribs
.getInteger( XML_r
, 0 ),
119 rAttribs
.getInteger( XML_g
, 0 ),
120 rAttribs
.getInteger( XML_b
, 0 ) );
123 mpComplexColor
->setCRGB(
124 rAttribs
.getInteger(XML_r
, 0),
125 rAttribs
.getInteger(XML_g
, 0),
126 rAttribs
.getInteger(XML_b
, 0));
131 case A_TOKEN(srgbClr
):
133 mrColor
.setSrgbClr(rAttribs
.getIntegerHex(XML_val
, 0));
136 mpComplexColor
->setRGB(rAttribs
.getIntegerHex(XML_val
, 0));
141 case A_TOKEN(hslClr
):
144 rAttribs
.getInteger( XML_hue
, 0 ),
145 rAttribs
.getInteger( XML_sat
, 0 ),
146 rAttribs
.getInteger( XML_lum
, 0 ) );
150 mpComplexColor
->setHSL(
151 rAttribs
.getInteger(XML_hue
, 0),
152 rAttribs
.getInteger(XML_sat
, 0),
153 rAttribs
.getInteger(XML_lum
, 0));
158 case A_TOKEN(sysClr
):
160 sal_Int32 nToken
= rAttribs
.getToken(XML_val
, XML_TOKEN_INVALID
);
161 sal_Int32 nLastColor
= rAttribs
.getIntegerHex(XML_lastClr
, -1);
163 mrColor
.setSysClr(nToken
, nLastColor
);
167 auto aIterator
= constSystemColorMap
.find(nToken
);
168 if (aIterator
!= constSystemColorMap
.end())
170 auto const& aPair
= *aIterator
;
171 model::SystemColorType eType
= aPair
.second
;
172 mpComplexColor
->setSystemColor(eType
, nLastColor
);
178 case A_TOKEN(schemeClr
):
180 auto nToken
= rAttribs
.getToken(XML_val
, XML_TOKEN_INVALID
);
181 mrColor
.setSchemeClr(nToken
);
182 std::optional
<OUString
> sSchemeName
= rAttribs
.getString(XML_val
);
183 if (sSchemeName
.has_value())
185 mrColor
.setSchemeName(*sSchemeName
);
189 if (nToken
== XML_phClr
)
191 mpComplexColor
->setSchemePlaceholder();
195 model::ThemeColorType eType
= schemeNameToThemeColorType(*sSchemeName
);
196 mpComplexColor
->setSchemeColor(eType
);
203 case A_TOKEN(prstClr
):
205 sal_Int32 nToken
= rAttribs
.getToken(XML_val
, XML_TOKEN_INVALID
);
206 mrColor
.setPrstClr(nToken
);
209 // TODO - just converted to RGB for now
210 ::Color nRgbValue
= Color::getDmlPresetColor(nToken
, API_RGB_TRANSPARENT
);
211 mpComplexColor
->mnComponent1
= nRgbValue
.GetRed();
212 mpComplexColor
->mnComponent2
= nRgbValue
.GetGreen();
213 mpComplexColor
->mnComponent3
= nRgbValue
.GetBlue();
214 mpComplexColor
->meType
= model::ColorType::RGB
;
221 ::oox::core::ContextHandlerRef
ColorValueContext::onCreateContext(
222 sal_Int32 nElement
, const AttributeList
& rAttribs
)
226 case A_TOKEN( alpha
):
227 case A_TOKEN( alphaMod
):
228 case A_TOKEN( alphaOff
):
229 case A_TOKEN( blue
):
230 case A_TOKEN( blueMod
):
231 case A_TOKEN( blueOff
):
233 case A_TOKEN( hueMod
):
234 case A_TOKEN( hueOff
):
236 case A_TOKEN( lumMod
):
237 case A_TOKEN( lumOff
):
238 case A_TOKEN( green
):
239 case A_TOKEN( greenMod
):
240 case A_TOKEN( greenOff
):
242 case A_TOKEN( redMod
):
243 case A_TOKEN( redOff
):
245 case A_TOKEN( satMod
):
246 case A_TOKEN( satOff
):
247 case A_TOKEN( shade
):
248 case A_TOKEN( tint
):
250 OUString aValue
= rAttribs
.getStringDefaulted( XML_val
);
252 if (aValue
.endsWith("%"))
254 nVal
= aValue
.toDouble() * PER_PERCENT
;
257 nVal
= rAttribs
.getInteger(XML_val
, 0);
258 mrColor
.addTransformation( nElement
, nVal
);
261 case A_TOKEN( comp
):
262 case A_TOKEN( gamma
):
263 case A_TOKEN( gray
):
265 case A_TOKEN( invGamma
):
266 mrColor
.addTransformation( nElement
);
272 auto aIterator
= constTransformTypeMap
.find(getBaseToken(nElement
));
273 if (aIterator
!= constTransformTypeMap
.end())
275 auto const& aPair
= *aIterator
;
276 model::TransformationType eType
= aPair
.second
;
278 OUString aValueString
= rAttribs
.getStringDefaulted(XML_val
);
279 sal_Int32 nValue
= 0;
280 if (aValueString
.endsWith("%"))
281 nValue
= aValueString
.toDouble() * PER_PERCENT
;
283 nValue
= rAttribs
.getInteger(XML_val
, 0);
285 mpComplexColor
->maTransformations
.push_back({eType
, sal_Int16(nValue
/ 10)});
292 ColorContext::ColorContext(ContextHandler2Helper
const & rParent
, Color
& rColor
, model::ComplexColor
* pComplexColor
)
293 : ContextHandler2(rParent
)
295 , mpComplexColor(pComplexColor
)
299 ::oox::core::ContextHandlerRef
ColorContext::onCreateContext(
300 sal_Int32 nElement
, const AttributeList
& )
304 case A_TOKEN( scrgbClr
):
305 case A_TOKEN( srgbClr
):
306 case A_TOKEN( hslClr
):
307 case A_TOKEN( sysClr
):
308 case A_TOKEN( schemeClr
):
309 case A_TOKEN( prstClr
):
310 return new ColorValueContext(*this, mrColor
, mpComplexColor
);
315 ColorsContext::ColorsContext(ContextHandler2Helper
const& rParent
, std::vector
<Color
>& rColors
)
316 : ContextHandler2(rParent
)
321 ::oox::core::ContextHandlerRef
ColorsContext::onCreateContext(sal_Int32 nElement
,
322 const AttributeList
&)
326 case A_TOKEN(scrgbClr
):
327 case A_TOKEN(srgbClr
):
328 case A_TOKEN(hslClr
):
329 case A_TOKEN(sysClr
):
330 case A_TOKEN(schemeClr
):
331 case A_TOKEN(prstClr
):
333 mrColors
.emplace_back();
334 return new ColorValueContext(*this, mrColors
.back(), nullptr);
340 } // namespace oox::drawingml
342 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */