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