diff options
Diffstat (limited to 'gerber/render/cairo_backend.py')
-rw-r--r-- | gerber/render/cairo_backend.py | 213 |
1 files changed, 102 insertions, 111 deletions
diff --git a/gerber/render/cairo_backend.py b/gerber/render/cairo_backend.py index d5efc2d..f5e5aca 100644 --- a/gerber/render/cairo_backend.py +++ b/gerber/render/cairo_backend.py @@ -16,71 +16,71 @@ # limitations under the License.
from .render import GerberContext
-from .apertures import Circle, Rect, Obround, Polygon
-import cairo
+from operator import mul
+import cairocffi as cairo
import math
-SCALE = 200.
-
-class CairoCircle(Circle):
- def line(self, ctx, x, y, color=(184/255., 115/255., 51/255.)):
- ctx.set_source_rgb (*color)
- ctx.set_line_width(self.diameter * SCALE)
- ctx.set_line_cap(cairo.LINE_CAP_ROUND)
- ctx.line_to(x * SCALE, y * SCALE)
- ctx.stroke()
-
- def arc(self, ctx, x, y, i, j, direction, color=(184/255., 115/255., 51/255.)):
- ctx_x, ctx_y = ctx.get_current_point()
-
- # Do the math
- center = ((x + i) * SCALE, (y + j) * SCALE)
- radius = math.sqrt(math.pow(ctx_x - center[0], 2) + math.pow(ctx_y - center[1], 2))
- delta_x0 = (ctx_x - center[0])
- delta_y0 = (ctx_y - center[1])
- delta_x1 = (x * SCALE - center[0])
- delta_y1 = (y * SCALE - center[1])
- theta0 = math.atan2(delta_y0, delta_x0)
- theta1 = math.atan2(delta_y1, delta_x1)
- # Draw the arc
- ctx.set_source_rgb (*color)
- ctx.set_line_width(self.diameter * SCALE)
- ctx.set_line_cap(cairo.LINE_CAP_ROUND)
- if direction == 'clockwise':
- ctx.arc_negative(center[0], center[1], radius, theta0, theta1)
- else:
- ctx.arc(center[0], center[1], radius, theta0, theta1)
- ctx.stroke()
-
- def flash(self, ctx, x, y, color=(184/255., 115/255., 51/255.)):
- ctx.set_source_rgb (*color)
- ctx.set_line_width(0)
- ctx.arc(x * SCALE, y * SCALE, (self.diameter/2.) * SCALE, 0, 2 * math.pi)
- ctx.fill()
-
-class CairoRect(Rect):
- def line(self, ctx, x, y, color=(184/255., 115/255., 51/255.)):
- ctx.set_source_rgb (*color)
- ctx.set_line_width(self.diameter * SCALE)
- ctx.set_line_cap(cairo.LINE_CAP_SQUARE)
- ctx.line_to(x * SCALE, y * SCALE)
- ctx.stroke()
-
- def flash(self, ctx, x, y, color=(184/255., 115/255., 51/255.)):
- xsize, ysize = self.size
- ctx.set_source_rgb (*color)
- ctx.set_line_width(0)
- x0 = SCALE * (x - (xsize / 2.))
- y0 = SCALE * (y - (ysize / 2.))
-
- ctx.rectangle(x0,y0,SCALE * xsize, SCALE * ysize)
- ctx.fill()
-
+SCALE = 300.
+
+
+#class CairoCircle(Circle):
+# def line(self, ctx, x, y, color=(184/255., 115/255., 51/255.)):
+# ctx.set_source_rgb (*color)
+# ctx.set_line_width(self.diameter * SCALE)
+# ctx.set_line_cap(cairo.LINE_CAP_ROUND)
+# ctx.line_to(x * SCALE, y * SCALE)
+# ctx.stroke()
+#
+# def arc(self, ctx, x, y, i, j, direction, color=(184/255., 115/255., 51/255.)):
+# ctx_x, ctx_y = ctx.get_current_point()
+#
+# # Do the math
+# center = ((x + i) * SCALE, (y + j) * SCALE)
+# radius = math.sqrt(math.pow(ctx_x - center[0], 2) + math.pow(ctx_y - center[1], 2))
+# delta_x0 = (ctx_x - center[0])
+# delta_y0 = (ctx_y - center[1])
+# delta_x1 = (x * SCALE - center[0])
+# delta_y1 = (y * SCALE - center[1])
+# theta0 = math.atan2(delta_y0, delta_x0)
+# theta1 = math.atan2(delta_y1, delta_x1)
+# # Draw the arc
+# ctx.set_source_rgb (*color)
+# ctx.set_line_width(self.diameter * SCALE)
+# ctx.set_line_cap(cairo.LINE_CAP_ROUND)
+# if direction == 'clockwise':
+# ctx.arc_negative(center[0], center[1], radius, theta0, theta1)
+# else:
+# ctx.arc(center[0], center[1], radius, theta0, theta1)
+# ctx.stroke()
+#
+# def flash(self, ctx, x, y, color=(184/255., 115/255., 51/255.)):
+# ctx.set_source_rgb (*color)
+# ctx.set_line_width(0)
+# ctx.arc(x * SCALE, y * SCALE, (self.diameter/2.) * SCALE, 0, 2 * math.pi)
+# ctx.fill()
+#
+#class CairoRect(Rect):
+# def line(self, ctx, x, y, color=(184/255., 115/255., 51/255.)):
+# ctx.set_source_rgb (*color)
+# ctx.set_line_width(self.diameter * SCALE)
+# ctx.set_line_cap(cairo.LINE_CAP_SQUARE)
+# ctx.line_to(x * SCALE, y * SCALE)
+# ctx.stroke()
+#
+# def flash(self, ctx, x, y, color=(184/255., 115/255., 51/255.)):
+# xsize, ysize = self.size
+# ctx.set_source_rgb (*color)
+# ctx.set_line_width(0)
+# x0 = SCALE * (x - (xsize / 2.))
+# y0 = SCALE * (y - (ysize / 2.))
+#
+# ctx.rectangle(x0,y0,SCALE * xsize, SCALE * ysize)
+# ctx.fill()
+#
class GerberCairoContext(GerberContext):
- def __init__(self, surface=None, size=(1000, 1000),
- color='rgb(184, 115, 51)', drill_color='gray'):
+ def __init__(self, surface=None, size=(1000, 1000)):
GerberContext.__init__(self)
if surface is None:
self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
@@ -90,10 +90,9 @@ class GerberCairoContext(GerberContext): self.ctx = cairo.Context(self.surface)
self.size = size
self.ctx.translate(0, self.size[1])
- self.ctx.scale(1,-1)
+ self.scale = (SCALE,SCALE)
+ self.ctx.scale(1, -1)
self.apertures = {}
- self.color = color
- self.drill_color = drill_color
self.background = False
def set_bounds(self, bounds):
@@ -102,55 +101,47 @@ class GerberCairoContext(GerberContext): self.ctx.set_source_rgb(0,0,0)
self.ctx.fill()
- def define_aperture(self, d, shape, modifiers):
- aperture = None
- if shape == 'C':
- aperture = CairoCircle(diameter=float(modifiers[0][0]))
- elif shape == 'R':
- aperture = CairoRect(size=modifiers[0][0:2])
- self.apertures[d] = aperture
-
- def stroke(self, x, y, i, j):
- super(GerberCairoContext, self).stroke(x, y, i, j)
-
- if self.interpolation == 'linear':
- self.line(x, y)
- elif self.interpolation == 'arc':
- self.arc(x, y, i, j)
- self.move(x,y)
-
- def line(self, x, y):
- x, y = self.resolve(x, y)
- ap = self.apertures.get(self.aperture, None)
- if ap is None:
- return
- ap.line(self.ctx, x, y)
-
- def arc(self, x, y, i, j):
- super(GerberCairoContext, self).arc(x, y, i, j)
- ap = self.apertures.get(self.aperture, None)
- if ap is None:
- return
- ap.arc(self.ctx, x, y, i, j, self.direction)
-
-
- def flash(self, x, y):
- x, y = self.resolve(x, y)
- ap = self.apertures.get(self.aperture, None)
- if ap is None:
- return
- ap.flash(self.ctx, x, y)
- self.move(x, y, resolve=False)
-
- def move(self, x, y, resolve=True):
- super(GerberCairoContext, self).move(x, y, resolve)
- if x is None:
- x = self.x
- if y is None:
- y = self.y
- if self.x is not None and self.y is not None:
- self.ctx.move_to(x * SCALE, y * SCALE)
+ def _render_line(self, line, color):
+ start = map(mul, line.start, self.scale)
+ end = map(mul, line.end, self.scale)
+ self.ctx.set_source_rgb (*color)
+ self.ctx.set_line_width(line.width * SCALE)
+ self.ctx.set_line_cap(cairo.LINE_CAP_ROUND)
+ self.ctx.move_to(*start)
+ self.ctx.line_to(*end)
+ self.ctx.stroke()
+
+ def _render_region(self, region, color):
+ points = [tuple(map(mul, point, self.scale)) for point in region.points]
+ self.ctx.set_source_rgb (*color)
+ self.ctx.set_line_width(0)
+ self.ctx.move_to(*points[0])
+ for point in points[1:]:
+ self.ctx.move_to(*point)
+ self.ctx.fill()
+
+ def _render_circle(self, circle, color):
+ center = map(mul, circle.position, self.scale)
+ self.ctx.set_source_rgb (*color)
+ self.ctx.set_line_width(0)
+ self.ctx.arc(*center, radius=circle.radius * SCALE, angle1=0, angle2=2 * math.pi)
+ self.ctx.fill()
+
+ def _render_rectangle(self, rectangle, color):
+ ll = map(mul, rectangle.lower_left, self.scale)
+ width, height = tuple(map(mul, (rectangle.width, rectangle.height), map(abs, self.scale)))
+ self.ctx.set_source_rgb (*color)
+ self.ctx.set_line_width(0)
+ self.ctx.rectangle(*ll,width=width, height=height)
+ self.ctx.fill()
+
+ def _render_obround(self, obround, color):
+ self._render_circle(obround.subshapes['circle1'], color)
+ self._render_circle(obround.subshapes['circle2'], color)
+ self._render_rectangle(obround.subshapes['rectangle'], color)
+ def _render_drill(self, circle, color):
+ self._render_circle(circle, color)
def dump(self, filename):
self.surface.write_to_png(filename)
\ No newline at end of file |