You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by al...@apache.org on 2012/08/23 17:03:21 UTC

svn commit: r1376528 - in /incubator/ooo/trunk/main: basegfx/inc/basegfx/numeric/ftools.hxx basegfx/source/numeric/ftools.cxx drawinglayer/source/primitive2d/gridprimitive2d.cxx

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;