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/viewcontactofsdrpathobj.hxx> 28 #include <svx/svdopath.hxx> 29 #include <svx/sdr/primitive2d/sdrattributecreator.hxx> 30 #include <basegfx/polygon/b2dpolypolygontools.hxx> 31 #include <svx/sdr/primitive2d/sdrpathprimitive2d.hxx> 32 #include <basegfx/matrix/b2dhommatrixtools.hxx> 33 34 ////////////////////////////////////////////////////////////////////////////// 35 36 namespace sdr 37 { 38 namespace contact 39 { ViewContactOfSdrPathObj(SdrPathObj & rPathObj)40 ViewContactOfSdrPathObj::ViewContactOfSdrPathObj(SdrPathObj& rPathObj) 41 : ViewContactOfTextObj(rPathObj) 42 { 43 } 44 ~ViewContactOfSdrPathObj()45 ViewContactOfSdrPathObj::~ViewContactOfSdrPathObj() 46 { 47 } 48 createViewIndependentPrimitive2DSequence() const49 drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrPathObj::createViewIndependentPrimitive2DSequence() const 50 { 51 const SfxItemSet& rItemSet = GetPathObj().GetMergedItemSet(); 52 const drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute( 53 drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute( 54 rItemSet, 55 GetPathObj().getText(0), 56 false)); 57 basegfx::B2DPolyPolygon aUnitPolyPolygon(GetPathObj().GetPathPoly()); 58 sal_uInt32 nPolyCount(aUnitPolyPolygon.count()); 59 sal_uInt32 nPointCount(0); 60 61 for(sal_uInt32 a(0); a < nPolyCount; a++) 62 { 63 nPointCount += aUnitPolyPolygon.getB2DPolygon(a).count(); 64 } 65 66 if(!nPointCount) 67 { 68 OSL_ENSURE(false, "PolyPolygon object without geometry detected, this should not be created (!)"); 69 basegfx::B2DPolygon aFallbackLine; 70 aFallbackLine.append(basegfx::B2DPoint(0.0, 0.0)); 71 aFallbackLine.append(basegfx::B2DPoint(1000.0, 1000.0)); 72 aUnitPolyPolygon = basegfx::B2DPolyPolygon(aFallbackLine); 73 74 nPolyCount = 1; 75 } 76 77 // prepare object transformation and unit polygon (direct model data) 78 basegfx::B2DHomMatrix aObjectMatrix; 79 const bool bIsLine( 80 !aUnitPolyPolygon.areControlPointsUsed() 81 && 1 == nPolyCount 82 && 2 == aUnitPolyPolygon.getB2DPolygon(0).count()); 83 84 if(bIsLine) 85 { 86 // special handling for single line mode (2 points) 87 const basegfx::B2DPolygon aSubPolygon(aUnitPolyPolygon.getB2DPolygon(0)); 88 const basegfx::B2DPoint aStart(aSubPolygon.getB2DPoint(0)); 89 const basegfx::B2DPoint aEnd(aSubPolygon.getB2DPoint(1)); 90 const basegfx::B2DVector aLine(aEnd - aStart); 91 92 // #i102548# create new unit polygon for line (horizontal) 93 basegfx::B2DPolygon aNewPolygon; 94 aNewPolygon.append(basegfx::B2DPoint(0.0, 0.0)); 95 aNewPolygon.append(basegfx::B2DPoint(1.0, 0.0)); 96 aUnitPolyPolygon.setB2DPolygon(0, aNewPolygon); 97 98 // #i102548# fill objectMatrix with rotation and offset (no shear for lines) 99 aObjectMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( 100 aLine.getLength(), 1.0, 101 0.0, 102 atan2(aLine.getY(), aLine.getX()), 103 aStart.getX(), aStart.getY()); 104 } 105 else 106 { 107 // #i102548# create unscaled, unsheared, unrotated and untranslated polygon 108 // (unit polygon) by creating the object matrix and back-transforming the polygon 109 const basegfx::B2DRange aObjectRange(basegfx::tools::getRange(aUnitPolyPolygon)); 110 const GeoStat& rGeoStat(GetPathObj().GetGeoStat()); 111 const double fWidth(aObjectRange.getWidth()); 112 const double fHeight(aObjectRange.getHeight()); 113 const double fScaleX(basegfx::fTools::equalZero(fWidth) ? 1.0 : fWidth); 114 const double fScaleY(basegfx::fTools::equalZero(fHeight) ? 1.0 : fHeight); 115 116 aObjectMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( 117 fScaleX, fScaleY, 118 rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0, 119 rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0, 120 aObjectRange.getMinX(), aObjectRange.getMinY()); 121 122 // ceate unit polygon from object's absolute path 123 basegfx::B2DHomMatrix aInverse(aObjectMatrix); 124 aInverse.invert(); 125 aUnitPolyPolygon.transform(aInverse); 126 } 127 128 // create primitive. Always create primitives to allow the decomposition of 129 // SdrPathPrimitive2D to create needed invisible elements for HitTest and/or BoundRect 130 const drawinglayer::primitive2d::Primitive2DReference xReference( 131 new drawinglayer::primitive2d::SdrPathPrimitive2D( 132 aObjectMatrix, 133 aAttribute, 134 aUnitPolyPolygon)); 135 136 return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); 137 } 138 } // end of namespace contact 139 } // end of namespace sdr 140 141 ////////////////////////////////////////////////////////////////////////////// 142 // eof 143