diff --git a/src/libply-splash-core/ply-pixel-buffer.c b/src/libply-splash-core/ply-pixel-buffer.c index 2ecfb256..120a2eb0 100644 --- a/src/libply-splash-core/ply-pixel-buffer.c +++ b/src/libply-splash-core/ply-pixel-buffer.c @@ -613,6 +613,50 @@ ply_pixel_buffer_fill_with_argb32_data_with_clip (ply_pixel_buffer_t *buffer, data, 1.0); } +static void +ply_pixel_buffer_copy_area (ply_pixel_buffer_t *canvas, + ply_pixel_buffer_t *source, + int x, int y, + ply_rectangle_t *cropped_area) +{ + unsigned long row; + + for (row = y; row < y + cropped_area->height; row++) { + memcpy (canvas->bytes + (cropped_area->y + row - y) * canvas->area.width + cropped_area->x, + source->bytes + (row * source->area.width) + x, + cropped_area->width * 4); + } +} + +static void +ply_pixel_buffer_blend_area (ply_pixel_buffer_t *canvas, + ply_pixel_buffer_t *source, + int x, int y, + ply_rectangle_t *cropped_area, + double opacity) +{ + unsigned long row, column; + uint8_t opacity_as_byte = (uint8_t) (opacity * 255.0); + + for (row = y; row < y + cropped_area->height; row++) { + for (column = x; column < x + cropped_area->width; column++) { + uint32_t pixel_value; + + pixel_value = source->bytes[row * source->area.width + column]; + + pixel_value = make_pixel_value_translucent (pixel_value, opacity_as_byte); + + if ((pixel_value >> 24) == 0x00) + continue; + + ply_pixel_buffer_blend_value_at_pixel (canvas, + cropped_area->x + (column - x), + cropped_area->y + (row - y), + pixel_value); + } + } +} + void ply_pixel_buffer_fill_with_buffer_at_opacity_with_clip (ply_pixel_buffer_t *canvas, ply_pixel_buffer_t *source, @@ -621,8 +665,6 @@ ply_pixel_buffer_fill_with_buffer_at_opacity_with_clip (ply_pixel_buffer_t *canv ply_rectangle_t *clip_area, float opacity) { - unsigned long row, column; - uint8_t opacity_as_byte; ply_rectangle_t cropped_area; unsigned long x; unsigned long y; @@ -645,25 +687,12 @@ ply_pixel_buffer_fill_with_buffer_at_opacity_with_clip (ply_pixel_buffer_t *canv x = cropped_area.x - x_offset; y = cropped_area.y - y_offset; - opacity_as_byte = (uint8_t) (opacity * 255.0); - for (row = y; row < y + cropped_area.height; row++) { - for (column = x; column < x + cropped_area.width; column++) { - uint32_t pixel_value; - - pixel_value = source->bytes[row * source->area.width + column]; - - pixel_value = make_pixel_value_translucent (pixel_value, opacity_as_byte); - - if ((pixel_value >> 24) == 0x00) - continue; - - ply_pixel_buffer_blend_value_at_pixel (canvas, - cropped_area.x + (column - x), - cropped_area.y + (row - y), - pixel_value); - } - } + if (opacity == 1.0 && ply_pixel_buffer_is_opaque (source)) + ply_pixel_buffer_copy_area (canvas, source, x, y, &cropped_area); + else + ply_pixel_buffer_blend_area (canvas, source, x, y, &cropped_area, + opacity); ply_region_add_rectangle (canvas->updated_areas, &cropped_area); }