summaryrefslogtreecommitdiff
path: root/gerbonara/gerber
diff options
context:
space:
mode:
Diffstat (limited to 'gerbonara/gerber')
-rw-r--r--gerbonara/gerber/cam.py42
-rw-r--r--gerbonara/gerber/graphic_objects.py6
-rw-r--r--gerbonara/gerber/graphic_primitives.py8
-rw-r--r--gerbonara/gerber/rs274x.py24
-rw-r--r--gerbonara/gerber/tests/resources/fritzing/combined.gbl9
-rw-r--r--gerbonara/gerber/tests/resources/fritzing/combined.gbo9
-rw-r--r--gerbonara/gerber/tests/resources/fritzing/combined.gbs10
-rw-r--r--gerbonara/gerber/tests/resources/fritzing/combined.gm19
-rw-r--r--gerbonara/gerber/tests/resources/fritzing/combined.gtl9
-rw-r--r--gerbonara/gerber/tests/resources/fritzing/combined.gto9
-rw-r--r--gerbonara/gerber/tests/resources/fritzing/combined.gts9
-rw-r--r--gerbonara/gerber/tests/test_rs274x.py6
12 files changed, 93 insertions, 57 deletions
diff --git a/gerbonara/gerber/cam.py b/gerbonara/gerber/cam.py
index 7283316..ccfa7a2 100644
--- a/gerbonara/gerber/cam.py
+++ b/gerbonara/gerber/cam.py
@@ -21,6 +21,7 @@ from copy import deepcopy
from .utils import LengthUnit, MM, Inch, Tag
from . import graphic_primitives as gp
+from . import graphic_objects as go
@dataclass
class FileSettings:
@@ -181,24 +182,37 @@ class CamFile:
w = 1.0 if math.isclose(w, 0.0) else w
h = 1.0 if math.isclose(h, 0.0) else h
- primitives = [ prim for obj in self.objects for prim in obj.to_primitives(unit=svg_unit) ]
view = tag('sodipodi:namedview', [], id='namedview1', pagecolor=bg,
inkscape__document_units=svg_unit.shorthand)
+
tags = []
polyline = None
- for primitive in primitives:
- if isinstance(primitive, gp.Line):
- if not polyline:
- polyline = gp.Polyline(primitive)
- else:
- if not polyline.append(primitive):
- tags.append(polyline.to_svg(tag, fg, bg))
- polyline = gp.Polyline(primitive)
- else:
- if polyline:
- tags.append(polyline.to_svg(tag, fg, bg))
- polyline = None
- tags.append(primitive.to_svg(tag, fg, bg))
+ for i, obj in enumerate(self.objects):
+ #if isinstance(obj, go.Flash):
+ # if polyline:
+ # tags.append(polyline.to_svg(tag, fg, bg))
+ # polyline = None
+
+ # mask_tags = [ prim.to_svg(tag, 'white', 'black') for prim in obj.to_primitives(unit=svg_unit) ]
+ # mask_tags.insert(0, tag('rect', width='100%', height='100%', fill='black'))
+ # mask_id = f'mask{i}'
+ # tag('mask', mask_tags, id=mask_id)
+ # tag('rect', width='100%', height='100%', mask='url(#{mask_id})', fill=fg)
+
+ #else:
+ for primitive in obj.to_primitives(unit=svg_unit):
+ if isinstance(primitive, gp.Line):
+ if not polyline:
+ polyline = gp.Polyline(primitive)
+ else:
+ if not polyline.append(primitive):
+ tags.append(polyline.to_svg(tag, fg, bg))
+ polyline = gp.Polyline(primitive)
+ else:
+ if polyline:
+ tags.append(polyline.to_svg(tag, fg, bg))
+ polyline = None
+ tags.append(primitive.to_svg(tag, fg, bg))
if polyline:
tags.append(polyline.to_svg(tag, fg, bg))
diff --git a/gerbonara/gerber/graphic_objects.py b/gerbonara/gerber/graphic_objects.py
index 131bf57..98fc094 100644
--- a/gerbonara/gerber/graphic_objects.py
+++ b/gerbonara/gerber/graphic_objects.py
@@ -154,6 +154,10 @@ class Region(GerberObject):
def to_statements(self, gs):
yield from gs.set_polarity(self.polarity_dark)
yield 'G36*'
+ # Repeat interpolation mode at start of region statement to work around gerbv bug. Without this, gerbv will
+ # not display a region consisting of only a single arc.
+ # TODO report gerbv issue upstream
+ yield gs.interpolation_mode_statement() + '*'
yield from gs.set_current_point(self.poly.outline[0], unit=self.unit)
@@ -266,7 +270,7 @@ class Arc(GerberObject):
cy : Length(float)
clockwise : bool
aperture : object
-
+
def _with_offset(self, dx, dy):
return replace(self, x1=self.x1+dx, y1=self.y1+dy, x2=self.x2+dx, y2=self.y2+dy)
diff --git a/gerbonara/gerber/graphic_primitives.py b/gerbonara/gerber/graphic_primitives.py
index 401156e..cd5e70c 100644
--- a/gerbonara/gerber/graphic_primitives.py
+++ b/gerbonara/gerber/graphic_primitives.py
@@ -65,13 +65,13 @@ class Obround(GraphicPrimitive):
def to_line(self):
if self.w > self.h:
- w, a, b = self.h, self.w, 0
+ w, a, b = self.h, self.w-self.h, 0
else:
- w, a, b = self.w, 0, self.h
+ w, a, b = self.w, 0, self.h-self.w
return Line(
*rotate_point(self.x-a/2, self.y-b/2, self.rotation, self.x, self.y),
*rotate_point(self.x+a/2, self.y+b/2, self.rotation, self.x, self.y),
- w)
+ w, polarity_dark=self.polarity_dark)
def bounding_box(self):
return self.to_line().bounding_box()
@@ -399,5 +399,5 @@ class RegularPolygon(GraphicPrimitive):
return self.to_arc_poly().bounding_box()
def to_svg(self, tag, fg, bg):
- return self.to_arc_poly().to_svg(tag, color, fg, bg)
+ return self.to_arc_poly().to_svg(tag, fg, bg)
diff --git a/gerbonara/gerber/rs274x.py b/gerbonara/gerber/rs274x.py
index db93fb5..2e04d13 100644
--- a/gerbonara/gerber/rs274x.py
+++ b/gerbonara/gerber/rs274x.py
@@ -470,7 +470,13 @@ class GraphicsState:
def set_interpolation_mode(self, mode):
if self.interpolation_mode != mode:
self.interpolation_mode = mode
- yield {InterpMode.LINEAR: 'G01', InterpMode.CIRCULAR_CW: 'G02', InterpMode.CIRCULAR_CCW: 'G03'}[mode]
+ yield self.interpolation_mode_statement()
+
+ def interpolation_mode_statement(self):
+ return {
+ InterpMode.LINEAR: 'G01',
+ InterpMode.CIRCULAR_CW: 'G02',
+ InterpMode.CIRCULAR_CCW: 'G03'}[self.interpolation_mode]
class GerberParser:
@@ -489,18 +495,18 @@ class GerberParser:
'allegro_format_spec': r"FS(?P<zero>(L|T|D))?(?P<notation>(A|I))[NG0-9]*X(?P<x>[0-7][0-7])Y(?P<y>[0-7][0-7])[DM0-9]*\*MO(?P<unit>IN|MM)",
'unit_mode': r"MO(?P<unit>(MM|IN))",
'format_spec': r"FS(?P<zero>(L|T|D))?(?P<notation>(A|I))[NG0-9]*X(?P<x>[0-7][0-7])Y(?P<y>[0-7][0-7])[DM0-9]*",
- 'allegro_legacy_params': r'IR(?P<rotation>[0-9]+)\*IP(?P<polarity>(POS|NEG))\*OF(A(?P<a>{DECIMAL}))?(B(?P<b>{DECIMAL}))?\*MI(A(?P<ma>0|1))?(B(?P<mb>0|1))?\*SF(A(?P<sa>{DECIMAL}))?(B(?P<sb>{DECIMAL}))?',
+ 'allegro_legacy_params': fr'^IR(?P<rotation>[0-9]+)\*IP(?P<polarity>(POS|NEG))\*OF(A(?P<a>{DECIMAL}))?(B(?P<b>{DECIMAL}))?\*MI(A(?P<ma>0|1))?(B(?P<mb>0|1))?\*SF(A(?P<sa>{DECIMAL}))?(B(?P<sb>{DECIMAL}))?',
'load_polarity': r"LP(?P<polarity>(D|C))",
# FIXME LM, LR, LS
'load_name': r"LN(?P<name>.*)",
'offset': fr"OF(A(?P<a>{DECIMAL}))?(B(?P<b>{DECIMAL}))?",
'include_file': r"IF(?P<filename>.*)",
- 'image_name': r"IN(?P<name>.*)",
- 'axis_selection': r"AS(?P<axes>AXBY|AYBX)",
- 'image_polarity': r"IP(?P<polarity>(POS|NEG))",
- 'image_rotation': fr"IR(?P<rotation>{NUMBER})",
- 'mirror_image': r"MI(A(?P<ma>0|1))?(B(?P<mb>0|1))?",
- 'scale_factor': fr"SF(A(?P<sa>{DECIMAL}))?(B(?P<sb>{DECIMAL}))?",
+ 'image_name': r"^IN(?P<name>.*)",
+ 'axis_selection': r"^AS(?P<axes>AXBY|AYBX)",
+ 'image_polarity': r"^IP(?P<polarity>(POS|NEG))",
+ 'image_rotation': fr"^IR(?P<rotation>{NUMBER})",
+ 'mirror_image': r"^MI(A(?P<ma>0|1))?(B(?P<mb>0|1))?",
+ 'scale_factor': fr"^SF(A(?P<sa>{DECIMAL}))?(B(?P<sb>{DECIMAL}))?",
'aperture_definition': fr"ADD(?P<number>\d+)(?P<shape>C|R|O|P|{NAME})(?P<modifiers>,[^,%]*)?$",
'aperture_macro': fr"AM(?P<name>{NAME})\*(?P<macro>[^%]*)",
'siemens_garbage': r'^ICAS$',
@@ -810,7 +816,7 @@ class GerberParser:
mirror = bool(int(match['ma'] or '0')), bool(int(match['mb'] or '1'))
if mirror != (False, False):
warnings.warn('Deprecated MI (mirror image) statement found. This deprecated since rev. I1 (Dec 2012).', DeprecationWarning)
- self.graphics_state.mirror = mirror
+ self.graphics_state.image_mirror = mirror
def _parse_scale_factor(self, match):
a = float(match['sa']) if match['sa'] else 1.0
diff --git a/gerbonara/gerber/tests/resources/fritzing/combined.gbl b/gerbonara/gerber/tests/resources/fritzing/combined.gbl
index ad7ca19..13b6118 100644
--- a/gerbonara/gerber/tests/resources/fritzing/combined.gbl
+++ b/gerbonara/gerber/tests/resources/fritzing/combined.gbl
@@ -1,3 +1,4 @@
+G04 file manually fixed for GerberTools #86 / #143*
%MOIN*%
%OFA0B0*%
%FSLAX23Y23*%
@@ -8487,7 +8488,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D29*
X01338Y00039D02*
X01444Y01876D03*
@@ -16936,7 +16937,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D38*
X02637Y00039D02*
X02743Y01876D03*
@@ -25385,7 +25386,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D47*
X02598Y02677D02*
X00761Y02783D03*
@@ -33827,4 +33828,4 @@ X02345Y03029D01*
G37*
D02*
G04 End of Copper0*
-M02* \ No newline at end of file
+M02*
diff --git a/gerbonara/gerber/tests/resources/fritzing/combined.gbo b/gerbonara/gerber/tests/resources/fritzing/combined.gbo
index 365bc71..fbb0103 100644
--- a/gerbonara/gerber/tests/resources/fritzing/combined.gbo
+++ b/gerbonara/gerber/tests/resources/fritzing/combined.gbo
@@ -1,3 +1,4 @@
+G04 file manually fixed for GerberTools #86 / #143*
%MOIN*%
%OFA0B0*%
%FSLAX23Y23*%
@@ -8633,7 +8634,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D21*
X01777Y02388D02*
X01786Y02388D01*
@@ -17260,7 +17261,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D22*
X03076Y02388D02*
X03085Y02388D01*
@@ -25887,7 +25888,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D23*
X00249Y03116D02*
X00249Y03125D01*
@@ -34507,4 +34508,4 @@ X02357Y02948D02*
X02357Y02949D01*
D02*
G04 End of Silk0*
-M02* \ No newline at end of file
+M02*
diff --git a/gerbonara/gerber/tests/resources/fritzing/combined.gbs b/gerbonara/gerber/tests/resources/fritzing/combined.gbs
index 737b8e4..72ac193 100644
--- a/gerbonara/gerber/tests/resources/fritzing/combined.gbs
+++ b/gerbonara/gerber/tests/resources/fritzing/combined.gbs
@@ -1,3 +1,5 @@
+G04 file was processed by a buggy GerberTools version.
+G04 file manually fixed for GerberTools #86 / #143*
%MOIN*%
%OFA0B0*%
%FSLAX23Y23*%
@@ -165,7 +167,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D28*
X01338Y00039D02*
X01751Y01768D03*
@@ -296,7 +298,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D36*
X02637Y00039D02*
X03049Y01768D03*
@@ -427,7 +429,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D44*
X02598Y02677D02*
X00869Y03090D03*
@@ -551,4 +553,4 @@ X01819Y03591D03*
X02019Y03591D03*
X02219Y03591D03*
G04 End of Mask0*
-M02* \ No newline at end of file
+M02*
diff --git a/gerbonara/gerber/tests/resources/fritzing/combined.gm1 b/gerbonara/gerber/tests/resources/fritzing/combined.gm1
index 4812d78..71a8a95 100644
--- a/gerbonara/gerber/tests/resources/fritzing/combined.gm1
+++ b/gerbonara/gerber/tests/resources/fritzing/combined.gm1
@@ -1,3 +1,4 @@
+G04 file manually fixed for GerberTools #86 / #143*
%MOIN*%
%OFA0B0*%
%FSLAX23Y23*%
@@ -2538,7 +2539,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D21*
X01443Y02598D02*
X01444Y02598D01*
@@ -5070,7 +5071,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D22*
X02742Y02598D02*
X02743Y02598D01*
@@ -7602,7 +7603,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D23*
X00039Y02781D02*
X00039Y02783D01*
@@ -10127,4 +10128,4 @@ X00040Y02781D01*
X00039Y02781D01*
D02*
G04 End of contour*
-M02* \ No newline at end of file
+M02*
diff --git a/gerbonara/gerber/tests/resources/fritzing/combined.gtl b/gerbonara/gerber/tests/resources/fritzing/combined.gtl
index 0689715..ac17106 100644
--- a/gerbonara/gerber/tests/resources/fritzing/combined.gtl
+++ b/gerbonara/gerber/tests/resources/fritzing/combined.gtl
@@ -1,3 +1,4 @@
+G04 file manually fixed for GerberTools #86 / #143*
%MOIN*%
%OFA0B0*%
%FSLAX23Y23*%
@@ -405,7 +406,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D30*
X01338Y00039D02*
X01751Y01768D03*
@@ -768,7 +769,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D40*
X02637Y00039D02*
X03049Y01768D03*
@@ -1131,7 +1132,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D50*
X02598Y02677D02*
X00869Y03090D03*
@@ -1487,4 +1488,4 @@ D02*
X01194Y03540D02*
X01194Y03464D01*
G04 End of Copper1*
-M02* \ No newline at end of file
+M02*
diff --git a/gerbonara/gerber/tests/resources/fritzing/combined.gto b/gerbonara/gerber/tests/resources/fritzing/combined.gto
index 65d56e2..a059149 100644
--- a/gerbonara/gerber/tests/resources/fritzing/combined.gto
+++ b/gerbonara/gerber/tests/resources/fritzing/combined.gto
@@ -1,3 +1,4 @@
+G04 file manually fixed for GerberTools #86 / #143*
%MOIN*%
%OFA0B0*%
%FSLAX23Y23*%
@@ -11538,7 +11539,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D26*
X01701Y02265D02*
X02501Y02265D01*
@@ -23054,7 +23055,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D31*
X02999Y02265D02*
X03800Y02265D01*
@@ -34570,7 +34571,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D36*
X00371Y03040D02*
X00371Y03840D01*
@@ -46079,4 +46080,4 @@ X02356Y02929D02*
X02356Y02939D01*
D02*
G04 End of Silk1*
-M02* \ No newline at end of file
+M02*
diff --git a/gerbonara/gerber/tests/resources/fritzing/combined.gts b/gerbonara/gerber/tests/resources/fritzing/combined.gts
index 80f0102..ab186a8 100644
--- a/gerbonara/gerber/tests/resources/fritzing/combined.gts
+++ b/gerbonara/gerber/tests/resources/fritzing/combined.gts
@@ -1,3 +1,4 @@
+G04 file manually fixed for GerberTools #86 / #143*
%MOIN*%
%OFA0B0*%
%FSLAX23Y23*%
@@ -165,7 +166,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D28*
X01338Y00039D02*
X01751Y01768D03*
@@ -296,7 +297,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D36*
X02637Y00039D02*
X03049Y01768D03*
@@ -427,7 +428,7 @@ G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
-G04 skipping 70
+G04 skipping 70*
D44*
X02598Y02677D02*
X00869Y03090D03*
@@ -551,4 +552,4 @@ X01819Y03591D03*
X02019Y03591D03*
X02219Y03591D03*
G04 End of Mask1*
-M02* \ No newline at end of file
+M02*
diff --git a/gerbonara/gerber/tests/test_rs274x.py b/gerbonara/gerber/tests/test_rs274x.py
index b7ddbd4..7e21d62 100644
--- a/gerbonara/gerber/tests/test_rs274x.py
+++ b/gerbonara/gerber/tests/test_rs274x.py
@@ -427,6 +427,10 @@ def test_svg_export(reference, tmpfile):
# fine though.
pytest.skip()
+ if reference.name == 'MinnowMax_assy.art':
+ # This leads to worst-case performance in resvg, this testcase takes over 1h to finish. So skip.
+ pytest.skip()
+
grb = GerberFile.open(reference)
bounds = (0.0, 0.0), (6.0, 6.0) # bottom left, top right
@@ -447,7 +451,7 @@ def test_svg_export(reference, tmpfile):
svg_to_png(out_svg, out_png, dpi=72) # make dpi match Cairo's default
mean, _max, hist = image_difference(ref_png, out_png, diff_out=tmpfile('Difference', '.png'))
- assert mean < 1e-3
+ assert mean < 1.2e-3
assert hist[9] < 1
assert hist[3:].sum() < 1e-3*hist.size