1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_svx.hxx" 26 27 #include <svx/sdr/contact/viewcontactofsdrcaptionobj.hxx> 28 #include <svx/svdocapt.hxx> 29 #include <svx/sdr/primitive2d/sdrattributecreator.hxx> 30 #include <svx/sdr/primitive2d/sdrcaptionprimitive2d.hxx> 31 #include <basegfx/matrix/b2dhommatrixtools.hxx> 32 33 ////////////////////////////////////////////////////////////////////////////// 34 // includes for special text box shadow (SC) 35 36 #include <svl/itemset.hxx> 37 #include <svx/xhatch.hxx> 38 #include <svx/xflhtit.hxx> 39 #include <svx/xflclit.hxx> 40 #include <svx/xfltrit.hxx> 41 #include <basegfx/polygon/b2dpolygontools.hxx> 42 #include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> 43 #include <basegfx/polygon/b2dpolygonclipper.hxx> 44 45 ////////////////////////////////////////////////////////////////////////////// 46 47 namespace sdr 48 { 49 namespace contact 50 { ViewContactOfSdrCaptionObj(SdrCaptionObj & rCaptionObj)51 ViewContactOfSdrCaptionObj::ViewContactOfSdrCaptionObj(SdrCaptionObj& rCaptionObj) 52 : ViewContactOfSdrRectObj(rCaptionObj) 53 { 54 } 55 ~ViewContactOfSdrCaptionObj()56 ViewContactOfSdrCaptionObj::~ViewContactOfSdrCaptionObj() 57 { 58 } 59 createViewIndependentPrimitive2DSequence() const60 drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrCaptionObj::createViewIndependentPrimitive2DSequence() const 61 { 62 drawinglayer::primitive2d::Primitive2DSequence xRetval; 63 const SdrCaptionObj& rCaptionObj(GetCaptionObj()); 64 const SfxItemSet& rItemSet = rCaptionObj.GetMergedItemSet(); 65 const drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute( 66 drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute( 67 rItemSet, 68 rCaptionObj.getText(0), 69 false)); 70 71 // take unrotated snap rect (direct model data) for position and size 72 const Rectangle& rRectangle = rCaptionObj.GetGeoRect(); 73 const ::basegfx::B2DRange aObjectRange( 74 rRectangle.Left(), rRectangle.Top(), 75 rRectangle.Right(), rRectangle.Bottom()); 76 const GeoStat& rGeoStat(rCaptionObj.GetGeoStat()); 77 78 // fill object matrix 79 basegfx::B2DHomMatrix aObjectMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( 80 aObjectRange.getWidth(), aObjectRange.getHeight(), 81 rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0, 82 rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0, 83 aObjectRange.getMinX(), aObjectRange.getMinY())); 84 85 // calculate corner radius 86 double fCornerRadiusX; 87 double fCornerRadiusY; 88 drawinglayer::primitive2d::calculateRelativeCornerRadius( 89 rCaptionObj.GetEckenradius(), aObjectRange, fCornerRadiusX, fCornerRadiusY); 90 91 // create primitive. Always create one (even if invisible) to let the decomposition 92 // of SdrCaptionPrimitive2D create needed invisible elements for HitTest and BoundRect 93 const drawinglayer::primitive2d::Primitive2DReference xReference( 94 new drawinglayer::primitive2d::SdrCaptionPrimitive2D( 95 aObjectMatrix, 96 aAttribute, 97 rCaptionObj.getTailPolygon(), 98 fCornerRadiusX, 99 fCornerRadiusY)); 100 101 xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); 102 103 if(!aAttribute.isDefault() && rCaptionObj.GetSpecialTextBoxShadow()) 104 { 105 // for SC, the caption object may have a specialized shadow. The usual object shadow is off 106 // and a specialized shadow gets created here (see old paint) 107 const SdrShadowColorItem& rShadColItem = (SdrShadowColorItem&)(rItemSet.Get(SDRATTR_SHADOWCOLOR)); 108 const sal_uInt16 nShadowTransparence(((SdrShadowTransparenceItem&)(rItemSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue()); 109 const Color aShadowColor(rShadColItem.GetColorValue()); 110 const XFillStyle eShadowStyle = ((XFillStyleItem&)(rItemSet.Get(XATTR_FILLSTYLE))).GetValue(); 111 112 // Create own ItemSet and modify as needed 113 // Always hide lines for special calc shadow 114 SfxItemSet aSet(rItemSet); 115 aSet.Put(XLineStyleItem(XLINE_NONE)); 116 117 if(XFILL_HATCH == eShadowStyle) 118 { 119 // #41666# Hatch color is set hard to shadow color 120 XHatch aHatch = ((XFillHatchItem&)(rItemSet.Get(XATTR_FILLHATCH))).GetHatchValue(); 121 aHatch.SetColor(aShadowColor); 122 aSet.Put(XFillHatchItem(String(),aHatch)); 123 } 124 else 125 { 126 if(XFILL_SOLID != eShadowStyle) 127 { 128 // force fill to solid (for Gradient, Bitmap and *no* fill (#119750# not filled comments *have* shadow)) 129 aSet.Put(XFillStyleItem(XFILL_SOLID)); 130 } 131 132 aSet.Put(XFillColorItem(String(),aShadowColor)); 133 aSet.Put(XFillTransparenceItem(nShadowTransparence)); 134 } 135 136 // crete FillAttribute from modified ItemSet 137 const drawinglayer::attribute::SdrFillAttribute aFill( 138 drawinglayer::primitive2d::createNewSdrFillAttribute(aSet)); 139 drawinglayer::primitive2d::Primitive2DReference xSpecialShadow; 140 141 if(!aFill.isDefault() && 1.0 != aFill.getTransparence()) 142 { 143 // add shadow offset to object matrix 144 const sal_uInt32 nXDist(((SdrShadowXDistItem&)(rItemSet.Get(SDRATTR_SHADOWXDIST))).GetValue()); 145 const sal_uInt32 nYDist(((SdrShadowYDistItem&)(rItemSet.Get(SDRATTR_SHADOWYDIST))).GetValue()); 146 147 if(nXDist || nYDist) 148 { 149 // #119750# create object and shadow outline, clip shadow outline 150 // on object outline. If there is a rest, create shadow. Do this to 151 // emulate that shadow is *not* visible behind the object for 152 // transparent object fill for comments in excel 153 basegfx::B2DPolygon aObjectOutline( 154 basegfx::tools::createPolygonFromRect( 155 basegfx::B2DRange(0.0, 0.0, 1.0, 1.0), 156 fCornerRadiusX, 157 fCornerRadiusY)); 158 aObjectOutline.transform(aObjectMatrix); 159 160 // create shadow outline 161 basegfx::B2DPolygon aShadowOutline(aObjectOutline); 162 aShadowOutline.transform( 163 basegfx::tools::createTranslateB2DHomMatrix(nXDist, nYDist)); 164 165 // clip shadow outline against object outline 166 const basegfx::B2DPolyPolygon aClippedShadow( 167 basegfx::tools::clipPolygonOnPolyPolygon( 168 aShadowOutline, 169 basegfx::B2DPolyPolygon(aObjectOutline), 170 false, // take the outside 171 false)); 172 173 if(aClippedShadow.count()) 174 { 175 // if there is shadow, create the specialized shadow primitive 176 xSpecialShadow = drawinglayer::primitive2d::createPolyPolygonFillPrimitive( 177 aClippedShadow, 178 aFill, 179 drawinglayer::attribute::FillGradientAttribute()); 180 } 181 } 182 } 183 184 if(xSpecialShadow.is()) 185 { 186 // if we really got a special shadow, create a two-element retval with the shadow 187 // behind the standard object's geometry 188 xRetval.realloc(2); 189 190 xRetval[0] = xSpecialShadow; 191 xRetval[1] = xReference; 192 } 193 } 194 195 return xRetval; 196 } 197 } // end of namespace contact 198 } // end of namespace sdr 199 200 ////////////////////////////////////////////////////////////////////////////// 201 // eof 202