# Pantum 4200 系列 PostScript 驱动

这是给 `Pantum 4200` 系列单独整理的 PostScript CUPS 驱动目录。

## 官方来源

官方驱动文件：

```text
/home/hao/Documents/系统适配培训/官方驱动/Pantum Linux Driver V1_1_166.zip
```

该 zip 内的 `Resources/pantum_1.1.166-1_amd64.deb` 包含 4200 系列 PS PPD。官方原始 PPD 模板保存在 `ppd/_templates/`，最终安装的修复版 PPD 保存在顶层 `ppd/*.ppd`。

## 支持型号

```text
BM4200AD
BM4200ADN
BM4200ADW
BM4200D
BM4200DN
BM4200DW
BP4200D
BP4200DN
BP4200DW
```

这些型号都有官方精确 PPD。

## 路线判断

官方 PPD 声明：

```text
*cupsFilter: "application/vnd.cups-postscript 0 ptps"
```

所以这组型号走 PostScript 路线，不是 CUPS raster/GDI 路线。本目录实现一个可审计的 PostScript 归一化 filter。

生成后的 PPD 不再引用全局 `ptps`，而是引用本包自己的 `pantum-4200-ps-filter`。这样可以和其他 Pantum PS 驱动包并存，避免多个包同时安装 `/usr/lib/cups/filter/ptps` 发生文件冲突。

当前 filter 不再做纯字节透传。它会剥离输入开头的 PJL/JCL 包装，避免 BM4200ADN 把 `@PJL JOB`、`@PJL SET ...`、`@PJL ENTER LANGUAGE=POSTSCRIPT` 当成正文打印；同时精确解析 `Duplex=` 和 `sides=` 选项，在未明确选择双面时注入 PostScript 单面设置，降低设备或队列默认双面导致误打双面的概率。

BM4200ADN 真机验证过一个关键边界：奇数页文档、双面打印、多份打印时，如果不补空白背面，下一份第一页会接到上一份最后一页的反面。本包的 PPD 强制：

```text
*cupsManualCopies: True
*cupsEvenDuplex: true
```

这会让 CUPS/pstops 生成每一份副本，并在双面奇数页副本后插入 filler 空白页，保证每份从新纸张正面开始。

## USB 扫描集成

参考 `lz-deepin` 这类扫描应用的工作方式，应用层只调用系统 SANE；真正决定 USB 设备能否发现的是系统是否安装了后端、`sane.d/dll.d` 注册和 udev 权限。

Debian 打包时扫描拆成两条：

```text
printer-driver-pantum-4200-driverless-scan  # eSCL/AirScan/ipp-usb，Architecture: any
printer-driver-pantum-4200-sane             # Pantum 私有 USB 后端，Architecture: amd64
```

`driverless-scan` 参考 `lz-deepin` 的 eSCL/AirScan/ipp-usb 路线，不包含闭源 Pantum 后端，适合其他架构先跑标准协议扫描。`sane` 包安装官方 `pantum_bm4200` 后端，只能在 amd64 架构构建。打印包 `printer-driver-pantum-4200` 是 `Architecture: any`，可以给 arm64、loong64、mips64el 等架构继续构建 CUPS 打印支持。

amd64 私有 USB 扫描包安装官方 `pantum_bm4200` SANE 后端的最小集：

```text
/lib/udev/rules.d/60-pantum-4200.rules
/etc/sane.d/pantum_bm4200.conf
/etc/sane.d/dll.d/pantum_bm4200
/usr/lib/<multiarch>/sane/libsane-pantum_bm4200.so.1.0.24
/usr/lib/<multiarch>/sane/libsane-pantum_bm4200.so.1
/usr/lib/<multiarch>/sane/libsane-pantum_bm4200.so
```

当前 USB ID 来自官方 V1.1.166 的 `pantum_bm4200.conf` 和 `60-pantum_bm4200.rules`，覆盖 `BM4200D/BM4200DN/BM4200DW/BM4200AD/BM4200ADN/BM4200ADW`。`BP4200D/BP4200DN/BP4200DW` 在官方扫描后端配置里没有对应项，当前按打印机型处理，不声明扫描能力。

## 重新生成 PPD

```bash
python3 tools/generate_ppds.py
```

生成脚本会做三件事：

- 从 `ppd/_templates/` 复制官方精确 PPD。
- 把 cupsFilter 改为 `pantum-4200-ps-filter`。
- 修复官方 PPD 中 `JCLSetup` 选项块的结构问题，把相关块从 `OpenUI/CloseUI` 转成 CUPS 可接受的 `JCLOpenUI/JCLCloseUI`。

## 构建验证

```bash
make
make check
```

`make check` 会验证 9 个 PPD 的 filter 和型号元数据；如果系统有 `cupstestppd`，还会检查 PPD 语法；最后验证 filter 的文件输入、stdin 输入、PJL 前缀剥离、默认单面注入、显式双面保留，以及 BM4200ADN 奇数页双面多份时 CUPS 是否插入 filler 空白页。

## 已有队列的双面默认

PPD 默认值是 `Duplex None`。如果系统里已有 CUPS 队列保存过双面默认，CUPS 会把这个历史默认合并进 filter 参数，filter 无法可靠区分它是“历史队列默认”还是“用户本次显式选择双面”。这种情况下需要把队列默认重置为单面：

```bash
lpoptions -p <队列名> -o Duplex=None -o sides=one-sided
```

确认队列当前选项：

```bash
lpoptions -p <队列名> -l | grep -E 'Duplex|sides'
```

## 安装

Debian 包拆分为：

```text
printer-driver-pantum-4200       # 打印，Architecture: any
printer-driver-pantum-4200-driverless-scan  # 免驱扫描辅助，Architecture: any
printer-driver-pantum-4200-sane             # 私有 USB 扫描，Architecture: amd64
```

从源码直接安装时，`make install` 仍安装打印和扫描全量文件：

```bash
sudo make install
```

默认会安装：

```text
/usr/lib/cups/filter/pantum-4200-ps-filter
/usr/share/cups/model/Pantum/Pantum <型号> Series PS.ppd
/lib/udev/rules.d/60-pantum-4200.rules
/etc/sane.d/pantum_bm4200.conf
/etc/sane.d/dll.d/pantum_bm4200
/usr/lib/<multiarch>/sane/libsane-pantum_bm4200.so*
```

也可以先用 `DESTDIR` 做离线安装布局检查：

```bash
make install DESTDIR=/tmp/pantum-4200-install
```

## 当前边界

- 已覆盖：CUPS filter 参数形式、文件输入、stdin 输入、PJL/JCL 前缀剥离、默认单面注入、显式双面保留、奇数页双面多份 filler 空白页、多型号 PPD 安装。
- 已覆盖：官方 `pantum_bm4200` SANE 后端安装、`dll.d` 注册、BM4200 USB 权限规则。
- 未覆盖：真机状态查询、厂商 side-channel、复杂设备私有控制、真实双面走纸行为、BP4200 扫描能力。
- 复杂打印选项仍应由 CUPS `pstops` 和官方 PPD 注入，filter 层只处理 PJL/JCL 包装和默认单面兜底。
