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 10464702f4SAndrew Rist * 11464702f4SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12464702f4SAndrew Rist * 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. 19464702f4SAndrew Rist * 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 } 172cdf0e10cSrcweir 173*2a27d9caSArmin Le Grand if(!aExtendedViewport.isEmpty()) 174*2a27d9caSArmin Le Grand { 175*2a27d9caSArmin Le Grand // prepare point vectors for point and cross markers 176*2a27d9caSArmin Le Grand std::vector< basegfx::B2DPoint > aPositionsPoint; 177*2a27d9caSArmin Le Grand std::vector< basegfx::B2DPoint > aPositionsCross; 178cdf0e10cSrcweir 179*2a27d9caSArmin Le Grand for(double fX(aExtendedViewport.getMinX()); fX < aExtendedViewport.getMaxX(); fX += fStepX) 180*2a27d9caSArmin Le Grand { 181*2a27d9caSArmin Le Grand const bool bXZero(basegfx::fTools::equalZero(fX)); 182cdf0e10cSrcweir 183*2a27d9caSArmin Le Grand for(double fY(aExtendedViewport.getMinY()); fY < aExtendedViewport.getMaxY(); fY += fStepY) 184*2a27d9caSArmin Le Grand { 185*2a27d9caSArmin Le Grand const bool bYZero(basegfx::fTools::equalZero(fY)); 186*2a27d9caSArmin Le Grand 187*2a27d9caSArmin Le Grand if(!bXZero && !bYZero) 188cdf0e10cSrcweir { 189*2a27d9caSArmin Le Grand // get discrete position and test against 3x3 area surrounding it 190*2a27d9caSArmin Le Grand // since it's a cross 191*2a27d9caSArmin Le Grand const double fHalfCrossSize(3.0 * 0.5); 192*2a27d9caSArmin Le Grand const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fX, fY)); 193*2a27d9caSArmin Le Grand const basegfx::B2DRange aDiscreteRangeCross( 194*2a27d9caSArmin Le Grand aViewPos.getX() - fHalfCrossSize, aViewPos.getY() - fHalfCrossSize, 195*2a27d9caSArmin Le Grand aViewPos.getX() + fHalfCrossSize, aViewPos.getY() + fHalfCrossSize); 196*2a27d9caSArmin Le Grand 197*2a27d9caSArmin Le Grand if(rViewInformation.getDiscreteViewport().overlaps(aDiscreteRangeCross)) 198*2a27d9caSArmin Le Grand { 199*2a27d9caSArmin Le Grand const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos); 200*2a27d9caSArmin Le Grand aPositionsCross.push_back(aLogicPos); 201*2a27d9caSArmin Le Grand } 202cdf0e10cSrcweir } 203cdf0e10cSrcweir 204*2a27d9caSArmin Le Grand if(getSubdivisionsX() && !bYZero) 205*2a27d9caSArmin Le Grand { 206*2a27d9caSArmin Le Grand double fF(fX + fSmallStepX); 207*2a27d9caSArmin Le Grand 208*2a27d9caSArmin Le Grand for(sal_uInt32 a(1); a < nSmallStepsX && fF < aExtendedViewport.getMaxX(); a++, fF += fSmallStepX) 209*2a27d9caSArmin Le Grand { 210*2a27d9caSArmin Le Grand const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fF, fY)); 211*2a27d9caSArmin Le Grand 212*2a27d9caSArmin Le Grand if(rViewInformation.getDiscreteViewport().isInside(aViewPos)) 213*2a27d9caSArmin Le Grand { 214*2a27d9caSArmin Le Grand const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos); 215*2a27d9caSArmin Le Grand aPositionsPoint.push_back(aLogicPos); 216*2a27d9caSArmin Le Grand } 217*2a27d9caSArmin Le Grand } 218*2a27d9caSArmin Le Grand } 219*2a27d9caSArmin Le Grand 220*2a27d9caSArmin Le Grand if(getSubdivisionsY() && !bXZero) 221*2a27d9caSArmin Le Grand { 222*2a27d9caSArmin Le Grand double fF(fY + fSmallStepY); 223*2a27d9caSArmin Le Grand 224*2a27d9caSArmin Le Grand for(sal_uInt32 a(1); a < nSmallStepsY && fF < aExtendedViewport.getMaxY(); a++, fF += fSmallStepY) 225*2a27d9caSArmin Le Grand { 226*2a27d9caSArmin Le Grand const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fX, fF)); 227*2a27d9caSArmin Le Grand 228*2a27d9caSArmin Le Grand if(rViewInformation.getDiscreteViewport().isInside(aViewPos)) 229*2a27d9caSArmin Le Grand { 230*2a27d9caSArmin Le Grand const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos); 231*2a27d9caSArmin Le Grand aPositionsPoint.push_back(aLogicPos); 232*2a27d9caSArmin Le Grand } 233*2a27d9caSArmin Le Grand } 234*2a27d9caSArmin Le Grand } 235*2a27d9caSArmin Le Grand } 236*2a27d9caSArmin Le Grand } 237*2a27d9caSArmin Le Grand 238*2a27d9caSArmin Le Grand // prepare return value 239*2a27d9caSArmin Le Grand const sal_uInt32 nCountPoint(aPositionsPoint.size()); 240*2a27d9caSArmin Le Grand const sal_uInt32 nCountCross(aPositionsCross.size()); 241*2a27d9caSArmin Le Grand const sal_uInt32 nRetvalCount((nCountPoint ? 1 : 0) + (nCountCross ? 1 : 0)); 242*2a27d9caSArmin Le Grand sal_uInt32 nInsertCounter(0); 243cdf0e10cSrcweir 244*2a27d9caSArmin Le Grand aRetval.realloc(nRetvalCount); 245*2a27d9caSArmin Le Grand 246*2a27d9caSArmin Le Grand // add PointArrayPrimitive2D if point markers were added 247*2a27d9caSArmin Le Grand if(nCountPoint) 248*2a27d9caSArmin Le Grand { 249*2a27d9caSArmin Le Grand aRetval[nInsertCounter++] = Primitive2DReference(new PointArrayPrimitive2D(aPositionsPoint, getBColor())); 250*2a27d9caSArmin Le Grand } 251*2a27d9caSArmin Le Grand 252*2a27d9caSArmin Le Grand // add MarkerArrayPrimitive2D if cross markers were added 253*2a27d9caSArmin Le Grand if(nCountCross) 254*2a27d9caSArmin Le Grand { 255*2a27d9caSArmin Le Grand if(!getSubdivisionsX() && !getSubdivisionsY()) 256*2a27d9caSArmin Le Grand { 257*2a27d9caSArmin Le Grand // no subdivisions, so fall back to points at grid positions, no need to 258*2a27d9caSArmin Le Grand // visualize a difference between divisions and sub-divisions 259*2a27d9caSArmin Le Grand aRetval[nInsertCounter++] = Primitive2DReference(new PointArrayPrimitive2D(aPositionsCross, getBColor())); 260*2a27d9caSArmin Le Grand } 261*2a27d9caSArmin Le Grand else 262*2a27d9caSArmin Le Grand { 263*2a27d9caSArmin Le Grand aRetval[nInsertCounter++] = Primitive2DReference(new MarkerArrayPrimitive2D(aPositionsCross, getCrossMarker())); 264*2a27d9caSArmin Le Grand } 265*2a27d9caSArmin Le Grand } 266*2a27d9caSArmin Le Grand } 267cdf0e10cSrcweir } 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