[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/assign/feedback/editpdf/fpdi/ -> fpdi_pdf_parser.php (source)

   1  <?php
   2  /**

   3   * This file is part of FPDI

   4   *

   5   * @package   FPDI

   6   * @copyright Copyright (c) 2015 Setasign - Jan Slabon (http://www.setasign.com)

   7   * @license   http://opensource.org/licenses/mit-license The MIT License

   8   * @version   1.6.1

   9   */
  10  
  11  if (!class_exists('pdf_parser')) {
  12      require_once ('pdf_parser.php');
  13  }
  14  
  15  /**

  16   * Class fpdi_pdf_parser

  17   */
  18  class fpdi_pdf_parser extends pdf_parser
  19  {
  20      /**

  21       * Pages

  22       *

  23       * Index begins at 0

  24       *

  25       * @var array

  26       */
  27      protected $_pages;
  28      
  29      /**

  30       * Page count

  31       *

  32       * @var integer

  33       */
  34      protected $_pageCount;
  35      
  36      /**

  37       * Current page number

  38       *

  39       * @var integer

  40       */
  41      public $pageNo;
  42      
  43      /**

  44       * PDF version of imported document

  45       *

  46       * @var string

  47       */
  48      public $_pdfVersion;
  49      
  50      /**

  51       * Available BoxTypes

  52       *

  53       * @var array

  54       */
  55      public $availableBoxes = array('/MediaBox', '/CropBox', '/BleedBox', '/TrimBox', '/ArtBox');
  56          
  57      /**

  58       * The constructor.

  59       *

  60       * @param string $filename The source filename

  61       */
  62      public function __construct($filename)
  63      {
  64          parent::__construct($filename);
  65  
  66          // resolve Pages-Dictonary

  67          $pages = $this->resolveObject($this->_root[1][1]['/Pages']);
  68  
  69          // Read pages

  70          $this->_readPages($pages, $this->_pages);
  71          
  72          // count pages;

  73          $this->_pageCount = count($this->_pages);
  74      }
  75      
  76      /**

  77       * Get page count from source file.

  78       *

  79       * @return int

  80       */
  81      public function getPageCount()
  82      {
  83          return $this->_pageCount;
  84      }
  85  
  86      /**

  87       * Set the page number.

  88       *

  89       * @param int $pageNo Page number to use

  90       * @throws InvalidArgumentException

  91       */
  92      public function setPageNo($pageNo)
  93      {
  94          $pageNo = ((int) $pageNo) - 1;
  95  
  96          if ($pageNo < 0 || $pageNo >= $this->getPageCount()) {
  97              throw new InvalidArgumentException('Invalid page number!');
  98          }
  99  
 100          $this->pageNo = $pageNo;
 101      }
 102      
 103      /**

 104       * Get page-resources from current page

 105       *

 106       * @return array|boolean

 107       */
 108      public function getPageResources()
 109      {
 110          return $this->_getPageResources($this->_pages[$this->pageNo]);
 111      }
 112      
 113      /**

 114       * Get page-resources from a /Page dictionary.

 115       *

 116       * @param array $obj Array of pdf-data

 117       * @return array|boolean

 118       */
 119      protected function _getPageResources($obj)
 120      {
 121          $obj = $this->resolveObject($obj);
 122  
 123          // If the current object has a resources

 124          // dictionary associated with it, we use

 125          // it. Otherwise, we move back to its

 126          // parent object.

 127          if (isset($obj[1][1]['/Resources'])) {
 128              $res = $this->resolveObject($obj[1][1]['/Resources']);
 129              if ($res[0] == pdf_parser::TYPE_OBJECT)
 130                  return $res[1];
 131              return $res;
 132          }
 133  
 134          if (!isset($obj[1][1]['/Parent'])) {
 135              return false;
 136          }
 137  
 138          $res = $this->_getPageResources($obj[1][1]['/Parent']);
 139          if ($res[0] == pdf_parser::TYPE_OBJECT)
 140              return $res[1];
 141          return $res;
 142      }
 143  
 144      /**

 145       * Get content of current page.

 146       *

 147       * If /Contents is an array, the streams are concatenated

 148       *

 149       * @return string

 150       */
 151      public function getContent()
 152      {
 153          $buffer = '';
 154          
 155          if (isset($this->_pages[$this->pageNo][1][1]['/Contents'])) {
 156              $contents = $this->_getPageContent($this->_pages[$this->pageNo][1][1]['/Contents']);
 157              foreach ($contents AS $tmpContent) {
 158                  $buffer .= $this->_unFilterStream($tmpContent) . ' ';
 159              }
 160          }
 161          
 162          return $buffer;
 163      }
 164  
 165      /**

 166       * Resolve all content objects.

 167       *

 168       * @param array $contentRef

 169       * @return array

 170       */
 171      protected function _getPageContent($contentRef)
 172      {
 173          $contents = array();
 174          
 175          if ($contentRef[0] == pdf_parser::TYPE_OBJREF) {
 176              $content = $this->resolveObject($contentRef);
 177              if ($content[1][0] == pdf_parser::TYPE_ARRAY) {
 178                  $contents = $this->_getPageContent($content[1]);
 179              } else {
 180                  $contents[] = $content;
 181              }
 182          } else if ($contentRef[0] == pdf_parser::TYPE_ARRAY) {
 183              foreach ($contentRef[1] AS $tmp_content_ref) {
 184                  $contents = array_merge($contents, $this->_getPageContent($tmp_content_ref));
 185              }
 186          }
 187  
 188          return $contents;
 189      }
 190  
 191      /**

 192       * Get a boundary box from a page

 193       *

 194       * Array format is same as used by FPDF_TPL.

 195       *

 196       * @param array $page a /Page dictionary

 197       * @param string $boxIndex Type of box {see {@link $availableBoxes})

 198       * @param float Scale factor from user space units to points

 199       *

 200       * @return array|boolean

 201       */
 202      protected function _getPageBox($page, $boxIndex, $k)
 203      {
 204          $page = $this->resolveObject($page);
 205          $box = null;
 206          if (isset($page[1][1][$boxIndex])) {
 207              $box = $page[1][1][$boxIndex];
 208          }
 209          
 210          if (!is_null($box) && $box[0] == pdf_parser::TYPE_OBJREF) {
 211              $tmp_box = $this->resolveObject($box);
 212              $box = $tmp_box[1];
 213          }
 214              
 215          if (!is_null($box) && $box[0] == pdf_parser::TYPE_ARRAY) {
 216              $b = $box[1];
 217              return array(
 218                  'x' => $b[0][1] / $k,
 219                  'y' => $b[1][1] / $k,
 220                  'w' => abs($b[0][1] - $b[2][1]) / $k,
 221                  'h' => abs($b[1][1] - $b[3][1]) / $k,
 222                  'llx' => min($b[0][1], $b[2][1]) / $k,
 223                  'lly' => min($b[1][1], $b[3][1]) / $k,
 224                  'urx' => max($b[0][1], $b[2][1]) / $k,
 225                  'ury' => max($b[1][1], $b[3][1]) / $k,
 226              );
 227          } else if (!isset($page[1][1]['/Parent'])) {
 228              return false;
 229          } else {
 230              return $this->_getPageBox($this->resolveObject($page[1][1]['/Parent']), $boxIndex, $k);
 231          }
 232      }
 233  
 234      /**

 235       * Get all page boundary boxes by page number

 236       * 

 237       * @param int $pageNo The page number

 238       * @param float $k Scale factor from user space units to points

 239       * @return array

 240       * @throws InvalidArgumentException

 241       */
 242      public function getPageBoxes($pageNo, $k)
 243      {
 244          if (!isset($this->_pages[$pageNo - 1])) {
 245              throw new InvalidArgumentException('Page ' . $pageNo . ' does not exists.');
 246          }
 247  
 248          return $this->_getPageBoxes($this->_pages[$pageNo - 1], $k);
 249      }
 250      
 251      /**

 252       * Get all boxes from /Page dictionary

 253       *

 254       * @param array $page A /Page dictionary

 255       * @param float $k Scale factor from user space units to points

 256       * @return array

 257       */
 258      protected function _getPageBoxes($page, $k)
 259      {
 260          $boxes = array();
 261  
 262          foreach($this->availableBoxes AS $box) {
 263              if ($_box = $this->_getPageBox($page, $box, $k)) {
 264                  $boxes[$box] = $_box;
 265              }
 266          }
 267  
 268          return $boxes;
 269      }
 270  
 271      /**

 272       * Get the page rotation by page number

 273       *

 274       * @param integer $pageNo

 275       * @throws InvalidArgumentException

 276       * @return array

 277       */
 278      public function getPageRotation($pageNo)
 279      {
 280          if (!isset($this->_pages[$pageNo - 1])) {
 281              throw new InvalidArgumentException('Page ' . $pageNo . ' does not exists.');
 282          }
 283  
 284          return $this->_getPageRotation($this->_pages[$pageNo - 1]);
 285      }
 286  
 287      /**

 288       * Get the rotation value of a page

 289       *

 290       * @param array $obj A /Page dictionary

 291       * @return array|bool

 292       */
 293      protected function _getPageRotation($obj)
 294      {
 295          $obj = $this->resolveObject($obj);
 296          if (isset($obj[1][1]['/Rotate'])) {
 297              $res = $this->resolveObject($obj[1][1]['/Rotate']);
 298              if ($res[0] == pdf_parser::TYPE_OBJECT)
 299                  return $res[1];
 300              return $res;
 301          }
 302  
 303          if (!isset($obj[1][1]['/Parent'])) {
 304              return false;
 305          }
 306  
 307          $res = $this->_getPageRotation($obj[1][1]['/Parent']);
 308          if ($res[0] == pdf_parser::TYPE_OBJECT)
 309              return $res[1];
 310  
 311          return $res;
 312      }
 313  
 314      /**

 315       * Read all pages

 316       *

 317       * @param array $pages /Pages dictionary

 318       * @param array $result The result array

 319       * @throws Exception

 320       */
 321      protected function _readPages(&$pages, &$result)
 322      {
 323          // Get the kids dictionary

 324          $_kids = $this->resolveObject($pages[1][1]['/Kids']);
 325  
 326          if (!is_array($_kids)) {
 327              throw new Exception('Cannot find /Kids in current /Page-Dictionary');
 328          }
 329  
 330          if ($_kids[0] === self::TYPE_OBJECT) {
 331              $_kids =  $_kids[1];
 332          }
 333  
 334          $kids = $_kids[1];
 335  
 336          foreach ($kids as $v) {
 337              $pg = $this->resolveObject($v);
 338              if ($pg[1][1]['/Type'][1] === '/Pages') {
 339                  // If one of the kids is an embedded

 340                  // /Pages array, resolve it as well.

 341                  $this->_readPages($pg, $result);
 342              } else {
 343                  $result[] = $pg;
 344              }
 345          }
 346      }
 347  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1