protected $date;\r
protected $localInfos;\r
protected $generalInfos;\r
+ protected $bookmarks;\r
+ protected $numberSections;\r
+ protected $links;\r
\r
protected $out;\r
protected $in;\r
$pdftk->execute();\r
$this->addToLog($pdftk);\r
\r
- $this->generalInfos = $this->parseInfos($pdfinfo->output . $pdftk->output);\r
+ $this->parseInfos($pdfinfo->output . $pdftk->output);\r
\r
file_put_contents($this->infos, $pdfinfo->output . $pdftk->output);\r
}\r
\r
public function parseInfos($data)\r
{\r
- $res = array();\r
+ // This function get general infos (pages sizes, boxes, number sections and\r
+ // bookmarks\r
+ // Init arrays\r
+ $this->generalInfos = array();\r
+ $this->bookmarks = array();\r
+ $this->numberSections = array();\r
+ // Number section styles\r
+ $numberStyles = array('NoNumber' => 'no', 'DecimalArabicNumerals' => 'decimal',\r
+ 'UppercaseRomanNumerals' => 'roman_up', 'LowercaseRomanNumerals' => 'roman_low',\r
+ 'UppercaseLetters' => 'letters_up', 'LowercaseLetters' => 'letters_low');\r
+\r
$res['size'] = array(0, 0);\r
$lines = explode("\n", $data);\r
foreach($lines as $line) {\r
$k = trim($e[0]);\r
$v = trim($e[1]);\r
if ($k == 'Pages' || $k == 'NumberOfPages') {\r
- $res['pages'] = $v;\r
+ $this->generalInfos['pages'] = $v;\r
} elseif (preg_match('|Page ([0-9]+) (.*)Box: ([0-9.]*) ([0-9.]*) ([0-9.]*) ([0-9.]*)|iu', $line, $m)) {\r
- $res['page'][$m[1]][strtolower($m[2])] = array($m[3], $m[4], $m[5], $m[6]);\r
+ $this->generalInfos['page'][$m[1]][strtolower($m[2])] = array($m[3], $m[4], $m[5], $m[6]);\r
} elseif (preg_match('|Page ([0-9]+) size: ([0-9.]*)([\sx]+)([0-9.]*)(.*)|iu', $line, $m)) {\r
- $res['page'][$m[1]]['size'] = array($m[2], $m[4]);\r
- $res['size'][0] = max($res['size'][0], $m[2]);\r
- $res['size'][1] = max($res['size'][1], $m[4]);\r
+ $this->generalInfos['page'][$m[1]]['size'] = array($m[2], $m[4]);\r
+ $this->generalInfos['size'][0] = max($this->generalInfos['size'][0], $m[2]);\r
+ $this->generalInfos['size'][1] = max($this->generalInfos['size'][1], $m[4]);\r
+ } elseif ($k == 'BookmarkTitle') {\r
+ $this->bookmarks[$bookmark_id] = array('titre' => str_replace(' ', '', trim($v)));\r
+ } elseif ($k == 'BookmarkLevel') {\r
+ $this->bookmarks[$bookmark_id]['level'] = $v;\r
+ } elseif ($k == 'BookmarkPageNumber') {\r
+ $this->bookmarks[$bookmark_id]['page'] = $v;\r
+ $bookmark_id++;\r
+ } elseif ($k == 'PageLabelNewIndex') {\r
+ $section = array('startAt' => $v, 'style' => 'decimal', 'firstNumber' => 1, 'prefix' => '');\r
+ } else if ($k == 'PageLabelStart') {\r
+ $section['firstNumber'] = $v;\r
+ } elseif ($k == 'PageLabelPrefix') {\r
+ $section['prefix'] = $v;\r
+ } else if ($k == 'PageLabelNumStyle') {\r
+ $section['style'] = $numberStyles[$v];\r
+ $this->numberSections[] = $section;\r
}\r
}\r
-\r
return $res;\r
}\r
\r
\r
public function makeMiniShot()\r
{\r
- $this->makeShotFixedWidth('p', 100);\r
+ $this->makeShotFixedWidth('p', 300, 70, 4, 'GS');\r
}\r
\r
public function makeRealShot()\r
$this->makeShot('te', 72);\r
}\r
\r
- public function makeShotFixedWidth($prefix, $w, $quality = 90, $antialiasing = 4)\r
+ public function makeShotFixedWidth($prefix, $w, $quality = 90, $antialiasing = 4, $method = 'GS')\r
{\r
// Make thumbs of $w width\r
// resolution 72 make 1pt=1px\r
$width = $this->generalInfos['size'][0];\r
$ratio = $width / $w;\r
- $this->makeShotGS($prefix, round(72 / $ratio), $quality, $antialiasing);\r
+ $this->makeShot($prefix, round(72 / $ratio, 2), $quality, $antialiasing, $method);\r
}\r
\r
- public function makeShotFixedHeight($prefix, $h, $quality = 90, $antialiasing = 4)\r
+ public function makeShotFixedHeight($prefix, $h, $quality = 90, $antialiasing = 4, $method = 'GS')\r
{\r
// Make thumbs of $w height\r
// resolution 72 make 1pt=1px\r
$height = $this->generalInfos['size'][1];\r
$ratio = $height / $h;\r
- $this->makeShotGS($prefix, round(72 / $ratio), $quality, $antialiasing);\r
+ $this->makeShot($prefix, round(72 / $ratio, 2), $quality, $antialiasing, $method);\r
}\r
\r
public function makeShot($prefix, $resolution = 72, $quality = 90, $antialiasing = 4, $method = 'GS')\r
$gs->setArg('-dJPEGQ=' . $quality);\r
$gs->setArg('-dTextAlphaBits=' . $antialiasing);\r
$gs->setArg('-dGraphicsAlphaBits=' . $antialiasing);\r
- $gs->setArg('-dUseCropBox');\r
+ // $gs->setArg('-dUseCropBox');\r
$gs->setArg('-sOutputFile=' . $this->out . '/' . $prefix . '%d.jpg');\r
$gs->setArg('-dAutoRotatePages=/None');\r
$gs->setArg(null, $this->in);\r
protected function makeShotPNM($prefix, $resolution = 72, $quality = 90, $antialiasing = 4)\r
{\r
$antialiasing = $antialiasing?'yes':'no';\r
+ $resolution = round($resolution);\r
// Exporte les fichiers\r
$pdftoppm = new cubeCommandLine('pdftoppm', null, true);\r
$pdftoppm->setArg('f', 1);\r
}\r
}\r
\r
- public function makeSWFFiles($resolution = 150, $quality = 90)\r
+ public function makeSWFFiles($resolution = 150, $quality = 90, $storeAllChars = true, $maxObjects = 1800, $method = 'flatten')\r
+ {\r
+ if ($maxObjects <= 1) {\r
+ $method = 'poly2bitmap';\r
+ }\r
+\r
+ $out = $this->pdf2swf($resolution, $quality, $storeAllChars, $method);\r
+ // Analyse de la sortie pour détecter des typos manquantes\r
+ $overflow = false;\r
+ $overflowObjects = false;\r
+ $written = false;\r
+ $missing_fonts = array();\r
+ $fp = fopen($out, 'rb');\r
+ while ($line = fgets($fp)) {\r
+ if (preg_match('|Try putting a TTF version of that font \(named \"([A-Z-_0-9.]*)\"\)|Uui', trim($line), $matches)) {\r
+ $missing_fonts[] = $matches[1];\r
+ } elseif (stristr($line, 'ID Table overflow')) {\r
+ $overflow = true;\r
+ } elseif (stristr($line, 'NOTICE SWF written')) {\r
+ $written = true;\r
+ } elseif (stristr($line, 'NOTICE Writing SWF file')) {\r
+ $written = true;\r
+ }\r
+ }\r
+ // On teste si le fichier est écrit et qu'il a été généré par le premier niveau\r
+ if ($method == 'flatten' && $written) {\r
+ $swfstrings = new cubeCommandLine($this->swftools . '/swfdump', null, true);\r
+ $swfstrings->setArg('t');\r
+ $swfstrings->setArg(null, $this->out . '/temp.swf');\r
+ $swfstrings->execute();\r
+\r
+ str_replace('[01a]', '', $swfstrings->output, $nbObjects);\r
+ if ($nbObjects > $maxObjects) {\r
+ $overflowObjects = true;\r
+ }\r
+ }\r
+ // On traite les erreurs\r
+ if (!$written && !$overflow) {\r
+ // Si le fichier n'a pas été généré et que il était en plus n'était pas en overflow,\r
+ // on tente directement la méthode de barbare\r
+ } elseif ($overflow || $overflowObjects) {\r
+ // Si le nombre d'objets max ou définis par l'utilisateur est trop important\r
+ // On écrase les graphismes.\r
+ $out = $this->pdf2swf($resolution, $quality, $storeAllChars, 'poly2bitmap');\r
+ }\r
+ }\r
+\r
+ protected function pdf2swf($resolution = 150, $quality = 90, $storeAllChars = true, $method = 'flatten')\r
+ {\r
+ /*\r
+-h , --help Print short help message and exit\r
+-V , --version Print version info and exit\r
+-o , --output file.swf Direct output to file.swf. If file.swf contains '%' (file%.swf), then each page goes to a seperate file.\r
+-p , --pages range Convert only pages in range with range e.g. 1-20 or 1,4,6,9-11 or\r
+-P , --password password Use password for deciphering the pdf.\r
+-v , --verbose Be verbose. Use more than one -v for greater effect.\r
+-z , --zlib Use Flash 6 (MX) zlib compression.\r
+-i , --ignore Allows pdf2swf to change the draw order of the pdf. This may make the generated\r
+-j , --jpegquality quality Set quality of embedded jpeg pictures to quality. 0 is worst (small), 100 is best (big). (default:85)\r
+-s , --set param=value Set a SWF encoder specific parameter. See pdf2swf -s help for more information.\r
+-w , --samewindow When converting pdf hyperlinks, don't make the links open a new window.\r
+-t , --stop Insert a stop() command in each page.\r
+-T , --flashversion num Set Flash Version in the SWF header to num.\r
+-F , --fontdir directory Add directory to the font search path.\r
+-b , --defaultviewer Link a standard viewer to the swf file.\r
+-l , --defaultloader Link a standard preloader to the swf file which will be displayed while the main swf is loading.\r
+-B , --viewer filename Link viewer filename to the swf file.\r
+-L , --preloader filename Link preloader filename to the swf file.\r
+-q , --quiet Suppress normal messages. Use -qq to suppress warnings, also.\r
+-S , --shapes Don't use SWF Fonts, but store everything as shape.\r
+-f , --fonts Store full fonts in SWF. (Don't reduce to used characters).\r
+-G , --flatten Remove as many clip layers from file as possible.\r
+-I , --info Don't do actual conversion, just display a list of all pages in the PDF.\r
+-Q , --maxtime n Abort conversion after n seconds. Only availableon Unix.\r
+\r
+PDF device global parameters:\r
+-----------------------------\r
+fontdir=<dir> a directory with additional fonts\r
+font=<filename> an additional font filename\r
+pages=<range> the range of pages to convert (example: pages=1-100,210-)\r
+zoom=<dpi> the resultion (default: 72)\r
+languagedir=<dir> Add an xpdf language directory\r
+multiply=<times> Render everything at <times> the resolution\r
+poly2bitmap Convert graphics to bitmaps\r
+bitmap Convert everything to bitmaps\r
+\r
+SWF Parameters :\r
+----------------\r
+SWF layer options :\r
+-------------------\r
+\r
+jpegsubpixels=<pixels> resolution adjustment for jpeg images (same as jpegdpi, but in pixels)\r
+ppmsubpixels=<pixels resolution adjustment for lossless images (same asppmdpi, but in pixels)\r
+subpixels=<pixels> shortcut for setting both jpegsubpixels and ppmsubpixels\r
+drawonlyshapes convert everything to shapes (currently broken)\r
+ignoredraworder allow to perform a few optimizations for creating smaller SWFs\r
+linksopennewwindow make links open a new browser window\r
+linktarget target window name of new links\r
+linkcolor=<color) color of links (format: RRGGBBAA)\r
+linknameurl Link buttons will be named like the URL they refer to (handy for iterating through links with actionscript)\r
+storeallcharacters don't reduce the fonts to used characters in the output file\r
+enablezlib switch on zlib compression (also done if flashversion>=7)\r
+bboxvars store the bounding box of the SWF file in actionscript variables\r
+dots Take care to handle dots correctly\r
+reordertags=0/1 (default: 1) perform some tag optimizations\r
+internallinkfunction=<name> when the user clicks a internal link (to a different page) in the converted file, this actionscript function is called\r
+externallinkfunction=<name> when the user clicks an external link (e.g. http://www.foo.bar/) on the converted file, this actionscript function is called\r
+disable_polygon_conversion never convert strokes to polygons (will remove capstyles and joint styles)\r
+caplinewidth=<width> the minimum thichness a line needs to have so that capstyles become visible (and are converted)\r
+insertstop put an ActionScript "STOP" tag in every frame\r
+protect add a "protect" tag to the file, to prevent loading in the Flash editor\r
+flashversion=<version> the SWF fileversion (6)\r
+framerate=<fps> SWF framerate\r
+minlinewidth=<width> convert horizontal/vertical boxes smaller than this width to lines (0.05)\r
+simpleviewer Add next/previous buttons to the SWF\r
+animate insert a showframe tag after each placeobject (animate draw order of PDF files)\r
+jpegquality=<quality> set compression quality of jpeg images\r
+splinequality=<value> Set the quality of spline convertion to value (0-100, default: 100).\r
+disablelinks Disable links.\r
+ */\r
+\r
+ $resolution2multiply = array(72 => 2, 100 => 2, 150 => 3, 200 => 3, 300 => 3, 450 => 4, 600 => 5);\r
+\r
+ $pdf2swf = new cubeCommandLine('pdf2swf', null, true);\r
+ if ($method == 'flatten') {\r
+ // Default\r
+ $pdf2swf->setArg('flatten');\r
+ $multiply = 1;\r
+ } elseif ($method == 'poly2bitmap') {\r
+ // Raster graphics, keep texts\r
+ $pdf2swf->setArg('poly2bitmap');\r
+ $multiply = $resolution2multiply[$resolution];\r
+ $pdf2swf->setArg('multiply', $multiply);\r
+ } elseif ($method == 'bitmap') {\r
+ // Raster all\r
+ $pdf2swf->setArg('bitmap');\r
+ $multiply = $resolution2multiply[$resolution];\r
+ $pdf2swf->setArg('multiply', $multiply);\r
+ }\r
+\r
+ $pdf2swf->setArg('stop');\r
+ $pdf2swf->setManualArg('-vvvv');\r
+ $pdf2swf->setArg('T', 9);\r
+ if ($storeAllChars) {\r
+ $pdf2swf->setArg('fonts');\r
+ }\r
+ if (DEV) {\r
+ $pdf2swf->setArg('F', 'C:/Windows/Fonts');\r
+ } else {\r
+ $pdf2swf->setArg('F', '/home/typo/fonts');\r
+ }\r
+ $pdf2swf->setArg('set subpixels', $resolution / 72);\r
+ $pdf2swf->setArg('set jpegquality', $quality);\r
+ $pdf2swf->setArg('set disablelinks');\r
+ $pdf2swf->setArg('set dots');\r
+\r
+ $pdf2swf->setArg(null, $this->in);\r
+ $pdf2swf->setArg('output', $this->out . 'p%.swf');\r
+ $pdf2swf->execute();\r
+\r
+ $this->addToLog($pdf2swf, true);\r
+\r
+ return $pdf2swf->outputfile;\r
+ }\r
+\r
+ protected function pdf2swfBarbare($resolution, $quality, $page = 'all')\r
{\r
+ // Fabrique les images\r
+ $this->makeShot('barbare', $resolution, $quality, 'PNM');\r
+ // A partir des images, on crée les swf\r
+ $jpeg2swf = new cubeCommandLine('jpeg2swf');\r
+ $jpeg2swf->setArg('q', $quality);\r
+ $jpeg2swf->setArg('o', $this->out . 'p' . $i . '.swf');\r
+ $jpeg2swf->setArg('f');\r
+ $jpeg2swf->setArg('T', 9);\r
+ $jpeg2swf->setArg(null, $this->out . 'barbare' . $i . '.jpg');\r
+ $jpeg2swf->execute();\r
+ $this->addToLog($jpeg2swf);\r
+ // Suppression du jpeg\r
+ @unlink($this->out . '/barbare' . $page . '.jpg') ;\r
}\r
\r
public function addToLog($cl, $output = true)\r
{\r
- $c = '---' . "\n" . $cl->commande . "\n\n";\r
+ $c = '--- Exécuté en ' . $cl->execTime . " s\n" . $cl->commande . "\n\n";\r
if ($output) {\r
- $cl->output . "\n\n";\r
+ $c .= $cl->output . "\n\n";\r
}\r
fwrite($this->log_pointer, $c);\r
}\r