qrforge 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qrforge-1.0.0/LICENSE.md +7 -0
- qrforge-1.0.0/PKG-INFO +174 -0
- qrforge-1.0.0/README.md +140 -0
- qrforge-1.0.0/pyproject.toml +13 -0
- qrforge-1.0.0/qrforge/__init__.py +51 -0
- qrforge-1.0.0/qrforge/__main__.py +6 -0
- qrforge-1.0.0/qrforge/api.py +338 -0
- qrforge-1.0.0/qrforge/bits.py +39 -0
- qrforge-1.0.0/qrforge/cli.py +92 -0
- qrforge-1.0.0/qrforge/color.py +235 -0
- qrforge-1.0.0/qrforge/encoder.py +279 -0
- qrforge-1.0.0/qrforge/exceptions.py +19 -0
- qrforge-1.0.0/qrforge/gf.py +218 -0
- qrforge-1.0.0/qrforge/gradient.py +270 -0
- qrforge-1.0.0/qrforge/image.py +405 -0
- qrforge-1.0.0/qrforge/matrix.py +363 -0
- qrforge-1.0.0/qrforge/presets.py +97 -0
- qrforge-1.0.0/qrforge/render/__init__.py +1 -0
- qrforge-1.0.0/qrforge/render/ansi.py +75 -0
- qrforge-1.0.0/qrforge/render/pdf.py +119 -0
- qrforge-1.0.0/qrforge/render/raster.py +421 -0
- qrforge-1.0.0/qrforge/render/svg.py +312 -0
- qrforge-1.0.0/qrforge/shaders.py +828 -0
- qrforge-1.0.0/qrforge/shapes.py +234 -0
- qrforge-1.0.0/qrforge/style.py +185 -0
- qrforge-1.0.0/qrforge/tables.py +138 -0
- qrforge-1.0.0/qrforge/verify.py +210 -0
- qrforge-1.0.0/qrforge.egg-info/PKG-INFO +174 -0
- qrforge-1.0.0/qrforge.egg-info/SOURCES.txt +34 -0
- qrforge-1.0.0/qrforge.egg-info/dependency_links.txt +1 -0
- qrforge-1.0.0/qrforge.egg-info/entry_points.txt +2 -0
- qrforge-1.0.0/qrforge.egg-info/requires.txt +3 -0
- qrforge-1.0.0/qrforge.egg-info/top_level.txt +1 -0
- qrforge-1.0.0/setup.cfg +4 -0
- qrforge-1.0.0/setup.py +58 -0
- qrforge-1.0.0/tests/test_qrforge.py +419 -0
qrforge-1.0.0/LICENSE.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
MIT License (Modified)
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to make derivative works based on the Software, provided that any substantial changes to the Software are clearly distinguished from the original work and are distributed under a different name.
|
|
4
|
+
|
|
5
|
+
The original copyright notice and disclaimer must be retained in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
qrforge-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: qrforge
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Generate and heavily customise QR codes (shapes, gradients, shaders, logos, textures) in pure Python; Pillow optional.
|
|
5
|
+
Author: qrforge contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: qr,qrcode,barcode,svg,png,generator,art
|
|
8
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
19
|
+
Requires-Python: >=3.8
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE.md
|
|
22
|
+
Provides-Extra: imaging
|
|
23
|
+
Requires-Dist: pillow>=9; extra == "imaging"
|
|
24
|
+
Dynamic: author
|
|
25
|
+
Dynamic: classifier
|
|
26
|
+
Dynamic: description
|
|
27
|
+
Dynamic: description-content-type
|
|
28
|
+
Dynamic: keywords
|
|
29
|
+
Dynamic: license
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
Dynamic: provides-extra
|
|
32
|
+
Dynamic: requires-python
|
|
33
|
+
Dynamic: summary
|
|
34
|
+
|
|
35
|
+
# qrforge
|
|
36
|
+

|
|
37
|
+

|
|
38
|
+

|
|
39
|
+
-blue.svg)
|
|
40
|
+
|
|
41
|
+
An open-source Python library for **generating and art-directing QR codes**: custom module shapes, gradients, shaders, logos, image textures, backgrounds and shadows — output to PNG, SVG, PDF, terminal ANSI, ASCII or Pillow.
|
|
42
|
+
|
|
43
|
+
*qrforge implements the full QR encoding pipeline (modes, Reed–Solomon error correction, masking, versions 1–40) from scratch against the standard library. There are **zero required dependencies**; [Pillow](https://pillow.readthedocs.io) is used only for non-PNG image formats, PIL images, or JPEG/GIF/WEBP logos. PNG reading/writing is built in.*
|
|
44
|
+
|
|
45
|
+
> [!NOTE]
|
|
46
|
+
> **qrforge** is intended to produce both *correct* and *beautiful* QR codes. Every rendered symbol is round-trip verified by a bundled decoder, and the test-suite re-rasterises the SVG geometry to prove it reproduces the matrix — so "pretty" never comes at the cost of "scannable".
|
|
47
|
+
|
|
48
|
+
## Installation
|
|
49
|
+
|
|
50
|
+
You can install qrforge using pip:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install qrforge
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Or from source:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install . # or copy the qrforge/ folder next to your code
|
|
60
|
+
pip install pillow # optional, only for non-PNG formats / PIL images
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Supported Python Versions
|
|
64
|
+
|
|
65
|
+
* Python 3.8 / 3.9 / 3.10 / 3.11 / 3.12 (or later)
|
|
66
|
+
|
|
67
|
+
## Features
|
|
68
|
+
|
|
69
|
+
* **Correct encoder** – versions 1–40, EC levels L/M/Q/H, optimal numeric/alphanumeric/byte segmentation, automatic mask selection.
|
|
70
|
+
* **Shapes** – square, rounded, dot, diamond, hexagon, star, cross, squircle, leaf, heart etc. plus random-per-module mixes and your own SDF shapes.
|
|
71
|
+
* **Gradients & colours** – hex / `rgb()` / `hsl()` / CSS names; linear, radial and conic gradients for modules, eyes and background.
|
|
72
|
+
* **Shaders** – grain, glow, wave, twist, glitch, chromatic aberration, halftone, duotone, scanlines, vignette etc. plus custom Python or one-line expression shaders.
|
|
73
|
+
* **Logos & textures** – auto knockout zone, round/clip the logo, logo background, stroke, rotation, opacity; paint any image inside the modules.
|
|
74
|
+
* **Outputs** – PNG (pure-Python codec), SVG (tiny vector), PDF (vector), terminal ANSI, ASCII, Pillow, HTML.
|
|
75
|
+
* **22 ready-made presets** and a CLI.
|
|
76
|
+
|
|
77
|
+
## Usage
|
|
78
|
+
|
|
79
|
+
### Quickstart
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
import qrforge
|
|
83
|
+
|
|
84
|
+
qrforge.save("https://example.com", "code.png", "neon", scale=12)
|
|
85
|
+
|
|
86
|
+
qr = qrforge.QR("hello", ec="h")
|
|
87
|
+
qr.use_style(module_shape="dot", fg=["#ff0080", "#7928ca"], logo="logo.png")
|
|
88
|
+
qr.save("poster.png", scale=14)
|
|
89
|
+
qr.save("poster.svg")
|
|
90
|
+
print(qr.terminal())
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Colours & gradients
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
qr.use_style(fg=["#ff9a3c", "#ff4d6d", "#7b2ff7"]) # linear
|
|
97
|
+
qr.use_style(fg={"kind":"radial", "colors":["#fff","#1f6feb"]})
|
|
98
|
+
qr.use_style(fg={"kind":"conic", "colors":["#ff71ce","#01cdfe","#05ffa1"]})
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Shapes & eyes
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
qr.use_style(module_shape=["dot","star","hexagon"], seed=3, module_jitter=0.2,
|
|
105
|
+
eye_shape="rounded", eye_dot_shape="circle")
|
|
106
|
+
|
|
107
|
+
@qrforge.shape("wave") # register a custom shape (SDF in module units)
|
|
108
|
+
def wave(x, y, radius=0.0):
|
|
109
|
+
import math
|
|
110
|
+
return qrforge.shapes.sd_circle(x, y + 0.08*math.sin(x*9), 0.5)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Shaders
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
qr.use_style(shaders=["wave:amplitude=4,wavelength=36", "chromatic:offset=2"])
|
|
117
|
+
|
|
118
|
+
@qrforge.shader # custom per-pixel shader
|
|
119
|
+
def heat(x, y, color, ctx):
|
|
120
|
+
return color.mix("#ff4400", ctx.uv(x, y)[1])
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Logos
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
qr.use_style(logo="logo.png", logo_size=0.26, logo_shape="rounded",
|
|
127
|
+
logo_radius=0.4, logo_bg="#ffffff", logo_stroke=("#000", 0.2),
|
|
128
|
+
logo_rotation=0, logo_opacity=1.0)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Presets & overrides
|
|
132
|
+
|
|
133
|
+
Any preset's defaults (colours, shaders, etc.) can be overridden:
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
qrforge.save("hi", "out.png", "neon", fg="#00ff88", scale=12)
|
|
137
|
+
qrforge.presets.get("sunset", bg="#000000")
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Presets: `classic dots rounded soft confetti neon sunset blueprint brutal vapor
|
|
141
|
+
film halftone gold ice leaf circuit retro glitch minimal badge starry cross`.
|
|
142
|
+
|
|
143
|
+
## Correctness
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
qr.verify() # decodes the symbol again
|
|
147
|
+
from qrforge.verify import decode
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## CLI
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
python -m qrforge "https://example.com" -o out.png -p neon -s 12 -e h
|
|
154
|
+
python -m qrforge "hi" --terminal
|
|
155
|
+
python -m qrforge --list-presets --list-shapes --list-shaders
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Testing
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
python -m pytest tests -q
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
The suite cross-checks the spec tables, Reed–Solomon correction, optimal
|
|
165
|
+
segmentation against a brute-force reference, the PNG codec against Pillow, and
|
|
166
|
+
re-rasterises every preset + the SVG geometry to prove each one still scans.
|
|
167
|
+
|
|
168
|
+
## Contributing
|
|
169
|
+
|
|
170
|
+
Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md). If you encounter any issues or have an edge use case, please open an issue using the templates in `.github/ISSUE_TEMPLATE`.
|
|
171
|
+
|
|
172
|
+
## License
|
|
173
|
+
|
|
174
|
+
qrforge is released under the terms of the **MIT License (Modified)**. Please see the [LICENSE.md](LICENSE.md) file for the full text.
|
qrforge-1.0.0/README.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# qrforge
|
|
2
|
+

|
|
3
|
+

|
|
4
|
+

|
|
5
|
+
-blue.svg)
|
|
6
|
+
|
|
7
|
+
An open-source Python library for **generating and art-directing QR codes**: custom module shapes, gradients, shaders, logos, image textures, backgrounds and shadows — output to PNG, SVG, PDF, terminal ANSI, ASCII or Pillow.
|
|
8
|
+
|
|
9
|
+
*qrforge implements the full QR encoding pipeline (modes, Reed–Solomon error correction, masking, versions 1–40) from scratch against the standard library. There are **zero required dependencies**; [Pillow](https://pillow.readthedocs.io) is used only for non-PNG image formats, PIL images, or JPEG/GIF/WEBP logos. PNG reading/writing is built in.*
|
|
10
|
+
|
|
11
|
+
> [!NOTE]
|
|
12
|
+
> **qrforge** is intended to produce both *correct* and *beautiful* QR codes. Every rendered symbol is round-trip verified by a bundled decoder, and the test-suite re-rasterises the SVG geometry to prove it reproduces the matrix — so "pretty" never comes at the cost of "scannable".
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
You can install qrforge using pip:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install qrforge
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or from source:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install . # or copy the qrforge/ folder next to your code
|
|
26
|
+
pip install pillow # optional, only for non-PNG formats / PIL images
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Supported Python Versions
|
|
30
|
+
|
|
31
|
+
* Python 3.8 / 3.9 / 3.10 / 3.11 / 3.12 (or later)
|
|
32
|
+
|
|
33
|
+
## Features
|
|
34
|
+
|
|
35
|
+
* **Correct encoder** – versions 1–40, EC levels L/M/Q/H, optimal numeric/alphanumeric/byte segmentation, automatic mask selection.
|
|
36
|
+
* **Shapes** – square, rounded, dot, diamond, hexagon, star, cross, squircle, leaf, heart etc. plus random-per-module mixes and your own SDF shapes.
|
|
37
|
+
* **Gradients & colours** – hex / `rgb()` / `hsl()` / CSS names; linear, radial and conic gradients for modules, eyes and background.
|
|
38
|
+
* **Shaders** – grain, glow, wave, twist, glitch, chromatic aberration, halftone, duotone, scanlines, vignette etc. plus custom Python or one-line expression shaders.
|
|
39
|
+
* **Logos & textures** – auto knockout zone, round/clip the logo, logo background, stroke, rotation, opacity; paint any image inside the modules.
|
|
40
|
+
* **Outputs** – PNG (pure-Python codec), SVG (tiny vector), PDF (vector), terminal ANSI, ASCII, Pillow, HTML.
|
|
41
|
+
* **22 ready-made presets** and a CLI.
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
44
|
+
|
|
45
|
+
### Quickstart
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
import qrforge
|
|
49
|
+
|
|
50
|
+
qrforge.save("https://example.com", "code.png", "neon", scale=12)
|
|
51
|
+
|
|
52
|
+
qr = qrforge.QR("hello", ec="h")
|
|
53
|
+
qr.use_style(module_shape="dot", fg=["#ff0080", "#7928ca"], logo="logo.png")
|
|
54
|
+
qr.save("poster.png", scale=14)
|
|
55
|
+
qr.save("poster.svg")
|
|
56
|
+
print(qr.terminal())
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Colours & gradients
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
qr.use_style(fg=["#ff9a3c", "#ff4d6d", "#7b2ff7"]) # linear
|
|
63
|
+
qr.use_style(fg={"kind":"radial", "colors":["#fff","#1f6feb"]})
|
|
64
|
+
qr.use_style(fg={"kind":"conic", "colors":["#ff71ce","#01cdfe","#05ffa1"]})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Shapes & eyes
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
qr.use_style(module_shape=["dot","star","hexagon"], seed=3, module_jitter=0.2,
|
|
71
|
+
eye_shape="rounded", eye_dot_shape="circle")
|
|
72
|
+
|
|
73
|
+
@qrforge.shape("wave") # register a custom shape (SDF in module units)
|
|
74
|
+
def wave(x, y, radius=0.0):
|
|
75
|
+
import math
|
|
76
|
+
return qrforge.shapes.sd_circle(x, y + 0.08*math.sin(x*9), 0.5)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Shaders
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
qr.use_style(shaders=["wave:amplitude=4,wavelength=36", "chromatic:offset=2"])
|
|
83
|
+
|
|
84
|
+
@qrforge.shader # custom per-pixel shader
|
|
85
|
+
def heat(x, y, color, ctx):
|
|
86
|
+
return color.mix("#ff4400", ctx.uv(x, y)[1])
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Logos
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
qr.use_style(logo="logo.png", logo_size=0.26, logo_shape="rounded",
|
|
93
|
+
logo_radius=0.4, logo_bg="#ffffff", logo_stroke=("#000", 0.2),
|
|
94
|
+
logo_rotation=0, logo_opacity=1.0)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Presets & overrides
|
|
98
|
+
|
|
99
|
+
Any preset's defaults (colours, shaders, etc.) can be overridden:
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
qrforge.save("hi", "out.png", "neon", fg="#00ff88", scale=12)
|
|
103
|
+
qrforge.presets.get("sunset", bg="#000000")
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Presets: `classic dots rounded soft confetti neon sunset blueprint brutal vapor
|
|
107
|
+
film halftone gold ice leaf circuit retro glitch minimal badge starry cross`.
|
|
108
|
+
|
|
109
|
+
## Correctness
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
qr.verify() # decodes the symbol again
|
|
113
|
+
from qrforge.verify import decode
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## CLI
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
python -m qrforge "https://example.com" -o out.png -p neon -s 12 -e h
|
|
120
|
+
python -m qrforge "hi" --terminal
|
|
121
|
+
python -m qrforge --list-presets --list-shapes --list-shaders
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Testing
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
python -m pytest tests -q
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The suite cross-checks the spec tables, Reed–Solomon correction, optimal
|
|
131
|
+
segmentation against a brute-force reference, the PNG codec against Pillow, and
|
|
132
|
+
re-rasterises every preset + the SVG geometry to prove each one still scans.
|
|
133
|
+
|
|
134
|
+
## Contributing
|
|
135
|
+
|
|
136
|
+
Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md). If you encounter any issues or have an edge use case, please open an issue using the templates in `.github/ISSUE_TEMPLATE`.
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
qrforge is released under the terms of the **MIT License (Modified)**. Please see the [LICENSE.md](LICENSE.md) file for the full text.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
# Metadata lives in setup.py (the publish workflow seds the version token there),
|
|
6
|
+
# so this file only declares the build backend and tool configuration.
|
|
7
|
+
|
|
8
|
+
[tool.pytest.ini_options]
|
|
9
|
+
testpaths = ["tests"]
|
|
10
|
+
addopts = "-q"
|
|
11
|
+
|
|
12
|
+
[tool.setuptools]
|
|
13
|
+
# packages are discovered by setup.py via find_packages()
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""qrforge -- generate and style QR codes with no dependencies.
|
|
2
|
+
|
|
3
|
+
import qrforge
|
|
4
|
+
|
|
5
|
+
qrforge.save("https://example.com", "hello.png", "neon", scale=12)
|
|
6
|
+
|
|
7
|
+
qr = qrforge.QR("hello", ec="h")
|
|
8
|
+
qr.use_style(module_shape="dot", fg=["#ff0080", "#7928ca"], logo="logo.png")
|
|
9
|
+
qr.save("hello.svg")
|
|
10
|
+
|
|
11
|
+
Everything (encoding, Reed-Solomon, rasterisation, the PNG codec) is written in
|
|
12
|
+
pure Python against the standard library. Pillow is used only when you ask for
|
|
13
|
+
a non-PNG format, a PIL image, or a non-PNG logo.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from .api import Artwork, QR, QRCode, make, png, save, svg, terminal
|
|
17
|
+
from .color import Color
|
|
18
|
+
from .exceptions import DataTooLong, QRForgeError, StyleError, UnsupportedFeature
|
|
19
|
+
from .gradient import Gradient, SolidFill
|
|
20
|
+
from .image import Pixmap
|
|
21
|
+
from .matrix import QRMatrix, build as build_matrix
|
|
22
|
+
from .shaders import Shader, expression, shader
|
|
23
|
+
from .shapes import Shape, custom as shape, register as register_shape
|
|
24
|
+
from .style import Style
|
|
25
|
+
|
|
26
|
+
__version__ = "1.0.0"
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"QR", "QRCode", "Artwork", "make", "save", "svg", "png", "terminal",
|
|
30
|
+
"Style", "Color", "Gradient", "SolidFill", "Pixmap", "QRMatrix", "build_matrix",
|
|
31
|
+
"Shader", "shader", "expression", "Shape", "shape", "register_shape",
|
|
32
|
+
"presets", "shapes", "shaders", "verify",
|
|
33
|
+
"QRForgeError", "DataTooLong", "StyleError", "UnsupportedFeature",
|
|
34
|
+
"__version__",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def __getattr__(name):
|
|
39
|
+
"""Lazily expose the heavier submodules (``qrforge.presets`` etc.)."""
|
|
40
|
+
if name in ("presets", "shapes", "shaders", "verify", "matrix", "encoder", "tables", "gf"):
|
|
41
|
+
from importlib import import_module
|
|
42
|
+
module = import_module(f".{name}", __name__)
|
|
43
|
+
globals()[name] = module
|
|
44
|
+
return module
|
|
45
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def preset(name: str) -> Style:
|
|
49
|
+
"""Shortcut for ``qrforge.presets.get(name)``."""
|
|
50
|
+
from .presets import get
|
|
51
|
+
return get(name)
|