diff options
author | Hamilton Kibbe <hamilton.kibbe@gmail.com> | 2014-10-26 22:35:56 -0400 |
---|---|---|
committer | Hamilton Kibbe <hamilton.kibbe@gmail.com> | 2014-10-26 22:36:47 -0400 |
commit | 0437e4198a0ff5d909d4321768341a173930904c (patch) | |
tree | 6f0959a0e5ccc9b101009f4f94f5d826d4500c10 | |
parent | c285e6b014f38716b257b6cc77245c37ac62b4f1 (diff) | |
download | gerbonara-0437e4198a0ff5d909d4321768341a173930904c.tar.gz gerbonara-0437e4198a0ff5d909d4321768341a173930904c.tar.bz2 gerbonara-0437e4198a0ff5d909d4321768341a173930904c.zip |
cairo working
-rw-r--r-- | gerber/primitives.py | 17 | ||||
-rw-r--r-- | gerber/render/__init__.py | 2 | ||||
-rw-r--r-- | gerber/render/cairo_backend.py | 213 | ||||
-rw-r--r-- | gerber/render/svgwrite_backend.py | 6 |
4 files changed, 123 insertions, 115 deletions
diff --git a/gerber/primitives.py b/gerber/primitives.py index 670b758..b3869e1 100644 --- a/gerber/primitives.py +++ b/gerber/primitives.py @@ -171,6 +171,23 @@ class Obround(Primitive): max_y = self.upper_right[1]
return ((min_x, max_x), (min_y, max_y))
+ @property
+ def subshapes(self):
+ if self.orientation == 'vertical':
+ circle1 = Circle((self.position[0], self.position[1] +
+ (self.height-self.width) / 2.), self.width)
+ circle2 = Circle((self.position[0], self.position[1] -
+ (self.height-self.width) / 2.), self.width)
+ rect = Rectangle(self.position, self.width,
+ (self.height - self.width))
+ else:
+ circle1 = Circle((self.position[0] - (self.height - self.width) / 2.,
+ self.position[1]), self.height)
+ circle2 = Circle((self.position[0] - (self.height - self.width) / 2.,
+ self.position[1]), self.height)
+ rect = Rectangle(self.position, (self.width - self.height),
+ self.height)
+ return {'circle1': circle1, 'circle2': circle2, 'rectangle': rect}
class Polygon(Primitive):
"""
diff --git a/gerber/render/__init__.py b/gerber/render/__init__.py index 0d3527b..b4af4ad 100644 --- a/gerber/render/__init__.py +++ b/gerber/render/__init__.py @@ -25,4 +25,4 @@ SVG is the only supported format. from svgwrite_backend import GerberSvgContext - +from cairo_backend import GerberCairoContext 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 diff --git a/gerber/render/svgwrite_backend.py b/gerber/render/svgwrite_backend.py index d9456a5..2df87b3 100644 --- a/gerber/render/svgwrite_backend.py +++ b/gerber/render/svgwrite_backend.py @@ -148,8 +148,8 @@ class GerberSvgContext(GerberContext): self.dwg.add(c2) self.dwg.add(rect) - def _render_drill(self, primitive, color): - center = map(mul, primitive.position, self.scale) - hit = self.dwg.circle(center=center, r=SCALE * primitive.radius, + def _render_drill(self, circle, color): + center = map(mul, circle.position, self.scale) + hit = self.dwg.circle(center=center, r=SCALE * circle.radius, fill=svg_color(color)) self.dwg.add(hit) |