cid#1606940 Check of thread-shared field evades lock acquisition
[LibreOffice.git] / svx / source / sdr / contact / viewcontactofsdrcaptionobj.cxx
blobd6d6446e589f89a9261c90b49a3b12a71449af70
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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(
64 rItemSet,
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());
73 // fill object matrix
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(
91 aObjectMatrix,
92 aAttribute,
93 std::move(aTail),
94 fCornerRadiusX,
95 fCornerRadiusY));
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));
118 else
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),
151 fCornerRadiusX,
152 fCornerRadiusY));
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(
163 aShadowOutline,
164 basegfx::B2DPolyPolygon(aObjectOutline),
165 false, // take the outside
166 false));
168 if(aClippedShadow.count())
170 // if there is shadow, create the specialized shadow primitive
171 xSpecialShadow = drawinglayer::primitive2d::createPolyPolygonFillPrimitive(
172 aClippedShadow,
173 aFill,
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: */