app icon: lion (owner's ArtCraft drawing), Dock/taskbar/launcher wiring, palette docs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon Thomas 2026-10-02 09:53:34 -04:00
parent 03fca33d10
commit 1f2e267f32
25 changed files with 388 additions and 3 deletions

View File

@ -4,7 +4,7 @@
Every asset PrintCraft includes, bundles or uses to build its published material, with its author, source and licence. The policy is in [AGENTS.md](AGENTS.md) §1. The machine-readable list, with SHA-256 hashes, is [ATTRIBUTION.toml](ATTRIBUTION.toml). Licence texts are kept beside the assets and summarised in [NOTICE](NOTICE).
## In this repository (223)
## In this repository (237)
| Asset | Title | Author | Licence | Source | Used for |
|---|---|---|---|---|---|
@ -206,6 +206,20 @@ Every asset PrintCraft includes, bundles or uses to build its published material
| `docs/brand/artcraft-mark-black.svg` | ArtCraft brand: artcraft-mark-black | Storyteller | LicenseRef-Storyteller-Trademark | Storyteller brand assets (provided by the project owner, 2026-10-01; identical copies in storytold/photocraft) | ArtCraft branding next to the community links (About dialog, Help menu, home screen) and in docs. Not open source; forks must remove it. |
| `docs/brand/artcraft-mark.png` | ArtCraft brand: artcraft-mark | Storyteller | LicenseRef-Storyteller-Trademark | Storyteller brand assets (provided by the project owner, 2026-10-01; identical copies in storytold/photocraft) | ArtCraft branding next to the community links (About dialog, Help menu, home screen) and in docs. Not open source; forks must remove it. |
| `docs/brand/artcraft-mark.svg` | ArtCraft brand: artcraft-mark | Storyteller | LicenseRef-Storyteller-Trademark | Storyteller brand assets (provided by the project owner, 2026-10-01; identical copies in storytold/photocraft) | ArtCraft branding next to the community links (About dialog, Help menu, home screen) and in docs. Not open source; forks must remove it. |
| `assets/app-icon/printcraft.svg` | PrintCraft app icon (master vector) | PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py) | MIT OR Apache-2.0 | Contributor-original (see assets/app-icon/README.md) | Master artwork; every other app-icon file is rendered from it (packaging/icons.sh) |
| `assets/app-icon/printcraft-small.svg` | PrintCraft app icon (light vector) | PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py) | MIT OR Apache-2.0 | Contributor-original (see assets/app-icon/README.md) | README header and assets/app-icon/README.md |
| `assets/app-icon/printcraft-1024.png` | PrintCraft app icon, 1024 px on Apple's icon grid | PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py) | MIT OR Apache-2.0 | Contributor-original (see assets/app-icon/README.md) | Runtime window/Dock icon on macOS (apps/printcraft/src/main.rs) |
| `assets/app-icon/printcraft.icns` | PrintCraft app icon (macOS .icns) | PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py) | MIT OR Apache-2.0 | Contributor-original (see assets/app-icon/README.md) | macOS app bundle icon |
| `assets/app-icon/printcraft.ico` | PrintCraft app icon (Windows .ico, 16-256 px) | PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py) | MIT OR Apache-2.0 | Contributor-original (see assets/app-icon/README.md) | Embedded in printcraft.exe by apps/printcraft/build.rs (Explorer, taskbar, Start menu, Alt-Tab) |
| `assets/app-icon/hicolor/16x16/apps/ai.storyteller.printcraft.png` | PrintCraft app icon, 16 px | PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py) | MIT OR Apache-2.0 | Contributor-original (see assets/app-icon/README.md) | Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop) |
| `assets/app-icon/hicolor/24x24/apps/ai.storyteller.printcraft.png` | PrintCraft app icon, 24 px | PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py) | MIT OR Apache-2.0 | Contributor-original (see assets/app-icon/README.md) | Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop) |
| `assets/app-icon/hicolor/32x32/apps/ai.storyteller.printcraft.png` | PrintCraft app icon, 32 px | PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py) | MIT OR Apache-2.0 | Contributor-original (see assets/app-icon/README.md) | Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop) |
| `assets/app-icon/hicolor/48x48/apps/ai.storyteller.printcraft.png` | PrintCraft app icon, 48 px | PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py) | MIT OR Apache-2.0 | Contributor-original (see assets/app-icon/README.md) | Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop) |
| `assets/app-icon/hicolor/64x64/apps/ai.storyteller.printcraft.png` | PrintCraft app icon, 64 px | PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py) | MIT OR Apache-2.0 | Contributor-original (see assets/app-icon/README.md) | Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop) |
| `assets/app-icon/hicolor/128x128/apps/ai.storyteller.printcraft.png` | PrintCraft app icon, 128 px | PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py) | MIT OR Apache-2.0 | Contributor-original (see assets/app-icon/README.md) | Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop) |
| `assets/app-icon/hicolor/256x256/apps/ai.storyteller.printcraft.png` | PrintCraft app icon, 256 px | PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py) | MIT OR Apache-2.0 | Contributor-original (see assets/app-icon/README.md) | Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop); runtime window icon on Windows and Linux (apps/printcraft/src/main.rs) |
| `assets/app-icon/hicolor/512x512/apps/ai.storyteller.printcraft.png` | PrintCraft app icon, 512 px | PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py) | MIT OR Apache-2.0 | Contributor-original (see assets/app-icon/README.md) | Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop) |
| `assets/app-icon/hicolor/scalable/apps/ai.storyteller.printcraft.svg` | PrintCraft app icon (Linux scalable) | PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py) | MIT OR Apache-2.0 | Contributor-original (see assets/app-icon/README.md) | Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop) |
| `docs/images/printcraft-bookmarks.png` | PrintCraft screenshot: Bookmarks | PrintCraft contributors (generated by `cargo xtask screenshots`) | MIT OR Apache-2.0 | this repository | README: navigation. Shows only PrintCraft UI, Lucide icons and the showcase PDF built from the [[fetched]] OFL fonts |
| `docs/images/printcraft-dark.png` | PrintCraft screenshot: Dark theme | PrintCraft contributors (generated by `cargo xtask screenshots`) | MIT OR Apache-2.0 | this repository | README: themes. Shows only PrintCraft UI, Lucide icons and the showcase PDF built from the [[fetched]] OFL fonts |
| `docs/images/printcraft-find.png` | PrintCraft screenshot: Find text | PrintCraft contributors (generated by `cargo xtask screenshots`) | MIT OR Apache-2.0 | this repository | README: search. Shows only PrintCraft UI, Lucide icons and the showcase PDF built from the [[fetched]] OFL fonts |

View File

@ -2520,6 +2520,160 @@ kind = "logo"
usage = "ArtCraft branding next to the community links (About dialog, Help menu, home screen) and in docs. Not open source; forks must remove it."
sha256 = "f87af81b6fa411da8820eed2bfdcc54c0ee9cd453b4e868c64f56c69db142d0e"
[[asset]]
path = "assets/app-icon/printcraft.svg"
title = "PrintCraft app icon (master vector)"
author = "PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py)"
source = "Contributor-original (see assets/app-icon/README.md)"
licence = "MIT OR Apache-2.0"
licence_file = "assets/app-icon/LICENSE.txt"
kind = "icon"
usage = "Master artwork; every other app-icon file is rendered from it (packaging/icons.sh)"
sha256 = "52b384a10a2a7fdd3145d9822972cfd568ef0cb7312549bd4399addd89d45a6d"
[[asset]]
path = "assets/app-icon/printcraft-small.svg"
title = "PrintCraft app icon (light vector)"
author = "PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py)"
source = "Contributor-original (see assets/app-icon/README.md)"
licence = "MIT OR Apache-2.0"
licence_file = "assets/app-icon/LICENSE.txt"
kind = "icon"
usage = "README header and assets/app-icon/README.md"
sha256 = "b036304c11ef5dcad36636d06ca0bf331b51e47650d25d3c916a0e1eabf544c7"
[[asset]]
path = "assets/app-icon/printcraft-1024.png"
title = "PrintCraft app icon, 1024 px on Apple's icon grid"
author = "PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py)"
source = "Contributor-original (see assets/app-icon/README.md)"
licence = "MIT OR Apache-2.0"
licence_file = "assets/app-icon/LICENSE.txt"
kind = "icon"
usage = "Runtime window/Dock icon on macOS (apps/printcraft/src/main.rs)"
sha256 = "da577d3f21fbcf5c739067787a9e683be2b064d76813b5d5fec9074a7a106538"
[[asset]]
path = "assets/app-icon/printcraft.icns"
title = "PrintCraft app icon (macOS .icns)"
author = "PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py)"
source = "Contributor-original (see assets/app-icon/README.md)"
licence = "MIT OR Apache-2.0"
licence_file = "assets/app-icon/LICENSE.txt"
kind = "icon"
usage = "macOS app bundle icon"
sha256 = "2425148222873de241d267aba667a8b234ecdd0149f2ca8bb6e79443b743b1e8"
[[asset]]
path = "assets/app-icon/printcraft.ico"
title = "PrintCraft app icon (Windows .ico, 16-256 px)"
author = "PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py)"
source = "Contributor-original (see assets/app-icon/README.md)"
licence = "MIT OR Apache-2.0"
licence_file = "assets/app-icon/LICENSE.txt"
kind = "icon"
usage = "Embedded in printcraft.exe by apps/printcraft/build.rs (Explorer, taskbar, Start menu, Alt-Tab)"
sha256 = "56daaaae9ae5389794909570885809adf5e1d9183bef2d9669ed2f9bba3ed6f5"
[[asset]]
path = "assets/app-icon/hicolor/16x16/apps/ai.storyteller.printcraft.png"
title = "PrintCraft app icon, 16 px"
author = "PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py)"
source = "Contributor-original (see assets/app-icon/README.md)"
licence = "MIT OR Apache-2.0"
licence_file = "assets/app-icon/LICENSE.txt"
kind = "icon"
usage = "Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop)"
sha256 = "9b77095cbe75dcba6b74a1fdcd4064812850efaf7a12edebefc9ded5eabb49da"
[[asset]]
path = "assets/app-icon/hicolor/24x24/apps/ai.storyteller.printcraft.png"
title = "PrintCraft app icon, 24 px"
author = "PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py)"
source = "Contributor-original (see assets/app-icon/README.md)"
licence = "MIT OR Apache-2.0"
licence_file = "assets/app-icon/LICENSE.txt"
kind = "icon"
usage = "Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop)"
sha256 = "a4cd466687f6c5cb59eef3fc564bdba1c8f0d9e324754eeebab82f18823efae7"
[[asset]]
path = "assets/app-icon/hicolor/32x32/apps/ai.storyteller.printcraft.png"
title = "PrintCraft app icon, 32 px"
author = "PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py)"
source = "Contributor-original (see assets/app-icon/README.md)"
licence = "MIT OR Apache-2.0"
licence_file = "assets/app-icon/LICENSE.txt"
kind = "icon"
usage = "Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop)"
sha256 = "e22279013a5ed5c02571e1e4e9bc4cef9aa0847fcb733a285b2916fabd16bf78"
[[asset]]
path = "assets/app-icon/hicolor/48x48/apps/ai.storyteller.printcraft.png"
title = "PrintCraft app icon, 48 px"
author = "PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py)"
source = "Contributor-original (see assets/app-icon/README.md)"
licence = "MIT OR Apache-2.0"
licence_file = "assets/app-icon/LICENSE.txt"
kind = "icon"
usage = "Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop)"
sha256 = "55daf2d5575f6c4e4c4975c9f1c74231178f1801963a8b19f68dfa9bc50cb22f"
[[asset]]
path = "assets/app-icon/hicolor/64x64/apps/ai.storyteller.printcraft.png"
title = "PrintCraft app icon, 64 px"
author = "PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py)"
source = "Contributor-original (see assets/app-icon/README.md)"
licence = "MIT OR Apache-2.0"
licence_file = "assets/app-icon/LICENSE.txt"
kind = "icon"
usage = "Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop)"
sha256 = "2975c200f341e247b5fa18f568fb27d390e3fa01e9b2ad37acb48d0e1cc8a124"
[[asset]]
path = "assets/app-icon/hicolor/128x128/apps/ai.storyteller.printcraft.png"
title = "PrintCraft app icon, 128 px"
author = "PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py)"
source = "Contributor-original (see assets/app-icon/README.md)"
licence = "MIT OR Apache-2.0"
licence_file = "assets/app-icon/LICENSE.txt"
kind = "icon"
usage = "Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop)"
sha256 = "6ef927ca252b40bc9b5d8843d84137334362f8aa1acbb1bf8c15a02affd25b2b"
[[asset]]
path = "assets/app-icon/hicolor/256x256/apps/ai.storyteller.printcraft.png"
title = "PrintCraft app icon, 256 px"
author = "PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py)"
source = "Contributor-original (see assets/app-icon/README.md)"
licence = "MIT OR Apache-2.0"
licence_file = "assets/app-icon/LICENSE.txt"
kind = "icon"
usage = "Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop); runtime window icon on Windows and Linux (apps/printcraft/src/main.rs)"
sha256 = "cde7ee8c5ee38f9fc40a429fd9e6d99a035bcd321701fce331bb13bac126614d"
[[asset]]
path = "assets/app-icon/hicolor/512x512/apps/ai.storyteller.printcraft.png"
title = "PrintCraft app icon, 512 px"
author = "PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py)"
source = "Contributor-original (see assets/app-icon/README.md)"
licence = "MIT OR Apache-2.0"
licence_file = "assets/app-icon/LICENSE.txt"
kind = "icon"
usage = "Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop)"
sha256 = "5ede733e93b96f4eb8d94299232cf2f9605fa19b0d913f95fe9828c316a2d066"
[[asset]]
path = "assets/app-icon/hicolor/scalable/apps/ai.storyteller.printcraft.svg"
title = "PrintCraft app icon (Linux scalable)"
author = "PrintCraft contributors (drawn by the project owner in ArtCraft; vectorised with craftrules vectorize_tile.py)"
source = "Contributor-original (see assets/app-icon/README.md)"
licence = "MIT OR Apache-2.0"
licence_file = "assets/app-icon/LICENSE.txt"
kind = "icon"
usage = "Linux hicolor theme icon (packaging/linux/ai.storyteller.printcraft.desktop)"
sha256 = "52b384a10a2a7fdd3145d9822972cfd568ef0cb7312549bd4399addd89d45a6d"
[[asset]]
path = "docs/images/printcraft-bookmarks.png"
title = "PrintCraft screenshot: Bookmarks"

11
Cargo.lock generated
View File

@ -3342,6 +3342,7 @@ dependencies = [
"egui",
"printcraft-ui-egui",
"serde_json",
"winresource",
]
[[package]]
@ -5729,6 +5730,16 @@ dependencies = [
"memchr",
]
[[package]]
name = "winresource"
version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0986a8b1d586b7d3e4fe3d9ea39fb451ae22869dcea4aa109d287a374d866087"
dependencies = [
"toml",
"version_check",
]
[[package]]
name = "wit-bindgen"
version = "0.57.1"

View File

@ -7,6 +7,10 @@
</a>
</p>
<p align="center">
<img alt="PrintCraft app icon: an engraved lion on PrintCraft green (#12a58a)" src="assets/app-icon/printcraft-small.svg" width="112">
</p>
<h1 align="center">PrintCraft</h1>
<p align="center">

View File

@ -13,3 +13,7 @@ printcraft-ui-egui = { workspace = true }
eframe = { workspace = true, features = ["default_fonts", "wgpu", "accesskit", "wayland", "x11", "persistence", "links"] }
egui = { workspace = true }
serde_json = { workspace = true }
[build-dependencies]
# Icon + VERSIONINFO for printcraft.exe; build.rs only uses it when targeting Windows.
winresource = "0.1"

28
apps/printcraft/build.rs Normal file
View File

@ -0,0 +1,28 @@
//! Windows only: embed the app icon and version info (VERSIONINFO) into `printcraft.exe`, so it
//! shows in Explorer, the taskbar, the Start menu and Alt-Tab.
//!
//! On every other target this does nothing. A missing resource compiler is a warning, so a
//! cross-compile from macOS or Linux still links, unless `PRINTCRAFT_REQUIRE_WINRES=1` turns it
//! into an error (for release builds).
fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=../../assets/app-icon/printcraft.ico");
println!("cargo:rerun-if-env-changed=PRINTCRAFT_REQUIRE_WINRES");
if std::env::var("CARGO_CFG_TARGET_OS").as_deref() != Ok("windows") {
return;
}
let mut res = winresource::WindowsResource::new();
res.set_icon("../../assets/app-icon/printcraft.ico")
.set("ProductName", "PrintCraft")
.set("FileDescription", "PrintCraft PDF workbench")
.set("LegalCopyright", "Copyright (c) the PrintCraft contributors. MIT OR Apache-2.0.")
.set("OriginalFilename", "printcraft.exe")
.set("InternalName", "printcraft");
if let Err(e) = res.compile() {
if std::env::var_os("PRINTCRAFT_REQUIRE_WINRES").is_some() {
panic!("embedding Windows resources failed: {e}");
}
println!("cargo:warning=printcraft.exe built without icon/version resources: {e}");
}
}

View File

@ -13,6 +13,16 @@
use printcraft_ui_egui::PrintCraftApp;
/// Freedesktop app id: the `.desktop` file name and the hicolor icon name.
const APP_ID: &str = "ai.storyteller.printcraft";
/// The app icon (assets/app-icon/README.md). macOS gets the version on Apple's icon grid, with a
/// transparent margin; Windows and Linux get the full-bleed tile.
#[cfg(target_os = "macos")]
const APP_ICON_PNG: &[u8] = include_bytes!("../../../assets/app-icon/printcraft-1024.png");
#[cfg(not(target_os = "macos"))]
const APP_ICON_PNG: &[u8] = include_bytes!("../../../assets/app-icon/hicolor/256x256/apps/ai.storyteller.printcraft.png");
fn main() -> eframe::Result {
let mut files = Vec::new();
let mut options: Vec<(String, String)> = Vec::new();
@ -37,11 +47,20 @@ fn main() -> eframe::Result {
.with_title("PrintCraft")
.with_inner_size([1440.0, 920.0])
.with_min_inner_size([820.0, 520.0])
.with_drag_and_drop(true);
.with_drag_and_drop(true)
// Wayland app id: matches packaging/linux/ai.storyteller.printcraft.desktop.
.with_app_id(APP_ID);
// Dock, taskbar, Alt-Tab and launcher icon when running unbundled.
match eframe::icon_data::from_png_bytes(APP_ICON_PNG) {
Ok(icon) => viewport = viewport.with_icon(icon),
Err(e) => eprintln!("printcraft: app icon: {e}"),
}
if integrated {
viewport = viewport.with_fullsize_content_view(true).with_titlebar_shown(false).with_title_shown(false);
}
let native = eframe::NativeOptions { viewport, ..Default::default() };
// eframe would otherwise derive the settings folder from the app id: keep it under "PrintCraft".
let persistence_path = eframe::storage_dir("PrintCraft").map(|d| d.join("app.ron"));
let native = eframe::NativeOptions { viewport, persistence_path, ..Default::default() };
eframe::run_native(
"PrintCraft",
native,

View File

@ -0,0 +1,12 @@
PrintCraft app icon (printcraft.svg, printcraft-small.svg and every file derived from them in this
directory: printcraft-1024.png, printcraft.icns, printcraft.ico, hicolor/).
Original artwork made for this project by the project owner, drawn in ArtCraft and vectorised for
PrintCraft (no third-party material). Licensed like the rest of PrintCraft, under either of
* Apache License, Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
* MIT license (https://opensource.org/licenses/MIT)
at your option.
Regenerate the derived files with packaging/icons.sh.

48
assets/app-icon/README.md Normal file
View File

@ -0,0 +1,48 @@
# PrintCraft app icon
<img src="printcraft-small.svg" alt="PrintCraft app icon: an engraved lion's head on green" width="128">
**Creature:** a lion, in a frontal head-and-shoulders portrait, mane running off the bottom of the tile.
**Style:** an engraving (woodcut-weight line work) portrait in the Crafting Apps "owl template" framing:
a full-bleed colour field, no frame or roundel, the animal looking at the viewer and filling the tile.
**Palette:** exactly three colours.
| Colour | Hex | Used for |
|---|---|---|
| Ink | `#0b0b0c` | line work and the figure's contour |
| Paper | `#efe9dc` | the figure (the lion's silhouette) |
| PrintCraft green (app colour) | `#12a58a` | the full-bleed field |
**Tile:** `viewBox="0 0 512 512"`, a rounded square with `rx=112` that clips everything. Windows and Linux
icons use the full-bleed tile. macOS icons put it on Apple's grid (an 824 px body centred on a transparent
1024 px canvas).
**Provenance:** the project owner's original drawing, made in ArtCraft (2880 px, keyed to the palette), then
vectorised with craftrules `assets/logo-options/_tools/vectorize_tile.py` (potrace; no filtering or
warping). The source drawing is kept in craftrules at `assets/app-icons/printcraft/source.png`, not here.
Licence: [LICENSE.txt](LICENSE.txt) (`MIT OR Apache-2.0`, like the repo).
## Files
| File | What it is |
|---|---|
| `printcraft.svg` | the master vector (traced at 2048 px); every PNG, `.ico` and `.icns` is rendered from it |
| `printcraft-small.svg` | a lighter vector (traced at 1024 px) for places where size matters, such as this README |
| `printcraft-1024.png` | 1024 px on Apple's grid; also the runtime Dock icon on macOS |
| `printcraft.icns` | macOS icon (16–1024 px) |
| `printcraft.ico` | Windows icon (16–256 px), embedded in `printcraft.exe` by `apps/printcraft/build.rs` |
| `hicolor/<n>x<n>/apps/ai.storyteller.printcraft.png` | Linux hicolor theme, 16–512 px; the 256 px one is the runtime icon on Windows and Linux |
| `hicolor/scalable/apps/ai.storyteller.printcraft.svg` | Linux scalable icon (copy of the master) |
Where it shows: `apps/printcraft/src/main.rs` sets the window icon (Dock, taskbar, Alt-Tab, launcher) and the
Wayland app id `ai.storyteller.printcraft`; `packaging/linux/ai.storyteller.printcraft.desktop` names the
hicolor icon.
## Regenerate
```sh
packaging/icons.sh # needs resvg and python3; iconutil (macOS) for the .icns
cargo xtask assets # then update the sha256 values in ATTRIBUTION.toml and run with --write
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 695 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 451 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 451 KiB

74
packaging/icons.sh Executable file
View File

@ -0,0 +1,74 @@
#!/usr/bin/env bash
# Regenerate every app icon from assets/app-icon/printcraft.svg (the master vector).
#
# Needs: resvg (brew install resvg / cargo install resvg) and python3 (stdlib only, for the .ico).
# On macOS, iconutil also writes the .icns. The outputs are committed, so building and packaging
# never need these tools. After running it, update the sha256 values in ATTRIBUTION.toml, then
# `cargo xtask assets --write`.
#
# packaging/icons.sh
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
DIR="$ROOT/assets/app-icon"
SVG="$DIR/printcraft.svg"
ID="ai.storyteller.printcraft"
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
command -v resvg >/dev/null || { echo "error: resvg not found (brew install resvg)" >&2; exit 1; }
# The master is a full-bleed 512 tile (rx=112): right for Windows and Linux. macOS icons follow
# Apple's grid instead: an 824 px body centred on a transparent 1024 canvas.
MAC="$TMP/macos.svg"
{
echo '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1024 1024">'
echo '<image x="100" y="100" width="824" height="824" xlink:href="'"$SVG"'"/>'
echo '</svg>'
} >"$MAC"
render() { resvg -w "$2" -h "$2" "$1" "$3" </dev/null; }
# 1024 px PNG on Apple's grid (also the runtime Dock icon on macOS, see apps/printcraft/src/main.rs).
render "$MAC" 1024 "$DIR/printcraft-1024.png"
# Linux hicolor theme (full bleed; hicolor/256x256 is also the runtime icon on Windows and Linux).
for s in 16 24 32 48 64 128 256 512; do
mkdir -p "$DIR/hicolor/${s}x${s}/apps"
render "$SVG" "$s" "$DIR/hicolor/${s}x${s}/apps/$ID.png"
done
mkdir -p "$DIR/hicolor/scalable/apps"
cp "$SVG" "$DIR/hicolor/scalable/apps/$ID.svg"
# Windows .ico: PNG-compressed entries, 16-256 px.
ICO_PNGS=()
for s in 16 20 24 32 40 48 64 128 256; do
render "$SVG" "$s" "$TMP/ico-$s.png"
ICO_PNGS+=("$TMP/ico-$s.png")
done
python3 - "$DIR/printcraft.ico" "${ICO_PNGS[@]}" <<'PY'
import struct, sys
out, pngs = sys.argv[1], sys.argv[2:]
blobs = [open(p, "rb").read() for p in pngs]
head = struct.pack("<HHH", 0, 1, len(blobs))
entries, data, offset = b"", b"", 6 + 16 * len(blobs)
for b in blobs:
w, h = struct.unpack(">II", b[16:24]) # IHDR
entries += struct.pack("<BBBBHHII", w % 256, h % 256, 0, 0, 1, 32, len(b), offset)
data += b
offset += len(b)
open(out, "wb").write(head + entries + data)
PY
# macOS .icns.
if command -v iconutil >/dev/null; then
SET="$TMP/printcraft.iconset"
mkdir -p "$SET"
for s in 16 32 128 256 512; do
render "$MAC" "$s" "$SET/icon_${s}x${s}.png"
render "$MAC" $((s * 2)) "$SET/icon_${s}x${s}@2x.png"
done
iconutil -c icns -o "$DIR/printcraft.icns" "$SET"
else
echo "warning: iconutil not found (macOS only); printcraft.icns not regenerated" >&2
fi
echo "icons written to $DIR"

View File

@ -0,0 +1,14 @@
[Desktop Entry]
Type=Application
Name=PrintCraft
GenericName=PDF Editor
Comment=Read, organize, combine, split and secure PDFs
Exec=printcraft %F
TryExec=printcraft
Icon=ai.storyteller.printcraft
Terminal=false
StartupNotify=true
StartupWMClass=printcraft
Categories=Office;Viewer;Graphics;
Keywords=pdf;viewer;editor;annotate;sign;forms;merge;split;
MimeType=application/pdf;