return temp;
}
+/**
+ * gdk_region_rectangle:
+ * @rectangle: a #GdkRectangle
+ *
+ * Creates a new region containing the area @rectangle.
+ *
+ * Return value: a new region
+ **/
GdkRegion *
gdk_region_rectangle (GdkRectangle *rectangle)
{
return temp;
}
+/**
+ * gdk_region_copy:
+ * @region: a #GdkRegion
+ *
+ * Copies @region, creating an identical new region.
+ *
+ * Return value: a new region identical to @region
+ **/
GdkRegion *
gdk_region_copy (GdkRegion *region)
{
rect->height = r->extents.y2 - r->extents.y1;
}
+
+/**
+ * gdk_region_get_rectangles:
+ * @region: a #GdkRegion
+ * @rectangles: return location for an array of rectangles
+ * @n_rectangles: length of returned array
+ *
+ * Obtains the area covered by the region as a list of rectangles.
+ * The array returned in @rectangles must be freed with g_free().
+ *
+ **/
+void
+gdk_region_get_rectangles (GdkRegion *region,
+ GdkRectangle **rectangles,
+ gint *n_rectangles)
+{
+ gint i;
+
+ g_return_if_fail (region != NULL);
+ g_return_if_fail (rectangles != NULL);
+ g_return_if_fail (n_rectangles != NULL);
+
+ *n_rectangles = region->numRects;
+ *rectangles = g_new (GdkRectangle, region->numRects);
+
+ for (i = 0; i < region->numRects; i++)
+ {
+ GdkRegionBox rect;
+ rect = region->rects[i];
+ (*rectangles)[i].x = rect.x1;
+ (*rectangles)[i].y = rect.y1;
+ (*rectangles)[i].width = rect.x2 - rect.x1;
+ (*rectangles)[i].height = rect.y2 - rect.y1;
+ }
+}
+
void
gdk_region_union_with_rect (GdkRegion *region,
GdkRectangle *rect)
}
}
+/**
+ * gdk_region_intersect:
+ * @source1: a #GdkRegion
+ * @source2: another #GdkRegion
+ *
+ * Converts @source1 into the intersection between @source1 and @source2.
+ * That is, after calling this function @source2 will be unchanged and
+ * @source1 will be the areas the two regions have in common.
+ *
+ **/
void
gdk_region_intersect (GdkRegion *region,
GdkRegion *other)
}
}
}
-
-/*-
- *-----------------------------------------------------------------------
- * gdk_region_subtract --
- * Subtract other from region and leave the result in region.
- *
- * Results:
- * TRUE.
- *
- * Side Effects:
- * region is overwritten.
- *
- *-----------------------------------------------------------------------
- */
+/**
+ * gdk_region_subtract:
+ * @source1: a #GdkRegion
+ * @source2: another #GdkRegion
+ *
+ * Subtracts any area in @source2 from the area in @source1.
+ *
+ **/
void
gdk_region_subtract (GdkRegion *region,
GdkRegion *other)
miSetExtents (region);
}
+/**
+ * gdk_region_xor:
+ * @source1: a #GdkRegion
+ * @source2: another #GdkRegion
+ *
+ * XORs the two regions, placing the result in @source1. The XOR of two
+ * regions contains all areas which were not overlapping. That is,
+ * it's the union of the regions minus the intersection of the
+ * regions.
+ *
+ **/
void
gdk_region_xor (GdkRegion *sra,
GdkRegion *srb)
GDK_OVERLAP_RECTANGLE_PART : GDK_OVERLAP_RECTANGLE_IN) :
GDK_OVERLAP_RECTANGLE_OUT);
}
+
+
+static void
+gdk_region_unsorted_spans_intersect_foreach (GdkRegion *region,
+ GdkSpan *spans,
+ int n_spans,
+ GdkSpanFunc function,
+ gpointer data)
+{
+ gint i, left, right, y;
+ gint clipped_left, clipped_right;
+ GdkRegionBox *pbox;
+ GdkRegionBox *pboxEnd;
+ GdkSpan out_span;
+
+ if (!region->numRects)
+ return;
+
+ for (i=0;i<n_spans;i++)
+ {
+ y = spans[i].y;
+ left = spans[i].x;
+ right = left + spans[i].width; /* right is not in the span! */
+
+ if (! ((region->extents.y1 <= y) &&
+ (region->extents.y2 > y) &&
+ (region->extents.x1 < right) &&
+ (region->extents.x2 > left)) )
+ continue;
+
+ /* can stop when we passed y */
+ for (pbox = region->rects, pboxEnd = pbox + region->numRects;
+ pbox < pboxEnd;
+ pbox++)
+ {
+ if (pbox->y2 <= y)
+ continue; /* Not quite there yet */
+
+ if (pbox->y1 > y)
+ break; /* passed the spanline */
+
+ if ((right > pbox->x1) && (left < pbox->x2))
+ {
+ clipped_left = MAX (left, pbox->x1);
+ clipped_right = MIN (right, pbox->x2);
+
+ out_span.y = y;
+ out_span.x = clipped_left;
+ out_span.width = clipped_right - clipped_left;
+ (*function) (&out_span, data);
+ }
+ }
+ }
+}
+
+
+void
+gdk_region_spans_intersect_foreach (GdkRegion *region,
+ GdkSpan *spans,
+ int n_spans,
+ gboolean sorted,
+ GdkSpanFunc function,
+ gpointer data)
+{
+ gint left, right, y;
+ gint clipped_left, clipped_right;
+ GdkRegionBox *pbox;
+ GdkRegionBox *pboxEnd;
+ GdkSpan *span, *tmpspan;
+ GdkSpan *end_span;
+ GdkSpan out_span;
+
+ if (!sorted)
+ {
+ gdk_region_unsorted_spans_intersect_foreach (region,
+ spans,
+ n_spans,
+ function,
+ data);
+ return;
+ }
+
+ if ((!region->numRects) || (n_spans == 0))
+ return;
+
+ y = span->y;
+ left = span->x;
+ right = span->x + span->width; /* right is not in the span! */
+
+ /* The main method here is to step along the
+ * sorted rectangles and spans in lock step, and
+ * clipping the spans that are in the current
+ * rectangle before going on to the next rectangle.
+ */
+
+ span = spans;
+ end_span = spans + n_spans;
+ pbox = region->rects;
+ pboxEnd = pbox + region->numRects;
+ while (pbox < pboxEnd)
+ {
+ while ((pbox->y2 < span->y) || (span->y < pbox->y1))
+ {
+ /* Skip any rectangles that are above the current span */
+ if (pbox->y2 < span->y)
+ {
+ pbox++;
+ if (pbox == pboxEnd)
+ return;
+ }
+ /* Skip any spans that are above the current rectangle */
+ if (span->y < pbox->y1)
+ {
+ span++;
+ if (span == end_span)
+ return;
+ }
+ }
+
+ /* Ok, we got at least one span that might intersect this rectangle. */
+ tmpspan = span;
+ while ((tmpspan < end_span) &&
+ (tmpspan->y < pbox->y2))
+ {
+ y = tmpspan->y;
+ left = tmpspan->x;
+ right = left + tmpspan->width; /* right is not in the span! */
+
+ if ((right > pbox->x1) && (left < pbox->x2))
+ {
+ clipped_left = MAX (left, pbox->x1);
+ clipped_right = MIN (right, pbox->x2);
+
+ out_span.y = y;
+ out_span.x = clipped_left;
+ out_span.width = clipped_right - clipped_left;
+ (*function) (&out_span, data);
+ }
+
+ tmpspan++;
+ }
+
+ /* Finished this rectangle.
+ * The spans could still intersect the next one
+ */
+ pbox++;
+ }
+}