xref: /AOO41X/main/drawinglayer/source/primitive2d/helplineprimitive2d.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <drawinglayer/primitive2d/helplineprimitive2d.hxx>
32*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
33*cdf0e10cSrcweir #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
34*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygonclipper.hxx>
35*cdf0e10cSrcweir #include <basegfx/tools/canvastools.hxx>
36*cdf0e10cSrcweir #include <drawinglayer/geometry/viewinformation2d.hxx>
37*cdf0e10cSrcweir #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir using namespace com::sun::star;
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir namespace drawinglayer
46*cdf0e10cSrcweir {
47*cdf0e10cSrcweir 	namespace primitive2d
48*cdf0e10cSrcweir 	{
49*cdf0e10cSrcweir 		Primitive2DSequence HelplinePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
50*cdf0e10cSrcweir 		{
51*cdf0e10cSrcweir 			std::vector< BasePrimitive2D* > aTempPrimitiveTarget;
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir 			if(!rViewInformation.getViewport().isEmpty() && !getDirection().equalZero())
54*cdf0e10cSrcweir 			{
55*cdf0e10cSrcweir 				// position to view coordinates, DashLen and DashLen in logic
56*cdf0e10cSrcweir 				const basegfx::B2DPoint aViewPosition(rViewInformation.getObjectToViewTransformation() * getPosition());
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir 				switch(getStyle())
59*cdf0e10cSrcweir 				{
60*cdf0e10cSrcweir 					default : // HELPLINESTYLE2D_POINT
61*cdf0e10cSrcweir 					{
62*cdf0e10cSrcweir 						const double fViewFixValue(15.0);
63*cdf0e10cSrcweir 						basegfx::B2DVector aNormalizedDirection(getDirection());
64*cdf0e10cSrcweir 						aNormalizedDirection.normalize();
65*cdf0e10cSrcweir 						aNormalizedDirection *= fViewFixValue;
66*cdf0e10cSrcweir 						const basegfx::B2DPoint aStartA(aViewPosition - aNormalizedDirection);
67*cdf0e10cSrcweir 						const basegfx::B2DPoint aEndA(aViewPosition + aNormalizedDirection);
68*cdf0e10cSrcweir 						basegfx::B2DPolygon aLineA;
69*cdf0e10cSrcweir 						aLineA.append(aStartA);
70*cdf0e10cSrcweir 						aLineA.append(aEndA);
71*cdf0e10cSrcweir 						aLineA.transform(rViewInformation.getInverseObjectToViewTransformation());
72*cdf0e10cSrcweir 						PolygonMarkerPrimitive2D* pNewA = new PolygonMarkerPrimitive2D(aLineA, getRGBColA(), getRGBColB(), getDiscreteDashLength());
73*cdf0e10cSrcweir 						aTempPrimitiveTarget.push_back(pNewA);
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir 						const basegfx::B2DVector aPerpendicularNormalizedDirection(basegfx::getPerpendicular(aNormalizedDirection));
76*cdf0e10cSrcweir 						const basegfx::B2DPoint aStartB(aViewPosition - aPerpendicularNormalizedDirection);
77*cdf0e10cSrcweir 						const basegfx::B2DPoint aEndB(aViewPosition + aPerpendicularNormalizedDirection);
78*cdf0e10cSrcweir 						basegfx::B2DPolygon aLineB;
79*cdf0e10cSrcweir 						aLineB.append(aStartB);
80*cdf0e10cSrcweir 						aLineB.append(aEndB);
81*cdf0e10cSrcweir 						aLineB.transform(rViewInformation.getInverseObjectToViewTransformation());
82*cdf0e10cSrcweir 						PolygonMarkerPrimitive2D* pNewB = new PolygonMarkerPrimitive2D(aLineB, getRGBColA(), getRGBColB(), getDiscreteDashLength());
83*cdf0e10cSrcweir 						aTempPrimitiveTarget.push_back(pNewB);
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir 						break;
86*cdf0e10cSrcweir 					}
87*cdf0e10cSrcweir 					case HELPLINESTYLE2D_LINE :
88*cdf0e10cSrcweir 					{
89*cdf0e10cSrcweir 						basegfx::B2DPolygon aLine;
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir 						if(basegfx::areParallel(getDirection(), basegfx::B2DVector(1.0, 0.0)))
92*cdf0e10cSrcweir 						{
93*cdf0e10cSrcweir 							// parallel to X-Axis, get cuts with Y-Axes
94*cdf0e10cSrcweir 							const double fCutA((rViewInformation.getDiscreteViewport().getMinX() - aViewPosition.getX()) / getDirection().getX());
95*cdf0e10cSrcweir 							const double fCutB((rViewInformation.getDiscreteViewport().getMaxX() - aViewPosition.getX()) / getDirection().getX());
96*cdf0e10cSrcweir 							const basegfx::B2DPoint aPosA(aViewPosition + (fCutA * getDirection()));
97*cdf0e10cSrcweir 							const basegfx::B2DPoint aPosB(aViewPosition + (fCutB * getDirection()));
98*cdf0e10cSrcweir 							const bool bBothLeft(aPosA.getX() < rViewInformation.getDiscreteViewport().getMinX() && aPosB.getX() < rViewInformation.getDiscreteViewport().getMinX());
99*cdf0e10cSrcweir 							const bool bBothRight(aPosA.getX() > rViewInformation.getDiscreteViewport().getMaxX() && aPosB.getX() < rViewInformation.getDiscreteViewport().getMaxX());
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir 							if(!bBothLeft && !bBothRight)
102*cdf0e10cSrcweir 							{
103*cdf0e10cSrcweir 								aLine.append(aPosA);
104*cdf0e10cSrcweir 								aLine.append(aPosB);
105*cdf0e10cSrcweir 							}
106*cdf0e10cSrcweir 						}
107*cdf0e10cSrcweir 						else
108*cdf0e10cSrcweir 						{
109*cdf0e10cSrcweir 							// get cuts with X-Axes
110*cdf0e10cSrcweir 							const double fCutA((rViewInformation.getDiscreteViewport().getMinY() - aViewPosition.getY()) / getDirection().getY());
111*cdf0e10cSrcweir 							const double fCutB((rViewInformation.getDiscreteViewport().getMaxY() - aViewPosition.getY()) / getDirection().getY());
112*cdf0e10cSrcweir 							const basegfx::B2DPoint aPosA(aViewPosition + (fCutA * getDirection()));
113*cdf0e10cSrcweir 							const basegfx::B2DPoint aPosB(aViewPosition + (fCutB * getDirection()));
114*cdf0e10cSrcweir 							const bool bBothAbove(aPosA.getY() < rViewInformation.getDiscreteViewport().getMinY() && aPosB.getY() < rViewInformation.getDiscreteViewport().getMinY());
115*cdf0e10cSrcweir 							const bool bBothBelow(aPosA.getY() > rViewInformation.getDiscreteViewport().getMaxY() && aPosB.getY() < rViewInformation.getDiscreteViewport().getMaxY());
116*cdf0e10cSrcweir 
117*cdf0e10cSrcweir 							if(!bBothAbove && !bBothBelow)
118*cdf0e10cSrcweir 							{
119*cdf0e10cSrcweir 								aLine.append(aPosA);
120*cdf0e10cSrcweir 								aLine.append(aPosB);
121*cdf0e10cSrcweir 							}
122*cdf0e10cSrcweir 						}
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir 						if(aLine.count())
125*cdf0e10cSrcweir 						{
126*cdf0e10cSrcweir 							// clip against visible area
127*cdf0e10cSrcweir 							const basegfx::B2DPolyPolygon aResult(basegfx::tools::clipPolygonOnRange(aLine, rViewInformation.getDiscreteViewport(), true, true));
128*cdf0e10cSrcweir 
129*cdf0e10cSrcweir 							for(sal_uInt32 a(0L); a < aResult.count(); a++)
130*cdf0e10cSrcweir 							{
131*cdf0e10cSrcweir 								basegfx::B2DPolygon aPart(aResult.getB2DPolygon(a));
132*cdf0e10cSrcweir 								aPart.transform(rViewInformation.getInverseObjectToViewTransformation());
133*cdf0e10cSrcweir 								PolygonMarkerPrimitive2D* pNew = new PolygonMarkerPrimitive2D(aPart, getRGBColA(), getRGBColB(), getDiscreteDashLength());
134*cdf0e10cSrcweir 								aTempPrimitiveTarget.push_back(pNew);
135*cdf0e10cSrcweir 							}
136*cdf0e10cSrcweir 						}
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir 						break;
139*cdf0e10cSrcweir 					}
140*cdf0e10cSrcweir 				}
141*cdf0e10cSrcweir 			}
142*cdf0e10cSrcweir 
143*cdf0e10cSrcweir 			// prepare return value
144*cdf0e10cSrcweir 			Primitive2DSequence aRetval(aTempPrimitiveTarget.size());
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < aTempPrimitiveTarget.size(); a++)
147*cdf0e10cSrcweir 			{
148*cdf0e10cSrcweir 				const Primitive2DReference xRef(aTempPrimitiveTarget[a]);
149*cdf0e10cSrcweir 				aRetval[a] = xRef;
150*cdf0e10cSrcweir 			}
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir 			return aRetval;
153*cdf0e10cSrcweir 		}
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir 		HelplinePrimitive2D::HelplinePrimitive2D(
156*cdf0e10cSrcweir 			const basegfx::B2DPoint& rPosition,
157*cdf0e10cSrcweir 			const basegfx::B2DVector& rDirection,
158*cdf0e10cSrcweir 			HelplineStyle2D eStyle,
159*cdf0e10cSrcweir 			const basegfx::BColor& rRGBColA,
160*cdf0e10cSrcweir 			const basegfx::BColor& rRGBColB,
161*cdf0e10cSrcweir 			double fDiscreteDashLength)
162*cdf0e10cSrcweir 		:	BufferedDecompositionPrimitive2D(),
163*cdf0e10cSrcweir 			maPosition(rPosition),
164*cdf0e10cSrcweir 			maDirection(rDirection),
165*cdf0e10cSrcweir 			meStyle(eStyle),
166*cdf0e10cSrcweir 			maRGBColA(rRGBColA),
167*cdf0e10cSrcweir 			maRGBColB(rRGBColB),
168*cdf0e10cSrcweir 			mfDiscreteDashLength(fDiscreteDashLength),
169*cdf0e10cSrcweir 			maLastObjectToViewTransformation(),
170*cdf0e10cSrcweir 			maLastViewport()
171*cdf0e10cSrcweir 		{
172*cdf0e10cSrcweir 		}
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir 		bool HelplinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
175*cdf0e10cSrcweir 		{
176*cdf0e10cSrcweir 			if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
177*cdf0e10cSrcweir 			{
178*cdf0e10cSrcweir 				const HelplinePrimitive2D& rCompare = (HelplinePrimitive2D&)rPrimitive;
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir 				return (getPosition() == rCompare.getPosition()
181*cdf0e10cSrcweir 					&& getDirection() == rCompare.getDirection()
182*cdf0e10cSrcweir 					&& getStyle() == rCompare.getStyle()
183*cdf0e10cSrcweir 					&& getRGBColA() == rCompare.getRGBColA()
184*cdf0e10cSrcweir 					&& getRGBColB() == rCompare.getRGBColB()
185*cdf0e10cSrcweir 					&& getDiscreteDashLength() == rCompare.getDiscreteDashLength());
186*cdf0e10cSrcweir 			}
187*cdf0e10cSrcweir 
188*cdf0e10cSrcweir 			return false;
189*cdf0e10cSrcweir 		}
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir 		Primitive2DSequence HelplinePrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
192*cdf0e10cSrcweir 		{
193*cdf0e10cSrcweir 			::osl::MutexGuard aGuard( m_aMutex );
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir 			if(getBuffered2DDecomposition().hasElements())
196*cdf0e10cSrcweir 			{
197*cdf0e10cSrcweir 				if(maLastViewport != rViewInformation.getViewport() || maLastObjectToViewTransformation != rViewInformation.getObjectToViewTransformation())
198*cdf0e10cSrcweir 				{
199*cdf0e10cSrcweir 					// conditions of last local decomposition have changed, delete
200*cdf0e10cSrcweir 					const_cast< HelplinePrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence());
201*cdf0e10cSrcweir 				}
202*cdf0e10cSrcweir 			}
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir 			if(!getBuffered2DDecomposition().hasElements())
205*cdf0e10cSrcweir 			{
206*cdf0e10cSrcweir 				// remember ViewRange and ViewTransformation
207*cdf0e10cSrcweir 				const_cast< HelplinePrimitive2D* >(this)->maLastObjectToViewTransformation = rViewInformation.getObjectToViewTransformation();
208*cdf0e10cSrcweir 				const_cast< HelplinePrimitive2D* >(this)->maLastViewport = rViewInformation.getViewport();
209*cdf0e10cSrcweir 			}
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir 			// use parent implementation
212*cdf0e10cSrcweir 			return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation);
213*cdf0e10cSrcweir 		}
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir 		// provide unique ID
216*cdf0e10cSrcweir 		ImplPrimitrive2DIDBlock(HelplinePrimitive2D, PRIMITIVE2D_ID_HELPLINEPRIMITIVE2D)
217*cdf0e10cSrcweir 
218*cdf0e10cSrcweir 	} // end of namespace primitive2d
219*cdf0e10cSrcweir } // end of namespace drawinglayer
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
222*cdf0e10cSrcweir // eof
223