class wsDocument extends cubeMetier
{
- protected $document_id;
- protected $file;
- protected $proprietaire;
- protected $pages;
- protected $trim;
- protected $date;
- protected $localInfos;
- protected $generalInfos;
- protected $conversionInfos;
- protected $bookmarks;
- protected $numberSections;
- protected $localHash;
- protected $version;
- // Crop & cut
- protected $autocrop;
- protected $manualcrop;
- protected $autocut;
- protected $manualcut;
- // Files
- protected $out;
- protected $in;
- protected $html;
- protected $uncompressed;
- protected $log;
- protected $common_log_pointer;
- protected $pages_log_pointers;
- protected $infos;
- protected $cropped;
- protected $rgb;
-
- protected static $_docsDir;
-
- const NORMAL = 0;
- const FLATTEN = 1;
- const POLY2BITMAP = 2;
- const BITMAP = 3;
- const BARBARE_PNM = 4;
- const BARBARE_GS = 5;
- const MAX = 5;
- const PNM_FILL = 2;
-
- protected static $resolution2multiply = array(72 => 2, 100 => 2, 150 => 3, 200 => 3, 300 => 3, 450 => 4, 600 => 5);
- // Number section styles
- protected static
- $numberStyles = array('NoNumber' => 'no', 'DecimalArabicNumerals' => 'decimal',
- 'UppercaseRomanNumerals' => 'roman_up', 'LowercaseRomanNumerals' => 'roman_low',
- 'UppercaseLetters' => 'letters_up', 'LowercaseLetters' => 'letters_low');
-
- public function init()
- {
- $this->out = wsDocument::getDir($this->document_id);
- $this->log = $this->out . '/logs/';
- $this->html = $this->out . '/html/';
- $this->in = $this->out . 'original.pdf';
- $this->uncompressed = $this->out . 'uncompressed.pdf';
- $this->infos = $this->out . 'infos.txt';
- if (!file_exists($this->out)) {
- mkdir($this->out, 0755, true);
- mkdir($this->log, 0755);
- }
- if (!file_exists($this->html)) {
- mkdir($this->html, 0755);
- }
- $this->cropped = $this->out . 'crop.pdf';
- $this->pages_log_pointers = array();
-
- if (is_null($this->conversionInfos)) {
- $this->conversionInfos = new wsDocumentConversionInfos();
- }
- }
-
- public function getCroppedPDF(){
- if(!file_exists($this->cropped)){
- return $this->in;
- }
- return $this->cropped;
- }
-
- public function copyOriginalFromUpload($tmp_file)
- {
- move_uploaded_file($tmp_file, $this->in);
- }
-
- public function copyOriginalFromOlderVersion()
- {
- if (!file_exists($this->in)) {
- copy('https://ws.fluidbook.com/docs/' . $this->document_id . '/original.pdf', $this->in);
- }
- }
-
- public function extractFonts()
- {
- $extractor = new wsPDFFontExtractor($this->out, $this);
- $extractor->extract();
- }
-
- public function getInfos($in = null, $force = false)
- {
- if (is_null($in)) {
- $in = $this->in;
- }
-
- $fwstk = new cubeCommandLine('fwstk.sh');
- $fwstk->setPath(CONVERTER_PATH);
- $fwstk->setArg('--input ' . $in);
- $fwstk->setArg('--infos');
- $fwstk->execute();
- $this->addToLog($fwstk);
- $out = $fwstk->output;
-
- $pdfinfo = new cubeCommandLine('pdfinfo');
- $pdfinfo->setPath(CONVERTER_PATH);
- $pdfinfo->setArg('-box');
- $pdfinfo->setArg('f', 1);
- $pdfinfo->setArg('l', 100000);
- $pdfinfo->setArg(null, $in);
- $pdfinfo->execute();
- $this->addToLog($pdfinfo);
- $out .= "\n";
- $out .= $pdfinfo->output;
-
- $this->addToLog('Parse infos');
- $this->parseInfos($out);
-
- $this->addToLog('Set Page Infos');
- $this->conversionInfos->setPageNumber($this->generalInfos['pages']);
-
- $this->addToLog('Write infos');
- file_put_contents($this->infos, $out);
-
- $this->addToLog('Find cut disposition');
-
- $this->findCutDisposition();
- }
-
- public function findCutDisposition()
- {
- $this->detectSpreads();
- $this->detectPageDifferences();
- }
-
- protected function detectPageDifferences()
- {
- $this->addToLog('Detect page differences');
- // Vérifie si la cropbox et la trimbox sont identiques pour toutes les pages
- $difference = false;
- foreach ($this->generalInfos['page'] as $page => $infos) {
- if (!isset($infos['crop']) || !isset($infos['crop'])) {
- continue;
- }
- if ($infos['crop'] != $infos['trim']) {
- $difference = true;
- }
- }
- if (!$difference) {
- return false;
- }
- // Vérifie si la trimbox définie toutes les pages de la même taille
- $heights = array();
- $widths = array();
- foreach ($this->generalInfos['page'] as $page => $infos) {
- $heights[] = round($infos['trim']->height);
- $widths[] = round($infos['trim']->width);
- }
- $heights = array_unique($heights);
- $widths = array_unique($widths);
- if (count($heights) == 1 && count($widths) == 1) {
- $this->autocrop = 'trim';
- $this->manualcrop = false;
- } else {
- $this->autocrop = false;
- $this->manualcrop = true;
- }
- }
-
- protected function detectSpreads()
- {
- $this->addToLog('Detect spreads');
- // Détection des spreads
-
- $this->autocut = false;
- $this->manualcut = false;
- if ($this->generalInfos['pages'] <= 2) {
- return;
- }
-
- foreach ($this->generalInfos['page'] as $page => $infos) {
- if ($page == 1) {
- $first = $infos['size'];
- } elseif ($page == $this->generalInfos['pages']) {
- $last = $infos['size'];
- } elseif ($page == 2) {
- $second = $infos['size'];
- }
- }
-
- if ($first == $last && $last == $second) {
- $ratio = $first[0] / $first[1];
- $this->autocut = false;
- if ($ratio <= 1) {
- $this->manualcut = false;
- } elseif ($ratio >= 6) {
- $this->manualcut = 'L8';
- } elseif ($ratio >= 3) {
- $this->manualcut = 'L4';
- } elseif ($ratio >= 2) {
- $this->manualcut = 'L3';
- } else {
- $this->manualcut = '14-23';
- }
- return;
- }
- $this->manualcut = false;
- if (self::compareSizes($last, $first) && cubeMath::compare($first[0] * 2, $second[0], 0.9)) {
- $this->autocut = '1-23-4';
- }
- if (cubeMath::compare($first[0] * 2, $second[0], 0.9) && self::compareSizes($last, $second)) {
- $this->autocut = '1-23';
- }
-
- $this->addToLog('Detect Spreads : Manual cut ' . $this->manualcut . ' ; Auto cut : ' . $this->autocut);
- }
-
- public static function compareSizes($x, $y, $tolerance = 0.9)
- {
- return cubeMath::compare($x[0], $y[0], $tolerance) && cubeMath::compare($x[1], $y[1], $tolerance);
- }
-
- public function lnCrop()
- {
- $root = dirname($this->cropped);
- `cd $root;ln -s original.pdf crop.pdf`;
- }
-
- public function parseInfos($data)
- {
- cubePHP::set_memory('4G');
- // This function get general infos (pages sizes, boxes, number sections and
- // bookmarks
- // Init arrays
- $this->generalInfos = array();
- $this->generalInfos['size'] = array(0, 0);
- $this->bookmarks = array();
- $this->numberSections = '';
- $bookmark_id = 0;
-
- $res['size'] = array(0, 0);
- $lines = explode("\n", $data);
- foreach ($lines as $line) {
- $line = trim(cubeText::condenseWhite($line));
- $e = explode(':', $line, 2);
- $k = trim($e[0]);
- if (count($e) < 2) {
- continue;
- }
- $v = trim($e[1]);
- if ($k == 'Pages' || $k == 'NumberOfPages') {
- $this->pages = $this->generalInfos['pages'] = $v;
- $this->generalInfos['page'] = array();
- for ($i = 1; $i <= $this->pages; $i++) {
- $this->generalInfos['page'][$i] = array();
- }
- } elseif (preg_match('|Page\s+([0-9]+)\s+(.*)Box:\s+([0-9.]*)\s+([0-9.]*)\s+([0-9.]*)\s+([0-9.]*)|iu', $line, $m)) {
- $this->generalInfos['page'][$m[1]][strtolower($m[2])] = new wsBox($m[3], $m[4], $m[5], $m[6]);
- } elseif (preg_match('|Page\s+([0-9]+)\s+size:\s+([0-9.]*)[pts[:space:]]+x\s+([0-9.]*)\s+pts|iu', $line, $m)) {
- $this->generalInfos['page'][$m[1]]['size'] = array($m[2], $m[3]);
- if ($m[1] == 1) {
- $this->generalInfos['size'][0] = $m[2];
- $this->generalInfos['size'][1] = $m[3];
- }
- } 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 == 'NumberSections') {
- $this->numberSections = $v;
- }
- }
- return $res;
- }
-
- public function getPagesNumber()
- {
- $this->getInfos();
- return $this->generalInfos['pages'];
- }
-
- public function globalOperations()
- {
- $this->addToLog('Get infos');
- $this->getInfos();
- if ($this->CropAndCut()) {
- $this->addToLog('Get infos after crop');
- $this->getInfos($this->cropped, true);
- }
- $this->addToLog('Get links');
- $this->getLinks();
- $this->addToLog('End of global ops');
- $this->splitDoc();
- }
-
- public function splitDoc()
- {
- $this->addToLog('Split document');
- mkdir($this->out . '/pdf');
- $pdftk = new cubeCommandLine('pdftk');
- $pdftk->setPath(CONVERTER_PATH);
- $pdftk->setArg(null, $this->getCroppedPDF());
- $pdftk->setArg(null, 'burst');
- $pdftk->setArg(null, 'output');
- $pdftk->setArg(null, $this->out . 'pdf/p%d.pdf');
- $pdftk->execute();
- $this->addToLog($pdftk);
- }
-
- public function CropAndCut()
- {
- $this->addToLog('Crop And Cut');
- if (!$this->isCropped()) {
- $this->lnCrop();
- return false;
- }
- if ($this->autocrop == 'trim') {
- $this->trimDocument();
- } else {
- $this->lnCrop();
- }
-
- if ($this->autocut) {
- $this->cutDocument($this->autocut);
- return true;
- }
- return false;
- }
-
- public function cutDocument($mode)
- {
- $fwstk = new cubeCommandLine('fwstk.sh');
- $fwstk->setPath(CONVERTER_PATH);
- $fwstk->setArg('--input ' . $this->in);
- $fwstk->setArg('--cut ' . $mode);
- $fwstk->setArg('--output ' . $this->cropped);
- $fwstk->execute();
- $this->addToLog($fwstk);
- }
-
- public function trimDocument()
- {
- $fwstk = new cubeCommandLine('fwstk.sh');
- $fwstk->setPath(CONVERTER_PATH);
- $fwstk->setArg('--input ' . $this->in);
- $fwstk->setArg('--trim');
- $fwstk->setArg('--output ' . $this->cropped);
- $fwstk->execute();
- $this->addToLog($fwstk);
- }
-
- public function processOnePage($page, $force = true)
- {
- if ($force) {
- $this->addToLog('Processing page #' . $page);
- $this->makeMiniShot($page);
- $this->makeSWFFiles($page);
- $this->makeHTML5Files($page);
- }
- }
-
- public function processAllPages()
- {
- for ($i = 1; $i <= $this->generalInfos['pages']; $i++) {
- $this->processOnePage($i);
- }
- }
-
- public function processRange($pages)
- {
- foreach ($pages as $i) {
- $this->processOnePage($i);
- }
- }
-
- public function getLinks()
- {
- $fwstk = new cubeCommandLine('fwstk.sh');
- $fwstk->setPath(CONVERTER_PATH);
- $fwstk->setArg('--input ' . $this->getCroppedPDF());
- $fwstk->setArg('--extractLinks ' . $this->out . 'p%d.csv');
- $fwstk->setArg('--threads 1');
- $fwstk->execute();
- $this->addToLog($fwstk);
- }
-
- public function getHighlightTextsData()
- {
- $fwstk = new cubeCommandLine('fwstk.sh');
- $fwstk->setPath(CONVERTER_PATH);
- $fwstk->setArg('--input ' . $this->getCroppedPDF());
- $fwstk->setArg('--layout ' . $this->html . 'p%d.fby');
- $fwstk->setArg('--cmaps ' . $this->html);
- $fwstk->setArg('--fonts' . $this->out . 'fonts/web/');
- $fwstk->execute();
- $this->addToLog($fwstk);
- }
-
- public function getResolutionRatio()
- {
- $a4surface = 500990; // en pt²
- $docSurface = $this->generalInfos['size'][0] * $this->generalInfos['size'][1]; // en pt²
- // to have the same surface resulting in px, we have to sqrt the ratio between the two surfaces defined above
- return sqrt($a4surface / $docSurface);
- }
-
- public function makeMiniShot($page)
- {
- $this->makeShotFixedWidth($page, 'p', 500, 65, 4, 'PNM');
- }
-
- public function makeShotFixedWidth($page, $prefix = '', $w = 100, $quality = 90, $antialiasing = 4, $method = 'PNM')
- {
- // Make thumbs of $w width
- // resolution 72 make 1pt=1px
- $width = $this->generalInfos['size'][0];
- $ratio = $width / $w;
- $this->makeShot($page, $prefix, round(72 / $ratio, 2), $quality, $antialiasing, $method);
- }
-
- public function makeShotFixedHeight($page, $prefix = '', $h = '', $quality = 90, $antialiasing = 4, $method = 'PNM')
- {
- // Make thumbs of $w height
- // resolution 72 make 1pt=1px
- $height = $this->generalInfos['size'][1];
- $ratio = $height / $h;
- $this->makeShot($page, $prefix, round(72 / $ratio, 2), $quality, $antialiasing, $method);
- }
-
- public function makeShot($page, $prefix = '', $resolution = 72, $quality = 90, $antialiasing = 4, $method = 'PNM', $in = null)
- {
- $error = false;
- if (is_null($in)) {
- $in = $this->getCroppedPDF();
- }
- // Delete all old files
- $res = $this->out . $prefix . $page . '.jpg';
- if (file_exists($res)) {
- @unlink($res);
- }
-
- if ($method == 'GS') {
- $this->makeShotGS($page, $prefix, $resolution, $quality, $antialiasing, $in);
- } elseif ($method == 'PNM') {
- $this->makeShotPNM($page, $prefix, $resolution, $quality, $antialiasing, $in);
- }
- // Test the result by checking all files
- if (!file_exists($res)) {
- $error = true;
- }
- // If error, we try to make thumbs with other method
- if ($error) {
- if ($method == 'GS') {
- $this->makeShotPNM($page, $prefix, $resolution, $quality, $antialiasing, $in);
- } elseif ($method == 'PNM') {
- $this->makeShotGS($page, $prefix, $resolution, $quality, $antialiasing, $in);
- }
- }
- }
-
- protected function makeShotGS($page, $prefix = '', $resolution = 72, $quality = 90, $antialiasing = 4, $in = null)
- {
- if (is_null($in)) {
- $in = $this->getCroppedPDF();
- }
- // Fabrication des thumbanails avec ghostscript
- $gs = new cubeCommandLine('gs', null, true);
- $gs->setPath(CONVERTER_PATH);
- $gs->setEnv('GS_FONTPATH', FONT_PATH);
- $gs->setArg('-dBATCH');
- $gs->setArg('-dNOPAUSE');
- $gs->setArg('-dNOPROMPT');
- // Antialias
- $gs->setArg('-dDOINTERPOLATE');
- $gs->setArg('-dTextAlphaBits=' . $antialiasing);
- $gs->setArg('-dGraphicsAlphaBits=' . $antialiasing);
- // Device
- $gs->setArg('-sDEVICE=jpeg');
- // Dispotion & colors
- // $gs->setArg('-dUseCIEColor');
- $gs->setArg('-dAutoRotatePages=/None');
- $gs->setArg('-dUseCropBox');
- // Resolution & Quality
- $gs->setArg('-r' . round($resolution));
- $gs->setArg('-dJPEGQ=' . $quality);
- // Performances
- $gs->setArg('-dNumRenderingThreads=4');
- // Page range
- $gs->setArg('-dFirstPage=' . $page);
- $gs->setArg('-dLastPage=' . $page);
- // Files
- $gs->setArg('-sOutputFile=' . $this->out . '/' . $prefix . $page . '.jpg');
-
- $gs->setArg(null, $in);
- $gs->execute();
- $this->addToLog($gs, true, $page);
- }
-
- protected function makeShotPNM($page, $prefix = '', $resolution = 72, $quality = 90, $antialiasing = 4, $in = null, $texts = true)
- {
- if (is_null($in)) {
- $in = $this->getCroppedPDF();
- }
-
- $tmp = cubeFiles::tempnam();
-
- $antialiasing = $antialiasing ? 'yes' : 'no';
- $freetype = $texts ? 'yes' : 'no';
- // Exporte les fichiers
- $pdftoppm = new cubeCommandLine('pdftoppm', null, true);
- $pdftoppm->setPath(CONVERTER_PATH);
-
- $pdftoppm->setArg('f', $page);
- $pdftoppm->setArg('l', $page);
- $pdftoppm->setArg('-cropbox');
- $pdftoppm->setArg('-freetype ' . $freetype);
- $pdftoppm->setArg('-singlefile');
- $pdftoppm->setArg('-aa ' . $antialiasing);
- $pdftoppm->setArg('-aaVector ' . $antialiasing);
- $pdftoppm->setArg('r', $resolution);
- $pdftoppm->setArg(null, $in);
- $pdftoppm->setArg(null, $tmp);
- $pdftoppm->execute();
- $this->addToLog($pdftoppm, true, $page);
-
- $tmp .= '.ppm';
-
- $jpegfile = $this->out . $prefix . $page . '.jpg';
-
- if (file_exists($tmp)) {
- // $pnmtojpeg = new cubeCommandLine('pnmtojpeg', $jpegfile, false);
- // $pnmtojpeg->setArg('-quality ' . $quality);
- // $pnmtojpeg->setArg(null, $tmp);
- // $pnmtojpeg->execute();
- // $this->addToLog($pnmtojpeg, false, $page);
-
-
- $cjpeg = new cubeCommandLine('cjpeg', null, true);
- $cjpeg->setArg('-quality ' . ($quality + 6));
- $cjpeg->setArg('-outfile ' . $jpegfile);
- $cjpeg->setArg(null, $tmp);
- $cjpeg->execute();
- $this->addToLog($cjpeg, false, $page);
-
- unlink($tmp);
- }
- }
-
- protected function isCropped()
- {
- return $this->autocrop || $this->manualcrop || $this->autocut || $this->manualcut;
- }
-
- public function makeSWFFiles($page, $resolution = null, $quality = null, $storeAllChars = null, $maxObjects = null, $method = null, $version = null)
- {
- $conversionSettings = $this->conversionInfos->pages[$page];
- if (is_null($storeAllChars)) {
- $storeAllChars = true;
- }
- if (is_null($resolution)) {
- $resolution = $conversionSettings->resolution;
- }
- if (is_null($method)) {
- $method = $conversionSettings->method;
- }
- if (is_null($quality)) {
- $quality = $conversionSettings->quality;
- }
- if (is_null($maxObjects)) {
- $maxObjects = $conversionSettings->objects;
- }
- if (is_null($version)) {
- $version = isset($conversionSettings->version) ? $conversionSettings->version : 'stable';
- }
-
- if ($maxObjects <= 1) {
- $method = self::POLY2BITMAP;
- }
-
- // Pour les fichiers croppés, on utilise la méthode flatten qui ne prends
- // pas en compte les objets hors de la box
- if ($this->isCropped()) {
- // $method = max($method, self::FLATTEN);
- }
-
- $out = $this->pdf2swf($page, $resolution * $this->getResolutionRatio(), $quality, $storeAllChars, $method, 'p', $version);
- if ($method < self::BARBARE_PNM) {
- // Analyse de la sortie pour détecter des typos manquantes
- $overflow = false;
- $overflowObjects = false;
- $written = false;
- $missing_fonts = array();
- if (file_exists($out)) {
- $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;
- }
- }
- }
- if (!is_null($page) && file_exists($this->out . 'p' . $page . '.swf')) {
- $written = true;
- }
- // On teste si le fichier est écrit et qu'il a été généré par le premier niveau
- if ($method < self::POLY2BITMAP && $written) {
- $overflowObjects = $this->checkObjectsNumber($this->out . 'p' . $page . '.swf', $maxObjects, $page);
- }
-
- if (!$written || $overflow || $overflowObjects) {
- if ($method == self::MAX) {
- return;
- }
- $nextMethod = $method + 1;
- return $this->makeSWFFiles($page, $resolution, $quality, $storeAllChars, $maxObjects, $nextMethod, $version);
- }
- }
- }
-
- public function makeHTML5Files($page)
- {
- // Then make HD background shots
- $resolutions = array(300 => 85, 150 => 85, 36 => 85);
- $rratio = $this->getResolutionRatio();
- foreach ($resolutions as $r => $q) {
- $this->makeShotPNM($page, 'html/h' . $r . '-', $r * $rratio, $q, 4, null, false);
- $this->makeShotPNM($page, 'html/t' . $r . '-', $r * $rratio, $q, 4, null, true);
- }
- $this->makeSVGFile($page);
- }
-
- public function makeSVGFile($page)
- {
- $svgFile = $this->out . '/html/fp' . $page . '.svg';
- $source = $this->getCroppedPDF();
-
- $pdftocairo = new cubeCommandLine('pdftocairo');
- $pdftocairo->setPath(CONVERTER_PATH);
- $pdftocairo->setArg('f', $page);
- $pdftocairo->setArg('l', $page);
- $pdftocairo->setArg('r', 300);
- $pdftocairo->setArg(null, '-expand');
- $pdftocairo->setArg(null, '-svg');
- $pdftocairo->setArg(null, $source);
- $pdftocairo->setArg(null, $svgFile);
- $pdftocairo->execute();
-
- $this->addToLog($pdftocairo, true, $page);
- }
-
- public static function extractTexts($svgFile, $textFile, $force = false)
- {
- $do = $force || !file_exists($textFile) || filesize($textFile) < 100 || filemtime($svgFile) > filemtime($textFile) || filemtime($textFile) < filemtime(__FILE__);
- if (!$do) {
- return;
- }
-
- $svg = new DOMDocument();
- $svg->preserveWhiteSpace = false;
- $svg->load($svgFile, LIBXML_PARSEHUGE);
-
- // Operations to delete
- $xpath = new DOMXPath($svg);
- $xpath->registerNamespace('svg', 'http://www.w3.org/2000/svg');
- $xpath->registerNamespace('xlink', 'http://www.w3.org/1999/xlink');
- $xpath->registerNamespace("php", "http://php.net/xpath");
- $xpath->registerPhpFunctions('has_not_text');
- $toDelete = array('//svg:defs/svg:clipPath',
- '//svg:defs/svg:image',
- '//svg:defs/svg:path',
- '//svg:defs/svg:pattern',
- '//svg:defs/svg:g[starts-with(@id, "surface")]//svg:path',
- '/svg:svg/svg:g//svg:path',
- '/svg:svg/svg:g//svg:rect',
- '//svg:use[starts-with(@xlink:href, "#image")]'
- );
-
- //global $svglog;
- //$svglog = array('XPATH : ' . print_r($xpath, true));
- foreach ($toDelete as $q) {
- $list = $xpath->query($q);
- // $svglog[] = "Evaluate xpath query " . $q;
- // $svglog[] = 'Give ' . $list->length . ' results';
- // $svglog[] = 'Deleting Nodes in ' . print_r($list, true);
- if (count($list)) {
- foreach ($list as $node) {
- /* @var $node DOMNode */
- $parent = $node->parentNode;
- $parent->removeChild($node);
- }
- }
- }
- file_put_contents($textFile, $svg->saveXML());
- }
-
- protected function checkObjectsNumber($file, $maxObjects, $page)
- {
- $swfdump = new cubeCommandLine('swfdump', null, true);
- $swfdump->setPath(CONVERTER_PATH);
- $swfdump->setArg(null, $file);
- $swfdump->execute();
- $this->addToLog($swfdump, true, $page);
-
- str_replace('[01a]', '', $swfdump->output, $nbObjects);
- if ($nbObjects > $maxObjects) {
- return true;
- }
- return false;
- }
-
- protected function dumpSWF($page, $prefix = 'p')
- {
- $swfdump = new cubeCommandLine('/usr/local/swftools/special-swfdump/bin/swfdump', null, true);
- $swfdump->setPath(CONVERTER_PATH);
- $swfdump->setArg('t');
- $swfdump->setArg('p');
- $swfdump->setArg('F');
- $swfdump->setArg(null, $this->out . $prefix . $page . '.swf');
- $swfdump->execute();
- $this->addToLog($swfdump, false, $page);
- return $swfdump->output;
- }
-
- /**
- * wsDocument::pdf2swf()
- *
- * @param mixed $page
- * @param integer $resolution
- * @param integer $quality
- * @param mixed $storeAllChars
- * @param integer $method
- * @return
- */
- protected function pdf2swf($page, $resolution = 150, $quality = 90, $storeAllChars = true, $method = 0, $prefix = 'p', $version = 'stable')
- {
- /*
- -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=<dir> a directory with additional fonts
- font=<filename> an additional font filename
- pages=<range> the range of pages to convert (example: pages=1-100,210-)
- zoom=<dpi> the resultion (default: 72)
- languagedir=<dir> Add an xpdf language directory
- multiply=<times> Render everything at <times> the resolution
- poly2bitmap Convert graphics to bitmaps
- bitmap Convert everything to bitmaps
-
- SWF Parameters :
- ----------------
- SWF layer options :
- -------------------
-
- jpegsubpixels=<pixels> resolution adjustment for jpeg images (same as jpegdpi, but in pixels)
- ppmsubpixels=<pixels resolution adjustment for lossless images (same asppmdpi, but in pixels)
- subpixels=<pixels> 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=<color) color of links (format: RRGGBBAA)
- linknameurl Link buttons will be named like the URL they refer to (handy for iterating through links with actionscript)
- storeallcharacters don't reduce the fonts to used characters in the output file
- enablezlib switch on zlib compression (also done if flashversion>=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=<name> when the user clicks a internal link (to a different page) in the converted file, this actionscript function is called
- externallinkfunction=<name> 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=<width> 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=<version> the SWF fileversion (6)
- framerate=<fps> SWF framerate
- minlinewidth=<width> 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=<quality> set compression quality of jpeg images
- splinequality=<value> Set the quality of spline convertion to value (0-100, default: 100).
- disablelinks Disable links.
- */
-
- if (file_exists($this->out . $prefix . $page . '.swf')) {
- unlink($this->out . $prefix . $page . '.swf');
- }
-
- if (!in_array($method, array(self::BARBARE_PNM, self::BARBARE_GS))) {
- if (in_array($version, array('legacy', 'stable', 'latest', 'git'))) {
- $program = '/usr/local/swftools/' . $version . '/bin/pdf2swf';
- } else {
- $program = 'pdf2swf';
- }
-
- $pdf2swf = new cubeCommandLine($program, null, true);
- $pdf2swf->setPath(CONVERTER_PATH);
-
- $pdf2swf->setArg('p', 1);
- $flashversion = 10;
-
- if ($method == self::NORMAL) {
- // Default
- $multiply = 1;
- } elseif ($method == self::FLATTEN) {
- $multiply = 1;
- $pdf2swf->setArg('flatten');
- } elseif ($method == self::POLY2BITMAP) {
- // Raster graphics, keep texts
- $pdf2swf->setArg('set poly2bitmap');
- $pdf2swf->setArg('set multiply', $this->_findMultiply($resolution));
- } elseif ($method == self::BITMAP) {
- // Raster all
- $pdf2swf->setArg('set bitmap');
- $pdf2swf->setArg('set multiply', $this->_findMultiply($resolution));
- }
- // $pdf2swf->setManualArg('-v');
- $pdf2swf->setArg('T', $flashversion);
- $pdf2swf->setArg('set reordertags', '0');
- if ($storeAllChars) {
- $pdf2swf->setArg('fonts');
- $pdf2swf->setArg('set storeallcharacters');
- }
- 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');
- if ($version == 'git') {
- $pdf2swf->setArg(null, '-T7');
- $pdf2swf->setArg('set alignfonts');
- }
- $pdf2swf->setArg(null, $this->out . 'pdf/p' . $page . '.pdf');
- $pdf2swf->setArg('output', $this->out . $prefix . $page . '.swf');
- $pdf2swf->execute();
-
- if ($version == 'git') {
- $f = $this->out . $prefix . $page . '.swf';
- $combine = new cubeCommandLine('swfcombine');
- $combine->setArg('d');
- $combine->setArg(null, '-F9');
- $combine->setArg(null, $f);
- $combine->setArg('o', $f);
- $combine->execute();
- }
-
- $this->addToLog($pdf2swf, true, $page);
- } else {
- $this->pdf2swfBarbare($page, $resolution, $quality, $method);
- }
- }
-
- protected function _findMultiply($resolution)
- {
- $resolution /= $this->getResolutionRatio();
- return self::$resolution2multiply[$resolution];
- }
-
- protected function makeAS3($page)
- {
- $swffile = $this->out . 'p' . $page . '.swf';
-
- $swfcombine = new cubeCommandLine('swfcombine');
- $swfcombine->setPath(CONVERTER_PATH);
- $swfcombine->setArg('merge');
- $swfcombine->setArg('stack1');
- $swfcombine->setArg('z');
- $swfcombine->setManualArg('-v');
- $swfcombine->setArg('o', $swffile);
- $swfcombine->setArg(null, ROOT . '/swf/as3Container.swf');
- $swfcombine->setManualArg('content=' . $swffile);
- $swfcombine->execute();
- $this->addToLog($swfcombine, true, $page);
- }
-
- protected function pdf2swfBarbare($page, $resolution = 150, $quality = 85, $method = 4)
- {
- // Fabrique les images
-
- $this->addToLog('Making barbare swf', true, $page);
-
- if ($method == self::BARBARE_PNM) {
- $this->makeShot($page, 'barbare', $resolution, $quality, 4, 'PNM');
- } elseif ($method == self::BARBARE_GS) {
- $this->makeShot($page, 'barbare', $resolution, $quality, 4, 'GS');
- }
-
- $dim = getimagesize($this->out . 'barbare' . $page . '.jpg');
-
- // A partir des images, on crée les swf
- $jpeg2swf = new cubeCommandLine('jpeg2swf');
- $jpeg2swf->setPath(CONVERTER_PATH);
- $jpeg2swf->setArg('--quality', $quality);
- $jpeg2swf->setArg('--output', $this->out . 'p' . $page . '.swf');
- $jpeg2swf->setArg('--flashversion', 10);
- $jpeg2swf->setArg('--width', $dim[0] * (72 / $resolution));
- $jpeg2swf->setArg('--height', $dim[1] * (72 / $resolution));
- $jpeg2swf->setArg('--fit-to-movie');
- $jpeg2swf->setArg(null, $this->out . 'barbare' . $page . '.jpg');
- $jpeg2swf->execute();
- $this->addToLog($jpeg2swf, true, $page);
- // Suppression du jpeg
- @unlink($this->out . '/barbare' . $page . '.jpg', true, $page);
-
- $pdf2swf = new cubeCommandLine('pdf2swf', null, true);
- $pdf2swf->setPath(CONVERTER_PATH);
- $pdf2swf->setArg('set poly2bitmap');
- $pdf2swf->setArg('p', 1);
- $pdf2swf->setArg('stop');
- $pdf2swf->setArg('T', 10);
- $pdf2swf->setArg('set reordertags', '0');
- $pdf2swf->setArg('fonts');
- $pdf2swf->setArg('set storeallcharacters');
- if (DEV) {
- $pdf2swf->setArg('F', 'C:/Windows/Fonts');
- } else {
- $pdf2swf->setArg('F', '/home/typo/fonts');
- }
- if (file_exists($this->out . 't' . $page . '.swf')) {
- unlink($this->out . 't' . $page . '.swf');
- }
- $pdf2swf->setArg('set subpixels', '0.01');
- $pdf2swf->setArg('set jpegquality', '1');
- $pdf2swf->setArg('set disablelinks');
- $pdf2swf->setArg(null, $this->out . 'pdf/p' . $page . '.pdf');
- $pdf2swf->setArg('output', $this->out . 't' . $page . '.swf');
- $pdf2swf->execute();
- $this->addToLog($pdf2swf, true, $page);
-
- return '';
- }
-
- public function resetLog()
- {
- $f=$this->log . '/commons.log.gz';
- if(file_exists($f)) {
- unlink($f);
- }
- }
-
- public function addToLog($cl, $output = true, $page = null)
- {
- if ($cl instanceof cubeCommandLine) {
- $c = '--- Exécuté en ' . $cl->execTime . " s\n" . $cl->commande . "\n\n";
- if ($output) {
- $c .= $cl->output . "\n\n";
- }
- } elseif (is_string($cl)) {
- $c = '--- ' . "\n\n";
- $c .= $cl . "\n\n";
- }
-
- if (!file_exists($this->log)) {
- mkdir($this->log, 0777, true);
- }
-
-
- if (is_null($page)) {
- $fname = 'commons.log';
- } else {
- $fname = 'p' . $page . '.log';
- }
-
- $file = $this->log . '/' . $fname;
- if (!file_exists($file) && file_exists($fname . '.gz')) {
- $fopen = 'gzopen';
- $fwrite = 'gzwrite';
- $fclose = 'gzclose';
- $file .= '.gz';
- } else {
- $fopen = 'fopen';
- $fwrite = 'fwrite';
- $fclose = 'fclose';
- }
-
- $pointer = $fopen($file, 'ab');
- $fwrite($pointer, $c);
- $fclose($pointer);
- }
-
- public function __destruct()
- {
-
- }
-
- public static function getDir($id)
- {
-
- if (!is_array(self::$_docsDir)) {
- self::$_docsDir = array();
- }
-
- if (isset(self::$_docsDir[$id])) {
- return self::$_docsDir[$id];
- }
-
- $new = WS_FILES . '/docs/' . $id . '/';
- $old = WS_FILES . '/docs1/' . $id . '/';
- $veryold = WS_FILES . '/docs2/' . $id . '/';
-
- if (file_exists($new . 'p1.swf')) {
- self::$_docsDir[$id] = $new;
- return $new;
- } elseif (file_exists($old . 'p1.swf')) {
- self::$_docsDir[$id] = $old;
- return $old;
- } else if (file_exists($veryold . 'p1.swf')) {
- self::$_docsDir[$id] = $veryold;
- return $veryold;
- }
- if (!file_exists($new)) {
- mkdir($new, 0777, true);
- }
- self::$_docsDir[$id] = $new;
- return $new;
- }
+ protected $document_id;
+ protected $file;
+ protected $proprietaire;
+ protected $pages;
+ protected $trim;
+ protected $date;
+ protected $localInfos;
+ protected $generalInfos;
+ protected $conversionInfos;
+ protected $bookmarks;
+ protected $numberSections;
+ protected $localHash;
+ protected $version;
+ // Crop & cut
+ protected $autocrop;
+ protected $manualcrop;
+ protected $autocut;
+ protected $manualcut;
+ // Files
+ protected $out;
+ protected $in;
+ protected $html;
+ protected $uncompressed;
+ protected $log;
+ protected $common_log_pointer;
+ protected $pages_log_pointers;
+ protected $infos;
+ protected $cropped;
+ protected $rgb;
+
+ protected static $_docsDir;
+
+ const NORMAL = 0;
+ const FLATTEN = 1;
+ const POLY2BITMAP = 2;
+ const BITMAP = 3;
+ const BARBARE_PNM = 4;
+ const BARBARE_GS = 5;
+ const MAX = 5;
+ const PNM_FILL = 2;
+
+ protected static $resolution2multiply = array(72 => 2, 100 => 2, 150 => 3, 200 => 3, 300 => 3, 450 => 4, 600 => 5);
+ // Number section styles
+ protected static
+ $numberStyles = array('NoNumber' => 'no', 'DecimalArabicNumerals' => 'decimal',
+ 'UppercaseRomanNumerals' => 'roman_up', 'LowercaseRomanNumerals' => 'roman_low',
+ 'UppercaseLetters' => 'letters_up', 'LowercaseLetters' => 'letters_low');
+
+ public function init()
+ {
+ $this->out = wsDocument::getDir($this->document_id);
+ $this->log = $this->out . '/logs/';
+ $this->html = $this->out . '/html/';
+ $this->in = $this->out . 'original.pdf';
+ $this->uncompressed = $this->out . 'uncompressed.pdf';
+ $this->infos = $this->out . 'infos.txt';
+ if (!file_exists($this->out)) {
+ mkdir($this->out, 0755, true);
+ mkdir($this->log, 0755);
+ }
+ if (!file_exists($this->html)) {
+ mkdir($this->html, 0755);
+ }
+ $this->cropped = $this->out . 'crop.pdf';
+ $this->pages_log_pointers = array();
+
+ if (is_null($this->conversionInfos)) {
+ $this->conversionInfos = new wsDocumentConversionInfos();
+ }
+ }
+
+ public function getCroppedPDF()
+ {
+ if (!file_exists($this->cropped)) {
+ return $this->in;
+ }
+ return $this->cropped;
+ }
+
+ public function copyOriginalFromUpload($tmp_file)
+ {
+ move_uploaded_file($tmp_file, $this->in);
+ }
+
+ public function copyOriginalFromOlderVersion()
+ {
+ if (!file_exists($this->in)) {
+ copy('https://ws.fluidbook.com/docs/' . $this->document_id . '/original.pdf', $this->in);
+ }
+ }
+
+ public function extractFonts()
+ {
+ $extractor = new wsPDFFontExtractor($this->out, $this);
+ $extractor->extract();
+ }
+
+ public function getInfos($in = null, $force = false)
+ {
+ if (is_null($in)) {
+ $in = $this->in;
+ }
+
+ $fwstk = new cubeCommandLine('fwstk.sh');
+ $fwstk->setPath(CONVERTER_PATH);
+ $fwstk->setArg('--input ' . $in);
+ $fwstk->setArg('--infos');
+ $fwstk->execute();
+ $this->addToLog($fwstk);
+ $out = $fwstk->output;
+
+ $pdfinfo = new cubeCommandLine('pdfinfo');
+ $pdfinfo->setPath(CONVERTER_PATH);
+ $pdfinfo->setArg('-box');
+ $pdfinfo->setArg('f', 1);
+ $pdfinfo->setArg('l', 100000);
+ $pdfinfo->setArg(null, $in);
+ $pdfinfo->execute();
+ $this->addToLog($pdfinfo);
+ $out .= "\n";
+ $out .= $pdfinfo->output;
+
+ $this->addToLog('Parse infos');
+ $this->parseInfos($out);
+
+ $this->addToLog('Set Page Infos');
+ $this->conversionInfos->setPageNumber($this->generalInfos['pages']);
+
+ $this->addToLog('Write infos');
+ file_put_contents($this->infos, $out);
+
+ $this->addToLog('Find cut disposition');
+
+ $this->findCutDisposition();
+ }
+
+ public function findCutDisposition()
+ {
+ $this->detectSpreads();
+ $this->detectPageDifferences();
+ }
+
+ protected function detectPageDifferences()
+ {
+ $this->addToLog('Detect page differences');
+ // Vérifie si la cropbox et la trimbox sont identiques pour toutes les pages
+ $difference = false;
+ foreach ($this->generalInfos['page'] as $page => $infos) {
+ if (!isset($infos['crop']) || !isset($infos['crop'])) {
+ continue;
+ }
+ if ($infos['crop'] != $infos['trim']) {
+ $difference = true;
+ }
+ }
+ if (!$difference) {
+ return false;
+ }
+ // Vérifie si la trimbox définie toutes les pages de la même taille
+ $heights = array();
+ $widths = array();
+ foreach ($this->generalInfos['page'] as $page => $infos) {
+ $heights[] = round($infos['trim']->height);
+ $widths[] = round($infos['trim']->width);
+ }
+ $heights = array_unique($heights);
+ $widths = array_unique($widths);
+ if (count($heights) == 1 && count($widths) == 1) {
+ $this->autocrop = 'trim';
+ $this->manualcrop = false;
+ } else {
+ $this->autocrop = false;
+ $this->manualcrop = true;
+ }
+ }
+
+ protected function detectSpreads()
+ {
+ $this->addToLog('Detect spreads');
+ // Détection des spreads
+
+ $this->autocut = false;
+ $this->manualcut = false;
+ if ($this->generalInfos['pages'] <= 2) {
+ return;
+ }
+
+ foreach ($this->generalInfos['page'] as $page => $infos) {
+ if ($page == 1) {
+ $first = $infos['size'];
+ } elseif ($page == $this->generalInfos['pages']) {
+ $last = $infos['size'];
+ } elseif ($page == 2) {
+ $second = $infos['size'];
+ }
+ }
+
+ if ($first == $last && $last == $second) {
+ $ratio = $first[0] / $first[1];
+ $this->autocut = false;
+ if ($ratio <= 1) {
+ $this->manualcut = false;
+ } elseif ($ratio >= 6) {
+ $this->manualcut = 'L8';
+ } elseif ($ratio >= 3) {
+ $this->manualcut = 'L4';
+ } elseif ($ratio >= 2) {
+ $this->manualcut = 'L3';
+ } else {
+ $this->manualcut = '14-23';
+ }
+ return;
+ }
+ $this->manualcut = false;
+ if (self::compareSizes($last, $first) && cubeMath::compare($first[0] * 2, $second[0], 0.9)) {
+ $this->autocut = '1-23-4';
+ }
+ if (cubeMath::compare($first[0] * 2, $second[0], 0.9) && self::compareSizes($last, $second)) {
+ $this->autocut = '1-23';
+ }
+
+ $this->addToLog('Detect Spreads : Manual cut ' . $this->manualcut . ' ; Auto cut : ' . $this->autocut);
+ }
+
+ public static function compareSizes($x, $y, $tolerance = 0.9)
+ {
+ return cubeMath::compare($x[0], $y[0], $tolerance) && cubeMath::compare($x[1], $y[1], $tolerance);
+ }
+
+ public function lnCrop()
+ {
+ $root = dirname($this->cropped);
+ `cd $root;ln -s original.pdf crop.pdf`;
+ }
+
+ public function parseInfos($data)
+ {
+ cubePHP::set_memory('4G');
+ // This function get general infos (pages sizes, boxes, number sections and
+ // bookmarks
+ // Init arrays
+ $this->generalInfos = array();
+ $this->generalInfos['size'] = array(0, 0);
+ $this->bookmarks = array();
+ $this->numberSections = '';
+ $bookmark_id = 0;
+
+ $res['size'] = array(0, 0);
+ $lines = explode("\n", $data);
+ foreach ($lines as $line) {
+ $line = trim(cubeText::condenseWhite($line));
+ $e = explode(':', $line, 2);
+ $k = trim($e[0]);
+ if (count($e) < 2) {
+ continue;
+ }
+ $v = trim($e[1]);
+ if ($k == 'Pages' || $k == 'NumberOfPages') {
+ $this->pages = $this->generalInfos['pages'] = $v;
+ $this->generalInfos['page'] = array();
+ for ($i = 1; $i <= $this->pages; $i++) {
+ $this->generalInfos['page'][$i] = array();
+ }
+ } elseif (preg_match('|Page\s+([0-9]+)\s+(.*)Box:\s+([0-9.]*)\s+([0-9.]*)\s+([0-9.]*)\s+([0-9.]*)|iu', $line, $m)) {
+ $this->generalInfos['page'][$m[1]][strtolower($m[2])] = new wsBox($m[3], $m[4], $m[5], $m[6]);
+ } elseif (preg_match('|Page\s+([0-9]+)\s+size:\s+([0-9.]*)[pts[:space:]]+x\s+([0-9.]*)\s+pts|iu', $line, $m)) {
+ $this->generalInfos['page'][$m[1]]['size'] = array($m[2], $m[3]);
+ if ($m[1] == 1) {
+ $this->generalInfos['size'][0] = $m[2];
+ $this->generalInfos['size'][1] = $m[3];
+ }
+ } 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 == 'NumberSections') {
+ $this->numberSections = $v;
+ }
+ }
+ return $res;
+ }
+
+ public function getPagesNumber()
+ {
+ $this->getInfos();
+ return $this->generalInfos['pages'];
+ }
+
+ public function globalOperations()
+ {
+ $this->addToLog('Get infos');
+ $this->getInfos();
+ if ($this->CropAndCut()) {
+ $this->addToLog('Get infos after crop');
+ $this->getInfos($this->cropped, true);
+ }
+ $this->addToLog('Get links');
+ $this->getLinks();
+ $this->addToLog('End of global ops');
+ $this->splitDoc();
+ }
+
+ public function splitDoc()
+ {
+ $this->addToLog('Split document');
+ mkdir($this->out . '/pdf');
+ $pdftk = new cubeCommandLine('pdftk');
+ $pdftk->setPath(CONVERTER_PATH);
+ $pdftk->setArg(null, $this->getCroppedPDF());
+ $pdftk->setArg(null, 'burst');
+ $pdftk->setArg(null, 'output');
+ $pdftk->setArg(null, $this->out . 'pdf/p%d.pdf');
+ $pdftk->execute();
+ $this->addToLog($pdftk);
+ }
+
+ public function CropAndCut()
+ {
+ $this->addToLog('Crop And Cut');
+ if (!$this->isCropped()) {
+ $this->lnCrop();
+ return false;
+ }
+ if ($this->autocrop == 'trim') {
+ $this->trimDocument();
+ } else {
+ $this->lnCrop();
+ }
+
+ if ($this->autocut) {
+ $this->cutDocument($this->autocut);
+ return true;
+ }
+ return false;
+ }
+
+ public function cutDocument($mode)
+ {
+ $fwstk = new cubeCommandLine('fwstk.sh');
+ $fwstk->setPath(CONVERTER_PATH);
+ $fwstk->setArg('--input ' . $this->in);
+ $fwstk->setArg('--cut ' . $mode);
+ $fwstk->setArg('--output ' . $this->cropped);
+ $fwstk->execute();
+ $this->addToLog($fwstk);
+ }
+
+ public function trimDocument()
+ {
+ $fwstk = new cubeCommandLine('fwstk.sh');
+ $fwstk->setPath(CONVERTER_PATH);
+ $fwstk->setArg('--input ' . $this->in);
+ $fwstk->setArg('--trim');
+ $fwstk->setArg('--output ' . $this->cropped);
+ $fwstk->execute();
+ $this->addToLog($fwstk);
+ }
+
+ public function processOnePage($page, $force = true)
+ {
+ if ($force) {
+ $this->addToLog('Processing page #' . $page);
+ $this->makeMiniShot($page);
+ $this->makeSWFFiles($page);
+ $this->makeHTML5Files($page);
+ }
+ }
+
+ public function processAllPages()
+ {
+ for ($i = 1; $i <= $this->generalInfos['pages']; $i++) {
+ $this->processOnePage($i);
+ }
+ }
+
+ public function processRange($pages)
+ {
+ foreach ($pages as $i) {
+ $this->processOnePage($i);
+ }
+ }
+
+ public function getLinks()
+ {
+ $fwstk = new cubeCommandLine('fwstk.sh');
+ $fwstk->setPath(CONVERTER_PATH);
+ $fwstk->setArg('--input ' . $this->getCroppedPDF());
+ $fwstk->setArg('--extractLinks ' . $this->out . 'p%d.csv');
+ $fwstk->setArg('--threads 1');
+ $fwstk->execute();
+ $this->addToLog($fwstk);
+ }
+
+ public function getHighlightTextsData()
+ {
+ $fwstk = new cubeCommandLine('fwstk.sh');
+ $fwstk->setPath(CONVERTER_PATH);
+ $fwstk->setArg('--input ' . $this->getCroppedPDF());
+ $fwstk->setArg('--layout ' . $this->html . 'p%d.fby');
+ $fwstk->setArg('--cmaps ' . $this->html);
+ $fwstk->setArg('--fonts' . $this->out . 'fonts/web/');
+ $fwstk->execute();
+ $this->addToLog($fwstk);
+ }
+
+ public function getResolutionRatio()
+ {
+ $a4surface = 500990; // en pt²
+ $docSurface = $this->generalInfos['size'][0] * $this->generalInfos['size'][1]; // en pt²
+ // to have the same surface resulting in px, we have to sqrt the ratio between the two surfaces defined above
+ return sqrt($a4surface / $docSurface);
+ }
+
+ public function makeMiniShot($page)
+ {
+ $this->makeShotFixedWidth($page, 'p', 500, 65, 4, 'PNM');
+ }
+
+ public function makeShotFixedWidth($page, $prefix = '', $w = 100, $quality = 90, $antialiasing = 4, $method = 'PNM')
+ {
+ // Make thumbs of $w width
+ // resolution 72 make 1pt=1px
+ $width = $this->generalInfos['size'][0];
+ $ratio = $width / $w;
+ $this->makeShot($page, $prefix, round(72 / $ratio, 2), $quality, $antialiasing, $method);
+ }
+
+ public function makeShotFixedHeight($page, $prefix = '', $h = '', $quality = 90, $antialiasing = 4, $method = 'PNM')
+ {
+ // Make thumbs of $w height
+ // resolution 72 make 1pt=1px
+ $height = $this->generalInfos['size'][1];
+ $ratio = $height / $h;
+ $this->makeShot($page, $prefix, round(72 / $ratio, 2), $quality, $antialiasing, $method);
+ }
+
+ public function makeShot($page, $prefix = '', $resolution = 72, $quality = 90, $antialiasing = 4, $method = 'PNM', $in = null)
+ {
+ $error = false;
+ if (is_null($in)) {
+ $in = $this->getCroppedPDF();
+ }
+ // Delete all old files
+ $res = $this->out . $prefix . $page . '.jpg';
+ if (file_exists($res)) {
+ @unlink($res);
+ }
+
+ if ($method == 'GS') {
+ $this->makeShotGS($page, $prefix, $resolution, $quality, $antialiasing, $in);
+ } elseif ($method == 'PNM') {
+ $this->makeShotPNM($page, $prefix, $resolution, $quality, $antialiasing, $in);
+ }
+ // Test the result by checking all files
+ if (!file_exists($res)) {
+ $error = true;
+ }
+ // If error, we try to make thumbs with other method
+ if ($error) {
+ if ($method == 'GS') {
+ $this->makeShotPNM($page, $prefix, $resolution, $quality, $antialiasing, $in);
+ } elseif ($method == 'PNM') {
+ $this->makeShotGS($page, $prefix, $resolution, $quality, $antialiasing, $in);
+ }
+ }
+ }
+
+ protected function makeShotGS($page, $prefix = '', $resolution = 72, $quality = 90, $antialiasing = 4, $in = null)
+ {
+ if (is_null($in)) {
+ $in = $this->getCroppedPDF();
+ }
+ // Fabrication des thumbanails avec ghostscript
+ $gs = new cubeCommandLine('gs', null, true);
+ $gs->setPath(CONVERTER_PATH);
+ $gs->setEnv('GS_FONTPATH', FONT_PATH);
+ $gs->setArg('-dBATCH');
+ $gs->setArg('-dNOPAUSE');
+ $gs->setArg('-dNOPROMPT');
+ // Antialias
+ $gs->setArg('-dDOINTERPOLATE');
+ $gs->setArg('-dTextAlphaBits=' . $antialiasing);
+ $gs->setArg('-dGraphicsAlphaBits=' . $antialiasing);
+ // Device
+ $gs->setArg('-sDEVICE=jpeg');
+ // Dispotion & colors
+ // $gs->setArg('-dUseCIEColor');
+ $gs->setArg('-dAutoRotatePages=/None');
+ $gs->setArg('-dUseCropBox');
+ // Resolution & Quality
+ $gs->setArg('-r' . round($resolution));
+ $gs->setArg('-dJPEGQ=' . $quality);
+ // Performances
+ $gs->setArg('-dNumRenderingThreads=4');
+ // Page range
+ $gs->setArg('-dFirstPage=' . $page);
+ $gs->setArg('-dLastPage=' . $page);
+ // Files
+ $gs->setArg('-sOutputFile=' . $this->out . '/' . $prefix . $page . '.jpg');
+
+ $gs->setArg(null, $in);
+ $gs->execute();
+ $this->addToLog($gs, true, $page);
+ }
+
+ protected function makeShotPNM($page, $prefix = '', $resolution = 72, $quality = 90, $antialiasing = 4, $in = null, $texts = true)
+ {
+ if (is_null($in)) {
+ $in = $this->getCroppedPDF();
+ }
+
+ $tmp = cubeFiles::tempnam();
+
+ $antialiasing = $antialiasing ? 'yes' : 'no';
+ $freetype = $texts ? 'yes' : 'no';
+ // Exporte les fichiers
+ $pdftoppm = new cubeCommandLine('pdftoppm', null, true);
+ $pdftoppm->setPath(CONVERTER_PATH);
+
+ $pdftoppm->setArg('f', $page);
+ $pdftoppm->setArg('l', $page);
+ $pdftoppm->setArg('-cropbox');
+ $pdftoppm->setArg('-freetype ' . $freetype);
+ $pdftoppm->setArg('-singlefile');
+ $pdftoppm->setArg('-aa ' . $antialiasing);
+ $pdftoppm->setArg('-aaVector ' . $antialiasing);
+ $pdftoppm->setArg('r', $resolution);
+ $pdftoppm->setArg(null, $in);
+ $pdftoppm->setArg(null, $tmp);
+ $pdftoppm->execute();
+ $this->addToLog($pdftoppm, true, $page);
+
+ $tmp .= '.ppm';
+
+ $jpegfile = $this->out . $prefix . $page . '.jpg';
+
+ if (file_exists($tmp)) {
+ // $pnmtojpeg = new cubeCommandLine('pnmtojpeg', $jpegfile, false);
+ // $pnmtojpeg->setArg('-quality ' . $quality);
+ // $pnmtojpeg->setArg(null, $tmp);
+ // $pnmtojpeg->execute();
+ // $this->addToLog($pnmtojpeg, false, $page);
+
+
+ $cjpeg = new cubeCommandLine('cjpeg', null, true);
+ $cjpeg->setArg('-quality ' . ($quality + 6));
+ $cjpeg->setArg('-outfile ' . $jpegfile);
+ $cjpeg->setArg(null, $tmp);
+ $cjpeg->execute();
+ $this->addToLog($cjpeg, false, $page);
+
+ unlink($tmp);
+ }
+ }
+
+ protected function isCropped()
+ {
+ return $this->autocrop || $this->manualcrop || $this->autocut || $this->manualcut;
+ }
+
+ public function makeSWFFiles($page, $resolution = null, $quality = null, $storeAllChars = null, $maxObjects = null, $method = null, $version = null)
+ {
+ $conversionSettings = $this->conversionInfos->pages[$page];
+ if (is_null($storeAllChars)) {
+ $storeAllChars = true;
+ }
+ if (is_null($resolution)) {
+ $resolution = $conversionSettings->resolution;
+ }
+ if (is_null($method)) {
+ $method = $conversionSettings->method;
+ }
+ if (is_null($quality)) {
+ $quality = $conversionSettings->quality;
+ }
+ if (is_null($maxObjects)) {
+ $maxObjects = $conversionSettings->objects;
+ }
+ if (is_null($version)) {
+ $version = isset($conversionSettings->version) ? $conversionSettings->version : 'stable';
+ }
+
+ if ($maxObjects <= 1) {
+ $method = self::POLY2BITMAP;
+ }
+
+ // Pour les fichiers croppés, on utilise la méthode flatten qui ne prends
+ // pas en compte les objets hors de la box
+ if ($this->isCropped()) {
+ // $method = max($method, self::FLATTEN);
+ }
+
+ $out = $this->pdf2swf($page, $resolution * $this->getResolutionRatio(), $quality, $storeAllChars, $method, 'p', $version);
+ if ($method < self::BARBARE_PNM) {
+ // Analyse de la sortie pour détecter des typos manquantes
+ $overflow = false;
+ $overflowObjects = false;
+ $written = false;
+ $missing_fonts = array();
+ if (file_exists($out)) {
+ $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;
+ }
+ }
+ }
+ if (!is_null($page) && file_exists($this->out . 'p' . $page . '.swf')) {
+ $written = true;
+ }
+ // On teste si le fichier est écrit et qu'il a été généré par le premier niveau
+ if ($method < self::POLY2BITMAP && $written) {
+ $overflowObjects = $this->checkObjectsNumber($this->out . 'p' . $page . '.swf', $maxObjects, $page);
+ }
+
+ if (!$written || $overflow || $overflowObjects) {
+ if ($method == self::MAX) {
+ return;
+ }
+ $nextMethod = $method + 1;
+ return $this->makeSWFFiles($page, $resolution, $quality, $storeAllChars, $maxObjects, $nextMethod, $version);
+ }
+ }
+ }
+
+ public function makeHTML5Files($page)
+ {
+ // Then make HD background shots
+ $resolutions = array(300 => 85, 150 => 85, 36 => 85);
+ $rratio = $this->getResolutionRatio();
+ foreach ($resolutions as $r => $q) {
+ $this->makeShotPNM($page, 'html/h' . $r . '-', $r * $rratio, $q, 4, null, false);
+ $this->makeShotPNM($page, 'html/t' . $r . '-', $r * $rratio, $q, 4, null, true);
+ }
+ $this->makeSVGFile($page);
+ }
+
+ public function makeSVGFile($page)
+ {
+ $svgFile = $this->out . '/html/fp' . $page . '.svg';
+ $source = $this->getCroppedPDF();
+
+ $pdftocairo = new cubeCommandLine('pdftocairo');
+ $pdftocairo->setPath(CONVERTER_PATH);
+ $pdftocairo->setArg('f', $page);
+ $pdftocairo->setArg('l', $page);
+ $pdftocairo->setArg('r', 300);
+ $pdftocairo->setArg(null, '-expand');
+ $pdftocairo->setArg(null, '-svg');
+ $pdftocairo->setArg(null, $source);
+ $pdftocairo->setArg(null, $svgFile);
+ $pdftocairo->execute();
+
+ $this->addToLog($pdftocairo, true, $page);
+ }
+
+ public static function extractTexts($svgFile, $textFile, $force = false)
+ {
+ $do = $force || !file_exists($textFile) || filesize($textFile) < 100 || filemtime($svgFile) > filemtime($textFile) || filemtime($textFile) < filemtime(__FILE__);
+ if (!$do) {
+ return;
+ }
+
+ $svg = new DOMDocument();
+ $svg->preserveWhiteSpace = false;
+ $svg->load($svgFile, LIBXML_PARSEHUGE);
+
+ // Operations to delete
+ $xpath = new DOMXPath($svg);
+ $xpath->registerNamespace('svg', 'http://www.w3.org/2000/svg');
+ $xpath->registerNamespace('xlink', 'http://www.w3.org/1999/xlink');
+ $xpath->registerNamespace("php", "http://php.net/xpath");
+ $xpath->registerPhpFunctions('has_not_text');
+ $toDelete = array('//svg:defs/svg:clipPath',
+ '//svg:defs/svg:image',
+ '//svg:defs/svg:path',
+ '//svg:defs/svg:pattern',
+ '//svg:defs/svg:g[starts-with(@id, "surface")]//svg:path',
+ '/svg:svg/svg:g//svg:path',
+ '/svg:svg/svg:g//svg:rect',
+ '//svg:use[starts-with(@xlink:href, "#image")]'
+ );
+
+ //global $svglog;
+ //$svglog = array('XPATH : ' . print_r($xpath, true));
+ foreach ($toDelete as $q) {
+ $list = $xpath->query($q);
+ // $svglog[] = "Evaluate xpath query " . $q;
+ // $svglog[] = 'Give ' . $list->length . ' results';
+ // $svglog[] = 'Deleting Nodes in ' . print_r($list, true);
+ if (count($list)) {
+ foreach ($list as $node) {
+ /* @var $node DOMNode */
+ $parent = $node->parentNode;
+ $parent->removeChild($node);
+ }
+ }
+ }
+ file_put_contents($textFile, $svg->saveXML());
+ }
+
+ protected function checkObjectsNumber($file, $maxObjects, $page)
+ {
+ $swfdump = new cubeCommandLine('swfdump', null, true);
+ $swfdump->setPath(CONVERTER_PATH);
+ $swfdump->setArg(null, $file);
+ $swfdump->execute();
+ $this->addToLog($swfdump, true, $page);
+
+ str_replace('[01a]', '', $swfdump->output, $nbObjects);
+ if ($nbObjects > $maxObjects) {
+ return true;
+ }
+ return false;
+ }
+
+ protected function dumpSWF($page, $prefix = 'p')
+ {
+ $swfdump = new cubeCommandLine('/usr/local/swftools/special-swfdump/bin/swfdump', null, true);
+ $swfdump->setPath(CONVERTER_PATH);
+ $swfdump->setArg('t');
+ $swfdump->setArg('p');
+ $swfdump->setArg('F');
+ $swfdump->setArg(null, $this->out . $prefix . $page . '.swf');
+ $swfdump->execute();
+ $this->addToLog($swfdump, false, $page);
+ return $swfdump->output;
+ }
+
+ /**
+ * wsDocument::pdf2swf()
+ *
+ * @param mixed $page
+ * @param integer $resolution
+ * @param integer $quality
+ * @param mixed $storeAllChars
+ * @param integer $method
+ * @return
+ */
+ protected function pdf2swf($page, $resolution = 150, $quality = 90, $storeAllChars = true, $method = 0, $prefix = 'p', $version = 'stable')
+ {
+ /*
+ -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=<dir> a directory with additional fonts
+ font=<filename> an additional font filename
+ pages=<range> the range of pages to convert (example: pages=1-100,210-)
+ zoom=<dpi> the resultion (default: 72)
+ languagedir=<dir> Add an xpdf language directory
+ multiply=<times> Render everything at <times> the resolution
+ poly2bitmap Convert graphics to bitmaps
+ bitmap Convert everything to bitmaps
+
+ SWF Parameters :
+ ----------------
+ SWF layer options :
+ -------------------
+
+ jpegsubpixels=<pixels> resolution adjustment for jpeg images (same as jpegdpi, but in pixels)
+ ppmsubpixels=<pixels resolution adjustment for lossless images (same asppmdpi, but in pixels)
+ subpixels=<pixels> 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=<color) color of links (format: RRGGBBAA)
+ linknameurl Link buttons will be named like the URL they refer to (handy for iterating through links with actionscript)
+ storeallcharacters don't reduce the fonts to used characters in the output file
+ enablezlib switch on zlib compression (also done if flashversion>=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=<name> when the user clicks a internal link (to a different page) in the converted file, this actionscript function is called
+ externallinkfunction=<name> 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=<width> 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=<version> the SWF fileversion (6)
+ framerate=<fps> SWF framerate
+ minlinewidth=<width> 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=<quality> set compression quality of jpeg images
+ splinequality=<value> Set the quality of spline convertion to value (0-100, default: 100).
+ disablelinks Disable links.
+ */
+
+ if (file_exists($this->out . $prefix . $page . '.swf')) {
+ unlink($this->out . $prefix . $page . '.swf');
+ }
+
+ if (!in_array($method, array(self::BARBARE_PNM, self::BARBARE_GS))) {
+ if (in_array($version, array('legacy', 'stable', 'latest', 'git'))) {
+ $program = '/usr/local/swftools/' . $version . '/bin/pdf2swf';
+ } else {
+ $program = 'pdf2swf';
+ }
+
+ $pdf2swf = new cubeCommandLine($program, null, true);
+ $pdf2swf->setPath(CONVERTER_PATH);
+
+ $pdf2swf->setArg('p', 1);
+ $flashversion = 10;
+
+ if ($method == self::NORMAL) {
+ // Default
+ $multiply = 1;
+ } elseif ($method == self::FLATTEN) {
+ $multiply = 1;
+ $pdf2swf->setArg('flatten');
+ } elseif ($method == self::POLY2BITMAP) {
+ // Raster graphics, keep texts
+ $pdf2swf->setArg('set poly2bitmap');
+ $pdf2swf->setArg('set multiply', $this->_findMultiply($resolution));
+ } elseif ($method == self::BITMAP) {
+ // Raster all
+ $pdf2swf->setArg('set bitmap');
+ $pdf2swf->setArg('set multiply', $this->_findMultiply($resolution));
+ }
+ // $pdf2swf->setManualArg('-v');
+ $pdf2swf->setArg('T', $flashversion);
+ $pdf2swf->setArg('set reordertags', '0');
+ if ($storeAllChars) {
+ $pdf2swf->setArg('fonts');
+ $pdf2swf->setArg('set storeallcharacters');
+ }
+ 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');
+ if ($version == 'git') {
+ $pdf2swf->setArg(null, '-T7');
+ $pdf2swf->setArg('set alignfonts');
+ }
+ $pdf2swf->setArg(null, $this->out . 'pdf/p' . $page . '.pdf');
+ $pdf2swf->setArg('output', $this->out . $prefix . $page . '.swf');
+ $pdf2swf->execute();
+
+ if ($version == 'git') {
+ $f = $this->out . $prefix . $page . '.swf';
+ $combine = new cubeCommandLine('swfcombine');
+ $combine->setArg('d');
+ $combine->setArg(null, '-F9');
+ $combine->setArg(null, $f);
+ $combine->setArg('o', $f);
+ $combine->execute();
+ }
+
+ $this->addToLog($pdf2swf, true, $page);
+ } else {
+ $this->pdf2swfBarbare($page, $resolution, $quality, $method);
+ }
+ }
+
+ protected function _findMultiply($resolution)
+ {
+ $resolution /= $this->getResolutionRatio();
+ return self::$resolution2multiply[$resolution];
+ }
+
+ protected function makeAS3($page)
+ {
+ $swffile = $this->out . 'p' . $page . '.swf';
+
+ $swfcombine = new cubeCommandLine('swfcombine');
+ $swfcombine->setPath(CONVERTER_PATH);
+ $swfcombine->setArg('merge');
+ $swfcombine->setArg('stack1');
+ $swfcombine->setArg('z');
+ $swfcombine->setManualArg('-v');
+ $swfcombine->setArg('o', $swffile);
+ $swfcombine->setArg(null, ROOT . '/swf/as3Container.swf');
+ $swfcombine->setManualArg('content=' . $swffile);
+ $swfcombine->execute();
+ $this->addToLog($swfcombine, true, $page);
+ }
+
+ protected function pdf2swfBarbare($page, $resolution = 150, $quality = 85, $method = 4)
+ {
+ // Fabrique les images
+
+ $this->addToLog('Making barbare swf', true, $page);
+
+ if ($method == self::BARBARE_PNM) {
+ $this->makeShot($page, 'barbare', $resolution, $quality, 4, 'PNM');
+ } elseif ($method == self::BARBARE_GS) {
+ $this->makeShot($page, 'barbare', $resolution, $quality, 4, 'GS');
+ }
+
+ $dim = getimagesize($this->out . 'barbare' . $page . '.jpg');
+
+ // A partir des images, on crée les swf
+ $jpeg2swf = new cubeCommandLine('jpeg2swf');
+ $jpeg2swf->setPath(CONVERTER_PATH);
+ $jpeg2swf->setArg('--quality', $quality);
+ $jpeg2swf->setArg('--output', $this->out . 'p' . $page . '.swf');
+ $jpeg2swf->setArg('--flashversion', 10);
+ $jpeg2swf->setArg('--width', $dim[0] * (72 / $resolution));
+ $jpeg2swf->setArg('--height', $dim[1] * (72 / $resolution));
+ $jpeg2swf->setArg('--fit-to-movie');
+ $jpeg2swf->setArg(null, $this->out . 'barbare' . $page . '.jpg');
+ $jpeg2swf->execute();
+ $this->addToLog($jpeg2swf, true, $page);
+ // Suppression du jpeg
+ @unlink($this->out . '/barbare' . $page . '.jpg', true, $page);
+
+ $pdf2swf = new cubeCommandLine('pdf2swf', null, true);
+ $pdf2swf->setPath(CONVERTER_PATH);
+ $pdf2swf->setArg('set poly2bitmap');
+ $pdf2swf->setArg('p', 1);
+ $pdf2swf->setArg('stop');
+ $pdf2swf->setArg('T', 10);
+ $pdf2swf->setArg('set reordertags', '0');
+ $pdf2swf->setArg('fonts');
+ $pdf2swf->setArg('set storeallcharacters');
+ if (DEV) {
+ $pdf2swf->setArg('F', 'C:/Windows/Fonts');
+ } else {
+ $pdf2swf->setArg('F', '/home/typo/fonts');
+ }
+ if (file_exists($this->out . 't' . $page . '.swf')) {
+ unlink($this->out . 't' . $page . '.swf');
+ }
+ $pdf2swf->setArg('set subpixels', '0.01');
+ $pdf2swf->setArg('set jpegquality', '1');
+ $pdf2swf->setArg('set disablelinks');
+ $pdf2swf->setArg(null, $this->out . 'pdf/p' . $page . '.pdf');
+ $pdf2swf->setArg('output', $this->out . 't' . $page . '.swf');
+ $pdf2swf->execute();
+ $this->addToLog($pdf2swf, true, $page);
+
+ return '';
+ }
+
+ public function resetLog()
+ {
+ $f = $this->log . '/commons.log.gz';
+ if (file_exists($f)) {
+ unlink($f);
+ }
+ }
+
+ public function addToLog($cl, $output = true, $page = null)
+ {
+ if ($cl instanceof cubeCommandLine) {
+ $c = '--- Exécuté en ' . $cl->execTime . " s\n" . $cl->commande . "\n\n";
+ if ($output) {
+ $c .= $cl->output . "\n\n";
+ }
+ } elseif (is_string($cl)) {
+ $c = '--- ' . "\n\n";
+ $c .= $cl . "\n\n";
+ }
+
+ if (!file_exists($this->log)) {
+ mkdir($this->log, 0777, true);
+ }
+
+
+ if (is_null($page)) {
+ $fname = 'commons.log';
+ } else {
+ $fname = 'p' . $page . '.log';
+ }
+
+ $file = $this->log . '/' . $fname;
+ if (!file_exists($file) && file_exists($fname . '.gz')) {
+ $fopen = 'gzopen';
+ $fwrite = 'gzwrite';
+ $fclose = 'gzclose';
+ $file .= '.gz';
+ } else {
+ $fopen = 'fopen';
+ $fwrite = 'fwrite';
+ $fclose = 'fclose';
+ }
+
+ $pointer = $fopen($file, 'ab');
+ $fwrite($pointer, $c);
+ $fclose($pointer);
+ }
+
+ public function __destruct()
+ {
+
+ }
+
+ public static function getDir($id)
+ {
+
+ if (!is_array(self::$_docsDir)) {
+ self::$_docsDir = array();
+ }
+
+ if (isset(self::$_docsDir[$id])) {
+ return self::$_docsDir[$id];
+ }
+
+ $new = WS_FILES . '/docs/' . $id . '/';
+ $old = WS_FILES . '/docs1/' . $id . '/';
+ $veryold = WS_FILES . '/docs2/' . $id . '/';
+ $vveryold = WS_FILES . '/docs3/' . $id . '/';
+
+ if (file_exists($new . 'p1.swf')) {
+ self::$_docsDir[$id] = $new;
+ return $new;
+ } elseif (file_exists($old . 'p1.swf')) {
+ self::$_docsDir[$id] = $old;
+ return $old;
+ } else if (file_exists($veryold . 'p1.swf')) {
+ self::$_docsDir[$id] = $veryold;
+ return $veryold;
+ } else if (file_exists($vveryold . 'p1.swf')) {
+ self::$_docsDir[$id] = $vveryold;
+ return $vveryold;
+ }
+ if (!file_exists($new)) {
+ mkdir($new, 0777, true);
+ }
+ self::$_docsDir[$id] = $new;
+ return $new;
+ }
}
\ No newline at end of file