1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <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
;
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 ),
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
),
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
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 ),
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
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 ),
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!?
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!?
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 ),
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
),
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 ),
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 ),
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 ),
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 ),
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 ),
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 ),
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 ),
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
) )
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 ),
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 ),
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 ),
435 #undef AUTOTEXT_COLOR
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
) )
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
=
475 PROP_BorderTransparency
,
488 PROP_FillTransparenceGradientName
,
492 PROP_FillBitmapSizeX
,
493 PROP_FillBitmapSizeY
,
494 PROP_FillBitmapPositionOffsetX
,
495 PROP_FillBitmapPositionOffsetY
,
496 PROP_FillBitmapRectanglePoint
,
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
,
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
;
576 struct ObjectFormatterData
;
580 class DetailFormatterBase
583 explicit DetailFormatterBase(
584 ObjectFormatterData
& rData
,
585 const AutoFormatEntry
* pAutoFormatEntry
);
586 explicit DetailFormatterBase(
587 ObjectFormatterData
& rData
,
588 const AutoTextEntry
* pAutoTextEntry
);
591 /** Returns the placeholder color which may depend on the passed series index. */
592 ::Color
getPhColor( sal_Int32 nSeriesIdx
) const;
595 /** Resolves and returns the scheme color with the passed transformation. */
596 ::Color
getSchemeColor( sal_Int32 nColorToken
, sal_Int32 nModToken
, sal_Int32 nModValue
) const;
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
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
);
621 LinePropertiesPtr mxAutoLine
; /// Automatic line properties.
624 class FillFormatter
: public DetailFormatterBase
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
);
640 FillPropertiesPtr mxAutoFill
; /// Automatic fill properties.
643 class TextFormatter
: public DetailFormatterBase
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
);
661 TextCharacterPropertiesPtr mxAutoText
; /// Automatic text properties.
664 /** Formatter for a specific object type. */
665 class ObjectTypeFormatter
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
);
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
) :
735 mnPhClr( ColorTransparency
, 0xffffffff )
737 if( !pAutoFormatEntry
)
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
) :
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) )
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
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%,
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%,
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 )
806 aColor
.setSrgbClr( nPhClr
);
807 aColor
.addChartTintTransformation( fShadeTint
);
808 nPhClr
= aColor
.getColor( mrData
.mrFilter
.getGraphicHelper() );
814 ::Color
DetailFormatterBase::getSchemeColor( sal_Int32 nColorToken
, sal_Int32 nModToken
, sal_Int32 nModValue
) const
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
)
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
;
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
)
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
;
885 aFillProps
.assignUsed( *mxAutoFill
);
887 aFillProps
.assignUsed( rxShapeProp
->getFillProperties() );
889 lclConvertPictureOptions( aFillProps
, *pPicOptions
);
890 aFillProps
.pushToPropMap( rPropMap
, mrData
.mrFilter
.getGraphicHelper(), 0, getPhColor( nSeriesIdx
) );
895 const TextCharacterProperties
* lclGetTextProperties( const ModelRef
< TextBody
>& rxTextProp
)
897 return (rxTextProp
.is() && !rxTextProp
->getParagraphs().empty()) ?
898 &rxTextProp
->getParagraphs().front()->getProperties().getTextCharacterProperties() : nullptr;
903 TextFormatter::TextFormatter( ObjectFormatterData
& rData
, const AutoTextEntry
* pAutoTextEntry
, const ModelRef
< TextBody
>& rxGlobalTextProp
) :
904 DetailFormatterBase( rData
, pAutoTextEntry
)
906 if( !pAutoTextEntry
)
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
;
933 aTextProps
.assignUsed( *mxAutoText
);
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
),
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
) :
988 maModelObjHelper( Reference
< XMultiServiceFactory
>( rxChartDoc
, UNO_QUERY
) ),
989 maEnUsLocale( u
"en"_ustr
, u
"US"_ustr
, OUString() ),
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
);
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() )
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 )
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 );
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;
1104 rPropSet
.setProperty( PROP_TextWordWrap
, bValue
);
1109 void ObjectFormatter::convertNumberFormat( PropertySet
& rPropSet
, const NumberFormat
& rNumberFormat
, bool bAxis
, bool bShowPercent
)
1111 if( !mxData
->mxNumFmts
.is() )
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
)
1122 sal_Int32 nIndex
= bGeneral
&& !bPercent
?
1123 mxData
->mxNumTypes
->getStandardIndex( mxData
->maFromLocale
) :
1124 mxData
->mxNumFmts
->addNewConverted( sFormatCode
, mxData
->maEnUsLocale
, mxData
->maFromLocale
);
1126 rPropSet
.setProperty( nPropId
, nIndex
);
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 :-/
1136 rPropSet
.setProperty(PROP_LinkNumberFormatToSource
, Any(rNumberFormat
.mbSourceLinked
));
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())
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
);
1167 DBG_UNHANDLED_EXCEPTION("oox.drawingml");
1175 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */