Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / oox / source / drawingml / fillproperties.cxx
blobc64b0862d225298cf0e53c34748a1f63a82d854b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <drawingml/fillproperties.hxx>
22 #include <iterator>
24 #include <drawingml/graphicproperties.hxx>
26 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 #include <com/sun/star/beans/XPropertySet.hpp>
28 #include <com/sun/star/awt/Gradient.hpp>
29 #include <com/sun/star/text/GraphicCrop.hpp>
30 #include <com/sun/star/awt/Size.hpp>
31 #include <com/sun/star/awt/XBitmap.hpp>
32 #include <com/sun/star/drawing/BitmapMode.hpp>
33 #include <com/sun/star/drawing/ColorMode.hpp>
34 #include <com/sun/star/drawing/FillStyle.hpp>
35 #include <com/sun/star/drawing/Hatch.hpp>
36 #include <com/sun/star/drawing/RectanglePoint.hpp>
37 #include <com/sun/star/graphic/XGraphicTransformer.hpp>
38 #include <oox/core/fragmenthandler.hxx>
39 #include <oox/helper/graphichelper.hxx>
40 #include <oox/drawingml/drawingmltypes.hxx>
41 #include <oox/drawingml/shapepropertymap.hxx>
42 #include <oox/token/namespaces.hxx>
43 #include <oox/token/properties.hxx>
44 #include <oox/token/tokens.hxx>
45 #include <rtl/math.hxx>
46 #include <osl/diagnose.h>
47 #include <sal/log.hxx>
49 using namespace ::com::sun::star;
50 using namespace ::com::sun::star::drawing;
51 using namespace ::com::sun::star::graphic;
53 using ::com::sun::star::uno::Reference;
54 using ::com::sun::star::uno::Exception;
55 using ::com::sun::star::uno::UNO_QUERY_THROW;
56 using ::com::sun::star::geometry::IntegerRectangle2D;
58 namespace oox {
59 namespace drawingml {
61 namespace {
63 Reference< XGraphic > lclCheckAndApplyDuotoneTransform(const BlipFillProperties& aBlipProps, uno::Reference<graphic::XGraphic> const & xGraphic,
64 const GraphicHelper& rGraphicHelper, const ::Color nPhClr)
66 if (aBlipProps.maDuotoneColors[0].isUsed() && aBlipProps.maDuotoneColors[1].isUsed())
68 ::Color nColor1 = aBlipProps.maDuotoneColors[0].getColor( rGraphicHelper, nPhClr );
69 ::Color nColor2 = aBlipProps.maDuotoneColors[1].getColor( rGraphicHelper, nPhClr );
71 uno::Reference<graphic::XGraphicTransformer> xTransformer(aBlipProps.mxFillGraphic, uno::UNO_QUERY);
72 if (xTransformer.is())
73 return xTransformer->applyDuotone(xGraphic, sal_Int32(nColor1), sal_Int32(nColor2));
75 return xGraphic;
78 Reference< XGraphic > lclCheckAndApplyChangeColorTransform(const BlipFillProperties &aBlipProps, uno::Reference<graphic::XGraphic> const & xGraphic,
79 const GraphicHelper& rGraphicHelper, const ::Color nPhClr)
81 if( aBlipProps.maColorChangeFrom.isUsed() && aBlipProps.maColorChangeTo.isUsed() )
83 ::Color nFromColor = aBlipProps.maColorChangeFrom.getColor( rGraphicHelper, nPhClr );
84 ::Color nToColor = aBlipProps.maColorChangeTo.getColor( rGraphicHelper, nPhClr );
85 if ( (nFromColor != nToColor) || aBlipProps.maColorChangeTo.hasTransparency() )
87 sal_Int16 nToTransparence = aBlipProps.maColorChangeTo.getTransparency();
88 sal_Int8 nToAlpha = static_cast< sal_Int8 >( (100 - nToTransparence) * 2.55 );
90 uno::Reference<graphic::XGraphicTransformer> xTransformer(aBlipProps.mxFillGraphic, uno::UNO_QUERY);
91 if (xTransformer.is())
92 return xTransformer->colorChange(xGraphic, sal_Int32(nFromColor), 9, sal_Int32(nToColor), nToAlpha);
95 return xGraphic;
98 uno::Reference<graphic::XGraphic> applyBrightnessContrast(uno::Reference<graphic::XGraphic> const & xGraphic, sal_Int32 brightness, sal_Int32 contrast)
100 uno::Reference<graphic::XGraphicTransformer> xTransformer(xGraphic, uno::UNO_QUERY);
101 if (xTransformer.is())
102 return xTransformer->applyBrightnessContrast(xGraphic, brightness, contrast, true);
103 return xGraphic;
106 BitmapMode lclGetBitmapMode( sal_Int32 nToken )
108 OSL_ASSERT((nToken & sal_Int32(0xFFFF0000))==0);
109 switch( nToken )
111 case XML_tile: return BitmapMode_REPEAT;
112 case XML_stretch: return BitmapMode_STRETCH;
114 return BitmapMode_NO_REPEAT;
117 RectanglePoint lclGetRectanglePoint( sal_Int32 nToken )
119 OSL_ASSERT((nToken & sal_Int32(0xFFFF0000))==0);
120 switch( nToken )
122 case XML_tl: return RectanglePoint_LEFT_TOP;
123 case XML_t: return RectanglePoint_MIDDLE_TOP;
124 case XML_tr: return RectanglePoint_RIGHT_TOP;
125 case XML_l: return RectanglePoint_LEFT_MIDDLE;
126 case XML_ctr: return RectanglePoint_MIDDLE_MIDDLE;
127 case XML_r: return RectanglePoint_RIGHT_MIDDLE;
128 case XML_bl: return RectanglePoint_LEFT_BOTTOM;
129 case XML_b: return RectanglePoint_MIDDLE_BOTTOM;
130 case XML_br: return RectanglePoint_RIGHT_BOTTOM;
132 return RectanglePoint_LEFT_TOP;
135 awt::Size lclGetOriginalSize( const GraphicHelper& rGraphicHelper, const Reference< XGraphic >& rxGraphic )
137 awt::Size aSizeHmm( 0, 0 );
140 Reference< beans::XPropertySet > xGraphicPropertySet( rxGraphic, UNO_QUERY_THROW );
141 if( xGraphicPropertySet->getPropertyValue( "Size100thMM" ) >>= aSizeHmm )
143 if( !aSizeHmm.Width && !aSizeHmm.Height )
144 { // MAPMODE_PIXEL USED :-(
145 awt::Size aSourceSizePixel( 0, 0 );
146 if( xGraphicPropertySet->getPropertyValue( "SizePixel" ) >>= aSourceSizePixel )
147 aSizeHmm = rGraphicHelper.convertScreenPixelToHmm( aSourceSizePixel );
151 catch( Exception& )
154 return aSizeHmm;
158 * Looks for a last gradient transition and possibly sets a gradient border
159 * based on that.
161 void extractGradientBorderFromStops(const GradientFillProperties& rGradientProps,
162 const GraphicHelper& rGraphicHelper, ::Color nPhClr,
163 awt::Gradient& rGradient)
165 if (rGradientProps.maGradientStops.size() <= 1)
166 return;
168 auto it = rGradientProps.maGradientStops.rbegin();
169 double fLastPos = it->first;
170 Color aLastColor = it->second;
171 ++it;
172 double fLastButOnePos = it->first;
173 Color aLastButOneColor = it->second;
174 if (!aLastColor.equals(aLastButOneColor, rGraphicHelper, nPhClr))
175 return;
177 // Last transition has the same color, we can map that to a border.
178 rGradient.Border = rtl::math::round((fLastPos - fLastButOnePos) * 100);
181 } // namespace
183 void GradientFillProperties::assignUsed( const GradientFillProperties& rSourceProps )
185 if( !rSourceProps.maGradientStops.empty() )
186 maGradientStops = rSourceProps.maGradientStops;
187 moFillToRect.assignIfUsed( rSourceProps.moFillToRect );
188 moTileRect.assignIfUsed( rSourceProps.moTileRect );
189 moGradientPath.assignIfUsed( rSourceProps.moGradientPath );
190 moShadeAngle.assignIfUsed( rSourceProps.moShadeAngle );
191 moShadeFlip.assignIfUsed( rSourceProps.moShadeFlip );
192 moShadeScaled.assignIfUsed( rSourceProps.moShadeScaled );
193 moRotateWithShape.assignIfUsed( rSourceProps.moRotateWithShape );
196 void PatternFillProperties::assignUsed( const PatternFillProperties& rSourceProps )
198 maPattFgColor.assignIfUsed( rSourceProps.maPattFgColor );
199 maPattBgColor.assignIfUsed( rSourceProps.maPattBgColor );
200 moPattPreset.assignIfUsed( rSourceProps.moPattPreset );
203 void BlipFillProperties::assignUsed( const BlipFillProperties& rSourceProps )
205 if(rSourceProps.mxFillGraphic.is())
206 mxFillGraphic = rSourceProps.mxFillGraphic;
207 moBitmapMode.assignIfUsed( rSourceProps.moBitmapMode );
208 moFillRect.assignIfUsed( rSourceProps.moFillRect );
209 moTileOffsetX.assignIfUsed( rSourceProps.moTileOffsetX );
210 moTileOffsetY.assignIfUsed( rSourceProps.moTileOffsetY );
211 moTileScaleX.assignIfUsed( rSourceProps.moTileScaleX );
212 moTileScaleY.assignIfUsed( rSourceProps.moTileScaleY );
213 moTileAlign.assignIfUsed( rSourceProps.moTileAlign );
214 moTileFlip.assignIfUsed( rSourceProps.moTileFlip );
215 moRotateWithShape.assignIfUsed( rSourceProps.moRotateWithShape );
216 moColorEffect.assignIfUsed( rSourceProps.moColorEffect );
217 moBrightness.assignIfUsed( rSourceProps.moBrightness );
218 moContrast.assignIfUsed( rSourceProps.moContrast );
219 maColorChangeFrom.assignIfUsed( rSourceProps.maColorChangeFrom );
220 maColorChangeTo.assignIfUsed( rSourceProps.maColorChangeTo );
221 maDuotoneColors[0].assignIfUsed( rSourceProps.maDuotoneColors[0] );
222 maDuotoneColors[1].assignIfUsed( rSourceProps.maDuotoneColors[1] );
223 maEffect.assignUsed( rSourceProps.maEffect );
224 moAlphaModFix.assignIfUsed(rSourceProps.moAlphaModFix);
227 void FillProperties::assignUsed( const FillProperties& rSourceProps )
229 moFillType.assignIfUsed( rSourceProps.moFillType );
230 maFillColor.assignIfUsed( rSourceProps.maFillColor );
231 maGradientProps.assignUsed( rSourceProps.maGradientProps );
232 maPatternProps.assignUsed( rSourceProps.maPatternProps );
233 maBlipProps.assignUsed( rSourceProps.maBlipProps );
236 Color FillProperties::getBestSolidColor() const
238 Color aSolidColor;
239 if( moFillType.has() ) switch( moFillType.get() )
241 case XML_solidFill:
242 aSolidColor = maFillColor;
243 break;
244 case XML_gradFill:
245 if( !maGradientProps.maGradientStops.empty() )
247 GradientFillProperties::GradientStopMap::const_iterator aGradientStop =
248 maGradientProps.maGradientStops.begin();
249 if (maGradientProps.maGradientStops.size() > 2)
250 ++aGradientStop;
251 aSolidColor = aGradientStop->second;
253 break;
254 case XML_pattFill:
255 aSolidColor = maPatternProps.maPattBgColor.isUsed() ? maPatternProps.maPattBgColor : maPatternProps.maPattFgColor;
256 break;
258 return aSolidColor;
261 /// Maps the hatch token to drawing::Hatch.
262 static drawing::Hatch createHatch( sal_Int32 nHatchToken, ::Color nColor )
264 drawing::Hatch aHatch;
265 aHatch.Color = sal_Int32(nColor);
267 // best-effort mapping; we do not support all the styles in core
268 switch ( nHatchToken )
270 case XML_pct5: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 250; aHatch.Angle = 450; break;
271 case XML_pct10: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 200; aHatch.Angle = 450; break;
272 case XML_pct20: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 150; aHatch.Angle = 450; break;
273 case XML_pct25: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 200; aHatch.Angle = 450; break;
274 case XML_pct30: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 175; aHatch.Angle = 450; break;
275 case XML_pct40: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 150; aHatch.Angle = 450; break;
276 case XML_pct50: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 125; aHatch.Angle = 450; break;
277 case XML_pct60: aHatch.Style = drawing::HatchStyle_TRIPLE; aHatch.Distance = 150; aHatch.Angle = 450; break;
278 case XML_pct70: aHatch.Style = drawing::HatchStyle_TRIPLE; aHatch.Distance = 125; aHatch.Angle = 450; break;
279 case XML_pct75: aHatch.Style = drawing::HatchStyle_TRIPLE; aHatch.Distance = 100; aHatch.Angle = 450; break;
280 case XML_pct80: aHatch.Style = drawing::HatchStyle_TRIPLE; aHatch.Distance = 75; aHatch.Angle = 450; break;
281 case XML_pct90: aHatch.Style = drawing::HatchStyle_TRIPLE; aHatch.Distance = 50; aHatch.Angle = 450; break;
282 case XML_horz: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 100; aHatch.Angle = 0; break;
283 case XML_vert: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 100; aHatch.Angle = 900; break;
284 case XML_ltHorz: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 50; aHatch.Angle = 0; break;
285 case XML_ltVert: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 50; aHatch.Angle = 900; break;
286 case XML_dkHorz: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 25; aHatch.Angle = 0; break;
287 case XML_dkVert: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 25; aHatch.Angle = 900; break;
288 case XML_narHorz: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 50; aHatch.Angle = 0; break;
289 case XML_narVert: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 50; aHatch.Angle = 900; break;
290 case XML_dashHorz: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 150; aHatch.Angle = 0; break;
291 case XML_dashVert: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 150; aHatch.Angle = 900; break;
292 case XML_cross: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 100; aHatch.Angle = 0; break;
293 case XML_dnDiag: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 100; aHatch.Angle = 1350; break;
294 case XML_upDiag: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 100; aHatch.Angle = 450; break;
295 case XML_ltDnDiag: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 50; aHatch.Angle = 1350; break;
296 case XML_ltUpDiag: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 50; aHatch.Angle = 450; break;
297 case XML_dkDnDiag: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 50; aHatch.Angle = 1350; break;
298 case XML_dkUpDiag: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 50; aHatch.Angle = 450; break;
299 case XML_wdDnDiag: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 100; aHatch.Angle = 1350; break;
300 case XML_wdUpDiag: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 100; aHatch.Angle = 450; break;
301 case XML_dashDnDiag: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 150; aHatch.Angle = 1350; break;
302 case XML_dashUpDiag: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 150; aHatch.Angle = 450; break;
303 case XML_diagCross: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 100; aHatch.Angle = 450; break;
304 case XML_smCheck: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 50; aHatch.Angle = 450; break;
305 case XML_lgCheck: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 100; aHatch.Angle = 450; break;
306 case XML_smGrid: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 50; aHatch.Angle = 0; break;
307 case XML_lgGrid: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 100; aHatch.Angle = 0; break;
308 case XML_dotGrid: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 400; aHatch.Angle = 0; break;
309 case XML_smConfetti: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 200; aHatch.Angle = 600; break;
310 case XML_lgConfetti: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 100; aHatch.Angle = 600; break;
311 case XML_horzBrick: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 300; aHatch.Angle = 0; break;
312 case XML_diagBrick: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 300; aHatch.Angle = 450; break;
313 case XML_solidDmnd: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 100; aHatch.Angle = 450; break;
314 case XML_openDmnd: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 100; aHatch.Angle = 450; break;
315 case XML_dotDmnd: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 300; aHatch.Angle = 450; break;
316 case XML_plaid: aHatch.Style = drawing::HatchStyle_TRIPLE; aHatch.Distance = 200; aHatch.Angle = 900; break;
317 case XML_sphere: aHatch.Style = drawing::HatchStyle_TRIPLE; aHatch.Distance = 100; aHatch.Angle = 0; break;
318 case XML_weave: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 150; aHatch.Angle = 450; break;
319 case XML_divot: aHatch.Style = drawing::HatchStyle_TRIPLE; aHatch.Distance = 400; aHatch.Angle = 450; break;
320 case XML_shingle: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 200; aHatch.Angle = 1350; break;
321 case XML_wave: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 100; aHatch.Angle = 0; break;
322 case XML_trellis: aHatch.Style = drawing::HatchStyle_DOUBLE; aHatch.Distance = 75; aHatch.Angle = 450; break;
323 case XML_zigZag: aHatch.Style = drawing::HatchStyle_SINGLE; aHatch.Distance = 75; aHatch.Angle = 0; break;
326 return aHatch;
329 void FillProperties::pushToPropMap( ShapePropertyMap& rPropMap,
330 const GraphicHelper& rGraphicHelper, sal_Int32 nShapeRotation, ::Color nPhClr,
331 bool bFlipH, bool bFlipV ) const
333 if( moFillType.has() )
335 FillStyle eFillStyle = FillStyle_NONE;
336 OSL_ASSERT((moFillType.get() & sal_Int32(0xFFFF0000))==0);
337 switch( moFillType.get() )
339 case XML_noFill:
340 eFillStyle = FillStyle_NONE;
341 break;
343 case XML_solidFill:
344 if( maFillColor.isUsed() )
346 rPropMap.setProperty( ShapeProperty::FillColor, maFillColor.getColor( rGraphicHelper, nPhClr ) );
347 if( maFillColor.hasTransparency() )
348 rPropMap.setProperty( ShapeProperty::FillTransparency, maFillColor.getTransparency() );
349 eFillStyle = FillStyle_SOLID;
351 break;
353 case XML_gradFill:
354 // do not create gradient struct if property is not supported...
355 if( rPropMap.supportsProperty( ShapeProperty::FillGradient ) )
357 sal_Int32 nEndTrans = 0;
358 sal_Int32 nStartTrans = 0;
359 awt::Gradient aGradient;
360 aGradient.Angle = 900;
361 aGradient.StartIntensity = 100;
362 aGradient.EndIntensity = 100;
364 // Old code, values in aGradient overwritten in many cases by newer code below
365 if( maGradientProps.maGradientStops.size() > 1 )
367 aGradient.StartColor = sal_Int32(maGradientProps.maGradientStops.begin()->second.getColor( rGraphicHelper, nPhClr ));
368 aGradient.EndColor = sal_Int32(maGradientProps.maGradientStops.rbegin()->second.getColor( rGraphicHelper, nPhClr ));
369 if( maGradientProps.maGradientStops.rbegin()->second.hasTransparency() )
370 nEndTrans = maGradientProps.maGradientStops.rbegin()->second.getTransparency()*255/100;
371 if( maGradientProps.maGradientStops.begin()->second.hasTransparency() )
372 nStartTrans = maGradientProps.maGradientStops.begin()->second.getTransparency()*255/100;
375 // "rotate with shape" set to false -> do not rotate
376 if ( !maGradientProps.moRotateWithShape.get( true ) )
377 nShapeRotation = 0;
379 if( maGradientProps.moGradientPath.has() )
381 // position of gradient center (limited to [30%;100%], otherwise gradient is too hidden)
382 IntegerRectangle2D aFillToRect = maGradientProps.moFillToRect.get( IntegerRectangle2D( 0, 0, MAX_PERCENT, MAX_PERCENT ) );
383 sal_Int32 nCenterX = (MAX_PERCENT + aFillToRect.X1 - aFillToRect.X2) / 2;
384 aGradient.XOffset = getLimitedValue<sal_Int16, sal_Int32>(
385 nCenterX / PER_PERCENT, 30, 100);
387 // Style should be radial at least when the horizontal center is at 50%.
388 awt::GradientStyle eCircle = aGradient.XOffset == 50
389 ? awt::GradientStyle_RADIAL
390 : awt::GradientStyle_ELLIPTICAL;
391 aGradient.Style = (maGradientProps.moGradientPath.get() == XML_circle)
392 ? eCircle
393 : awt::GradientStyle_RECT;
395 sal_Int32 nCenterY = (MAX_PERCENT + aFillToRect.Y1 - aFillToRect.Y2) / 2;
396 aGradient.YOffset = getLimitedValue<sal_Int16, sal_Int32>(
397 nCenterY / PER_PERCENT, 30, 100);
398 ::std::swap( aGradient.StartColor, aGradient.EndColor );
399 ::std::swap( nStartTrans, nEndTrans );
401 extractGradientBorderFromStops(maGradientProps, rGraphicHelper, nPhClr,
402 aGradient);
404 else if (!maGradientProps.maGradientStops.empty())
406 // A copy of the gradient stops for local modification
407 GradientFillProperties::GradientStopMap aGradientStops(maGradientProps.maGradientStops);
409 // Add a fake gradient stop at 0% and 100% if necessary, so that the gradient always starts
410 // at 0% and ends at 100%, to make following logic clearer (?).
411 auto a0 = aGradientStops.find( 0.0 );
412 if( a0 == aGradientStops.end() )
414 // temp variable required
415 Color aFirstColor(aGradientStops.begin()->second);
416 aGradientStops.emplace( 0.0, aFirstColor );
419 auto a1 = aGradientStops.find( 1.0 );
420 if( a1 == aGradientStops.end() )
422 // ditto
423 Color aLastColor(aGradientStops.rbegin()->second);
424 aGradientStops.emplace( 1.0, aLastColor );
427 // Check if the gradient is symmetric, which we will emulate with an "axial" gradient.
428 bool bSymmetric(true);
430 GradientFillProperties::GradientStopMap::const_iterator aItA( aGradientStops.begin() );
431 GradientFillProperties::GradientStopMap::const_iterator aItZ(std::prev(aGradientStops.end()));
432 while( bSymmetric && aItA->first < aItZ->first )
434 if (!aItA->second.equals(aItZ->second, rGraphicHelper, nPhClr))
435 bSymmetric = false;
436 else
438 ++aItA;
439 aItZ = std::prev(aItZ);
442 // Don't be fooled if the middlemost stop isn't at 0.5.
443 if( bSymmetric && aItA == aItZ && aItA->first != 0.5 )
444 bSymmetric = false;
446 // If symmetric, do the rest of the logic for just a half.
447 if( bSymmetric )
449 // aItZ already points to the colour for the middle, but insert a fake stop at the
450 // exact middle if necessary.
451 if( aItA->first != aItZ->first )
453 Color aMiddleColor = aItZ->second;
454 auto a05 = aGradientStops.find( 0.5 );
456 if( a05 != aGradientStops.end() )
457 a05->second = aMiddleColor;
458 else
459 aGradientStops.emplace( 0.5, aMiddleColor );
461 // Drop the rest of the stops
462 while( aGradientStops.rbegin()->first > 0.5 )
463 aGradientStops.erase( aGradientStops.rbegin()->first );
467 SAL_INFO("oox.drawingml.gradient", "symmetric: " << (bSymmetric ? "YES" : "NO") <<
468 ", number of stops: " << aGradientStops.size());
469 size_t nIndex = 0;
470 for (auto const& gradientStop : aGradientStops)
471 SAL_INFO("oox.drawingml.gradient", " " << nIndex++ << ": " <<
472 gradientStop.first << ": " <<
473 std::hex << sal_Int32(gradientStop.second.getColor( rGraphicHelper, nPhClr )) << std::dec <<
474 "@" << (100 - gradientStop.second.getTransparency()) << "%");
476 // Now estimate the simple LO style gradient (only two stops, at n% and 100%, where n ==
477 // the "border") that best emulates the gradient between begin() and prior(end()).
479 // First look for the largest segment in the gradient.
480 GradientFillProperties::GradientStopMap::iterator aIt(aGradientStops.begin());
481 double nWidestWidth = -1;
482 GradientFillProperties::GradientStopMap::iterator aWidestSegmentStart;
483 ++aIt;
484 while( aIt != aGradientStops.end() )
486 if (aIt->first - std::prev(aIt)->first > nWidestWidth)
488 nWidestWidth = aIt->first - std::prev(aIt)->first;
489 aWidestSegmentStart = std::prev(aIt);
491 ++aIt;
493 assert( nWidestWidth > 0 );
495 double nBorder = 0;
496 bool bSwap(false);
498 // Do we have just two segments, and either one is of uniform colour, or three or more
499 // segments, and the widest one is the first or last one, and is it of uniform colour? If
500 // so, deduce the border from it, and drop that segment.
501 if( aGradientStops.size() == 3 &&
502 aGradientStops.begin()->second.getColor(rGraphicHelper, nPhClr) == std::next(aGradientStops.begin())->second.getColor(rGraphicHelper, nPhClr) &&
503 aGradientStops.begin()->second.getTransparency() == std::next(aGradientStops.begin())->second.getTransparency())
505 // Two segments, first is uniformly coloured
506 SAL_INFO("oox.drawingml.gradient", "two segments, first is uniformly coloured");
507 nBorder = std::next(aGradientStops.begin())->first - aGradientStops.begin()->first;
508 aGradientStops.erase(aGradientStops.begin());
509 aWidestSegmentStart = aGradientStops.begin();
511 else if( !bSymmetric &&
512 aGradientStops.size() == 3 &&
513 std::next(aGradientStops.begin())->second.getColor(rGraphicHelper, nPhClr) == std::prev(aGradientStops.end())->second.getColor(rGraphicHelper, nPhClr) &&
514 std::next(aGradientStops.begin())->second.getTransparency() == std::prev(aGradientStops.end())->second.getTransparency())
516 // Two segments, second is uniformly coloured
517 SAL_INFO("oox.drawingml.gradient", "two segments, second is uniformly coloured");
518 nBorder = std::prev(aGradientStops.end())->first - std::next(aGradientStops.begin())->first;
519 aGradientStops.erase(std::next(aGradientStops.begin()));
520 aWidestSegmentStart = aGradientStops.begin();
521 bSwap = true;
522 nShapeRotation = 180*60000 - nShapeRotation;
524 else if( !bSymmetric &&
525 aGradientStops.size() >= 4 &&
526 aWidestSegmentStart->second.getColor( rGraphicHelper, nPhClr ) == std::next(aWidestSegmentStart)->second.getColor(rGraphicHelper, nPhClr) &&
527 aWidestSegmentStart->second.getTransparency() == std::next(aWidestSegmentStart)->second.getTransparency() &&
528 ( aWidestSegmentStart == aGradientStops.begin() ||
529 std::next(aWidestSegmentStart) == std::prev(aGradientStops.end())))
531 // Not symmetric, three or more segments, the widest is first or last and is uniformly coloured
532 SAL_INFO("oox.drawingml.gradient", "first or last segment is widest and is uniformly coloured");
533 nBorder = std::next(aWidestSegmentStart)->first - aWidestSegmentStart->first;
535 // If it's the last segment that is uniformly coloured, rotate the gradient 180
536 // degrees and swap start and end colours
537 if (std::next(aWidestSegmentStart) == std::prev(aGradientStops.end()))
539 bSwap = true;
540 nShapeRotation = 180*60000 - nShapeRotation;
543 aGradientStops.erase( aWidestSegmentStart++ );
545 // Look for which is widest now
546 aIt = std::next(aGradientStops.begin());
547 nWidestWidth = -1;
548 while( aIt != aGradientStops.end() )
550 if (aIt->first - std::prev(aIt)->first > nWidestWidth)
552 nWidestWidth = aIt->first - std::prev(aIt)->first;
553 aWidestSegmentStart = std::prev(aIt);
555 ++aIt;
558 SAL_INFO("oox.drawingml.gradient", "widest segment start: " << aWidestSegmentStart->first << ", border: " << nBorder);
559 assert( (!bSymmetric && !bSwap) || !(bSymmetric && bSwap) );
561 // Now we have a potential border and a largest segment. Use those.
563 aGradient.Style = bSymmetric ? awt::GradientStyle_AXIAL : awt::GradientStyle_LINEAR;
564 sal_Int32 nShadeAngle = maGradientProps.moShadeAngle.get( 0 );
565 // Adjust for flips
566 if ( bFlipH )
567 nShadeAngle = 180*60000 - nShadeAngle;
568 if ( bFlipV )
569 nShadeAngle = -nShadeAngle;
570 sal_Int32 nDmlAngle = nShadeAngle + nShapeRotation;
571 // convert DrawingML angle (in 1/60000 degrees) to API angle (in 1/10 degrees)
572 aGradient.Angle = static_cast< sal_Int16 >( (8100 - (nDmlAngle / (PER_DEGREE / 10))) % 3600 );
573 Color aStartColor, aEndColor;
574 if( bSymmetric )
576 aStartColor = std::next(aWidestSegmentStart)->second;
577 aEndColor = aWidestSegmentStart->second;
578 nBorder *= 2;
580 else if( bSwap )
582 aStartColor = std::next(aWidestSegmentStart)->second;
583 aEndColor = aWidestSegmentStart->second;
585 else
587 aStartColor = aWidestSegmentStart->second;
588 aEndColor = std::next(aWidestSegmentStart)->second;
591 SAL_INFO("oox.drawingml.gradient", "start color: " << std::hex << sal_Int32(aStartColor.getColor( rGraphicHelper, nPhClr )) << std::dec <<
592 "@" << (100-aStartColor.getTransparency()) << "%"
593 ", end color: " << std::hex << sal_Int32(aEndColor.getColor( rGraphicHelper, nPhClr )) << std::dec <<
594 "@" << (100-aEndColor.getTransparency()) << "%");
596 aGradient.StartColor = sal_Int32(aStartColor.getColor( rGraphicHelper, nPhClr ));
597 aGradient.EndColor = sal_Int32(aEndColor.getColor( rGraphicHelper, nPhClr ));
599 if( aStartColor.hasTransparency() )
600 nStartTrans = aStartColor.getTransparency()*255/100;
601 if( aEndColor.hasTransparency() )
602 nEndTrans = aEndColor.getTransparency()*255/100;
604 aGradient.Border = rtl::math::round(100*nBorder);
607 // push gradient or named gradient to property map
608 if( rPropMap.setProperty( ShapeProperty::FillGradient, aGradient ) )
609 eFillStyle = FillStyle_GRADIENT;
611 // push gradient transparency to property map
612 if( nStartTrans != 0 || nEndTrans != 0 )
614 awt::Gradient aGrad(aGradient);
615 uno::Any aVal;
616 aGrad.EndColor = static_cast<sal_Int32>( nEndTrans | nEndTrans << 8 | nEndTrans << 16 );
617 aGrad.StartColor = static_cast<sal_Int32>( nStartTrans | nStartTrans << 8 | nStartTrans << 16 );
618 aVal <<= aGrad;
619 rPropMap.setProperty( ShapeProperty::GradientTransparency, aGrad );
623 break;
625 case XML_blipFill:
626 // do not start complex graphic transformation if property is not supported...
627 if (maBlipProps.mxFillGraphic.is() && rPropMap.supportsProperty(ShapeProperty::FillBitmap))
629 uno::Reference<graphic::XGraphic> xGraphic = lclCheckAndApplyDuotoneTransform(maBlipProps, maBlipProps.mxFillGraphic, rGraphicHelper, nPhClr);
630 // TODO: "rotate with shape" is not possible with our current core
632 if (xGraphic.is())
634 if (rPropMap.supportsProperty(ShapeProperty::FillBitmapName) &&
635 rPropMap.setProperty(ShapeProperty::FillBitmapName, xGraphic))
637 eFillStyle = FillStyle_BITMAP;
639 else if (rPropMap.setProperty(ShapeProperty::FillBitmap, xGraphic))
641 eFillStyle = FillStyle_BITMAP;
645 // set other bitmap properties, if bitmap has been inserted into the map
646 if( eFillStyle == FillStyle_BITMAP )
648 // bitmap mode (single, repeat, stretch)
649 BitmapMode eBitmapMode = lclGetBitmapMode( maBlipProps.moBitmapMode.get( XML_TOKEN_INVALID ) );
650 rPropMap.setProperty( ShapeProperty::FillBitmapMode, eBitmapMode );
652 // additional settings for repeated bitmap
653 if( eBitmapMode == BitmapMode_REPEAT )
655 // anchor position inside bitmap
656 RectanglePoint eRectPoint = lclGetRectanglePoint( maBlipProps.moTileAlign.get( XML_tl ) );
657 rPropMap.setProperty( ShapeProperty::FillBitmapRectanglePoint, eRectPoint );
659 awt::Size aOriginalSize = lclGetOriginalSize(rGraphicHelper, maBlipProps.mxFillGraphic);
660 if( (aOriginalSize.Width > 0) && (aOriginalSize.Height > 0) )
662 // size of one bitmap tile (given as 1/1000 percent of bitmap size), convert to 1/100 mm
663 double fScaleX = maBlipProps.moTileScaleX.get( MAX_PERCENT ) / static_cast< double >( MAX_PERCENT );
664 sal_Int32 nFillBmpSizeX = getLimitedValue< sal_Int32, double >( aOriginalSize.Width * fScaleX, 1, SAL_MAX_INT32 );
665 rPropMap.setProperty( ShapeProperty::FillBitmapSizeX, nFillBmpSizeX );
666 double fScaleY = maBlipProps.moTileScaleY.get( MAX_PERCENT ) / static_cast< double >( MAX_PERCENT );
667 sal_Int32 nFillBmpSizeY = getLimitedValue< sal_Int32, double >( aOriginalSize.Height * fScaleY, 1, SAL_MAX_INT32 );
668 rPropMap.setProperty( ShapeProperty::FillBitmapSizeY, nFillBmpSizeY );
670 // offset of the first bitmap tile (given as EMUs), convert to percent
671 sal_Int16 nTileOffsetX = getDoubleIntervalValue< sal_Int16 >( maBlipProps.moTileOffsetX.get( 0 ) / 3.6 / aOriginalSize.Width, 0, 100 );
672 rPropMap.setProperty( ShapeProperty::FillBitmapOffsetX, nTileOffsetX );
673 sal_Int16 nTileOffsetY = getDoubleIntervalValue< sal_Int16 >( maBlipProps.moTileOffsetY.get( 0 ) / 3.6 / aOriginalSize.Height, 0, 100 );
674 rPropMap.setProperty( ShapeProperty::FillBitmapOffsetY, nTileOffsetY );
677 else if ( eBitmapMode == BitmapMode_STRETCH && maBlipProps.moFillRect.has() )
679 geometry::IntegerRectangle2D aFillRect( maBlipProps.moFillRect.get() );
680 awt::Size aOriginalSize( rGraphicHelper.getOriginalSize( xGraphic ) );
681 if ( aOriginalSize.Width && aOriginalSize.Height )
683 text::GraphicCrop aGraphCrop( 0, 0, 0, 0 );
684 if ( aFillRect.X1 )
685 aGraphCrop.Left = static_cast< sal_Int32 >( ( static_cast< double >( aOriginalSize.Width ) * aFillRect.X1 ) / 100000 );
686 if ( aFillRect.Y1 )
687 aGraphCrop.Top = static_cast< sal_Int32 >( ( static_cast< double >( aOriginalSize.Height ) * aFillRect.Y1 ) / 100000 );
688 if ( aFillRect.X2 )
689 aGraphCrop.Right = static_cast< sal_Int32 >( ( static_cast< double >( aOriginalSize.Width ) * aFillRect.X2 ) / 100000 );
690 if ( aFillRect.Y2 )
691 aGraphCrop.Bottom = static_cast< sal_Int32 >( ( static_cast< double >( aOriginalSize.Height ) * aFillRect.Y2 ) / 100000 );
692 rPropMap.setProperty(PROP_GraphicCrop, aGraphCrop);
697 if (maBlipProps.moAlphaModFix.has())
698 rPropMap.setProperty(ShapeProperty::FillTransparency, static_cast<sal_Int16>(100 - (maBlipProps.moAlphaModFix.get() / PER_PERCENT)));
700 break;
702 case XML_pattFill:
704 if( rPropMap.supportsProperty( ShapeProperty::FillHatch ) )
706 Color aColor( maPatternProps.maPattFgColor );
707 if( aColor.isUsed() && maPatternProps.moPattPreset.has() )
709 eFillStyle = FillStyle_HATCH;
710 rPropMap.setProperty( ShapeProperty::FillHatch, createHatch( maPatternProps.moPattPreset.get(), aColor.getColor( rGraphicHelper, nPhClr ) ) );
712 // Set background color for hatch
713 if(maPatternProps.maPattBgColor.isUsed())
715 rPropMap.setProperty( ShapeProperty::FillBackground, true );
716 rPropMap.setProperty( ShapeProperty::FillColor, maPatternProps.maPattBgColor.getColor( rGraphicHelper, nPhClr ) );
719 else if ( maPatternProps.maPattBgColor.isUsed() )
721 aColor = maPatternProps.maPattBgColor;
722 rPropMap.setProperty( ShapeProperty::FillColor, aColor.getColor( rGraphicHelper, nPhClr ) );
723 if( aColor.hasTransparency() )
724 rPropMap.setProperty( ShapeProperty::FillTransparency, aColor.getTransparency() );
725 eFillStyle = FillStyle_SOLID;
729 break;
731 case XML_grpFill:
732 // todo
733 eFillStyle = FillStyle_NONE;
734 break;
737 // set final fill style property
738 rPropMap.setProperty( ShapeProperty::FillStyle, eFillStyle );
742 void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const GraphicHelper& rGraphicHelper) const
744 sal_Int16 nBrightness = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moBrightness.get( 0 ) / PER_PERCENT, -100, 100 );
745 sal_Int16 nContrast = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moContrast.get( 0 ) / PER_PERCENT, -100, 100 );
746 ColorMode eColorMode = ColorMode_STANDARD;
748 switch( maBlipProps.moColorEffect.get( XML_TOKEN_INVALID ) )
750 case XML_biLevel: eColorMode = ColorMode_MONO; break;
751 case XML_grayscl: eColorMode = ColorMode_GREYS; break;
754 if (maBlipProps.mxFillGraphic.is())
756 // created transformed graphic
757 uno::Reference<graphic::XGraphic> xGraphic = lclCheckAndApplyChangeColorTransform(maBlipProps, maBlipProps.mxFillGraphic, rGraphicHelper, API_RGB_TRANSPARENT);
758 xGraphic = lclCheckAndApplyDuotoneTransform(maBlipProps, xGraphic, rGraphicHelper, API_RGB_TRANSPARENT);
760 if (eColorMode == ColorMode_STANDARD && nBrightness == 70 && nContrast == -70)
762 // map MSO 'washout' to our Watermark colormode
763 eColorMode = ColorMode_WATERMARK;
764 nBrightness = 0;
765 nContrast = 0;
767 else if( nBrightness != 0 && nContrast != 0 )
769 // MSO uses a different algorithm for contrast+brightness, LO applies contrast before brightness,
770 // while MSO apparently applies half of brightness before contrast and half after. So if only
771 // contrast or brightness need to be altered, the result is the same, but if both are involved,
772 // there's no way to map that, so just force a conversion of the image.
773 xGraphic = applyBrightnessContrast( xGraphic, nBrightness, nContrast );
774 nBrightness = 0;
775 nContrast = 0;
778 if(mbIsCustomShape)
780 // it is a cropped graphic.
781 rPropMap.setProperty(PROP_FillStyle, FillStyle_BITMAP);
782 rPropMap.setProperty(PROP_FillBitmapMode, BitmapMode_STRETCH);
783 rPropMap.setProperty(PROP_FillBitmap, xGraphic);
785 else
786 rPropMap.setProperty(PROP_Graphic, xGraphic);
788 // cropping
789 if ( maBlipProps.moClipRect.has() )
791 geometry::IntegerRectangle2D oClipRect( maBlipProps.moClipRect.get() );
792 awt::Size aOriginalSize( rGraphicHelper.getOriginalSize( xGraphic ) );
793 if ( aOriginalSize.Width && aOriginalSize.Height )
795 text::GraphicCrop aGraphCrop( 0, 0, 0, 0 );
796 if ( oClipRect.X1 )
797 aGraphCrop.Left = rtl::math::round( ( static_cast< double >( aOriginalSize.Width ) * oClipRect.X1 ) / 100000 );
798 if ( oClipRect.Y1 )
799 aGraphCrop.Top = rtl::math::round( ( static_cast< double >( aOriginalSize.Height ) * oClipRect.Y1 ) / 100000 );
800 if ( oClipRect.X2 )
801 aGraphCrop.Right = rtl::math::round( ( static_cast< double >( aOriginalSize.Width ) * oClipRect.X2 ) / 100000 );
802 if ( oClipRect.Y2 )
803 aGraphCrop.Bottom = rtl::math::round( ( static_cast< double >( aOriginalSize.Height ) * oClipRect.Y2 ) / 100000 );
804 rPropMap.setProperty(PROP_GraphicCrop, aGraphCrop);
808 if ( maBlipProps.moAlphaModFix.has() )
810 rPropMap.setProperty(PROP_Transparency, static_cast<sal_Int16>(100 - (maBlipProps.moAlphaModFix.get() / PER_PERCENT)));
813 rPropMap.setProperty(PROP_GraphicColorMode, eColorMode);
815 // brightness and contrast
816 if( nBrightness != 0 )
817 rPropMap.setProperty(PROP_AdjustLuminance, nBrightness);
818 if( nContrast != 0 )
819 rPropMap.setProperty(PROP_AdjustContrast, nContrast);
821 // Media content
822 assert(m_xMediaStream.is() != m_sMediaPackageURL.isEmpty());
823 if (m_xMediaStream.is() && !m_sMediaPackageURL.isEmpty())
825 rPropMap.setProperty(PROP_PrivateStream, m_xMediaStream);
826 rPropMap.setProperty(PROP_MediaURL, m_sMediaPackageURL);
830 bool ArtisticEffectProperties::isEmpty() const
832 return msName.isEmpty();
835 css::beans::PropertyValue ArtisticEffectProperties::getEffect()
837 css::beans::PropertyValue aRet;
838 if( msName.isEmpty() )
839 return aRet;
841 css::uno::Sequence< css::beans::PropertyValue > aSeq( maAttribs.size() + 1 );
842 sal_uInt32 i = 0;
843 for (auto const& attrib : maAttribs)
845 aSeq[i].Name = attrib.first;
846 aSeq[i].Value = attrib.second;
847 i++;
850 if( mrOleObjectInfo.maEmbeddedData.hasElements() )
852 css::uno::Sequence< css::beans::PropertyValue > aGraphicSeq( 2 );
853 aGraphicSeq[0].Name = "Id";
854 aGraphicSeq[0].Value <<= mrOleObjectInfo.maProgId;
855 aGraphicSeq[1].Name = "Data";
856 aGraphicSeq[1].Value <<= mrOleObjectInfo.maEmbeddedData;
858 aSeq[i].Name = "OriginalGraphic";
859 aSeq[i].Value <<= aGraphicSeq;
862 aRet.Name = msName;
863 aRet.Value <<= aSeq;
865 return aRet;
868 void ArtisticEffectProperties::assignUsed( const ArtisticEffectProperties& rSourceProps )
870 if( !rSourceProps.isEmpty() )
872 msName = rSourceProps.msName;
873 maAttribs = rSourceProps.maAttribs;
877 OUString ArtisticEffectProperties::getEffectString( sal_Int32 nToken )
879 switch( nToken )
881 // effects
882 case OOX_TOKEN( a14, artisticBlur ): return "artisticBlur";
883 case OOX_TOKEN( a14, artisticCement ): return "artisticCement";
884 case OOX_TOKEN( a14, artisticChalkSketch ): return "artisticChalkSketch";
885 case OOX_TOKEN( a14, artisticCrisscrossEtching ): return "artisticCrisscrossEtching";
886 case OOX_TOKEN( a14, artisticCutout ): return "artisticCutout";
887 case OOX_TOKEN( a14, artisticFilmGrain ): return "artisticFilmGrain";
888 case OOX_TOKEN( a14, artisticGlass ): return "artisticGlass";
889 case OOX_TOKEN( a14, artisticGlowDiffused ): return "artisticGlowDiffused";
890 case OOX_TOKEN( a14, artisticGlowEdges ): return "artisticGlowEdges";
891 case OOX_TOKEN( a14, artisticLightScreen ): return "artisticLightScreen";
892 case OOX_TOKEN( a14, artisticLineDrawing ): return "artisticLineDrawing";
893 case OOX_TOKEN( a14, artisticMarker ): return "artisticMarker";
894 case OOX_TOKEN( a14, artisticMosiaicBubbles ): return "artisticMosiaicBubbles";
895 case OOX_TOKEN( a14, artisticPaintStrokes ): return "artisticPaintStrokes";
896 case OOX_TOKEN( a14, artisticPaintBrush ): return "artisticPaintBrush";
897 case OOX_TOKEN( a14, artisticPastelsSmooth ): return "artisticPastelsSmooth";
898 case OOX_TOKEN( a14, artisticPencilGrayscale ): return "artisticPencilGrayscale";
899 case OOX_TOKEN( a14, artisticPencilSketch ): return "artisticPencilSketch";
900 case OOX_TOKEN( a14, artisticPhotocopy ): return "artisticPhotocopy";
901 case OOX_TOKEN( a14, artisticPlasticWrap ): return "artisticPlasticWrap";
902 case OOX_TOKEN( a14, artisticTexturizer ): return "artisticTexturizer";
903 case OOX_TOKEN( a14, artisticWatercolorSponge ): return "artisticWatercolorSponge";
904 case OOX_TOKEN( a14, brightnessContrast ): return "brightnessContrast";
905 case OOX_TOKEN( a14, colorTemperature ): return "colorTemperature";
906 case OOX_TOKEN( a14, saturation ): return "saturation";
907 case OOX_TOKEN( a14, sharpenSoften ): return "sharpenSoften";
909 // attributes
910 case XML_visible: return "visible";
911 case XML_trans: return "trans";
912 case XML_crackSpacing: return "crackSpacing";
913 case XML_pressure: return "pressure";
914 case XML_numberOfShades: return "numberOfShades";
915 case XML_grainSize: return "grainSize";
916 case XML_intensity: return "intensity";
917 case XML_smoothness: return "smoothness";
918 case XML_gridSize: return "gridSize";
919 case XML_pencilSize: return "pencilSize";
920 case XML_size: return "size";
921 case XML_brushSize: return "brushSize";
922 case XML_scaling: return "scaling";
923 case XML_detail: return "detail";
924 case XML_bright: return "bright";
925 case XML_contrast: return "contrast";
926 case XML_colorTemp: return "colorTemp";
927 case XML_sat: return "sat";
928 case XML_amount: return "amount";
930 SAL_WARN( "oox.drawingml", "ArtisticEffectProperties::getEffectString: unexpected token " << nToken );
931 return OUString();
934 sal_Int32 ArtisticEffectProperties::getEffectToken( const OUString& sName )
936 // effects
937 if( sName == "artisticBlur" )
938 return XML_artisticBlur;
939 else if( sName == "artisticCement" )
940 return XML_artisticCement;
941 else if( sName == "artisticChalkSketch" )
942 return XML_artisticChalkSketch;
943 else if( sName == "artisticCrisscrossEtching" )
944 return XML_artisticCrisscrossEtching;
945 else if( sName == "artisticCutout" )
946 return XML_artisticCutout;
947 else if( sName == "artisticFilmGrain" )
948 return XML_artisticFilmGrain;
949 else if( sName == "artisticGlass" )
950 return XML_artisticGlass;
951 else if( sName == "artisticGlowDiffused" )
952 return XML_artisticGlowDiffused;
953 else if( sName == "artisticGlowEdges" )
954 return XML_artisticGlowEdges;
955 else if( sName == "artisticLightScreen" )
956 return XML_artisticLightScreen;
957 else if( sName == "artisticLineDrawing" )
958 return XML_artisticLineDrawing;
959 else if( sName == "artisticMarker" )
960 return XML_artisticMarker;
961 else if( sName == "artisticMosiaicBubbles" )
962 return XML_artisticMosiaicBubbles;
963 else if( sName == "artisticPaintStrokes" )
964 return XML_artisticPaintStrokes;
965 else if( sName == "artisticPaintBrush" )
966 return XML_artisticPaintBrush;
967 else if( sName == "artisticPastelsSmooth" )
968 return XML_artisticPastelsSmooth;
969 else if( sName == "artisticPencilGrayscale" )
970 return XML_artisticPencilGrayscale;
971 else if( sName == "artisticPencilSketch" )
972 return XML_artisticPencilSketch;
973 else if( sName == "artisticPhotocopy" )
974 return XML_artisticPhotocopy;
975 else if( sName == "artisticPlasticWrap" )
976 return XML_artisticPlasticWrap;
977 else if( sName == "artisticTexturizer" )
978 return XML_artisticTexturizer;
979 else if( sName == "artisticWatercolorSponge" )
980 return XML_artisticWatercolorSponge;
981 else if( sName == "brightnessContrast" )
982 return XML_brightnessContrast;
983 else if( sName == "colorTemperature" )
984 return XML_colorTemperature;
985 else if( sName == "saturation" )
986 return XML_saturation;
987 else if( sName == "sharpenSoften" )
988 return XML_sharpenSoften;
990 // attributes
991 else if( sName == "visible" )
992 return XML_visible;
993 else if( sName == "trans" )
994 return XML_trans;
995 else if( sName == "crackSpacing" )
996 return XML_crackSpacing;
997 else if( sName == "pressure" )
998 return XML_pressure;
999 else if( sName == "numberOfShades" )
1000 return XML_numberOfShades;
1001 else if( sName == "grainSize" )
1002 return XML_grainSize;
1003 else if( sName == "intensity" )
1004 return XML_intensity;
1005 else if( sName == "smoothness" )
1006 return XML_smoothness;
1007 else if( sName == "gridSize" )
1008 return XML_gridSize;
1009 else if( sName == "pencilSize" )
1010 return XML_pencilSize;
1011 else if( sName == "size" )
1012 return XML_size;
1013 else if( sName == "brushSize" )
1014 return XML_brushSize;
1015 else if( sName == "scaling" )
1016 return XML_scaling;
1017 else if( sName == "detail" )
1018 return XML_detail;
1019 else if( sName == "bright" )
1020 return XML_bright;
1021 else if( sName == "contrast" )
1022 return XML_contrast;
1023 else if( sName == "colorTemp" )
1024 return XML_colorTemp;
1025 else if( sName == "sat" )
1026 return XML_sat;
1027 else if( sName == "amount" )
1028 return XML_amount;
1030 SAL_WARN( "oox.drawingml", "ArtisticEffectProperties::getEffectToken - unexpected token name" );
1031 return XML_none;
1034 } // namespace drawingml
1035 } // namespace oox
1037 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */