PHP
<?php
namespace setasign\SetaPDF2\Demos\Inspector;
use setasign\SetaPDF2\Core\Document;
use setasign\SetaPDF2\Core\Resource\ResourceInterface;
use setasign\SetaPDF2\Core\Type\PdfDictionary;
use setasign\SetaPDF2\Core\XObject\XObject;
use setasign\SetaPDF2\Core\XObject\Form;
use setasign\SetaPDF2\Core\XObject\Image;
use setasign\SetaPDF2\NotImplementedException;
class TransparencyInspector
{
protected $_document;
protected $_currentLocation = [];
protected $_elements = [];
public function __construct(Document $document)
{
$this->_document = $document;
}
public function process()
{
$this->_elements = [];
$pages = $this->_document->getCatalog()->getPages();
for ($pageNo = 1, $pageCount = $pages->count(); $pageNo <= $pageCount; $pageNo++) {
$page = $pages->getPage($pageNo);
$this->_currentLocation = ['Page ' . $pageNo];
$xObjects = $page->getCanvas()->getResources(true, false, ResourceInterface::TYPE_X_OBJECT);
if ($xObjects) {
$this->_processXObjects($xObjects);
}
$graphicStates = $page->getCanvas()->getResources(true, false, ResourceInterface::TYPE_EXT_G_STATE);
if ($graphicStates) {
$this->_processGraphicStates($graphicStates);
}
}
return $this->_elements;
}
protected function _processGraphicStates(PdfDictionary $graphicStates)
{
$root = $this->_currentLocation;
foreach ($graphicStates AS $name => $graphicState) {
$this->_currentLocation = $root;
$this->_currentLocation[] = 'GraphicState (' . $name . ')';
$dictionary = $graphicState->ensure();
if (!$dictionary instanceof PdfDictionary) {
continue;
}
if (isset($dictionary['SMask']) && $dictionary->getValue('SMask')->ensure()->getValue() !== 'None') {
$this->_addTransparentElement('GraphicState', $dictionary, 'Graphic state with SMask entry');
continue;
}
if (isset($dictionary['CA']) && $dictionary->getValue('CA')->getValue() != 1.0) {
$this->_addTransparentElement(
'GraphicState',
$dictionary,
'Graphic state with "CA" value of ' . sprintf('%.5F', $dictionary->getValue('CA')->getValue())
);
}
if (isset($dictionary['ca']) && $dictionary->getValue('ca')->getValue() != 1.0) {
$this->_addTransparentElement(
'GraphicState',
$dictionary,
'Graphic state with "ca" value of ' . sprintf('%.5F', $dictionary->getValue('CA')->getValue())
);
}
}
$this->_currentLocation = $root;
}
protected function _processXObjects(PdfDictionary $xObjects)
{
$root = $this->_currentLocation;
foreach ($xObjects AS $name => $xObject) {
$this->_currentLocation = $root;
$this->_currentLocation[] = 'XObject (' . $name . ')';
$xObject = XObject::get($xObject);
if ($xObject instanceof Image) {
$dictionary = $xObject->getIndirectObject()->ensure()->getValue();
if (isset($dictionary['SMask'])) {
$this->_addTransparentElement('Image', $xObject, 'Image with SMask entry');
continue;
}
if ($dictionary->getValue('Filter')->getValue() === 'JPXDecode') {
if (isset($dictionary['SMaskInData']) && $dictionary->getValue('SMaskInData')->getValue() != 0) {
$this->_addTransparentElement(
'Image',
$xObject,
'Image with JPXDecode filter and SMaskInData entry'
);
continue;
}
}
} elseif ($xObject instanceof Form) {
$_xObjects = $xObject->getCanvas()->getResources(true, false, ResourceInterface::TYPE_X_OBJECT);
if ($_xObjects) {
$this->_processXObjects($_xObjects);
}
$graphicStates = $xObject->getCanvas()->getResources(true, false, ResourceInterface::TYPE_EXT_G_STATE);
if ($graphicStates) {
$this->_processGraphicStates($graphicStates);
}
}
}
}
protected function _addTransparentElement($type, $data, $info)
{
$this->_elements[] = [
'type' => $type,
'data' => $data,
'info' => $info,
'location' => join(', ', $this->_currentLocation)
];
}
}