summaryrefslogtreecommitdiff
path: root/drawinglayer
diff options
context:
space:
mode:
authorArmin Le Grand <alg@apache.org>2012-08-23 14:03:21 +0000
committerCaolán McNamara <caolanm@redhat.com>2013-05-19 16:50:31 +0100
commit5a6ed660ec74e445a827c7aa41e4793c64a46271 (patch)
treede8dedebb69847d3e96c371e0c19554051364470 /drawinglayer
parent2d55b2e5ae0d4f1a05e1ce5b20a7b342d6ea8b1d (diff)
Resolves: #i120596# Optimized grid primitive
added some tooling to basegfx (cherry picked from commit 97fa4faaa0b09724cf98dbf22390b283ba57b41c) Conflicts: basegfx/inc/basegfx/numeric/ftools.hxx Change-Id: Ib15c43cf4d5b50605ec596dab498e3a678f3734a
Diffstat (limited to 'drawinglayer')
-rw-r--r--drawinglayer/source/primitive2d/gridprimitive2d.cxx166
1 files changed, 105 insertions, 61 deletions
diff --git a/drawinglayer/source/primitive2d/gridprimitive2d.cxx b/drawinglayer/source/primitive2d/gridprimitive2d.cxx
index c24173818bb8..1f7dcb1168a3 100644
--- a/drawinglayer/source/primitive2d/gridprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/gridprimitive2d.cxx
@@ -122,95 +122,139 @@ namespace drawinglayer
nSmallStepsY = (sal_uInt32)(fStepY / fSmallStepY);
}
- // prepare point vectors for point and cross markers
- std::vector< basegfx::B2DPoint > aPositionsPoint;
- std::vector< basegfx::B2DPoint > aPositionsCross;
+ // calculate extended viewport in which grid points may lie at all
+ basegfx::B2DRange aExtendedViewport;
- for(double fX(0.0); fX < aScale.getX(); fX += fStepX)
+ if(rViewInformation.getDiscreteViewport().isEmpty())
{
- const bool bXZero(basegfx::fTools::equalZero(fX));
+ // not set, use logic size to travel over all potentioal grid points
+ aExtendedViewport = basegfx::B2DRange(0.0, 0.0, aScale.getX(), aScale.getY());
+ }
+ else
+ {
+ // transform unit range to discrete view
+ aExtendedViewport = basegfx::B2DRange(0.0, 0.0, 1.0, 1.0);
+ basegfx::B2DHomMatrix aTrans(rViewInformation.getObjectToViewTransformation() * getTransform());
+ aExtendedViewport.transform(aTrans);
+
+ // intersect with visible part
+ aExtendedViewport.intersect(rViewInformation.getDiscreteViewport());
- for(double fY(0.0); fY < aScale.getY(); fY += fStepY)
+ if(!aExtendedViewport.isEmpty())
{
- const bool bYZero(basegfx::fTools::equalZero(fY));
+ // convert back and apply scale
+ aTrans.invert();
+ aTrans.scale(aScale.getX(), aScale.getY());
+ aExtendedViewport.transform(aTrans);
+
+ // crop start/end in X/Y to multiples of logical step width
+ const double fHalfCrossSize((rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(3.0, 0.0)).getLength());
+ const double fMinX(floor((aExtendedViewport.getMinX() - fHalfCrossSize) / fStepX) * fStepX);
+ const double fMaxX(ceil((aExtendedViewport.getMaxX() + fHalfCrossSize) / fStepX) * fStepX);
+ const double fMinY(floor((aExtendedViewport.getMinY() - fHalfCrossSize) / fStepY) * fStepY);
+ const double fMaxY(ceil((aExtendedViewport.getMaxY() + fHalfCrossSize) / fStepY) * fStepY);
+
+ // put to aExtendedViewport and crop on object logic size
+ aExtendedViewport = basegfx::B2DRange(
+ std::max(fMinX, 0.0),
+ std::max(fMinY, 0.0),
+ std::min(fMaxX, aScale.getX()),
+ std::min(fMaxY, aScale.getY()));
+ }
+ }
- if(!bXZero && !bYZero)
- {
- // get discrete position and test against 3x3 area surrounding it
- // since it's a cross
- const double fHalfCrossSize(3.0 * 0.5);
- const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fX, fY));
- const basegfx::B2DRange aDiscreteRangeCross(
- aViewPos.getX() - fHalfCrossSize, aViewPos.getY() - fHalfCrossSize,
- aViewPos.getX() + fHalfCrossSize, aViewPos.getY() + fHalfCrossSize);
-
- if(rViewInformation.getDiscreteViewport().overlaps(aDiscreteRangeCross))
- {
- const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos);
- aPositionsCross.push_back(aLogicPos);
- }
- }
+ if(!aExtendedViewport.isEmpty())
+ {
+ // prepare point vectors for point and cross markers
+ std::vector< basegfx::B2DPoint > aPositionsPoint;
+ std::vector< basegfx::B2DPoint > aPositionsCross;
+
+ for(double fX(aExtendedViewport.getMinX()); fX < aExtendedViewport.getMaxX(); fX += fStepX)
+ {
+ const bool bXZero(basegfx::fTools::equalZero(fX));
- if(getSubdivisionsX() && !bYZero)
+ for(double fY(aExtendedViewport.getMinY()); fY < aExtendedViewport.getMaxY(); fY += fStepY)
{
- double fF(fX + fSmallStepX);
+ const bool bYZero(basegfx::fTools::equalZero(fY));
- for(sal_uInt32 a(1L); a < nSmallStepsX && fF < aScale.getX(); a++, fF += fSmallStepX)
+ if(!bXZero && !bYZero)
{
- const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fF, fY));
-
- if(rViewInformation.getDiscreteViewport().isInside(aViewPos))
+ // get discrete position and test against 3x3 area surrounding it
+ // since it's a cross
+ const double fHalfCrossSize(3.0 * 0.5);
+ const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fX, fY));
+ const basegfx::B2DRange aDiscreteRangeCross(
+ aViewPos.getX() - fHalfCrossSize, aViewPos.getY() - fHalfCrossSize,
+ aViewPos.getX() + fHalfCrossSize, aViewPos.getY() + fHalfCrossSize);
+
+ if(rViewInformation.getDiscreteViewport().overlaps(aDiscreteRangeCross))
{
const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos);
- aPositionsPoint.push_back(aLogicPos);
+ aPositionsCross.push_back(aLogicPos);
}
}
- }
- if(getSubdivisionsY() && !bXZero)
- {
- double fF(fY + fSmallStepY);
+ if(getSubdivisionsX() && !bYZero)
+ {
+ double fF(fX + fSmallStepX);
- for(sal_uInt32 a(1L); a < nSmallStepsY && fF < aScale.getY(); a++, fF += fSmallStepY)
+ for(sal_uInt32 a(1); a < nSmallStepsX && fF < aExtendedViewport.getMaxX(); a++, fF += fSmallStepX)
+ {
+ const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fF, fY));
+
+ if(rViewInformation.getDiscreteViewport().isInside(aViewPos))
+ {
+ const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos);
+ aPositionsPoint.push_back(aLogicPos);
+ }
+ }
+ }
+
+ if(getSubdivisionsY() && !bXZero)
{
- const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fX, fF));
+ double fF(fY + fSmallStepY);
- if(rViewInformation.getDiscreteViewport().isInside(aViewPos))
+ for(sal_uInt32 a(1); a < nSmallStepsY && fF < aExtendedViewport.getMaxY(); a++, fF += fSmallStepY)
{
- const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos);
- aPositionsPoint.push_back(aLogicPos);
+ const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fX, fF));
+
+ if(rViewInformation.getDiscreteViewport().isInside(aViewPos))
+ {
+ const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos);
+ aPositionsPoint.push_back(aLogicPos);
+ }
}
}
}
}
- }
-
- // prepare return value
- const sal_uInt32 nCountPoint(aPositionsPoint.size());
- const sal_uInt32 nCountCross(aPositionsCross.size());
- const sal_uInt32 nRetvalCount((nCountPoint ? 1 : 0) + (nCountCross ? 1 : 0));
- sal_uInt32 nInsertCounter(0);
- aRetval.realloc(nRetvalCount);
+ // prepare return value
+ const sal_uInt32 nCountPoint(aPositionsPoint.size());
+ const sal_uInt32 nCountCross(aPositionsCross.size());
+ const sal_uInt32 nRetvalCount((nCountPoint ? 1 : 0) + (nCountCross ? 1 : 0));
+ sal_uInt32 nInsertCounter(0);
- // add PointArrayPrimitive2D if point markers were added
- if(nCountPoint)
- {
- aRetval[nInsertCounter++] = Primitive2DReference(new PointArrayPrimitive2D(aPositionsPoint, getBColor()));
- }
+ aRetval.realloc(nRetvalCount);
- // add MarkerArrayPrimitive2D if cross markers were added
- if(nCountCross)
- {
- if(!getSubdivisionsX() && !getSubdivisionsY())
+ // add PointArrayPrimitive2D if point markers were added
+ if(nCountPoint)
{
- // no subdivisions, so fall back to points at grid positions, no need to
- // visualize a difference between divisions and sub-divisions
- aRetval[nInsertCounter++] = Primitive2DReference(new PointArrayPrimitive2D(aPositionsCross, getBColor()));
+ aRetval[nInsertCounter++] = Primitive2DReference(new PointArrayPrimitive2D(aPositionsPoint, getBColor()));
}
- else
+
+ // add MarkerArrayPrimitive2D if cross markers were added
+ if(nCountCross)
{
- aRetval[nInsertCounter++] = Primitive2DReference(new MarkerArrayPrimitive2D(aPositionsCross, getCrossMarker()));
+ if(!getSubdivisionsX() && !getSubdivisionsY())
+ {
+ // no subdivisions, so fall back to points at grid positions, no need to
+ // visualize a difference between divisions and sub-divisions
+ aRetval[nInsertCounter++] = Primitive2DReference(new PointArrayPrimitive2D(aPositionsCross, getBColor()));
+ }
+ else
+ {
+ aRetval[nInsertCounter++] = Primitive2DReference(new MarkerArrayPrimitive2D(aPositionsCross, getCrossMarker()));
+ }
}
}
}