Skip to content

Commit c1f3478

Browse files
supports transform & scale (#10)
* src/naive_svg.hpp: - SVG 类新增 transform_ 成员变量和 fluent API (svg.transform("scale(1,-1)")) - write() 方法:当 transform_ 非空时,用 <g transform='...'>...</g> 包裹所有内容(grid + elements),缩进也相应调整 src/pybind11_naive_svg.cpp: - 新增 SVG.transform() 的 Python 绑定 用法示例: svg = SVG(800, 600) svg.view_box([xmin, ymin, width, height]) # ENU: Y 轴翻转 svg.transform("scale(1,-1) translate(0,-{})".format(ymin + ymax)) # Ego (x→front, y→left): 旋转 + 翻转 svg.transform("rotate(-90) scale(1,-1)") 所有尺寸(stroke-width, r, font-size)都在世界坐标单位下,用户自己按米估量。 * fix headers * update stub * init CLAUDE.md * add skill.md * fix --------- Co-authored-by: tang zhixiong <zhixiong.tang@momenta.ai>
1 parent dc96a0e commit c1f3478

File tree

7 files changed

+582
-143
lines changed

7 files changed

+582
-143
lines changed

CLAUDE.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
**naive-svg** is a C++/Python hybrid library for SVG generation with GeoJSON-to-SVG conversion. C++ core (`src/naive_svg.hpp`) provides SVG primitives via a fluent API, exposed to Python through pybind11 bindings (`src/pybind11_naive_svg.cpp`). A pure-Python module (`src/naive_svg/geojson2svg.py`) handles GeoJSON conversion with WGS84/ENU coordinate transforms.
8+
9+
## Build & Development Commands
10+
11+
```bash
12+
# Build (editable install with C++ compilation)
13+
make build
14+
15+
# Run tests
16+
make pytest # runs pytest tests/test_basic.py
17+
pytest tests/test_basic.py # core tests
18+
pytest tests/test_geojson_showcase.py -v -s # showcase with SVG output
19+
20+
# Lint (runs pre-commit hooks: ruff, clang-format, cmake-format, mypy)
21+
make lint
22+
23+
# Regenerate type stubs after changing C++ bindings
24+
make restub # runs pybind11-stubgen, copies to src/naive_svg/_core.pyi
25+
```
26+
27+
## Architecture
28+
29+
### Two-layer design
30+
31+
1. **C++ layer** (`src/naive_svg.hpp`): All SVG types live in `namespace cubao` under `struct SVG`. Element types: `Color`, `Polyline`, `Polygon`, `Circle`, `Text`, `Path`, `Rect`. The `SVG` class is the container that holds elements and produces SVG XML via `write()`/`to_string()`/`dump()`.
32+
33+
2. **Python layer** (`src/naive_svg/`): `_core` is the compiled pybind11 module. `geojson2svg.py` adds GeoJSON parsing, coordinate conversion (via `pybind11_geobuf`), and layered styling.
34+
35+
### Fluent API pattern
36+
37+
The C++ macro `SETUP_FLUENT_API(Klass, VarType, VarName)` generates getter/setter pairs where setters return `Klass&` for chaining. A corresponding pybind11 macro `SETUP_FLUENT_API_PYBIND` mirrors this in Python bindings. When adding new element properties, update both macros.
38+
39+
### Key conventions
40+
41+
- All Python files require `from __future__ import annotations` (enforced by ruff isort).
42+
- C++ formatted with `.clang-format`; Python with `ruff format`.
43+
- Type stubs in `stubs/naive_svg/_core.pyi` are auto-generated — edit the C++ bindings, then `make restub`.
44+
- The C++ header is canonical and synced upstream to `cubao-headers` via `make sync_headers`.
45+
46+
## Source Layout
47+
48+
- `src/naive_svg.hpp` — C++ SVG library (single header)
49+
- `src/pybind11_naive_svg.cpp` — pybind11 bindings
50+
- `src/main.cpp` — PYBIND11_MODULE entry point
51+
- `src/naive_svg/geojson2svg.py` — GeoJSON-to-SVG converter (pure Python)
52+
- `src/naive_svg/_core.pyi` — auto-generated type stubs
53+
- `tests/test_basic.py` — unit tests for C++ bindings and geojson2svg
54+
- `tests/test_geojson_showcase.py` — integration test generating showcase SVG

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ test_in_dev_container:
4646

4747
PYTHON ?= python3
4848
build:
49-
$(PYTHON) -m pip install scikit_build_core pyproject_metadata pathspec pybind11
49+
$(PYTHON) -m pip install scikit_build_core pyproject_metadata pathspec pybind11 cubao_headers
5050
CMAKE_BUILD_PARALLEL_LEVEL=$(NUM_JOBS) $(PYTHON) -m pip install --no-build-isolation -Ceditable.rebuild=true -Cbuild-dir=build -ve.
5151
python_install:
5252
$(PYTHON) -m pip install . --verbose
@@ -63,7 +63,7 @@ pytest:
6363
restub:
6464
pybind11-stubgen naive_svg._core -o stubs
6565
cp stubs/naive_svg/_core.pyi src/naive_svg
66-
pre-commit run --files src/naive_svg/_core.pyi
66+
pre-commit run --files src/naive_svg/_core.pyi >/dev/null 2>&1 || true
6767

6868
# conda create -y -n py38 python=3.8
6969
# conda create -y -n py39 python=3.9

0 commit comments

Comments
 (0)