LibreOffice Module oox (master) 1
fillproperties.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
21
22#include <iterator>
23
26#include <vcl/graph.hxx>
27#include <vcl/BitmapFilter.hxx>
31
32#include <com/sun/star/beans/XPropertySet.hpp>
33#include <com/sun/star/awt/Gradient2.hpp>
34#include <com/sun/star/text/GraphicCrop.hpp>
35#include <com/sun/star/awt/Size.hpp>
36#include <com/sun/star/drawing/BitmapMode.hpp>
37#include <com/sun/star/drawing/ColorMode.hpp>
38#include <com/sun/star/drawing/FillStyle.hpp>
39#include <com/sun/star/drawing/RectanglePoint.hpp>
40#include <com/sun/star/graphic/XGraphicTransformer.hpp>
45#include <oox/token/namespaces.hxx>
46#include <oox/token/properties.hxx>
47#include <oox/token/tokens.hxx>
48#include <osl/diagnose.h>
49#include <sal/log.hxx>
50
51using namespace ::com::sun::star;
52using namespace ::com::sun::star::drawing;
53using namespace ::com::sun::star::graphic;
54
55using ::com::sun::star::uno::Reference;
56using ::com::sun::star::uno::Exception;
57using ::com::sun::star::uno::UNO_QUERY_THROW;
58using ::com::sun::star::geometry::IntegerRectangle2D;
59
60namespace oox::drawingml {
61
62namespace {
63
64Reference< XGraphic > lclCheckAndApplyDuotoneTransform(const BlipFillProperties& aBlipProps, uno::Reference<graphic::XGraphic> const & xGraphic,
65 const GraphicHelper& rGraphicHelper, const ::Color nPhClr)
66{
67 if (aBlipProps.maDuotoneColors[0].isUsed() && aBlipProps.maDuotoneColors[1].isUsed())
68 {
69 ::Color nColor1 = aBlipProps.maDuotoneColors[0].getColor( rGraphicHelper, nPhClr );
70 ::Color nColor2 = aBlipProps.maDuotoneColors[1].getColor( rGraphicHelper, nPhClr );
71
72 uno::Reference<graphic::XGraphicTransformer> xTransformer(aBlipProps.mxFillGraphic, uno::UNO_QUERY);
73 if (xTransformer.is())
74 return xTransformer->applyDuotone(xGraphic, sal_Int32(nColor1), sal_Int32(nColor2));
75 }
76 return xGraphic;
77}
78
79Reference< XGraphic > lclRotateGraphic(uno::Reference<graphic::XGraphic> const & xGraphic, Degree10 nRotation)
80{
81 ::Graphic aGraphic(xGraphic);
82 ::Graphic aReturnGraphic;
83
84 assert (aGraphic.GetType() == GraphicType::Bitmap);
85
86 BitmapEx aBitmapEx(aGraphic.GetBitmapEx());
87 const ::Color& aColor = ::Color(0x00);
88 aBitmapEx.Rotate(nRotation, aColor);
89 aReturnGraphic = ::Graphic(aBitmapEx);
90 aReturnGraphic.setOriginURL(aGraphic.getOriginURL());
91
92 return aReturnGraphic.GetXGraphic();
93}
94
95using Quotients = std::tuple<double, double, double, double>;
96Quotients getQuotients(geometry::IntegerRectangle2D aRelRect, double hDiv, double vDiv)
97{
98 return { aRelRect.X1 / hDiv, aRelRect.Y1 / vDiv, aRelRect.X2 / hDiv, aRelRect.Y2 / vDiv };
99}
100
101// ECMA-376 Part 1 20.1.8.55 srcRect (Source Rectangle)
102std::optional<Quotients> CropQuotientsFromSrcRect(geometry::IntegerRectangle2D aSrcRect)
103{
104 aSrcRect.X1 = std::max(aSrcRect.X1, sal_Int32(0));
105 aSrcRect.X2 = std::max(aSrcRect.X2, sal_Int32(0));
106 aSrcRect.Y1 = std::max(aSrcRect.Y1, sal_Int32(0));
107 aSrcRect.Y2 = std::max(aSrcRect.Y2, sal_Int32(0));
108 if (aSrcRect.X1 + aSrcRect.X2 >= 100'000 || aSrcRect.Y1 + aSrcRect.Y2 >= 100'000)
109 return {}; // Cropped everything
110 return getQuotients(aSrcRect, 100'000.0, 100'000.0);
111}
112
113// ECMA-376 Part 1 20.1.8.30 fillRect (Fill Rectangle)
114std::optional<Quotients> CropQuotientsFromFillRect(geometry::IntegerRectangle2D aFillRect)
115{
116 aFillRect.X1 = std::min(aFillRect.X1, sal_Int32(0));
117 aFillRect.X2 = std::min(aFillRect.X2, sal_Int32(0));
118 aFillRect.Y1 = std::min(aFillRect.Y1, sal_Int32(0));
119 aFillRect.Y2 = std::min(aFillRect.Y2, sal_Int32(0));
120 // Negative divisor and negative relative offset give positive value wanted in lclCropGraphic
121 return getQuotients(aFillRect, -100'000.0 + aFillRect.X1 + aFillRect.X2,
122 -100'000.0 + aFillRect.Y1 + aFillRect.Y2);
123}
124
125// Crops a piece of the bitmap. lclCropGraphic doesn't handle growing.
126Reference<XGraphic> lclCropGraphic(uno::Reference<graphic::XGraphic> const& xGraphic,
127 std::optional<Quotients> quotients)
128{
129 ::Graphic aGraphic(xGraphic);
130 assert (aGraphic.GetType() == GraphicType::Bitmap);
131
132 BitmapEx aBitmapEx;
133 if (quotients)
134 {
135 aBitmapEx = aGraphic.GetBitmapEx();
136
137 const Size bmpSize = aBitmapEx.GetSizePixel();
138 const auto& [qx1, qy1, qx2, qy2] = *quotients;
139 const tools::Long l = std::round(bmpSize.Width() * qx1);
140 const tools::Long t = std::round(bmpSize.Height() * qy1);
141 const tools::Long r = std::round(bmpSize.Width() * qx2);
142 const tools::Long b = std::round(bmpSize.Height() * qy2);
143
144 aBitmapEx.Crop({ l, t, bmpSize.Width() - r - 1, bmpSize.Height() - b - 1 });
145 }
146
147 ::Graphic aReturnGraphic(aBitmapEx);
148 aReturnGraphic.setOriginURL(aGraphic.getOriginURL());
149
150 return aReturnGraphic.GetXGraphic();
151}
152
153Reference< XGraphic > lclMirrorGraphic(uno::Reference<graphic::XGraphic> const & xGraphic, bool bFlipH, bool bFlipV)
154{
155 ::Graphic aGraphic(xGraphic);
156 ::Graphic aReturnGraphic;
157
158 assert (aGraphic.GetType() == GraphicType::Bitmap);
159
160 BitmapEx aBitmapEx(aGraphic.GetBitmapEx());
161 BmpMirrorFlags nMirrorFlags = BmpMirrorFlags::NONE;
162
163 if(bFlipH)
164 nMirrorFlags |= BmpMirrorFlags::Horizontal;
165 if(bFlipV)
166 nMirrorFlags |= BmpMirrorFlags::Vertical;
167
168 aBitmapEx.Mirror(nMirrorFlags);
169
170 aReturnGraphic = ::Graphic(aBitmapEx);
171 aReturnGraphic.setOriginURL(aGraphic.getOriginURL());
172
173 return aReturnGraphic.GetXGraphic();
174}
175
176Reference< XGraphic > lclGreysScaleGraphic(uno::Reference<graphic::XGraphic> const & xGraphic)
177{
178 ::Graphic aGraphic(xGraphic);
179 ::Graphic aReturnGraphic;
180
181 assert (aGraphic.GetType() == GraphicType::Bitmap);
182
183 BitmapEx aBitmapEx(aGraphic.GetBitmapEx());
184 aBitmapEx.Convert(BmpConversion::N8BitGreys);
185
186 aReturnGraphic = ::Graphic(aBitmapEx);
187 aReturnGraphic.setOriginURL(aGraphic.getOriginURL());
188
189 return aReturnGraphic.GetXGraphic();
190}
191
193Reference<XGraphic> lclApplyBlackWhiteEffect(const BlipFillProperties& aBlipProps,
194 const uno::Reference<graphic::XGraphic>& xGraphic)
195{
196 const auto& oBiLevelThreshold = aBlipProps.moBiLevelThreshold;
197 if (oBiLevelThreshold.has_value())
198 {
199 sal_uInt8 nThreshold
200 = static_cast<sal_uInt8>(oBiLevelThreshold.value() * 255 / MAX_PERCENT);
201
202 ::Graphic aGraphic(xGraphic);
203 ::Graphic aReturnGraphic;
204
205 BitmapEx aBitmapEx(aGraphic.GetBitmapEx());
206 AlphaMask aMask(aBitmapEx.GetAlphaMask());
207
208 BitmapEx aTmpBmpEx(aBitmapEx.GetBitmap());
209 BitmapFilter::Filter(aTmpBmpEx, BitmapMonochromeFilter{ nThreshold });
210
211 aReturnGraphic = ::Graphic(BitmapEx(aTmpBmpEx.GetBitmap(), aMask));
212 aReturnGraphic.setOriginURL(aGraphic.getOriginURL());
213 return aReturnGraphic.GetXGraphic();
214 }
215 return xGraphic;
216}
217
218Reference< XGraphic > lclCheckAndApplyChangeColorTransform(const BlipFillProperties &aBlipProps, uno::Reference<graphic::XGraphic> const & xGraphic,
219 const GraphicHelper& rGraphicHelper, const ::Color nPhClr)
220{
221 if( aBlipProps.maColorChangeFrom.isUsed() && aBlipProps.maColorChangeTo.isUsed() )
222 {
223 ::Color nFromColor = aBlipProps.maColorChangeFrom.getColor( rGraphicHelper, nPhClr );
224 ::Color nToColor = aBlipProps.maColorChangeTo.getColor( rGraphicHelper, nPhClr );
225 if ( (nFromColor != nToColor) || aBlipProps.maColorChangeTo.hasTransparency() )
226 {
227 sal_Int16 nToTransparence = aBlipProps.maColorChangeTo.getTransparency();
228 sal_Int8 nToAlpha = static_cast< sal_Int8 >( (100 - nToTransparence) * 2.55 );
229
230 sal_uInt8 nTolerance = 9;
231 Graphic aGraphic{ xGraphic };
232 if( aGraphic.IsGfxLink() )
233 {
234 // tdf#149670: Try to guess tolerance depending on image format
235 switch (aGraphic.GetGfxLink().GetType())
236 {
237 case GfxLinkType::NativeJpg:
238 nTolerance = 15;
239 break;
240 case GfxLinkType::NativePng:
241 case GfxLinkType::NativeTif:
242 nTolerance = 1;
243 break;
244 case GfxLinkType::NativeBmp:
245 nTolerance = 0;
246 break;
247 default:
248 break;
249 }
250 }
251
252 uno::Reference<graphic::XGraphicTransformer> xTransformer(aBlipProps.mxFillGraphic, uno::UNO_QUERY);
253 if (xTransformer.is())
254 return xTransformer->colorChange(xGraphic, sal_Int32(nFromColor), nTolerance, sal_Int32(nToColor), nToAlpha);
255 }
256 }
257 return xGraphic;
258}
259
260uno::Reference<graphic::XGraphic> applyBrightnessContrast(uno::Reference<graphic::XGraphic> const & xGraphic, sal_Int32 brightness, sal_Int32 contrast)
261{
262 uno::Reference<graphic::XGraphicTransformer> xTransformer(xGraphic, uno::UNO_QUERY);
263 if (xTransformer.is())
264 return xTransformer->applyBrightnessContrast(xGraphic, brightness, contrast, true);
265 return xGraphic;
266}
267
268BitmapMode lclGetBitmapMode( sal_Int32 nToken )
269{
270 OSL_ASSERT((nToken & sal_Int32(0xFFFF0000))==0);
271 switch( nToken )
272 {
273 case XML_tile: return BitmapMode_REPEAT;
274 case XML_stretch: return BitmapMode_STRETCH;
275 }
276
277 // tdf#128596 Default value is XML_tile for MSO.
278 return BitmapMode_REPEAT;
279}
280
281RectanglePoint lclGetRectanglePoint( sal_Int32 nToken )
282{
283 OSL_ASSERT((nToken & sal_Int32(0xFFFF0000))==0);
284 switch( nToken )
285 {
286 case XML_tl: return RectanglePoint_LEFT_TOP;
287 case XML_t: return RectanglePoint_MIDDLE_TOP;
288 case XML_tr: return RectanglePoint_RIGHT_TOP;
289 case XML_l: return RectanglePoint_LEFT_MIDDLE;
290 case XML_ctr: return RectanglePoint_MIDDLE_MIDDLE;
291 case XML_r: return RectanglePoint_RIGHT_MIDDLE;
292 case XML_bl: return RectanglePoint_LEFT_BOTTOM;
293 case XML_b: return RectanglePoint_MIDDLE_BOTTOM;
294 case XML_br: return RectanglePoint_RIGHT_BOTTOM;
295 }
296 return RectanglePoint_LEFT_TOP;
297}
298
299awt::Size lclGetOriginalSize( const GraphicHelper& rGraphicHelper, const Reference< XGraphic >& rxGraphic )
300{
301 awt::Size aSizeHmm( 0, 0 );
302 try
303 {
304 Reference< beans::XPropertySet > xGraphicPropertySet( rxGraphic, UNO_QUERY_THROW );
305 if( xGraphicPropertySet->getPropertyValue( "Size100thMM" ) >>= aSizeHmm )
306 {
307 if( !aSizeHmm.Width && !aSizeHmm.Height )
308 { // MAPMODE_PIXEL USED :-(
309 awt::Size aSourceSizePixel( 0, 0 );
310 if( xGraphicPropertySet->getPropertyValue( "SizePixel" ) >>= aSourceSizePixel )
311 aSizeHmm = rGraphicHelper.convertScreenPixelToHmm( aSourceSizePixel );
312 }
313 }
314 }
315 catch( Exception& )
316 {
317 }
318 return aSizeHmm;
319}
320
321} // namespace
322
324{
325 if( !rSourceProps.maGradientStops.empty() )
326 maGradientStops = rSourceProps.maGradientStops;
327 assignIfUsed( moFillToRect, rSourceProps.moFillToRect );
328 assignIfUsed( moTileRect, rSourceProps.moTileRect );
330 assignIfUsed( moShadeAngle, rSourceProps.moShadeAngle );
331 assignIfUsed( moShadeFlip, rSourceProps.moShadeFlip );
334}
335
337{
340 assignIfUsed( moPattPreset, rSourceProps.moPattPreset );
341}
342
344{
345 if(rSourceProps.mxFillGraphic.is())
346 mxFillGraphic = rSourceProps.mxFillGraphic;
347 assignIfUsed( moBitmapMode, rSourceProps.moBitmapMode );
348 assignIfUsed( moFillRect, rSourceProps.moFillRect );
351 assignIfUsed( moTileScaleX, rSourceProps.moTileScaleX );
352 assignIfUsed( moTileScaleY, rSourceProps.moTileScaleY );
353 assignIfUsed( moTileAlign, rSourceProps.moTileAlign );
354 assignIfUsed( moTileFlip, rSourceProps.moTileFlip );
357 assignIfUsed( moBrightness, rSourceProps.moBrightness );
358 assignIfUsed( moContrast, rSourceProps.moContrast );
362 maDuotoneColors[0].assignIfUsed( rSourceProps.maDuotoneColors[0] );
363 maDuotoneColors[1].assignIfUsed( rSourceProps.maDuotoneColors[1] );
364 maEffect.assignUsed( rSourceProps.maEffect );
366}
367
369{
370 assignIfUsed( moFillType, rSourceProps.moFillType );
371 maFillColor.assignIfUsed( rSourceProps.maFillColor );
372 assignIfUsed( moUseBgFill, rSourceProps.moUseBgFill );
375 maBlipProps.assignUsed( rSourceProps.maBlipProps );
376}
377
379{
380 Color aSolidColor;
381 if( moFillType.has_value() ) switch( moFillType.value() )
382 {
383 case XML_solidFill:
384 aSolidColor = maFillColor;
385 break;
386 case XML_gradFill:
387 if( !maGradientProps.maGradientStops.empty() )
388 {
389 GradientFillProperties::GradientStopMap::const_iterator aGradientStop =
391 if (maGradientProps.maGradientStops.size() > 2)
392 ++aGradientStop;
393 aSolidColor = aGradientStop->second;
394 }
395 break;
396 case XML_pattFill:
398 break;
399 }
400 return aSolidColor;
401}
402
404 sal_Int32 nShapeRotation, ::Color nPhClr,
405 const css::awt::Size& rSize, sal_Int16 nPhClrTheme, bool bFlipH,
406 bool bFlipV, bool bIsCustomShape) const
407{
408 if( !moFillType.has_value() )
409 return;
410
411 FillStyle eFillStyle = FillStyle_NONE;
412 OSL_ASSERT((moFillType.value() & sal_Int32(0xFFFF0000))==0);
413 switch( moFillType.value() )
414 {
415 case XML_noFill:
416 {
417 eFillStyle = FillStyle_NONE;
419 }
420 break;
421
422 case XML_solidFill:
423 if( maFillColor.isUsed() )
424 {
425 ::Color aFillColor = maFillColor.getColor(rGraphicHelper, nPhClr);
426 rPropMap.setProperty(ShapeProperty::FillColor, aFillColor);
429
430 model::ComplexColor aComplexColor;
431 if (aFillColor == nPhClr)
432 {
433 aComplexColor.setSchemeColor(model::convertToThemeColorType(nPhClrTheme));
434 }
435 else
436 {
437 aComplexColor = maFillColor.getComplexColor();
438 }
440
441 eFillStyle = FillStyle_SOLID;
442 }
443 break;
444
445 case XML_gradFill:
446 // do not create gradient struct if property is not supported...
448 {
449 // prepare ColorStops
450 basegfx::BColorStops aColorStops;
451 basegfx::BColorStops aTransparencyStops;
452 bool bContainsTransparency(false);
453
454 // convert to BColorStops, check for contained transparency
455 for (const auto& rCandidate : maGradientProps.maGradientStops)
456 {
457 const ::Color aColor(rCandidate.second.getColor(rGraphicHelper, nPhClr));
458 aColorStops.emplace_back(rCandidate.first, aColor.getBColor());
459 bContainsTransparency = bContainsTransparency || rCandidate.second.hasTransparency();
460 }
461
462 // if we have transparency, convert to BColorStops
463 if (bContainsTransparency)
464 {
465 for (const auto& rCandidate : maGradientProps.maGradientStops)
466 {
467 const double fTrans(rCandidate.second.getTransparency() * (1.0/100.0));
468 aTransparencyStops.emplace_back(rCandidate.first, basegfx::BColor(fTrans, fTrans, fTrans));
469 }
470 }
471
472 // prepare BGradient with some defaults
473 // CAUTION: This used awt::Gradient2 before who's empty constructor
474 // (see workdir/UnoApiHeadersTarget/offapi/normal/com/sun/
475 // star/awt/Gradient.hpp) initializes all to zeros, so reflect
476 // this here. OTOH set all that were set, e.g. Start/EndIntens
477 // were set to 100, so just use default of BGradient constructor
478 basegfx::BGradient aGradient(
479 aColorStops,
480 awt::GradientStyle_LINEAR,
481 Degree10(900),
482 0, // border
483 0, // OfsX -> 0, not 50 (!)
484 0); // OfsY -> 0, not 50 (!)
485
486 // "rotate with shape" set to false -> do not rotate
487 if (!maGradientProps.moRotateWithShape.value_or(true))
488 {
489 nShapeRotation = 0;
490 }
491
492 if (maGradientProps.moGradientPath.has_value())
493 {
494 IntegerRectangle2D aFillToRect = maGradientProps.moFillToRect.value_or( IntegerRectangle2D( 0, 0, MAX_PERCENT, MAX_PERCENT ) );
495 sal_Int32 nCenterX = (MAX_PERCENT + aFillToRect.X1 - aFillToRect.X2) / 2;
496 aGradient.SetXOffset(getLimitedValue<sal_Int16, sal_Int32>(
497 nCenterX / PER_PERCENT, 0, 100));
498 sal_Int32 nCenterY = (MAX_PERCENT + aFillToRect.Y1 - aFillToRect.Y2) / 2;
499 aGradient.SetYOffset(getLimitedValue<sal_Int16, sal_Int32>(
500 nCenterY / PER_PERCENT, 0, 100));
501
502 if( maGradientProps.moGradientPath.value() == XML_circle )
503 {
504 // Style should be radial at least when the horizontal center is at 50%.
505 // Otherwise import as a linear gradient, because it is the most similar to the MSO radial style.
506 // aGradient.SetGradientStyle(awt::GradientStyle_LINEAR);
507 if( 100 == aGradient.GetXOffset() && 100 == aGradient.GetYOffset() )
508 aGradient.SetAngle( Degree10(450) );
509 else if( 0 == aGradient.GetXOffset() && 100 == aGradient.GetYOffset() )
510 aGradient.SetAngle( Degree10(3150) );
511 else if( 100 == aGradient.GetXOffset() && 0 == aGradient.GetYOffset() )
512 aGradient.SetAngle( Degree10(1350) );
513 else if( 0 == aGradient.GetXOffset() && 0 == aGradient.GetYOffset() )
514 aGradient.SetAngle( Degree10(2250) );
515 else
516 aGradient.SetGradientStyle(awt::GradientStyle_RADIAL);
517 }
518 else
519 {
520 aGradient.SetGradientStyle(awt::GradientStyle_RECT);
521 }
522
523 aColorStops.reverseColorStops();
524 aGradient.SetColorStops(aColorStops);
525 aTransparencyStops.reverseColorStops();
526 }
527 else if (!maGradientProps.maGradientStops.empty())
528 {
529 // aGradient.SetGradientStyle(awt::GradientStyle_LINEAR);
530 sal_Int32 nShadeAngle(maGradientProps.moShadeAngle.value_or( 0 ));
531 // Adjust for flips
532 if ( bFlipH )
533 nShadeAngle = 180*60000 - nShadeAngle;
534 if ( bFlipV )
535 nShadeAngle = -nShadeAngle;
536 const sal_Int32 nDmlAngle = nShadeAngle + nShapeRotation;
537
538 // convert DrawingML angle (in 1/60000 degrees) to API angle (in 1/10 degrees)
539 aGradient.SetAngle(Degree10(static_cast< sal_Int16 >( (8100 - (nDmlAngle / (PER_DEGREE / 10))) % 3600 )));
540 }
541
542 if (awt::GradientStyle_RECT == aGradient.GetGradientStyle())
543 {
544 // MCGR: tdf#155362: better support border
545 // CAUTION: Need to handle TransparencyStops if used
546 aGradient.tryToRecreateBorder(aTransparencyStops.empty() ? nullptr : &aTransparencyStops);
547 }
548
549 // push gradient or named gradient to property map
550 if (rPropMap.setProperty(ShapeProperty::FillGradient, aGradient.getAsGradient2()))
551 {
552 eFillStyle = FillStyle_GRADIENT;
553 }
554
555 // push gradient transparency to property map if it exists
556 if (!aTransparencyStops.empty())
557 {
558 aGradient.SetColorStops(aTransparencyStops);
560 }
561 }
562 break;
563
564 case XML_blipFill:
565 // do not start complex graphic transformation if property is not supported...
567 {
568 uno::Reference<graphic::XGraphic> xGraphic = lclCheckAndApplyDuotoneTransform(maBlipProps, maBlipProps.mxFillGraphic, rGraphicHelper, nPhClr);
569 // TODO: "rotate with shape" is not possible with our current core
570
571 if (xGraphic.is())
572 {
573 if (maBlipProps.moColorEffect.value_or(XML_TOKEN_INVALID) == XML_grayscl)
574 xGraphic = lclGreysScaleGraphic(xGraphic);
575
577 rPropMap.setProperty(ShapeProperty::FillBitmapName, xGraphic))
578 {
579 eFillStyle = FillStyle_BITMAP;
580 }
581 else if (rPropMap.setProperty(ShapeProperty::FillBitmap, xGraphic))
582 {
583 eFillStyle = FillStyle_BITMAP;
584 }
585 }
586
587 // set other bitmap properties, if bitmap has been inserted into the map
588 if( eFillStyle == FillStyle_BITMAP )
589 {
590 // bitmap mode (single, repeat, stretch)
591 BitmapMode eBitmapMode = lclGetBitmapMode( maBlipProps.moBitmapMode.value_or( XML_TOKEN_INVALID ) );
592
593 // additional settings for repeated bitmap
594 if( eBitmapMode == BitmapMode_REPEAT )
595 {
596 // anchor position inside bitmap
597 RectanglePoint eRectPoint = lclGetRectanglePoint( maBlipProps.moTileAlign.value_or( XML_tl ) );
599
600 awt::Size aOriginalSize = lclGetOriginalSize(rGraphicHelper, maBlipProps.mxFillGraphic);
601 if( (aOriginalSize.Width > 0) && (aOriginalSize.Height > 0) )
602 {
603 // size of one bitmap tile (given as 1/1000 percent of bitmap size), convert to 1/100 mm
604 double fScaleX = maBlipProps.moTileScaleX.value_or( MAX_PERCENT ) / static_cast< double >( MAX_PERCENT );
605 sal_Int32 nFillBmpSizeX = getLimitedValue< sal_Int32, double >( aOriginalSize.Width * fScaleX, 1, SAL_MAX_INT32 );
606 rPropMap.setProperty( ShapeProperty::FillBitmapSizeX, nFillBmpSizeX );
607 double fScaleY = maBlipProps.moTileScaleY.value_or( MAX_PERCENT ) / static_cast< double >( MAX_PERCENT );
608 sal_Int32 nFillBmpSizeY = getLimitedValue< sal_Int32, double >( aOriginalSize.Height * fScaleY, 1, SAL_MAX_INT32 );
609 rPropMap.setProperty( ShapeProperty::FillBitmapSizeY, nFillBmpSizeY );
610
611 awt::Size aBmpSize(nFillBmpSizeX, nFillBmpSizeY);
612 // offset of the first bitmap tile (given as EMUs), convert to percent
613 sal_Int16 nTileOffsetX = getDoubleIntervalValue< sal_Int16 >(std::round(maBlipProps.moTileOffsetX.value_or( 0 ) / 3.6 / aBmpSize.Width), 0, 100 );
614 rPropMap.setProperty( ShapeProperty::FillBitmapOffsetX, nTileOffsetX );
615 sal_Int16 nTileOffsetY = getDoubleIntervalValue< sal_Int16 >(std::round(maBlipProps.moTileOffsetY.value_or( 0 ) / 3.6 / aBmpSize.Height), 0, 100 );
616 rPropMap.setProperty( ShapeProperty::FillBitmapOffsetY, nTileOffsetY );
617 }
618 }
619 else if ( eBitmapMode == BitmapMode_STRETCH && maBlipProps.moFillRect.has_value() )
620 {
621 geometry::IntegerRectangle2D aFillRect( maBlipProps.moFillRect.value() );
622 awt::Size aOriginalSize( rGraphicHelper.getOriginalSize( xGraphic ) );
623 if ( aOriginalSize.Width && aOriginalSize.Height )
624 {
625 text::GraphicCrop aGraphCrop( 0, 0, 0, 0 );
626 if ( aFillRect.X1 )
627 aGraphCrop.Left = static_cast< sal_Int32 >( ( static_cast< double >( aOriginalSize.Width ) * aFillRect.X1 ) / 100000 );
628 if ( aFillRect.Y1 )
629 aGraphCrop.Top = static_cast< sal_Int32 >( ( static_cast< double >( aOriginalSize.Height ) * aFillRect.Y1 ) / 100000 );
630 if ( aFillRect.X2 )
631 aGraphCrop.Right = static_cast< sal_Int32 >( ( static_cast< double >( aOriginalSize.Width ) * aFillRect.X2 ) / 100000 );
632 if ( aFillRect.Y2 )
633 aGraphCrop.Bottom = static_cast< sal_Int32 >( ( static_cast< double >( aOriginalSize.Height ) * aFillRect.Y2 ) / 100000 );
634
635 bool bHasCropValues = aGraphCrop.Left != 0 || aGraphCrop.Right !=0 || aGraphCrop.Top != 0 || aGraphCrop.Bottom != 0;
636 // Negative GraphicCrop values means "crop" here.
637 bool bNeedCrop = aGraphCrop.Left <= 0 && aGraphCrop.Right <= 0 && aGraphCrop.Top <= 0 && aGraphCrop.Bottom <= 0;
638
639 if (bHasCropValues)
640 {
641 if (bIsCustomShape && bNeedCrop)
642 {
643 // Physically crop the image
644 // In this case, don't set the PROP_GraphicCrop because that
645 // would lead to applying the crop twice after roundtrip
646 xGraphic = lclCropGraphic(xGraphic, CropQuotientsFromFillRect(aFillRect));
648 rPropMap.setProperty(ShapeProperty::FillBitmapName, xGraphic);
649 else
650 rPropMap.setProperty(ShapeProperty::FillBitmap, xGraphic);
651 }
652 else if ((aFillRect.X1 != 0 && aFillRect.X2 != 0
653 && aFillRect.X1 != aFillRect.X2)
654 || (aFillRect.Y1 != 0 && aFillRect.Y2 != 0
655 && aFillRect.Y1 != aFillRect.Y2))
656 {
657 rPropMap.setProperty(PROP_GraphicCrop, aGraphCrop);
658 }
659 else
660 {
661 double nL = aFillRect.X1 / static_cast<double>(MAX_PERCENT);
662 double nT = aFillRect.Y1 / static_cast<double>(MAX_PERCENT);
663 double nR = aFillRect.X2 / static_cast<double>(MAX_PERCENT);
664 double nB = aFillRect.Y2 / static_cast<double>(MAX_PERCENT);
665
666 sal_Int32 nSizeX;
667 if (nL || nR)
668 nSizeX = rSize.Width * (1 - (nL + nR));
669 else
670 nSizeX = rSize.Width;
672
673 sal_Int32 nSizeY;
674 if (nT || nB)
675 nSizeY = rSize.Height * (1 - (nT + nB));
676 else
677 nSizeY = rSize.Height;
679
680 RectanglePoint eRectPoint;
681 if (!aFillRect.X1 && aFillRect.X2)
682 {
683 if (!aFillRect.Y1 && aFillRect.Y2)
684 eRectPoint = lclGetRectanglePoint(XML_tl);
685 else if (aFillRect.Y1 && !aFillRect.Y2)
686 eRectPoint = lclGetRectanglePoint(XML_bl);
687 else
688 eRectPoint = lclGetRectanglePoint(XML_l);
689 }
690 else if (aFillRect.X1 && !aFillRect.X2)
691 {
692 if (!aFillRect.Y1 && aFillRect.Y2)
693 eRectPoint = lclGetRectanglePoint(XML_tr);
694 else if (aFillRect.Y1 && !aFillRect.Y2)
695 eRectPoint = lclGetRectanglePoint(XML_br);
696 else
697 eRectPoint = lclGetRectanglePoint(XML_r);
698 }
699 else
700 {
701 if (!aFillRect.Y1 && aFillRect.Y2)
702 eRectPoint = lclGetRectanglePoint(XML_t);
703 else if (aFillRect.Y1 && !aFillRect.Y2)
704 eRectPoint = lclGetRectanglePoint(XML_b);
705 else
706 eRectPoint = lclGetRectanglePoint(XML_ctr);
707 }
709 eBitmapMode = BitmapMode_NO_REPEAT;
710 }
711 }
712 }
713 }
714 rPropMap.setProperty(ShapeProperty::FillBitmapMode, eBitmapMode);
715 }
716
717 if (maBlipProps.moAlphaModFix.has_value())
718 rPropMap.setProperty(ShapeProperty::FillTransparency, static_cast<sal_Int16>(100 - (maBlipProps.moAlphaModFix.value() / PER_PERCENT)));
719 }
720 break;
721
722 case XML_pattFill:
723 {
725 {
727 if( aColor.isUsed() && maPatternProps.moPattPreset.has_value() )
728 {
729 eFillStyle = FillStyle_HATCH;
730 rPropMap.setProperty( ShapeProperty::FillHatch, createHatch( maPatternProps.moPattPreset.value(), aColor.getColor( rGraphicHelper, nPhClr ) ) );
731 if( aColor.hasTransparency() )
733
734 // Set background color for hatch
736 {
738 rPropMap.setProperty( ShapeProperty::FillBackground, aColor.getTransparency() != 100 );
739 rPropMap.setProperty( ShapeProperty::FillColor, aColor.getColor( rGraphicHelper, nPhClr ) );
740 }
741 }
743 {
745 rPropMap.setProperty( ShapeProperty::FillColor, aColor.getColor( rGraphicHelper, nPhClr ) );
746 if( aColor.hasTransparency() )
748 eFillStyle = FillStyle_SOLID;
749 }
750 }
751 }
752 break;
753
754 case XML_grpFill:
755 // todo
756 eFillStyle = FillStyle_NONE;
757 break;
758 }
759
760 // set final fill style property
761 rPropMap.setProperty( ShapeProperty::FillStyle, eFillStyle );
762}
763
764void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const GraphicHelper& rGraphicHelper, bool bFlipH, bool bFlipV) const
765{
766 sal_Int16 nBrightness = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moBrightness.value_or( 0 ) / PER_PERCENT, -100, 100 );
767 sal_Int16 nContrast = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moContrast.value_or( 0 ) / PER_PERCENT, -100, 100 );
768 ColorMode eColorMode = ColorMode_STANDARD;
769
770 switch( maBlipProps.moColorEffect.value_or( XML_TOKEN_INVALID ) )
771 {
772 case XML_biLevel: eColorMode = ColorMode_MONO; break;
773 case XML_grayscl: eColorMode = ColorMode_GREYS; break;
774 }
775
776 if (maBlipProps.mxFillGraphic.is())
777 {
778 // created transformed graphic
779 uno::Reference<graphic::XGraphic> xGraphic = lclCheckAndApplyChangeColorTransform(maBlipProps, maBlipProps.mxFillGraphic, rGraphicHelper, API_RGB_TRANSPARENT);
780 xGraphic = lclCheckAndApplyDuotoneTransform(maBlipProps, xGraphic, rGraphicHelper, API_RGB_TRANSPARENT);
781
782 if( eColorMode == ColorMode_MONO )
783 {
784 // ColorMode_MONO is the same with MSO's biLevel with 50000 (50%) threshold,
785 // when threshold isn't 50000 bake the effect instead.
786 if( maBlipProps.moBiLevelThreshold != 50000 )
787 {
788 xGraphic = lclApplyBlackWhiteEffect(maBlipProps, xGraphic);
789 eColorMode = ColorMode_STANDARD;
790 }
791 }
792
793 if (eColorMode == ColorMode_STANDARD && nBrightness == 70 && nContrast == -70)
794 {
795 // map MSO 'washout' to our Watermark colormode
796 eColorMode = ColorMode_WATERMARK;
797 nBrightness = 0;
798 nContrast = 0;
799 }
800 else if( nBrightness != 0 && nContrast != 0 )
801 {
802 // MSO uses a different algorithm for contrast+brightness, LO applies contrast before brightness,
803 // while MSO apparently applies half of brightness before contrast and half after. So if only
804 // contrast or brightness need to be altered, the result is the same, but if both are involved,
805 // there's no way to map that, so just force a conversion of the image.
806 xGraphic = applyBrightnessContrast( xGraphic, nBrightness, nContrast );
807 nBrightness = 0;
808 nContrast = 0;
809 }
810
811 // cropping
812 if ( maBlipProps.moClipRect.has_value() )
813 {
814 geometry::IntegerRectangle2D oClipRect( maBlipProps.moClipRect.value() );
815 awt::Size aOriginalSize( rGraphicHelper.getOriginalSize( xGraphic ) );
816 if ( aOriginalSize.Width && aOriginalSize.Height )
817 {
818 text::GraphicCrop aGraphCrop( 0, 0, 0, 0 );
819 if ( oClipRect.X1 )
820 aGraphCrop.Left = rtl::math::round( ( static_cast< double >( aOriginalSize.Width ) * oClipRect.X1 ) / 100000 );
821 if ( oClipRect.Y1 )
822 aGraphCrop.Top = rtl::math::round( ( static_cast< double >( aOriginalSize.Height ) * oClipRect.Y1 ) / 100000 );
823 if ( oClipRect.X2 )
824 aGraphCrop.Right = rtl::math::round( ( static_cast< double >( aOriginalSize.Width ) * oClipRect.X2 ) / 100000 );
825 if ( oClipRect.Y2 )
826 aGraphCrop.Bottom = rtl::math::round( ( static_cast< double >( aOriginalSize.Height ) * oClipRect.Y2 ) / 100000 );
827 rPropMap.setProperty(PROP_GraphicCrop, aGraphCrop);
828
829 bool bHasCropValues = aGraphCrop.Left != 0 || aGraphCrop.Right !=0 || aGraphCrop.Top != 0 || aGraphCrop.Bottom != 0;
830 // Positive GraphicCrop values means "crop" here.
831 bool bNeedCrop = aGraphCrop.Left >= 0 && aGraphCrop.Right >= 0 && aGraphCrop.Top >= 0 && aGraphCrop.Bottom >= 0;
832
833 if(mbIsCustomShape && bHasCropValues && bNeedCrop)
834 {
835 xGraphic = lclCropGraphic(xGraphic, CropQuotientsFromSrcRect(oClipRect));
836 }
837 }
838 }
839
841 {
842 // it is a cropped graphic.
843 rPropMap.setProperty(PROP_FillStyle, FillStyle_BITMAP);
844 rPropMap.setProperty(PROP_FillBitmapMode, BitmapMode_STRETCH);
845
846 // It is a bitmap filled and rotated graphic.
847 // When custom shape is rotated, bitmap have to be rotated too.
848 if(rPropMap.hasProperty(PROP_RotateAngle))
849 {
850 tools::Long nAngle = rPropMap.getProperty(PROP_RotateAngle).get<tools::Long>();
851 xGraphic = lclRotateGraphic(xGraphic, Degree10(nAngle/10) );
852 }
853
854 // We have not core feature that flips graphic in the shape.
855 // Here we are applying flip property to bitmap directly.
856 if(bFlipH || bFlipV)
857 xGraphic = lclMirrorGraphic(xGraphic, bFlipH, bFlipV );
858
859 if(eColorMode == ColorMode_GREYS)
860 xGraphic = lclGreysScaleGraphic( xGraphic );
861
862 rPropMap.setProperty(PROP_FillBitmap, xGraphic);
863 }
864 else
865 rPropMap.setProperty(PROP_Graphic, xGraphic);
866
867
868 if ( maBlipProps.moAlphaModFix.has_value() )
869 {
870 rPropMap.setProperty(PROP_Transparency, static_cast<sal_Int16>(100 - (maBlipProps.moAlphaModFix.value() / PER_PERCENT)));
871 }
872 }
873 rPropMap.setProperty(PROP_GraphicColorMode, eColorMode);
874
875 // brightness and contrast
876 if( nBrightness != 0 )
877 rPropMap.setProperty(PROP_AdjustLuminance, nBrightness);
878 if( nContrast != 0 )
879 rPropMap.setProperty(PROP_AdjustContrast, nContrast);
880
881 // Media content
882 if (!m_sMediaPackageURL.isEmpty())
883 {
884 rPropMap.setProperty(PROP_MediaURL, m_sMediaPackageURL);
885 if (m_xMediaStream.is())
886 rPropMap.setProperty(PROP_PrivateStream, m_xMediaStream);
887 }
888}
889
891{
892 return msName.isEmpty();
893}
894
895css::beans::PropertyValue ArtisticEffectProperties::getEffect()
896{
897 css::beans::PropertyValue aRet;
898 if( msName.isEmpty() )
899 return aRet;
900
901 css::uno::Sequence< css::beans::PropertyValue > aSeq( maAttribs.size() + 1 );
902 auto pSeq = aSeq.getArray();
903 sal_uInt32 i = 0;
904 for (auto const& attrib : maAttribs)
905 {
906 pSeq[i].Name = attrib.first;
907 pSeq[i].Value = attrib.second;
908 i++;
909 }
910
911 if( mrOleObjectInfo.maEmbeddedData.hasElements() )
912 {
913 css::uno::Sequence< css::beans::PropertyValue > aGraphicSeq{
916 };
917
918 pSeq[i].Name = "OriginalGraphic";
919 pSeq[i].Value <<= aGraphicSeq;
920 }
921
922 aRet.Name = msName;
923 aRet.Value <<= aSeq;
924
925 return aRet;
926}
927
929{
930 if( !rSourceProps.isEmpty() )
931 {
932 msName = rSourceProps.msName;
933 maAttribs = rSourceProps.maAttribs;
934 }
935}
936
938{
939 switch( nToken )
940 {
941 // effects
942 case OOX_TOKEN( a14, artisticBlur ): return "artisticBlur";
943 case OOX_TOKEN( a14, artisticCement ): return "artisticCement";
944 case OOX_TOKEN( a14, artisticChalkSketch ): return "artisticChalkSketch";
945 case OOX_TOKEN( a14, artisticCrisscrossEtching ): return "artisticCrisscrossEtching";
946 case OOX_TOKEN( a14, artisticCutout ): return "artisticCutout";
947 case OOX_TOKEN( a14, artisticFilmGrain ): return "artisticFilmGrain";
948 case OOX_TOKEN( a14, artisticGlass ): return "artisticGlass";
949 case OOX_TOKEN( a14, artisticGlowDiffused ): return "artisticGlowDiffused";
950 case OOX_TOKEN( a14, artisticGlowEdges ): return "artisticGlowEdges";
951 case OOX_TOKEN( a14, artisticLightScreen ): return "artisticLightScreen";
952 case OOX_TOKEN( a14, artisticLineDrawing ): return "artisticLineDrawing";
953 case OOX_TOKEN( a14, artisticMarker ): return "artisticMarker";
954 case OOX_TOKEN( a14, artisticMosiaicBubbles ): return "artisticMosiaicBubbles";
955 case OOX_TOKEN( a14, artisticPaintStrokes ): return "artisticPaintStrokes";
956 case OOX_TOKEN( a14, artisticPaintBrush ): return "artisticPaintBrush";
957 case OOX_TOKEN( a14, artisticPastelsSmooth ): return "artisticPastelsSmooth";
958 case OOX_TOKEN( a14, artisticPencilGrayscale ): return "artisticPencilGrayscale";
959 case OOX_TOKEN( a14, artisticPencilSketch ): return "artisticPencilSketch";
960 case OOX_TOKEN( a14, artisticPhotocopy ): return "artisticPhotocopy";
961 case OOX_TOKEN( a14, artisticPlasticWrap ): return "artisticPlasticWrap";
962 case OOX_TOKEN( a14, artisticTexturizer ): return "artisticTexturizer";
963 case OOX_TOKEN( a14, artisticWatercolorSponge ): return "artisticWatercolorSponge";
964 case OOX_TOKEN( a14, brightnessContrast ): return "brightnessContrast";
965 case OOX_TOKEN( a14, colorTemperature ): return "colorTemperature";
966 case OOX_TOKEN( a14, saturation ): return "saturation";
967 case OOX_TOKEN( a14, sharpenSoften ): return "sharpenSoften";
968
969 // attributes
970 case XML_visible: return "visible";
971 case XML_trans: return "trans";
972 case XML_crackSpacing: return "crackSpacing";
973 case XML_pressure: return "pressure";
974 case XML_numberOfShades: return "numberOfShades";
975 case XML_grainSize: return "grainSize";
976 case XML_intensity: return "intensity";
977 case XML_smoothness: return "smoothness";
978 case XML_gridSize: return "gridSize";
979 case XML_pencilSize: return "pencilSize";
980 case XML_size: return "size";
981 case XML_brushSize: return "brushSize";
982 case XML_scaling: return "scaling";
983 case XML_detail: return "detail";
984 case XML_bright: return "bright";
985 case XML_contrast: return "contrast";
986 case XML_colorTemp: return "colorTemp";
987 case XML_sat: return "sat";
988 case XML_amount: return "amount";
989 }
990 SAL_WARN( "oox.drawingml", "ArtisticEffectProperties::getEffectString: unexpected token " << nToken );
991 return OUString();
992}
993
995{
996 // effects
997 if( sName == "artisticBlur" )
998 return XML_artisticBlur;
999 else if( sName == "artisticCement" )
1000 return XML_artisticCement;
1001 else if( sName == "artisticChalkSketch" )
1002 return XML_artisticChalkSketch;
1003 else if( sName == "artisticCrisscrossEtching" )
1004 return XML_artisticCrisscrossEtching;
1005 else if( sName == "artisticCutout" )
1006 return XML_artisticCutout;
1007 else if( sName == "artisticFilmGrain" )
1008 return XML_artisticFilmGrain;
1009 else if( sName == "artisticGlass" )
1010 return XML_artisticGlass;
1011 else if( sName == "artisticGlowDiffused" )
1012 return XML_artisticGlowDiffused;
1013 else if( sName == "artisticGlowEdges" )
1014 return XML_artisticGlowEdges;
1015 else if( sName == "artisticLightScreen" )
1016 return XML_artisticLightScreen;
1017 else if( sName == "artisticLineDrawing" )
1018 return XML_artisticLineDrawing;
1019 else if( sName == "artisticMarker" )
1020 return XML_artisticMarker;
1021 else if( sName == "artisticMosiaicBubbles" )
1022 return XML_artisticMosiaicBubbles;
1023 else if( sName == "artisticPaintStrokes" )
1024 return XML_artisticPaintStrokes;
1025 else if( sName == "artisticPaintBrush" )
1026 return XML_artisticPaintBrush;
1027 else if( sName == "artisticPastelsSmooth" )
1028 return XML_artisticPastelsSmooth;
1029 else if( sName == "artisticPencilGrayscale" )
1030 return XML_artisticPencilGrayscale;
1031 else if( sName == "artisticPencilSketch" )
1032 return XML_artisticPencilSketch;
1033 else if( sName == "artisticPhotocopy" )
1034 return XML_artisticPhotocopy;
1035 else if( sName == "artisticPlasticWrap" )
1036 return XML_artisticPlasticWrap;
1037 else if( sName == "artisticTexturizer" )
1038 return XML_artisticTexturizer;
1039 else if( sName == "artisticWatercolorSponge" )
1040 return XML_artisticWatercolorSponge;
1041 else if( sName == "brightnessContrast" )
1042 return XML_brightnessContrast;
1043 else if( sName == "colorTemperature" )
1044 return XML_colorTemperature;
1045 else if( sName == "saturation" )
1046 return XML_saturation;
1047 else if( sName == "sharpenSoften" )
1048 return XML_sharpenSoften;
1049
1050 // attributes
1051 else if( sName == "visible" )
1052 return XML_visible;
1053 else if( sName == "trans" )
1054 return XML_trans;
1055 else if( sName == "crackSpacing" )
1056 return XML_crackSpacing;
1057 else if( sName == "pressure" )
1058 return XML_pressure;
1059 else if( sName == "numberOfShades" )
1060 return XML_numberOfShades;
1061 else if( sName == "grainSize" )
1062 return XML_grainSize;
1063 else if( sName == "intensity" )
1064 return XML_intensity;
1065 else if( sName == "smoothness" )
1066 return XML_smoothness;
1067 else if( sName == "gridSize" )
1068 return XML_gridSize;
1069 else if( sName == "pencilSize" )
1070 return XML_pencilSize;
1071 else if( sName == "size" )
1072 return XML_size;
1073 else if( sName == "brushSize" )
1074 return XML_brushSize;
1075 else if( sName == "scaling" )
1076 return XML_scaling;
1077 else if( sName == "detail" )
1078 return XML_detail;
1079 else if( sName == "bright" )
1080 return XML_bright;
1081 else if( sName == "contrast" )
1082 return XML_contrast;
1083 else if( sName == "colorTemp" )
1084 return XML_colorTemp;
1085 else if( sName == "sat" )
1086 return XML_sat;
1087 else if( sName == "amount" )
1088 return XML_amount;
1089
1090 SAL_WARN( "oox.drawingml", "ArtisticEffectProperties::getEffectToken - unexpected token name: " << sName );
1091 return XML_none;
1092}
1093
1094} // namespace oox
1095
1096/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XPropertyListType t
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 tryToRecreateBorder(basegfx::BColorStops *pAssociatedTransparencyStops=nullptr)
void SetGradientStyle(css::awt::GradientStyle eNewStyle)
void SetColorStops(const basegfx::BColorStops &rSteps)
void SetYOffset(sal_uInt16 nNewOffset)
void SetXOffset(sal_uInt16 nNewOffset)
sal_uInt16 GetXOffset() const
css::awt::Gradient2 getAsGradient2() const
css::awt::GradientStyle GetGradientStyle() const
void SetAngle(Degree10 nNewAngle)
sal_uInt16 GetYOffset() const
void setSchemeColor(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.
Definition: propertymap.hxx:52
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.
Definition: propertymap.hxx:72
sal_Int16 getTransparency() const
Returns the transparency of the color (0 = opaque, 100 = full transparent).
Definition: color.cxx:804
void assignIfUsed(const Color &rColor)
Overwrites this color with the passed color, if it is used.
Definition: color.hxx:89
bool isUsed() const
Returns true, if the color is initialized.
Definition: color.hxx:92
model::ComplexColor getComplexColor() const
Definition: color.cxx:620
bool hasTransparency() const
Returns true, if the color is transparent.
Definition: color.cxx:799
::Color getColor(const GraphicHelper &rGraphicHelper, ::Color nPhClr=API_RGB_TRANSPARENT) const
Returns the final RGB color value.
Definition: color.cxx:644
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.
OString sName
Definition: drawingml.cxx:4451
static drawing::Hatch createHatch(sal_Int32 nHatchToken, ::Color nColor)
Definition: hatchmap.hxx:18
BmpMirrorFlags
Sequence< sal_Int8 > aSeq
#define SAL_WARN(area, stream)
enum SAL_DLLPUBLIC_RTTI FillStyle
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
uno::Reference< util::XComplexColor > createXComplexColor(model::ComplexColor const &rColor)
constexpr ThemeColorType convertToThemeColorType(sal_Int32 nIndex)
BitmapMode
@ FillBitmap
Explicit fill bitmap or name of a fill bitmap stored in a global container.
@ 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)
Definition: helper.hxx:174
const ::Color API_RGB_TRANSPARENT(ColorTransparency, 0xffffffff)
Transparent color for API calls.
XML_none
long Long
XML_TOKEN_INVALID
DefTokenId nToken
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.
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.
unsigned char sal_uInt8
#define SAL_MAX_INT32
signed char sal_Int8
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_GraphicCrop
constexpr OUStringLiteral PROP_FillComplexColor
constexpr OUStringLiteral PROP_FillStyle