1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "oox/drawingml/chart/objectformatter.hxx"
29 
30 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
31 #include <com/sun/star/util/XNumberFormatTypes.hpp>
32 #include <osl/thread.h>
33 #include <rtl/strbuf.hxx>
34 #include "oox/core/xmlfilterbase.hxx"
35 #include "oox/drawingml/fillproperties.hxx"
36 #include "oox/drawingml/lineproperties.hxx"
37 #include "oox/drawingml/shapepropertymap.hxx"
38 #include "oox/drawingml/textbody.hxx"
39 #include "oox/drawingml/textparagraph.hxx"
40 #include "oox/drawingml/theme.hxx"
41 #include "oox/drawingml/chart/chartspacemodel.hxx"
42 #include "oox/helper/modelobjecthelper.hxx"
43 
44 namespace oox {
45 namespace drawingml {
46 namespace chart {
47 
48 // ============================================================================
49 
50 using namespace ::com::sun::star::chart2;
51 using namespace ::com::sun::star::frame;
52 using namespace ::com::sun::star::graphic;
53 using namespace ::com::sun::star::lang;
54 using namespace ::com::sun::star::uno;
55 using namespace ::com::sun::star::util;
56 
57 using ::oox::core::XmlFilterBase;
58 using ::rtl::OStringBuffer;
59 using ::rtl::OUString;
60 using ::rtl::OUStringToOString;
61 
62 // ============================================================================
63 
64 namespace {
65 
66 struct AutoFormatPatternEntry
67 {
68     sal_Int32           mnColorToken;       /// Theme color token.
69     sal_Int32           mnModToken;         /// Color modification token.
70     sal_Int32           mnModValue;         /// Color modification value.
71 };
72 
73 #define AUTOFORMAT_PATTERN_COLOR( color_token ) \
74     { color_token, XML_TOKEN_INVALID, 0 }
75 
76 #define AUTOFORMAT_PATTERN_COLORMOD( color_token, mod_token, mod_value ) \
77     { color_token, mod_token, mod_value }
78 
79 #define AUTOFORMAT_PATTERN_END() \
80     AUTOFORMAT_PATTERN_COLOR( XML_TOKEN_INVALID )
81 
82 static const AutoFormatPatternEntry spAutoFormatPattern1[] =
83 {
84     AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 88500 ),
85     AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 55000 ),
86     AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 78000 ),
87     AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 92500 ),
88     AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 70000 ),
89     AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 30000 ),
90     AUTOFORMAT_PATTERN_END()
91 };
92 
93 static const AutoFormatPatternEntry spAutoFormatPattern2[] =
94 {
95     AUTOFORMAT_PATTERN_COLOR( XML_accent1 ),
96     AUTOFORMAT_PATTERN_COLOR( XML_accent2 ),
97     AUTOFORMAT_PATTERN_COLOR( XML_accent3 ),
98     AUTOFORMAT_PATTERN_COLOR( XML_accent4 ),
99     AUTOFORMAT_PATTERN_COLOR( XML_accent5 ),
100     AUTOFORMAT_PATTERN_COLOR( XML_accent6 ),
101     AUTOFORMAT_PATTERN_END()
102 };
103 
104 static const AutoFormatPatternEntry spAutoFormatPattern3[] =
105 {
106     AUTOFORMAT_PATTERN_COLORMOD( XML_accent1, XML_shade, 50000 ),
107     AUTOFORMAT_PATTERN_COLORMOD( XML_accent2, XML_shade, 50000 ),
108     AUTOFORMAT_PATTERN_COLORMOD( XML_accent3, XML_shade, 50000 ),
109     AUTOFORMAT_PATTERN_COLORMOD( XML_accent4, XML_shade, 50000 ),
110     AUTOFORMAT_PATTERN_COLORMOD( XML_accent5, XML_shade, 50000 ),
111     AUTOFORMAT_PATTERN_COLORMOD( XML_accent6, XML_shade, 50000 ),
112     AUTOFORMAT_PATTERN_END()
113 };
114 
115 static const AutoFormatPatternEntry spAutoFormatPattern4[] =
116 {
117     AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint,  5000 ),
118     AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 55000 ),
119     AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 78000 ),
120     AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 15000 ),
121     AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 70000 ),
122     AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 30000 ),
123     AUTOFORMAT_PATTERN_END()
124 };
125 
126 #undef AUTOFORMAT_PATTERN_COLOR
127 #undef AUTOFORMAT_PATTERN_COLORMOD
128 #undef AUTOFORMAT_PATTERN_END
129 
130 // ----------------------------------------------------------------------------
131 
132 struct AutoFormatEntry
133 {
134     sal_Int32           mnFirstStyleIdx;    /// First chart style index.
135     sal_Int32           mnLastStyleIdx;     /// Last chart style index.
136     sal_Int32           mnThemedIdx;        /// Themed style index.
137     sal_Int32           mnColorToken;       /// Theme color token.
138     sal_Int32           mnModToken;         /// Color modification token.
139     sal_Int32           mnModValue;         /// Color modification value.
140     sal_Int32           mnRelLineWidth;     /// Relative line width (percent).
141     const AutoFormatPatternEntry* mpPattern;/// Color cycling pattern for data series.
142     bool                mbFadedColor;       /// True = Faded color for data series.
143 };
144 
145 #define AUTOFORMAT_COLOR( first, last, themed_style, color_token ) \
146     { first, last, themed_style, color_token, XML_TOKEN_INVALID, 0, 100, 0, false }
147 
148 #define AUTOFORMAT_ACCENTS( first, themed_style ) \
149     AUTOFORMAT_COLOR( first,     first,     themed_style, XML_accent1 ), \
150     AUTOFORMAT_COLOR( first + 1, first + 1, themed_style, XML_accent2 ), \
151     AUTOFORMAT_COLOR( first + 2, first + 2, themed_style, XML_accent3 ), \
152     AUTOFORMAT_COLOR( first + 3, first + 3, themed_style, XML_accent4 ), \
153     AUTOFORMAT_COLOR( first + 4, first + 4, themed_style, XML_accent5 ), \
154     AUTOFORMAT_COLOR( first + 5, first + 5, themed_style, XML_accent6 )
155 
156 #define AUTOFORMAT_COLORMOD( first, last, themed_style, color_token, mod_token, mod_value ) \
157     { first, last, themed_style, color_token, mod_token, mod_value, 100, 0, false }
158 
159 #define AUTOFORMAT_ACCENTSMOD( first, themed_style, mod_token, mod_value ) \
160     AUTOFORMAT_COLORMOD( first,     first,     themed_style, XML_accent1, mod_token, mod_value ), \
161     AUTOFORMAT_COLORMOD( first + 1, first + 1, themed_style, XML_accent2, mod_token, mod_value ), \
162     AUTOFORMAT_COLORMOD( first + 2, first + 2, themed_style, XML_accent3, mod_token, mod_value ), \
163     AUTOFORMAT_COLORMOD( first + 3, first + 3, themed_style, XML_accent4, mod_token, mod_value ), \
164     AUTOFORMAT_COLORMOD( first + 4, first + 4, themed_style, XML_accent5, mod_token, mod_value ), \
165     AUTOFORMAT_COLORMOD( first + 5, first + 5, themed_style, XML_accent6, mod_token, mod_value )
166 
167 #define AUTOFORMAT_PATTERN( first, last, themed_style, line_width, pattern ) \
168     { first, last, themed_style, XML_TOKEN_INVALID, XML_TOKEN_INVALID, 0, line_width, pattern, false }
169 
170 #define AUTOFORMAT_FADED( first, last, themed_style, color_token, line_width ) \
171     { first, last, themed_style, color_token, XML_TOKEN_INVALID, 0, line_width, 0, true }
172 
173 #define AUTOFORMAT_FADEDACCENTS( first, themed_style, line_width ) \
174     AUTOFORMAT_FADED( first,     first,     themed_style, XML_accent1, line_width ), \
175     AUTOFORMAT_FADED( first + 1, first + 1, themed_style, XML_accent2, line_width ), \
176     AUTOFORMAT_FADED( first + 2, first + 2, themed_style, XML_accent3, line_width ), \
177     AUTOFORMAT_FADED( first + 3, first + 3, themed_style, XML_accent4, line_width ), \
178     AUTOFORMAT_FADED( first + 4, first + 4, themed_style, XML_accent5, line_width ), \
179     AUTOFORMAT_FADED( first + 5, first + 5, themed_style, XML_accent6, line_width )
180 
181 #define AUTOFORMAT_INVISIBLE( first, last ) \
182     AUTOFORMAT_COLOR( first, last, -1, XML_TOKEN_INVALID )
183 
184 #define AUTOFORMAT_END() \
185     AUTOFORMAT_INVISIBLE( -1, -1 )
186 
187 static const AutoFormatEntry spNoFormats[] =
188 {
189     AUTOFORMAT_INVISIBLE( 1, 48 ),
190     AUTOFORMAT_END()
191 };
192 
193 static const AutoFormatEntry spChartSpaceLines[] =
194 {
195     AUTOFORMAT_COLORMOD(  1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ),
196     AUTOFORMAT_COLORMOD( 33, 40, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ),
197     // 41...48: no line, same as Chart2
198     AUTOFORMAT_END()
199 };
200 
201 static const AutoFormatEntry spChartSpaceFills[] =
202 {
203     AUTOFORMAT_COLOR(  1, 32, THEMED_STYLE_SUBTLE, XML_bg1 ),
204     AUTOFORMAT_COLOR( 33, 40, THEMED_STYLE_SUBTLE, XML_lt1 ),
205     AUTOFORMAT_COLOR( 41, 48, THEMED_STYLE_SUBTLE, XML_dk1 ),
206     AUTOFORMAT_END()
207 };
208 
209 static const AutoFormatEntry spPlotArea2dFills[] =
210 {
211     AUTOFORMAT_COLOR(       1, 32, THEMED_STYLE_SUBTLE, XML_bg1 ),
212     AUTOFORMAT_COLORMOD(   33, 34, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 20000 ),
213     AUTOFORMAT_ACCENTSMOD( 35,     THEMED_STYLE_SUBTLE,          XML_tint, 20000 ), // tint not documented!?
214     AUTOFORMAT_COLORMOD(   41, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
215     AUTOFORMAT_END()
216 };
217 
218 static const AutoFormatEntry spFloorLines[] =
219 {
220     AUTOFORMAT_COLORMOD(  1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ),
221     AUTOFORMAT_COLORMOD( 33, 40, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ),
222     // 41...48: no line, same as Chart2
223     AUTOFORMAT_END()
224 };
225 
226 static const AutoFormatEntry spWallFloorFills[] =
227 {
228     AUTOFORMAT_INVISIBLE(   1, 32 ),
229     AUTOFORMAT_COLORMOD(   33, 34, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 20000 ),
230     AUTOFORMAT_ACCENTSMOD( 35,     THEMED_STYLE_SUBTLE,          XML_tint, 20000 ), // tint not documented!?
231     AUTOFORMAT_COLORMOD(   41, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
232     AUTOFORMAT_END()
233 };
234 
235 static const AutoFormatEntry spAxisLines[] =
236 {
237     AUTOFORMAT_COLORMOD(  1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ),   // tint not documented!?
238     AUTOFORMAT_COLORMOD( 33, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ),   // tint not documented!?
239     AUTOFORMAT_END()
240 };
241 
242 static const AutoFormatEntry spMajorGridLines[] =
243 {
244     AUTOFORMAT_COLORMOD(  1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ),   // tint not documented!?
245     AUTOFORMAT_COLORMOD( 33, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ),   // tint not documented!?
246     AUTOFORMAT_END()
247 };
248 
249 static const AutoFormatEntry spMinorGridLines[] =
250 {
251     AUTOFORMAT_COLORMOD(  1, 40, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 50000 ),
252     AUTOFORMAT_COLORMOD( 41, 48, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 90000 ),
253     AUTOFORMAT_END()
254 };
255 
256 static const AutoFormatEntry spOtherLines[] =
257 {
258     AUTOFORMAT_COLOR(     1, 32, THEMED_STYLE_SUBTLE, XML_tx1 ),
259     AUTOFORMAT_COLOR(    33, 34, THEMED_STYLE_SUBTLE, XML_dk1 ),
260     AUTOFORMAT_COLORMOD( 35, 40, THEMED_STYLE_SUBTLE, XML_dk1, XML_shade, 25000 ),
261     AUTOFORMAT_COLOR(    41, 48, THEMED_STYLE_SUBTLE, XML_lt1 ),
262     AUTOFORMAT_END()
263 };
264 
265 static const AutoFormatEntry spLinearSeriesLines[] =
266 {
267     AUTOFORMAT_PATTERN(       1,  1, THEMED_STYLE_SUBTLE, 300, spAutoFormatPattern1 ),
268     AUTOFORMAT_PATTERN(       2,  2, THEMED_STYLE_SUBTLE, 300, spAutoFormatPattern2 ),
269     AUTOFORMAT_FADEDACCENTS(  3,     THEMED_STYLE_SUBTLE, 300 ),
270     AUTOFORMAT_PATTERN(       9,  9, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
271     AUTOFORMAT_PATTERN(      10, 10, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
272     AUTOFORMAT_FADEDACCENTS( 11,     THEMED_STYLE_SUBTLE, 500 ),
273     AUTOFORMAT_PATTERN(      17, 17, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
274     AUTOFORMAT_PATTERN(      18, 18, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
275     AUTOFORMAT_FADEDACCENTS( 19,     THEMED_STYLE_SUBTLE, 500 ),
276     AUTOFORMAT_PATTERN(      25, 25, THEMED_STYLE_SUBTLE, 700, spAutoFormatPattern1 ),
277     AUTOFORMAT_PATTERN(      26, 26, THEMED_STYLE_SUBTLE, 700, spAutoFormatPattern2 ),
278     AUTOFORMAT_FADEDACCENTS( 27,     THEMED_STYLE_SUBTLE, 700 ),
279     AUTOFORMAT_PATTERN(      33, 33, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
280     AUTOFORMAT_PATTERN(      34, 34, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
281     AUTOFORMAT_FADEDACCENTS( 35,     THEMED_STYLE_SUBTLE, 500 ),
282     AUTOFORMAT_PATTERN(      41, 42, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern4 ),
283     AUTOFORMAT_PATTERN(      42, 42, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
284     AUTOFORMAT_FADEDACCENTS( 43,     THEMED_STYLE_SUBTLE, 500 ),
285     AUTOFORMAT_END()
286 };
287 
288 static const AutoFormatEntry spFilledSeriesLines[] =
289 {
290     AUTOFORMAT_INVISIBLE(   1,  8 ),
291     AUTOFORMAT_COLOR(       9, 16, THEMED_STYLE_SUBTLE, XML_lt1 ),
292     AUTOFORMAT_INVISIBLE(  17, 32 ),
293     AUTOFORMAT_COLORMOD(   33, 33, THEMED_STYLE_SUBTLE, XML_dk1, XML_shade, 50000 ),
294     AUTOFORMAT_PATTERN(    34, 34, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern3 ),
295     AUTOFORMAT_ACCENTSMOD( 35,     THEMED_STYLE_SUBTLE,          XML_shade, 50000 ),
296     AUTOFORMAT_INVISIBLE(  41, 48 ),
297     AUTOFORMAT_END()
298 };
299 
300 static const AutoFormatEntry spFilledSeries2dFills[] =
301 {
302     AUTOFORMAT_PATTERN(       1,  1, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern1 ),
303     AUTOFORMAT_PATTERN(       2,  2, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern2 ),
304     AUTOFORMAT_FADEDACCENTS(  3,     THEMED_STYLE_SUBTLE,  100 ),
305     AUTOFORMAT_PATTERN(       9,  9, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern1 ),
306     AUTOFORMAT_PATTERN(      10, 10, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern2 ),
307     AUTOFORMAT_FADEDACCENTS( 11,     THEMED_STYLE_SUBTLE,  100 ),
308     AUTOFORMAT_PATTERN(      17, 17, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern1 ),
309     AUTOFORMAT_PATTERN(      18, 18, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
310     AUTOFORMAT_FADEDACCENTS( 19,     THEMED_STYLE_INTENSE, 100 ),
311     AUTOFORMAT_PATTERN(      25, 25, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern1 ),
312     AUTOFORMAT_PATTERN(      26, 26, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
313     AUTOFORMAT_FADEDACCENTS( 27,     THEMED_STYLE_INTENSE, 100 ),
314     AUTOFORMAT_PATTERN(      33, 33, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern1 ),
315     AUTOFORMAT_PATTERN(      34, 34, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern2 ),
316     AUTOFORMAT_FADEDACCENTS( 35,     THEMED_STYLE_SUBTLE,  100 ),
317     AUTOFORMAT_PATTERN(      41, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern4 ),
318     AUTOFORMAT_PATTERN(      42, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
319     AUTOFORMAT_FADEDACCENTS( 43,     THEMED_STYLE_INTENSE, 100 ),
320     AUTOFORMAT_END()
321 };
322 
323 static const AutoFormatEntry spFilledSeries3dFills[] =
324 {
325     AUTOFORMAT_PATTERN(       1,  1, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern1 ),
326     AUTOFORMAT_PATTERN(       2,  2, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern2 ),
327     AUTOFORMAT_FADEDACCENTS(  3,     THEMED_STYLE_SUBTLE,  100 ),
328     AUTOFORMAT_PATTERN(       9,  9, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern1 ),
329     AUTOFORMAT_PATTERN(      10, 10, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern2 ),
330     AUTOFORMAT_FADEDACCENTS( 11,     THEMED_STYLE_SUBTLE,  100 ),
331     AUTOFORMAT_PATTERN(      17, 17, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern1 ),
332     AUTOFORMAT_PATTERN(      18, 18, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
333     AUTOFORMAT_FADEDACCENTS( 19,     THEMED_STYLE_SUBTLE,  100 ),
334     AUTOFORMAT_PATTERN(      25, 25, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern1 ),
335     AUTOFORMAT_PATTERN(      26, 26, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
336     AUTOFORMAT_FADEDACCENTS( 27,     THEMED_STYLE_SUBTLE,  100 ),
337     AUTOFORMAT_PATTERN(      33, 33, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern1 ),
338     AUTOFORMAT_PATTERN(      34, 34, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern2 ),
339     AUTOFORMAT_FADEDACCENTS( 35,     THEMED_STYLE_SUBTLE,  100 ),
340     AUTOFORMAT_PATTERN(      41, 42, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern4 ),
341     AUTOFORMAT_PATTERN(      42, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
342     AUTOFORMAT_FADEDACCENTS( 43,     THEMED_STYLE_SUBTLE,  100 ),
343     AUTOFORMAT_END()
344 };
345 
346 static const AutoFormatEntry spFilledSeriesEffects[] =
347 {
348     // 1...8: no effect, same as Chart2
349     AUTOFORMAT_COLOR(  9, 16, THEMED_STYLE_SUBTLE,   XML_dk1 ),
350     AUTOFORMAT_COLOR( 17, 24, THEMED_STYLE_MODERATE, XML_dk1 ),
351     AUTOFORMAT_COLOR( 25, 32, THEMED_STYLE_INTENSE,  XML_dk1 ),
352     // 33...40: no effect, same as Chart2
353     AUTOFORMAT_COLOR( 41, 48, THEMED_STYLE_INTENSE,  XML_dk1 ),
354     AUTOFORMAT_END()
355 };
356 
357 static const AutoFormatEntry spUpDownBarLines[] =
358 {
359     AUTOFORMAT_COLOR(       1, 16, THEMED_STYLE_SUBTLE, XML_tx1 ),
360     AUTOFORMAT_INVISIBLE(  17, 32 ),
361     AUTOFORMAT_COLOR(      33, 34, THEMED_STYLE_SUBTLE, XML_dk1 ),
362     AUTOFORMAT_ACCENTSMOD( 35,     THEMED_STYLE_SUBTLE, XML_shade, 25000 ),
363     AUTOFORMAT_INVISIBLE(  41, 48 ),
364     AUTOFORMAT_END()
365 };
366 
367 static const AutoFormatEntry spUpBarFills[] =
368 {
369     AUTOFORMAT_COLORMOD(    1,  1, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint, 25000 ),
370     AUTOFORMAT_COLORMOD(    2,  2, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint,  5000 ),
371     AUTOFORMAT_ACCENTSMOD(  3,     THEMED_STYLE_SUBTLE,           XML_tint, 25000 ),
372     AUTOFORMAT_COLORMOD(    9,  9, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint, 25000 ),
373     AUTOFORMAT_COLORMOD(   10, 10, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint,  5000 ),
374     AUTOFORMAT_ACCENTSMOD( 11,     THEMED_STYLE_SUBTLE,           XML_tint, 25000 ),
375     AUTOFORMAT_COLORMOD(   17, 17, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 25000 ),
376     AUTOFORMAT_COLORMOD(   18, 18, THEMED_STYLE_INTENSE, XML_dk1, XML_tint,  5000 ),
377     AUTOFORMAT_ACCENTSMOD( 19,     THEMED_STYLE_INTENSE,          XML_tint, 25000 ),
378     AUTOFORMAT_COLORMOD(   25, 25, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 25000 ),
379     AUTOFORMAT_COLORMOD(   26, 26, THEMED_STYLE_INTENSE, XML_dk1, XML_tint,  5000 ),
380     AUTOFORMAT_ACCENTSMOD( 27,     THEMED_STYLE_INTENSE,          XML_tint, 25000 ),
381     AUTOFORMAT_COLOR(      33, 40, THEMED_STYLE_SUBTLE,  XML_lt1 ),
382     AUTOFORMAT_COLORMOD(   41, 41, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 25000 ),
383     AUTOFORMAT_COLOR(      42, 42, THEMED_STYLE_INTENSE, XML_lt1 ),
384     AUTOFORMAT_ACCENTSMOD( 43,     THEMED_STYLE_INTENSE,          XML_tint, 25000 ),
385     AUTOFORMAT_END()
386 };
387 
388 static const AutoFormatEntry spDownBarFills[] =
389 {
390     AUTOFORMAT_COLORMOD(    1,  1, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint,  85000 ),
391     AUTOFORMAT_COLORMOD(    2,  2, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint,  95000 ),
392     AUTOFORMAT_ACCENTSMOD(  3,     THEMED_STYLE_SUBTLE,           XML_shade, 25000 ),
393     AUTOFORMAT_COLORMOD(    9,  9, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint,  85000 ),
394     AUTOFORMAT_COLORMOD(   10, 10, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint,  95000 ),
395     AUTOFORMAT_ACCENTSMOD( 11,     THEMED_STYLE_SUBTLE,           XML_shade, 25000 ),
396     AUTOFORMAT_COLORMOD(   17, 17, THEMED_STYLE_INTENSE, XML_dk1, XML_tint,  85000 ),
397     AUTOFORMAT_COLORMOD(   18, 18, THEMED_STYLE_INTENSE, XML_dk1, XML_tint,  95000 ),
398     AUTOFORMAT_ACCENTSMOD( 19,     THEMED_STYLE_INTENSE,          XML_shade, 25000 ),
399     AUTOFORMAT_COLORMOD(   25, 25, THEMED_STYLE_INTENSE, XML_dk1, XML_tint,  85000 ),
400     AUTOFORMAT_COLORMOD(   26, 26, THEMED_STYLE_INTENSE, XML_dk1, XML_tint,  95000 ),
401     AUTOFORMAT_ACCENTSMOD( 27,     THEMED_STYLE_INTENSE,          XML_shade, 25000 ),
402     AUTOFORMAT_COLORMOD(   33, 33, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint,  85000 ),
403     AUTOFORMAT_COLORMOD(   34, 34, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint,  95000 ),
404     AUTOFORMAT_ACCENTSMOD( 27,     THEMED_STYLE_SUBTLE,           XML_shade, 25000 ),
405     AUTOFORMAT_COLORMOD(   41, 41, THEMED_STYLE_INTENSE, XML_dk1, XML_tint,  85000 ),
406     AUTOFORMAT_COLOR(      42, 42, THEMED_STYLE_INTENSE, XML_dk1 ),
407     AUTOFORMAT_ACCENTSMOD( 43,     THEMED_STYLE_INTENSE,          XML_shade, 25000 ),
408     AUTOFORMAT_END()
409 };
410 
411 static const AutoFormatEntry spUpDownBarEffects[] =
412 {
413     // 1...8: no effect, same as Chart2
414     AUTOFORMAT_COLOR(  9, 16, THEMED_STYLE_SUBTLE,   XML_dk1 ),
415     AUTOFORMAT_COLOR( 17, 24, THEMED_STYLE_MODERATE, XML_dk1 ),
416     AUTOFORMAT_COLOR( 25, 32, THEMED_STYLE_INTENSE,  XML_dk1 ),
417     // 33...40: no effect, same as Chart2
418     AUTOFORMAT_COLOR( 41, 48, THEMED_STYLE_INTENSE,  XML_dk1 ),
419     AUTOFORMAT_END()
420 };
421 
422 #undef AUTOFORMAT_COLOR
423 #undef AUTOFORMAT_ACCENTS
424 #undef AUTOFORMAT_COLORMOD
425 #undef AUTOFORMAT_ACCENTSMOD
426 #undef AUTOFORMAT_PATTERN
427 #undef AUTOFORMAT_FADED
428 #undef AUTOFORMAT_FADEDACCENTS
429 #undef AUTOFORMAT_INVISIBLE
430 #undef AUTOFORMAT_END
431 
432 const AutoFormatEntry* lclGetAutoFormatEntry( const AutoFormatEntry* pEntries, sal_Int32 nStyle )
433 {
434     for( ; pEntries && (pEntries->mnFirstStyleIdx >= 0); ++pEntries )
435         if( (pEntries->mnFirstStyleIdx <= nStyle) && (nStyle <= pEntries->mnLastStyleIdx) )
436             return pEntries;
437     return 0;
438 }
439 
440 // ----------------------------------------------------------------------------
441 
442 struct AutoTextEntry
443 {
444     sal_Int32           mnFirstStyleIdx;    /// First chart style index.
445     sal_Int32           mnLastStyleIdx;     /// Last chart style index.
446     sal_Int32           mnThemedFont;       /// Themed font (minor/major).
447     sal_Int32           mnColorToken;       /// Theme color token.
448     sal_Int32           mnDefFontSize;      /// Default font size (1/100 points).
449     sal_Int32           mnRelFontSize;      /// Font size relative to chart global font (percent).
450     bool                mbBold;             /// True = bold font.
451 };
452 
453 #define AUTOTEXT_COLOR( first, last, themed_font, color_token, def_font_size, rel_font_size, bold ) \
454     { first, last, themed_font, color_token, def_font_size, rel_font_size, bold }
455 
456 #define AUTOTEXT_END() \
457     AUTOTEXT_COLOR( -1, -1, XML_none, XML_TOKEN_INVALID, 1000, 100, false )
458 
459 static const AutoTextEntry spChartTitleTexts[] =
460 {
461     AUTOTEXT_COLOR(  1, 40, XML_minor, XML_tx1, 1800, 120, true ),
462     AUTOTEXT_COLOR( 41, 48, XML_minor, XML_lt1, 1800, 120, true ),
463     AUTOTEXT_END()
464 };
465 
466 static const AutoTextEntry spAxisTitleTexts[] =
467 {
468     AUTOTEXT_COLOR(  1, 40, XML_minor, XML_tx1, 1000, 100, true ),
469     AUTOTEXT_COLOR( 41, 48, XML_minor, XML_lt1, 1000, 100, true ),
470     AUTOTEXT_END()
471 };
472 
473 static const AutoTextEntry spOtherTexts[] =
474 {
475     AUTOTEXT_COLOR(  1, 40, XML_minor, XML_tx1, 1000, 100, false ),
476     AUTOTEXT_COLOR( 41, 48, XML_minor, XML_lt1, 1000, 100, false ),
477     AUTOTEXT_END()
478 };
479 
480 #undef AUTOTEXT_COLOR
481 #undef AUTOTEXT_END
482 
483 const AutoTextEntry* lclGetAutoTextEntry( const AutoTextEntry* pEntries, sal_Int32 nStyle )
484 {
485     for( ; pEntries && (pEntries->mnFirstStyleIdx >= 0); ++pEntries )
486         if( (pEntries->mnFirstStyleIdx <= nStyle) && (nStyle <= pEntries->mnLastStyleIdx) )
487             return pEntries;
488     return 0;
489 }
490 
491 // ----------------------------------------------------------------------------
492 
493 /** Property identifiers for common chart objects, to be used in ShapePropertyInfo. */
494 static const sal_Int32 spnCommonPropIds[] =
495 {
496     PROP_LineStyle, PROP_LineWidth, PROP_LineColor, PROP_LineTransparence, PROP_LineDashName,
497     PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
498     PROP_FillStyle, PROP_FillColor, PROP_FillTransparence, PROP_FillGradientName,
499     PROP_FillBitmapName, PROP_FillBitmapMode, PROP_FillBitmapSizeX, PROP_FillBitmapSizeY,
500     PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint
501 };
502 
503 /** Property identifiers for linear data series, to be used in ShapePropertyInfo. */
504 static const sal_Int32 spnLinearPropIds[] =
505 {
506     PROP_LineStyle, PROP_LineWidth, PROP_Color, PROP_Transparency, PROP_LineDashName,
507     PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
508     PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
509     PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
510     PROP_INVALID, PROP_INVALID, PROP_INVALID
511 };
512 
513 /** Property identifiers for filled data series, to be used in ShapePropertyInfo. */
514 static const sal_Int32 spnFilledPropIds[] =
515 {
516     PROP_BorderStyle, PROP_BorderWidth, PROP_BorderColor, PROP_BorderTransparency, PROP_BorderDashName,
517     PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
518     PROP_FillStyle, PROP_Color, PROP_Transparency, PROP_GradientName,
519     PROP_FillBitmapName, PROP_FillBitmapMode, PROP_FillBitmapSizeX, PROP_FillBitmapSizeY,
520     PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint
521 };
522 
523 /** Property info for common chart objects, to be used in ShapePropertyMap. */
524 static const ShapePropertyInfo saCommonPropInfo( spnCommonPropIds, false, true, true, true );
525 /** Property info for linear data series, to be used in ShapePropertyMap. */
526 static const ShapePropertyInfo saLinearPropInfo( spnLinearPropIds, false, true, true, true );
527 /** Property info for filled data series, to be used in ShapePropertyMap. */
528 static const ShapePropertyInfo saFilledPropInfo( spnFilledPropIds, false, true, true, true );
529 
530 // ----------------------------------------------------------------------------
531 
532 /** Contains information about formatting of a specific chart object type. */
533 struct ObjectTypeFormatEntry
534 {
535     ObjectType          meObjType;          /// Object type for automatic format.
536     const ShapePropertyInfo* mpPropInfo;    /// Property info for the ShapePropertyMap class.
537     const AutoFormatEntry* mpAutoLines;     /// Automatic line formatting for all chart styles.
538     const AutoFormatEntry* mpAutoFills;     /// Automatic fill formatting for all chart styles.
539     const AutoFormatEntry* mpAutoEffects;   /// Automatic effect formatting for all chart styles.
540     const AutoTextEntry* mpAutoTexts;       /// Automatic text attributes for all chart styles.
541     bool                mbIsFrame;          /// True = object is a frame, false = object is a line.
542 };
543 
544 #define TYPEFORMAT_FRAME( obj_type, prop_type, auto_texts, auto_lines, auto_fills, auto_effects ) \
545     { obj_type, prop_type, auto_lines, auto_fills, auto_effects, auto_texts, true }
546 
547 #define TYPEFORMAT_LINE( obj_type, prop_type, auto_texts, auto_lines ) \
548     { obj_type, prop_type, auto_lines, 0, 0, auto_texts, false }
549 
550 static const ObjectTypeFormatEntry spObjTypeFormatEntries[] =
551 {
552     //                object type                property info      auto text          auto line            auto fill              auto effect
553     TYPEFORMAT_FRAME( OBJECTTYPE_CHARTSPACE,     &saCommonPropInfo, 0,                 spChartSpaceLines,   spChartSpaceFills,     0 /* eq to Ch2 */ ),
554     TYPEFORMAT_FRAME( OBJECTTYPE_CHARTTITLE,     &saCommonPropInfo, spChartTitleTexts, 0 /* eq to Ch2 */,   0 /* eq to Ch2 */,     0 /* eq to Ch2 */ ),
555     TYPEFORMAT_FRAME( OBJECTTYPE_LEGEND,         &saCommonPropInfo, spOtherTexts,      spNoFormats,         spNoFormats,           0 /* eq to Ch2 */ ),
556     TYPEFORMAT_FRAME( OBJECTTYPE_PLOTAREA2D,     &saCommonPropInfo, 0,                 0 /* eq to Ch2 */,   spPlotArea2dFills,     0 /* eq to Ch2 */ ),
557     TYPEFORMAT_FRAME( OBJECTTYPE_PLOTAREA3D,     &saCommonPropInfo, 0,                 0 /* eq to Ch2 */,   0 /* eq to Ch2 */,     0 /* eq to Ch2 */ ),
558     TYPEFORMAT_FRAME( OBJECTTYPE_WALL,           &saCommonPropInfo, 0,                 0 /* eq to Ch2 */,   spWallFloorFills,      0 /* eq to Ch2 */ ),
559     TYPEFORMAT_FRAME( OBJECTTYPE_FLOOR,          &saCommonPropInfo, 0,                 spFloorLines,        spWallFloorFills,      0 /* eq to Ch2 */ ),
560     TYPEFORMAT_LINE(  OBJECTTYPE_AXIS,           &saCommonPropInfo, spOtherTexts,      spAxisLines ),
561     TYPEFORMAT_FRAME( OBJECTTYPE_AXISTITLE,      &saCommonPropInfo, spAxisTitleTexts,  0 /* eq to Ch2 */,   0 /* eq to Ch2 */,     0 /* eq to Ch2 */ ),
562     TYPEFORMAT_FRAME( OBJECTTYPE_AXISUNIT,       &saCommonPropInfo, spAxisTitleTexts,  0 /* eq in Ch2 */,   0 /* eq in Ch2 */,     0 /* eq in Ch2 */ ),
563     TYPEFORMAT_LINE(  OBJECTTYPE_MAJORGRIDLINE,  &saCommonPropInfo, 0,                 spMajorGridLines ),
564     TYPEFORMAT_LINE(  OBJECTTYPE_MINORGRIDLINE,  &saCommonPropInfo, 0,                 spMinorGridLines ),
565     TYPEFORMAT_LINE(  OBJECTTYPE_LINEARSERIES2D, &saLinearPropInfo, 0,                 spLinearSeriesLines ),
566     TYPEFORMAT_FRAME( OBJECTTYPE_FILLEDSERIES2D, &saFilledPropInfo, 0,                 spFilledSeriesLines, spFilledSeries2dFills, spFilledSeriesEffects ),
567     TYPEFORMAT_FRAME( OBJECTTYPE_FILLEDSERIES3D, &saFilledPropInfo, 0,                 spFilledSeriesLines, spFilledSeries3dFills, spFilledSeriesEffects ),
568     TYPEFORMAT_FRAME( OBJECTTYPE_DATALABEL,      &saCommonPropInfo, spOtherTexts,      0 /* eq to Ch2 */,   0 /* eq to Ch2 */,     0 /* eq to Ch2 */ ),
569     TYPEFORMAT_LINE(  OBJECTTYPE_TRENDLINE,      &saCommonPropInfo, 0,                 spOtherLines ),
570     TYPEFORMAT_FRAME( OBJECTTYPE_TRENDLINELABEL, &saCommonPropInfo, spOtherTexts,      0 /* eq to Ch2 */,   0 /* eq to Ch2 */,     0 /* eq to Ch2 */ ),
571     TYPEFORMAT_LINE(  OBJECTTYPE_ERRORBAR,       &saCommonPropInfo, 0,                 spOtherLines ),
572     TYPEFORMAT_LINE(  OBJECTTYPE_SERLINE,        &saCommonPropInfo, 0,                 spOtherLines ),
573     TYPEFORMAT_LINE(  OBJECTTYPE_LEADERLINE,     &saCommonPropInfo, 0,                 spOtherLines ),
574     TYPEFORMAT_LINE(  OBJECTTYPE_DROPLINE,       &saCommonPropInfo, 0,                 spOtherLines ),
575     TYPEFORMAT_LINE(  OBJECTTYPE_HILOLINE,       &saLinearPropInfo, 0,                 spOtherLines ),
576     TYPEFORMAT_FRAME( OBJECTTYPE_UPBAR,          &saCommonPropInfo, 0,                 spUpDownBarLines,    spUpBarFills,          spUpDownBarEffects ),
577     TYPEFORMAT_FRAME( OBJECTTYPE_DOWNBAR,        &saCommonPropInfo, 0,                 spUpDownBarLines,    spDownBarFills,        spUpDownBarEffects ),
578     TYPEFORMAT_LINE(  OBJECTTYPE_DATATABLE,      &saCommonPropInfo, spOtherTexts,      spChartSpaceLines )
579 };
580 
581 #undef TYPEFORMAT_FRAME
582 #undef TYPEFORMAT_LINE
583 
584 // ----------------------------------------------------------------------------
585 
586 void lclConvertPictureOptions( FillProperties& orFillProps, const PictureOptionsModel& rPicOptions )
587 {
588     bool bStacked = (rPicOptions.mnPictureFormat == XML_stack) || (rPicOptions.mnPictureFormat == XML_stackScale);
589     orFillProps.maBlipProps.moBitmapMode = bStacked ? XML_tile : XML_stretch;
590 }
591 
592 } // namespace
593 
594 // ============================================================================
595 
596 struct ObjectFormatterData;
597 
598 // ----------------------------------------------------------------------------
599 
600 class DetailFormatterBase
601 {
602 public:
603     explicit            DetailFormatterBase(
604                             ObjectFormatterData& rData,
605                             const AutoFormatEntry* pAutoFormatEntry );
606     explicit            DetailFormatterBase(
607                             ObjectFormatterData& rData,
608                             const AutoTextEntry* pAutoTextEntry );
609 
610 protected:
611     /** Returns the placeholder color which may depend on the passed series index. */
612     sal_Int32           getPhColor( sal_Int32 nSeriesIdx ) const;
613 
614 private:
615     /** Resolves and returns the scheme color with the passed transformation. */
616     sal_Int32           getSchemeColor( sal_Int32 nColorToken, sal_Int32 nModToken, sal_Int32 nModValue ) const;
617 
618 protected:
619     typedef ::std::vector< sal_Int32 > ColorPatternVec;
620 
621     ObjectFormatterData& mrData;            /// Shared formatter data.
622     sal_Int32           mnPhClr;            /// RGB placeholder color for themed style.
623     ColorPatternVec     maColorPattern;     /// Different cycling colors for data series.
624 };
625 
626 // ----------------------------------------------------------------------------
627 
628 class LineFormatter : public DetailFormatterBase
629 {
630 public:
631     explicit            LineFormatter(
632                             ObjectFormatterData& rData,
633                             const AutoFormatEntry* pAutoFormatEntry );
634 
635     /** Converts line formatting to the passed property set. */
636     void                convertFormatting(
637                             ShapePropertyMap& rPropMap,
638                             const ModelRef< Shape >& rxShapeProp,
639                             sal_Int32 nSeriesIdx );
640 
641 private:
642     LinePropertiesPtr   mxAutoLine;         /// Automatic line properties.
643 };
644 
645 // ----------------------------------------------------------------------------
646 
647 class FillFormatter : public DetailFormatterBase
648 {
649 public:
650     explicit            FillFormatter(
651                             ObjectFormatterData& rData,
652                             const AutoFormatEntry* pAutoFormatEntry );
653 
654     /** Converts area formatting to the passed property set. */
655     void                convertFormatting(
656                             ShapePropertyMap& rPropMap,
657                             const ModelRef< Shape >& rxShapeProp,
658                             const PictureOptionsModel* pPicOptions,
659                             sal_Int32 nSeriesIdx );
660 
661 private:
662     FillPropertiesPtr   mxAutoFill;         /// Automatic fill properties.
663 };
664 
665 // ----------------------------------------------------------------------------
666 
667 class EffectFormatter : public DetailFormatterBase
668 {
669 public:
670     explicit            EffectFormatter(
671                             ObjectFormatterData& rData,
672                             const AutoFormatEntry* pAutoFormatEntry );
673 
674     /** Converts effect formatting to the passed property set. */
675     void                convertFormatting(
676                             ShapePropertyMap& rPropMap,
677                             const ModelRef< Shape >& rxShapeProp,
678                             sal_Int32 nSeriesIdx );
679 };
680 
681 // ----------------------------------------------------------------------------
682 
683 class TextFormatter : public DetailFormatterBase
684 {
685 public:
686     explicit            TextFormatter(
687                             ObjectFormatterData& rData,
688                             const AutoTextEntry* pAutoTextEntry,
689                             const ModelRef< TextBody >& rxGlobalTextProp );
690 
691     /** Converts text formatting to the passed property set. */
692     void                convertFormatting(
693                             PropertySet& rPropSet,
694                             const TextCharacterProperties* pTextProps );
695     /** Converts text formatting to the passed property set. */
696     void                convertFormatting(
697                             PropertySet& rPropSet,
698                             const ModelRef< TextBody >& rxTextProp );
699 
700 private:
701     TextCharacterPropertiesPtr mxAutoText;  /// Automatic text properties.
702 };
703 
704 // ----------------------------------------------------------------------------
705 
706 /** Formatter for a specific object type. */
707 class ObjectTypeFormatter
708 {
709 public:
710     explicit            ObjectTypeFormatter(
711                             ObjectFormatterData& rData,
712                             const ObjectTypeFormatEntry& rEntry,
713                             const ChartSpaceModel& rChartSpace );
714 
715     /** Sets frame formatting properties to the passed property set. */
716     void                convertFrameFormatting(
717                             PropertySet& rPropSet,
718                             const ModelRef< Shape >& rxShapeProp,
719                             const PictureOptionsModel* pPicOptions,
720                             sal_Int32 nSeriesIdx );
721 
722     /** Sets text formatting properties to the passed property set. */
723     void                convertTextFormatting(
724                             PropertySet& rPropSet,
725                             const ModelRef< TextBody >& rxTextProp );
726 
727     /** Sets frame/text formatting properties to the passed property set. */
728     void                convertFormatting(
729                             PropertySet& rPropSet,
730                             const ModelRef< Shape >& rxShapeProp,
731                             const ModelRef< TextBody >& rxTextProp );
732 
733     /** Sets text formatting properties to the passed property set. */
734     void                convertTextFormatting(
735                             PropertySet& rPropSet,
736                             const TextCharacterProperties& rTextProps );
737 
738     /** Sets automatic line properties to the passed property set. */
739     void                convertAutomaticLine(
740                             PropertySet& rPropSet,
741                             sal_Int32 nSeriesIdx );
742 
743     /** Sets automatic fill properties to the passed property set. */
744     void                convertAutomaticFill(
745                             PropertySet& rPropSet,
746                             sal_Int32 nSeriesIdx );
747 
748 private:
749     LineFormatter       maLineFormatter;    /// Converter for line formatting.
750     FillFormatter       maFillFormatter;    /// Converter for fill formatting.
751     EffectFormatter     maEffectFormatter;  /// Converter for effect formatting.
752     TextFormatter       maTextFormatter;    /// Converter for text formatting.
753     ModelObjectHelper&  mrModelObjHelper;   /// Helper for named drawing formatting.
754     const ObjectTypeFormatEntry& mrEntry;   /// Additional settings.
755 };
756 
757 // ----------------------------------------------------------------------------
758 
759 struct ObjectFormatterData
760 {
761     typedef RefMap< ObjectType, ObjectTypeFormatter > ObjectTypeFormatterMap;
762 
763     const XmlFilterBase& mrFilter;              /// Base filter object.
764     ObjectTypeFormatterMap maTypeFormatters;    /// Formatters for all types of objects in a chart.
765     ModelObjectHelper   maModelObjHelper;       /// Helper for named drawing formatting (dashes, gradients, bitmaps).
766     Reference< XNumberFormats > mxNumFmts;      /// Number formats collection of container document.
767     Reference< XNumberFormatTypes > mxNumTypes; /// Number format types collection of container document.
768     Locale              maEnUsLocale;           /// Locale struct containing en-US.
769     Locale              maFromLocale;           /// Empty locale struct.
770     sal_Int32           mnMaxSeriesIdx;         /// Maximum series index used for color cycling/fading.
771 
772     explicit            ObjectFormatterData(
773                             const XmlFilterBase& rFilter,
774                             const Reference< XChartDocument >& rxChartDoc,
775                             const ChartSpaceModel& rChartSpace );
776 
777     ObjectTypeFormatter* getTypeFormatter( ObjectType eObjType );
778 };
779 
780 // ============================================================================
781 
782 DetailFormatterBase::DetailFormatterBase( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry ) :
783     mrData( rData ),
784     mnPhClr( -1 )
785 {
786     if( pAutoFormatEntry )
787     {
788         if( pAutoFormatEntry->mpPattern )
789         {
790             // prepare multi-color pattern
791             for( const AutoFormatPatternEntry* pPatternEntry = pAutoFormatEntry->mpPattern; pPatternEntry->mnColorToken != XML_TOKEN_INVALID; ++pPatternEntry )
792                 maColorPattern.push_back( getSchemeColor( pPatternEntry->mnColorToken, pPatternEntry->mnModToken, pPatternEntry->mnModValue ) );
793         }
794         else if( pAutoFormatEntry->mnColorToken != XML_TOKEN_INVALID )
795         {
796             // prepare color or single-color pattern (color fading)
797             mnPhClr = getSchemeColor( pAutoFormatEntry->mnColorToken, pAutoFormatEntry->mnModToken, pAutoFormatEntry->mnModValue );
798             if( pAutoFormatEntry->mbFadedColor )
799                 maColorPattern.push_back( mnPhClr );
800         }
801     }
802 }
803 
804 DetailFormatterBase::DetailFormatterBase( ObjectFormatterData& rData, const AutoTextEntry* pAutoTextEntry ) :
805     mrData( rData ),
806     mnPhClr( -1 )
807 {
808     if( pAutoTextEntry && (pAutoTextEntry->mnColorToken != XML_TOKEN_INVALID) )
809         mnPhClr = getSchemeColor( pAutoTextEntry->mnColorToken, XML_TOKEN_INVALID, 0 );
810 }
811 
812 sal_Int32 DetailFormatterBase::getPhColor( sal_Int32 nSeriesIdx ) const
813 {
814     if( maColorPattern.empty() || (mrData.mnMaxSeriesIdx < 0) || (nSeriesIdx < 0) )
815         return mnPhClr;
816 
817     /*  Apply tint/shade depending on the cycle index. The colors of leading
818         series are darkened (color shade), the colors of trailing series are
819         lightened (color tint). Shade/tint is applied in an exclusive range of
820         -70% to 70%.
821 
822         Example 1: 3 data series using single-color shading with accent color 1
823         (e.g. automatic chart style #3). Shade/tint is applied per series.
824         Shade/tint changes in steps of 140%/(<series_count+1) = 140%/4 = 35%,
825         starting at -70%:
826             Step 1: -70% -> Not used.
827             Step 2: -35% -> Series 1 has 35% shade of accent color 1.
828             Step 3:   0% -> Series 2 has pure accent color 1.
829             Step 4:  35% -> Series 3 has 35% tint of accent color 1.
830             Step 5:  70% -> Not used.
831 
832         Example 2: 20 data series using accent color pattern (e.g. automatic
833         chart style #2). Each color cycle has a size of 6 series (accent colors
834         1 to 6). Shade/tint is applied per color cycle.
835             Cycle #1: Series 1...6 are based on accent colors 1 to 6.
836             Cycle #2: Series 7...12 are based on accent colors 1 to 6.
837             Cycle #3: Series 13...18 are based on accent colors 1 to 6.
838             Cycle #4: Series 19...20 are based on accent colors 1 to 2.
839         Shade/tint changes in steps of 140%/(cycle_count+1) = 140%/5 = 28%,
840         starting at -70%:
841             Step 1: -70% -> Not used.
842             Step 2: -42% -> Cycle #1 has 42% shade of accent colors 1...6
843             step 3: -14% -> Cycle #2 has 14% shade of accent colors 1...6
844             step 4:  14% -> Cycle #3 has 14% tint of accent colors 1...6
845             step 5:  42% -> Cycle #4 has 42% tint of accent colors 1...6
846             step 6:  70% -> Not used.
847      */
848     sal_Int32 nPhClr = maColorPattern[ static_cast< size_t >( nSeriesIdx % maColorPattern.size() ) ];
849     size_t nCycleIdx = static_cast< size_t >( nSeriesIdx / maColorPattern.size() );
850     size_t nMaxCycleIdx = static_cast< size_t >( mrData.mnMaxSeriesIdx / maColorPattern.size() );
851     double fShadeTint = static_cast< double >( nCycleIdx + 1 ) / (nMaxCycleIdx + 2) * 1.4 - 0.7;
852     if( fShadeTint != 0.0 )
853     {
854         Color aColor;
855         aColor.setSrgbClr( nPhClr );
856         aColor.addChartTintTransformation( fShadeTint );
857         nPhClr = aColor.getColor( mrData.mrFilter.getGraphicHelper() );
858     }
859 
860     return nPhClr;
861 }
862 
863 sal_Int32 DetailFormatterBase::getSchemeColor( sal_Int32 nColorToken, sal_Int32 nModToken, sal_Int32 nModValue ) const
864 {
865     Color aColor;
866     aColor.setSchemeClr( nColorToken );
867     if( nModToken != XML_TOKEN_INVALID )
868         aColor.addTransformation( nModToken, nModValue );
869     return aColor.getColor( mrData.mrFilter.getGraphicHelper() );
870 }
871 
872 // ============================================================================
873 
874 LineFormatter::LineFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry ) :
875     DetailFormatterBase( rData, pAutoFormatEntry )
876 {
877     if( pAutoFormatEntry )
878     {
879         mxAutoLine.reset( new LineProperties );
880         mxAutoLine->maLineFill.moFillType = XML_noFill;
881         if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
882             if( const LineProperties* pLineProps = pTheme->getLineStyle( pAutoFormatEntry->mnThemedIdx ) )
883                 *mxAutoLine = *pLineProps;
884         // change line width according to chart auto style
885         if( mxAutoLine->moLineWidth.has() )
886             mxAutoLine->moLineWidth = mxAutoLine->moLineWidth.get() * pAutoFormatEntry->mnRelLineWidth / 100;
887     }
888 }
889 
890 void LineFormatter::convertFormatting( ShapePropertyMap& rPropMap, const ModelRef< Shape >& rxShapeProp, sal_Int32 nSeriesIdx )
891 {
892     LineProperties aLineProps;
893     if( mxAutoLine.get() )
894         aLineProps.assignUsed( *mxAutoLine );
895     if( rxShapeProp.is() )
896         aLineProps.assignUsed( rxShapeProp->getLineProperties() );
897     aLineProps.pushToPropMap( rPropMap, mrData.mrFilter.getGraphicHelper(), getPhColor( nSeriesIdx ) );
898 }
899 
900 // ============================================================================
901 
902 FillFormatter::FillFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry ) :
903     DetailFormatterBase( rData, pAutoFormatEntry )
904 {
905     if( pAutoFormatEntry )
906     {
907         mxAutoFill.reset( new FillProperties );
908         mxAutoFill->moFillType = XML_noFill;
909         if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
910             if( const FillProperties* pFillProps = pTheme->getFillStyle( pAutoFormatEntry->mnThemedIdx ) )
911                 *mxAutoFill = *pFillProps;
912     }
913 }
914 
915 void FillFormatter::convertFormatting( ShapePropertyMap& rPropMap, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, sal_Int32 nSeriesIdx )
916 {
917     FillProperties aFillProps;
918     if( mxAutoFill.get() )
919         aFillProps.assignUsed( *mxAutoFill );
920     if( rxShapeProp.is() )
921         aFillProps.assignUsed( rxShapeProp->getFillProperties() );
922     if( pPicOptions )
923         lclConvertPictureOptions( aFillProps, *pPicOptions );
924     aFillProps.pushToPropMap( rPropMap, mrData.mrFilter.getGraphicHelper(), 0, getPhColor( nSeriesIdx ) );
925 }
926 
927 // ============================================================================
928 
929 EffectFormatter::EffectFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry ) :
930     DetailFormatterBase( rData, pAutoFormatEntry )
931 {
932 }
933 
934 void EffectFormatter::convertFormatting( ShapePropertyMap& /*rPropMap*/, const ModelRef< Shape >& /*rxShapeProp*/, sal_Int32 /*nSeriesIdx*/ )
935 {
936 }
937 
938 // ============================================================================
939 
940 namespace {
941 
942 const TextCharacterProperties* lclGetTextProperties( const ModelRef< TextBody >& rxTextProp )
943 {
944     return (rxTextProp.is() && !rxTextProp->getParagraphs().empty()) ?
945         &rxTextProp->getParagraphs().front()->getProperties().getTextCharacterProperties() : 0;
946 }
947 
948 } // namespace
949 
950 TextFormatter::TextFormatter( ObjectFormatterData& rData, const AutoTextEntry* pAutoTextEntry, const ModelRef< TextBody >& rxGlobalTextProp ) :
951     DetailFormatterBase( rData, pAutoTextEntry )
952 {
953     if( pAutoTextEntry )
954     {
955         mxAutoText.reset( new TextCharacterProperties );
956         if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
957             if( const TextCharacterProperties* pTextProps = pTheme->getFontStyle( pAutoTextEntry->mnThemedFont ) )
958                 *mxAutoText = *pTextProps;
959         sal_Int32 nTextColor = getPhColor( -1 );
960         if( nTextColor >= 0 )
961             mxAutoText->maCharColor.setSrgbClr( nTextColor );
962         mxAutoText->moHeight = pAutoTextEntry->mnDefFontSize;
963         mxAutoText->moBold = pAutoTextEntry->mbBold;
964 
965         if( const TextCharacterProperties* pTextProps = lclGetTextProperties( rxGlobalTextProp ) )
966         {
967             mxAutoText->assignUsed( *pTextProps );
968             if( pTextProps->moHeight.has() )
969                 mxAutoText->moHeight = pTextProps->moHeight.get() * pAutoTextEntry->mnRelFontSize / 100;
970         }
971     }
972 }
973 
974 void TextFormatter::convertFormatting( PropertySet& rPropSet, const TextCharacterProperties* pTextProps )
975 {
976     TextCharacterProperties aTextProps;
977     if( mxAutoText.get() )
978         aTextProps.assignUsed( *mxAutoText );
979     if( pTextProps )
980         aTextProps.assignUsed( *pTextProps );
981     aTextProps.pushToPropSet( rPropSet, mrData.mrFilter );
982 }
983 
984 void TextFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp )
985 {
986     convertFormatting( rPropSet, lclGetTextProperties( rxTextProp ) );
987 }
988 
989 // ============================================================================
990 
991 ObjectTypeFormatter::ObjectTypeFormatter( ObjectFormatterData& rData, const ObjectTypeFormatEntry& rEntry, const ChartSpaceModel& rChartSpace ) :
992     maLineFormatter(   rData, lclGetAutoFormatEntry( rEntry.mpAutoLines,   rChartSpace.mnStyle ) ),
993     maFillFormatter(   rData, lclGetAutoFormatEntry( rEntry.mpAutoFills,   rChartSpace.mnStyle ) ),
994     maEffectFormatter( rData, lclGetAutoFormatEntry( rEntry.mpAutoEffects, rChartSpace.mnStyle ) ),
995     maTextFormatter(   rData, lclGetAutoTextEntry(   rEntry.mpAutoTexts,   rChartSpace.mnStyle ), rChartSpace.mxTextProp ),
996     mrModelObjHelper( rData.maModelObjHelper ),
997     mrEntry( rEntry )
998 {
999 }
1000 
1001 void ObjectTypeFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, sal_Int32 nSeriesIdx )
1002 {
1003     ShapePropertyMap aPropMap( mrModelObjHelper, *mrEntry.mpPropInfo );
1004     maLineFormatter.convertFormatting( aPropMap, rxShapeProp, nSeriesIdx );
1005     if( mrEntry.mbIsFrame )
1006         maFillFormatter.convertFormatting( aPropMap, rxShapeProp, pPicOptions, nSeriesIdx );
1007     maEffectFormatter.convertFormatting( aPropMap, rxShapeProp, nSeriesIdx );
1008     rPropSet.setProperties( aPropMap );
1009 }
1010 
1011 void ObjectTypeFormatter::convertTextFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp )
1012 {
1013     maTextFormatter.convertFormatting( rPropSet, rxTextProp );
1014 }
1015 
1016 void ObjectTypeFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const ModelRef< TextBody >& rxTextProp )
1017 {
1018     convertFrameFormatting( rPropSet, rxShapeProp, 0, -1 );
1019     convertTextFormatting( rPropSet, rxTextProp );
1020 }
1021 
1022 void ObjectTypeFormatter::convertTextFormatting( PropertySet& rPropSet, const TextCharacterProperties& rTextProps )
1023 {
1024     maTextFormatter.convertFormatting( rPropSet, &rTextProps );
1025 }
1026 
1027 void ObjectTypeFormatter::convertAutomaticLine( PropertySet& rPropSet, sal_Int32 nSeriesIdx )
1028 {
1029     ShapePropertyMap aPropMap( mrModelObjHelper, *mrEntry.mpPropInfo );
1030     ModelRef< Shape > xShapeProp;
1031     maLineFormatter.convertFormatting( aPropMap, xShapeProp, nSeriesIdx );
1032     maEffectFormatter.convertFormatting( aPropMap, xShapeProp, nSeriesIdx );
1033     rPropSet.setProperties( aPropMap );
1034 }
1035 
1036 void ObjectTypeFormatter::convertAutomaticFill( PropertySet& rPropSet, sal_Int32 nSeriesIdx )
1037 {
1038     ShapePropertyMap aPropMap( mrModelObjHelper, *mrEntry.mpPropInfo );
1039     ModelRef< Shape > xShapeProp;
1040     maFillFormatter.convertFormatting( aPropMap, xShapeProp, 0, nSeriesIdx );
1041     maEffectFormatter.convertFormatting( aPropMap, xShapeProp, nSeriesIdx );
1042     rPropSet.setProperties( aPropMap );
1043 }
1044 
1045 // ============================================================================
1046 
1047 ObjectFormatterData::ObjectFormatterData( const XmlFilterBase& rFilter, const Reference< XChartDocument >& rxChartDoc, const ChartSpaceModel& rChartSpace ) :
1048     mrFilter( rFilter ),
1049     maModelObjHelper( Reference< XMultiServiceFactory >( rxChartDoc, UNO_QUERY ) ),
1050     maEnUsLocale( CREATE_OUSTRING( "en" ), CREATE_OUSTRING( "US" ), OUString() ),
1051     mnMaxSeriesIdx( -1 )
1052 {
1053     const ObjectTypeFormatEntry* pEntryEnd = STATIC_ARRAY_END( spObjTypeFormatEntries );
1054     for( const ObjectTypeFormatEntry* pEntry = spObjTypeFormatEntries; pEntry != pEntryEnd; ++pEntry )
1055         maTypeFormatters[ pEntry->meObjType ].reset( new ObjectTypeFormatter( *this, *pEntry, rChartSpace ) );
1056 
1057     try
1058     {
1059         Reference< XNumberFormatsSupplier > xNumFmtsSupp( mrFilter.getModel(), UNO_QUERY_THROW );
1060         mxNumFmts = xNumFmtsSupp->getNumberFormats();
1061         mxNumTypes.set( mxNumFmts, UNO_QUERY );
1062     }
1063     catch( Exception& )
1064     {
1065     }
1066     OSL_ENSURE( mxNumFmts.is() && mxNumTypes.is(), "ObjectFormatterData::ObjectFormatterData - cannot get number formats" );
1067 }
1068 
1069 ObjectTypeFormatter* ObjectFormatterData::getTypeFormatter( ObjectType eObjType )
1070 {
1071     OSL_ENSURE( maTypeFormatters.has( eObjType ), "ObjectFormatterData::getTypeFormatter - unknown object type" );
1072     return maTypeFormatters.get( eObjType ).get();
1073 }
1074 
1075 // ============================================================================
1076 
1077 ObjectFormatter::ObjectFormatter( const XmlFilterBase& rFilter, const Reference< XChartDocument >& rxChartDoc, const ChartSpaceModel& rChartSpace ) :
1078     mxData( new ObjectFormatterData( rFilter, rxChartDoc, rChartSpace ) )
1079 {
1080 }
1081 
1082 ObjectFormatter::~ObjectFormatter()
1083 {
1084 }
1085 
1086 void ObjectFormatter::setMaxSeriesIndex( sal_Int32 nMaxSeriesIdx )
1087 {
1088     mxData->mnMaxSeriesIdx = nMaxSeriesIdx;
1089 }
1090 
1091 sal_Int32 ObjectFormatter::getMaxSeriesIndex() const
1092 {
1093     return mxData->mnMaxSeriesIdx;
1094 }
1095 
1096 void ObjectFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, ObjectType eObjType, sal_Int32 nSeriesIdx )
1097 {
1098     if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1099         pFormat->convertFrameFormatting( rPropSet, rxShapeProp, 0, nSeriesIdx );
1100 }
1101 
1102 void ObjectFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel& rPicOptions, ObjectType eObjType, sal_Int32 nSeriesIdx )
1103 {
1104     if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1105         pFormat->convertFrameFormatting( rPropSet, rxShapeProp, &rPicOptions, nSeriesIdx );
1106 }
1107 
1108 void ObjectFormatter::convertTextFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp, ObjectType eObjType )
1109 {
1110     if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1111         pFormat->convertTextFormatting( rPropSet, rxTextProp );
1112 }
1113 
1114 void ObjectFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const ModelRef< TextBody >& rxTextProp, ObjectType eObjType )
1115 {
1116     if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1117         pFormat->convertFormatting( rPropSet, rxShapeProp, rxTextProp );
1118 }
1119 
1120 void ObjectFormatter::convertTextFormatting( PropertySet& rPropSet, const TextCharacterProperties& rTextProps, ObjectType eObjType )
1121 {
1122     if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1123         pFormat->convertTextFormatting( rPropSet, rTextProps );
1124 }
1125 
1126 void ObjectFormatter::convertTextRotation( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp, bool bSupportsStacked )
1127 {
1128     if( rxTextProp.is() )
1129     {
1130         bool bStacked = false;
1131         if( bSupportsStacked )
1132         {
1133             sal_Int32 nVert = rxTextProp->getTextProperties().moVert.get( XML_horz );
1134             bStacked = (nVert == XML_wordArtVert) || (nVert == XML_wordArtVertRtl);
1135             rPropSet.setProperty( PROP_StackCharacters, bStacked );
1136         }
1137 
1138         /*  Chart2 expects rotation angle as double value in range of [0,360).
1139             OOXML counts clockwise, Chart2 counts counterclockwise. */
1140         double fAngle = static_cast< double >( bStacked ? 0 : rxTextProp->getTextProperties().moRotation.get( 0 ) );
1141         fAngle = getDoubleIntervalValue< double >( -fAngle / 60000.0, 0.0, 360.0 );
1142         rPropSet.setProperty( PROP_TextRotation, fAngle );
1143     }
1144 }
1145 
1146 void ObjectFormatter::convertNumberFormat( PropertySet& rPropSet, const NumberFormat& rNumberFormat, bool bPercentFormat )
1147 {
1148     if( mxData->mxNumFmts.is() )
1149     {
1150         sal_Int32 nPropId = bPercentFormat ? PROP_PercentageNumberFormat : PROP_NumberFormat;
1151         if( rNumberFormat.mbSourceLinked || (rNumberFormat.maFormatCode.getLength() == 0) )
1152         {
1153             rPropSet.setAnyProperty( nPropId, Any() );
1154         }
1155         else try
1156         {
1157             sal_Int32 nIndex = rNumberFormat.maFormatCode.equalsIgnoreAsciiCaseAscii( "general" ) ?
1158                 mxData->mxNumTypes->getStandardIndex( mxData->maFromLocale ) :
1159                 mxData->mxNumFmts->addNewConverted( rNumberFormat.maFormatCode, mxData->maEnUsLocale, mxData->maFromLocale );
1160             if( nIndex >= 0 )
1161                 rPropSet.setProperty( nPropId, nIndex );
1162         }
1163         catch( Exception& )
1164         {
1165             OSL_ENSURE( false,
1166                 OStringBuffer( "ObjectFormatter::convertNumberFormat - cannot create number format '" ).
1167                 append( OUStringToOString( rNumberFormat.maFormatCode, osl_getThreadTextEncoding() ) ).append( '\'' ).getStr() );
1168         }
1169     }
1170 }
1171 
1172 void ObjectFormatter::convertAutomaticLine( PropertySet& rPropSet, ObjectType eObjType, sal_Int32 nSeriesIdx )
1173 {
1174     if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1175         pFormat->convertAutomaticLine( rPropSet, nSeriesIdx );
1176 }
1177 
1178 void ObjectFormatter::convertAutomaticFill( PropertySet& rPropSet, ObjectType eObjType, sal_Int32 nSeriesIdx )
1179 {
1180     if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1181         pFormat->convertAutomaticFill( rPropSet, nSeriesIdx );
1182 }
1183 
1184 /*static*/ bool ObjectFormatter::isAutomaticLine( const ModelRef< Shape >& rxShapeProp )
1185 {
1186     return !rxShapeProp || !rxShapeProp->getLineProperties().maLineFill.moFillType.has();
1187 }
1188 
1189 /*static*/ bool ObjectFormatter::isAutomaticFill( const ModelRef< Shape >& rxShapeProp )
1190 {
1191     return !rxShapeProp || !rxShapeProp->getFillProperties().moFillType.has();
1192 }
1193 
1194 // ============================================================================
1195 
1196 } // namespace chart
1197 } // namespace drawingml
1198 } // namespace oox
1199