| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_svx.hxx" |
| |
| #include <svx/sdr/contact/viewcontactofsdrcaptionobj.hxx> |
| #include <svx/svdocapt.hxx> |
| #include <svx/sdr/primitive2d/sdrattributecreator.hxx> |
| #include <svx/sdr/primitive2d/sdrcaptionprimitive2d.hxx> |
| #include <basegfx/matrix/b2dhommatrixtools.hxx> |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // includes for special text box shadow (SC) |
| |
| #include <svl/itemset.hxx> |
| #include <svx/xhatch.hxx> |
| #include <svx/xflhtit.hxx> |
| #include <svx/xflclit.hxx> |
| #include <svx/xfltrit.hxx> |
| #include <basegfx/polygon/b2dpolygontools.hxx> |
| #include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> |
| #include <basegfx/polygon/b2dpolygonclipper.hxx> |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| namespace sdr |
| { |
| namespace contact |
| { |
| ViewContactOfSdrCaptionObj::ViewContactOfSdrCaptionObj(SdrCaptionObj& rCaptionObj) |
| : ViewContactOfSdrRectObj(rCaptionObj) |
| { |
| } |
| |
| ViewContactOfSdrCaptionObj::~ViewContactOfSdrCaptionObj() |
| { |
| } |
| |
| drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrCaptionObj::createViewIndependentPrimitive2DSequence() const |
| { |
| drawinglayer::primitive2d::Primitive2DSequence xRetval; |
| const SdrCaptionObj& rCaptionObj(GetCaptionObj()); |
| const SfxItemSet& rItemSet = rCaptionObj.GetMergedItemSet(); |
| const drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute( |
| drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute( |
| rItemSet, |
| rCaptionObj.getText(0), |
| false)); |
| |
| // take unrotated snap rect (direct model data) for position and size |
| const Rectangle& rRectangle = rCaptionObj.GetGeoRect(); |
| const ::basegfx::B2DRange aObjectRange( |
| rRectangle.Left(), rRectangle.Top(), |
| rRectangle.Right(), rRectangle.Bottom()); |
| const GeoStat& rGeoStat(rCaptionObj.GetGeoStat()); |
| |
| // fill object matrix |
| basegfx::B2DHomMatrix aObjectMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( |
| aObjectRange.getWidth(), aObjectRange.getHeight(), |
| rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0, |
| rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0, |
| aObjectRange.getMinX(), aObjectRange.getMinY())); |
| |
| // calculate corner radius |
| double fCornerRadiusX; |
| double fCornerRadiusY; |
| drawinglayer::primitive2d::calculateRelativeCornerRadius( |
| rCaptionObj.GetEckenradius(), aObjectRange, fCornerRadiusX, fCornerRadiusY); |
| |
| // create primitive. Always create one (even if invisible) to let the decomposition |
| // of SdrCaptionPrimitive2D create needed invisible elements for HitTest and BoundRect |
| const drawinglayer::primitive2d::Primitive2DReference xReference( |
| new drawinglayer::primitive2d::SdrCaptionPrimitive2D( |
| aObjectMatrix, |
| aAttribute, |
| rCaptionObj.getTailPolygon(), |
| fCornerRadiusX, |
| fCornerRadiusY)); |
| |
| xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); |
| |
| if(!aAttribute.isDefault() && rCaptionObj.GetSpecialTextBoxShadow()) |
| { |
| // for SC, the caption object may have a specialized shadow. The usual object shadow is off |
| // and a specialized shadow gets created here (see old paint) |
| const SdrShadowColorItem& rShadColItem = (SdrShadowColorItem&)(rItemSet.Get(SDRATTR_SHADOWCOLOR)); |
| const sal_uInt16 nShadowTransparence(((SdrShadowTransparenceItem&)(rItemSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue()); |
| const Color aShadowColor(rShadColItem.GetColorValue()); |
| const XFillStyle eShadowStyle = ((XFillStyleItem&)(rItemSet.Get(XATTR_FILLSTYLE))).GetValue(); |
| |
| // Create own ItemSet and modify as needed |
| // Always hide lines for special calc shadow |
| SfxItemSet aSet(rItemSet); |
| aSet.Put(XLineStyleItem(XLINE_NONE)); |
| |
| if(XFILL_HATCH == eShadowStyle) |
| { |
| // #41666# Hatch color is set hard to shadow color |
| XHatch aHatch = ((XFillHatchItem&)(rItemSet.Get(XATTR_FILLHATCH))).GetHatchValue(); |
| aHatch.SetColor(aShadowColor); |
| aSet.Put(XFillHatchItem(String(),aHatch)); |
| } |
| else |
| { |
| if(XFILL_SOLID != eShadowStyle) |
| { |
| // force fill to solid (for Gradient, Bitmap and *no* fill (#119750# not filled comments *have* shadow)) |
| aSet.Put(XFillStyleItem(XFILL_SOLID)); |
| } |
| |
| aSet.Put(XFillColorItem(String(),aShadowColor)); |
| aSet.Put(XFillTransparenceItem(nShadowTransparence)); |
| } |
| |
| // crete FillAttribute from modified ItemSet |
| const drawinglayer::attribute::SdrFillAttribute aFill( |
| drawinglayer::primitive2d::createNewSdrFillAttribute(aSet)); |
| drawinglayer::primitive2d::Primitive2DReference xSpecialShadow; |
| |
| if(!aFill.isDefault() && 1.0 != aFill.getTransparence()) |
| { |
| // add shadow offset to object matrix |
| const sal_uInt32 nXDist(((SdrShadowXDistItem&)(rItemSet.Get(SDRATTR_SHADOWXDIST))).GetValue()); |
| const sal_uInt32 nYDist(((SdrShadowYDistItem&)(rItemSet.Get(SDRATTR_SHADOWYDIST))).GetValue()); |
| |
| if(nXDist || nYDist) |
| { |
| // #119750# create obect and shadow outline, clip shadow outline |
| // on object outline. If there is a rest, create shadow. Do this to |
| // emulate that shadow is *not* visible behind the object for |
| // transparent object fill for comments in excel |
| basegfx::B2DPolygon aObjectOutline( |
| basegfx::tools::createPolygonFromRect( |
| basegfx::B2DRange(0.0, 0.0, 1.0, 1.0), |
| fCornerRadiusX, |
| fCornerRadiusY)); |
| aObjectOutline.transform(aObjectMatrix); |
| |
| // create shadow outline |
| basegfx::B2DPolygon aShadowOutline(aObjectOutline); |
| aShadowOutline.transform( |
| basegfx::tools::createTranslateB2DHomMatrix(nXDist, nYDist)); |
| |
| // clip shadow outline against object outline |
| const basegfx::B2DPolyPolygon aClippedShadow( |
| basegfx::tools::clipPolygonOnPolyPolygon( |
| aShadowOutline, |
| basegfx::B2DPolyPolygon(aObjectOutline), |
| false, // take the outside |
| false)); |
| |
| if(aClippedShadow.count()) |
| { |
| // if there is shadow, create the specialized shadow primitive |
| xSpecialShadow = drawinglayer::primitive2d::createPolyPolygonFillPrimitive( |
| aClippedShadow, |
| basegfx::B2DHomMatrix(), |
| aFill, |
| drawinglayer::attribute::FillGradientAttribute()); |
| } |
| } |
| } |
| |
| if(xSpecialShadow.is()) |
| { |
| // if we really got a special shadow, create a two-element retval with the shadow |
| // behind the standard object's geometry |
| xRetval.realloc(2); |
| |
| xRetval[0] = xSpecialShadow; |
| xRetval[1] = xReference; |
| } |
| } |
| |
| return xRetval; |
| } |
| } // end of namespace contact |
| } // end of namespace sdr |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // eof |