Commit 71eb8253d9e51ca02d624c3383792fbc1763665c

sammy 2008-04-13T07:48:50

* Refactoring FTContour.

diff --git a/include/FTContour.h b/include/FTContour.h
index 62bb6ec..12e8293 100644
--- a/include/FTContour.h
+++ b/include/FTContour.h
@@ -92,31 +92,24 @@ class FTGL_EXPORT FTContour
          * @param point The point to be added to the contour.
          */
         inline void AddPoint( FTPoint point);
-        
-        inline void AddPoint( float x, float y);
-        
+
         /**
          * De Casteljau (bezier) algorithm contributed by Jed Soane
          * Evaluates a quadratic or conic (second degree) curve
          */
-        inline void evaluateQuadraticCurve();
+        inline void evaluateQuadraticCurve(FTPoint, FTPoint, FTPoint);
 
         /**
          * De Casteljau (bezier) algorithm contributed by Jed Soane
          * Evaluates a cubic (third degree) curve
          */
-        inline void evaluateCubicCurve();
+        inline void evaluateCubicCurve(FTPoint, FTPoint, FTPoint, FTPoint);
 
         /**
          *  The list of points in this contour
          */
         typedef FTVector<FTPoint> PointVector;
         PointVector pointList;
-        
-        /**
-         * 2D array storing values of de Casteljau algorithm.
-         */
-        float controlPoints[4][2];
 };
 
 #endif // __FTContour__
diff --git a/src/FTContour.cpp b/src/FTContour.cpp
index ae57efc..ca4a989 100644
--- a/src/FTContour.cpp
+++ b/src/FTContour.cpp
@@ -2,6 +2,7 @@
  * FTGL - OpenGL font library
  *
  * Copyright (c) 2001-2004 Henry Maddocks <ftgl@opengl.geek.nz>
+ *               2008 Sam Hocevar <sam@zoy.org>
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
@@ -10,10 +11,10 @@
  * distribute, sublicense, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject to
  * the following conditions:
- * 
+ *
  * The above copyright notice and this permission notice shall be
  * included in all copies or substantial portions of the Software.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
@@ -39,145 +40,98 @@
 static const float BEZIER_STEP_SIZE = 0.2f;
 
 
-void FTContour::AddPoint( FTPoint point)
+void FTContour::AddPoint(FTPoint point)
 {
-    if( pointList.empty() || point != pointList[pointList.size() - 1])
+    if(pointList.empty() || point != pointList[pointList.size() - 1])
     {
-        pointList.push_back( point);
+        pointList.push_back(point);
     }
 }
 
 
-void FTContour::AddPoint( float x, float y)
-{
-    AddPoint( FTPoint( x, y, 0.0f));
-}
-
-
-void FTContour::evaluateQuadraticCurve()
+void FTContour::evaluateQuadraticCurve(FTPoint A, FTPoint B, FTPoint C)
 {
-    for( unsigned int i = 0; i <= ( 1.0f / BEZIER_STEP_SIZE); i++)
+    for(unsigned int i = 0; i <= (1.0f / BEZIER_STEP_SIZE); i++)
     {
-        float bezierValues[2][2];
-
         float t = static_cast<float>(i) * BEZIER_STEP_SIZE;
 
-        bezierValues[0][0] = (1.0f - t) * controlPoints[0][0] + t * controlPoints[1][0];
-        bezierValues[0][1] = (1.0f - t) * controlPoints[0][1] + t * controlPoints[1][1];
-    
-        bezierValues[1][0] = (1.0f - t) * controlPoints[1][0] + t * controlPoints[2][0];
-        bezierValues[1][1] = (1.0f - t) * controlPoints[1][1] + t * controlPoints[2][1];
-        
-        bezierValues[0][0] = (1.0f - t) * bezierValues[0][0] + t * bezierValues[1][0];
-        bezierValues[0][1] = (1.0f - t) * bezierValues[0][1] + t * bezierValues[1][1];
-    
-        AddPoint( bezierValues[0][0], bezierValues[0][1]);
+        FTPoint U = (1.0f - t) * A + t * B;
+        FTPoint V = (1.0f - t) * B + t * C;
+
+        AddPoint((1.0f - t) * U + t * V);
     }
 }
 
-void FTContour::evaluateCubicCurve()
+
+void FTContour::evaluateCubicCurve(FTPoint A, FTPoint B, FTPoint C, FTPoint D)
 {
-    for( unsigned int i = 0; i <= ( 1.0f / BEZIER_STEP_SIZE); i++)
+    for(unsigned int i = 0; i <= (1.0f / BEZIER_STEP_SIZE); i++)
     {
-        float bezierValues[3][2];
-
         float t = static_cast<float>(i) * BEZIER_STEP_SIZE;
 
-        bezierValues[0][0] = (1.0f - t) * controlPoints[0][0] + t * controlPoints[1][0];
-        bezierValues[0][1] = (1.0f - t) * controlPoints[0][1] + t * controlPoints[1][1];
-    
-        bezierValues[1][0] = (1.0f - t) * controlPoints[1][0] + t * controlPoints[2][0];
-        bezierValues[1][1] = (1.0f - t) * controlPoints[1][1] + t * controlPoints[2][1];
-        
-        bezierValues[2][0] = (1.0f - t) * controlPoints[2][0] + t * controlPoints[3][0];
-        bezierValues[2][1] = (1.0f - t) * controlPoints[2][1] + t * controlPoints[3][1];
-        
-        bezierValues[0][0] = (1.0f - t) * bezierValues[0][0] + t * bezierValues[1][0];
-        bezierValues[0][1] = (1.0f - t) * bezierValues[0][1] + t * bezierValues[1][1];
-    
-        bezierValues[1][0] = (1.0f - t) * bezierValues[1][0] + t * bezierValues[2][0];
-        bezierValues[1][1] = (1.0f - t) * bezierValues[1][1] + t * bezierValues[2][1];
-        
-        bezierValues[0][0] = (1.0f - t) * bezierValues[0][0] + t * bezierValues[1][0];
-        bezierValues[0][1] = (1.0f - t) * bezierValues[0][1] + t * bezierValues[1][1];
-    
-        AddPoint( bezierValues[0][0], bezierValues[0][1]);
+        FTPoint U = (1.0f - t) * A + t * B;
+        FTPoint V = (1.0f - t) * B + t * C;
+        FTPoint W = (1.0f - t) * C + t * D;
+
+        FTPoint M = (1.0f - t) * U + t * V;
+        FTPoint N = (1.0f - t) * V + t * W;
+
+        AddPoint((1.0f - t) * M + t * N);
     }
 }
 
 
-FTContour::FTContour( FT_Vector* contour, char* pointTags, unsigned int numberOfPoints)
+FTContour::FTContour(FT_Vector* contour, char* tags, unsigned int n)
 {
-    for( unsigned int pointIndex = 0; pointIndex < numberOfPoints; ++ pointIndex)
+    for(unsigned int i = 0; i < n; ++ i)
     {
-        char pointTag = pointTags[pointIndex];
-        
-        if( pointTag == FT_Curve_Tag_On || numberOfPoints < 2)
+        if(tags[i] == FT_Curve_Tag_On || n < 2)
         {
-            AddPoint( contour[pointIndex].x, contour[pointIndex].y);
+            AddPoint(contour[i]);
             continue;
         }
-        
-        FTPoint controlPoint( contour[pointIndex]);
-        FTPoint previousPoint = ( 0 == pointIndex)
-                                ? FTPoint( contour[numberOfPoints - 1])
-                                : pointList[pointList.size() - 1];
 
-        FTPoint nextPoint = ( pointIndex == numberOfPoints - 1)
-                            ? pointList[0]
-                            : FTPoint( contour[pointIndex + 1]);
+        FTPoint cur(contour[i]);
+        FTPoint prev = (0 == i)
+                       ? FTPoint(contour[n - 1])
+                       : pointList[pointList.size() - 1];
+
+        FTPoint next = (i == n - 1)
+                       ? pointList[0]
+                       : FTPoint(contour[i + 1]);
 
-        if( pointTag == FT_Curve_Tag_Conic)
+        if(tags[i] == FT_Curve_Tag_Conic)
         {
-            char nextPointTag = ( pointIndex == numberOfPoints - 1)
-                                ? pointTags[0]
-                                : pointTags[pointIndex + 1];
-            
-            while( nextPointTag == FT_Curve_Tag_Conic)
+            while(tags[(i == n - 1) ? 0 : i + 1] == FT_Curve_Tag_Conic)
             {
-                nextPoint = ( controlPoint + nextPoint) * 0.5f;
-
-                controlPoints[0][0] = previousPoint.X(); controlPoints[0][1] = previousPoint.Y();
-                controlPoints[1][0] = controlPoint.X();  controlPoints[1][1] = controlPoint.Y();
-                controlPoints[2][0] = nextPoint.X();     controlPoints[2][1] = nextPoint.Y();
-                
-                evaluateQuadraticCurve();
-                ++pointIndex;
-                
-                previousPoint = nextPoint;
-                controlPoint = FTPoint( contour[pointIndex]);
-                nextPoint = ( pointIndex == numberOfPoints - 1)
-                            ? pointList[0]
-                            : FTPoint( contour[pointIndex + 1]);
-                nextPointTag = ( pointIndex == numberOfPoints - 1)
-                               ? pointTags[0]
-                               : pointTags[pointIndex + 1];
+                next = (cur + next) * 0.5f;
+
+                evaluateQuadraticCurve(prev, cur, next);
+                ++i;
+
+                prev = next;
+                cur = FTPoint(contour[i]);
+                next = (i == n - 1)
+                       ? pointList[0]
+                       : FTPoint(contour[i + 1]);
             }
-            
-            controlPoints[0][0] = previousPoint.X(); controlPoints[0][1] = previousPoint.Y();
-            controlPoints[1][0] = controlPoint.X();  controlPoints[1][1] = controlPoint.Y();
-            controlPoints[2][0] = nextPoint.X();     controlPoints[2][1] = nextPoint.Y();
-            
-            evaluateQuadraticCurve();
+
+            evaluateQuadraticCurve(prev, cur, next);
             continue;
         }
 
-        if( pointTag == FT_Curve_Tag_Cubic)
+        if(tags[i] == FT_Curve_Tag_Cubic)
         {
-            FTPoint controlPoint2 = nextPoint;
-            
-            FTPoint nextPoint = ( pointIndex == numberOfPoints - 2)
-                                ? pointList[0]
-                                : FTPoint( contour[pointIndex + 2]);
-            
-            controlPoints[0][0] = previousPoint.X(); controlPoints[0][1] = previousPoint.Y();
-            controlPoints[1][0] = controlPoint.X();  controlPoints[1][1] = controlPoint.Y();
-            controlPoints[2][0] = controlPoint2.X(); controlPoints[2][1] = controlPoint2.Y();
-            controlPoints[3][0] = nextPoint.X();     controlPoints[3][1] = nextPoint.Y();
-        
-            evaluateCubicCurve();
-            ++pointIndex;
+            FTPoint cur2 = next;
+
+            FTPoint next = (i == n - 2)
+                           ? pointList[0]
+                           : FTPoint(contour[i + 2]);
+
+            evaluateCubicCurve(prev, cur, cur2, next);
+            ++i;
             continue;
         }
     }
 }
+