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