1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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 #include <frozen/bits/defines.h>
53 #include <frozen/bits/elsa_std.h>
54 #include <frozen/unordered_map.h>
57 using namespace ::com::sun::star
;
58 using namespace ::com::sun::star::drawing
;
59 using namespace ::com::sun::star::graphic
;
61 using ::com::sun::star::uno::Reference
;
62 using ::com::sun::star::uno::Exception
;
63 using ::com::sun::star::uno::UNO_QUERY_THROW
;
64 using ::com::sun::star::geometry::IntegerRectangle2D
;
66 namespace oox::drawingml
{
70 Reference
< XGraphic
> lclCheckAndApplyDuotoneTransform(const BlipFillProperties
& aBlipProps
, uno::Reference
<graphic::XGraphic
> const & xGraphic
,
71 const GraphicHelper
& rGraphicHelper
, const ::Color nPhClr
)
73 if (aBlipProps
.maDuotoneColors
[0].isUsed() && aBlipProps
.maDuotoneColors
[1].isUsed())
75 ::Color nColor1
= aBlipProps
.maDuotoneColors
[0].getColor( rGraphicHelper
, nPhClr
);
76 ::Color nColor2
= aBlipProps
.maDuotoneColors
[1].getColor( rGraphicHelper
, nPhClr
);
78 uno::Reference
<graphic::XGraphicTransformer
> xTransformer(aBlipProps
.mxFillGraphic
, uno::UNO_QUERY
);
79 if (xTransformer
.is())
80 return xTransformer
->applyDuotone(xGraphic
, sal_Int32(nColor1
), sal_Int32(nColor2
));
85 Reference
< XGraphic
> lclRotateGraphic(uno::Reference
<graphic::XGraphic
> const & xGraphic
, Degree10 nRotation
)
87 ::Graphic
aGraphic(xGraphic
);
88 ::Graphic aReturnGraphic
;
90 assert (aGraphic
.GetType() == GraphicType::Bitmap
);
92 BitmapEx
aBitmapEx(aGraphic
.GetBitmapEx());
93 const ::Color
& aColor
= ::Color(0x00);
94 aBitmapEx
.Rotate(nRotation
, aColor
);
95 aReturnGraphic
= ::Graphic(aBitmapEx
);
96 aReturnGraphic
.setOriginURL(aGraphic
.getOriginURL());
98 return aReturnGraphic
.GetXGraphic();
101 using Quotients
= std::tuple
<double, double, double, double>;
102 Quotients
getQuotients(geometry::IntegerRectangle2D aRelRect
, double hDiv
, double vDiv
)
104 return { aRelRect
.X1
/ hDiv
, aRelRect
.Y1
/ vDiv
, aRelRect
.X2
/ hDiv
, aRelRect
.Y2
/ vDiv
};
107 // ECMA-376 Part 1 20.1.8.55 srcRect (Source Rectangle)
108 std::optional
<Quotients
> CropQuotientsFromSrcRect(geometry::IntegerRectangle2D aSrcRect
)
110 aSrcRect
.X1
= std::max(aSrcRect
.X1
, sal_Int32(0));
111 aSrcRect
.X2
= std::max(aSrcRect
.X2
, sal_Int32(0));
112 aSrcRect
.Y1
= std::max(aSrcRect
.Y1
, sal_Int32(0));
113 aSrcRect
.Y2
= std::max(aSrcRect
.Y2
, sal_Int32(0));
114 if (aSrcRect
.X1
+ aSrcRect
.X2
>= MAX_PERCENT
|| aSrcRect
.Y1
+ aSrcRect
.Y2
>= MAX_PERCENT
)
115 return {}; // Cropped everything
116 return getQuotients(aSrcRect
, MAX_PERCENT
, MAX_PERCENT
);
119 // ECMA-376 Part 1 20.1.8.30 fillRect (Fill Rectangle)
120 std::optional
<Quotients
> CropQuotientsFromFillRect(geometry::IntegerRectangle2D aFillRect
)
122 aFillRect
.X1
= std::min(aFillRect
.X1
, sal_Int32(0));
123 aFillRect
.X2
= std::min(aFillRect
.X2
, sal_Int32(0));
124 aFillRect
.Y1
= std::min(aFillRect
.Y1
, sal_Int32(0));
125 aFillRect
.Y2
= std::min(aFillRect
.Y2
, sal_Int32(0));
126 // Negative divisor and negative relative offset give positive value wanted in lclCropGraphic
127 return getQuotients(aFillRect
, -MAX_PERCENT
+ aFillRect
.X1
+ aFillRect
.X2
,
128 -MAX_PERCENT
+ aFillRect
.Y1
+ aFillRect
.Y2
);
131 // Crops a piece of the bitmap. lclCropGraphic doesn't handle growing.
132 Reference
<XGraphic
> lclCropGraphic(uno::Reference
<graphic::XGraphic
> const& xGraphic
,
133 std::optional
<Quotients
> quotients
)
135 ::Graphic
aGraphic(xGraphic
);
136 assert (aGraphic
.GetType() == GraphicType::Bitmap
);
141 aBitmapEx
= aGraphic
.GetBitmapEx();
143 const Size bmpSize
= aBitmapEx
.GetSizePixel();
144 const auto& [qx1
, qy1
, qx2
, qy2
] = *quotients
;
145 const tools::Long l
= std::round(bmpSize
.Width() * qx1
);
146 const tools::Long t
= std::round(bmpSize
.Height() * qy1
);
147 const tools::Long r
= std::round(bmpSize
.Width() * qx2
);
148 const tools::Long b
= std::round(bmpSize
.Height() * qy2
);
150 aBitmapEx
.Crop({ l
, t
, bmpSize
.Width() - r
- 1, bmpSize
.Height() - b
- 1 });
153 ::Graphic
aReturnGraphic(aBitmapEx
);
154 aReturnGraphic
.setOriginURL(aGraphic
.getOriginURL());
156 return aReturnGraphic
.GetXGraphic();
159 Reference
< XGraphic
> lclMirrorGraphic(uno::Reference
<graphic::XGraphic
> const & xGraphic
, bool bFlipH
, bool bFlipV
)
161 ::Graphic
aGraphic(xGraphic
);
162 ::Graphic aReturnGraphic
;
164 assert (aGraphic
.GetType() == GraphicType::Bitmap
);
166 BitmapEx
aBitmapEx(aGraphic
.GetBitmapEx());
167 BmpMirrorFlags nMirrorFlags
= BmpMirrorFlags::NONE
;
170 nMirrorFlags
|= BmpMirrorFlags::Horizontal
;
172 nMirrorFlags
|= BmpMirrorFlags::Vertical
;
174 aBitmapEx
.Mirror(nMirrorFlags
);
176 aReturnGraphic
= ::Graphic(aBitmapEx
);
177 aReturnGraphic
.setOriginURL(aGraphic
.getOriginURL());
179 return aReturnGraphic
.GetXGraphic();
182 Reference
< XGraphic
> lclGreysScaleGraphic(uno::Reference
<graphic::XGraphic
> const & xGraphic
)
184 ::Graphic
aGraphic(xGraphic
);
185 ::Graphic aReturnGraphic
;
187 assert (aGraphic
.GetType() == GraphicType::Bitmap
);
189 BitmapEx
aBitmapEx(aGraphic
.GetBitmapEx());
190 aBitmapEx
.Convert(BmpConversion::N8BitGreys
);
192 aReturnGraphic
= ::Graphic(aBitmapEx
);
193 aReturnGraphic
.setOriginURL(aGraphic
.getOriginURL());
195 return aReturnGraphic
.GetXGraphic();
198 /// Applies the graphic Black&White (Monochrome) effect with the imported threshold
199 Reference
<XGraphic
> lclApplyBlackWhiteEffect(const BlipFillProperties
& aBlipProps
,
200 const uno::Reference
<graphic::XGraphic
>& xGraphic
)
202 const auto& oBiLevelThreshold
= aBlipProps
.moBiLevelThreshold
;
203 if (oBiLevelThreshold
.has_value())
206 = static_cast<sal_uInt8
>(oBiLevelThreshold
.value() * 255 / MAX_PERCENT
);
208 ::Graphic
aGraphic(xGraphic
);
209 ::Graphic aReturnGraphic
;
211 BitmapEx
aBitmapEx(aGraphic
.GetBitmapEx());
212 AlphaMask
aMask(aBitmapEx
.GetAlphaMask());
214 BitmapEx
aTmpBmpEx(aBitmapEx
.GetBitmap());
215 BitmapFilter::Filter(aTmpBmpEx
, BitmapMonochromeFilter
{ nThreshold
});
217 aReturnGraphic
= ::Graphic(BitmapEx(aTmpBmpEx
.GetBitmap(), aMask
));
218 aReturnGraphic
.setOriginURL(aGraphic
.getOriginURL());
219 return aReturnGraphic
.GetXGraphic();
224 Reference
< XGraphic
> lclCheckAndApplyChangeColorTransform(const BlipFillProperties
&aBlipProps
, uno::Reference
<graphic::XGraphic
> const & xGraphic
,
225 const GraphicHelper
& rGraphicHelper
, const ::Color nPhClr
)
227 if( aBlipProps
.maColorChangeFrom
.isUsed() && aBlipProps
.maColorChangeTo
.isUsed() )
229 ::Color nFromColor
= aBlipProps
.maColorChangeFrom
.getColor( rGraphicHelper
, nPhClr
);
230 ::Color nToColor
= aBlipProps
.maColorChangeTo
.getColor( rGraphicHelper
, nPhClr
);
231 if ( (nFromColor
!= nToColor
) || aBlipProps
.maColorChangeTo
.hasTransparency() )
233 sal_Int16 nToTransparence
= aBlipProps
.maColorChangeTo
.getTransparency();
234 sal_Int8 nToAlpha
= static_cast< sal_Int8
>( (100 - nToTransparence
) * 2.55 );
236 sal_uInt8 nTolerance
= 9;
237 Graphic aGraphic
{ xGraphic
};
238 if( aGraphic
.IsGfxLink() )
240 // tdf#149670: Try to guess tolerance depending on image format
241 switch (aGraphic
.GetGfxLink().GetType())
243 case GfxLinkType::NativeJpg
:
246 case GfxLinkType::NativePng
:
247 case GfxLinkType::NativeTif
:
250 case GfxLinkType::NativeBmp
:
258 uno::Reference
<graphic::XGraphicTransformer
> xTransformer(aBlipProps
.mxFillGraphic
, uno::UNO_QUERY
);
259 if (xTransformer
.is())
260 return xTransformer
->colorChange(xGraphic
, sal_Int32(nFromColor
), nTolerance
, sal_Int32(nToColor
), nToAlpha
);
266 uno::Reference
<graphic::XGraphic
> applyBrightnessContrast(uno::Reference
<graphic::XGraphic
> const & xGraphic
, sal_Int32 brightness
, sal_Int32 contrast
)
268 uno::Reference
<graphic::XGraphicTransformer
> xTransformer(xGraphic
, uno::UNO_QUERY
);
269 if (xTransformer
.is())
270 return xTransformer
->applyBrightnessContrast(xGraphic
, brightness
, contrast
, true);
274 BitmapMode
lclGetBitmapMode( sal_Int32 nToken
)
276 OSL_ASSERT((nToken
& sal_Int32(0xFFFF0000))==0);
279 case XML_tile
: return BitmapMode_REPEAT
;
280 case XML_stretch
: return BitmapMode_STRETCH
;
283 // tdf#128596 Default value is XML_tile for MSO.
284 return BitmapMode_REPEAT
;
287 RectanglePoint
lclGetRectanglePoint( sal_Int32 nToken
)
289 OSL_ASSERT((nToken
& sal_Int32(0xFFFF0000))==0);
292 case XML_tl
: return RectanglePoint_LEFT_TOP
;
293 case XML_t
: return RectanglePoint_MIDDLE_TOP
;
294 case XML_tr
: return RectanglePoint_RIGHT_TOP
;
295 case XML_l
: return RectanglePoint_LEFT_MIDDLE
;
296 case XML_ctr
: return RectanglePoint_MIDDLE_MIDDLE
;
297 case XML_r
: return RectanglePoint_RIGHT_MIDDLE
;
298 case XML_bl
: return RectanglePoint_LEFT_BOTTOM
;
299 case XML_b
: return RectanglePoint_MIDDLE_BOTTOM
;
300 case XML_br
: return RectanglePoint_RIGHT_BOTTOM
;
302 return RectanglePoint_LEFT_TOP
;
305 awt::Size
lclGetOriginalSize( const GraphicHelper
& rGraphicHelper
, const Reference
< XGraphic
>& rxGraphic
)
307 awt::Size
aSizeHmm( 0, 0 );
310 Reference
< beans::XPropertySet
> xGraphicPropertySet( rxGraphic
, UNO_QUERY_THROW
);
311 if( xGraphicPropertySet
->getPropertyValue( u
"Size100thMM"_ustr
) >>= aSizeHmm
)
313 if( !aSizeHmm
.Width
&& !aSizeHmm
.Height
)
314 { // MAPMODE_PIXEL USED :-(
315 awt::Size
aSourceSizePixel( 0, 0 );
316 if( xGraphicPropertySet
->getPropertyValue( u
"SizePixel"_ustr
) >>= aSourceSizePixel
)
317 aSizeHmm
= rGraphicHelper
.convertScreenPixelToHmm( aSourceSizePixel
);
329 void GradientFillProperties::assignUsed( const GradientFillProperties
& rSourceProps
)
331 if( !rSourceProps
.maGradientStops
.empty() )
332 maGradientStops
= rSourceProps
.maGradientStops
;
333 assignIfUsed( moFillToRect
, rSourceProps
.moFillToRect
);
334 assignIfUsed( moTileRect
, rSourceProps
.moTileRect
);
335 assignIfUsed( moGradientPath
, rSourceProps
.moGradientPath
);
336 assignIfUsed( moShadeAngle
, rSourceProps
.moShadeAngle
);
337 assignIfUsed( moShadeFlip
, rSourceProps
.moShadeFlip
);
338 assignIfUsed( moShadeScaled
, rSourceProps
.moShadeScaled
);
339 assignIfUsed( moRotateWithShape
, rSourceProps
.moRotateWithShape
);
342 void PatternFillProperties::assignUsed( const PatternFillProperties
& rSourceProps
)
344 maPattFgColor
.assignIfUsed( rSourceProps
.maPattFgColor
);
345 maPattBgColor
.assignIfUsed( rSourceProps
.maPattBgColor
);
346 assignIfUsed( moPattPreset
, rSourceProps
.moPattPreset
);
349 void BlipFillProperties::assignUsed( const BlipFillProperties
& rSourceProps
)
351 if(rSourceProps
.mxFillGraphic
.is())
352 mxFillGraphic
= rSourceProps
.mxFillGraphic
;
353 assignIfUsed( moBitmapMode
, rSourceProps
.moBitmapMode
);
354 assignIfUsed( moFillRect
, rSourceProps
.moFillRect
);
355 assignIfUsed( moTileOffsetX
, rSourceProps
.moTileOffsetX
);
356 assignIfUsed( moTileOffsetY
, rSourceProps
.moTileOffsetY
);
357 assignIfUsed( moTileScaleX
, rSourceProps
.moTileScaleX
);
358 assignIfUsed( moTileScaleY
, rSourceProps
.moTileScaleY
);
359 assignIfUsed( moTileAlign
, rSourceProps
.moTileAlign
);
360 assignIfUsed( moTileFlip
, rSourceProps
.moTileFlip
);
361 assignIfUsed( moRotateWithShape
, rSourceProps
.moRotateWithShape
);
362 assignIfUsed( moColorEffect
, rSourceProps
.moColorEffect
);
363 assignIfUsed( moBrightness
, rSourceProps
.moBrightness
);
364 assignIfUsed( moContrast
, rSourceProps
.moContrast
);
365 assignIfUsed( moBiLevelThreshold
, rSourceProps
.moBiLevelThreshold
);
366 maColorChangeFrom
.assignIfUsed( rSourceProps
.maColorChangeFrom
);
367 maColorChangeTo
.assignIfUsed( rSourceProps
.maColorChangeTo
);
368 maDuotoneColors
[0].assignIfUsed( rSourceProps
.maDuotoneColors
[0] );
369 maDuotoneColors
[1].assignIfUsed( rSourceProps
.maDuotoneColors
[1] );
370 maEffect
.assignUsed( rSourceProps
.maEffect
);
371 assignIfUsed(moAlphaModFix
, rSourceProps
.moAlphaModFix
);
374 void FillProperties::assignUsed( const FillProperties
& rSourceProps
)
376 assignIfUsed( moFillType
, rSourceProps
.moFillType
);
377 maFillColor
.assignIfUsed( rSourceProps
.maFillColor
);
378 assignIfUsed( moUseBgFill
, rSourceProps
.moUseBgFill
);
379 maGradientProps
.assignUsed( rSourceProps
.maGradientProps
);
380 maPatternProps
.assignUsed( rSourceProps
.maPatternProps
);
381 maBlipProps
.assignUsed( rSourceProps
.maBlipProps
);
384 Color
FillProperties::getBestSolidColor() const
387 if( moFillType
.has_value() ) switch( moFillType
.value() )
390 aSolidColor
= maFillColor
;
393 if( !maGradientProps
.maGradientStops
.empty() )
395 GradientFillProperties::GradientStopMap::const_iterator aGradientStop
=
396 maGradientProps
.maGradientStops
.begin();
397 if (maGradientProps
.maGradientStops
.size() > 2)
399 aSolidColor
= aGradientStop
->second
;
403 aSolidColor
= maPatternProps
.maPattBgColor
.isUsed() ? maPatternProps
.maPattBgColor
: maPatternProps
.maPattFgColor
;
409 void FillProperties::pushToPropMap(ShapePropertyMap
& rPropMap
, const GraphicHelper
& rGraphicHelper
,
410 sal_Int32 nShapeRotation
, ::Color nPhClr
,
411 const css::awt::Size
& rSize
, sal_Int16 nPhClrTheme
, bool bFlipH
,
412 bool bFlipV
, bool bIsCustomShape
) const
414 if( !moFillType
.has_value() )
417 FillStyle eFillStyle
= FillStyle_NONE
;
418 OSL_ASSERT((moFillType
.value() & sal_Int32(0xFFFF0000))==0);
419 switch( moFillType
.value() )
423 eFillStyle
= FillStyle_NONE
;
424 rPropMap
.setProperty(ShapeProperty::FillUseSlideBackground
, moUseBgFill
.value_or(false));
429 if( maFillColor
.isUsed() )
431 ::Color aFillColor
= maFillColor
.getColor(rGraphicHelper
, nPhClr
);
432 rPropMap
.setProperty(ShapeProperty::FillColor
, aFillColor
);
433 if( maFillColor
.hasTransparency() )
434 rPropMap
.setProperty( ShapeProperty::FillTransparency
, maFillColor
.getTransparency() );
436 model::ComplexColor aComplexColor
;
437 if (aFillColor
== nPhClr
)
439 aComplexColor
.setThemeColor(model::convertToThemeColorType(nPhClrTheme
));
443 aComplexColor
= maFillColor
.getComplexColor();
445 rPropMap
.setProperty(PROP_FillComplexColor
, model::color::createXComplexColor(aComplexColor
));
447 eFillStyle
= FillStyle_SOLID
;
452 // do not create gradient struct if property is not supported...
453 if( rPropMap
.supportsProperty( ShapeProperty::FillGradient
) )
455 // prepare ColorStops
456 basegfx::BColorStops aColorStops
;
457 basegfx::BColorStops aTransparencyStops
;
458 bool bContainsTransparency(false);
460 // convert to BColorStops, check for contained transparency
461 for (const auto& rCandidate
: maGradientProps
.maGradientStops
)
463 const ::Color
aColor(rCandidate
.second
.getColor(rGraphicHelper
, nPhClr
));
464 aColorStops
.emplace_back(rCandidate
.first
, aColor
.getBColor());
465 bContainsTransparency
= bContainsTransparency
|| rCandidate
.second
.hasTransparency();
468 // if we have transparency, convert to BColorStops
469 if (bContainsTransparency
)
471 for (const auto& rCandidate
: maGradientProps
.maGradientStops
)
473 const double fTrans(rCandidate
.second
.getTransparency() * (1.0/100.0));
474 aTransparencyStops
.emplace_back(rCandidate
.first
, basegfx::BColor(fTrans
, fTrans
, fTrans
));
478 // prepare BGradient with some defaults
479 // CAUTION: This used awt::Gradient2 before who's empty constructor
480 // (see workdir/UnoApiHeadersTarget/offapi/normal/com/sun/
481 // star/awt/Gradient.hpp) initializes all to zeros, so reflect
482 // this here. OTOH set all that were set, e.g. Start/EndIntens
483 // were set to 100, so just use default of BGradient constructor
484 basegfx::BGradient
aGradient(
486 awt::GradientStyle_LINEAR
,
489 0, // OfsX -> 0, not 50 (!)
490 0); // OfsY -> 0, not 50 (!)
492 // "rotate with shape" set to false -> do not rotate
493 if (!maGradientProps
.moRotateWithShape
.value_or(true))
498 if (maGradientProps
.moGradientPath
.has_value())
500 IntegerRectangle2D aFillToRect
= maGradientProps
.moFillToRect
.value_or( IntegerRectangle2D( 0, 0, MAX_PERCENT
, MAX_PERCENT
) );
501 sal_Int32 nCenterX
= (MAX_PERCENT
+ aFillToRect
.X1
- aFillToRect
.X2
) / 2;
502 aGradient
.SetXOffset(getLimitedValue
<sal_Int16
, sal_Int32
>(
503 nCenterX
/ PER_PERCENT
, 0, 100));
504 sal_Int32 nCenterY
= (MAX_PERCENT
+ aFillToRect
.Y1
- aFillToRect
.Y2
) / 2;
505 aGradient
.SetYOffset(getLimitedValue
<sal_Int16
, sal_Int32
>(
506 nCenterY
/ PER_PERCENT
, 0, 100));
508 if( maGradientProps
.moGradientPath
.value() == XML_circle
)
510 // Style should be radial at least when the horizontal center is at 50%.
511 // Otherwise import as a linear gradient, because it is the most similar to the MSO radial style.
512 // aGradient.SetGradientStyle(awt::GradientStyle_LINEAR);
513 if( 100 == aGradient
.GetXOffset() && 100 == aGradient
.GetYOffset() )
514 aGradient
.SetAngle( Degree10(450) );
515 else if( 0 == aGradient
.GetXOffset() && 100 == aGradient
.GetYOffset() )
516 aGradient
.SetAngle( Degree10(3150) );
517 else if( 100 == aGradient
.GetXOffset() && 0 == aGradient
.GetYOffset() )
518 aGradient
.SetAngle( Degree10(1350) );
519 else if( 0 == aGradient
.GetXOffset() && 0 == aGradient
.GetYOffset() )
520 aGradient
.SetAngle( Degree10(2250) );
522 aGradient
.SetGradientStyle(awt::GradientStyle_RADIAL
);
526 aGradient
.SetGradientStyle(awt::GradientStyle_RECT
);
529 aColorStops
.reverseColorStops();
530 aGradient
.SetColorStops(aColorStops
);
531 aTransparencyStops
.reverseColorStops();
533 else if (!maGradientProps
.maGradientStops
.empty())
535 // aGradient.SetGradientStyle(awt::GradientStyle_LINEAR);
536 sal_Int32
nShadeAngle(maGradientProps
.moShadeAngle
.value_or( 0 ));
539 nShadeAngle
= 180*60000 - nShadeAngle
;
541 nShadeAngle
= -nShadeAngle
;
542 const sal_Int32 nDmlAngle
= nShadeAngle
+ nShapeRotation
;
544 // convert DrawingML angle (in 1/60000 degrees) to API angle (in 1/10 degrees)
545 aGradient
.SetAngle(Degree10(static_cast< sal_Int16
>( (8100 - (nDmlAngle
/ (PER_DEGREE
/ 10))) % 3600 )));
547 // If this is symmetrical, set it as an axial gradient for better UI/export.
548 // There were chart2 unit test failures when doing this to transparent gradients
549 // so just avoid that case.
550 if (!bContainsTransparency
)
551 aGradient
.tryToConvertToAxial();
554 if (awt::GradientStyle_RECT
== aGradient
.GetGradientStyle())
556 // MCGR: tdf#155362: better support border
557 // CAUTION: Need to handle TransparencyStops if used
558 aGradient
.tryToRecreateBorder(aTransparencyStops
.empty() ? nullptr : &aTransparencyStops
);
561 // push gradient or named gradient to property map
562 if (rPropMap
.setProperty(ShapeProperty::FillGradient
, model::gradient::createUnoGradient2(aGradient
)))
564 eFillStyle
= FillStyle_GRADIENT
;
567 // push gradient transparency to property map if it exists
568 if (!aTransparencyStops
.empty())
570 aGradient
.SetColorStops(aTransparencyStops
);
571 rPropMap
.setProperty(ShapeProperty::GradientTransparency
, model::gradient::createUnoGradient2(aGradient
));
577 // do not start complex graphic transformation if property is not supported...
578 if (maBlipProps
.mxFillGraphic
.is() && rPropMap
.supportsProperty(ShapeProperty::FillBitmap
))
580 uno::Reference
<graphic::XGraphic
> xGraphic
= lclCheckAndApplyDuotoneTransform(maBlipProps
, maBlipProps
.mxFillGraphic
, rGraphicHelper
, nPhClr
);
581 // TODO: "rotate with shape" is not possible with our current core
585 if (maBlipProps
.moColorEffect
.value_or(XML_TOKEN_INVALID
) == XML_grayscl
)
586 xGraphic
= lclGreysScaleGraphic(xGraphic
);
588 if (rPropMap
.supportsProperty(ShapeProperty::FillBitmapName
) &&
589 rPropMap
.setProperty(ShapeProperty::FillBitmapName
, xGraphic
))
591 eFillStyle
= FillStyle_BITMAP
;
593 else if (rPropMap
.setProperty(ShapeProperty::FillBitmap
, xGraphic
))
595 eFillStyle
= FillStyle_BITMAP
;
599 // set other bitmap properties, if bitmap has been inserted into the map
600 if( eFillStyle
== FillStyle_BITMAP
)
602 // bitmap mode (single, repeat, stretch)
603 BitmapMode eBitmapMode
= lclGetBitmapMode( maBlipProps
.moBitmapMode
.value_or( XML_TOKEN_INVALID
) );
605 // additional settings for repeated bitmap
606 if( eBitmapMode
== BitmapMode_REPEAT
)
608 // anchor position inside bitmap
609 RectanglePoint eRectPoint
= lclGetRectanglePoint( maBlipProps
.moTileAlign
.value_or( XML_tl
) );
610 rPropMap
.setProperty( ShapeProperty::FillBitmapRectanglePoint
, eRectPoint
);
612 awt::Size aOriginalSize
= lclGetOriginalSize(rGraphicHelper
, maBlipProps
.mxFillGraphic
);
613 if( (aOriginalSize
.Width
> 0) && (aOriginalSize
.Height
> 0) )
615 // size of one bitmap tile (given as 1/1000 percent of bitmap size), convert to 1/100 mm
616 double fScaleX
= maBlipProps
.moTileScaleX
.value_or( MAX_PERCENT
) / static_cast< double >( MAX_PERCENT
);
617 sal_Int32 nFillBmpSizeX
= getLimitedValue
< sal_Int32
, double >( aOriginalSize
.Width
* fScaleX
, 1, SAL_MAX_INT32
);
618 rPropMap
.setProperty( ShapeProperty::FillBitmapSizeX
, nFillBmpSizeX
);
619 double fScaleY
= maBlipProps
.moTileScaleY
.value_or( MAX_PERCENT
) / static_cast< double >( MAX_PERCENT
);
620 sal_Int32 nFillBmpSizeY
= getLimitedValue
< sal_Int32
, double >( aOriginalSize
.Height
* fScaleY
, 1, SAL_MAX_INT32
);
621 rPropMap
.setProperty( ShapeProperty::FillBitmapSizeY
, nFillBmpSizeY
);
623 awt::Size
aBmpSize(nFillBmpSizeX
, nFillBmpSizeY
);
624 // offset of the first bitmap tile (given as EMUs), convert to percent
625 sal_Int16 nTileOffsetX
= getDoubleIntervalValue
< sal_Int16
>(std::round(maBlipProps
.moTileOffsetX
.value_or( 0 ) / 3.6 / aBmpSize
.Width
), 0, 100 );
626 rPropMap
.setProperty( ShapeProperty::FillBitmapOffsetX
, nTileOffsetX
);
627 sal_Int16 nTileOffsetY
= getDoubleIntervalValue
< sal_Int16
>(std::round(maBlipProps
.moTileOffsetY
.value_or( 0 ) / 3.6 / aBmpSize
.Height
), 0, 100 );
628 rPropMap
.setProperty( ShapeProperty::FillBitmapOffsetY
, nTileOffsetY
);
631 else if ( eBitmapMode
== BitmapMode_STRETCH
&& maBlipProps
.moFillRect
.has_value() )
633 geometry::IntegerRectangle2D
aFillRect( maBlipProps
.moFillRect
.value() );
634 awt::Size
aOriginalSize( rGraphicHelper
.getOriginalSize( xGraphic
) );
635 if ( aOriginalSize
.Width
&& aOriginalSize
.Height
)
637 text::GraphicCrop
aGraphCrop( 0, 0, 0, 0 );
639 aGraphCrop
.Left
= o3tl::convert(aFillRect
.X1
, aOriginalSize
.Width
, MAX_PERCENT
);
641 aGraphCrop
.Top
= o3tl::convert(aFillRect
.Y1
, aOriginalSize
.Height
, MAX_PERCENT
);
643 aGraphCrop
.Right
= o3tl::convert(aFillRect
.X2
, aOriginalSize
.Width
, MAX_PERCENT
);
645 aGraphCrop
.Bottom
= o3tl::convert(aFillRect
.Y2
, aOriginalSize
.Height
, MAX_PERCENT
);
647 bool bHasCropValues
= aGraphCrop
.Left
!= 0 || aGraphCrop
.Right
!=0 || aGraphCrop
.Top
!= 0 || aGraphCrop
.Bottom
!= 0;
648 // Negative GraphicCrop values means "crop" here.
649 bool bNeedCrop
= aGraphCrop
.Left
<= 0 && aGraphCrop
.Right
<= 0 && aGraphCrop
.Top
<= 0 && aGraphCrop
.Bottom
<= 0;
653 if (bIsCustomShape
&& bNeedCrop
)
655 // Physically crop the image
656 // In this case, don't set the PROP_GraphicCrop because that
657 // would lead to applying the crop twice after roundtrip
658 xGraphic
= lclCropGraphic(xGraphic
, CropQuotientsFromFillRect(aFillRect
));
659 if (rPropMap
.supportsProperty(ShapeProperty::FillBitmapName
))
660 rPropMap
.setProperty(ShapeProperty::FillBitmapName
, xGraphic
);
662 rPropMap
.setProperty(ShapeProperty::FillBitmap
, xGraphic
);
664 else if ((aFillRect
.X1
!= 0 && aFillRect
.X2
!= 0
665 && aFillRect
.X1
!= aFillRect
.X2
)
666 || (aFillRect
.Y1
!= 0 && aFillRect
.Y2
!= 0
667 && aFillRect
.Y1
!= aFillRect
.Y2
))
669 rPropMap
.setProperty(PROP_GraphicCrop
, aGraphCrop
);
673 double nL
= aFillRect
.X1
/ static_cast<double>(MAX_PERCENT
);
674 double nT
= aFillRect
.Y1
/ static_cast<double>(MAX_PERCENT
);
675 double nR
= aFillRect
.X2
/ static_cast<double>(MAX_PERCENT
);
676 double nB
= aFillRect
.Y2
/ static_cast<double>(MAX_PERCENT
);
680 nSizeX
= rSize
.Width
* (1 - (nL
+ nR
));
682 nSizeX
= rSize
.Width
;
683 rPropMap
.setProperty(ShapeProperty::FillBitmapSizeX
, nSizeX
);
687 nSizeY
= rSize
.Height
* (1 - (nT
+ nB
));
689 nSizeY
= rSize
.Height
;
690 rPropMap
.setProperty(ShapeProperty::FillBitmapSizeY
, nSizeY
);
692 RectanglePoint eRectPoint
;
693 if (!aFillRect
.X1
&& aFillRect
.X2
)
695 if (!aFillRect
.Y1
&& aFillRect
.Y2
)
696 eRectPoint
= lclGetRectanglePoint(XML_tl
);
697 else if (aFillRect
.Y1
&& !aFillRect
.Y2
)
698 eRectPoint
= lclGetRectanglePoint(XML_bl
);
700 eRectPoint
= lclGetRectanglePoint(XML_l
);
702 else if (aFillRect
.X1
&& !aFillRect
.X2
)
704 if (!aFillRect
.Y1
&& aFillRect
.Y2
)
705 eRectPoint
= lclGetRectanglePoint(XML_tr
);
706 else if (aFillRect
.Y1
&& !aFillRect
.Y2
)
707 eRectPoint
= lclGetRectanglePoint(XML_br
);
709 eRectPoint
= lclGetRectanglePoint(XML_r
);
713 if (!aFillRect
.Y1
&& aFillRect
.Y2
)
714 eRectPoint
= lclGetRectanglePoint(XML_t
);
715 else if (aFillRect
.Y1
&& !aFillRect
.Y2
)
716 eRectPoint
= lclGetRectanglePoint(XML_b
);
718 eRectPoint
= lclGetRectanglePoint(XML_ctr
);
720 rPropMap
.setProperty(ShapeProperty::FillBitmapRectanglePoint
, eRectPoint
);
721 eBitmapMode
= BitmapMode_NO_REPEAT
;
726 rPropMap
.setProperty(ShapeProperty::FillBitmapMode
, eBitmapMode
);
729 if (maBlipProps
.moAlphaModFix
.has_value())
730 rPropMap
.setProperty(ShapeProperty::FillTransparency
, static_cast<sal_Int16
>(100 - (maBlipProps
.moAlphaModFix
.value() / PER_PERCENT
)));
736 if( rPropMap
.supportsProperty( ShapeProperty::FillHatch
) )
738 Color
aColor( maPatternProps
.maPattFgColor
);
739 if( aColor
.isUsed() && maPatternProps
.moPattPreset
.has_value() )
741 eFillStyle
= FillStyle_HATCH
;
742 rPropMap
.setProperty( ShapeProperty::FillHatch
, createHatch( maPatternProps
.moPattPreset
.value(), aColor
.getColor( rGraphicHelper
, nPhClr
) ) );
743 if( aColor
.hasTransparency() )
744 rPropMap
.setProperty( ShapeProperty::FillTransparency
, aColor
.getTransparency() );
746 // Set background color for hatch
747 if(maPatternProps
.maPattBgColor
.isUsed())
749 aColor
= maPatternProps
.maPattBgColor
;
750 rPropMap
.setProperty( ShapeProperty::FillBackground
, aColor
.getTransparency() != 100 );
751 rPropMap
.setProperty( ShapeProperty::FillColor
, aColor
.getColor( rGraphicHelper
, nPhClr
) );
754 else if ( maPatternProps
.maPattBgColor
.isUsed() )
756 aColor
= maPatternProps
.maPattBgColor
;
757 rPropMap
.setProperty( ShapeProperty::FillColor
, aColor
.getColor( rGraphicHelper
, nPhClr
) );
758 if( aColor
.hasTransparency() )
759 rPropMap
.setProperty( ShapeProperty::FillTransparency
, aColor
.getTransparency() );
760 eFillStyle
= FillStyle_SOLID
;
768 eFillStyle
= FillStyle_NONE
;
772 // set final fill style property
773 rPropMap
.setProperty( ShapeProperty::FillStyle
, eFillStyle
);
776 void GraphicProperties::pushToPropMap( PropertyMap
& rPropMap
, const GraphicHelper
& rGraphicHelper
, bool bFlipH
, bool bFlipV
) const
778 sal_Int16 nBrightness
= getLimitedValue
< sal_Int16
, sal_Int32
>( maBlipProps
.moBrightness
.value_or( 0 ) / PER_PERCENT
, -100, 100 );
779 sal_Int16 nContrast
= getLimitedValue
< sal_Int16
, sal_Int32
>( maBlipProps
.moContrast
.value_or( 0 ) / PER_PERCENT
, -100, 100 );
780 ColorMode eColorMode
= ColorMode_STANDARD
;
782 switch( maBlipProps
.moColorEffect
.value_or( XML_TOKEN_INVALID
) )
784 case XML_biLevel
: eColorMode
= ColorMode_MONO
; break;
785 case XML_grayscl
: eColorMode
= ColorMode_GREYS
; break;
788 if (maBlipProps
.mxFillGraphic
.is())
790 // created transformed graphic
791 uno::Reference
<graphic::XGraphic
> xGraphic
= lclCheckAndApplyChangeColorTransform(maBlipProps
, maBlipProps
.mxFillGraphic
, rGraphicHelper
, API_RGB_TRANSPARENT
);
792 xGraphic
= lclCheckAndApplyDuotoneTransform(maBlipProps
, xGraphic
, rGraphicHelper
, API_RGB_TRANSPARENT
);
794 if( eColorMode
== ColorMode_MONO
)
796 // ColorMode_MONO is the same with MSO's biLevel with 50000 (50%) threshold,
797 // when threshold isn't 50000 bake the effect instead.
798 if( maBlipProps
.moBiLevelThreshold
!= 50000 )
800 xGraphic
= lclApplyBlackWhiteEffect(maBlipProps
, xGraphic
);
801 eColorMode
= ColorMode_STANDARD
;
805 if (eColorMode
== ColorMode_STANDARD
&& nBrightness
== 70 && nContrast
== -70)
807 // map MSO 'washout' to our Watermark colormode
808 eColorMode
= ColorMode_WATERMARK
;
812 else if( nBrightness
!= 0 && nContrast
!= 0 )
814 // MSO uses a different algorithm for contrast+brightness, LO applies contrast before brightness,
815 // while MSO apparently applies half of brightness before contrast and half after. So if only
816 // contrast or brightness need to be altered, the result is the same, but if both are involved,
817 // there's no way to map that, so just force a conversion of the image.
818 xGraphic
= applyBrightnessContrast( xGraphic
, nBrightness
, nContrast
);
824 if ( maBlipProps
.moClipRect
.has_value() )
826 geometry::IntegerRectangle2D
oClipRect( maBlipProps
.moClipRect
.value() );
827 awt::Size
aOriginalSize( rGraphicHelper
.getOriginalSize( xGraphic
) );
828 if ( aOriginalSize
.Width
&& aOriginalSize
.Height
)
830 text::GraphicCrop
aGraphCrop( 0, 0, 0, 0 );
832 aGraphCrop
.Left
= o3tl::convert(oClipRect
.X1
, aOriginalSize
.Width
, MAX_PERCENT
);
834 aGraphCrop
.Top
= o3tl::convert(oClipRect
.Y1
, aOriginalSize
.Height
, MAX_PERCENT
);
836 aGraphCrop
.Right
= o3tl::convert(oClipRect
.X2
, aOriginalSize
.Width
, MAX_PERCENT
);
838 aGraphCrop
.Bottom
= o3tl::convert(oClipRect
.Y2
, aOriginalSize
.Height
, MAX_PERCENT
);
839 rPropMap
.setProperty(PROP_GraphicCrop
, aGraphCrop
);
843 // Positive GraphicCrop values means "crop" here.
844 if (aGraphCrop
.Left
> 0 || aGraphCrop
.Right
> 0 || aGraphCrop
.Top
> 0 || aGraphCrop
.Bottom
> 0)
845 xGraphic
= lclCropGraphic(xGraphic
, CropQuotientsFromSrcRect(oClipRect
));
852 // it is a cropped graphic.
853 rPropMap
.setProperty(PROP_FillStyle
, FillStyle_BITMAP
);
854 rPropMap
.setProperty(PROP_FillBitmapMode
, BitmapMode_STRETCH
);
856 // It is a bitmap filled and rotated graphic.
857 // When custom shape is rotated, bitmap have to be rotated too.
858 // Only in extruded mode the bitmap is transformed together with the shape
859 if(rPropMap
.hasProperty(PROP_RotateAngle
) && !mbIsExtruded
)
861 tools::Long nAngle
= rPropMap
.getProperty(PROP_RotateAngle
).get
<tools::Long
>();
862 xGraphic
= lclRotateGraphic(xGraphic
, Degree10(nAngle
/10) );
865 // We have not core feature that flips graphic in the shape.
866 // Here we are applying flip property to bitmap directly.
867 if((bFlipH
|| bFlipV
) && !mbIsExtruded
)
868 xGraphic
= lclMirrorGraphic(xGraphic
, bFlipH
, bFlipV
);
870 if(eColorMode
== ColorMode_GREYS
)
871 xGraphic
= lclGreysScaleGraphic( xGraphic
);
873 rPropMap
.setProperty(PROP_FillBitmap
, xGraphic
);
876 rPropMap
.setProperty(PROP_Graphic
, xGraphic
);
879 if ( maBlipProps
.moAlphaModFix
.has_value() )
881 rPropMap
.setProperty(
882 mbIsCustomShape
? PROP_FillTransparence
: PROP_Transparency
,
883 static_cast<sal_Int16
>(100 - (maBlipProps
.moAlphaModFix
.value() / PER_PERCENT
)));
886 rPropMap
.setProperty(PROP_GraphicColorMode
, eColorMode
);
888 // brightness and contrast
889 if( nBrightness
!= 0 )
890 rPropMap
.setProperty(PROP_AdjustLuminance
, nBrightness
);
892 rPropMap
.setProperty(PROP_AdjustContrast
, nContrast
);
895 if (!m_sMediaPackageURL
.isEmpty())
897 rPropMap
.setProperty(PROP_MediaURL
, m_sMediaPackageURL
);
898 if (m_xMediaStream
.is())
899 rPropMap
.setProperty(PROP_PrivateStream
, m_xMediaStream
);
903 bool ArtisticEffectProperties::isEmpty() const
905 return msName
.isEmpty();
908 css::beans::PropertyValue
ArtisticEffectProperties::getEffect()
910 css::beans::PropertyValue aRet
;
911 if( msName
.isEmpty() )
914 css::uno::Sequence
< css::beans::PropertyValue
> aSeq( maAttribs
.size() + 1 );
915 auto pSeq
= aSeq
.getArray();
917 for (auto const& attrib
: maAttribs
)
919 pSeq
[i
].Name
= attrib
.first
;
920 pSeq
[i
].Value
= attrib
.second
;
924 if( mrOleObjectInfo
.maEmbeddedData
.hasElements() )
926 css::uno::Sequence
< css::beans::PropertyValue
> aGraphicSeq
{
927 comphelper::makePropertyValue(u
"Id"_ustr
, mrOleObjectInfo
.maProgId
),
928 comphelper::makePropertyValue(u
"Data"_ustr
, mrOleObjectInfo
.maEmbeddedData
)
931 pSeq
[i
].Name
= "OriginalGraphic";
932 pSeq
[i
].Value
<<= aGraphicSeq
;
941 void ArtisticEffectProperties::assignUsed( const ArtisticEffectProperties
& rSourceProps
)
943 if( !rSourceProps
.isEmpty() )
945 msName
= rSourceProps
.msName
;
946 maAttribs
= rSourceProps
.maAttribs
;
950 OUString
ArtisticEffectProperties::getEffectString( sal_Int32 nToken
)
955 case OOX_TOKEN( a14
, artisticBlur
): return u
"artisticBlur"_ustr
;
956 case OOX_TOKEN( a14
, artisticCement
): return u
"artisticCement"_ustr
;
957 case OOX_TOKEN( a14
, artisticChalkSketch
): return u
"artisticChalkSketch"_ustr
;
958 case OOX_TOKEN( a14
, artisticCrisscrossEtching
): return u
"artisticCrisscrossEtching"_ustr
;
959 case OOX_TOKEN( a14
, artisticCutout
): return u
"artisticCutout"_ustr
;
960 case OOX_TOKEN( a14
, artisticFilmGrain
): return u
"artisticFilmGrain"_ustr
;
961 case OOX_TOKEN( a14
, artisticGlass
): return u
"artisticGlass"_ustr
;
962 case OOX_TOKEN( a14
, artisticGlowDiffused
): return u
"artisticGlowDiffused"_ustr
;
963 case OOX_TOKEN( a14
, artisticGlowEdges
): return u
"artisticGlowEdges"_ustr
;
964 case OOX_TOKEN( a14
, artisticLightScreen
): return u
"artisticLightScreen"_ustr
;
965 case OOX_TOKEN( a14
, artisticLineDrawing
): return u
"artisticLineDrawing"_ustr
;
966 case OOX_TOKEN( a14
, artisticMarker
): return u
"artisticMarker"_ustr
;
967 case OOX_TOKEN( a14
, artisticMosiaicBubbles
): return u
"artisticMosiaicBubbles"_ustr
;
968 case OOX_TOKEN( a14
, artisticPaintStrokes
): return u
"artisticPaintStrokes"_ustr
;
969 case OOX_TOKEN( a14
, artisticPaintBrush
): return u
"artisticPaintBrush"_ustr
;
970 case OOX_TOKEN( a14
, artisticPastelsSmooth
): return u
"artisticPastelsSmooth"_ustr
;
971 case OOX_TOKEN( a14
, artisticPencilGrayscale
): return u
"artisticPencilGrayscale"_ustr
;
972 case OOX_TOKEN( a14
, artisticPencilSketch
): return u
"artisticPencilSketch"_ustr
;
973 case OOX_TOKEN( a14
, artisticPhotocopy
): return u
"artisticPhotocopy"_ustr
;
974 case OOX_TOKEN( a14
, artisticPlasticWrap
): return u
"artisticPlasticWrap"_ustr
;
975 case OOX_TOKEN( a14
, artisticTexturizer
): return u
"artisticTexturizer"_ustr
;
976 case OOX_TOKEN( a14
, artisticWatercolorSponge
): return u
"artisticWatercolorSponge"_ustr
;
977 case OOX_TOKEN( a14
, brightnessContrast
): return u
"brightnessContrast"_ustr
;
978 case OOX_TOKEN( a14
, colorTemperature
): return u
"colorTemperature"_ustr
;
979 case OOX_TOKEN( a14
, saturation
): return u
"saturation"_ustr
;
980 case OOX_TOKEN( a14
, sharpenSoften
): return u
"sharpenSoften"_ustr
;
983 case XML_visible
: return u
"visible"_ustr
;
984 case XML_trans
: return u
"trans"_ustr
;
985 case XML_crackSpacing
: return u
"crackSpacing"_ustr
;
986 case XML_pressure
: return u
"pressure"_ustr
;
987 case XML_numberOfShades
: return u
"numberOfShades"_ustr
;
988 case XML_grainSize
: return u
"grainSize"_ustr
;
989 case XML_intensity
: return u
"intensity"_ustr
;
990 case XML_smoothness
: return u
"smoothness"_ustr
;
991 case XML_gridSize
: return u
"gridSize"_ustr
;
992 case XML_pencilSize
: return u
"pencilSize"_ustr
;
993 case XML_size
: return u
"size"_ustr
;
994 case XML_brushSize
: return u
"brushSize"_ustr
;
995 case XML_scaling
: return u
"scaling"_ustr
;
996 case XML_detail
: return u
"detail"_ustr
;
997 case XML_bright
: return u
"bright"_ustr
;
998 case XML_contrast
: return u
"contrast"_ustr
;
999 case XML_colorTemp
: return u
"colorTemp"_ustr
;
1000 case XML_sat
: return u
"sat"_ustr
;
1001 case XML_amount
: return u
"amount"_ustr
;
1003 SAL_WARN( "oox.drawingml", "ArtisticEffectProperties::getEffectString: unexpected token " << nToken
);
1007 constexpr auto constEffectTokenForEffectNameMap
= frozen::make_unordered_map
<std::u16string_view
, sal_Int32
>(
1010 { u
"artisticBlur", XML_artisticBlur
},
1011 { u
"artisticCement", XML_artisticCement
},
1012 { u
"artisticChalkSketch", XML_artisticChalkSketch
},
1013 { u
"artisticCrisscrossEtching", XML_artisticCrisscrossEtching
},
1014 { u
"artisticCutout", XML_artisticCutout
},
1015 { u
"artisticFilmGrain", XML_artisticFilmGrain
},
1016 { u
"artisticGlass", XML_artisticGlass
},
1017 { u
"artisticGlowDiffused", XML_artisticGlowDiffused
},
1018 { u
"artisticGlowEdges", XML_artisticGlowEdges
},
1019 { u
"artisticLightScreen", XML_artisticLightScreen
},
1020 { u
"artisticLineDrawing", XML_artisticLineDrawing
},
1021 { u
"artisticMarker", XML_artisticMarker
},
1022 { u
"artisticMosiaicBubbles", XML_artisticMosiaicBubbles
},
1023 { u
"artisticPaintStrokes", XML_artisticPaintStrokes
},
1024 { u
"artisticPaintBrush", XML_artisticPaintBrush
},
1025 { u
"artisticPastelsSmooth", XML_artisticPastelsSmooth
},
1026 { u
"artisticPencilGrayscale", XML_artisticPencilGrayscale
},
1027 { u
"artisticPencilSketch", XML_artisticPencilSketch
},
1028 { u
"artisticPhotocopy", XML_artisticPhotocopy
},
1029 { u
"artisticPlasticWrap", XML_artisticPlasticWrap
},
1030 { u
"artisticTexturizer", XML_artisticTexturizer
},
1031 { u
"artisticWatercolorSponge", XML_artisticWatercolorSponge
},
1032 { u
"brightnessContrast", XML_brightnessContrast
},
1033 { u
"colorTemperature", XML_colorTemperature
},
1034 { u
"saturation", XML_saturation
},
1035 { u
"sharpenSoften", XML_sharpenSoften
},
1038 { u
"visible", XML_visible
},
1039 { u
"trans", XML_trans
},
1040 { u
"crackSpacing", XML_crackSpacing
},
1041 { u
"pressure", XML_pressure
},
1042 { u
"numberOfShades", XML_numberOfShades
},
1043 { u
"grainSize", XML_grainSize
},
1044 { u
"intensity", XML_intensity
},
1045 { u
"smoothness", XML_smoothness
},
1046 { u
"gridSize", XML_gridSize
},
1047 { u
"pencilSize", XML_pencilSize
},
1048 { u
"size", XML_size
},
1049 { u
"brushSize", XML_brushSize
},
1050 { u
"scaling", XML_scaling
},
1051 { u
"detail", XML_detail
},
1052 { u
"bright", XML_bright
},
1053 { u
"contrast", XML_contrast
},
1054 { u
"colorTemp", XML_colorTemp
},
1055 { u
"sat", XML_sat
},
1056 { u
"amount", XML_amount
}
1059 sal_Int32
ArtisticEffectProperties::getEffectToken(const OUString
& sName
)
1061 auto const aIterator
= constEffectTokenForEffectNameMap
.find(sName
);
1063 if (aIterator
!= constEffectTokenForEffectNameMap
.end())
1064 return aIterator
->second
;
1066 SAL_WARN( "oox.drawingml", "ArtisticEffectProperties::getEffectToken - unexpected token name: " << sName
);
1072 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */