Валідація 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 — найбільш поширений сучасний рівень, що дозволяє прозорість та RGB з ICC-профілями.
Швидка валідація
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 валідатора
Builder 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 Identification
Валідатор підтверджує, що метадані XMP декларують правильну версію PDF/X:
pdfxid:GTS_PDFXVersionmust match the target level- The declared version is compared against the
gts_pdfx_version()for the target level
Сторінка Box Relationships
PDF/X requires specific nesting of page boxes:
TrimBox <= BleedBox <= MediaBox
ArtBox <= MediaBox
Валідатор перевіряє кожну сторінку, щоб переконатися:
- TrimBox is present (required by all PDF/X levels)
- TrimBox is contained within BleedBox (if BleedBox is defined)
- BleedBox is contained within MediaBox
- ArtBox is contained within MediaBox (if ArtBox is defined)
- Tolerance of 0.01 points for floating-point rounding
Transparency Detection
For PDF/X-1a and PDF/X-3, no transparency is permitted. The validator checks:
- SMask in ExtGState dictionaries (must be
/Noneor absent) - CA (stroke opacity) must equal 1.0
- ca (fill opacity) must equal 1.0
- BM (blend mode) must be
NormalorCompatible
PDF/X-4 and later levels permit transparency.
Color Space Validation
Валідатор перевіряє використання залежних від пристрою кольорів:
- DeviceRGB is not allowed in PDF/X-1a (CMYK-only)
- DeviceRGB, DeviceCMYK, and DeviceGray used without an output intent trigger errors in stricter levels
- Color operators
rg,RG,k,K,g,Gin page content streams are scanned
ICC Profile Validation
For ICCBased color spaces, the validator checks:
- The profile stream contains the required
/N(number of components) entry - The
/Nvalue matches the expected color space dimension (1 for gray, 3 for RGB, 4 for CMYK) - The profile data is present and non-empty
Output Intent
PDF/X requires an output intent that describes the intended print condition:
/OutputIntentsarray must be present in the document catalog- At least one entry with subtype
GTS_PDFXis required - The output intent should reference an ICC profile or a registered print condition
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
Enum 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
| Метод | Повертає | Опис |
|---|---|---|
iso_standard() |
&str |
ISO standard number (e.g., "ISO 15930-7") |
required_pdf_version() |
&str |
Minimum Версія PDF (e.g., "1.6") |
allows_transparency() |
bool |
Whether transparency groups are permitted |
allows_rgb() |
bool |
Whether RGB-колір space is permitted |
allows_layers() |
bool |
Whether optional content groups are permitted |
allows_external_icc() |
bool |
Whether external ICC profiles are permitted |
allows_external_graphics() |
bool |
Whether external graphics references are permitted |
gts_pdfx_version() |
&str |
Expected GTS_PDFXVersion value |
xmp_version() |
&str |
Expected XMP version identifier |
from_gts_version(version) |
Option<Self> |
Parse level from a GTS version string |
Practical Example: 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" });
// Group errors by severity
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);
}
}
Наступні кроки
- PDF/A Validation – archival compliance
- PDF/UA Accessibility – accessibility validation
- API Reference – complete Rust API