Files
ICCery-CPU/README.md
T
Local Admin e0b1719921
Build macOS Packages / Build macOS (Intel) (push) Successful in 31s
Build macOS Packages / Build macOS (Apple Silicon) (push) Successful in 48s
Build macOS Packages / Build macOS (Universal) (push) Failing after 11s
amended build target version numbers
2026-09-07 06:30:42 -07:00

146 lines
5.1 KiB
Markdown

# ICCery-CPU — TargetPrint
**ICCery Colour Print Utility** (`TargetPrint`)
A high-precision, native macOS utility for printing multi-page raster colour profiling targets with absolute geometric and pixel-level fidelity. Companion to [ICCery](https://git.i3omb.com/gronod/ICCery).
`TargetPrint` disables or strictly controls ColourSync and driver-level colour management so TIFF pixel values reach the printer without unwanted transformation.
This directory is the **native AppKit implementation** of [`SPEC.md`](SPEC.md). Build it on a Mac with Xcode 10+ (Swift 5, macOS 10.15+).
---
## Features (SPEC v1)
- **1:1 geometric fidelity** — physical size from embedded DPI; 72 pt = 1 in; never `backingScaleFactor`
- **Zero interpolation / anti-aliasing** in `TargetCanvasView.draw`
- **Colour-management bypass** at Quartz (`PMColorMatchingMode=APCustomColorMatching`) and CUPS/PPD layers
- **Structured Job Mode** — `TargetPrint --job /tmp/iccery_job_<uuid>.json` presents `NSPrintPanel` immediately
- **Standalone Mode** — drop `.tif` / `.tiff`, inspector, **Print…**
- **Multi-page** — `knowsPageRange` / `rectForPage`; page order is the job `files` array
- **AirPrint detection** with the specified persistent warning
- **Universal 2** (`x86_64` + `arm64`)
- **Zero third-party dependencies** — AppKit, CoreGraphics, ImageIO, ApplicationServices, libcups
---
## Requirements
| Item | Value |
|------|--------|
| macOS | Intel **10.15** Catalina · Apple Silicon **11.0** Big Sur → 26+ Tahoe |
| Architecture | Universal 2 (Intel + Apple Silicon) |
| Xcode | Command Line Tools / full Xcode (Swift 5) |
| Sandbox | Hardened Runtime **on**, App Sandbox **off** |
---
## Building
## Building
```bash
chmod +x Scripts/*.sh
# One architecture
./Scripts/build_macos.sh x86_64 # Intel
./Scripts/build_macos.sh arm64 # Apple Silicon
# All three: x86_64, arm64, Universal 2 (SPEC §12)
./Scripts/build_universal.sh
# Zip + installable DMG + ICCery vendor tree
./Scripts/package_app.sh TargetPrint_dev
```
Or open `TargetPrint.xcodeproj` in Xcode.
Unit tests (JSON, geometry, AirPrint heuristics):
```bash
xcodebuild -project TargetPrint.xcodeproj -scheme TargetPrint \
-destination 'platform=macOS' -only-testing:TargetPrintTests test
```
### CI (Gitea Actions)
[`.gitea/workflows/build-macos.yml`](.gitea/workflows/build-macos.yml) runs on `v*` tags, `main`, pull requests, and `workflow_dispatch`. It builds **Intel**, **Apple Silicon**, and **Universal 2** on the `macos` runner (same label as ICCery).
Each architecture publishes:
| Artifact | Use |
|----------|-----|
| `TargetPrint_<tag>-<sha>-macos-<arch>.app.zip` | Drop `TargetPrint.app` into ICCery |
| `TargetPrint_<tag>-<sha>-macos-<arch>.dmg` | Double-click installer (app + Applications shortcut) |
Plus `TargetPrint_<tag>-<sha>-vendor-iccery.zip`:
```
vendor-iccery/
macos-x86_64/TargetPrint.app
macos-aarch64/TargetPrint.app
macos-universal/TargetPrint.app
```
Copy that folder to ICCery as `src-tauri/targetprint/` and spawn `TargetPrint.app/Contents/MacOS/TargetPrint --job …` from Rust (SPEC §16).
The `macos` runner does **not** need a full Xcode.app. If `/Applications/Xcode.app` is missing (the `xcode-select: invalid developer directory` error), the workflow compiles with **Command Line Tools** `swiftc` and the macOS SDK. Install CLT on the runner if needed: `xcode-select --install`. Optional Actions variable `XCODE_APP` only if a full Xcode is installed somewhere other than `/Applications/Xcode.app`.
Optional repository secret `MACOS_CODESIGN_IDENTITY` (Developer ID). If unset, binaries are ad-hoc signed with Hardened Runtime.
On a `v*` tag, assets are also attached to the Gitea release (the release must already exist for that tag, same pattern as ICCery).
---
## Usage
### Mode A — Structured Job (from ICCery)
```bash
/Applications/TargetPrint.app/Contents/MacOS/TargetPrint \
--job /tmp/iccery_job_<uuid>.json
```
Optional: `--verbose` writes `~/Library/Logs/TargetPrint/TargetPrint.log`.
Exit codes: `0` ok/cancel, `1` invalid job, `2` unreadable TIFF, `3` CUPS, `4` fatal.
The job JSON is **never deleted** by TargetPrint (SPEC §13).
### Mode B — Standalone
Double-click, drop TIFFs, **File → Open…**, then **Print…**.
`.targetjob` files are registered as a document type (`com.iccery.targetjob`).
---
## Layout (SPEC §11)
```
macos/
├── .gitea/workflows/build-macos.yml
├── SPEC.md
├── LICENCE.md
├── VENDOR.md # drop TargetPrint.app into ICCery
├── Info.plist
├── TargetPrint.entitlements
├── Bridging-Header.h
├── TargetPrint.xcodeproj/
├── Sources/
├── Tests/
├── Resources/
└── Scripts/
├── build_macos.sh # one arch
├── build_universal.sh # x86_64 + arm64 + lipo
├── make_universal.sh
├── create_dmg.sh # installable UDZO
├── package_release.sh # .app.zip + .dmg + vendor dir
└── vendor_bundle.sh # ICCery zip
```
---
## Licence
MIT — Copyright 2026 Gordon Bolton. See [`LICENCE.md`](LICENCE.md).