Skip to content

Commit

Permalink
Seems LINEWIDTH selects a predefined width and is not a scalar
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Panter committed Jan 20, 2018
1 parent 1bca834 commit 0c21e31
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 36 deletions.
41 changes: 24 additions & 17 deletions altium.py
Expand Up @@ -302,6 +302,9 @@ def display_part(objects, obj):
return ((part == b"-1" or part == owner.get("CURRENTPARTID")) and
mode == owner.get_int("DISPLAYMODE"))

def get_line_width(obj):
return [0.4, 1, 2, 4][obj.get_int("LINEWIDTH")]

class Record:
"""Schematic object record types"""
HEADER = 0
Expand Down Expand Up @@ -392,7 +395,8 @@ class LineShape:

class LineShapeSize:
'''Size of start and end shapes for polylines'''
SMALL = 0
XSMALL = 0
SMALL = 1
MEDIUM = 2
LARGE = 3

Expand Down Expand Up @@ -660,7 +664,7 @@ def handle_line(self, owners, obj):

kw = dict(
colour=colour(obj),
width=obj.get_int("LINEWIDTH"),
width=get_line_width(obj),
a=get_location(obj),
b=tuple(obj.get_int("CORNER." + x) for x in "XY"),
)
Expand All @@ -671,7 +675,7 @@ def handle_line(self, owners, obj):
def handle_polyline(self, owners, obj):
obj.get_int("INDEXINSHEET")
obj.get_bool("ISNOTACCESIBLE")
linewidth = obj.get_int("LINEWIDTH")
linewidth = get_line_width(obj)

points = list()
for i in range(obj.get_int("LOCATIONCOUNT")):
Expand All @@ -682,9 +686,10 @@ def handle_polyline(self, owners, obj):
col = colour(obj)

scale = {
LineShapeSize.SMALL: 1,
LineShapeSize.MEDIUM: 1.5,
LineShapeSize.LARGE: 2,
LineShapeSize.XSMALL: 1,
LineShapeSize.SMALL: 2.5,
LineShapeSize.MEDIUM: 5,
LineShapeSize.LARGE: 10,
}
scale = scale[obj.get_int("LINESHAPESIZE")]
arrows = {
Expand All @@ -708,7 +713,6 @@ def handle_polyline(self, owners, obj):
end_shape = None

if display_part(owners[-1], obj):
linewidth = linewidth or 0.6
start = points[0]
end = points[-1]
if start_shape:
Expand Down Expand Up @@ -761,7 +765,7 @@ def handle_polyline(self, owners, obj):
def handle_arc(self, owners, obj):
obj.get_int("INDEXINSHEET")
obj.check("ISNOTACCESIBLE", b"T")
obj.check("LINEWIDTH", b"1")
width = get_line_width(obj)

r = get_int_frac(obj, "RADIUS")
if obj.get_int("RECORD") == Record.ELLIPTICAL_ARC:
Expand All @@ -781,7 +785,11 @@ def handle_arc(self, owners, obj):
start = degrees(atan2(r * sin(start), r2 * cos(start)))
end = radians(end)
end = degrees(atan2(r * sin(end), r2 * cos(end)))
self.renderer.arc((r, r2), start, end, location, colour=col)
kw = dict()
if width != 1:
kw.update(width=width)
self.renderer.arc((r, r2), start, end, location,
colour=col, **kw)

@_setitem(handlers, Record.BEZIER)
def handle_bezier(self, owners, obj):
Expand All @@ -795,7 +803,7 @@ def handle_bezier(self, owners, obj):
for n in range(4):
n = format(1 + n)
points.append(tuple(obj.get_int(x + n) for x in "XY"))
width = obj.get_int("LINEWIDTH")
width = get_line_width(obj)
if width != 1:
kw.update(width=width)
self.renderer.cubicbezier(*points, **kw)
Expand All @@ -807,7 +815,7 @@ def handle_rectangle(self, owners, obj):
obj.get_bool("ISNOTACCESIBLE")

kw = dict(
width=obj.get_int("LINEWIDTH") or 0.6,
width=get_line_width(obj),
outline=colour(obj),
)
fill = colour(obj, "AREACOLOR")
Expand Down Expand Up @@ -873,7 +881,7 @@ def handle_polygon(self, owners, obj):

kw = dict(
outline=colour(obj),
width=obj.get_int("LINEWIDTH") or 0.6,
width=get_line_width(obj),
)
if obj.get_bool("ISSOLID"):
kw.update(fill=fill)
Expand All @@ -895,7 +903,7 @@ def handle_ellipse(self, owners, obj):
self.renderer.ellipse(
r=(get_int_frac(obj, "RADIUS"),
get_int_frac(obj, "SECONDARYRADIUS")),
width=obj.get_int("LINEWIDTH") or 0.6,
width=get_line_width(obj),
outline=colour(obj),
offset=get_location(obj),
**kw)
Expand Down Expand Up @@ -1284,18 +1292,17 @@ def handle_wire(self, owners, obj):
points.append(point)
self.renderer.polyline(points,
colour=colour(obj),
width=obj.get_int("LINEWIDTH"),
width=get_line_width(obj),
)

@_setitem(handlers, Record.BUS_ENTRY)
def handle_bus_entry(self, owners, obj):
obj.check("LINEWIDTH", b"2")
obj.check("OWNERPARTID", b"-1")
self.renderer.line(
get_location(obj),
tuple(obj.get_int("CORNER." + x) for x in "XY"),
colour=colour(obj),
width=obj.get_int("LINEWIDTH"),
width=get_line_width(obj),
)

@_setitem(handlers, Record.JUNCTION)
Expand Down Expand Up @@ -1455,7 +1462,7 @@ def handle_sheet_symbol(self, owners, obj):

corner = (obj.get_int("XSIZE"), -obj.get_int("YSIZE"))
self.renderer.rectangle(corner,
width=obj.get_int("LINEWIDTH") or 0.6,
width=get_line_width(obj),
outline=colour(obj), fill=colour(obj, "AREACOLOR"),
offset=get_location(obj),
)
Expand Down
34 changes: 21 additions & 13 deletions format.md
Expand Up @@ -10,7 +10,8 @@ Contents:

* [OLE compound document](#ole-compound-document)
* [Property list](#property-list)
* [Data types](#data-types): [Integer], [Colour], [Real], [Boolean]
* [Data types](#data-types): [Integer], [Colour], [Real], [Boolean],
[Line width]
* [Object records](#object-records)
* [0: Header](#header)
* [1: Component](#component)
Expand Down Expand Up @@ -163,6 +164,15 @@ Typically three decimal places. Property omitted when the value is zero.
`|ISHIDDEN=T|PARTIDLOCKED=F`. When false, the property is often omitted,
rather than explicitly set to `F`.

### Line width ###

`|LINEWIDTH`

* Omitted: 4 mil
* 1: 10 mil
* 2: 20 mil
* 3: 40 mil

## Object records ##

Each item in the FileHeader stream describes an object.
Expand Down Expand Up @@ -310,8 +320,7 @@ The component object seems to occur before any of its child objects.
* `|INDEXINSHEET`: [Integer]
* `|OWNERPARTID`: See [Component](#component) `|CURRENTPARTID`
* `|OWNERPARTDISPLAYMODE`: See [Component](#component) `|DISPLAYMODE`
* `|LINEWIDTH` ([integer]): Values greater than one seem to be drawn thicker
than expected
* `|LINEWIDTH`
* `|COLOR`
* `|LOCATIONCOUNT|X`_n_`|Y`_n_`|`. . .: May also include `_FRAC` counterparts
* `|STARTLINESHAPE|ENDLINESHAPE` ([Integers](#integers)):
Expand All @@ -324,8 +333,8 @@ The component object seems to occur before any of its child objects.
* 5: Solid circle
* 6: Solid square
* `|LINESHAPESIZE`: [Integer]
* Omitted, 1: Small [Is there a distinction?
Perhaps 0 (omitted) is extra small, and 1 is larger.]
* Omitted: Extra small
* 1: Small
* 2: Medium
* 3: Large

Expand All @@ -335,8 +344,7 @@ The component object seems to occur before any of its child objects.
* `|INDEXINSHEET`: [Integer]
* `|OWNERPARTID|OWNERPARTDISPLAYMODE`:
See [Component](#component) `|CURRENTPARTID` and `|DISPLAYMODE`
* `|LINEWIDTH` ([integer]): If omitted (zero), there is a thin but visible
outline
* `|LINEWIDTH`
* `|COLOR|AREACOLOR|ISSOLID`
* `|LOCATIONCOUNT|X`_n_`|X`_n_`_FRAC|Y`_n_`Y`_n_`_FRAC|`. . .
* `|EXTRALOCATIONCOUNT|E(X/Y)<n>[_FRAC]`:
Expand All @@ -350,7 +358,7 @@ The component object seems to occur before any of its child objects.
* `|SECONDARYRADIUS|SECONDARYRADIUS_FRAC`: Radius in _y_ direction
* `|COLOR|AREACOLOR|ISSOLID`
* `|INDEXINSHEET`: [Integer]
* `|LINEWIDTH=1`: Optional
* `|LINEWIDTH`
* `|OWNERINDEX|ISNOTACCESIBLE=T|OWNERPARTID=1|LOCATION.X|LOCATION.Y`

### Piechart ###
Expand Down Expand Up @@ -380,7 +388,7 @@ circ_angle = atan2( RADIUS * sin(angle), SECONDARYRADIUS * cos(angle) )
* `|OWNERPARTDISPLAYMODE`: See [Component](#component) `|DISPLAYMODE`
* `|LOCATION.X|LOCATION.Y`: Centre of circle
* `|RADIUS|RADIUS_FRAC`: [Integer]s
* `|LINEWIDTH=1`
* `|LINEWIDTH`
* `|STARTANGLE` ([real]): Default 0; 0 for full circle
* `|ENDANGLE` ([real]): 360 for full circle. Setting both to zero may
also specify a full circle.
Expand All @@ -394,7 +402,7 @@ circ_angle = atan2( RADIUS * sin(angle), SECONDARYRADIUS * cos(angle) )
* `|OWNERPARTID=1`
* `|OWNERPARTDISPLAYMODE`: See [Component](#component) `|DISPLAYMODE`
* `|LOCATION.X|LOCATION.Y|CORNER.X|CORNER.Y`: Endpoints of the line
* `|LINEWIDTH=1`: Line thickness
* `|LINEWIDTH`: Line thickness
* `|COLOR`

### Rectangle ###
Expand All @@ -406,7 +414,7 @@ circ_angle = atan2( RADIUS * sin(angle), SECONDARYRADIUS * cos(angle) )
* `|OWNERPARTDISPLAYMODE`: Optional
* `|LOCATION.X|LOCATION.Y`: Bottom left corner
* `|CORNER.X[_FRAC]|CORNER.Y[_FRAC]`: Top right corner
* `|LINEWIDTH`: [Integer]. If zero, there is still a thin visible outline.
* `|LINEWIDTH`
* `|COLOR`: Outline colour
* `|AREACOLOR`: Fill colour
* `|ISSOLID` ([boolean]):
Expand Down Expand Up @@ -656,7 +664,7 @@ Labels on top-level schematic
### Bus entry ###
`|RECORD=37`: Bus entry line

`|COLOR=8388608|CORNER.X|CORNER.Y|LINEWIDTH=2|LOCATION.X|LOCATION.Y|OWNERPARTID=-1`
`|COLOR=8388608|CORNER.X|CORNER.Y|LINEWIDTH|LOCATION.X|LOCATION.Y|OWNERPARTID=-1`

### Template ###
`|RECORD=39`: Sheet template, owning custom title block lines and labels
Expand Down Expand Up @@ -749,7 +757,7 @@ Children of [Sheet](#sheet), seen in the Additional stream
#sheet-name-and-file-name), also with `|OWNERINDEXADDITIONALLIST=T`
and optionally `|ISHIDDEN=T`

`|RECORD=218|COLOR=15187117|INDEXINSHEET|LINEWIDTH=2|LOCATIONCOUNT=2|OWNERPARTID=-1|X1|X2|Y1|Y2`
`|RECORD=218|COLOR=15187117|INDEXINSHEET|LINEWIDTH|LOCATIONCOUNT=2|OWNERPARTID=-1|X1|X2|Y1|Y2`

### Hyperlink ###
`|RECORD=226`
4 changes: 2 additions & 2 deletions test.py
Expand Up @@ -109,14 +109,14 @@ def test_svg(self):
self.assertCountEqual(sheet.items(), (
("transform", "translate(100.0, -200.0)"),
("width", "40"), ("height", "30"),
("stroke-width", "0.6"), ("class", "solid"),
("stroke-width", "0.4"), ("class", "solid"),
("style", "fill: #DD9933; stroke: #11BB77"),
))

self.assertEqual(triangle.tag, SVG + "polygon")
self.assertCountEqual(triangle.items(), (
("points", "100.0,-100.0 110.0,-120.0 120.0,-100.0"),
("class", "solid"), ("stroke-width", "0.6"),
("class", "solid"), ("stroke-width", "0.4"),
("style", "fill: #FFFFFF; stroke: #0000FF"),
))

Expand Down
5 changes: 3 additions & 2 deletions vector/svg.py
Expand Up @@ -233,9 +233,9 @@ def _width(self, attrs, width=None):
if width is not None:
attrs["stroke-width"] = format(width)

def arc(self, r, start, end, offset=None, *, colour=None):
def arc(self, r, start, end, offset=None, *, colour=None, width=None):
if abs(end - start) >= 360:
return self.ellipse(r, offset, outline=colour)
return self.ellipse(r, offset, outline=colour, width=width)

a = list()
d = list()
Expand All @@ -253,6 +253,7 @@ def arc(self, r, start, end, offset=None, *, colour=None):
large=large,
d=",".join(d),
)
self._width(at, width)
self.emptyelement("path", at, transform=self._offset(offset))

def text(self, text, offset=None, horiz=None, vert=None, *,
Expand Down
8 changes: 6 additions & 2 deletions vector/tk.py
Expand Up @@ -62,20 +62,24 @@ def cubicbezier(self, a, b, c, d, *,
self.canvas.create_line(*points, smooth="bezier",
fill=colour, width=width)

def arc(self, r, start, end, offset=(0, 0), *, colour):
def arc(self, r, start, end, offset=(0, 0), *, colour, width=None):
(rx, ry) = r
extent = end - start
if abs(extent) >= 360:
return self.ellipse(r, offset, outline=colour)
return self.ellipse(r, offset, outline=colour, width=width)
extent %= 360

(ox, oy) = offset
kw = dict()
if width is not None:
kw.update(width=width)
self.canvas.create_arc(
(ox - rx) * self.scaling[0], (oy - ry) * self.scaling[1],
(ox + rx) * self.scaling[0], (oy + ry) * self.scaling[1],
style=tkinter.ARC,
start=start, extent=extent,
outline=self._colour(colour),
**kw,
)

def ellipse(self, r, offset=(0, 0), *,
Expand Down

0 comments on commit 0c21e31

Please sign in to comment.