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_drawinglayer.hxx" 30 31 #include <drawinglayer/primitive2d/helplineprimitive2d.hxx> 32 #include <basegfx/polygon/b2dpolygon.hxx> 33 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 34 #include <basegfx/polygon/b2dpolygonclipper.hxx> 35 #include <basegfx/tools/canvastools.hxx> 36 #include <drawinglayer/geometry/viewinformation2d.hxx> 37 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 38 39 ////////////////////////////////////////////////////////////////////////////// 40 41 using namespace com::sun::star; 42 43 ////////////////////////////////////////////////////////////////////////////// 44 45 namespace drawinglayer 46 { 47 namespace primitive2d 48 { 49 Primitive2DSequence HelplinePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const 50 { 51 std::vector< BasePrimitive2D* > aTempPrimitiveTarget; 52 53 if(!rViewInformation.getViewport().isEmpty() && !getDirection().equalZero()) 54 { 55 // position to view coordinates, DashLen and DashLen in logic 56 const basegfx::B2DPoint aViewPosition(rViewInformation.getObjectToViewTransformation() * getPosition()); 57 58 switch(getStyle()) 59 { 60 default : // HELPLINESTYLE2D_POINT 61 { 62 const double fViewFixValue(15.0); 63 basegfx::B2DVector aNormalizedDirection(getDirection()); 64 aNormalizedDirection.normalize(); 65 aNormalizedDirection *= fViewFixValue; 66 const basegfx::B2DPoint aStartA(aViewPosition - aNormalizedDirection); 67 const basegfx::B2DPoint aEndA(aViewPosition + aNormalizedDirection); 68 basegfx::B2DPolygon aLineA; 69 aLineA.append(aStartA); 70 aLineA.append(aEndA); 71 aLineA.transform(rViewInformation.getInverseObjectToViewTransformation()); 72 PolygonMarkerPrimitive2D* pNewA = new PolygonMarkerPrimitive2D(aLineA, getRGBColA(), getRGBColB(), getDiscreteDashLength()); 73 aTempPrimitiveTarget.push_back(pNewA); 74 75 const basegfx::B2DVector aPerpendicularNormalizedDirection(basegfx::getPerpendicular(aNormalizedDirection)); 76 const basegfx::B2DPoint aStartB(aViewPosition - aPerpendicularNormalizedDirection); 77 const basegfx::B2DPoint aEndB(aViewPosition + aPerpendicularNormalizedDirection); 78 basegfx::B2DPolygon aLineB; 79 aLineB.append(aStartB); 80 aLineB.append(aEndB); 81 aLineB.transform(rViewInformation.getInverseObjectToViewTransformation()); 82 PolygonMarkerPrimitive2D* pNewB = new PolygonMarkerPrimitive2D(aLineB, getRGBColA(), getRGBColB(), getDiscreteDashLength()); 83 aTempPrimitiveTarget.push_back(pNewB); 84 85 break; 86 } 87 case HELPLINESTYLE2D_LINE : 88 { 89 basegfx::B2DPolygon aLine; 90 91 if(basegfx::areParallel(getDirection(), basegfx::B2DVector(1.0, 0.0))) 92 { 93 // parallel to X-Axis, get cuts with Y-Axes 94 const double fCutA((rViewInformation.getDiscreteViewport().getMinX() - aViewPosition.getX()) / getDirection().getX()); 95 const double fCutB((rViewInformation.getDiscreteViewport().getMaxX() - aViewPosition.getX()) / getDirection().getX()); 96 const basegfx::B2DPoint aPosA(aViewPosition + (fCutA * getDirection())); 97 const basegfx::B2DPoint aPosB(aViewPosition + (fCutB * getDirection())); 98 const bool bBothLeft(aPosA.getX() < rViewInformation.getDiscreteViewport().getMinX() && aPosB.getX() < rViewInformation.getDiscreteViewport().getMinX()); 99 const bool bBothRight(aPosA.getX() > rViewInformation.getDiscreteViewport().getMaxX() && aPosB.getX() < rViewInformation.getDiscreteViewport().getMaxX()); 100 101 if(!bBothLeft && !bBothRight) 102 { 103 aLine.append(aPosA); 104 aLine.append(aPosB); 105 } 106 } 107 else 108 { 109 // get cuts with X-Axes 110 const double fCutA((rViewInformation.getDiscreteViewport().getMinY() - aViewPosition.getY()) / getDirection().getY()); 111 const double fCutB((rViewInformation.getDiscreteViewport().getMaxY() - aViewPosition.getY()) / getDirection().getY()); 112 const basegfx::B2DPoint aPosA(aViewPosition + (fCutA * getDirection())); 113 const basegfx::B2DPoint aPosB(aViewPosition + (fCutB * getDirection())); 114 const bool bBothAbove(aPosA.getY() < rViewInformation.getDiscreteViewport().getMinY() && aPosB.getY() < rViewInformation.getDiscreteViewport().getMinY()); 115 const bool bBothBelow(aPosA.getY() > rViewInformation.getDiscreteViewport().getMaxY() && aPosB.getY() < rViewInformation.getDiscreteViewport().getMaxY()); 116 117 if(!bBothAbove && !bBothBelow) 118 { 119 aLine.append(aPosA); 120 aLine.append(aPosB); 121 } 122 } 123 124 if(aLine.count()) 125 { 126 // clip against visible area 127 const basegfx::B2DPolyPolygon aResult(basegfx::tools::clipPolygonOnRange(aLine, rViewInformation.getDiscreteViewport(), true, true)); 128 129 for(sal_uInt32 a(0L); a < aResult.count(); a++) 130 { 131 basegfx::B2DPolygon aPart(aResult.getB2DPolygon(a)); 132 aPart.transform(rViewInformation.getInverseObjectToViewTransformation()); 133 PolygonMarkerPrimitive2D* pNew = new PolygonMarkerPrimitive2D(aPart, getRGBColA(), getRGBColB(), getDiscreteDashLength()); 134 aTempPrimitiveTarget.push_back(pNew); 135 } 136 } 137 138 break; 139 } 140 } 141 } 142 143 // prepare return value 144 Primitive2DSequence aRetval(aTempPrimitiveTarget.size()); 145 146 for(sal_uInt32 a(0L); a < aTempPrimitiveTarget.size(); a++) 147 { 148 const Primitive2DReference xRef(aTempPrimitiveTarget[a]); 149 aRetval[a] = xRef; 150 } 151 152 return aRetval; 153 } 154 155 HelplinePrimitive2D::HelplinePrimitive2D( 156 const basegfx::B2DPoint& rPosition, 157 const basegfx::B2DVector& rDirection, 158 HelplineStyle2D eStyle, 159 const basegfx::BColor& rRGBColA, 160 const basegfx::BColor& rRGBColB, 161 double fDiscreteDashLength) 162 : BufferedDecompositionPrimitive2D(), 163 maPosition(rPosition), 164 maDirection(rDirection), 165 meStyle(eStyle), 166 maRGBColA(rRGBColA), 167 maRGBColB(rRGBColB), 168 mfDiscreteDashLength(fDiscreteDashLength), 169 maLastObjectToViewTransformation(), 170 maLastViewport() 171 { 172 } 173 174 bool HelplinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 175 { 176 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 177 { 178 const HelplinePrimitive2D& rCompare = (HelplinePrimitive2D&)rPrimitive; 179 180 return (getPosition() == rCompare.getPosition() 181 && getDirection() == rCompare.getDirection() 182 && getStyle() == rCompare.getStyle() 183 && getRGBColA() == rCompare.getRGBColA() 184 && getRGBColB() == rCompare.getRGBColB() 185 && getDiscreteDashLength() == rCompare.getDiscreteDashLength()); 186 } 187 188 return false; 189 } 190 191 Primitive2DSequence HelplinePrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const 192 { 193 ::osl::MutexGuard aGuard( m_aMutex ); 194 195 if(getBuffered2DDecomposition().hasElements()) 196 { 197 if(maLastViewport != rViewInformation.getViewport() || maLastObjectToViewTransformation != rViewInformation.getObjectToViewTransformation()) 198 { 199 // conditions of last local decomposition have changed, delete 200 const_cast< HelplinePrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); 201 } 202 } 203 204 if(!getBuffered2DDecomposition().hasElements()) 205 { 206 // remember ViewRange and ViewTransformation 207 const_cast< HelplinePrimitive2D* >(this)->maLastObjectToViewTransformation = rViewInformation.getObjectToViewTransformation(); 208 const_cast< HelplinePrimitive2D* >(this)->maLastViewport = rViewInformation.getViewport(); 209 } 210 211 // use parent implementation 212 return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); 213 } 214 215 // provide unique ID 216 ImplPrimitrive2DIDBlock(HelplinePrimitive2D, PRIMITIVE2D_ID_HELPLINEPRIMITIVE2D) 217 218 } // end of namespace primitive2d 219 } // end of namespace drawinglayer 220 221 ////////////////////////////////////////////////////////////////////////////// 222 // eof 223