LibreOffice Module xmloff (master)  1
TransGradientStyle.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 <TransGradientStyle.hxx>
21 
22 #include <com/sun/star/awt/Gradient.hpp>
23 
24 #include <sax/tools/converter.hxx>
26 
27 #include <xmloff/nmspmap.hxx>
28 #include <xmloff/xmluconv.hxx>
29 #include <xmloff/xmlnmspe.hxx>
30 #include <rtl/ustrbuf.hxx>
31 #include <rtl/ustring.hxx>
32 #include <sal/log.hxx>
33 #include <tools/color.hxx>
34 #include <xmloff/xmltkmap.hxx>
35 #include <xmloff/xmlexp.hxx>
36 #include <xmloff/xmlimp.hxx>
37 #include <xmloff/xmlement.hxx>
38 
39 using namespace ::com::sun::star;
40 
41 using namespace ::xmloff::token;
42 
43 namespace {
44 
46 {
47  XML_TOK_GRADIENT_NAME,
48  XML_TOK_GRADIENT_DISPLAY_NAME,
49  XML_TOK_GRADIENT_STYLE,
50  XML_TOK_GRADIENT_CX,
51  XML_TOK_GRADIENT_CY,
52  XML_TOK_GRADIENT_START,
53  XML_TOK_GRADIENT_END,
54  XML_TOK_GRADIENT_ANGLE,
55  XML_TOK_GRADIENT_BORDER
56 };
57 
58 }
59 
61 {
62  { XML_LINEAR, awt::GradientStyle_LINEAR },
63  { XML_GRADIENTSTYLE_AXIAL, awt::GradientStyle_AXIAL },
64  { XML_GRADIENTSTYLE_RADIAL, awt::GradientStyle_RADIAL },
65  { XML_GRADIENTSTYLE_ELLIPSOID, awt::GradientStyle_ELLIPTICAL },
66  { XML_GRADIENTSTYLE_SQUARE, awt::GradientStyle_SQUARE },
67  { XML_GRADIENTSTYLE_RECTANGULAR, awt::GradientStyle_RECT },
68  { XML_TOKEN_INVALID, awt::GradientStyle(0) }
69 };
70 
71 // Import
72 
74  : rImport(rImp)
75 {
76 }
77 
79 {
80 }
81 
83  const uno::Reference< xml::sax::XAttributeList >& xAttrList,
85  OUString& rStrName )
86 {
87  OUString aDisplayName;
88 
89  awt::Gradient aGradient;
90  aGradient.XOffset = 0;
91  aGradient.YOffset = 0;
92  aGradient.StartIntensity = 100;
93  aGradient.EndIntensity = 100;
94  aGradient.Angle = 0;
95  aGradient.Border = 0;
96 
97  static const SvXMLTokenMapEntry aTrGradientAttrTokenMap[] =
98  {
99  { XML_NAMESPACE_DRAW, XML_NAME, XML_TOK_GRADIENT_NAME },
100  { XML_NAMESPACE_DRAW, XML_DISPLAY_NAME, XML_TOK_GRADIENT_DISPLAY_NAME },
101  { XML_NAMESPACE_DRAW, XML_STYLE, XML_TOK_GRADIENT_STYLE },
102  { XML_NAMESPACE_DRAW, XML_CX, XML_TOK_GRADIENT_CX },
103  { XML_NAMESPACE_DRAW, XML_CY, XML_TOK_GRADIENT_CY },
104  { XML_NAMESPACE_DRAW, XML_START, XML_TOK_GRADIENT_START },
105  { XML_NAMESPACE_DRAW, XML_END, XML_TOK_GRADIENT_END },
106  { XML_NAMESPACE_DRAW, XML_GRADIENT_ANGLE, XML_TOK_GRADIENT_ANGLE },
107  { XML_NAMESPACE_DRAW, XML_BORDER, XML_TOK_GRADIENT_BORDER, },
109  };
110 
111  static const SvXMLTokenMap aTokenMap( aTrGradientAttrTokenMap );
112  SvXMLNamespaceMap& rNamespaceMap = rImport.GetNamespaceMap();
113 
114  sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
115  for( sal_Int16 i=0; i < nAttrCount; i++ )
116  {
117  const OUString& rFullAttrName = xAttrList->getNameByIndex( i );
118  OUString aStrAttrName;
119  sal_uInt16 nPrefix = rNamespaceMap.GetKeyByAttrName( rFullAttrName, &aStrAttrName );
120  const OUString& rStrValue = xAttrList->getValueByIndex( i );
121 
122  sal_Int32 nTmpValue;
123 
124  switch( aTokenMap.Get( nPrefix, aStrAttrName ) )
125  {
126  case XML_TOK_GRADIENT_NAME:
127  {
128  rStrName = rStrValue;
129  }
130  break;
131  case XML_TOK_GRADIENT_DISPLAY_NAME:
132  {
133  aDisplayName = rStrValue;
134  }
135  break;
136  case XML_TOK_GRADIENT_STYLE:
137  {
138  SvXMLUnitConverter::convertEnum( aGradient.Style, rStrValue, pXML_GradientStyle_Enum );
139  }
140  break;
141  case XML_TOK_GRADIENT_CX:
142  ::sax::Converter::convertPercent( nTmpValue, rStrValue );
143  aGradient.XOffset = sal::static_int_cast< sal_Int16 >(nTmpValue);
144  break;
145  case XML_TOK_GRADIENT_CY:
146  ::sax::Converter::convertPercent( nTmpValue, rStrValue );
147  aGradient.YOffset = sal::static_int_cast< sal_Int16 >(nTmpValue);
148  break;
149  case XML_TOK_GRADIENT_START:
150  {
151  sal_Int32 aStartTransparency;
152  ::sax::Converter::convertPercent( aStartTransparency, rStrValue );
153 
154  sal_uInt8 n = sal::static_int_cast< sal_uInt8 >(
155  ( (100 - aStartTransparency) * 255 ) / 100 );
156 
157  Color aColor( n, n, n );
158  aGradient.StartColor = static_cast<sal_Int32>( aColor );
159  }
160  break;
161  case XML_TOK_GRADIENT_END:
162  {
163  sal_Int32 aEndTransparency;
164  ::sax::Converter::convertPercent( aEndTransparency, rStrValue );
165 
166  sal_uInt8 n = sal::static_int_cast< sal_uInt8 >(
167  ( (100 - aEndTransparency) * 255 ) / 100 );
168 
169  Color aColor( n, n, n );
170  aGradient.EndColor = static_cast<sal_Int32>( aColor );
171  }
172  break;
173  case XML_TOK_GRADIENT_ANGLE:
174  {
175  auto const cmp12(rImport.GetODFVersion().compareTo(ODFVER_012_TEXT));
176  bool const bSuccess =
177  ::sax::Converter::convertAngle(aGradient.Angle, rStrValue,
178  // tdf#89475 try to detect borked OOo angles
179  (cmp12 < 0) || (cmp12 == 0
181  // also for AOO 4.x, assume there won't ever be a 4.2
183  SAL_INFO_IF(!bSuccess, "xmloff.style", "failed to import draw:angle");
184  }
185  break;
186  case XML_TOK_GRADIENT_BORDER:
187  ::sax::Converter::convertPercent( nTmpValue, rStrValue );
188  aGradient.Border = sal::static_int_cast< sal_Int16 >(nTmpValue);
189  break;
190 
191  default:
192  SAL_INFO("xmloff.style", "Unknown token at import transparency gradient style");
193  }
194  }
195 
196  rValue <<= aGradient;
197 
198  if( !aDisplayName.isEmpty() )
199  {
201  aDisplayName );
202  rStrName = aDisplayName;
203  }
204 }
205 
206 // Export
207 
209  : rExport(rExp)
210 {
211 }
212 
214 {
215 }
216 
218  const OUString& rStrName,
219  const uno::Any& rValue )
220 {
221  awt::Gradient aGradient;
222 
223  if( rStrName.isEmpty() )
224  return;
225 
226  if( !(rValue >>= aGradient) )
227  return;
228 
229  OUString aStrValue;
230  OUStringBuffer aOut;
231 
232  // Style
233  if( !SvXMLUnitConverter::convertEnum( aOut, aGradient.Style, pXML_GradientStyle_Enum ) )
234  return;
235 
236  // Name
237  bool bEncoded = false;
239  rExport.EncodeStyleName( rStrName,
240  &bEncoded ) );
241  if( bEncoded )
243  rStrName );
244 
245  aStrValue = aOut.makeStringAndClear();
247 
248  // Center x/y
249  if( aGradient.Style != awt::GradientStyle_LINEAR &&
250  aGradient.Style != awt::GradientStyle_AXIAL )
251  {
252  ::sax::Converter::convertPercent(aOut, aGradient.XOffset);
253  aStrValue = aOut.makeStringAndClear();
255 
256  ::sax::Converter::convertPercent(aOut, aGradient.YOffset);
257  aStrValue = aOut.makeStringAndClear();
259  }
260 
261  // Transparency start
262  Color aColor(aGradient.StartColor);
263  sal_Int32 aStartValue = 100 - static_cast<sal_Int32>(((aColor.GetRed() + 1) * 100) / 255);
264  ::sax::Converter::convertPercent( aOut, aStartValue );
265  aStrValue = aOut.makeStringAndClear();
267 
268  // Transparency end
269  aColor = Color(aGradient.EndColor);
270  sal_Int32 aEndValue = 100 - static_cast<sal_Int32>(((aColor.GetRed() + 1) * 100) / 255);
271  ::sax::Converter::convertPercent( aOut, aEndValue );
272  aStrValue = aOut.makeStringAndClear();
274 
275  // Angle
276  if( aGradient.Style != awt::GradientStyle_RADIAL )
277  {
279  aStrValue = aOut.makeStringAndClear();
281  }
282 
283  // Border
284  ::sax::Converter::convertPercent( aOut, aGradient.Border );
285  aStrValue = aOut.makeStringAndClear();
287 
288  // Do Write
291  true, false );
292 }
293 
294 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XMLTokenEnum const aTokenMap[]
Definition: Oasis2OOo.cxx:1145
static bool convertEnum(EnumT &rEnum, const OUString &rValue, const SvXMLEnumMapEntry< EnumT > *pMap)
convert string to enum using given enum map, if the enum is not found in the map, this method will re...
Definition: xmluconv.hxx:128
sal_uInt8 GetRed() const
void importXML(const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList, css::uno::Any &rValue, OUString &rStrName)
SvXMLTokenMapAttrs
#define SAL_INFO_IF(condition, area, stream)
#define ODFVER_012_TEXT
sal_Int64 n
SvXMLNamespaceMap & GetNamespaceMap()
Definition: xmlimp.hxx:401
sal_uInt16 GetKeyByAttrName(const OUString &rAttrName, OUString *pPrefix, OUString *pLocalName, OUString *pNamespace) const
Definition: nmspmap.cxx:437
#define XML_TOKEN_MAP_END
Definition: xmltkmap.hxx:33
css::uno::Any const & rValue
Definition: ImageStyle.hxx:38
static const sal_uInt16 LO_7x
Definition: xmlimp.hxx:565
sal_uInt16 getGeneratorVersion() const
this checks the build ID and returns
Definition: xmlimp.cxx:1945
void AddAttribute(sal_uInt16 nPrefix, const char *pName, const OUString &rValue)
Definition: xmlexp.cxx:909
static const sal_uInt16 AOO_4x
Definition: xmlimp.hxx:554
static void convertAngle(OUStringBuffer &rBuffer, sal_Int16 nAngle, SvtSaveOptions::ODFSaneDefaultVersion nVersion)
XMLTransGradientStyleImport(SvXMLImport &rImport)
constexpr sal_uInt16 XML_NAMESPACE_DRAW
Definition: xmlnmspe.hxx:33
SvtSaveOptions::ODFSaneDefaultVersion getSaneDefaultVersion() const
returns the deterministic version for odf export
Definition: xmlexp.cxx:2297
int i
sal_uInt16 Get(sal_uInt16 nPrefix, const OUString &rLName) const
Definition: xmltkmap.cxx:93
OUString EncodeStyleName(const OUString &rName, bool *pEncoded=nullptr) const
Definition: xmlexp.cxx:1954
Map an XMLTokenEnum to an enum value.
Definition: ximpshap.hxx:40
SvXMLEnumMapEntry< awt::GradientStyle > const pXML_GradientStyle_Enum[]
XMLTransGradientStyleExport(SvXMLExport &rExport)
OUString const & GetODFVersion() const
Definition: xmlimp.cxx:1964
unsigned char sal_uInt8
Handling of tokens in XML:
#define SAL_INFO(area, stream)
void AddStyleDisplayName(XmlStyleFamily nFamily, const OUString &rName, const OUString &rDisplayName)
Definition: xmlimp.cxx:1474
bool isGeneratorVersionOlderThan(sal_uInt16 const nOOoVersion, sal_uInt16 const nLOVersion)
depending on whether the generator version indicates LO, compare against either the given LO or given...
Definition: xmlimp.cxx:1952
void exportXML(const OUString &rStrName, const css::uno::Any &rValue)
css::uno::Any const SvXMLExport & rExport
Definition: ImageStyle.hxx:38
static bool convertPercent(sal_Int32 &rValue, const OUString &rString)