Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / oox / source / drawingml / chart / objectformatter.cxx
blobed52ccf5c2b134bebe8d9b0ebac021657f44300c
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/lang/XMultiServiceFactory.hpp>
23 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
24 #include <com/sun/star/util/XNumberFormatTypes.hpp>
25 #include <osl/thread.h>
26 #include <osl/diagnose.h>
27 #include <rtl/strbuf.hxx>
28 #include <oox/core/xmlfilterbase.hxx>
29 #include <drawingml/fillproperties.hxx>
30 #include <drawingml/lineproperties.hxx>
31 #include <oox/drawingml/shapepropertymap.hxx>
32 #include <drawingml/textbody.hxx>
33 #include <drawingml/textparagraph.hxx>
34 #include <oox/drawingml/theme.hxx>
35 #include <drawingml/chart/chartspacemodel.hxx>
36 #include <oox/helper/modelobjecthelper.hxx>
37 #include <oox/helper/graphichelper.hxx>
38 #include <oox/token/properties.hxx>
40 namespace oox {
41 namespace drawingml {
42 namespace chart {
44 using namespace ::com::sun::star::chart2;
45 using namespace ::com::sun::star::graphic;
46 using namespace ::com::sun::star::lang;
47 using namespace ::com::sun::star::uno;
48 using namespace ::com::sun::star::util;
50 using ::oox::core::XmlFilterBase;
52 namespace {
54 struct AutoFormatPatternEntry
56 sal_Int32 const mnColorToken; /// Theme color token.
57 sal_Int32 const mnModToken; /// Color modification token.
58 sal_Int32 const mnModValue; /// Color modification value.
61 #define AUTOFORMAT_PATTERN_COLOR( color_token ) \
62 { color_token, XML_TOKEN_INVALID, 0 }
64 #define AUTOFORMAT_PATTERN_COLORMOD( color_token, mod_token, mod_value ) \
65 { color_token, mod_token, mod_value }
67 #define AUTOFORMAT_PATTERN_END() \
68 AUTOFORMAT_PATTERN_COLOR( XML_TOKEN_INVALID )
70 static const AutoFormatPatternEntry spAutoFormatPattern1[] =
72 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 88500 ),
73 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 55000 ),
74 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 78000 ),
75 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 92500 ),
76 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 70000 ),
77 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 30000 ),
78 AUTOFORMAT_PATTERN_END()
81 static const AutoFormatPatternEntry spAutoFormatPattern2[] =
83 AUTOFORMAT_PATTERN_COLOR( XML_accent1 ),
84 AUTOFORMAT_PATTERN_COLOR( XML_accent2 ),
85 AUTOFORMAT_PATTERN_COLOR( XML_accent3 ),
86 AUTOFORMAT_PATTERN_COLOR( XML_accent4 ),
87 AUTOFORMAT_PATTERN_COLOR( XML_accent5 ),
88 AUTOFORMAT_PATTERN_COLOR( XML_accent6 ),
89 AUTOFORMAT_PATTERN_END()
92 static const AutoFormatPatternEntry spAutoFormatPattern3[] =
94 AUTOFORMAT_PATTERN_COLORMOD( XML_accent1, XML_shade, 50000 ),
95 AUTOFORMAT_PATTERN_COLORMOD( XML_accent2, XML_shade, 50000 ),
96 AUTOFORMAT_PATTERN_COLORMOD( XML_accent3, XML_shade, 50000 ),
97 AUTOFORMAT_PATTERN_COLORMOD( XML_accent4, XML_shade, 50000 ),
98 AUTOFORMAT_PATTERN_COLORMOD( XML_accent5, XML_shade, 50000 ),
99 AUTOFORMAT_PATTERN_COLORMOD( XML_accent6, XML_shade, 50000 ),
100 AUTOFORMAT_PATTERN_END()
103 static const AutoFormatPatternEntry spAutoFormatPattern4[] =
105 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 5000 ),
106 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 55000 ),
107 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 78000 ),
108 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 15000 ),
109 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 70000 ),
110 AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 30000 ),
111 AUTOFORMAT_PATTERN_END()
114 #undef AUTOFORMAT_PATTERN_COLOR
115 #undef AUTOFORMAT_PATTERN_COLORMOD
116 #undef AUTOFORMAT_PATTERN_END
118 struct AutoFormatEntry
120 sal_Int32 const mnFirstStyleIdx; /// First chart style index.
121 sal_Int32 const mnLastStyleIdx; /// Last chart style index.
122 sal_Int32 const mnThemedIdx; /// Themed style index.
123 sal_Int32 const mnColorToken; /// Theme color token.
124 sal_Int32 const mnModToken; /// Color modification token.
125 sal_Int32 const mnModValue; /// Color modification value.
126 sal_Int32 const mnRelLineWidth; /// Relative line width (percent).
127 const AutoFormatPatternEntry* mpPattern;/// Color cycling pattern for data series.
128 bool const mbFadedColor; /// True = Faded color for data series.
131 #define AUTOFORMAT_COLOR( first, last, themed_style, color_token ) \
132 { first, last, themed_style, color_token, XML_TOKEN_INVALID, 0, 100, nullptr, false }
134 #define AUTOFORMAT_COLORMOD( first, last, themed_style, color_token, mod_token, mod_value ) \
135 { first, last, themed_style, color_token, mod_token, mod_value, 100, nullptr, false }
137 #define AUTOFORMAT_ACCENTSMOD( first, themed_style, mod_token, mod_value ) \
138 AUTOFORMAT_COLORMOD( first, first, themed_style, XML_accent1, mod_token, mod_value ), \
139 AUTOFORMAT_COLORMOD( first + 1, first + 1, themed_style, XML_accent2, mod_token, mod_value ), \
140 AUTOFORMAT_COLORMOD( first + 2, first + 2, themed_style, XML_accent3, mod_token, mod_value ), \
141 AUTOFORMAT_COLORMOD( first + 3, first + 3, themed_style, XML_accent4, mod_token, mod_value ), \
142 AUTOFORMAT_COLORMOD( first + 4, first + 4, themed_style, XML_accent5, mod_token, mod_value ), \
143 AUTOFORMAT_COLORMOD( first + 5, first + 5, themed_style, XML_accent6, mod_token, mod_value )
145 #define AUTOFORMAT_PATTERN( first, last, themed_style, line_width, pattern ) \
146 { first, last, themed_style, XML_TOKEN_INVALID, XML_TOKEN_INVALID, 0, line_width, pattern, false }
148 #define AUTOFORMAT_FADED( first, last, themed_style, color_token, line_width ) \
149 { first, last, themed_style, color_token, XML_TOKEN_INVALID, 0, line_width, nullptr, true }
151 #define AUTOFORMAT_FADEDACCENTS( first, themed_style, line_width ) \
152 AUTOFORMAT_FADED( first, first, themed_style, XML_accent1, line_width ), \
153 AUTOFORMAT_FADED( first + 1, first + 1, themed_style, XML_accent2, line_width ), \
154 AUTOFORMAT_FADED( first + 2, first + 2, themed_style, XML_accent3, line_width ), \
155 AUTOFORMAT_FADED( first + 3, first + 3, themed_style, XML_accent4, line_width ), \
156 AUTOFORMAT_FADED( first + 4, first + 4, themed_style, XML_accent5, line_width ), \
157 AUTOFORMAT_FADED( first + 5, first + 5, themed_style, XML_accent6, line_width )
159 #define AUTOFORMAT_INVISIBLE( first, last ) \
160 AUTOFORMAT_COLOR( first, last, -1, XML_TOKEN_INVALID )
162 #define AUTOFORMAT_END() \
163 AUTOFORMAT_INVISIBLE( -1, -1 )
165 static const AutoFormatEntry spNoFormats[] =
167 AUTOFORMAT_INVISIBLE( 1, 48 ),
168 AUTOFORMAT_END()
171 static const AutoFormatEntry spChartSpaceFill[] =
173 AUTOFORMAT_COLOR( 1, 32, THEMED_STYLE_SUBTLE, XML_bg1 ),
174 AUTOFORMAT_COLOR( 33, 40, THEMED_STYLE_SUBTLE, XML_lt1 ),
175 AUTOFORMAT_COLOR( 41, 48, THEMED_STYLE_SUBTLE, XML_dk1 ),
176 AUTOFORMAT_END()
179 static const AutoFormatEntry spDataTableLines[] =
181 AUTOFORMAT_COLORMOD( 1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ),
182 AUTOFORMAT_COLORMOD( 33, 40, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ),
183 // 41...48: no line, same as Chart2
184 AUTOFORMAT_END()
187 static const AutoFormatEntry spPlotArea2dFills[] =
189 AUTOFORMAT_COLOR( 1, 32, THEMED_STYLE_SUBTLE, XML_bg1 ),
190 AUTOFORMAT_COLORMOD( 33, 34, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 20000 ),
191 AUTOFORMAT_ACCENTSMOD( 35, THEMED_STYLE_SUBTLE, XML_tint, 20000 ), // tint not documented!?
192 AUTOFORMAT_COLORMOD( 41, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
193 AUTOFORMAT_END()
196 static const AutoFormatEntry spWallFloorLines[] =
198 AUTOFORMAT_COLORMOD( 1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ),
199 AUTOFORMAT_COLORMOD( 33, 40, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ),
200 // 41...48: no line, same as Chart2
201 AUTOFORMAT_END()
204 static const AutoFormatEntry spWallFloorFills[] =
206 AUTOFORMAT_INVISIBLE( 1, 32 ),
207 AUTOFORMAT_COLORMOD( 33, 34, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 20000 ),
208 AUTOFORMAT_ACCENTSMOD( 35, THEMED_STYLE_SUBTLE, XML_tint, 20000 ), // tint not documented!?
209 AUTOFORMAT_COLORMOD( 41, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
210 AUTOFORMAT_END()
213 static const AutoFormatEntry spAxisLines[] =
215 AUTOFORMAT_COLORMOD( 1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ), // tint not documented!?
216 AUTOFORMAT_COLORMOD( 33, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ), // tint not documented!?
217 AUTOFORMAT_END()
220 static const AutoFormatEntry spMajorGridLines[] =
222 AUTOFORMAT_COLORMOD( 1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ), // tint not documented!?
223 AUTOFORMAT_COLORMOD( 33, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ), // tint not documented!?
224 AUTOFORMAT_END()
227 static const AutoFormatEntry spMinorGridLines[] =
229 AUTOFORMAT_COLORMOD( 1, 40, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 50000 ),
230 AUTOFORMAT_COLORMOD( 41, 48, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 90000 ),
231 AUTOFORMAT_END()
234 static const AutoFormatEntry spOtherLines[] =
236 AUTOFORMAT_COLOR( 1, 32, THEMED_STYLE_SUBTLE, XML_tx1 ),
237 AUTOFORMAT_COLOR( 33, 34, THEMED_STYLE_SUBTLE, XML_dk1 ),
238 AUTOFORMAT_COLORMOD( 35, 40, THEMED_STYLE_SUBTLE, XML_dk1, XML_shade, 25000 ),
239 AUTOFORMAT_COLOR( 41, 48, THEMED_STYLE_SUBTLE, XML_lt1 ),
240 AUTOFORMAT_END()
243 static const AutoFormatEntry spLinearSeriesLines[] =
245 AUTOFORMAT_PATTERN( 1, 1, THEMED_STYLE_SUBTLE, 300, spAutoFormatPattern1 ),
246 AUTOFORMAT_PATTERN( 2, 2, THEMED_STYLE_SUBTLE, 300, spAutoFormatPattern2 ),
247 AUTOFORMAT_FADEDACCENTS( 3, THEMED_STYLE_SUBTLE, 300 ),
248 AUTOFORMAT_PATTERN( 9, 9, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
249 AUTOFORMAT_PATTERN( 10, 10, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
250 AUTOFORMAT_FADEDACCENTS( 11, THEMED_STYLE_SUBTLE, 500 ),
251 AUTOFORMAT_PATTERN( 17, 17, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
252 AUTOFORMAT_PATTERN( 18, 18, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
253 AUTOFORMAT_FADEDACCENTS( 19, THEMED_STYLE_SUBTLE, 500 ),
254 AUTOFORMAT_PATTERN( 25, 25, THEMED_STYLE_SUBTLE, 700, spAutoFormatPattern1 ),
255 AUTOFORMAT_PATTERN( 26, 26, THEMED_STYLE_SUBTLE, 700, spAutoFormatPattern2 ),
256 AUTOFORMAT_FADEDACCENTS( 27, THEMED_STYLE_SUBTLE, 700 ),
257 AUTOFORMAT_PATTERN( 33, 33, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
258 AUTOFORMAT_PATTERN( 34, 34, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
259 AUTOFORMAT_FADEDACCENTS( 35, THEMED_STYLE_SUBTLE, 500 ),
260 AUTOFORMAT_PATTERN( 41, 42, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern4 ),
261 AUTOFORMAT_PATTERN( 42, 42, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
262 AUTOFORMAT_FADEDACCENTS( 43, THEMED_STYLE_SUBTLE, 500 ),
263 AUTOFORMAT_END()
266 static const AutoFormatEntry spFilledSeriesLines[] =
268 AUTOFORMAT_INVISIBLE( 1, 8 ),
269 AUTOFORMAT_COLOR( 9, 16, THEMED_STYLE_SUBTLE, XML_lt1 ),
270 AUTOFORMAT_INVISIBLE( 17, 32 ),
271 AUTOFORMAT_COLORMOD( 33, 33, THEMED_STYLE_SUBTLE, XML_dk1, XML_shade, 50000 ),
272 AUTOFORMAT_PATTERN( 34, 34, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern3 ),
273 AUTOFORMAT_ACCENTSMOD( 35, THEMED_STYLE_SUBTLE, XML_shade, 50000 ),
274 AUTOFORMAT_INVISIBLE( 41, 48 ),
275 AUTOFORMAT_END()
278 static const AutoFormatEntry spFilledSeries2dFills[] =
280 AUTOFORMAT_PATTERN( 1, 1, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
281 AUTOFORMAT_PATTERN( 2, 2, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
282 AUTOFORMAT_FADEDACCENTS( 3, THEMED_STYLE_SUBTLE, 100 ),
283 AUTOFORMAT_PATTERN( 9, 9, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
284 AUTOFORMAT_PATTERN( 10, 10, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
285 AUTOFORMAT_FADEDACCENTS( 11, THEMED_STYLE_SUBTLE, 100 ),
286 AUTOFORMAT_PATTERN( 17, 17, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern1 ),
287 AUTOFORMAT_PATTERN( 18, 18, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
288 AUTOFORMAT_FADEDACCENTS( 19, THEMED_STYLE_INTENSE, 100 ),
289 AUTOFORMAT_PATTERN( 25, 25, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern1 ),
290 AUTOFORMAT_PATTERN( 26, 26, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
291 AUTOFORMAT_FADEDACCENTS( 27, THEMED_STYLE_INTENSE, 100 ),
292 AUTOFORMAT_PATTERN( 33, 33, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
293 AUTOFORMAT_PATTERN( 34, 34, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
294 AUTOFORMAT_FADEDACCENTS( 35, THEMED_STYLE_SUBTLE, 100 ),
295 AUTOFORMAT_PATTERN( 41, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern4 ),
296 AUTOFORMAT_PATTERN( 42, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
297 AUTOFORMAT_FADEDACCENTS( 43, THEMED_STYLE_INTENSE, 100 ),
298 AUTOFORMAT_END()
301 static const AutoFormatEntry spFilledSeries3dFills[] =
303 AUTOFORMAT_PATTERN( 1, 1, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
304 AUTOFORMAT_PATTERN( 2, 2, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
305 AUTOFORMAT_FADEDACCENTS( 3, THEMED_STYLE_SUBTLE, 100 ),
306 AUTOFORMAT_PATTERN( 9, 9, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
307 AUTOFORMAT_PATTERN( 10, 10, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
308 AUTOFORMAT_FADEDACCENTS( 11, THEMED_STYLE_SUBTLE, 100 ),
309 AUTOFORMAT_PATTERN( 17, 17, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
310 AUTOFORMAT_PATTERN( 18, 18, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
311 AUTOFORMAT_FADEDACCENTS( 19, THEMED_STYLE_SUBTLE, 100 ),
312 AUTOFORMAT_PATTERN( 25, 25, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
313 AUTOFORMAT_PATTERN( 26, 26, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
314 AUTOFORMAT_FADEDACCENTS( 27, THEMED_STYLE_SUBTLE, 100 ),
315 AUTOFORMAT_PATTERN( 33, 33, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
316 AUTOFORMAT_PATTERN( 34, 34, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
317 AUTOFORMAT_FADEDACCENTS( 35, THEMED_STYLE_SUBTLE, 100 ),
318 AUTOFORMAT_PATTERN( 41, 42, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern4 ),
319 AUTOFORMAT_PATTERN( 42, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
320 AUTOFORMAT_FADEDACCENTS( 43, THEMED_STYLE_SUBTLE, 100 ),
321 AUTOFORMAT_END()
324 static const AutoFormatEntry spUpDownBarLines[] =
326 AUTOFORMAT_COLOR( 1, 16, THEMED_STYLE_SUBTLE, XML_tx1 ),
327 AUTOFORMAT_INVISIBLE( 17, 32 ),
328 AUTOFORMAT_COLOR( 33, 34, THEMED_STYLE_SUBTLE, XML_dk1 ),
329 AUTOFORMAT_ACCENTSMOD( 35, THEMED_STYLE_SUBTLE, XML_shade, 25000 ),
330 AUTOFORMAT_INVISIBLE( 41, 48 ),
331 AUTOFORMAT_END()
334 static const AutoFormatEntry spUpBarFills[] =
336 AUTOFORMAT_COLORMOD( 1, 1, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 25000 ),
337 AUTOFORMAT_COLORMOD( 2, 2, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 5000 ),
338 AUTOFORMAT_ACCENTSMOD( 3, THEMED_STYLE_SUBTLE, XML_tint, 25000 ),
339 AUTOFORMAT_COLORMOD( 9, 9, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 25000 ),
340 AUTOFORMAT_COLORMOD( 10, 10, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 5000 ),
341 AUTOFORMAT_ACCENTSMOD( 11, THEMED_STYLE_SUBTLE, XML_tint, 25000 ),
342 AUTOFORMAT_COLORMOD( 17, 17, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 25000 ),
343 AUTOFORMAT_COLORMOD( 18, 18, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 5000 ),
344 AUTOFORMAT_ACCENTSMOD( 19, THEMED_STYLE_INTENSE, XML_tint, 25000 ),
345 AUTOFORMAT_COLORMOD( 25, 25, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 25000 ),
346 AUTOFORMAT_COLORMOD( 26, 26, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 5000 ),
347 AUTOFORMAT_ACCENTSMOD( 27, THEMED_STYLE_INTENSE, XML_tint, 25000 ),
348 AUTOFORMAT_COLOR( 33, 40, THEMED_STYLE_SUBTLE, XML_lt1 ),
349 AUTOFORMAT_COLORMOD( 41, 41, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 25000 ),
350 AUTOFORMAT_COLOR( 42, 42, THEMED_STYLE_INTENSE, XML_lt1 ),
351 AUTOFORMAT_ACCENTSMOD( 43, THEMED_STYLE_INTENSE, XML_tint, 25000 ),
352 AUTOFORMAT_END()
355 static const AutoFormatEntry spDownBarFills[] =
357 AUTOFORMAT_COLORMOD( 1, 1, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 85000 ),
358 AUTOFORMAT_COLORMOD( 2, 2, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
359 AUTOFORMAT_ACCENTSMOD( 3, THEMED_STYLE_SUBTLE, XML_shade, 25000 ),
360 AUTOFORMAT_COLORMOD( 9, 9, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 85000 ),
361 AUTOFORMAT_COLORMOD( 10, 10, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
362 AUTOFORMAT_ACCENTSMOD( 11, THEMED_STYLE_SUBTLE, XML_shade, 25000 ),
363 AUTOFORMAT_COLORMOD( 17, 17, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 85000 ),
364 AUTOFORMAT_COLORMOD( 18, 18, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 95000 ),
365 AUTOFORMAT_ACCENTSMOD( 19, THEMED_STYLE_INTENSE, XML_shade, 25000 ),
366 AUTOFORMAT_COLORMOD( 25, 25, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 85000 ),
367 AUTOFORMAT_COLORMOD( 26, 26, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 95000 ),
368 AUTOFORMAT_ACCENTSMOD( 27, THEMED_STYLE_INTENSE, XML_shade, 25000 ),
369 AUTOFORMAT_COLORMOD( 33, 33, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 85000 ),
370 AUTOFORMAT_COLORMOD( 34, 34, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
371 AUTOFORMAT_ACCENTSMOD( 35, THEMED_STYLE_SUBTLE, XML_shade, 25000 ),
372 AUTOFORMAT_COLORMOD( 41, 41, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 85000 ),
373 AUTOFORMAT_COLOR( 42, 42, THEMED_STYLE_INTENSE, XML_dk1 ),
374 AUTOFORMAT_ACCENTSMOD( 43, THEMED_STYLE_INTENSE, XML_shade, 25000 ),
375 AUTOFORMAT_END()
378 #undef AUTOFORMAT_COLOR
379 #undef AUTOFORMAT_COLORMOD
380 #undef AUTOFORMAT_ACCENTSMOD
381 #undef AUTOFORMAT_PATTERN
382 #undef AUTOFORMAT_FADED
383 #undef AUTOFORMAT_FADEDACCENTS
384 #undef AUTOFORMAT_INVISIBLE
385 #undef AUTOFORMAT_END
387 const AutoFormatEntry* lclGetAutoFormatEntry( const AutoFormatEntry* pEntries, sal_Int32 nStyle )
389 for( ; pEntries && (pEntries->mnFirstStyleIdx >= 0); ++pEntries )
390 if( (pEntries->mnFirstStyleIdx <= nStyle) && (nStyle <= pEntries->mnLastStyleIdx) )
391 return pEntries;
392 return nullptr;
395 struct AutoTextEntry
397 sal_Int32 const mnFirstStyleIdx; /// First chart style index.
398 sal_Int32 const mnLastStyleIdx; /// Last chart style index.
399 sal_Int32 const mnThemedFont; /// Themed font (minor/major).
400 sal_Int32 const mnColorToken; /// Theme color token.
401 sal_Int32 const mnDefFontSize; /// Default font size (1/100 points).
402 sal_Int32 const mnRelFontSize; /// Font size relative to chart global font (percent).
403 bool const mbBold; /// True = bold font.
406 #define AUTOTEXT_COLOR( first, last, themed_font, color_token, def_font_size, rel_font_size, bold ) \
407 { first, last, themed_font, color_token, def_font_size, rel_font_size, bold }
409 #define AUTOTEXT_END() \
410 AUTOTEXT_COLOR( -1, -1, XML_none, XML_TOKEN_INVALID, 1000, 100, false )
412 static const AutoTextEntry spChartTitleTexts[] =
414 AUTOTEXT_COLOR( 1, 40, XML_minor, XML_tx1, 1800, 120, true ),
415 AUTOTEXT_COLOR( 41, 48, XML_minor, XML_lt1, 1800, 120, true ),
416 AUTOTEXT_END()
419 static const AutoTextEntry spAxisTitleTexts[] =
421 AUTOTEXT_COLOR( 1, 40, XML_minor, XML_tx1, 1000, 100, true ),
422 AUTOTEXT_COLOR( 41, 48, XML_minor, XML_lt1, 1000, 100, true ),
423 AUTOTEXT_END()
426 static const AutoTextEntry spOtherTexts[] =
428 AUTOTEXT_COLOR( 1, 40, XML_minor, XML_tx1, 1000, 100, false ),
429 AUTOTEXT_COLOR( 41, 48, XML_minor, XML_lt1, 1000, 100, false ),
430 AUTOTEXT_END()
433 #undef AUTOTEXT_COLOR
434 #undef AUTOTEXT_END
436 const AutoTextEntry* lclGetAutoTextEntry( const AutoTextEntry* pEntries, sal_Int32 nStyle )
438 for( ; pEntries && (pEntries->mnFirstStyleIdx >= 0); ++pEntries )
439 if( (pEntries->mnFirstStyleIdx <= nStyle) && (nStyle <= pEntries->mnLastStyleIdx) )
440 return pEntries;
441 return nullptr;
444 // These PropIds arrays will be indexed into using a ShapeProperty enum
446 static const ShapePropertyIds spnCommonPropIds =
448 PROP_LineStyle, PROP_LineWidth, PROP_LineColor, PROP_LineTransparence, PROP_LineDashName,
449 PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
450 PROP_FillStyle, PROP_FillColor, PROP_FillTransparence, PROP_INVALID, PROP_FillGradientName,
451 PROP_FillBitmapName, PROP_FillBitmapMode, PROP_FillBitmapSizeX, PROP_FillBitmapSizeY,
452 PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint,
453 PROP_FillHatchName, PROP_FillBackground
456 static const ShapePropertyIds spnLinearPropIds =
458 PROP_LineStyle, PROP_LineWidth, PROP_Color, PROP_Transparency, PROP_LineDashName,
459 PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
460 PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
461 PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
462 PROP_INVALID, PROP_INVALID, PROP_INVALID,
463 PROP_INVALID, PROP_INVALID
466 static const ShapePropertyIds spnFilledPropIds =
468 PROP_BorderStyle,
469 PROP_BorderWidth,
470 PROP_BorderColor,
471 PROP_BorderTransparency,
472 PROP_BorderDashName,
473 PROP_INVALID,
474 PROP_INVALID,
475 PROP_INVALID,
476 PROP_INVALID,
477 PROP_INVALID,
478 PROP_INVALID,
479 PROP_INVALID,
480 PROP_INVALID,
481 PROP_FillStyle,
482 PROP_Color,
483 PROP_Transparency,
484 PROP_FillTransparenceGradientName,
485 PROP_GradientName,
486 PROP_FillBitmapName,
487 PROP_FillBitmapMode,
488 PROP_FillBitmapSizeX,
489 PROP_FillBitmapSizeY,
490 PROP_FillBitmapPositionOffsetX,
491 PROP_FillBitmapPositionOffsetY,
492 PROP_FillBitmapRectanglePoint,
493 PROP_HatchName,
494 PROP_FillBackground
497 /** Property info for common chart objects, to be used in ShapePropertyMap. */
498 static const ShapePropertyInfo saCommonPropInfo( spnCommonPropIds, false, true, true, true, true );
499 /** Property info for linear data series, to be used in ShapePropertyMap. */
500 static const ShapePropertyInfo saLinearPropInfo( spnLinearPropIds, false, true, true, true, true );
501 /** Property info for filled data series, to be used in ShapePropertyMap. */
502 static const ShapePropertyInfo saFilledPropInfo( spnFilledPropIds, false, true, true, true, true );
504 /** Contains information about formatting of a specific chart object type. */
505 struct ObjectTypeFormatEntry
507 ObjectType meObjType; /// Object type for automatic format.
508 const ShapePropertyInfo& mrPropInfo; /// Property info for the ShapePropertyMap class.
509 const AutoFormatEntry* mpAutoLines; /// Automatic line formatting for all chart styles.
510 const AutoFormatEntry* mpAutoFills; /// Automatic fill formatting for all chart styles.
511 const AutoTextEntry* mpAutoTexts; /// Automatic text attributes for all chart styles.
512 bool const mbIsFrame; /// True = object is a frame, false = object is a line.
513 ObjectTypeFormatEntry(ObjectType eObjType, const ShapePropertyInfo& rPropInfo,
514 const AutoFormatEntry* pAutoLines,
515 const AutoFormatEntry* pAutoFills,
516 const AutoTextEntry* pAutoTexts,
517 bool bIsFrame)
518 :meObjType(eObjType), mrPropInfo(rPropInfo), mpAutoLines(pAutoLines)
519 ,mpAutoFills(pAutoFills), mpAutoTexts(pAutoTexts), mbIsFrame(bIsFrame)
520 {} // prevent creation of implicit default ctor which fails in MSVC
523 #define TYPEFORMAT_FRAME( obj_type, prop_type, auto_texts, auto_lines, auto_fills ) \
524 { obj_type, prop_type, auto_lines, auto_fills, auto_texts, true }
526 #define TYPEFORMAT_LINE( obj_type, prop_type, auto_texts, auto_lines ) \
527 { obj_type, prop_type, auto_lines, nullptr, auto_texts, false }
529 static const ObjectTypeFormatEntry spObjTypeFormatEntries[] =
531 // object type property info auto text auto line auto fill
532 TYPEFORMAT_FRAME( OBJECTTYPE_CHARTSPACE, saCommonPropInfo, nullptr, spNoFormats, spChartSpaceFill ),
533 TYPEFORMAT_FRAME( OBJECTTYPE_CHARTTITLE, saCommonPropInfo, spChartTitleTexts, nullptr /* eq to Ch2 */, nullptr /* eq to Ch2 */),
534 TYPEFORMAT_FRAME( OBJECTTYPE_LEGEND, saCommonPropInfo, spOtherTexts, spNoFormats, spNoFormats ),
535 TYPEFORMAT_FRAME( OBJECTTYPE_PLOTAREA2D, saCommonPropInfo, nullptr, nullptr /* eq to Ch2 */, spPlotArea2dFills ),
536 TYPEFORMAT_FRAME( OBJECTTYPE_PLOTAREA3D, saCommonPropInfo, nullptr, nullptr /* eq to Ch2 */, nullptr /* eq to Ch2 */ ),
537 TYPEFORMAT_FRAME( OBJECTTYPE_WALL, saCommonPropInfo, nullptr, spWallFloorLines, spWallFloorFills ),
538 TYPEFORMAT_FRAME( OBJECTTYPE_FLOOR, saCommonPropInfo, nullptr, spWallFloorLines, spWallFloorFills ),
539 TYPEFORMAT_LINE( OBJECTTYPE_AXIS, saCommonPropInfo, spOtherTexts, spAxisLines ),
540 TYPEFORMAT_FRAME( OBJECTTYPE_AXISTITLE, saCommonPropInfo, spAxisTitleTexts, nullptr /* eq to Ch2 */, nullptr /* eq to Ch2 */ ),
541 TYPEFORMAT_FRAME( OBJECTTYPE_AXISUNIT, saCommonPropInfo, spAxisTitleTexts, nullptr /* eq in Ch2 */, nullptr /* eq in Ch2 */ ),
542 TYPEFORMAT_LINE( OBJECTTYPE_MAJORGRIDLINE, saCommonPropInfo, nullptr, spMajorGridLines ),
543 TYPEFORMAT_LINE( OBJECTTYPE_MINORGRIDLINE, saCommonPropInfo, nullptr, spMinorGridLines ),
544 TYPEFORMAT_LINE( OBJECTTYPE_LINEARSERIES2D, saLinearPropInfo, nullptr, spLinearSeriesLines ),
545 TYPEFORMAT_FRAME( OBJECTTYPE_FILLEDSERIES2D, saFilledPropInfo, nullptr, spFilledSeriesLines, spFilledSeries2dFills ),
546 TYPEFORMAT_FRAME( OBJECTTYPE_FILLEDSERIES3D, saFilledPropInfo, nullptr, spFilledSeriesLines, spFilledSeries3dFills ),
547 TYPEFORMAT_FRAME( OBJECTTYPE_DATALABEL, saCommonPropInfo, spOtherTexts, nullptr /* eq to Ch2 */, nullptr /* eq to Ch2 */ ),
548 TYPEFORMAT_LINE( OBJECTTYPE_TRENDLINE, saCommonPropInfo, nullptr, spOtherLines ),
549 TYPEFORMAT_FRAME( OBJECTTYPE_TRENDLINELABEL, saCommonPropInfo, spOtherTexts, nullptr /* eq to Ch2 */, nullptr /* eq to Ch2 */ ),
550 TYPEFORMAT_LINE( OBJECTTYPE_ERRORBAR, saCommonPropInfo, nullptr, spOtherLines ),
551 TYPEFORMAT_LINE( OBJECTTYPE_SERLINE, saCommonPropInfo, nullptr, spOtherLines ),
552 TYPEFORMAT_LINE( OBJECTTYPE_LEADERLINE, saCommonPropInfo, nullptr, spOtherLines ),
553 TYPEFORMAT_LINE( OBJECTTYPE_DROPLINE, saCommonPropInfo, nullptr, spOtherLines ),
554 TYPEFORMAT_LINE( OBJECTTYPE_HILOLINE, saLinearPropInfo, nullptr, spOtherLines ),
555 TYPEFORMAT_FRAME( OBJECTTYPE_UPBAR, saCommonPropInfo, nullptr, spUpDownBarLines, spUpBarFills ),
556 TYPEFORMAT_FRAME( OBJECTTYPE_DOWNBAR, saCommonPropInfo, nullptr, spUpDownBarLines, spDownBarFills ),
557 TYPEFORMAT_LINE( OBJECTTYPE_DATATABLE, saCommonPropInfo, spOtherTexts, spDataTableLines )
560 #undef TYPEFORMAT_FRAME
561 #undef TYPEFORMAT_LINE
563 void lclConvertPictureOptions( FillProperties& orFillProps, const PictureOptionsModel& rPicOptions )
565 bool bStacked = (rPicOptions.mnPictureFormat == XML_stack) || (rPicOptions.mnPictureFormat == XML_stackScale);
566 orFillProps.maBlipProps.moBitmapMode = bStacked ? XML_tile : XML_stretch;
569 } // namespace
571 struct ObjectFormatterData;
573 class DetailFormatterBase
575 public:
576 explicit DetailFormatterBase(
577 ObjectFormatterData& rData,
578 const AutoFormatEntry* pAutoFormatEntry );
579 explicit DetailFormatterBase(
580 ObjectFormatterData& rData,
581 const AutoTextEntry* pAutoTextEntry );
583 protected:
584 /** Returns the placeholder color which may depend on the passed series index. */
585 ::Color getPhColor( sal_Int32 nSeriesIdx ) const;
587 private:
588 /** Resolves and returns the scheme color with the passed transformation. */
589 ::Color getSchemeColor( sal_Int32 nColorToken, sal_Int32 nModToken, sal_Int32 nModValue ) const;
591 protected:
592 typedef ::std::vector< ::Color > ColorPatternVec;
594 ObjectFormatterData& mrData; /// Shared formatter data.
595 ::Color mnPhClr; /// RGB placeholder color for themed style.
596 ColorPatternVec maColorPattern; /// Different cycling colors for data series.
599 class LineFormatter : public DetailFormatterBase
601 public:
602 explicit LineFormatter(
603 ObjectFormatterData& rData,
604 const AutoFormatEntry* pAutoFormatEntry,
605 const ObjectType eObjType );
607 /** Converts line formatting to the passed property set. */
608 void convertFormatting(
609 ShapePropertyMap& rPropMap,
610 const ModelRef< Shape >& rxShapeProp,
611 sal_Int32 nSeriesIdx );
613 private:
614 LinePropertiesPtr mxAutoLine; /// Automatic line properties.
617 class FillFormatter : public DetailFormatterBase
619 public:
620 explicit FillFormatter(
621 ObjectFormatterData& rData,
622 const AutoFormatEntry* pAutoFormatEntry,
623 const ObjectType eObjType );
625 /** Converts area formatting to the passed property set. */
626 void convertFormatting(
627 ShapePropertyMap& rPropMap,
628 const ModelRef< Shape >& rxShapeProp,
629 const PictureOptionsModel* pPicOptions,
630 sal_Int32 nSeriesIdx );
632 private:
633 FillPropertiesPtr mxAutoFill; /// Automatic fill properties.
636 class TextFormatter : public DetailFormatterBase
638 public:
639 explicit TextFormatter(
640 ObjectFormatterData& rData,
641 const AutoTextEntry* pAutoTextEntry,
642 const ModelRef< TextBody >& rxGlobalTextProp );
644 /** Converts text formatting to the passed property set. */
645 void convertFormatting(
646 PropertySet& rPropSet,
647 const TextCharacterProperties* pTextProps );
648 /** Converts text formatting to the passed property set. */
649 void convertFormatting(
650 PropertySet& rPropSet,
651 const ModelRef< TextBody >& rxTextProp );
653 private:
654 TextCharacterPropertiesPtr mxAutoText; /// Automatic text properties.
657 /** Formatter for a specific object type. */
658 class ObjectTypeFormatter
660 public:
661 explicit ObjectTypeFormatter(
662 ObjectFormatterData& rData,
663 const ObjectTypeFormatEntry& rEntry,
664 const ChartSpaceModel& rChartSpace,
665 const ObjectType eObjType );
667 /** Sets frame formatting properties to the passed property set. */
668 void convertFrameFormatting(
669 PropertySet& rPropSet,
670 const ModelRef< Shape >& rxShapeProp,
671 const PictureOptionsModel* pPicOptions,
672 sal_Int32 nSeriesIdx );
674 /** Sets text formatting properties to the passed property set. */
675 void convertTextFormatting(
676 PropertySet& rPropSet,
677 const ModelRef< TextBody >& rxTextProp );
679 /** Sets frame/text formatting properties to the passed property set. */
680 void convertFormatting(
681 PropertySet& rPropSet,
682 const ModelRef< Shape >& rxShapeProp,
683 const ModelRef< TextBody >& rxTextProp );
685 /** Sets text formatting properties to the passed property set. */
686 void convertTextFormatting(
687 PropertySet& rPropSet,
688 const TextCharacterProperties& rTextProps );
690 /** Sets automatic fill properties to the passed property set. */
691 void convertAutomaticFill(
692 PropertySet& rPropSet,
693 sal_Int32 nSeriesIdx );
695 private:
696 LineFormatter maLineFormatter; /// Converter for line formatting.
697 FillFormatter maFillFormatter; /// Converter for fill formatting.
698 TextFormatter maTextFormatter; /// Converter for text formatting.
699 ModelObjectHelper& mrModelObjHelper; /// Helper for named drawing formatting.
700 const ObjectTypeFormatEntry& mrEntry; /// Additional settings.
703 struct ObjectFormatterData
705 typedef RefMap< ObjectType, ObjectTypeFormatter > ObjectTypeFormatterMap;
707 const XmlFilterBase& mrFilter; /// Base filter object.
708 ObjectTypeFormatterMap maTypeFormatters; /// Formatters for all types of objects in a chart.
709 ModelObjectHelper maModelObjHelper; /// Helper for named drawing formatting (dashes, gradients, bitmaps).
710 Reference< XNumberFormats > mxNumFmts; /// Number formats collection of container document.
711 Reference< XNumberFormatTypes > mxNumTypes; /// Number format types collection of container document.
712 Locale const maEnUsLocale; /// Locale struct containing en-US.
713 Locale const maFromLocale; /// Empty locale struct.
714 sal_Int32 mnMaxSeriesIdx; /// Maximum series index used for color cycling/fading.
716 explicit ObjectFormatterData(
717 const XmlFilterBase& rFilter,
718 const Reference< XChartDocument >& rxChartDoc,
719 const ChartSpaceModel& rChartSpace );
721 ObjectTypeFormatter* getTypeFormatter( ObjectType eObjType );
724 DetailFormatterBase::DetailFormatterBase( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry ) :
725 mrData( rData ),
726 mnPhClr( 0xffffffff )
728 if( pAutoFormatEntry )
730 if( pAutoFormatEntry->mpPattern )
732 // prepare multi-color pattern
733 for( const AutoFormatPatternEntry* pPatternEntry = pAutoFormatEntry->mpPattern; pPatternEntry->mnColorToken != XML_TOKEN_INVALID; ++pPatternEntry )
734 maColorPattern.push_back( getSchemeColor( pPatternEntry->mnColorToken, pPatternEntry->mnModToken, pPatternEntry->mnModValue ) );
736 else if( pAutoFormatEntry->mnColorToken != XML_TOKEN_INVALID )
738 // prepare color or single-color pattern (color fading)
739 mnPhClr = getSchemeColor( pAutoFormatEntry->mnColorToken, pAutoFormatEntry->mnModToken, pAutoFormatEntry->mnModValue );
740 if( pAutoFormatEntry->mbFadedColor )
741 maColorPattern.push_back( mnPhClr );
746 DetailFormatterBase::DetailFormatterBase( ObjectFormatterData& rData, const AutoTextEntry* pAutoTextEntry ) :
747 mrData( rData ),
748 mnPhClr( 0xffffffff )
750 if( pAutoTextEntry && (pAutoTextEntry->mnColorToken != XML_TOKEN_INVALID) )
751 mnPhClr = getSchemeColor( pAutoTextEntry->mnColorToken, XML_TOKEN_INVALID, 0 );
754 ::Color DetailFormatterBase::getPhColor( sal_Int32 nSeriesIdx ) const
756 if( maColorPattern.empty() || (mrData.mnMaxSeriesIdx < 0) || (nSeriesIdx < 0) )
757 return mnPhClr;
759 /* Apply tint/shade depending on the cycle index. The colors of leading
760 series are darkened (color shade), the colors of trailing series are
761 lightened (color tint). Shade/tint is applied in an exclusive range of
762 -70% to 70%.
764 Example 1: 3 data series using single-color shading with accent color 1
765 (e.g. automatic chart style #3). Shade/tint is applied per series.
766 Shade/tint changes in steps of 140%/(<series_count+1) = 140%/4 = 35%,
767 starting at -70%:
768 Step 1: -70% -> Not used.
769 Step 2: -35% -> Series 1 has 35% shade of accent color 1.
770 Step 3: 0% -> Series 2 has pure accent color 1.
771 Step 4: 35% -> Series 3 has 35% tint of accent color 1.
772 Step 5: 70% -> Not used.
774 Example 2: 20 data series using accent color pattern (e.g. automatic
775 chart style #2). Each color cycle has a size of 6 series (accent colors
776 1 to 6). Shade/tint is applied per color cycle.
777 Cycle #1: Series 1...6 are based on accent colors 1 to 6.
778 Cycle #2: Series 7...12 are based on accent colors 1 to 6.
779 Cycle #3: Series 13...18 are based on accent colors 1 to 6.
780 Cycle #4: Series 19...20 are based on accent colors 1 to 2.
781 Shade/tint changes in steps of 140%/(cycle_count+1) = 140%/5 = 28%,
782 starting at -70%:
783 Step 1: -70% -> Not used.
784 Step 2: -42% -> Cycle #1 has 42% shade of accent colors 1...6
785 step 3: -14% -> Cycle #2 has 14% shade of accent colors 1...6
786 step 4: 14% -> Cycle #3 has 14% tint of accent colors 1...6
787 step 5: 42% -> Cycle #4 has 42% tint of accent colors 1...6
788 step 6: 70% -> Not used.
790 ::Color nPhClr = maColorPattern[ static_cast< size_t >( nSeriesIdx % maColorPattern.size() ) ];
791 size_t nCycleIdx = static_cast< size_t >( nSeriesIdx / maColorPattern.size() );
792 size_t nMaxCycleIdx = static_cast< size_t >( mrData.mnMaxSeriesIdx / maColorPattern.size() );
793 double fShadeTint = static_cast< double >( nCycleIdx + 1 ) / (nMaxCycleIdx + 2) * 1.4 - 0.7;
794 if( fShadeTint != 0.0 )
796 Color aColor;
797 aColor.setSrgbClr( nPhClr );
798 aColor.addChartTintTransformation( fShadeTint );
799 nPhClr = aColor.getColor( mrData.mrFilter.getGraphicHelper() );
802 return nPhClr;
805 ::Color DetailFormatterBase::getSchemeColor( sal_Int32 nColorToken, sal_Int32 nModToken, sal_Int32 nModValue ) const
807 Color aColor;
808 aColor.setSchemeClr( nColorToken );
809 if( nModToken != XML_TOKEN_INVALID )
810 aColor.addTransformation( nModToken, nModValue );
811 return aColor.getColor( mrData.mrFilter.getGraphicHelper() );
814 LineFormatter::LineFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry, const ObjectType eObjType ) :
815 DetailFormatterBase(rData, pAutoFormatEntry)
817 if( pAutoFormatEntry )
819 mxAutoLine.reset( new LineProperties );
820 mxAutoLine->maLineFill.moFillType = XML_noFill;
821 if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
822 if( const LineProperties* pLineProps = pTheme->getLineStyle( pAutoFormatEntry->mnThemedIdx ) )
823 *mxAutoLine = *pLineProps;
824 // set automatic border property for chartarea, because of tdf#81437 and tdf#82217
825 if ( eObjType == OBJECTTYPE_CHARTSPACE )
827 mxAutoLine->maLineFill.moFillType = oox::GraphicHelper::getDefaultChartAreaLineStyle();
828 mxAutoLine->moLineWidth = oox::GraphicHelper::getDefaultChartAreaLineWidth();
829 // this value is what MSO 2016 use as a default color for chartspace border
830 mxAutoLine->maLineFill.maFillColor.setSrgbClr( 0xD9D9D9 );
832 // change line width according to chart auto style
833 if( mxAutoLine->moLineWidth.has() )
834 mxAutoLine->moLineWidth = mxAutoLine->moLineWidth.get() * pAutoFormatEntry->mnRelLineWidth / 100;
838 void LineFormatter::convertFormatting( ShapePropertyMap& rPropMap, const ModelRef< Shape >& rxShapeProp, sal_Int32 nSeriesIdx )
840 LineProperties aLineProps;
841 if( mxAutoLine.get() )
842 aLineProps.assignUsed( *mxAutoLine );
843 if( rxShapeProp.is() )
844 aLineProps.assignUsed( rxShapeProp->getLineProperties() );
845 aLineProps.pushToPropMap( rPropMap, mrData.mrFilter.getGraphicHelper(), getPhColor( nSeriesIdx ) );
848 FillFormatter::FillFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry, const ObjectType eObjType ) :
849 DetailFormatterBase( rData, pAutoFormatEntry )
851 if( pAutoFormatEntry )
853 mxAutoFill.reset( new FillProperties );
854 if( eObjType != OBJECTTYPE_CHARTSPACE )
855 mxAutoFill->moFillType = XML_noFill;
856 if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
857 if( const FillProperties* pFillProps = pTheme->getFillStyle( pAutoFormatEntry->mnThemedIdx ) )
858 *mxAutoFill = *pFillProps;
860 if (eObjType == OBJECTTYPE_CHARTSPACE)
862 mxAutoFill->moFillType = rData.mrFilter.getGraphicHelper().getDefaultChartAreaFillStyle();
867 void FillFormatter::convertFormatting( ShapePropertyMap& rPropMap, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, sal_Int32 nSeriesIdx )
869 FillProperties aFillProps;
870 if( mxAutoFill.get() )
871 aFillProps.assignUsed( *mxAutoFill );
872 if( rxShapeProp.is() )
873 aFillProps.assignUsed( rxShapeProp->getFillProperties() );
874 if( pPicOptions )
875 lclConvertPictureOptions( aFillProps, *pPicOptions );
876 aFillProps.pushToPropMap( rPropMap, mrData.mrFilter.getGraphicHelper(), 0, getPhColor( nSeriesIdx ) );
879 namespace {
881 const TextCharacterProperties* lclGetTextProperties( const ModelRef< TextBody >& rxTextProp )
883 return (rxTextProp.is() && !rxTextProp->getParagraphs().empty()) ?
884 &rxTextProp->getParagraphs().front()->getProperties().getTextCharacterProperties() : nullptr;
887 } // namespace
889 TextFormatter::TextFormatter( ObjectFormatterData& rData, const AutoTextEntry* pAutoTextEntry, const ModelRef< TextBody >& rxGlobalTextProp ) :
890 DetailFormatterBase( rData, pAutoTextEntry )
892 if( pAutoTextEntry )
894 mxAutoText.reset( new TextCharacterProperties );
895 if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
896 if( const TextCharacterProperties* pTextProps = pTheme->getFontStyle( pAutoTextEntry->mnThemedFont ) )
897 *mxAutoText = *pTextProps;
898 ::Color nTextColor = getPhColor( -1 );
899 if( sal_Int32(nTextColor) >= 0 ) {
900 mxAutoText->maFillProperties.maFillColor.setSrgbClr( nTextColor );
901 mxAutoText->maFillProperties.moFillType.set(XML_solidFill);
903 mxAutoText->moHeight = pAutoTextEntry->mnDefFontSize;
904 mxAutoText->moBold = pAutoTextEntry->mbBold;
906 if( const TextCharacterProperties* pTextProps = lclGetTextProperties( rxGlobalTextProp ) )
908 mxAutoText->assignUsed( *pTextProps );
909 if( pTextProps->moHeight.has() )
910 mxAutoText->moHeight = pTextProps->moHeight.get() * pAutoTextEntry->mnRelFontSize / 100;
915 void TextFormatter::convertFormatting( PropertySet& rPropSet, const TextCharacterProperties* pTextProps )
917 TextCharacterProperties aTextProps;
918 if( mxAutoText.get() )
919 aTextProps.assignUsed( *mxAutoText );
920 if( pTextProps )
921 aTextProps.assignUsed( *pTextProps );
922 aTextProps.pushToPropSet( rPropSet, mrData.mrFilter );
925 void TextFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp )
927 convertFormatting( rPropSet, lclGetTextProperties( rxTextProp ) );
930 ObjectTypeFormatter::ObjectTypeFormatter( ObjectFormatterData& rData, const ObjectTypeFormatEntry& rEntry, const ChartSpaceModel& rChartSpace, const ObjectType eObjType ) :
931 maLineFormatter( rData, lclGetAutoFormatEntry( rEntry.mpAutoLines, rChartSpace.mnStyle ), eObjType ),
932 maFillFormatter( rData, lclGetAutoFormatEntry( rEntry.mpAutoFills, rChartSpace.mnStyle ), eObjType ),
933 maTextFormatter( rData, lclGetAutoTextEntry( rEntry.mpAutoTexts, rChartSpace.mnStyle ), rChartSpace.mxTextProp ),
934 mrModelObjHelper( rData.maModelObjHelper ),
935 mrEntry( rEntry )
939 void ObjectTypeFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, sal_Int32 nSeriesIdx )
941 ShapePropertyMap aPropMap( mrModelObjHelper, mrEntry.mrPropInfo );
942 maLineFormatter.convertFormatting( aPropMap, rxShapeProp, nSeriesIdx );
943 if( mrEntry.mbIsFrame )
944 maFillFormatter.convertFormatting( aPropMap, rxShapeProp, pPicOptions, nSeriesIdx );
945 rPropSet.setProperties( aPropMap );
948 void ObjectTypeFormatter::convertTextFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp )
950 maTextFormatter.convertFormatting( rPropSet, rxTextProp );
953 void ObjectTypeFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const ModelRef< TextBody >& rxTextProp )
955 convertFrameFormatting( rPropSet, rxShapeProp, nullptr, -1 );
956 convertTextFormatting( rPropSet, rxTextProp );
959 void ObjectTypeFormatter::convertTextFormatting( PropertySet& rPropSet, const TextCharacterProperties& rTextProps )
961 maTextFormatter.convertFormatting( rPropSet, &rTextProps );
964 void ObjectTypeFormatter::convertAutomaticFill( PropertySet& rPropSet, sal_Int32 nSeriesIdx )
966 ShapePropertyMap aPropMap( mrModelObjHelper, mrEntry.mrPropInfo );
967 ModelRef< Shape > xShapeProp;
968 maFillFormatter.convertFormatting( aPropMap, xShapeProp, nullptr, nSeriesIdx );
969 rPropSet.setProperties( aPropMap );
972 ObjectFormatterData::ObjectFormatterData( const XmlFilterBase& rFilter, const Reference< XChartDocument >& rxChartDoc, const ChartSpaceModel& rChartSpace ) :
973 mrFilter( rFilter ),
974 maModelObjHelper( Reference< XMultiServiceFactory >( rxChartDoc, UNO_QUERY ) ),
975 maEnUsLocale( "en", "US", OUString() ),
976 mnMaxSeriesIdx( -1 )
978 for(auto const &rEntry : spObjTypeFormatEntries)
979 maTypeFormatters[ rEntry.meObjType ].reset( new ObjectTypeFormatter( *this, rEntry, rChartSpace, rEntry.meObjType ) );
983 Reference< XNumberFormatsSupplier > xNumFmtsSupp( rxChartDoc, UNO_QUERY_THROW );
984 mxNumFmts = xNumFmtsSupp->getNumberFormats();
985 mxNumTypes.set( mxNumFmts, UNO_QUERY );
987 catch( Exception& )
990 OSL_ENSURE( mxNumFmts.is() && mxNumTypes.is(), "ObjectFormatterData::ObjectFormatterData - cannot get number formats" );
993 ObjectTypeFormatter* ObjectFormatterData::getTypeFormatter( ObjectType eObjType )
995 OSL_ENSURE( maTypeFormatters.has( eObjType ), "ObjectFormatterData::getTypeFormatter - unknown object type" );
996 return maTypeFormatters.get( eObjType ).get();
999 ObjectFormatter::ObjectFormatter( const XmlFilterBase& rFilter, const Reference< XChartDocument >& rxChartDoc, const ChartSpaceModel& rChartSpace ) :
1000 mxData( new ObjectFormatterData( rFilter, rxChartDoc, rChartSpace ) )
1004 ObjectFormatter::~ObjectFormatter()
1008 void ObjectFormatter::setMaxSeriesIndex( sal_Int32 nMaxSeriesIdx )
1010 mxData->mnMaxSeriesIdx = nMaxSeriesIdx;
1013 sal_Int32 ObjectFormatter::getMaxSeriesIndex() const
1015 return mxData->mnMaxSeriesIdx;
1018 void ObjectFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, ObjectType eObjType, sal_Int32 nSeriesIdx )
1020 if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1021 pFormat->convertFrameFormatting( rPropSet, rxShapeProp, nullptr, nSeriesIdx );
1024 void ObjectFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel& rPicOptions, ObjectType eObjType, sal_Int32 nSeriesIdx )
1026 if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1027 pFormat->convertFrameFormatting( rPropSet, rxShapeProp, &rPicOptions, nSeriesIdx );
1030 void ObjectFormatter::convertTextFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp, ObjectType eObjType )
1032 if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1033 pFormat->convertTextFormatting( rPropSet, rxTextProp );
1036 void ObjectFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const ModelRef< TextBody >& rxTextProp, ObjectType eObjType )
1038 if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1039 pFormat->convertFormatting( rPropSet, rxShapeProp, rxTextProp );
1042 void ObjectFormatter::convertTextFormatting( PropertySet& rPropSet, const TextCharacterProperties& rTextProps, ObjectType eObjType )
1044 if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1045 pFormat->convertTextFormatting( rPropSet, rTextProps );
1048 void ObjectFormatter::convertTextRotation( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp, bool bSupportsStacked, sal_Int32 nDefaultRotation )
1050 if( rxTextProp.is() )
1052 bool bStacked = false;
1053 if( bSupportsStacked )
1055 sal_Int32 nVert = rxTextProp->getTextProperties().moVert.get( XML_horz );
1056 bStacked = (nVert == XML_wordArtVert) || (nVert == XML_wordArtVertRtl);
1057 rPropSet.setProperty( PROP_StackCharacters, bStacked );
1060 /* Chart2 expects rotation angle as double value in range of [0,360).
1061 OOXML counts clockwise, Chart2 counts counterclockwise. */
1062 double fAngle = static_cast< double >( bStacked ? 0 : rxTextProp->getTextProperties().moRotation.get( nDefaultRotation ) );
1063 // MS Office UI allows values only in range of [-90,90].
1064 if ( fAngle < -5400000.0 || fAngle > 5400000.0 )
1066 fAngle = 0.0;
1068 fAngle = getDoubleIntervalValue< double >( -fAngle / 60000.0, 0.0, 360.0 );
1069 rPropSet.setProperty( PROP_TextRotation, fAngle );
1073 void ObjectFormatter::convertTextWrap( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp )
1075 if( rxTextProp.is() )
1077 PropertyMap& aPropMap = rxTextProp->getTextProperties().maPropertyMap;
1078 if( aPropMap.hasProperty(PROP_TextWordWrap) )
1080 Any aValue = aPropMap.getProperty( PROP_TextWordWrap );
1081 if( aValue.hasValue() )
1083 bool bValue = false;
1084 aValue >>= bValue;
1085 rPropSet.setProperty( PROP_TextWordWrap, bValue );
1091 void ObjectFormatter::convertNumberFormat( PropertySet& rPropSet, const NumberFormat& rNumberFormat, bool bAxis, bool bShowPercent )
1093 if( mxData->mxNumFmts.is() )
1095 const bool bGeneral = rNumberFormat.maFormatCode.equalsIgnoreAsciiCase("general");
1096 const bool bPercent = !bAxis && bShowPercent && !rNumberFormat.mbSourceLinked;
1097 sal_Int32 nPropId = bPercent ? PROP_PercentageNumberFormat : PROP_NumberFormat;
1098 OUString sFormatCode(rNumberFormat.maFormatCode);
1099 if (bPercent && bGeneral)
1100 sFormatCode = "0%";
1103 sal_Int32 nIndex = bGeneral && !bPercent ?
1104 mxData->mxNumTypes->getStandardIndex( mxData->maFromLocale ) :
1105 mxData->mxNumFmts->addNewConverted( sFormatCode, mxData->maEnUsLocale, mxData->maFromLocale );
1106 if( nIndex >= 0 )
1107 rPropSet.setProperty( nPropId, nIndex );
1109 catch( Exception& )
1111 OSL_FAIL( OStringBuffer( "ObjectFormatter::convertNumberFormat - cannot create number format '" ).
1112 append( OUStringToOString( rNumberFormat.maFormatCode, osl_getThreadTextEncoding() ) ).append( '\'' ).getStr() );
1115 // Setting "LinkNumberFormatToSource" does not really work, at least not for axis :-/
1116 if (!bAxis)
1117 rPropSet.setProperty(PROP_LinkNumberFormatToSource, makeAny(rNumberFormat.mbSourceLinked));
1118 else
1119 rPropSet.setProperty(PROP_LinkNumberFormatToSource, makeAny(rNumberFormat.maFormatCode.isEmpty()));
1123 void ObjectFormatter::convertAutomaticFill( PropertySet& rPropSet, ObjectType eObjType, sal_Int32 nSeriesIdx )
1125 if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1126 pFormat->convertAutomaticFill( rPropSet, nSeriesIdx );
1129 bool ObjectFormatter::isAutomaticFill( const ModelRef< Shape >& rxShapeProp )
1131 return !rxShapeProp || !rxShapeProp->getFillProperties().moFillType.has();
1134 bool ObjectFormatter::getTextRotation( const ModelRef< TextBody >& rxTextProp, sal_Int32 nDefaultRotation )
1136 if( rxTextProp.is() )
1138 double fAnglevalue = static_cast< double >( rxTextProp->getTextProperties().moRotation.get( nDefaultRotation ) );
1139 if( fAnglevalue < -5400000.0 || fAnglevalue > 5400000.0 || fAnglevalue == 0.0 )
1141 return true;
1143 else
1145 return false;
1148 else
1150 return false;
1154 } // namespace chart
1155 } // namespace drawingml
1156 } // namespace oox
1158 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */