1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svx.hxx" 30 31 #include <svx/sdr/contact/viewcontactofsdrpathobj.hxx> 32 #include <svx/svdopath.hxx> 33 #include <svx/sdr/primitive2d/sdrattributecreator.hxx> 34 #include <basegfx/polygon/b2dpolypolygontools.hxx> 35 #include <svx/sdr/primitive2d/sdrpathprimitive2d.hxx> 36 #include <basegfx/matrix/b2dhommatrixtools.hxx> 37 38 ////////////////////////////////////////////////////////////////////////////// 39 40 namespace sdr 41 { 42 namespace contact 43 { 44 ViewContactOfSdrPathObj::ViewContactOfSdrPathObj(SdrPathObj& rPathObj) 45 : ViewContactOfTextObj(rPathObj) 46 { 47 } 48 49 ViewContactOfSdrPathObj::~ViewContactOfSdrPathObj() 50 { 51 } 52 53 drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrPathObj::createViewIndependentPrimitive2DSequence() const 54 { 55 const SfxItemSet& rItemSet = GetPathObj().GetMergedItemSet(); 56 const drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute( 57 drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute( 58 rItemSet, 59 GetPathObj().getText(0))); 60 basegfx::B2DPolyPolygon aUnitPolyPolygon(GetPathObj().GetPathPoly()); 61 sal_uInt32 nPolyCount(aUnitPolyPolygon.count()); 62 sal_uInt32 nPointCount(0); 63 64 for(sal_uInt32 a(0); a < nPolyCount; a++) 65 { 66 nPointCount += aUnitPolyPolygon.getB2DPolygon(a).count(); 67 } 68 69 if(!nPointCount) 70 { 71 OSL_ENSURE(false, "PolyPolygon object without geometry detected, this should not be created (!)"); 72 basegfx::B2DPolygon aFallbackLine; 73 aFallbackLine.append(basegfx::B2DPoint(0.0, 0.0)); 74 aFallbackLine.append(basegfx::B2DPoint(1000.0, 1000.0)); 75 aUnitPolyPolygon = basegfx::B2DPolyPolygon(aFallbackLine); 76 77 nPolyCount = 1; 78 } 79 80 // prepare object transformation and unit polygon (direct model data) 81 basegfx::B2DHomMatrix aObjectMatrix; 82 const bool bIsLine( 83 !aUnitPolyPolygon.areControlPointsUsed() 84 && 1 == nPolyCount 85 && 2 == aUnitPolyPolygon.getB2DPolygon(0).count()); 86 87 if(bIsLine) 88 { 89 // special handling for single line mode (2 points) 90 const basegfx::B2DPolygon aSubPolygon(aUnitPolyPolygon.getB2DPolygon(0)); 91 const basegfx::B2DPoint aStart(aSubPolygon.getB2DPoint(0)); 92 const basegfx::B2DPoint aEnd(aSubPolygon.getB2DPoint(1)); 93 const basegfx::B2DVector aLine(aEnd - aStart); 94 95 // #i102548# create new unit polygon for line (horizontal) 96 basegfx::B2DPolygon aNewPolygon; 97 aNewPolygon.append(basegfx::B2DPoint(0.0, 0.0)); 98 aNewPolygon.append(basegfx::B2DPoint(1.0, 0.0)); 99 aUnitPolyPolygon.setB2DPolygon(0, aNewPolygon); 100 101 // #i102548# fill objectMatrix with rotation and offset (no shear for lines) 102 aObjectMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( 103 aLine.getLength(), 1.0, 104 0.0, 105 atan2(aLine.getY(), aLine.getX()), 106 aStart.getX(), aStart.getY()); 107 } 108 else 109 { 110 // #i102548# create unscaled, unsheared, unrotated and untranslated polygon 111 // (unit polygon) by creating the object matrix and back-transforming the polygon 112 const basegfx::B2DRange aObjectRange(basegfx::tools::getRange(aUnitPolyPolygon)); 113 const GeoStat& rGeoStat(GetPathObj().GetGeoStat()); 114 const double fWidth(aObjectRange.getWidth()); 115 const double fHeight(aObjectRange.getHeight()); 116 const double fScaleX(basegfx::fTools::equalZero(fWidth) ? 1.0 : fWidth); 117 const double fScaleY(basegfx::fTools::equalZero(fHeight) ? 1.0 : fHeight); 118 119 aObjectMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( 120 fScaleX, fScaleY, 121 rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0, 122 rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0, 123 aObjectRange.getMinX(), aObjectRange.getMinY()); 124 125 // ceate unit polygon from object's absolute path 126 basegfx::B2DHomMatrix aInverse(aObjectMatrix); 127 aInverse.invert(); 128 aUnitPolyPolygon.transform(aInverse); 129 } 130 131 // create primitive. Always create primitives to allow the decomposition of 132 // SdrPathPrimitive2D to create needed invisible elements for HitTest and/or BoundRect 133 const drawinglayer::primitive2d::Primitive2DReference xReference( 134 new drawinglayer::primitive2d::SdrPathPrimitive2D( 135 aObjectMatrix, 136 aAttribute, 137 aUnitPolyPolygon)); 138 139 return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); 140 } 141 } // end of namespace contact 142 } // end of namespace sdr 143 144 ////////////////////////////////////////////////////////////////////////////// 145 // eof 146