// A helper which quickly fills a rectangle with a simple color fill.
static inline void fillRectWithColor(cairo_t* cr, const FloatRect& rect, const Color& color)
{
    if (!color.alpha() && cairo_get_operator(cr) == CAIRO_OPERATOR_OVER)
        return;
    setSourceRGBAFromColor(cr, color);
    cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
    cairo_fill(cr);
}
Beispiel #2
0
static int cairo_get_operator_l( lua_State* L )
{
  lua_cairo_t* lc = lua_cairo_check( L, 1 );

  lua_pushstring( L, cairo_operator_lst[cairo_get_operator( lc->cairo )] );

  return( 1 );
}
Beispiel #3
0
void plotstuff_clear(plot_args_t* pargs) {
  cairo_operator_t op;
  assert(pargs->cairo);
  op = cairo_get_operator(pargs->cairo);
  cairo_set_operator(pargs->cairo, CAIRO_OPERATOR_CLEAR);
  cairo_paint(pargs->cairo);
  cairo_set_operator(pargs->cairo, op);
}
Beispiel #4
0
gboolean
draw_update_macro_exposure (cairo_t *cairoTarget, cairo_operator_t clearOperator,
		cairo_operator_t darkOperator, gdouble exposureSetting){

	if (exposureSetting == 0.0) {
		cairo_set_operator (cairoTarget, clearOperator);
	} else if (exposureSetting == 1.0) {
		cairo_set_operator (cairoTarget, darkOperator);
	} else if (exposureSetting == 2.0) {
		/* reverse current exposure setting */
		cairo_operator_t currentOperator = cairo_get_operator (cairoTarget);
		if (currentOperator == clearOperator) {
			cairo_set_operator (cairoTarget, darkOperator);
		} else {
			cairo_set_operator (cairoTarget, clearOperator);
		}
	}

	return TRUE;
}
Beispiel #5
0
static int
settings_get (cairo_t *cr, settings_t *settings)
{
    int count;

    settings->op = cairo_get_operator (cr);
    settings->tolerance = cairo_get_tolerance (cr);
    settings->fill_rule = cairo_get_fill_rule (cr);
    settings->line_width = cairo_get_line_width (cr);
    settings->line_cap = cairo_get_line_cap (cr);
    settings->line_join = cairo_get_line_join (cr);
    settings->miter_limit = cairo_get_miter_limit (cr);
    cairo_get_matrix (cr, &settings->matrix);

    count = cairo_get_dash_count (cr);
    if (count != 5)
	return -1;

    cairo_get_dash (cr, settings->dash, &settings->dash_offset);

    return 0;
}
Beispiel #6
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;
}
Beispiel #7
0
int
gerbv_draw_amacro(cairo_t *cairoTarget, cairo_operator_t clearOperator,
	cairo_operator_t darkOperator, gerbv_simplified_amacro_t *s,
	gint usesClearPrimative, gdouble pixelWidth, enum draw_mode drawMode,
	gerbv_selection_info_t *selectionInfo,
	gerbv_image_t *image, struct gerbv_net *net)
{
	int handled = 1;
	gerbv_simplified_amacro_t *ls = s;

	dprintf("Drawing simplified aperture macros:\n");

	if (usesClearPrimative)
		cairo_push_group (cairoTarget);

	while (ls != NULL) {
		/* 
		 * This handles the exposure thing in the aperture macro
		 * The exposure is always the first element on stack independent
		 * of aperture macro.
		 */
		cairo_save (cairoTarget);
		cairo_new_path(cairoTarget);
		cairo_operator_t oldOperator = cairo_get_operator (cairoTarget);

		switch (ls->type) {
		case GERBV_APTYPE_MACRO_CIRCLE:
			if (draw_update_macro_exposure (cairoTarget, clearOperator,
						darkOperator, ls->parameter[CIRCLE_EXPOSURE])) {
				cairo_translate (cairoTarget, ls->parameter[CIRCLE_CENTER_X],
						ls->parameter[CIRCLE_CENTER_Y]);

				gerbv_draw_circle (cairoTarget, ls->parameter[CIRCLE_DIAMETER]);
				draw_fill (cairoTarget, drawMode, selectionInfo, image, net);
			}
			break;
		case GERBV_APTYPE_MACRO_OUTLINE: {
			int pointCounter,numberOfPoints;
			/* Number of points parameter seems to not include the start point,
			 * so we add one to include the start point.
			 */
			numberOfPoints = (int) ls->parameter[OUTLINE_NUMBER_OF_POINTS] + 1;

			if (draw_update_macro_exposure (cairoTarget, clearOperator,
					darkOperator, ls->parameter[OUTLINE_EXPOSURE])) {
				cairo_rotate (cairoTarget,
						DEG2RAD(ls->parameter[2*(numberOfPoints - 1) + OUTLINE_ROTATION]));
				cairo_move_to (cairoTarget, ls->parameter[OUTLINE_FIRST_X],
						ls->parameter[OUTLINE_FIRST_Y]);

				for (pointCounter=0; pointCounter < numberOfPoints; pointCounter++) {
					cairo_line_to (cairoTarget,
						ls->parameter[pointCounter * 2 + OUTLINE_FIRST_X],
						ls->parameter[pointCounter * 2 + OUTLINE_FIRST_Y]);
				}

				/* although the gerber specs allow for an open outline,
				   I interpret it to mean the outline should be closed by the
				   rendering softare automatically, since there is no dimension
				   for line thickness.
				*/
				draw_fill (cairoTarget, drawMode, selectionInfo, image, net);
			}
			break;
		}
		case GERBV_APTYPE_MACRO_POLYGON:
			if (draw_update_macro_exposure (cairoTarget, clearOperator,
						darkOperator, ls->parameter[POLYGON_EXPOSURE])) {
				cairo_translate (cairoTarget, ls->parameter[POLYGON_CENTER_X],
						ls->parameter[POLYGON_CENTER_Y]);
				gerbv_draw_polygon(cairoTarget, ls->parameter[POLYGON_DIAMETER],
						ls->parameter[POLYGON_NUMBER_OF_POINTS],
						ls->parameter[POLYGON_ROTATION]);
				draw_fill (cairoTarget, drawMode, selectionInfo, image, net);
			}
			break;
		case GERBV_APTYPE_MACRO_MOIRE: {
			gdouble diameter, diameterDifference;
			int circleIndex;

			cairo_translate (cairoTarget, ls->parameter[MOIRE_CENTER_X],
					ls->parameter[MOIRE_CENTER_Y]);
			cairo_rotate (cairoTarget,
					DEG2RAD(ls->parameter[MOIRE_ROTATION]));
			diameter = ls->parameter[MOIRE_OUTSIDE_DIAMETER]
				 - ls->parameter[MOIRE_CIRCLE_THICKNESS];
			diameterDifference = 2*(ls->parameter[MOIRE_GAP_WIDTH]
						+ ls->parameter[MOIRE_CIRCLE_THICKNESS]);
			cairo_set_line_width (cairoTarget, ls->parameter[MOIRE_CIRCLE_THICKNESS]);

			for (circleIndex = 0;
					circleIndex < (int)ls->parameter[MOIRE_NUMBER_OF_CIRCLES];
					circleIndex++) {
				gdouble currentDiameter = diameter - diameterDifference * (float) circleIndex;

				if (currentDiameter >= 0) {
					gerbv_draw_circle (cairoTarget, currentDiameter);
					draw_stroke (cairoTarget, drawMode, selectionInfo, image, net);
				}
			}

			gdouble crosshairRadius = ls->parameter[MOIRE_CROSSHAIR_LENGTH] / 2.0;

			cairo_set_line_width (cairoTarget, ls->parameter[MOIRE_CROSSHAIR_THICKNESS]);
			cairo_move_to (cairoTarget, -crosshairRadius, 0);
			cairo_line_to (cairoTarget, crosshairRadius, 0);
			cairo_move_to (cairoTarget, 0, -crosshairRadius);
			cairo_line_to (cairoTarget, 0, crosshairRadius);
			draw_stroke (cairoTarget, drawMode, selectionInfo, image, net);
			break;
		}
		case GERBV_APTYPE_MACRO_THERMAL: {
			gint i;
			gdouble startAngle1, startAngle2, endAngle1, endAngle2;

			cairo_translate (cairoTarget, ls->parameter[THERMAL_CENTER_X],
					ls->parameter[THERMAL_CENTER_Y]);
			cairo_rotate (cairoTarget,
				DEG2RAD(ls->parameter[THERMAL_ROTATION]));
			startAngle1 = asin (ls->parameter[THERMAL_CROSSHAIR_THICKNESS]/ls->parameter[THERMAL_INSIDE_DIAMETER]);
			endAngle1 = M_PI_2 - startAngle1;
			endAngle2 = asin (ls->parameter[THERMAL_CROSSHAIR_THICKNESS]/ls->parameter[THERMAL_OUTSIDE_DIAMETER]);
			startAngle2 = M_PI_2 - endAngle2;

			for (i = 0; i < 4; i++) {
				cairo_arc (cairoTarget, 0, 0,
						ls->parameter[THERMAL_INSIDE_DIAMETER]/2.0,
						startAngle1, endAngle1);
				cairo_arc_negative (cairoTarget, 0, 0,
						ls->parameter[THERMAL_OUTSIDE_DIAMETER]/2.0,
						startAngle2, endAngle2);
				draw_fill (cairoTarget, drawMode, selectionInfo, image, net);
				cairo_rotate (cairoTarget, M_PI_2);
			}
			break;
		}
		case GERBV_APTYPE_MACRO_LINE20:
			if (draw_update_macro_exposure (cairoTarget, clearOperator,
						darkOperator, ls->parameter[LINE20_EXPOSURE])) {
				gdouble cParameter = ls->parameter[LINE20_LINE_WIDTH];
				if (cParameter < pixelWidth)
					cParameter = pixelWidth;

				cairo_set_line_width (cairoTarget, cParameter);
				cairo_set_line_cap (cairoTarget, CAIRO_LINE_CAP_BUTT);
				cairo_rotate (cairoTarget,
						DEG2RAD(ls->parameter[LINE20_ROTATION]));
				cairo_move_to (cairoTarget, ls->parameter[LINE20_START_X],
						ls->parameter[LINE20_START_Y]);
				cairo_line_to (cairoTarget, ls->parameter[LINE20_END_X],
						ls->parameter[LINE20_END_Y]);
				draw_stroke (cairoTarget, drawMode, selectionInfo, image, net);
			}
			break;
		case GERBV_APTYPE_MACRO_LINE21: {
			gdouble halfWidth, halfHeight; 

			if (draw_update_macro_exposure (cairoTarget, clearOperator,
						darkOperator, ls->parameter[LINE21_EXPOSURE])) {
				halfWidth = ls->parameter[LINE21_WIDTH] / 2.0;
				halfHeight = ls->parameter[LINE21_HEIGHT] / 2.0;
				if (halfWidth < pixelWidth)
					halfWidth = pixelWidth;
				if (halfHeight < pixelWidth)
					halfHeight = pixelWidth;
				cairo_rotate (cairoTarget,
						DEG2RAD(ls->parameter[LINE21_ROTATION]));
				cairo_translate (cairoTarget, ls->parameter[LINE21_CENTER_X],
						ls->parameter[LINE21_CENTER_Y]);
				cairo_rectangle (cairoTarget, -halfWidth, -halfHeight,
						ls->parameter[LINE21_WIDTH], ls->parameter[LINE21_HEIGHT]);
				draw_fill (cairoTarget, drawMode, selectionInfo, image, net);
			}
			break;
		}
		case GERBV_APTYPE_MACRO_LINE22: {
			gdouble halfWidth, halfHeight;

			if (draw_update_macro_exposure (cairoTarget, clearOperator,
						darkOperator, ls->parameter[LINE22_EXPOSURE])) {
				halfWidth = ls->parameter[LINE22_WIDTH] / 2.0;
				halfHeight = ls->parameter[LINE22_HEIGHT] / 2.0;
				if (halfWidth < pixelWidth)
					halfWidth = pixelWidth;
				if (halfHeight < pixelWidth)
					halfHeight = pixelWidth;
				cairo_rotate (cairoTarget,
						DEG2RAD(ls->parameter[LINE22_ROTATION]));
				cairo_translate (cairoTarget,
						ls->parameter[LINE22_LOWER_LEFT_X],
						ls->parameter[LINE22_LOWER_LEFT_Y]);
				cairo_rectangle (cairoTarget, 0, 0,
						ls->parameter[LINE22_WIDTH],
						ls->parameter[LINE22_HEIGHT]);
				draw_fill (cairoTarget, drawMode,
						selectionInfo, image, net);
			}
			break;
		}
		default:
			handled = 0;
		}

		cairo_set_operator (cairoTarget, oldOperator);
		cairo_restore (cairoTarget);
		ls = ls->next;
	}

	if (usesClearPrimative) {
		cairo_pop_group_to_source (cairoTarget);
		cairo_paint (cairoTarget);
	}

	return handled;
}
Beispiel #8
0
	int lime_cairo_get_operator (value handle) {
		
		return cairo_get_operator ((cairo_t*)val_data (handle));
		
	}
Beispiel #9
0
	int lime_cairo_get_operator (double handle) {
		
		return cairo_get_operator ((cairo_t*)(intptr_t)handle);
		
	}
static PyObject *
pycairo_get_operator (PycairoContext *o)
{
    return PyInt_FromLong(cairo_get_operator (o->ctx));
}
Beispiel #11
0
int32_t Context::getOperator()
{
	return static_cast<int32_t>( cairo_get_operator( mCairo ) );
}
/* Query functions */
static VALUE
cr_get_operator (VALUE self)
{
  return INT2FIX (cairo_get_operator (_SELF));
}
Beispiel #13
0
gfxContext::GraphicsOperator gfxContext::CurrentOperator() const
{
    return (GraphicsOperator)cairo_get_operator(mCairo);
}
Beispiel #14
0
static int
cr_get_operator (lua_State *L) {
    cairo_t **obj = luaL_checkudata(L, 1, OOCAIRO_MT_NAME_CONTEXT);
    return operator_to_lua(L, cairo_get_operator(*obj));
}
/**
 * Try the direct path.
 * @param status the status returned by the callback, if we took the direct path
 * @return True if we took the direct path
 */
static cairo_bool_t
_draw_with_xlib_direct (cairo_t *cr,
                        Display *default_display,
                        cairo_xlib_drawing_callback callback,
                        void *closure,
                        int bounds_width, int bounds_height,
                        cairo_xlib_drawing_support_t capabilities)
{
    cairo_surface_t *target;
    Drawable d;
    cairo_matrix_t matrix;
    short offset_x, offset_y;
    cairo_bool_t needs_clip;
    XRectangle rectangles[MAX_STATIC_CLIP_RECTANGLES];
    int rect_count;
    double device_offset_x, device_offset_y;
    int max_rectangles;
    Screen *screen;
    Visual *visual;
    cairo_bool_t have_rectangular_clip;

    target = cairo_get_group_target (cr);
    cairo_surface_get_device_offset (target, &device_offset_x, &device_offset_y);
    d = cairo_xlib_surface_get_drawable (target);

    cairo_get_matrix (cr, &matrix);
    
    /* Check that the matrix is a pure translation */
    /* XXX test some approximation to == 1.0 here? */
    if (matrix.xx != 1.0 || matrix.yy != 1.0 || matrix.xy != 0.0 || matrix.yx != 0.0) {
        CAIRO_XLIB_DRAWING_NOTE("TAKING SLOW PATH: matrix not a pure translation\n");
        return False;
    }
    /* Check that the matrix translation offsets (adjusted for
       device offset) are integers */
    if (!_convert_coord_to_short (matrix.x0 + device_offset_x, &offset_x) ||
        !_convert_coord_to_short (matrix.y0 + device_offset_y, &offset_y)) {
        CAIRO_XLIB_DRAWING_NOTE("TAKING SLOW PATH: non-integer offset\n");
        return False;
    }
    
    max_rectangles = 0;
    if (capabilities & CAIRO_XLIB_DRAWING_SUPPORTS_CLIP_RECT) {
      max_rectangles = 1;
    }
    if (capabilities & CAIRO_XLIB_DRAWING_SUPPORTS_CLIP_LIST) {
      max_rectangles = MAX_STATIC_CLIP_RECTANGLES;
    }
    
    /* Check that the clip is rectangular and aligned on unit boundaries. */
    /* Temporarily set the matrix for _get_rectangular_clip. It's basically
       the identity matrix, but we must adjust for the fact that our
       offset-rect is in device coordinates. */
    cairo_identity_matrix (cr);
    cairo_translate (cr, -device_offset_x, -device_offset_y);
    have_rectangular_clip =
        _get_rectangular_clip (cr,
                               offset_x, offset_y, bounds_width, bounds_height,
                               &needs_clip,
                               rectangles, max_rectangles, &rect_count);
    cairo_set_matrix (cr, &matrix);
    if (!have_rectangular_clip) {
        CAIRO_XLIB_DRAWING_NOTE("TAKING SLOW PATH: unsupported clip\n");
        return False;
    }

    /* Stop now if everything is clipped out */
    if (needs_clip && rect_count == 0) {
        CAIRO_XLIB_DRAWING_NOTE("TAKING FAST PATH: all clipped\n");
        return True;
    }
      
    /* Check that the operator is OVER */
    if (cairo_get_operator (cr) != CAIRO_OPERATOR_OVER) {
        CAIRO_XLIB_DRAWING_NOTE("TAKING SLOW PATH: non-OVER operator\n");
        return False;
    }
    
    /* Check that the offset is supported */  
    if (!(capabilities & CAIRO_XLIB_DRAWING_SUPPORTS_OFFSET) &&
        (offset_x != 0 || offset_y != 0)) {
        CAIRO_XLIB_DRAWING_NOTE("TAKING SLOW PATH: unsupported offset\n");
        return False;
    }
    
    /* Check that the target surface is an xlib surface. Do this late because
       we might complete early above when when the object to be drawn is
       completely clipped out. */
    if (!d) {
        CAIRO_XLIB_DRAWING_NOTE("TAKING SLOW PATH: non-X surface\n");
        return False;
    }
    
    /* Check that the display is supported */  
    screen = cairo_xlib_surface_get_screen (target);
    if (!(capabilities & CAIRO_XLIB_DRAWING_SUPPORTS_ALTERNATE_SCREEN) &&
        screen != DefaultScreenOfDisplay (default_display)) {
        CAIRO_XLIB_DRAWING_NOTE("TAKING SLOW PATH: non-default display\n");
        return False;
    }
        
    /* Check that there is a visual */
    visual = cairo_xlib_surface_get_visual (target);
    if (!visual) {
        CAIRO_XLIB_DRAWING_NOTE("TAKING SLOW PATH: no Visual for surface\n");
        return False;
    }        
    /* Check that the visual is supported */
    if (!(capabilities & CAIRO_XLIB_DRAWING_SUPPORTS_NONDEFAULT_VISUAL) &&
        DefaultVisualOfScreen (screen) != visual) {
        CAIRO_XLIB_DRAWING_NOTE("TAKING SLOW PATH: non-default visual\n");
        return False;
    }
  
    /* we're good to go! */
    CAIRO_XLIB_DRAWING_NOTE("TAKING FAST PATH\n");
    cairo_surface_flush (target);
    callback (closure, screen, d, visual, offset_x, offset_y, rectangles,
              needs_clip ? rect_count : 0);
    cairo_surface_mark_dirty (target);
    return True;
}