summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2020-12-17 04:37:18 +0100
committerBenjamin Otte <otte@redhat.com>2020-12-19 18:35:12 +0100
commit4708d17cb88ec4b46287597efa9d99c3ad075b0f (patch)
treeb6e55a0e58b57d85b837a04dd7545e75c47fe3db
parent6e9bb79aa1d3e790ff6a5fed1482830c3347e44f (diff)
downloadgtk+-4708d17cb88ec4b46287597efa9d99c3ad075b0f.tar.gz
path: Add gsk_path_measure_restrict_to_contour()
-rw-r--r--docs/reference/gsk/gsk4-sections.txt3
-rw-r--r--gsk/gskpathmeasure.c77
-rw-r--r--gsk/gskpathmeasure.h6
3 files changed, 79 insertions, 7 deletions
diff --git a/docs/reference/gsk/gsk4-sections.txt b/docs/reference/gsk/gsk4-sections.txt
index 6c600954ed..8c8729302b 100644
--- a/docs/reference/gsk/gsk4-sections.txt
+++ b/docs/reference/gsk/gsk4-sections.txt
@@ -382,6 +382,9 @@ gsk_path_measure_unref
<SUBSECTION>
gsk_path_measure_get_path
gsk_path_measure_get_tolerance
+gsk_path_measure_get_n_contours
+gsk_path_measure_restrict_to_contour
+<SUBSECTION>
gsk_path_measure_get_length
gsk_path_measure_get_point
gsk_path_measure_get_closest_point
diff --git a/gsk/gskpathmeasure.c b/gsk/gskpathmeasure.c
index 17c3a608f8..d9afeffcb4 100644
--- a/gsk/gskpathmeasure.c
+++ b/gsk/gskpathmeasure.c
@@ -50,6 +50,9 @@ struct _GskPathMeasure
GskPath *path;
float tolerance;
+ gsize first;
+ gsize last;
+
float length;
gsize n_contours;
GskContourMeasure measures[];
@@ -107,6 +110,8 @@ gsk_path_measure_new_with_tolerance (GskPath *path,
self->path = gsk_path_ref (path);
self->tolerance = tolerance;
self->n_contours = n_contours;
+ self->first = 0;
+ self->last = n_contours;
for (i = 0; i < n_contours; i++)
{
@@ -177,6 +182,8 @@ gsk_path_measure_unref (GskPathMeasure *self)
GskPath *
gsk_path_measure_get_path (GskPathMeasure *self)
{
+ g_return_val_if_fail (self != NULL, NULL);
+
return self->path;
}
@@ -191,10 +198,66 @@ gsk_path_measure_get_path (GskPathMeasure *self)
float
gsk_path_measure_get_tolerance (GskPathMeasure *self)
{
+ g_return_val_if_fail (self != NULL, 0.f);
+
return self->tolerance;
}
/**
+ * gsk_path_measure_get_n_contours:
+ * @self: a #GskPathMeasure
+ *
+ * Returns the number of contours in the path being measured.
+ *
+ * The returned value is independent of whether @self if restricted
+ * or not.
+ *
+ * Returns: The number of contours
+ **/
+gsize
+gsk_path_measure_get_n_contours (GskPathMeasure *self)
+{
+ g_return_val_if_fail (self != NULL, 0);
+
+ return self->n_contours;
+}
+
+/**
+ * gsk_path_measure_restrict_to_contour:
+ * @self: a #GskPathMeasure
+ * @contour: contour to restrict to or (gsize) -1 for using the
+ * whole path
+ *
+ * Restricts all functions on the path to just the given @contour.
+ *
+ * If @contour >= gsk_path_measure_get_n_contours() - so in
+ * particular when it is set to -1 - the whole path will be used.
+ **/
+void
+gsk_path_measure_restrict_to_contour (GskPathMeasure *self,
+ gsize contour)
+{
+ if (contour >= self->n_contours)
+ {
+ /* use the whole path */
+ self->first = 0;
+ self->last = self->n_contours;
+ }
+ else
+ {
+ /* use just one contour */
+ self->first = contour;
+ self->last = contour + 1;
+ }
+
+ self->length = 0;
+ for (gsize i = self->first; i < self->last; i++)
+ {
+ self->length += self->measures[i].length;
+ }
+}
+
+/**
* gsk_path_measure_get_length:
* @self: a #GskPathMeasure
*
@@ -257,7 +320,7 @@ gsk_path_measure_get_point (GskPathMeasure *self,
distance = gsk_path_measure_clamp_distance (self, distance);
- for (i = 0; i < self->n_contours; i++)
+ for (i = self->first; i < self->last; i++)
{
if (distance < self->measures[i].length)
break;
@@ -266,10 +329,10 @@ gsk_path_measure_get_point (GskPathMeasure *self,
}
/* weird corner cases */
- if (i == self->n_contours)
+ if (i == self->last)
{
/* the empty path goes here */
- if (self->n_contours == 0)
+ if (self->first == self->last)
{
if (pos)
graphene_point_init (pos, 0.f, 0.f);
@@ -278,7 +341,7 @@ gsk_path_measure_get_point (GskPathMeasure *self,
return;
}
/* rounding errors can make this happen */
- i = self->n_contours - 1;
+ i = self->last - 1;
distance = self->measures[i].length;
}
@@ -372,7 +435,7 @@ gsk_path_measure_get_closest_point_full (GskPathMeasure *self,
result = FALSE;
length = 0;
- for (i = 0; i < self->n_contours; i++)
+ for (i = self->first; i < self->last; i++)
{
if (gsk_contour_get_closest_point (gsk_path_get_contour (self->path, i),
self->measures[i].contour_data,
@@ -422,7 +485,7 @@ gsk_path_measure_in_fill (GskPathMeasure *self,
gboolean on_edge = FALSE;
int i;
- for (i = 0; i < self->n_contours; i++)
+ for (i = self->first; i < self->last; i++)
{
winding += gsk_contour_get_winding (gsk_path_get_contour (self->path, i),
self->measures[i].contour_data,
@@ -476,7 +539,7 @@ gsk_path_builder_add_segment (GskPathBuilder *self,
if (start >= end)
return;
- for (i = 0; i < measure->n_contours; i++)
+ for (i = measure->first; i < measure->last; i++)
{
if (measure->measures[i].length < start)
{
diff --git a/gsk/gskpathmeasure.h b/gsk/gskpathmeasure.h
index d2ca5799c2..0a3ff9bf17 100644
--- a/gsk/gskpathmeasure.h
+++ b/gsk/gskpathmeasure.h
@@ -48,6 +48,12 @@ GDK_AVAILABLE_IN_ALL
GskPath * gsk_path_measure_get_path (GskPathMeasure *self);
GDK_AVAILABLE_IN_ALL
float gsk_path_measure_get_tolerance (GskPathMeasure *self);
+GDK_AVAILABLE_IN_ALL
+gsize gsk_path_measure_get_n_contours (GskPathMeasure *self);
+
+GDK_AVAILABLE_IN_ALL
+void gsk_path_measure_restrict_to_contour (GskPathMeasure *self,
+ gsize contour);
GDK_AVAILABLE_IN_ALL
float gsk_path_measure_get_length (GskPathMeasure *self);