LibreOffice Module oox (master)  1
objectformatter.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
21 
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 <osl/thread.h>
27 #include <osl/diagnose.h>
28 #include <rtl/strbuf.hxx>
33 #include <drawingml/textbody.hxx>
35 #include <oox/drawingml/theme.hxx>
39 #include <oox/token/properties.hxx>
40 #include <oox/token/tokens.hxx>
41 
42 namespace oox::drawingml::chart {
43 
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;
49 
50 using ::oox::core::XmlFilterBase;
51 
52 namespace {
53 
54 struct AutoFormatPatternEntry
55 {
56  sal_Int32 mnColorToken;
57  sal_Int32 mnModToken;
58  sal_Int32 mnModValue;
59 };
60 
61 #define AUTOFORMAT_PATTERN_COLOR( color_token ) \
62  { color_token, XML_TOKEN_INVALID, 0 }
63 
64 #define AUTOFORMAT_PATTERN_COLORMOD( color_token, mod_token, mod_value ) \
65  { color_token, mod_token, mod_value }
66 
67 #define AUTOFORMAT_PATTERN_END() \
68  AUTOFORMAT_PATTERN_COLOR( XML_TOKEN_INVALID )
69 
70 const AutoFormatPatternEntry spAutoFormatPattern1[] =
71 {
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 ),
79 };
80 
81 const AutoFormatPatternEntry spAutoFormatPattern2[] =
82 {
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 ),
90 };
91 
92 const AutoFormatPatternEntry spAutoFormatPattern3[] =
93 {
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 ),
101 };
102 
103 const AutoFormatPatternEntry spAutoFormatPattern4[] =
104 {
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 ),
112 };
113 
114 #undef AUTOFORMAT_PATTERN_COLOR
115 #undef AUTOFORMAT_PATTERN_COLORMOD
116 #undef AUTOFORMAT_PATTERN_END
117 
118 struct AutoFormatEntry
119 {
120  sal_Int32 mnFirstStyleIdx;
121  sal_Int32 mnLastStyleIdx;
122  sal_Int32 mnThemedIdx;
123  sal_Int32 mnColorToken;
124  sal_Int32 mnModToken;
125  sal_Int32 mnModValue;
126  sal_Int32 mnRelLineWidth;
127  const AutoFormatPatternEntry* mpPattern;
129 };
130 
131 #define AUTOFORMAT_COLOR( first, last, themed_style, color_token ) \
132  { first, last, themed_style, color_token, XML_TOKEN_INVALID, 0, 100, nullptr, false }
133 
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 }
136 
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 )
144 
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 }
147 
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 }
150 
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 )
158 
159 #define AUTOFORMAT_INVISIBLE( first, last ) \
160  AUTOFORMAT_COLOR( first, last, -1, XML_TOKEN_INVALID )
161 
162 #define AUTOFORMAT_END() \
163  AUTOFORMAT_INVISIBLE( -1, -1 )
164 
165 const AutoFormatEntry spNoFormats[] =
166 {
167  AUTOFORMAT_INVISIBLE( 1, 48 ),
169 };
170 
171 const AutoFormatEntry spChartSpaceFill[] =
172 {
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 ),
177 };
178 
179 const AutoFormatEntry spDataTableLines[] =
180 {
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
185 };
186 
187 const AutoFormatEntry spPlotArea2dFills[] =
188 {
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 ),
194 };
195 
196 const AutoFormatEntry spWallFloorLines[] =
197 {
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
202 };
203 
204 const AutoFormatEntry spWallFloorFills[] =
205 {
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 ),
211 };
212 
213 const AutoFormatEntry spAxisLines[] =
214 {
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!?
218 };
219 
220 const AutoFormatEntry spMajorGridLines[] =
221 {
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!?
225 };
226 
227 const AutoFormatEntry spMinorGridLines[] =
228 {
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 ),
232 };
233 
234 const AutoFormatEntry spOtherLines[] =
235 {
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 ),
241 };
242 
243 const AutoFormatEntry spLinearSeriesLines[] =
244 {
245  AUTOFORMAT_PATTERN( 1, 1, THEMED_STYLE_SUBTLE, 300, spAutoFormatPattern1 ),
246  AUTOFORMAT_PATTERN( 2, 2, THEMED_STYLE_SUBTLE, 300, spAutoFormatPattern2 ),
248  AUTOFORMAT_PATTERN( 9, 9, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
249  AUTOFORMAT_PATTERN( 10, 10, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
251  AUTOFORMAT_PATTERN( 17, 17, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
252  AUTOFORMAT_PATTERN( 18, 18, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
254  AUTOFORMAT_PATTERN( 25, 25, THEMED_STYLE_SUBTLE, 700, spAutoFormatPattern1 ),
255  AUTOFORMAT_PATTERN( 26, 26, THEMED_STYLE_SUBTLE, 700, spAutoFormatPattern2 ),
257  AUTOFORMAT_PATTERN( 33, 33, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
258  AUTOFORMAT_PATTERN( 34, 34, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
260  AUTOFORMAT_PATTERN( 41, 42, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern4 ),
261  AUTOFORMAT_PATTERN( 42, 42, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
264 };
265 
266 const AutoFormatEntry spFilledSeriesLines[] =
267 {
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 ),
276 };
277 
278 const AutoFormatEntry spFilledSeries2dFills[] =
279 {
280  AUTOFORMAT_PATTERN( 1, 1, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
281  AUTOFORMAT_PATTERN( 2, 2, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
283  AUTOFORMAT_PATTERN( 9, 9, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
284  AUTOFORMAT_PATTERN( 10, 10, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
286  AUTOFORMAT_PATTERN( 17, 17, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern1 ),
287  AUTOFORMAT_PATTERN( 18, 18, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
289  AUTOFORMAT_PATTERN( 25, 25, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern1 ),
290  AUTOFORMAT_PATTERN( 26, 26, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
292  AUTOFORMAT_PATTERN( 33, 33, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
293  AUTOFORMAT_PATTERN( 34, 34, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
295  AUTOFORMAT_PATTERN( 41, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern4 ),
296  AUTOFORMAT_PATTERN( 42, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
299 };
300 
301 const AutoFormatEntry spFilledSeries3dFills[] =
302 {
303  AUTOFORMAT_PATTERN( 1, 1, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
304  AUTOFORMAT_PATTERN( 2, 2, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
306  AUTOFORMAT_PATTERN( 9, 9, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
307  AUTOFORMAT_PATTERN( 10, 10, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
309  AUTOFORMAT_PATTERN( 17, 17, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
310  AUTOFORMAT_PATTERN( 18, 18, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
312  AUTOFORMAT_PATTERN( 25, 25, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
313  AUTOFORMAT_PATTERN( 26, 26, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
315  AUTOFORMAT_PATTERN( 33, 33, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern1 ),
316  AUTOFORMAT_PATTERN( 34, 34, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern2 ),
318  AUTOFORMAT_PATTERN( 41, 42, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern4 ),
319  AUTOFORMAT_PATTERN( 42, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
322 };
323 
324 const AutoFormatEntry spUpDownBarLines[] =
325 {
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 ),
332 };
333 
334 const AutoFormatEntry spUpBarFills[] =
335 {
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 ),
353 };
354 
355 const AutoFormatEntry spDownBarFills[] =
356 {
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 ),
376 };
377 
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
386 
387 const AutoFormatEntry* lclGetAutoFormatEntry( const AutoFormatEntry* pEntries, sal_Int32 nStyle )
388 {
389  for( ; pEntries && (pEntries->mnFirstStyleIdx >= 0); ++pEntries )
390  if( (pEntries->mnFirstStyleIdx <= nStyle) && (nStyle <= pEntries->mnLastStyleIdx) )
391  return pEntries;
392  return nullptr;
393 }
394 
395 struct AutoTextEntry
396 {
397  sal_Int32 mnFirstStyleIdx;
398  sal_Int32 mnLastStyleIdx;
399  sal_Int32 mnThemedFont;
400  sal_Int32 mnColorToken;
401  sal_Int32 mnDefFontSize;
402  sal_Int32 mnRelFontSize;
403  bool mbBold;
404 };
405 
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 }
408 
409 #define AUTOTEXT_END() \
410  AUTOTEXT_COLOR( -1, -1, XML_none, XML_TOKEN_INVALID, 1000, 100, false )
411 
412 const AutoTextEntry spChartTitleTexts[] =
413 {
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()
417 };
418 
419 const AutoTextEntry spAxisTitleTexts[] =
420 {
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()
424 };
425 
426 const AutoTextEntry spOtherTexts[] =
427 {
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()
431 };
432 
433 #undef AUTOTEXT_COLOR
434 #undef AUTOTEXT_END
435 
436 const AutoTextEntry* lclGetAutoTextEntry( const AutoTextEntry* pEntries, sal_Int32 nStyle )
437 {
438  for( ; pEntries && (pEntries->mnFirstStyleIdx >= 0); ++pEntries )
439  if( (pEntries->mnFirstStyleIdx <= nStyle) && (nStyle <= pEntries->mnLastStyleIdx) )
440  return pEntries;
441  return nullptr;
442 }
443 
444 // These PropIds arrays will be indexed into using a ShapeProperty enum
445 
446 const ShapePropertyIds spnCommonPropIds =
447 {
448  PROP_LineStyle, PROP_LineWidth, PROP_LineColor, PROP_LineTransparence, PROP_LineDashName,
449  PROP_LineCap, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
450  PROP_FillStyle, PROP_FillColor, PROP_FillTransparence, PROP_FillTransparenceGradientName, PROP_FillGradientName,
451  PROP_FillBitmapName, PROP_FillBitmapMode, PROP_FillBitmapSizeX, PROP_FillBitmapSizeY,
452  PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint,
453  PROP_FillHatchName, PROP_FillBackground
454 };
455 
456 const ShapePropertyIds spnLinearPropIds =
457 {
458  PROP_LineStyle, PROP_LineWidth, PROP_Color, PROP_Transparency, PROP_LineDashName,
459  PROP_LineCap, 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
464 };
465 
466 const ShapePropertyIds spnFilledPropIds =
467 {
468  PROP_BorderStyle,
469  PROP_BorderWidth,
470  PROP_BorderColor,
471  PROP_BorderTransparency,
472  PROP_BorderDashName,
473  PROP_LineCap,
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
495 };
496 
498 const ShapePropertyInfo saCommonPropInfo( spnCommonPropIds, false, true, true, true, true );
500 const ShapePropertyInfo saLinearPropInfo( spnLinearPropIds, false, true, true, true, true );
502 const ShapePropertyInfo saFilledPropInfo( spnFilledPropIds, false, true, true, true, true );
503 
505 struct ObjectTypeFormatEntry
506 {
508  const ShapePropertyInfo& mrPropInfo;
509  const AutoFormatEntry* mpAutoLines;
510  const AutoFormatEntry* mpAutoFills;
511  const AutoTextEntry* mpAutoTexts;
512  bool mbIsFrame;
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
521 };
522 
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 }
525 
526 #define TYPEFORMAT_LINE( obj_type, prop_type, auto_texts, auto_lines ) \
527  { obj_type, prop_type, auto_lines, nullptr, auto_texts, false }
528 
529 const ObjectTypeFormatEntry spObjTypeFormatEntries[] =
530 {
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 )
558 };
559 
560 #undef TYPEFORMAT_FRAME
561 #undef TYPEFORMAT_LINE
562 
563 void lclConvertPictureOptions( FillProperties& orFillProps, const PictureOptionsModel& rPicOptions )
564 {
565  bool bStacked = (rPicOptions.mnPictureFormat == XML_stack) || (rPicOptions.mnPictureFormat == XML_stackScale);
566  orFillProps.maBlipProps.moBitmapMode = bStacked ? XML_tile : XML_stretch;
567 }
568 
569 } // namespace
570 
571 struct ObjectFormatterData;
572 
573 namespace {
574 
575 class DetailFormatterBase
576 {
577 public:
578  explicit DetailFormatterBase(
579  ObjectFormatterData& rData,
580  const AutoFormatEntry* pAutoFormatEntry );
581  explicit DetailFormatterBase(
582  ObjectFormatterData& rData,
583  const AutoTextEntry* pAutoTextEntry );
584 
585 protected:
587  ::Color getPhColor( sal_Int32 nSeriesIdx ) const;
588 
589 private:
591  ::Color getSchemeColor( sal_Int32 nColorToken, sal_Int32 nModToken, sal_Int32 nModValue ) const;
592 
593 protected:
594  typedef ::std::vector< ::Color > ColorPatternVec;
595 
598  ColorPatternVec maColorPattern;
599 };
600 
601 class LineFormatter : public DetailFormatterBase
602 {
603 public:
604  explicit LineFormatter(
606  const AutoFormatEntry* pAutoFormatEntry,
607  const ObjectType eObjType );
608 
610  void convertFormatting(
611  ShapePropertyMap& rPropMap,
612  const ModelRef< Shape >& rxShapeProp,
613  sal_Int32 nSeriesIdx );
614 
615 private:
617 };
618 
619 class FillFormatter : public DetailFormatterBase
620 {
621 public:
622  explicit FillFormatter(
624  const AutoFormatEntry* pAutoFormatEntry,
625  const ObjectType eObjType );
626 
628  void convertFormatting(
629  ShapePropertyMap& rPropMap,
630  const ModelRef< Shape >& rxShapeProp,
631  const PictureOptionsModel* pPicOptions,
632  sal_Int32 nSeriesIdx );
633 
634 private:
636 };
637 
638 class TextFormatter : public DetailFormatterBase
639 {
640 public:
641  explicit TextFormatter(
643  const AutoTextEntry* pAutoTextEntry,
644  const ModelRef< TextBody >& rxGlobalTextProp );
645 
647  void convertFormatting(
648  PropertySet& rPropSet,
649  const TextCharacterProperties* pTextProps );
651  void convertFormatting(
652  PropertySet& rPropSet,
653  const ModelRef< TextBody >& rxTextProp );
654 
655 private:
657 };
658 
660 class ObjectTypeFormatter
661 {
662 public:
663  explicit ObjectTypeFormatter(
665  const ObjectTypeFormatEntry& rEntry,
666  const ChartSpaceModel& rChartSpace,
667  const ObjectType eObjType );
668 
670  void convertFrameFormatting(
671  PropertySet& rPropSet,
672  const ModelRef< Shape >& rxShapeProp,
673  const PictureOptionsModel* pPicOptions,
674  sal_Int32 nSeriesIdx );
675 
677  void convertTextFormatting(
678  PropertySet& rPropSet,
679  const ModelRef< TextBody >& rxTextProp );
680 
682  void convertFormatting(
683  PropertySet& rPropSet,
684  const ModelRef< Shape >& rxShapeProp,
685  const ModelRef< TextBody >& rxTextProp );
686 
688  void convertTextFormatting(
689  PropertySet& rPropSet,
690  const TextCharacterProperties& rTextProps );
691 
693  void convertAutomaticFill(
694  PropertySet& rPropSet,
695  sal_Int32 nSeriesIdx );
696 
697 private:
698  LineFormatter maLineFormatter;
699  FillFormatter maFillFormatter;
700  TextFormatter maTextFormatter;
701  ModelObjectHelper& mrModelObjHelper;
702  const ObjectTypeFormatEntry& mrEntry;
703 };
704 
705 }
706 
708 {
710 
712  ObjectTypeFormatterMap maTypeFormatters;
718  sal_Int32 mnMaxSeriesIdx;
719 
720  explicit ObjectFormatterData(
721  const XmlFilterBase& rFilter,
722  const Reference< XChartDocument >& rxChartDoc,
723  const ChartSpaceModel& rChartSpace );
724 
725  ObjectTypeFormatter* getTypeFormatter( ObjectType eObjType );
726 };
727 
728 DetailFormatterBase::DetailFormatterBase( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry ) :
729  mrData( rData ),
730  mnPhClr( ColorTransparency, 0xffffffff )
731 {
732  if( !pAutoFormatEntry )
733  return;
734 
735  if( pAutoFormatEntry->mpPattern )
736  {
737  // prepare multi-color pattern
738  for( const AutoFormatPatternEntry* pPatternEntry = pAutoFormatEntry->mpPattern; pPatternEntry->mnColorToken != XML_TOKEN_INVALID; ++pPatternEntry )
739  maColorPattern.push_back( getSchemeColor( pPatternEntry->mnColorToken, pPatternEntry->mnModToken, pPatternEntry->mnModValue ) );
740  }
741  else if( pAutoFormatEntry->mnColorToken != XML_TOKEN_INVALID )
742  {
743  // prepare color or single-color pattern (color fading)
744  mnPhClr = getSchemeColor( pAutoFormatEntry->mnColorToken, pAutoFormatEntry->mnModToken, pAutoFormatEntry->mnModValue );
745  if( pAutoFormatEntry->mbFadedColor )
746  maColorPattern.push_back( mnPhClr );
747  }
748 }
749 
750 DetailFormatterBase::DetailFormatterBase( ObjectFormatterData& rData, const AutoTextEntry* pAutoTextEntry ) :
751  mrData( rData ),
752  mnPhClr( ColorTransparency, 0xffffffff )
753 {
754  if( pAutoTextEntry && (pAutoTextEntry->mnColorToken != XML_TOKEN_INVALID) )
755  mnPhClr = getSchemeColor( pAutoTextEntry->mnColorToken, XML_TOKEN_INVALID, 0 );
756 }
757 
758 ::Color DetailFormatterBase::getPhColor( sal_Int32 nSeriesIdx ) const
759 {
760  if( maColorPattern.empty() || (mrData.mnMaxSeriesIdx < 0) || (nSeriesIdx < 0) )
761  return mnPhClr;
762 
763  /* Apply tint/shade depending on the cycle index. The colors of leading
764  series are darkened (color shade), the colors of trailing series are
765  lightened (color tint). Shade/tint is applied in an exclusive range of
766  -70% to 70%.
767 
768  Example 1: 3 data series using single-color shading with accent color 1
769  (e.g. automatic chart style #3). Shade/tint is applied per series.
770  Shade/tint changes in steps of 140%/(<series_count+1) = 140%/4 = 35%,
771  starting at -70%:
772  Step 1: -70% -> Not used.
773  Step 2: -35% -> Series 1 has 35% shade of accent color 1.
774  Step 3: 0% -> Series 2 has pure accent color 1.
775  Step 4: 35% -> Series 3 has 35% tint of accent color 1.
776  Step 5: 70% -> Not used.
777 
778  Example 2: 20 data series using accent color pattern (e.g. automatic
779  chart style #2). Each color cycle has a size of 6 series (accent colors
780  1 to 6). Shade/tint is applied per color cycle.
781  Cycle #1: Series 1...6 are based on accent colors 1 to 6.
782  Cycle #2: Series 7...12 are based on accent colors 1 to 6.
783  Cycle #3: Series 13...18 are based on accent colors 1 to 6.
784  Cycle #4: Series 19...20 are based on accent colors 1 to 2.
785  Shade/tint changes in steps of 140%/(cycle_count+1) = 140%/5 = 28%,
786  starting at -70%:
787  Step 1: -70% -> Not used.
788  Step 2: -42% -> Cycle #1 has 42% shade of accent colors 1...6
789  step 3: -14% -> Cycle #2 has 14% shade of accent colors 1...6
790  step 4: 14% -> Cycle #3 has 14% tint of accent colors 1...6
791  step 5: 42% -> Cycle #4 has 42% tint of accent colors 1...6
792  step 6: 70% -> Not used.
793  */
794  ::Color nPhClr = maColorPattern[ static_cast< size_t >( nSeriesIdx % maColorPattern.size() ) ];
795  size_t nCycleIdx = static_cast< size_t >( nSeriesIdx / maColorPattern.size() );
796  size_t nMaxCycleIdx = static_cast< size_t >( mrData.mnMaxSeriesIdx / maColorPattern.size() );
797  double fShadeTint = static_cast< double >( nCycleIdx + 1 ) / (nMaxCycleIdx + 2) * 1.4 - 0.7;
798  if( fShadeTint != 0.0 )
799  {
800  Color aColor;
801  aColor.setSrgbClr( nPhClr );
802  aColor.addChartTintTransformation( fShadeTint );
803  nPhClr = aColor.getColor( mrData.mrFilter.getGraphicHelper() );
804  }
805 
806  return nPhClr;
807 }
808 
809 ::Color DetailFormatterBase::getSchemeColor( sal_Int32 nColorToken, sal_Int32 nModToken, sal_Int32 nModValue ) const
810 {
811  Color aColor;
812  aColor.setSchemeClr( nColorToken );
813  if( nModToken != XML_TOKEN_INVALID )
814  aColor.addTransformation( nModToken, nModValue );
815  return aColor.getColor( mrData.mrFilter.getGraphicHelper() );
816 }
817 
818 LineFormatter::LineFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry, const ObjectType eObjType ) :
819  DetailFormatterBase(rData, pAutoFormatEntry)
820 {
821  if( !pAutoFormatEntry )
822  return;
823 
824  mxAutoLine = std::make_shared<LineProperties>();
825  mxAutoLine->maLineFill.moFillType = XML_noFill;
826  if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
827  if( const LineProperties* pLineProps = pTheme->getLineStyle( pAutoFormatEntry->mnThemedIdx ) )
828  *mxAutoLine = *pLineProps;
829  // set automatic border property for chartarea, because of tdf#81437 and tdf#82217
830  if ( eObjType == OBJECTTYPE_CHARTSPACE )
831  {
834  // this value is what MSO 2016 use as a default color for chartspace border
835  mxAutoLine->maLineFill.maFillColor.setSrgbClr( 0xD9D9D9 );
836  }
837  // change line width according to chart auto style
838  if( mxAutoLine->moLineWidth.has() )
839  mxAutoLine->moLineWidth = mxAutoLine->moLineWidth.get() * pAutoFormatEntry->mnRelLineWidth / 100;
840 }
841 
842 void LineFormatter::convertFormatting( ShapePropertyMap& rPropMap, const ModelRef< Shape >& rxShapeProp, sal_Int32 nSeriesIdx )
843 {
844  LineProperties aLineProps;
845  if( mxAutoLine )
846  aLineProps.assignUsed( *mxAutoLine );
847  if( rxShapeProp.is() )
848  aLineProps.assignUsed( rxShapeProp->getLineProperties() );
849  aLineProps.pushToPropMap( rPropMap, mrData.mrFilter.getGraphicHelper(), getPhColor( nSeriesIdx ) );
850 }
851 
852 FillFormatter::FillFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry, const ObjectType eObjType ) :
853  DetailFormatterBase( rData, pAutoFormatEntry )
854 {
855  if( !pAutoFormatEntry )
856  return;
857 
858  mxAutoFill = std::make_shared<FillProperties>();
859  if( eObjType != OBJECTTYPE_CHARTSPACE )
860  mxAutoFill->moFillType = XML_noFill;
861  if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
862  if( const FillProperties* pFillProps = pTheme->getFillStyle( pAutoFormatEntry->mnThemedIdx ) )
863  *mxAutoFill = *pFillProps;
864 
865  if (eObjType == OBJECTTYPE_CHARTSPACE)
866  {
867  mxAutoFill->moFillType = rData.mrFilter.getGraphicHelper().getDefaultChartAreaFillStyle();
868  }
869 }
870 
871 void FillFormatter::convertFormatting( ShapePropertyMap& rPropMap, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, sal_Int32 nSeriesIdx )
872 {
873  FillProperties aFillProps;
874  if( mxAutoFill )
875  aFillProps.assignUsed( *mxAutoFill );
876  if( rxShapeProp.is() )
877  aFillProps.assignUsed( rxShapeProp->getFillProperties() );
878  if( pPicOptions )
879  lclConvertPictureOptions( aFillProps, *pPicOptions );
880  aFillProps.pushToPropMap( rPropMap, mrData.mrFilter.getGraphicHelper(), 0, getPhColor( nSeriesIdx ) );
881 }
882 
883 namespace {
884 
885 const TextCharacterProperties* lclGetTextProperties( const ModelRef< TextBody >& rxTextProp )
886 {
887  return (rxTextProp.is() && !rxTextProp->getParagraphs().empty()) ?
888  &rxTextProp->getParagraphs().front()->getProperties().getTextCharacterProperties() : nullptr;
889 }
890 
891 } // namespace
892 
893 TextFormatter::TextFormatter( ObjectFormatterData& rData, const AutoTextEntry* pAutoTextEntry, const ModelRef< TextBody >& rxGlobalTextProp ) :
894  DetailFormatterBase( rData, pAutoTextEntry )
895 {
896  if( !pAutoTextEntry )
897  return;
898 
899  mxAutoText = std::make_shared<TextCharacterProperties>();
900  if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
901  if( const TextCharacterProperties* pTextProps = pTheme->getFontStyle( pAutoTextEntry->mnThemedFont ) )
902  *mxAutoText = *pTextProps;
903  ::Color nTextColor = getPhColor( -1 );
904  if( sal_Int32(nTextColor) >= 0 ) {
905  mxAutoText->maFillProperties.maFillColor.setSrgbClr( nTextColor );
906  mxAutoText->maFillProperties.moFillType.set(XML_solidFill);
907  }
908  mxAutoText->moHeight = pAutoTextEntry->mnDefFontSize;
909  mxAutoText->moBold = pAutoTextEntry->mbBold;
910 
911  if( const TextCharacterProperties* pTextProps = lclGetTextProperties( rxGlobalTextProp ) )
912  {
913  mxAutoText->assignUsed( *pTextProps );
914  if( pTextProps->moHeight.has() )
915  mxAutoText->moHeight = pTextProps->moHeight.get() * pAutoTextEntry->mnRelFontSize / 100;
916  }
917 }
918 
919 void TextFormatter::convertFormatting( PropertySet& rPropSet, const TextCharacterProperties* pTextProps )
920 {
921  TextCharacterProperties aTextProps;
922  if( mxAutoText )
923  aTextProps.assignUsed( *mxAutoText );
924  if( pTextProps )
925  aTextProps.assignUsed( *pTextProps );
926  aTextProps.pushToPropSet( rPropSet, mrData.mrFilter );
927 }
928 
929 void TextFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp )
930 {
931  convertFormatting( rPropSet, lclGetTextProperties( rxTextProp ) );
932 }
933 
934 ObjectTypeFormatter::ObjectTypeFormatter( ObjectFormatterData& rData, const ObjectTypeFormatEntry& rEntry, const ChartSpaceModel& rChartSpace, const ObjectType eObjType ) :
935  maLineFormatter( rData, lclGetAutoFormatEntry( rEntry.mpAutoLines, rChartSpace.mnStyle ), eObjType ),
936  maFillFormatter( rData, lclGetAutoFormatEntry( rEntry.mpAutoFills, rChartSpace.mnStyle ), eObjType ),
937  maTextFormatter( rData, lclGetAutoTextEntry( rEntry.mpAutoTexts, rChartSpace.mnStyle ), rChartSpace.mxTextProp ),
938  mrModelObjHelper( rData.maModelObjHelper ),
939  mrEntry( rEntry )
940 {
941 }
942 
943 void ObjectTypeFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, sal_Int32 nSeriesIdx )
944 {
945  ShapePropertyMap aPropMap( mrModelObjHelper, mrEntry.mrPropInfo );
946  maLineFormatter.convertFormatting( aPropMap, rxShapeProp, nSeriesIdx );
947  if( mrEntry.mbIsFrame )
948  maFillFormatter.convertFormatting( aPropMap, rxShapeProp, pPicOptions, nSeriesIdx );
949  rPropSet.setProperties( aPropMap );
950 }
951 
952 void ObjectTypeFormatter::convertTextFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp )
953 {
954  maTextFormatter.convertFormatting( rPropSet, rxTextProp );
955 }
956 
957 void ObjectTypeFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const ModelRef< TextBody >& rxTextProp )
958 {
959  convertFrameFormatting( rPropSet, rxShapeProp, nullptr, -1 );
960  convertTextFormatting( rPropSet, rxTextProp );
961 }
962 
963 void ObjectTypeFormatter::convertTextFormatting( PropertySet& rPropSet, const TextCharacterProperties& rTextProps )
964 {
965  maTextFormatter.convertFormatting( rPropSet, &rTextProps );
966 }
967 
968 void ObjectTypeFormatter::convertAutomaticFill( PropertySet& rPropSet, sal_Int32 nSeriesIdx )
969 {
970  ShapePropertyMap aPropMap( mrModelObjHelper, mrEntry.mrPropInfo );
971  ModelRef< Shape > xShapeProp;
972  maFillFormatter.convertFormatting( aPropMap, xShapeProp, nullptr, nSeriesIdx );
973  rPropSet.setProperties( aPropMap );
974 }
975 
977  mrFilter( rFilter ),
978  maModelObjHelper( Reference< XMultiServiceFactory >( rxChartDoc, UNO_QUERY ) ),
979  maEnUsLocale( "en", "US", OUString() ),
980  mnMaxSeriesIdx( -1 )
981 {
982  for(auto const &rEntry : spObjTypeFormatEntries)
983  maTypeFormatters[ rEntry.meObjType ] = std::make_shared<ObjectTypeFormatter>( *this, rEntry, rChartSpace, rEntry.meObjType );
984 
985  try
986  {
987  Reference< XNumberFormatsSupplier > xNumFmtsSupp( rxChartDoc, UNO_QUERY_THROW );
988  mxNumFmts = xNumFmtsSupp->getNumberFormats();
989  mxNumTypes.set( mxNumFmts, UNO_QUERY );
990  }
991  catch( Exception& )
992  {
993  }
994  OSL_ENSURE( mxNumFmts.is() && mxNumTypes.is(), "ObjectFormatterData::ObjectFormatterData - cannot get number formats" );
995 }
996 
997 ObjectTypeFormatter* ObjectFormatterData::getTypeFormatter( ObjectType eObjType )
998 {
999  OSL_ENSURE( maTypeFormatters.has( eObjType ), "ObjectFormatterData::getTypeFormatter - unknown object type" );
1000  return maTypeFormatters.get( eObjType ).get();
1001 }
1002 
1003 ObjectFormatter::ObjectFormatter( const XmlFilterBase& rFilter, const Reference< XChartDocument >& rxChartDoc, const ChartSpaceModel& rChartSpace ) :
1004  mxData( std::make_shared<ObjectFormatterData>( rFilter, rxChartDoc, rChartSpace ) )
1005 {
1006 }
1007 
1009 {
1010 }
1011 
1012 void ObjectFormatter::setMaxSeriesIndex( sal_Int32 nMaxSeriesIdx )
1013 {
1014  mxData->mnMaxSeriesIdx = nMaxSeriesIdx;
1015 }
1016 
1018 {
1019  return mxData->mnMaxSeriesIdx;
1020 }
1021 
1022 void ObjectFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, ObjectType eObjType, sal_Int32 nSeriesIdx )
1023 {
1024  if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1025  pFormat->convertFrameFormatting( rPropSet, rxShapeProp, nullptr, nSeriesIdx );
1026 }
1027 
1028 void ObjectFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel& rPicOptions, ObjectType eObjType, sal_Int32 nSeriesIdx )
1029 {
1030  if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1031  pFormat->convertFrameFormatting( rPropSet, rxShapeProp, &rPicOptions, nSeriesIdx );
1032 }
1033 
1035 {
1036  if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1037  pFormat->convertTextFormatting( rPropSet, rxTextProp );
1038 }
1039 
1040 void ObjectFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const ModelRef< TextBody >& rxTextProp, ObjectType eObjType )
1041 {
1042  if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1043  pFormat->convertFormatting( rPropSet, rxShapeProp, rxTextProp );
1044 }
1045 
1047 {
1048  if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1049  pFormat->convertTextFormatting( rPropSet, rTextProps );
1050 }
1051 
1052 void ObjectFormatter::convertTextRotation( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp, bool bSupportsStacked, sal_Int32 nDefaultRotation )
1053 {
1054  if( !rxTextProp.is() )
1055  return;
1056 
1057  bool bStacked = false;
1058  if( bSupportsStacked )
1059  {
1060  sal_Int32 nVert = rxTextProp->getTextProperties().moVert.get( XML_horz );
1061  bStacked = (nVert == XML_wordArtVert) || (nVert == XML_wordArtVertRtl);
1062  rPropSet.setProperty( PROP_StackCharacters, bStacked );
1063  }
1064 
1065  /* Chart2 expects rotation angle as double value in range of [0,360).
1066  OOXML counts clockwise, Chart2 counts counterclockwise. */
1067  double fAngle = static_cast< double >( bStacked ? 0 : rxTextProp->getTextProperties().moRotation.get( nDefaultRotation ) );
1068  // MS Office UI allows values only in range of [-90,90].
1069  if ( fAngle < -5400000.0 || fAngle > 5400000.0 )
1070  {
1071  fAngle = 0.0;
1072  }
1073  fAngle = getDoubleIntervalValue< double >( -fAngle / 60000.0, 0.0, 360.0 );
1074  rPropSet.setProperty( PROP_TextRotation, fAngle );
1075 }
1076 
1078 {
1079  if( !rxTextProp.is() )
1080  {
1081  // set default value (in OOXML the default value is true)
1082  rPropSet.setProperty( PROP_TextWordWrap, true );
1083  return;
1084  }
1085 
1086  PropertyMap& aPropMap = rxTextProp->getTextProperties().maPropertyMap;
1087  if( aPropMap.hasProperty(PROP_TextWordWrap) )
1088  {
1089  Any aValue = aPropMap.getProperty( PROP_TextWordWrap );
1090  if( aValue.hasValue() )
1091  {
1092  bool bValue = false;
1093  aValue >>= bValue;
1094  rPropSet.setProperty( PROP_TextWordWrap, bValue );
1095  }
1096  }
1097 }
1098 
1099 void ObjectFormatter::convertNumberFormat( PropertySet& rPropSet, const NumberFormat& rNumberFormat, bool bAxis, bool bShowPercent )
1100 {
1101  if( !mxData->mxNumFmts.is() )
1102  return;
1103 
1104  const bool bGeneral = rNumberFormat.maFormatCode.equalsIgnoreAsciiCase("general");
1105  const bool bPercent = !bAxis && bShowPercent && !rNumberFormat.mbSourceLinked;
1106  sal_Int32 nPropId = bPercent ? PROP_PercentageNumberFormat : PROP_NumberFormat;
1107  OUString sFormatCode(rNumberFormat.maFormatCode);
1108  if (bPercent && bGeneral)
1109  sFormatCode = "0%";
1110  try
1111  {
1112  sal_Int32 nIndex = bGeneral && !bPercent ?
1113  mxData->mxNumTypes->getStandardIndex( mxData->maFromLocale ) :
1114  mxData->mxNumFmts->addNewConverted( sFormatCode, mxData->maEnUsLocale, mxData->maFromLocale );
1115  if( nIndex >= 0 )
1116  rPropSet.setProperty( nPropId, nIndex );
1117  }
1118  catch( Exception& )
1119  {
1120  OSL_FAIL( OStringBuffer( "ObjectFormatter::convertNumberFormat - cannot create number format '" +
1121  OUStringToOString( rNumberFormat.maFormatCode, osl_getThreadTextEncoding() ) + "'" ).getStr() );
1122  }
1123 
1124  // Setting "LinkNumberFormatToSource" does not really work, at least not for axis :-/
1125  if (!bAxis)
1126  rPropSet.setProperty(PROP_LinkNumberFormatToSource, makeAny(rNumberFormat.mbSourceLinked));
1127  else
1128  rPropSet.setProperty(PROP_LinkNumberFormatToSource, makeAny(rNumberFormat.maFormatCode.isEmpty()));
1129 }
1130 
1131 void ObjectFormatter::convertAutomaticFill( PropertySet& rPropSet, ObjectType eObjType, sal_Int32 nSeriesIdx )
1132 {
1133  if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1134  pFormat->convertAutomaticFill( rPropSet, nSeriesIdx );
1135 }
1136 
1138 {
1139  return !rxShapeProp || !rxShapeProp->getFillProperties().moFillType.has();
1140 }
1141 
1142 } // namespace oox
1143 
1144 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int32 mnModValue
Color modification token.
ObjectType meObjType
#define AUTOFORMAT_PATTERN(first, last, themed_style, line_width, pattern)
#define AUTOFORMAT_PATTERN_END()
ObjectTypeFormatterMap maTypeFormatters
Base filter object.
RefMap< ObjectType, ObjectTypeFormatter > ObjectTypeFormatterMap
ObjectType
Plot area containing axes and data series in 2D charts.
#define AUTOFORMAT_FADEDACCENTS(first, themed_style, line_width)
sal_Int32 nIndex
Locale maEnUsLocale
Number format types collection of container document.
const AutoTextEntry * mpAutoTexts
Automatic fill formatting for all chart styles.
std::shared_ptr< FillProperties > FillPropertiesPtr
A helper that maps property identifiers to property values.
Definition: propertymap.hxx:52
sal_Int32 mnRelLineWidth
Color modification value.
ModelObjectHelper & mrModelObjHelper
Converter for text formatting.
static sal_Int16 getDefaultChartAreaLineWidth()
Returns chartspace automatic default border width in Emu.
const AutoFormatPatternEntry * mpPattern
Relative line width (percent).
void convertTextFormatting(PropertySet &rPropSet, const ModelRef< TextBody > &rxTextProp, ObjectType eObjType)
Sets text formatting properties to the passed property set.
void convertAutomaticFill(PropertySet &rPropSet, ObjectType eObjType, sal_Int32 nSeriesIdx)
Sets automatic fill properties to the passed property set.
bool mbFadedColor
Color cycling pattern for data series.
Reference< XNumberFormats > mxNumFmts
Helper for named drawing formatting (dashes, gradients, bitmaps).
void setMaxSeriesIndex(sal_Int32 nMaxSeriesIdx)
Sets the maximum series index used for color cycling/fading.
sal_Int32 mnLastStyleIdx
First chart style index.
o3tl::enumarray< ShapeProperty, sal_Int32 > ShapePropertyIds
const ObjectTypeFormatEntry & mrEntry
Helper for named drawing formatting.
#define TYPEFORMAT_FRAME(obj_type, prop_type, auto_texts, auto_lines, auto_fills)
const ContentProperties & rData
const sal_Int32 THEMED_STYLE_SUBTLE
Definition: theme.hxx:45
#define AUTOFORMAT_COLOR(first, last, themed_style, color_token)
FillFormatter maFillFormatter
Converter for line formatting.
sal_Int32 mnThemedFont
Last chart style index.
std::shared_ptr< T > make_shared(Args &&...args)
sal_Int32 mnThemedIdx
Last chart style index.
static bool isAutomaticFill(const ModelRef< Shape > &rxShapeProp)
Returns true, if the passed shape properties have automatic fill mode.
ObjectFormatterData(const XmlFilterBase &rFilter, const Reference< XChartDocument > &rxChartDoc, const ChartSpaceModel &rChartSpace)
Maximum series index used for color cycling/fading.
#define TYPEFORMAT_LINE(obj_type, prop_type, auto_texts, auto_lines)
Data series error indicator line.
sal_Int32 mnColorToken
Themed style index.
GraphicHelper & getGraphicHelper() const
Returns a helper for the handling of graphics and graphic objects.
Definition: filterbase.cxx:343
std::shared_ptr< TextCharacterProperties > TextCharacterPropertiesPtr
sal_Int32 mnRelFontSize
Default font size (1/100 points).
TextCharacterPropertiesPtr mxAutoText
ObjectFormatterData & mrData
ObjectType
Enumerates different object types for specific automatic formatting behaviour.
bool mbIsFrame
Automatic text attributes for all chart styles.
#define AUTOTEXT_END()
#define AUTOFORMAT_COLORMOD(first, last, themed_style, color_token, mod_token, mod_value)
bool has(key_type nKey) const
Returns true, if the object associated to the passed key exists.
Definition: refmap.hxx:51
static void convertTextWrap(PropertySet &rPropSet, const ModelRef< TextBody > &rxTextProp)
Sets text wrap properties to the passed property set.
FillPropertiesPtr mxAutoFill
const sal_Int32 THEMED_STYLE_INTENSE
Definition: theme.hxx:47
static sal_Int32 getDefaultChartAreaLineStyle()
Returns chartspace automatic default border style.
const ShapePropertyInfo & mrPropInfo
Object type for automatic format.
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
std::shared_ptr< ObjectFormatterData > mxData
void convertFrameFormatting(PropertySet &rPropSet, const ModelRef< Shape > &rxShapeProp, ObjectType eObjType, sal_Int32 nSeriesIdx=-1)
Sets frame formatting properties to the passed property set.
const AutoFormatEntry * mpAutoFills
Automatic line formatting for all chart styles.
sal_Int32 mnFirstStyleIdx
sal_Int32 mnModToken
Theme color token.
bool hasProperty(sal_Int32 nPropId) const
Returns true, if the map contains a property with the passed identifier.
Plot area containing axes and data series in 3D charts.
Locale maFromLocale
Locale struct containing en-US.
Contains tables for named drawing objects for a document model.
void convertFormatting(PropertySet &rPropSet, const ModelRef< Shape > &rxShapeProp, const ModelRef< TextBody > &rxTextProp, ObjectType eObjType)
Sets frame/text formatting properties to the passed property set.
LineFormatter maLineFormatter
ObjectTypeFormatter * getTypeFormatter(ObjectType eObjType)
void convertNumberFormat(PropertySet &rPropSet, const NumberFormat &rNumberFormat, bool bAxis, bool bShowPercent=false)
Sets number format properties to the passed property set.
Linear series in 2D line/radarline/scatter charts.
ColorTransparency
A wrapper for a UNO property set.
Definition: propertyset.hxx:57
#define AUTOTEXT_COLOR(first, last, themed_font, color_token, def_font_size, rel_font_size, bold)
bool mbSourceLinked
Number format code.
Definition: modelbase.hxx:98
Drop lines between data points and X axis.
sal_Int32 mnMaxSeriesIdx
Empty locale struct.
#define AUTOFORMAT_ACCENTSMOD(first, themed_style, mod_token, mod_value)
Locale maEnUsLocale
static void convertTextRotation(PropertySet &rPropSet, const ModelRef< TextBody > &rxTextProp, bool bSupportsStacked, sal_Int32 nDefaultRotation=0)
Sets text rotation properties to the passed property set.
std::shared_ptr< LineProperties > LinePropertiesPtr
ColorPatternVec maColorPattern
RGB placeholder color for themed style.
mapped_type get(key_type nKey) const
Returns a reference to the object associated to the passed key, or an empty reference on error...
Definition: refmap.hxx:59
ObjectFormatter(const ::oox::core::XmlFilterBase &rFilter, const css::uno::Reference< css::chart2::XChartDocument > &rxChartDoc, const ChartSpaceModel &rChartSpace)
sal_Int32 getMaxSeriesIndex() const
Returns the current maximum series index used for color cycling/fading.
bool mbBold
Font size relative to chart global font (percent).
::Color mnPhClr
Shared formatter data.
TextFormatter maTextFormatter
Converter for fill formatting.
const AutoFormatEntry * mpAutoLines
Property info for the ShapePropertyMap class.
#define AUTOFORMAT_END()
Reference< XNumberFormatTypes > mxNumTypes
Number formats collection of container document.
Leader lines between pie slice and data label.
sal_Int32 mnDefFontSize
Theme color token.
css::uno::Any getProperty(sal_Int32 nPropId)
const PowerPointImport & mrFilter
Definition: pptimport.cxx:253
LinePropertiesPtr mxAutoLine
Filled series in 2D bar/area/radararea/bubble/pie/surface charts.
Background and side wall in 3D charts.
#define AUTOFORMAT_PATTERN_COLOR(color_token)
#define AUTOFORMAT_INVISIBLE(first, last)
High/low lines in line/stock charts.
bool setProperty(sal_Int32 nPropId, const Type &rValue)
Puts the passed value into the property set.
#define AUTOFORMAT_PATTERN_COLORMOD(color_token, mod_token, mod_value)
ModelObjectHelper maModelObjHelper
Formatters for all types of objects in a chart.
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)