[gvar] Don't try IUP if all points are specified

This commit is contained in:
Behdad Esfahbod 2022-11-22 13:21:01 -07:00
parent 27c4037e59
commit c34c77698c
1 changed files with 47 additions and 41 deletions

View File

@ -612,11 +612,13 @@ struct gvar
hb_memset (deltas.arrayZ, 0, deltas.length * sizeof (deltas.arrayZ[0])); hb_memset (deltas.arrayZ, 0, deltas.length * sizeof (deltas.arrayZ[0]));
unsigned ref_points = 0;
if (scalar != 1.0f) if (scalar != 1.0f)
for (unsigned int i = 0; i < num_deltas; i++) for (unsigned int i = 0; i < num_deltas; i++)
{ {
unsigned int pt_index = apply_to_all ? i : indices[i]; unsigned int pt_index = apply_to_all ? i : indices[i];
if (unlikely (pt_index >= deltas.length)) continue; if (unlikely (pt_index >= deltas.length)) continue;
ref_points += !deltas.arrayZ[pt_index].flag;
deltas.arrayZ[pt_index].flag = 1; /* this point is referenced, i.e., explicit deltas specified */ deltas.arrayZ[pt_index].flag = 1; /* this point is referenced, i.e., explicit deltas specified */
deltas.arrayZ[pt_index].x += x_deltas.arrayZ[i] * scalar; deltas.arrayZ[pt_index].x += x_deltas.arrayZ[i] * scalar;
deltas.arrayZ[pt_index].y += y_deltas.arrayZ[i] * scalar; deltas.arrayZ[pt_index].y += y_deltas.arrayZ[i] * scalar;
@ -626,59 +628,63 @@ struct gvar
{ {
unsigned int pt_index = apply_to_all ? i : indices[i]; unsigned int pt_index = apply_to_all ? i : indices[i];
if (unlikely (pt_index >= deltas.length)) continue; if (unlikely (pt_index >= deltas.length)) continue;
ref_points += !deltas.arrayZ[pt_index].flag;
deltas.arrayZ[pt_index].flag = 1; /* this point is referenced, i.e., explicit deltas specified */ deltas.arrayZ[pt_index].flag = 1; /* this point is referenced, i.e., explicit deltas specified */
deltas.arrayZ[pt_index].x += x_deltas.arrayZ[i]; deltas.arrayZ[pt_index].x += x_deltas.arrayZ[i];
deltas.arrayZ[pt_index].y += y_deltas.arrayZ[i]; deltas.arrayZ[pt_index].y += y_deltas.arrayZ[i];
} }
/* infer deltas for unreferenced points */ /* infer deltas for unreferenced points */
unsigned start_point = 0; if (ref_points < orig_points.length)
for (unsigned c = 0; c < end_points.length; c++)
{ {
unsigned end_point = end_points.arrayZ[c]; unsigned start_point = 0;
for (unsigned c = 0; c < end_points.length; c++)
/* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */
unsigned unref_count = 0;
for (unsigned i = start_point; i <= end_point; i++)
if (!deltas.arrayZ[i].flag) unref_count++;
unsigned j = start_point;
if (unref_count == 0 || unref_count > end_point - start_point)
goto no_more_gaps;
for (;;)
{ {
/* Locate the next gap of unreferenced points between two referenced points prev and next. unsigned end_point = end_points.arrayZ[c];
* Note that a gap may wrap around at left (start_point) and/or at right (end_point).
*/ /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */
unsigned int prev, next, i; unsigned unref_count = 0;
for (unsigned i = start_point; i <= end_point; i++)
if (!deltas.arrayZ[i].flag) unref_count++;
unsigned j = start_point;
if (unref_count == 0 || unref_count > end_point - start_point)
goto no_more_gaps;
for (;;) for (;;)
{ {
i = j; /* Locate the next gap of unreferenced points between two referenced points prev and next.
j = next_index (i, start_point, end_point); * Note that a gap may wrap around at left (start_point) and/or at right (end_point).
if (deltas.arrayZ[i].flag && !deltas.arrayZ[j].flag) break; */
} unsigned int prev, next, i;
prev = j = i; for (;;)
for (;;) {
{ i = j;
i = j; j = next_index (i, start_point, end_point);
j = next_index (i, start_point, end_point); if (deltas.arrayZ[i].flag && !deltas.arrayZ[j].flag) break;
if (!deltas.arrayZ[i].flag && deltas.arrayZ[j].flag) break; }
} prev = j = i;
next = j; for (;;)
/* Infer deltas for all unref points in the gap between prev and next */ {
i = prev; i = j;
for (;;) j = next_index (i, start_point, end_point);
{ if (!deltas.arrayZ[i].flag && deltas.arrayZ[j].flag) break;
i = next_index (i, start_point, end_point); }
if (i == next) break; next = j;
deltas.arrayZ[i].x = infer_delta (orig_points, deltas, i, prev, next, &contour_point_t::x); /* Infer deltas for all unref points in the gap between prev and next */
deltas.arrayZ[i].y = infer_delta (orig_points, deltas, i, prev, next, &contour_point_t::y); i = prev;
if (--unref_count == 0) goto no_more_gaps; for (;;)
{
i = next_index (i, start_point, end_point);
if (i == next) break;
deltas.arrayZ[i].x = infer_delta (orig_points, deltas, i, prev, next, &contour_point_t::x);
deltas.arrayZ[i].y = infer_delta (orig_points, deltas, i, prev, next, &contour_point_t::y);
if (--unref_count == 0) goto no_more_gaps;
}
} }
no_more_gaps:
start_point = end_point + 1;
} }
no_more_gaps:
start_point = end_point + 1;
} }
/* apply specified / inferred deltas to points */ /* apply specified / inferred deltas to points */