Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
30e27de
nixoslogo: bump minimum python version to 3.11
djacu Oct 10, 2026
9fa5f94
devShells.nixos-logo-dev: add types-lxml to fix linting warnings
djacu Oct 10, 2026
6e0fccd
nixoslogo: fix linting errors in core.py
djacu Oct 10, 2026
615ba24
nixoslogo: fix make_filename typing treewide
djacu Oct 10, 2026
a387134
nixoslogo: fix and rename _init_canvas to _make canvas
djacu Oct 10, 2026
bdaa077
nixoslogo: fix canvas parameters type hints in layout.py
djacu Oct 10, 2026
198d426
nixoslogo: return a flat list of elements from make_svg_elements
djacu Oct 11, 2026
10dd881
nixoslogo: add py.typed marker
djacu Oct 11, 2026
2084f7f
nixoslogo: import Lambda from its defining module in clearspace
djacu Oct 11, 2026
144d0cc
nixoslogo: require a DimensionedLambda in the dimensioned logomarks
djacu Oct 11, 2026
c5e96d9
nixoslogo: annotate LogoClearspace.logo as a class
djacu Oct 11, 2026
b598ecb
nixoslogo: fix logomark colors typing
djacu Oct 11, 2026
2e80738
nixoslogo: make FontLoader cap height and loader non-optional
djacu Oct 11, 2026
78ac46e
nixoslogo: assign the logo's optional arguments once
djacu Oct 11, 2026
017665b
nixoslogo: accept a float dimension reference
djacu Oct 11, 2026
630a6f1
nixoslogo: fix geometry return types and drop Number annotations
djacu Oct 11, 2026
fba1a11
nixoslogo: give the geometry sequences their element types
djacu Oct 11, 2026
e6b5273
nixoslogo: type stroke_dasharray as the list svg expects
djacu Oct 11, 2026
d3de832
nixoslogo: drop the unused colors parameter from make_filename
djacu Oct 11, 2026
435be7c
nixoslogo: return a bounding box tuple from NixosLogo
djacu Oct 11, 2026
1a7556f
nixoslogo: describe the annotation config dicts
djacu Oct 11, 2026
70b8354
nixoslogo: narrow the glyph scale guards
djacu Oct 11, 2026
42e91fe
nixoslogo: type the dimension line options
djacu Oct 11, 2026
de01ab6
nixoslogo: pass lists where svg expects lists in clearspace
djacu Oct 11, 2026
cdba9de
nixoslogo: use svg Length for the gradient stop offsets
djacu Oct 11, 2026
e571b37
nixoslogo: fix the last of the type errors
djacu Oct 11, 2026
63ab326
nixoslogo: annotate the dimension drawing parameters
djacu Oct 11, 2026
32e8d39
nixoslogo: treewide fix of a bunch of unannotated parameters
djacu Oct 11, 2026
4a203ee
nixoslogo: annotate the darken lambda
djacu Oct 11, 2026
b252cfb
nixoslogo: treewide more type annotation fixes
djacu Oct 11, 2026
fe019a6
nixoslogo: declare the types of computed attributes
djacu Oct 11, 2026
8745bb8
nixoslogo: mark the overriding methods
djacu Oct 11, 2026
889a19b
nixoslogo: sort the typing imports
djacu Oct 11, 2026
2ae4d25
nixoslogo: drop the unreachable enum match guards
djacu Oct 11, 2026
ee03e5b
nixoslogo: ruff fixes
djacu Oct 11, 2026
f812749
nixoslogo: return NotImplemented for unsupported operands
djacu Oct 11, 2026
a52039a
nixoslogo: improve logotype error handling
djacu Oct 11, 2026
5e4a56e
nixoslogo: overload the geometry operators
djacu Oct 11, 2026
36e7d82
nixoslogo: remove dead parameter, `side`
djacu Oct 11, 2026
7faf2ba
nixoslogo: add list annotation in logomark for linear_gradient
djacu Oct 11, 2026
95b66dc
nixoslogo: remove transforms from _offset_glyph as it was not used
djacu Oct 11, 2026
5a60219
nixoslogo: copy2 returns an unused value
djacu Oct 11, 2026
c7bde69
nixoslogo: annotate[C the glyph bounding box and read translate offse…
djacu Oct 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dev-shells/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ mapAttrs (system: pkgs: {
(python3.withPackages (ps: [
ps.nixoslogo-editable
ps.fontforge
ps.types-lxml
]))

];
Expand Down
190 changes: 111 additions & 79 deletions package-sets/python-packages/nixoslogo/nixoslogo/annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
from collections.abc import Callable
from dataclasses import dataclass
from pathlib import Path
from typing import NotRequired, TypedDict, override

import svg
from svg._types import Number

from nixoslogo.core import (
CHARACTER_GLYPHNAME_MAP,
DEFAULT_JURA_TRANSFORMS,
BaseRenderable,
flatten_svg_elements,
get_nixos_annotation_font_file,
)
from nixoslogo.geometry import Point
Expand All @@ -27,25 +30,25 @@ def __init__(
cap_height: float | None = None,
**kwargs,
):
self.characters = characters
self.loader = loader
self.color = color
self.scale = scale
self.cap_height = cap_height
self.characters: str = characters
self.loader: FontLoader = loader
self.color: str = color
self.scale: float | None = scale
self.cap_height: float | None = cap_height

self._load_glyphs()
self.original_cap_height = self.loader.capHeight
self.original_scale = self.loader.scale
self.original_cap_height: float = self.loader.capHeight
self.original_scale: float = self.loader.scale
self._set_spacings()
self._scale_glyphs()

super().__init__(**kwargs)

def _map_characters(self, character):
def _map_characters(self, character: str) -> str:
return CHARACTER_GLYPHNAME_MAP.get(character, character)

def _load_glyphs(self):
self.glyphs = tuple(
self.glyphs: tuple[Glyph, ...] = tuple(
Glyph(
loader=self.loader,
character=self._map_characters(character),
Expand All @@ -55,6 +58,7 @@ def _load_glyphs(self):
)

@property
@override
def elements_bounding_box(self):
characters_box = tuple(
f(elem)
Expand All @@ -77,27 +81,31 @@ def _set_spacings(self):
x_offset += glyph.glyph.width

def _scale_glyphs(self):
if self.scale is None and self.cap_height is None:
return

if self.scale is not None and self.cap_height is not None:
raise ValueError("Only one of scale or cap_height can be set.")

if self.cap_height is not None:
self.scale = self.original_cap_height / self.cap_height
scale = self.original_cap_height / self.cap_height
elif self.scale is not None:
scale = self.scale
self.cap_height = self.original_cap_height / scale
else:
self.cap_height = self.original_cap_height / self.scale
return

self.scale = scale
for glyph in self.glyphs:
glyph.layer.transform((1 / self.scale, 0, 0, 1 / self.scale, 0, 0))
glyph.layer.transform((1 / scale, 0, 0, 1 / scale, 0, 0))

@override
def _get_clearspace(self):
return 0

def make_svg_elements(self):
return tuple(elem.make_svg_element() for elem in self.glyphs)
@override
def make_svg_elements(self) -> list[svg.Element]:
return flatten_svg_elements(*(elem.make_svg_element() for elem in self.glyphs))

def make_filename(self, extras: tuple[str] = ()):
@override
def make_filename(self, extras: tuple[str, ...] = ()):
return "-".join(
[
self.characters.lower(),
Expand All @@ -108,12 +116,27 @@ def make_filename(self, extras: tuple[str] = ()):
)


class LineConfig(TypedDict):
name: str
stroke: str
stroke_width: int
stroke_dasharray: list[Number]
fill: NotRequired[str]


class FontConfig(TypedDict):
scale: float | None
cap_height: float
color: str
stroke_dasharray: list[Number]


@dataclass
class LineGroup:
name: str
stroke: str
stroke_width: int
stroke_dasharray: int
stroke_dasharray: list[Number]
fill: str = "transparent"


Expand All @@ -131,25 +154,25 @@ class DimensionLines(LineGroup):
def __init__(
self,
font_loader: FontLoader,
font_config: dict,
font_config: FontConfig,
**kwargs,
):
super().__init__(**kwargs)
self.font_loader = font_loader
self.font_config = font_config
self.font_loader: FontLoader = font_loader
self.font_config: FontConfig = font_config

def make_dimension_line(
self,
point1,
point2,
flip=False,
side="left",
offset=1,
reference=1,
text=None,
text_offset=False,
fractional=True,
precision=3,
point1: Point,
point2: Point,
flip: bool = False,
side: str = "left",
offset: float = 1,
reference: float = 1,
text: str | None = None,
text_offset: bool = False,
fractional: bool = True,
precision: int = 3,
):
if flip:
point1, point2 = point2, point1
Expand All @@ -172,12 +195,16 @@ def make_dimension_line(
else:
if text is None:
if fractional:
text = fractions.Fraction(round(measured_line.length()), reference)
label = fractions.Fraction(
round(measured_line.length()), round(reference)
)
else:
text = round(measured_line.length() / reference, precision)
label = round(measured_line.length() / reference, precision)
else:
label = text

text_annotation = TextAnnotations(
characters=str(text),
characters=str(label),
loader=self.font_loader,
**self.font_config,
)
Expand Down Expand Up @@ -261,16 +288,16 @@ def make_dimension_line(

def make_dimension_line_outer(
self,
point1,
point2,
flip=False,
side="left",
offset=1,
reference=1,
text=None,
text_offset=False,
fractional=True,
precision=3,
point1: Point,
point2: Point,
flip: bool = False,
side: str = "left",
offset: float = 1,
reference: float = 1,
text: str | None = None,
text_offset: bool = False,
fractional: bool = True,
precision: int = 3,
):
if flip:
point1, point2 = point2, point1
Expand All @@ -297,12 +324,16 @@ def make_dimension_line_outer(
else:
if text is None:
if fractional:
text = fractions.Fraction(round(measured_line.length()), reference)
label = fractions.Fraction(
round(measured_line.length()), round(reference)
)
else:
text = round(measured_line.length() / reference, precision)
label = round(measured_line.length() / reference, precision)
else:
label = text

text_annotation = TextAnnotations(
characters=str(text),
characters=str(label),
loader=self.font_loader,
**self.font_config,
)
Expand Down Expand Up @@ -386,14 +417,13 @@ def make_dimension_line_outer(

def make_dimension_angle(
self,
point1,
point2,
reference,
flip,
large,
side,
ratio,
text=None,
point1: Point,
point2: Point,
reference: Point,
flip: bool,
large: bool,
ratio: float,
text: str | None = None,
):
if flip:
point1, point2 = point2, point1
Expand Down Expand Up @@ -492,28 +522,30 @@ def make_dimension_arrow_defs(self):
class Annotations:
def __init__(
self,
object_lines_config: dict,
construction_lines_config: dict,
dimension_lines_config: dict,
font_config: dict,
object_lines_config: LineConfig,
construction_lines_config: LineConfig,
dimension_lines_config: LineConfig,
font_config: FontConfig,
get_font_file: Callable[[], Path] = get_nixos_annotation_font_file,
transforms_map: dict = DEFAULT_JURA_TRANSFORMS,
transforms_map: dict[str, dict[str, int]] = DEFAULT_JURA_TRANSFORMS,
):
self.font_loader = FontLoader(
self.font_loader: FontLoader = FontLoader(
get_font_file=get_font_file,
transforms_map=transforms_map,
offset_glyph=False,
)
self.font_config = font_config
self.object_lines = ObjectLines(**object_lines_config)
self.construction_lines = ConstructionLines(**construction_lines_config)
self.dimension_lines = DimensionLines(
self.font_config: FontConfig = font_config
self.object_lines: ObjectLines = ObjectLines(**object_lines_config)
self.construction_lines: ConstructionLines = ConstructionLines(
**construction_lines_config
)
self.dimension_lines: DimensionLines = DimensionLines(
**dimension_lines_config,
font_loader=self.font_loader,
font_config=self.font_config,
)

def make_annotation(self, text):
def make_annotation(self, text: str) -> TextAnnotations:
return TextAnnotations(
characters=str(text),
loader=self.font_loader,
Expand All @@ -527,25 +559,25 @@ def small(cls) -> "Annotations":
"name": "object",
"stroke": "green",
"stroke_width": 4,
"stroke_dasharray": 4,
"stroke_dasharray": [4],
},
construction_lines_config={
"name": "construction",
"stroke": "blue",
"stroke_width": 2,
"stroke_dasharray": 4,
"stroke_dasharray": [4],
},
dimension_lines_config={
"name": "dimension",
"stroke": "red",
"stroke_width": 1,
"stroke_dasharray": 4,
"stroke_dasharray": [4],
},
font_config={
"scale": None,
"cap_height": 24,
"color": "black",
"stroke_dasharray": 4,
"stroke_dasharray": [4],
},
)

Expand All @@ -556,25 +588,25 @@ def medium(cls) -> "Annotations":
"name": "object",
"stroke": "green",
"stroke_width": 8,
"stroke_dasharray": 8,
"stroke_dasharray": [8],
},
construction_lines_config={
"name": "construction",
"stroke": "blue",
"stroke_width": 4,
"stroke_dasharray": 8,
"stroke_dasharray": [8],
},
dimension_lines_config={
"name": "dimension",
"stroke": "red",
"stroke_width": 2,
"stroke_dasharray": 8,
"stroke_dasharray": [8],
},
font_config={
"scale": None,
"cap_height": 48,
"color": "black",
"stroke_dasharray": 8,
"stroke_dasharray": [8],
},
)

Expand All @@ -585,25 +617,25 @@ def large(cls) -> "Annotations":
"name": "object",
"stroke": "green",
"stroke_width": 16,
"stroke_dasharray": 16,
"stroke_dasharray": [16],
},
construction_lines_config={
"name": "construction",
"stroke": "blue",
"stroke_width": 8,
"stroke_dasharray": 16,
"stroke_dasharray": [16],
},
dimension_lines_config={
"name": "dimension",
"stroke": "red",
"stroke_width": 4,
"stroke_dasharray": 16,
"stroke_dasharray": [16],
},
font_config={
"scale": None,
"cap_height": 96,
"color": "black",
"stroke_dasharray": 16,
"stroke_dasharray": [16],
},
)

Expand Down
Loading
Loading