LibreOffice Module oox (master) 1
pptfilterhelpers.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <com/sun/star/animations/TransitionType.hpp>
21#include <com/sun/star/animations/TransitionSubType.hpp>
22#include <com/sun/star/animations/ValuePair.hpp>
23#include <com/sun/star/awt/FontWeight.hpp>
24#include <com/sun/star/awt/FontUnderline.hpp>
25#include <com/sun/star/awt/FontSlant.hpp>
26#include <com/sun/star/drawing/LineStyle.hpp>
27#include <com/sun/star/drawing/FillStyle.hpp>
28#include <com/sun/star/uno/Sequence.hxx>
30#include <tools/color.hxx>
31#include <o3tl/string_view.hxx>
32
33namespace {
34 int lcl_gethex(int nChar)
35 {
36 if (nChar >= '0' && nChar <= '9')
37 return nChar - '0';
38 else if (nChar >= 'a' && nChar <= 'f')
39 return nChar - 'a' + 10;
40 else if (nChar >= 'A' && nChar <= 'F')
41 return nChar - 'A' + 10;
42 else
43 return 0;
44 }
45}
46
47namespace oox::ppt {
48
50 {
51 static const ImplAttributeNameConversion aList[] =
52 {
53 { AnimationAttributeEnum::PPT_X, "ppt_x", "X" },
54 { AnimationAttributeEnum::PPT_Y, "ppt_y", "Y" },
55 { AnimationAttributeEnum::PPT_W, "ppt_w", "Width" },
56 { AnimationAttributeEnum::PPT_H, "ppt_h", "Height" },
57 { AnimationAttributeEnum::PPT_C, "ppt_c", "DimColor" },
58 { AnimationAttributeEnum::R, "r", "Rotate" },
59 { AnimationAttributeEnum::XSHEAR, "xshear", "SkewX" },
60 { AnimationAttributeEnum::FILLCOLOR, "fillcolor", "FillColor" },
61 { AnimationAttributeEnum::FILLCOLOR, "fillColor", "FillColor" },
62 { AnimationAttributeEnum::FILLTYPE, "fill.type", "FillStyle" },
63 { AnimationAttributeEnum::FILLON, "fill.on", "FillOn" },
64 { AnimationAttributeEnum::STROKECOLOR, "stroke.color", "LineColor" },
65 { AnimationAttributeEnum::STROKEON, "stroke.on", "LineStyle" },
66 { AnimationAttributeEnum::STYLECOLOR, "style.color", "CharColor" },
67 { AnimationAttributeEnum::STYLEROTATION, "style.rotation", "Rotate" },
68 { AnimationAttributeEnum::FONTWEIGHT, "style.fontWeight", "CharWeight" },
69 { AnimationAttributeEnum::STYLEUNDERLINE, "style.textDecorationUnderline","CharUnderline" },
70 { AnimationAttributeEnum::STYLEFONTFAMILY, "style.fontFamily", "CharFontName" },
71 { AnimationAttributeEnum::STYLEFONTSIZE, "style.fontSize", "CharHeight" },
72 { AnimationAttributeEnum::STYLEFONTSTYLE, "style.fontStyle", "CharPosture" },
73 { AnimationAttributeEnum::STYLEVISIBILITY, "style.visibility", "Visibility" },
74 { AnimationAttributeEnum::STYLEOPACITY, "style.opacity", "Opacity" },
75 { AnimationAttributeEnum::UNKNOWN, nullptr, nullptr }
76 };
77
78 return aList;
79 }
80
82 {
83 static const transition aList[] =
84 {
85 { "wipe(up)", css::animations::TransitionType::BARWIPE, css::animations::TransitionSubType::TOPTOBOTTOM, true },
86 { "wipe(right)", css::animations::TransitionType::BARWIPE, css::animations::TransitionSubType::LEFTTORIGHT, false },
87 { "wipe(left)", css::animations::TransitionType::BARWIPE, css::animations::TransitionSubType::LEFTTORIGHT, true },
88 { "wipe(down)", css::animations::TransitionType::BARWIPE, css::animations::TransitionSubType::TOPTOBOTTOM, false },
89 { "wheel(1)", css::animations::TransitionType::PINWHEELWIPE, css::animations::TransitionSubType::ONEBLADE, true },
90 { "wheel(2)", css::animations::TransitionType::PINWHEELWIPE, css::animations::TransitionSubType::TWOBLADEVERTICAL, true },
91 { "wheel(3)", css::animations::TransitionType::PINWHEELWIPE, css::animations::TransitionSubType::THREEBLADE, true },
92 { "wheel(4)", css::animations::TransitionType::PINWHEELWIPE, css::animations::TransitionSubType::FOURBLADE, true },
93 { "wheel(8)", css::animations::TransitionType::PINWHEELWIPE, css::animations::TransitionSubType::EIGHTBLADE, true },
94 { "strips(downLeft)", css::animations::TransitionType::WATERFALLWIPE, css::animations::TransitionSubType::HORIZONTALRIGHT, true },
95 { "strips(upLeft)", css::animations::TransitionType::WATERFALLWIPE, css::animations::TransitionSubType::HORIZONTALLEFT, false },
96 { "strips(downRight)", css::animations::TransitionType::WATERFALLWIPE, css::animations::TransitionSubType::HORIZONTALLEFT, true },
97 { "strips(upRight)", css::animations::TransitionType::WATERFALLWIPE, css::animations::TransitionSubType::HORIZONTALRIGHT, false },
98 { "barn(inVertical)", css::animations::TransitionType::BARNDOORWIPE, css::animations::TransitionSubType::VERTICAL, false },
99 { "barn(outVertical)", css::animations::TransitionType::BARNDOORWIPE, css::animations::TransitionSubType::VERTICAL, true },
100 { "barn(inHorizontal)", css::animations::TransitionType::BARNDOORWIPE, css::animations::TransitionSubType::HORIZONTAL, false },
101 { "barn(outHorizontal)", css::animations::TransitionType::BARNDOORWIPE, css::animations::TransitionSubType::HORIZONTAL, true },
102 { "randombar(vertical)", css::animations::TransitionType::RANDOMBARWIPE, css::animations::TransitionSubType::VERTICAL, true},
103 { "randombar(horizontal)", css::animations::TransitionType::RANDOMBARWIPE, css::animations::TransitionSubType::HORIZONTAL, true },
104 { "checkerboard(down)", css::animations::TransitionType::CHECKERBOARDWIPE, css::animations::TransitionSubType::DOWN, true},
105 { "checkerboard(across)", css::animations::TransitionType::CHECKERBOARDWIPE, css::animations::TransitionSubType::ACROSS, true },
106 { "plus(out)", css::animations::TransitionType::FOURBOXWIPE, css::animations::TransitionSubType::CORNERSIN, false },
107 { "plus(in)", css::animations::TransitionType::FOURBOXWIPE, css::animations::TransitionSubType::CORNERSIN, true },
108 { "diamond(out)", css::animations::TransitionType::IRISWIPE, css::animations::TransitionSubType::DIAMOND, true },
109 { "diamond(in)", css::animations::TransitionType::IRISWIPE, css::animations::TransitionSubType::DIAMOND, false },
110 { "circle(out)", css::animations::TransitionType::ELLIPSEWIPE, css::animations::TransitionSubType::HORIZONTAL, true },
111 { "circle(in)", css::animations::TransitionType::ELLIPSEWIPE, css::animations::TransitionSubType::HORIZONTAL, false },
112 { "box(out)", css::animations::TransitionType::IRISWIPE, css::animations::TransitionSubType::RECTANGLE, true },
113 { "box(in)", css::animations::TransitionType::IRISWIPE, css::animations::TransitionSubType::RECTANGLE, false },
114 { "wedge", css::animations::TransitionType::FANWIPE, css::animations::TransitionSubType::CENTERTOP, true },
115 { "blinds(vertical)", css::animations::TransitionType::BLINDSWIPE, css::animations::TransitionSubType::VERTICAL, true },
116 { "blinds(horizontal)", css::animations::TransitionType::BLINDSWIPE, css::animations::TransitionSubType::HORIZONTAL, true },
117 { "fade", css::animations::TransitionType::FADE, css::animations::TransitionSubType::CROSSFADE, true },
118 { "slide(fromTop)", css::animations::TransitionType::SLIDEWIPE, css::animations::TransitionSubType::FROMTOP, true },
119 { "slide(fromRight)", css::animations::TransitionType::SLIDEWIPE, css::animations::TransitionSubType::FROMRIGHT, true },
120 { "slide(fromLeft)", css::animations::TransitionType::SLIDEWIPE, css::animations::TransitionSubType::FROMLEFT, true },
121 { "slide(fromBottom)", css::animations::TransitionType::SLIDEWIPE, css::animations::TransitionSubType::FROMBOTTOM, true },
122 { "dissolve", css::animations::TransitionType::DISSOLVE, css::animations::TransitionSubType::DEFAULT, true },
123 { "image", css::animations::TransitionType::DISSOLVE, css::animations::TransitionSubType::DEFAULT, true }, // TODO
124 { nullptr, 0, 0, false }
125 };
126
127 return aList;
128 }
129
130 const transition* transition::find( std::u16string_view rName )
131 {
133
134 while( p->mpName )
135 {
136 if( o3tl::equalsAscii( rName, p->mpName ) )
137 return p;
138
139 p++;
140 }
141
142 return nullptr;
143 }
144
145 bool convertMeasure(OUString& rString)
146 {
147 bool bRet = false;
148
149 const char* pSource[] = { "ppt_x", "ppt_y", "ppt_w", "ppt_h", nullptr };
150 const char* pDest[] = { "x", "y", "width", "height", nullptr };
151
152 /* here we want to substitute all occurrences of
153 * [#]ppt_[xyhw] with
154 * x,y,height and width respectively
155 */
156 sal_Int32 nIndex = 0;
157
158 const char** ps = pSource;
159 const char** pd = pDest;
160
161 while (*ps)
162 {
163 const OUString aSearch(OUString::createFromAscii(*ps));
164 while ((nIndex = rString.indexOf(aSearch, nIndex)) != -1)
165 {
166 sal_Int32 nLength = aSearch.getLength();
167 if (nIndex && (rString[nIndex - 1] == '#'))
168 {
169 nIndex--;
170 nLength++;
171 }
172
173 const OUString aNew(OUString::createFromAscii(*pd));
174 rString = rString.replaceAt(nIndex, nLength, aNew);
175 nIndex += aNew.getLength();
176 bRet = true;
177 }
178 ps++;
179 pd++;
180 }
181
182 return bRet;
183 }
184
185 bool convertAnimationValue(AnimationAttributeEnum eAttribute, css::uno::Any& rValue)
186 {
187 using css::animations::ValuePair;
188 bool bRet = false;
189 switch (eAttribute)
190 {
195 {
196 OUString aString;
197
198 if (rValue.getValueType() == cppu::UnoType<ValuePair>::get())
199 {
200 ValuePair aValuePair;
201 if (rValue >>= aValuePair)
202 {
203 if (aValuePair.First >>= aString)
204 {
205 if (convertMeasure(aString))
206 {
207 aValuePair.First <<= aString;
208 bRet = true;
209 }
210 }
211
212 if (aValuePair.Second >>= aString)
213 {
214 if (convertMeasure(aString))
215 {
216 aValuePair.Second <<= aString;
217 bRet = true;
218 }
219 }
220 }
221 }
222 else if (rValue.getValueType() == cppu::UnoType<OUString>::get())
223 {
224 if (rValue >>= aString)
225 {
226 bRet = convertMeasure(aString);
227
228 if (bRet)
229 rValue <<= aString;
230 }
231 }
232 }
233 break;
234
237 {
238 OUString aString;
239 if (rValue >>= aString)
240 {
241 rValue <<= aString.toDouble();
242 bRet = true;
243 }
244 }
245 break;
246
248 {
249 if (rValue.getValueType() == cppu::UnoType<OUString>::get())
250 {
251 OUString aString;
252 rValue >>= aString;
253 rValue <<= static_cast<sal_Int16>(aString.toDouble());
254 bRet = true;
255 }
256 else if (rValue.getValueType() == cppu::UnoType<double>::get())
257 {
258 double fValue = 0.0;
259 rValue >>= fValue;
260 rValue <<= static_cast<sal_Int16>(fValue);
261 bRet = true;
262 }
263 }
264 break;
265
270 {
271 OUString aString;
272 if (rValue >>= aString)
273 {
274 if (aString.getLength() >= 7 && aString[0] == '#')
275 {
276 Color aColor;
277 aColor.SetRed(static_cast<sal_uInt8>(lcl_gethex(aString[1]) * 16
278 + lcl_gethex(aString[2])));
279 aColor.SetGreen(static_cast<sal_uInt8>(lcl_gethex(aString[3]) * 16
280 + lcl_gethex(aString[4])));
281 aColor.SetBlue(static_cast<sal_uInt8>(lcl_gethex(aString[5]) * 16
282 + lcl_gethex(aString[6])));
283 rValue <<= aColor;
284 bRet = true;
285 }
286 else if (aString.startsWith("rgb("))
287 {
288 aString = aString.copy(4, aString.getLength() - 5);
289 Color aColor;
290 sal_Int32 index = 0;
291 aColor.SetRed(
292 static_cast<sal_uInt8>(o3tl::toInt32(o3tl::getToken(aString, 0, ',', index))));
293 aColor.SetGreen(
294 static_cast<sal_uInt8>(o3tl::toInt32(o3tl::getToken(aString, 0, ',', index))));
295 aColor.SetRed(
296 static_cast<sal_uInt8>(o3tl::toInt32(o3tl::getToken(aString, 0, ',', index))));
297 rValue <<= aColor;
298 bRet = true;
299 }
300 else if (aString.startsWith("hsl("))
301 {
302 sal_Int32 index = 0;
303 sal_Int32 nA = o3tl::toInt32(o3tl::getToken(aString, 0, ',', index));
304 sal_Int32 nB = o3tl::toInt32(o3tl::getToken(aString, 0, ',', index));
305 sal_Int32 nC = o3tl::toInt32(o3tl::getToken(aString, 0, ',', index));
306 css::uno::Sequence<double> aHSL
307 {
308 nA * 360.0 / 255.0,
309 nB / 255.0,
310 nC / 255.0
311 };
312 rValue <<= aHSL;
313 bRet = true;
314 }
315 }
316 }
317 break;
319 {
320 // Slideshow doesn't support FillOn, but we need to convert the value type
321 // so it can be written out again.
322 OUString aString;
323 if (rValue >>= aString)
324 {
325 rValue <<= aString == "true";
326 bRet = true;
327 }
328 }
329 break;
330
332 {
333 OUString aString;
334 if (rValue >>= aString)
335 {
336 rValue <<= aString == "solid" ? css::drawing::FillStyle_SOLID
337 : css::drawing::FillStyle_NONE;
338 bRet = true;
339 }
340 }
341 break;
342
344 {
345 OUString aString;
346 if (rValue >>= aString)
347 {
348 rValue <<= aString == "true" ? css::drawing::LineStyle_SOLID
349 : css::drawing::LineStyle_NONE;
350 bRet = true;
351 }
352 }
353 break;
354
356 {
357 OUString aString;
358 if (rValue >>= aString)
359 {
360 rValue <<= aString == "bold" ? css::awt::FontWeight::BOLD
361 : css::awt::FontWeight::NORMAL;
362 bRet = true;
363 }
364 }
365 break;
366
368 {
369 OUString aString;
370 if (rValue >>= aString)
371 {
372 rValue
373 <<= aString == "italic" ? css::awt::FontSlant_ITALIC : css::awt::FontSlant_NONE;
374 bRet = true;
375 }
376 }
377 break;
378
380 {
381 OUString aString;
382 if (rValue >>= aString)
383 {
384 rValue <<= aString == "true" ? css::awt::FontUnderline::SINGLE
385 : css::awt::FontUnderline::NONE;
386 bRet = true;
387 }
388 }
389 break;
390
393 {
394 OUString aString;
395 if (rValue >>= aString)
396 {
397 rValue <<= static_cast<float>(aString.toDouble());
398 bRet = true;
399 }
400 }
401 break;
402
404 {
405 OUString aString;
406 if (rValue >>= aString)
407 {
408 rValue <<= aString == "visible";
409 bRet = true;
410 }
411 }
412 break;
413 default:
414 break;
415 }
416
417 return bRet;
418 }
419
420}
421
422/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetGreen(sal_uInt8 nGreen)
void SetRed(sal_uInt8 nRed)
void SetBlue(sal_uInt8 nBlue)
sal_Int32 nIndex
void * p
index
bool equalsAscii(std::u16string_view s1, const char *s2)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
bool convertMeasure(OUString &rString)
convert the measure string to LibreOffice format.
const ImplAttributeNameConversion * getAttributeConversionList()
bool convertAnimationValue(AnimationAttributeEnum eAttribute, css::uno::Any &rValue)
convert attribute values of the animation target so that LibreOffice understand.
static const transition * find(std::u16string_view rName)
static const transition * getList()
unsigned char sal_uInt8
sal_Int32 nLength