-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
350 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
root = true | ||
|
||
[*] | ||
charset = utf-8 | ||
# end_of_line = lf | ||
insert_final_newline = true | ||
trim_trailing_whitespace = true | ||
indent_style = tab | ||
indent_size = 2 | ||
tab_width = 2 | ||
|
||
|
||
[*.py] | ||
indent_style = tab | ||
indent_size = 2 | ||
|
||
[*.{yml,yaml}] | ||
indent_style = space | ||
indent_size = 2 | ||
|
||
[*.{json,ini}] | ||
indent_style = tab | ||
indent_size = 2 | ||
|
||
[*.md] | ||
trim_trailing_whitespace = false | ||
|
||
[*.rst] | ||
indent_style = space | ||
indent_size = 3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
name: Generate EDA² logos | ||
|
||
on: | ||
push: | ||
paths: | ||
- '.github/workflows/Pipeline.yml' | ||
- '*.py' | ||
pull_request: | ||
paths: | ||
- '.github/workflows/Pipeline.yml' | ||
- '*.py' | ||
schedule: | ||
- cron: '0 0 * * 5' | ||
workflow_dispatch: | ||
|
||
jobs: | ||
Logos: | ||
runs-on: ubuntu-latest | ||
name: Generate logos | ||
|
||
steps: | ||
- name: ⏬ Repository Checkout | ||
uses: actions/checkout@v4 | ||
|
||
- name: 🐍 Setup Python 3.13 | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: "3.13" | ||
|
||
- name: Install dependencies | ||
run: | | ||
python -m pip install --disable-pip-version-check -U ./requirements.txt | ||
- name: Generate EDA² logos | ||
id: generate | ||
run: | | ||
python main.py | ||
- name: Investigate | ||
run: | | ||
tree . |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Python cache and object files | ||
__pycache__/ | ||
*.py[cod] | ||
|
||
# PyCharm project files | ||
/.idea/workspace.xml | ||
|
||
# Git files | ||
!.git* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
from typing import TypeVar, Union, Generic, Any, Self, Tuple | ||
|
||
from pyTooling.Decorators import export | ||
|
||
Coordinate = TypeVar("Coordinate", bound=Union[int, float]) | ||
|
||
|
||
@export | ||
class Point(Generic[Coordinate]): | ||
x: Coordinate | ||
y: Coordinate | ||
|
||
def __init__(self, x: Coordinate, y: Coordinate) -> None: | ||
if not isinstance(x, (int, float)): | ||
raise TypeError() | ||
if not isinstance(y, (int, float)): | ||
raise TypeError() | ||
|
||
self.x = x | ||
self.y = y | ||
|
||
def ToTuple(self) -> Tuple[Coordinate, Coordinate]: | ||
return self.x, self.y | ||
|
||
def __add__(self, other: Any) -> "Point[Coordinate]": | ||
if isinstance(other, Offset): | ||
return Point( | ||
self.x + other.xOffset, | ||
self.y + other.yOffset | ||
) | ||
else: | ||
raise TypeError() | ||
|
||
def __iadd__(self, other: Any) -> Self: | ||
if isinstance(other, Offset): | ||
self.x += other.xOffset | ||
self.y += other.yOffset | ||
else: | ||
raise TypeError() | ||
|
||
return self | ||
|
||
def __sub__(self, other: Any) -> Union["Offset[Coordinate]", "Point[Coordinate]"]: | ||
if isinstance(other, Point): | ||
return Offset( | ||
self.x - other.x, | ||
self.y - other.y | ||
) | ||
elif isinstance(other, Offset): | ||
return Point( | ||
self.x - other.xOffset, | ||
self.y - other.yOffset | ||
) | ||
else: | ||
raise TypeError() | ||
|
||
def __isub__(self, other: Any) -> Self: | ||
if isinstance(other, Offset): | ||
self.x -= other.xOffset | ||
self.y -= other.yOffset | ||
else: | ||
raise TypeError() | ||
|
||
return self | ||
|
||
def __repr__(self) -> str: | ||
return f"Point({self.x}, {self.y})" | ||
|
||
def __str__(self) -> str: | ||
return f"({self.x}, {self.y})" | ||
|
||
|
||
@export | ||
class Offset(Generic[Coordinate]): | ||
xOffset: Coordinate | ||
yOffset: Coordinate | ||
|
||
def __init__(self, xOffset: Coordinate, yOffset: Coordinate) -> None: | ||
if not isinstance(xOffset, (int, float)): | ||
raise TypeError() | ||
if not isinstance(yOffset, (int, float)): | ||
raise TypeError() | ||
|
||
self.xOffset = xOffset | ||
self.yOffset = yOffset | ||
|
||
def ToTuple(self) -> Tuple[Coordinate, Coordinate]: | ||
return self.xOffset, self.yOffset | ||
|
||
def __add__(self, other: Any) -> "Offset[Coordinate]": | ||
if isinstance(other, Offset): | ||
return Offset( | ||
self.xOffset + other.xOffset, | ||
self.yOffset + other.yOffset | ||
) | ||
else: | ||
raise TypeError() | ||
|
||
def __iadd__(self, other: Any) -> Self: | ||
if isinstance(other, Offset): | ||
self.xOffset += other.xOffset | ||
self.yOffset += other.yOffset | ||
else: | ||
raise TypeError() | ||
|
||
return self | ||
|
||
def __sub__(self, other: Any) -> "Offset[Coordinate]": | ||
if isinstance(other, Offset): | ||
return Offset( | ||
self.xOffset - other.xOffset, | ||
self.yOffset - other.yOffset | ||
) | ||
else: | ||
raise TypeError() | ||
|
||
def __isub__(self, other: Any) -> Self: | ||
if isinstance(other, Offset): | ||
self.xOffset -= other.xOffset | ||
self.yOffset -= other.yOffset | ||
else: | ||
raise TypeError() | ||
|
||
return self | ||
|
||
def __repr__(self) -> str: | ||
return f"Offset({self.xOffset}, {self.yOffset})" | ||
|
||
def __str__(self) -> str: | ||
return f"({self.xOffset}, {self.yOffset})" | ||
|
||
|
||
@export | ||
class Size: | ||
width: Coordinate | ||
height: Coordinate | ||
|
||
def __init__(self, width: Coordinate, height: Coordinate) -> None: | ||
if not isinstance(width, (int, float)): | ||
raise TypeError() | ||
if not isinstance(height, (int, float)): | ||
raise TypeError() | ||
|
||
self.width = width | ||
self.height = height | ||
|
||
def ToTuple(self) -> Tuple[Coordinate, Coordinate]: | ||
return self.width, self.height | ||
|
||
def __repr__(self) -> str: | ||
return f"Size({self.width}, {self.height})" | ||
|
||
def __str__(self) -> str: | ||
return f"({self.width}, {self.height})" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
from enum import Enum | ||
from pathlib import Path | ||
from typing import Optional as Nullable, Tuple, Dict | ||
|
||
from pyTooling.Decorators import export | ||
from pyTooling.MetaClasses import abstractmethod | ||
from svgwrite import Drawing | ||
|
||
from Datatypes import Offset, Size | ||
|
||
|
||
@export | ||
class ColorMode(Enum): | ||
LightMode = 0 | ||
DarkMode = 1 | ||
|
||
|
||
@export | ||
class ColorTuple: | ||
dark: str | ||
light: str | ||
|
||
def __init__(self, dark: str, light: str) -> None: | ||
self.dark = dark | ||
self.light = light | ||
|
||
|
||
@export | ||
class Logo: | ||
@abstractmethod | ||
def GenerateSVG(self, file: Path, colorMode: ColorMode) -> None: | ||
pass | ||
|
||
|
||
|
||
@export | ||
class PyEDAALayers(Logo): | ||
colors: Dict[ColorMode, Tuple[ColorTuple, ...]] | ||
|
||
def __init__(self): | ||
self.colors = { | ||
ColorMode.LightMode: (# dark, light on light | ||
ColorTuple("#c62828", "#ef5350"), # Red | ||
ColorTuple("#8e24aa", "#ba68c8"), # Purple | ||
ColorTuple("#0277bd", "#29b6f6"), # Light Blue | ||
ColorTuple("#558b2f", "#9ccc65"), # Light Green | ||
ColorTuple("#ff8f00", "#ffca28"), # Amber | ||
ColorTuple("#37474f", "#78909c") # Blue Grey | ||
), | ||
ColorMode.DarkMode: (# dark, light on light | ||
ColorTuple("#c62828", "#ef5350"), | ||
ColorTuple("#8e24aa", "#ba68c8"), | ||
ColorTuple("#0277bd", "#29b6f6"), | ||
ColorTuple("#558b2f", "#9ccc65"), | ||
ColorTuple("#ff8f00", "#ffca28"), | ||
ColorTuple("#78909c", "#b0bec5") | ||
) | ||
} | ||
|
||
def _drawRectangles(self, dwg, shades: Tuple[ColorTuple, ...], offset: Nullable[Offset] = None, unit: int = 50): | ||
""" | ||
Draw the default multi-coloured EDA² logo without strokes. | ||
:param dwg: | ||
:param colors: Tuple of 6 colors. One per layer. | ||
:param shades: Tuple of 2 shades. | ||
:param offset: | ||
:param unit: | ||
:return: | ||
""" | ||
if offset is None: | ||
offset = Offset(0, 0) | ||
|
||
rectSize = Size(2 * unit, unit) | ||
|
||
for levelIndex, colors in enumerate(shades): | ||
firstRectOffset = offset + Offset(2 * unit, levelIndex * unit) | ||
secondRectOffset = offset + Offset(4 * unit * (levelIndex % 2), levelIndex * unit) | ||
|
||
dwg.add( | ||
dwg.rect( | ||
insert=firstRectOffset.ToTuple(), | ||
size=rectSize.ToTuple(), | ||
fill=colors.dark, | ||
) | ||
) | ||
dwg.add( | ||
dwg.rect( | ||
insert=secondRectOffset.ToTuple(), | ||
size=rectSize.ToTuple(), | ||
fill=colors.light, | ||
) | ||
) | ||
|
||
def GenerateSVG(self, file: Path, colorMode: ColorMode) -> None: | ||
""" | ||
Generate and save the default logo to file 'edaa.svg' | ||
""" | ||
dwg = Drawing(str(file), (300, 300), debug=True) | ||
self._drawRectangles(dwg, self.colors[colorMode]) | ||
dwg.save(pretty=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from pathlib import Path | ||
from typing import Dict, NoReturn | ||
|
||
from Logo import PyEDAALayers, ColorMode | ||
|
||
|
||
def main() -> NoReturn: | ||
pyEDAALayersLogo = PyEDAALayers() | ||
pyEDAALayersLogo.GenerateSVG(Path("edaa-light.svg"), ColorMode.LightMode) | ||
pyEDAALayersLogo.GenerateSVG(Path("edaa-dark.svg"), ColorMode.DarkMode) | ||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
svgwrite | ||
pyTooling ~= 8.0 | ||
svgwrite ~= 1.4 |