--- /dev/null
+# -*- coding: ASCII -*-
+'''footprinter.py version 0.1
+Classes for gEDA PCB footprint creation
+according to <http://www.brorson.com/gEDA/land_patterns_20050129.pdf>
+Copyright (c) 2011, Mel Wilson <mwilson@melwilsonsoftware.ca>
+
+Licence: Creative Commons Attribution 3.0 Unported License
+<http://creativecommons.org/licenses/by-sa/3.0/>
+'''
+
+def mm (x):
+ '''Get standard units from a measurement in millimeters.'''
+ return x * 1e5 / 25.4
+
+def mil (x):
+ '''Get standard units from a measurement in thousandths of an inch.'''
+ return x * 100
+
+def inch (x):
+ '''Get standard units from a measurement in inches.'''
+ return x * 1e5
+
+def hmil (x):
+ '''For completeness: Get standard units from a measurement in hundreths of a mil.'''
+ return x
+
+class Footprint (object):
+ def __init__ (self, padpins=None, linearcs=None, sflags='', description=''):
+ if padpins is None: padpins = []
+ if linearcs is None: linearcs = []
+ self.mx = 1000
+ self.my = 1000
+ self.tx = 600
+ self.ty = 600
+ self.tdir = 0
+ self.tscale = 100
+ self.tsflags = ''
+ self.sflags = sflags
+ self.pads = padpins
+ self.lines = linearcs
+ self.description = description
+
+ def file_element (self, filepath):
+ '''Write the footprint to a PCB-compatible file.'''
+ with open (filepath, 'wt') as f:
+ self.write (f)
+
+ def write (self, f):
+ f.write ('Element ["%s" "%s" "" "" %d %d %d %d %d %d "%s"]\n'
+ % (self.sflags, self.description, self.mx, self.my
+ , self.tx, self.ty, self.tdir, self.tscale, self.tsflags)
+ )
+ f.write ('(\n')
+ for p in self.pads:
+ p.write (f)
+ for L in self.lines:
+ L.write (f)
+ f.write (')\n')
+
+
+class Pad (object):
+ def __init__ (self, number, padrect, trace_clearance, mask_clearance, name='', sflags=''):
+ px1, py1, px2, py2 = padrect # x,y of diagonally opposite corners
+ thickness = min (abs (px1-px2), abs (py1-py2))
+ t2 = thickness/2
+ # find the centerline of the pad ..
+ if px1 < px2:
+ rx1, rx2 = px1 + t2, px2 - t2
+ else:
+ rx1, rx2 = px1 - t2, px1 + t2
+ if py1 < py2:
+ ry1, ry2 = py1 + t2, py2 - t2
+ else:
+ ry1, ry2 = py1 - t2, py1 + t2
+ self.rx1 = rx1
+ self.ry1 = ry1
+ self.rx2 = rx2
+ self.ry2 = ry2
+ self.thickness = thickness
+ self.clearance = trace_clearance
+ #~ self.mask = mask
+ self.mask = thickness + mask_clearance*2
+ self.name = name
+ self.number = number
+ self.sflags = sflags
+
+ def write (self, f):
+ f.write ('Pad [%d %d %d %d %d %d %d "%s" "%s" "%s"]\n'
+ % (self.rx1, self.ry1, self.rx2, self.ry2
+ , self.thickness, self.clearance, self.mask
+ , self.name, self.number, self.sflags
+ )
+ )
+
+class Pin (object):
+ def __init__ (self, number, rx, ry, thickness, trace_clearance, mask_clearance, drill, name='', sflags=''):
+ self.rx = rx
+ self.ry = ry
+ self.thickness = thickness
+ self.clearance = trace_clearance
+ #~ self.mask = mask
+ self.mask = thickness + mask_clearance*2
+ self.drill = drill
+ self.name = str (name)
+ self.number = str (number)
+ self.sflags = sflags
+
+ def write (self, f):
+ f.write ('Pin [%d %d %d %d %d %d "%s" "%s" "%s"]\n'
+ % (self.rx, self.ry
+ , self.thickness, self.clearance, self.mask, self.drill
+ , self.name, self.number, self.sflags
+ )
+ )
+
+class ElementLine (object):
+ def __init__ (self, rx1, ry1, rx2, ry2, thickness):
+ self.rx1 = rx1
+ self.ry1 = ry1
+ self.rx2 = rx2
+ self.ry2 = ry2
+ self.thickness = thickness
+
+ def write (self, f):
+ f.write ('ElementLine [%d %d %d %d %d]\n'
+ % (self.rx1, self.ry1, self.rx2, self.ry2, self.thickness)
+ )
+
+class ElementArc (object):
+ def __init__ (self, rx, ry, width, height, start_angle, delta_angle, thickness):
+ self.rx = rx
+ self.ry = ry
+ self.width = width
+ self.height = height
+ self.start_angle = start_angle
+ self.delta_angle = delta_angle
+ self.thickness = thickness
+
+ def write (self, f):
+ f.write ('ElementArc [%d %d %d %d %d %d %d]\n'
+ % (self.rx, self.ry, self.width, self.height, self.start_angle, self.delta_angle, self.thickness)
+ )