path: Deal with non-uniformness of progress parameter

The progress is non-uniform, so simple translation of progress doesn't work.
So check if larger and smaller values inch closer towards minimal distance.
This commit is contained in:
Benjamin Otte
2020-12-09 21:42:55 +01:00
parent 9abf9bb3b2
commit 65f8338a30

View File

@@ -1124,23 +1124,6 @@ gsk_standard_contour_find_measure (gconstpointer m,
return 0;
}
static void
gsk_standard_contour_measure_get_point (GskStandardContour *self,
gsize op,
float progress,
graphene_point_t *pos,
graphene_vec2_t *tangent)
{
GskCurve curve;
gsk_curve_init (&curve, self->ops[op]);
if (pos)
gsk_curve_get_point (&curve, progress, pos);
if (tangent)
gsk_curve_get_tangent (&curve, progress, tangent);
}
static void
gsk_standard_contour_get_point (const GskContour *contour,
gpointer measure_data,
@@ -1153,6 +1136,7 @@ gsk_standard_contour_get_point (const GskContour *contour,
guint index;
float progress;
GskStandardContourMeasure *measure;
GskCurve curve;
if (array->len == 0)
{
@@ -1172,7 +1156,12 @@ gsk_standard_contour_get_point (const GskContour *contour,
progress = measure->start_progress + (measure->end_progress - measure->start_progress) * progress;
g_assert (progress >= 0 && progress <= 1);
gsk_standard_contour_measure_get_point (self, measure->op, progress, pos, tangent);
gsk_curve_init (&curve, self->ops[measure->op]);
if (pos)
gsk_curve_get_point (&curve, progress, pos);
if (tangent)
gsk_curve_get_tangent (&curve, progress, tangent);
}
static gboolean
@@ -1235,15 +1224,45 @@ gsk_standard_contour_get_closest_point (const GskContour *contour,
//g_print ("%zu: (%g-%g) dist %g\n", i, measure->start, measure->end, dist);
if (dist <= threshold + 1.0f)
{
graphene_vec2_t t;
float found_progress;
GskCurve curve;
graphene_point_t p2;
float found_progress, test_progress, test_dist;
const float step = 1/1024.f;
gsk_curve_init (&curve, self->ops[measure->op]);
found_progress = measure->start_progress + (measure->end_progress - measure->start_progress) * progress;
gsk_standard_contour_measure_get_point (self, measure->op, found_progress, &p, out_tangent ? &t : NULL);
gsk_curve_get_point (&curve, found_progress, &p);
dist = graphene_point_distance (point, &p, NULL, NULL);
//g_print ("!!! %zu: (%g-%g @ %g) dist %g\n", i, measure->start_progress, measure->end_progress, progress, dist);
/* The progress is non-uniform, so simple translation of progress doesn't work.
* Check if larger values inch closer towards minimal distance. */
while (progress + step < 1.0f) {
test_progress = measure->start_progress + (measure->end_progress - measure->start_progress) * (progress + step);
gsk_curve_get_point (&curve, test_progress, &p2);
test_dist = graphene_point_distance (point, &p2, NULL, NULL);
if (test_dist > dist)
break;
progress += step;
p = p2;
found_progress = test_progress;
dist = test_dist;
}
/* Also check smaller ones */
while (progress - step > 0.0f) {
test_progress = measure->start_progress + (measure->end_progress - measure->start_progress) * (progress - step);
gsk_curve_get_point (&curve, test_progress, &p2);
test_dist = graphene_point_distance (point, &p2, NULL, NULL);
if (test_dist > dist)
break;
progress -= step;
p = p2;
found_progress = test_progress;
dist = test_dist;
}
//g_print ("!!! %zu: (%g-%g @ %g) dist %g\n", i, measure->start_progress, measure->end_progress, progress, dist);
/* double check that the point actually is closer */
//g_print ("!!! %zu: (%g-%g) dist %g\n", i, measure->start, measure->end, dist);
if (dist <= threshold)
{
if (out_distance)
@@ -1253,7 +1272,7 @@ gsk_standard_contour_get_closest_point (const GskContour *contour,
if (out_offset)
*out_offset = measure->start + (measure->end - measure->start) * progress;
if (out_tangent)
*out_tangent = t;
gsk_curve_get_tangent (&curve, found_progress, out_tangent);
result = TRUE;
if (tolerance >= dist)
return TRUE;