From 340dd9476ea0cc3c35e96fecd37318fd16717cc5 Mon Sep 17 00:00:00 2001 From: "vincent@cubedesigners.com" Date: Sun, 1 May 2011 13:37:07 +0000 Subject: [PATCH] --- _project/Project.mpp | Bin 544768 -> 544768 bytes fluidbook/tools/fwstk.jar | Bin 12585749 -> 12566098 bytes inc/ws/Metier/class.ws.document.php | 1726 ++++++++--------- .../Util/packager/class.ws.packager.html5.php | 305 +-- 4 files changed, 1016 insertions(+), 1015 deletions(-) diff --git a/_project/Project.mpp b/_project/Project.mpp index 53dd7b97682b8ab3dd91e1cda0bc0ea0b75bbb3a..7562783334220dc031a0b2d7c8f97df5e030c55f 100644 GIT binary patch delta 1031 zcmXw2ZD^ZS6h7y?AH8jwt|ndjp>0x|WiT3y>prZ4yza}`t-|bd6o*Z>E^eJ`lbOQy zqYwpkrJdGw^!Q_H7+VF|kG0X=!sr%I92-MhhteM^ZI~YfDuYD^1&#Mj^uT$~eeONa zx##1)$y9SP)qG`-jy)5dy4M-0KKlDu*&VzL0GWwX`fdKI51&jYjFhHTYK3%d`HCnm z%3MLh$%)N1UOL{Kex;`2H;kp@t1lfZ5{!i6hxx6$bn~-J6t&4=JT1fhc+u2SRWI}M z6gJZ3E?E`FFGZ1nTjgJ;(4leWD2CbEOHaw&KE&NJ_5nr|kP3L+?#1;h0hJY$*&ihebNmvn z<@qVx$eDAf%NH-<&@;t+WPS;CRHgCiGB()Olf}t~bv}UC&~n%@CJCSlO6wt?{3eS% z>v?lIt!te+BLE5o`;wA$TXomYsD!hM^1pOj4>wHL4YbxPtYXyf4aRl~%CUC( z#lg89R3Q^P$-8DEq#Kyz;F#(rS5WfQj?8%Pq4VIHUPZb=*o;WiAOYh%gYX6%ZPk zE53yJ+p|T>nT=SNu3Yjs-@Be6rJ7P*sUfdt%ui;^?dI5b-sBsPi!Qko(p?|BEJwyw zP|wP8)Tm>_upIIykC<)LpH-vgk2Z-2{xcmf!>e0F(rM&WWjTIlyEu;h^1*hofaVj5 z76JbB2W^Adq&R|jb*Bgf_roBZfMf6`9Du`c5)uma!hl*Q)J_k?6dr_rg%3eOZrvr? ykdx1guT8s6y`_LM5f-NjxA5N`B4qBETU39xY}+k5b>omC4si9)`a!OaV*S5O-b9=L delta 926 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 KC+6&7{PjPBnjyFV delta 86040 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 Q+L#Uf*Vri2RR@v(2Pk$(W&i*H diff --git a/inc/ws/Metier/class.ws.document.php b/inc/ws/Metier/class.ws.document.php index 07c1fadeb..7491b7714 100644 --- a/inc/ws/Metier/class.ws.document.php +++ b/inc/ws/Metier/class.ws.document.php @@ -1,4 +1,5 @@ 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 = WS_DOCS . '/' . $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->uncropped = $this->out . 'uncrop.pdf'; - $this->common_log_pointer = fopen($this->log . '/commons.log', 'ab'); - $this->pages_log_pointers = array(); - - if (is_null($this->conversionInfos)) { - $this->conversionInfos = new wsDocumentConversionInfos(); - } - } - - public function copyOriginalFromUpload($tmp_file) - { - move_uploaded_file($tmp_file, $this->in); - $this->uncropDocument(); - } - - public function copyOriginalFromOlderVersion() - { - if (!file_exists($this->in)) { - copy('http://ws.fluidbook.com/docs/' . $this->document_id . '/original.pdf', $this->in); - } - $this->uncropDocument(); - } - - public function extractFonts() - { - $out = $this->out . 'fonts/pdf'; - if (!file_exists($out)) { - mkdir($out, 0777, true); - } - // Extract fonts from PDF - $gs = new cubeCommandLine('gs'); - $gs->setPath(CONVERTER_PATH); - $gs->cd($out); - $gs->setArg('-dBATCH'); - $gs->setArg('-dNOPAUSE'); - $gs->setArg('-dNOPROMPT'); - $gs->setArg('-dNODISPLAY'); - $gs->setArg(null, WS_TOOLS . '/extractFonts.ps'); - $gs->setManualArg('-c "(' . $this->cropped . ') extractFonts quit"'); - - $gs->execute(); - $this->addToLog($gs); - - $dr = opendir($out); - - if (!file_exists($this->out . '/fonts/web')) { - mkdir($this->out . '/fonts/web', 0777, true); - } - $formats = array('ttf', 'woff', 'svg', 'svgz', 'eot'); - // Fonts conversion - while ($file = readdir($dr)) { - if ($file == '.' || $file == '..') { - continue; - } - - $e = explode('.', $file); - array_pop($e); - $fname = implode('.', $e); - - foreach($formats as $format) { - if ($format == 'eot') { - $ttf2eot = new cubeCommandLine('ttf2eot', $this->out . '/fonts/web/' . $fname . '.eot'); - $ttf2eot->setPath(CONVERTER_PATH); - $ttf2eot->setManualArg('< ' . $this->out . '/fonts/web/' . $fname . '.ttf'); - $ttf2eot->execute(); - } else { - $fontforge = new cubeCommandLine('convert.pe'); - $fontforge->setPath(CONVERTER_PATH); - $fontforge->setArg(null, $out . '/' . $file); - $fontforge->setArg(null, $this->out . '/fonts/web/' . $fname . '.' . $format); - $fontforge->execute(); - $this->addToLog($fontforge); - } - } - } - } - - public function getInfos($in = null, $force = false) - { - if (is_null($in)) { - $in = $this->in; - } - - $fwstk = new cubeCommandLine('fwstk'); - $fwstk->setPath(CONVERTER_PATH); - $fwstk->setArg('--input ' . $in); - $fwstk->setArg('--infos'); - $fwstk->execute(); - $this->addToLog($fwstk); - $this->parseInfos($fwstk->output); - - $this->conversionInfos->setPageNumber($this->generalInfos['pages']); - - file_put_contents($this->infos, $fwstk->output); - $this->findCutDisposition(); - } - - public function findCutDisposition() - { - $this->detectSpreads(); - $this->detectPageDifferences(); - } - - protected function detectPageDifferences() - { - // 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() - { - // Détection des spreads - 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 ($first == $last && round($first[0] * 2) == round($second[0])) { - $this->autocut = '1-23-4'; - } - if (round($first[0] * 2) == round($second[0]) && $last == $second) { - $this->autocut = '1-23'; - } - } - - public function parseInfos($data) - { - // 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 ([0-9]+) (.*)Box: ([0-9.]*) ([0-9.]*) ([0-9.]*) ([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 ([0-9]+) size: ([0-9.]*) pts x ([0-9.]*) 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->getInfos(); - if ($this->CropAndCut()) { - $this->getInfos($this->cropped, true); - } - $this->getLinksAndTexts(); - $this->extractFonts(); - } - - public function CropAndCut() - { - if (!$this->isCropped()) { - copy($this->in, $this->cropped); - return false; - } - if ($this->autocrop == 'trim') { - $this->trimDocument(); - } else { - copy($this->in, $this->cropped); - } - - if ($this->autocut) { - $this->cutDocument($this->autocut); - return true; - } - return false; - } - - public function cutDocument($mode) - { - $fwstk = new cubeCommandLine('fwstk'); - $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'); - $fwstk->setPath(CONVERTER_PATH); - $fwstk->setArg('--input ' . $this->in); - $fwstk->setArg('--trim'); - $fwstk->setArg('--output ' . $this->cropped); - $fwstk->execute(); - $this->addToLog($fwstk); - } - - public function uncropDocument() - { - $fwstk = new cubeCommandLine('fwstk'); - $fwstk->setPath(CONVERTER_PATH); - $fwstk->setArg('--input ' . $this->in); - $fwstk->setArg('--reset'); - $fwstk->setArg('--output ' . $this->uncropped); - $fwstk->execute(); - $this->addToLog($fwstk); - } - - public function processOnePage($page, $force = true) - { - // $this->makeRealShot($page); - 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 getLinksAndTexts() - { - $fwstk = new cubeCommandLine('fwstk'); - $fwstk->setPath(CONVERTER_PATH); - $fwstk->setArg('--input ' . $this->cropped); - $fwstk->setArg('--extractTexts ' . $this->out . '%s%d.txt'); - $fwstk->setArg('--extractLinks ' . $this->out . 'p%d.csv'); - $fwstk->execute(); - $this->addToLog($fwstk); - - /*$temp = cubeFiles::tempnam(); - $pdftotext = new cubeCommandLine('pdftotext', null, true); - $pdftotext->setPath(CONVERTER_PATH); - $pdftotext->setArg('q'); - $pdftotext->setArg('-eol', 'unix'); - $pdftotext->setArg('-enc', 'UTF-8'); - $pdftotext->setArg(null, $this->cropped); - $pdftotext->setArg(null, $temp); - $pdftotext->execute(); - $this->addToLog($pdftotext); - - $pages = explode("\f", file_get_contents($temp)); - foreach($pages as $i => $page) { - $i++; - $txt = mb_strtolower($page); - $txt = cubeText::removeAccents($txt); - $txt = trim($txt); - - file_put_contents($this->out . 'p' . $i . '.txt', $txt); - } - - unlink($temp);*/ - } - - public function makeMiniShot($page) - { - $this->makeShotFixedWidth($page, 'p', 100, 90, 4, 'PNM'); - } - - public function makeRealShot($page) - { - $this->makeShot($page, 'te', 150, 60, 4, 'GS', $this->uncropped); - } - - 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->cropped; - } - // 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->cropped; - } - // 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->cropped; - } - $antialiasing = $antialiasing?'yes':'no'; - $freetype = $texts?'yes':'no'; - $resolution = round($resolution); - // 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('-jpeg'); - $pdftoppm->setArg('-aa ' . $antialiasing); - $pdftoppm->setArg('-aaVector ' . $antialiasing); - $pdftoppm->setArg('r', $resolution); - $pdftoppm->setArg(null, $in); - $pdftoppm->setArg(null, $this->out . 'ppm'); - $pdftoppm->execute(); - $this->addToLog($pdftoppm, true, $page); - - $jpegfile = $this->out . $prefix . $page . '.jpg'; - - $ppmjpgfile = $this->out . 'ppm-' . cubeMath::fill($page, strlen((string)$this->pages)) . '.jpg'; - if (file_exists($ppmjpgfile)) { - rename($ppmjpgfile, $jpegfile); - $this->addToLog('Move ' . $ppmjpgfile . ' to ' . $jpegfile, true, $page); - } - } - - protected function isCropped() - { - return $this->autocrop || $this->manualcrop || $this->autocut || $this->manualcut; - } - - public function makeSWFFiles($page, $resolution = null, $quality = null, $storeAllChars = null, $maxObjects = 1800, $method = 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 ($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, $quality, $storeAllChars, $method); - 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); - } - } - } - - public function makeHTML5Files($page) - { - // First, make swf with polytobitmap to rasterize bitmap & vectors - $this->pdf2swf($page, 72, 80, true, self::POLY2BITMAP, 'h'); - // Then get the special unicode dump - $dump = $this->dumpSWF($page, 'h'); - // Then, process it - $swf2html = new wsSWF2HTML($dump); - $swf2html->process(); - $this->addToLog(print_r($swf2html, true), true, $page); - file_put_contents($this->html . '/p' . $page . '.obj', serialize($swf2html)); - // Then make HD background shots - $resolutions = array(36 => 80, 72 => 70, 150 => 50); - foreach($resolutions as $r => $q) { - $this->makeShotPNM($page, 'html/h' . $r . '-', $r, $q, 4, null, false); - } - } - - 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') - { - /* --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. - */ - - 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))) { - $pdf2swf = new cubeCommandLine('pdf2swf', null, true); - $pdf2swf->setPath(CONVERTER_PATH); - - $pdf2swf->setArg('p', $page); - - if ($method == self::NORMAL) { - // Default - $multiply = 1; - } elseif ($method == self::FLATTEN) { - $pdf2swf->setArg('flatten'); - $multiply = 1; - } elseif ($method == self::POLY2BITMAP) { - // Raster graphics, keep texts - $pdf2swf->setArg('set poly2bitmap'); - $multiply = self::$resolution2multiply[$resolution]; - $pdf2swf->setArg('set multiply', $multiply); - } elseif ($method == self::BITMAP) { - // Raster all - $pdf2swf->setArg('set bitmap'); - $multiply = self::$resolution2multiply[$resolution]; - $pdf2swf->setArg('set multiply', $multiply); - } - - $pdf2swf->setArg('stop'); - // $pdf2swf->setManualArg('-v'); - $pdf2swf->setArg('T', 10); - $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'); - // $pdf2swf->setManualArg('-vvv'); - $pdf2swf->setArg(null, $this->cropped); - $pdf2swf->setArg('output', $this->out . $prefix . '%.swf'); - $pdf2swf->execute(); - - $this->addToLog($pdf2swf, true, $page); - } else { - $this->pdf2swfBarbare($page, $resolution, $quality, $method); - } - } - - 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 - 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'); - } - // 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('--fit-to-movie'); - $jpeg2swf->setArg('--flashversion', 9); - $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) ; - - return ''; - } - - 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 (is_null($page)) { - $pointer = $this->common_log_pointer; - } else { - if (isset($this->pages_log_pointers[$page]) && is_resource($this->pages_log_pointers[$page])) { - $pointer = $this->pages_log_pointers[$page]; - } else { - $pointer = fopen($this->log . '/p' . $page . '.log', 'wb'); - $this->pages_log_pointers[$page] = $pointer; - } - } - - fwrite($pointer, $c); - } - public function __destruct() - { - if (isset($this->common_log_pointer) && is_resource($this->common_log_pointer)) { - fclose($this->common_log_pointer); - } - - foreach($this->pages_log_pointers as $p) { - if (!is_null($p) && is_resource($p)) { - fclose($p); - } - } - } + + 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 $uncropped; + + 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 = WS_DOCS . '/' . $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->uncropped = $this->out . 'uncrop.pdf'; + $this->common_log_pointer = fopen($this->log . '/commons.log', 'ab'); + $this->pages_log_pointers = array(); + + if (is_null($this->conversionInfos)) { + $this->conversionInfos = new wsDocumentConversionInfos(); + } + } + + public function copyOriginalFromUpload($tmp_file) { + move_uploaded_file($tmp_file, $this->in); + $this->uncropDocument(); + } + + public function copyOriginalFromOlderVersion() { + if (!file_exists($this->in)) { + copy('http://ws.fluidbook.com/docs/' . $this->document_id . '/original.pdf', $this->in); + } + $this->uncropDocument(); + } + + public function extractFonts() { + $out = $this->out . 'fonts/pdf'; + if (!file_exists($out)) { + mkdir($out, 0777, true); + } + // Extract fonts from PDF + $gs = new cubeCommandLine('gs'); + $gs->setPath(CONVERTER_PATH); + $gs->cd($out); + $gs->setArg('-dBATCH'); + $gs->setArg('-dNOPAUSE'); + $gs->setArg('-dNOPROMPT'); + $gs->setArg('-dNODISPLAY'); + $gs->setArg(null, WS_TOOLS . '/extractFonts.ps'); + $gs->setManualArg('-c "(' . $this->cropped . ') extractFonts quit"'); + + $gs->execute(); + $this->addToLog($gs); + + $dr = opendir($out); + + if (!file_exists($this->out . '/fonts/web')) { + mkdir($this->out . '/fonts/web', 0777, true); + } + $formats = array('ttf', 'woff', 'svg', 'svgz', 'eot'); + // Fonts conversion + while ($file = readdir($dr)) { + if ($file == '.' || $file == '..') { + continue; + } + + $e = explode('.', $file); + array_pop($e); + $fname = implode('.', $e); + + foreach ($formats as $format) { + if ($format == 'eot') { + $ttf2eot = new cubeCommandLine('ttf2eot', $this->out . '/fonts/web/' . $fname . '.eot'); + $ttf2eot->setPath(CONVERTER_PATH); + $ttf2eot->setManualArg('< ' . $this->out . '/fonts/web/' . $fname . '.ttf'); + $ttf2eot->execute(); + } else { + $fontforge = new cubeCommandLine('convert.pe'); + $fontforge->setPath(CONVERTER_PATH); + $fontforge->setArg(null, $out . '/' . $file); + $fontforge->setArg(null, $this->out . '/fonts/web/' . $fname . '.' . $format); + $fontforge->execute(); + $this->addToLog($fontforge); + } + } + } + } + + public function getInfos($in = null, $force = false) { + if (is_null($in)) { + $in = $this->in; + } + + $fwstk = new cubeCommandLine('fwstk'); + $fwstk->setPath(CONVERTER_PATH); + $fwstk->setArg('--input ' . $in); + $fwstk->setArg('--infos'); + $fwstk->execute(); + $this->addToLog($fwstk); + $this->parseInfos($fwstk->output); + + $this->conversionInfos->setPageNumber($this->generalInfos['pages']); + + file_put_contents($this->infos, $fwstk->output); + $this->findCutDisposition(); + } + + public function findCutDisposition() { + $this->detectSpreads(); + $this->detectPageDifferences(); + } + + protected function detectPageDifferences() { + // 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() { + // Détection des spreads + 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 ($first == $last && round($first[0] * 2) == round($second[0])) { + $this->autocut = '1-23-4'; + } + if (round($first[0] * 2) == round($second[0]) && $last == $second) { + $this->autocut = '1-23'; + } + } + + public function parseInfos($data) { + // 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 ([0-9]+) (.*)Box: ([0-9.]*) ([0-9.]*) ([0-9.]*) ([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 ([0-9]+) size: ([0-9.]*) pts x ([0-9.]*) 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->getInfos(); + if ($this->CropAndCut()) { + $this->getInfos($this->cropped, true); + } + $this->getLinksAndTexts(); + $this->extractFonts(); + } + + public function CropAndCut() { + if (!$this->isCropped()) { + copy($this->in, $this->cropped); + return false; + } + if ($this->autocrop == 'trim') { + $this->trimDocument(); + } else { + copy($this->in, $this->cropped); + } + + if ($this->autocut) { + $this->cutDocument($this->autocut); + return true; + } + return false; + } + + public function cutDocument($mode) { + $fwstk = new cubeCommandLine('fwstk'); + $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'); + $fwstk->setPath(CONVERTER_PATH); + $fwstk->setArg('--input ' . $this->in); + $fwstk->setArg('--trim'); + $fwstk->setArg('--output ' . $this->cropped); + $fwstk->execute(); + $this->addToLog($fwstk); + } + + public function uncropDocument() { + $fwstk = new cubeCommandLine('fwstk'); + $fwstk->setPath(CONVERTER_PATH); + $fwstk->setArg('--input ' . $this->in); + $fwstk->setArg('--reset'); + $fwstk->setArg('--output ' . $this->uncropped); + $fwstk->execute(); + $this->addToLog($fwstk); + } + + public function processOnePage($page, $force = true) { + // $this->makeRealShot($page); + 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 getLinksAndTexts() { + $fwstk = new cubeCommandLine('fwstk'); + $fwstk->setPath(CONVERTER_PATH); + $fwstk->setArg('--input ' . $this->cropped); + $fwstk->setArg('--extractTexts ' . $this->out . '%s%d.txt'); + $fwstk->setArg('--extractLinks ' . $this->out . 'p%d.csv'); + $fwstk->setArg('--layout '.$this->html.'p%d.layout'); + $fwstk->execute(); + $this->addToLog($fwstk); + + /* $temp = cubeFiles::tempnam(); + $pdftotext = new cubeCommandLine('pdftotext', null, true); + $pdftotext->setPath(CONVERTER_PATH); + $pdftotext->setArg('q'); + $pdftotext->setArg('-eol', 'unix'); + $pdftotext->setArg('-enc', 'UTF-8'); + $pdftotext->setArg(null, $this->cropped); + $pdftotext->setArg(null, $temp); + $pdftotext->execute(); + $this->addToLog($pdftotext); + + $pages = explode("\f", file_get_contents($temp)); + foreach($pages as $i => $page) { + $i++; + $txt = mb_strtolower($page); + $txt = cubeText::removeAccents($txt); + $txt = trim($txt); + + file_put_contents($this->out . 'p' . $i . '.txt', $txt); + } + + unlink($temp); */ + } + + public function makeMiniShot($page) { + $this->makeShotFixedWidth($page, 'p', 100, 90, 4, 'PNM'); + } + + public function makeRealShot($page) { + $this->makeShot($page, 'te', 150, 60, 4, 'GS', $this->uncropped); + } + + 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->cropped; + } + // 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->cropped; + } + // 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->cropped; + } + $antialiasing = $antialiasing ? 'yes' : 'no'; + $freetype = $texts ? 'yes' : 'no'; + $resolution = round($resolution); + // 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('-jpeg'); + $pdftoppm->setArg('-aa ' . $antialiasing); + $pdftoppm->setArg('-aaVector ' . $antialiasing); + $pdftoppm->setArg('r', $resolution); + $pdftoppm->setArg(null, $in); + $pdftoppm->setArg(null, $this->out . 'ppm'); + $pdftoppm->execute(); + $this->addToLog($pdftoppm, true, $page); + + $jpegfile = $this->out . $prefix . $page . '.jpg'; + + $ppmjpgfile = $this->out . 'ppm-' . cubeMath::fill($page, strlen((string) $this->pages)) . '.jpg'; + if (file_exists($ppmjpgfile)) { + rename($ppmjpgfile, $jpegfile); + $this->addToLog('Move ' . $ppmjpgfile . ' to ' . $jpegfile, true, $page); + } + } + + protected function isCropped() { + return $this->autocrop || $this->manualcrop || $this->autocut || $this->manualcut; + } + + public function makeSWFFiles($page, $resolution = null, $quality = null, $storeAllChars = null, $maxObjects = 1800, $method = 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 ($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, $quality, $storeAllChars, $method); + 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); + } + } + } + + public function makeHTML5Files($page) { + // Then make HD background shots + $resolutions = array(36 => 80, 72 => 70, 150 => 50); + foreach ($resolutions as $r => $q) { + $this->makeShotPNM($page, 'html/h' . $r . '-', $r, $q, 4, null, false); + } + } + + 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') { + /* + -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. + */ + + 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))) { + $pdf2swf = new cubeCommandLine('pdf2swf', null, true); + $pdf2swf->setPath(CONVERTER_PATH); + + $pdf2swf->setArg('p', $page); + + if ($method == self::NORMAL) { + // Default + $multiply = 1; + } elseif ($method == self::FLATTEN) { + $pdf2swf->setArg('flatten'); + $multiply = 1; + } elseif ($method == self::POLY2BITMAP) { + // Raster graphics, keep texts + $pdf2swf->setArg('set poly2bitmap'); + $multiply = self::$resolution2multiply[$resolution]; + $pdf2swf->setArg('set multiply', $multiply); + } elseif ($method == self::BITMAP) { + // Raster all + $pdf2swf->setArg('set bitmap'); + $multiply = self::$resolution2multiply[$resolution]; + $pdf2swf->setArg('set multiply', $multiply); + } + + $pdf2swf->setArg('stop'); + // $pdf2swf->setManualArg('-v'); + $pdf2swf->setArg('T', 10); + $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'); + // $pdf2swf->setManualArg('-vvv'); + $pdf2swf->setArg(null, $this->cropped); + $pdf2swf->setArg('output', $this->out . $prefix . '%.swf'); + $pdf2swf->execute(); + + $this->addToLog($pdf2swf, true, $page); + } else { + $this->pdf2swfBarbare($page, $resolution, $quality, $method); + } + } + + 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 + 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'); + } + // 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('--fit-to-movie'); + $jpeg2swf->setArg('--flashversion', 9); + $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); + + return ''; + } + + 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 (is_null($page)) { + $pointer = $this->common_log_pointer; + } else { + if (isset($this->pages_log_pointers[$page]) && is_resource($this->pages_log_pointers[$page])) { + $pointer = $this->pages_log_pointers[$page]; + } else { + $pointer = fopen($this->log . '/p' . $page . '.log', 'wb'); + $this->pages_log_pointers[$page] = $pointer; + } + } + + fwrite($pointer, $c); + } + + public function __destruct() { + if (isset($this->common_log_pointer) && is_resource($this->common_log_pointer)) { + fclose($this->common_log_pointer); + } + + foreach ($this->pages_log_pointers as $p) { + if (!is_null($p) && is_resource($p)) { + fclose($p); + } + } + } + } ?> \ No newline at end of file diff --git a/inc/ws/Util/packager/class.ws.packager.html5.php b/inc/ws/Util/packager/class.ws.packager.html5.php index 1102205ce..b80da19a4 100644 --- a/inc/ws/Util/packager/class.ws.packager.html5.php +++ b/inc/ws/Util/packager/class.ws.packager.html5.php @@ -1,229 +1,270 @@ version = 'html5'; - - $this->coef = 150 / 72; } - protected function preparePackage() - { + protected function preparePackage() { parent::preparePackage(); - foreach($this->pages as $page => $infos) { - $file = WS_DOCS . '/' . $infos['document_id'] . '/html/p' . $infos['document_page'] . '.obj'; + foreach ($this->pages as $page => $infos) { + $file = WS_DOCS . '/' . $infos['document_id'] . '/html/p' . $infos['document_page'] . '.layout'; if (file_exists($file)) { - $this->layouts[$page] = unserialize(file_get_contents($file)); + $this->layouts[$page] = simplexml_load_file($file, null, LIBXML_ERR_WARNING); } } + $imagesize = getimagesize(WS_DOCS . '/' . $this->pages[1]['document_id'] . '/html/h150-' . $this->pages[1]['document_page'] . '.jpg'); + $this->pdf2htmlRatio = $imagesize[0] / $this->layouts[1]['width']; + $this->scale = 20; + $this->multiply = $this->pdf2htmlRatio * $this->scale; + $this->createHTML(); } - public function makePackage() - { + public function makePackage() { parent::makePackage(); return $this->zip(); } - protected function createHTML() - { - foreach($this->layouts as $page => $infos) { + protected function createHTML() { + foreach ($this->layouts as $page => $layout) { $this->div[$page] = array(); - foreach($infos->tags as $tag) { - if ($tag instanceof wsSWF2HTMLFont) { - $this->addFont($tag, $this->pages[$page], $page); - } else if ($tag instanceof wsSWF2HTMLParagraph) { - $this->addParagraph($tag, $this->div[$page], $page); - } + $document_id = $this->pages[$page]['document_id']; + foreach ($layout->xpath('//a') as $div) { + $this->div[$page][] = $this->addCSSText($div, $document_id); } } mkdir($this->vdir . '/style', 0777, true); mkdir($this->vdir . '/contents', 0777, true); mkdir($this->vdir . '/images', 0777, true); - mkdir($this->vdir . '/fonts', 0777, true); file_put_contents($this->vdir . '/style/style.css', $this->writeCSS()); - foreach($this->div as $n => $page) { + foreach ($this->div as $n => $page) { file_put_contents($this->vdir . '/contents/p' . $n . '.html', $this->writePage($page)); } $this->writeFonts(); $this->writeImages(); } - protected function writeFonts() - { + protected function writeFonts() { $fext = array('ttf', 'eot', 'svg', 'svgz', 'woff'); - foreach($this->fonts as $font) { - if (!$font['embed']) { - return; - } - foreach($fext as $ext) { - copy($font['file'] . '.' . $ext, $this->vdir . '/fonts/' . $font['name'] . '.' . $ext); + foreach ($this->cssFont as $font => $index) { + list($font, $document_id) = explode('//', $font); + foreach ($fext as $ext) { + copy(WS_DOCS . '/' . $document_id . "/fonts/web/" . $font . '.' . $ext, $this->vdir . '/style/F' . $index . '.' . $ext); } } } - protected function writeImages() - { + protected function writeImages() { $resolutions = array(36, 72, 150); - foreach($resolutions as $r) { + foreach ($resolutions as $r) { mkdir($this->vdir . '/images/' . $r, 0777); } - foreach($this->pages as $page => $infos) { - foreach($resolutions as $r) { + foreach ($this->pages as $page => $infos) { + foreach ($resolutions as $r) { copy(WS_DOCS . '/' . $infos['document_id'] . '/html/h' . $r . '-' . $infos['document_page'] . '.jpg', $this->vdir . '/images/' . $r . '/p' . $page . '.jpg'); } } } - protected function writePage($page) - { + protected function writePage($page) { $res = ''; - foreach($page as $div) { - $res .= $this->writeDiv($div); + foreach ($page as $div) { + $res .= $this->writeSpan($div); } return $res; } - protected function writeDiv($div) - { - $res = '
'; - foreach($div['span'] as $span) { - $res .= $this->writeSpan($span); + protected function writeSpan($span) { + if ($span === false) { + return ''; } - $res .= '
'; - return $res; - } - protected function writeSpan($span) - { - $res = 'coef) . 'px;top:' . ($span['top'] * $this->coef) . 'px" '; - $res .= 'class="c' . $span['color'] . ' s' . $span['size'] . ' f' . $span['font'] . '"'; - $res .= '>'; + $top = round($span['y'] * $this->multiply, 2); + $left = round($span['x'] * $this->multiply, 2); + + $class = ''; + if (!is_null($span['color'])) { + $class.=' c' . $span['color']; + } + if (!is_null($span['size'])) { + $class.=' s' . $span['size']; + } + if (!is_null($span['font'])) { + $class.=' f' . $span['font']; + } + if (!is_null($span['wordSpacing'])) { + $class.=' w' . $span['wordSpacing']; + } + if (!is_null($span['letterSpacing'])) { + $class.=' l' . $span['letterSpacing']; + } + if (!is_null($span['rotation'])) { + $class.=' r' . $span['rotation']; + } + + $class = trim($class); + + $res = '
'; $res .= htmlentities($span['text'], ENT_NOQUOTES, 'UTF-8'); - $res .= ''; + $res .= '
'; return $res; } - protected function writeCSS() - { + protected function writeCSS() { $res = array(); - foreach($this->cssColor as $color => $index) { - $res[] = '.c' . $index . '{color:' . $color . ';}'; - } - - foreach($this->cssSize as $size => $index) { - $size = ($size/(20*16))*$this->coef; - $res[] = '.s' . $index . '{font-size:' . $size . 'em;}'; - } - - foreach($this->fonts as $id => $font) { - if ($font['embed']) { - $svg = simplexml_load_file($font['file'] . '.svg'); - foreach($svg->defs->font as $f) { - $svgid = $f['id']; - break; - } - $res[] = "@font-face{font-family:'" . $font['name'] . "';src:url('" . $font['url'] . ".eot');src:url('" . $font['url'] . ".eot?#iefix') format('eot'),url('" . $font['url'] . ".woff') format('woff'),url('" . $font['url'] . ".ttf') format('truetype'),url('" . $font['url'] . ".svgz#" . $svgid . "') format('svgz'),url('" . $font['url'] . ".svg#" . $svgid . "') format('svg');font-weight:normal;font-style:normal;}"; - $res[] = '.f' . $font['index'] . '{font-family:' . $font['name'] . ',Arial,Helvetica;}'; - } else { - $res[] = '.f' . $font['index'] . '{font-family:' . $font['realname'] . ',Arial,Helvetica;}'; - } + foreach ($this->cssColor as $color => $index) { + $res[] = '.c' . $index . '{color:#' . $color . '}'; } - return implode("\n", $res); - } - protected function addFont($tag, $infos, $page) - { - $this->fontsNames[$tag->id . ',' . $page] = $tag->name; - if (isset($this->fonts[$tag->name])) { - return; + foreach ($this->cssSize as $size => $index) { + $size*=$this->multiply; + // Point to pixel conversion + $res[] = '.s' . $index . '{font-size:' . $size . 'px}'; } - $index = $this->fontsCount; - $file = WS_DOCS . '/' . $infos['document_id'] . '/fonts/web/' . $tag->name; - $embed = file_exists($file . '.ttf'); - $this->fonts[$tag->name] = array('index' => $index, 'realname' => $tag->name, 'name' => 'FB' . $index, 'file' => $file, 'embed' => $embed, 'url' => '../fonts/FB' . $index); - $this->fontsCount++; - } - protected function addParagraph($tag, &$div, $page) - { - $d = array('span' => array(), 'left' => $tag->left, 'top' => $tag->top); - foreach($tag->textes as $text) { - $s = $this->addCSSText($text, $page); - if ($s === false) { - continue; - } - $d['span'][] = $s; + foreach ($this->cssLetterSpacing as $letterspacing => $index) { + $letterspacing*=$this->multiply; + $res[] = '.l' . $index . '{letter-spacing:' . $letterspacing . 'px}'; } - $div[] = $d; + + foreach ($this->cssWordSpacing as $wordspacing => $index) { + $wordspacing*=$this->multiply; + $res[] = '.w' . $index . '{word-spacing:' . $wordspacing . 'px}'; + } + + foreach ($this->cssRotation as $rotation => $index) { + $rotation*= - 1; + $res[] = '.r' . $index . '{-webkit-transform: rotate(' . $rotation . 'deg);-moz-transform: rotate(' . $rotation . 'deg)}'; + } + + foreach ($this->cssFont as $font => $index) { + list($font, $document_id) = explode('//', $font); + $res[] = "@font-face{font-family:F" . $index . ";src:url('F" . $index . ".eot');src:url('F" . $index . ".eot?#iefix') format('eot'),url('F" . $index . ".woff') format('woff'),url('F" . $index . ".ttf') format('truetype'),url('F" . $index . ".svgz#" . $font . "') format('svgz'),url('F" . $index . ".svg#" . $font . "') format('svg')}"; + $res[] = '.f' . $index . '{font-family:F' . $index . ',Arial,Helvetica}'; + } + return implode("\n", $res); } - protected function addCSSText($text, $page) - { - $alpha = intval(substr($text->color, -2), 16); + protected function addCSSText($l, $document_id) { + $alpha = intval(substr($l['color'], 1, 2), 16); + $text = (string) $l; + if ($text == '') { + return false; + } if ($alpha == 0) { return false; } - return array('text' => $text->text, - 'color' => $this->getCSSColor($text->color), - 'size' => $this->getCSSSize($text->size), - 'font' => $this->getCSSFont($text->font, $page), - 'left' => $text->x, - 'top' => $text->y); + return array('text' => $text, + 'color' => $this->getCSSColor($l['color']), + 'size' => $this->getCSSSize($l['size']), + 'font' => $this->getCSSFont($l['font'], $document_id), + 'letterSpacing' => $this->getCSSLetterSpacing($l['letterspacing']), + 'wordSpacing' => $this->getCSSWordSpacing($l['wordspacing']), + 'rotation' => $this->getCSSRotation($l['rotation']), + 'x' => $this->normalizeFloatValue($l['x']), + 'y' => $this->normalizeFloatValue($l['y'])); } - protected function getCSSSize($size) - { + protected function getCSSSize($size) { + $size = $this->normalizeFloatValue($size); return $this->getIndex($size, $this->cssSize); } - protected function getCSSFont($font, $page) - { - $name = $this->fontsNames[$font . ',' . $page]; + protected function getCSSFont($font, $document_id) { - return $this->fonts[$name]['index']; + return $this->getIndex($font . "//" . $document_id, $this->cssFont); } - protected function getCSSColor($color) - { - if (strlen($color) > 7) { - $color = substr($color, 0, 7); + protected function getCSSColor($color) { + $color = trim($color, '#'); + if (strlen($color) > 6) { + $color = substr($color, 2, 6); + } + if ($color == '000000') { + return null; } return $this->getIndex($color, $this->cssColor); } - protected function getIndex($value, &$tab) - { - $value = (string)$value; + protected function getCSSLetterSpacing($letterspacing) { + $letterspacing = $this->normalizeFloatValue($letterspacing); + if ($letterspacing == 0) { + return null; + } + + return $this->getIndex($letterspacing, $this->cssLetterSpacing); + } + + protected function getCSSWordSpacing($wordspacing) { + $wordspacing = $this->normalizeFloatValue($wordspacing); + if ($wordspacing == 0) { + return null; + } + return $this->getIndex($wordspacing, $this->cssWordSpacing); + } + + protected function getCSSRotation($rotation) { + $rotation = round($rotation); + if ($rotation == 0) { + return null; + } + return $this->getIndex($rotation, $this->cssRotation); + } + + protected function getIndex($value, &$tab) { + $value = (string) $value; if (isset($tab[$value])) { return $tab[$value]; } - $res = count($tab); + $res = $this->base36(count($tab)); $tab[$value] = $res; return $res; } - public function __destruct() - { + protected function normalizeFloatValue($value) { + $value = str_replace(',', '.', $value); + $value = (float) $value; + $value = round($value, 3); + return $value; + } + + protected function base36($val) { + $base = 36; + $chars = '0123456789abcdefghijklmnopqrstuvwxyz'; + $str = ''; + do { + $i = $val % $base; + $str = $chars[$i] . $str; + $val = ($val - $i) / $base; + } while ($val > 0); + return $str; } + + public function __destruct() { + + } + } ?> \ No newline at end of file -- 2.39.5