Example #1
0
void
eda_cairo_arc (cairo_t *cr, int flags,
               double width, double x, double y,
               double radius, double start_angle, double sweep_angle)
{
  int s_width;
  double x1, y1, x2, y2;
  double s_x, s_y, s_radius;
  double offset, dummy = 0;

  if (!(flags & EDA_CAIRO_ENABLE_HINTS)) {
    do_arc (cr, x, y, radius, start_angle, sweep_angle);
    return;
  }

  WORLDtoSCREEN (cr, x - radius, y + radius, &x1, &y1);
  WORLDtoSCREEN (cr, x + radius, y - radius, &x2, &y2);
  s_width = screen_width (cr, width);
  offset = ((s_width % 2) == 0) ? 0 : 0.5;

  s_x = (double)(x1 + x2) / 2.;
  s_y = (double)(y1 + y2) / 2.;
  s_radius = (double)(y2 - y1) / 2.;

  cairo_device_to_user (cr, &s_x, &s_y);
  cairo_device_to_user_distance (cr, &offset, &dummy);
  cairo_device_to_user_distance (cr, &s_radius, &dummy);

  do_arc (cr, s_x + offset, s_y + offset,
          s_radius, start_angle, sweep_angle);
}
Example #2
0
gfxRect gfxContext::DeviceToUser(gfxRect rect) const
{
    gfxRect ret = rect;
    cairo_device_to_user(mCairo, &ret.pos.x, &ret.pos.y);
    cairo_device_to_user_distance(mCairo, &ret.size.width, &ret.size.height);
    return ret;
}
Example #3
0
static void
fill_pixel_rect(DiaRenderer *object,
		int x, int y,
		int width, int height,
		Color *color)
{
#if 1 /* if we do it with cairo there is something wrong with the clipping? */
  DiaCairoInteractiveRenderer *renderer = DIA_CAIRO_INTERACTIVE_RENDERER (object);
  GdkGC *gc = renderer->gc;
  GdkColor gdkcolor;
    
  color_convert(color, &gdkcolor);
  gdk_gc_set_foreground(gc, &gdkcolor);

  gdk_draw_rectangle (renderer->pixmap, gc, TRUE,
		      x, y,  width, height);
#else
  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (object);
  double x1u = x + .5, y1u = y + .5, x2u = x + width + .5, y2u = y + height + .5;
  double lw[2];
  lw[0] = 1; lw[1] = 0;
  
  cairo_device_to_user_distance (renderer->cr, &lw[0], &lw[1]);
  cairo_set_line_width (renderer->cr, lw[0]);

  cairo_device_to_user (renderer->cr, &x1u, &y1u);
  cairo_device_to_user (renderer->cr, &x2u, &y2u);

  cairo_set_source_rgba (renderer->cr, color->red, color->green, color->blue, 1.0);
  cairo_rectangle (renderer->cr, x1u, y1u, x2u - x1u, y2u - y1u);
  cairo_fill (renderer->cr);
#endif
}
Example #4
0
gfxSize
gfxContext::DeviceToUser(const gfxSize& size) const
{
    gfxSize ret = size;
    cairo_device_to_user_distance(mCairo, &ret.width, &ret.height);
    return ret;
}
Example #5
0
static int
cr_device_to_user_distance (lua_State *L) {
    cairo_t **obj = luaL_checkudata(L, 1, OOCAIRO_MT_NAME_CONTEXT);
    double x = luaL_checknumber(L, 2), y = luaL_checknumber(L, 3);
    cairo_device_to_user_distance(*obj, &x, &y);
    lua_pushnumber(L, x);
    lua_pushnumber(L, y);
    return 2;
}
Example #6
0
CAMLprim value
ml_cairo_device_to_user_distance (value cr, value p)
{
  double x, y;
  x = Double_field (p, 0);
  y = Double_field (p, 1);
  cairo_device_to_user_distance (cairo_t_val (cr), &x, &y);
  check_cairo_status (cr);
  return ml_cairo_point (x, y);
}
static VALUE
cr_device_to_user_distance (VALUE self, VALUE dx, VALUE dy)
{
  double pair[2];
  pair[0] = NUM2DBL (dx);
  pair[1] = NUM2DBL (dy);
  cairo_device_to_user_distance (_SELF, pair, pair + 1);
  cr_check_status (_SELF);
  return rb_cairo__float_array (pair, 2);
}
Example #8
0
/*!
 * \brief Ensure a minimum of one device unit
 * Dia as well as many other drawing applications/libraries is using a
 * line with 0f 0.0 tho mean hairline. Cairo doe not have this capability
 * so this functions should be used to get the thinnest line possible.
 * \protected \memberof _DiaCairoRenderer
 */
static void
ensure_minimum_one_device_unit(DiaCairoRenderer *renderer, real *value)
{
  double ax = 1., ay = 1.;

  cairo_device_to_user_distance (renderer->cr, &ax, &ay);

  ax = MAX(ax, ay);
  if (*value < ax)
      *value = ax;
}
 ///maps back to user distance before stoking.
 void scaled_stroke(cairo_t *cr)
 {
   double xwise = 1;
   double ywise = 1;
   cairo_save(cr);
   cairo_device_to_user_distance (cr,&xwise,&ywise);
   
   cairo_scale(cr,xwise,ywise);
   cairo_stroke(cr);
   cairo_restore(cr);
 }
Example #10
0
static PyObject *
pycairo_device_to_user_distance (PycairoContext *o, PyObject *args) {
  double dx, dy;

  if (!PyArg_ParseTuple (args, "dd:Context.device_to_user_distance",
			 &dx, &dy))
    return NULL;

  cairo_device_to_user_distance (o->ctx, &dx, &dy);
  RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
  return Py_BuildValue("(dd)", dx, dy);
}
Example #11
0
static void
set_linewidth(DiaRenderer *self, real linewidth)
{  
  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);

  DIAG_NOTE(g_message("set_linewidth %f", linewidth));

  /* make hairline? */
  if (linewidth == 0.0) {
    double ax = 0.0, ay = 0.0;
    double bx = 1.0, by = 0.0;    
    
    cairo_device_to_user_distance (renderer->cr, &ax, &ay);
    cairo_device_to_user_distance (renderer->cr, &bx, &by);
    
    linewidth = sqrt ((bx - ax) * (bx - ax) + (by - ay) * (by - ay));
  }

  cairo_set_line_width (renderer->cr, linewidth);
  DIAG_STATE(renderer->cr)
}
Example #12
0
void
eda_cairo_center_arc (cairo_t *cr, int flags,
                      double center_width,
                      double line_width, double x, double y,
                      double radius, double start_angle, double sweep_angle)
{
  int s_center_width, s_line_width;
  double s_x, s_y, dummy = 0;
  int s_diameter;
  double even_center_width;
  double even_line_width;
  double even_diameter;
  double center_offset;
  double s_radius;
  int do_radius_hint = TRUE;

  if (!(flags & EDA_CAIRO_ENABLE_HINTS)) {
    do_arc (cr, x, y, radius, start_angle, sweep_angle);
    return;
  }

  WORLDtoSCREEN (cr, x, y, &s_x, &s_y);
  s_diameter = SCREENabs (cr, 2 * radius);
  even_diameter = ((s_diameter % 2) == 0);
  s_radius = (double) s_diameter / 2.;

  /* Switch off radius hinting for small radii. If we don't, then we get
   * a very abrupt transition once the arc reaches a single pixel size. */
  if (s_radius <= 1.) do_radius_hint = FALSE;

  /* Hint the center of the arc based on where a line
   * of thickness center_width (world) would drawn */
  s_center_width = screen_width (cr, center_width);
  even_center_width = (center_width == -1 || (s_center_width % 2) == 0);
  center_offset = even_center_width ? 0. : 0.5;

  /* Hint the radius to land its extermity on the pixel grid */
  s_line_width = screen_width (cr, line_width);
  even_line_width = (line_width == -1 || (s_line_width % 2) == 0);
  if (do_radius_hint)
    s_radius += ((even_center_width ==
                        even_line_width) == even_diameter) ? 0. : 0.5;

  s_x += center_offset;
  s_y += center_offset;
  cairo_device_to_user (cr, &s_x, &s_y);
  cairo_device_to_user_distance (cr, &s_radius, &dummy);

  do_arc (cr, s_x, s_y, s_radius, start_angle, sweep_angle);
}
static PyObject *
pycairo_device_to_user_distance (PycairoContext *o, PyObject *args)
{
    double dx, dy;

    if (!PyArg_ParseTuple (args, "dd:Context.device_to_user_distance",
			   &dx, &dy))
	return NULL;

    cairo_device_to_user_distance (o->ctx, &dx, &dy);
    if (Pycairo_Check_Status (cairo_status (o->ctx)))
	return NULL;
    return Py_BuildValue("(dd)", dx, dy);
}
Example #14
0
/** Draw the rectangle _centered_ at current Cairo coordinates.
  @param width	Width of the rectangle.
  @param height	Height of the rectangle.
  @param pixelOutput	Round width and height to pixels.
 */
static void
gerbv_draw_rectangle(cairo_t *cairoTarget, gdouble width, gdouble height,
			gboolean pixelOutput)
{
	if (pixelOutput) {
		cairo_user_to_device_distance (cairoTarget, &width, &height);
		width  -= (int)round(width)  % 2;
		height -= (int)round(height) % 2;
		cairo_device_to_user_distance (cairoTarget, &width, &height);
	}

	cairo_rectangle (cairoTarget, -width/2.0, -height/2.0, width, height);

	return;
}
  ///maps to user distance before displaying text
  void scaled_show_text (cairo_t *cr, const char* s, float size=-1.)
  {
    double xwise = 1;
    double ywise = 1;
    cairo_save(cr);

    if (size > 0)
      cairo_set_font_size(cr, size);

    cairo_device_to_user_distance (cr, &xwise, &ywise);
   
    cairo_scale(cr,xwise,ywise);
    cairo_show_text (cr, s );
    cairo_restore(cr);
  }
Example #16
0
void
lsm_cairo_box_device_to_user (cairo_t *cairo, LsmBox *to, const LsmBox *from)
{
	if (to == NULL)
		return;

	if (from == NULL || cairo == NULL) {
		to->x = 0;
		to->y = 0;
		to->width = 0;
		to->height = 0;
	}

	*to = *from;

	cairo_device_to_user (cairo, &to->x, &to->y);
	cairo_device_to_user_distance (cairo, &to->width, &to->height);
}
Example #17
0
static void
draw_pixel_rect(DiaRenderer *object,
		int x, int y,
		int width, int height,
		Color *color)
{
  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (object);
  double x1u = x + .5, y1u = y + .5, x2u = x + width + .5, y2u = y + height + .5;
  double lw[2];
  lw[0] = 1; lw[1] = 0;
  
  cairo_device_to_user_distance (renderer->cr, &lw[0], &lw[1]);
  cairo_set_line_width (renderer->cr, lw[0]);

  cairo_device_to_user (renderer->cr, &x1u, &y1u);
  cairo_device_to_user (renderer->cr, &x2u, &y2u);

  cairo_set_source_rgba (renderer->cr, color->red, color->green, color->blue, 1.0);
  cairo_rectangle (renderer->cr, x1u, y1u, x2u - x1u, y2u - y1u);
  cairo_stroke (renderer->cr);
}
Example #18
0
static void
draw_pixel_line(DiaRenderer *object,
		int x1, int y1,
		int x2, int y2,
		Color *color)
{
  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (object);
  double x1u = x1 + .5, y1u = y1 + .5, x2u = x2 + .5, y2u = y2 + .5;
  double lw[2];
  lw[0] = 1; lw[1] = 0;
  
  cairo_device_to_user_distance (renderer->cr, &lw[0], &lw[1]);
  cairo_set_line_width (renderer->cr, lw[0]);

  cairo_device_to_user (renderer->cr, &x1u, &y1u);
  cairo_device_to_user (renderer->cr, &x2u, &y2u);

  cairo_set_source_rgba (renderer->cr, color->red, color->green, color->blue, 1.0);
  cairo_move_to (renderer->cr, x1u, y1u);
  cairo_line_to (renderer->cr, x2u, y2u);
  cairo_stroke (renderer->cr);
}
FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect)
{
    FloatRect result;
    double x = frect.x();
    double y = frect.y();
    cairo_t* cr = m_data->cr;
    cairo_user_to_device(cr, &x, &y);
    x = round(x);
    y = round(y);
    cairo_device_to_user(cr, &x, &y);
    result.setX(static_cast<float>(x));
    result.setY(static_cast<float>(y));
    x = frect.width();
    y = frect.height();
    cairo_user_to_device_distance(cr, &x, &y);
    x = round(x);
    y = round(y);
    cairo_device_to_user_distance(cr, &x, &y);
    result.setWidth(static_cast<float>(x));
    result.setHeight(static_cast<float>(y));
    return result;
}
FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect, RoundingMode)
{
    FloatRect result;
    double x = frect.x();
    double y = frect.y();
    cairo_t* cr = platformContext()->cr();
    cairo_user_to_device(cr, &x, &y);
    x = round(x);
    y = round(y);
    cairo_device_to_user(cr, &x, &y);
    result.setX(narrowPrecisionToFloat(x));
    result.setY(narrowPrecisionToFloat(y));

    // We must ensure width and height are at least 1 (or -1) when
    // we're given float values in the range between 0 and 1 (or -1 and 0).
    double width = frect.width();
    double height = frect.height();
    cairo_user_to_device_distance(cr, &width, &height);
    if (width > -1 && width < 0)
        width = -1;
    else if (width > 0 && width < 1)
        width = 1;
    else
        width = round(width);
    if (height > -1 && width < 0)
        height = -1;
    else if (height > 0 && height < 1)
        height = 1;
    else
        height = round(height);
    cairo_device_to_user_distance(cr, &width, &height);
    result.setWidth(narrowPrecisionToFloat(width));
    result.setHeight(narrowPrecisionToFloat(height));

    return result;
}
Example #21
0
int
draw_image_to_cairo_target (cairo_t *cairoTarget, gerbv_image_t *image,
		gdouble pixelWidth, enum draw_mode drawMode,
		gerbv_selection_info_t *selectionInfo,
		gerbv_render_info_t *renderInfo, gboolean allowOptimization,
		gerbv_user_transformation_t transform, gboolean pixelOutput)
{
	const int hole_cross_inc_px = 8;
	struct gerbv_net *net, *polygonStartNet=NULL;
	double x1, y1, x2, y2, cp_x=0, cp_y=0;
	gdouble *p, p0, p1, dx, dy, lineWidth, r;
	gerbv_netstate_t *oldState;
	gerbv_layer_t *oldLayer;
	cairo_operator_t drawOperatorClear, drawOperatorDark;
	gboolean invertPolarity = FALSE, oddWidth = FALSE;
	gdouble minX=0, minY=0, maxX=0, maxY=0;
	gdouble criticalRadius;
	gdouble scaleX = transform.scaleX;
	gdouble scaleY = transform.scaleY;
	gboolean limitLineWidth = TRUE;
	gboolean displayPixel = TRUE;

	/* If we are scaling the image at all, ignore the line width checks
	 * since scaled up lines can still be visible */
	if ((scaleX != 1)||(scaleY != 1)){
		limitLineWidth = FALSE;
	}

	if (transform.mirrorAroundX)
		scaleY *= -1;
	if (transform.mirrorAroundY)
		scaleX *= -1;

	cairo_translate (cairoTarget, transform.translateX, transform.translateY);
	cairo_scale (cairoTarget, scaleX, scaleY);
	cairo_rotate (cairoTarget, transform.rotation);

	gboolean useOptimizations = allowOptimization;

	/* If the user is using any transformations for this layer, then don't
	 * bother using rendering optimizations */
	if ((fabs(transform.translateX) > 0.00001) ||
			(fabs(transform.translateY) > 0.00001) ||
			(fabs(transform.scaleX - 1) > 0.00001) ||
			(fabs(transform.scaleY - 1) > 0.00001) ||
			(fabs(transform.rotation) > 0.00001) ||
			transform.mirrorAroundX || transform.mirrorAroundY)
		useOptimizations = FALSE;

	if (useOptimizations && pixelOutput) {
		minX = renderInfo->lowerLeftX;
		minY = renderInfo->lowerLeftY;
		maxX = renderInfo->lowerLeftX + (renderInfo->displayWidth /
					renderInfo->scaleFactorX);
		maxY = renderInfo->lowerLeftY + (renderInfo->displayHeight /
					renderInfo->scaleFactorY);
	}

	/* do initial justify */
	cairo_translate (cairoTarget, image->info->imageJustifyOffsetActualA,
		 image->info->imageJustifyOffsetActualB);

	/* set the fill rule so aperture holes are cleared correctly */
	cairo_set_fill_rule (cairoTarget, CAIRO_FILL_RULE_EVEN_ODD);
	/* offset image */
	cairo_translate (cairoTarget, image->info->offsetA, image->info->offsetB);
	/* do image rotation */
	cairo_rotate (cairoTarget, image->info->imageRotation);

	/* load in polarity operators depending on the image polarity */
	invertPolarity = transform.inverted;
	if (image->info->polarity == GERBV_POLARITY_NEGATIVE)
		invertPolarity = !invertPolarity;
	if (drawMode == DRAW_SELECTIONS)
		invertPolarity = FALSE;

	if (invertPolarity) {
		drawOperatorClear = CAIRO_OPERATOR_OVER;
		drawOperatorDark = CAIRO_OPERATOR_CLEAR;
		cairo_set_operator (cairoTarget, CAIRO_OPERATOR_OVER);
		cairo_paint (cairoTarget);
		cairo_set_operator (cairoTarget, CAIRO_OPERATOR_CLEAR);
	} else {
		drawOperatorClear = CAIRO_OPERATOR_CLEAR;
		drawOperatorDark = CAIRO_OPERATOR_OVER;
	}

	/* next, push two cairo states to simulate the first layer and netstate
	   translations (these will be popped when another layer or netstate is
	   started */
	cairo_save (cairoTarget);
	cairo_save (cairoTarget);

	/* store the current layer and netstate so we know when they change */
	oldLayer = image->layers;
	oldState = image->states;

	for (net = image->netlist->next; net != NULL;
			net = gerbv_image_return_next_renderable_object(net)) {

		/* check if this is a new layer */
		if (net->layer != oldLayer){
			/* it's a new layer, so recalculate the new transformation matrix
			   for it */
			cairo_restore (cairoTarget);
			cairo_restore (cairoTarget);
			cairo_save (cairoTarget);
			/* do any rotations */
			cairo_rotate (cairoTarget, net->layer->rotation);
			/* handle the layer polarity */
			if ((net->layer->polarity == GERBV_POLARITY_CLEAR)^invertPolarity) {
				cairo_set_operator (cairoTarget, CAIRO_OPERATOR_CLEAR);
				drawOperatorClear = CAIRO_OPERATOR_OVER;
				drawOperatorDark = CAIRO_OPERATOR_CLEAR;
			}
			else {
				cairo_set_operator (cairoTarget, CAIRO_OPERATOR_OVER);
				drawOperatorClear = CAIRO_OPERATOR_CLEAR;
				drawOperatorDark = CAIRO_OPERATOR_OVER;
			}

			/* Draw any knockout areas */
			gerbv_knockout_t *ko = &net->layer->knockout;
			if (ko->firstInstance == TRUE) {
				cairo_operator_t oldOperator = cairo_get_operator (cairoTarget);

				if (ko->polarity == GERBV_POLARITY_CLEAR) {
					cairo_set_operator (cairoTarget, drawOperatorClear);
				} else {
					cairo_set_operator (cairoTarget, drawOperatorDark);
				}
				cairo_new_path (cairoTarget);
				cairo_rectangle (cairoTarget,
						ko->lowerLeftX - ko->border,
						ko->lowerLeftY - ko->border,
						ko->width + 2*ko->border,
						ko->height + 2*ko->border);
				draw_fill (cairoTarget, drawMode, selectionInfo, image, net);
				cairo_set_operator (cairoTarget, oldOperator);
			}

			/* Finally, reapply old netstate transformation */
			cairo_save (cairoTarget);
			draw_apply_netstate_transformation (cairoTarget, net->state);
			oldLayer = net->layer;
		}

		/* check if this is a new netstate */
		if (net->state != oldState){
			/* pop the transformation matrix back to the "pre-state" state and
			   resave it */
			cairo_restore (cairoTarget);
			cairo_save (cairoTarget);
			/* it's a new state, so recalculate the new transformation matrix
			   for it */
			draw_apply_netstate_transformation (cairoTarget, net->state);
			oldState = net->state;
		}

		/* if we are only drawing from the selection buffer, search if this net is
		   in the buffer */
		if (drawMode == DRAW_SELECTIONS) {
			/* this flag makes sure we don't draw any unintentional polygons...
			   if we've successfully entered a polygon (the first net matches, and
			   we don't want to check the nets inside the polygon) then
			   polygonStartNet will be set */
			if (!polygonStartNet) {
				if (!draw_net_is_in_selection_buffer_remove (net,
							selectionInfo, FALSE))
					continue;
			}
		}

		/* step and repeat */
		gerbv_step_and_repeat_t *sr = &net->layer->stepAndRepeat;
		int ix, iy;
		for (ix = 0; ix < sr->X; ix++) {
			for (iy = 0; iy < sr->Y; iy++) {
				double sr_x = ix * sr->dist_X;
				double sr_y = iy * sr->dist_Y;

				if (useOptimizations && pixelOutput
				&& ((net->boundingBox.right+sr_x < minX)
				 || (net->boundingBox.left+sr_x > maxX)
				 || (net->boundingBox.top+sr_y < minY)
				 || (net->boundingBox.bottom+sr_y > maxY))) {
					continue;
				}

				x1 = net->start_x + sr_x;
				y1 = net->start_y + sr_y;
				x2 = net->stop_x + sr_x;
				y2 = net->stop_y + sr_y;

				/* translate circular x,y data as well */
				if (net->cirseg) {
					cp_x = net->cirseg->cp_x + sr_x;
					cp_y = net->cirseg->cp_y + sr_y;
				}

				/* render any labels attached to this net */
				/* NOTE: this is currently only used on PNP files, so we may
				   make some assumptions here... */
				if (net->label) {
					cairo_set_font_size (cairoTarget, 0.05);
					cairo_save (cairoTarget);

					cairo_move_to (cairoTarget, x1, y1);
					cairo_scale (cairoTarget, 1, -1);
					cairo_show_text (cairoTarget, net->label->str);
					cairo_restore (cairoTarget);
				}

				/* Polygon area fill routines */
				switch (net->interpolation) {
				case GERBV_INTERPOLATION_PAREA_START :
					draw_render_polygon_object (net, cairoTarget,
							sr_x, sr_y, image, drawMode,
							selectionInfo, pixelOutput);
					continue;
				case GERBV_INTERPOLATION_DELETED:
					continue;
				default :
					break;
				}

				/*
				 * If aperture state is off we allow use of undefined apertures.
				 * This happens when gerber files starts, but hasn't decided on 
				 * which aperture to use.
				 */
				if (image->aperture[net->aperture] == NULL)
					continue;

				switch (net->aperture_state) {
				case GERBV_APERTURE_STATE_ON :
					/* if the aperture width is truly 0, then render as a 1 pixel width
					   line.  0 diameter apertures are used by some programs to draw labels,
					   etc, and they are rendered by other programs as 1 pixel wide */
					/* NOTE: also, make sure all lines are at least 1 pixel wide, so they
					   always show up at low zoom levels */

					if (limitLineWidth&&((image->aperture[net->aperture]->parameter[0] < pixelWidth)&&
							(pixelOutput)))
						criticalRadius = pixelWidth/2.0;
					else
						criticalRadius = image->aperture[net->aperture]->parameter[0]/2.0;
					lineWidth = criticalRadius*2.0;
					// convert to a pixel integer
					cairo_user_to_device_distance (cairoTarget, &lineWidth, &x1);
					if (pixelOutput) {
						lineWidth = round(lineWidth);
						if ((int)lineWidth % 2) {
							oddWidth = TRUE;
						}
						else {
							oddWidth = FALSE;
						}
					}
					cairo_device_to_user_distance (cairoTarget, &lineWidth, &x1);
					cairo_set_line_width (cairoTarget, lineWidth);

					switch (net->interpolation) {
					case GERBV_INTERPOLATION_x10 :
					case GERBV_INTERPOLATION_LINEARx01 :
					case GERBV_INTERPOLATION_LINEARx001 :
					case GERBV_INTERPOLATION_LINEARx1 :
						cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_ROUND);

						/* weed out any lines that are
						 * obviously not going to
						 * render on the visible screen */
						switch (image->aperture[net->aperture]->type) {
						case GERBV_APTYPE_CIRCLE :
							if (renderInfo->show_cross_on_drill_holes
							&&  image->layertype == GERBV_LAYERTYPE_DRILL) {
								/* Draw center crosses on slot hole */
								cairo_set_line_width (cairoTarget, pixelWidth);
								cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_SQUARE);
								r = image->aperture[net->aperture]->parameter[0]/2.0 +
									hole_cross_inc_px*pixelWidth;
								draw_cairo_cross (cairoTarget, x1, y1, r);
								draw_cairo_cross (cairoTarget, x2, y2, r);
								cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_ROUND);
								cairo_set_line_width (cairoTarget, lineWidth);
							}

							draw_cairo_move_to (cairoTarget, x1, y1, oddWidth, pixelOutput);
							draw_cairo_line_to (cairoTarget, x2, y2, oddWidth, pixelOutput);
							draw_stroke (cairoTarget, drawMode, selectionInfo, image, net);
							break;
						case GERBV_APTYPE_RECTANGLE :
							dx = image->aperture[net->aperture]->parameter[0]/2;
							dy = image->aperture[net->aperture]->parameter[1]/2;
							if(x1 > x2)
								dx = -dx;
							if(y1 > y2)
								dy = -dy;
							cairo_new_path(cairoTarget);
							draw_cairo_move_to (cairoTarget, x1 - dx, y1 - dy, FALSE, pixelOutput);
							draw_cairo_line_to (cairoTarget, x1 - dx, y1 + dy, FALSE, pixelOutput);
							draw_cairo_line_to (cairoTarget, x2 - dx, y2 + dy, FALSE, pixelOutput);
							draw_cairo_line_to (cairoTarget, x2 + dx, y2 + dy, FALSE, pixelOutput);
							draw_cairo_line_to (cairoTarget, x2 + dx, y2 - dy, FALSE, pixelOutput);
							draw_cairo_line_to (cairoTarget, x1 + dx, y1 - dy, FALSE, pixelOutput);
							draw_fill (cairoTarget, drawMode, selectionInfo, image, net);
							break;
						/* TODO: for now, just render ovals or polygons like a circle */
						case GERBV_APTYPE_OVAL :
						case GERBV_APTYPE_POLYGON :
							draw_cairo_move_to (cairoTarget, x1,y1, oddWidth, pixelOutput);
							draw_cairo_line_to (cairoTarget, x2,y2, oddWidth, pixelOutput);
							draw_stroke (cairoTarget, drawMode, selectionInfo, image, net);
							break;
						/* macros can only be flashed, so ignore any that might be here */
						default:
							GERB_COMPILE_WARNING(_("Skipped aperture type \"%s\""),
								_(aperture_names[image->aperture[net->aperture]->type]));
							break;
						}
						break;
					case GERBV_INTERPOLATION_CW_CIRCULAR :
					case GERBV_INTERPOLATION_CCW_CIRCULAR :
						/* cairo doesn't have a function to draw oval arcs, so we must
						 * draw an arc and stretch it by scaling different x and y values
						 */
						cairo_new_path(cairoTarget);
						if (image->aperture[net->aperture]->type == GERBV_APTYPE_RECTANGLE) {
							cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_SQUARE);
						}
						else {
							cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_ROUND);
						}
						cairo_save (cairoTarget);
						cairo_translate(cairoTarget, cp_x, cp_y);
						cairo_scale (cairoTarget, net->cirseg->width, net->cirseg->height);
						if (net->cirseg->angle2 > net->cirseg->angle1) {
							cairo_arc (cairoTarget, 0.0, 0.0, 0.5,
								DEG2RAD(net->cirseg->angle1),
								DEG2RAD(net->cirseg->angle2));
						}
						else {
							cairo_arc_negative (cairoTarget, 0.0, 0.0, 0.5,
								DEG2RAD(net->cirseg->angle1),
								DEG2RAD(net->cirseg->angle2));
						}
						cairo_restore (cairoTarget);
						draw_stroke (cairoTarget, drawMode, selectionInfo, image, net);
						break;
					default :
						GERB_COMPILE_WARNING(_("Skipped interpolation type %d"),
								net->interpolation);
						break;
					}
					break;
				case GERBV_APERTURE_STATE_OFF :
					break;
				case GERBV_APERTURE_STATE_FLASH :
					p = image->aperture[net->aperture]->parameter;

					cairo_save (cairoTarget);
					draw_cairo_translate_adjust(cairoTarget, x2, y2, pixelOutput);

					switch (image->aperture[net->aperture]->type) {
					case GERBV_APTYPE_CIRCLE :
						if (renderInfo->show_cross_on_drill_holes
						&& image->layertype == GERBV_LAYERTYPE_DRILL) {
							/* Draw center cross on drill hole */
							cairo_set_line_width (cairoTarget, pixelWidth);
							cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_SQUARE);
							r = p[0]/2.0 + hole_cross_inc_px*pixelWidth;
							draw_cairo_cross (cairoTarget, 0, 0, r);
							cairo_set_line_width (cairoTarget, lineWidth);
							cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_ROUND);
						}

						gerbv_draw_circle(cairoTarget, p[0]);
						gerbv_draw_aperture_hole (cairoTarget, p[1], p[2], pixelOutput);
						break;
					case GERBV_APTYPE_RECTANGLE :
						// some CAD programs use very thin flashed rectangles to compose
						//	logos/images, so we must make sure those display here
						displayPixel = pixelOutput;
						p0 = p[0];
						p1 = p[1];
						if (limitLineWidth && (p[0] < pixelWidth) && pixelOutput) {
							p0 = pixelWidth;
							displayPixel = FALSE;
						}
						if (limitLineWidth && (p[1] < pixelWidth) && pixelOutput) {
							p1 = pixelWidth;
							displayPixel = FALSE;
						}
						gerbv_draw_rectangle(cairoTarget, p0, p1, displayPixel);
						gerbv_draw_aperture_hole (cairoTarget, p[2], p[3], displayPixel);
						break;
					case GERBV_APTYPE_OVAL :
						gerbv_draw_oblong(cairoTarget, p[0], p[1]);
						gerbv_draw_aperture_hole (cairoTarget, p[2], p[3], pixelOutput);
						break;
					case GERBV_APTYPE_POLYGON :
						gerbv_draw_polygon(cairoTarget, p[0], p[1], p[2]);
						gerbv_draw_aperture_hole (cairoTarget, p[3], p[4], pixelOutput);
						break;
					case GERBV_APTYPE_MACRO :
						gerbv_draw_amacro(cairoTarget, drawOperatorClear, drawOperatorDark,
							image->aperture[net->aperture]->simplified,
							(gint)p[0], pixelWidth,
							drawMode, selectionInfo, image, net);
						break;
					default :
						GERB_MESSAGE(_("Unknown aperture type"));
						return 0;
					}
					/* and finally fill the path */
					draw_fill (cairoTarget, drawMode, selectionInfo, image, net);
					cairo_restore (cairoTarget);
					break;
				default:
					GERB_MESSAGE(_("Unknown aperture state"));
					return 0;
				}
			}
		}
	}

	/* restore the initial two state saves (one for layer, one for netstate)*/
	cairo_restore (cairoTarget);
	cairo_restore (cairoTarget);

	return 1;
}
Example #22
0
void LcCairoPainter::device_to_user_distance(double* dx, double* dy) {
    cairo_device_to_user_distance(_cr, dx, dy);
}
Example #23
0
void Context::deviceToUserDistance( double *dx, double *dy )
{
	cairo_device_to_user_distance( mCairo, dx, dy );
}
Example #24
0
void
_cairo_paint_grid (cairo_t               *cr,
		   cairo_rectangle_int_t *rectangle,
		   GthGridType            grid_type)
{
	double ux, uy;

	cairo_save (cr);

	ux = uy = 1.0;
	cairo_device_to_user_distance (cr, &ux, &uy);
	cairo_set_line_width (cr, MAX (ux, uy));

	cairo_rectangle (cr, rectangle->x - ux + 0.5, rectangle->y - uy + 0.5, rectangle->width + (ux * 2), rectangle->height + (uy * 2));
	cairo_clip (cr);

#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 2)
	cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
#endif

	cairo_rectangle (cr, rectangle->x + 0.5, rectangle->y + 0.5, rectangle->width - 0.5, rectangle->height - 0.5);
	cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
	cairo_stroke (cr);

	if (grid_type == GTH_GRID_NONE) {
		cairo_restore (cr);
		return;
	}

	if (grid_type == GTH_GRID_THIRDS) {
		int i;

		cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.60);
		for (i = 1; i < 3; i++) {
			cairo_move_to (cr, rectangle->x + rectangle->width * i / 3 + 0.5, rectangle->y + 1.5);
			cairo_line_to (cr, rectangle->x + rectangle->width * i / 3 + 0.5, rectangle->y + rectangle->height - 0.5);

			cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + rectangle->height * i / 3 + 0.5);
			cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + rectangle->height * i / 3 + 0.5);
		}
		cairo_stroke (cr);

		cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.10);
		for (i = 1; i < 9; i++) {

			if (i % 3 == 0)
				continue;

			cairo_move_to (cr, rectangle->x + rectangle->width * i / 9 + 0.5, rectangle->y + 1.5);
			cairo_line_to (cr, rectangle->x + rectangle->width * i / 9 + 0.5, rectangle->y + rectangle->height - 0.5);

			cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + rectangle->height * i / 9 + 0.5);
			cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + rectangle->height * i / 9 + 0.5);
		}
		cairo_stroke (cr);
	}
	else if (grid_type == GTH_GRID_GOLDEN) {
		cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.60);

		int grid_x0, grid_x1, grid_x2, grid_x3;
	        int grid_y0, grid_y1, grid_y2, grid_y3;
		int x_delta, y_delta;

		grid_x0 = rectangle->x;
		grid_x3 = rectangle->x + rectangle->width;

                grid_y0 = rectangle->y;
                grid_y3 = rectangle->y + rectangle->height;

		x_delta = rectangle->width * GOLDER_RATIO_FACTOR;
		y_delta = rectangle->height * GOLDER_RATIO_FACTOR;

		grid_x1 = grid_x0 + x_delta;
		grid_x2 = grid_x3 - x_delta;
                grid_y1 = grid_y0 + y_delta;
                grid_y2 = grid_y3 - y_delta;

		cairo_move_to (cr, grid_x1 + 0.5, grid_y0 + 0.5);
		cairo_line_to (cr, grid_x1 + 0.5, grid_y3 + 0.5);

		if (x_delta < rectangle->width / 2) {
			cairo_move_to (cr, grid_x2 + 0.5, grid_y0 + 0.5);
			cairo_line_to (cr, grid_x2 + 0.5, grid_y3 + 0.5);
		}

		cairo_move_to (cr, grid_x0 + 0.5, grid_y1 + 0.5);
		cairo_line_to (cr, grid_x3 + 0.5, grid_y1 + 0.5);

		if (y_delta < rectangle->height / 2) {
			cairo_move_to (cr, grid_x0 + 0.5, grid_y2 + 0.5);
			cairo_line_to (cr, grid_x3 + 0.5, grid_y2 + 0.5);
		}

		cairo_stroke (cr);
	}
	else if (grid_type == GTH_GRID_CENTER) {
		int i;

		cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.60);
		cairo_move_to (cr, rectangle->x + rectangle->width / 2 + 0.5, rectangle->y + 1.5);
		cairo_line_to (cr, rectangle->x + rectangle->width / 2 + 0.5, rectangle->y + rectangle->height - 0.5);
		cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + rectangle->height / 2 + 0.5);
		cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + rectangle->height / 2 + 0.5);
		cairo_stroke (cr);

		cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.10);
		for (i = 1; i < 4; i++) {

			if (i == 2)
				continue;

			cairo_move_to (cr, rectangle->x + rectangle->width * i / 4 + 0.5, rectangle->y + 1.5);
			cairo_line_to (cr, rectangle->x + rectangle->width * i / 4 + 0.5, rectangle->y + rectangle->height - 0.5);
			cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + rectangle->height * i / 4 + 0.5);
			cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + rectangle->height * i / 4 + 0.5);
		}
		cairo_stroke (cr);
	}
	else if (grid_type == GTH_GRID_UNIFORM) {

		int x;
		int y;

		if (rectangle->width / GRID_STEP_3 <= MAX_GRID_LINES) {
			cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.40);
			for (x = GRID_STEP_3; x < rectangle->width; x += GRID_STEP_3) {
				cairo_move_to (cr, rectangle->x + x + 0.5, rectangle->y + 1.5);
				cairo_line_to (cr, rectangle->x + x + 0.5, rectangle->y + rectangle->height - 0.5);
			}
			for (y = GRID_STEP_3; y < rectangle->height; y += GRID_STEP_3) {
				cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + y + 0.5);
				cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + y + 0.5);
			}
			cairo_stroke (cr);
		}

		if (rectangle->width / GRID_STEP_2 <= MAX_GRID_LINES) {
			cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.20);
			for (x = GRID_STEP_2; x < rectangle->width; x += GRID_STEP_2) {
				if (x % GRID_STEP_3 == 0)
					continue;
				cairo_move_to (cr, rectangle->x + x + 0.5, rectangle->y + 1.5);
				cairo_line_to (cr, rectangle->x + x + 0.5, rectangle->y + rectangle->height - 0.5);
			}
			for (y = GRID_STEP_2; y < rectangle->height; y += GRID_STEP_2) {
				if (y % GRID_STEP_3 == 0)
					continue;
				cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + y + 0.5);
				cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + y + 0.5);
			}
			cairo_stroke (cr);
		}

		if (rectangle->width / GRID_STEP_1 <= MAX_GRID_LINES) {
			cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.10);
			for (x = GRID_STEP_1; x < rectangle->width; x += GRID_STEP_1) {
				if (x % GRID_STEP_2 == 0)
					continue;
				cairo_move_to (cr, rectangle->x + x + 0.5, rectangle->y + 1.5);
				cairo_line_to (cr, rectangle->x + x + 0.5, rectangle->y + rectangle->height - 0.5);
			}
			for (y = GRID_STEP_1; y < rectangle->height; y += GRID_STEP_1) {
				if (y % GRID_STEP_2 == 0)
					continue;
				cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + y + 0.5);
				cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + y + 0.5);
			}
		}
		cairo_stroke (cr);
	}

	cairo_restore (cr);
}
Example #25
0
GpStatus
gdip_pen_setup (GpGraphics *graphics, GpPen *pen)
{
	GpStatus status;
	cairo_matrix_t product;
	double widthx;

	if (!graphics || !pen)
		return InvalidParameter;

	status = gdip_brush_setup (graphics, pen->brush);
	if (status != Ok)
		return status;

	cairo_matrix_init_identity (&product);

	/* Here we use product of pen->matrix and graphics->copy_of_ctm.
	 * This gives us absolute results with respect to graphics. We
	 * do following irrespective of the pen->changed state since graphics
	 * has its own matrix and we need to multiply that with pen->matrix
	 * every time we perform stroke operations. Graphics matrix gets
	 * reset to its own state after stroking.
	 */
	cairo_matrix_multiply (&product, &pen->matrix, graphics->copy_of_ctm);
	/* Pen scaling by 0 are supported by MS GDI+ but would error in Cairo, see bug #338233 */
	if (gdip_near_zero (product.xx) || gdip_near_zero (product.yy)) {
		/* *both* X and Y are affected if either is 0 */
		product.xx = product.yy = 0.0001f;
	}
	cairo_set_matrix (graphics->ct, &product);

	/* Don't need to setup, if pen is the same as the cached pen and
	 * it is not changed. Just comparing pointers may not be sufficient
	 * to say that the pens are same. It is possible to have different
	 * pen on the same memory, but probability is very low. We would
	 * need a function to check the equality of the pens in that case.
	 */
	if (pen == graphics->last_pen && !pen->changed)
		return Ok;

	if (pen->width < 1.0) { /* we draw a pixel wide line if width is < 1.0 */
		double widthy = 1.0;
		widthx = 1.0;

		cairo_device_to_user_distance (graphics->ct, &widthx, &widthy);
	} else {
		widthx = (double) pen->width;
	}
	cairo_set_line_width (graphics->ct, widthx);

	cairo_set_miter_limit (graphics->ct, (double) pen->miter_limit);
	cairo_set_line_join (graphics->ct, convert_line_join (pen->line_join));
	cairo_set_line_cap (graphics->ct, convert_line_cap (pen));

	if (pen->dash_count > 0) {
		double *dash_array;

		/* note: pen->width may be different from what was used to
		call cairo_set_line_width, e.g. 0.0 (#78742) */
		dash_array = convert_dash_array (pen->dash_array, widthx, pen->dash_count);
		if (!dash_array)
			return OutOfMemory;

		cairo_set_dash (graphics->ct, dash_array, pen->dash_count, pen->dash_offset);
		GdipFree (dash_array);
	} else /* Clear the dashes, if set in previous calls */
		cairo_set_dash (graphics->ct, NULL, 0, 0);

	/* We are done with using all the changes in the pen. */
	pen->changed = FALSE;
	graphics->last_pen = pen;

	return gdip_get_status (cairo_status (graphics->ct));
}
Example #26
0
void
eda_cairo_stroke (cairo_t *cr, int flags, int line_type, int line_end,
                  double wwidth, double wlength, double wspace)
{
  double offset = 0;
  double dashes[4];
  double dummy = 0;
  cairo_line_cap_t cap;
  cairo_line_cap_t round_cap_if_legible = CAIRO_LINE_CAP_ROUND;
  int num_dashes;
  int iwidth;
  double width = wwidth, length = wlength, space = wspace;

  if (flags & EDA_CAIRO_ENABLE_HINTS) {
    width  = iwidth = screen_width (cr, wwidth);
    length = screen_width (cr, wlength);
    space  = screen_width (cr, wspace);
    cairo_device_to_user_distance (cr, &width, &dummy);
    cairo_device_to_user_distance (cr, &length, &dummy);
    cairo_device_to_user_distance (cr, &space, &dummy);

    offset = ((iwidth % 2) == 0) ? 0 : 0.5;

    round_cap_if_legible =
      (iwidth <= 1) ? CAIRO_LINE_CAP_SQUARE : CAIRO_LINE_CAP_ROUND;
  }

  cairo_set_line_width (cr, width);
  cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);

  switch (line_end) {
    case END_NONE:   cap = CAIRO_LINE_CAP_BUTT;   break;
    case END_SQUARE: cap = CAIRO_LINE_CAP_SQUARE; break;
    case END_ROUND:  cap = round_cap_if_legible;  break;
    default:
      g_warn_if_reached ();
      cap = CAIRO_LINE_CAP_BUTT;
    break;
  }

  switch (line_type) {

    default:
      g_warn_if_reached ();
      /* Fall through */

    case TYPE_SOLID:
      num_dashes = 0;

      cairo_set_dash (cr, dashes, num_dashes, 0.);
      cairo_set_line_cap (cr, cap);
      cairo_stroke (cr);
      break;

    case TYPE_DOTTED:
      dashes[0] = 0;                    /* DOT */
      dashes[1] = space;
      num_dashes = 2;

      cairo_set_dash (cr, dashes, num_dashes, offset);
      cairo_set_line_cap (cr, round_cap_if_legible);
      cairo_stroke (cr);
      break;

    case TYPE_DASHED:
      dashes[0] = length;               /* DASH */
      dashes[1] = space;
      num_dashes = 2;

      cairo_set_dash (cr, dashes, num_dashes, 0.);
      cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
      cairo_stroke (cr);
      break;

    case TYPE_CENTER:
      dashes[0] = length;               /* DASH */
      dashes[1] = 2 * space;
      num_dashes = 2;

      cairo_set_dash (cr, dashes, num_dashes, 0.);
      cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
      cairo_stroke_preserve (cr);

      dashes[0] = 0;                    /* DOT */
      dashes[1] = 2 * space + length;
      num_dashes = 2;

      cairo_set_dash (cr, dashes, num_dashes, -length - space + offset);
      cairo_set_line_cap (cr, round_cap_if_legible);
      cairo_stroke (cr);
      break;

    case TYPE_PHANTOM:
      dashes[0] = length;               /* DASH */
      dashes[1] = 3 * space;
      num_dashes = 2;

      cairo_set_dash (cr, dashes, num_dashes, 0.);
      cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
      cairo_stroke_preserve (cr);

      dashes[0] = 0;                    /* DOT */
      dashes[1] = space;
      dashes[2] = 0;                    /* DOT */
      dashes[3] = 2 * space + length;
      num_dashes = 4;

      cairo_set_dash (cr, dashes, num_dashes, -length - space + offset);
      cairo_set_line_cap (cr, round_cap_if_legible);
      cairo_stroke (cr);
      break;
  }

  cairo_set_dash (cr, NULL, 0, 0.);
}