X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fdisplay%2Fcanvas-arena.cpp;h=bb60cdc938cd32ba481bb923a73d90562add9415;hb=02c3f3ebde37bbc650b2e8eb951e7037ed714360;hp=a7615b3d7c571ca3556c03797fe98585c64fe9e4;hpb=76be04672cb5648cfe283a5b2cc713a619b1d4d6;p=inkscape.git diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp index a7615b3d7..bb60cdc93 100644 --- a/src/display/canvas-arena.cpp +++ b/src/display/canvas-arena.cpp @@ -21,6 +21,7 @@ #include #include #include +#include enum { ARENA_EVENT, @@ -100,6 +101,7 @@ sp_canvas_arena_init (SPCanvasArena *arena) arena->sticky = FALSE; arena->arena = NRArena::create(); + arena->arena->canvasarena = arena; arena->root = NRArenaGroup::create(arena->arena); nr_arena_group_set_transparent (NR_ARENA_GROUP (arena->root), TRUE); @@ -248,9 +250,15 @@ sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf) } } -/* fixme: RGB transformed bitmap blit is not implemented (Lauris) */ -/* And even if it would be, unless it uses MMX there is little reason to go RGB */ -// CAIRO FIXME: undefine this so that arena renders directly into SPCanvasBuf, without blitting and squishing (32bpp -> 24bpp packed) from a pixblock +/* +This define chooses between two modes: When on, arena renders into a temporary +32bpp buffer, and the result is then squished into the SPCanvasBuf. When off, arena +renders directly to SPCanvasBuf. However currently this gives no speed advantage, +perhaps because the lack of squishing is offset by the need for arena items to render +to the inconvenient (and probably slower) 24bpp buffer. When SPCanvasBuf is +switched to 32bpp and cairo drawing, however, this define should be removed to +streamline rendering. +*/ #define STRICT_RGBA for (y = buf->rect.y0; y < buf->rect.y1; y += sh) { @@ -268,8 +276,6 @@ sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf) #ifdef STRICT_RGBA nr_pixblock_setup_fast (&pb, NR_PIXBLOCK_MODE_R8G8B8A8P, area.x0, area.y0, area.x1, area.y1, TRUE); - /* fixme: */ - pb.empty = FALSE; #endif // CAIRO FIXME: switch this to R8G8B8A8P and 4 * ... @@ -279,15 +285,52 @@ sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf) FALSE, FALSE); #ifdef STRICT_RGBA - pb.visible_area = buf->visible_rect; + pb.visible_area = buf->visible_rect; + if (pb.data.px != NULL) { - nr_arena_item_invoke_render (arena->root, &area, &pb, 0); - nr_blit_pixblock_pixblock (&cb, &pb); + cairo_t *ct = nr_create_cairo_context (&area, &pb); + + nr_arena_item_invoke_render (ct, arena->root, &area, &pb, 0); + + if (pb.empty == FALSE) { + + if (arena->arena->rendermode == RENDERMODE_OUTLINE) { + // currently we only use cairo in outline mode + + // ENDIANNESS FIX + // Inkscape and GTK use fixed byte order in their buffers: r, g, b, a. + // Cairo reads/writes buffer values as in32s and therefore depends on the hardware byte order + // (little-endian vs big-endian). + // Until we move ALL of inkscape rendering and screen display to cairo, + // we must reverse the order for big-endian architectures (e.g. PowerPC). + if (G_BYTE_ORDER == G_BIG_ENDIAN) { + unsigned char *start = NR_PIXBLOCK_PX(&pb); + unsigned char *end = start + pb.rs * (pb.area.y1 - pb.area.y0); + for (unsigned char *i = start; i < end; i += 4) { + unsigned char tmp0 = i[0]; + unsigned char tmp1 = i[1]; + i[0] = i[3]; + i[1] = i[2]; + i[2] = tmp1; + i[3] = tmp0; + } + } + } + + // this does the 32->24 squishing, using an assembler routine: + nr_blit_pixblock_pixblock (&cb, &pb); + } + + cairo_surface_t *cst = cairo_get_target(ct); + cairo_destroy (ct); + cairo_surface_finish (cst); + cairo_surface_destroy (cst); } + nr_pixblock_release (&pb); #else - cb.visible_area = buf->visible_rect; - nr_arena_item_invoke_render (arena->root, &area, &cb, 0); + cb.visible_area = buf->visible_rect; + nr_arena_item_invoke_render (NULL, arena->root, &area, &cb, 0); #endif nr_pixblock_release (&cb); @@ -451,6 +494,6 @@ sp_canvas_arena_render_pixblock (SPCanvasArena *ca, NRPixBlock *pb) area.x1 = pb->area.x1; area.y1 = pb->area.y1; - nr_arena_item_invoke_render (ca->root, &area, pb, 0); + nr_arena_item_invoke_render (NULL, ca->root, &area, pb, 0); }