Logo Search packages:      
Sourcecode: inkscape version File versions  Download package

static void sp_canvas_paint_single_buffer ( SPCanvas canvas,
int  x0,
int  y0,
int  x1,
int  y1,
int  draw_x1,
int  draw_y1,
int  draw_x2,
int  draw_y2,
int  sw 
) [static]

define CANVAS_OUTPUT_VIA_CAIRO

Definition at line 1601 of file sp-canvas.cpp.

References SPCanvasBuf::bg_color, Inkscape::Preferences::get(), Inkscape::Preferences::getBool(), NR_PIXBLOCK_MODE_R8G8B8, NR_PIXBLOCK_MODE_R8G8B8A8P, NR_PIXBLOCK_PX(), nr_pixblock_release(), nr_pixblock_setup_extern(), nr_pixblock_setup_fast(), and sp_canvas_mark_rect().

Referenced by sp_canvas_paint_rect_internal().

{
    GtkWidget *widget = GTK_WIDGET (canvas);

    SPCanvasBuf buf;
    if (canvas->rendermode != Inkscape::RENDERMODE_OUTLINE) {
        buf.buf = nr_pixelstore_256K_new (FALSE, 0);
    } else {
        buf.buf = nr_pixelstore_1M_new (FALSE, 0);
    }

    // Mark the region clean
    sp_canvas_mark_rect(canvas, x0, y0, x1, y1, 0);

    buf.buf_rowstride = sw * 4;
    buf.rect.x0 = x0;
    buf.rect.y0 = y0;
    buf.rect.x1 = x1;
    buf.rect.y1 = y1;
    buf.visible_rect.x0 = draw_x1;
    buf.visible_rect.y0 = draw_y1;
    buf.visible_rect.x1 = draw_x2;
    buf.visible_rect.y1 = draw_y2;
    GdkColor *color = &widget->style->bg[GTK_STATE_NORMAL];
    buf.bg_color = (((color->red & 0xff00) << 8)
                    | (color->green & 0xff00)
                    | (color->blue >> 8));
    buf.is_empty = true;

    buf.ct = nr_create_cairo_context_canvasbuf (&(buf.visible_rect), &buf);

    if (canvas->root->flags & SP_CANVAS_ITEM_VISIBLE) {
        SP_CANVAS_ITEM_GET_CLASS (canvas->root)->render (canvas->root, &buf);
    }

#if ENABLE_LCMS
    cmsHTRANSFORM transf = 0;
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    bool fromDisplay = prefs->getBool( "/options/displayprofile/from_display");
    if ( fromDisplay ) {
        transf = Inkscape::colorprofile_get_display_per( canvas->cms_key ? *(canvas->cms_key) : "" );
    } else {
        transf = Inkscape::colorprofile_get_display_transform();
    }
#endif // ENABLE_LCMS

    if (buf.is_empty) {
#if ENABLE_LCMS
        if ( transf && canvas->enable_cms_display_adj ) {
            cmsDoTransform( transf, &buf.bg_color, &buf.bg_color, 1 );
        }
#endif // ENABLE_LCMS
        gdk_rgb_gc_set_foreground (canvas->pixmap_gc, buf.bg_color);
        gdk_draw_rectangle (SP_CANVAS_WINDOW (canvas),
                            canvas->pixmap_gc,
                            TRUE,
                            x0 - canvas->x0, y0 - canvas->y0,
                            x1 - x0, y1 - y0);
    } else {

#if ENABLE_LCMS
        if ( transf && canvas->enable_cms_display_adj ) {
            for ( gint yy = 0; yy < (y1 - y0); yy++ ) {
                guchar* p = buf.buf + (buf.buf_rowstride * yy);
                cmsDoTransform( transf, p, p, (x1 - x0) );
            }
        }
#endif // ENABLE_LCMS

// Now we only need to output the prepared pixmap to the actual screen, and this define chooses one
// of the two ways to do it. The cairo way is direct and straightforward, but unfortunately
// noticeably slower. I asked Carl Worth but he was unable so far to suggest any specific reason
// for this slowness. So, for now we use the oldish method: squeeze out 32bpp buffer to 24bpp and
// use gdk_draw_rgb_image_dithalign, for unfortunately gdk can only handle 24 bpp, which cairo
// cannot handle at all. Still, this way is currently faster even despite the blit with squeeze.

///#define CANVAS_OUTPUT_VIA_CAIRO

#ifdef CANVAS_OUTPUT_VIA_CAIRO

        buf.cst = cairo_image_surface_create_for_data (
            buf.buf,
            CAIRO_FORMAT_ARGB32,  // unpacked, i.e. 32 bits! one byte is unused
            x1 - x0, y1 - y0,
            buf.buf_rowstride
            );
        cairo_t *window_ct = gdk_cairo_create(SP_CANVAS_WINDOW (canvas));
        cairo_set_source_surface (window_ct, buf.cst, x0 - canvas->x0, y0 - canvas->y0);
        cairo_paint (window_ct);
        cairo_destroy (window_ct);
        cairo_surface_finish (buf.cst);
        cairo_surface_destroy (buf.cst);

#else

        NRPixBlock b3;
        nr_pixblock_setup_fast (&b3, NR_PIXBLOCK_MODE_R8G8B8, x0, y0, x1, y1, TRUE);

        NRPixBlock b4;
        nr_pixblock_setup_extern (&b4, NR_PIXBLOCK_MODE_R8G8B8A8P, x0, y0, x1, y1,
                                  buf.buf,
                                  buf.buf_rowstride,
                                  FALSE, FALSE);

        // this does the 32->24 squishing, using an assembler routine:
        nr_blit_pixblock_pixblock (&b3, &b4);

        gdk_draw_rgb_image_dithalign (SP_CANVAS_WINDOW (canvas),
                                      canvas->pixmap_gc,
                                      x0 - canvas->x0, y0 - canvas->y0,
                                      x1 - x0, y1 - y0,
                                      GDK_RGB_DITHER_MAX,
                                      NR_PIXBLOCK_PX(&b3),
                                      sw * 3,
                                      x0 - canvas->x0, y0 - canvas->y0);

        nr_pixblock_release (&b3);
        nr_pixblock_release (&b4);
#endif
    }

    cairo_surface_t *cst = cairo_get_target(buf.ct);
    cairo_destroy (buf.ct);
    cairo_surface_finish (cst);
    cairo_surface_destroy (cst);

    if (canvas->rendermode != Inkscape::RENDERMODE_OUTLINE) {
        nr_pixelstore_256K_free (buf.buf);
    } else {
        nr_pixelstore_1M_free (buf.buf);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Generated by  Doxygen 1.6.0   Back to index