Clone in a terminal:
Commit 1ca4849
Johan Mattsson - 2015-11-07T15:31:01+00:00
1ca4849348ec8f4c3b894c369eb0167208d1ddeejohan.mattsson.m@gmail.com

Handle full buffer in bezier curve simplification

Changed files (2)

Diff

diff --git a/libbirdfont/OpenFontFormat/load_font.c b/libbirdfont/OpenFontFormat/load_font.cindex 793804c..513da74 100644--- a/libbirdfont/OpenFontFormat/load_font.c+++ b/libbirdfont/OpenFontFormat/load_font.c@@ -792,13 +792,14 @@ void append_description (GString* str, FT_SfntName* name_table_data) {  int getIndexForNameIdEncoding (FT_Face face, int id, int encoding) { 	FT_SfntName name_table_data;-	FT_Error e;+	FT_Error error; 	int c = FT_Get_Sfnt_Name_Count (face); 	int i = 0; 	while (i < c){-		e = FT_Get_Sfnt_Name (face, i, &name_table_data);+		error = FT_Get_Sfnt_Name (face, i, &name_table_data); 		-		if (e == 0 && name_table_data.name_id == id +		if (error == 0+			&& name_table_data.name_id == id  			&& name_table_data.encoding_id == encoding) { 			return i; 		}diff --git a/libbirdgems/fit_cubic.c b/libbirdgems/fit_cubic.cindex 7587128..cda61f7 100644--- a/libbirdgems/fit_cubic.c+++ b/libbirdgems/fit_cubic.c@@ -21,7 +21,6 @@ Adapted to BirdFont by Johan Mattsson 2015 /*	Piecewise cubic fitting code	*/  #include "GraphicsGems.h"-#include <stdio.h>  #ifdef MAC #include <malloc/malloc.h>@@ -31,6 +30,8 @@ Adapted to BirdFont by Johan Mattsson 2015  #include <math.h> #include <stdio.h>+#include <glib.h>+  typedef Point2 *BezierCurve; @@ -115,7 +116,7 @@ void fit_bezier_curve_to_line ( 		j += 2; 	} 	-	int buffer_size = 8 * npoints;+	int buffer_size = 8 * lines_size; 	double* simplified_path = malloc (buffer_size * sizeof (double)); 	Buffer* buffer = gems_buffer_new (buffer_size, simplified_path); 	@@ -134,12 +135,12 @@ void DrawBezierCurve(Buffer* buffer, int n, Point2* curve) 	double* simplified_path;  	if (buffer->simplified_path_size + 8 > buffer->simplified_path_buffer_size) {-		fprintf (stderr, "The bezier buffer is full (%d).\n", buffer->simplified_path_buffer_size);+		g_warning ("The bezier buffer is full (%d).\n", buffer->simplified_path_buffer_size); 		return; 	}  	if (n != 3) {-		fprintf (stderr, "Expecting three points\n");+		g_warning ("Expecting three points\n"); 		return; 	} 	@@ -172,19 +173,20 @@ void FitCurve(buffer, d, nPts, error)      tHat1 = ComputeLeftTangent(d, 0);     tHat2 = ComputeRightTangent(d, nPts - 1);-    FitCubic(buffer, d, 0, nPts - 1, tHat1, tHat2, error);+    FitCubic(buffer, d, 0, nPts - 1, tHat1, tHat2, error, 0); }  /*  *  FitCubic :  *  	Fit a Bezier curve to a (sub)set of digitized points  */-static void FitCubic(buffer, d, first, last, tHat1, tHat2, error)+static void FitCubic(buffer, d, first, last, tHat1, tHat2, error, iterations)     Buffer* buffer;     Point2	*d;			/*  Array of digitized points */     int		first, last;	/* Indices of first and last pts in region */     Vector2	tHat1, tHat2;	/* Unit tangent vectors at endpoints */     double	error;		/*  User-defined error squared	   */+    int iterations; {     BezierCurve	bezCurve; /*Control points of fitted Bezier curve*/     double	*u;		/*  Parameter values for point  */@@ -197,9 +199,20 @@ static void FitCubic(buffer, d, first, last, tHat1, tHat2, error)     Vector2	tHatCenter;   	/* Unit tangent vector at splitPoint */     int		i;		 +	if (iterations > 2000) {+		g_warning("Too many iterations.");+		return;+	}+	iterations++;+     iterationError = error * error;     nPts = last - first + 1; +	if (nPts <= 1) {+		g_warning("nPts <= 1");+		return;+	}+	     /*  Use heuristic if region only has two points in it */     if (nPts == 2) { 	    double dist = V2DistanceBetween2Points(&d[last], &d[first]) / 3.0;@@ -216,6 +229,10 @@ static void FitCubic(buffer, d, first, last, tHat1, tHat2, error)      /*  Parameterize points, and attempt to fit curve */     u = ChordLengthParameterize(d, first, last);+    if (u == NULL) {+		return;+	}+         bezCurve = GenerateBezier(d, first, last, u, tHat1, tHat2);      /*  Find max deviation of points to fitted curve */@@ -227,7 +244,6 @@ static void FitCubic(buffer, d, first, last, tHat1, tHat2, error) 		return;     } -     /*  If error not too large, try some reparameterization  */     /*  and iteration */     if (maxError < iterationError) {@@ -253,9 +269,9 @@ static void FitCubic(buffer, d, first, last, tHat1, tHat2, error)     free((void *)u);     free((void *)bezCurve);     tHatCenter = ComputeCenterTangent(d, splitPoint);-    FitCubic(buffer, d, first, splitPoint, tHat1, tHatCenter, error);+    FitCubic(buffer, d, first, splitPoint, tHat1, tHatCenter, error, iterations);     V2Negate(&tHatCenter);-    FitCubic(buffer, d, splitPoint, last, tHatCenter, tHat2, error);+    FitCubic(buffer, d, splitPoint, last, tHatCenter, tHat2, error, iterations); }  @@ -558,7 +574,17 @@ static double *ChordLengthParameterize(d, first, last)     int		i;	     double	*u;			/*  Parameterization		*/ +	if (last-first+1 <= 0) {+		g_warning("No array.");+		return NULL;+	}+     u = (double *)malloc((unsigned)(last-first+1) * sizeof(double));+	+	if (u == NULL) {+		g_warning("Can't allocate array in ChordLengthParameterize");+		return NULL;+	}      u[0] = 0.0;     for (i = first+1; i <= last; i++) {

Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
GitHub: johanmattssonm
LinkedIn: johan-mattsson-2ab324112