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