cairo_status_t _cairo_polygon_init_boxes (cairo_polygon_t *polygon, const cairo_boxes_t *boxes) { const struct _cairo_boxes_chunk *chunk; int i; VG (VALGRIND_MAKE_MEM_UNDEFINED (polygon, sizeof (cairo_polygon_t))); polygon->status = CAIRO_STATUS_SUCCESS; polygon->num_edges = 0; polygon->edges = polygon->edges_embedded; polygon->edges_size = ARRAY_LENGTH (polygon->edges_embedded); if (boxes->num_boxes > ARRAY_LENGTH (polygon->edges_embedded)/2) { polygon->edges_size = 2 * boxes->num_boxes; polygon->edges = _cairo_malloc_ab (polygon->edges_size, 2*sizeof(cairo_edge_t)); if (unlikely (polygon->edges == XNULL)) return polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); } polygon->extents.p1.x = polygon->extents.p1.y = INT32_MAX; polygon->extents.p2.x = polygon->extents.p2.y = INT32_MIN; polygon->limits = XNULL; polygon->num_limits = 0; for (chunk = &boxes->chunks; chunk != XNULL; chunk = chunk->next) { for (i = 0; i < chunk->count; i++) { cairo_point_t p1, p2; p1 = chunk->base[i].p1; p2.x = p1.x; p2.y = chunk->base[i].p2.y; _cairo_polygon_add_edge (polygon, &p1, &p2, 1); p1 = chunk->base[i].p2; p2.x = p1.x; p2.y = chunk->base[i].p1.y; _cairo_polygon_add_edge (polygon, &p1, &p2, 1); } } return polygon->status; }
cairo_status_t _cairo_polygon_add_external_edge (void *polygon, const cairo_point_t *p1, const cairo_point_t *p2) { _cairo_polygon_add_edge (polygon, p1, p2, 1); return _cairo_polygon_status (polygon); }
cairo_status_t _cairo_polygon_init_box_array (cairo_polygon_t *polygon, cairo_box_t *boxes, int num_boxes) { int i; VG (VALGRIND_MAKE_MEM_UNDEFINED (polygon, sizeof (cairo_polygon_t))); polygon->status = CAIRO_STATUS_SUCCESS; polygon->num_edges = 0; polygon->edges = polygon->edges_embedded; polygon->edges_size = ARRAY_LENGTH (polygon->edges_embedded); if (num_boxes > ARRAY_LENGTH (polygon->edges_embedded)/2) { polygon->edges_size = 2 * num_boxes; polygon->edges = _cairo_malloc_ab (polygon->edges_size, 2*sizeof(cairo_edge_t)); if (unlikely (polygon->edges == XNULL)) return polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); } polygon->extents.p1.x = polygon->extents.p1.y = INT32_MAX; polygon->extents.p2.x = polygon->extents.p2.y = INT32_MIN; polygon->limits = XNULL; polygon->num_limits = 0; for (i = 0; i < num_boxes; i++) { cairo_point_t p1, p2; p1 = boxes[i].p1; p2.x = p1.x; p2.y = boxes[i].p2.y; _cairo_polygon_add_edge (polygon, &p1, &p2, 1); p1 = boxes[i].p2; p2.x = p1.x; p2.y = boxes[i].p1.y; _cairo_polygon_add_edge (polygon, &p1, &p2, 1); } return polygon->status; }
void _cairo_polygon_line_to (cairo_polygon_t *polygon, const cairo_point_t *point) { if (polygon->has_current_point) _cairo_polygon_add_edge (polygon, &polygon->current_point, point); else _cairo_polygon_move_to (polygon, point); }
void _cairo_polygon_close (cairo_polygon_t *polygon) { if (polygon->has_current_point) { _cairo_polygon_add_edge (polygon, &polygon->current_point, &polygon->first_point); polygon->has_current_point = FALSE; } }
cairo_status_t _cairo_polygon_close (cairo_polygon_t *polygon) { cairo_status_t status; if (polygon->has_current_point) { status = _cairo_polygon_line_to (polygon, &polygon->first_point); polygon->has_current_point = FALSE; } if (polygon->has_current_edge) { _cairo_polygon_add_edge (polygon, &polygon->last_point, &polygon->current_point); polygon->has_current_edge = FALSE; } return polygon->status; }
cairo_status_t _cairo_polygon_move_to (cairo_polygon_t *polygon, const cairo_point_t *point) { if (polygon->has_current_edge) { _cairo_polygon_add_edge (polygon, &polygon->last_point, &polygon->current_point); polygon->has_current_edge = FALSE; } if (! polygon->has_current_point) { polygon->first_point = *point; polygon->has_current_point = TRUE; } polygon->current_point = *point; return polygon->status; }
cairo_status_t _cairo_polygon_line_to (cairo_polygon_t *polygon, const cairo_point_t *point) { /* squash collinear edges */ if (polygon->has_current_edge) { if (polygon->current_point.x != point->x || polygon->current_point.y != point->y) { cairo_slope_t this; _cairo_slope_init (&this, &polygon->current_point, point); if (_cairo_slope_equal (&polygon->current_edge, &this)) { polygon->current_point = *point; return CAIRO_STATUS_SUCCESS; } _cairo_polygon_add_edge (polygon, &polygon->last_point, &polygon->current_point); polygon->last_point = polygon->current_point; polygon->current_edge = this; } } else if (polygon->has_current_point) { if (polygon->current_point.x != point->x || polygon->current_point.y != point->y) { polygon->last_point = polygon->current_point; _cairo_slope_init (&polygon->current_edge, &polygon->last_point, point); polygon->has_current_edge = TRUE; } } else { polygon->first_point = *point; polygon->has_current_point = TRUE; } polygon->current_point = *point; return polygon->status; }
cairo_status_t _cairo_polygon_add_contour (cairo_polygon_t *polygon, const cairo_contour_t *contour) { const struct _cairo_contour_chain *chain; const cairo_point_t *prev = XNULL; int i; if (contour->chain.num_points <= 1) return CAIRO_INT_STATUS_SUCCESS; prev = &contour->chain.points[0]; for (chain = &contour->chain; chain; chain = chain->next) { for (i = 0; i < chain->num_points; i++) { _cairo_polygon_add_edge (polygon, prev, &chain->points[i], contour->direction); prev = &chain->points[i]; } } return polygon->status; }