Skip to content

Commit

Permalink
Show file tree
Hide file tree
Showing 47 changed files with 1,674 additions and 104 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/unit_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ jobs:
run: pip install poetry==1.6.1

- name: Install dependencies
run: poetry install --no-cache --sync
run: poetry install --no-cache --sync --extras=svg

- name: Run unit tests
run: poetry run poe run-unit-tests
Expand Down
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"printWidth": 88,
"overrides": [
{
"files": ["*.html", "*.js", "*.json", "*.prettierrc"],
"files": ["*.html", "*.js", "*.json", "*.prettierrc", "*.overrides"],
"options": {
"tabWidth": 4
}
Expand Down
259 changes: 259 additions & 0 deletions docs/gerber/feature_support/svgrenderer2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
# SvgRenderer2 feature support

## Introduction

`SvgRenderer2` is an experimental SVG backend for rendering of Gerber files. It operates
on command buffers generated by `Parser2`.

| Symbol | Meaning |
| ------ | ------------------------------------------ |
|| Feature implemented and usable. |
| 🚧 | Work in progress. Related APIs can change. |
| 🚫 | Not planned, unless contributed or needed. |
|| Not implemented, but planned. |
| 👽 | Partially implemented. |
| 👾 | Bugged. |
|| Feature doesn't apply. |

| Symbol | Count |
| ------ | ----- |
|| 169 |
| 🚧 | 0 |
| 🚫 | 2 |
|| 7 |
| 👽 | 2 |
| 👾 | 0 |
| total | 185 |

## Supported Gerber X3 features

### General

- ⛔ MO - Mode - Sets the unit to mm or inch.
- ⛔ FS - Format specification:
- ⛔ absolute coordinates.
- ⛔ incremental coordinates
- ⛔ trailing zeros omission.
- ⛔ leading zeros omission.
- ⛔ AD - Aperture define - Defines a template-based aperture, assigns a D code to it.
- ⛔ circle.
- ⛔ rectangle.
- ⛔ obround.
- ⛔ polygon.
- ⛔ Define macro.
- ⛔ AM - Aperture macro - Defines a macro aperture template.
- ⛔ Dnn (nn≥10) - Sets the current aperture to D code nn.
- ⛔ G01 - Sets draw mode to linear.
- ⛔ Variable zero padding variants allowed.
- ⛔ G02 - Sets draw mode to clockwise circular.
- ⛔ Variable zero padding variants allowed.
- ⛔ G03 - Sets draw mode to counterclockwise circular.
- ⛔ Variable zero padding variants allowed.
- ❌ LP - Load polarity (changes flag, not fully implemented).
- ❌ LM - Load mirroring (changes flag, not fully implemented).
- ❌ LR - Load rotation (changes flag, not fully implemented).
- ❌ LS - Load scaling (changes flag, not fully implemented).
- ⛔ TF - Attribute on file.
- ⛔ TA - Attribute on aperture.
- ⛔ TO - Attribute on object.
- ⛔ TD - Attribute delete.
- ⛔ M02 - End of file.

### D01, D02, D03

- 👽 D01 - Plot operation, mode
- 👽 Line, with:
- ✅ circle,
- 👽 rectangle,
- 👽 obround,
- 👽 polygon,
- 👽 macro.
- 👾 Arc, with:
- 👾 circle,
- 👽 rectangle,
- 👽 obround,
- 👽 polygon,
- 👽 macro.
- 👾 Counter clockwise arc, with:
- 👾 circle,
- 👽 rectangle,
- 👽 obround,
- 👽 polygon,
- 👽 macro.
- ⛔ Variable zero padding variants allowed.
- ⛔ D02 - Move operation
- ⛔ Variable zero padding variants allowed.
- 👽 D03 - Flash operation, with
- ✅ circle,
- ✅ rectangle,
- ✅ obround,
- ✅ polygon,
- 👽 macro.
- ⛔ Variable zero padding variants allowed.

### Regions

- ✅ G36 - Starts a region statement.
- ✅ G37 - Ends the region statement.
- 👽 Regions, with:
- 👽 Line, aperture:
- ✅ circle,
- ✅ rectangle,
- ✅ obround,
- ✅ polygon,
- 👽 macro.
- 👽 Arc, aperture:
- ✅ circle,
- ✅ rectangle,
- ✅ obround,
- ✅ polygon,
- 👽 macro.
- 👽 Counter clockwise arc, aperture:
- ✅ circle,
- ✅ rectangle,
- ✅ obround,
- ✅ polygon,
- 👽 macro.

### Macros

- ⛔ Parameters.
- 👽 Primitives in definition:
- ✅ Code 1, Circle
- ❌ Code 2, Vector line
- ✅ Code 4, Outline
- ✅ Code 5, Polygon
- ❌ Code 6, Moire
- ✅ Code 7, Thermal
- ✅ Code 20, Vector line
- ✅ Code 21, Center Line
- ❌ Code 22, Lower Left Line
- 👽 Primitives in aperture instance:
- ✅ Code 1, Circle
- ❌ Code 2, Vector line
- ✅ Code 4, Outline
- ✅ Code 5, Polygon
- ❌ Code 6, Moire
- ❌ Code 7, Thermal
- ✅ Code 20, Vector line
- ✅ Code 21, Center Line
- ❌ Code 22, Lower Left Line
- ❌ Rotation around macro origin:
- ❌ Code 1, Circle
- ❌ Code 2, Vector line
- ❌ Code 4, Outline
- ❌ Code 5, Polygon
- ❌ Code 6, Moire
- ❌ Code 7, Thermal
- ❌ Code 20, Vector line
- ❌ Code 21, Center Line
- ❌ Code 22, Lower Left Line
- ⛔ Expressions.
- ⛔ Constants.
- ⛔ Variables.
- ⛔ Addition.
- ⛔ Subtraction.
- ⛔ Multiplication.
- ⛔ Division.
- ⛔ Unary + operator.
- ⛔ Negation.
- ⛔ Variable definitions.

### Aperture blocks

- 👽 Nested Line, aperture:
- ✅ circle,
- ✅ rectangle,
- ✅ obround,
- ✅ polygon,
- 👽 macro.
- 👽 Nested Arc, aperture:
- ✅ circle,
- ✅ rectangle,
- ✅ obround,
- ✅ polygon,
- 👽 macro.
- 👽 Nested Counter clockwise arc, aperture:
- ✅ circle,
- ✅ rectangle,
- ✅ obround,
- ✅ polygon,
- 👽 macro.
- 👽 Nested Flash:
- ✅ circle,
- ✅ rectangle,
- ✅ obround,
- ✅ polygon,
- 👽 macro.
- 👽 Nested regions (partial macro support).

### Step and repeat

- 👽 Nested Line, aperture:
- ✅ circle,
- ✅ rectangle,
- ✅ obround,
- ✅ polygon,
- 👽 macro.
- 👽 Nested Arc, aperture:
- ✅ circle,
- ✅ rectangle,
- ✅ obround,
- ✅ polygon,
- 👽 macro.
- 👽 Nested Counter clockwise arc, aperture:
- ✅ circle,
- ✅ rectangle,
- ✅ obround,
- ✅ polygon,
- 👽 macro.
- 👽 Nested Flash:
- ✅ circle,
- ✅ rectangle,
- ✅ obround,
- ✅ polygon,
- 👽 macro.
- 👽 Nested regions (partial macro support).
- 👽 Nested blocks (partial macro support).

## Supported DEPRECATED Gerber features

- ⛔ G54 - Select aperture. (Spec. 8.1.1)
- ⛔ G55 - Prepare for flash. (Spec. 8.1.1)
- ⛔ G70 - Set the 'Unit' to inch. (Spec. 8.1.1)
- ⛔ G71 - Set the 'Unit' to mm. (Spec. 8.1.1)
- ⛔ G90 - Set the 'Coordinate format' to 'Absolute notation'. (Spec. 8.1.1)
- ⛔ G91 - Set the 'Coordinate format' to 'Incremental notation'. (Spec. 8.1.1)

- **Important**: _Incremental notation itself is not supported and is not planned
due to lack of test assets and expected complications during implementation._

- ⛔ M00 - Program stop. (Spec. 8.1.1)
- ⛔ M01 - Optional stop. (Spec. 8.1.1)
- ⛔ AS - Sets the 'Axes correspondence'. (Spec. 8.1.2)
- ⛔ IN - Sets the name of the file image. (Spec. 8.1.3)
- ⛔ IP - Sets the 'Image polarity'. (Spec. 8.1.4)
- ❌ IR - Sets 'Image rotation' graphics state parameter. (Spec. 8.1.5)
- ⛔ LN - Loads a name. (Spec. 8.1.6)
- ❌ MI - Sets 'Image mirroring' graphics state parameter (Spec. 8.1.7)
- ❌ OF - Sets 'Image offset' graphics state parameter (Spec. 8.1.8)
- ❌ SF - Sets 'Scale factor' graphics state parameter (Spec. 8.1.9)
- ✅ G74 - Sets single quadrant mode. (Spec. 8.1.10)
- 🚫 Format Specification (FS) Options. (Spec. 8.2.1)
- 🚫 Rectangular aperture hole in standard apertures. (Spec. 8.2.2)
- 👽 Draws and arcs wit rectangular apertures. (Spec. 8.2.3)
- ❌ Macro Primitive Code 2, Vector Line. (Spec 8.2.4)
- ❌ Macro Primitive Code 22, Lower Left Line. (Spec 8.2.5)
- ❌ Macro Primitive Code 6, Moiré. (Spec 8.2.6)
- ✅ Combining G01/G02/G03/G70/G71 and D01 in a single command. (Spec 8.3.1)
- ✅ Combining G01/G02/G03/G70/G71 and D02 in a single command. (Spec 8.3.1)
- ✅ Combining G01/G02/G03/G70/G71 and D03 in a single command. (Spec 8.3.1)
- ⛔ Coordinate Data without Operation Code. (Spec 8.3.2)
- ⛔ Style Variations in Command Codes. (Spec 8.3.3)
- ❌ Deprecated usage of SR. (Spec 8.3.4)
- ❌ Deprecated Attribute Values. (Spec 8.4)

- **Important**: _Incremental notation itself is not supported and is not planned
due to lack of test assets and expected complications during implementation._

> PS. I had great time adding emoji to this table.
20 changes: 18 additions & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ numpy = [
pyyaml = "^6.0.1"
pygls = { version = "^1.0.2", optional = true }
lsprotocol = { version = "^2023.0.0a3", optional = true }
drawsvg = { version = "^2.3.0", optional = true }

[tool.poetry.group.dev.dependencies]
mypy = "^1.6.1"
Expand Down Expand Up @@ -93,6 +94,7 @@ mike = "^1.1.2"

[tool.poetry.extras]
language_server = ["pygls", "lsprotocol"]
svg = ["drawsvg"]

[build-system]
requires = ["poetry-core"]
Expand Down
8 changes: 8 additions & 0 deletions src/pygerber/common/rgba.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,11 @@ def as_rgba_float(self) -> tuple[float, float, float, float]:
float(Decimal(self.b) / Decimal(255)),
float(Decimal(self.a) / Decimal(255)),
)

def to_hex(self) -> str:
"""Return color as hexadecimal string."""
r = f"{self.r:0{2}x}"
g = f"{self.g:0{2}x}"
b = f"{self.b:0{2}x}"
a = f"{self.a:0{2}x}"
return f"#{r}{g}{b}{a}"
27 changes: 25 additions & 2 deletions src/pygerber/gerberx3/math/vector_2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ def angle_between_cc(self, other: Vector2D) -> float:
Value returned is always between 0 and 360 (can be 0, never 360).
"""
v0 = self / self.length()
v1 = other / other.length()
v0 = self.normalize()
v1 = other.normalize()
angle_radians = math.atan2(
((v0.x * v1.y) - (v1.x * v0.y)).value, # determinant
((v0.x * v1.x) + (v0.y * v1.y)).value, # dot product
Expand All @@ -209,6 +209,29 @@ def determinant(self, other: Vector2D) -> Offset:
"""Calculate determinant of matrix constructed from self and other."""
return self.x * other.y - self.y * other.x

def perpendicular(self) -> Vector2D:
"""Return perpendicular vector to self."""
return Vector2D(x=self.y, y=-self.x)

def normalize(self) -> Vector2D:
"""Return normalized (unit length) vector."""
if self == Vector2D.NULL:
return Vector2D.UNIT_X

return self / self.length()

def as_float_tuple(self) -> tuple[float, float]:
"""Return x, y Offset as tuple."""
return (float(self.x.value), float(self.y.value))

def rotate_around_origin(self, angle_degrees: Decimal) -> Vector2D:
"""Return vector rotated x degrees around origin."""
angle_radians = math.radians(angle_degrees)
return Vector2D(
x=self.x * math.cos(angle_radians) - self.y * math.sin(angle_radians),
y=self.x * math.sin(angle_radians) + self.y * math.cos(angle_radians),
)


Vector2D.NULL = Vector2D(x=Offset.NULL, y=Offset.NULL)
Vector2D.UNIT_X = Vector2D(x=Offset(value=Decimal(1)), y=Offset.NULL)
Expand Down
Loading

0 comments on commit 940c61c

Please sign in to comment.