summaryrefslogtreecommitdiff
path: root/src/cairo-rectangular-scan-converter.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-07-30 18:46:50 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-07-31 08:12:54 +0100
commit1c3b0ebb32eb35d07a7d8b9a4c6849edfc88e3f7 (patch)
tree14308d227394ec405eca3d01eada368efed4e1f1 /src/cairo-rectangular-scan-converter.c
parentb231bb0a0b971a9b424292be065229ffe234352e (diff)
downloadcairo-1c3b0ebb32eb35d07a7d8b9a4c6849edfc88e3f7.tar.gz
spans: fast-path common case of a single box.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/cairo-rectangular-scan-converter.c')
-rw-r--r--src/cairo-rectangular-scan-converter.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/cairo-rectangular-scan-converter.c b/src/cairo-rectangular-scan-converter.c
index dab2c151f..56e552b7a 100644
--- a/src/cairo-rectangular-scan-converter.c
+++ b/src/cairo-rectangular-scan-converter.c
@@ -586,6 +586,74 @@ generate (cairo_rectangular_scan_converter_t *self,
return status;
}
+static void generate_row(cairo_span_renderer_t *renderer,
+ const rectangle_t *r,
+ int y, int h,
+ uint16_t coverage)
+{
+ cairo_half_open_span_t spans[4];
+ unsigned int num_spans = 0;
+ int x1 = _cairo_fixed_integer_part (r->left);
+ int x2 = _cairo_fixed_integer_part (r->right);
+ if (x2 > x1) {
+ if (! _cairo_fixed_is_integer (r->left)) {
+ spans[num_spans].x = x1;
+ spans[num_spans].coverage =
+ coverage * (256 - _cairo_fixed_fractional_part (r->left)) >> 8;
+ num_spans++;
+ x1++;
+ }
+
+ if (x2 > x1) {
+ spans[num_spans].x = x1;
+ spans[num_spans].coverage = coverage - (coverage >> 8);
+ num_spans++;
+ }
+
+ if (! _cairo_fixed_is_integer (r->right)) {
+ spans[num_spans].x = x2;
+ spans[num_spans].coverage =
+ coverage * _cairo_fixed_fractional_part (r->right) >> 8;
+ num_spans++;
+ }
+ } else {
+ spans[num_spans].x = x1;
+ spans[num_spans].coverage = coverage * (r->right - r->left) >> 8;
+ num_spans++;
+ }
+
+ spans[num_spans].x = x2 + 1;
+ spans[num_spans].coverage = 0;
+ num_spans++;
+
+ renderer->render_rows (renderer, y, h, spans, num_spans);
+}
+
+static cairo_status_t
+generate_box (cairo_rectangular_scan_converter_t *self,
+ cairo_span_renderer_t *renderer)
+{
+ const rectangle_t *r = self->chunks.base;
+ int y1 = _cairo_fixed_integer_part (r->top);
+ int y2 = _cairo_fixed_integer_part (r->bottom);
+ if (y2 > y1) {
+ if (! _cairo_fixed_is_integer (r->top)) {
+ generate_row(renderer, r, y1, 1,
+ 256 - _cairo_fixed_fractional_part (r->top));
+ y1++;
+ }
+
+ if (y2 > y1)
+ generate_row(renderer, r, y1, y2-y1, 256);
+
+ if (! _cairo_fixed_is_integer (r->bottom))
+ generate_row(renderer, r, y2, 1,
+ _cairo_fixed_fractional_part (r->bottom));
+ } else
+ generate_row(renderer, r, y1, 1, r->bottom - r->top);
+
+ return CAIRO_STATUS_SUCCESS;
+}
static cairo_status_t
_cairo_rectangular_scan_converter_generate (void *converter,
@@ -604,6 +672,9 @@ _cairo_rectangular_scan_converter_generate (void *converter,
NULL, 0);
}
+ if (self->num_rectangles == 1)
+ return generate_box (self, renderer);
+
rectangles = rectangles_stack;
if (unlikely (self->num_rectangles >= ARRAY_LENGTH (rectangles_stack))) {
rectangles = _cairo_malloc_ab (self->num_rectangles + 1,