diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2011-07-13 21:43:55 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2011-07-13 21:43:55 +0000 |
| commit | 6973283a77d7becd6a5a1bd7396206c6840ca785 (patch) | |
| tree | 548ecd769aee550eb36b1ccfce7bcc95651ccdd9 /src | |
| parent | UI fixes for gcodetools extension (diff) | |
| download | inkscape-6973283a77d7becd6a5a1bd7396206c6840ca785.tar.gz inkscape-6973283a77d7becd6a5a1bd7396206c6840ca785.zip | |
Fix crashes in print preview
Fixed bugs:
- https://launchpad.net/bugs/806105
(bzr r10450)
Diffstat (limited to 'src')
| -rw-r--r-- | src/display/cairo-utils.cpp | 12 | ||||
| -rw-r--r-- | src/display/cairo-utils.h | 1 | ||||
| -rw-r--r-- | src/extension/internal/cairo-renderer.cpp | 8 | ||||
| -rw-r--r-- | src/helper/pixbuf-ops.cpp | 5 | ||||
| -rw-r--r-- | src/ui/cache/svg_preview_cache.cpp | 3 | ||||
| -rw-r--r-- | src/ui/dialog/color-item.cpp | 4 |
6 files changed, 24 insertions, 9 deletions
diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index 90f65c33e..8b75f09a6 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -345,6 +345,18 @@ ink_cairo_surface_create_for_argb32_pixbuf(GdkPixbuf *pb) return pbs; } +/** @brief Cleanup function for GdkPixbuf. + * This function should be passed as the GdkPixbufDestroyNotify parameter + * to gdk_pixbuf_new_from_data when creating a GdkPixbuf backed by + * a Cairo surface. + */ +void +ink_cairo_pixbuf_cleanup(guchar *pixels, void *data) +{ + cairo_surface_t *surface = reinterpret_cast<cairo_surface_t*>(data); + cairo_surface_destroy(surface); +} + /** @brief Create an exact copy of a surface. * Creates a surface that has the same type, content type, dimensions and contents * as the specified surface. */ diff --git a/src/display/cairo-utils.h b/src/display/cairo-utils.h index 0c2ac2dd6..1de88785d 100644 --- a/src/display/cairo-utils.h +++ b/src/display/cairo-utils.h @@ -106,6 +106,7 @@ void convert_pixels_argb32_to_pixbuf(guchar *data, int w, int h, int rs); void convert_pixbuf_normal_to_argb32(GdkPixbuf *); void convert_pixbuf_argb32_to_normal(GdkPixbuf *); cairo_surface_t *ink_cairo_surface_create_for_argb32_pixbuf(GdkPixbuf *pb); +void ink_cairo_pixbuf_cleanup(guchar *pixels, void *surface); G_GNUC_CONST guint32 argb32_from_pixbuf(guint32 in); G_GNUC_CONST guint32 pixbuf_from_argb32(guint32 in); diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index 6118a7ae9..1e550f7d1 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -475,9 +475,11 @@ static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx) } // The width and height of the bitmap in pixels - unsigned width = (unsigned) floor ((bbox->max()[Geom::X] - bbox->min()[Geom::X]) * (res / PX_PER_IN)); - unsigned height =(unsigned) floor ((bbox->max()[Geom::Y] - bbox->min()[Geom::Y]) * (res / PX_PER_IN)); - + unsigned width = ceil((bbox->max()[Geom::X] - bbox->min()[Geom::X]) * (res / PX_PER_IN)); + unsigned height = ceil((bbox->max()[Geom::Y] - bbox->min()[Geom::Y]) * (res / PX_PER_IN)); + + if (width == 0 || height == 0) return; + // Scale to exactly fit integer bitmap inside bounding box double scale_x = (bbox->max()[Geom::X] - bbox->min()[Geom::X]) / width; double scale_y = (bbox->max()[Geom::Y] - bbox->min()[Geom::Y]) / height; diff --git a/src/helper/pixbuf-ops.cpp b/src/helper/pixbuf-ops.cpp index f6796f2ad..9ebbe13c7 100644 --- a/src/helper/pixbuf-ops.cpp +++ b/src/helper/pixbuf-ops.cpp @@ -107,6 +107,7 @@ sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/, GSList *items_only) { + if (width == 0 || height == 0) return NULL; GdkPixbuf* pixbuf = NULL; /* Create new arena for offscreen rendering*/ @@ -167,8 +168,8 @@ sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/, pixbuf = gdk_pixbuf_new_from_data(cairo_image_surface_get_data(surface), GDK_COLORSPACE_RGB, TRUE, 8, width, height, cairo_image_surface_get_stride(surface), - (GdkPixbufDestroyNotify) cairo_surface_destroy, - NULL); + ink_cairo_pixbuf_cleanup, + surface); convert_pixbuf_argb32_to_normal(pixbuf); } else diff --git a/src/ui/cache/svg_preview_cache.cpp b/src/ui/cache/svg_preview_cache.cpp index fd7070bab..edd7c9431 100644 --- a/src/ui/cache/svg_preview_cache.cpp +++ b/src/ui/cache/svg_preview_cache.cpp @@ -79,8 +79,7 @@ GdkPixbuf* render_pixbuf(NRArenaItem* root, double scale_factor, const Geom::Rec GDK_COLORSPACE_RGB, TRUE, 8, psize, psize, cairo_image_surface_get_stride(s), - (GdkPixbufDestroyNotify)cairo_surface_destroy, - NULL); + ink_cairo_pixbuf_cleanup, s); convert_pixbuf_argb32_to_normal(pixbuf); return pixbuf; diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index 3463aa496..598827da9 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -225,7 +225,7 @@ static void colorItemDragBegin( GtkWidget */*widget*/, GdkDragContext* dc, gpoin pixbuf = gdk_pixbuf_new_from_data(cairo_image_surface_get_data(s), GDK_COLORSPACE_RGB, TRUE, 8, width, height, cairo_image_surface_get_stride(s), - (GdkPixbufDestroyNotify) cairo_surface_destroy, NULL); + ink_cairo_pixbuf_cleanup, s); convert_pixbuf_argb32_to_normal(pixbuf); } else { Glib::RefPtr<Gdk::Pixbuf> thumb = Gdk::Pixbuf::create( Gdk::COLORSPACE_RGB, false, 8, width, height ); @@ -533,7 +533,7 @@ void ColorItem::_regenPreview(EekPreview * preview) GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data( cairo_image_surface_get_data(s), GDK_COLORSPACE_RGB, TRUE, 8, w, h, cairo_image_surface_get_stride(s), - (GdkPixbufDestroyNotify) cairo_surface_destroy, NULL); + ink_cairo_pixbuf_cleanup, s); convert_pixbuf_argb32_to_normal(pixbuf); eek_preview_set_pixbuf( preview, pixbuf ); } |
