31#include <com/sun/star/beans/XPropertySet.hpp>
32#include <com/sun/star/awt/Gradient.hpp>
33#include <com/sun/star/text/GraphicCrop.hpp>
34#include <com/sun/star/awt/Size.hpp>
35#include <com/sun/star/drawing/BitmapMode.hpp>
36#include <com/sun/star/drawing/ColorMode.hpp>
37#include <com/sun/star/drawing/FillStyle.hpp>
38#include <com/sun/star/drawing/RectanglePoint.hpp>
39#include <com/sun/star/graphic/XGraphicTransformer.hpp>
44#include <oox/token/namespaces.hxx>
45#include <oox/token/properties.hxx>
46#include <oox/token/tokens.hxx>
47#include <osl/diagnose.h>
54using ::com::sun::star::uno::Reference;
55using ::com::sun::star::uno::Exception;
56using ::com::sun::star::uno::UNO_QUERY_THROW;
57using ::com::sun::star::geometry::IntegerRectangle2D;
63Reference< XGraphic > lclCheckAndApplyDuotoneTransform(
const BlipFillProperties& aBlipProps, uno::Reference<graphic::XGraphic>
const & xGraphic,
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));
78Reference< XGraphic > lclRotateGraphic(uno::Reference<graphic::XGraphic>
const & xGraphic,
Degree10 nRotation)
83 assert (aGraphic.GetType() == GraphicType::Bitmap);
85 BitmapEx aBitmapEx(aGraphic.GetBitmapEx());
86 const ::Color& aColor =
::Color(0x00);
87 aBitmapEx.Rotate(nRotation, aColor);
94using Quotients = std::tuple<double, double, double, double>;
95Quotients getQuotients(geometry::IntegerRectangle2D aRelRect,
double hDiv,
double vDiv)
97 return { aRelRect.X1 / hDiv, aRelRect.Y1 / vDiv, aRelRect.X2 / hDiv, aRelRect.Y2 / vDiv };
101std::optional<Quotients> CropQuotientsFromSrcRect(geometry::IntegerRectangle2D aSrcRect)
103 aSrcRect.X1 = std::max(aSrcRect.X1, sal_Int32(0));
104 aSrcRect.X2 = std::max(aSrcRect.X2, sal_Int32(0));
105 aSrcRect.Y1 = std::max(aSrcRect.Y1, sal_Int32(0));
106 aSrcRect.Y2 = std::max(aSrcRect.Y2, sal_Int32(0));
107 if (aSrcRect.X1 + aSrcRect.X2 >= 100'000 || aSrcRect.Y1 + aSrcRect.Y2 >= 100'000)
109 return getQuotients(aSrcRect, 100'000.0, 100'000.0);
113std::optional<Quotients> CropQuotientsFromFillRect(geometry::IntegerRectangle2D aFillRect)
115 aFillRect.X1 = std::min(aFillRect.X1, sal_Int32(0));
116 aFillRect.X2 = std::min(aFillRect.X2, sal_Int32(0));
117 aFillRect.Y1 = std::min(aFillRect.Y1, sal_Int32(0));
118 aFillRect.Y2 = std::min(aFillRect.Y2, sal_Int32(0));
120 return getQuotients(aFillRect, -100'000.0 + aFillRect.X1 + aFillRect.X2,
121 -100'000.0 + aFillRect.Y1 + aFillRect.Y2);
125Reference<XGraphic> lclCropGraphic(uno::Reference<graphic::XGraphic>
const& xGraphic,
126 std::optional<Quotients> quotients)
129 assert (aGraphic.GetType() == GraphicType::Bitmap);
134 aBitmapEx = aGraphic.GetBitmapEx();
137 const auto& [qx1, qy1, qx2, qy2] = *quotients;
143 aBitmapEx.
Crop({ l,
t, bmpSize.
Width() - r - 1, bmpSize.
Height() - b - 1 });
152Reference< XGraphic > lclMirrorGraphic(uno::Reference<graphic::XGraphic>
const & xGraphic,
bool bFlipH,
bool bFlipV)
157 assert (aGraphic.GetType() == GraphicType::Bitmap);
159 BitmapEx aBitmapEx(aGraphic.GetBitmapEx());
163 nMirrorFlags |= BmpMirrorFlags::Horizontal;
165 nMirrorFlags |= BmpMirrorFlags::Vertical;
167 aBitmapEx.
Mirror(nMirrorFlags);
175Reference< XGraphic > lclGreysScaleGraphic(uno::Reference<graphic::XGraphic>
const & xGraphic)
180 assert (aGraphic.GetType() == GraphicType::Bitmap);
182 BitmapEx aBitmapEx(aGraphic.GetBitmapEx());
183 aBitmapEx.
Convert(BmpConversion::N8BitGreys);
192Reference<XGraphic> lclApplyBlackWhiteEffect(
const BlipFillProperties& aBlipProps,
193 const uno::Reference<graphic::XGraphic>& xGraphic)
195 const auto& oBiLevelThreshold = aBlipProps.moBiLevelThreshold;
196 if (oBiLevelThreshold.has_value())
204 BitmapEx aBitmapEx(aGraphic.GetBitmapEx());
211 aReturnGraphic.setOriginURL(aGraphic.getOriginURL());
212 return aReturnGraphic.GetXGraphic();
217Reference< XGraphic > lclCheckAndApplyChangeColorTransform(
const BlipFillProperties &aBlipProps, uno::Reference<graphic::XGraphic>
const & xGraphic,
220 if( aBlipProps.maColorChangeFrom.isUsed() && aBlipProps.maColorChangeTo.isUsed() )
222 ::Color nFromColor = aBlipProps.maColorChangeFrom.getColor( rGraphicHelper, nPhClr );
223 ::Color nToColor = aBlipProps.maColorChangeTo.getColor( rGraphicHelper, nPhClr );
224 if ( (nFromColor != nToColor) || aBlipProps.maColorChangeTo.hasTransparency() )
226 sal_Int16 nToTransparence = aBlipProps.maColorChangeTo.getTransparency();
227 sal_Int8 nToAlpha =
static_cast< sal_Int8 >( (100 - nToTransparence) * 2.55 );
231 if( aGraphic.IsGfxLink() )
234 switch (aGraphic.GetGfxLink().GetType())
236 case GfxLinkType::NativeJpg:
239 case GfxLinkType::NativePng:
240 case GfxLinkType::NativeTif:
243 case GfxLinkType::NativeBmp:
251 uno::Reference<graphic::XGraphicTransformer> xTransformer(aBlipProps.mxFillGraphic, uno::UNO_QUERY);
252 if (xTransformer.is())
253 return xTransformer->colorChange(xGraphic, sal_Int32(nFromColor), nTolerance, sal_Int32(nToColor), nToAlpha);
259uno::Reference<graphic::XGraphic> applyBrightnessContrast(uno::Reference<graphic::XGraphic>
const & xGraphic, sal_Int32 brightness, sal_Int32 contrast)
261 uno::Reference<graphic::XGraphicTransformer> xTransformer(xGraphic, uno::UNO_QUERY);
262 if (xTransformer.is())
263 return xTransformer->applyBrightnessContrast(xGraphic, brightness, contrast,
true);
267BitmapMode lclGetBitmapMode( sal_Int32 nToken )
269 OSL_ASSERT((nToken & sal_Int32(0xFFFF0000))==0);
272 case XML_tile:
return BitmapMode_REPEAT;
273 case XML_stretch:
return BitmapMode_STRETCH;
277 return BitmapMode_REPEAT;
280RectanglePoint lclGetRectanglePoint( sal_Int32 nToken )
282 OSL_ASSERT((nToken & sal_Int32(0xFFFF0000))==0);
285 case XML_tl:
return RectanglePoint_LEFT_TOP;
286 case XML_t:
return RectanglePoint_MIDDLE_TOP;
287 case XML_tr:
return RectanglePoint_RIGHT_TOP;
288 case XML_l:
return RectanglePoint_LEFT_MIDDLE;
289 case XML_ctr:
return RectanglePoint_MIDDLE_MIDDLE;
290 case XML_r:
return RectanglePoint_RIGHT_MIDDLE;
291 case XML_bl:
return RectanglePoint_LEFT_BOTTOM;
292 case XML_b:
return RectanglePoint_MIDDLE_BOTTOM;
293 case XML_br:
return RectanglePoint_RIGHT_BOTTOM;
295 return RectanglePoint_LEFT_TOP;
298awt::Size lclGetOriginalSize(
const GraphicHelper& rGraphicHelper,
const Reference< XGraphic >& rxGraphic )
300 awt::Size aSizeHmm( 0, 0 );
303 Reference< beans::XPropertySet > xGraphicPropertySet( rxGraphic, UNO_QUERY_THROW );
304 if( xGraphicPropertySet->getPropertyValue(
"Size100thMM" ) >>= aSizeHmm )
306 if( !aSizeHmm.Width && !aSizeHmm.Height )
308 awt::Size aSourceSizePixel( 0, 0 );
309 if( xGraphicPropertySet->getPropertyValue(
"SizePixel" ) >>= aSourceSizePixel )
324void extractGradientBorderFromStops(
const GradientFillProperties& rGradientProps,
326 awt::Gradient& rGradient)
328 if (rGradientProps.maGradientStops.size() <= 1)
331 auto it = rGradientProps.maGradientStops.rbegin();
332 double fLastPos = it->first;
333 Color aLastColor = it->second;
335 double fLastButOnePos = it->first;
336 Color aLastButOneColor = it->second;
337 if (!aLastColor.equals(aLastButOneColor, rGraphicHelper, nPhClr))
341 rGradient.Border = rtl::math::round((fLastPos - fLastButOnePos) * 100);
412 GradientFillProperties::GradientStopMap::const_iterator aGradientStop =
416 aSolidColor = aGradientStop->second;
427 sal_Int32 nShapeRotation,
::Color nPhClr,
428 const css::awt::Size& rSize, sal_Int16 nPhClrTheme,
bool bFlipH,
429 bool bFlipV,
bool bIsCustomShape)
const
435 OSL_ASSERT((
moFillType.value() & sal_Int32(0xFFFF0000))==0);
440 eFillStyle = FillStyle_NONE;
454 if (aFillColor == nPhClr)
476 eFillStyle = FillStyle_SOLID;
484 sal_Int32 nEndTrans = 0;
485 sal_Int32 nStartTrans = 0;
486 awt::Gradient aGradient;
487 aGradient.Angle = 900;
488 aGradient.StartIntensity = 100;
489 aGradient.EndIntensity = 100;
509 sal_Int32 nCenterX = (
MAX_PERCENT + aFillToRect.X1 - aFillToRect.X2) / 2;
510 aGradient.XOffset = getLimitedValue<sal_Int16, sal_Int32>(
512 sal_Int32 nCenterY = (
MAX_PERCENT + aFillToRect.Y1 - aFillToRect.Y2) / 2;
513 aGradient.YOffset = getLimitedValue<sal_Int16, sal_Int32>(
520 aGradient.Style = awt::GradientStyle_LINEAR;
521 if( aGradient.XOffset == 100 && aGradient.YOffset == 100 )
522 aGradient.Angle = 450;
523 else if( aGradient.XOffset == 0 && aGradient.YOffset == 100 )
524 aGradient.Angle = 3150;
525 else if( aGradient.XOffset == 100 && aGradient.YOffset == 0 )
526 aGradient.Angle = 1350;
527 else if( aGradient.XOffset == 0 && aGradient.YOffset == 0 )
528 aGradient.Angle = 2250;
530 aGradient.Style = awt::GradientStyle_RADIAL;
534 aGradient.Style = awt::GradientStyle_RECT;
537 ::std::swap( aGradient.StartColor, aGradient.EndColor );
538 ::std::swap( nStartTrans, nEndTrans );
540 extractGradientBorderFromStops(
maGradientProps, rGraphicHelper, nPhClr,
550 auto a0 = aGradientStops.find( 0.0 );
551 if( a0 == aGradientStops.end() )
554 Color aFirstColor(aGradientStops.begin()->second);
555 aGradientStops.emplace( 0.0, aFirstColor );
558 auto a1 = aGradientStops.find( 1.0 );
559 if( a1 == aGradientStops.end() )
562 Color aLastColor(aGradientStops.rbegin()->second);
563 aGradientStops.emplace( 1.0, aLastColor );
567 bool bSymmetric(
true);
569 GradientFillProperties::GradientStopMap::const_iterator aItA( aGradientStops.begin() );
570 GradientFillProperties::GradientStopMap::const_iterator aItZ(std::prev(aGradientStops.end()));
571 assert(aItZ != aGradientStops.end());
572 while( bSymmetric && aItA->first < aItZ->first )
574 if (!aItA->second.equals(aItZ->second, rGraphicHelper, nPhClr))
579 aItZ = std::prev(aItZ);
583 if( bSymmetric && aItA == aItZ && aItA->first != 0.5 )
591 if( aItA->first != aItZ->first )
593 Color aMiddleColor = aItZ->second;
594 auto a05 = aGradientStops.find( 0.5 );
596 if( a05 != aGradientStops.end() )
597 a05->second = aMiddleColor;
599 aGradientStops.emplace( 0.5, aMiddleColor );
602 while( aGradientStops.rbegin()->first > 0.5 )
603 aGradientStops.erase( aGradientStops.rbegin()->first );
607 SAL_INFO(
"oox.drawingml.gradient",
"symmetric: " << (bSymmetric ?
"YES" :
"NO") <<
608 ", number of stops: " << aGradientStops.size());
610 for (
auto const& gradientStop : aGradientStops)
612 gradientStop.first <<
": " <<
613 std::hex << sal_Int32(gradientStop.second.getColor( rGraphicHelper, nPhClr )) << std::dec <<
614 "@" << (100 - gradientStop.second.getTransparency()) <<
"%");
620 GradientFillProperties::GradientStopMap::iterator aIt(aGradientStops.begin());
621 double nWidestWidth = -1;
622 GradientFillProperties::GradientStopMap::iterator aWidestSegmentStart;
624 while( aIt != aGradientStops.end() )
626 if (aIt->first - std::prev(aIt)->first > nWidestWidth)
628 nWidestWidth = aIt->first - std::prev(aIt)->first;
629 aWidestSegmentStart = std::prev(aIt);
633 assert( nWidestWidth >= 0 );
641 if( aGradientStops.size() == 3 &&
642 aGradientStops.begin()->second.getColor(rGraphicHelper, nPhClr) == std::next(aGradientStops.begin())->second.getColor(rGraphicHelper, nPhClr) &&
643 aGradientStops.begin()->second.getTransparency() == std::next(aGradientStops.begin())->second.getTransparency())
646 SAL_INFO(
"oox.drawingml.gradient",
"two segments, first is uniformly coloured");
647 nBorder = std::next(aGradientStops.begin())->first - aGradientStops.begin()->first;
648 aGradientStops.erase(aGradientStops.begin());
649 aWidestSegmentStart = aGradientStops.begin();
651 else if( !bSymmetric &&
652 aGradientStops.size() == 3 &&
653 std::next(aGradientStops.begin())->second.getColor(rGraphicHelper, nPhClr) == std::prev(aGradientStops.end())->second.getColor(rGraphicHelper, nPhClr) &&
654 std::next(aGradientStops.begin())->second.getTransparency() == std::prev(aGradientStops.end())->second.getTransparency())
657 SAL_INFO(
"oox.drawingml.gradient",
"two segments, second is uniformly coloured");
658 auto aNext = std::next(aGradientStops.begin());
659 auto aPrev = std::prev(aGradientStops.end());
660 assert(aPrev != aGradientStops.end());
661 nBorder = aPrev->first - aNext->first;
662 aGradientStops.erase(aNext);
663 aWidestSegmentStart = aGradientStops.begin();
665 nShapeRotation = 180*60000 - nShapeRotation;
667 else if( !bSymmetric &&
668 aGradientStops.size() >= 4 &&
669 aWidestSegmentStart->second.getColor( rGraphicHelper, nPhClr ) == std::next(aWidestSegmentStart)->second.getColor(rGraphicHelper, nPhClr) &&
670 aWidestSegmentStart->second.getTransparency() == std::next(aWidestSegmentStart)->second.getTransparency() &&
671 ( aWidestSegmentStart == aGradientStops.begin() ||
672 std::next(aWidestSegmentStart) == std::prev(aGradientStops.end())))
675 SAL_INFO(
"oox.drawingml.gradient",
"first or last segment is widest and is uniformly coloured");
676 nBorder = std::next(aWidestSegmentStart)->first - aWidestSegmentStart->first;
680 if (std::next(aWidestSegmentStart) == std::prev(aGradientStops.end()))
683 nShapeRotation = 180*60000 - nShapeRotation;
686 aGradientStops.erase( aWidestSegmentStart++ );
689 aIt = std::next(aGradientStops.begin());
691 while( aIt != aGradientStops.end() )
693 if (aIt->first - std::prev(aIt)->first > nWidestWidth)
695 nWidestWidth = aIt->first - std::prev(aIt)->first;
696 aWidestSegmentStart = std::prev(aIt);
701 SAL_INFO(
"oox.drawingml.gradient",
"widest segment start: " << aWidestSegmentStart->first <<
", border: " <<
nBorder);
702 assert( (!bSymmetric && !bSwap) || !(bSymmetric && bSwap) );
706 aGradient.Style = bSymmetric ? awt::GradientStyle_AXIAL : awt::GradientStyle_LINEAR;
710 nShadeAngle = 180*60000 - nShadeAngle;
712 nShadeAngle = -nShadeAngle;
713 sal_Int32 nDmlAngle = nShadeAngle + nShapeRotation;
715 aGradient.Angle =
static_cast< sal_Int16
>( (8100 - (nDmlAngle / (
PER_DEGREE / 10))) % 3600 );
716 Color aStartColor, aEndColor;
719 auto aWidestSegmentEnd = std::next(aWidestSegmentStart);
723 while (aWidestSegmentStart != aGradientStops.begin())
725 auto it = std::prev(aWidestSegmentStart);
726 if (it->second.getColor(rGraphicHelper, nPhClr)
727 != aWidestSegmentStart->second.getColor(rGraphicHelper, nPhClr))
732 aWidestSegmentStart = it;
737 while (aWidestSegmentEnd != std::prev(aGradientStops.end()))
739 auto it = std::next(aWidestSegmentEnd);
740 if (it->second.getColor(rGraphicHelper, nPhClr)
741 != aWidestSegmentEnd->second.getColor(rGraphicHelper, nPhClr))
746 aWidestSegmentEnd = it;
749 assert(aWidestSegmentEnd != aGradientStops.end());
753 aStartColor = aWidestSegmentEnd->second;
754 aEndColor = aWidestSegmentStart->second;
759 aStartColor = aWidestSegmentEnd->second;
760 aEndColor = aWidestSegmentStart->second;
764 aStartColor = aWidestSegmentStart->second;
765 aEndColor = aWidestSegmentEnd->second;
768 SAL_INFO(
"oox.drawingml.gradient",
"start color: " << std::hex << sal_Int32(aStartColor.
getColor( rGraphicHelper, nPhClr )) << std::dec <<
770 ", end color: " << std::hex << sal_Int32(aEndColor.
getColor( rGraphicHelper, nPhClr )) << std::dec <<
773 aGradient.StartColor = sal_Int32(aStartColor.
getColor( rGraphicHelper, nPhClr ));
774 aGradient.EndColor = sal_Int32(aEndColor.
getColor( rGraphicHelper, nPhClr ));
779 aGradient.Border = rtl::math::round(100*
nBorder);
784 eFillStyle = FillStyle_GRADIENT;
787 if( nStartTrans != 0 || nEndTrans != 0 )
789 awt::Gradient aGrad(aGradient);
791 aGrad.EndColor =
static_cast<sal_Int32
>( nEndTrans | nEndTrans << 8 | nEndTrans << 16 );
792 aGrad.StartColor =
static_cast<sal_Int32
>( nStartTrans | nStartTrans << 8 | nStartTrans << 16 );
810 xGraphic = lclGreysScaleGraphic(xGraphic);
815 eFillStyle = FillStyle_BITMAP;
819 eFillStyle = FillStyle_BITMAP;
824 if( eFillStyle == FillStyle_BITMAP )
830 if( eBitmapMode == BitmapMode_REPEAT )
837 if( (aOriginalSize.Width > 0) && (aOriginalSize.Height > 0) )
841 sal_Int32 nFillBmpSizeX = getLimitedValue< sal_Int32, double >( aOriginalSize.Width * fScaleX, 1,
SAL_MAX_INT32 );
844 sal_Int32 nFillBmpSizeY = getLimitedValue< sal_Int32, double >( aOriginalSize.Height * fScaleY, 1,
SAL_MAX_INT32 );
847 awt::Size aBmpSize(nFillBmpSizeX, nFillBmpSizeY);
849 sal_Int16 nTileOffsetX = getDoubleIntervalValue< sal_Int16 >(std::round(
maBlipProps.
moTileOffsetX.value_or( 0 ) / 3.6 / aBmpSize.Width), 0, 100 );
851 sal_Int16 nTileOffsetY = getDoubleIntervalValue< sal_Int16 >(std::round(
maBlipProps.
moTileOffsetY.value_or( 0 ) / 3.6 / aBmpSize.Height), 0, 100 );
859 if ( aOriginalSize.Width && aOriginalSize.Height )
861 text::GraphicCrop aGraphCrop( 0, 0, 0, 0 );
863 aGraphCrop.Left =
static_cast< sal_Int32
>( (
static_cast< double >( aOriginalSize.Width ) * aFillRect.X1 ) / 100000 );
865 aGraphCrop.Top =
static_cast< sal_Int32
>( (
static_cast< double >( aOriginalSize.Height ) * aFillRect.Y1 ) / 100000 );
867 aGraphCrop.Right =
static_cast< sal_Int32
>( (
static_cast< double >( aOriginalSize.Width ) * aFillRect.X2 ) / 100000 );
869 aGraphCrop.Bottom =
static_cast< sal_Int32
>( (
static_cast< double >( aOriginalSize.Height ) * aFillRect.Y2 ) / 100000 );
871 bool bHasCropValues = aGraphCrop.Left != 0 || aGraphCrop.Right !=0 || aGraphCrop.Top != 0 || aGraphCrop.Bottom != 0;
873 bool bNeedCrop = aGraphCrop.Left <= 0 && aGraphCrop.Right <= 0 && aGraphCrop.Top <= 0 && aGraphCrop.Bottom <= 0;
877 if (bIsCustomShape && bNeedCrop)
882 xGraphic = lclCropGraphic(xGraphic, CropQuotientsFromFillRect(aFillRect));
888 else if ((aFillRect.X1 != 0 && aFillRect.X2 != 0
889 && aFillRect.X1 != aFillRect.X2)
890 || (aFillRect.Y1 != 0 && aFillRect.Y2 != 0
891 && aFillRect.Y1 != aFillRect.Y2))
897 double nL = aFillRect.X1 /
static_cast<double>(
MAX_PERCENT);
898 double nT = aFillRect.Y1 /
static_cast<double>(
MAX_PERCENT);
899 double nR = aFillRect.X2 /
static_cast<double>(
MAX_PERCENT);
900 double nB = aFillRect.Y2 /
static_cast<double>(
MAX_PERCENT);
904 nSizeX = rSize.Width * (1 - (nL + nR));
906 nSizeX = rSize.Width;
911 nSizeY = rSize.Height * (1 - (nT + nB));
913 nSizeY = rSize.Height;
916 RectanglePoint eRectPoint;
917 if (!aFillRect.X1 && aFillRect.X2)
919 if (!aFillRect.Y1 && aFillRect.Y2)
920 eRectPoint = lclGetRectanglePoint(XML_tl);
921 else if (aFillRect.Y1 && !aFillRect.Y2)
922 eRectPoint = lclGetRectanglePoint(XML_bl);
924 eRectPoint = lclGetRectanglePoint(XML_l);
926 else if (aFillRect.X1 && !aFillRect.X2)
928 if (!aFillRect.Y1 && aFillRect.Y2)
929 eRectPoint = lclGetRectanglePoint(XML_tr);
930 else if (aFillRect.Y1 && !aFillRect.Y2)
931 eRectPoint = lclGetRectanglePoint(XML_br);
933 eRectPoint = lclGetRectanglePoint(XML_r);
937 if (!aFillRect.Y1 && aFillRect.Y2)
938 eRectPoint = lclGetRectanglePoint(XML_t);
939 else if (aFillRect.Y1 && !aFillRect.Y2)
940 eRectPoint = lclGetRectanglePoint(XML_b);
942 eRectPoint = lclGetRectanglePoint(XML_ctr);
945 eBitmapMode = BitmapMode_NO_REPEAT;
965 eFillStyle = FillStyle_HATCH;
984 eFillStyle = FillStyle_SOLID;
992 eFillStyle = FillStyle_NONE;
1004 ColorMode eColorMode = ColorMode_STANDARD;
1008 case XML_biLevel: eColorMode = ColorMode_MONO;
break;
1009 case XML_grayscl: eColorMode = ColorMode_GREYS;
break;
1018 if( eColorMode == ColorMode_MONO )
1024 xGraphic = lclApplyBlackWhiteEffect(
maBlipProps, xGraphic);
1025 eColorMode = ColorMode_STANDARD;
1029 if (eColorMode == ColorMode_STANDARD && nBrightness == 70 && nContrast == -70)
1032 eColorMode = ColorMode_WATERMARK;
1036 else if( nBrightness != 0 && nContrast != 0 )
1042 xGraphic = applyBrightnessContrast( xGraphic, nBrightness, nContrast );
1051 awt::Size aOriginalSize( rGraphicHelper.
getOriginalSize( xGraphic ) );
1052 if ( aOriginalSize.Width && aOriginalSize.Height )
1054 text::GraphicCrop aGraphCrop( 0, 0, 0, 0 );
1056 aGraphCrop.Left = rtl::math::round( (
static_cast< double >( aOriginalSize.Width ) * oClipRect.X1 ) / 100000 );
1058 aGraphCrop.Top = rtl::math::round( (
static_cast< double >( aOriginalSize.Height ) * oClipRect.Y1 ) / 100000 );
1060 aGraphCrop.Right = rtl::math::round( (
static_cast< double >( aOriginalSize.Width ) * oClipRect.X2 ) / 100000 );
1062 aGraphCrop.Bottom = rtl::math::round( (
static_cast< double >( aOriginalSize.Height ) * oClipRect.Y2 ) / 100000 );
1065 bool bHasCropValues = aGraphCrop.Left != 0 || aGraphCrop.Right !=0 || aGraphCrop.Top != 0 || aGraphCrop.Bottom != 0;
1067 bool bNeedCrop = aGraphCrop.Left >= 0 && aGraphCrop.Right >= 0 && aGraphCrop.Top >= 0 && aGraphCrop.Bottom >= 0;
1071 xGraphic = lclCropGraphic(xGraphic, CropQuotientsFromSrcRect(oClipRect));
1087 xGraphic = lclRotateGraphic(xGraphic,
Degree10(nAngle/10) );
1092 if(bFlipH || bFlipV)
1093 xGraphic = lclMirrorGraphic(xGraphic, bFlipH, bFlipV );
1095 if(eColorMode == ColorMode_GREYS)
1096 xGraphic = lclGreysScaleGraphic( xGraphic );
1112 if( nBrightness != 0 )
1114 if( nContrast != 0 )
1133 css::beans::PropertyValue aRet;
1137 css::uno::Sequence< css::beans::PropertyValue >
aSeq(
maAttribs.size() + 1 );
1138 auto pSeq =
aSeq.getArray();
1142 pSeq[
i].Name = attrib.first;
1143 pSeq[
i].Value = attrib.second;
1149 css::uno::Sequence< css::beans::PropertyValue > aGraphicSeq{
1154 pSeq[
i].Name =
"OriginalGraphic";
1155 pSeq[
i].Value <<= aGraphicSeq;
1159 aRet.Value <<=
aSeq;
1178 case OOX_TOKEN( a14, artisticBlur ):
return "artisticBlur";
1179 case OOX_TOKEN( a14, artisticCement ):
return "artisticCement";
1180 case OOX_TOKEN( a14, artisticChalkSketch ):
return "artisticChalkSketch";
1181 case OOX_TOKEN( a14, artisticCrisscrossEtching ):
return "artisticCrisscrossEtching";
1182 case OOX_TOKEN( a14, artisticCutout ):
return "artisticCutout";
1183 case OOX_TOKEN( a14, artisticFilmGrain ):
return "artisticFilmGrain";
1184 case OOX_TOKEN( a14, artisticGlass ):
return "artisticGlass";
1185 case OOX_TOKEN( a14, artisticGlowDiffused ):
return "artisticGlowDiffused";
1186 case OOX_TOKEN( a14, artisticGlowEdges ):
return "artisticGlowEdges";
1187 case OOX_TOKEN( a14, artisticLightScreen ):
return "artisticLightScreen";
1188 case OOX_TOKEN( a14, artisticLineDrawing ):
return "artisticLineDrawing";
1189 case OOX_TOKEN( a14, artisticMarker ):
return "artisticMarker";
1190 case OOX_TOKEN( a14, artisticMosiaicBubbles ):
return "artisticMosiaicBubbles";
1191 case OOX_TOKEN( a14, artisticPaintStrokes ):
return "artisticPaintStrokes";
1192 case OOX_TOKEN( a14, artisticPaintBrush ):
return "artisticPaintBrush";
1193 case OOX_TOKEN( a14, artisticPastelsSmooth ):
return "artisticPastelsSmooth";
1194 case OOX_TOKEN( a14, artisticPencilGrayscale ):
return "artisticPencilGrayscale";
1195 case OOX_TOKEN( a14, artisticPencilSketch ):
return "artisticPencilSketch";
1196 case OOX_TOKEN( a14, artisticPhotocopy ):
return "artisticPhotocopy";
1197 case OOX_TOKEN( a14, artisticPlasticWrap ):
return "artisticPlasticWrap";
1198 case OOX_TOKEN( a14, artisticTexturizer ):
return "artisticTexturizer";
1199 case OOX_TOKEN( a14, artisticWatercolorSponge ):
return "artisticWatercolorSponge";
1200 case OOX_TOKEN( a14, brightnessContrast ):
return "brightnessContrast";
1201 case OOX_TOKEN( a14, colorTemperature ):
return "colorTemperature";
1202 case OOX_TOKEN( a14, saturation ):
return "saturation";
1203 case OOX_TOKEN( a14, sharpenSoften ):
return "sharpenSoften";
1206 case XML_visible:
return "visible";
1207 case XML_trans:
return "trans";
1208 case XML_crackSpacing:
return "crackSpacing";
1209 case XML_pressure:
return "pressure";
1210 case XML_numberOfShades:
return "numberOfShades";
1211 case XML_grainSize:
return "grainSize";
1212 case XML_intensity:
return "intensity";
1213 case XML_smoothness:
return "smoothness";
1214 case XML_gridSize:
return "gridSize";
1215 case XML_pencilSize:
return "pencilSize";
1216 case XML_size:
return "size";
1217 case XML_brushSize:
return "brushSize";
1218 case XML_scaling:
return "scaling";
1219 case XML_detail:
return "detail";
1220 case XML_bright:
return "bright";
1221 case XML_contrast:
return "contrast";
1222 case XML_colorTemp:
return "colorTemp";
1223 case XML_sat:
return "sat";
1224 case XML_amount:
return "amount";
1226 SAL_WARN(
"oox.drawingml",
"ArtisticEffectProperties::getEffectString: unexpected token " <<
nToken );
1233 if(
sName ==
"artisticBlur" )
1234 return XML_artisticBlur;
1235 else if(
sName ==
"artisticCement" )
1236 return XML_artisticCement;
1237 else if(
sName ==
"artisticChalkSketch" )
1238 return XML_artisticChalkSketch;
1239 else if(
sName ==
"artisticCrisscrossEtching" )
1240 return XML_artisticCrisscrossEtching;
1241 else if(
sName ==
"artisticCutout" )
1242 return XML_artisticCutout;
1243 else if(
sName ==
"artisticFilmGrain" )
1244 return XML_artisticFilmGrain;
1245 else if(
sName ==
"artisticGlass" )
1246 return XML_artisticGlass;
1247 else if(
sName ==
"artisticGlowDiffused" )
1248 return XML_artisticGlowDiffused;
1249 else if(
sName ==
"artisticGlowEdges" )
1250 return XML_artisticGlowEdges;
1251 else if(
sName ==
"artisticLightScreen" )
1252 return XML_artisticLightScreen;
1253 else if(
sName ==
"artisticLineDrawing" )
1254 return XML_artisticLineDrawing;
1255 else if(
sName ==
"artisticMarker" )
1256 return XML_artisticMarker;
1257 else if(
sName ==
"artisticMosiaicBubbles" )
1258 return XML_artisticMosiaicBubbles;
1259 else if(
sName ==
"artisticPaintStrokes" )
1260 return XML_artisticPaintStrokes;
1261 else if(
sName ==
"artisticPaintBrush" )
1262 return XML_artisticPaintBrush;
1263 else if(
sName ==
"artisticPastelsSmooth" )
1264 return XML_artisticPastelsSmooth;
1265 else if(
sName ==
"artisticPencilGrayscale" )
1266 return XML_artisticPencilGrayscale;
1267 else if(
sName ==
"artisticPencilSketch" )
1268 return XML_artisticPencilSketch;
1269 else if(
sName ==
"artisticPhotocopy" )
1270 return XML_artisticPhotocopy;
1271 else if(
sName ==
"artisticPlasticWrap" )
1272 return XML_artisticPlasticWrap;
1273 else if(
sName ==
"artisticTexturizer" )
1274 return XML_artisticTexturizer;
1275 else if(
sName ==
"artisticWatercolorSponge" )
1276 return XML_artisticWatercolorSponge;
1277 else if(
sName ==
"brightnessContrast" )
1278 return XML_brightnessContrast;
1279 else if(
sName ==
"colorTemperature" )
1280 return XML_colorTemperature;
1281 else if(
sName ==
"saturation" )
1282 return XML_saturation;
1283 else if(
sName ==
"sharpenSoften" )
1284 return XML_sharpenSoften;
1287 else if(
sName ==
"visible" )
1289 else if(
sName ==
"trans" )
1291 else if(
sName ==
"crackSpacing" )
1292 return XML_crackSpacing;
1293 else if(
sName ==
"pressure" )
1294 return XML_pressure;
1295 else if(
sName ==
"numberOfShades" )
1296 return XML_numberOfShades;
1297 else if(
sName ==
"grainSize" )
1298 return XML_grainSize;
1299 else if(
sName ==
"intensity" )
1300 return XML_intensity;
1301 else if(
sName ==
"smoothness" )
1302 return XML_smoothness;
1303 else if(
sName ==
"gridSize" )
1304 return XML_gridSize;
1305 else if(
sName ==
"pencilSize" )
1306 return XML_pencilSize;
1307 else if(
sName ==
"size" )
1309 else if(
sName ==
"brushSize" )
1310 return XML_brushSize;
1311 else if(
sName ==
"scaling" )
1313 else if(
sName ==
"detail" )
1315 else if(
sName ==
"bright" )
1317 else if(
sName ==
"contrast" )
1318 return XML_contrast;
1319 else if(
sName ==
"colorTemp" )
1320 return XML_colorTemp;
1321 else if(
sName ==
"sat" )
1323 else if(
sName ==
"amount" )
1326 SAL_WARN(
"oox.drawingml",
"ArtisticEffectProperties::getEffectToken - unexpected token name: " <<
sName );
const AlphaMask & GetAlphaMask() const
bool Convert(BmpConversion eConversion)
bool Mirror(BmpMirrorFlags nMirrorFlags)
Bitmap GetBitmap(Color aTransparentReplaceColor) const
bool Crop(const tools::Rectangle &rRectPixel)
const Size & GetSizePixel() const
static bool Filter(BitmapEx &rBmpEx, BitmapFilter const &rFilter)
css::uno::Reference< css::graphic::XGraphic > GetXGraphic() const
void setOriginURL(OUString const &rOriginURL)
constexpr tools::Long Height() const
constexpr tools::Long Width() const
void addTransformation(Transformation const &rTransform)
void setType(ThemeColorType eType)
Provides helper functions for colors, device measurement conversion, graphics, and graphic objects ha...
css::awt::Size getOriginalSize(const css::uno::Reference< css::graphic::XGraphic > &rxGraphic) const
calculates the original size of a graphic which is necessary to be able to calculate cropping values
css::awt::Size convertScreenPixelToHmm(const css::awt::Size &rPixel) const
Converts the passed size from screen pixels to 1/100 mm.
A helper that maps property identifiers to property values.
css::uno::Any getProperty(sal_Int32 nPropId)
bool hasProperty(sal_Int32 nPropId) const
Returns true, if the map contains a property with the passed identifier.
bool setProperty(sal_Int32 nPropId, Type &&rValue)
Sets the specified property to the passed value.
sal_Int16 getTintOrShade() const
sal_Int16 getLumMod() const
sal_Int16 getTransparency() const
Returns the transparency of the color (0 = opaque, 100 = full transparent).
void assignIfUsed(const Color &rColor)
Overwrites this color with the passed color, if it is used.
sal_Int16 getLumOff() const
bool isUsed() const
Returns true, if the color is initialized.
bool hasTransparency() const
Returns true, if the color is transparent.
sal_Int16 getSchemeColorIndex() const
::Color getColor(const GraphicHelper &rGraphicHelper, ::Color nPhClr=API_RGB_TRANSPARENT) const
Returns the final RGB color value.
bool setProperty(ShapeProperty ePropId, const Type &rValue)
Sets the specified shape property to the passed value.
bool supportsProperty(ShapeProperty ePropId) const
Returns true, if the specified property is supported.
static drawing::Hatch createHatch(sal_Int32 nHatchToken, ::Color nColor)
Sequence< sal_Int8 > aSeq
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
tools::Long const nBorder
enum SAL_DLLPUBLIC_RTTI FillStyle
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
uno::Reference< util::XThemeColor > createXThemeColor(model::ThemeColor const &rThemeColor)
constexpr ThemeColorType convertToThemeColorType(sal_Int32 nIndex)
@ FillBitmap
Explicit fill bitmap or name of a fill bitmap stored in a global container.
@ FillBitmapRectanglePoint
@ FillGradient
Explicit fill gradient or name of a fill gradient stored in a global container.
@ FillHatch
Explicit fill hatch or name of a fill hatch stored in a global container.
const sal_Int32 MAX_PERCENT
const sal_Int32 PER_DEGREE
const sal_Int32 PER_PERCENT
void assignIfUsed(std::optional< Type > &rDestValue, const std::optional< Type > &rSourceValue)
const ::Color API_RGB_TRANSPARENT(ColorTransparency, 0xffffffff)
Transparent color for API calls.
bool isEmpty() const
The original graphic as embedded object.
css::beans::PropertyValue getEffect()
Returns the struct as a PropertyValue with Name = msName and Value = maAttribs as a Sequence< Propert...
void assignUsed(const ArtisticEffectProperties &rSourceProps)
Overwrites all members that are explicitly set in rSourceProps.
::oox::ole::OleObjectInfo mrOleObjectInfo
std::map< OUString, css::uno::Any > maAttribs
static OUString getEffectString(sal_Int32 nToken)
Translate effect tokens to strings.
static sal_Int32 getEffectToken(const OUString &sName)
Translate effect strings to tokens.
std::optional< css::geometry::IntegerRectangle2D > moClipRect
Stretch fill offsets.
Color maColorChangeTo
Start color of color transformation.
std::optional< css::geometry::IntegerRectangle2D > moFillRect
Bitmap tile or stretch.
std::optional< sal_Int32 > moColorEffect
True = rotate bitmap with shape.
std::optional< sal_Int32 > moBitmapMode
The fill graphic.
std::optional< sal_Int32 > moTileFlip
Anchor point inside bitmap.
Color maDuotoneColors[2]
Destination color of color transformation.
std::optional< sal_Int32 > moAlphaModFix
Artistic effect, not supported by core.
std::optional< sal_Int32 > moTileScaleY
Horizontal scaling of bitmap tiles (1/1000 percent).
std::optional< sal_Int32 > moTileOffsetY
Width of bitmap tiles (EMUs).
std::optional< sal_Int32 > moBrightness
XML token for a color effect.
Color maColorChangeFrom
Bi-Level (Black/White) effect threshold (1/1000 percent)
std::optional< bool > moRotateWithShape
Flip mode of bitmap tiles.
std::optional< sal_Int32 > moBiLevelThreshold
Contrast in the range [-100000,100000].
css::uno::Reference< css::graphic::XGraphic > mxFillGraphic
ArtisticEffectProperties maEffect
Duotone Colors.
void assignUsed(const BlipFillProperties &rSourceProps)
Overwrites all members that are explicitly set in rSourceProps.
std::optional< sal_Int32 > moTileAlign
Vertical scaling of bitmap tiles (1/1000 percent).
std::optional< sal_Int32 > moTileScaleX
Height of bitmap tiles (EMUs).
std::optional< sal_Int32 > moTileOffsetX
std::optional< sal_Int32 > moContrast
Brightness in the range [-100000,100000].
PatternFillProperties maPatternProps
Properties for gradient fills.
GradientFillProperties maGradientProps
Whether the background is used as fill type.
BlipFillProperties maBlipProps
Properties for pattern fills.
void pushToPropMap(ShapePropertyMap &rPropMap, const GraphicHelper &rGraphicHelper, sal_Int32 nShapeRotation=0, ::Color nPhClr=API_RGB_TRANSPARENT, const css::awt::Size &rSize={}, sal_Int16 nPhClrTheme=-1, bool bFlipH=false, bool bFlipV=false, bool bIsCustomShape=false) const
Writes the properties to the passed property map.
void assignUsed(const FillProperties &rSourceProps)
Properties for bitmap fills.
Color getBestSolidColor() const
Tries to resolve current settings to a solid color, e.g.
std::optional< bool > moUseBgFill
Solid fill color and transparence.
Color maFillColor
Fill type (OOXML token).
std::optional< sal_Int32 > moFillType
std::optional< css::geometry::IntegerRectangle2D > moFillToRect
Gradient stops (colors/transparence).
std::optional< sal_Int32 > moShadeFlip
Rotation angle of linear gradients.
std::optional< bool > moRotateWithShape
True = scale gradient into shape.
std::optional< sal_Int32 > moGradientPath
void assignUsed(const GradientFillProperties &rSourceProps)
True = rotate gradient with shape.
std::optional< css::geometry::IntegerRectangle2D > moTileRect
std::optional< bool > moShadeScaled
Flip mode of gradient, if not stretched to shape.
std::optional< sal_Int32 > moShadeAngle
If set, gradient follows rectangle, circle, or shape.
GradientStopMap maGradientStops
::std::multimap< double, Color > GradientStopMap
OUString m_sMediaPackageURL
Audio/Video URL.
css::uno::Reference< css::io::XInputStream > m_xMediaStream
Audio/Video input stream.
void pushToPropMap(PropertyMap &rPropMap, const GraphicHelper &rGraphicHelper, bool bFlipH=false, bool bFlipV=false) const
Writes the properties to the passed property map.
BlipFillProperties maBlipProps
Properties for the graphic.
Color maPattBgColor
Pattern foreground color.
std::optional< sal_Int32 > moPattPreset
Pattern background color.
void assignUsed(const PatternFillProperties &rSourceProps)
Preset pattern type.
StreamDataSequence maEmbeddedData
Data of an embedded OLE object.
constexpr OUStringLiteral PROP_FillBitmapMode
constexpr OUStringLiteral PROP_GraphicColorMode
constexpr OUStringLiteral PROP_AdjustLuminance
constexpr OUStringLiteral PROP_RotateAngle
constexpr OUStringLiteral PROP_AdjustContrast
constexpr OUStringLiteral PROP_Transparency
constexpr OUStringLiteral PROP_FillColorThemeReference
constexpr OUStringLiteral PROP_GraphicCrop
constexpr OUStringLiteral PROP_FillStyle