xref: /trunk/main/drawinglayer/source/primitive2d/gridprimitive2d.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1464702f4SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3464702f4SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4464702f4SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5464702f4SAndrew Rist  * distributed with this work for additional information
6464702f4SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7464702f4SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8464702f4SAndrew Rist  * "License"); you may not use this file except in compliance
9464702f4SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11464702f4SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13464702f4SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14464702f4SAndrew Rist  * software distributed under the License is distributed on an
15464702f4SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16464702f4SAndrew Rist  * KIND, either express or implied.  See the License for the
17464702f4SAndrew Rist  * specific language governing permissions and limitations
18464702f4SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20464702f4SAndrew Rist  *************************************************************/
21464702f4SAndrew Rist 
22464702f4SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <drawinglayer/primitive2d/gridprimitive2d.hxx>
28cdf0e10cSrcweir #include <basegfx/tools/canvastools.hxx>
29cdf0e10cSrcweir #include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx>
30cdf0e10cSrcweir #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx>
31cdf0e10cSrcweir #include <drawinglayer/geometry/viewinformation2d.hxx>
32cdf0e10cSrcweir #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
33cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrixtools.hxx>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
36cdf0e10cSrcweir 
37cdf0e10cSrcweir using namespace com::sun::star;
38cdf0e10cSrcweir 
39cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
40cdf0e10cSrcweir 
41cdf0e10cSrcweir namespace drawinglayer
42cdf0e10cSrcweir {
43cdf0e10cSrcweir     namespace primitive2d
44cdf0e10cSrcweir     {
create2DDecomposition(const geometry::ViewInformation2D & rViewInformation) const45cdf0e10cSrcweir         Primitive2DSequence GridPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
46cdf0e10cSrcweir         {
47cdf0e10cSrcweir             Primitive2DSequence aRetval;
48cdf0e10cSrcweir 
49cdf0e10cSrcweir             if(!rViewInformation.getViewport().isEmpty() && getWidth() > 0.0 && getHeight() > 0.0)
50cdf0e10cSrcweir             {
51cdf0e10cSrcweir                 // decompose grid matrix to get logic size
52cdf0e10cSrcweir                 basegfx::B2DVector aScale, aTranslate;
53cdf0e10cSrcweir                 double fRotate, fShearX;
54cdf0e10cSrcweir                 getTransform().decompose(aScale, aTranslate, fRotate, fShearX);
55cdf0e10cSrcweir 
56cdf0e10cSrcweir                 // create grid matrix which transforms from scaled logic to view
57cdf0e10cSrcweir                 basegfx::B2DHomMatrix aRST(basegfx::tools::createShearXRotateTranslateB2DHomMatrix(
58cdf0e10cSrcweir                     fShearX, fRotate, aTranslate.getX(), aTranslate.getY()));
59cdf0e10cSrcweir                 aRST *= rViewInformation.getObjectToViewTransformation();
60cdf0e10cSrcweir 
61cdf0e10cSrcweir                 // get step widths
62cdf0e10cSrcweir                 double fStepX(getWidth());
63cdf0e10cSrcweir                 double fStepY(getHeight());
64cdf0e10cSrcweir                 const double fMinimalStep(10.0);
65cdf0e10cSrcweir 
66cdf0e10cSrcweir                 // guarantee a step width of 10.0
67cdf0e10cSrcweir                 if(basegfx::fTools::less(fStepX, fMinimalStep))
68cdf0e10cSrcweir                 {
69cdf0e10cSrcweir                     fStepX = fMinimalStep;
70cdf0e10cSrcweir                 }
71cdf0e10cSrcweir 
72cdf0e10cSrcweir                 if(basegfx::fTools::less(fStepY, fMinimalStep))
73cdf0e10cSrcweir                 {
74cdf0e10cSrcweir                     fStepY = fMinimalStep;
75cdf0e10cSrcweir                 }
76cdf0e10cSrcweir 
77cdf0e10cSrcweir                 // get relative distances in view coordinates
78cdf0e10cSrcweir                 double fViewStepX((rViewInformation.getObjectToViewTransformation() * basegfx::B2DVector(fStepX, 0.0)).getLength());
79cdf0e10cSrcweir                 double fViewStepY((rViewInformation.getObjectToViewTransformation() * basegfx::B2DVector(0.0, fStepY)).getLength());
80cdf0e10cSrcweir                 double fSmallStepX(1.0), fViewSmallStepX(1.0), fSmallStepY(1.0), fViewSmallStepY(1.0);
81cdf0e10cSrcweir                 sal_uInt32 nSmallStepsX(0L), nSmallStepsY(0L);
82cdf0e10cSrcweir 
83cdf0e10cSrcweir                 // setup subdivisions
84cdf0e10cSrcweir                 if(getSubdivisionsX())
85cdf0e10cSrcweir                 {
86cdf0e10cSrcweir                     fSmallStepX = fStepX / getSubdivisionsX();
87cdf0e10cSrcweir                     fViewSmallStepX = fViewStepX / getSubdivisionsX();
88cdf0e10cSrcweir                 }
89cdf0e10cSrcweir 
90cdf0e10cSrcweir                 if(getSubdivisionsY())
91cdf0e10cSrcweir                 {
92cdf0e10cSrcweir                     fSmallStepY = fStepY / getSubdivisionsY();
93cdf0e10cSrcweir                     fViewSmallStepY = fViewStepY / getSubdivisionsY();
94cdf0e10cSrcweir                 }
95cdf0e10cSrcweir 
96cdf0e10cSrcweir                 // correct step width
97cdf0e10cSrcweir                 while(fViewStepX < getSmallestViewDistance())
98cdf0e10cSrcweir                 {
99cdf0e10cSrcweir                     fViewStepX *= 2.0;
100cdf0e10cSrcweir                     fStepX *= 2.0;
101cdf0e10cSrcweir                 }
102cdf0e10cSrcweir 
103cdf0e10cSrcweir                 while(fViewStepY < getSmallestViewDistance())
104cdf0e10cSrcweir                 {
105cdf0e10cSrcweir                     fViewStepY *= 2.0;
106cdf0e10cSrcweir                     fStepY *= 2.0;
107cdf0e10cSrcweir                 }
108cdf0e10cSrcweir 
109cdf0e10cSrcweir                 // correct small step width
110cdf0e10cSrcweir                 if(getSubdivisionsX())
111cdf0e10cSrcweir                 {
112cdf0e10cSrcweir                     while(fViewSmallStepX < getSmallestSubdivisionViewDistance())
113cdf0e10cSrcweir                     {
114cdf0e10cSrcweir                         fViewSmallStepX *= 2.0;
115cdf0e10cSrcweir                         fSmallStepX *= 2.0;
116cdf0e10cSrcweir                     }
117cdf0e10cSrcweir 
118cdf0e10cSrcweir                     nSmallStepsX = (sal_uInt32)(fStepX / fSmallStepX);
119cdf0e10cSrcweir                 }
120cdf0e10cSrcweir 
121cdf0e10cSrcweir                 if(getSubdivisionsY())
122cdf0e10cSrcweir                 {
123cdf0e10cSrcweir                     while(fViewSmallStepY < getSmallestSubdivisionViewDistance())
124cdf0e10cSrcweir                     {
125cdf0e10cSrcweir                         fViewSmallStepY *= 2.0;
126cdf0e10cSrcweir                         fSmallStepY *= 2.0;
127cdf0e10cSrcweir                     }
128cdf0e10cSrcweir 
129cdf0e10cSrcweir                     nSmallStepsY = (sal_uInt32)(fStepY / fSmallStepY);
130cdf0e10cSrcweir                 }
131cdf0e10cSrcweir 
132*2a27d9caSArmin Le Grand                 // calculate extended viewport in which grid points may lie at all
133*2a27d9caSArmin Le Grand                 basegfx::B2DRange aExtendedViewport;
134*2a27d9caSArmin Le Grand 
135*2a27d9caSArmin Le Grand                 if(rViewInformation.getDiscreteViewport().isEmpty())
136*2a27d9caSArmin Le Grand                 {
137*2a27d9caSArmin Le Grand                     // not set, use logic size to travel over all potentioal grid points
138*2a27d9caSArmin Le Grand                     aExtendedViewport = basegfx::B2DRange(0.0, 0.0, aScale.getX(), aScale.getY());
139*2a27d9caSArmin Le Grand                 }
140*2a27d9caSArmin Le Grand                 else
141*2a27d9caSArmin Le Grand                 {
142*2a27d9caSArmin Le Grand                     // transform unit range to discrete view
143*2a27d9caSArmin Le Grand                     aExtendedViewport = basegfx::B2DRange(0.0, 0.0, 1.0, 1.0);
144*2a27d9caSArmin Le Grand                     basegfx::B2DHomMatrix aTrans(rViewInformation.getObjectToViewTransformation() * getTransform());
145*2a27d9caSArmin Le Grand                     aExtendedViewport.transform(aTrans);
146*2a27d9caSArmin Le Grand 
147*2a27d9caSArmin Le Grand                     // intersect with visible part
148*2a27d9caSArmin Le Grand                     aExtendedViewport.intersect(rViewInformation.getDiscreteViewport());
149*2a27d9caSArmin Le Grand 
150*2a27d9caSArmin Le Grand                     if(!aExtendedViewport.isEmpty())
151*2a27d9caSArmin Le Grand                     {
152*2a27d9caSArmin Le Grand                         // convert back and apply scale
153*2a27d9caSArmin Le Grand                         aTrans.invert();
154*2a27d9caSArmin Le Grand                         aTrans.scale(aScale.getX(), aScale.getY());
155*2a27d9caSArmin Le Grand                         aExtendedViewport.transform(aTrans);
156*2a27d9caSArmin Le Grand 
157*2a27d9caSArmin Le Grand                         // crop start/end in X/Y to multiples of logical step width
158*2a27d9caSArmin Le Grand                         const double fHalfCrossSize((rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(3.0, 0.0)).getLength());
159*2a27d9caSArmin Le Grand                         const double fMinX(floor((aExtendedViewport.getMinX() - fHalfCrossSize) / fStepX) * fStepX);
160*2a27d9caSArmin Le Grand                         const double fMaxX(ceil((aExtendedViewport.getMaxX() + fHalfCrossSize) / fStepX) * fStepX);
161*2a27d9caSArmin Le Grand                         const double fMinY(floor((aExtendedViewport.getMinY() - fHalfCrossSize) / fStepY) * fStepY);
162*2a27d9caSArmin Le Grand                         const double fMaxY(ceil((aExtendedViewport.getMaxY() + fHalfCrossSize) / fStepY) * fStepY);
163*2a27d9caSArmin Le Grand 
164*2a27d9caSArmin Le Grand                         // put to aExtendedViewport and crop on object logic size
165*2a27d9caSArmin Le Grand                         aExtendedViewport = basegfx::B2DRange(
166*2a27d9caSArmin Le Grand                             std::max(fMinX, 0.0),
167*2a27d9caSArmin Le Grand                             std::max(fMinY, 0.0),
168*2a27d9caSArmin Le Grand                             std::min(fMaxX, aScale.getX()),
169*2a27d9caSArmin Le Grand                             std::min(fMaxY, aScale.getY()));
170*2a27d9caSArmin Le Grand                     }
171*2a27d9caSArmin Le Grand                 }
172*2a27d9caSArmin Le Grand 
173*2a27d9caSArmin Le Grand                 if(!aExtendedViewport.isEmpty())
174*2a27d9caSArmin Le Grand                 {
175cdf0e10cSrcweir                     // prepare point vectors for point and cross markers
176cdf0e10cSrcweir                     std::vector< basegfx::B2DPoint > aPositionsPoint;
177cdf0e10cSrcweir                     std::vector< basegfx::B2DPoint > aPositionsCross;
178cdf0e10cSrcweir 
179*2a27d9caSArmin Le Grand                     for(double fX(aExtendedViewport.getMinX()); fX < aExtendedViewport.getMaxX(); fX += fStepX)
180cdf0e10cSrcweir                     {
181cdf0e10cSrcweir                         const bool bXZero(basegfx::fTools::equalZero(fX));
182cdf0e10cSrcweir 
183*2a27d9caSArmin Le Grand                         for(double fY(aExtendedViewport.getMinY()); fY < aExtendedViewport.getMaxY(); fY += fStepY)
184cdf0e10cSrcweir                         {
185cdf0e10cSrcweir                             const bool bYZero(basegfx::fTools::equalZero(fY));
186cdf0e10cSrcweir 
187cdf0e10cSrcweir                             if(!bXZero && !bYZero)
188cdf0e10cSrcweir                             {
189cdf0e10cSrcweir                                 // get discrete position and test against 3x3 area surrounding it
190cdf0e10cSrcweir                                 // since it's a cross
191cdf0e10cSrcweir                                 const double fHalfCrossSize(3.0 * 0.5);
192cdf0e10cSrcweir                                 const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fX, fY));
193cdf0e10cSrcweir                                 const basegfx::B2DRange aDiscreteRangeCross(
194cdf0e10cSrcweir                                     aViewPos.getX() - fHalfCrossSize, aViewPos.getY() - fHalfCrossSize,
195cdf0e10cSrcweir                                     aViewPos.getX() + fHalfCrossSize, aViewPos.getY() + fHalfCrossSize);
196cdf0e10cSrcweir 
197cdf0e10cSrcweir                                 if(rViewInformation.getDiscreteViewport().overlaps(aDiscreteRangeCross))
198cdf0e10cSrcweir                                 {
199cdf0e10cSrcweir                                     const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos);
200cdf0e10cSrcweir                                     aPositionsCross.push_back(aLogicPos);
201cdf0e10cSrcweir                                 }
202cdf0e10cSrcweir                             }
203cdf0e10cSrcweir 
204cdf0e10cSrcweir                             if(getSubdivisionsX() && !bYZero)
205cdf0e10cSrcweir                             {
206cdf0e10cSrcweir                                 double fF(fX + fSmallStepX);
207cdf0e10cSrcweir 
208*2a27d9caSArmin Le Grand                                 for(sal_uInt32 a(1); a < nSmallStepsX && fF < aExtendedViewport.getMaxX(); a++, fF += fSmallStepX)
209cdf0e10cSrcweir                                 {
210cdf0e10cSrcweir                                     const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fF, fY));
211cdf0e10cSrcweir 
212cdf0e10cSrcweir                                     if(rViewInformation.getDiscreteViewport().isInside(aViewPos))
213cdf0e10cSrcweir                                     {
214cdf0e10cSrcweir                                         const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos);
215cdf0e10cSrcweir                                         aPositionsPoint.push_back(aLogicPos);
216cdf0e10cSrcweir                                     }
217cdf0e10cSrcweir                                 }
218cdf0e10cSrcweir                             }
219cdf0e10cSrcweir 
220cdf0e10cSrcweir                             if(getSubdivisionsY() && !bXZero)
221cdf0e10cSrcweir                             {
222cdf0e10cSrcweir                                 double fF(fY + fSmallStepY);
223cdf0e10cSrcweir 
224*2a27d9caSArmin Le Grand                                 for(sal_uInt32 a(1); a < nSmallStepsY && fF < aExtendedViewport.getMaxY(); a++, fF += fSmallStepY)
225cdf0e10cSrcweir                                 {
226cdf0e10cSrcweir                                     const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fX, fF));
227cdf0e10cSrcweir 
228cdf0e10cSrcweir                                     if(rViewInformation.getDiscreteViewport().isInside(aViewPos))
229cdf0e10cSrcweir                                     {
230cdf0e10cSrcweir                                         const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos);
231cdf0e10cSrcweir                                         aPositionsPoint.push_back(aLogicPos);
232cdf0e10cSrcweir                                     }
233cdf0e10cSrcweir                                 }
234cdf0e10cSrcweir                             }
235cdf0e10cSrcweir                         }
236cdf0e10cSrcweir                     }
237cdf0e10cSrcweir 
238cdf0e10cSrcweir                     // prepare return value
239cdf0e10cSrcweir                     const sal_uInt32 nCountPoint(aPositionsPoint.size());
240cdf0e10cSrcweir                     const sal_uInt32 nCountCross(aPositionsCross.size());
241cdf0e10cSrcweir                     const sal_uInt32 nRetvalCount((nCountPoint ? 1 : 0) + (nCountCross ? 1 : 0));
242cdf0e10cSrcweir                     sal_uInt32 nInsertCounter(0);
243cdf0e10cSrcweir 
244cdf0e10cSrcweir                     aRetval.realloc(nRetvalCount);
245cdf0e10cSrcweir 
246cdf0e10cSrcweir                     // add PointArrayPrimitive2D if point markers were added
247cdf0e10cSrcweir                     if(nCountPoint)
248cdf0e10cSrcweir                     {
249cdf0e10cSrcweir                         aRetval[nInsertCounter++] = Primitive2DReference(new PointArrayPrimitive2D(aPositionsPoint, getBColor()));
250cdf0e10cSrcweir                     }
251cdf0e10cSrcweir 
252cdf0e10cSrcweir                     // add MarkerArrayPrimitive2D if cross markers were added
253cdf0e10cSrcweir                     if(nCountCross)
254cdf0e10cSrcweir                     {
255cdf0e10cSrcweir                         if(!getSubdivisionsX() && !getSubdivisionsY())
256cdf0e10cSrcweir                         {
257cdf0e10cSrcweir                             // no subdivisions, so fall back to points at grid positions, no need to
258cdf0e10cSrcweir                             // visualize a difference between divisions and sub-divisions
259cdf0e10cSrcweir                             aRetval[nInsertCounter++] = Primitive2DReference(new PointArrayPrimitive2D(aPositionsCross, getBColor()));
260cdf0e10cSrcweir                         }
261cdf0e10cSrcweir                         else
262cdf0e10cSrcweir                         {
263cdf0e10cSrcweir                             aRetval[nInsertCounter++] = Primitive2DReference(new MarkerArrayPrimitive2D(aPositionsCross, getCrossMarker()));
264cdf0e10cSrcweir                         }
265cdf0e10cSrcweir                     }
266cdf0e10cSrcweir                 }
267*2a27d9caSArmin Le Grand             }
268cdf0e10cSrcweir 
269cdf0e10cSrcweir             return aRetval;
270cdf0e10cSrcweir         }
271cdf0e10cSrcweir 
GridPrimitive2D(const basegfx::B2DHomMatrix & rTransform,double fWidth,double fHeight,double fSmallestViewDistance,double fSmallestSubdivisionViewDistance,sal_uInt32 nSubdivisionsX,sal_uInt32 nSubdivisionsY,const basegfx::BColor & rBColor,const BitmapEx & rCrossMarker)272cdf0e10cSrcweir         GridPrimitive2D::GridPrimitive2D(
273cdf0e10cSrcweir             const basegfx::B2DHomMatrix& rTransform,
274cdf0e10cSrcweir             double fWidth,
275cdf0e10cSrcweir             double fHeight,
276cdf0e10cSrcweir             double fSmallestViewDistance,
277cdf0e10cSrcweir             double fSmallestSubdivisionViewDistance,
278cdf0e10cSrcweir             sal_uInt32 nSubdivisionsX,
279cdf0e10cSrcweir             sal_uInt32 nSubdivisionsY,
280cdf0e10cSrcweir             const basegfx::BColor& rBColor,
281cdf0e10cSrcweir             const BitmapEx& rCrossMarker)
282cdf0e10cSrcweir         :   BufferedDecompositionPrimitive2D(),
283cdf0e10cSrcweir             maTransform(rTransform),
284cdf0e10cSrcweir             mfWidth(fWidth),
285cdf0e10cSrcweir             mfHeight(fHeight),
286cdf0e10cSrcweir             mfSmallestViewDistance(fSmallestViewDistance),
287cdf0e10cSrcweir             mfSmallestSubdivisionViewDistance(fSmallestSubdivisionViewDistance),
288cdf0e10cSrcweir             mnSubdivisionsX(nSubdivisionsX),
289cdf0e10cSrcweir             mnSubdivisionsY(nSubdivisionsY),
290cdf0e10cSrcweir             maBColor(rBColor),
291cdf0e10cSrcweir             maCrossMarker(rCrossMarker),
292cdf0e10cSrcweir             maLastObjectToViewTransformation(),
293cdf0e10cSrcweir             maLastViewport()
294cdf0e10cSrcweir         {
295cdf0e10cSrcweir         }
296cdf0e10cSrcweir 
operator ==(const BasePrimitive2D & rPrimitive) const297cdf0e10cSrcweir         bool GridPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
298cdf0e10cSrcweir         {
299cdf0e10cSrcweir             if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
300cdf0e10cSrcweir             {
301cdf0e10cSrcweir                 const GridPrimitive2D& rCompare = (GridPrimitive2D&)rPrimitive;
302cdf0e10cSrcweir 
303cdf0e10cSrcweir                 return (getTransform() == rCompare.getTransform()
304cdf0e10cSrcweir                     && getWidth() == rCompare.getWidth()
305cdf0e10cSrcweir                     && getHeight() == rCompare.getHeight()
306cdf0e10cSrcweir                     && getSmallestViewDistance() == rCompare.getSmallestViewDistance()
307cdf0e10cSrcweir                     && getSmallestSubdivisionViewDistance() == rCompare.getSmallestSubdivisionViewDistance()
308cdf0e10cSrcweir                     && getSubdivisionsX() == rCompare.getSubdivisionsX()
309cdf0e10cSrcweir                     && getSubdivisionsY() == rCompare.getSubdivisionsY()
310cdf0e10cSrcweir                     && getBColor() == rCompare.getBColor()
311cdf0e10cSrcweir                     && getCrossMarker() == rCompare.getCrossMarker());
312cdf0e10cSrcweir             }
313cdf0e10cSrcweir 
314cdf0e10cSrcweir             return false;
315cdf0e10cSrcweir         }
316cdf0e10cSrcweir 
getB2DRange(const geometry::ViewInformation2D & rViewInformation) const317cdf0e10cSrcweir         basegfx::B2DRange GridPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
318cdf0e10cSrcweir         {
319cdf0e10cSrcweir             // get object's range
320cdf0e10cSrcweir             basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0);
321cdf0e10cSrcweir             aUnitRange.transform(getTransform());
322cdf0e10cSrcweir 
323cdf0e10cSrcweir             // intersect with visible part
324cdf0e10cSrcweir             aUnitRange.intersect(rViewInformation.getViewport());
325cdf0e10cSrcweir 
326cdf0e10cSrcweir             return aUnitRange;
327cdf0e10cSrcweir         }
328cdf0e10cSrcweir 
get2DDecomposition(const geometry::ViewInformation2D & rViewInformation) const329cdf0e10cSrcweir         Primitive2DSequence GridPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
330cdf0e10cSrcweir         {
331cdf0e10cSrcweir             ::osl::MutexGuard aGuard( m_aMutex );
332cdf0e10cSrcweir 
333cdf0e10cSrcweir             if(getBuffered2DDecomposition().hasElements())
334cdf0e10cSrcweir             {
335cdf0e10cSrcweir                 if(maLastViewport != rViewInformation.getViewport() || maLastObjectToViewTransformation != rViewInformation.getObjectToViewTransformation())
336cdf0e10cSrcweir                 {
337cdf0e10cSrcweir                     // conditions of last local decomposition have changed, delete
338cdf0e10cSrcweir                     const_cast< GridPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence());
339cdf0e10cSrcweir                 }
340cdf0e10cSrcweir             }
341cdf0e10cSrcweir 
342cdf0e10cSrcweir             if(!getBuffered2DDecomposition().hasElements())
343cdf0e10cSrcweir             {
344cdf0e10cSrcweir                 // remember ViewRange and ViewTransformation
345cdf0e10cSrcweir                 const_cast< GridPrimitive2D* >(this)->maLastObjectToViewTransformation = rViewInformation.getObjectToViewTransformation();
346cdf0e10cSrcweir                 const_cast< GridPrimitive2D* >(this)->maLastViewport = rViewInformation.getViewport();
347cdf0e10cSrcweir             }
348cdf0e10cSrcweir 
349cdf0e10cSrcweir             // use parent implementation
350cdf0e10cSrcweir             return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation);
351cdf0e10cSrcweir         }
352cdf0e10cSrcweir 
353cdf0e10cSrcweir         // provide unique ID
354cdf0e10cSrcweir         ImplPrimitrive2DIDBlock(GridPrimitive2D, PRIMITIVE2D_ID_GRIDPRIMITIVE2D)
355cdf0e10cSrcweir 
356cdf0e10cSrcweir     } // end of namespace primitive2d
357cdf0e10cSrcweir } // end of namespace drawinglayer
358cdf0e10cSrcweir 
359cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
360cdf0e10cSrcweir // eof
361