tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / oox / source / drawingml / chart / objectformatter.cxx
blob0d746ab783f8284ffe161f95024a8c926a9a9c29
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <drawingml/chart/objectformatter.hxx>
22 #include <com/sun/star/chart2/XChartDocument.hpp>
23 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
24 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
25 #include <com/sun/star/util/XNumberFormatTypes.hpp>
26 #include <comphelper/diagnose_ex.hxx>
27 #include <osl/thread.h>
28 #include <osl/diagnose.h>
29 #include <rtl/strbuf.hxx>
30 #include <oox/core/xmlfilterbase.hxx>
31 #include <drawingml/fillproperties.hxx>
32 #include <drawingml/lineproperties.hxx>
33 #include <oox/drawingml/shapepropertymap.hxx>
34 #include <drawingml/textbody.hxx>
35 #include <drawingml/textparagraph.hxx>
36 #include <oox/drawingml/theme.hxx>
37 #include <drawingml/chart/chartspacemodel.hxx>
38 #include <oox/helper/modelobjecthelper.hxx>
39 #include <oox/helper/graphichelper.hxx>
40 #include <oox/token/properties.hxx>
41 #include <oox/token/tokens.hxx>
43 #include <unotools/mediadescriptor.hxx>
45 namespace oox::drawingml::chart {
47 using namespace ::com::sun::star::chart2;
48 using namespace ::com::sun::star::lang;
49 using namespace ::com::sun::star::uno;
50 using namespace ::com::sun::star::util;
52 using ::oox::core::XmlFilterBase;
54 namespace {
56 struct AutoFormatPatternEntry
58 sal_Int32 mnColorToken; /// Theme color token.
59 sal_Int32 mnModToken; /// Color modification token.
60 sal_Int32 mnModValue; /// Color modification value.
63 #define AUTOFORMAT_PATTERN_COLOR( color_token ) \
64 { color_token, XML_TOKEN_INVALID, 0 }
66 #define AUTOFORMAT_PATTERN_COLORMOD( color_token, mod_token, mod_value ) \
67 { color_token, mod_token, mod_value }
69 #define AUTOFORMAT_PATTERN_END() \
70 AUTOFORMAT_PATTERN_COLOR( XML_TOKEN_INVALID )
72 const AutoFormatPatternEntry spAutoFormatPattern1[] =
74 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 88500 ),
75 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 55000 ),
76 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 78000 ),
77 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 92500 ),
78 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 70000 ),
79 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 30000 ),
80 AUTOFORMAT_PATTERN_END()
83 const AutoFormatPatternEntry spAutoFormatPattern2[] =
85 AUTOFORMAT_PATTERN_COLOR( XML_accent1 ),
86 AUTOFORMAT_PATTERN_COLOR( XML_accent2 ),
87 AUTOFORMAT_PATTERN_COLOR( XML_accent3 ),
88 AUTOFORMAT_PATTERN_COLOR( XML_accent4 ),
89 AUTOFORMAT_PATTERN_COLOR( XML_accent5 ),
90 AUTOFORMAT_PATTERN_COLOR( XML_accent6 ),
91 AUTOFORMAT_PATTERN_END()
94 const AutoFormatPatternEntry spAutoFormatPattern3[] =
96 AUTOFORMAT_PATTERN_COLORMOD( XML_accent1, XML_shade, 50000 ),
97 AUTOFORMAT_PATTERN_COLORMOD( XML_accent2, XML_shade, 50000 ),
98 AUTOFORMAT_PATTERN_COLORMOD( XML_accent3, XML_shade, 50000 ),
99 AUTOFORMAT_PATTERN_COLORMOD( XML_accent4, XML_shade, 50000 ),
100 AUTOFORMAT_PATTERN_COLORMOD( XML_accent5, XML_shade, 50000 ),
101 AUTOFORMAT_PATTERN_COLORMOD( XML_accent6, XML_shade, 50000 ),
102 AUTOFORMAT_PATTERN_END()
105 const AutoFormatPatternEntry spAutoFormatPattern4[] =
107 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 5000 ),
108 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 55000 ),
109 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 78000 ),
110 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 15000 ),
111 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 70000 ),
112 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 30000 ),
113 AUTOFORMAT_PATTERN_END()
116 #undef AUTOFORMAT_PATTERN_COLOR
117 #undef AUTOFORMAT_PATTERN_COLORMOD
118 #undef AUTOFORMAT_PATTERN_END
120 struct AutoFormatEntry
122 sal_Int32 mnFirstStyleIdx; /// First chart style index.
123 sal_Int32 mnLastStyleIdx; /// Last chart style index.
124 sal_Int32 mnThemedIdx; /// Themed style index.
125 sal_Int32 mnColorToken; /// Theme color token.
126 sal_Int32 mnModToken; /// Color modification token.
127 sal_Int32 mnModValue; /// Color modification value.
128 sal_Int32 mnRelLineWidth; /// Relative line width (percent).
129 const AutoFormatPatternEntry* mpPattern;/// Color cycling pattern for data series.
130 bool mbFadedColor; /// True = Faded color for data series.
133 #define AUTOFORMAT_COLOR( first, last, themed_style, color_token ) \
134 { first, last, themed_style, color_token, XML_TOKEN_INVALID, 0, 100, nullptr, false }
136 #define AUTOFORMAT_COLORMOD( first, last, themed_style, color_token, mod_token, mod_value ) \
137 { first, last, themed_style, color_token, mod_token, mod_value, 100, nullptr, false }
139 #define AUTOFORMAT_ACCENTSMOD( first, themed_style, mod_token, mod_value ) \
140 AUTOFORMAT_COLORMOD( first, first, themed_style, XML_accent1, mod_token, mod_value ), \
141 AUTOFORMAT_COLORMOD( first + 1, first + 1, themed_style, XML_accent2, mod_token, mod_value ), \
142 AUTOFORMAT_COLORMOD( first + 2, first + 2, themed_style, XML_accent3, mod_token, mod_value ), \
143 AUTOFORMAT_COLORMOD( first + 3, first + 3, themed_style, XML_accent4, mod_token, mod_value ), \
144 AUTOFORMAT_COLORMOD( first + 4, first + 4, themed_style, XML_accent5, mod_token, mod_value ), \
145 AUTOFORMAT_COLORMOD( first + 5, first + 5, themed_style, XML_accent6, mod_token, mod_value )
147 #define AUTOFORMAT_PATTERN( first, last, themed_style, line_width, pattern ) \
148 { first, last, themed_style, XML_TOKEN_INVALID, XML_TOKEN_INVALID, 0, line_width, pattern, false }
150 #define AUTOFORMAT_FADED( first, last, themed_style, color_token, line_width ) \
151 { first, last, themed_style, color_token, XML_TOKEN_INVALID, 0, line_width, nullptr, true }
153 #define AUTOFORMAT_FADEDACCENTS( first, themed_style, line_width ) \
154 AUTOFORMAT_FADED( first, first, themed_style, XML_accent1, line_width ), \
155 AUTOFORMAT_FADED( first + 1, first + 1, themed_style, XML_accent2, line_width ), \
156 AUTOFORMAT_FADED( first + 2, first + 2, themed_style, XML_accent3, line_width ), \
157 AUTOFORMAT_FADED( first + 3, first + 3, themed_style, XML_accent4, line_width ), \
158 AUTOFORMAT_FADED( first + 4, first + 4, themed_style, XML_accent5, line_width ), \
159 AUTOFORMAT_FADED( first + 5, first + 5, themed_style, XML_accent6, line_width )
161 #define AUTOFORMAT_INVISIBLE( first, last ) \
162 AUTOFORMAT_COLOR( first, last, -1, XML_TOKEN_INVALID )
164 #define AUTOFORMAT_END() \
165 AUTOFORMAT_INVISIBLE( -1, -1 )
167 const AutoFormatEntry spNoFormats[] =
169 AUTOFORMAT_INVISIBLE( 1, 48 ),
170 AUTOFORMAT_END()
173 const AutoFormatEntry spChartSpaceFill[] =
175 AUTOFORMAT_COLOR( 1, 32, THEMED_STYLE_SUBTLE, XML_bg1 ),
176 AUTOFORMAT_COLOR( 33, 40, THEMED_STYLE_SUBTLE, XML_lt1 ),
177 AUTOFORMAT_COLOR( 41, 48, THEMED_STYLE_SUBTLE, XML_dk1 ),
178 AUTOFORMAT_END()
181 const AutoFormatEntry spDataTableLines[] =
183 AUTOFORMAT_COLORMOD( 1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ),
184 AUTOFORMAT_COLORMOD( 33, 40, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ),
185 // 41...48: no line, same as Chart2
186 AUTOFORMAT_END()
189 const AutoFormatEntry spPlotArea2dFills[] =
191 AUTOFORMAT_COLOR( 1, 32, THEMED_STYLE_SUBTLE, XML_bg1 ),
192 AUTOFORMAT_COLORMOD( 33, 34, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 20000 ),
193 AUTOFORMAT_ACCENTSMOD( 35, THEMED_STYLE_SUBTLE, XML_tint, 20000 ), // tint not documented!?
194 AUTOFORMAT_COLORMOD( 41, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
195 AUTOFORMAT_END()
198 const AutoFormatEntry spWallFloorLines[] =
200 AUTOFORMAT_COLORMOD( 1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ),
201 AUTOFORMAT_COLORMOD( 33, 40, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ),
202 // 41...48: no line, same as Chart2
203 AUTOFORMAT_END()
206 const AutoFormatEntry spWallFloorFills[] =
208 AUTOFORMAT_INVISIBLE( 1, 32 ),
209 AUTOFORMAT_COLORMOD( 33, 34, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 20000 ),
210 AUTOFORMAT_ACCENTSMOD( 35, THEMED_STYLE_SUBTLE, XML_tint, 20000 ), // tint not documented!?
211 AUTOFORMAT_COLORMOD( 41, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
212 AUTOFORMAT_END()
215 const AutoFormatEntry spAxisLines[] =
217 AUTOFORMAT_COLORMOD( 1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ), // tint not documented!?
218 AUTOFORMAT_COLORMOD( 33, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ), // tint not documented!?
219 AUTOFORMAT_END()
222 const AutoFormatEntry spMajorGridLines[] =
224 AUTOFORMAT_COLORMOD( 1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ), // tint not documented!?
225 AUTOFORMAT_COLORMOD( 33, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ), // tint not documented!?
226 AUTOFORMAT_END()
229 const AutoFormatEntry spMinorGridLines[] =
231 AUTOFORMAT_COLORMOD( 1, 40, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 50000 ),
232 AUTOFORMAT_COLORMOD( 41, 48, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 90000 ),
233 AUTOFORMAT_END()
236 const AutoFormatEntry spOtherLines[] =
238 AUTOFORMAT_COLOR( 1, 32, THEMED_STYLE_SUBTLE, XML_tx1 ),
239 AUTOFORMAT_COLOR( 33, 34, THEMED_STYLE_SUBTLE, XML_dk1 ),
240 AUTOFORMAT_COLORMOD( 35, 40, THEMED_STYLE_SUBTLE, XML_dk1, XML_shade, 25000 ),
241 AUTOFORMAT_COLOR( 41, 48, THEMED_STYLE_SUBTLE, XML_lt1 ),
242 AUTOFORMAT_END()
245 const AutoFormatEntry spLinearSeriesLines[] =
247 AUTOFORMAT_PATTERN( 1, 1, THEMED_STYLE_SUBTLE, 300, spAutoFormatPattern1 ),
248 AUTOFORMAT_PATTERN( 2, 2, THEMED_STYLE_SUBTLE, 300, spAutoFormatPattern2 ),
249 AUTOFORMAT_FADEDACCENTS( 3, THEMED_STYLE_SUBTLE, 300 ),
250 AUTOFORMAT_PATTERN( 9, 9, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
251 AUTOFORMAT_PATTERN( 10, 10, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
252 AUTOFORMAT_FADEDACCENTS( 11, THEMED_STYLE_SUBTLE, 500 ),
253 AUTOFORMAT_PATTERN( 17, 17, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
254 AUTOFORMAT_PATTERN( 18, 18, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
255 AUTOFORMAT_FADEDACCENTS( 19, THEMED_STYLE_SUBTLE, 500 ),
256 AUTOFORMAT_PATTERN( 25, 25, THEMED_STYLE_SUBTLE, 700, spAutoFormatPattern1 ),
257 AUTOFORMAT_PATTERN( 26, 26, THEMED_STYLE_SUBTLE, 700, spAutoFormatPattern2 ),
258 AUTOFORMAT_FADEDACCENTS( 27, THEMED_STYLE_SUBTLE, 700 ),
259 AUTOFORMAT_PATTERN( 33, 33, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
260 AUTOFORMAT_PATTERN( 34, 34, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
261 AUTOFORMAT_FADEDACCENTS( 35, THEMED_STYLE_SUBTLE, 500 ),
262 AUTOFORMAT_PATTERN( 41, 42, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern4 ),
263 AUTOFORMAT_PATTERN( 42, 42, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
264 AUTOFORMAT_FADEDACCENTS( 43, THEMED_STYLE_SUBTLE, 500 ),
265 AUTOFORMAT_END()
268 const AutoFormatEntry spFilledSeriesLines[] =
270 AUTOFORMAT_INVISIBLE( 1, 8 ),
271 AUTOFORMAT_COLOR( 9, 16, THEMED_STYLE_SUBTLE, XML_lt1 ),
272 AUTOFORMAT_INVISIBLE( 17, 32 ),
273 AUTOFORMAT_COLORMOD( 33, 33, THEMED_STYLE_SUBTLE, XML_dk1, XML_shade, 50000 ),
274 AUTOFORMAT_PATTERN( 34, 34, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern3 ),
275 AUTOFORMAT_ACCENTSMOD( 35, THEMED_STYLE_SUBTLE, XML_shade, 50000 ),
276 AUTOFORMAT_INVISIBLE( 41, 48 ),
277 AUTOFORMAT_END()
280 const AutoFormatEntry spFilledSeries2dFills[] =
282 AUTOFORMAT_PATTERN( 1, 1, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
283 AUTOFORMAT_PATTERN( 2, 2, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
284 AUTOFORMAT_FADEDACCENTS( 3, THEMED_STYLE_SUBTLE, 100 ),
285 AUTOFORMAT_PATTERN( 9, 9, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
286 AUTOFORMAT_PATTERN( 10, 10, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
287 AUTOFORMAT_FADEDACCENTS( 11, THEMED_STYLE_SUBTLE, 100 ),
288 AUTOFORMAT_PATTERN( 17, 17, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern1 ),
289 AUTOFORMAT_PATTERN( 18, 18, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
290 AUTOFORMAT_FADEDACCENTS( 19, THEMED_STYLE_INTENSE, 100 ),
291 AUTOFORMAT_PATTERN( 25, 25, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern1 ),
292 AUTOFORMAT_PATTERN( 26, 26, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
293 AUTOFORMAT_FADEDACCENTS( 27, THEMED_STYLE_INTENSE, 100 ),
294 AUTOFORMAT_PATTERN( 33, 33, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
295 AUTOFORMAT_PATTERN( 34, 34, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
296 AUTOFORMAT_FADEDACCENTS( 35, THEMED_STYLE_SUBTLE, 100 ),
297 AUTOFORMAT_PATTERN( 41, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern4 ),
298 AUTOFORMAT_PATTERN( 42, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
299 AUTOFORMAT_FADEDACCENTS( 43, THEMED_STYLE_INTENSE, 100 ),
300 AUTOFORMAT_END()
303 const AutoFormatEntry spFilledSeries3dFills[] =
305 AUTOFORMAT_PATTERN( 1, 1, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
306 AUTOFORMAT_PATTERN( 2, 2, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
307 AUTOFORMAT_FADEDACCENTS( 3, THEMED_STYLE_SUBTLE, 100 ),
308 AUTOFORMAT_PATTERN( 9, 9, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
309 AUTOFORMAT_PATTERN( 10, 10, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
310 AUTOFORMAT_FADEDACCENTS( 11, THEMED_STYLE_SUBTLE, 100 ),
311 AUTOFORMAT_PATTERN( 17, 17, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
312 AUTOFORMAT_PATTERN( 18, 18, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
313 AUTOFORMAT_FADEDACCENTS( 19, THEMED_STYLE_SUBTLE, 100 ),
314 AUTOFORMAT_PATTERN( 25, 25, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
315 AUTOFORMAT_PATTERN( 26, 26, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
316 AUTOFORMAT_FADEDACCENTS( 27, THEMED_STYLE_SUBTLE, 100 ),
317 AUTOFORMAT_PATTERN( 33, 33, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
318 AUTOFORMAT_PATTERN( 34, 34, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
319 AUTOFORMAT_FADEDACCENTS( 35, THEMED_STYLE_SUBTLE, 100 ),
320 AUTOFORMAT_PATTERN( 41, 42, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern4 ),
321 AUTOFORMAT_PATTERN( 42, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
322 AUTOFORMAT_FADEDACCENTS( 43, THEMED_STYLE_SUBTLE, 100 ),
323 AUTOFORMAT_END()
326 const AutoFormatEntry spUpDownBarLines[] =
328 AUTOFORMAT_COLOR( 1, 16, THEMED_STYLE_SUBTLE, XML_tx1 ),
329 AUTOFORMAT_INVISIBLE( 17, 32 ),
330 AUTOFORMAT_COLOR( 33, 34, THEMED_STYLE_SUBTLE, XML_dk1 ),
331 AUTOFORMAT_ACCENTSMOD( 35, THEMED_STYLE_SUBTLE, XML_shade, 25000 ),
332 AUTOFORMAT_INVISIBLE( 41, 48 ),
333 AUTOFORMAT_END()
336 const AutoFormatEntry spUpBarFills[] =
338 AUTOFORMAT_COLORMOD( 1, 1, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 25000 ),
339 AUTOFORMAT_COLORMOD( 2, 2, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 5000 ),
340 AUTOFORMAT_ACCENTSMOD( 3, THEMED_STYLE_SUBTLE, XML_tint, 25000 ),
341 AUTOFORMAT_COLORMOD( 9, 9, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 25000 ),
342 AUTOFORMAT_COLORMOD( 10, 10, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 5000 ),
343 AUTOFORMAT_ACCENTSMOD( 11, THEMED_STYLE_SUBTLE, XML_tint, 25000 ),
344 AUTOFORMAT_COLORMOD( 17, 17, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 25000 ),
345 AUTOFORMAT_COLORMOD( 18, 18, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 5000 ),
346 AUTOFORMAT_ACCENTSMOD( 19, THEMED_STYLE_INTENSE, XML_tint, 25000 ),
347 AUTOFORMAT_COLORMOD( 25, 25, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 25000 ),
348 AUTOFORMAT_COLORMOD( 26, 26, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 5000 ),
349 AUTOFORMAT_ACCENTSMOD( 27, THEMED_STYLE_INTENSE, XML_tint, 25000 ),
350 AUTOFORMAT_COLOR( 33, 40, THEMED_STYLE_SUBTLE, XML_lt1 ),
351 AUTOFORMAT_COLORMOD( 41, 41, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 25000 ),
352 AUTOFORMAT_COLOR( 42, 42, THEMED_STYLE_INTENSE, XML_lt1 ),
353 AUTOFORMAT_ACCENTSMOD( 43, THEMED_STYLE_INTENSE, XML_tint, 25000 ),
354 AUTOFORMAT_END()
357 const AutoFormatEntry spDownBarFills[] =
359 AUTOFORMAT_COLORMOD( 1, 1, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 85000 ),
360 AUTOFORMAT_COLORMOD( 2, 2, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
361 AUTOFORMAT_ACCENTSMOD( 3, THEMED_STYLE_SUBTLE, XML_shade, 25000 ),
362 AUTOFORMAT_COLORMOD( 9, 9, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 85000 ),
363 AUTOFORMAT_COLORMOD( 10, 10, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
364 AUTOFORMAT_ACCENTSMOD( 11, THEMED_STYLE_SUBTLE, XML_shade, 25000 ),
365 AUTOFORMAT_COLORMOD( 17, 17, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 85000 ),
366 AUTOFORMAT_COLORMOD( 18, 18, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 95000 ),
367 AUTOFORMAT_ACCENTSMOD( 19, THEMED_STYLE_INTENSE, XML_shade, 25000 ),
368 AUTOFORMAT_COLORMOD( 25, 25, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 85000 ),
369 AUTOFORMAT_COLORMOD( 26, 26, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 95000 ),
370 AUTOFORMAT_ACCENTSMOD( 27, THEMED_STYLE_INTENSE, XML_shade, 25000 ),
371 AUTOFORMAT_COLORMOD( 33, 33, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 85000 ),
372 AUTOFORMAT_COLORMOD( 34, 34, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
373 AUTOFORMAT_ACCENTSMOD( 35, THEMED_STYLE_SUBTLE, XML_shade, 25000 ),
374 AUTOFORMAT_COLORMOD( 41, 41, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 85000 ),
375 AUTOFORMAT_COLOR( 42, 42, THEMED_STYLE_INTENSE, XML_dk1 ),
376 AUTOFORMAT_ACCENTSMOD( 43, THEMED_STYLE_INTENSE, XML_shade, 25000 ),
377 AUTOFORMAT_END()
380 #undef AUTOFORMAT_COLOR
381 #undef AUTOFORMAT_COLORMOD
382 #undef AUTOFORMAT_ACCENTSMOD
383 #undef AUTOFORMAT_PATTERN
384 #undef AUTOFORMAT_FADED
385 #undef AUTOFORMAT_FADEDACCENTS
386 #undef AUTOFORMAT_INVISIBLE
387 #undef AUTOFORMAT_END
389 const AutoFormatEntry* lclGetAutoFormatEntry( const AutoFormatEntry* pEntries, sal_Int32 nStyle )
391 for( ; pEntries && (pEntries->mnFirstStyleIdx >= 0); ++pEntries )
392 if( (pEntries->mnFirstStyleIdx <= nStyle) && (nStyle <= pEntries->mnLastStyleIdx) )
393 return pEntries;
394 return nullptr;
397 struct AutoTextEntry
399 sal_Int32 mnFirstStyleIdx; /// First chart style index.
400 sal_Int32 mnLastStyleIdx; /// Last chart style index.
401 sal_Int32 mnThemedFont; /// Themed font (minor/major).
402 sal_Int32 mnColorToken; /// Theme color token.
403 sal_Int32 mnDefFontSize; /// Default font size (1/100 points).
404 sal_Int32 mnRelFontSize; /// Font size relative to chart global font (percent).
405 bool mbBold; /// True = bold font.
408 #define AUTOTEXT_COLOR( first, last, themed_font, color_token, def_font_size, rel_font_size, bold ) \
409 { first, last, themed_font, color_token, def_font_size, rel_font_size, bold }
411 #define AUTOTEXT_END() \
412 AUTOTEXT_COLOR( -1, -1, XML_none, XML_TOKEN_INVALID, 1000, 100, false )
414 const AutoTextEntry spChartTitleTexts[] =
416 AUTOTEXT_COLOR( 1, 40, XML_minor, XML_tx1, 1800, 120, true ),
417 AUTOTEXT_COLOR( 41, 48, XML_minor, XML_lt1, 1800, 120, true ),
418 AUTOTEXT_END()
421 const AutoTextEntry spAxisTitleTexts[] =
423 AUTOTEXT_COLOR( 1, 40, XML_minor, XML_tx1, 1000, 100, true ),
424 AUTOTEXT_COLOR( 41, 48, XML_minor, XML_lt1, 1000, 100, true ),
425 AUTOTEXT_END()
428 const AutoTextEntry spOtherTexts[] =
430 AUTOTEXT_COLOR( 1, 40, XML_minor, XML_tx1, 1000, 100, false ),
431 AUTOTEXT_COLOR( 41, 48, XML_minor, XML_lt1, 1000, 100, false ),
432 AUTOTEXT_END()
435 #undef AUTOTEXT_COLOR
436 #undef AUTOTEXT_END
438 const AutoTextEntry* lclGetAutoTextEntry( const AutoTextEntry* pEntries, sal_Int32 nStyle )
440 for( ; pEntries && (pEntries->mnFirstStyleIdx >= 0); ++pEntries )
441 if( (pEntries->mnFirstStyleIdx <= nStyle) && (nStyle <= pEntries->mnLastStyleIdx) )
442 return pEntries;
443 return nullptr;
446 // These PropIds arrays will be indexed into using a ShapeProperty enum
448 const ShapePropertyIds spnCommonPropIds =
450 PROP_LineStyle, PROP_LineWidth, PROP_LineColor, PROP_LineTransparence, PROP_LineDashName,
451 PROP_LineCap, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
452 PROP_FillStyle, PROP_FillColor, PROP_FillTransparence, PROP_FillTransparenceGradientName, PROP_FillGradientName,
453 PROP_FillBitmapName, PROP_FillBitmapMode, PROP_FillBitmapSizeX, PROP_FillBitmapSizeY,
454 PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint,
455 PROP_FillHatchName, PROP_FillBackground,
456 PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID
459 const ShapePropertyIds spnLinearPropIds =
461 PROP_LineStyle, PROP_LineWidth, PROP_Color, PROP_Transparency, PROP_LineDashName,
462 PROP_LineCap, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
463 PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
464 PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
465 PROP_INVALID, PROP_INVALID, PROP_INVALID,
466 PROP_INVALID, PROP_INVALID,
467 PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID
470 const ShapePropertyIds spnFilledPropIds =
472 PROP_BorderStyle,
473 PROP_BorderWidth,
474 PROP_BorderColor,
475 PROP_BorderTransparency,
476 PROP_BorderDashName,
477 PROP_LineCap,
478 PROP_INVALID,
479 PROP_INVALID,
480 PROP_INVALID,
481 PROP_INVALID,
482 PROP_INVALID,
483 PROP_INVALID,
484 PROP_INVALID,
485 PROP_FillStyle,
486 PROP_Color,
487 PROP_Transparency,
488 PROP_FillTransparenceGradientName,
489 PROP_GradientName,
490 PROP_FillBitmapName,
491 PROP_FillBitmapMode,
492 PROP_FillBitmapSizeX,
493 PROP_FillBitmapSizeY,
494 PROP_FillBitmapPositionOffsetX,
495 PROP_FillBitmapPositionOffsetY,
496 PROP_FillBitmapRectanglePoint,
497 PROP_HatchName,
498 PROP_FillBackground,
499 PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID
502 /** Property info for common chart objects, to be used in ShapePropertyMap. */
503 const ShapePropertyInfo saCommonPropInfo( spnCommonPropIds, false, true, true, true, true );
504 /** Property info for linear data series, to be used in ShapePropertyMap. */
505 const ShapePropertyInfo saLinearPropInfo( spnLinearPropIds, false, true, true, true, true );
506 /** Property info for filled data series, to be used in ShapePropertyMap. */
507 const ShapePropertyInfo saFilledPropInfo( spnFilledPropIds, false, true, true, true, true );
509 /** Contains information about formatting of a specific chart object type. */
510 struct ObjectTypeFormatEntry
512 ObjectType meObjType; /// Object type for automatic format.
513 const ShapePropertyInfo& mrPropInfo; /// Property info for the ShapePropertyMap class.
514 const AutoFormatEntry* mpAutoLines; /// Automatic line formatting for all chart styles.
515 const AutoFormatEntry* mpAutoFills; /// Automatic fill formatting for all chart styles.
516 const AutoTextEntry* mpAutoTexts; /// Automatic text attributes for all chart styles.
517 bool mbIsFrame; /// True = object is a frame, false = object is a line.
518 ObjectTypeFormatEntry(ObjectType eObjType, const ShapePropertyInfo& rPropInfo,
519 const AutoFormatEntry* pAutoLines,
520 const AutoFormatEntry* pAutoFills,
521 const AutoTextEntry* pAutoTexts,
522 bool bIsFrame)
523 :meObjType(eObjType), mrPropInfo(rPropInfo), mpAutoLines(pAutoLines)
524 ,mpAutoFills(pAutoFills), mpAutoTexts(pAutoTexts), mbIsFrame(bIsFrame)
525 {} // prevent creation of implicit default ctor which fails in MSVC
528 #define TYPEFORMAT_FRAME( obj_type, prop_type, auto_texts, auto_lines, auto_fills ) \
529 { obj_type, prop_type, auto_lines, auto_fills, auto_texts, true }
531 #define TYPEFORMAT_LINE( obj_type, prop_type, auto_texts, auto_lines ) \
532 { obj_type, prop_type, auto_lines, nullptr, auto_texts, false }
534 const ObjectTypeFormatEntry spObjTypeFormatEntries[] =
536 // object type property info auto text auto line auto fill
537 TYPEFORMAT_FRAME( OBJECTTYPE_CHARTSPACE, saCommonPropInfo, nullptr, spNoFormats, spChartSpaceFill ),
538 TYPEFORMAT_FRAME( OBJECTTYPE_CHARTTITLE, saCommonPropInfo, spChartTitleTexts, nullptr /* eq to Ch2 */, nullptr /* eq to Ch2 */),
539 TYPEFORMAT_FRAME( OBJECTTYPE_LEGEND, saCommonPropInfo, spOtherTexts, spNoFormats, spNoFormats ),
540 TYPEFORMAT_FRAME( OBJECTTYPE_PLOTAREA2D, saCommonPropInfo, nullptr, nullptr /* eq to Ch2 */, spPlotArea2dFills ),
541 TYPEFORMAT_FRAME( OBJECTTYPE_PLOTAREA3D, saCommonPropInfo, nullptr, nullptr /* eq to Ch2 */, nullptr /* eq to Ch2 */ ),
542 TYPEFORMAT_FRAME( OBJECTTYPE_WALL, saCommonPropInfo, nullptr, spWallFloorLines, spWallFloorFills ),
543 TYPEFORMAT_FRAME( OBJECTTYPE_FLOOR, saCommonPropInfo, nullptr, spWallFloorLines, spWallFloorFills ),
544 TYPEFORMAT_LINE( OBJECTTYPE_AXIS, saCommonPropInfo, spOtherTexts, spAxisLines ),
545 TYPEFORMAT_FRAME( OBJECTTYPE_AXISTITLE, saCommonPropInfo, spAxisTitleTexts, nullptr /* eq to Ch2 */, nullptr /* eq to Ch2 */ ),
546 TYPEFORMAT_FRAME( OBJECTTYPE_AXISUNIT, saCommonPropInfo, spAxisTitleTexts, nullptr /* eq in Ch2 */, nullptr /* eq in Ch2 */ ),
547 TYPEFORMAT_LINE( OBJECTTYPE_MAJORGRIDLINE, saCommonPropInfo, nullptr, spMajorGridLines ),
548 TYPEFORMAT_LINE( OBJECTTYPE_MINORGRIDLINE, saCommonPropInfo, nullptr, spMinorGridLines ),
549 TYPEFORMAT_LINE( OBJECTTYPE_LINEARSERIES2D, saLinearPropInfo, nullptr, spLinearSeriesLines ),
550 TYPEFORMAT_FRAME( OBJECTTYPE_FILLEDSERIES2D, saFilledPropInfo, nullptr, spFilledSeriesLines, spFilledSeries2dFills ),
551 TYPEFORMAT_FRAME( OBJECTTYPE_FILLEDSERIES3D, saFilledPropInfo, nullptr, spFilledSeriesLines, spFilledSeries3dFills ),
552 TYPEFORMAT_FRAME( OBJECTTYPE_DATALABEL, saCommonPropInfo, spOtherTexts, nullptr /* eq to Ch2 */, nullptr /* eq to Ch2 */ ),
553 TYPEFORMAT_LINE( OBJECTTYPE_TRENDLINE, saCommonPropInfo, nullptr, spOtherLines ),
554 TYPEFORMAT_FRAME( OBJECTTYPE_TRENDLINELABEL, saCommonPropInfo, spOtherTexts, nullptr /* eq to Ch2 */, nullptr /* eq to Ch2 */ ),
555 TYPEFORMAT_LINE( OBJECTTYPE_ERRORBAR, saCommonPropInfo, nullptr, spOtherLines ),
556 TYPEFORMAT_LINE( OBJECTTYPE_SERLINE, saCommonPropInfo, nullptr, spOtherLines ),
557 TYPEFORMAT_LINE( OBJECTTYPE_LEADERLINE, saCommonPropInfo, nullptr, spOtherLines ),
558 TYPEFORMAT_LINE( OBJECTTYPE_DROPLINE, saCommonPropInfo, nullptr, spOtherLines ),
559 TYPEFORMAT_LINE( OBJECTTYPE_HILOLINE, saLinearPropInfo, nullptr, spOtherLines ),
560 TYPEFORMAT_FRAME( OBJECTTYPE_UPBAR, saCommonPropInfo, nullptr, spUpDownBarLines, spUpBarFills ),
561 TYPEFORMAT_FRAME( OBJECTTYPE_DOWNBAR, saCommonPropInfo, nullptr, spUpDownBarLines, spDownBarFills ),
562 TYPEFORMAT_FRAME( OBJECTTYPE_DATATABLE, saCommonPropInfo, spOtherTexts, spDataTableLines, nullptr )
565 #undef TYPEFORMAT_FRAME
566 #undef TYPEFORMAT_LINE
568 void lclConvertPictureOptions( FillProperties& orFillProps, const PictureOptionsModel& rPicOptions )
570 bool bStacked = (rPicOptions.mnPictureFormat == XML_stack) || (rPicOptions.mnPictureFormat == XML_stackScale);
571 orFillProps.maBlipProps.moBitmapMode = bStacked ? XML_tile : XML_stretch;
574 } // namespace
576 struct ObjectFormatterData;
578 namespace {
580 class DetailFormatterBase
582 public:
583 explicit DetailFormatterBase(
584 ObjectFormatterData& rData,
585 const AutoFormatEntry* pAutoFormatEntry );
586 explicit DetailFormatterBase(
587 ObjectFormatterData& rData,
588 const AutoTextEntry* pAutoTextEntry );
590 protected:
591 /** Returns the placeholder color which may depend on the passed series index. */
592 ::Color getPhColor( sal_Int32 nSeriesIdx ) const;
594 private:
595 /** Resolves and returns the scheme color with the passed transformation. */
596 ::Color getSchemeColor( sal_Int32 nColorToken, sal_Int32 nModToken, sal_Int32 nModValue ) const;
598 protected:
599 typedef ::std::vector< ::Color > ColorPatternVec;
601 ObjectFormatterData& mrData; /// Shared formatter data.
602 ::Color mnPhClr; /// RGB placeholder color for themed style.
603 ColorPatternVec maColorPattern; /// Different cycling colors for data series.
606 class LineFormatter : public DetailFormatterBase
608 public:
609 explicit LineFormatter(
610 ObjectFormatterData& rData,
611 const AutoFormatEntry* pAutoFormatEntry,
612 const ObjectType eObjType );
614 /** Converts line formatting to the passed property set. */
615 void convertFormatting(
616 ShapePropertyMap& rPropMap,
617 const ModelRef< Shape >& rxShapeProp,
618 sal_Int32 nSeriesIdx );
620 private:
621 LinePropertiesPtr mxAutoLine; /// Automatic line properties.
624 class FillFormatter : public DetailFormatterBase
626 public:
627 explicit FillFormatter(
628 ObjectFormatterData& rData,
629 const AutoFormatEntry* pAutoFormatEntry,
630 const ObjectType eObjType );
632 /** Converts area formatting to the passed property set. */
633 void convertFormatting(
634 ShapePropertyMap& rPropMap,
635 const ModelRef< Shape >& rxShapeProp,
636 const PictureOptionsModel* pPicOptions,
637 sal_Int32 nSeriesIdx );
639 private:
640 FillPropertiesPtr mxAutoFill; /// Automatic fill properties.
643 class TextFormatter : public DetailFormatterBase
645 public:
646 explicit TextFormatter(
647 ObjectFormatterData& rData,
648 const AutoTextEntry* pAutoTextEntry,
649 const ModelRef< TextBody >& rxGlobalTextProp );
651 /** Converts text formatting to the passed property set. */
652 void convertFormatting(
653 PropertySet& rPropSet,
654 const TextCharacterProperties* pTextProps );
655 /** Converts text formatting to the passed property set. */
656 void convertFormatting(
657 PropertySet& rPropSet,
658 const ModelRef< TextBody >& rxTextProp );
660 private:
661 TextCharacterPropertiesPtr mxAutoText; /// Automatic text properties.
664 /** Formatter for a specific object type. */
665 class ObjectTypeFormatter
667 public:
668 explicit ObjectTypeFormatter(
669 ObjectFormatterData& rData,
670 const ObjectTypeFormatEntry& rEntry,
671 const ChartSpaceModel& rChartSpace,
672 const ObjectType eObjType );
674 /** Sets frame formatting properties to the passed property set. */
675 void convertFrameFormatting(
676 PropertySet& rPropSet,
677 const ModelRef< Shape >& rxShapeProp,
678 const PictureOptionsModel* pPicOptions,
679 sal_Int32 nSeriesIdx );
681 /** Sets text formatting properties to the passed property set. */
682 void convertTextFormatting(
683 PropertySet& rPropSet,
684 const ModelRef< TextBody >& rxTextProp );
686 /** Sets frame/text formatting properties to the passed property set. */
687 void convertFormatting(
688 PropertySet& rPropSet,
689 const ModelRef< Shape >& rxShapeProp,
690 const ModelRef< TextBody >& rxTextProp );
692 /** Sets text formatting properties to the passed property set. */
693 void convertTextFormatting(
694 PropertySet& rPropSet,
695 const TextCharacterProperties& rTextProps );
697 /** Sets automatic fill properties to the passed property set. */
698 void convertAutomaticFill(
699 PropertySet& rPropSet,
700 sal_Int32 nSeriesIdx );
702 private:
703 LineFormatter maLineFormatter; /// Converter for line formatting.
704 FillFormatter maFillFormatter; /// Converter for fill formatting.
705 TextFormatter maTextFormatter; /// Converter for text formatting.
706 ModelObjectHelper& mrModelObjHelper; /// Helper for named drawing formatting.
707 const ObjectTypeFormatEntry& mrEntry; /// Additional settings.
712 struct ObjectFormatterData
714 typedef RefMap< ObjectType, ObjectTypeFormatter > ObjectTypeFormatterMap;
716 const XmlFilterBase& mrFilter; /// Base filter object.
717 ObjectTypeFormatterMap maTypeFormatters; /// Formatters for all types of objects in a chart.
718 ModelObjectHelper maModelObjHelper; /// Helper for named drawing formatting (dashes, gradients, bitmaps).
719 Reference< XNumberFormats > mxNumFmts; /// Number formats collection of container document.
720 Reference< XNumberFormatTypes > mxNumTypes; /// Number format types collection of container document.
721 Locale maEnUsLocale; /// Locale struct containing en-US.
722 Locale maFromLocale; /// Empty locale struct.
723 sal_Int32 mnMaxSeriesIdx; /// Maximum series index used for color cycling/fading.
725 explicit ObjectFormatterData(
726 const XmlFilterBase& rFilter,
727 const Reference< XChartDocument >& rxChartDoc,
728 const ChartSpaceModel& rChartSpace );
730 ObjectTypeFormatter* getTypeFormatter( ObjectType eObjType );
733 DetailFormatterBase::DetailFormatterBase( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry ) :
734 mrData( rData ),
735 mnPhClr( ColorTransparency, 0xffffffff )
737 if( !pAutoFormatEntry )
738 return;
740 if( pAutoFormatEntry->mpPattern )
742 // prepare multi-color pattern
743 for( const AutoFormatPatternEntry* pPatternEntry = pAutoFormatEntry->mpPattern; pPatternEntry->mnColorToken != XML_TOKEN_INVALID; ++pPatternEntry )
744 maColorPattern.push_back( getSchemeColor( pPatternEntry->mnColorToken, pPatternEntry->mnModToken, pPatternEntry->mnModValue ) );
746 else if( pAutoFormatEntry->mnColorToken != XML_TOKEN_INVALID )
748 // prepare color or single-color pattern (color fading)
749 mnPhClr = getSchemeColor( pAutoFormatEntry->mnColorToken, pAutoFormatEntry->mnModToken, pAutoFormatEntry->mnModValue );
750 if( pAutoFormatEntry->mbFadedColor )
751 maColorPattern.push_back( mnPhClr );
755 DetailFormatterBase::DetailFormatterBase( ObjectFormatterData& rData, const AutoTextEntry* pAutoTextEntry ) :
756 mrData( rData ),
757 mnPhClr( ColorTransparency, 0xffffffff )
759 if( pAutoTextEntry && (pAutoTextEntry->mnColorToken != XML_TOKEN_INVALID) )
760 mnPhClr = getSchemeColor( pAutoTextEntry->mnColorToken, XML_TOKEN_INVALID, 0 );
763 ::Color DetailFormatterBase::getPhColor( sal_Int32 nSeriesIdx ) const
765 if( maColorPattern.empty() || (mrData.mnMaxSeriesIdx < 0) || (nSeriesIdx < 0) )
766 return mnPhClr;
768 /* Apply tint/shade depending on the cycle index. The colors of leading
769 series are darkened (color shade), the colors of trailing series are
770 lightened (color tint). Shade/tint is applied in an exclusive range of
771 -70% to 70%.
773 Example 1: 3 data series using single-color shading with accent color 1
774 (e.g. automatic chart style #3). Shade/tint is applied per series.
775 Shade/tint changes in steps of 140%/(<series_count+1) = 140%/4 = 35%,
776 starting at -70%:
777 Step 1: -70% -> Not used.
778 Step 2: -35% -> Series 1 has 35% shade of accent color 1.
779 Step 3: 0% -> Series 2 has pure accent color 1.
780 Step 4: 35% -> Series 3 has 35% tint of accent color 1.
781 Step 5: 70% -> Not used.
783 Example 2: 20 data series using accent color pattern (e.g. automatic
784 chart style #2). Each color cycle has a size of 6 series (accent colors
785 1 to 6). Shade/tint is applied per color cycle.
786 Cycle #1: Series 1...6 are based on accent colors 1 to 6.
787 Cycle #2: Series 7...12 are based on accent colors 1 to 6.
788 Cycle #3: Series 13...18 are based on accent colors 1 to 6.
789 Cycle #4: Series 19...20 are based on accent colors 1 to 2.
790 Shade/tint changes in steps of 140%/(cycle_count+1) = 140%/5 = 28%,
791 starting at -70%:
792 Step 1: -70% -> Not used.
793 Step 2: -42% -> Cycle #1 has 42% shade of accent colors 1...6
794 step 3: -14% -> Cycle #2 has 14% shade of accent colors 1...6
795 step 4: 14% -> Cycle #3 has 14% tint of accent colors 1...6
796 step 5: 42% -> Cycle #4 has 42% tint of accent colors 1...6
797 step 6: 70% -> Not used.
799 ::Color nPhClr = maColorPattern[ static_cast< size_t >( nSeriesIdx % maColorPattern.size() ) ];
800 size_t nCycleIdx = static_cast< size_t >( nSeriesIdx / maColorPattern.size() );
801 size_t nMaxCycleIdx = static_cast< size_t >( mrData.mnMaxSeriesIdx / maColorPattern.size() );
802 double fShadeTint = static_cast< double >( nCycleIdx + 1 ) / (nMaxCycleIdx + 2) * 1.4 - 0.7;
803 if( fShadeTint != 0.0 )
805 Color aColor;
806 aColor.setSrgbClr( nPhClr );
807 aColor.addChartTintTransformation( fShadeTint );
808 nPhClr = aColor.getColor( mrData.mrFilter.getGraphicHelper() );
811 return nPhClr;
814 ::Color DetailFormatterBase::getSchemeColor( sal_Int32 nColorToken, sal_Int32 nModToken, sal_Int32 nModValue ) const
816 Color aColor;
817 aColor.setSchemeClr( nColorToken );
818 if( nModToken != XML_TOKEN_INVALID )
819 aColor.addTransformation( nModToken, nModValue );
820 return aColor.getColor( mrData.mrFilter.getGraphicHelper() );
823 LineFormatter::LineFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry, const ObjectType eObjType ) :
824 DetailFormatterBase(rData, pAutoFormatEntry)
826 if( !pAutoFormatEntry )
827 return;
829 mxAutoLine = std::make_shared<LineProperties>();
830 mxAutoLine->maLineFill.moFillType = XML_noFill;
831 if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
832 if( const LineProperties* pLineProps = pTheme->getLineStyle( pAutoFormatEntry->mnThemedIdx ) )
833 *mxAutoLine = *pLineProps;
834 // set automatic border property for chartarea, because of tdf#81437 and tdf#82217, except for Impress (tdf#150176)
835 if ( eObjType == OBJECTTYPE_CHARTSPACE )
837 OUString aFilterName;
838 rData.mrFilter.getMediaDescriptor()[utl::MediaDescriptor::PROP_FILTERNAME] >>= aFilterName;
839 if (!aFilterName.startsWithIgnoreAsciiCase("Impress"))
841 mxAutoLine->maLineFill.moFillType = oox::GraphicHelper::getDefaultChartAreaLineStyle();
842 mxAutoLine->moLineWidth = oox::GraphicHelper::getDefaultChartAreaLineWidth();
843 // this value is what MSO 2016 use as a default color for chartspace border
844 mxAutoLine->maLineFill.maFillColor.setSrgbClr(0xD9D9D9);
847 // change line width according to chart auto style
848 if( mxAutoLine->moLineWidth.has_value() )
849 mxAutoLine->moLineWidth = mxAutoLine->moLineWidth.value() * pAutoFormatEntry->mnRelLineWidth / 100;
852 void LineFormatter::convertFormatting( ShapePropertyMap& rPropMap, const ModelRef< Shape >& rxShapeProp, sal_Int32 nSeriesIdx )
854 LineProperties aLineProps;
855 if( mxAutoLine )
856 aLineProps.assignUsed( *mxAutoLine );
857 if( rxShapeProp.is() )
858 aLineProps.assignUsed( rxShapeProp->getLineProperties() );
859 aLineProps.pushToPropMap( rPropMap, mrData.mrFilter.getGraphicHelper(), getPhColor( nSeriesIdx ) );
862 FillFormatter::FillFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry, const ObjectType eObjType ) :
863 DetailFormatterBase( rData, pAutoFormatEntry )
865 if( !pAutoFormatEntry )
866 return;
868 mxAutoFill = std::make_shared<FillProperties>();
869 if( eObjType != OBJECTTYPE_CHARTSPACE )
870 mxAutoFill->moFillType = XML_noFill;
871 if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
872 if( const FillProperties* pFillProps = pTheme->getFillStyle( pAutoFormatEntry->mnThemedIdx ) )
873 *mxAutoFill = *pFillProps;
875 if (eObjType == OBJECTTYPE_CHARTSPACE)
877 mxAutoFill->moFillType = rData.mrFilter.getGraphicHelper().getDefaultChartAreaFillStyle();
881 void FillFormatter::convertFormatting( ShapePropertyMap& rPropMap, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, sal_Int32 nSeriesIdx )
883 FillProperties aFillProps;
884 if( mxAutoFill )
885 aFillProps.assignUsed( *mxAutoFill );
886 if (rxShapeProp)
887 aFillProps.assignUsed( rxShapeProp->getFillProperties() );
888 if( pPicOptions )
889 lclConvertPictureOptions( aFillProps, *pPicOptions );
890 aFillProps.pushToPropMap( rPropMap, mrData.mrFilter.getGraphicHelper(), 0, getPhColor( nSeriesIdx ) );
893 namespace {
895 const TextCharacterProperties* lclGetTextProperties( const ModelRef< TextBody >& rxTextProp )
897 return (rxTextProp.is() && !rxTextProp->getParagraphs().empty()) ?
898 &rxTextProp->getParagraphs().front()->getProperties().getTextCharacterProperties() : nullptr;
901 } // namespace
903 TextFormatter::TextFormatter( ObjectFormatterData& rData, const AutoTextEntry* pAutoTextEntry, const ModelRef< TextBody >& rxGlobalTextProp ) :
904 DetailFormatterBase( rData, pAutoTextEntry )
906 if( !pAutoTextEntry )
907 return;
909 mxAutoText = std::make_shared<TextCharacterProperties>();
910 if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
911 if( const TextCharacterProperties* pTextProps = pTheme->getFontStyle( pAutoTextEntry->mnThemedFont ) )
912 *mxAutoText = *pTextProps;
913 ::Color nTextColor = getPhColor( -1 );
914 if( sal_Int32(nTextColor) >= 0 ) {
915 mxAutoText->maFillProperties.maFillColor.setSrgbClr( nTextColor );
916 mxAutoText->maFillProperties.moFillType = XML_solidFill;
918 mxAutoText->moHeight = pAutoTextEntry->mnDefFontSize;
919 mxAutoText->moBold = pAutoTextEntry->mbBold;
921 if( const TextCharacterProperties* pTextProps = lclGetTextProperties( rxGlobalTextProp ) )
923 mxAutoText->assignUsed( *pTextProps );
924 if( pTextProps->moHeight.has_value() )
925 mxAutoText->moHeight = pTextProps->moHeight.value() * pAutoTextEntry->mnRelFontSize / 100;
929 void TextFormatter::convertFormatting( PropertySet& rPropSet, const TextCharacterProperties* pTextProps )
931 TextCharacterProperties aTextProps;
932 if( mxAutoText )
933 aTextProps.assignUsed( *mxAutoText );
934 if( pTextProps )
935 aTextProps.assignUsed( *pTextProps );
936 aTextProps.pushToPropSet( rPropSet, mrData.mrFilter );
939 void TextFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp )
941 convertFormatting( rPropSet, lclGetTextProperties( rxTextProp ) );
944 ObjectTypeFormatter::ObjectTypeFormatter( ObjectFormatterData& rData, const ObjectTypeFormatEntry& rEntry, const ChartSpaceModel& rChartSpace, const ObjectType eObjType ) :
945 maLineFormatter( rData, lclGetAutoFormatEntry( rEntry.mpAutoLines, rChartSpace.mnStyle ), eObjType ),
946 maFillFormatter( rData, lclGetAutoFormatEntry( rEntry.mpAutoFills, rChartSpace.mnStyle ), eObjType ),
947 maTextFormatter( rData, lclGetAutoTextEntry( rEntry.mpAutoTexts, rChartSpace.mnStyle ), rChartSpace.mxTextProp ),
948 mrModelObjHelper( rData.maModelObjHelper ),
949 mrEntry( rEntry )
953 void ObjectTypeFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, sal_Int32 nSeriesIdx )
955 ShapePropertyMap aPropMap( mrModelObjHelper, mrEntry.mrPropInfo );
956 maLineFormatter.convertFormatting( aPropMap, rxShapeProp, nSeriesIdx );
957 if( mrEntry.mbIsFrame )
958 maFillFormatter.convertFormatting( aPropMap, rxShapeProp, pPicOptions, nSeriesIdx );
959 rPropSet.setProperties( aPropMap );
962 void ObjectTypeFormatter::convertTextFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp )
964 maTextFormatter.convertFormatting( rPropSet, rxTextProp );
967 void ObjectTypeFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const ModelRef< TextBody >& rxTextProp )
969 convertFrameFormatting( rPropSet, rxShapeProp, nullptr, -1 );
970 convertTextFormatting( rPropSet, rxTextProp );
973 void ObjectTypeFormatter::convertTextFormatting( PropertySet& rPropSet, const TextCharacterProperties& rTextProps )
975 maTextFormatter.convertFormatting( rPropSet, &rTextProps );
978 void ObjectTypeFormatter::convertAutomaticFill( PropertySet& rPropSet, sal_Int32 nSeriesIdx )
980 ShapePropertyMap aPropMap( mrModelObjHelper, mrEntry.mrPropInfo );
981 ModelRef< Shape > xShapeProp;
982 maFillFormatter.convertFormatting( aPropMap, xShapeProp, nullptr, nSeriesIdx );
983 rPropSet.setProperties( aPropMap );
986 ObjectFormatterData::ObjectFormatterData( const XmlFilterBase& rFilter, const Reference< XChartDocument >& rxChartDoc, const ChartSpaceModel& rChartSpace ) :
987 mrFilter( rFilter ),
988 maModelObjHelper( Reference< XMultiServiceFactory >( rxChartDoc, UNO_QUERY ) ),
989 maEnUsLocale( u"en"_ustr, u"US"_ustr, OUString() ),
990 mnMaxSeriesIdx( -1 )
992 for(auto const &rEntry : spObjTypeFormatEntries)
993 maTypeFormatters[ rEntry.meObjType ] = std::make_shared<ObjectTypeFormatter>( *this, rEntry, rChartSpace, rEntry.meObjType );
997 Reference< XNumberFormatsSupplier > xNumFmtsSupp( rxChartDoc, UNO_QUERY_THROW );
998 mxNumFmts = xNumFmtsSupp->getNumberFormats();
999 mxNumTypes.set( mxNumFmts, UNO_QUERY );
1001 catch( Exception& )
1004 OSL_ENSURE( mxNumFmts.is() && mxNumTypes.is(), "ObjectFormatterData::ObjectFormatterData - cannot get number formats" );
1007 ObjectTypeFormatter* ObjectFormatterData::getTypeFormatter( ObjectType eObjType )
1009 OSL_ENSURE( maTypeFormatters.has( eObjType ), "ObjectFormatterData::getTypeFormatter - unknown object type" );
1010 return maTypeFormatters.get( eObjType ).get();
1013 ObjectFormatter::ObjectFormatter( const XmlFilterBase& rFilter, const Reference< XChartDocument >& rxChartDoc, const ChartSpaceModel& rChartSpace ) :
1014 mxData( std::make_shared<ObjectFormatterData>( rFilter, rxChartDoc, rChartSpace ) )
1018 ObjectFormatter::~ObjectFormatter()
1022 void ObjectFormatter::setMaxSeriesIndex( sal_Int32 nMaxSeriesIdx )
1024 mxData->mnMaxSeriesIdx = nMaxSeriesIdx;
1027 sal_Int32 ObjectFormatter::getMaxSeriesIndex() const
1029 return mxData->mnMaxSeriesIdx;
1032 void ObjectFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, ObjectType eObjType, sal_Int32 nSeriesIdx )
1034 if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1035 pFormat->convertFrameFormatting( rPropSet, rxShapeProp, nullptr, nSeriesIdx );
1038 void ObjectFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel& rPicOptions, ObjectType eObjType, sal_Int32 nSeriesIdx )
1040 if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1041 pFormat->convertFrameFormatting( rPropSet, rxShapeProp, &rPicOptions, nSeriesIdx );
1044 void ObjectFormatter::convertTextFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp, ObjectType eObjType )
1046 if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1047 pFormat->convertTextFormatting( rPropSet, rxTextProp );
1050 void ObjectFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const ModelRef< TextBody >& rxTextProp, ObjectType eObjType )
1052 if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1053 pFormat->convertFormatting( rPropSet, rxShapeProp, rxTextProp );
1056 void ObjectFormatter::convertTextFormatting( PropertySet& rPropSet, const TextCharacterProperties& rTextProps, ObjectType eObjType )
1058 if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1059 pFormat->convertTextFormatting( rPropSet, rTextProps );
1062 void ObjectFormatter::convertTextRotation( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp, bool bSupportsStacked, sal_Int32 nDefaultRotation )
1064 if( !rxTextProp.is() )
1065 return;
1067 bool bStacked = false;
1068 if( bSupportsStacked )
1070 sal_Int32 nVert = rxTextProp->getTextProperties().moVert.value_or( XML_horz );
1071 bStacked = (nVert == XML_wordArtVert) || (nVert == XML_wordArtVertRtl);
1072 rPropSet.setProperty( PROP_StackCharacters, bStacked );
1075 /* Chart2 expects rotation angle as double value in range of [0,360).
1076 OOXML counts clockwise, Chart2 counts counterclockwise. */
1077 double fAngle = static_cast< double >( bStacked ? 0 : rxTextProp->getTextProperties().moTextAreaRotation.value_or( nDefaultRotation ) );
1078 // MS Office UI allows values only in range of [-90,90].
1079 if ( fAngle < -5400000.0 || fAngle > 5400000.0 )
1081 fAngle = 0.0;
1083 fAngle = getDoubleIntervalValue< double >( -fAngle / 60000.0, 0.0, 360.0 );
1084 rPropSet.setProperty( PROP_TextRotation, fAngle );
1087 void ObjectFormatter::convertTextWrap( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp )
1089 if( !rxTextProp.is() )
1091 // set default value (in OOXML the default value is true)
1092 rPropSet.setProperty( PROP_TextWordWrap, true );
1093 return;
1096 PropertyMap& aPropMap = rxTextProp->getTextProperties().maPropertyMap;
1097 if( aPropMap.hasProperty(PROP_TextWordWrap) )
1099 Any aValue = aPropMap.getProperty( PROP_TextWordWrap );
1100 if( aValue.hasValue() )
1102 bool bValue = false;
1103 aValue >>= bValue;
1104 rPropSet.setProperty( PROP_TextWordWrap, bValue );
1109 void ObjectFormatter::convertNumberFormat( PropertySet& rPropSet, const NumberFormat& rNumberFormat, bool bAxis, bool bShowPercent )
1111 if( !mxData->mxNumFmts.is() )
1112 return;
1114 const bool bGeneral = rNumberFormat.maFormatCode.equalsIgnoreAsciiCase("general");
1115 const bool bPercent = !bAxis && bShowPercent && !rNumberFormat.mbSourceLinked;
1116 sal_Int32 nPropId = bPercent ? PROP_PercentageNumberFormat : PROP_NumberFormat;
1117 OUString sFormatCode(rNumberFormat.maFormatCode);
1118 if (bPercent && bGeneral)
1119 sFormatCode = "0%";
1122 sal_Int32 nIndex = bGeneral && !bPercent ?
1123 mxData->mxNumTypes->getStandardIndex( mxData->maFromLocale ) :
1124 mxData->mxNumFmts->addNewConverted( sFormatCode, mxData->maEnUsLocale, mxData->maFromLocale );
1125 if( nIndex >= 0 )
1126 rPropSet.setProperty( nPropId, nIndex );
1128 catch( Exception& )
1130 OSL_FAIL( OStringBuffer( "ObjectFormatter::convertNumberFormat - cannot create number format '" +
1131 OUStringToOString( rNumberFormat.maFormatCode, osl_getThreadTextEncoding() ) + "'" ).getStr() );
1134 // Setting "LinkNumberFormatToSource" does not really work, at least not for axis :-/
1135 if (!bAxis)
1136 rPropSet.setProperty(PROP_LinkNumberFormatToSource, Any(rNumberFormat.mbSourceLinked));
1137 else
1138 rPropSet.setProperty(PROP_LinkNumberFormatToSource, Any(rNumberFormat.maFormatCode.isEmpty()));
1141 void ObjectFormatter::convertAutomaticFill( PropertySet& rPropSet, ObjectType eObjType, sal_Int32 nSeriesIdx )
1143 if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1144 pFormat->convertAutomaticFill( rPropSet, nSeriesIdx );
1147 bool ObjectFormatter::isAutomaticFill( const ModelRef< Shape >& rxShapeProp )
1149 return !rxShapeProp || !rxShapeProp->getFillProperties().moFillType.has_value();
1152 sal_Int32 ObjectFormatter::getNumberFormatKey(const OUString& sNumberFormat)
1154 if (!mxData->mxNumFmts.is() || sNumberFormat.isEmpty())
1155 return -1;
1157 sal_Int32 nIndex = -1;
1160 const bool bGeneral = sNumberFormat.equalsIgnoreAsciiCase("general");
1161 nIndex = bGeneral ? mxData->mxNumTypes->getStandardIndex(mxData->maFromLocale)
1162 : mxData->mxNumFmts->addNewConverted(sNumberFormat, mxData->maEnUsLocale,
1163 mxData->maFromLocale);
1165 catch (Exception&)
1167 DBG_UNHANDLED_EXCEPTION("oox.drawingml");
1170 return nIndex;
1173 } // namespace oox
1175 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */