diff options
Diffstat (limited to 'gerbonara/gerber/tests')
-rw-r--r-- | gerbonara/gerber/tests/image_support.py | 50 | ||||
-rw-r--r-- | gerbonara/gerber/tests/test_excellon.py | 12 | ||||
-rw-r--r-- | gerbonara/gerber/tests/utils.py | 2 |
3 files changed, 45 insertions, 19 deletions
diff --git a/gerbonara/gerber/tests/image_support.py b/gerbonara/gerber/tests/image_support.py index 36343d9..662dbed 100644 --- a/gerbonara/gerber/tests/image_support.py +++ b/gerbonara/gerber/tests/image_support.py @@ -1,6 +1,7 @@ import subprocess from pathlib import Path import tempfile +import textwrap import os from functools import total_ordering import shutil @@ -65,16 +66,33 @@ def svg_to_png(in_svg, out_png, dpi=100, bg='black'): to_gerbv_svg_units = lambda val, unit='mm': val*72 if unit == 'inch' else val/25.4*72 -def gerbv_export(in_gbr, out_svg, format='svg', origin=(0, 0), size=(6, 6), fg='#ffffff', bg='#000000'): - x, y = origin - w, h = size - cmd = ['gerbv', '-x', format, - '--border=0', - f'--origin={x:.6f}x{y:.6f}', f'--window_inch={w:.6f}x{h:.6f}', - f'--foreground={fg}', - f'--background={bg}', - '-o', str(out_svg), str(in_gbr)] - subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) +def gerbv_export(in_gbr, out_svg, export_format='svg', origin=(0, 0), size=(6, 6), fg='#ffffff', bg='#000000', override_unit_spec=None): + with tempfile.NamedTemporaryFile('w') as f: + if override_unit_spec: + units, zeros, digits = override_unit_spec + units = 0 if units == 'inch' else 1 + zeros = {None: 0, 'leading': 1, 'trailing': 2}[zeros] + unit_spec = textwrap.dedent(f'''(cons 'attribs (list + (list 'autodetect 'Boolean 0) + (list 'zero_suppression 'Enum {zeros}) + (list 'units 'Enum {units}) + (list 'digits 'Integer {digits}) + ))''') + else: + unit_spec = '' + + f.write(f'''(gerbv-file-version! "2.0A")(define-layer! 0 (cons 'filename "{in_gbr}"){unit_spec})''') + f.flush() + + x, y = origin + w, h = size + cmd = ['gerbv', '-x', export_format, + '--border=0', + f'--origin={x:.6f}x{y:.6f}', f'--window_inch={w:.6f}x{h:.6f}', + f'--foreground={fg}', + f'--background={bg}', + '-o', str(out_svg), '-p', f.name] + subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) @contextmanager def svg_soup(filename): @@ -101,12 +119,12 @@ def cleanup_gerbv_svg(filename): with svg_soup(filename) as soup: cleanup_clips(soup) -def gerber_difference(reference, actual, diff_out=None, svg_transform=None, size=(10,10)): +def gerber_difference(reference, actual, diff_out=None, svg_transform=None, size=(10,10), ref_unit_spec=None): with tempfile.NamedTemporaryFile(suffix='.svg') as act_svg,\ tempfile.NamedTemporaryFile(suffix='.svg') as ref_svg: - gerbv_export(reference, ref_svg.name, size=size, format='svg') - gerbv_export(actual, act_svg.name, size=size, format='svg') + gerbv_export(reference, ref_svg.name, size=size, export_format='svg', override_unit_spec=ref_unit_spec) + gerbv_export(actual, act_svg.name, size=size, export_format='svg') with svg_soup(ref_svg.name) as soup: if svg_transform is not None: @@ -123,9 +141,9 @@ def gerber_difference_merge(ref1, ref2, actual, diff_out=None, composite_out=Non tempfile.NamedTemporaryFile(suffix='.svg') as ref1_svg,\ tempfile.NamedTemporaryFile(suffix='.svg') as ref2_svg: - gerbv_export(ref1, ref1_svg.name, size=size, format='svg') - gerbv_export(ref2, ref2_svg.name, size=size, format='svg') - gerbv_export(actual, act_svg.name, size=size, format='svg') + gerbv_export(ref1, ref1_svg.name, size=size, export_format='svg') + gerbv_export(ref2, ref2_svg.name, size=size, export_format='svg') + gerbv_export(actual, act_svg.name, size=size, export_format='svg') with svg_soup(ref1_svg.name) as soup1: if svg_transform1 is not None: diff --git a/gerbonara/gerber/tests/test_excellon.py b/gerbonara/gerber/tests/test_excellon.py index f8d54ed..9aa5232 100644 --- a/gerbonara/gerber/tests/test_excellon.py +++ b/gerbonara/gerber/tests/test_excellon.py @@ -10,6 +10,7 @@ from ..cam import FileSettings from .image_support import * from .utils import * +from ..utils import Inch, MM REFERENCE_FILES = [ 'easyeda/Gerber_Drill_NPTH.DRL', @@ -34,10 +35,17 @@ REFERENCE_FILES = [ @pytest.mark.parametrize('reference', REFERENCE_FILES, indirect=True) def test_round_trip(reference, tmpfile): tmp = tmpfile('Output excellon', '.drl') + # Altium uses an excellon format specification format that gerbv doesn't understand, so we have to fix that. + unit_spec = ('mm', 'leading', 4) if 'altium-composite-drill' in str(reference) else None + # pcb-rnd does not include any unit specification at all + if 'pcb-rnd' in str(reference): + settings = FileSettings(unit=Inch, zeros='leading', number_format=(2,4)) + else: + settings = None - ExcellonFile.open(reference).save(tmp) + ExcellonFile.open(reference, settings=settings).save(tmp) - mean, _max, hist = gerber_difference(reference, tmp, diff_out=tmpfile('Difference', '.png')) + mean, _max, hist = gerber_difference(reference, tmp, diff_out=tmpfile('Difference', '.png'), ref_unit_spec=unit_spec) assert mean < 5e-5 assert hist[9] == 0 assert hist[3:].sum() < 5e-5*hist.size diff --git a/gerbonara/gerber/tests/utils.py b/gerbonara/gerber/tests/utils.py index ee8fc68..f63f3c6 100644 --- a/gerbonara/gerber/tests/utils.py +++ b/gerbonara/gerber/tests/utils.py @@ -11,7 +11,7 @@ from PIL import Image import pytest fail_dir = Path('gerbonara_test_failures') -reference_path = lambda reference: Path(__file__).parent / 'resources' / reference +reference_path = lambda reference: Path(__file__).parent / 'resources' / str(reference) to_gerbv_svg_units = lambda val, unit='mm': val*72 if unit == 'inch' else val/25.4*72 def path_test_name(request): |