Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / oox / source / drawingml / fillproperties.cxx
blob365f38f5ddb27bad3e144d3c1664097b713717e7
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 <comphelper/propertyvalue.hxx>
25 #include <drawingml/graphicproperties.hxx>
26 #include <vcl/graph.hxx>
27 #include <vcl/BitmapFilter.hxx>
28 #include <vcl/BitmapMonochromeFilter.hxx>
29 #include <docmodel/uno/UnoComplexColor.hxx>
30 #include <docmodel/uno/UnoGradientTools.hxx>
31 #include <basegfx/utils/gradienttools.hxx>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/awt/Gradient2.hpp>
35 #include <com/sun/star/text/GraphicCrop.hpp>
36 #include <com/sun/star/awt/Size.hpp>
37 #include <com/sun/star/drawing/BitmapMode.hpp>
38 #include <com/sun/star/drawing/ColorMode.hpp>
39 #include <com/sun/star/drawing/FillStyle.hpp>
40 #include <com/sun/star/drawing/RectanglePoint.hpp>
41 #include <com/sun/star/graphic/XGraphicTransformer.hpp>
42 #include <oox/helper/graphichelper.hxx>
43 #include <oox/drawingml/drawingmltypes.hxx>
44 #include <oox/drawingml/shapepropertymap.hxx>
45 #include <drawingml/hatchmap.hxx>
46 #include <oox/token/namespaces.hxx>
47 #include <oox/token/properties.hxx>
48 #include <oox/token/tokens.hxx>
49 #include <osl/diagnose.h>
50 #include <sal/log.hxx>
52 using namespace ::com::sun::star;
53 using namespace ::com::sun::star::drawing;
54 using namespace ::com::sun::star::graphic;
56 using ::com::sun::star::uno::Reference;
57 using ::com::sun::star::uno::Exception;
58 using ::com::sun::star::uno::UNO_QUERY_THROW;
59 using ::com::sun::star::geometry::IntegerRectangle2D;
61 namespace oox::drawingml {
63 namespace {
65 Reference< XGraphic > lclCheckAndApplyDuotoneTransform(const BlipFillProperties& aBlipProps, uno::Reference<graphic::XGraphic> const & xGraphic,
66 const GraphicHelper& rGraphicHelper, const ::Color nPhClr)
68 if (aBlipProps.maDuotoneColors[0].isUsed() && aBlipProps.maDuotoneColors[1].isUsed())
70 ::Color nColor1 = aBlipProps.maDuotoneColors[0].getColor( rGraphicHelper, nPhClr );
71 ::Color nColor2 = aBlipProps.maDuotoneColors[1].getColor( rGraphicHelper, nPhClr );
73 uno::Reference<graphic::XGraphicTransformer> xTransformer(aBlipProps.mxFillGraphic, uno::UNO_QUERY);
74 if (xTransformer.is())
75 return xTransformer->applyDuotone(xGraphic, sal_Int32(nColor1), sal_Int32(nColor2));
77 return xGraphic;
80 Reference< XGraphic > lclRotateGraphic(uno::Reference<graphic::XGraphic> const & xGraphic, Degree10 nRotation)
82 ::Graphic aGraphic(xGraphic);
83 ::Graphic aReturnGraphic;
85 assert (aGraphic.GetType() == GraphicType::Bitmap);
87 BitmapEx aBitmapEx(aGraphic.GetBitmapEx());
88 const ::Color& aColor = ::Color(0x00);
89 aBitmapEx.Rotate(nRotation, aColor);
90 aReturnGraphic = ::Graphic(aBitmapEx);
91 aReturnGraphic.setOriginURL(aGraphic.getOriginURL());
93 return aReturnGraphic.GetXGraphic();
96 using Quotients = std::tuple<double, double, double, double>;
97 Quotients getQuotients(geometry::IntegerRectangle2D aRelRect, double hDiv, double vDiv)
99 return { aRelRect.X1 / hDiv, aRelRect.Y1 / vDiv, aRelRect.X2 / hDiv, aRelRect.Y2 / vDiv };
102 // ECMA-376 Part 1 20.1.8.55 srcRect (Source Rectangle)
103 std::optional<Quotients> CropQuotientsFromSrcRect(geometry::IntegerRectangle2D aSrcRect)
105 aSrcRect.X1 = std::max(aSrcRect.X1, sal_Int32(0));
106 aSrcRect.X2 = std::max(aSrcRect.X2, sal_Int32(0));
107 aSrcRect.Y1 = std::max(aSrcRect.Y1, sal_Int32(0));
108 aSrcRect.Y2 = std::max(aSrcRect.Y2, sal_Int32(0));
109 if (aSrcRect.X1 + aSrcRect.X2 >= MAX_PERCENT || aSrcRect.Y1 + aSrcRect.Y2 >= MAX_PERCENT)
110 return {}; // Cropped everything
111 return getQuotients(aSrcRect, MAX_PERCENT, MAX_PERCENT);
114 // ECMA-376 Part 1 20.1.8.30 fillRect (Fill Rectangle)
115 std::optional<Quotients> CropQuotientsFromFillRect(geometry::IntegerRectangle2D aFillRect)
117 aFillRect.X1 = std::min(aFillRect.X1, sal_Int32(0));
118 aFillRect.X2 = std::min(aFillRect.X2, sal_Int32(0));
119 aFillRect.Y1 = std::min(aFillRect.Y1, sal_Int32(0));
120 aFillRect.Y2 = std::min(aFillRect.Y2, sal_Int32(0));
121 // Negative divisor and negative relative offset give positive value wanted in lclCropGraphic
122 return getQuotients(aFillRect, -MAX_PERCENT + aFillRect.X1 + aFillRect.X2,
123 -MAX_PERCENT + aFillRect.Y1 + aFillRect.Y2);
126 // Crops a piece of the bitmap. lclCropGraphic doesn't handle growing.
127 Reference<XGraphic> lclCropGraphic(uno::Reference<graphic::XGraphic> const& xGraphic,
128 std::optional<Quotients> quotients)
130 ::Graphic aGraphic(xGraphic);
131 assert (aGraphic.GetType() == GraphicType::Bitmap);
133 BitmapEx aBitmapEx;
134 if (quotients)
136 aBitmapEx = aGraphic.GetBitmapEx();
138 const Size bmpSize = aBitmapEx.GetSizePixel();
139 const auto& [qx1, qy1, qx2, qy2] = *quotients;
140 const tools::Long l = std::round(bmpSize.Width() * qx1);
141 const tools::Long t = std::round(bmpSize.Height() * qy1);
142 const tools::Long r = std::round(bmpSize.Width() * qx2);
143 const tools::Long b = std::round(bmpSize.Height() * qy2);
145 aBitmapEx.Crop({ l, t, bmpSize.Width() - r - 1, bmpSize.Height() - b - 1 });
148 ::Graphic aReturnGraphic(aBitmapEx);
149 aReturnGraphic.setOriginURL(aGraphic.getOriginURL());
151 return aReturnGraphic.GetXGraphic();
154 Reference< XGraphic > lclMirrorGraphic(uno::Reference<graphic::XGraphic> const & xGraphic, bool bFlipH, bool bFlipV)
156 ::Graphic aGraphic(xGraphic);
157 ::Graphic aReturnGraphic;
159 assert (aGraphic.GetType() == GraphicType::Bitmap);
161 BitmapEx aBitmapEx(aGraphic.GetBitmapEx());
162 BmpMirrorFlags nMirrorFlags = BmpMirrorFlags::NONE;
164 if(bFlipH)
165 nMirrorFlags |= BmpMirrorFlags::Horizontal;
166 if(bFlipV)
167 nMirrorFlags |= BmpMirrorFlags::Vertical;
169 aBitmapEx.Mirror(nMirrorFlags);
171 aReturnGraphic = ::Graphic(aBitmapEx);
172 aReturnGraphic.setOriginURL(aGraphic.getOriginURL());
174 return aReturnGraphic.GetXGraphic();
177 Reference< XGraphic > lclGreysScaleGraphic(uno::Reference<graphic::XGraphic> const & xGraphic)
179 ::Graphic aGraphic(xGraphic);
180 ::Graphic aReturnGraphic;
182 assert (aGraphic.GetType() == GraphicType::Bitmap);
184 BitmapEx aBitmapEx(aGraphic.GetBitmapEx());
185 aBitmapEx.Convert(BmpConversion::N8BitGreys);
187 aReturnGraphic = ::Graphic(aBitmapEx);
188 aReturnGraphic.setOriginURL(aGraphic.getOriginURL());
190 return aReturnGraphic.GetXGraphic();
193 /// Applies the graphic Black&White (Monochrome) effect with the imported threshold
194 Reference<XGraphic> lclApplyBlackWhiteEffect(const BlipFillProperties& aBlipProps,
195 const uno::Reference<graphic::XGraphic>& xGraphic)
197 const auto& oBiLevelThreshold = aBlipProps.moBiLevelThreshold;
198 if (oBiLevelThreshold.has_value())
200 sal_uInt8 nThreshold
201 = static_cast<sal_uInt8>(oBiLevelThreshold.value() * 255 / MAX_PERCENT);
203 ::Graphic aGraphic(xGraphic);
204 ::Graphic aReturnGraphic;
206 BitmapEx aBitmapEx(aGraphic.GetBitmapEx());
207 AlphaMask aMask(aBitmapEx.GetAlphaMask());
209 BitmapEx aTmpBmpEx(aBitmapEx.GetBitmap());
210 BitmapFilter::Filter(aTmpBmpEx, BitmapMonochromeFilter{ nThreshold });
212 aReturnGraphic = ::Graphic(BitmapEx(aTmpBmpEx.GetBitmap(), aMask));
213 aReturnGraphic.setOriginURL(aGraphic.getOriginURL());
214 return aReturnGraphic.GetXGraphic();
216 return xGraphic;
219 Reference< XGraphic > lclCheckAndApplyChangeColorTransform(const BlipFillProperties &aBlipProps, uno::Reference<graphic::XGraphic> const & xGraphic,
220 const GraphicHelper& rGraphicHelper, const ::Color nPhClr)
222 if( aBlipProps.maColorChangeFrom.isUsed() && aBlipProps.maColorChangeTo.isUsed() )
224 ::Color nFromColor = aBlipProps.maColorChangeFrom.getColor( rGraphicHelper, nPhClr );
225 ::Color nToColor = aBlipProps.maColorChangeTo.getColor( rGraphicHelper, nPhClr );
226 if ( (nFromColor != nToColor) || aBlipProps.maColorChangeTo.hasTransparency() )
228 sal_Int16 nToTransparence = aBlipProps.maColorChangeTo.getTransparency();
229 sal_Int8 nToAlpha = static_cast< sal_Int8 >( (100 - nToTransparence) * 2.55 );
231 sal_uInt8 nTolerance = 9;
232 Graphic aGraphic{ xGraphic };
233 if( aGraphic.IsGfxLink() )
235 // tdf#149670: Try to guess tolerance depending on image format
236 switch (aGraphic.GetGfxLink().GetType())
238 case GfxLinkType::NativeJpg:
239 nTolerance = 15;
240 break;
241 case GfxLinkType::NativePng:
242 case GfxLinkType::NativeTif:
243 nTolerance = 1;
244 break;
245 case GfxLinkType::NativeBmp:
246 nTolerance = 0;
247 break;
248 default:
249 break;
253 uno::Reference<graphic::XGraphicTransformer> xTransformer(aBlipProps.mxFillGraphic, uno::UNO_QUERY);
254 if (xTransformer.is())
255 return xTransformer->colorChange(xGraphic, sal_Int32(nFromColor), nTolerance, sal_Int32(nToColor), nToAlpha);
258 return xGraphic;
261 uno::Reference<graphic::XGraphic> applyBrightnessContrast(uno::Reference<graphic::XGraphic> const & xGraphic, sal_Int32 brightness, sal_Int32 contrast)
263 uno::Reference<graphic::XGraphicTransformer> xTransformer(xGraphic, uno::UNO_QUERY);
264 if (xTransformer.is())
265 return xTransformer->applyBrightnessContrast(xGraphic, brightness, contrast, true);
266 return xGraphic;
269 BitmapMode lclGetBitmapMode( sal_Int32 nToken )
271 OSL_ASSERT((nToken & sal_Int32(0xFFFF0000))==0);
272 switch( nToken )
274 case XML_tile: return BitmapMode_REPEAT;
275 case XML_stretch: return BitmapMode_STRETCH;
278 // tdf#128596 Default value is XML_tile for MSO.
279 return BitmapMode_REPEAT;
282 RectanglePoint lclGetRectanglePoint( sal_Int32 nToken )
284 OSL_ASSERT((nToken & sal_Int32(0xFFFF0000))==0);
285 switch( nToken )
287 case XML_tl: return RectanglePoint_LEFT_TOP;
288 case XML_t: return RectanglePoint_MIDDLE_TOP;
289 case XML_tr: return RectanglePoint_RIGHT_TOP;
290 case XML_l: return RectanglePoint_LEFT_MIDDLE;
291 case XML_ctr: return RectanglePoint_MIDDLE_MIDDLE;
292 case XML_r: return RectanglePoint_RIGHT_MIDDLE;
293 case XML_bl: return RectanglePoint_LEFT_BOTTOM;
294 case XML_b: return RectanglePoint_MIDDLE_BOTTOM;
295 case XML_br: return RectanglePoint_RIGHT_BOTTOM;
297 return RectanglePoint_LEFT_TOP;
300 awt::Size lclGetOriginalSize( const GraphicHelper& rGraphicHelper, const Reference< XGraphic >& rxGraphic )
302 awt::Size aSizeHmm( 0, 0 );
305 Reference< beans::XPropertySet > xGraphicPropertySet( rxGraphic, UNO_QUERY_THROW );
306 if( xGraphicPropertySet->getPropertyValue( "Size100thMM" ) >>= aSizeHmm )
308 if( !aSizeHmm.Width && !aSizeHmm.Height )
309 { // MAPMODE_PIXEL USED :-(
310 awt::Size aSourceSizePixel( 0, 0 );
311 if( xGraphicPropertySet->getPropertyValue( "SizePixel" ) >>= aSourceSizePixel )
312 aSizeHmm = rGraphicHelper.convertScreenPixelToHmm( aSourceSizePixel );
316 catch( Exception& )
319 return aSizeHmm;
322 } // namespace
324 void GradientFillProperties::assignUsed( const GradientFillProperties& rSourceProps )
326 if( !rSourceProps.maGradientStops.empty() )
327 maGradientStops = rSourceProps.maGradientStops;
328 assignIfUsed( moFillToRect, rSourceProps.moFillToRect );
329 assignIfUsed( moTileRect, rSourceProps.moTileRect );
330 assignIfUsed( moGradientPath, rSourceProps.moGradientPath );
331 assignIfUsed( moShadeAngle, rSourceProps.moShadeAngle );
332 assignIfUsed( moShadeFlip, rSourceProps.moShadeFlip );
333 assignIfUsed( moShadeScaled, rSourceProps.moShadeScaled );
334 assignIfUsed( moRotateWithShape, rSourceProps.moRotateWithShape );
337 void PatternFillProperties::assignUsed( const PatternFillProperties& rSourceProps )
339 maPattFgColor.assignIfUsed( rSourceProps.maPattFgColor );
340 maPattBgColor.assignIfUsed( rSourceProps.maPattBgColor );
341 assignIfUsed( moPattPreset, rSourceProps.moPattPreset );
344 void BlipFillProperties::assignUsed( const BlipFillProperties& rSourceProps )
346 if(rSourceProps.mxFillGraphic.is())
347 mxFillGraphic = rSourceProps.mxFillGraphic;
348 assignIfUsed( moBitmapMode, rSourceProps.moBitmapMode );
349 assignIfUsed( moFillRect, rSourceProps.moFillRect );
350 assignIfUsed( moTileOffsetX, rSourceProps.moTileOffsetX );
351 assignIfUsed( moTileOffsetY, rSourceProps.moTileOffsetY );
352 assignIfUsed( moTileScaleX, rSourceProps.moTileScaleX );
353 assignIfUsed( moTileScaleY, rSourceProps.moTileScaleY );
354 assignIfUsed( moTileAlign, rSourceProps.moTileAlign );
355 assignIfUsed( moTileFlip, rSourceProps.moTileFlip );
356 assignIfUsed( moRotateWithShape, rSourceProps.moRotateWithShape );
357 assignIfUsed( moColorEffect, rSourceProps.moColorEffect );
358 assignIfUsed( moBrightness, rSourceProps.moBrightness );
359 assignIfUsed( moContrast, rSourceProps.moContrast );
360 assignIfUsed( moBiLevelThreshold, rSourceProps.moBiLevelThreshold );
361 maColorChangeFrom.assignIfUsed( rSourceProps.maColorChangeFrom );
362 maColorChangeTo.assignIfUsed( rSourceProps.maColorChangeTo );
363 maDuotoneColors[0].assignIfUsed( rSourceProps.maDuotoneColors[0] );
364 maDuotoneColors[1].assignIfUsed( rSourceProps.maDuotoneColors[1] );
365 maEffect.assignUsed( rSourceProps.maEffect );
366 assignIfUsed(moAlphaModFix, rSourceProps.moAlphaModFix);
369 void FillProperties::assignUsed( const FillProperties& rSourceProps )
371 assignIfUsed( moFillType, rSourceProps.moFillType );
372 maFillColor.assignIfUsed( rSourceProps.maFillColor );
373 assignIfUsed( moUseBgFill, rSourceProps.moUseBgFill );
374 maGradientProps.assignUsed( rSourceProps.maGradientProps );
375 maPatternProps.assignUsed( rSourceProps.maPatternProps );
376 maBlipProps.assignUsed( rSourceProps.maBlipProps );
379 Color FillProperties::getBestSolidColor() const
381 Color aSolidColor;
382 if( moFillType.has_value() ) switch( moFillType.value() )
384 case XML_solidFill:
385 aSolidColor = maFillColor;
386 break;
387 case XML_gradFill:
388 if( !maGradientProps.maGradientStops.empty() )
390 GradientFillProperties::GradientStopMap::const_iterator aGradientStop =
391 maGradientProps.maGradientStops.begin();
392 if (maGradientProps.maGradientStops.size() > 2)
393 ++aGradientStop;
394 aSolidColor = aGradientStop->second;
396 break;
397 case XML_pattFill:
398 aSolidColor = maPatternProps.maPattBgColor.isUsed() ? maPatternProps.maPattBgColor : maPatternProps.maPattFgColor;
399 break;
401 return aSolidColor;
404 void FillProperties::pushToPropMap(ShapePropertyMap& rPropMap, const GraphicHelper& rGraphicHelper,
405 sal_Int32 nShapeRotation, ::Color nPhClr,
406 const css::awt::Size& rSize, sal_Int16 nPhClrTheme, bool bFlipH,
407 bool bFlipV, bool bIsCustomShape) const
409 if( !moFillType.has_value() )
410 return;
412 FillStyle eFillStyle = FillStyle_NONE;
413 OSL_ASSERT((moFillType.value() & sal_Int32(0xFFFF0000))==0);
414 switch( moFillType.value() )
416 case XML_noFill:
418 eFillStyle = FillStyle_NONE;
419 rPropMap.setProperty(ShapeProperty::FillUseSlideBackground, moUseBgFill.value_or(false));
421 break;
423 case XML_solidFill:
424 if( maFillColor.isUsed() )
426 ::Color aFillColor = maFillColor.getColor(rGraphicHelper, nPhClr);
427 rPropMap.setProperty(ShapeProperty::FillColor, aFillColor);
428 if( maFillColor.hasTransparency() )
429 rPropMap.setProperty( ShapeProperty::FillTransparency, maFillColor.getTransparency() );
431 model::ComplexColor aComplexColor;
432 if (aFillColor == nPhClr)
434 aComplexColor.setSchemeColor(model::convertToThemeColorType(nPhClrTheme));
436 else
438 aComplexColor = maFillColor.getComplexColor();
440 rPropMap.setProperty(PROP_FillComplexColor, model::color::createXComplexColor(aComplexColor));
442 eFillStyle = FillStyle_SOLID;
444 break;
446 case XML_gradFill:
447 // do not create gradient struct if property is not supported...
448 if( rPropMap.supportsProperty( ShapeProperty::FillGradient ) )
450 // prepare ColorStops
451 basegfx::BColorStops aColorStops;
452 basegfx::BColorStops aTransparencyStops;
453 bool bContainsTransparency(false);
455 // convert to BColorStops, check for contained transparency
456 for (const auto& rCandidate : maGradientProps.maGradientStops)
458 const ::Color aColor(rCandidate.second.getColor(rGraphicHelper, nPhClr));
459 aColorStops.emplace_back(rCandidate.first, aColor.getBColor());
460 bContainsTransparency = bContainsTransparency || rCandidate.second.hasTransparency();
463 // if we have transparency, convert to BColorStops
464 if (bContainsTransparency)
466 for (const auto& rCandidate : maGradientProps.maGradientStops)
468 const double fTrans(rCandidate.second.getTransparency() * (1.0/100.0));
469 aTransparencyStops.emplace_back(rCandidate.first, basegfx::BColor(fTrans, fTrans, fTrans));
473 // prepare BGradient with some defaults
474 // CAUTION: This used awt::Gradient2 before who's empty constructor
475 // (see workdir/UnoApiHeadersTarget/offapi/normal/com/sun/
476 // star/awt/Gradient.hpp) initializes all to zeros, so reflect
477 // this here. OTOH set all that were set, e.g. Start/EndIntens
478 // were set to 100, so just use default of BGradient constructor
479 basegfx::BGradient aGradient(
480 aColorStops,
481 awt::GradientStyle_LINEAR,
482 Degree10(900),
483 0, // border
484 0, // OfsX -> 0, not 50 (!)
485 0); // OfsY -> 0, not 50 (!)
487 // "rotate with shape" set to false -> do not rotate
488 if (!maGradientProps.moRotateWithShape.value_or(true))
490 nShapeRotation = 0;
493 if (maGradientProps.moGradientPath.has_value())
495 IntegerRectangle2D aFillToRect = maGradientProps.moFillToRect.value_or( IntegerRectangle2D( 0, 0, MAX_PERCENT, MAX_PERCENT ) );
496 sal_Int32 nCenterX = (MAX_PERCENT + aFillToRect.X1 - aFillToRect.X2) / 2;
497 aGradient.SetXOffset(getLimitedValue<sal_Int16, sal_Int32>(
498 nCenterX / PER_PERCENT, 0, 100));
499 sal_Int32 nCenterY = (MAX_PERCENT + aFillToRect.Y1 - aFillToRect.Y2) / 2;
500 aGradient.SetYOffset(getLimitedValue<sal_Int16, sal_Int32>(
501 nCenterY / PER_PERCENT, 0, 100));
503 if( maGradientProps.moGradientPath.value() == XML_circle )
505 // Style should be radial at least when the horizontal center is at 50%.
506 // Otherwise import as a linear gradient, because it is the most similar to the MSO radial style.
507 // aGradient.SetGradientStyle(awt::GradientStyle_LINEAR);
508 if( 100 == aGradient.GetXOffset() && 100 == aGradient.GetYOffset() )
509 aGradient.SetAngle( Degree10(450) );
510 else if( 0 == aGradient.GetXOffset() && 100 == aGradient.GetYOffset() )
511 aGradient.SetAngle( Degree10(3150) );
512 else if( 100 == aGradient.GetXOffset() && 0 == aGradient.GetYOffset() )
513 aGradient.SetAngle( Degree10(1350) );
514 else if( 0 == aGradient.GetXOffset() && 0 == aGradient.GetYOffset() )
515 aGradient.SetAngle( Degree10(2250) );
516 else
517 aGradient.SetGradientStyle(awt::GradientStyle_RADIAL);
519 else
521 aGradient.SetGradientStyle(awt::GradientStyle_RECT);
524 aColorStops.reverseColorStops();
525 aGradient.SetColorStops(aColorStops);
526 aTransparencyStops.reverseColorStops();
528 else if (!maGradientProps.maGradientStops.empty())
530 // aGradient.SetGradientStyle(awt::GradientStyle_LINEAR);
531 sal_Int32 nShadeAngle(maGradientProps.moShadeAngle.value_or( 0 ));
532 // Adjust for flips
533 if ( bFlipH )
534 nShadeAngle = 180*60000 - nShadeAngle;
535 if ( bFlipV )
536 nShadeAngle = -nShadeAngle;
537 const sal_Int32 nDmlAngle = nShadeAngle + nShapeRotation;
539 // convert DrawingML angle (in 1/60000 degrees) to API angle (in 1/10 degrees)
540 aGradient.SetAngle(Degree10(static_cast< sal_Int16 >( (8100 - (nDmlAngle / (PER_DEGREE / 10))) % 3600 )));
543 if (awt::GradientStyle_RECT == aGradient.GetGradientStyle())
545 // MCGR: tdf#155362: better support border
546 // CAUTION: Need to handle TransparencyStops if used
547 aGradient.tryToRecreateBorder(aTransparencyStops.empty() ? nullptr : &aTransparencyStops);
550 // push gradient or named gradient to property map
551 if (rPropMap.setProperty(ShapeProperty::FillGradient, model::gradient::createUnoGradient2(aGradient)))
553 eFillStyle = FillStyle_GRADIENT;
556 // push gradient transparency to property map if it exists
557 if (!aTransparencyStops.empty())
559 aGradient.SetColorStops(aTransparencyStops);
560 rPropMap.setProperty(ShapeProperty::GradientTransparency, model::gradient::createUnoGradient2(aGradient));
563 break;
565 case XML_blipFill:
566 // do not start complex graphic transformation if property is not supported...
567 if (maBlipProps.mxFillGraphic.is() && rPropMap.supportsProperty(ShapeProperty::FillBitmap))
569 uno::Reference<graphic::XGraphic> xGraphic = lclCheckAndApplyDuotoneTransform(maBlipProps, maBlipProps.mxFillGraphic, rGraphicHelper, nPhClr);
570 // TODO: "rotate with shape" is not possible with our current core
572 if (xGraphic.is())
574 if (maBlipProps.moColorEffect.value_or(XML_TOKEN_INVALID) == XML_grayscl)
575 xGraphic = lclGreysScaleGraphic(xGraphic);
577 if (rPropMap.supportsProperty(ShapeProperty::FillBitmapName) &&
578 rPropMap.setProperty(ShapeProperty::FillBitmapName, xGraphic))
580 eFillStyle = FillStyle_BITMAP;
582 else if (rPropMap.setProperty(ShapeProperty::FillBitmap, xGraphic))
584 eFillStyle = FillStyle_BITMAP;
588 // set other bitmap properties, if bitmap has been inserted into the map
589 if( eFillStyle == FillStyle_BITMAP )
591 // bitmap mode (single, repeat, stretch)
592 BitmapMode eBitmapMode = lclGetBitmapMode( maBlipProps.moBitmapMode.value_or( XML_TOKEN_INVALID ) );
594 // additional settings for repeated bitmap
595 if( eBitmapMode == BitmapMode_REPEAT )
597 // anchor position inside bitmap
598 RectanglePoint eRectPoint = lclGetRectanglePoint( maBlipProps.moTileAlign.value_or( XML_tl ) );
599 rPropMap.setProperty( ShapeProperty::FillBitmapRectanglePoint, eRectPoint );
601 awt::Size aOriginalSize = lclGetOriginalSize(rGraphicHelper, maBlipProps.mxFillGraphic);
602 if( (aOriginalSize.Width > 0) && (aOriginalSize.Height > 0) )
604 // size of one bitmap tile (given as 1/1000 percent of bitmap size), convert to 1/100 mm
605 double fScaleX = maBlipProps.moTileScaleX.value_or( MAX_PERCENT ) / static_cast< double >( MAX_PERCENT );
606 sal_Int32 nFillBmpSizeX = getLimitedValue< sal_Int32, double >( aOriginalSize.Width * fScaleX, 1, SAL_MAX_INT32 );
607 rPropMap.setProperty( ShapeProperty::FillBitmapSizeX, nFillBmpSizeX );
608 double fScaleY = maBlipProps.moTileScaleY.value_or( MAX_PERCENT ) / static_cast< double >( MAX_PERCENT );
609 sal_Int32 nFillBmpSizeY = getLimitedValue< sal_Int32, double >( aOriginalSize.Height * fScaleY, 1, SAL_MAX_INT32 );
610 rPropMap.setProperty( ShapeProperty::FillBitmapSizeY, nFillBmpSizeY );
612 awt::Size aBmpSize(nFillBmpSizeX, nFillBmpSizeY);
613 // offset of the first bitmap tile (given as EMUs), convert to percent
614 sal_Int16 nTileOffsetX = getDoubleIntervalValue< sal_Int16 >(std::round(maBlipProps.moTileOffsetX.value_or( 0 ) / 3.6 / aBmpSize.Width), 0, 100 );
615 rPropMap.setProperty( ShapeProperty::FillBitmapOffsetX, nTileOffsetX );
616 sal_Int16 nTileOffsetY = getDoubleIntervalValue< sal_Int16 >(std::round(maBlipProps.moTileOffsetY.value_or( 0 ) / 3.6 / aBmpSize.Height), 0, 100 );
617 rPropMap.setProperty( ShapeProperty::FillBitmapOffsetY, nTileOffsetY );
620 else if ( eBitmapMode == BitmapMode_STRETCH && maBlipProps.moFillRect.has_value() )
622 geometry::IntegerRectangle2D aFillRect( maBlipProps.moFillRect.value() );
623 awt::Size aOriginalSize( rGraphicHelper.getOriginalSize( xGraphic ) );
624 if ( aOriginalSize.Width && aOriginalSize.Height )
626 text::GraphicCrop aGraphCrop( 0, 0, 0, 0 );
627 if ( aFillRect.X1 )
628 aGraphCrop.Left = o3tl::convert(aFillRect.X1, aOriginalSize.Width, MAX_PERCENT);
629 if ( aFillRect.Y1 )
630 aGraphCrop.Top = o3tl::convert(aFillRect.Y1, aOriginalSize.Height, MAX_PERCENT);
631 if ( aFillRect.X2 )
632 aGraphCrop.Right = o3tl::convert(aFillRect.X2, aOriginalSize.Width, MAX_PERCENT);
633 if ( aFillRect.Y2 )
634 aGraphCrop.Bottom = o3tl::convert(aFillRect.Y2, aOriginalSize.Height, MAX_PERCENT);
636 bool bHasCropValues = aGraphCrop.Left != 0 || aGraphCrop.Right !=0 || aGraphCrop.Top != 0 || aGraphCrop.Bottom != 0;
637 // Negative GraphicCrop values means "crop" here.
638 bool bNeedCrop = aGraphCrop.Left <= 0 && aGraphCrop.Right <= 0 && aGraphCrop.Top <= 0 && aGraphCrop.Bottom <= 0;
640 if (bHasCropValues)
642 if (bIsCustomShape && bNeedCrop)
644 // Physically crop the image
645 // In this case, don't set the PROP_GraphicCrop because that
646 // would lead to applying the crop twice after roundtrip
647 xGraphic = lclCropGraphic(xGraphic, CropQuotientsFromFillRect(aFillRect));
648 if (rPropMap.supportsProperty(ShapeProperty::FillBitmapName))
649 rPropMap.setProperty(ShapeProperty::FillBitmapName, xGraphic);
650 else
651 rPropMap.setProperty(ShapeProperty::FillBitmap, xGraphic);
653 else if ((aFillRect.X1 != 0 && aFillRect.X2 != 0
654 && aFillRect.X1 != aFillRect.X2)
655 || (aFillRect.Y1 != 0 && aFillRect.Y2 != 0
656 && aFillRect.Y1 != aFillRect.Y2))
658 rPropMap.setProperty(PROP_GraphicCrop, aGraphCrop);
660 else
662 double nL = aFillRect.X1 / static_cast<double>(MAX_PERCENT);
663 double nT = aFillRect.Y1 / static_cast<double>(MAX_PERCENT);
664 double nR = aFillRect.X2 / static_cast<double>(MAX_PERCENT);
665 double nB = aFillRect.Y2 / static_cast<double>(MAX_PERCENT);
667 sal_Int32 nSizeX;
668 if (nL || nR)
669 nSizeX = rSize.Width * (1 - (nL + nR));
670 else
671 nSizeX = rSize.Width;
672 rPropMap.setProperty(ShapeProperty::FillBitmapSizeX, nSizeX);
674 sal_Int32 nSizeY;
675 if (nT || nB)
676 nSizeY = rSize.Height * (1 - (nT + nB));
677 else
678 nSizeY = rSize.Height;
679 rPropMap.setProperty(ShapeProperty::FillBitmapSizeY, nSizeY);
681 RectanglePoint eRectPoint;
682 if (!aFillRect.X1 && aFillRect.X2)
684 if (!aFillRect.Y1 && aFillRect.Y2)
685 eRectPoint = lclGetRectanglePoint(XML_tl);
686 else if (aFillRect.Y1 && !aFillRect.Y2)
687 eRectPoint = lclGetRectanglePoint(XML_bl);
688 else
689 eRectPoint = lclGetRectanglePoint(XML_l);
691 else if (aFillRect.X1 && !aFillRect.X2)
693 if (!aFillRect.Y1 && aFillRect.Y2)
694 eRectPoint = lclGetRectanglePoint(XML_tr);
695 else if (aFillRect.Y1 && !aFillRect.Y2)
696 eRectPoint = lclGetRectanglePoint(XML_br);
697 else
698 eRectPoint = lclGetRectanglePoint(XML_r);
700 else
702 if (!aFillRect.Y1 && aFillRect.Y2)
703 eRectPoint = lclGetRectanglePoint(XML_t);
704 else if (aFillRect.Y1 && !aFillRect.Y2)
705 eRectPoint = lclGetRectanglePoint(XML_b);
706 else
707 eRectPoint = lclGetRectanglePoint(XML_ctr);
709 rPropMap.setProperty(ShapeProperty::FillBitmapRectanglePoint, eRectPoint);
710 eBitmapMode = BitmapMode_NO_REPEAT;
715 rPropMap.setProperty(ShapeProperty::FillBitmapMode, eBitmapMode);
718 if (maBlipProps.moAlphaModFix.has_value())
719 rPropMap.setProperty(ShapeProperty::FillTransparency, static_cast<sal_Int16>(100 - (maBlipProps.moAlphaModFix.value() / PER_PERCENT)));
721 break;
723 case XML_pattFill:
725 if( rPropMap.supportsProperty( ShapeProperty::FillHatch ) )
727 Color aColor( maPatternProps.maPattFgColor );
728 if( aColor.isUsed() && maPatternProps.moPattPreset.has_value() )
730 eFillStyle = FillStyle_HATCH;
731 rPropMap.setProperty( ShapeProperty::FillHatch, createHatch( maPatternProps.moPattPreset.value(), aColor.getColor( rGraphicHelper, nPhClr ) ) );
732 if( aColor.hasTransparency() )
733 rPropMap.setProperty( ShapeProperty::FillTransparency, aColor.getTransparency() );
735 // Set background color for hatch
736 if(maPatternProps.maPattBgColor.isUsed())
738 aColor = maPatternProps.maPattBgColor;
739 rPropMap.setProperty( ShapeProperty::FillBackground, aColor.getTransparency() != 100 );
740 rPropMap.setProperty( ShapeProperty::FillColor, aColor.getColor( rGraphicHelper, nPhClr ) );
743 else if ( maPatternProps.maPattBgColor.isUsed() )
745 aColor = maPatternProps.maPattBgColor;
746 rPropMap.setProperty( ShapeProperty::FillColor, aColor.getColor( rGraphicHelper, nPhClr ) );
747 if( aColor.hasTransparency() )
748 rPropMap.setProperty( ShapeProperty::FillTransparency, aColor.getTransparency() );
749 eFillStyle = FillStyle_SOLID;
753 break;
755 case XML_grpFill:
756 // todo
757 eFillStyle = FillStyle_NONE;
758 break;
761 // set final fill style property
762 rPropMap.setProperty( ShapeProperty::FillStyle, eFillStyle );
765 void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const GraphicHelper& rGraphicHelper, bool bFlipH, bool bFlipV) const
767 sal_Int16 nBrightness = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moBrightness.value_or( 0 ) / PER_PERCENT, -100, 100 );
768 sal_Int16 nContrast = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moContrast.value_or( 0 ) / PER_PERCENT, -100, 100 );
769 ColorMode eColorMode = ColorMode_STANDARD;
771 switch( maBlipProps.moColorEffect.value_or( XML_TOKEN_INVALID ) )
773 case XML_biLevel: eColorMode = ColorMode_MONO; break;
774 case XML_grayscl: eColorMode = ColorMode_GREYS; break;
777 if (maBlipProps.mxFillGraphic.is())
779 // created transformed graphic
780 uno::Reference<graphic::XGraphic> xGraphic = lclCheckAndApplyChangeColorTransform(maBlipProps, maBlipProps.mxFillGraphic, rGraphicHelper, API_RGB_TRANSPARENT);
781 xGraphic = lclCheckAndApplyDuotoneTransform(maBlipProps, xGraphic, rGraphicHelper, API_RGB_TRANSPARENT);
783 if( eColorMode == ColorMode_MONO )
785 // ColorMode_MONO is the same with MSO's biLevel with 50000 (50%) threshold,
786 // when threshold isn't 50000 bake the effect instead.
787 if( maBlipProps.moBiLevelThreshold != 50000 )
789 xGraphic = lclApplyBlackWhiteEffect(maBlipProps, xGraphic);
790 eColorMode = ColorMode_STANDARD;
794 if (eColorMode == ColorMode_STANDARD && nBrightness == 70 && nContrast == -70)
796 // map MSO 'washout' to our Watermark colormode
797 eColorMode = ColorMode_WATERMARK;
798 nBrightness = 0;
799 nContrast = 0;
801 else if( nBrightness != 0 && nContrast != 0 )
803 // MSO uses a different algorithm for contrast+brightness, LO applies contrast before brightness,
804 // while MSO apparently applies half of brightness before contrast and half after. So if only
805 // contrast or brightness need to be altered, the result is the same, but if both are involved,
806 // there's no way to map that, so just force a conversion of the image.
807 xGraphic = applyBrightnessContrast( xGraphic, nBrightness, nContrast );
808 nBrightness = 0;
809 nContrast = 0;
812 // cropping
813 if ( maBlipProps.moClipRect.has_value() )
815 geometry::IntegerRectangle2D oClipRect( maBlipProps.moClipRect.value() );
816 awt::Size aOriginalSize( rGraphicHelper.getOriginalSize( xGraphic ) );
817 if ( aOriginalSize.Width && aOriginalSize.Height )
819 text::GraphicCrop aGraphCrop( 0, 0, 0, 0 );
820 if ( oClipRect.X1 )
821 aGraphCrop.Left = o3tl::convert(oClipRect.X1, aOriginalSize.Width, MAX_PERCENT);
822 if ( oClipRect.Y1 )
823 aGraphCrop.Top = o3tl::convert(oClipRect.Y1, aOriginalSize.Height, MAX_PERCENT);
824 if ( oClipRect.X2 )
825 aGraphCrop.Right = o3tl::convert(oClipRect.X2, aOriginalSize.Width, MAX_PERCENT);
826 if ( oClipRect.Y2 )
827 aGraphCrop.Bottom = o3tl::convert(oClipRect.Y2, aOriginalSize.Height, MAX_PERCENT);
828 rPropMap.setProperty(PROP_GraphicCrop, aGraphCrop);
830 if(mbIsCustomShape)
832 // Positive GraphicCrop values means "crop" here.
833 if (aGraphCrop.Left > 0 || aGraphCrop.Right > 0 || aGraphCrop.Top > 0 || aGraphCrop.Bottom > 0)
834 xGraphic = lclCropGraphic(xGraphic, CropQuotientsFromSrcRect(oClipRect));
839 if(mbIsCustomShape)
841 // it is a cropped graphic.
842 rPropMap.setProperty(PROP_FillStyle, FillStyle_BITMAP);
843 rPropMap.setProperty(PROP_FillBitmapMode, BitmapMode_STRETCH);
845 // It is a bitmap filled and rotated graphic.
846 // When custom shape is rotated, bitmap have to be rotated too.
847 if(rPropMap.hasProperty(PROP_RotateAngle))
849 tools::Long nAngle = rPropMap.getProperty(PROP_RotateAngle).get<tools::Long>();
850 xGraphic = lclRotateGraphic(xGraphic, Degree10(nAngle/10) );
853 // We have not core feature that flips graphic in the shape.
854 // Here we are applying flip property to bitmap directly.
855 if(bFlipH || bFlipV)
856 xGraphic = lclMirrorGraphic(xGraphic, bFlipH, bFlipV );
858 if(eColorMode == ColorMode_GREYS)
859 xGraphic = lclGreysScaleGraphic( xGraphic );
861 rPropMap.setProperty(PROP_FillBitmap, xGraphic);
863 else
864 rPropMap.setProperty(PROP_Graphic, xGraphic);
867 if ( maBlipProps.moAlphaModFix.has_value() )
869 rPropMap.setProperty(
870 mbIsCustomShape ? PROP_FillTransparence : PROP_Transparency,
871 static_cast<sal_Int16>(100 - (maBlipProps.moAlphaModFix.value() / PER_PERCENT)));
874 rPropMap.setProperty(PROP_GraphicColorMode, eColorMode);
876 // brightness and contrast
877 if( nBrightness != 0 )
878 rPropMap.setProperty(PROP_AdjustLuminance, nBrightness);
879 if( nContrast != 0 )
880 rPropMap.setProperty(PROP_AdjustContrast, nContrast);
882 // Media content
883 if (!m_sMediaPackageURL.isEmpty())
885 rPropMap.setProperty(PROP_MediaURL, m_sMediaPackageURL);
886 if (m_xMediaStream.is())
887 rPropMap.setProperty(PROP_PrivateStream, m_xMediaStream);
891 bool ArtisticEffectProperties::isEmpty() const
893 return msName.isEmpty();
896 css::beans::PropertyValue ArtisticEffectProperties::getEffect()
898 css::beans::PropertyValue aRet;
899 if( msName.isEmpty() )
900 return aRet;
902 css::uno::Sequence< css::beans::PropertyValue > aSeq( maAttribs.size() + 1 );
903 auto pSeq = aSeq.getArray();
904 sal_uInt32 i = 0;
905 for (auto const& attrib : maAttribs)
907 pSeq[i].Name = attrib.first;
908 pSeq[i].Value = attrib.second;
909 i++;
912 if( mrOleObjectInfo.maEmbeddedData.hasElements() )
914 css::uno::Sequence< css::beans::PropertyValue > aGraphicSeq{
915 comphelper::makePropertyValue("Id", mrOleObjectInfo.maProgId),
916 comphelper::makePropertyValue("Data", mrOleObjectInfo.maEmbeddedData)
919 pSeq[i].Name = "OriginalGraphic";
920 pSeq[i].Value <<= aGraphicSeq;
923 aRet.Name = msName;
924 aRet.Value <<= aSeq;
926 return aRet;
929 void ArtisticEffectProperties::assignUsed( const ArtisticEffectProperties& rSourceProps )
931 if( !rSourceProps.isEmpty() )
933 msName = rSourceProps.msName;
934 maAttribs = rSourceProps.maAttribs;
938 OUString ArtisticEffectProperties::getEffectString( sal_Int32 nToken )
940 switch( nToken )
942 // effects
943 case OOX_TOKEN( a14, artisticBlur ): return "artisticBlur";
944 case OOX_TOKEN( a14, artisticCement ): return "artisticCement";
945 case OOX_TOKEN( a14, artisticChalkSketch ): return "artisticChalkSketch";
946 case OOX_TOKEN( a14, artisticCrisscrossEtching ): return "artisticCrisscrossEtching";
947 case OOX_TOKEN( a14, artisticCutout ): return "artisticCutout";
948 case OOX_TOKEN( a14, artisticFilmGrain ): return "artisticFilmGrain";
949 case OOX_TOKEN( a14, artisticGlass ): return "artisticGlass";
950 case OOX_TOKEN( a14, artisticGlowDiffused ): return "artisticGlowDiffused";
951 case OOX_TOKEN( a14, artisticGlowEdges ): return "artisticGlowEdges";
952 case OOX_TOKEN( a14, artisticLightScreen ): return "artisticLightScreen";
953 case OOX_TOKEN( a14, artisticLineDrawing ): return "artisticLineDrawing";
954 case OOX_TOKEN( a14, artisticMarker ): return "artisticMarker";
955 case OOX_TOKEN( a14, artisticMosiaicBubbles ): return "artisticMosiaicBubbles";
956 case OOX_TOKEN( a14, artisticPaintStrokes ): return "artisticPaintStrokes";
957 case OOX_TOKEN( a14, artisticPaintBrush ): return "artisticPaintBrush";
958 case OOX_TOKEN( a14, artisticPastelsSmooth ): return "artisticPastelsSmooth";
959 case OOX_TOKEN( a14, artisticPencilGrayscale ): return "artisticPencilGrayscale";
960 case OOX_TOKEN( a14, artisticPencilSketch ): return "artisticPencilSketch";
961 case OOX_TOKEN( a14, artisticPhotocopy ): return "artisticPhotocopy";
962 case OOX_TOKEN( a14, artisticPlasticWrap ): return "artisticPlasticWrap";
963 case OOX_TOKEN( a14, artisticTexturizer ): return "artisticTexturizer";
964 case OOX_TOKEN( a14, artisticWatercolorSponge ): return "artisticWatercolorSponge";
965 case OOX_TOKEN( a14, brightnessContrast ): return "brightnessContrast";
966 case OOX_TOKEN( a14, colorTemperature ): return "colorTemperature";
967 case OOX_TOKEN( a14, saturation ): return "saturation";
968 case OOX_TOKEN( a14, sharpenSoften ): return "sharpenSoften";
970 // attributes
971 case XML_visible: return "visible";
972 case XML_trans: return "trans";
973 case XML_crackSpacing: return "crackSpacing";
974 case XML_pressure: return "pressure";
975 case XML_numberOfShades: return "numberOfShades";
976 case XML_grainSize: return "grainSize";
977 case XML_intensity: return "intensity";
978 case XML_smoothness: return "smoothness";
979 case XML_gridSize: return "gridSize";
980 case XML_pencilSize: return "pencilSize";
981 case XML_size: return "size";
982 case XML_brushSize: return "brushSize";
983 case XML_scaling: return "scaling";
984 case XML_detail: return "detail";
985 case XML_bright: return "bright";
986 case XML_contrast: return "contrast";
987 case XML_colorTemp: return "colorTemp";
988 case XML_sat: return "sat";
989 case XML_amount: return "amount";
991 SAL_WARN( "oox.drawingml", "ArtisticEffectProperties::getEffectString: unexpected token " << nToken );
992 return OUString();
995 sal_Int32 ArtisticEffectProperties::getEffectToken( const OUString& sName )
997 // effects
998 if( sName == "artisticBlur" )
999 return XML_artisticBlur;
1000 else if( sName == "artisticCement" )
1001 return XML_artisticCement;
1002 else if( sName == "artisticChalkSketch" )
1003 return XML_artisticChalkSketch;
1004 else if( sName == "artisticCrisscrossEtching" )
1005 return XML_artisticCrisscrossEtching;
1006 else if( sName == "artisticCutout" )
1007 return XML_artisticCutout;
1008 else if( sName == "artisticFilmGrain" )
1009 return XML_artisticFilmGrain;
1010 else if( sName == "artisticGlass" )
1011 return XML_artisticGlass;
1012 else if( sName == "artisticGlowDiffused" )
1013 return XML_artisticGlowDiffused;
1014 else if( sName == "artisticGlowEdges" )
1015 return XML_artisticGlowEdges;
1016 else if( sName == "artisticLightScreen" )
1017 return XML_artisticLightScreen;
1018 else if( sName == "artisticLineDrawing" )
1019 return XML_artisticLineDrawing;
1020 else if( sName == "artisticMarker" )
1021 return XML_artisticMarker;
1022 else if( sName == "artisticMosiaicBubbles" )
1023 return XML_artisticMosiaicBubbles;
1024 else if( sName == "artisticPaintStrokes" )
1025 return XML_artisticPaintStrokes;
1026 else if( sName == "artisticPaintBrush" )
1027 return XML_artisticPaintBrush;
1028 else if( sName == "artisticPastelsSmooth" )
1029 return XML_artisticPastelsSmooth;
1030 else if( sName == "artisticPencilGrayscale" )
1031 return XML_artisticPencilGrayscale;
1032 else if( sName == "artisticPencilSketch" )
1033 return XML_artisticPencilSketch;
1034 else if( sName == "artisticPhotocopy" )
1035 return XML_artisticPhotocopy;
1036 else if( sName == "artisticPlasticWrap" )
1037 return XML_artisticPlasticWrap;
1038 else if( sName == "artisticTexturizer" )
1039 return XML_artisticTexturizer;
1040 else if( sName == "artisticWatercolorSponge" )
1041 return XML_artisticWatercolorSponge;
1042 else if( sName == "brightnessContrast" )
1043 return XML_brightnessContrast;
1044 else if( sName == "colorTemperature" )
1045 return XML_colorTemperature;
1046 else if( sName == "saturation" )
1047 return XML_saturation;
1048 else if( sName == "sharpenSoften" )
1049 return XML_sharpenSoften;
1051 // attributes
1052 else if( sName == "visible" )
1053 return XML_visible;
1054 else if( sName == "trans" )
1055 return XML_trans;
1056 else if( sName == "crackSpacing" )
1057 return XML_crackSpacing;
1058 else if( sName == "pressure" )
1059 return XML_pressure;
1060 else if( sName == "numberOfShades" )
1061 return XML_numberOfShades;
1062 else if( sName == "grainSize" )
1063 return XML_grainSize;
1064 else if( sName == "intensity" )
1065 return XML_intensity;
1066 else if( sName == "smoothness" )
1067 return XML_smoothness;
1068 else if( sName == "gridSize" )
1069 return XML_gridSize;
1070 else if( sName == "pencilSize" )
1071 return XML_pencilSize;
1072 else if( sName == "size" )
1073 return XML_size;
1074 else if( sName == "brushSize" )
1075 return XML_brushSize;
1076 else if( sName == "scaling" )
1077 return XML_scaling;
1078 else if( sName == "detail" )
1079 return XML_detail;
1080 else if( sName == "bright" )
1081 return XML_bright;
1082 else if( sName == "contrast" )
1083 return XML_contrast;
1084 else if( sName == "colorTemp" )
1085 return XML_colorTemp;
1086 else if( sName == "sat" )
1087 return XML_sat;
1088 else if( sName == "amount" )
1089 return XML_amount;
1091 SAL_WARN( "oox.drawingml", "ArtisticEffectProperties::getEffectToken - unexpected token name: " << sName );
1092 return XML_none;
1095 } // namespace oox
1097 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */