Files
putnamrec/vendor/tecnickcom/tc-lib-pdf/examples/E053_spot_overprint_proof.php
T
2026-08-20 11:41:17 +00:00

289 lines
10 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* E053_spot_overprint_proof.php
*
* Demonstrates spot color registration, tint ramp generation, and
* overprint simulation using tc-lib-color and tc-lib-pdf-graph.
*
* What this demonstrates:
* - color->addSpotColor(): register named spot colors with CMYK equivalents.
* - color->getPdfColor($name, $stroke, $tint): apply spot ink at any tint level.
* - Tint ramps: a sequence of filled rectangles stepping from 0% to 100% tint.
* - Layered spot rectangles: simulate overprint by stacking semi-transparent shapes.
* - Companion lib: tc-lib-color (spot/Lab color model), tc-lib-pdf-graph (rects).
*
* Note: tc-lib-pdf does not expose a native /OP (overprint) ExtGState toggle.
* Overprint simulation here uses stacked shapes with varying tints to give a
* visual impression of ink mixing, which is representative for screen proofing.
*
* @since 2026-05-01
* @category Library
* @package Pdf
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2002-2026 Nicola Asuni - Tecnick.com LTD
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
* @link https://github.com/tecnickcom/tc-lib-pdf
*
* This file is part of tc-lib-pdf software library.
*/
// NOTE: local file reads (images, fonts, attachments) are restricted to an allowlist of
// trusted paths that covers this package tree, so run the examples in place. To read assets
// from other locations, list them in the 'allowedPaths' entry of the fileOptions constructor
// parameter (see E047_remote_resources_security.php).
// NOTE: run make fonts in the project root to generate the dependencies and example fonts.
require __DIR__ . '/../vendor/autoload.php';
define('K_PATH_FONTS', (string) realpath(__DIR__ . '/../vendor/tecnickcom/tc-lib-pdf-font/target/fonts'));
$pdf = new \Com\Tecnick\Pdf\Tcpdf(
unit: \Com\Tecnick\Pdf\Page\Unit::Millimeter,
isunicode: true,
subsetfont: false,
compress: true,
mode: \Com\Tecnick\Pdf\PdfConformance::None,
objEncrypt: null,
);
$pdf->setCreator('tc-lib-pdf');
$pdf->setAuthor('Nicola Asuni');
$pdf->setSubject('tc-lib-pdf example: 053');
$pdf->setTitle('Spot Color & Overprint Proof');
$pdf->setKeywords('TCPDF tc-lib-pdf spot color CMYK tint ramp overprint proof');
$pdf->setPDFFilename('053_spot_overprint_proof.pdf');
$pdf->setViewerPreferences(['DisplayDocTitle' => true]);
$pdf->enableDefaultPageContent();
// ----------
// Register spot colors with CMYK fallback values.
// These simulate industry-standard spot-like named inks. In a real press
// workflow the names would match the RIP spot-color library exactly.
$pdf->color->addSpotColor('PROOF Cyan', new \Com\Tecnick\Color\Model\Cmyk([
'cyan' => 1.0,
'magenta' => 0.0,
'yellow' => 0.0,
'key' => 0.0,
'alpha' => 0.0,
]));
$pdf->color->addSpotColor('PROOF Magenta', new \Com\Tecnick\Color\Model\Cmyk([
'cyan' => 0.0,
'magenta' => 1.0,
'yellow' => 0.0,
'key' => 0.0,
'alpha' => 0.0,
]));
$pdf->color->addSpotColor('PROOF Yellow', new \Com\Tecnick\Color\Model\Cmyk([
'cyan' => 0.0,
'magenta' => 0.0,
'yellow' => 1.0,
'key' => 0.0,
'alpha' => 0.0,
]));
$pdf->color->addSpotColor('PROOF Black', new \Com\Tecnick\Color\Model\Cmyk([
'cyan' => 0.0,
'magenta' => 0.0,
'yellow' => 0.0,
'key' => 1.0,
'alpha' => 0.0,
]));
$pdf->color->addSpotColor('PROOF Warm Red', new \Com\Tecnick\Color\Model\Cmyk([
'cyan' => 0.0,
'magenta' => 0.85,
'yellow' => 0.9,
'key' => 0.02,
'alpha' => 0.0,
]));
$pdf->color->addSpotColor('PROOF Reflex Blue', new \Com\Tecnick\Color\Model\Cmyk([
'cyan' => 0.93,
'magenta' => 0.75,
'yellow' => 0.0,
'key' => 0.02,
'alpha' => 0.0,
]));
// ----------
$labelFont = $pdf->font->insert($pdf->pon, 'helvetica', 'B', 8);
$noteFont = $pdf->font->insert($pdf->pon, 'helvetica', '', 8);
// ===| Page 1 Tint Ramps |=================================================
$pdf->addPage(['format' => 'A4']);
$pdf->page->addContent($labelFont['out']);
$introHtml = '<h1 style="font-family: helvetica;">Spot Color Proof — Tint Ramps</h1>
<p style="font-family: helvetica; font-size: 9pt;">
Each row shows a named spot color at tints from 10% to 100%.
Spot colors are registered via <code>color-&gt;addSpotColor()</code> with a CMYK equivalent
and applied using <code>color-&gt;getPdfColor($name, $stroke, $tint)</code>.
The label column shows the spot name as it would appear in a PDF color dictionary.
</p>';
$pdf->addHTMLCell(html: $introHtml, posx: 15, posy: 20, width: 175);
// List of spots to render and their display label color
/** @var array<int, array{name: string, label: string}> $spotRows */
$spotRows = [
['name' => 'PROOF Cyan', 'label' => '#007799'],
['name' => 'PROOF Magenta', 'label' => '#990077'],
['name' => 'PROOF Yellow', 'label' => '#887700'],
['name' => 'PROOF Black', 'label' => '#222222'],
['name' => 'PROOF Warm Red', 'label' => '#993300'],
['name' => 'PROOF Reflex Blue', 'label' => '#001177'],
];
$tintSteps = 10;
$swatchW = 14.0;
$swatchH = 10.0;
$labelW = 42.0;
$rowGap = 2.0;
$startX = 15.0;
$startY = 55.0;
// Draw tint scale header
$pdf->page->addContent($noteFont['out']);
for ($t = 1; $t <= $tintSteps; $t++) {
$tx = $startX + $labelW + (($t - 1) * $swatchW);
$pdf->page->addContent($pdf->getTextCell(
txt: (string) ($t * 10) . '%',
posx: $tx,
posy: $startY - 5,
width: $swatchW,
height: 0,
offset: 0,
linespace: 1,
valign: \Com\Tecnick\Pdf\TextVAlign::Top,
halign: \Com\Tecnick\Pdf\TextHAlign::Center,
));
}
$rowY = $startY;
foreach ($spotRows as $row) {
$spotName = $row['name'];
$labelColor = $row['label'];
// Spot name label
$pdf->page->addContent($labelFont['out']);
$pdf->page->addContent($pdf->color->getPdfColor($labelColor, true, 1.0));
$pdf->page->addContent($pdf->color->getPdfColor($labelColor, false, 1.0));
$pdf->page->addContent($pdf->getTextCell(
txt: $spotName,
posx: $startX,
posy: $rowY + 2,
width: $labelW,
height: 0,
offset: 0,
linespace: 1,
valign: \Com\Tecnick\Pdf\TextVAlign::Top,
halign: \Com\Tecnick\Pdf\TextHAlign::Left,
));
// Draw tint swatches 10%100%
for ($t = 1; $t <= $tintSteps; $t++) {
$tint = $t / $tintSteps;
$sx = $startX + $labelW + (($t - 1) * $swatchW);
// Set fill and stroke to spot color at this tint level
$pdf->page->addContent($pdf->color->getPdfColor($spotName, true, $tint));
$pdf->page->addContent($pdf->color->getPdfColor($spotName, false, $tint));
$pdf->page->addContent($pdf->graph->getRect($sx, $rowY, $swatchW, $swatchH, 'DF'));
}
$rowY += $swatchH + $rowGap;
}
// Reset to black for subsequent text
$pdf->page->addContent($pdf->color->getPdfColor('black', true, 1.0));
$pdf->page->addContent($pdf->color->getPdfColor('black', false, 1.0));
$pdf->page->addContent($noteFont['out']);
$footNote = '<p style="font-family: helvetica; font-size: 8pt; color: #555555; margin-top: 4mm;">
Spot colors use the PDF <em>Separation</em> color space with a CMYK alternate.
Screen rendering uses the CMYK alternate; print output uses the named ink.
</p>';
$pdf->addHTMLCell(html: $footNote, posx: 15, posy: 170, width: 175);
// ===| Page 2 Stacked Spot Layers (Overprint Simulation) |=================
$pdf->addPage(['format' => 'A4']);
$pdf->page->addContent($labelFont['out']);
$overHtml = '<h1 style="font-family: helvetica;">Overprint Simulation — Stacked Spot Layers</h1>
<p style="font-family: helvetica; font-size: 9pt;">
Two spot inks are drawn in overlapping rectangles at varying tints to simulate
the visual effect of overprinting. In a real press workflow the RIP controls overprint
behaviour via the <em>/OP</em> and <em>/op</em> ExtGState flags.
This page shows the CMYK-alternate screen rendering of the overlap.
</p>';
$pdf->addHTMLCell(html: $overHtml, posx: 15, posy: 20, width: 175);
// Overprint grid: every combination of Cyan × Magenta at 25/50/75/100% tints
$ox = 25.0;
$oy = 55.0;
$cellSize = 22.0;
$tints = [0.25, 0.5, 0.75, 1.0];
$labelNames = ['25%', '50%', '75%', '100%'];
// Column headers (Cyan tint)
$pdf->page->addContent($labelFont['out']);
foreach ($labelNames as $ci => $clab) {
$pdf->page->addContent($pdf->getTextCell(
txt: 'C ' . $clab,
posx: $ox + 12 + ($ci * $cellSize),
posy: $oy - 7,
width: $cellSize,
height: 0,
offset: 0,
linespace: 1,
valign: \Com\Tecnick\Pdf\TextVAlign::Top,
halign: \Com\Tecnick\Pdf\TextHAlign::Center,
));
}
foreach ($tints as $mi => $mTint) {
// Row header (Magenta tint)
$pdf->page->addContent($pdf->getTextCell(
txt: 'M ' . $labelNames[$mi],
posx: $ox,
posy: $oy + ($mi * $cellSize) + 5,
width: 12,
height: 0,
offset: 0,
linespace: 1,
valign: \Com\Tecnick\Pdf\TextVAlign::Top,
halign: \Com\Tecnick\Pdf\TextHAlign::Left,
));
foreach ($tints as $ci => $cTint) {
$cx = $ox + 12 + ($ci * $cellSize);
$cy = $oy + ($mi * $cellSize);
// Draw Cyan layer first, then Magenta layer on top
$pdf->page->addContent($pdf->color->getPdfColor('PROOF Cyan', false, $cTint));
$pdf->page->addContent($pdf->graph->getRect($cx, $cy, $cellSize, $cellSize, 'F'));
$pdf->page->addContent($pdf->color->getPdfColor('PROOF Magenta', false, $mTint));
$pdf->page->addContent($pdf->graph->getAlpha(0.6)); // partial alpha to show both layers
$pdf->page->addContent($pdf->graph->getRect($cx, $cy, $cellSize, $cellSize, 'F'));
$pdf->page->addContent($pdf->graph->getAlpha(1.0)); // restore
}
}
// Reset colors
$pdf->page->addContent($pdf->color->getPdfColor('black', true, 1.0));
$pdf->page->addContent($pdf->color->getPdfColor('black', false, 1.0));
$overNote = '<p style="font-family: helvetica; font-size: 8pt; color: #555555; margin-top: 4mm;">
Each cell renders Cyan at the column tint, then Magenta at the row tint with 60% opacity —
approximating a soft-proof of two overprinted inks on a white substrate.
</p>';
$pdf->addHTMLCell(html: $overNote, posx: 15, posy: 165, width: 175);
// ----------
$rawpdf = $pdf->getOutPDFString();
$pdf->renderPDF(rawpdf: $rawpdf);