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