Skip to content

Commit 1d9b553

Browse files
authored
Merge pull request #57 from Zulko/modernize-deps
Modernize the dependencies
2 parents d9fda97 + f2bf220 commit 1d9b553

25 files changed

+2582
-455
lines changed

.github/workflows/tests.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main, master ]
6+
pull_request:
7+
branches: [ main, master ]
8+
9+
permissions:
10+
contents: read
11+
12+
concurrency:
13+
group: ci-${{ github.ref }}
14+
cancel-in-progress: true
15+
16+
jobs:
17+
tests:
18+
runs-on: ubuntu-latest
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13" ]
23+
24+
steps:
25+
- name: Checkout
26+
uses: actions/checkout@v4
27+
28+
- name: Set up Python ${{ matrix.python-version }}
29+
uses: actions/setup-python@v5
30+
with:
31+
python-version: ${{ matrix.python-version }}
32+
cache: "pip"
33+
34+
- name: Install system dependencies (Cairo)
35+
run: |
36+
sudo apt-get update
37+
sudo apt-get install -y libcairo2-dev pkg-config
38+
39+
- name: Install project and test dependencies
40+
run: |
41+
python -m pip install --upgrade pip
42+
pip install -e .
43+
pip install pytest Pillow
44+
45+
- name: Run tests
46+
run: |
47+
pytest -q
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
name: Version Bump & Release
2+
3+
on:
4+
push:
5+
branches: [ main, master ]
6+
7+
permissions:
8+
contents: write
9+
id-token: write
10+
11+
jobs:
12+
bump-and-release:
13+
if: ${{ !startsWith(github.event.head_commit.message, '[SKIP]') }}
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0
20+
21+
- name: Set up Python
22+
uses: actions/setup-python@v5
23+
with:
24+
python-version: "3.x"
25+
26+
- name: Configure Git author
27+
run: |
28+
git config user.name "${GITHUB_ACTOR}"
29+
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
30+
31+
- name: Install bump and build tooling
32+
run: |
33+
python -m pip install --upgrade pip
34+
pip install bump2version build
35+
36+
# Bump logic controlled by commit message prefix:
37+
# [MAJOR] -> major, [FEATURE] -> minor, default -> patch
38+
- name: Bump Major Version
39+
if: startsWith(github.event.head_commit.message, '[MAJOR]')
40+
run: |
41+
bump2version major
42+
echo "BUMPED=1" >> $GITHUB_ENV
43+
44+
- name: Bump Minor Version
45+
if: startsWith(github.event.head_commit.message, '[FEATURE]')
46+
run: |
47+
bump2version minor
48+
echo "BUMPED=1" >> $GITHUB_ENV
49+
50+
- name: Bump Patch Version
51+
if: env.BUMPED != '1'
52+
run: |
53+
bump2version patch
54+
55+
- name: Push version tag
56+
run: |
57+
git push --follow-tags
58+
59+
- name: Build distributions
60+
run: |
61+
python -m build
62+
63+
# Prefer Trusted Publisher via OIDC if configured on PyPI.
64+
# If not yet configured, set PYPI_API_TOKEN secret and uncomment 'password:' below.
65+
- name: Publish to PyPI
66+
uses: pypa/gh-action-pypi-publish@release/v1
67+
with:
68+
# password: ${{ secrets.PYPI_API_TOKEN }}
69+
skip-existing: true

.pre-commit-config.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
repos:
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
rev: v0.8.4
4+
hooks:
5+
# Run the linter
6+
- id: ruff
7+
args: [--fix]
8+
# Run the formatter
9+
- id: ruff-format
10+
11+
- repo: https://github.com/pre-commit/pre-commit-hooks
12+
rev: v5.0.0
13+
hooks:
14+
- id: trailing-whitespace
15+
- id: end-of-file-fixer
16+
- id: check-yaml
17+
- id: check-added-large-files
18+
- id: check-merge-conflict
19+
- id: check-toml

.travis.yml

Lines changed: 0 additions & 14 deletions
This file was deleted.

LICENCE.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ The MIT License (MIT)
44

55
The MIT License (MIT)
66

7-
Copyright (c) 2014 Zulko
7+
Copyright (c) 2025 Zulko
88

99
Permission is hereby granted, free of charge, to any person obtaining a copy
1010
of this software and associated documentation files (the "Software"), to deal
@@ -23,4 +23,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2323
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2424
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2525
THE SOFTWARE.
26-

README.md

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
<p align="center">
2+
<img src="https://raw.githubusercontent.com/Zulko/gizeh/master/logo.jpeg" alt="[logo]" />
3+
</p>
4+
5+
# Gizeh — Cairo for tourists
6+
7+
Gizeh is a Python library for vector graphics, built on top of [`cairocffi`](https://cairocffi.readthedocs.io/) (Cairo bindings for Python). Cairo is powerful but low-level; Gizeh adds a small set of intuitive primitives to make drawing easier.
8+
9+
```python
10+
# Let's draw a red circle!
11+
import gizeh
12+
13+
surface = gizeh.Surface(width=320, height=260) # pixels
14+
circle = gizeh.circle(r=30, xy=[40, 40], fill=(1, 0, 0))
15+
circle.draw(surface) # draw the circle on the surface
16+
surface.write_to_png("circle.png") # export as PNG
17+
```
18+
19+
See Gizeh in action (combined with MoviePy for animations) in
20+
[this blog post](http://zulko.github.io/blog/2014/09/20/vector-animations-with-python/).
21+
22+
Gizeh supports Python 3.7+.
23+
24+
## Installation
25+
26+
Gizeh requires the Cairo graphics library to be installed on your system.
27+
28+
- macOS (Homebrew):
29+
- `brew install cairo pkg-config`
30+
- Debian/Ubuntu:
31+
- `sudo apt-get install -y libcairo2-dev pkg-config`
32+
33+
Then install the Python package:
34+
35+
```bash
36+
pip install gizeh
37+
```
38+
39+
Alternatively, from source (editable/development install):
40+
41+
```bash
42+
pip install -e .
43+
```
44+
45+
## User Guide
46+
47+
This guide, along with the examples in `gizeh/examples`, should give you everything you need to get started. Check docstrings for details.
48+
49+
### Surfaces
50+
51+
A Surface is a rectangle of fixed dimensions (in pixels) on which you draw elements, and which you can save/export as an image:
52+
53+
```python
54+
import gizeh
55+
56+
# initialize surface
57+
surface = gizeh.Surface(width=320, height=260) # in pixels
58+
59+
# make a shape and draw it on the surface
60+
circle = gizeh.circle(r=30, xy=[40, 40], fill=(1, 1, 1))
61+
circle.draw(surface)
62+
63+
# export the surface
64+
surface.get_npimage() # returns a (width x height x 3) numpy array
65+
surface.write_to_png("circle.png")
66+
```
67+
68+
### Elements
69+
70+
Basic elements are circles, rectangles, lines, text, etc., that you draw on a surface using `my_element.draw(surface)`. Common parameters:
71+
72+
- `xy`: center coordinates of the object. At render time (`surface.write_to_png`) you can set `y_origin` to `"top"` (default) or `"bottom"`. With `"top"`, `(0, 0)` is the upper-left of the final image; the bottom-right is `(width, height)`. With `"bottom"`, `(0, 0)` is the bottom-left (like plots), and `(width, height)` is the top-right.
73+
- `angle`: rotation (radians) around `xy`.
74+
- `fill`: interior fill (default: none). Can be a color `(R, G, B)`, gradient, image pattern, etc.
75+
- `stroke`: contour fill; same rules as `fill`.
76+
- `stroke_width`: contour width (pixels). Default is `0` (no stroke).
77+
78+
Examples:
79+
80+
```python
81+
import numpy as np
82+
Pi = np.pi
83+
84+
circ = gizeh.circle(r=30, xy=(50, 50), fill=(1, 1, 1))
85+
rect = gizeh.rectangle(lx=60.3, ly=45, xy=(60, 70), fill=(0, 1, 0), angle=Pi/8)
86+
sqr = gizeh.square(l=20, stroke=(1, 1, 1), stroke_width=1.5)
87+
arc = gizeh.arc(r=20, a1=Pi/4, a2=3*Pi/4, fill=(1, 1, 1))
88+
text = gizeh.text("Hello world", fontfamily="Impact", fontsize=40,
89+
fill=(1, 1, 1), xy=(100, 100), angle=Pi/12)
90+
poly = gizeh.regular_polygon(r=40, n=5, angle=np.pi/4, xy=[40, 50], fill=(1, 0, 1))
91+
line = gizeh.polyline(points=[(0, 0), (20, 30), (40, 40), (0, 10)],
92+
stroke_width=3, stroke=(1, 0, 0), fill=(0, 1, 0))
93+
```
94+
95+
### Fill and stroke
96+
97+
`fill` and `stroke` can be:
98+
99+
- RGB `(r, g, b)` with values in `[0, 1]`
100+
- RGBA `(r, g, b, a)` with `a` in `[0, 1]`
101+
- `gizeh.ColorGradient`
102+
- `gizeh.ImagePattern` (an image)
103+
- A NumPy RGB/RGBA image array (where implemented)
104+
105+
### Transformations
106+
107+
Elements can be transformed (translated, rotated, scaled). All transformations are out-of-place: they return a modified copy.
108+
109+
```python
110+
square_1 = gizeh.square(l=20, xy=[30, 35], fill=(1, 0, 0))
111+
square_2 = square_1.rotate(np.pi/8) # rotation around [0, 0] by default
112+
square_3 = square_2.rotate(np.pi/4, center=[10, 15]) # rotation around a center
113+
square_4 = square_1.scale(2) # two times bigger
114+
square_5 = square_1.scale(sx=2, sy=3) # width x2, height x3
115+
square_6 = square_1.scale(2, center=[30, 30]) # zoom around a center
116+
square_7 = square_1.translate(xy=[5, 15]) # translation
117+
```
118+
119+
### Groups
120+
121+
A `Group` is a collection of elements (including nested groups) transformed and drawn together:
122+
123+
```python
124+
square = gizeh.square(l=20, fill=(1, 0, 0), xy=(40, 40))
125+
circle = gizeh.circle(r=20, fill=(1, 1, 0), xy=(50, 30))
126+
group_1 = gizeh.Group([square, circle])
127+
group_2 = group_1.translate(xy=[30, 30]).rotate(np.pi/4)
128+
group_3 = gizeh.Group([circle, group_1])
129+
130+
surface = gizeh.Surface(width=300, height=200)
131+
group_1.draw(surface)
132+
group_2.draw(surface)
133+
group_3.draw(surface)
134+
surface.write_to_png("my_masterwork.png")
135+
```
136+
137+
## Troubleshooting installation
138+
139+
If pip installation fails, ensure you have the system Cairo development packages and `pkg-config` installed (see “Installation” above).
140+
141+
- macOS (Homebrew): `brew install cairo pkg-config`
142+
- Debian/Ubuntu: `sudo apt-get install -y libcairo2-dev pkg-config`
143+
144+
## Developers
145+
146+
Development uses [`uv`](https://github.com/astral-sh/uv) for fast Python packaging and workflows.
147+
148+
Prerequisites:
149+
150+
- Install system packages
151+
- macOS: `brew install uv cairo pkg-config`
152+
- Debian/Ubuntu: `sudo apt-get install -y libcairo2-dev pkg-config` and install `uv` from its docs
153+
154+
Setup and install deps:
155+
156+
```bash
157+
uv python install 3.12
158+
uv venv --python 3.12
159+
uv sync --group dev
160+
```
161+
162+
Run tests:
163+
164+
```bash
165+
uv run pytest -q
166+
```
167+
168+
Run a specific test:
169+
170+
```bash
171+
uv run pytest -q tests/test_samples.py::test_random_squares
172+
```
173+
174+
Quick import check:
175+
176+
```bash
177+
uv run python -c "import gizeh, numpy, cairocffi; print('ok')"
178+
```
179+
180+
Install and run pre-commit hooks:
181+
182+
```bash
183+
uv run pre-commit install
184+
uv run pre-commit run --all-files
185+
```
186+
187+
## Contributing
188+
189+
Gizeh is open-source (MIT) by [Zulko](https://github.com/Zulko). Contributions are welcome—issues and pull requests on
190+
[GitHub](https://github.com/Zulko/gizeh).

0 commit comments

Comments
 (0)