summaryrefslogtreecommitdiffstats
path: root/src/widgets/icon.cpp
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2010-06-29 21:05:56 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2010-06-29 21:05:56 +0000
commit55f7e59c13b6fb502a0cfbbe811f2f3f90cc6f80 (patch)
tree59cad53c22c3820db30fc96ba21d54f5f0b269fd /src/widgets/icon.cpp
parentBitmap image rendering (diff)
downloadinkscape-55f7e59c13b6fb502a0cfbbe811f2f3f90cc6f80.tar.gz
inkscape-55f7e59c13b6fb502a0cfbbe811f2f3f90cc6f80.zip
Fix icons
(bzr r9508.1.7)
Diffstat (limited to 'src/widgets/icon.cpp')
-rw-r--r--src/widgets/icon.cpp47
1 files changed, 44 insertions, 3 deletions
diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp
index 5d91d3532..51bdfef66 100644
--- a/src/widgets/icon.cpp
+++ b/src/widgets/icon.cpp
@@ -913,6 +913,7 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root,
{
bool const dump = Inkscape::Preferences::get()->getBool("/debug/icons/dumpSvg");
guchar *px = NULL;
+ int w, h, stride;
if (doc) {
SPObject *object = doc->getObjectById(name);
@@ -1010,19 +1011,59 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root,
g_message( " area --'%s' (%f,%f)-(%f,%f)", name, (double)area.x0, (double)area.y0, (double)area.x1, (double)area.y1 );
g_message( " ua --'%s' (%f,%f)-(%f,%f)", name, (double)ua.x0, (double)ua.y0, (double)ua.x1, (double)ua.y1 );
}
+
+ w = ua.x1 - ua.x0;
+ h = ua.y1 - ua.y0;
+ stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, w);
+
/* Set up pixblock */
- px = g_new(guchar, 4 * psize * psize);
- memset(px, 0x00, 4 * psize * psize);
+ px = g_new(guchar, stride * h);
+ memset(px, 0x00, stride * h);
+
/* Render */
+ cairo_surface_t *s = cairo_image_surface_create_for_data(px,
+ CAIRO_FORMAT_ARGB32, w, h, stride);
+ cairo_t *ct = cairo_create(s);
+
NRPixBlock B;
nr_pixblock_setup_extern( &B, NR_PIXBLOCK_MODE_R8G8B8A8N,
ua.x0, ua.y0, ua.x1, ua.y1,
px + 4 * psize * (ua.y0 - area.y0) +
4 * (ua.x0 - area.x0),
4 * psize, FALSE, FALSE );
- nr_arena_item_invoke_render(NULL, root, &ua, &B,
+ nr_arena_item_invoke_render(ct, root, &ua, &B,
NR_ARENA_ITEM_RENDER_NO_CACHE );
nr_pixblock_release(&B);
+ cairo_destroy(ct);
+ cairo_surface_destroy(s);
+
+ // convert to GdkPixbuf format
+ guint32 *ipx = reinterpret_cast<guint32*>(px);
+ for (int i = 0; i < h; ++i) {
+ for (int j = 0; j < w; ++j) {
+ int index = i * stride / 4 + j;
+ guint32 c = ipx[index];
+ guint32 o = 0;
+ guint32 a = (c & 0xff000000) >> 24;
+ if (a != 0) {
+ // extract color components
+ guint32 r = (c & 0x00ff0000) >> 16;
+ guint32 g = (c & 0x0000ff00) >> 8;
+ guint32 b = (c & 0x000000ff);
+ // unpremultiply; adding a/2 gives correct rounding
+ r = (r * 255 + a/2) / a;
+ b = (b * 255 + a/2) / a;
+ g = (g * 255 + a/2) / a;
+ // combine into output
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ o = (r) | (g << 8) | (b << 16) | (a << 24);
+#else
+ o = (r << 24) | (g << 16) | (b << 8) | (a);
+#endif
+ }
+ ipx[index] = o;
+ }
+ }
if ( Inkscape::Preferences::get()->getBool("/debug/icons/overlaySvg") ) {
sp_icon_overlay_pixels( px, psize, psize, 4 * psize, 0x00, 0x00, 0xff );