[cairo] Clipping and on-demand redraw

Enrico Weigelt, metux IT consult enrico.weigelt at gr13.net
Sat Jan 9 14:11:44 PST 2016


Hi folks,


I'm currently trying to sort out how to do effiencent on-demand redraw
in my gui toolkit.

For now, the draw function looks like this:
(hope you can understand it w/o all the rest of the code ;-o)

The whole process starts with the root widget and steps down the tree.


int twtk_widget_do_draw(twtk_widget_t *widget, cairo_t* cr)
{
    if (widget == NULL)
        return -EFAULT;

    twtk_vector_t vp_size = widget->viewport_size;

    cairo_save(cr);
    cairo_translate(cr, widget->viewport_pos.x, widget->viewport_pos.y);
    if (widget->viewport_angle)
    {
        double dx = widget->viewport_size.x / 2;
        double dy = widget->viewport_size.y / 2;
        cairo_translate(cr, dx, dy);
        cairo_rotate(cr, widget->viewport_angle);
        cairo_translate(cr, - dx, - dy);
    }
    cairo_rectangle(cr, 0, 0, vp_size.x, vp_size.y);
    cairo_clip(cr);

    /* fill with background color */
    if (widget->background_color.alpha)
    {
        _twtk_ut_set_rgba(cr, widget->background_color);
        cairo_rectangle (cr, 0, 0, vp_size.x, vp_size.y);
        cairo_fill (cr);
    }

    cairo_scale(cr, widget->surface_scale.x, widget->surface_scale.y);
    cairo_rotate(cr, widget->surface_angle);
    // call the widget's paint() method
    if ((widget->cls) && (widget->cls->op_paint))
    {
        cairo_save(cr);
        widget->cls->op_paint(widget, cr);
        cairo_restore(cr);
    }

    // trigger repaint of sub's
    twtk_widget_list_entry_t *ent;
    for (ent = widget->frames.first; ent != NULL; ent = ent->next)
    {
        printf("repainting: %s\n", ent->name);
        twtk_widget_do_draw(ent->widget, cr);
    }

    cairo_restore(cr);

    return 0;
}


Now I'd like to change it in a way, that

a) repaint only happens when the widget isn't overlapped by others
b) clip-out all regions that are overlapped by others
c) dont paint at all if completely overlapped


I'd guess, at the very first, i should iterate through all subsequent
widgets (which, per definition are in front of the current one) and
clip them out. And before actual painting, check whether everything's
clipped-out. But I dont know yet, how to do that also w/ rotation.

Any suggestions ?


--mtx

--
Enrico Weigelt,
metux IT consulting
+49-151-27565287


More information about the cairo mailing list