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 .
21 #include <sdr/contact/viewcontactofsdrcaptionobj.hxx>
22 #include <svx/svdocapt.hxx>
23 #include <sdr/primitive2d/sdrattributecreator.hxx>
24 #include <sdr/primitive2d/sdrcaptionprimitive2d.hxx>
25 #include <basegfx/matrix/b2dhommatrixtools.hxx>
28 // includes for special text box shadow (SC)
30 #include <svl/itemset.hxx>
31 #include <svx/xhatch.hxx>
32 #include <svx/xfillit0.hxx>
33 #include <svx/xflhtit.hxx>
34 #include <svx/xflclit.hxx>
35 #include <svx/xfltrit.hxx>
36 #include <svx/xlineit0.hxx>
37 #include <svx/sdmetitm.hxx>
38 #include <svx/sdooitm.hxx>
39 #include <svx/sdprcitm.hxx>
40 #include <basegfx/polygon/b2dpolygontools.hxx>
41 #include <sdr/primitive2d/sdrdecompositiontools.hxx>
42 #include <basegfx/polygon/b2dpolygonclipper.hxx>
43 #include <vcl/canvastools.hxx>
45 using namespace com::sun::star
;
47 namespace sdr::contact
49 ViewContactOfSdrCaptionObj::ViewContactOfSdrCaptionObj(SdrCaptionObj
& rCaptionObj
)
50 : ViewContactOfSdrRectObj(rCaptionObj
)
54 ViewContactOfSdrCaptionObj::~ViewContactOfSdrCaptionObj()
58 void ViewContactOfSdrCaptionObj::createViewIndependentPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DDecompositionVisitor
& rVisitor
) const
60 const SdrCaptionObj
& rCaptionObj(static_cast<const SdrCaptionObj
&>(GetSdrObject()));
61 const SfxItemSet
& rItemSet
= rCaptionObj
.GetMergedItemSet();
62 const drawinglayer::attribute::SdrLineFillEffectsTextAttribute
aAttribute(
63 drawinglayer::primitive2d::createNewSdrLineFillEffectsTextAttribute(
65 rCaptionObj
.getText(0),
66 false, rCaptionObj
.GetSpecialTextBoxShadow()));
68 // take unrotated snap rect (direct model data) for position and size
69 const tools::Rectangle
aRectangle(rCaptionObj
.GetGeoRect());
70 const ::basegfx::B2DRange aObjectRange
= vcl::unotools::b2DRectangleFromRectangle(aRectangle
);
71 const GeoStat
& rGeoStat(rCaptionObj
.GetGeoStat());
74 basegfx::B2DHomMatrix
aObjectMatrix(basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix(
75 aObjectRange
.getWidth(), aObjectRange
.getHeight(),
76 -rGeoStat
.mfTanShearAngle
,
77 rGeoStat
.m_nRotationAngle
? toRadians(36000_deg100
- rGeoStat
.m_nRotationAngle
) : 0.0,
78 aObjectRange
.getMinX(), aObjectRange
.getMinY()));
80 // calculate corner radius
81 double fCornerRadiusX
;
82 double fCornerRadiusY
;
83 drawinglayer::primitive2d::calculateRelativeCornerRadius(
84 rCaptionObj
.GetEckenradius(), aObjectRange
, fCornerRadiusX
, fCornerRadiusY
);
85 basegfx::B2DPolygon
aTail(rCaptionObj
.getTailPolygon());
87 // create primitive. Always create one (even if invisible) to let the decomposition
88 // of SdrCaptionPrimitive2D create needed invisible elements for HitTest and BoundRect
89 drawinglayer::primitive2d::Primitive2DReference
xReference(
90 new drawinglayer::primitive2d::SdrCaptionPrimitive2D(
97 if(!aAttribute
.isDefault() && rCaptionObj
.GetSpecialTextBoxShadow())
99 // for SC, the caption object may have a specialized shadow. The usual object shadow is off
100 // and a specialized shadow gets created here (see old paint)
101 const XColorItem
& rShadColItem
= rItemSet
.Get(SDRATTR_SHADOWCOLOR
);
102 const sal_uInt16
nShadowTransparence(rItemSet
.Get(SDRATTR_SHADOWTRANSPARENCE
).GetValue());
103 const Color
aShadowColor(rShadColItem
.GetColorValue());
104 const drawing::FillStyle eShadowStyle
= rItemSet
.Get(XATTR_FILLSTYLE
).GetValue();
106 // Create own ItemSet and modify as needed
107 // Always hide lines for special calc shadow
108 SfxItemSet
aSet(rItemSet
);
109 aSet
.Put(XLineStyleItem(drawing::LineStyle_NONE
));
111 if(drawing::FillStyle_HATCH
== eShadowStyle
)
113 // #41666# Hatch color is set hard to shadow color
114 XHatch aHatch
= rItemSet
.Get(XATTR_FILLHATCH
).GetHatchValue();
115 aHatch
.SetColor(aShadowColor
);
116 aSet
.Put(XFillHatchItem(OUString(),aHatch
));
120 if(drawing::FillStyle_SOLID
!= eShadowStyle
)
122 // force fill to solid (for Gradient, Bitmap and *no* fill (#119750# not filled comments *have* shadow))
123 aSet
.Put(XFillStyleItem(drawing::FillStyle_SOLID
));
126 aSet
.Put(XFillColorItem(OUString(),aShadowColor
));
127 aSet
.Put(XFillTransparenceItem(nShadowTransparence
));
130 // create FillAttribute from modified ItemSet
131 const drawinglayer::attribute::SdrFillAttribute
aFill(
132 drawinglayer::primitive2d::createNewSdrFillAttribute(aSet
));
133 drawinglayer::primitive2d::Primitive2DReference xSpecialShadow
;
135 if(!aFill
.isDefault() && 1.0 != aFill
.getTransparence())
137 // add shadow offset to object matrix
138 const bool bShadow(rItemSet
.Get(SDRATTR_SHADOW
).GetValue());
139 const sal_uInt32
nXDist(rItemSet
.Get(SDRATTR_SHADOWXDIST
).GetValue());
140 const sal_uInt32
nYDist(rItemSet
.Get(SDRATTR_SHADOWYDIST
).GetValue());
142 if (bShadow
&& (nXDist
|| nYDist
))
144 // #119750# create object and shadow outline, clip shadow outline
145 // on object outline. If there is a rest, create shadow. Do this to
146 // emulate that shadow is *not* visible behind the object for
147 // transparent object fill for comments in excel
148 basegfx::B2DPolygon
aObjectOutline(
149 basegfx::utils::createPolygonFromRect(
150 basegfx::B2DRange(0.0, 0.0, 1.0, 1.0),
153 aObjectOutline
.transform(aObjectMatrix
);
155 // create shadow outline
156 basegfx::B2DPolygon
aShadowOutline(aObjectOutline
);
157 aShadowOutline
.transform(
158 basegfx::utils::createTranslateB2DHomMatrix(nXDist
, nYDist
));
160 // clip shadow outline against object outline
161 const basegfx::B2DPolyPolygon
aClippedShadow(
162 basegfx::utils::clipPolygonOnPolyPolygon(
164 basegfx::B2DPolyPolygon(aObjectOutline
),
165 false, // take the outside
168 if(aClippedShadow
.count())
170 // if there is shadow, create the specialized shadow primitive
171 xSpecialShadow
= drawinglayer::primitive2d::createPolyPolygonFillPrimitive(
174 drawinglayer::attribute::FillGradientAttribute());
179 if(xSpecialShadow
.is())
181 // if we really got a special shadow, create a two-element retval with the shadow
182 // behind the standard object's geometry
183 rVisitor
.visit(std::move(xSpecialShadow
));
187 rVisitor
.visit(std::move(xReference
));
190 } // end of namespace
192 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */