You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
472 lines
15 KiB
472 lines
15 KiB
--- libgxps-0.3.0/libgxps/gxps-brush.c |
|
+++ libgxps-0.3.0/libgxps/gxps-brush.c |
|
@@ -965,7 +965,7 @@ brush_end_element (GMarkupParseContext |
|
g_markup_parse_context_pop (context); |
|
} else if (strcmp (element_name, "ImageBrush") == 0) { |
|
GXPSBrushImage *brush_image; |
|
- GXPSImage *image; |
|
+ cairo_surface_t *image; |
|
GError *err = NULL; |
|
|
|
brush_image = g_markup_parse_context_pop (context); |
|
@@ -976,14 +976,20 @@ brush_end_element (GMarkupParseContext |
|
cairo_matrix_t matrix; |
|
gdouble x_scale, y_scale; |
|
cairo_surface_t *clip_surface; |
|
+ double *res_x, *res_y; |
|
|
|
- /* viewbox units is 1/96 inch, convert to pixels */ |
|
- brush_image->viewbox.x *= image->res_x / 96; |
|
- brush_image->viewbox.y *= image->res_y / 96; |
|
- brush_image->viewbox.width *= image->res_x / 96; |
|
- brush_image->viewbox.height *= image->res_y / 96; |
|
+ res_x = cairo_surface_get_user_data (image, (const cairo_user_data_key_t *) 0x1); |
|
+ res_y = cairo_surface_get_user_data (image, (const cairo_user_data_key_t *) 0x2); |
|
|
|
- clip_surface = cairo_surface_create_for_rectangle (image->surface, |
|
+ if (res_x != NULL && res_y != NULL) { |
|
+ /* viewbox units is 1/96 inch, convert to pixels */ |
|
+ brush_image->viewbox.x *= *res_x / 96; |
|
+ brush_image->viewbox.y *= *res_y / 96; |
|
+ brush_image->viewbox.width *= *res_x / 96; |
|
+ brush_image->viewbox.height *= *res_y / 96; |
|
+ } |
|
+ |
|
+ clip_surface = cairo_surface_create_for_rectangle (image, |
|
brush_image->viewbox.x, |
|
brush_image->viewbox.y, |
|
brush_image->viewbox.width, |
|
--- libgxps-0.3.0/libgxps/gxps-images.c |
|
+++ libgxps-0.3.0/libgxps/gxps-images.c |
|
@@ -88,6 +88,45 @@ multiply_alpha (int alpha, int color) |
|
return ((temp + (temp >> 8)) >> 8); |
|
} |
|
|
|
+static void |
|
+image_set_res_x (cairo_surface_t *image, |
|
+ double res_x) |
|
+{ |
|
+ double *x; |
|
+ |
|
+ x = g_new (double, 1); |
|
+ *x = res_x; |
|
+ |
|
+ cairo_surface_set_user_data (image, |
|
+ (const cairo_user_data_key_t *) 0x1, |
|
+ x, |
|
+ (cairo_destroy_func_t) g_free); |
|
+} |
|
+ |
|
+static void |
|
+image_set_res_y (cairo_surface_t *image, |
|
+ double res_y) |
|
+{ |
|
+ double *y; |
|
+ |
|
+ y = g_new (double, 1); |
|
+ *y = res_y; |
|
+ |
|
+ cairo_surface_set_user_data (image, |
|
+ (const cairo_user_data_key_t *) 0x2, |
|
+ y, |
|
+ (cairo_destroy_func_t) g_free); |
|
+} |
|
+ |
|
+static void |
|
+image_set_res (cairo_surface_t *image, |
|
+ double res_x, |
|
+ double res_y) |
|
+{ |
|
+ image_set_res_x (image, res_x); |
|
+ image_set_res_y (image, res_y); |
|
+} |
|
+ |
|
/* Premultiplies data and converts RGBA bytes => native endian |
|
* From cairo's cairo-png.c <http://cairographics.org> */ |
|
static void |
|
@@ -163,14 +202,14 @@ fill_png_error (GError **error, |
|
|
|
/* Adapted from cairo's read_png in cairo-png.c |
|
* http://cairographics.org/ */ |
|
-static GXPSImage * |
|
+static cairo_surface_t * |
|
gxps_images_create_from_png (GXPSArchive *zip, |
|
const gchar *image_uri, |
|
GError **error) |
|
{ |
|
#ifdef HAVE_LIBPNG |
|
GInputStream *stream; |
|
- GXPSImage *image = NULL; |
|
+ cairo_surface_t *image = NULL; |
|
char *png_err_msg = NULL; |
|
png_struct *png; |
|
png_info *info; |
|
@@ -181,6 +220,7 @@ gxps_images_create_from_png (GXPSArchive |
|
unsigned int i; |
|
cairo_format_t format; |
|
cairo_status_t status; |
|
+ double res_x, res_y; |
|
|
|
stream = gxps_archive_open (zip, image_uri); |
|
if (!stream) { |
|
@@ -217,7 +257,7 @@ gxps_images_create_from_png (GXPSArchive |
|
g_free (png_err_msg); |
|
g_object_unref (stream); |
|
png_destroy_read_struct (&png, &info, NULL); |
|
- gxps_image_free (image); |
|
+ cairo_surface_destroy (image); |
|
g_free (row_pointers); |
|
g_free (data); |
|
return NULL; |
|
@@ -295,13 +335,12 @@ gxps_images_create_from_png (GXPSArchive |
|
return NULL; |
|
} |
|
|
|
- image = g_slice_new0 (GXPSImage); |
|
- image->res_x = png_get_x_pixels_per_meter (png, info) * METERS_PER_INCH; |
|
- if (image->res_x == 0) |
|
- image->res_x = 96; |
|
- image->res_y = png_get_y_pixels_per_meter (png, info) * METERS_PER_INCH; |
|
- if (image->res_y == 0) |
|
- image->res_y = 96; |
|
+ res_x = png_get_x_pixels_per_meter (png, info) * METERS_PER_INCH; |
|
+ if (res_x == 0) |
|
+ res_x = 96; |
|
+ res_y = png_get_y_pixels_per_meter (png, info) * METERS_PER_INCH; |
|
+ if (res_y == 0) |
|
+ res_y = 96; |
|
|
|
data = g_malloc (png_height * stride); |
|
row_pointers = g_new (png_byte *, png_height); |
|
@@ -315,23 +354,25 @@ gxps_images_create_from_png (GXPSArchive |
|
g_object_unref (stream); |
|
g_free (row_pointers); |
|
|
|
- image->surface = cairo_image_surface_create_for_data (data, format, |
|
- png_width, png_height, |
|
- stride); |
|
- if (cairo_surface_status (image->surface)) { |
|
+ image = cairo_image_surface_create_for_data (data, format, |
|
+ png_width, png_height, |
|
+ stride); |
|
+ if (cairo_surface_status (image)) { |
|
fill_png_error (error, image_uri, NULL); |
|
- gxps_image_free (image); |
|
+ cairo_surface_destroy (image); |
|
g_free (data); |
|
return NULL; |
|
} |
|
|
|
- status = cairo_surface_set_user_data (image->surface, |
|
+ image_set_res (image, res_x, res_y); |
|
+ |
|
+ status = cairo_surface_set_user_data (image, |
|
&image_data_cairo_key, |
|
data, |
|
(cairo_destroy_func_t) g_free); |
|
if (status) { |
|
fill_png_error (error, image_uri, NULL); |
|
- gxps_image_free (image); |
|
+ cairo_surface_destroy (image); |
|
g_free (data); |
|
return NULL; |
|
} |
|
@@ -423,7 +463,7 @@ _jpeg_error_exit (j_common_ptr error) |
|
} |
|
#endif /* HAVE_LIBJPEG */ |
|
|
|
-static GXPSImage * |
|
+static cairo_surface_t * |
|
gxps_images_create_from_jpeg (GXPSArchive *zip, |
|
const gchar *image_uri, |
|
GError **error) |
|
@@ -433,7 +473,7 @@ gxps_images_create_from_jpeg (GXPSArchiv |
|
struct jpeg_error_mgr error_mgr; |
|
struct jpeg_decompress_struct cinfo; |
|
struct _jpeg_src_mgr src; |
|
- GXPSImage *image; |
|
+ cairo_surface_t *image; |
|
guchar *data; |
|
gint stride; |
|
JSAMPARRAY lines; |
|
@@ -484,28 +524,26 @@ gxps_images_create_from_jpeg (GXPSArchiv |
|
cinfo.do_fancy_upsampling = FALSE; |
|
jpeg_start_decompress (&cinfo); |
|
|
|
- image = g_slice_new (GXPSImage); |
|
- image->surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, |
|
- cinfo.output_width, |
|
- cinfo.output_height); |
|
- image->res_x = 96; |
|
- image->res_y = 96; |
|
- if (cairo_surface_status (image->surface)) { |
|
+ image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, |
|
+ cinfo.output_width, |
|
+ cinfo.output_height); |
|
+ image_set_res (image, 96, 96); |
|
+ if (cairo_surface_status (image)) { |
|
g_set_error (error, |
|
GXPS_ERROR, |
|
GXPS_ERROR_IMAGE, |
|
"Error loading JPEG image %s: %s", |
|
image_uri, |
|
- cairo_status_to_string (cairo_surface_status (image->surface))); |
|
+ cairo_status_to_string (cairo_surface_status (image))); |
|
jpeg_destroy_decompress (&cinfo); |
|
- gxps_image_free (image); |
|
+ cairo_surface_destroy (image); |
|
g_object_unref (stream); |
|
|
|
return NULL; |
|
} |
|
|
|
- data = cairo_image_surface_get_data (image->surface); |
|
- stride = cairo_image_surface_get_stride (image->surface); |
|
+ data = cairo_image_surface_get_data (image); |
|
+ stride = cairo_image_surface_get_stride (image); |
|
jpeg_stride = cinfo.output_width * cinfo.out_color_components; |
|
lines = cinfo.mem->alloc_sarray((j_common_ptr) &cinfo, JPOOL_IMAGE, jpeg_stride, 4); |
|
|
|
@@ -535,7 +573,7 @@ gxps_images_create_from_jpeg (GXPSArchiv |
|
GXPS_DEBUG (g_message ("Unsupported jpeg color space %s", |
|
_jpeg_color_space_name (cinfo.out_color_space))); |
|
|
|
- gxps_image_free (image); |
|
+ cairo_surface_destroy (image); |
|
jpeg_destroy_decompress (&cinfo); |
|
g_object_unref (stream); |
|
return NULL; |
|
@@ -549,27 +587,25 @@ gxps_images_create_from_jpeg (GXPSArchiv |
|
} |
|
|
|
if (cinfo.density_unit == 1) { /* dots/inch */ |
|
- image->res_x = cinfo.X_density; |
|
- image->res_y = cinfo.Y_density; |
|
+ image_set_res (image, cinfo.X_density, cinfo.Y_density); |
|
} else if (cinfo.density_unit == 2) { /* dots/cm */ |
|
- image->res_x = cinfo.X_density * CENTIMETERS_PER_INCH; |
|
- image->res_y = cinfo.Y_density * CENTIMETERS_PER_INCH; |
|
+ image_set_res (image, cinfo.X_density * CENTIMETERS_PER_INCH, cinfo.Y_density * CENTIMETERS_PER_INCH); |
|
} |
|
|
|
jpeg_finish_decompress (&cinfo); |
|
jpeg_destroy_decompress (&cinfo); |
|
g_object_unref (stream); |
|
|
|
- cairo_surface_mark_dirty (image->surface); |
|
+ cairo_surface_mark_dirty (image); |
|
|
|
- if (cairo_surface_status (image->surface)) { |
|
+ if (cairo_surface_status (image)) { |
|
g_set_error (error, |
|
GXPS_ERROR, |
|
GXPS_ERROR_IMAGE, |
|
"Error loading JPEG image %s: %s", |
|
image_uri, |
|
- cairo_status_to_string (cairo_surface_status (image->surface))); |
|
- gxps_image_free (image); |
|
+ cairo_status_to_string (cairo_surface_status (image))); |
|
+ cairo_surface_destroy (image); |
|
|
|
return NULL; |
|
} |
|
@@ -728,7 +764,7 @@ _tiff_unmap_file (thandle_t handle, |
|
} |
|
#endif /* #ifdef HAVE_LIBTIFF */ |
|
|
|
-static GXPSImage * |
|
+static cairo_surface_t * |
|
gxps_images_create_from_tiff (GXPSArchive *zip, |
|
const gchar *image_uri, |
|
GError **error) |
|
@@ -736,7 +772,7 @@ gxps_images_create_from_tiff (GXPSArchiv |
|
#ifdef HAVE_LIBTIFF |
|
TIFF *tiff; |
|
TiffBuffer buffer; |
|
- GXPSImage *image; |
|
+ cairo_surface_t *image; |
|
gint width, height; |
|
guint16 res_unit; |
|
float res_x, res_y; |
|
@@ -802,49 +838,47 @@ gxps_images_create_from_tiff (GXPSArchiv |
|
return NULL; |
|
} |
|
|
|
- image = g_slice_new (GXPSImage); |
|
- image->surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, |
|
- width, height); |
|
- image->res_x = 96; |
|
- image->res_y = 96; |
|
+ image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, |
|
+ width, height); |
|
+ image_set_res (image, 96, 96); |
|
|
|
if (!TIFFGetField (tiff, TIFFTAG_RESOLUTIONUNIT, &res_unit)) |
|
res_unit = 0; |
|
if (TIFFGetField (tiff, TIFFTAG_XRESOLUTION, &res_x)) { |
|
if (res_unit == 2) { /* inches */ |
|
- image->res_x = res_x; |
|
+ image_set_res_x (image, res_x); |
|
} else if (res_unit == 3) { /* centimeters */ |
|
- image->res_x = res_x * CENTIMETERS_PER_INCH; |
|
+ image_set_res_x (image, res_x * CENTIMETERS_PER_INCH); |
|
} |
|
} |
|
if (TIFFGetField (tiff, TIFFTAG_YRESOLUTION, &res_y)) { |
|
if (res_unit == 2) { /* inches */ |
|
- image->res_y = res_y; |
|
+ image_set_res_y (image, res_y); |
|
} else if (res_unit == 3) { /* centimeters */ |
|
- image->res_y = res_y * CENTIMETERS_PER_INCH; |
|
+ image_set_res_y (image, res_y * CENTIMETERS_PER_INCH); |
|
} |
|
} |
|
|
|
- if (cairo_surface_status (image->surface)) { |
|
+ if (cairo_surface_status (image)) { |
|
g_set_error (error, |
|
GXPS_ERROR, |
|
GXPS_ERROR_IMAGE, |
|
"Error loading TIFF image %s: %s", |
|
image_uri, |
|
- cairo_status_to_string (cairo_surface_status (image->surface))); |
|
- gxps_image_free (image); |
|
+ cairo_status_to_string (cairo_surface_status (image))); |
|
+ cairo_surface_destroy (image); |
|
TIFFClose (tiff); |
|
_tiff_pop_handlers (); |
|
g_free (buffer.buffer); |
|
return NULL; |
|
} |
|
|
|
- data = cairo_image_surface_get_data (image->surface); |
|
+ data = cairo_image_surface_get_data (image); |
|
if (!TIFFReadRGBAImageOriented (tiff, width, height, |
|
(uint32 *)data, |
|
ORIENTATION_TOPLEFT, 1) || _tiff_error) { |
|
fill_tiff_error (error, image_uri); |
|
- gxps_image_free (image); |
|
+ cairo_surface_destroy (image); |
|
TIFFClose (tiff); |
|
_tiff_pop_handlers (); |
|
g_free (buffer.buffer); |
|
@@ -855,7 +889,7 @@ gxps_images_create_from_tiff (GXPSArchiv |
|
_tiff_pop_handlers (); |
|
g_free (buffer.buffer); |
|
|
|
- stride = cairo_image_surface_get_stride (image->surface); |
|
+ stride = cairo_image_surface_get_stride (image); |
|
p = data; |
|
while (p < data + (height * stride)) { |
|
guint32 *pixel = (guint32 *)p; |
|
@@ -869,7 +903,7 @@ gxps_images_create_from_tiff (GXPSArchiv |
|
p += 4; |
|
} |
|
|
|
- cairo_surface_mark_dirty (image->surface); |
|
+ cairo_surface_mark_dirty (image); |
|
|
|
return image; |
|
#else |
|
@@ -897,12 +931,12 @@ gxps_images_guess_content_type (GXPSArch |
|
return mime_type; |
|
} |
|
|
|
-GXPSImage * |
|
+cairo_surface_t * |
|
gxps_images_get_image (GXPSArchive *zip, |
|
const gchar *image_uri, |
|
GError **error) |
|
{ |
|
- GXPSImage *image = NULL; |
|
+ cairo_surface_t *image = NULL; |
|
gchar *image_uri_lower; |
|
|
|
/* First try with extensions, |
|
@@ -942,15 +976,3 @@ gxps_images_get_image (GXPSArchive *zip, |
|
|
|
return image; |
|
} |
|
- |
|
-void |
|
-gxps_image_free (GXPSImage *image) |
|
-{ |
|
- if (G_UNLIKELY (!image)) |
|
- return; |
|
- |
|
- if (G_LIKELY (image->surface)) |
|
- cairo_surface_destroy (image->surface); |
|
- |
|
- g_slice_free (GXPSImage, image); |
|
-} |
|
--- libgxps-0.3.0/libgxps/gxps-images.h |
|
+++ libgxps-0.3.0/libgxps/gxps-images.h |
|
@@ -25,18 +25,9 @@ |
|
|
|
G_BEGIN_DECLS |
|
|
|
-typedef struct _GXPSImage GXPSImage; |
|
- |
|
-struct _GXPSImage { |
|
- cairo_surface_t *surface; |
|
- double res_x; |
|
- double res_y; |
|
-}; |
|
- |
|
-GXPSImage *gxps_images_get_image (GXPSArchive *zip, |
|
- const gchar *image_uri, |
|
- GError **error); |
|
-void gxps_image_free (GXPSImage *image); |
|
+cairo_surface_t *gxps_images_get_image (GXPSArchive *zip, |
|
+ const gchar *image_uri, |
|
+ GError **error); |
|
|
|
G_END_DECLS |
|
|
|
--- libgxps-0.3.0/libgxps/gxps-page.c |
|
+++ libgxps-0.3.0/libgxps/gxps-page.c |
|
@@ -77,12 +77,12 @@ gxps_page_error_quark (void) |
|
} |
|
|
|
/* Images */ |
|
-GXPSImage * |
|
+cairo_surface_t * |
|
gxps_page_get_image (GXPSPage *page, |
|
const gchar *image_uri, |
|
GError **error) |
|
{ |
|
- GXPSImage *image; |
|
+ cairo_surface_t *image; |
|
|
|
if (page->priv->image_cache) { |
|
image = g_hash_table_lookup (page->priv->image_cache, |
|
@@ -99,12 +99,12 @@ gxps_page_get_image (GXPSPage *page, |
|
page->priv->image_cache = g_hash_table_new_full (g_str_hash, |
|
g_str_equal, |
|
(GDestroyNotify)g_free, |
|
- (GDestroyNotify)gxps_image_free); |
|
+ (GDestroyNotify)cairo_surface_destroy); |
|
} |
|
|
|
g_hash_table_insert (page->priv->image_cache, |
|
g_strdup (image_uri), |
|
- image); |
|
+ cairo_surface_reference (image)); |
|
return image; |
|
} |
|
|
|
--- libgxps-0.3.0/libgxps/gxps-page-private.h |
|
+++ libgxps-0.3.0/libgxps/gxps-page-private.h |
|
@@ -58,9 +58,9 @@ struct _GXPSRenderContext { |
|
GXPSBrushVisual *visual; |
|
}; |
|
|
|
-GXPSImage *gxps_page_get_image (GXPSPage *page, |
|
- const gchar *image_uri, |
|
- GError **error); |
|
+cairo_surface_t *gxps_page_get_image (GXPSPage *page, |
|
+ const gchar *image_uri, |
|
+ GError **error); |
|
void gxps_page_render_parser_push (GMarkupParseContext *context, |
|
GXPSRenderContext *ctx); |
|
|
|
|