Exemple #1
0
static cairo_test_status_t
draw (cairo_t *cr, int width, int height)
{
    cairo_surface_t *surface;
    cairo_surface_t *image;
    cairo_surface_t *subimage;
    cairo_rectangle_int_t extents;
    cairo_t *cr2;

    extents.x = extents.y = 10;
    extents.width = WIDTH - 20;
    extents.height = HEIGHT - 20;

    /* We use a similar surface to have way smaller ref images */
    surface = cairo_surface_create_similar (cairo_get_target (cr),
					    CAIRO_CONTENT_COLOR_ALPHA,
					    WIDTH, HEIGHT);

    /* First we have to defeat xcb's deferred clear */
    cr2 = cairo_create (surface);
    cairo_test_paint_checkered (cr2);
    cairo_destroy (cr2);

    /* Get us an image surface with a non-natural stride */
    image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
					WIDTH, HEIGHT);
    subimage = cairo_surface_map_to_image (image, &extents);

    /* Paint the subimage to the similar surface and trigger the big upload */
    cr2 = cairo_create (surface);
    cairo_set_source_surface (cr2, subimage, 0, 0);
    cairo_paint (cr2);
    cairo_destroy (cr2);

    /* Finally we make sure that errors aren't lost. */
    cairo_surface_unmap_image (image, subimage);
    cairo_set_source_surface (cr, surface, 0, 0);
    cairo_paint (cr);
    cairo_surface_destroy (image);
    cairo_surface_destroy (surface);

    return CAIRO_TEST_SUCCESS;
}
Exemple #2
0
static int
map_to_image(lua_State *L)
{
    cairo_rectangle_int_t rect;
    cairo_rectangle_int_t *prect;
    cairo_surface_t **obj = luaL_checkudata(L, 1, OOCAIRO_MT_NAME_SURFACE);
    cairo_surface_t **res;

    lua_settop(L, 2);
    if (lua_isnil(L, 2)) {
        prect = NULL;
    } else {
        prect = ▭
        from_lua_rectangle(L, prect, 2);
    }

    res = create_surface_userdata(L);
    *res = cairo_surface_map_to_image(*obj, prect);
    return 1;
}
Exemple #3
0
/*
 * If we ever support GL/D3D surfaces, we will have to
 * filter on these surface types
 * For now, everything is CPU-rendered, so map_to_image
 * will give us the best possible backend for our blur
 */
void
eventd_nd_draw_blur_surface(cairo_t *cr, gint blur)
{
    cairo_surface_t *target, *surface;

    target = cairo_get_target(cr);
    surface = cairo_surface_map_to_image(target, NULL);

    if ( cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS )
        return;

    gint width, height, stride, channels;
    guint8 *data, *tmp;

    switch ( cairo_image_surface_get_format(surface) )
    {
    case CAIRO_FORMAT_ARGB32:
    case CAIRO_FORMAT_RGB24:
        channels = 4;
    break;
    case CAIRO_FORMAT_A8:
        channels = 1;
    break;
    default:
        goto fail;
    }

    width  = cairo_image_surface_get_width(surface);
    height = cairo_image_surface_get_height(surface);

    data = cairo_image_surface_get_data(surface);
    stride = cairo_image_surface_get_stride(surface);

    tmp = g_alloca(stride * height * sizeof(guint8));
    _eventd_nd_draw_blur_gauss(data, tmp, blur, 3 /* number of passes */, width, height, stride, channels);

    cairo_surface_mark_dirty(surface);

fail:
    cairo_surface_unmap_image(target, surface);
}
Exemple #4
0
/* This is always called with the paint context current */
void
gdk_gl_texture_from_surface (cairo_surface_t *surface,
                             cairo_region_t  *region)
{
    GdkGLContext *paint_context;
    cairo_surface_t *image;
    double device_x_offset, device_y_offset;
    cairo_rectangle_int_t rect, e;
    int n_rects, i;
    GdkWindow *window;
    int unscaled_window_height;
    unsigned int texture_id;
    int window_scale;
    double sx, sy;
    float umax, vmax;
    gboolean use_texture_rectangle;
    guint target;
    paint_context = gdk_gl_context_get_current ();
    if ((_gdk_gl_flags & GDK_GL_SOFTWARE_DRAW_SURFACE) == 0 &&
            paint_context &&
            GDK_GL_CONTEXT_GET_CLASS (paint_context)->texture_from_surface &&
            GDK_GL_CONTEXT_GET_CLASS (paint_context)->texture_from_surface (paint_context, surface, region))
        return;

    /* Software fallback */
    use_texture_rectangle = gdk_gl_context_use_texture_rectangle (paint_context);

    window = gdk_gl_context_get_window (paint_context);
    window_scale = gdk_window_get_scale_factor (window);
    gdk_window_get_unscaled_size (window, NULL, &unscaled_window_height);

    sx = sy = 1;
    cairo_surface_get_device_scale (window->current_paint.surface, &sx, &sy);

    cairo_surface_get_device_offset (surface,
                                     &device_x_offset, &device_y_offset);

    glGenTextures (1, &texture_id);
    if (use_texture_rectangle)
        target = GL_TEXTURE_RECTANGLE_ARB;
    else
        target = GL_TEXTURE_2D;

    glBindTexture (target, texture_id);
    glEnable (GL_SCISSOR_TEST);

    glTexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    n_rects = cairo_region_num_rectangles (region);

#define FLIP_Y(_y) (unscaled_window_height - (_y))

    for (i = 0; i < n_rects; i++)
    {
        cairo_region_get_rectangle (region, i, &rect);

        glScissor (rect.x * window_scale, FLIP_Y ((rect.y + rect.height) * window_scale),
                   rect.width * window_scale, rect.height * window_scale);

        e = rect;
        e.x *= sx;
        e.y *= sy;
        e.x += (int)device_x_offset;
        e.y += (int)device_y_offset;
        e.width *= sx;
        e.height *= sy;
        image = cairo_surface_map_to_image (surface, &e);

        gdk_gl_context_upload_texture (paint_context, image, e.width, e.height, target);

        cairo_surface_unmap_image (surface, image);

        if (use_texture_rectangle)
        {
            umax = rect.width * sx;
            vmax = rect.height * sy;
        }
        else
        {
            umax = 1.0;
            vmax = 1.0;
        }

        {
            GdkTexturedQuad quad = {
                rect.x * window_scale, FLIP_Y(rect.y * window_scale),
                (rect.x + rect.width) * window_scale, FLIP_Y((rect.y + rect.height) * window_scale),
                0, 0,
                umax, vmax,
            };

            /* We don't want to combine the quads here, because they have different textures.
             * And we don't want to upload the unused source areas to make it one texture. */
            gdk_gl_texture_quads (paint_context, target, 1, &quad);
        }
    }

#undef FLIP_Y

    glDisable (GL_SCISSOR_TEST);
    glDeleteTextures (1, &texture_id);
}