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