PDF Output

Emitting colour into a PDF with tc-lib-color: fill and stroke operators, component strings, appearance arrays and Acrobat JavaScript colours

\Com\Tecnick\Color\Pdf turns a colour string into the operators a PDF content stream takes. It extends the spot registry, which extends the web parser, so the same object resolves a name, registers a separation and writes the operator.

Fill And Stroke

<?php

require_once __DIR__ . '/vendor/autoload.php';

$pdf = new \Com\Tecnick\Color\Pdf();

echo $pdf->getPdfFillColor('#336699');
echo $pdf->getPdfStrokeColor('#336699');
echo $pdf->getPdfFillColor('cmyk(67%,33%,0%,40%)');
echo $pdf->getPdfFillColor('g(128)');
0.200000 0.400000 0.600000 rg
0.200000 0.400000 0.600000 RG
0.670000 0.330000 0.000000 0.400000 k
0.501961 g

The operator comes from the model, so the colour space follows the notation:

ModelFillStroke
GrayscalegG
RGBrgRG
HSLrg, by conversionRG
CMYKkK
CIE Labrg, by conversionRG
Spot colourcs + scnCS + SCN

Each returned string ends in a newline, ready to append to a content stream.

getPdfColor() is the method underneath both: getPdfFillColor() and getPdfStrokeColor() fix the $stroke argument. All three return an empty string for a transparent colour and for unparseable input, rather than raising. See Errors.

Components Without The Operator

echo $pdf->getPdfRgbComponents('#336699'), "\n";
echo $pdf->getPdfCmykComponents('#336699'), "\n";
0.200000 0.400000 0.600000
0.666667 0.333333 0.000000 0.400000

getPdfRgbComponents() and getPdfCmykComponents() give the numbers alone, for building an operator that is not a plain fill: a shading dictionary, an annotation border, a transparency group.

Tint

The fourth argument of getPdfColor(), and the second of the two wrappers, is the tint. It is the operand of scn and applies to spot colours only. A device colour is always written at full intensity and ignores the argument.

$pdf->addSpotColorFromArray('PANTONE 032 C', [
    'cyan' => 0.0,
    'magenta' => 0.91,
    'yellow' => 0.86,
    'key' => 0.0,
]);

echo $pdf->getPdfFillColor('PANTONE 032 C');
echo $pdf->getPdfFillColor('PANTONE 032 C', 0.5);
echo $pdf->getPdfStrokeColor('PANTONE 032 C', 0.5);
/CS1 cs 1.000000 scn
/CS1 cs 0.500000 scn
/CS1 CS 0.500000 SCN

Appearance Characteristics

getPDFacArray() returns the bare components for the appearance characteristics dictionary of a form field, where the array length picks the colour space: one element is DeviceGray, three is DeviceRGB, four is DeviceCMYK.

print_r($pdf->getColorObject('g(128)')->getPDFacArray());
print_r($pdf->getColorObject('#336699')->getPDFacArray());
print_r($pdf->getColorObject('cmyk(67%,33%,0%,40%)')->getPDFacArray());
Array
(
    [0] => 0.50196078431373
)
Array
(
    [0] => 0.2
    [1] => 0.4
    [2] => 0.6
)
Array
(
    [0] => 0.67
    [1] => 0.33
    [2] => 0
    [3] => 0.4
)

An HSL or Lab colour produces three elements, since it converts to RGB first.

Acrobat JavaScript

getJsColorString() writes the colour in the form a PDF script expects, either as one of the twelve built-in names or as a component array.

echo $pdf->getJsColorString('dkGray'), "\n";
echo $pdf->getJsColorString('dkgray'), "\n";
echo $pdf->getJsColorString('#336699'), "\n";
echo $pdf->getJsColorString('rgba(51,102,153,0)'), "\n";
echo $pdf->getJsColorString('nosuchcolor'), "\n";
color.dkGray
["RGB",0.662745,0.662745,0.662745]
["RGB",0.200000,0.400000,0.600000]
["T"]
color.transparent

The names are matched case-sensitively and emitted verbatim, because they are JavaScript identifiers:

NamegetJsColorString()
transparentcolor.transparent
blackcolor.black
whitecolor.white
redcolor.red
greencolor.green
bluecolor.blue
cyancolor.cyan
magentacolor.magenta
yellowcolor.yellow
dkGraycolor.dkGray
graycolor.gray
ltGraycolor.ltGray

dkGray matches the JavaScript name; dkgray falls through to the parser and resolves as a web colour. Unparseable input returns color.transparent, so the method never raises and never returns an empty string.

Alpha

The PDF colour operators have no alpha component, and neither do the JavaScript arrays. Transparency in a PDF is a graphics state parameter, set separately from the colour, so getPdfColor(), getComponentsString() and getPDFacArray() all drop the alpha channel.

The one exception is a fully transparent colour, which getJsPdfColor() writes as ["T"].

Standards

A DeviceCMYK colour is only valid in a PDF/A document when the output intent is a CMYK profile, and a spot colour needs its Separation resource present on every page that references it. tc-lib-pdf reports both through getWarnings(); see /docs/standards/.

See Also