Skip to content

PDF/X 印刷プロダクション

PDF/X (ISO 15930) は印刷用 PDF ファイルの信頼性の高い交換のための標準です。 PDF Oxide はすべての主要な PDF/X レベルを検証し、ページボックス、色空間、透明度、ICC プロファイル、出力インテントを確認します。

サポートされるレベル

Level Standard Transparency RGB Layers External ICC External Graphics
X-1a:2001 ISO 15930-1 No No No No No
X-1a:2003 ISO 15930-4 No No No No No
X-3:2002 ISO 15930-3 No Yes No No No
X-3:2003 ISO 15930-6 No Yes No No No
X-4 ISO 15930-7 Yes Yes Yes No No
X-4p ISO 15930-7 Yes Yes Yes Yes No
X-5g ISO 15930-8 Yes Yes Yes No Yes
X-5n ISO 15930-8 Yes Yes Yes No Yes
X-5pg ISO 15930-8 Yes Yes Yes Yes Yes
X-6 ISO 15930-9 Yes Yes Yes No No
X-6n ISO 15930-9 Yes Yes Yes No Yes
X-6p ISO 15930-9 Yes Yes Yes Yes No

PDF/X-1a は最も制限的:CMYKのみ、透明度なし、レイヤーなし。PDF/X-4 は最も一般的に使用される現代レベルで、ICCプロファイル付きの透明度とRGBを許可します。

簡易バリデーション

from pdf_oxide import PdfDocument

doc = PdfDocument("document.pdf")
result = doc.validate_pdf_x("4")
print(f"Valid: {result.valid}")
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::pdf_x::{validate_pdf_x, PdfXLevel};

let mut doc = PdfDocument::open("print-ready.pdf")?;
let result = validate_pdf_x(&mut doc, PdfXLevel::X4)?;

if result.has_errors() {
    println!("Not PDF/X-4 compliant ({} errors):", result.errors.len());
    for error in &result.errors {
        println!("  [{}] {} (clause {})",
            error.code, error.message,
            error.clause.as_deref().unwrap_or("n/a"));
    }
} else {
    println!("Document is PDF/X-4 compliant");
}

バリデータ API

PdfXValidator ビルダーでバリデーション実行を設定します:

use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::pdf_x::{PdfXValidator, PdfXLevel};

let mut doc = PdfDocument::open("artwork.pdf")?;

let result = PdfXValidator::new(PdfXLevel::X1a2001)
    .stop_on_first_error(false)
    .include_warnings(true)
    .validate(&mut doc)?;

println!("Errors: {}", result.errors.len());
println!("Warnings: {}", result.warnings.len());
println!("Total issues: {}", result.total_issues());

検証される項目

XMP 識別

バリデータはXMPメタデータが正しいPDF/Xバージョンを宣言していることを確認します:

  • pdfxid:GTS_PDFXVersion がターゲットレベルと一致する必要がある
  • 宣言されたバージョンがターゲットレベルの gts_pdfx_version() と比較される

ページボックスの関係

PDF/X requires specific nesting of page boxes:

TrimBox <= BleedBox <= MediaBox
ArtBox  <= MediaBox

バリデータはすべてのページで以下を確認します:

  • TrimBox が存在する(すべてのPDF/Xレベルで必須)
  • TrimBoxがBleedBox内に含まれる(BleedBoxが定義されている場合)
  • BleedBoxがMediaBox内に含まれる
  • ArtBoxがMediaBox内に含まれる(ArtBoxが定義されている場合)
  • 浮動小数点丸めの0.01ポイントの許容値

透明度の検出

For PDF/X-1a and PDF/X-3, 透明度は許可されません. The validator checks:

  • ExtGState辞書の SMask/None または不在でなければならない)
  • CA(ストローク不透明度)は1.0でなければならない
  • ca(塗りつぶし不透明度)は1.0でなければならない
  • BM(ブレンドモード)は Normal または Compatible でなければならない

PDF/X-4以降のレベルでは透明度が許可されます。

色空間のバリデーション

バリデータはデバイス依存色の使用を確認します:

  • DeviceRGB はPDF/X-1a(CMYKのみ)では許可されない
  • より厳格なレベルでは出力インテントなしの DeviceRGBDeviceCMYKDeviceGray の使用はエラー
  • ページコンテンツストリーム内の色演算子 rgRGkKgG がスキャンされる

ICC プロファイルのバリデーション

ICCBased色空間の場合、バリデータは以下を確認します:

  • プロファイルストリームに必須の /N(コンポーネント数)エントリが含まれる
  • /N 値が期待される色空間次元と一致(グレー1、RGB3、CMYK4)
  • プロファイルデータが存在し空でない

出力インテント

PDF/X requires an output intent that describes the intended print condition:

  • ドキュメントカタログに /OutputIntents 配列が必要
  • サブタイプ GTS_PDFX のエントリが少なくとも1つ必要
  • 出力インテントはICCプロファイルまたは登録印刷条件を参照する必要がある

XValidationResult

pub struct XValidationResult {
    pub level: PdfXLevel,
    pub errors: Vec<XComplianceError>,
    pub warnings: Vec<XComplianceError>,
    pub stats: XValidationStats,
}

XComplianceError

pub struct XComplianceError {
    pub code: XErrorCode,
    pub message: String,
    pub severity: XSeverity,
    pub page: Option<usize>,
    pub object_id: Option<u32>,
    pub clause: Option<String>,
}

Errors include the page number and object ID where the violation was found, making it straightforward to locate and fix issues in the source file.

XErrorCode Categories

XErrorCode 列挙型にはカテゴリ別に整理された40以上の特定エラーコードが含まれます:

Metadata: MissingOutputIntent, InvalidGtsPdfxVersion, MissingXmpIdentification

Page boxes: MissingTrimBox, TrimBoxOutsideBleedBox, BleedBoxOutsideMediaBox, ArtBoxOutsideMediaBox

Transparency: TransparencyNotAllowed, InvalidBlendMode, InvalidSMask, InvalidOpacity

Color: DeviceRgbNotAllowed, DeviceDependentColorWithoutIntent, InvalidIccProfile, MissingIccComponents

Content: ExternalContentNotAllowed, EncryptionNotAllowed, JavaScriptNotAllowed

PdfXLevel Methods

Method Return 説明
iso_standard() &str ISO標準番号 (e.g., "ISO 15930-7")
required_pdf_version() &str Minimum PDFバージョン (e.g., "1.6")
allows_transparency() bool 透明度グループが許可されるか
allows_rgb() bool Whether RGB色 space is permitted
allows_layers() bool オプショナルコンテンツグループが許可されるか
allows_external_icc() bool 外部ICCプロファイルが許可されるか
allows_external_graphics() bool 外部グラフィックス参照が許可されるか
gts_pdfx_version() &str 期待される GTS_PDFXVersion
xmp_version() &str 期待されるXMPバージョン識別子
from_gts_version(version) Option<Self> GTSバージョン文字列からレベルをパース

実践例: Prepress Check

use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::pdf_x::{validate_pdf_x, PdfXLevel, XSeverity};

let mut doc = PdfDocument::open("magazine-cover.pdf")?;
let result = validate_pdf_x(&mut doc, PdfXLevel::X4)?;

println!("=== PDF/X-4 Prepress Report ===");
println!("Status: {}", if result.has_errors() { "REJECT" } else { "ACCEPT" });

// 重大度でエラーをグループ化
let critical: Vec<_> = result.errors.iter()
    .filter(|e| e.is_error())
    .collect();
let advisory: Vec<_> = result.warnings.iter().collect();

if !critical.is_empty() {
    println!("\nCritical ({}):", critical.len());
    for e in &critical {
        let page_str = e.page
            .map(|p| format!("page {}", p + 1))
            .unwrap_or_else(|| "document".into());
        println!("  [{}] {} ({})", e.code, e.message, page_str);
    }
}

if !advisory.is_empty() {
    println!("\nAdvisory ({}):", advisory.len());
    for w in &advisory {
        println!("  [{}] {}", w.code, w.message);
    }
}

次のステップ