Related: #430 (support color model), vivliostyle/vivliostyle-cli#774 (CMYK conversion audit)
Is your feature request related to a problem? Please describe.
商業印刷では、blend color、metaric ink、CMYK色域外の色などに、(単色)特色(DIC, PANTONE 等の特色)が必要です。
現在の Vivliostyle は device-cmyk() による /DeviceCMYK 出力に対応していますが、以下の2つの問題があります。
-
特色(Separation 色空間)に対応していない。 device-cmyk() は PDF の /DeviceCMYK のみを出力でき、/Separation(特色版)を出力できません。
-
CSS に tint(濃淡)を指定する手段がない。 LaTeX の xcolor パッケージでは DIC161s!50(50% tint)や black!20(黒 20%)のように簡単に書けますが、CSS には相当する機能がありません。ユーザーが device-cmyk(0 0.32 0.5 0) のように手動で CMYK 値を計算する必要があり、ミスの温床になります。
In commercial printing, spot colors (DIC, PANTONE, etc.) are required for brand colors, metallic inks, and out-of-gamut colors. Vivliostyle currently supports /DeviceCMYK via device-cmyk(), but cannot output PDF /Separation color spaces. Also, CSS lacks a tint mechanism equivalent to xcolor's ! operator.
Describe the solution you'd like
2つの CSS 関数の追加を提案したいです。
1. spot-color(NAME): 特色参照
特色を名前で参照する関数です。
名前は vivliostyle.config.js で定義します。
h1 { color: spot-color(DIC161s); }
2. color-tint(COLOR, N%): 汎用 tint 関数
任意の色に tint(濃淡)を適用する汎用関数です。
これはLaTeXにおける xcolor パッケージの ! 演算子に相当します。
spot-color 専用ではなく、rgb(), device-cmyk(), 名前付きカラーなど、すべての色モデルで動作します。
/* 特色の tint(xcolor の DIC161s!50 に相当) */
.tint50 { color: color-tint(spot-color(DIC161s), 50%); }
/* プロセスカラーの tint(xcolor の black!20 に相当) */
.black20 { color: color-tint(black, 20%); }
.cyan50 { color: color-tint(device-cmyk(1 0 0 0), 50%); }
/* RGB の tint */
.red90 { color: color-tint(rgb(255 0 0), 90%); }
/* tint と alpha(透明度)の併用: これらは独立した概念です */
.both { color: color-tint(device-cmyk(0 0 0 1 / 0.5), 50%); }
tint 演算は「白との混合」として定義されます(xcolor の ! と同じ)。
| 色モデル |
白 |
color-tint(color, N%) の意味 |
| CMYK |
(0,0,0,0) |
各成分 × N/100 |
| RGB |
(255,255,255) |
c + (255−c) × (1 − N/100) |
| Spot |
— |
Separation tint 値 = N/100 |
特色の設定
特色は vivliostyle.config.js の 一箇所でのみ定義 します。
CSS と config の両方に CMYK 値を書く二重定義の問題を避けるためです。
// vivliostyle.config.js
export default {
output: [{
path: 'output.pdf',
pdfPostprocess: {
cmyk: true,
spotColors: [
{ name: 'DIC161s', pdfName: 'DIC 161s*', cmyk: { c: 0, m: 0.64, y: 1, k: 0 } },
{ name: 'DIC256s', pdfName: 'DIC 256s*', cmyk: { c: 0.9, m: 0, y: 0.4, k: 0 } },
],
},
}],
};
spotxcolor(LaTeX)との対応関係
本提案は、LaTeXにおける拙作の spotxcolor パッケージの「Intercept, Detect, Replace」戦略に基づいています。
spotxcolor Vivliostyle (proposed)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
\definespotcolor{DIC161s} → vivliostyle.config.js spotColors[]
{DIC 161s*}{0, 0.64, 1, 0}
\color{DIC161s} → spot-color(DIC161s)
DIC161s!50 → color-tint(spot-color(DIC161s), 50%)
black!20 → color-tint(black, 20%)
\set@color intercept → CLI post-process intercept
|c_i - t·b_i| < ε → Separation → same algorithm → Separation
期待される PDF 出力
%% Separation 色空間オブジェクト
<< /FunctionType 2 /Domain [0 1] /C0 [0 0 0 0] /C1 [0 0.64 1 0] /N 1 >>
[/Separation /DIC#20161s* /DeviceCMYK <func ref>]
%% Content stream
/DIC161s cs 1 sc % spot-color(DIC161s) — 100% tint
/DIC161s CS 1 SC % stroking
/DIC161s cs 0.5 sc % color-tint(spot-color(DIC161s), 50%)
0 0 0 0.2 k % color-tint(black, 20%) — DeviceCMYK fallback
重要: tint と alpha(透明度)は異なる概念です
印刷においてこの2つは、根本的に異なる操作です。
しばしば印刷現場で起きていることは、一部のWebデザイナーが opacity で「薄い色」を作ろうとするのは、印刷では誤りです。
color-tint() が印刷で正しい代替手段を提供します。
|
tint |
alpha(transparency) |
| 意味 |
インキ濃度(網点面積率) |
合成透明度 |
| PDF オペレータ |
0 0 0 0.5 k |
0 0 0 1 k + ExtGState /ca 0.5 |
| 版分解 |
1版で50%ハーフトーン |
フラット化(透明の解除)が必要 |
| 併用 |
color-tint(device-cmyk(... / 0.5), 50%) = tint 50% かつ alpha 0.5 |
|
Describe alternatives you've considered
A. CSS 変更なし(config + proportional tint 検出のみ)
CSS 側は device-cmyk() をそのまま使い、CLI の config で特色名と CMYK 値のマッピングを定義する方式。
CLI の後処理で proportional tint 検出(spotxcolor の |c_i - t·b_i| < ε アルゴリズム)により、CMYK 値が特色の比例 tint であることを自動検出する。
不採用の理由
- ユーザーが
device-cmyk(0 0.32 0.5 0) のように tint 値を手計算する必要がある(ミスの原因)
- CSS と config の両方に特色の CMYK 値を書く二重定義になる
- CSS 上で特色の意図が読み取れない
B. CSS custom property のみ
:root { --DIC161s: device-cmyk(0 0.64 1 0); }
h1 { color: var(--DIC161s); }
不採用の理由
- tint の問題は解決されない(
var(--DIC161s) に 50% tint を適用する CSS 構文がない)
- config との二重定義の問題が残る
C. color-mix() の実装
CSS Color Level 5 の color-mix() を実装する方式。
不採用の理由
color-mix() は汎用的すぎて、tint(白との混合)だけでなく任意の2色混合を扱う
- Separation 色空間の tint 値に直接対応しない
- 実装が大きくなりすぎる
Additional context
実装方針
vivliostyle.js(Core)
spot-color() と color-tint() を CSS 関数としてパース(Vivliostyle 独自 CSS 拡張の前例あり: crop-offset, env(pub-title) など)
- Webブラウザ上のプレビュー用に
color(srgb ...) に変換(device-cmyk() と同じ代替 RGB 方式)
getSpotColorMap() API で特色マップをエクスポート(getCmykMap() と同パターン)
- 既存の
device-cmyk() パイプラインへの変更なし
vivliostyle-cli
spotColors 設定スキーマの追加
- proportional tint 検出アルゴリズム(spotxcolor より移植:
|c_i - t·b_i| < ε)
- pdf-lib を用いた PDF Separation オブジェクト生成
- content stream 書き換え: 特色にマッチ
- →
rg/RG → /NAME cs TINT sc、不一致 → k/K(DeviceCMYK fallback)
既知の制約(設計上の判断)
ここで相談したいこと
- 関数名:
color-tint() vs tint() vs 他の良い案はありますか?
- Vivliostyle 独自の CSS 関数を追加することへの懸念はありますか?
Related: #430 (support color model), vivliostyle/vivliostyle-cli#774 (CMYK conversion audit)
商業印刷では、blend color、metaric ink、CMYK色域外の色などに、(単色)特色(DIC, PANTONE 等の特色)が必要です。
現在の Vivliostyle は
device-cmyk()による/DeviceCMYK出力に対応していますが、以下の2つの問題があります。特色(Separation 色空間)に対応していない。
device-cmyk()は PDF の/DeviceCMYKのみを出力でき、/Separation(特色版)を出力できません。CSS に tint(濃淡)を指定する手段がない。 LaTeX の xcolor パッケージでは
DIC161s!50(50% tint)やblack!20(黒 20%)のように簡単に書けますが、CSS には相当する機能がありません。ユーザーがdevice-cmyk(0 0.32 0.5 0)のように手動で CMYK 値を計算する必要があり、ミスの温床になります。In commercial printing, spot colors (DIC, PANTONE, etc.) are required for brand colors, metallic inks, and out-of-gamut colors. Vivliostyle currently supports
/DeviceCMYKviadevice-cmyk(), but cannot output PDF/Separationcolor spaces. Also, CSS lacks a tint mechanism equivalent to xcolor's!operator.2つの CSS 関数の追加を提案したいです。
1.
spot-color(NAME): 特色参照特色を名前で参照する関数です。
名前は
vivliostyle.config.jsで定義します。2.
color-tint(COLOR, N%): 汎用 tint 関数任意の色に tint(濃淡)を適用する汎用関数です。
これはLaTeXにおける xcolor パッケージの
!演算子に相当します。spot-color専用ではなく、rgb(),device-cmyk(), 名前付きカラーなど、すべての色モデルで動作します。tint 演算は「白との混合」として定義されます(xcolor の
!と同じ)。color-tint(color, N%)の意味特色の設定
特色は
vivliostyle.config.jsの 一箇所でのみ定義 します。CSS と config の両方に CMYK 値を書く二重定義の問題を避けるためです。
spotxcolor(LaTeX)との対応関係
本提案は、LaTeXにおける拙作の spotxcolor パッケージの「Intercept, Detect, Replace」戦略に基づいています。
期待される PDF 出力
重要: tint と alpha(透明度)は異なる概念です
印刷においてこの2つは、根本的に異なる操作です。
しばしば印刷現場で起きていることは、一部のWebデザイナーが
opacityで「薄い色」を作ろうとするのは、印刷では誤りです。color-tint()が印刷で正しい代替手段を提供します。0 0 0 0.5 k0 0 0 1 k+ ExtGState/ca 0.5color-tint(device-cmyk(... / 0.5), 50%)= tint 50% かつ alpha 0.5A. CSS 変更なし(config + proportional tint 検出のみ)
CSS 側は
device-cmyk()をそのまま使い、CLI の config で特色名と CMYK 値のマッピングを定義する方式。CLI の後処理で proportional tint 検出(spotxcolor の
|c_i - t·b_i| < εアルゴリズム)により、CMYK 値が特色の比例 tint であることを自動検出する。不採用の理由
device-cmyk(0 0.32 0.5 0)のように tint 値を手計算する必要がある(ミスの原因)B. CSS custom property のみ
不採用の理由
var(--DIC161s)に 50% tint を適用する CSS 構文がない)C.
color-mix()の実装CSS Color Level 5 の
color-mix()を実装する方式。不採用の理由
color-mix()は汎用的すぎて、tint(白との混合)だけでなく任意の2色混合を扱う実装方針
vivliostyle.js(Core)
spot-color()とcolor-tint()を CSS 関数としてパース(Vivliostyle 独自 CSS 拡張の前例あり:crop-offset,env(pub-title)など)color(srgb ...)に変換(device-cmyk()と同じ代替 RGB 方式)getSpotColorMap()API で特色マップをエクスポート(getCmykMap()と同パターン)device-cmyk()パイプラインへの変更なしvivliostyle-cli
spotColors設定スキーマの追加|c_i - t·b_i| < ε)rg/RG→/NAME cs TINT sc、不一致 →k/K(DeviceCMYK fallback)既知の制約(設計上の判断)
/DeviceRGBの Shading オブジェクトのまま残ります(Chromium の構造的制約、device-cmyk() の DeviceCMYK 変換: CSS パターン別の調査結果 vivliostyle-cli#774 参照)ここで相談したいこと
color-tint()vstint()vs 他の良い案はありますか?