summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2011-07-06 20:59:33 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2011-07-06 20:59:33 +0000
commitaa7a997188b7f69017897a93bd153048df6b1dbc (patch)
tree4f8e3fe17f06b8f0b64486775e3a6a2e2c9f7761 /src
parentRefactoring color profile to bring more internal. Help to prep for optional l... (diff)
downloadinkscape-aa7a997188b7f69017897a93bd153048df6b1dbc.tar.gz
inkscape-aa7a997188b7f69017897a93bd153048df6b1dbc.zip
Fix mixed up colors when exporting images with bitmaps to PDF and other
Cairo formats. Fixes LP #804311 Fixed bugs: - https://launchpad.net/bugs/804311 (bzr r10421)
Diffstat (limited to 'src')
-rw-r--r--src/extension/internal/cairo-render-context.cpp65
-rw-r--r--src/extension/internal/cairo-render-context.h2
-rw-r--r--src/extension/internal/cairo-renderer.cpp16
3 files changed, 14 insertions, 69 deletions
diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp
index 1c1dac028..22b68b0ca 100644
--- a/src/extension/internal/cairo-render-context.cpp
+++ b/src/extension/internal/cairo-render-context.cpp
@@ -1419,7 +1419,7 @@ CairoRenderContext::renderPathVector(Geom::PathVector const & pathv, SPStyle con
return true;
}
-bool CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h, unsigned int rs,
+bool CairoRenderContext::renderImage(GdkPixbuf *pb,
Geom::Affine const *image_transform, SPStyle const * /*style*/)
{
g_assert( _is_valid );
@@ -1428,63 +1428,18 @@ bool CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h,
return true;
}
- guchar* px_rgba = NULL;
- guint64 size = 4L * (guint64)w * (guint64)h;
+ int w = gdk_pixbuf_get_width (pb);
+ int h = gdk_pixbuf_get_height (pb);
- if(size < (guint64)G_MAXSIZE) {
- px_rgba = (guchar*)g_try_malloc(4 * w * h);
- if (!px_rgba) {
- g_warning ("Could not allocate %lu bytes for pixel buffer!", (long unsigned) size);
- return false;
- }
- } else {
- g_warning ("the requested memory exceeds the system limit");
- return false;
- }
-
-
- float opacity;
- if (_state->merge_opacity)
- opacity = _state->opacity;
- else
- opacity = 1.0;
-
- // make a copy of the original pixbuf with premultiplied alpha
- // if we pass the original pixbuf it will get messed up
- /// @todo optimize this code, it costs a lot of time
- for (unsigned i = 0; i < h; i++) {
- guchar const *src = px + i * rs;
- guint32 *dst = (guint32 *)(px_rgba + i * rs);
- for (unsigned j = 0; j < w; j++) {
- guchar r, g, b, alpha_dst;
-
- // calculate opacity-modified alpha
- alpha_dst = src[3];
- if ((opacity != 1.0) && _vector_based_target)
- alpha_dst = (guchar)ceil((float)alpha_dst * opacity);
-
- // premul alpha (needed because this will be undone by cairo-pdf)
- r = src[0]*alpha_dst/255;
- g = src[1]*alpha_dst/255;
- b = src[2]*alpha_dst/255;
-
- *dst = (((alpha_dst) << 24) | (((r)) << 16) | (((g)) << 8) | (b));
-
- dst++; // pointer to 4byte variables
- src += 4; // pointer to 1byte variables
- }
- }
+ // TODO: reenable merge_opacity if useful
+ float opacity = _state->opacity;
- cairo_surface_t *image_surface = cairo_image_surface_create_for_data(px_rgba, CAIRO_FORMAT_ARGB32, w, h, w * 4);
+ cairo_surface_t *image_surface = ink_cairo_surface_create_for_argb32_pixbuf(pb);
if (cairo_surface_status(image_surface)) {
TRACE(("Image surface creation failed:\n%s\n", cairo_status_to_string(cairo_surface_status(image_surface))));
return false;
}
- // setup automatic freeing of the image data when destroying the surface
- static cairo_user_data_key_t key;
- cairo_surface_set_user_data(image_surface, &key, px_rgba, (cairo_destroy_func_t)g_free);
-
cairo_save(_cr);
// scaling by width & height is not needed because it will be done by Cairo
@@ -1499,16 +1454,10 @@ bool CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h,
cairo_rectangle(_cr, 0, 0, w, h);
cairo_clip(_cr);
}
-
- if (_vector_based_target)
- cairo_paint(_cr);
- else
- cairo_paint_with_alpha(_cr, opacity);
+ cairo_paint_with_alpha(_cr, opacity);
cairo_restore(_cr);
-
cairo_surface_destroy(image_surface);
-
return true;
}
diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h
index 68a3c6537..d4117ff7e 100644
--- a/src/extension/internal/cairo-render-context.h
+++ b/src/extension/internal/cairo-render-context.h
@@ -139,7 +139,7 @@ public:
/* Rendering methods */
bool renderPathVector(Geom::PathVector const & pathv, SPStyle const *style, NRRect const *pbox);
- bool renderImage(unsigned char *px, unsigned int w, unsigned int h, unsigned int rs,
+ bool renderImage(GdkPixbuf *pb,
Geom::Affine const *image_transform, SPStyle const *style);
bool renderGlyphtext(PangoFont *font, Geom::Affine const *font_matrix,
std::vector<CairoGlyphInfo> const &glyphtext, SPStyle const *style);
diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp
index bbafd7e94..6118a7ae9 100644
--- a/src/extension/internal/cairo-renderer.cpp
+++ b/src/extension/internal/cairo-renderer.cpp
@@ -41,6 +41,7 @@
#include "display/nr-arena-group.h"
#include "display/curve.h"
#include "display/canvas-bpath.h"
+#include "display/cairo-utils.h"
#include "sp-item.h"
#include "sp-item-group.h"
#include "style.h"
@@ -345,18 +346,15 @@ static void sp_flowtext_render(SPItem *item, CairoRenderContext *ctx)
static void sp_image_render(SPItem *item, CairoRenderContext *ctx)
{
SPImage *image;
- guchar *px;
- int w, h, rs;
+ int w, h;
image = SP_IMAGE (item);
if (!image->pixbuf) return;
if ((image->width.computed <= 0.0) || (image->height.computed <= 0.0)) return;
- px = gdk_pixbuf_get_pixels (image->pixbuf);
w = gdk_pixbuf_get_width (image->pixbuf);
h = gdk_pixbuf_get_height (image->pixbuf);
- rs = gdk_pixbuf_get_rowstride (image->pixbuf);
double x = image->x.computed;
double y = image->y.computed;
@@ -376,7 +374,7 @@ static void sp_image_render(SPItem *item, CairoRenderContext *ctx)
Geom::Scale s(width / (double)w, height / (double)h);
Geom::Affine t(s * tp);
- ctx->renderImage (px, w, h, rs, &t, item->style);
+ ctx->renderImage (image->pixbuf, &t, item->style);
}
static void sp_symbol_render(SPItem *item, CairoRenderContext *ctx)
@@ -516,11 +514,9 @@ static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx)
if (pb) {
TEST(gdk_pixbuf_save( pb, "bitmap.png", "png", NULL, NULL ));
- unsigned char *px = gdk_pixbuf_get_pixels (pb);
- unsigned int w = gdk_pixbuf_get_width(pb);
- unsigned int h = gdk_pixbuf_get_height(pb);
- unsigned int rs = gdk_pixbuf_get_rowstride(pb);
- ctx->renderImage(px, w, h, rs, &t, item->style);
+ // TODO this is stupid - we just converted to pixbuf format when generating the bitmap!
+ convert_pixbuf_normal_to_argb32(pb);
+ ctx->renderImage(pb, &t, item->style);
gdk_pixbuf_unref(pb);
pb = 0;
}