Beispiel #1
0
Rect
Geometry::ComputePathBounds()
{
	if (!IsBuilt ())
		Build ();

	if (!path || (path->cairo.num_data == 0))
		return Rect ();

	cairo_t *cr = measuring_context_create ();

	cairo_append_path (cr, &path->cairo);
	
	double x1, y1, x2, y2;

	cairo_path_extents (cr, &x1, &y1, &x2, &y2);

	Rect bounds = Rect (MIN (x1, x2), MIN (y1, y2), fabs (x2 - x1), fabs (y2 - y1));

	measuring_context_destroy (cr);

	return bounds;
}
Beispiel #2
0
static void
_adg_render(AdgEntity *entity, cairo_t *cr)
{
    AdgStroke *stroke;
    AdgStrokePrivate *data;
    const cairo_path_t *cairo_path;

    stroke = (AdgStroke *) entity;
    data = stroke->data;
    cairo_path = adg_trail_get_cairo_path(data->trail);

    if (cairo_path != NULL) {
        cairo_transform(cr, adg_entity_get_global_matrix(entity));

        cairo_save(cr);
        cairo_transform(cr, adg_entity_get_local_matrix(entity));
        cairo_append_path(cr, cairo_path);
        cairo_restore(cr);

        adg_entity_apply_dress(entity, data->line_dress, cr);
        cairo_stroke(cr);
    }
}
void
CairoPathContext::DuplicateContextAndPath()
{
  // Duplicate the path.
  cairo_path_t* path = cairo_copy_path(mContext);

  // Duplicate the context.
  cairo_surface_t* surf = cairo_get_target(mContext);
  cairo_matrix_t matrix;
  cairo_get_matrix(mContext, &matrix);
  cairo_destroy(mContext);

  mContext = cairo_create(surf);

  // Set the matrix to match the source context so that the path is copied in
  // device space. After this point it doesn't matter what the transform is
  // set to because it's always swapped out before use.
  cairo_set_matrix(mContext, &matrix);

  // Add the path, and throw away our duplicate.
  cairo_append_path(mContext, path);
  cairo_path_destroy(path);
}
Beispiel #4
0
static void
_adg_render(AdgEntity *entity, cairo_t *cr)
{
    AdgADim *adim;
    AdgDim *dim;
    AdgADimPrivate *data;
    AdgDimStyle *dim_style;
    AdgDress dress;
    const cairo_path_t *cairo_path;

    adim = (AdgADim *) entity;
    data = adim->data;

    if (!data->geometry_arranged) {
        /* Entity not arranged, probably due to undefined pair found */
        return;
    }

    dim = (AdgDim *) entity;
    dim_style = _ADG_GET_DIM_STYLE(dim);

    adg_style_apply((AdgStyle *) dim_style, entity, cr);
    adg_entity_render((AdgEntity *) adg_dim_get_quote(dim), cr);

    if (data->marker1 != NULL)
        adg_entity_render((AdgEntity *) data->marker1, cr);
    if (data->marker2 != NULL)
        adg_entity_render((AdgEntity *) data->marker2, cr);

    cairo_transform(cr, adg_entity_get_global_matrix(entity));
    dress = adg_dim_style_get_line_dress(dim_style);
    adg_entity_apply_dress(entity, dress, cr);

    cairo_path = adg_trail_get_cairo_path(data->trail);
    cairo_append_path(cr, cairo_path);
    cairo_stroke(cr);
}
Beispiel #5
0
void
Geometry::Draw (cairo_t *cr)
{
	Transform *transform = GetTransform ();
	cairo_matrix_t saved;
	cairo_get_matrix (cr, &saved);

	if (transform) {
		cairo_matrix_t matrix;
		transform->GetTransform (&matrix);
		cairo_transform (cr, &matrix);
	}

	if (!IsBuilt ())
		Build ();

	// Geometry is used for Clip so Fill (normally setting the fill rule) is never called
	cairo_set_fill_rule (cr, convert_fill_rule (GetFillRule ()));

	if (path)
		cairo_append_path (cr, &path->cairo);

	cairo_set_matrix (cr, &saved);
}
Beispiel #6
0
static bool
appendPath_func(JSContext *context,
                unsigned   argc,
                JS::Value *vp)
{
    GJS_GET_PRIV(context, argc, vp, argv, obj, GjsCairoContext, priv);
    JS::RootedObject path_wrapper(context);
    cairo_path_t *path;
    cairo_t *cr = priv ? priv->cr : NULL;

    if (!gjs_parse_call_args(context, "path", argv, "o",
                             "path", &path_wrapper))
        return false;

    path = gjs_cairo_path_get_path(context, path_wrapper);
    if (!path) {
        gjs_throw(context, "first argument to appendPath() should be a path");
        return false;
    }

    cairo_append_path(cr, path);
    argv.rval().setUndefined();
    return true;
}
Beispiel #7
0
static cairo_test_status_t
draw (cairo_t *cr, int width, int height)
{
    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
    cairo_path_t *path;
    cairo_t *cr_error;

    /* Ensure that calling cairo_copy_path on an in-error cairo_t will
     * propagate the error. */
    cr_error = cairo_create (NULL);
    path = cairo_copy_path (cr_error);
    if (path->status != CAIRO_STATUS_NULL_POINTER) {
	cairo_test_log (ctx,
			"Error: cairo_copy_path returned status of %s rather than propagating %s\n",
			cairo_status_to_string (path->status),
			cairo_status_to_string (CAIRO_STATUS_NULL_POINTER));
	cairo_path_destroy (path);
	cairo_destroy (cr_error);
	return CAIRO_TEST_FAILURE;
    }
    cairo_path_destroy (path);

    path = cairo_copy_path_flat (cr_error);
    if (path->status != CAIRO_STATUS_NULL_POINTER) {
	cairo_test_log (ctx,
			"Error: cairo_copy_path_flat returned status of %s rather than propagating %s\n",
			cairo_status_to_string (path->status),
			cairo_status_to_string (CAIRO_STATUS_NULL_POINTER));
	cairo_path_destroy (path);
	cairo_destroy (cr_error);
	return CAIRO_TEST_FAILURE;
    }
    cairo_path_destroy (path);

    cairo_destroy (cr_error);

    /* first check that we can copy an empty path */
    cairo_new_path (cr);
    path = cairo_copy_path (cr);
    if (path->status != CAIRO_STATUS_SUCCESS) {
	cairo_status_t status = path->status;
	cairo_test_log (ctx,
			"Error: cairo_copy_path returned status of %s\n",
			cairo_status_to_string (status));
	cairo_path_destroy (path);
	return cairo_test_status_from_status (ctx, status);
    }
    if (path->num_data != 0) {
	cairo_test_log (ctx,
			"Error: cairo_copy_path did not copy an empty path, returned path contains %d elements\n",
		        path->num_data);
	cairo_path_destroy (path);
	return CAIRO_TEST_FAILURE;
    }
    cairo_append_path (cr, path);
    cairo_path_destroy (path);
    if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) {
	cairo_test_log (ctx,
			"Error: cairo_append_path failed with a copy of an empty path, returned status of %s\n",
			cairo_status_to_string (cairo_status (cr)));
	return cairo_test_status_from_status (ctx, cairo_status (cr));
    }

    /* We draw in the default black, so paint white first. */
    cairo_save (cr);
    cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
    cairo_paint (cr);
    cairo_restore (cr);

    /* copy path, munge, and fill */
    cairo_translate (cr, 5, 5);
    make_path (cr);
    path = cairo_copy_path (cr);

    cairo_new_path (cr);
    munge_and_set_path (cr, path, scale_by_two);
    cairo_path_destroy (path);
    cairo_fill (cr);

    /* copy flattened path, munge, and fill */
    cairo_translate (cr, 0, 15);
    make_path (cr);
    path = cairo_copy_path_flat (cr);

    cairo_new_path (cr);
    munge_and_set_path (cr, path, scale_by_two);
    cairo_path_destroy (path);
    cairo_fill (cr);

    /* append two copies of path, and fill */
    cairo_translate (cr, 0, 15);
    cairo_scale (cr, 2.0, 2.0);
    make_path (cr);
    path = cairo_copy_path (cr);

    cairo_new_path (cr);
    cairo_append_path (cr, path);
    cairo_translate (cr, 2.5, 2.5);
    cairo_append_path (cr, path);

    cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
    cairo_fill (cr);

    cairo_path_destroy (path);

    return CAIRO_TEST_SUCCESS;
}
Beispiel #8
0
static cairo_test_status_t
preamble (cairo_test_context_t *ctx)
{
    cairo_t *cr;
    cairo_path_data_t data;
    cairo_path_t path;
    cairo_surface_t *surface;
    cairo_status_t status;

    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
    status = cairo_surface_status (surface);
    if (status) {
	cairo_surface_destroy (surface);
	return cairo_test_status_from_status (ctx, status);
    }

    /* Test a few error cases for cairo_append_path_data */
#define CAIRO_CREATE() do {\
    cr = cairo_create (surface); \
    status = cairo_status (cr); \
    if (status) { \
	cairo_destroy (cr); \
	cairo_surface_destroy (surface); \
	return cairo_test_status_from_status (ctx, status); \
    } \
} while (0)
    CAIRO_CREATE ();
    cairo_append_path (cr, NULL);
    status = cairo_status (cr);
    cairo_destroy (cr);
    if (status != CAIRO_STATUS_NULL_POINTER) {
	cairo_surface_destroy (surface);
	return cairo_test_status_from_status (ctx, status);
    }

    CAIRO_CREATE ();
    path.status = -1;
    cairo_append_path (cr, &path);
    status = cairo_status (cr);
    cairo_destroy (cr);
    if (status != CAIRO_STATUS_INVALID_STATUS) {
	cairo_surface_destroy (surface);
	return cairo_test_status_from_status (ctx, status);
    }

    CAIRO_CREATE ();
    path.status = CAIRO_STATUS_NO_MEMORY;
    cairo_append_path (cr, &path);
    status = cairo_status (cr);
    cairo_destroy (cr);
    if (status != CAIRO_STATUS_NO_MEMORY) {
	cairo_surface_destroy (surface);
	return cairo_test_status_from_status (ctx, status);
    }

    CAIRO_CREATE ();
    path.data = NULL;
    path.num_data = 0;
    path.status = CAIRO_STATUS_SUCCESS;
    cairo_append_path (cr, &path);
    status = cairo_status (cr);
    cairo_destroy (cr);
    if (status != CAIRO_STATUS_SUCCESS) {
	cairo_surface_destroy (surface);
	return cairo_test_status_from_status (ctx, status);
    }

    CAIRO_CREATE ();
    path.data = NULL;
    path.num_data = 1;
    path.status = CAIRO_STATUS_SUCCESS;
    cairo_append_path (cr, &path);
    status = cairo_status (cr);
    cairo_destroy (cr);
    if (status != CAIRO_STATUS_NULL_POINTER) {
	cairo_surface_destroy (surface);
	return cairo_test_status_from_status (ctx, status);
    }

    CAIRO_CREATE ();
    /* Intentionally insert bogus header.length value (otherwise would be 2) */
    data.header.type = CAIRO_PATH_MOVE_TO;
    data.header.length = 1;
    path.data = &data;
    path.num_data = 1;
    cairo_append_path (cr, &path);
    status = cairo_status (cr);
    cairo_destroy (cr);
    if (status != CAIRO_STATUS_INVALID_PATH_DATA) {
	cairo_surface_destroy (surface);
	return cairo_test_status_from_status (ctx, status);
    }

    /* And test the degnerate case */
    CAIRO_CREATE ();
    path.num_data = 0;
    cairo_append_path (cr, &path);
    status = cairo_status (cr);
    cairo_destroy (cr);
    if (status != CAIRO_STATUS_SUCCESS) {
	cairo_surface_destroy (surface);
	return cairo_test_status_from_status (ctx, status);
    }

    cairo_surface_destroy (surface);

    return CAIRO_TEST_SUCCESS;
}
/*! \private
 *  \brief Render the swatch into the cell
 *
 *  \param [in] cell this cell renderer
 *  \param [in] window the window to renter to
 *  \param [in] widget the widget owning the window
 *  \param [in] background_area entire cell area
 *  \param [in] cell_area area rendered normally
 *  \param [in] expose_area the area requiring update
 *  \param [in] flags
 */
static void
render (GtkCellRenderer      *cell,
        GdkWindow            *window,
        GtkWidget            *widget,
        GdkRectangle         *background_area,
        GdkRectangle         *cell_area,
        GdkRectangle         *expose_area,
        GtkCellRendererState flags)
{
  GschemFillSwatchCellRenderer *swatch = GSCHEM_FILL_SWATCH_CELL_RENDERER (cell);

  if (swatch->enabled) {
    GdkColor color;
    cairo_t *cr = gdk_cairo_create (window);
    double offset = SWATCH_BORDER_WIDTH / 2.0;
    gboolean success;

    if (expose_area) {
      gdk_cairo_rectangle (cr, expose_area);
      cairo_clip (cr);
    }

    /* Paint the swatch using the text color to match the user's desktop theme.
     */

    success = gtk_style_lookup_color (gtk_widget_get_style (widget),
                                      "text_color",
                                      &color);

    if (success) {
      cairo_set_source_rgb (cr,
                            color.red   / 65535.0,
                            color.green / 65535.0,
                            color.blue  / 65535.0);
    }

    cairo_move_to (cr,
                   (double) cell_area->x + offset,
                   (double) cell_area->y + offset);

    cairo_line_to (cr,
                   (double) cell_area->x + (double) cell_area->width - offset,
                   (double) cell_area->y + offset);

    cairo_line_to (cr,
                   (double) cell_area->x + (double) cell_area->width - offset,
                   (double) cell_area->y + (double) cell_area->height - offset);

    cairo_line_to (cr,
                   (double) cell_area->x + offset,
                   (double) cell_area->y + (double) cell_area->height - offset);

    cairo_close_path (cr);

    if ((swatch->fill_type == FILLING_HATCH) || (swatch->fill_type == FILLING_MESH)) {
      BOX box;
      int index;
      GArray *lines = g_array_new (FALSE, FALSE, sizeof (LINE));
      cairo_path_t *save_path = cairo_copy_path (cr);

      cairo_save (cr);
      cairo_clip (cr);

      box.lower_x = cell_area->x;
      box.lower_y = cell_area->y;
      box.upper_x = cell_area->x + cell_area->width;
      box.upper_y = cell_area->y + cell_area->height;

      m_hatch_box (&box, 135, SWATCH_LINE_PITCH, lines);

      if (swatch->fill_type == FILLING_MESH) {
        m_hatch_box (&box, 45, SWATCH_LINE_PITCH, lines);
      }

      for (index=0; index<lines->len; index++) {
        LINE *line = &g_array_index (lines, LINE, index);

        cairo_move_to (cr, line->x[0], line->y[0]);
        cairo_line_to (cr, line->x[1], line->y[1]);
      }

      g_array_free (lines, TRUE);

      cairo_set_line_width (cr, SWATCH_LINE_WIDTH);
      cairo_stroke (cr);
      cairo_restore (cr);

      cairo_append_path (cr, save_path);
      cairo_path_destroy (save_path);
    }

    if (swatch->fill_type == FILLING_FILL) {
      cairo_fill_preserve (cr);
    }

    cairo_set_line_width (cr, SWATCH_BORDER_WIDTH);
    cairo_stroke (cr);
    cairo_destroy (cr);
  }
}
static void
render (GtkWidget * widget)
{
  GSMColorButton *color_button = GSM_COLOR_BUTTON (widget);
  GdkColor *color, tmp_color = color_button->priv->color;
  color = &tmp_color;
  cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (widget));
  cairo_path_t *path = NULL;
  gint width, height;
  gdouble radius, arc_start, arc_end;
  gint highlight_factor;

  if (color_button->priv->highlight > 0) {
    highlight_factor = 8192 * color_button->priv->highlight;

    if (color->red + highlight_factor > 65535) 
      color->red = 65535;
    else
      color->red = color->red + highlight_factor;
    
    if (color->blue + highlight_factor > 65535) 
      color->blue = 65535;
    else
      color->blue = color->blue + highlight_factor;
    
    if (color->green + highlight_factor > 65535) 
      color->green = 65535;
    else
      color->green = color->green + highlight_factor;
  }
  gdk_cairo_set_source_color (cr, color);
  gdk_drawable_get_size (gtk_widget_get_window (widget), &width, &height);

  switch (color_button->priv->type)
    {
    case GSMCP_TYPE_CPU:
      //gtk_widget_set_size_request (widget, GSMCP_MIN_WIDTH, GSMCP_MIN_HEIGHT);
      cairo_paint (cr);
      cairo_set_line_width (cr, 1);
      cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
      cairo_rectangle (cr, 0.5, 0.5, width - 1, height - 1);
      cairo_stroke (cr);
      cairo_set_line_width (cr, 1);
      cairo_set_source_rgba (cr, 1, 1, 1, 0.4);
      cairo_rectangle (cr, 1.5, 1.5, width - 3, height - 3);
      cairo_stroke (cr);
      break;
    case GSMCP_TYPE_PIE:
      if (width < 32)		// 32px minimum size
	gtk_widget_set_size_request (widget, 32, 32);
      if (width < height)
	radius = width / 2;
      else
	radius = height / 2;

      arc_start = -G_PI_2 + 2 * G_PI * color_button->priv->fraction;
      arc_end = -G_PI_2;

      cairo_set_line_width (cr, 1);
      
      // Draw external stroke and fill
      if (color_button->priv->fraction < 0.01) {
        cairo_arc (cr, (width / 2) + .5, (height / 2) + .5, 4.5,
		   0, 2 * G_PI);
      } else if (color_button->priv->fraction > 0.99) { 
        cairo_arc (cr, (width / 2) + .5, (height / 2) + .5, radius - 2.25,
		   0, 2 * G_PI);
      } else {
        cairo_arc_negative (cr, (width / 2) + .5, (height / 2) + .5, radius - 2.25,
		   arc_start, arc_end);
        cairo_arc_negative (cr, (width / 2) + .5, (height / 2) + .5, 4.5,
		   arc_end, arc_start);
        cairo_arc_negative (cr, (width / 2) + .5, (height / 2) + .5, radius - 2.25,
		   arc_start, arc_start);
      }
      cairo_fill_preserve (cr);
      cairo_set_source_rgba (cr, 0, 0, 0, 0.7);
      cairo_stroke (cr);

      // Draw internal highlight
      cairo_set_source_rgba (cr, 1, 1, 1, 0.45);
      cairo_set_line_width (cr, 1);

      if (color_button->priv->fraction < 0.03) {
        cairo_arc (cr, (width / 2) + .5, (height / 2) + .5, 3.25,
			    0, 2 * G_PI);
      } else if (color_button->priv->fraction > 0.99) {
        cairo_arc (cr, (width / 2) + .5, (height / 2) + .5, radius - 3.5,
			    0, 2 * G_PI);
      } else {
        cairo_arc_negative (cr, (width / 2) + .5, (height / 2) + .5, radius - 3.5,
		 arc_start + (1 / (radius - 3.75)), 
		 arc_end - (1 / (radius - 3.75)));
        cairo_arc_negative (cr, (width / 2) + .5, (height / 2) + .5, 3.25,
		   arc_end - (1 / (radius - 3.75)),
                   arc_start + (1 / (radius - 3.75)));
        cairo_arc_negative (cr, (width / 2) + .5, (height / 2) + .5, radius - 3.5,
		 arc_start + (1 / (radius - 3.75)), 
		 arc_start + (1 / (radius - 3.75)));
      }
      cairo_stroke (cr);

      // Draw external shape
      cairo_set_line_width (cr, 1);
      cairo_set_source_rgba (cr, 0, 0, 0, 0.2);
      cairo_arc (cr, (width / 2) + .5, (height / 2) + .5, radius - 1.25, 0,
		 G_PI * 2);
      cairo_stroke (cr);

      break;
    case GSMCP_TYPE_NETWORK_IN:
      if (color_button->priv->image_buffer == NULL)
	color_button->priv->image_buffer =
	  fill_image_buffer_from_file (cr, DATADIR "/pixmaps/gnome-system-monitor/download.svg");
      gtk_widget_set_size_request (widget, 32, 32);
      cairo_move_to (cr, 8.5, 1.5);
      cairo_line_to (cr, 23.5, 1.5);
      cairo_line_to (cr, 23.5, 11.5);
      cairo_line_to (cr, 29.5, 11.5);
      cairo_line_to (cr, 16.5, 27.5);
      cairo_line_to (cr, 15.5, 27.5);
      cairo_line_to (cr, 2.5, 11.5);
      cairo_line_to (cr, 8.5, 11.5);
      cairo_line_to (cr, 8.5, 1.5);
      cairo_close_path (cr);
      path = cairo_copy_path (cr);
      cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
      cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
      cairo_set_line_width (cr, 1);
      cairo_fill_preserve (cr);
      cairo_set_miter_limit (cr, 5.0);
      cairo_stroke (cr);
      cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
      cairo_append_path (cr, path);
      cairo_path_destroy(path);
      cairo_stroke (cr);
      cairo_set_source_surface (cr, color_button->priv->image_buffer, 0.0,
				0.0);
      cairo_paint (cr);

      break;
    case GSMCP_TYPE_NETWORK_OUT:
      if (color_button->priv->image_buffer == NULL)
	color_button->priv->image_buffer =
	  fill_image_buffer_from_file (cr, DATADIR "/pixmaps/gnome-system-monitor/upload.svg");
      gtk_widget_set_size_request (widget, 32, 32);
      cairo_move_to (cr, 16.5, 1.5);
      cairo_line_to (cr, 29.5, 17.5);
      cairo_line_to (cr, 23.5, 17.5);
      cairo_line_to (cr, 23.5, 27.5);
      cairo_line_to (cr, 8.5, 27.5);
      cairo_line_to (cr, 8.5, 17.5);
      cairo_line_to (cr, 2.5, 17.5);
      cairo_line_to (cr, 15.5, 1.5);
      cairo_line_to (cr, 16.5, 1.5);
      cairo_close_path (cr);
      path = cairo_copy_path (cr);
      cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
      cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
      cairo_set_line_width (cr, 1);
      cairo_fill_preserve (cr);
      cairo_set_miter_limit (cr, 5.0);
      cairo_stroke (cr);
      cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
      cairo_append_path (cr, path);
      cairo_path_destroy(path);
      cairo_stroke (cr);
      cairo_set_source_surface (cr, color_button->priv->image_buffer, 0.0,
				0.0);
      cairo_paint (cr);

      break;
    }
  cairo_destroy (cr);
}
Beispiel #11
0
void appendPathToCairoContext(cairo_t* to, cairo_t* from)
{
    OwnPtr<cairo_path_t> cairoPath = adoptPtr(cairo_copy_path(from));
    cairo_append_path(to, cairoPath.get());
}
Beispiel #12
0
static cairo_test_status_t
draw (cairo_t *cr, int width, int height)
{
    cairo_path_data_t path_data[] = {
	{ { CAIRO_PATH_MOVE_TO, 2 }, },
	{ { 95.000000, 40.000000 }, },

	{ { CAIRO_PATH_LINE_TO, 2 }, },
	{ { 94.960533, 41.255810 }, },

	{ { CAIRO_PATH_LINE_TO, 2 }, },
	{ { 94.842293, 42.50666 }, },

	{ { CAIRO_PATH_LINE_TO, 2 }, },
	{ { 94.645744, 43.747627 }, },

	{ { CAIRO_PATH_LINE_TO, 2 }, },
	{ { 94.371666, 44.973797 }, },
    };
    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
    cairo_path_t path, *path_copy;
    int i, j, n;
    cairo_test_status_t result = CAIRO_TEST_SUCCESS;

    path.status = CAIRO_STATUS_SUCCESS;
    path.num_data = sizeof (path_data) / sizeof (path_data[0]);
    path.data = path_data;

    cairo_new_path (cr);
    cairo_append_path (cr, &path);
    path_copy = cairo_copy_path (cr);

    if (path_copy->status)
	return cairo_test_status_from_status (ctx, path_copy->status);

    for (i = j = n = 0;
	 i < path.num_data && j < path_copy->num_data;
	 i += path.data[i].header.length,
	 j += path_copy->data[j].header.length,
	 n++)
    {
	const cairo_path_data_t *src, *dst;

	src = &path.data[i];
	dst = &path_copy->data[j];

	if (src->header.type != dst->header.type) {
	    cairo_test_log (ctx,
			    "Paths differ in header type after %d operations.\n"
			    "Expected path operation %d, found %d.\n",
			    n, src->header.type, dst->header.type);
	    result = FAIL;
	    break;
	}

	if (memcmp (&src[1].point, &dst[1].point, sizeof (src->point))) {
	    cairo_test_log (ctx,
			    "Paths differ in coordinates after %d operations.\n"
			    "Expected point (%f, %f), found (%f, %f).\n",
			    n,
			    src[1].point.x, src[1].point.y,
			    dst[1].point.x, dst[1].point.y);
	    result = FAIL;
	    break;
	}
    }

    cairo_path_destroy (path_copy);
    return result;
}
Beispiel #13
0
/**
 * gimp_scan_convert_render_full:
 * @sc:        a #GimpScanConvert context
 * @buffer:    the #GeglBuffer to render to
 * @off_x:     horizontal offset into the @buffer
 * @off_y:     vertical offset into the @buffer
 * @replace:   if true the original content of the @buffer gets estroyed
 * @antialias: if true the rendering happens antialiased
 * @value:     value to use for covered pixels
 *
 * This function renders the area described by the path to the
 * @buffer, taking the offset @off_x and @off_y in the buffer into
 * account.  The rendering can happen antialiased and be rendered on
 * top of existing content or replacing it completely. The @value
 * specifies the opacity value to be used for the objects in the @sc.
 *
 * You cannot add additional polygons after this command.
 */
void
gimp_scan_convert_render_full (GimpScanConvert *sc,
                               GeglBuffer      *buffer,
                               gint             off_x,
                               gint             off_y,
                               gboolean         replace,
                               gboolean         antialias,
                               gdouble          value)
{
  const Babl         *format;
  GeglBufferIterator *iter;
  GeglRectangle      *roi;
  cairo_t            *cr;
  cairo_surface_t    *surface;
  cairo_path_t        path;
  gint                bpp;
  gint                x, y;
  gint                width, height;

  g_return_if_fail (sc != NULL);
  g_return_if_fail (GEGL_IS_BUFFER (buffer));

  x      = 0;
  y      = 0;
  width  = gegl_buffer_get_width  (buffer);
  height = gegl_buffer_get_height (buffer);

  if (sc->clip && ! gimp_rectangle_intersect (x, y, width, height,
                                              sc->clip_x, sc->clip_y,
                                              sc->clip_w, sc->clip_h,
                                              &x, &y, &width, &height))
    return;

  path.status   = CAIRO_STATUS_SUCCESS;
  path.data     = (cairo_path_data_t *) sc->path_data->data;
  path.num_data = sc->path_data->len;

  format = babl_format ("Y u8");
  bpp    = babl_format_get_bytes_per_pixel (format);

  iter = gegl_buffer_iterator_new (buffer, NULL, 0, format,
                                   GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE);
  roi = &iter->roi[0];

  while (gegl_buffer_iterator_next (iter))
    {
      guchar     *data    = iter->data[0];
      guchar     *tmp_buf = NULL;
      const gint  stride  = cairo_format_stride_for_width (CAIRO_FORMAT_A8,
                                                           roi->width);

      /*  cairo rowstrides are always multiples of 4, whereas
       *  maskPR.rowstride can be anything, so to be able to create an
       *  image surface, we maybe have to create our own temporary
       *  buffer
       */
      if (roi->width * bpp != stride)
        {
          tmp_buf = g_alloca (stride * roi->height);

          if (! replace)
            {
              const guchar *src  = data;
              guchar       *dest = tmp_buf;
              gint          i;

              for (i = 0; i < roi->height; i++)
                {
                  memcpy (dest, src, roi->width * bpp);

                  src  += roi->width * bpp;
                  dest += stride;
                }
            }
        }

      surface = cairo_image_surface_create_for_data (tmp_buf ?
                                                     tmp_buf : data,
                                                     CAIRO_FORMAT_A8,
                                                     roi->width, roi->height,
                                                     stride);

      cairo_surface_set_device_offset (surface,
                                       -off_x - roi->x,
                                       -off_y - roi->y);
      cr = cairo_create (surface);
      cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);

      if (replace)
        {
          cairo_set_source_rgba (cr, 0, 0, 0, 0);
          cairo_paint (cr);
        }

      cairo_set_source_rgba (cr, 0, 0, 0, value);
      cairo_append_path (cr, &path);

      cairo_set_antialias (cr, antialias ?
                           CAIRO_ANTIALIAS_GRAY : CAIRO_ANTIALIAS_NONE);
      cairo_set_miter_limit (cr, sc->miter);

      if (sc->do_stroke)
        {
          cairo_set_line_cap (cr,
                              sc->cap == GIMP_CAP_BUTT ? CAIRO_LINE_CAP_BUTT :
                              sc->cap == GIMP_CAP_ROUND ? CAIRO_LINE_CAP_ROUND :
                              CAIRO_LINE_CAP_SQUARE);
          cairo_set_line_join (cr,
                               sc->join == GIMP_JOIN_MITER ? CAIRO_LINE_JOIN_MITER :
                               sc->join == GIMP_JOIN_ROUND ? CAIRO_LINE_JOIN_ROUND :
                               CAIRO_LINE_JOIN_BEVEL);

          cairo_set_line_width (cr, sc->width);

          if (sc->dash_info)
            cairo_set_dash (cr,
                            (double *) sc->dash_info->data,
                            sc->dash_info->len,
                            sc->dash_offset);

          cairo_scale (cr, 1.0, sc->ratio_xy);
          cairo_stroke (cr);
        }
      else
        {
          cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
          cairo_fill (cr);
        }

      cairo_destroy (cr);
      cairo_surface_destroy (surface);

      if (tmp_buf)
        {
          const guchar *src  = tmp_buf;
          guchar       *dest = data;
          gint          i;

          for (i = 0; i < roi->height; i++)
            {
              memcpy (dest, src, roi->width * bpp);

              src  += stride;
              dest += roi->width * bpp;
            }
        }
    }
}
Beispiel #14
0
void gfxContext::AppendPath(gfxPath* path)
{
    if (path->mPath->status == CAIRO_STATUS_SUCCESS && path->mPath->num_data != 0)
        cairo_append_path(mCairo, path->mPath);
}
svg_status_t _svg_android_set_pattern (svg_android_t *svg_android,
			  svg_element_t *pattern_element,
			  svg_android_render_type_t type)
{
	svg_pattern_t *pattern = svg_element_pattern (pattern_element);
	jobject pattern_bitmap;
	jobject pattern_shader;
	double x_px, y_px, width_px, height_px;
	jobject path;

	_svg_android_length_to_pixel (svg_android, &pattern->x, &x_px);
	_svg_android_length_to_pixel (svg_android, &pattern->y, &y_px);
	_svg_android_length_to_pixel (svg_android, &pattern->width, &width_px);
	_svg_android_length_to_pixel (svg_android, &pattern->height, &height_px);

	/* OK. We've got the final path to be filled/stroked inside the
	 * android context right now. But we're also going to re-use that
	 * same context to draw the pattern. And since the path is no
	 * longer in the graphics state, android_save/restore will not help
	 * us here.
	 *
	 * Currently we deal with this by manually saving/restoring the
	 * path.
	 *
	 * It might be simpler to just use a new cairo_t for drawing the
	 * pattern.
	 */
	path = svg_android->state->path; //cairo_copy_path (svg_android->cr);
	svg_android->state->path = ANDROID_PATH_CREATE(svg_android); // cairo_new_path (svg_android->cr);
	ANDROID_SAVE(svg_android);

	pattern_bitmap = ANDROID_CREATE_BITMAP(svg_android,
					       (int) (width_px + 0.5),
					       (int) (height_px + 0.5));
#if 0
	pattern_surface = cairo_surface_create_similar (cairo_get_target (svg_android->cr),
							CAIRO_FORMAT_ARGB32,
							(int) (width_px + 0.5),
							(int) (height_px + 0.5));
#endif
	
	_svg_android_push_state (svg_android, pattern_bitmap);

	svg_android->state->matrix = ANDROID_IDENTITY_MATRIX(svg_android);
	//cairo_identity_matrix (svg_android->cr);
    
	svg_android->state->fill_paint.type = SVG_PAINT_TYPE_NONE;
	svg_android->state->stroke_paint.type = SVG_PAINT_TYPE_NONE;
    
	svg_element_render (pattern->group_element, &SVG_ANDROID_RENDER_ENGINE, svg_android);
	_svg_android_pop_state (svg_android);

	ANDROID_RESTORE(svg_android);

	svg_android->state->path = path ;
#if 0
	cairo_new_path (svg_android->cr);
	cairo_append_path (svg_android->cr, path);
	cairo_path_destroy (path);
#endif

	pattern_shader = ANDROID_CREATE_BITMAP_SHADER(svg_android, pattern_bitmap);
	ANDROID_PAINT_SET_SHADER(svg_android, pattern_shader);

#if 0
	surface_pattern = cairo_pattern_create_for_surface (pattern_surface);
	cairo_surface_destroy (pattern_surface);
    
	cairo_pattern_set_extend (surface_pattern, CAIRO_EXTEND_REPEAT);
    
	cairo_set_source (svg_android->cr, surface_pattern);
    
	cairo_pattern_destroy (surface_pattern);
#endif
	
	return SVG_STATUS_SUCCESS;
}
Beispiel #16
0
gboolean draw_callback
(GtkWidget *widget, GdkEventExpose *event, UNUSED gpointer data)
{
	guint width, height;
	cairo_pattern_t *color;
	cairo_path_t *bolt, *fill, *text;

	// Grab our widget size
	width = widget->allocation.width;
	height = widget->allocation.height;

	// Set up Cairo
	cairo_t *cr = gdk_cairo_create(widget->window);

	cairo_set_antialias(cr, CAIRO_ANTIALIAS_BEST);

	// Clear canvas
	#ifdef BACKGROUND_FILL_ENTIRE_WIDGET
	cairo_rectangle(cr, 0, 0, width, height);
	#else
	cairo_rectangle(cr, (MARGIN / 2) + STROKE_WIDTH, (MARGIN / 2) + STROKE_WIDTH, BATTERY_WIDTH, BATTERY_HEIGHT);
	#endif
	cairo_set_source_rgba(cr, COLOR_BACKGROUND, OPACITY_BACKGROUND);
	cairo_fill(cr);

	// Decide on a color
	color = cairo_pattern_create_rgb(COLOR_DEFAULT);
	if (battery_get_charging())
		color = cairo_pattern_create_rgb(COLOR_CHARGING);
	if (battery_get_critical())
		color = cairo_pattern_create_rgb(COLOR_CRITICAL);

	battery_border_draw(cr, color, (int)CENTERED(width, BATTERY_WIDTH),
	                               (int)CENTERED(height, BATTERY_HEIGHT),
	                               BATTERY_WIDTH,
	                               BATTERY_HEIGHT,
	                               STROKE_WIDTH,
	                               PEG_WIDTH,
	                               PEG_HEIGHT);


	int fill_x = CENTERED(width, BATTERY_WIDTH);
	int fill_y = CENTERED(height, BATTERY_HEIGHT);

	// Set fill style
	cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);

	// Generate battery fill
	fill = battery_fill_generate(BATTERY_WIDTH, BATTERY_HEIGHT, battery_get_percent());
	cairo_translate(cr, fill_x, fill_y);
	cairo_append_path(cr, fill);

	if (battery_get_charging()) {
		int bolt_x = CENTERED(BATTERY_WIDTH, BOLT_WIDTH);
		int bolt_y = CENTERED(BATTERY_HEIGHT, BOLT_HEIGHT);

		cairo_translate(cr, bolt_x, bolt_y);
		bolt = battery_bolt_generate(BOLT_WIDTH, BOLT_HEIGHT);
		cairo_append_path(cr, bolt);
		cairo_translate(cr, bolt_x, bolt_y);
	} else {
		cairo_text_extents_t extents;
		char strpercent[5];
		snprintf(strpercent, 5, "%i%%", (int)(battery_get_percent() * 100));

		cairo_select_font_face(cr, FONT_FACE, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
		cairo_set_font_size(cr, FONT_SIZE);
		cairo_text_extents(cr, strpercent, &extents);

		int text_x = CENTERED(BATTERY_WIDTH, extents.width);
		int text_y = CENTERED(BATTERY_HEIGHT,  extents.height + extents.y_bearing*2);

		text = battery_text_generate(strpercent, FONT_FACE, FONT_SIZE);

		cairo_translate(cr, text_x, text_y);
		cairo_append_path(cr, text);
		cairo_translate(cr, -text_x, -text_y);
	}
	cairo_translate(cr, -fill_x, -fill_y);

	cairo_set_source(cr, color);
	cairo_fill(cr);

	return FALSE;
}