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 <basegfx/utils/gradienttools.hxx>
66 #include <svx/svx3ditems.hxx>
67 #include <com/sun/star/drawing/ProjectionMode.hpp>
68 #include <com/sun/star/drawing/ShadeMode.hpp>
69 #include <drawinglayer/attribute/sdrallattribute3d.hxx>
70 #include <svx/rectenum.hxx>
71 #include <svx/sdtfchim.hxx>
72 #include <svx/svdoutl.hxx>
73 #include <svx/svdmodel.hxx>
74 #include <svx/xflbmsli.hxx>
75 #include <editeng/editstat.hxx>
76 #include <osl/diagnose.h>
77 #include <drawinglayer/attribute/fillhatchattribute.hxx>
78 #include <drawinglayer/attribute/fillgradientattribute.hxx>
79 #include <sdr/attribute/sdreffectstextattribute.hxx>
80 #include <sdr/attribute/sdrlineeffectstextattribute.hxx>
81 #include <sdr/attribute/sdrformtextattribute.hxx>
82 #include <sdr/attribute/sdrlinefilleffectstextattribute.hxx>
83 #include <drawinglayer/attribute/sdrglowattribute.hxx>
84 #include <drawinglayer/attribute/sdrsceneattribute3d.hxx>
85 #include <drawinglayer/attribute/sdrlightingattribute3d.hxx>
86 #include <drawinglayer/attribute/sdrlightattribute3d.hxx>
87 #include <sdr/attribute/sdrfilltextattribute.hxx>
88 #include <com/sun/star/drawing/LineCap.hpp>
90 using namespace com::sun::star
;
92 namespace drawinglayer
96 attribute::HatchStyle
XHatchStyleToHatchStyle(css::drawing::HatchStyle eStyle
)
100 case css::drawing::HatchStyle_SINGLE
:
102 return attribute::HatchStyle::Single
;
104 case css::drawing::HatchStyle_DOUBLE
:
106 return attribute::HatchStyle::Double
;
110 return attribute::HatchStyle::Triple
; // css::drawing::HatchStyle_TRIPLE
115 basegfx::B2DLineJoin
LineJointToB2DLineJoin(css::drawing::LineJoint eLineJoint
)
119 case css::drawing::LineJoint_BEVEL
:
121 return basegfx::B2DLineJoin::Bevel
;
123 case css::drawing::LineJoint_MIDDLE
:
124 case css::drawing::LineJoint_MITER
:
126 return basegfx::B2DLineJoin::Miter
;
128 case css::drawing::LineJoint_ROUND
:
130 return basegfx::B2DLineJoin::Round
;
132 default : // css::drawing::LineJoint_NONE
134 return basegfx::B2DLineJoin::NONE
;
139 basegfx::B2DVector
RectPointToB2DVector(RectPoint eRectPoint
)
141 basegfx::B2DVector
aRetval(0.0, 0.0);
143 // position changes X
146 case RectPoint::LT
: case RectPoint::LM
: case RectPoint::LB
:
152 case RectPoint::RT
: case RectPoint::RM
: case RectPoint::RB
:
164 // position changes Y
167 case RectPoint::LT
: case RectPoint::MT
: case RectPoint::RT
:
173 case RectPoint::LB
: case RectPoint::MB
: case RectPoint::RB
:
188 attribute::SdrGlowAttribute
createNewSdrGlowAttribute(const SfxItemSet
& rSet
)
190 sal_Int32 nRadius
= rSet
.Get(SDRATTR_GLOW_RADIUS
).GetValue();
192 return attribute::SdrGlowAttribute();
193 Color
aColor(rSet
.Get(SDRATTR_GLOW_COLOR
).GetColorValue());
194 sal_uInt16
nTransparency(rSet
.Get(SDRATTR_GLOW_TRANSPARENCY
).GetValue());
196 aColor
.SetAlpha(255 - std::round(nTransparency
/ 100.0 * 255.0));
198 attribute::SdrGlowAttribute glowAttr
{ nRadius
, aColor
};
202 sal_Int32
getSoftEdgeRadius(const SfxItemSet
& rSet
)
204 return rSet
.Get(SDRATTR_SOFTEDGE_RADIUS
).GetValue();
206 } // end of anonymous namespace
207 } // end of namespace drawinglayer
210 namespace drawinglayer::primitive2d
212 attribute::SdrLineAttribute
createNewSdrLineAttribute(const SfxItemSet
& rSet
)
214 const css::drawing::LineStyle
eStyle(rSet
.Get(XATTR_LINESTYLE
).GetValue());
216 if(drawing::LineStyle_NONE
!= eStyle
)
218 sal_uInt16
nTransparence(rSet
.Get(XATTR_LINETRANSPARENCE
).GetValue());
220 if(nTransparence
> 100)
225 if(100 != nTransparence
)
227 const sal_uInt32
nWidth(rSet
.Get(XATTR_LINEWIDTH
).GetValue());
228 const Color
aColor(rSet
.Get(XATTR_LINECOLOR
).GetColorValue());
229 const css::drawing::LineJoint
eJoint(rSet
.Get(XATTR_LINEJOINT
).GetValue());
230 const css::drawing::LineCap
eCap(rSet
.Get(XATTR_LINECAP
).GetValue());
231 ::std::vector
< double > aDotDashArray
;
232 double fFullDotDashLen(0.0);
234 if(drawing::LineStyle_DASH
== eStyle
)
236 const XDash
& rDash
= rSet
.Get(XATTR_LINEDASH
).GetDashValue();
238 if(rDash
.GetDots() || rDash
.GetDashes())
240 fFullDotDashLen
= rDash
.CreateDotDashArray(aDotDashArray
, static_cast<double>(nWidth
));
244 return attribute::SdrLineAttribute(
245 LineJointToB2DLineJoin(eJoint
),
246 static_cast<double>(nWidth
),
247 static_cast<double>(nTransparence
) * 0.01,
250 std::move(aDotDashArray
),
255 return attribute::SdrLineAttribute();
258 attribute::SdrLineStartEndAttribute
createNewSdrLineStartEndAttribute(
259 const SfxItemSet
& rSet
,
262 const sal_Int32
nTempStartWidth(rSet
.Get(XATTR_LINESTARTWIDTH
).GetValue());
263 const sal_Int32
nTempEndWidth(rSet
.Get(XATTR_LINEENDWIDTH
).GetValue());
264 basegfx::B2DPolyPolygon aStartPolyPolygon
;
265 basegfx::B2DPolyPolygon aEndPolyPolygon
;
266 double fStartWidth(0.0);
267 double fEndWidth(0.0);
268 bool bStartActive(false);
269 bool bEndActive(false);
270 bool bStartCentered(true);
271 bool bEndCentered(true);
275 if(nTempStartWidth
< 0)
277 fStartWidth
= (static_cast<double>(-nTempStartWidth
) * fWidth
) * 0.01;
281 fStartWidth
= static_cast<double>(nTempStartWidth
);
284 if(0.0 != fStartWidth
)
286 aStartPolyPolygon
= rSet
.Get(XATTR_LINESTART
).GetLineStartValue();
288 if(aStartPolyPolygon
.count() && aStartPolyPolygon
.getB2DPolygon(0).count())
291 bStartCentered
= rSet
.Get(XATTR_LINESTARTCENTER
).GetValue();
298 if(nTempEndWidth
< 0)
300 fEndWidth
= (static_cast<double>(-nTempEndWidth
) * fWidth
) * 0.01;
304 fEndWidth
= static_cast<double>(nTempEndWidth
);
309 aEndPolyPolygon
= rSet
.Get(XATTR_LINEEND
).GetLineEndValue();
311 if(aEndPolyPolygon
.count() && aEndPolyPolygon
.getB2DPolygon(0).count())
314 bEndCentered
= rSet
.Get(XATTR_LINEENDCENTER
).GetValue();
319 if(bStartActive
|| bEndActive
)
321 return attribute::SdrLineStartEndAttribute(
322 aStartPolyPolygon
, aEndPolyPolygon
, fStartWidth
, fEndWidth
,
323 bStartActive
, bEndActive
, bStartCentered
, bEndCentered
);
326 return attribute::SdrLineStartEndAttribute();
329 attribute::SdrShadowAttribute
createNewSdrShadowAttribute(const SfxItemSet
& rSet
)
331 const bool bShadow(rSet
.Get(SDRATTR_SHADOW
).GetValue());
335 sal_uInt16
nTransparence(rSet
.Get(SDRATTR_SHADOWTRANSPARENCE
).GetValue());
337 if(nTransparence
> 100)
344 sal_uInt16
nFillTransparence(rSet
.Get(XATTR_FILLTRANSPARENCE
).GetValue());
346 if(nFillTransparence
> 100)
348 nFillTransparence
= 100;
351 if(nTransparence
== nFillTransparence
)
353 // shadow does not really have an own transparence, but the application
354 // sets the shadow transparence equal to the object transparence for
355 // convenience. This is not useful for primitive creation, so take
356 // this as no shadow transparence
361 if(100 != nTransparence
)
363 const basegfx::B2DVector
aOffset(
364 static_cast<double>(rSet
.Get(SDRATTR_SHADOWXDIST
).GetValue()),
365 static_cast<double>(rSet
.Get(SDRATTR_SHADOWYDIST
).GetValue()));
367 const basegfx::B2DVector
aSize(
368 static_cast<double>(rSet
.Get(SDRATTR_SHADOWSIZEX
).GetValue()),
369 static_cast<double>(rSet
.Get(SDRATTR_SHADOWSIZEY
).GetValue()));
371 const Color
aColor(rSet
.Get(SDRATTR_SHADOWCOLOR
).GetColorValue());
373 sal_Int32
nBlur(rSet
.Get(SDRATTR_SHADOWBLUR
).GetValue());
375 model::RectangleAlignment eAlignment
{rSet
.Get(SDRATTR_SHADOWALIGNMENT
).GetValue()};
377 return attribute::SdrShadowAttribute(aOffset
, aSize
, static_cast<double>(nTransparence
) * 0.01, nBlur
, eAlignment
, aColor
.getBColor());
381 return attribute::SdrShadowAttribute();
384 attribute::SdrFillAttribute
createNewSdrFillAttribute(const SfxItemSet
& rSet
)
386 const drawing::FillStyle
eStyle(rSet
.Get(XATTR_FILLSTYLE
).GetValue());
388 sal_uInt16
nTransparence(rSet
.Get(XATTR_FILLTRANSPARENCE
).GetValue());
390 if(nTransparence
> 100)
395 if(drawing::FillStyle_NONE
== eStyle
)
397 XFillUseSlideBackgroundItem
aBckItem(rSet
.Get(XATTR_FILLUSESLIDEBACKGROUND
));
398 const bool bSlideBackgroundFill(aBckItem
.GetValue());
400 if(bSlideBackgroundFill
)
402 // we have SlideBackgroundFill mode, create a
403 // SdrFillAttribute accordingly
404 return attribute::SdrFillAttribute(true);
408 if(drawing::FillStyle_NONE
!= eStyle
)
410 if(100 != nTransparence
)
412 // need to check XFillFloatTransparence, object fill may still be completely transparent
413 const XFillFloatTransparenceItem
* pGradientItem
;
415 if((pGradientItem
= rSet
.GetItemIfSet(XATTR_FILLFLOATTRANSPARENCE
, true))
416 && pGradientItem
->IsEnabled())
418 const basegfx::BGradient
& rGradient
= pGradientItem
->GetGradientValue();
419 basegfx::BColor aSingleColor
;
420 const bool bSingleColor(rGradient
.GetColorStops().isSingleColor(aSingleColor
));
421 const bool bCompletelyTransparent(bSingleColor
&& basegfx::fTools::equal(aSingleColor
.luminance(), 1.0));
423 if(bCompletelyTransparent
)
430 if(100 != nTransparence
)
432 const Color
aColor(rSet
.Get(XATTR_FILLCOLOR
).GetColorValue());
433 attribute::FillGradientAttribute aGradient
;
434 attribute::FillHatchAttribute aHatch
;
435 attribute::SdrFillGraphicAttribute aFillGraphic
;
441 // nothing to do, color is defined
444 case drawing::FillStyle_GRADIENT
:
446 basegfx::BGradient
aBGradient(rSet
.Get(XATTR_FILLGRADIENT
).GetGradientValue());
447 basegfx::BColorStops
aColorStops(aBGradient
.GetColorStops());
450 if (aBGradient
.GetStartIntens() != 100 || aBGradient
.GetEndIntens() != 100)
452 // Need to do the (old, crazy) blend against black for a
453 // used intensity, but now for all ColorStops relative to their
454 // offsets, where 0 means black and 100 means original color
455 aColorStops
.blendToIntensity(
456 aBGradient
.GetStartIntens() * 0.01,
457 aBGradient
.GetEndIntens() * 0.01,
458 basegfx::BColor()); // COL_BLACK
461 aGradient
= attribute::FillGradientAttribute(
462 aBGradient
.GetGradientStyle(),
463 static_cast<double>(aBGradient
.GetBorder()) * 0.01,
464 static_cast<double>(aBGradient
.GetXOffset()) * 0.01,
465 static_cast<double>(aBGradient
.GetYOffset()) * 0.01,
466 toRadians(aBGradient
.GetAngle()),
468 rSet
.Get(XATTR_GRADIENTSTEPCOUNT
).GetValue());
472 case drawing::FillStyle_HATCH
:
474 const XHatch
& rHatch(rSet
.Get(XATTR_FILLHATCH
).GetHatchValue());
475 const Color
aColorB(rHatch
.GetColor());
477 aHatch
= attribute::FillHatchAttribute(
478 XHatchStyleToHatchStyle(rHatch
.GetHatchStyle()),
479 static_cast<double>(rHatch
.GetDistance()),
480 toRadians(rHatch
.GetAngle()),
482 3, // same default as VCL, a minimum of three discrete units (pixels) offset
483 rSet
.Get(XATTR_FILLBACKGROUND
).GetValue());
487 case drawing::FillStyle_BITMAP
:
489 aFillGraphic
= createNewSdrFillGraphicAttribute(rSet
);
494 return attribute::SdrFillAttribute(
495 static_cast<double>(nTransparence
) * 0.01,
503 if(nTransparence
== 100)
505 attribute::FillGradientAttribute aGradient
;
506 attribute::FillHatchAttribute aHatch
;
507 attribute::SdrFillGraphicAttribute aFillGraphic
;
508 return attribute::SdrFillAttribute(
510 basegfx::BColor( 0, 0, 0 ),
516 return attribute::SdrFillAttribute();
519 // #i101508# Support handing over given text-to-border distances
520 attribute::SdrTextAttribute
createNewSdrTextAttribute(
521 const SfxItemSet
& rSet
,
522 const SdrText
& rText
,
523 const sal_Int32
* pLeft
,
524 const sal_Int32
* pUpper
,
525 const sal_Int32
* pRight
,
526 const sal_Int32
* pLower
)
528 const SdrTextObj
& rTextObj
= rText
.GetObject();
530 // Save chaining attributes
531 bool bChainable
= rTextObj
.IsChainable();
534 if(rText
.GetOutlinerParaObject())
536 // added TextEdit text suppression
537 bool bInEditMode(false);
539 if(rText
.GetObject().getTextCount() > 1)
541 bInEditMode
= rTextObj
.IsInEditMode() && rText
.GetObject().getActiveText() == &rText
;
545 bInEditMode
= rTextObj
.IsInEditMode();
548 OutlinerParaObject
aOutlinerParaObject(*rText
.GetOutlinerParaObject());
552 std::optional
<OutlinerParaObject
> pTempObj
= rTextObj
.CreateEditOutlinerParaObject();
556 aOutlinerParaObject
= *pTempObj
;
561 // CreateEditOutlinerParaObject() returning no object does not mean that
562 // text edit mode is not active. Do not reset the flag here
563 // bInEditMode = false;
567 const SdrTextAniKind
eAniKind(rTextObj
.GetTextAniKind());
570 const SdrOutliner
& rDrawTextOutliner(rText
.GetObject().getSdrModelFromSdrObject().GetDrawOutliner(&rTextObj
));
571 const bool bWrongSpell(rDrawTextOutliner
.GetControlWord() & EEControlBits::ONLINESPELLING
);
573 return attribute::SdrTextAttribute(
576 rSet
.Get(XATTR_FORMTXTSTYLE
).GetValue(),
577 pLeft
? *pLeft
: rTextObj
.GetTextLeftDistance(),
578 pUpper
? *pUpper
: rTextObj
.GetTextUpperDistance(),
579 pRight
? *pRight
: rTextObj
.GetTextRightDistance(),
580 pLower
? *pLower
: rTextObj
.GetTextLowerDistance(),
581 rTextObj
.GetTextHorizontalAdjust(rSet
),
582 rTextObj
.GetTextVerticalAdjust(rSet
),
583 rSet
.Get(SDRATTR_TEXT_CONTOURFRAME
).GetValue(),
584 rTextObj
.IsFitToSize(),
585 rTextObj
.IsAutoFit(),
586 rSet
.Get(XATTR_FORMTXTHIDEFORM
).GetValue(),
587 SdrTextAniKind::Blink
== eAniKind
,
588 SdrTextAniKind::Scroll
== eAniKind
|| SdrTextAniKind::Alternate
== eAniKind
|| SdrTextAniKind::Slide
== eAniKind
,
590 rSet
.Get(SDRATTR_TEXT_USEFIXEDCELLHEIGHT
).GetValue(),
595 return attribute::SdrTextAttribute();
598 attribute::FillGradientAttribute
createNewTransparenceGradientAttribute(const SfxItemSet
& rSet
)
600 const XFillFloatTransparenceItem
* pGradientItem
;
602 if((pGradientItem
= rSet
.GetItemIfSet(XATTR_FILLFLOATTRANSPARENCE
))
603 && pGradientItem
->IsEnabled())
605 // test if float transparency is completely transparent
606 const basegfx::BGradient
& rGradient(pGradientItem
->GetGradientValue());
607 basegfx::BColor aSingleColor
;
608 const bool bSingleColor(rGradient
.GetColorStops().isSingleColor(aSingleColor
));
609 const bool bCompletelyTransparent(bSingleColor
&& basegfx::fTools::equal(aSingleColor
.luminance(), 1.0));
610 const bool bNotTransparent(bSingleColor
&& basegfx::fTools::equalZero(aSingleColor
.luminance()));
612 // create nothing when completely transparent: This case is already checked for the
613 // normal fill attributes, XFILL_NONE will be used.
614 // create nothing when not transparent: use normal fill, no need t create a FillGradientAttribute.
615 // Both cases are optimizations, always creating FillGradientAttribute will work, too
616 if (!bNotTransparent
&& !bCompletelyTransparent
)
618 basegfx::BColorStops
aColorStops(rGradient
.GetColorStops());
620 if (rGradient
.GetStartIntens() != 100 || rGradient
.GetEndIntens() != 100)
622 // tdf#155913 Start/EndIntens is not used for transparency gradient,
623 // so might even get asserted (?)
624 // this may also be set for transparence, so need to take care of it
625 aColorStops
.blendToIntensity(
626 rGradient
.GetStartIntens() * 0.01,
627 rGradient
.GetEndIntens() * 0.01,
628 basegfx::BColor()); // COL_BLACK
631 // tdf#155913 GradientStepCount is not used for transparency gradient
632 return attribute::FillGradientAttribute(
633 rGradient
.GetGradientStyle(),
634 static_cast<double>(rGradient
.GetBorder()) * 0.01,
635 static_cast<double>(rGradient
.GetXOffset()) * 0.01,
636 static_cast<double>(rGradient
.GetYOffset()) * 0.01,
637 toRadians(rGradient
.GetAngle()),
642 return attribute::FillGradientAttribute();
645 attribute::SdrFillGraphicAttribute
createNewSdrFillGraphicAttribute(const SfxItemSet
& rSet
)
647 Graphic
aGraphic(rSet
.Get(XATTR_FILLBITMAP
).GetGraphicObject().GetGraphic());
649 OUString aOriginURL
= aGraphic
.getOriginURL();
650 if (aGraphic
.GetType() == GraphicType::Default
&& !aOriginURL
.isEmpty())
652 aGraphic
= vcl::graphic::loadFromURL(aGraphic
.getOriginURL());
653 aGraphic
.setOriginURL(aOriginURL
);
656 if(GraphicType::Bitmap
!= aGraphic
.GetType() && GraphicType::GdiMetafile
!= aGraphic
.GetType())
658 // no content if not bitmap or metafile
659 OSL_ENSURE(false, "No fill graphic in SfxItemSet (!)");
660 return attribute::SdrFillGraphicAttribute();
663 Size
aPrefSize(aGraphic
.GetPrefSize());
665 if(!aPrefSize
.Width() || !aPrefSize
.Height())
667 // if there is no logical size, create a size from pixel size and set MapMode accordingly
668 if(GraphicType::Bitmap
== aGraphic
.GetType())
670 aGraphic
.SetPrefSize(aGraphic
.GetBitmapEx().GetSizePixel());
671 aGraphic
.SetPrefMapMode(MapMode(MapUnit::MapPixel
));
672 aPrefSize
= aGraphic
.GetPrefSize();
676 if(!aPrefSize
.Width() || !aPrefSize
.Height())
678 // no content if no size
679 OSL_ENSURE(false, "Graphic has no size in SfxItemSet (!)");
680 return attribute::SdrFillGraphicAttribute();
683 // convert size and MapMode to destination logical size and MapMode
684 const MapUnit
aDestinationMapUnit(rSet
.GetPool()->GetMetric(0));
685 basegfx::B2DVector
aGraphicLogicSize(aGraphic
.GetPrefSize().Width(), aGraphic
.GetPrefSize().Height());
687 if (aGraphic
.GetPrefMapMode().GetMapUnit() != aDestinationMapUnit
)
689 // #i100360# for MapUnit::MapPixel, LogicToLogic will not work properly,
690 // so fallback to Application::GetDefaultDevice()
693 if(MapUnit::MapPixel
== aGraphic
.GetPrefMapMode().GetMapUnit())
695 aNewSize
= Application::GetDefaultDevice()->PixelToLogic(
696 aGraphic
.GetPrefSize(),
697 MapMode(aDestinationMapUnit
));
701 aNewSize
= OutputDevice::LogicToLogic(
702 aGraphic
.GetPrefSize(),
703 aGraphic
.GetPrefMapMode(),
704 MapMode(aDestinationMapUnit
));
707 // #i124002# do not set new size using SetPrefSize at the graphic, this will lead to problems.
708 // Instead, adapt the GraphicLogicSize which will be used for further decompositions
709 aGraphicLogicSize
= basegfx::B2DVector(aNewSize
.Width(), aNewSize
.Height());
713 const basegfx::B2DVector
aSize(
714 static_cast<double>(rSet
.Get(XATTR_FILLBMP_SIZEX
).GetValue()),
715 static_cast<double>(rSet
.Get(XATTR_FILLBMP_SIZEY
).GetValue()));
716 const basegfx::B2DVector
aOffset(
717 static_cast<double>(rSet
.Get(XATTR_FILLBMP_TILEOFFSETX
).GetValue()),
718 static_cast<double>(rSet
.Get(XATTR_FILLBMP_TILEOFFSETY
).GetValue()));
719 const basegfx::B2DVector
aOffsetPosition(
720 static_cast<double>(rSet
.Get(XATTR_FILLBMP_POSOFFSETX
).GetValue()),
721 static_cast<double>(rSet
.Get(XATTR_FILLBMP_POSOFFSETY
).GetValue()));
723 return attribute::SdrFillGraphicAttribute(
729 RectPointToB2DVector(rSet
.GetItem
<XFillBmpPosItem
>(XATTR_FILLBMP_POS
)->GetValue()),
730 rSet
.Get(XATTR_FILLBMP_TILE
).GetValue(),
731 rSet
.Get(XATTR_FILLBMP_STRETCH
).GetValue(),
732 rSet
.Get(XATTR_FILLBMP_SIZELOG
).GetValue());
735 attribute::SdrEffectsTextAttribute
createNewSdrEffectsTextAttribute(
736 const SfxItemSet
& rSet
,
737 const SdrText
* pText
,
740 attribute::SdrTextAttribute aText
;
742 // #i98072# added option to suppress text
743 // look for text first
744 if(!bSuppressText
&& pText
)
746 aText
= createNewSdrTextAttribute(rSet
, *pText
);
750 const attribute::SdrShadowAttribute
aShadow(createNewSdrShadowAttribute(rSet
));
751 const attribute::SdrGlowAttribute
aGlow(createNewSdrGlowAttribute(rSet
));
752 const sal_Int32
nSoftEdgeRadius(getSoftEdgeRadius(rSet
));
754 return attribute::SdrEffectsTextAttribute(aShadow
, aText
, aGlow
, nSoftEdgeRadius
);
757 attribute::SdrLineEffectsTextAttribute
createNewSdrLineEffectsTextAttribute(
758 const SfxItemSet
& rSet
,
759 const SdrText
* pText
)
761 attribute::SdrLineAttribute aLine
;
762 attribute::SdrLineStartEndAttribute aLineStartEnd
;
763 attribute::SdrTextAttribute aText
;
764 bool bFontworkHideContour(false);
766 // look for text first
769 aText
= createNewSdrTextAttribute(rSet
, *pText
);
771 // when object has text and text is fontwork and hide contour is set for fontwork, force
772 // line and fill style to empty
773 if(!aText
.isDefault()
774 && !aText
.getSdrFormTextAttribute().isDefault()
775 && aText
.isHideContour())
777 bFontworkHideContour
= true;
782 if(!bFontworkHideContour
)
784 aLine
= createNewSdrLineAttribute(rSet
);
786 if(!aLine
.isDefault())
789 aLineStartEnd
= createNewSdrLineStartEndAttribute(rSet
, aLine
.getWidth());
793 if(!aLine
.isDefault() || !aText
.isDefault())
796 const attribute::SdrShadowAttribute
aShadow(createNewSdrShadowAttribute(rSet
));
797 const attribute::SdrGlowAttribute aGlow
= createNewSdrGlowAttribute(rSet
);
798 const sal_Int32
nSoftEdgeRadius(getSoftEdgeRadius(rSet
));
800 return attribute::SdrLineEffectsTextAttribute(aLine
, aLineStartEnd
, aShadow
, aText
,
801 aGlow
, nSoftEdgeRadius
);
804 return attribute::SdrLineEffectsTextAttribute();
807 attribute::SdrLineFillEffectsTextAttribute
createNewSdrLineFillEffectsTextAttribute(
808 const SfxItemSet
& rSet
,
809 const SdrText
* pText
,
811 bool bSuppressShadow
)
813 attribute::SdrLineAttribute aLine
;
814 attribute::SdrFillAttribute aFill
;
815 attribute::SdrLineStartEndAttribute aLineStartEnd
;
816 attribute::FillGradientAttribute aFillFloatTransGradient
;
817 attribute::SdrTextAttribute aText
;
818 bool bFontworkHideContour(false);
820 // look for text first
823 aText
= createNewSdrTextAttribute(rSet
, *pText
);
825 // when object has text and text is fontwork and hide contour is set for fontwork, force
826 // line and fill style to empty
827 if(!aText
.getSdrFormTextAttribute().isDefault() && aText
.isHideContour())
829 bFontworkHideContour
= true;
833 if(!bFontworkHideContour
)
836 aLine
= createNewSdrLineAttribute(rSet
);
838 if(!aLine
.isDefault())
841 aLineStartEnd
= createNewSdrLineStartEndAttribute(rSet
, aLine
.getWidth());
845 aFill
= createNewSdrFillAttribute(rSet
);
847 if(!aFill
.isDefault())
849 // try fillfloattransparence
850 aFillFloatTransGradient
= createNewTransparenceGradientAttribute(rSet
);
854 // bHasContent is used from OLE and graphic objects. Normally a possible shadow
855 // depends on line, fill or text to be set, but for these objects it is possible
856 // to have none of these, but still content which needs to have a shadow (if set),
857 // so shadow needs to be tried
858 if(bHasContent
|| !aLine
.isDefault() || !aFill
.isDefault() || !aText
.isDefault())
861 const attribute::SdrShadowAttribute aShadow
= !bSuppressShadow
?
862 createNewSdrShadowAttribute(rSet
) : attribute::SdrShadowAttribute();
865 const attribute::SdrGlowAttribute aGlow
= createNewSdrGlowAttribute(rSet
);
867 const sal_Int32
nSoftEdgeRadius(getSoftEdgeRadius(rSet
));
869 return attribute::SdrLineFillEffectsTextAttribute(aLine
, aFill
, aLineStartEnd
,
870 aShadow
, aFillFloatTransGradient
,
871 aText
, aGlow
, nSoftEdgeRadius
);
874 return attribute::SdrLineFillEffectsTextAttribute();
877 attribute::SdrLineFillShadowAttribute3D
createNewSdrLineFillShadowAttribute(const SfxItemSet
& rSet
, bool bSuppressFill
)
879 attribute::SdrFillAttribute aFill
;
880 attribute::SdrLineStartEndAttribute aLineStartEnd
;
881 attribute::SdrShadowAttribute aShadow
;
882 attribute::FillGradientAttribute aFillFloatTransGradient
;
885 const attribute::SdrLineAttribute
aLine(createNewSdrLineAttribute(rSet
));
887 if(!aLine
.isDefault())
890 aLineStartEnd
= createNewSdrLineStartEndAttribute(rSet
, aLine
.getWidth());
896 aFill
= createNewSdrFillAttribute(rSet
);
898 if(!aFill
.isDefault())
900 // try fillfloattransparence
901 aFillFloatTransGradient
= createNewTransparenceGradientAttribute(rSet
);
905 if(!aLine
.isDefault() || !aFill
.isDefault())
908 aShadow
= createNewSdrShadowAttribute(rSet
);
910 return attribute::SdrLineFillShadowAttribute3D(
911 aLine
, aFill
, aLineStartEnd
, aShadow
, aFillFloatTransGradient
);
914 return attribute::SdrLineFillShadowAttribute3D();
917 attribute::SdrSceneAttribute
createNewSdrSceneAttribute(const SfxItemSet
& rSet
)
920 css::drawing::ProjectionMode
aProjectionMode(css::drawing::ProjectionMode_PARALLEL
);
921 const sal_uInt16
nProjectionValue(rSet
.Get(SDRATTR_3DSCENE_PERSPECTIVE
).GetValue());
923 if(1 == nProjectionValue
)
925 aProjectionMode
= css::drawing::ProjectionMode_PERSPECTIVE
;
929 const double fDistance(rSet
.Get(SDRATTR_3DSCENE_DISTANCE
).GetValue());
932 const double fShadowSlant(
933 basegfx::deg2rad(rSet
.Get(SDRATTR_3DSCENE_SHADOW_SLANT
).GetValue()));
936 css::drawing::ShadeMode
aShadeMode(css::drawing::ShadeMode_FLAT
);
937 const sal_uInt16
nShadeValue(rSet
.Get(SDRATTR_3DSCENE_SHADE_MODE
).GetValue());
941 aShadeMode
= css::drawing::ShadeMode_PHONG
;
943 else if(2 == nShadeValue
)
945 aShadeMode
= css::drawing::ShadeMode_SMOOTH
;
947 else if(3 == nShadeValue
)
949 aShadeMode
= css::drawing::ShadeMode_DRAFT
;
952 // get two sided lighting
953 const bool bTwoSidedLighting(rSet
.Get(SDRATTR_3DSCENE_TWO_SIDED_LIGHTING
).GetValue());
955 return attribute::SdrSceneAttribute(fDistance
, fShadowSlant
, aProjectionMode
, aShadeMode
, bTwoSidedLighting
);
958 attribute::SdrLightingAttribute
createNewSdrLightingAttribute(const SfxItemSet
& rSet
)
960 // extract lights from given SfxItemSet (from scene)
961 ::std::vector
< attribute::Sdr3DLightAttribute
> aLightVector
;
963 if(rSet
.Get(SDRATTR_3DSCENE_LIGHTON_1
).GetValue())
965 const basegfx::BColor
aColor(rSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_1
).GetValue().getBColor());
966 const basegfx::B3DVector
aDirection(rSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_1
).GetValue());
967 aLightVector
.emplace_back(aColor
, aDirection
, true);
970 if(rSet
.Get(SDRATTR_3DSCENE_LIGHTON_2
).GetValue())
972 const basegfx::BColor
aColor(rSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_2
).GetValue().getBColor());
973 const basegfx::B3DVector
aDirection(rSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_2
).GetValue());
974 aLightVector
.emplace_back(aColor
, aDirection
, false);
977 if(rSet
.Get(SDRATTR_3DSCENE_LIGHTON_3
).GetValue())
979 const basegfx::BColor
aColor(rSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_3
).GetValue().getBColor());
980 const basegfx::B3DVector
aDirection(rSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_3
).GetValue());
981 aLightVector
.emplace_back(aColor
, aDirection
, false);
984 if(rSet
.Get(SDRATTR_3DSCENE_LIGHTON_4
).GetValue())
986 const basegfx::BColor
aColor(rSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_4
).GetValue().getBColor());
987 const basegfx::B3DVector
aDirection(rSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_4
).GetValue());
988 aLightVector
.emplace_back(aColor
, aDirection
, false);
991 if(rSet
.Get(SDRATTR_3DSCENE_LIGHTON_5
).GetValue())
993 const basegfx::BColor
aColor(rSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_5
).GetValue().getBColor());
994 const basegfx::B3DVector
aDirection(rSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_5
).GetValue());
995 aLightVector
.emplace_back(aColor
, aDirection
, false);
998 if(rSet
.Get(SDRATTR_3DSCENE_LIGHTON_6
).GetValue())
1000 const basegfx::BColor
aColor(rSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_6
).GetValue().getBColor());
1001 const basegfx::B3DVector
aDirection(rSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_6
).GetValue());
1002 aLightVector
.emplace_back(aColor
, aDirection
, false);
1005 if(rSet
.Get(SDRATTR_3DSCENE_LIGHTON_7
).GetValue())
1007 const basegfx::BColor
aColor(rSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_7
).GetValue().getBColor());
1008 const basegfx::B3DVector
aDirection(rSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_7
).GetValue());
1009 aLightVector
.emplace_back(aColor
, aDirection
, false);
1012 if(rSet
.Get(SDRATTR_3DSCENE_LIGHTON_8
).GetValue())
1014 const basegfx::BColor
aColor(rSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_8
).GetValue().getBColor());
1015 const basegfx::B3DVector
aDirection(rSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_8
).GetValue());
1016 aLightVector
.emplace_back(aColor
, aDirection
, false);
1019 // get ambient color
1020 const Color
aAmbientValue(rSet
.Get(SDRATTR_3DSCENE_AMBIENTCOLOR
).GetValue());
1021 const basegfx::BColor
aAmbientLight(aAmbientValue
.getBColor());
1023 return attribute::SdrLightingAttribute(aAmbientLight
, std::move(aLightVector
));
1026 void calculateRelativeCornerRadius(sal_Int32 nRadius
, const basegfx::B2DRange
& rObjectRange
, double& rfCornerRadiusX
, double& rfCornerRadiusY
)
1028 rfCornerRadiusX
= rfCornerRadiusY
= static_cast<double>(nRadius
);
1030 if(0.0 != rfCornerRadiusX
)
1032 const double fHalfObjectWidth(rObjectRange
.getWidth() * 0.5);
1034 if(0.0 != fHalfObjectWidth
)
1036 if(rfCornerRadiusX
< 0.0)
1038 rfCornerRadiusX
= 0.0;
1041 if(rfCornerRadiusX
> fHalfObjectWidth
)
1043 rfCornerRadiusX
= fHalfObjectWidth
;
1046 rfCornerRadiusX
/= fHalfObjectWidth
;
1050 rfCornerRadiusX
= 0.0;
1054 if(0.0 == rfCornerRadiusY
)
1057 const double fHalfObjectHeight(rObjectRange
.getHeight() * 0.5);
1059 if(0.0 != fHalfObjectHeight
)
1061 if(rfCornerRadiusY
< 0.0)
1063 rfCornerRadiusY
= 0.0;
1066 if(rfCornerRadiusY
> fHalfObjectHeight
)
1068 rfCornerRadiusY
= fHalfObjectHeight
;
1071 rfCornerRadiusY
/= fHalfObjectHeight
;
1075 rfCornerRadiusY
= 0.0;
1079 // #i101508# Support handing over given text-to-border distances
1080 attribute::SdrFillTextAttribute
createNewSdrFillTextAttribute(
1081 const SfxItemSet
& rSet
,
1082 const SdrText
* pText
,
1083 const sal_Int32
* pLeft
,
1084 const sal_Int32
* pUpper
,
1085 const sal_Int32
* pRight
,
1086 const sal_Int32
* pLower
)
1088 attribute::SdrFillAttribute aFill
;
1089 attribute::FillGradientAttribute aFillFloatTransGradient
;
1090 attribute::SdrTextAttribute aText
;
1091 bool bFontworkHideContour(false);
1093 // look for text first
1096 aText
= createNewSdrTextAttribute(rSet
, *pText
, pLeft
, pUpper
, pRight
, pLower
);
1098 // when object has text and text is fontwork and hide contour is set for fontwork, force
1099 // fill style to empty
1100 if(!aText
.getSdrFormTextAttribute().isDefault() && aText
.isHideContour())
1102 bFontworkHideContour
= true;
1106 if(!bFontworkHideContour
)
1109 aFill
= createNewSdrFillAttribute(rSet
);
1111 if(!aFill
.isDefault())
1113 // try fillfloattransparence
1114 aFillFloatTransGradient
= createNewTransparenceGradientAttribute(rSet
);
1118 if(!aFill
.isDefault() || !aText
.isDefault())
1120 return attribute::SdrFillTextAttribute(aFill
, aFillFloatTransGradient
, aText
);
1123 return attribute::SdrFillTextAttribute();
1126 } // end of namespace
1128 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */