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 <sdr/primitive2d/sdrattributecreator.hxx>
21 #include <svl/itemset.hxx>
22 #include <svx/sdmetitm.hxx>
23 #include <svx/sdooitm.hxx>
24 #include <svx/sdprcitm.hxx>
25 #include <svx/xdef.hxx>
26 #include <basegfx/polygon/b2dpolygon.hxx>
27 #include <svx/xlineit0.hxx>
28 #include <svx/xfillit0.hxx>
29 #include <svx/xflbmpit.hxx>
30 #include <svx/xlntrit.hxx>
31 #include <svx/xlnwtit.hxx>
32 #include <svx/xlinjoit.hxx>
33 #include <svx/xlncapit.hxx>
34 #include <svx/xlnclit.hxx>
35 #include <svx/xlnstwit.hxx>
36 #include <svx/xlnedwit.hxx>
37 #include <svx/xlnstit.hxx>
38 #include <svx/xlnstcit.hxx>
39 #include <svx/xlnedit.hxx>
40 #include <svx/xlnedcit.hxx>
41 #include <svx/xdash.hxx>
42 #include <svx/xlndsit.hxx>
43 #include <svx/xfilluseslidebackgrounditem.hxx>
44 #include <svx/xfltrit.hxx>
45 #include <svx/xflftrit.hxx>
46 #include <svx/xflclit.hxx>
47 #include <svx/xgrscit.hxx>
48 #include <svx/xflhtit.hxx>
49 #include <svx/xflbckit.hxx>
50 #include <svx/xflbmsxy.hxx>
51 #include <svx/xflbtoxy.hxx>
52 #include <svx/xflboxy.hxx>
53 #include <svx/xflbmtit.hxx>
54 #include <svx/xflbstit.hxx>
55 #include <svx/xtextit0.hxx>
56 #include <svx/RectangleAlignmentItem.hxx>
57 #include <drawinglayer/attribute/sdrfillgraphicattribute.hxx>
58 #include <svx/svdotext.hxx>
59 #include <sdr/attribute/sdrtextattribute.hxx>
60 #include <svx/xbtmpit.hxx>
61 #include <svl/itempool.hxx>
62 #include <vcl/svapp.hxx>
63 #include <vcl/GraphicLoader.hxx>
64 #include <basegfx/range/b2drange.hxx>
65 #include <svx/svx3ditems.hxx>
66 #include <com/sun/star/drawing/ProjectionMode.hpp>
67 #include <com/sun/star/drawing/ShadeMode.hpp>
68 #include <drawinglayer/attribute/sdrallattribute3d.hxx>
69 #include <svx/rectenum.hxx>
70 #include <svx/sdtfchim.hxx>
71 #include <svx/svdoutl.hxx>
72 #include <svx/svdmodel.hxx>
73 #include <svx/xflbmsli.hxx>
74 #include <editeng/editstat.hxx>
75 #include <editeng/eeitem.hxx>
76 #include <editeng/fhgtitem.hxx>
77 #include <editeng/editobj.hxx>
78 #include <osl/diagnose.h>
79 #include <drawinglayer/attribute/fillhatchattribute.hxx>
80 #include <drawinglayer/attribute/fillgradientattribute.hxx>
81 #include <sdr/attribute/sdreffectstextattribute.hxx>
82 #include <sdr/attribute/sdrlineeffectstextattribute.hxx>
83 #include <sdr/attribute/sdrformtextattribute.hxx>
84 #include <sdr/attribute/sdrlinefilleffectstextattribute.hxx>
85 #include <drawinglayer/attribute/sdrglowattribute.hxx>
86 #include <drawinglayer/attribute/sdrglowtextattribute.hxx>
87 #include <drawinglayer/attribute/sdrsceneattribute3d.hxx>
88 #include <drawinglayer/attribute/sdrlightingattribute3d.hxx>
89 #include <drawinglayer/attribute/sdrlightattribute3d.hxx>
90 #include <sdr/attribute/sdrfilltextattribute.hxx>
91 #include <com/sun/star/drawing/LineCap.hpp>
95 using namespace com::sun::star
;
97 namespace drawinglayer
101 attribute::HatchStyle
XHatchStyleToHatchStyle(css::drawing::HatchStyle eStyle
)
105 case css::drawing::HatchStyle_SINGLE
:
107 return attribute::HatchStyle::Single
;
109 case css::drawing::HatchStyle_DOUBLE
:
111 return attribute::HatchStyle::Double
;
115 return attribute::HatchStyle::Triple
; // css::drawing::HatchStyle_TRIPLE
120 basegfx::B2DLineJoin
LineJointToB2DLineJoin(css::drawing::LineJoint eLineJoint
)
124 case css::drawing::LineJoint_BEVEL
:
126 return basegfx::B2DLineJoin::Bevel
;
128 case css::drawing::LineJoint_MIDDLE
:
129 case css::drawing::LineJoint_MITER
:
131 return basegfx::B2DLineJoin::Miter
;
133 case css::drawing::LineJoint_ROUND
:
135 return basegfx::B2DLineJoin::Round
;
137 default : // css::drawing::LineJoint_NONE
139 return basegfx::B2DLineJoin::NONE
;
144 basegfx::B2DVector
RectPointToB2DVector(RectPoint eRectPoint
)
146 basegfx::B2DVector
aRetval(0.0, 0.0);
148 // position changes X
151 case RectPoint::LT
: case RectPoint::LM
: case RectPoint::LB
:
157 case RectPoint::RT
: case RectPoint::RM
: case RectPoint::RB
:
169 // position changes Y
172 case RectPoint::LT
: case RectPoint::MT
: case RectPoint::RT
:
178 case RectPoint::LB
: case RectPoint::MB
: case RectPoint::RB
:
193 attribute::SdrGlowAttribute
createNewSdrGlowAttribute(const SfxItemSet
& rSet
)
195 sal_Int32 nRadius
= rSet
.Get(SDRATTR_GLOW_RADIUS
).GetValue();
198 return attribute::SdrGlowAttribute();
200 Color
aColor(rSet
.Get(SDRATTR_GLOW_COLOR
).GetColorValue());
202 sal_uInt16
nTransparency(rSet
.Get(SDRATTR_GLOW_TRANSPARENCY
).GetValue());
204 aColor
.SetAlpha(255 - std::round(nTransparency
/ 100.0 * 255.0));
206 attribute::SdrGlowAttribute glowAttr
{ nRadius
, aColor
};
210 attribute::SdrGlowTextAttribute
createNewSdrGlowTextAttribute(const SfxItemSet
& rSet
, const OutlinerParaObject
* pOutliner
)
212 sal_Int32 nTextRadius
= rSet
.Get(SDRATTR_GLOW_TEXT_RADIUS
).GetValue();
215 return attribute::SdrGlowTextAttribute();
217 Color
aTextColor(rSet
.Get(SDRATTR_GLOW_TEXT_COLOR
).GetColorValue());
219 sal_uInt16
nTextTransparency(rSet
.Get(SDRATTR_GLOW_TEXT_TRANSPARENCY
).GetValue());
220 if (nTextTransparency
)
221 aTextColor
.SetAlpha(255 - std::round(nTextTransparency
/ 100.0 * 255.0));
223 // calculate rendering text glow radius from biggest Char size for the full text in shape
224 double nRadius
= 0.0;
225 sal_uInt32 nFontSize
= 0;
226 if (const SvxFontHeightItem
* pItem
= rSet
.GetItemIfSet(EE_CHAR_FONTHEIGHT
))
227 nFontSize
= pItem
->GetHeight();
231 const EditTextObject
& aEdit
= pOutliner
->GetTextObject();
232 for (sal_Int32 i
= 0; i
< aEdit
.GetParagraphCount(); i
++)
234 std::vector
<EECharAttrib
> aAttribs
;
235 aEdit
.GetCharAttribs(i
, aAttribs
);
236 for (const auto& attrib
: aAttribs
)
238 if (const SvxFontHeightItem
* pFontHeight
= dynamic_cast<const SvxFontHeightItem
*>(attrib
.pAttr
))
240 if (nFontSize
< pFontHeight
->GetHeight())
241 nFontSize
= pFontHeight
->GetHeight();
249 // Rendering_glow_size = Original_glow_size / (154.39 * FontSize ^ -0,575)
250 // This is an approximate calculation similar to MSO text glow size which is
251 // depending on font size
252 nRadius
= nTextRadius
/ (154.39 * pow(nFontSize
, -0.575));
253 nTextRadius
= std::round(nRadius
);
256 attribute::SdrGlowTextAttribute glowTextAttr
{ nTextRadius
, aTextColor
};
260 sal_Int32
getSoftEdgeRadius(const SfxItemSet
& rSet
)
262 return rSet
.Get(SDRATTR_SOFTEDGE_RADIUS
).GetValue();
264 } // end of anonymous namespace
265 } // end of namespace drawinglayer
268 namespace drawinglayer::primitive2d
270 attribute::SdrLineAttribute
createNewSdrLineAttribute(const SfxItemSet
& rSet
)
272 const css::drawing::LineStyle
eStyle(rSet
.Get(XATTR_LINESTYLE
).GetValue());
274 if(drawing::LineStyle_NONE
!= eStyle
)
276 sal_uInt16
nTransparence(rSet
.Get(XATTR_LINETRANSPARENCE
).GetValue());
278 if(nTransparence
> 100)
283 if(100 != nTransparence
)
285 const sal_uInt32
nWidth(rSet
.Get(XATTR_LINEWIDTH
).GetValue());
286 const Color
aColor(rSet
.Get(XATTR_LINECOLOR
).GetColorValue());
287 const css::drawing::LineJoint
eJoint(rSet
.Get(XATTR_LINEJOINT
).GetValue());
288 const css::drawing::LineCap
eCap(rSet
.Get(XATTR_LINECAP
).GetValue());
289 ::std::vector
< double > aDotDashArray
;
290 double fFullDotDashLen(0.0);
292 if(drawing::LineStyle_DASH
== eStyle
)
294 const XDash
& rDash
= rSet
.Get(XATTR_LINEDASH
).GetDashValue();
296 if(rDash
.GetDots() || rDash
.GetDashes())
298 fFullDotDashLen
= rDash
.CreateDotDashArray(aDotDashArray
, static_cast<double>(nWidth
));
302 return attribute::SdrLineAttribute(
303 LineJointToB2DLineJoin(eJoint
),
304 static_cast<double>(nWidth
),
305 static_cast<double>(nTransparence
) * 0.01,
308 std::move(aDotDashArray
),
313 return attribute::SdrLineAttribute();
316 attribute::SdrLineStartEndAttribute
createNewSdrLineStartEndAttribute(
317 const SfxItemSet
& rSet
,
320 const sal_Int32
nTempStartWidth(rSet
.Get(XATTR_LINESTARTWIDTH
).GetValue());
321 const sal_Int32
nTempEndWidth(rSet
.Get(XATTR_LINEENDWIDTH
).GetValue());
322 basegfx::B2DPolyPolygon aStartPolyPolygon
;
323 basegfx::B2DPolyPolygon aEndPolyPolygon
;
324 double fStartWidth(0.0);
325 double fEndWidth(0.0);
326 bool bStartActive(false);
327 bool bEndActive(false);
328 bool bStartCentered(true);
329 bool bEndCentered(true);
333 if(nTempStartWidth
< 0)
335 fStartWidth
= (static_cast<double>(-nTempStartWidth
) * fWidth
) * 0.01;
339 fStartWidth
= static_cast<double>(nTempStartWidth
);
342 if(0.0 != fStartWidth
)
344 aStartPolyPolygon
= rSet
.Get(XATTR_LINESTART
).GetLineStartValue();
346 if(aStartPolyPolygon
.count() && aStartPolyPolygon
.getB2DPolygon(0).count())
349 bStartCentered
= rSet
.Get(XATTR_LINESTARTCENTER
).GetValue();
356 if(nTempEndWidth
< 0)
358 fEndWidth
= (static_cast<double>(-nTempEndWidth
) * fWidth
) * 0.01;
362 fEndWidth
= static_cast<double>(nTempEndWidth
);
367 aEndPolyPolygon
= rSet
.Get(XATTR_LINEEND
).GetLineEndValue();
369 if(aEndPolyPolygon
.count() && aEndPolyPolygon
.getB2DPolygon(0).count())
372 bEndCentered
= rSet
.Get(XATTR_LINEENDCENTER
).GetValue();
377 if(bStartActive
|| bEndActive
)
379 return attribute::SdrLineStartEndAttribute(
380 aStartPolyPolygon
, aEndPolyPolygon
, fStartWidth
, fEndWidth
,
381 bStartActive
, bEndActive
, bStartCentered
, bEndCentered
);
384 return attribute::SdrLineStartEndAttribute();
387 attribute::SdrShadowAttribute
createNewSdrShadowAttribute(const SfxItemSet
& rSet
)
389 const bool bShadow(rSet
.Get(SDRATTR_SHADOW
).GetValue());
393 sal_uInt16
nTransparence(rSet
.Get(SDRATTR_SHADOWTRANSPARENCE
).GetValue());
395 if(nTransparence
> 100)
402 sal_uInt16
nFillTransparence(rSet
.Get(XATTR_FILLTRANSPARENCE
).GetValue());
404 if(nFillTransparence
> 100)
406 nFillTransparence
= 100;
409 if(nTransparence
== nFillTransparence
)
411 // shadow does not really have an own transparence, but the application
412 // sets the shadow transparence equal to the object transparence for
413 // convenience. This is not useful for primitive creation, so take
414 // this as no shadow transparence
419 if(100 != nTransparence
)
421 const basegfx::B2DVector
aOffset(
422 static_cast<double>(rSet
.Get(SDRATTR_SHADOWXDIST
).GetValue()),
423 static_cast<double>(rSet
.Get(SDRATTR_SHADOWYDIST
).GetValue()));
425 const basegfx::B2DVector
aSize(
426 static_cast<double>(rSet
.Get(SDRATTR_SHADOWSIZEX
).GetValue()),
427 static_cast<double>(rSet
.Get(SDRATTR_SHADOWSIZEY
).GetValue()));
429 const Color
aColor(rSet
.Get(SDRATTR_SHADOWCOLOR
).GetColorValue());
431 sal_Int32
nBlur(rSet
.Get(SDRATTR_SHADOWBLUR
).GetValue());
433 model::RectangleAlignment eAlignment
{rSet
.Get(SDRATTR_SHADOWALIGNMENT
).GetValue()};
435 return attribute::SdrShadowAttribute(aOffset
, aSize
, static_cast<double>(nTransparence
) * 0.01, nBlur
, eAlignment
, aColor
.getBColor());
439 return attribute::SdrShadowAttribute();
442 attribute::SdrFillAttribute
createNewSdrFillAttribute(const SfxItemSet
& rSet
)
444 const drawing::FillStyle
eStyle(rSet
.Get(XATTR_FILLSTYLE
).GetValue());
446 sal_uInt16
nTransparence(rSet
.Get(XATTR_FILLTRANSPARENCE
).GetValue());
448 if(nTransparence
> 100)
453 if(drawing::FillStyle_NONE
== eStyle
)
455 const XFillUseSlideBackgroundItem
& aBckItem(rSet
.Get(XATTR_FILLUSESLIDEBACKGROUND
));
456 const bool bSlideBackgroundFill(aBckItem
.GetValue());
458 if(bSlideBackgroundFill
)
460 // we have SlideBackgroundFill mode, create a
461 // SdrFillAttribute accordingly
462 return attribute::SdrFillAttribute(true);
466 if(drawing::FillStyle_NONE
!= eStyle
)
468 if(100 != nTransparence
)
470 // need to check XFillFloatTransparence, object fill may still be completely transparent
471 const XFillFloatTransparenceItem
* pGradientItem
;
473 if((pGradientItem
= rSet
.GetItemIfSet(XATTR_FILLFLOATTRANSPARENCE
, true))
474 && pGradientItem
->IsEnabled())
476 const basegfx::BGradient
& rGradient
= pGradientItem
->GetGradientValue();
477 basegfx::BColor aSingleColor
;
478 const bool bSingleColor(rGradient
.GetColorStops().isSingleColor(aSingleColor
));
479 const bool bCompletelyTransparent(bSingleColor
&& basegfx::fTools::equal(aSingleColor
.luminance(), 1.0));
481 if(bCompletelyTransparent
)
488 if(100 != nTransparence
)
490 const Color
aColor(rSet
.Get(XATTR_FILLCOLOR
).GetColorValue());
491 attribute::FillGradientAttribute aGradient
;
492 attribute::FillHatchAttribute aHatch
;
493 attribute::SdrFillGraphicAttribute aFillGraphic
;
499 // nothing to do, color is defined
502 case drawing::FillStyle_GRADIENT
:
504 basegfx::BGradient
aBGradient(rSet
.Get(XATTR_FILLGRADIENT
).GetGradientValue());
505 basegfx::BColorStops
aColorStops(aBGradient
.GetColorStops());
508 if (aBGradient
.GetStartIntens() != 100 || aBGradient
.GetEndIntens() != 100)
510 // Need to do the (old, crazy) blend against black for a
511 // used intensity, but now for all ColorStops relative to their
512 // offsets, where 0 means black and 100 means original color
513 aColorStops
.blendToIntensity(
514 aBGradient
.GetStartIntens() * 0.01,
515 aBGradient
.GetEndIntens() * 0.01,
516 basegfx::BColor()); // COL_BLACK
519 aGradient
= attribute::FillGradientAttribute(
520 aBGradient
.GetGradientStyle(),
521 static_cast<double>(aBGradient
.GetBorder()) * 0.01,
522 static_cast<double>(aBGradient
.GetXOffset()) * 0.01,
523 static_cast<double>(aBGradient
.GetYOffset()) * 0.01,
524 toRadians(aBGradient
.GetAngle()),
526 rSet
.Get(XATTR_GRADIENTSTEPCOUNT
).GetValue());
530 case drawing::FillStyle_HATCH
:
532 const XHatch
& rHatch(rSet
.Get(XATTR_FILLHATCH
).GetHatchValue());
533 const Color
aColorB(rHatch
.GetColor());
535 aHatch
= attribute::FillHatchAttribute(
536 XHatchStyleToHatchStyle(rHatch
.GetHatchStyle()),
537 static_cast<double>(rHatch
.GetDistance()),
538 toRadians(rHatch
.GetAngle()),
540 3, // same default as VCL, a minimum of three discrete units (pixels) offset
541 rSet
.Get(XATTR_FILLBACKGROUND
).GetValue());
545 case drawing::FillStyle_BITMAP
:
547 aFillGraphic
= createNewSdrFillGraphicAttribute(rSet
);
552 return attribute::SdrFillAttribute(
553 static_cast<double>(nTransparence
) * 0.01,
561 if(nTransparence
== 100)
563 attribute::FillGradientAttribute aGradient
;
564 attribute::FillHatchAttribute aHatch
;
565 attribute::SdrFillGraphicAttribute aFillGraphic
;
566 return attribute::SdrFillAttribute(
568 basegfx::BColor( 0, 0, 0 ),
574 return attribute::SdrFillAttribute();
577 // #i101508# Support handing over given text-to-border distances
578 attribute::SdrTextAttribute
createNewSdrTextAttribute(
579 const SfxItemSet
& rSet
,
580 const SdrText
& rText
,
581 const sal_Int32
* pLeft
,
582 const sal_Int32
* pUpper
,
583 const sal_Int32
* pRight
,
584 const sal_Int32
* pLower
)
586 const SdrTextObj
& rTextObj
= rText
.GetObject();
588 // Save chaining attributes
589 bool bChainable
= rTextObj
.IsChainable();
591 // get OutlinerParaObject
592 std::optional
<OutlinerParaObject
> aOutlinerParaObject
;
594 // 1st try to get from rText
595 if(rText
.GetOutlinerParaObject())
597 aOutlinerParaObject
.emplace(*rText
.GetOutlinerParaObject());
600 // added TextEdit text suppression - check if rText is in EditMode
601 bool bInEditMode(false);
603 if(rText
.GetObject().getTextCount() > 1)
605 bInEditMode
= rTextObj
.IsInEditMode() && rText
.GetObject().getActiveText() == &rText
;
609 bInEditMode
= rTextObj
.IsInEditMode();
614 // if yes, try to get OutlinerParaObject from active TextEdit
615 std::optional
<OutlinerParaObject
> aTextEditOutlinerParaObject(rTextObj
.CreateEditOutlinerParaObject());
617 if (aTextEditOutlinerParaObject
)
619 // if we got one, prefer text from active TextEdit
620 aOutlinerParaObject
= std::move(aTextEditOutlinerParaObject
);
624 if(aOutlinerParaObject
)
626 const SdrTextAniKind
eAniKind(rTextObj
.GetTextAniKind());
629 const SdrOutliner
& rDrawTextOutliner(rText
.GetObject().getSdrModelFromSdrObject().GetDrawOutliner(&rTextObj
));
630 const bool bWrongSpell(rDrawTextOutliner
.GetControlWord() & EEControlBits::ONLINESPELLING
);
632 return attribute::SdrTextAttribute(
634 *aOutlinerParaObject
,
635 rSet
.Get(XATTR_FORMTXTSTYLE
).GetValue(),
636 pLeft
? *pLeft
: rTextObj
.GetTextLeftDistance(),
637 pUpper
? *pUpper
: rTextObj
.GetTextUpperDistance(),
638 pRight
? *pRight
: rTextObj
.GetTextRightDistance(),
639 pLower
? *pLower
: rTextObj
.GetTextLowerDistance(),
640 rTextObj
.GetTextHorizontalAdjust(rSet
),
641 rTextObj
.GetTextVerticalAdjust(rSet
),
642 rSet
.Get(SDRATTR_TEXT_CONTOURFRAME
).GetValue(),
643 rTextObj
.IsFitToSize(),
644 rTextObj
.IsAutoFit(),
645 rSet
.Get(XATTR_FORMTXTHIDEFORM
).GetValue(),
646 SdrTextAniKind::Blink
== eAniKind
,
647 SdrTextAniKind::Scroll
== eAniKind
|| SdrTextAniKind::Alternate
== eAniKind
|| SdrTextAniKind::Slide
== eAniKind
,
649 rSet
.Get(SDRATTR_TEXT_USEFIXEDCELLHEIGHT
).GetValue(),
654 return attribute::SdrTextAttribute();
657 attribute::FillGradientAttribute
createNewTransparenceGradientAttribute(const SfxItemSet
& rSet
)
659 const XFillFloatTransparenceItem
* pGradientItem
;
661 if((pGradientItem
= rSet
.GetItemIfSet(XATTR_FILLFLOATTRANSPARENCE
))
662 && pGradientItem
->IsEnabled())
664 // test if float transparency is completely transparent
665 const basegfx::BGradient
& rGradient(pGradientItem
->GetGradientValue());
666 basegfx::BColor aSingleColor
;
667 const bool bSingleColor(rGradient
.GetColorStops().isSingleColor(aSingleColor
));
668 const bool bCompletelyTransparent(bSingleColor
&& basegfx::fTools::equal(aSingleColor
.luminance(), 1.0));
669 const bool bNotTransparent(bSingleColor
&& basegfx::fTools::equalZero(aSingleColor
.luminance()));
671 // create nothing when completely transparent: This case is already checked for the
672 // normal fill attributes, XFILL_NONE will be used.
673 // create nothing when not transparent: use normal fill, no need t create a FillGradientAttribute.
674 // Both cases are optimizations, always creating FillGradientAttribute will work, too
675 if (!bNotTransparent
&& !bCompletelyTransparent
)
677 basegfx::BColorStops
aColorStops(rGradient
.GetColorStops());
679 if (rGradient
.GetStartIntens() != 100 || rGradient
.GetEndIntens() != 100)
681 // tdf#155913 Start/EndIntens is not used for transparency gradient,
682 // so might even get asserted (?)
683 // this may also be set for transparence, so need to take care of it
684 aColorStops
.blendToIntensity(
685 rGradient
.GetStartIntens() * 0.01,
686 rGradient
.GetEndIntens() * 0.01,
687 basegfx::BColor()); // COL_BLACK
690 // tdf#155913 GradientStepCount is not used for transparency gradient
691 return attribute::FillGradientAttribute(
692 rGradient
.GetGradientStyle(),
693 static_cast<double>(rGradient
.GetBorder()) * 0.01,
694 static_cast<double>(rGradient
.GetXOffset()) * 0.01,
695 static_cast<double>(rGradient
.GetYOffset()) * 0.01,
696 toRadians(rGradient
.GetAngle()),
701 return attribute::FillGradientAttribute();
704 attribute::SdrFillGraphicAttribute
createNewSdrFillGraphicAttribute(const SfxItemSet
& rSet
)
706 Graphic
aGraphic(rSet
.Get(XATTR_FILLBITMAP
).GetGraphicObject().GetGraphic());
708 OUString aOriginURL
= aGraphic
.getOriginURL();
709 if (aGraphic
.GetType() == GraphicType::Default
&& !aOriginURL
.isEmpty())
711 aGraphic
= vcl::graphic::loadFromURL(aGraphic
.getOriginURL());
712 aGraphic
.setOriginURL(aOriginURL
);
715 if(GraphicType::Bitmap
!= aGraphic
.GetType() && GraphicType::GdiMetafile
!= aGraphic
.GetType())
717 // no content if not bitmap or metafile
718 OSL_ENSURE(false, "No fill graphic in SfxItemSet (!)");
719 return attribute::SdrFillGraphicAttribute();
722 Size
aPrefSize(aGraphic
.GetPrefSize());
724 if(!aPrefSize
.Width() || !aPrefSize
.Height())
726 // if there is no logical size, create a size from pixel size and set MapMode accordingly
727 if(GraphicType::Bitmap
== aGraphic
.GetType())
729 aGraphic
.SetPrefSize(aGraphic
.GetBitmapEx().GetSizePixel());
730 aGraphic
.SetPrefMapMode(MapMode(MapUnit::MapPixel
));
731 aPrefSize
= aGraphic
.GetPrefSize();
735 if(!aPrefSize
.Width() || !aPrefSize
.Height())
737 // no content if no size
738 OSL_ENSURE(false, "Graphic has no size in SfxItemSet (!)");
739 return attribute::SdrFillGraphicAttribute();
742 // convert size and MapMode to destination logical size and MapMode
743 const MapUnit
aDestinationMapUnit(rSet
.GetPool()->GetMetric(0));
744 basegfx::B2DVector
aGraphicLogicSize(aGraphic
.GetPrefSize().Width(), aGraphic
.GetPrefSize().Height());
746 if (aGraphic
.GetPrefMapMode().GetMapUnit() != aDestinationMapUnit
)
748 // #i100360# for MapUnit::MapPixel, LogicToLogic will not work properly,
749 // so fallback to Application::GetDefaultDevice()
752 if(MapUnit::MapPixel
== aGraphic
.GetPrefMapMode().GetMapUnit())
754 aNewSize
= Application::GetDefaultDevice()->PixelToLogic(
755 aGraphic
.GetPrefSize(),
756 MapMode(aDestinationMapUnit
));
760 aNewSize
= OutputDevice::LogicToLogic(
761 aGraphic
.GetPrefSize(),
762 aGraphic
.GetPrefMapMode(),
763 MapMode(aDestinationMapUnit
));
766 // #i124002# do not set new size using SetPrefSize at the graphic, this will lead to problems.
767 // Instead, adapt the GraphicLogicSize which will be used for further decompositions
768 aGraphicLogicSize
= basegfx::B2DVector(aNewSize
.Width(), aNewSize
.Height());
772 const basegfx::B2DVector
aSize(
773 static_cast<double>(rSet
.Get(XATTR_FILLBMP_SIZEX
).GetValue()),
774 static_cast<double>(rSet
.Get(XATTR_FILLBMP_SIZEY
).GetValue()));
775 const basegfx::B2DVector
aOffset(
776 static_cast<double>(rSet
.Get(XATTR_FILLBMP_TILEOFFSETX
).GetValue()),
777 static_cast<double>(rSet
.Get(XATTR_FILLBMP_TILEOFFSETY
).GetValue()));
778 const basegfx::B2DVector
aOffsetPosition(
779 static_cast<double>(rSet
.Get(XATTR_FILLBMP_POSOFFSETX
).GetValue()),
780 static_cast<double>(rSet
.Get(XATTR_FILLBMP_POSOFFSETY
).GetValue()));
782 return attribute::SdrFillGraphicAttribute(
788 RectPointToB2DVector(rSet
.GetItem
<XFillBmpPosItem
>(XATTR_FILLBMP_POS
)->GetValue()),
789 rSet
.Get(XATTR_FILLBMP_TILE
).GetValue(),
790 rSet
.Get(XATTR_FILLBMP_STRETCH
).GetValue(),
791 rSet
.Get(XATTR_FILLBMP_SIZELOG
).GetValue());
794 attribute::SdrEffectsTextAttribute
createNewSdrEffectsTextAttribute(
795 const SfxItemSet
& rSet
,
796 const SdrText
* pText
,
799 attribute::SdrTextAttribute aText
;
801 // #i98072# added option to suppress text
802 // look for text first
803 if(!bSuppressText
&& pText
)
805 aText
= createNewSdrTextAttribute(rSet
, *pText
);
809 const attribute::SdrShadowAttribute
aShadow(createNewSdrShadowAttribute(rSet
));
810 const attribute::SdrGlowAttribute
aGlow(createNewSdrGlowAttribute(rSet
));
811 const OutlinerParaObject
* pOutliner
= pText
? pText
->GetObject().GetOutlinerParaObject() : nullptr;
812 const attribute::SdrGlowTextAttribute
aGlowText(createNewSdrGlowTextAttribute(rSet
, pOutliner
));
813 const sal_Int32
nSoftEdgeRadius(getSoftEdgeRadius(rSet
));
815 return attribute::SdrEffectsTextAttribute(aShadow
, std::move(aText
),
816 aGlow
, aGlowText
, nSoftEdgeRadius
);
819 attribute::SdrLineEffectsTextAttribute
createNewSdrLineEffectsTextAttribute(
820 const SfxItemSet
& rSet
,
821 const SdrText
* pText
)
823 attribute::SdrLineAttribute aLine
;
824 attribute::SdrLineStartEndAttribute aLineStartEnd
;
825 attribute::SdrTextAttribute aText
;
826 bool bFontworkHideContour(false);
828 // look for text first
831 aText
= createNewSdrTextAttribute(rSet
, *pText
);
833 // when object has text and text is fontwork and hide contour is set for fontwork, force
834 // line and fill style to empty
835 if(!aText
.isDefault()
836 && !aText
.getSdrFormTextAttribute().isDefault()
837 && aText
.isHideContour())
839 bFontworkHideContour
= true;
844 if(!bFontworkHideContour
)
846 aLine
= createNewSdrLineAttribute(rSet
);
848 if(!aLine
.isDefault())
851 aLineStartEnd
= createNewSdrLineStartEndAttribute(rSet
, aLine
.getWidth());
855 if(!aLine
.isDefault() || !aText
.isDefault())
858 attribute::SdrShadowAttribute
aShadow(createNewSdrShadowAttribute(rSet
));
859 attribute::SdrGlowAttribute aGlow
= createNewSdrGlowAttribute(rSet
);
860 const OutlinerParaObject
* pOutliner
= pText
? pText
->GetObject().GetOutlinerParaObject() : nullptr;
861 attribute::SdrGlowTextAttribute aGlowText
= createNewSdrGlowTextAttribute(rSet
, pOutliner
);
862 const sal_Int32
nSoftEdgeRadius(getSoftEdgeRadius(rSet
));
864 return attribute::SdrLineEffectsTextAttribute(std::move(aLine
),
865 std::move(aLineStartEnd
),
869 std::move(aGlowText
), nSoftEdgeRadius
);
872 return attribute::SdrLineEffectsTextAttribute();
875 attribute::SdrLineFillEffectsTextAttribute
createNewSdrLineFillEffectsTextAttribute(
876 const SfxItemSet
& rSet
,
877 const SdrText
* pText
,
879 bool bSuppressShadow
)
881 attribute::SdrLineAttribute aLine
;
882 attribute::SdrFillAttribute aFill
;
883 attribute::SdrLineStartEndAttribute aLineStartEnd
;
884 attribute::FillGradientAttribute aFillFloatTransGradient
;
885 attribute::SdrTextAttribute aText
;
886 bool bFontworkHideContour(false);
888 // look for text first
891 aText
= createNewSdrTextAttribute(rSet
, *pText
);
893 // when object has text and text is fontwork and hide contour is set for fontwork, force
894 // line and fill style to empty
895 if(!aText
.getSdrFormTextAttribute().isDefault() && aText
.isHideContour())
897 bFontworkHideContour
= true;
901 if(!bFontworkHideContour
)
904 aLine
= createNewSdrLineAttribute(rSet
);
906 if(!aLine
.isDefault())
909 aLineStartEnd
= createNewSdrLineStartEndAttribute(rSet
, aLine
.getWidth());
913 aFill
= createNewSdrFillAttribute(rSet
);
915 if(!aFill
.isDefault())
917 // try fillfloattransparence
918 aFillFloatTransGradient
= createNewTransparenceGradientAttribute(rSet
);
922 // bHasContent is used from OLE and graphic objects. Normally a possible shadow
923 // depends on line, fill or text to be set, but for these objects it is possible
924 // to have none of these, but still content which needs to have a shadow (if set),
925 // so shadow needs to be tried
926 if(bHasContent
|| !aLine
.isDefault() || !aFill
.isDefault() || !aText
.isDefault())
929 const attribute::SdrShadowAttribute aShadow
= !bSuppressShadow
?
930 createNewSdrShadowAttribute(rSet
) : attribute::SdrShadowAttribute();
933 const attribute::SdrGlowAttribute aGlow
= createNewSdrGlowAttribute(rSet
);
936 const OutlinerParaObject
* pOutliner
= pText
? pText
->GetObject().GetOutlinerParaObject() : nullptr;
937 const attribute::SdrGlowTextAttribute aGlowText
= createNewSdrGlowTextAttribute(rSet
, pOutliner
);
939 const sal_Int32
nSoftEdgeRadius(getSoftEdgeRadius(rSet
));
941 return attribute::SdrLineFillEffectsTextAttribute(aLine
, std::move(aFill
), aLineStartEnd
,
942 aShadow
, std::move(aFillFloatTransGradient
),
943 aText
, aGlow
, aGlowText
, nSoftEdgeRadius
);
946 return attribute::SdrLineFillEffectsTextAttribute();
949 attribute::SdrLineFillShadowAttribute3D
createNewSdrLineFillShadowAttribute(const SfxItemSet
& rSet
, bool bSuppressFill
)
951 attribute::SdrFillAttribute aFill
;
952 attribute::SdrLineStartEndAttribute aLineStartEnd
;
953 attribute::SdrShadowAttribute aShadow
;
954 attribute::FillGradientAttribute aFillFloatTransGradient
;
957 attribute::SdrLineAttribute
aLine(createNewSdrLineAttribute(rSet
));
959 if(!aLine
.isDefault())
962 aLineStartEnd
= createNewSdrLineStartEndAttribute(rSet
, aLine
.getWidth());
968 aFill
= createNewSdrFillAttribute(rSet
);
970 if(!aFill
.isDefault())
972 // try fillfloattransparence
973 aFillFloatTransGradient
= createNewTransparenceGradientAttribute(rSet
);
977 if(!aLine
.isDefault() || !aFill
.isDefault())
980 aShadow
= createNewSdrShadowAttribute(rSet
);
982 return attribute::SdrLineFillShadowAttribute3D(
983 std::move(aLine
), std::move(aFill
), std::move(aLineStartEnd
),
984 std::move(aShadow
), std::move(aFillFloatTransGradient
));
987 return attribute::SdrLineFillShadowAttribute3D();
990 attribute::SdrSceneAttribute
createNewSdrSceneAttribute(const SfxItemSet
& rSet
)
993 css::drawing::ProjectionMode
aProjectionMode(css::drawing::ProjectionMode_PARALLEL
);
994 const sal_uInt16
nProjectionValue(rSet
.Get(SDRATTR_3DSCENE_PERSPECTIVE
).GetValue());
996 if(1 == nProjectionValue
)
998 aProjectionMode
= css::drawing::ProjectionMode_PERSPECTIVE
;
1002 const double fDistance(rSet
.Get(SDRATTR_3DSCENE_DISTANCE
).GetValue());
1005 const double fShadowSlant(
1006 basegfx::deg2rad(rSet
.Get(SDRATTR_3DSCENE_SHADOW_SLANT
).GetValue()));
1009 css::drawing::ShadeMode
aShadeMode(css::drawing::ShadeMode_FLAT
);
1010 const sal_uInt16
nShadeValue(rSet
.Get(SDRATTR_3DSCENE_SHADE_MODE
).GetValue());
1012 if(1 == nShadeValue
)
1014 aShadeMode
= css::drawing::ShadeMode_PHONG
;
1016 else if(2 == nShadeValue
)
1018 aShadeMode
= css::drawing::ShadeMode_SMOOTH
;
1020 else if(3 == nShadeValue
)
1022 aShadeMode
= css::drawing::ShadeMode_DRAFT
;
1025 // get two sided lighting
1026 const bool bTwoSidedLighting(rSet
.Get(SDRATTR_3DSCENE_TWO_SIDED_LIGHTING
).GetValue());
1028 return attribute::SdrSceneAttribute(fDistance
, fShadowSlant
, aProjectionMode
, aShadeMode
, bTwoSidedLighting
);
1031 attribute::SdrLightingAttribute
createNewSdrLightingAttribute(const SfxItemSet
& rSet
)
1033 // extract lights from given SfxItemSet (from scene)
1034 ::std::vector
< attribute::Sdr3DLightAttribute
> aLightVector
;
1036 if(rSet
.Get(SDRATTR_3DSCENE_LIGHTON_1
).GetValue())
1038 const basegfx::BColor
aColor(rSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_1
).GetValue().getBColor());
1039 const basegfx::B3DVector
aDirection(rSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_1
).GetValue());
1040 aLightVector
.emplace_back(aColor
, aDirection
, true);
1043 if(rSet
.Get(SDRATTR_3DSCENE_LIGHTON_2
).GetValue())
1045 const basegfx::BColor
aColor(rSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_2
).GetValue().getBColor());
1046 const basegfx::B3DVector
aDirection(rSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_2
).GetValue());
1047 aLightVector
.emplace_back(aColor
, aDirection
, false);
1050 if(rSet
.Get(SDRATTR_3DSCENE_LIGHTON_3
).GetValue())
1052 const basegfx::BColor
aColor(rSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_3
).GetValue().getBColor());
1053 const basegfx::B3DVector
aDirection(rSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_3
).GetValue());
1054 aLightVector
.emplace_back(aColor
, aDirection
, false);
1057 if(rSet
.Get(SDRATTR_3DSCENE_LIGHTON_4
).GetValue())
1059 const basegfx::BColor
aColor(rSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_4
).GetValue().getBColor());
1060 const basegfx::B3DVector
aDirection(rSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_4
).GetValue());
1061 aLightVector
.emplace_back(aColor
, aDirection
, false);
1064 if(rSet
.Get(SDRATTR_3DSCENE_LIGHTON_5
).GetValue())
1066 const basegfx::BColor
aColor(rSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_5
).GetValue().getBColor());
1067 const basegfx::B3DVector
aDirection(rSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_5
).GetValue());
1068 aLightVector
.emplace_back(aColor
, aDirection
, false);
1071 if(rSet
.Get(SDRATTR_3DSCENE_LIGHTON_6
).GetValue())
1073 const basegfx::BColor
aColor(rSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_6
).GetValue().getBColor());
1074 const basegfx::B3DVector
aDirection(rSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_6
).GetValue());
1075 aLightVector
.emplace_back(aColor
, aDirection
, false);
1078 if(rSet
.Get(SDRATTR_3DSCENE_LIGHTON_7
).GetValue())
1080 const basegfx::BColor
aColor(rSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_7
).GetValue().getBColor());
1081 const basegfx::B3DVector
aDirection(rSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_7
).GetValue());
1082 aLightVector
.emplace_back(aColor
, aDirection
, false);
1085 if(rSet
.Get(SDRATTR_3DSCENE_LIGHTON_8
).GetValue())
1087 const basegfx::BColor
aColor(rSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_8
).GetValue().getBColor());
1088 const basegfx::B3DVector
aDirection(rSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_8
).GetValue());
1089 aLightVector
.emplace_back(aColor
, aDirection
, false);
1092 // get ambient color
1093 const Color
aAmbientValue(rSet
.Get(SDRATTR_3DSCENE_AMBIENTCOLOR
).GetValue());
1094 const basegfx::BColor
aAmbientLight(aAmbientValue
.getBColor());
1096 return attribute::SdrLightingAttribute(aAmbientLight
, std::move(aLightVector
));
1099 void calculateRelativeCornerRadius(sal_Int32 nRadius
, const basegfx::B2DRange
& rObjectRange
, double& rfCornerRadiusX
, double& rfCornerRadiusY
)
1101 rfCornerRadiusX
= rfCornerRadiusY
= static_cast<double>(nRadius
);
1103 if(0.0 != rfCornerRadiusX
)
1105 const double fHalfObjectWidth(rObjectRange
.getWidth() * 0.5);
1107 if(0.0 != fHalfObjectWidth
)
1109 if(rfCornerRadiusX
< 0.0)
1111 rfCornerRadiusX
= 0.0;
1114 if(rfCornerRadiusX
> fHalfObjectWidth
)
1116 rfCornerRadiusX
= fHalfObjectWidth
;
1119 rfCornerRadiusX
/= fHalfObjectWidth
;
1123 rfCornerRadiusX
= 0.0;
1127 if(0.0 == rfCornerRadiusY
)
1130 const double fHalfObjectHeight(rObjectRange
.getHeight() * 0.5);
1132 if(0.0 != fHalfObjectHeight
)
1134 if(rfCornerRadiusY
< 0.0)
1136 rfCornerRadiusY
= 0.0;
1139 if(rfCornerRadiusY
> fHalfObjectHeight
)
1141 rfCornerRadiusY
= fHalfObjectHeight
;
1144 rfCornerRadiusY
/= fHalfObjectHeight
;
1148 rfCornerRadiusY
= 0.0;
1152 // #i101508# Support handing over given text-to-border distances
1153 attribute::SdrFillTextAttribute
createNewSdrFillTextAttribute(
1154 const SfxItemSet
& rSet
,
1155 const SdrText
* pText
,
1156 const sal_Int32
* pLeft
,
1157 const sal_Int32
* pUpper
,
1158 const sal_Int32
* pRight
,
1159 const sal_Int32
* pLower
)
1161 attribute::SdrFillAttribute aFill
;
1162 attribute::FillGradientAttribute aFillFloatTransGradient
;
1163 attribute::SdrTextAttribute aText
;
1164 bool bFontworkHideContour(false);
1166 // look for text first
1169 aText
= createNewSdrTextAttribute(rSet
, *pText
, pLeft
, pUpper
, pRight
, pLower
);
1171 // when object has text and text is fontwork and hide contour is set for fontwork, force
1172 // fill style to empty
1173 if(!aText
.getSdrFormTextAttribute().isDefault() && aText
.isHideContour())
1175 bFontworkHideContour
= true;
1179 if(!bFontworkHideContour
)
1182 aFill
= createNewSdrFillAttribute(rSet
);
1184 if(!aFill
.isDefault())
1186 // try fillfloattransparence
1187 aFillFloatTransGradient
= createNewTransparenceGradientAttribute(rSet
);
1191 if (!aFill
.isDefault() || !aText
.isDefault())
1193 return attribute::SdrFillTextAttribute(std::move(aFill
),
1194 std::move(aFillFloatTransGradient
),
1198 return attribute::SdrFillTextAttribute();
1201 } // end of namespace
1203 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */