Пример #1
0
static cairo_int_status_t
_cairo_gl_composite_setup_clipping (cairo_gl_composite_t *setup,
				    cairo_gl_context_t *ctx,
				    int vertex_size)
{

    if (! _cairo_gl_context_is_flushed (ctx) &&
	(! cairo_region_equal (ctx->clip_region, setup->clip_region) ||
	 ! _cairo_clip_equal (ctx->clip, setup->clip)))
	_cairo_gl_composite_flush (ctx);

    cairo_region_destroy (ctx->clip_region);
    ctx->clip_region = cairo_region_reference (setup->clip_region);
    _cairo_clip_destroy (ctx->clip);
    ctx->clip = _cairo_clip_copy (setup->clip);

    assert (!setup->clip_region || !setup->clip);

    if (ctx->clip_region) {
	_disable_stencil_buffer ();
	glEnable (GL_SCISSOR_TEST);
	return CAIRO_INT_STATUS_SUCCESS;
    }

    if (ctx->clip)
	return _cairo_gl_composite_setup_painted_clipping (setup, ctx,
							   vertex_size);

    _disable_stencil_buffer ();
    glDisable (GL_SCISSOR_TEST);
    return CAIRO_INT_STATUS_SUCCESS;
}
Пример #2
0
// cairo_public cairo_bool_t
// cairo_region_equal (const cairo_region_t *a, const cairo_region_t *b);
static int l_cairo_region_equal (lua_State* L)
{
    const cairo_region_t *a = get_cairo_region_t (L, 1);
    const cairo_region_t *b = get_cairo_region_t (L, 2);
    cairo_bool_t v = cairo_region_equal (a, b);
    lua_pushboolean(L, v);
    return 1;
}
Пример #3
0
bool wxRegion::DoIsEqual(const wxRegion& region) const
{
#ifdef __WXGTK3__
    return cairo_region_equal(
        M_REGIONDATA->m_region, M_REGIONDATA_OF(region)->m_region);
#else
    return gdk_region_equal(M_REGIONDATA->m_region,
                            M_REGIONDATA_OF(region)->m_region) != 0;
#endif
}
Пример #4
0
static cairo_int_status_t
_cairo_gl_composite_setup_clipping (cairo_gl_composite_t *setup,
				    cairo_gl_context_t *ctx,
				    int vertex_size)
{
    cairo_bool_t clip_changing = TRUE;
    cairo_bool_t clip_region_changing = TRUE;

    if (! ctx->clip && ! setup->clip && ! setup->clip_region && ! ctx->clip_region)
	goto disable_all_clipping;

    clip_changing = ! _cairo_clip_equal (ctx->clip, setup->clip);
    clip_region_changing = ! cairo_region_equal (ctx->clip_region, setup->clip_region);
    if (! _cairo_gl_context_is_flushed (ctx) &&
	(clip_region_changing || clip_changing))
	_cairo_gl_composite_flush (ctx);

    assert (!setup->clip_region || !setup->clip);

    /* setup->clip is only used by the msaa compositor and setup->clip_region
     * only by the other compositors, so it's safe to wait to clean up obsolete
     * clips. */
    if (clip_region_changing) {
	cairo_region_destroy (ctx->clip_region);
	ctx->clip_region = cairo_region_reference (setup->clip_region);
    }
    if (clip_changing) {
	_cairo_clip_destroy (ctx->clip);
	ctx->clip = _cairo_clip_copy (setup->clip);
    }

    /* For clip regions, we scissor right before drawing. */
    if (setup->clip_region)
	goto disable_all_clipping;

    if (setup->clip)
	return _cairo_gl_composite_setup_painted_clipping (setup, ctx,
                                                           vertex_size);
disable_all_clipping:
    _disable_stencil_buffer ();
    glDisable (GL_SCISSOR_TEST);
    return CAIRO_INT_STATUS_SUCCESS;
}
Пример #5
0
/* We double buffer the image.  It looks nice and it enables
 * grabbing the graph with the pointer and translating it.
 * We draw on our own larger surface and then copy part of that
 * to the gdk surface.
 *
 * We assume that this function is drawing to an exposed/showing
 * drawing area, so the status update will reflect the current
 * exposed/showing drawing area. */
void qp_graph_draw(struct qp_graph *gr, cairo_t *gdk_cr)
{
  GtkAllocation allocation;

  if(gr->waiting_to_resize_draw && !gr->qp->shape)
  {
    //WARN("gr=%p gr->name=\"%s\" gr->ref_count=%d\n", gr, gr->name, gr->ref_count);
    cairo_set_source_rgba(gdk_cr, gr->background_color.r,
      gr->background_color.g, gr->background_color.b,
      gr->background_color.a);

    cairo_paint(gdk_cr);

    g_idle_add_full(G_PRIORITY_LOW, idle_callback, gr, NULL);
    /* fight qp_graph_destroy() race condition with flag */
    ++gr->ref_count;
    /* We draw after the other widgets are drawn, in case drawing
     * takes a long time.  This waiting also gives a chance
     * for the watch cursor to show.  But that seems to only
     * show if the window had focus at the right time. */
    return;
  }

  gtk_widget_get_allocation(gr->drawing_area, &allocation);
  
  if(gr->pixbuf_needs_draw)
  {
    cairo_t *db_cr; /* double buffer cr */

    db_cr = cairo_create(gr->pixbuf_surface);
    graph_draw(gr, db_cr, gr->pixbuf_x, gr->pixbuf_y,
                  gr->pixbuf_width, gr->pixbuf_height);
    cairo_destroy(db_cr);
    // debuging
    //cairo_surface_write_to_png(gr->pixbuf_surface, "x.png");
    qp_win_set_status(gr->qp);
  }

  /* the GTK cairo_t *gdk_cr has no alpha bits so all the
   * alpha drawn to it will be smushed. */
  //WARN("content=0x%lx\n", (unsigned long)cairo_get_target(gdk_cr));


  if(!gr->qp->shape)
  {
    /* Not using the shape X11 extension */

    /* This is where we go from the back buffer to the drawing area */
    draw_from_pixbuf(gdk_cr, gr, allocation.width, allocation.height);

    if(gr->draw_zoom_box == 1)
      draw_zoom_box(gdk_cr, gr);
    if(gr->draw_value_pick)
      draw_value_pick_line(gdk_cr, gr, allocation.width, allocation.height);


    if(gr->pixbuf_needs_draw)
    {
      gdk_window_set_cursor(gtk_widget_get_window(gr->qp->window), NULL);
      gr->pixbuf_needs_draw = 0;
      // gr->qp->wait_warning_showing = 0;
    }
  }
  else
  {
    /* Use the X11 shape extension */


    /* TODO: This is a resource pig.  Fix it. */

    cairo_region_t *reg_draw_area, *window_region;
    /* empty flag */ 
    int empty;
    cairo_surface_t *mask_surface;
    GtkAllocation all;

    /* Make sure the surface is up to date */
    //cairo_surface_flush(gr->pixbuf_surface);

    /* make a sub surface that is the size of the graph drawing area */
    mask_surface = cairo_surface_create_for_rectangle(gr->pixbuf_surface,
        INT(gr->pixbuf_x+gr->grab_x),
        INT(gr->pixbuf_y+gr->grab_y),
        allocation.width, allocation.height);
    
    reg_draw_area = get_cairo_region_create_from_surface(gr,
        mask_surface, allocation.width, allocation.height);

    cairo_surface_destroy(mask_surface);

    cairo_region_translate(reg_draw_area, allocation.x, allocation.y);

    gtk_widget_get_allocation(gr->qp->window, &all);
    all.x = all.y = 0;

    window_region = cairo_region_create_rectangle(&all);

    cairo_region_subtract_rectangle(window_region, &allocation);

    empty = cairo_region_is_empty(reg_draw_area);

    if(!empty)  
      cairo_region_union(window_region, reg_draw_area);

    cairo_region_destroy(reg_draw_area);

    /* window_region is a region with a hole in it the
     * size of the drawing area with the graph and grid added back. */


    if(gr->draw_zoom_box && !empty)
    {
      cairo_rectangle_int_t rec;
      rec.x = allocation.x + gr->z_x;
      rec.y = allocation.y + gr->z_y;
      rec.width = gr->z_w;
      rec.height = gr->z_h;
      /* regions do not like negitive values or
       * maybe shapes do not like negitive values
       * in any case we keep width and height
       * positive */
      if(rec.width < 0)
      {
        rec.width *= -1;
        rec.x -= rec.width;
      }
      if(rec.height < 0)
      {
        rec.height *= -1;
        rec.y -= rec.height;
      }
        
      cairo_region_union_rectangle(window_region, &rec);
      /* now we have the zoom box added to window_region */
    }


    /* This is where we go from the back buffer to the drawing area */
    draw_from_pixbuf(gdk_cr, gr, allocation.width, allocation.height);
    if(gr->draw_zoom_box)
      draw_zoom_box(gdk_cr, gr);
    if(gr->draw_value_pick)
      draw_value_pick_line(gdk_cr, gr, allocation.width, allocation.height);


    if(empty)
    {
      /* we have nothing to make a shape with */
      if(gr->qp->last_shape_region)
      {
        cairo_region_destroy(gr->qp->last_shape_region);
        gr->qp->last_shape_region = NULL;
      }
      cairo_region_destroy(window_region);
      /* remove the old shape region */
      gtk_widget_shape_combine_region(gr->qp->window, NULL);
    }
    else if(!gr->qp->last_shape_region ||
        !cairo_region_equal(gr->qp->last_shape_region, window_region))
    {
      // DEBUG("creating new shape region\n");
      
      /* We need to undo the old shape first */
      gtk_widget_shape_combine_region(gr->qp->window, NULL);

      gtk_widget_shape_combine_region(gr->qp->window, window_region);

      if(gr->qp->last_shape_region)
        cairo_region_destroy(gr->qp->last_shape_region);

      gr->qp->last_shape_region = window_region;
    }
    else
      cairo_region_destroy(window_region);


    gr->pixbuf_needs_draw = 0;

    gdk_window_set_cursor(gtk_widget_get_window(gr->qp->window), NULL);
    // debuging
    //cairo_surface_write_to_png(cairo_get_target(gdk_cr), "y.png");
  }

  if(gr->qp->update_graph_detail && gr->qp->graph_detail)
  {
    gr->qp->update_graph_detail = 0;
    /* make the graph configure window show stuff about this graph */
    qp_win_graph_detail_init(gr->qp);
  }
}
Пример #6
0
cairo_status_t
_cairo_gl_composite_begin (cairo_gl_composite_t *setup,
                           cairo_gl_context_t **ctx_out)
{
    unsigned int dst_size, src_size, mask_size, vertex_size;
    cairo_gl_context_t *ctx;
    cairo_status_t status;
    cairo_bool_t component_alpha;
    cairo_gl_shader_t *shader;

    assert (setup->dst);

    status = _cairo_gl_context_acquire (setup->dst->base.device, &ctx);
    if (unlikely (status))
	return status;

    glEnable (GL_BLEND);

    component_alpha =
	setup->mask.type == CAIRO_GL_OPERAND_TEXTURE &&
	setup->mask.texture.attributes.has_component_alpha;

    /* Do various magic for component alpha */
    if (component_alpha) {
        status = _cairo_gl_composite_begin_component_alpha (ctx, setup);
        if (unlikely (status))
            goto FAIL;
    } else {
        if (ctx->pre_shader) {
            _cairo_gl_composite_flush (ctx);
            ctx->pre_shader = NULL;
        }
    }

    status = _cairo_gl_get_shader_by_type (ctx,
					   &setup->src,
					   &setup->mask,
					   setup->spans,
                                           component_alpha ?
					   CAIRO_GL_SHADER_IN_CA_SOURCE :
					   CAIRO_GL_SHADER_IN_NORMAL,
                                           &shader);
    if (unlikely (status)) {
        ctx->pre_shader = NULL;
        goto FAIL;
    }
    if (ctx->current_shader != shader)
        _cairo_gl_composite_flush (ctx);

    status = CAIRO_STATUS_SUCCESS;

    dst_size  = 2 * sizeof (GLfloat);
    src_size  = _cairo_gl_operand_get_vertex_size (setup->src.type);
    mask_size = _cairo_gl_operand_get_vertex_size (setup->mask.type);

    vertex_size = dst_size + src_size + mask_size;
    if (setup->spans)
	    vertex_size += sizeof (GLfloat);

    if (ctx->vertex_size != vertex_size)
        _cairo_gl_composite_flush (ctx);

    _cairo_gl_context_set_destination (ctx, setup->dst);

    if (_cairo_gl_context_is_flushed (ctx)) {
        ctx->dispatch.BindBuffer (GL_ARRAY_BUFFER, ctx->vbo);

	ctx->dispatch.VertexAttribPointer (CAIRO_GL_VERTEX_ATTRIB_INDEX, 2,
					   GL_FLOAT, GL_FALSE, vertex_size, NULL);
	ctx->dispatch.EnableVertexAttribArray (CAIRO_GL_VERTEX_ATTRIB_INDEX);
    }

    _cairo_gl_context_setup_operand (ctx, CAIRO_GL_TEX_SOURCE, &setup->src, vertex_size, dst_size);
    _cairo_gl_context_setup_operand (ctx, CAIRO_GL_TEX_MASK, &setup->mask, vertex_size, dst_size + src_size);
    if (setup->spans)
	_cairo_gl_context_setup_spans (ctx, vertex_size, dst_size + src_size + mask_size);
    else
	ctx->dispatch.DisableVertexAttribArray (CAIRO_GL_COLOR_ATTRIB_INDEX);

    _cairo_gl_set_operator (ctx, setup->op, component_alpha);

    ctx->vertex_size = vertex_size;

    if (_cairo_gl_context_is_flushed (ctx)) {
        if (ctx->pre_shader) {
            _cairo_gl_set_shader (ctx, ctx->pre_shader);
            _cairo_gl_composite_bind_to_shader (ctx, setup);
        }
        _cairo_gl_set_shader (ctx, shader);
        _cairo_gl_composite_bind_to_shader (ctx, setup);
    }

    if (! _cairo_gl_context_is_flushed (ctx) &&
        ! cairo_region_equal (ctx->clip_region, setup->clip_region))
        _cairo_gl_composite_flush (ctx);
    cairo_region_destroy (ctx->clip_region);
    ctx->clip_region = cairo_region_reference (setup->clip_region);
    if (ctx->clip_region)
	glEnable (GL_SCISSOR_TEST);
    else
	glDisable (GL_SCISSOR_TEST);

    *ctx_out = ctx;

FAIL:
    if (unlikely (status))
        status = _cairo_gl_context_release (ctx, status);

    return status;
}
Пример #7
0
static gboolean
goc_canvas_draw (GtkWidget *widget, cairo_t *cr)
{
	double x0, y0, x1, y1;
	double ax0, ay0, ax1, ay1;
	double clip_x1, clip_y1, clip_x2, clip_y2;
	GocCanvas *canvas = GOC_CANVAS (widget);
	GdkEventExpose *event = (GdkEventExpose *) gtk_get_current_event ();
	GocCanvasPrivate *priv = (GocCanvasPrivate *) canvas->priv;
	cairo_rectangle_list_t *l = cairo_copy_clip_rectangle_list (cr);
	int i, x, y;

	if (GOC_IS_ITEM (priv->invalidated_item) && priv->invalid_region) {
		/* evaluate the cairo clipped region and compare with the saved one */
		cairo_region_t *region;
		cairo_rectangle_int_t rect[l->num_rectangles];
	    for (i= 0; i  < l->num_rectangles; i++) {
			rect[i].x = l->rectangles[i].x;
			rect[i].y = l->rectangles[i].y;
			rect[i].width = l->rectangles[i].width;
			rect[i].height = l->rectangles[i].height;
		}
		region = cairo_region_create_rectangles (rect, l->num_rectangles);
		if (cairo_region_equal (priv->invalid_region, region)) {
			cairo_rectangle_list_destroy (l);
			cairo_region_destroy (region);
			/* looks like each time we call gtk_widget_queue_draw*,
			   the draw event is fired twice */
			if (priv->done) {
				priv->invalidated_item = NULL;
				cairo_region_destroy (priv->invalid_region);
				priv->invalid_region = NULL;
			} else {
				goc_item_draw (priv->invalidated_item, cr);
				priv->done = TRUE;
			}
			return TRUE;
		}

		cairo_region_destroy (region);
	}

	x = gtk_adjustment_get_value (gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (canvas)));
	y = gtk_adjustment_get_value (gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (canvas)));
	cairo_translate (cr, -x, -y);
	goc_item_get_bounds (GOC_ITEM (canvas->root),&x0, &y0, &x1, &y1);
	for (i= 0; i  < l->num_rectangles; i++) {
		cairo_save (cr);
		cairo_rectangle (cr, l->rectangles[i].x, l->rectangles[i].y,
		                 l->rectangles[i].width, l->rectangles[i].height);
		cairo_clip (cr);
		clip_x1 = l->rectangles[i].x;
		clip_y1 = l->rectangles[i].y;
		clip_x2 = clip_x1 + l->rectangles[i].width;
		clip_y2 = clip_y1 + l->rectangles[i].height;

		if (canvas->direction == GOC_DIRECTION_RTL) {
			ax1 = (double) (canvas->width - clip_x1) / canvas->pixels_per_unit + canvas->scroll_x1;
			ax0 = (double) (canvas->width - clip_x2) / canvas->pixels_per_unit + canvas->scroll_x1;
		} else {
			ax0 = (double) clip_x1 / canvas->pixels_per_unit + canvas->scroll_x1;
			ax1 = ((double) clip_x1 + event->area.width) / canvas->pixels_per_unit + canvas->scroll_x1;
		}
		ay0 = (double) clip_y1 / canvas->pixels_per_unit + canvas->scroll_y1;
		ay1 = (double) clip_y2 / canvas->pixels_per_unit + canvas->scroll_y1;
		if (x0 <= ax1 && x1 >= ax0 && y0 <= ay1 && y1 >= ay0) {
			canvas->cur_event = (GdkEvent *) event;
			goc_item_draw_region (GOC_ITEM (canvas->root), cr, ax0, ay0, ax1, ay1);
		}
		cairo_restore (cr);
	}
	cairo_rectangle_list_destroy (l);
	return TRUE;
}