1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove 25*b1cdbd2cSJim Jagielski #include "precompiled_svx.hxx" 26*b1cdbd2cSJim Jagielski #include <svx/sdr/contact/viewcontactofsdrobjcustomshape.hxx> 27*b1cdbd2cSJim Jagielski #include <svx/svdoashp.hxx> 28*b1cdbd2cSJim Jagielski #include <svx/sdr/contact/displayinfo.hxx> 29*b1cdbd2cSJim Jagielski #include <svx/sdr/primitive2d/sdrattributecreator.hxx> 30*b1cdbd2cSJim Jagielski #include <svx/svditer.hxx> 31*b1cdbd2cSJim Jagielski #include <svx/sdr/primitive2d/sdrcustomshapeprimitive2d.hxx> 32*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolygontools.hxx> 33*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolygon.hxx> 34*b1cdbd2cSJim Jagielski #include <basegfx/matrix/b2dhommatrixtools.hxx> 35*b1cdbd2cSJim Jagielski #include <svx/obj3d.hxx> 36*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> 37*b1cdbd2cSJim Jagielski 38*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 39*b1cdbd2cSJim Jagielski 40*b1cdbd2cSJim Jagielski namespace sdr 41*b1cdbd2cSJim Jagielski { 42*b1cdbd2cSJim Jagielski namespace contact 43*b1cdbd2cSJim Jagielski { ViewContactOfSdrObjCustomShape(SdrObjCustomShape & rCustomShape)44*b1cdbd2cSJim Jagielski ViewContactOfSdrObjCustomShape::ViewContactOfSdrObjCustomShape(SdrObjCustomShape& rCustomShape) 45*b1cdbd2cSJim Jagielski : ViewContactOfTextObj(rCustomShape) 46*b1cdbd2cSJim Jagielski { 47*b1cdbd2cSJim Jagielski } 48*b1cdbd2cSJim Jagielski ~ViewContactOfSdrObjCustomShape()49*b1cdbd2cSJim Jagielski ViewContactOfSdrObjCustomShape::~ViewContactOfSdrObjCustomShape() 50*b1cdbd2cSJim Jagielski { 51*b1cdbd2cSJim Jagielski } 52*b1cdbd2cSJim Jagielski getCorrectedTextBoundRect() const53*b1cdbd2cSJim Jagielski basegfx::B2DRange ViewContactOfSdrObjCustomShape::getCorrectedTextBoundRect() const 54*b1cdbd2cSJim Jagielski { 55*b1cdbd2cSJim Jagielski const Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); 56*b1cdbd2cSJim Jagielski Rectangle aTextBound(aObjectBound); 57*b1cdbd2cSJim Jagielski GetCustomShapeObj().GetTextBounds(aTextBound); 58*b1cdbd2cSJim Jagielski basegfx::B2DRange aTextRange(aTextBound.Left(), aTextBound.Top(), aTextBound.Right(), aTextBound.Bottom()); 59*b1cdbd2cSJim Jagielski const basegfx::B2DRange aObjectRange(aObjectBound.Left(), aObjectBound.Top(), aObjectBound.Right(), aObjectBound.Bottom()); 60*b1cdbd2cSJim Jagielski 61*b1cdbd2cSJim Jagielski // no need to correct if no extra text range 62*b1cdbd2cSJim Jagielski if(aTextRange != aObjectRange) 63*b1cdbd2cSJim Jagielski { 64*b1cdbd2cSJim Jagielski const GeoStat& rGeoStat(GetCustomShapeObj().GetGeoStat()); 65*b1cdbd2cSJim Jagielski 66*b1cdbd2cSJim Jagielski // only correct when rotation and/or shear is used 67*b1cdbd2cSJim Jagielski if(rGeoStat.nShearWink || rGeoStat.nDrehWink ) 68*b1cdbd2cSJim Jagielski { 69*b1cdbd2cSJim Jagielski // text range needs to be corrected by 70*b1cdbd2cSJim Jagielski // aObjectRange.getCenter() - aRotObjectRange.getCenter() since it's 71*b1cdbd2cSJim Jagielski // defined differenly by using rotation around object center. Start 72*b1cdbd2cSJim Jagielski // with positive part 73*b1cdbd2cSJim Jagielski basegfx::B2DVector aTranslation(aObjectRange.getCenter()); 74*b1cdbd2cSJim Jagielski 75*b1cdbd2cSJim Jagielski // get rotated and sheared object's range 76*b1cdbd2cSJim Jagielski basegfx::B2DRange aRotObjectRange(aObjectRange); 77*b1cdbd2cSJim Jagielski basegfx::B2DHomMatrix aRotMatrix; 78*b1cdbd2cSJim Jagielski 79*b1cdbd2cSJim Jagielski aRotMatrix.translate(-aObjectRange.getMinimum().getX(), -aObjectRange.getMinimum().getY()); 80*b1cdbd2cSJim Jagielski 81*b1cdbd2cSJim Jagielski if(rGeoStat.nShearWink) 82*b1cdbd2cSJim Jagielski { 83*b1cdbd2cSJim Jagielski aRotMatrix.shearX(tan((36000 - rGeoStat.nShearWink) * F_PI18000)); 84*b1cdbd2cSJim Jagielski } 85*b1cdbd2cSJim Jagielski 86*b1cdbd2cSJim Jagielski if(rGeoStat.nDrehWink) 87*b1cdbd2cSJim Jagielski { 88*b1cdbd2cSJim Jagielski aRotMatrix.rotate((36000 - rGeoStat.nDrehWink) * F_PI18000); 89*b1cdbd2cSJim Jagielski } 90*b1cdbd2cSJim Jagielski 91*b1cdbd2cSJim Jagielski aRotMatrix.translate(aObjectRange.getMinimum().getX(), aObjectRange.getMinimum().getY()); 92*b1cdbd2cSJim Jagielski aRotObjectRange.transform(aRotMatrix); 93*b1cdbd2cSJim Jagielski 94*b1cdbd2cSJim Jagielski // add negative translation part 95*b1cdbd2cSJim Jagielski aTranslation -= aRotObjectRange.getCenter(); 96*b1cdbd2cSJim Jagielski 97*b1cdbd2cSJim Jagielski // create new range 98*b1cdbd2cSJim Jagielski aTextRange = basegfx::B2DRange( 99*b1cdbd2cSJim Jagielski aTextRange.getMinX() + aTranslation.getX(), aTextRange.getMinY() + aTranslation.getY(), 100*b1cdbd2cSJim Jagielski aTextRange.getMaxX() + aTranslation.getX(), aTextRange.getMaxY() + aTranslation.getY()); 101*b1cdbd2cSJim Jagielski } 102*b1cdbd2cSJim Jagielski } 103*b1cdbd2cSJim Jagielski 104*b1cdbd2cSJim Jagielski return aTextRange; 105*b1cdbd2cSJim Jagielski } 106*b1cdbd2cSJim Jagielski createViewIndependentPrimitive2DSequence() const107*b1cdbd2cSJim Jagielski drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrObjCustomShape::createViewIndependentPrimitive2DSequence() const 108*b1cdbd2cSJim Jagielski { 109*b1cdbd2cSJim Jagielski drawinglayer::primitive2d::Primitive2DSequence xRetval; 110*b1cdbd2cSJim Jagielski const SfxItemSet& rItemSet = GetCustomShapeObj().GetMergedItemSet(); 111*b1cdbd2cSJim Jagielski 112*b1cdbd2cSJim Jagielski // #i98072# Get shandow and text; eventually suppress the text if it's 113*b1cdbd2cSJim Jagielski // a TextPath FontworkGallery object 114*b1cdbd2cSJim Jagielski const drawinglayer::attribute::SdrShadowTextAttribute aAttribute( 115*b1cdbd2cSJim Jagielski drawinglayer::primitive2d::createNewSdrShadowTextAttribute( 116*b1cdbd2cSJim Jagielski rItemSet, 117*b1cdbd2cSJim Jagielski GetCustomShapeObj().getText(0), 118*b1cdbd2cSJim Jagielski GetCustomShapeObj().IsTextPath())); 119*b1cdbd2cSJim Jagielski drawinglayer::primitive2d::Primitive2DSequence xGroup; 120*b1cdbd2cSJim Jagielski bool bHasText(!aAttribute.getText().isDefault()); 121*b1cdbd2cSJim Jagielski 122*b1cdbd2cSJim Jagielski // create Primitive2DSequence from sub-geometry 123*b1cdbd2cSJim Jagielski const SdrObject* pSdrObjRepresentation = GetCustomShapeObj().GetSdrObjectFromCustomShape(); 124*b1cdbd2cSJim Jagielski bool b3DShape(false); 125*b1cdbd2cSJim Jagielski 126*b1cdbd2cSJim Jagielski if(pSdrObjRepresentation) 127*b1cdbd2cSJim Jagielski { 128*b1cdbd2cSJim Jagielski SdrObjListIter aIterator(*pSdrObjRepresentation); 129*b1cdbd2cSJim Jagielski 130*b1cdbd2cSJim Jagielski while(aIterator.IsMore()) 131*b1cdbd2cSJim Jagielski { 132*b1cdbd2cSJim Jagielski SdrObject& rCandidate = *aIterator.Next(); 133*b1cdbd2cSJim Jagielski 134*b1cdbd2cSJim Jagielski if(!b3DShape && dynamic_cast< E3dObject* >(&rCandidate)) 135*b1cdbd2cSJim Jagielski { 136*b1cdbd2cSJim Jagielski b3DShape = true; 137*b1cdbd2cSJim Jagielski } 138*b1cdbd2cSJim Jagielski 139*b1cdbd2cSJim Jagielski const drawinglayer::primitive2d::Primitive2DSequence xNew(rCandidate.GetViewContact().getViewIndependentPrimitive2DSequence()); 140*b1cdbd2cSJim Jagielski drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xGroup, xNew); 141*b1cdbd2cSJim Jagielski } 142*b1cdbd2cSJim Jagielski } 143*b1cdbd2cSJim Jagielski 144*b1cdbd2cSJim Jagielski if(bHasText || xGroup.hasElements()) 145*b1cdbd2cSJim Jagielski { 146*b1cdbd2cSJim Jagielski // prepare text box geometry 147*b1cdbd2cSJim Jagielski basegfx::B2DHomMatrix aTextBoxMatrix; 148*b1cdbd2cSJim Jagielski bool bWordWrap(false); 149*b1cdbd2cSJim Jagielski 150*b1cdbd2cSJim Jagielski if(bHasText) 151*b1cdbd2cSJim Jagielski { 152*b1cdbd2cSJim Jagielski // take unrotated snap rect as default, then get the 153*b1cdbd2cSJim Jagielski // unrotated text box. Rotation needs to be done centered 154*b1cdbd2cSJim Jagielski const Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); 155*b1cdbd2cSJim Jagielski const basegfx::B2DRange aObjectRange(aObjectBound.Left(), aObjectBound.Top(), aObjectBound.Right(), aObjectBound.Bottom()); 156*b1cdbd2cSJim Jagielski 157*b1cdbd2cSJim Jagielski // #i101684# get the text range unrotated and absolute to the object range 158*b1cdbd2cSJim Jagielski const basegfx::B2DRange aTextRange(getCorrectedTextBoundRect()); 159*b1cdbd2cSJim Jagielski 160*b1cdbd2cSJim Jagielski // give text object a size 161*b1cdbd2cSJim Jagielski aTextBoxMatrix.scale(aTextRange.getWidth(), aTextRange.getHeight()); 162*b1cdbd2cSJim Jagielski 163*b1cdbd2cSJim Jagielski // check if we have a rotation/shear at all to take care of 164*b1cdbd2cSJim Jagielski const double fExtraTextRotation(GetCustomShapeObj().GetExtraTextRotation()); 165*b1cdbd2cSJim Jagielski const GeoStat& rGeoStat(GetCustomShapeObj().GetGeoStat()); 166*b1cdbd2cSJim Jagielski 167*b1cdbd2cSJim Jagielski if(rGeoStat.nShearWink || rGeoStat.nDrehWink || !basegfx::fTools::equalZero(fExtraTextRotation)) 168*b1cdbd2cSJim Jagielski { 169*b1cdbd2cSJim Jagielski if(aObjectRange != aTextRange) 170*b1cdbd2cSJim Jagielski { 171*b1cdbd2cSJim Jagielski // move relative to unrotated object range 172*b1cdbd2cSJim Jagielski aTextBoxMatrix.translate( 173*b1cdbd2cSJim Jagielski aTextRange.getMinX() - aObjectRange.getMinimum().getX(), 174*b1cdbd2cSJim Jagielski aTextRange.getMinY() - aObjectRange.getMinimum().getY()); 175*b1cdbd2cSJim Jagielski } 176*b1cdbd2cSJim Jagielski 177*b1cdbd2cSJim Jagielski if(!basegfx::fTools::equalZero(fExtraTextRotation)) 178*b1cdbd2cSJim Jagielski { 179*b1cdbd2cSJim Jagielski basegfx::B2DVector aTranslation( 180*b1cdbd2cSJim Jagielski ( aTextRange.getWidth() / 2 ) + ( aTextRange.getMinX() - aObjectRange.getMinimum().getX() ), 181*b1cdbd2cSJim Jagielski ( aTextRange.getHeight() / 2 ) + ( aTextRange.getMinY() - aObjectRange.getMinimum().getY() ) ); 182*b1cdbd2cSJim Jagielski aTextBoxMatrix.translate( -aTranslation.getX(), -aTranslation.getY() ); 183*b1cdbd2cSJim Jagielski aTextBoxMatrix.rotate((360.0 - fExtraTextRotation) * F_PI180); 184*b1cdbd2cSJim Jagielski aTextBoxMatrix.translate( aTranslation.getX(), aTranslation.getY() ); 185*b1cdbd2cSJim Jagielski } 186*b1cdbd2cSJim Jagielski 187*b1cdbd2cSJim Jagielski if(rGeoStat.nShearWink) 188*b1cdbd2cSJim Jagielski { 189*b1cdbd2cSJim Jagielski aTextBoxMatrix.shearX(tan((36000 - rGeoStat.nShearWink) * F_PI18000)); 190*b1cdbd2cSJim Jagielski } 191*b1cdbd2cSJim Jagielski 192*b1cdbd2cSJim Jagielski if(rGeoStat.nDrehWink) 193*b1cdbd2cSJim Jagielski { 194*b1cdbd2cSJim Jagielski aTextBoxMatrix.rotate((36000 - rGeoStat.nDrehWink) * F_PI18000); 195*b1cdbd2cSJim Jagielski } 196*b1cdbd2cSJim Jagielski 197*b1cdbd2cSJim Jagielski // give text it's target position 198*b1cdbd2cSJim Jagielski aTextBoxMatrix.translate(aObjectRange.getMinimum().getX(), aObjectRange.getMinimum().getY()); 199*b1cdbd2cSJim Jagielski } 200*b1cdbd2cSJim Jagielski else 201*b1cdbd2cSJim Jagielski { 202*b1cdbd2cSJim Jagielski aTextBoxMatrix.translate(aTextRange.getMinX(), aTextRange.getMinY()); 203*b1cdbd2cSJim Jagielski } 204*b1cdbd2cSJim Jagielski 205*b1cdbd2cSJim Jagielski // check if SdrTextWordWrapItem is set 206*b1cdbd2cSJim Jagielski bWordWrap = ((SdrTextWordWrapItem&)(GetCustomShapeObj().GetMergedItem(SDRATTR_TEXT_WORDWRAP))).GetValue(); 207*b1cdbd2cSJim Jagielski } 208*b1cdbd2cSJim Jagielski 209*b1cdbd2cSJim Jagielski // create primitive 210*b1cdbd2cSJim Jagielski const drawinglayer::primitive2d::Primitive2DReference xReference( 211*b1cdbd2cSJim Jagielski new drawinglayer::primitive2d::SdrCustomShapePrimitive2D( 212*b1cdbd2cSJim Jagielski aAttribute, 213*b1cdbd2cSJim Jagielski xGroup, 214*b1cdbd2cSJim Jagielski aTextBoxMatrix, 215*b1cdbd2cSJim Jagielski bWordWrap, 216*b1cdbd2cSJim Jagielski b3DShape, 217*b1cdbd2cSJim Jagielski false)); // #SJ# New parameter to force to clipped BlockText for SC 218*b1cdbd2cSJim Jagielski xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); 219*b1cdbd2cSJim Jagielski } 220*b1cdbd2cSJim Jagielski 221*b1cdbd2cSJim Jagielski // #119863# always append an invisible outline for the cases where no visible content exists 222*b1cdbd2cSJim Jagielski if(true) 223*b1cdbd2cSJim Jagielski { 224*b1cdbd2cSJim Jagielski const Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); 225*b1cdbd2cSJim Jagielski const basegfx::B2DRange aObjectRange( 226*b1cdbd2cSJim Jagielski aObjectBound.Left(), aObjectBound.Top(), 227*b1cdbd2cSJim Jagielski aObjectBound.Right(), aObjectBound.Bottom()); 228*b1cdbd2cSJim Jagielski 229*b1cdbd2cSJim Jagielski // create object matrix 230*b1cdbd2cSJim Jagielski const GeoStat& rGeoStat(GetCustomShapeObj().GetGeoStat()); 231*b1cdbd2cSJim Jagielski const double fShearX(rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0); 232*b1cdbd2cSJim Jagielski const double fRotate(rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0); 233*b1cdbd2cSJim Jagielski const basegfx::B2DHomMatrix aObjectMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( 234*b1cdbd2cSJim Jagielski aObjectRange.getWidth(), aObjectRange.getHeight(), fShearX, fRotate, 235*b1cdbd2cSJim Jagielski aObjectRange.getMinX(), aObjectRange.getMinY())); 236*b1cdbd2cSJim Jagielski 237*b1cdbd2cSJim Jagielski drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, 238*b1cdbd2cSJim Jagielski drawinglayer::primitive2d::createHiddenGeometryPrimitives2D( 239*b1cdbd2cSJim Jagielski false, 240*b1cdbd2cSJim Jagielski aObjectMatrix)); 241*b1cdbd2cSJim Jagielski } 242*b1cdbd2cSJim Jagielski 243*b1cdbd2cSJim Jagielski return xRetval; 244*b1cdbd2cSJim Jagielski } 245*b1cdbd2cSJim Jagielski } // end of namespace contact 246*b1cdbd2cSJim Jagielski } // end of namespace sdr 247*b1cdbd2cSJim Jagielski 248*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 249*b1cdbd2cSJim Jagielski // eof 250