diff options
Diffstat (limited to 'gerber')
-rw-r--r-- | gerber/primitives.py | 17 | ||||
-rw-r--r-- | gerber/render/__init__.py | 2 | ||||
-rw-r--r-- | gerber/render/cairo_backend.py | 91 | ||||
-rw-r--r-- | gerber/render/svgwrite_backend.py | 6 |
4 files changed, 112 insertions, 4 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 new file mode 100644 index 0000000..df513bb --- /dev/null +++ b/gerber/render/cairo_backend.py @@ -0,0 +1,91 @@ +#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# Copyright 2014 Hamilton Kibbe <ham@hamiltonkib.be>
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from .render import GerberContext
+from operator import mul
+import cairocffi as cairo
+import math
+
+SCALE = 300.
+
+
+class GerberCairoContext(GerberContext):
+ def __init__(self, surface=None, size=(1000, 1000)):
+ GerberContext.__init__(self)
+ if surface is None:
+ self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
+ size[0], size[1])
+ else:
+ self.surface = surface
+ self.ctx = cairo.Context(self.surface)
+ self.size = size
+ self.ctx.translate(0, self.size[1])
+ self.scale = (SCALE,SCALE)
+ self.ctx.scale(1, -1)
+ self.apertures = {}
+ self.background = False
+
+ def set_bounds(self, bounds):
+ xbounds, ybounds = bounds
+ self.ctx.rectangle(SCALE * xbounds[0], SCALE * ybounds[0], SCALE * (xbounds[1]- xbounds[0]), SCALE * (ybounds[1] - ybounds[0]))
+ self.ctx.set_source_rgb(0,0,0)
+ self.ctx.fill()
+
+ 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)
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) |