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/namespacemap.hxx>
28 #include <xmloff/xmluconv.hxx>
29 #include <xmloff/xmlnamespace.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::XFastAttributeList >& 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  for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
98  {
99  const OUString aStrValue = aIter.toString();
100 
101  sal_Int32 nTmpValue;
102 
103  switch( aIter.getToken() )
104  {
105  case XML_ELEMENT(DRAW, XML_NAME):
106  {
107  rStrName = aStrValue;
108  }
109  break;
111  {
112  aDisplayName = aStrValue;
113  }
114  break;
115  case XML_ELEMENT(DRAW, XML_STYLE):
116  {
117  SvXMLUnitConverter::convertEnum( aGradient.Style, aStrValue, pXML_GradientStyle_Enum );
118  }
119  break;
120  case XML_ELEMENT(DRAW, XML_CX):
121  ::sax::Converter::convertPercent( nTmpValue, aStrValue );
122  aGradient.XOffset = sal::static_int_cast< sal_Int16 >(nTmpValue);
123  break;
124  case XML_ELEMENT(DRAW, XML_CY):
125  ::sax::Converter::convertPercent( nTmpValue, aStrValue );
126  aGradient.YOffset = sal::static_int_cast< sal_Int16 >(nTmpValue);
127  break;
128  case XML_ELEMENT(DRAW, XML_START):
129  {
130  sal_Int32 aStartTransparency;
131  ::sax::Converter::convertPercent( aStartTransparency, aStrValue );
132 
133  sal_uInt8 n = sal::static_int_cast< sal_uInt8 >(
134  ( (100 - aStartTransparency) * 255 ) / 100 );
135 
136  Color aColor( n, n, n );
137  aGradient.StartColor = static_cast<sal_Int32>( aColor );
138  }
139  break;
140  case XML_ELEMENT(DRAW, XML_END):
141  {
142  sal_Int32 aEndTransparency;
143  ::sax::Converter::convertPercent( aEndTransparency, aStrValue );
144 
145  sal_uInt8 n = sal::static_int_cast< sal_uInt8 >(
146  ( (100 - aEndTransparency) * 255 ) / 100 );
147 
148  Color aColor( n, n, n );
149  aGradient.EndColor = static_cast<sal_Int32>( aColor );
150  }
151  break;
153  {
154  auto const cmp12(rImport.GetODFVersion().compareTo(ODFVER_012_TEXT));
155  bool const bSuccess =
156  ::sax::Converter::convertAngle(aGradient.Angle, aStrValue,
157  // tdf#89475 try to detect borked OOo angles
158  (cmp12 < 0) || (cmp12 == 0
160  // also for AOO 4.x, assume there won't ever be a 4.2
162  SAL_INFO_IF(!bSuccess, "xmloff.style", "failed to import draw:angle");
163  }
164  break;
165  case XML_ELEMENT(DRAW, XML_BORDER):
166  ::sax::Converter::convertPercent( nTmpValue, aStrValue );
167  aGradient.Border = sal::static_int_cast< sal_Int16 >(nTmpValue);
168  break;
169 
170  default:
171  SAL_WARN("xmloff.style", "unknown attribute " << SvXMLImport::getPrefixAndNameFromToken(aIter.getToken()) << "=" << aStrValue);
172  }
173  }
174 
175  rValue <<= aGradient;
176 
177  if( !aDisplayName.isEmpty() )
178  {
180  aDisplayName );
181  rStrName = aDisplayName;
182  }
183 }
184 
185 // Export
186 
188  : rExport(rExp)
189 {
190 }
191 
193 {
194 }
195 
197  const OUString& rStrName,
198  const uno::Any& rValue )
199 {
200  awt::Gradient aGradient;
201 
202  if( rStrName.isEmpty() )
203  return;
204 
205  if( !(rValue >>= aGradient) )
206  return;
207 
208  OUString aStrValue;
209  OUStringBuffer aOut;
210 
211  // Style
212  if( !SvXMLUnitConverter::convertEnum( aOut, aGradient.Style, pXML_GradientStyle_Enum ) )
213  return;
214 
215  // Name
216  bool bEncoded = false;
218  rExport.EncodeStyleName( rStrName,
219  &bEncoded ) );
220  if( bEncoded )
222  rStrName );
223 
224  aStrValue = aOut.makeStringAndClear();
226 
227  // Center x/y
228  if( aGradient.Style != awt::GradientStyle_LINEAR &&
229  aGradient.Style != awt::GradientStyle_AXIAL )
230  {
231  ::sax::Converter::convertPercent(aOut, aGradient.XOffset);
232  aStrValue = aOut.makeStringAndClear();
234 
235  ::sax::Converter::convertPercent(aOut, aGradient.YOffset);
236  aStrValue = aOut.makeStringAndClear();
238  }
239 
240  // Transparency start
241  Color aColor(aGradient.StartColor);
242  sal_Int32 aStartValue = 100 - static_cast<sal_Int32>(((aColor.GetRed() + 1) * 100) / 255);
243  ::sax::Converter::convertPercent( aOut, aStartValue );
244  aStrValue = aOut.makeStringAndClear();
246 
247  // Transparency end
248  aColor = Color(aGradient.EndColor);
249  sal_Int32 aEndValue = 100 - static_cast<sal_Int32>(((aColor.GetRed() + 1) * 100) / 255);
250  ::sax::Converter::convertPercent( aOut, aEndValue );
251  aStrValue = aOut.makeStringAndClear();
253 
254  // Angle
255  if( aGradient.Style != awt::GradientStyle_RADIAL )
256  {
258  aStrValue = aOut.makeStringAndClear();
260  }
261 
262  // Border
263  ::sax::Converter::convertPercent( aOut, aGradient.Border );
264  aStrValue = aOut.makeStringAndClear();
266 
267  // Do Write
270  true, false );
271 }
272 
273 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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
SvXMLTokenMapAttrs
#define SAL_INFO_IF(condition, area, stream)
#define ODFVER_012_TEXT
sal_Int64 n
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
css::uno::Any const & rValue
Definition: ImageStyle.hxx:38
static const sal_uInt16 LO_7x
Definition: xmlimp.hxx:558
sal_uInt16 getGeneratorVersion() const
this checks the build ID and returns
Definition: xmlimp.cxx:1909
DRAW
void AddAttribute(sal_uInt16 nPrefix, const char *pName, const OUString &rValue)
Definition: xmlexp.cxx:909
static OUString getPrefixAndNameFromToken(sal_Int32 nToken)
Definition: xmlimp.cxx:2000
static const sal_uInt16 AOO_4x
Definition: xmlimp.hxx:547
static void convertAngle(OUStringBuffer &rBuffer, sal_Int16 nAngle, SvtSaveOptions::ODFSaneDefaultVersion nVersion)
constexpr sal_uInt16 XML_NAMESPACE_DRAW
XMLTransGradientStyleImport(SvXMLImport &rImport)
SvtSaveOptions::ODFSaneDefaultVersion getSaneDefaultVersion() const
returns the deterministic version for odf export
Definition: xmlexp.cxx:2297
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 GetODFVersion() const
Definition: xmlimp.cxx:1928
unsigned char sal_uInt8
Handling of tokens in XML:
#define XML_ELEMENT(prefix, name)
Definition: xmlimp.hxx:94
void importXML(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList, css::uno::Any &rValue, OUString &rStrName)
void AddStyleDisplayName(XmlStyleFamily nFamily, const OUString &rName, const OUString &rDisplayName)
Definition: xmlimp.cxx:1438
#define SAL_WARN(area, stream)
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:1916
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)