From 4eb0e063bcd34c21b737023aa6ed5baed80658d1 Mon Sep 17 00:00:00 2001 From: jaseg Date: Sun, 13 Jun 2021 15:00:17 +0200 Subject: Repo re-org, make gerberex tests run --- gerbonara/gerber/render/render.py | 246 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 gerbonara/gerber/render/render.py (limited to 'gerbonara/gerber/render/render.py') diff --git a/gerbonara/gerber/render/render.py b/gerbonara/gerber/render/render.py new file mode 100644 index 0000000..580a7ea --- /dev/null +++ b/gerbonara/gerber/render/render.py @@ -0,0 +1,246 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +# copyright 2014 Hamilton Kibbe +# Modified from code by Paulo Henrique Silva + +# 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. +""" +Rendering +============ +**Gerber (RS-274X) and Excellon file rendering** + +Render Gerber and Excellon files to a variety of formats. The render module +currently supports SVG rendering using the `svgwrite` library. +""" + + +from ..primitives import * +from ..gerber_statements import (CommentStmt, UnknownStmt, EofStmt, ParamStmt, + CoordStmt, ApertureStmt, RegionModeStmt, + QuadrantModeStmt,) + + +class GerberContext(object): + """ Gerber rendering context base class + + Provides basic functionality and API for rendering gerber files. Medium- + specific renderers should subclass GerberContext and implement the drawing + functions. Colors are stored internally as 32-bit RGB and may need to be + converted to a native format in the rendering subclass. + + Attributes + ---------- + units : string + Measurement units. 'inch' or 'metric' + + color : tuple (, , ) + Color used for rendering as a tuple of normalized (red, green, blue) + values. + + drill_color : tuple (, , ) + Color used for rendering drill hits. Format is the same as for `color`. + + background_color : tuple (, , ) + Color of the background. Used when exposing areas in 'clear' level + polarity mode. Format is the same as for `color`. + + alpha : float + Rendering opacity. Between 0.0 (transparent) and 1.0 (opaque.) + """ + + def __init__(self, units='inch'): + self._units = units + self._color = (0.7215, 0.451, 0.200) + self._background_color = (0.0, 0.0, 0.0) + self._drill_color = (0.0, 0.0, 0.0) + self._alpha = 1.0 + self._invert = False + self.ctx = None + + @property + def units(self): + return self._units + + @units.setter + def units(self, units): + if units not in ('inch', 'metric'): + raise ValueError('Units may be "inch" or "metric"') + self._units = units + + @property + def color(self): + return self._color + + @color.setter + def color(self, color): + if len(color) != 3: + raise TypeError('Color must be a tuple of R, G, and B values') + for c in color: + if c < 0 or c > 1: + raise ValueError('Channel values must be between 0.0 and 1.0') + self._color = color + + @property + def drill_color(self): + return self._drill_color + + @drill_color.setter + def drill_color(self, color): + if len(color) != 3: + raise TypeError('Drill color must be a tuple of R, G, and B values') + for c in color: + if c < 0 or c > 1: + raise ValueError('Channel values must be between 0.0 and 1.0') + self._drill_color = color + + @property + def background_color(self): + return self._background_color + + @background_color.setter + def background_color(self, color): + if len(color) != 3: + raise TypeError('Background color must be a tuple of R, G, and B values') + for c in color: + if c < 0 or c > 1: + raise ValueError('Channel values must be between 0.0 and 1.0') + self._background_color = color + + @property + def alpha(self): + return self._alpha + + @alpha.setter + def alpha(self, alpha): + if alpha < 0 or alpha > 1: + raise ValueError('Alpha must be between 0.0 and 1.0') + self._alpha = alpha + + @property + def invert(self): + return self._invert + + @invert.setter + def invert(self, invert): + self._invert = invert + + def render(self, primitive): + if not primitive: + return + + self.pre_render_primitive(primitive) + + color = self.color + if isinstance(primitive, Line): + self._render_line(primitive, color) + elif isinstance(primitive, Arc): + self._render_arc(primitive, color) + elif isinstance(primitive, Region): + self._render_region(primitive, color) + elif isinstance(primitive, Circle): + self._render_circle(primitive, color) + elif isinstance(primitive, Rectangle): + self._render_rectangle(primitive, color) + elif isinstance(primitive, Obround): + self._render_obround(primitive, color) + elif isinstance(primitive, Polygon): + self._render_polygon(primitive, color) + elif isinstance(primitive, Drill): + self._render_drill(primitive, self.color) + elif isinstance(primitive, Slot): + self._render_slot(primitive, self.color) + elif isinstance(primitive, AMGroup): + self._render_amgroup(primitive, color) + elif isinstance(primitive, Outline): + self._render_region(primitive, color) + elif isinstance(primitive, TestRecord): + self._render_test_record(primitive, color) + + self.post_render_primitive(primitive) + + def set_bounds(self, bounds, *args, **kwargs): + """Called by the renderer to set the extents of the file to render. + + Parameters + ---------- + bounds: Tuple[Tuple[float, float], Tuple[float, float]] + ( (x_min, x_max), (y_min, y_max) + """ + pass + + def paint_background(self): + pass + + def new_render_layer(self): + pass + + def flatten(self): + pass + + def pre_render_primitive(self, primitive): + """ + Called before rendering a primitive. Use the callback to perform some action before rendering + a primitive, for example adding a comment. + """ + return + + def post_render_primitive(self, primitive): + """ + Called after rendering a primitive. Use the callback to perform some action after rendering + a primitive + """ + return + + + def _render_line(self, primitive, color): + pass + + def _render_arc(self, primitive, color): + pass + + def _render_region(self, primitive, color): + pass + + def _render_circle(self, primitive, color): + pass + + def _render_rectangle(self, primitive, color): + pass + + def _render_obround(self, primitive, color): + pass + + def _render_polygon(self, primitive, color): + pass + + def _render_drill(self, primitive, color): + pass + + def _render_slot(self, primitive, color): + pass + + def _render_amgroup(self, primitive, color): + pass + + def _render_test_record(self, primitive, color): + pass + + +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 -- cgit