Commit ec4a06b789983b1e527fbef735ede677a877d56b

henry 2001-08-02T21:52:58

Made the ftPoint struct an external class and added some helper functions eg operator != Got rid of ftLoop, it's not needed now that I've tidied up the curve parsing code (which fixed the Vivaldi Q bug) Minor code tidy ups.

diff --git a/include/FTVectoriser.h b/include/FTVectoriser.h
index 0d41d9a..e80ada5 100644
--- a/include/FTVectoriser.h
+++ b/include/FTVectoriser.h
@@ -9,6 +9,64 @@
 
 #include "FTGlyph.h"
 
+
+// template < typename T>
+// class ftLoop
+// {
+// 	public:	
+// 		ftLoop();
+// 		~ftLoop()
+// 		{
+// 			list.clear();
+// 		}
+// 		
+// 		T& operator [] (unsigned int i)
+// 		{
+// 			int x = i;
+// 			if( i < 0)
+// 				x = i + list.size();
+// 			
+// 			if( i > list.size())
+// 				x = i % list.size();
+// 			
+// 			return list[x];
+// 		}
+// 		
+// 		void push_back( T t)
+// 		{
+// 			list.push_back(t);
+// 		}
+// 		
+// 	private:
+// 		vector<T> list;
+// };
+
+
+class ftPoint
+{
+	public:
+		ftPoint()
+		: x(0), y(0), z(0){}
+		
+		ftPoint( float X, float Y, float Z)
+		: x(X), y(Y), z(Z){}
+		
+		friend bool operator == (const ftPoint &a, const ftPoint &b)
+		{
+			return((a.x == b.x) && (a.y == b.y) && (a.z == b.z));
+		}
+
+		friend bool operator != (const ftPoint &a, const ftPoint &b)
+		{
+			return((a.x != b.x) || (a.y != b.y) || (a.z != b.z));
+		}
+		
+		float x, y, z;
+		
+	private:
+};
+
+
 class FTContour
 {
 	public:
@@ -21,28 +79,15 @@ class FTContour
 		int size() const { return pointList.size();}
 
 		// attributes
-		
-//		typedef pair<int, int> ftPoint;
-		struct ftPoint
-		{
-			float x, y, z;
-			ftPoint()
-			: x(0), y(0), z(0){}
-			
-			ftPoint( float X, float Y, float Z)
-			: x(X), y(Y), z(Z){}
-		};
-
 		vector< ftPoint> pointList;
 		float ctrlPtArray[4][2];
+		
 	private:
 		// methods
 
 		// attributes
 };
 
-//FIXME get rid of this
-#define MAX_DEG 4
 
 class FTVectoriser
 {
@@ -52,12 +97,13 @@ class FTVectoriser
 		virtual ~FTVectoriser();
 		
 		bool Ingest();
-		void Output( float* d);
+		void Output( double* d);
 		int points();
 		int contours() const { return contourList.size();}
 		int contourSize( int c) const { return contourList[c]->size();}
 		
 		// attributes
+		int contourFlag; 
 		
 	private:
 		// methods
@@ -68,13 +114,14 @@ class FTVectoriser
 
 		// attributes
 		vector< FTContour*> contourList;
-		float ctrlPtArray[4][2];
+		float ctrlPtArray[4][2]; // Magic numbers
 			
 		FTContour* contour;
 
 		FT_Outline ftOutline;
 		
-		float bValues[MAX_DEG][MAX_DEG][2];	//3D array storing values
+		 // Magic numbers -- #define MAX_DEG 4
+		float bValues[4][4][2];	//3D array storing values
                                         	//of de Casteljau algorithm.
 
 
diff --git a/src/FTVectoriser.cpp b/src/FTVectoriser.cpp
index 2e7e21a..6f20f1a 100644
--- a/src/FTVectoriser.cpp
+++ b/src/FTVectoriser.cpp
@@ -18,14 +18,13 @@ FTContour::~FTContour()
 
 void FTContour::AddPoint( int x, int y)
 {
-	float fx, fy, fz;
+	ftPoint point( static_cast<float>( x), static_cast<float>( y), 0.0); 
 	
-	fx = static_cast<float>( x);
-	fy = static_cast<float>( y);
-	fy = 0;
-	
-	pointList.push_back( ftPoint( fx, fy, fz));
-
+	// Eliminate duplicate points.
+	if( ( pointList[pointList.size() - 1] != point) || pointList[0] != point)
+	{
+		pointList.push_back( point);
+	}
 }
 
 
@@ -112,7 +111,9 @@ bool FTVectoriser::Ingest()
 	{
 		contour = new FTContour;
 		
-		short last =  ftOutline.contours[c];
+		contourFlag = ftOutline.flags;
+		
+		short last = ftOutline.contours[c];
 
 		for( short p = first; p <= last; ++p)
 		{
@@ -142,53 +143,40 @@ bool FTVectoriser::Ingest()
 
 int FTVectoriser::Conic( int index, int first, int last)
 {
-	if( ftOutline.tags[index + 1] != FT_Curve_Tag_Conic)
-	{
-		if( index != first)
-		{
-			ctrlPtArray[0][0] = ftOutline.points[index-1].x;	ctrlPtArray[0][1] = ftOutline.points[index-1].y;
-		}
-		else
-		{
-			ctrlPtArray[0][0] = ftOutline.points[last].x;	ctrlPtArray[0][1] = ftOutline.points[last].y;
-		}
+	int next = index + 1;
+	int prev = index - 1;
 	
+	if( index == last)
+		next = first; 
+	
+	if( index == first)
+		prev = last; 
+	
+	if( ftOutline.tags[next] != FT_Curve_Tag_Conic)
+	{
+		ctrlPtArray[0][0] = ftOutline.points[prev].x;	ctrlPtArray[0][1] = ftOutline.points[prev].y;
 		ctrlPtArray[1][0] = ftOutline.points[index].x;		ctrlPtArray[1][1] = ftOutline.points[index].y;
+		ctrlPtArray[2][0] = ftOutline.points[next].x;	ctrlPtArray[2][1] = ftOutline.points[next].y;
 		
-//		if( index != last)
-//		{
-//			ctrlPtArray[2][0] = ftOutline.points[index+1].x;	ctrlPtArray[2][1] = ftOutline.points[index+1].y;
-//		}
-//		else
-//		{
-//			ctrlPtArray[2][0] = ftOutline.points[first].x;	ctrlPtArray[2][1] = ftOutline.points[first].y;
-//		}
 		evaluateCurve( 2);
 		return 1;
 	}
 	else
 	{
 		//create a phantom point
-		float x = ( ftOutline.points[index].x + ftOutline.points[index+1].x) / 2;
-		float y = ( ftOutline.points[index].y + ftOutline.points[index+1].y) / 2;
+		float x = ( ftOutline.points[index].x + ftOutline.points[next].x) / 2;
+		float y = ( ftOutline.points[index].y + ftOutline.points[next].y) / 2;
 		
 		// process first curve
-		if( index != first)
-		{
-			ctrlPtArray[0][0] = ftOutline.points[index-1].x;	ctrlPtArray[0][1] = ftOutline.points[index-1].y;
-		}
-		else
-		{
-			ctrlPtArray[0][0] = ftOutline.points[last].x;	ctrlPtArray[0][1] = ftOutline.points[last].y;
-		}
-		
+		ctrlPtArray[0][0] = ftOutline.points[prev].x;	ctrlPtArray[0][1] = ftOutline.points[prev].y;
 		ctrlPtArray[1][0] = ftOutline.points[index].x;		ctrlPtArray[1][1] = ftOutline.points[index].y;
 		ctrlPtArray[2][0] = x;	ctrlPtArray[2][1] = y;
+		
 		evaluateCurve( 2);
 		
 		// process second curve
 		ctrlPtArray[0][0] = x;	ctrlPtArray[0][1] = y;
-		ctrlPtArray[1][0] = ftOutline.points[index + 1].x;		ctrlPtArray[1][1] = ftOutline.points[index + 1].y;
+		ctrlPtArray[1][0] = ftOutline.points[next].x;		ctrlPtArray[1][1] = ftOutline.points[next].y;
 		
 		if( index != last -1)
 		{
@@ -207,17 +195,18 @@ int FTVectoriser::Conic( int index, int first, int last)
 
 int FTVectoriser::Cubic( int index, int first, int last)
 {
-	if( index != first)
-	{
-		ctrlPtArray[0][0] = ftOutline.points[index-1].x;	ctrlPtArray[0][1] = ftOutline.points[index-1].y;
-	}
-	else
-	{
-		ctrlPtArray[0][0] = ftOutline.points[last].x;	ctrlPtArray[0][1] = ftOutline.points[last].y;
-	}
+	int next = index + 1;
+	int prev = index - 1;
+	
+	if( index == last)
+		next = first; 
 	
+	if( index == first)
+		prev = last; 
+
+	ctrlPtArray[0][0] = ftOutline.points[prev].x;	ctrlPtArray[0][1] = ftOutline.points[prev].y;
 	ctrlPtArray[1][0] = ftOutline.points[index].x;		ctrlPtArray[1][1] = ftOutline.points[index].y;
-	ctrlPtArray[2][0] = ftOutline.points[index + 1].x;		ctrlPtArray[2][1] = ftOutline.points[index + 1].y;
+	ctrlPtArray[2][0] = ftOutline.points[next].x;		ctrlPtArray[2][1] = ftOutline.points[next].y;
 	if( index != last -1)
 	{
 		ctrlPtArray[3][0] = ftOutline.points[index+2].x;	ctrlPtArray[3][1] = ftOutline.points[index+2].y;
@@ -231,7 +220,7 @@ int FTVectoriser::Cubic( int index, int first, int last)
 }
 
 
-void FTVectoriser::Output( float* data)
+void FTVectoriser::Output( double* data)
 {
 	int i = 0;
 	
@@ -241,9 +230,9 @@ void FTVectoriser::Output( float* data)
 		
 		for( int p = 0; p < contour->size(); ++p)
 		{
-			data[i] = contour->pointList[p].x / 64.0f; // is 64 correct?
-			data[i + 1] = contour->pointList[p].y / 64.0f;
-			data[i + 2] = contour->pointList[p].z / 64.0f;
+			data[i] = static_cast<double>(contour->pointList[p].x / 64.0f); // is 64 correct?
+			data[i + 1] = static_cast<double>(contour->pointList[p].y / 64.0f);
+			data[i + 2] = static_cast<double>(contour->pointList[p].z / 64.0f);
 			i += 3;
 		}
 	}