fix pale colours and map driverless print options
ci/woodpecker/push/build Pipeline was successful

Set *DefaultBRColorMode: None in the vendor PPD so every job sends
<</UseCIEColor false>>: Brother's Normal/Vivid modes enable the printer's
own CIE conversion, which washed the colours out.

Add six APPrinterPreset entries mapping print-color-mode and
print-quality from driverless (AirPrint/IPP) clients onto the Brother
device options; they use the notation CUPS generates itself (Apple
metadata as 'key value' pairs, PPD options as '*Name Value'), because
key=value strings are silently discarded. print-quality is 3/4/5.

Add the PRINTER_OPTIONS env var: whitespace-separated key=value pairs
applied as queue defaults on every start via lpadmin -o, validated
against the queue's PPD, with warnings instead of a failed startup.

Document all of it in the README. The VividNoCIE candidate was dropped
after test prints showed no difference from None. Archive the OpenSpec
change and sync the printserver/cups spec with the two new
requirements.
This commit is contained in:
juergen committed 2026-10-20 08:28:08 +02:00
1 parent 75b68fe438
commit 30670de93b
9 files changed
+319 -33

No files matched your search

+99 -1
View File
@@ -85,11 +85,26 @@ podman run -d --name printserver \
| `PRINTER_NAME` | `HL4150CDN` | CUPS queue name. Also used as the name advertised via AirPrint/DNS-SD. |
| `PRINTER_DESCRIPTION` | *(empty)* | CUPS printer description (`lpadmin -D`), shown in the CUPS web UI. |
| `PPD_FILE` | `/usr/share/cups/model/BR4150_2.PPD` | PPD used for the queue. |
| `PRINTER_OPTIONS` | *(empty)* | Space-separated PPD option assignments (`key=value`) applied as queue defaults on every start, e.g. `BRColorMode=Vivid TonerSaveMode=False`. Discover the names with `lpoptions -p <queue> -l`. |
| `CERT_EXTRA_NAMES` | *(empty)* | Comma-separated extra DNS names and/or IP addresses to put into the generated `_ipps` certificate. |
| `CERT_DAYS` | `3650` | Validity of the generated certificate, in days. |
No queue is created when neither `PRINTER_IP` nor `PRINTER_URI` is set.
`PRINTER_OPTIONS` sets queue defaults that survive the recreation of the queue,
because they are re-applied on every start:
```sh
podman run -d --name printserver \
--network host \
-e PRINTER_IP=192.168.100.7 \
-e PRINTER_OPTIONS="BRMediaType=Plain BRColorMode=Vivid TonerSaveMode=False" \
printserver:latest
```
Entries that the PPD does not know are logged as a warning and ignored; the
remaining ones are applied and the container starts normally.
### Choosing the connection
The HL-4150CDN accepts PostScript directly, so the default is raw AppSocket.
@@ -187,7 +202,7 @@ The BR-Script3 PPD exposes the HL-4150CDN's hardware options. Common ones:
| Paper source | `InputSlot` | `AutoSelect`, `Tray1`, `Tray2`, `MPTray` |
| Two-sided printing | `Duplex` | `None`, `DuplexNoTumble` (long edge), `DuplexTumble` (short edge) |
| Colour / mono | `BRPrintQuality` | `Auto`, `Color`, `Black` |
| Colour mode | `BRColorMode` | `Normal`, `Vivid`, `None` |
| Colour mode | `BRColorMode` | `Normal`, `Vivid`, `None` (default) |
| Media type | `BRMediaType` | `Plain`, `Thin`, `Thick`, `Recycled`, `Glossy`, `Label`, envelopes, … |
| Print quality | `CAPT` | `Fine` (600×600), `SuperFine` (2400 dpi class) |
| Toner save | `TonerSaveMode` | `True`, `False` |
@@ -200,6 +215,57 @@ podman exec printserver lp -d HL4150CDN \
-o Duplex=DuplexNoTumble -o BRPrintQuality=Color -o InputSlot=Tray1 report.pdf
```
### Why the macOS/iOS dialog shows fewer options
macOS and iOS print driverless (AirPrint / IPP Everywhere), so the dialog shows
only IPP-standard options: media size, duplex, pages per sheet, the
black-and-white/colour toggle and the quality slider. Brother-specific options
(`BRColorMode`, `BRMediaType`, `TonerSaveMode`, `CAPT`, …) have no IPP
equivalent and can never appear there. Set them server-side instead:
- as queue defaults at container start via `PRINTER_OPTIONS` (see
*Environment variables*),
- per job with `lp -o …`, or
- interactively in the CUPS web UI (`http://<host>:631/admin`, *Printing Options*).
The dialog's black-and-white/colour toggle maps to `print-color-mode` and the
quality slider to `print-quality`; the PPD presets documented below translate
both onto the Brother options, so they now really take effect:
| Dialog / IPP | PPD option it becomes |
| --- | --- |
| `print-color-mode=monochrome` | `BRPrintQuality=Black` |
| `print-color-mode=color` | `BRPrintQuality=Auto` |
| `print-quality=3` (draft) | `TonerSaveMode=True` |
| `print-quality=4` (normal) | defaults (`Fine`, toner save off) |
| `print-quality=5` (high) | `CAPT=SuperFine` (2400 dpi class) |
Client-specified values always win over the preset.
### Changes to the vendor PPD
`assets/Brother HL-4150CDN/ppd/BR4150_2.PPD` is Brother's original file plus
two additions, each marked with a `%` comment in the file:
- **`*DefaultBRColorMode: None` instead of `Normal`.** `Normal` and `Vivid` both
set `<</UseCIEColor true>>`; the printer's own CIE conversion washes the
colours out (see [Colours are printed pale / washed out](#colours-are-printed-pale--washed-out)).
- **Six `APPrinterPreset` entries** mapping `print-color-mode`
(color/monochrome) and `print-quality` (draft/normal/high) onto
`BRPrintQuality`, `CAPT` and `TonerSaveMode`. CUPS applies such presets for
driverless clients and always lets the client's own option values win. In
particular `print-color-mode=monochrome` becomes `BRPrintQuality=Black`, so
black-and-white printing works: the server cannot do the greyscale conversion
itself, because `pdftops` uses Poppler for Brother printers and Poppler
cannot produce greyscale (`WARNING: Grayscale/monochrome could be printed as
color with Poppler` in the CUPS log). The presets use the notation CUPS
generates itself — Apple metadata as `key value` pairs *without* `=`, PPD
options as `*Name Value` pairs on separate lines inside a multiline
`"…"` string. With `key=value` on a single line CUPS silently ignores the
whole preset (verified against libcups 2.4.2: `_ppdParseOptions()` splits on
whitespace, so `key=value` becomes the option *name* and the lookup fails).
Note that IPP `print-quality` is `3` (draft), `4` (normal), `5` (high).
## Client support
| Platform | Path | Notes |
@@ -384,6 +450,38 @@ still being rejected — fix that, or add the queue from the command line as
above. macOS caches the failed attempt, so remove and re-add the printer after
changing anything on the server.
### Colours are printed pale / washed out
Symptom: colour printouts look desaturated compared to the same PDF printed
directly from the Mac, or with Brother's own driver.
Cause: the PPD colour mode `Normal` (Brother's default) makes the printer's
PostScript interpreter apply its own CIE conversion (`<</UseCIEColor true>>`),
which washes colours out. `Vivid` sets `UseCIEColor` as well, so it does not
help either; `BRPrintQuality` (`BRColorAdapt`) and `TonerSaveMode` made no
visible difference in a side-by-side test. The container therefore ships the
PPD with `*DefaultBRColorMode: None` (`UseCIEColor` off), which produces
saturated output.
Check and, if needed, override the current default:
```sh
podman exec printserver lpoptions -p <queue> -l | grep BRColorMode # expect *None
podman exec printserver lp -d <queue> -o BRColorMode=None test.pdf
```
If output is still pale with `BRColorMode=None`, check the printer's own menu
(Toner → Toner Save off) and make sure `BRMediaType` matches the media in the
tray.
Black-and-white is a related but separate path: `print-color-mode=monochrome`
from a driverless client is mapped by the PPD presets onto
`BRPrintQuality=Black` (the printer renders mono). It is deliberately *not* done
by the server — with its Poppler renderer, `pdftops` cannot convert to
greyscale. Forcing Ghostscript with `-o pdftops-renderer=gs` would, but that
path is not recommended for Brother printers (bugs in their PostScript
interpreters).
## CUPS 3 and the future of PPDs
Adding the queue with a PPD makes `lpadmin` print: