summaryrefslogtreecommitdiff
path: root/gerber/render
diff options
context:
space:
mode:
authorHamilton Kibbe <hamilton.kibbe@gmail.com>2016-01-01 12:25:38 -0500
committerHamilton Kibbe <hamilton.kibbe@gmail.com>2016-01-01 12:25:38 -0500
commit6a005436b475e3517fd6a583473b60e601bcc661 (patch)
tree5678cff7ba877e9c93ea63445f081fd0430f8b4b /gerber/render
parent5430fa6738b74f324c47c947477dd5b779db5d1c (diff)
downloadgerbonara-6a005436b475e3517fd6a583473b60e601bcc661.tar.gz
gerbonara-6a005436b475e3517fd6a583473b60e601bcc661.tar.bz2
gerbonara-6a005436b475e3517fd6a583473b60e601bcc661.zip
Refactor a little
pulled all rendering stuff out of the pcb/layer objects
Diffstat (limited to 'gerber/render')
-rw-r--r--gerber/render/cairo_backend.py96
-rw-r--r--gerber/render/render.py10
-rw-r--r--gerber/render/theme.py17
3 files changed, 65 insertions, 58 deletions
diff --git a/gerber/render/cairo_backend.py b/gerber/render/cairo_backend.py
index c3e9ac2..4e71e75 100644
--- a/gerber/render/cairo_backend.py
+++ b/gerber/render/cairo_backend.py
@@ -21,7 +21,8 @@ from operator import mul
import math
import tempfile
-from .render import GerberContext
+from .render import GerberContext, RenderSettings
+from .theme import THEMES
from ..primitives import *
try:
@@ -41,6 +42,15 @@ class GerberCairoContext(GerberContext):
self.mask_ctx = None
self.origin_in_inch = None
self.size_in_inch = None
+ self._xform_matrix = None
+
+ @property
+ def origin_in_pixels(self):
+ return tuple(map(mul, self.origin_in_inch, self.scale)) if self.origin_in_inch is not None else (0.0, 0.0)
+
+ @property
+ def size_in_pixels(self):
+ return tuple(map(mul, self.size_in_inch, self.scale)) if self.size_in_inch is not None else (0.0, 0.0)
def set_bounds(self, bounds, new_surface=False):
origin_in_inch = (bounds[0][0], bounds[1][0])
@@ -60,34 +70,56 @@ class GerberCairoContext(GerberContext):
self.mask_ctx.set_fill_rule(cairo.FILL_RULE_EVEN_ODD)
self.mask_ctx.scale(1, -1)
self.mask_ctx.translate(-(origin_in_inch[0] * self.scale[0]), (-origin_in_inch[1]*self.scale[0]) - size_in_pixels[1])
+ self._xform_matrix = cairo.Matrix(xx=1.0, yy=-1.0, x0=-self.origin_in_pixels[0], y0=self.size_in_pixels[1] + self.origin_in_pixels[1])
- def render_layers(self, layers, filename):
+ def render_layers(self, layers, filename, theme=THEMES['default']):
""" Render a set of layers
"""
self.set_bounds(layers[0].bounds, True)
self._paint_background(True)
for layer in layers:
- self._render_layer(layer)
+ self._render_layer(layer, theme)
self.dump(filename)
- @property
- def origin_in_pixels(self):
- return tuple(map(mul, self.origin_in_inch, self.scale)) if self.origin_in_inch is not None else (0.0, 0.0)
+ def dump(self, filename):
+ """ Save image as `filename`
+ """
+ is_svg = filename.lower().endswith(".svg")
+ if is_svg:
+ self.surface.finish()
+ self.surface_buffer.flush()
+ with open(filename, "w") as f:
+ self.surface_buffer.seek(0)
+ f.write(self.surface_buffer.read())
+ f.flush()
+ else:
+ self.surface.write_to_png(filename)
- @property
- def size_in_pixels(self):
- return tuple(map(mul, self.size_in_inch, self.scale)) if self.size_in_inch is not None else (0.0, 0.0)
+ def dump_str(self):
+ """ Return a string containing the rendered image.
+ """
+ fobj = StringIO()
+ self.surface.write_to_png(fobj)
+ return fobj.getvalue()
+
+ def dump_svg_str(self):
+ """ Return a string containg the rendered SVG.
+ """
+ self.surface.finish()
+ self.surface_buffer.flush()
+ return self.surface_buffer.read()
- def _render_layer(self, layer):
- self.color = layer.settings.color
- self.alpha = layer.settings.alpha
- self.invert = layer.settings.invert
- if layer.settings.mirror:
+ def _render_layer(self, layer, theme=THEMES['default']):
+ settings = theme.get(layer.layer_class, RenderSettings())
+ self.color = settings.color
+ self.alpha = settings.alpha
+ self.invert = settings.invert
+ if settings.mirror:
raise Warning('mirrored layers aren\'t supported yet...')
if self.invert:
self._clear_mask()
- for p in layer.primitives:
- self.render(p)
+ for prim in layer.primitives:
+ self.render(prim)
if self.invert:
self._render_mask()
@@ -209,10 +241,11 @@ class GerberCairoContext(GerberContext):
def _render_test_record(self, primitive, color):
position = tuple(map(add, primitive.position, self.origin_in_inch))
+ self.ctx.set_operator(cairo.OPERATOR_OVER)
self.ctx.select_font_face('monospace', cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
self.ctx.set_font_size(13)
self._render_circle(Circle(position, 0.015), color)
- self.ctx.set_source_rgb(*color)
+ self.ctx.set_source_rgba(*color, alpha=self.alpha)
self.ctx.set_operator(cairo.OPERATOR_OVER if primitive.level_polarity == "dark" else cairo.OPERATOR_CLEAR)
self.ctx.move_to(*[self.scale[0] * (coord + 0.015) for coord in position])
self.ctx.scale(1, -1)
@@ -227,8 +260,7 @@ class GerberCairoContext(GerberContext):
def _render_mask(self):
self.ctx.set_operator(cairo.OPERATOR_OVER)
ptn = cairo.SurfacePattern(self.mask)
- ptn.set_matrix(cairo.Matrix(xx=1.0, yy=-1.0, x0=-self.origin_in_pixels[0],
- y0=self.size_in_pixels[1] + self.origin_in_pixels[1]))
+ ptn.set_matrix(self._xform_matrix)
self.ctx.set_source(ptn)
self.ctx.paint()
@@ -237,29 +269,3 @@ class GerberCairoContext(GerberContext):
self.bg = True
self.ctx.set_source_rgba(*self.background_color, alpha=1.0)
self.ctx.paint()
-
- def dump(self, filename):
- is_svg = filename.lower().endswith(".svg")
- if is_svg:
- self.surface.finish()
- self.surface_buffer.flush()
- with open(filename, "w") as f:
- self.surface_buffer.seek(0)
- f.write(self.surface_buffer.read())
- f.flush()
- else:
- self.surface.write_to_png(filename)
-
- def dump_str(self):
- """ Return a string containing the rendered image.
- """
- fobj = StringIO()
- self.surface.write_to_png(fobj)
- return fobj.getvalue()
-
- def dump_svg_str(self):
- """ Return a string containg the rendered SVG.
- """
- self.surface.finish()
- self.surface_buffer.flush()
- return self.surface_buffer.read()
diff --git a/gerber/render/render.py b/gerber/render/render.py
index c76ead5..6af8bf1 100644
--- a/gerber/render/render.py
+++ b/gerber/render/render.py
@@ -183,8 +183,10 @@ class GerberContext(object):
pass
-class Renderable(object):
- def __init__(self, settings=None):
- self.settings = settings
- self.primitives = []
+class RenderSettings(object):
+ def __init__(self, color=(0.0, 0.0, 0.0), alpha=1.0, invert=False, mirror=False):
+ self.color = color
+ self.alpha = alpha
+ self.invert = invert
+ self.mirror = mirror
diff --git a/gerber/render/theme.py b/gerber/render/theme.py
index 5978831..e538df8 100644
--- a/gerber/render/theme.py
+++ b/gerber/render/theme.py
@@ -16,6 +16,8 @@
# limitations under the License.
+from .render import RenderSettings
+
COLORS = {
'black': (0.0, 0.0, 0.0),
'white': (1.0, 1.0, 1.0),
@@ -33,14 +35,6 @@ COLORS = {
}
-class RenderSettings(object):
- def __init__(self, color, alpha=1.0, invert=False, mirror=False):
- self.color = color
- self.alpha = alpha
- self.invert = invert
- self.mirror = mirror
-
-
class Theme(object):
def __init__(self, name=None, **kwargs):
self.name = 'Default' if name is None else name
@@ -57,8 +51,13 @@ class Theme(object):
def __getitem__(self, key):
return getattr(self, key)
+ def get(self, key, noneval=None):
+ val = getattr(self, key)
+ return val if val is not None else noneval
+
+
THEMES = {
- 'Default': Theme(),
+ 'default': Theme(),
'OSH Park': Theme(name='OSH Park',
top=RenderSettings(COLORS['enig copper']),
bottom=RenderSettings(COLORS['enig copper']),