The Birdfont Source Code


All Repositories / birdfont.git / commitdiff – RSS feed

Handle full buffer in bezier curve simplification

These changes was commited to the Birdfont repository Sat, 07 Nov 2015 15:31:01 +0000.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
[Sat, 07 Nov 2015 15:31:01 +0000]

Updated Files

libbirdfont/OpenFontFormat/load_font.c
libbirdgems/fit_cubic.c
--- a/libbirdfont/OpenFontFormat/load_font.c +++ b/libbirdfont/OpenFontFormat/load_font.c @@ -792,13 +792,14 @@ 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; }
--- a/libbirdgems/fit_cubic.c +++ b/libbirdgems/fit_cubic.c @@ -21,7 +21,6 @@ /* Piecewise cubic fitting code */ #include "GraphicsGems.h" - #include <stdio.h> #ifdef MAC #include <malloc/malloc.h> @@ -31,6 +30,8 @@ #include <math.h> #include <stdio.h> + #include <glib.h> + typedef Point2 *BezierCurve; @@ -115,7 +116,7 @@ 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 @@ 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 @@ 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 */ @@ -196,10 +198,21 @@ int maxIterations = 4; /* Max times to try iterating */ 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 @@ /* 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 */ @@ -226,7 +243,6 @@ free((void *)bezCurve); return; } - /* If error not too large, try some reparameterization */ /* and iteration */ @@ -253,9 +269,9 @@ 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); } @@ -557,8 +573,18 @@ { 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++) {