Update ooo320-m1
[ooovba.git] / drawinglayer / source / primitive2d / gridprimitive2d.cxx
blob14a3398697780ce83c6e23e4f6d229f284500872
1 /*************************************************************************
3 * OpenOffice.org - a multi-platform office productivity suite
5 * $RCSfile: gridprimitive2d.cxx,v $
7 * $Revision: 1.10 $
9 * last change: $Author: aw $ $Date: 2008-06-24 15:31:08 $
11 * The Contents of this file are made available subject to
12 * the terms of GNU Lesser General Public License Version 2.1.
15 * GNU Lesser General Public License Version 2.1
16 * =============================================
17 * Copyright 2005 by Sun Microsystems, Inc.
18 * 901 San Antonio Road, Palo Alto, CA 94303, USA
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License version 2.1, as published by the Free Software Foundation.
24 * This library is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * Lesser General Public License for more details.
29 * You should have received a copy of the GNU Lesser General Public
30 * License along with this library; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32 * MA 02111-1307 USA
34 ************************************************************************/
36 // MARKER(update_precomp.py): autogen include statement, do not remove
37 #include "precompiled_drawinglayer.hxx"
39 #include <drawinglayer/primitive2d/gridprimitive2d.hxx>
40 #include <basegfx/tools/canvastools.hxx>
41 #include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx>
42 #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx>
43 #include <drawinglayer/geometry/viewinformation2d.hxx>
44 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
46 //////////////////////////////////////////////////////////////////////////////
48 using namespace com::sun::star;
50 //////////////////////////////////////////////////////////////////////////////
52 namespace drawinglayer
54 namespace primitive2d
56 Primitive2DSequence GridPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const
58 Primitive2DSequence aRetval;
60 if(!rViewInformation.getViewport().isEmpty() && getWidth() > 0.0 && getHeight() > 0.0)
62 // decompose grid matrix to get logic size
63 basegfx::B2DVector aScale, aTranslate;
64 double fRotate, fShearX;
65 getTransform().decompose(aScale, aTranslate, fRotate, fShearX);
67 // create grid matrix which transforms from scaled logic to view
68 basegfx::B2DHomMatrix aRST;
69 aRST.shearX(fShearX);
70 aRST.rotate(fRotate);
71 aRST.translate(aTranslate.getX(), aTranslate.getY());
72 aRST *= rViewInformation.getObjectToViewTransformation();
74 // get step widths
75 double fStepX(getWidth());
76 double fStepY(getHeight());
77 const double fMinimalStep(10.0);
79 // guarantee a step width of 10.0
80 if(basegfx::fTools::less(fStepX, fMinimalStep))
82 fStepX = fMinimalStep;
85 if(basegfx::fTools::less(fStepY, fMinimalStep))
87 fStepY = fMinimalStep;
90 // get relative distances in view coordinates
91 double fViewStepX((rViewInformation.getObjectToViewTransformation() * basegfx::B2DVector(fStepX, 0.0)).getLength());
92 double fViewStepY((rViewInformation.getObjectToViewTransformation() * basegfx::B2DVector(0.0, fStepY)).getLength());
93 double fSmallStepX(1.0), fViewSmallStepX(1.0), fSmallStepY(1.0), fViewSmallStepY(1.0);
94 sal_uInt32 nSmallStepsX(0L), nSmallStepsY(0L);
96 // setup subdivisions
97 if(getSubdivisionsX())
99 fSmallStepX = fStepX / getSubdivisionsX();
100 fViewSmallStepX = fViewStepX / getSubdivisionsX();
103 if(getSubdivisionsY())
105 fSmallStepY = fStepY / getSubdivisionsY();
106 fViewSmallStepY = fViewStepY / getSubdivisionsY();
109 // correct step width
110 while(fViewStepX < getSmallestViewDistance())
112 fViewStepX *= 2.0;
113 fStepX *= 2.0;
116 while(fViewStepY < getSmallestViewDistance())
118 fViewStepY *= 2.0;
119 fStepY *= 2.0;
122 // correct small step width
123 if(getSubdivisionsX())
125 while(fViewSmallStepX < getSmallestSubdivisionViewDistance())
127 fViewSmallStepX *= 2.0;
128 fSmallStepX *= 2.0;
131 nSmallStepsX = (sal_uInt32)(fStepX / fSmallStepX);
134 if(getSubdivisionsY())
136 while(fViewSmallStepY < getSmallestSubdivisionViewDistance())
138 fViewSmallStepY *= 2.0;
139 fSmallStepY *= 2.0;
142 nSmallStepsY = (sal_uInt32)(fStepY / fSmallStepY);
145 // prepare point vectors for point and cross markers
146 std::vector< basegfx::B2DPoint > aPositionsPoint;
147 std::vector< basegfx::B2DPoint > aPositionsCross;
149 for(double fX(0.0); fX < aScale.getX(); fX += fStepX)
151 const bool bXZero(basegfx::fTools::equalZero(fX));
153 for(double fY(0.0); fY < aScale.getY(); fY += fStepY)
155 const bool bYZero(basegfx::fTools::equalZero(fY));
157 if(!bXZero && !bYZero)
159 // get discrete position and test against 3x3 area surrounding it
160 // since it's a cross
161 const double fHalfCrossSize(3.0 * 0.5);
162 const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fX, fY));
163 const basegfx::B2DRange aDiscreteRangeCross(
164 aViewPos.getX() - fHalfCrossSize, aViewPos.getY() - fHalfCrossSize,
165 aViewPos.getX() + fHalfCrossSize, aViewPos.getY() + fHalfCrossSize);
167 if(rViewInformation.getDiscreteViewport().overlaps(aDiscreteRangeCross))
169 const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos);
170 aPositionsCross.push_back(aLogicPos);
174 if(getSubdivisionsX() && !bYZero)
176 double fF(fX + fSmallStepX);
178 for(sal_uInt32 a(1L); a < nSmallStepsX && fF < aScale.getX(); a++, fF += fSmallStepX)
180 const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fF, fY));
182 if(rViewInformation.getDiscreteViewport().isInside(aViewPos))
184 const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos);
185 aPositionsPoint.push_back(aLogicPos);
190 if(getSubdivisionsY() && !bXZero)
192 double fF(fY + fSmallStepY);
194 for(sal_uInt32 a(1L); a < nSmallStepsY && fF < aScale.getY(); a++, fF += fSmallStepY)
196 const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fX, fF));
198 if(rViewInformation.getDiscreteViewport().isInside(aViewPos))
200 const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos);
201 aPositionsPoint.push_back(aLogicPos);
208 // prepare return value
209 const sal_uInt32 nCountPoint(aPositionsPoint.size());
210 const sal_uInt32 nCountCross(aPositionsCross.size());
211 const sal_uInt32 nRetvalCount((nCountPoint ? 1 : 0) + (nCountCross ? 1 : 0));
212 sal_uInt32 nInsertCounter(0);
214 aRetval.realloc(nRetvalCount);
216 // add PointArrayPrimitive2D if point markers were added
217 if(nCountPoint)
219 aRetval[nInsertCounter++] = Primitive2DReference(new PointArrayPrimitive2D(aPositionsPoint, getBColor()));
222 // add MarkerArrayPrimitive2D if cross markers were added
223 if(nCountCross)
225 if(!getSubdivisionsX() && !getSubdivisionsY())
227 // no subdivisions, so fall back to points at grid positions, no need to
228 // visualize a difference between divisions and sub-divisions
229 aRetval[nInsertCounter++] = Primitive2DReference(new PointArrayPrimitive2D(aPositionsCross, getBColor()));
231 else
233 aRetval[nInsertCounter++] = Primitive2DReference(new MarkerArrayPrimitive2D(aPositionsCross, getCrossMarker()));
238 return aRetval;
241 GridPrimitive2D::GridPrimitive2D(
242 const basegfx::B2DHomMatrix& rTransform,
243 double fWidth,
244 double fHeight,
245 double fSmallestViewDistance,
246 double fSmallestSubdivisionViewDistance,
247 sal_uInt32 nSubdivisionsX,
248 sal_uInt32 nSubdivisionsY,
249 const basegfx::BColor& rBColor,
250 const BitmapEx& rCrossMarker)
251 : BasePrimitive2D(),
252 maTransform(rTransform),
253 mfWidth(fWidth),
254 mfHeight(fHeight),
255 mfSmallestViewDistance(fSmallestViewDistance),
256 mfSmallestSubdivisionViewDistance(fSmallestSubdivisionViewDistance),
257 mnSubdivisionsX(nSubdivisionsX),
258 mnSubdivisionsY(nSubdivisionsY),
259 maBColor(rBColor),
260 maCrossMarker(rCrossMarker),
261 maLastObjectToViewTransformation(),
262 maLastViewport()
266 bool GridPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
268 if(BasePrimitive2D::operator==(rPrimitive))
270 const GridPrimitive2D& rCompare = (GridPrimitive2D&)rPrimitive;
272 return (getTransform() == rCompare.getTransform()
273 && getWidth() == rCompare.getWidth()
274 && getHeight() == rCompare.getHeight()
275 && getSmallestViewDistance() == rCompare.getSmallestViewDistance()
276 && getSmallestSubdivisionViewDistance() == rCompare.getSmallestSubdivisionViewDistance()
277 && getSubdivisionsX() == rCompare.getSubdivisionsX()
278 && getSubdivisionsY() == rCompare.getSubdivisionsY()
279 && getBColor() == rCompare.getBColor()
280 && getCrossMarker() == rCompare.getCrossMarker());
283 return false;
286 basegfx::B2DRange GridPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
288 // get object's range
289 basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0);
290 aUnitRange.transform(getTransform());
292 // intersect with visible part
293 aUnitRange.intersect(rViewInformation.getViewport());
295 return aUnitRange;
298 Primitive2DSequence GridPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
300 ::osl::MutexGuard aGuard( m_aMutex );
302 if(getLocalDecomposition().hasElements())
304 if(maLastViewport != rViewInformation.getViewport() || maLastObjectToViewTransformation != rViewInformation.getObjectToViewTransformation())
306 // conditions of last local decomposition have changed, delete
307 const_cast< GridPrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence());
311 if(!getLocalDecomposition().hasElements())
313 // remember ViewRange and ViewTransformation
314 const_cast< GridPrimitive2D* >(this)->maLastObjectToViewTransformation = rViewInformation.getObjectToViewTransformation();
315 const_cast< GridPrimitive2D* >(this)->maLastViewport = rViewInformation.getViewport();
318 // use parent implementation
319 return BasePrimitive2D::get2DDecomposition(rViewInformation);
322 // provide unique ID
323 ImplPrimitrive2DIDBlock(GridPrimitive2D, PRIMITIVE2D_ID_GRIDPRIMITIVE2D)
325 } // end of namespace primitive2d
326 } // end of namespace drawinglayer
328 //////////////////////////////////////////////////////////////////////////////
329 // eof