Author: alg
Date: Thu Aug 23 15:03:21 2012
New Revision: 1376528

URL: http://svn.apache.org/viewvc?rev=1376528&view=rev
Log:
#120596# Optimized grid primitive, added some tooling to basegfx

Modified:
    incubator/ooo/trunk/main/basegfx/inc/basegfx/numeric/ftools.hxx
    incubator/ooo/trunk/main/basegfx/source/numeric/ftools.cxx
    incubator/ooo/trunk/main/drawinglayer/source/primitive2d/gridprimitive2d.cxx

Modified: incubator/ooo/trunk/main/basegfx/inc/basegfx/numeric/ftools.hxx
URL: 
http://svn.apache.org/viewvc/incubator/ooo/trunk/main/basegfx/inc/basegfx/numeric/ftools.hxx?rev=1376528&r1=1376527&r2=1376528&view=diff
==============================================================================
--- incubator/ooo/trunk/main/basegfx/inc/basegfx/numeric/ftools.hxx (original)
+++ incubator/ooo/trunk/main/basegfx/inc/basegfx/numeric/ftools.hxx Thu Aug 23 
15:03:21 2012
@@ -139,8 +139,38 @@ namespace basegfx
         return v / M_PI_2 * 90.0;
     }
 
+    /** Snap v to nearest multiple of fStep, from negative and
+               positive side.
 
-       class fTools
+               Examples:
+
+               snapToNearestMultiple(-0.1, 0.5) = 0.0
+               snapToNearestMultiple(0.1, 0.5) = 0.0
+               snapToNearestMultiple(0.25, 0.5) = 0.0
+               snapToNearestMultiple(0.26, 0.5) = 0.5
+     */
+       double snapToNearestMultiple(double v, const double fStep);
+
+    /** Snap v to the range [0.0 .. fWidth] using modulo
+     */
+       double snapToZeroRange(double v, double fWidth);
+
+    /** Snap v to the range [fLow .. fHigh] using modulo
+     */
+       double snapToRange(double v, double fLow, double fHigh);
+
+       /** return fValue with the sign of fSignCarrier, thus evtl. changed
+       */
+       inline double copySign(double fValue, double fSignCarrier)
+       {
+#ifdef WNT
+               return _copysign(fValue, fSignCarrier);
+#else
+               return copysign(fValue, fSignCarrier);
+#endif
+       }
+
+    class fTools
        {
         /// Threshold value for equalZero()
                static double                                                   
                mfSmallValue;

Modified: incubator/ooo/trunk/main/basegfx/source/numeric/ftools.cxx
URL: 
http://svn.apache.org/viewvc/incubator/ooo/trunk/main/basegfx/source/numeric/ftools.cxx?rev=1376528&r1=1376527&r2=1376528&view=diff
==============================================================================
--- incubator/ooo/trunk/main/basegfx/source/numeric/ftools.cxx (original)
+++ incubator/ooo/trunk/main/basegfx/source/numeric/ftools.cxx Thu Aug 23 
15:03:21 2012
@@ -24,11 +24,88 @@
 // MARKER(update_precomp.py): autogen include statement, do not remove
 #include "precompiled_basegfx.hxx"
 #include <basegfx/numeric/ftools.hxx>
+#include <algorithm>
 
 namespace basegfx
 {
        // init static member of class fTools
        double ::basegfx::fTools::mfSmallValue = 0.000000001;
+
+       double snapToNearestMultiple(double v, const double fStep)
+       {
+               if(fTools::equalZero(fStep))
+               {
+                       // with a zero step, all snaps to 0.0
+                       return 0.0;
+               }
+               else
+               {
+                       const double fHalfStep(fStep * 0.5);
+                       const double fChange(fHalfStep - fmod(v + fHalfStep, 
fStep));
+
+            if(basegfx::fTools::equal(fabs(v), fabs(fChange)))
+            {
+                return 0.0;
+            }
+            else
+            {
+                       return v + fChange;
+            }
+               }
+       }
+
+       double snapToZeroRange(double v, double fWidth)
+       {
+               if(fTools::equalZero(fWidth))
+               {
+                       // with no range all snaps to range bound
+                       return 0.0;
+               }
+               else
+               {
+                       if(v < 0.0 || v > fWidth)
+                       {
+                               double fRetval(fmod(v, fWidth));
+
+                               if(fRetval < 0.0)
+                               {
+                                       fRetval += fWidth;
+                               }
+
+                               return fRetval;
+                       }
+                       else
+                       {
+                               return v;
+                       }
+               }
+       }
+
+       double snapToRange(double v, double fLow, double fHigh)
+       {
+               if(fTools::equal(fLow, fHigh))
+               {
+                       // with no range all snaps to range bound
+                       return 0.0;
+               }
+               else
+               {
+                       if(fLow > fHigh)
+                       {
+                               // correct range order. Evtl. assert this (?)
+                               std::swap(fLow, fHigh);
+                       }
+
+                       if(v < fLow || v > fHigh)
+                       {
+                               return snapToZeroRange(v - fLow, fHigh - fLow) 
+ fLow;
+                       }
+                       else
+                       {
+                               return v;
+                       }
+               }
+       }
 } // end of namespace basegfx
 
 // eof

Modified: 
incubator/ooo/trunk/main/drawinglayer/source/primitive2d/gridprimitive2d.cxx
URL: 
http://svn.apache.org/viewvc/incubator/ooo/trunk/main/drawinglayer/source/primitive2d/gridprimitive2d.cxx?rev=1376528&r1=1376527&r2=1376528&view=diff
==============================================================================
--- 
incubator/ooo/trunk/main/drawinglayer/source/primitive2d/gridprimitive2d.cxx 
(original)
+++ 
incubator/ooo/trunk/main/drawinglayer/source/primitive2d/gridprimitive2d.cxx 
Thu Aug 23 15:03:21 2012
@@ -129,97 +129,141 @@ 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)
-                               {
-                                       const bool 
bXZero(basegfx::fTools::equalZero(fX));
+                if(rViewInformation.getDiscreteViewport().isEmpty())
+                {
+                    // 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);
 
-                                       for(double fY(0.0); fY < aScale.getY(); 
fY += fStepY)
-                                       {
-                                               const bool 
bYZero(basegfx::fTools::equalZero(fY));
+                    // intersect with visible part
+                    
aExtendedViewport.intersect(rViewInformation.getDiscreteViewport());
 
-                        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))
+                    if(!aExtendedViewport.isEmpty())
+                    {
+                        // 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(!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));
+
+                                           for(double 
fY(aExtendedViewport.getMinY()); fY < aExtendedViewport.getMaxY(); fY += fStepY)
+                                           {
+                                                   const bool 
bYZero(basegfx::fTools::equalZero(fY));
+
+                            if(!bXZero && !bYZero)
                             {
-                                                           const 
basegfx::B2DPoint 
aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos);
-                                                           
aPositionsCross.push_back(aLogicPos);
+                                // 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(getSubdivisionsX() && 
!bYZero)
-                                               {
-                                                       double fF(fX + 
fSmallStepX);
-
-                                                       for(sal_uInt32 a(1L); a 
< nSmallStepsX && fF < aScale.getX(); 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)
-                                               {
-                                                       double fF(fY + 
fSmallStepY);
-
-                                                       for(sal_uInt32 a(1L); a 
< nSmallStepsY && fF < aScale.getY(); a++, fF += fSmallStepY)
-                                                       {
-                                                               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);
+                                                   if(getSubdivisionsX() && 
!bYZero)
+                                                   {
+                                                           double fF(fX + 
fSmallStepX);
+
+                                                           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)
+                                                   {
+                                                           double fF(fY + 
fSmallStepY);
+
+                                                           for(sal_uInt32 
a(1); a < nSmallStepsY && fF < aExtendedViewport.getMaxY(); a++, fF += 
fSmallStepY)
+                                                           {
+                                                                   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);
-
-                               // 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())
-                    {
-                        // 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()));
-                    }
-                               }
+                                   // add PointArrayPrimitive2D if point 
markers were added
+                                   if(nCountPoint)
+                                   {
+                                           aRetval[nInsertCounter++] = 
Primitive2DReference(new PointArrayPrimitive2D(aPositionsPoint, getBColor()));
+                                   }
+
+                                   // add MarkerArrayPrimitive2D if cross 
markers were added
+                                   if(nCountCross)
+                                   {
+                                   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()));
+                        }
+                                   }
+                }
                        }
 
                        return aRetval;


Reply via email to