Commit fded97c8 authored by Paolo Bacchilega's avatar Paolo Bacchilega
Browse files

added the _cairo_image_surface_transform_get_steps() function

simplified _cairo_image_surface_transform using _cairo_image_surface_transform_get_steps 
parent 6f880263
......@@ -306,159 +306,165 @@ _cairo_image_surface_scale_to (cairo_surface_t *surface,
}
cairo_surface_t *
_cairo_image_surface_transform (cairo_surface_t *source,
GthTransform transform)
void
_cairo_image_surface_transform_get_steps (cairo_format_t format,
int width,
int height,
GthTransform transform,
int *destination_width_p,
int *destination_height_p,
int *line_start_p,
int *line_step_p,
int *pixel_step_p)
{
cairo_surface_t *destination = NULL;
cairo_format_t format;
int width;
int height;
int source_stride;
int destination_stride;
unsigned char *p_source_line;
unsigned char *p_destination_line;
unsigned char *p_source;
unsigned char *p_destination;
int x;
if (source == NULL)
return NULL;
format = cairo_image_surface_get_format (source);
width = cairo_image_surface_get_width (source);
height = cairo_image_surface_get_height (source);
source_stride = cairo_image_surface_get_stride (source);
int destination_stride;
int destination_width = 0;
int destination_height = 0;
int line_start = 0;
int line_step = 0;
int pixel_step = 0;
switch (transform) {
case GTH_TRANSFORM_NONE:
destination = _cairo_image_surface_copy (source);
default:
destination_width = width;
destination_height = height;
destination_stride = cairo_format_stride_for_width (format, destination_width);
line_start = 0;
line_step = destination_stride;
pixel_step = 4;
break;
case GTH_TRANSFORM_FLIP_H:
destination = cairo_image_surface_create (format, width, height);
destination_stride = cairo_image_surface_get_stride (destination);
p_source_line = cairo_image_surface_get_data (source);
p_destination_line = cairo_image_surface_get_data (destination) + ((width - 1) * 4);
while (height-- > 0) {
p_source = p_source_line;
p_destination = p_destination_line;
for (x = 0; x < width; x++) {
memcpy (p_destination, p_source, 4);
p_source += 4;
p_destination -= 4;
}
p_source_line += source_stride;
p_destination_line += destination_stride;
}
destination_width = width;
destination_height = height;
destination_stride = cairo_format_stride_for_width (format, destination_width);
line_start = (destination_width - 1) * 4;
line_step = destination_stride;
pixel_step = -4;
break;
case GTH_TRANSFORM_ROTATE_180:
destination = cairo_image_surface_create (format, width, height);
destination_stride = cairo_image_surface_get_stride (destination);
p_source_line = cairo_image_surface_get_data (source);
p_destination_line = cairo_image_surface_get_data (destination) + ((height - 1) * destination_stride) + ((width - 1) * 4);
while (height-- > 0) {
p_source = p_source_line;
p_destination = p_destination_line;
for (x = 0; x < width; x++) {
memcpy (p_destination, p_source, 4);
p_source += 4;
p_destination -= 4;
}
p_source_line += source_stride;
p_destination_line -= destination_stride;
}
destination_width = width;
destination_height = height;
destination_stride = cairo_format_stride_for_width (format, destination_width);
line_start = ((destination_height - 1) * destination_stride) + ((destination_width - 1) * 4);
line_step = -destination_stride;
pixel_step = -4;
break;
case GTH_TRANSFORM_FLIP_V:
destination = cairo_image_surface_create (format, width, height);
destination_stride = cairo_image_surface_get_stride (destination);
g_return_val_if_fail (source_stride == destination_stride, NULL);
p_source_line = cairo_image_surface_get_data (source);
p_destination_line = cairo_image_surface_get_data (destination) + ((height - 1) * destination_stride);
while (height-- > 0) {
memcpy (p_destination_line, p_source_line, source_stride);
p_source_line += source_stride;
p_destination_line -= destination_stride;
}
destination_width = width;
destination_height = height;
destination_stride = cairo_format_stride_for_width (format, destination_width);
line_start = (destination_height - 1) * destination_stride;
line_step = -destination_stride;
pixel_step = 4;
break;
case GTH_TRANSFORM_TRANSPOSE:
destination = cairo_image_surface_create (format, height, width);
destination_stride = cairo_image_surface_get_stride (destination);
p_source_line = cairo_image_surface_get_data (source);
p_destination_line = cairo_image_surface_get_data (destination);
while (height-- > 0) {
p_source = p_source_line;
p_destination = p_destination_line;
for (x = 0; x < width; x++) {
memcpy (p_destination, p_source, 4);
p_source += 4;
p_destination += destination_stride;
}
p_source_line += source_stride;
p_destination_line += 4;
}
destination_width = height;
destination_height = width;
destination_stride = cairo_format_stride_for_width (format, destination_width);
line_start = 0;
line_step = 4;
pixel_step = destination_stride;
break;
case GTH_TRANSFORM_ROTATE_90:
destination = cairo_image_surface_create (format, height, width);
destination_stride = cairo_image_surface_get_stride (destination);
p_source_line = cairo_image_surface_get_data (source);
p_destination_line = cairo_image_surface_get_data (destination) + ((height - 1) * 4);
while (height-- > 0) {
p_source = p_source_line;
p_destination = p_destination_line;
for (x = 0; x < width; x++) {
memcpy (p_destination, p_source, 4);
p_source += 4;
p_destination += destination_stride;
}
p_source_line += source_stride;
p_destination_line -= 4;
}
destination_width = height;
destination_height = width;
destination_stride = cairo_format_stride_for_width (format, destination_width);
line_start = (destination_width - 1) * 4;
line_step = -4;
pixel_step = destination_stride;
break;
case GTH_TRANSFORM_TRANSVERSE:
destination = cairo_image_surface_create (format, height, width);
destination_stride = cairo_image_surface_get_stride (destination);
p_source_line = cairo_image_surface_get_data (source);
p_destination_line = cairo_image_surface_get_data (destination) + ((width - 1) * destination_stride) + ((height - 1) * 4);
while (height-- > 0) {
p_source = p_source_line;
p_destination = p_destination_line;
for (x = 0; x < width; x++) {
memcpy (p_destination, p_source, 4);
p_source += 4;
p_destination -= destination_stride;
}
p_source_line += source_stride;
p_destination_line -= 4;
}
destination_width = height;
destination_height = width;
destination_stride = cairo_format_stride_for_width (format, destination_width);
line_start = ((destination_height - 1) * destination_stride) + ((destination_width - 1) * 4);
line_step = -4;
pixel_step = -destination_stride;
break;
case GTH_TRANSFORM_ROTATE_270:
destination = cairo_image_surface_create (format, height, width);
destination_stride = cairo_image_surface_get_stride (destination);
p_source_line = cairo_image_surface_get_data (source);
p_destination_line = cairo_image_surface_get_data (destination) + ((width - 1) * destination_stride);
while (height-- > 0) {
p_source = p_source_line;
p_destination = p_destination_line;
for (x = 0; x < width; x++) {
memcpy (p_destination, p_source, 4);
p_source += 4;
p_destination -= destination_stride;
}
p_source_line += source_stride;
p_destination_line += 4;
}
destination_width = height;
destination_height = width;
destination_stride = cairo_format_stride_for_width (format, destination_width);
line_start = (destination_height - 1) * destination_stride;
line_step = 4;
pixel_step = -destination_stride;
break;
}
default:
g_warning ("_cairo_image_surface_transform: unknown transformation value %d", transform);
break;
if (destination_width_p != NULL)
*destination_width_p = destination_width;
if (destination_height_p != NULL)
*destination_height_p = destination_height;
if (line_start_p != NULL)
*line_start_p = line_start;
if (line_step_p != NULL)
*line_step_p = line_step;
if (pixel_step_p != NULL)
*pixel_step_p = pixel_step;
}
cairo_surface_t *
_cairo_image_surface_transform (cairo_surface_t *source,
GthTransform transform)
{
cairo_surface_t *destination = NULL;
cairo_format_t format;
int width;
int height;
int source_stride;
int destination_width;
int destination_height;
int line_start;
int line_step;
int pixel_step;
int destination_stride;
unsigned char *p_source_line;
unsigned char *p_destination_line;
unsigned char *p_source;
unsigned char *p_destination;
int x;
if (source == NULL)
return NULL;
format = cairo_image_surface_get_format (source);
width = cairo_image_surface_get_width (source);
height = cairo_image_surface_get_height (source);
source_stride = cairo_image_surface_get_stride (source);
_cairo_image_surface_transform_get_steps (format,
width,
height,
transform,
&destination_width,
&destination_height,
&line_start,
&line_step,
&pixel_step);
destination = cairo_image_surface_create (format, destination_width, destination_height);
destination_stride = cairo_image_surface_get_stride (destination);
p_source_line = cairo_image_surface_get_data (source);
p_destination_line = cairo_image_surface_get_data (destination) + line_start;
while (height-- > 0) {
p_source = p_source_line;
p_destination = p_destination_line;
for (x = 0; x < width; x++) {
memcpy (p_destination, p_source, 4);
p_source += 4;
p_destination += pixel_step;
}
p_source_line += source_stride;
p_destination_line += line_step;
}
return destination;
......
......@@ -147,6 +147,15 @@ cairo_surface_t * _cairo_image_surface_scale_to (cairo_surface_t *
int width,
int height,
cairo_filter_t filter);
void _cairo_image_surface_transform_get_steps (cairo_format_t format,
int width,
int height,
GthTransform transform,
int *destination_width_p,
int *destination_height_p,
int *line_start_p,
int *line_step_p,
int *pixel_step_p);
cairo_surface_t * _cairo_image_surface_transform (cairo_surface_t *surface,
GthTransform transform);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment