From e59a2dd54dddc027210b0a1601bff9a8512a34f1 Mon Sep 17 00:00:00 2001 From: "vincent@cubedesigners.com" Date: Thu, 15 Oct 2020 17:31:17 +0000 Subject: [PATCH] wip #3954 @6 --- inc/ws/Controlleur/class.ws.flash.php | 20 +- inc/ws/DAO/class.ws.dao.book.php | 55 +--- inc/ws/Metier/class.ws.book.php | 173 ++++++---- inc/ws/Metier/class.ws.document.php | 311 ++++-------------- inc/ws/Util/class.ws.pdf.convert.php | 55 +++- inc/ws/Util/class.ws.tools.php | 150 +-------- .../html5/app/class.ws.html5.app.compiler.php | 4 - .../html5/master/class.ws.html5.compiler.php | 103 +----- 8 files changed, 256 insertions(+), 615 deletions(-) diff --git a/inc/ws/Controlleur/class.ws.flash.php b/inc/ws/Controlleur/class.ws.flash.php index 0c06c8cd9..20ae31f7a 100644 --- a/inc/ws/Controlleur/class.ws.flash.php +++ b/inc/ws/Controlleur/class.ws.flash.php @@ -369,6 +369,7 @@ class wsFlash extends cubeFlashGateway $docs = array(); $defaultNum = array(); foreach ($pages as $page => $info) { + $book->getFile($page, 'jpg', 150, true, true); $file = WS_DOCS . '/' . $info['document_id'] . '/p' . $info['document_page'] . '.jpg'; if (!file_exists($file)) { $info['resolution'] = 150; @@ -766,16 +767,6 @@ class wsFlash extends cubeFlashGateway $daoDoc = new wsDAODocument($core->con); $nb_pages = count($pages); $this->xml->addChild('pages', $nb_pages); - $total_size = 0; - - foreach ($pages as $page => $info) { - $docdir = wsDocument::getDir($info['document_id']); - $file = $docdir . '/p' . $info['document_page'] . '.swf'; - $total_size += filesize($file); - } - $average_size = $total_size / $nb_pages; - $total = self::formatSize($total_size); - $average = self::formatSize($average_size); $firstDoc = $daoDoc->selectById($pages[1]['document_id']); $size = $firstDoc->generalInfos['size']; $this->xml->addChild('width', $size[0]); @@ -785,13 +776,6 @@ class wsFlash extends cubeFlashGateway $res .= "\n"; $res .= '' . __('Dimensions') . ' : ' . "\n"; $res .= round($size[0], 3) . ' x ' . round($size[1], 3) . ' pts' . "\n"; - $res .= "\n"; - $res .= '' . __('Taille totale des pages') . ' : ' . "\n"; - $res .= $total . "\n"; - $res .= "\n"; - $res .= '' . __('Taille moyenne des pages') . ' : ' . "\n"; - $res .= $average . "\n"; - $res .= "\n"; $this->xml->addChild('infos', $res); } @@ -847,6 +831,8 @@ class wsFlash extends cubeFlashGateway global $core; $dao = new wsDAOBook($core->con); $dao->setComposition($this->args['book_id'], json_decode($this->args['pages'])); + // Begin to generate files + $dao->compile($this->args['book_id']); } public function getTexts() diff --git a/inc/ws/DAO/class.ws.dao.book.php b/inc/ws/DAO/class.ws.dao.book.php index c7f1421a2..8759df48b 100644 --- a/inc/ws/DAO/class.ws.dao.book.php +++ b/inc/ws/DAO/class.ws.dao.book.php @@ -1190,42 +1190,16 @@ class wsDAOBook extends commonDAO return; } - $v1 = $v2 = $html5 = false; - - if ($version == 'all') { - $v1 = $v2 = $html5 = true; - } else if ($version == '1') { - $v1 = true; - } else if ($version == '2') { - $v2 = true; - } elseif ($version == 'html5') { - $html5 = true; - } - if (null === $book) { $book = $this->selectById($book_id); } $pages = $this->getPagesOfBook($book_id); - if (!$force) { - $v1 = $v1 && !$this->isUpToDate($book, 1); - $v2 = $v2 && !$this->isUpToDate($book, 2); - $html5 = $html5 && !$this->isUpToDate($book, 'html5'); - } else { - $v1 = false; - $html5 = true; - $v2 = true; - } - $res = ''; - if ($html5) { - fb(time(), 'Compile HTML5'); - $this->compilePDF($book, $pages); - $res .= $this->compileHTML5($book_id, $book, $dev, $delete); - $this->touchCompile($book_id, 'html5'); - } + $this->compilePDF($book, $pages); + $res .= $this->compileHTML5($book_id, $book, $dev, $delete); + $this->touchCompile($book_id, 'html5'); - fb(time(), 'End Compile'); return $res; } @@ -1267,31 +1241,8 @@ class wsDAOBook extends commonDAO $htmlCompiler->compile($delete); self::$lastHTML5Compiler = $htmlCompiler; - } - /* public function indexPDF($book, $pages) { - $indexPath = WS_BOOKS . '/search/' . $book->book_id; - - Zend_Search_Lucene_Analysis_Analyzer::setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive()); - - if (file_exists($indexPath)) { - files::deltree($indexPath); - } - $index = Zend_Search_Lucene::create($indexPath); - - foreach ($pages as $i => $infos) { - $doc = new Zend_Search_Lucene_Document(); - $doc->addField(Zend_Search_Lucene_Field::Text('url', '#' . $i)); - $doc->addField(Zend_Search_Lucene_Field::UnStored('contents', file_get_contents(wsDocument::getDir($infos['document_id']) . 'p' . $infos['document_page'] . '.txt'))); - $index->addDocument($doc); - } - - $c = $this->con->openCursor('books'); - $c->lucene_time = TIME; - $c->update('WHERE book_id=' . $book->book_id); - } */ - public function compilePDF($book, $pages) { $res = wsUtil::compilePDF($book, $pages); diff --git a/inc/ws/Metier/class.ws.book.php b/inc/ws/Metier/class.ws.book.php index 104649a05..747f28911 100644 --- a/inc/ws/Metier/class.ws.book.php +++ b/inc/ws/Metier/class.ws.book.php @@ -1,82 +1,109 @@ $varname) || is_object($this->$varname)) { - return $this->$varname; - } - if ($this->$varname == '') { - $this->$varname = array(); - } else { - $this->$varname = json_decode($this->$varname, in_array($varname, $assoc)); - } - return $this->$varname; - } - if ($varname == 'parametres') { - if ($this->parametres instanceof wsBookParametres) { - return $this->parametres; - } + $classic = array('chapters', 'specialLinks', 'specialRulers', 'traductions'); + $assoc = array('specialLinks', 'specialRulers'); - $p = unserialize($this->parametres); - if (!$p || $p->isEmpty()) { - $p = new wsBookParametres($this); - } else { - $p->setParent($this); - } - $this->parametres = $p; - return $this->parametres; - } + if (in_array($varname, $classic)) { + if (is_array($this->$varname) || is_object($this->$varname)) { + return $this->$varname; + } + if ($this->$varname == '') { + $this->$varname = array(); + } else { + $this->$varname = json_decode($this->$varname, in_array($varname, $assoc)); + } + return $this->$varname; + } + if ($varname == 'parametres') { + if ($this->parametres instanceof wsBookParametres) { + return $this->parametres; + } - return $this->$varname; - } + $p = unserialize($this->parametres); + if (!$p || $p->isEmpty()) { + $p = new wsBookParametres($this); + } else { + $p->setParent($this); + } + $this->parametres = $p; + return $this->parametres; + } + + return $this->$varname; + } + + public function getFile($page, $format = 'jpg', $resolution = 150, $withText = true, $withGraphics = true, $version = 'html') + { + $p = wsDAOBook::getDocumentPage($this->book_id, $page); + if (!isset($this->_docs[$p['document_id']])) { + global $core; + $dao = new wsDAODocument($core->con); + $this->_docs[$p['document_id']] = $dao->selectById($p['document_id']); + } + $doc = $this->_docs[$p['document_id']]; + return $doc->getFile($p['document_page'], $format, $resolution, $withText, $withGraphics, $version); + } + + public function getThumbFile($page, $format) + { + $thumbpdf = WS_BOOKS . '/working/' . $this->book_id . '/' . $this->parametres->pdfThumbnails; + if ($this->parametres->pdfThumbnails && file_exists($thumbpdf)) { + + return wsPDFConvert::getThumbFromPDF($thumbpdf, $page, $format); + + } + return $this->getFile($page, $format, 'thumb'); + } } \ No newline at end of file diff --git a/inc/ws/Metier/class.ws.document.php b/inc/ws/Metier/class.ws.document.php index a6283ac7d..44faa63ed 100644 --- a/inc/ws/Metier/class.ws.document.php +++ b/inc/ws/Metier/class.ws.document.php @@ -385,8 +385,18 @@ class wsDocument extends cubeMetier if ($format === 'jpeg') { $format = 'jpg'; } + if ($format === 'svg') { + $version = 'html'; + } + + if ($resolution === 'thumb') { + $withGraphics = true; + $withText = true; + $version = ''; + } - $dir = $this->out . '/' . $version . '/'; + + $dir = rtrim($this->out . $version, '/') . '/'; if ($format === 'svg') { $prefix = $withGraphics ? 'f' : 't'; $file = $dir . $prefix . 'o' . $page; @@ -396,23 +406,36 @@ class wsDocument extends cubeMetier $file .= '.svg'; } else if ($format === 'png' || $format === 'jpg') { $prefix = $withText ? 't' : 'h'; - $file = $dir . $prefix . $resolution . '-' . $page . '.' . $format; + if ($resolution === 'thumb') { + $file = $dir . 'p' . $page . '.' . $format; + } else { + $file = $dir . $prefix . $page . '-' . $resolution . '.' . $format; + } } if (!file_exists($file)) { - $this->makeFile($file, $page, $format, $resolution, $withText, $version); + $this->makeFile($file, $page, $format, $resolution, $withText, $withGraphics, $version); } return $file; } - public function makeFile($file, $page, $format = 'jpg', $resolution = 150, $withText = true, $withGraphics = true, $version = 'html') + public function makeFile($file, $page, $format = 'jpg', $resolution = 150, $withText = true, $withGraphics = true) { if ($format === 'jpeg') { $format = 'jpg'; } if ($format === 'svg') { - + if ($withGraphics) { + $this->makeOptimizedSVGFile($page, $resolution, $file); + } else { + $this->makeTextSVGFile($page, $file); + } } else if ($format === 'png' || $format === 'jpg') { - wsPDFConvert::makeShotPNM($this->getSplittedPDFPage($page), $file, 1, '', $resolution * $this->getResolutionRatio(), 85, 4, $withText, null, null, $format); + if ($resolution === 'thumb') { + wsPDFConvert::makeMiniShot($this->getSplittedPDFPage($page), $file, 1, $format); + } else { + $rr = version === 'html' ? $this->getResolutionRatio() : $this->getMobileFirstRatio(); + wsPDFConvert::makeShotPNM($this->getSplittedPDFPage($page), $file, 1, '', $resolution * $rr, 85, 4, $withText, null, null, $format); + } } } @@ -446,6 +469,8 @@ class wsDocument extends cubeMetier $this->makeMiniShot($page); // Image for link editor $this->getFile($page, 'jpg', 150, true, true); + // Make SVG base file + $this->makeSVGFile($page, false); } } @@ -505,237 +530,37 @@ class wsDocument extends cubeMetier return 620 / $this->generalInfos['size'][0]; } - 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 ($in === null) { - $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) - { - $tmp = cubeFiles::tempnam(); - $pttopx = 1; - - $s = $this->generalInfos['page'][$page]['size']; - $w = floor(($s[0] * $pttopx) * ($resolution / 72)); - $h = floor(($s[1] * $pttopx) * ($resolution / 72)); - - $antialiasing = $antialiasing ? 'yes' : 'no'; - $freetype = $texts ? 'yes' : 'no'; - // Exporte les fichiers - $pdftoppm = new CubeIT_CommandLine('pdftoppm', null, true); - $pdftoppm->setPath(CONVERTER_PATH); - - $pdftoppm->setArg('f', 1); - $pdftoppm->setArg('l', 1); - $pdftoppm->setArg('-cropbox'); - $pdftoppm->setArg('-freetype ' . $freetype); - $pdftoppm->setArg('-singlefile'); - $pdftoppm->setArg('-aa ' . $antialiasing); - $pdftoppm->setArg('-aaVector ' . $antialiasing); - $pdftoppm->setArg('r', $resolution); - $pdftoppm->setArg('W', $w); - $pdftoppm->setArg('H', $h); - $pdftoppm->setArg(null, $this->getSplittedPDFPage($page)); - $pdftoppm->setArg(null, $tmp); - $pdftoppm->execute(); - $pdftoppm->debug(); - - $tmp .= '.ppm'; - - $jpegfile = $this->out . $prefix . $page . '.jpg'; - $pngfile = $this->out . $prefix . $page . '.png'; - - if (file_exists($tmp)) { - $cjpeg = new cubeCommandLine('/opt/mozjpeg/bin/cjpeg', null, true); - $cjpeg->setArg('-quality ' . ($quality + 6)); - $cjpeg->setArg('-outfile ' . $jpegfile); - $cjpeg->setArg(null, $tmp); - $cjpeg->execute(); - $this->addToLog($cjpeg, false, $page); - - $pnmtopng = new CubeIT_CommandLine('pnmtopng', $pngfile, false); - $pnmtopng->setArg('-background white'); - $pnmtopng->setArg(null, $tmp); - $pnmtopng->execute(); - - unlink($tmp); - } - } - protected function isCropped() { return $this->autocrop || $this->manualcrop || $this->autocut || $this->manualcut; } - 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); - } - $this->makeSVGFile($page, false); - } - - public function makeMobileFirstFiles($page) - { - // Then make HD background shots - $resolutions = array(300 => 85, 150 => 85, 36 => 85); - $rratio = $this->getMobileFirstRatio(); - foreach ($resolutions as $r => $q) { - $this->makeShotPNM($page, 'mf/h' . $r . '-', $r * $rratio, $q, 4, null, false); - $this->makeShotPNM($page, 'mf/t' . $r . '-', $r * $rratio, $q); - } - } - - public function makeSVGFile($page, $force = true) + public function makeSVGFile($page, $force = false) { $svgFile = $this->out . '/html/fp' . $page . '.svg'; if (!$force && file_exists($svgFile) && filesize($svgFile) > 0) { return; } - - $pdftocairo = new cubeCommandLine('pdftocairo'); - $pdftocairo->setPath(CONVERTER_PATH); - $pdftocairo->setArg('f', 1); - $pdftocairo->setArg('l', 1); - $pdftocairo->setArg('r', 300); - $pdftocairo->setArg(null, '-expand'); - $pdftocairo->setArg(null, '-svg'); - $pdftocairo->setArg(null, $this->getSplittedPDFPage($page)); - $pdftocairo->setArg(null, $svgFile); - $pdftocairo->execute(); - - $this->addToLog($pdftocairo, true, $page); + wsPDFConvert::makeBaseSVGFile($this->getSplittedPDFPage($page), $svgFile, 1); + return $svgFile; } - public static function extractTexts($svgFile, $textFile, $force = false) + public function makeTextSVGFile($page, $out, $force = false) { - $do = $force || !file_exists($textFile) || filesize($textFile) < 100 || filemtime($svgFile) > filemtime($textFile) || filemtime($textFile) < filemtime(__FILE__); + $in = $this->makeSVGFile($page); + $do = $force || !file_exists($out) || filesize($out) < 100 || filemtime($in) > filemtime($out) || filemtime($out) < filemtime(__FILE__); if (!$do) { return; } + wsPDFConvert::makeTextSVGFile($in, $out); + wsTools::optimizeSVG($out, $out); + } - $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()); + public function makeOptimizedSVGFile($page, $resolution, $out) + { + $in = $this->makeSVGFile($page); + wsTools::optimizeSVGImages($in, $out, $resolution); + wsTools::optimizeSVG($out, $out); } protected function getSplittedPDFPage($page) @@ -817,27 +642,27 @@ class wsDocument extends cubeMetier return $res; } - public static function makeHTML5FilesIfNotExists($document_id, $document_page, $format = 'jpg') - { - global $core; - - $path = self::getDir($document_id) . '/html/h150-' . $document_page . '.' . $format; - if (!file_exists($path)) { - $dao = new wsDAODocument($core->con); - $doc = $dao->selectById($document_id); - $doc->makeHTML5Files($document_page); - } - } - - public static function makeMobileFirstFilesIfNotExists($document_id, $document_page, $format = 'jpg') - { - global $core; - - $path = self::getDir($document_id) . '/mf/h150-' . $document_page . '.' . $format; - if (!file_exists($path)) { - $dao = new wsDAODocument($core->con); - $doc = $dao->selectById($document_id); - $doc->makeMobileFirstFiles($document_page); - } - } +// public static function makeHTML5FilesIfNotExists($document_id, $document_page, $format = 'jpg') +// { +// global $core; +// +// $path = self::getDir($document_id) . '/html/h150-' . $document_page . '.' . $format; +// if (!file_exists($path)) { +// $dao = new wsDAODocument($core->con); +// $doc = $dao->selectById($document_id); +// $doc->makeHTML5Files($document_page); +// } +// } +// +// public static function makeMobileFirstFilesIfNotExists($document_id, $document_page, $format = 'jpg') +// { +// global $core; +// +// $path = self::getDir($document_id) . '/mf/h150-' . $document_page . '.' . $format; +// if (!file_exists($path)) { +// $dao = new wsDAODocument($core->con); +// $doc = $dao->selectById($document_id); +// $doc->makeMobileFirstFiles($document_page); +// } +// } } \ No newline at end of file diff --git a/inc/ws/Util/class.ws.pdf.convert.php b/inc/ws/Util/class.ws.pdf.convert.php index f39527132..4749d2ce2 100644 --- a/inc/ws/Util/class.ws.pdf.convert.php +++ b/inc/ws/Util/class.ws.pdf.convert.php @@ -26,6 +26,59 @@ class wsPDFConvert self::makeShot($in, $out, $page, $prefix, null, $quality, $antialiasing, $method, -1, $h, $format); } + public static function makeBaseSVGFile($in, $out, $page) + { + $pdftocairo = new CubeIT_CommandLine('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, $in); + $pdftocairo->setArg(null, $out); + $pdftocairo->execute(); + } + + public static function makeTextSVGFile($in,$out){ + $svg = new DOMDocument(); + $svg->preserveWhiteSpace = false; + $svg->load($in, 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($out, $svg->saveXML()); + } + public static function makeShot($in, $out, $page, $prefix = '', $resolution = 72, $quality = 90, $antialiasing = 4, $method = 'PNM', $width = null, $height = null, $format = 'jpg') { $error = false; @@ -93,7 +146,7 @@ class wsPDFConvert $antialiasing = $antialiasing ? 'yes' : 'no'; $freetype = $texts ? 'yes' : 'no'; // Exporte les fichiers - $pdftoppm = new cubeCommandLine('pdftoppm', null, true); + $pdftoppm = new cubeCommandLine('/usr/local/bin/pdftoppm', null, true); $pdftoppm->setPath(CONVERTER_PATH); $pdftoppm->setArg('f', $page); diff --git a/inc/ws/Util/class.ws.tools.php b/inc/ws/Util/class.ws.tools.php index 6b7a43950..ff659c7e3 100644 --- a/inc/ws/Util/class.ws.tools.php +++ b/inc/ws/Util/class.ws.tools.php @@ -57,144 +57,30 @@ class wsTools $webvideo->execute(); } - public static function colorizeAndRasterizeIcon($iconSet, $icon, $colors, $dest, $scale, &$w, &$h, $makepng = true) + public static function optimizeSVG($in, $out) { - // Init directory - if (is_string($colors)) { - $colors = array('colorize' => $colors); - } - $hash = sha1(json_encode($colors)); - foreach ($colors as $k => $v) { - $colors[$k] = wsHTML5::colorToArray($colors[$k]); - } - - $e = explode('-', $icon); - $type = $e[0]; - - if ($type == 'nav') { - $svgRef = WS_ICONS . '/' . $iconSet . '/mobile/' . $icon . '.svg'; - if (!file_exists($svgRef)) { - $iconSet = 1; - $svgRef = WS_ICONS . '/' . $iconSet . '/mobile/' . $icon . '.svg'; - } - - $dirColorized = WS_ICONS . '/' . $iconSet . '/mobile/colorized/' . $hash . '/'; - $svgColorized = $dirColorized . '/' . $icon . '.svg'; - } else { - $dirColorized = WS_ICONS . '/' . $type . '/colorized/' . $hash; - $svgRef = WS_ICONS . '/' . $type . '/' . $icon . '.svg'; - $svgColorized = $dirColorized . '/' . $icon . '.svg'; - } - - if (!file_exists($dirColorized)) { - mkdir($dirColorized, 0777, true); - } - - - // SVG - $time = max(filemtime(__FILE__), filemtime($svgRef)); - if (!file_exists($svgColorized) || filemtime($svgColorized) <= $time) { - $svg = file_get_contents($svgRef); - // Colorize it - foreach ($colors as $k => $v) { - $replace = "#" . $v['hex']; - if ($v['opacity'] < 1) { - $replace .= '" stroke-opacity="' . $v['opacity']; - } - $svg = str_replace('$s' . $k, $replace, $svg); - - - $replace = "#" . $v['hex']; - if ($v['opacity'] < 1) { - $replace .= '" fill-opacity="' . $v['opacity']; - } - $svg = str_replace('$' . $k, $replace, $svg); - } - file_put_contents($svgColorized, $svg); - } - self::copy($svgColorized, $dest . '/' . $icon . '.svg'); - - // PNG - $png = $dirColorized . '/' . $icon . '.png'; - $time = max(filemtime(__FILE__), filemtime($svgColorized)); - if (!file_exists($png) || filemtime($png) <= $time) { - $svg = simplexml_load_file($svgColorized); - $w = (string)$svg['width']; - $h = (string)$svg['height']; - $w = rtrim($w, 'px'); - $h = rtrim($h, 'px'); - // Finally rasterize it - $batik = new cubeCommandLine('inkscape'); - $batik->setArg('z'); - $batik->setArg('e', $png); - $batik->setArg('w', floatval($w) * $scale); - $batik->setArg('h', floatval($h) * $scale); - $batik->setManualArg($svgColorized); - $batik->execute(); - } - - if (file_exists($png)) { - $dim = getimagesize($png); - $w = $dim[0] / $scale; - $h = $dim[1] / $scale; - } - - if ($makepng) { - self::copy($png, $dest . '/' . $icon . '.png'); + $cmd = "timeout -s 1 120 /usr/local/bin/svgcleaner --allow-bigger-file --paths-coordinates-precision 3 --copy-on-error --stdout $in"; + $svg = `$cmd`; + if ($svg == '') { + copy($in, $out); + return; } + file_put_contents($out, $svg); } - public static function optimizeSVG($original, $optimized, $resolutions = [], $force = false) + public static function optimizeSVGImages($in, $out, $resolution) { - - if (!file_exists($original)) { - return 'doesnt exists'; - } - - $baseoptimized = str_replace('%s', '', $optimized); - - $expireoriginallimit = max(filemtime($original), filemtime(__FILE__)); - - $notexists = !file_exists($baseoptimized) || filesize($baseoptimized) < 60; - if (!$notexists) { - $cleanerexpired = filemtime($baseoptimized) < filemtime('/usr/local/bin/svgcleaner'); - $originalexpired = filemtime($baseoptimized) < $expireoriginallimit; - } else { - $cleanerexpired = false; - $originalexpired = false; - } - - $optimize = $force || - $notexists || - $cleanerexpired || - $originalexpired; - - if ($optimize) { - $cmd = "timeout -s 1 120 /usr/local/bin/svgcleaner --allow-bigger-file --paths-coordinates-precision 3 --copy-on-error --stdout $original"; - $svg = `$cmd`; - if ($svg == '') { - $svg = file_get_contents($original); - } - $svg = substr_replace($svg, ' preserveAspectRatio="none" ', 5, 0); - - $fname = $baseoptimized; - file_put_contents($fname, $svg); - - if (count($resolutions) > 0) { - foreach ($resolutions as $resolution) { - self::$_r = $resolution; - $osvg = preg_replace_callback('|\]*)\>|', 'wsTools::optimizeRaster', $svg); - $osvg = preg_replace('/^]*>/', '$0', $osvg); - $ofname = sprintf($optimized, '-' . $resolution); - file_put_contents($ofname, $osvg); - } - } - return true; - } - return false; + $svg = file_get_contents($in); + $svg = substr_replace($svg, ' preserveAspectRatio="none" ', 5, 0); + + $osvg = preg_replace_callback('|\]*)\>|', function ($matches) use ($resolution) { + return wsTools::optimizeRaster($matches, $resolution); + }, $svg); + $osvg = preg_replace('/^]*>/', '$0', $osvg); + file_put_contents($out, $osvg); } - public static function optimizeRaster($matches) + public static function optimizeRaster($matches, $resolution) { preg_match_all('/([a-z\:\-]*)="([^"]*)"/', $matches[1], $m); @@ -212,7 +98,7 @@ class wsTools $scale = max($values[0], $values[1]); } - $resolutionScale = ($iw / $attrs['width']) * $scale * (self::$_r / 72); + $resolutionScale = ($iw / $attrs['width']) * $scale * ($resolution / 72); $dw = round($resolutionScale * $iw); $dh = round($resolutionScale * $ih); diff --git a/inc/ws/Util/html5/app/class.ws.html5.app.compiler.php b/inc/ws/Util/html5/app/class.ws.html5.app.compiler.php index 5bba1f46d..901bac2ec 100644 --- a/inc/ws/Util/html5/app/class.ws.html5.app.compiler.php +++ b/inc/ws/Util/html5/app/class.ws.html5.app.compiler.php @@ -246,10 +246,6 @@ class wsHTML5AppCompiler $svg = array('interface-back-arrow'); - foreach ($svg as $icon) { - wsTools::colorizeAndRasterizeIcon(1, $icon, $text, $this->vdir . '/images/', 4, $w, $h); - } - $caption .= "#bar{border-bottom:1px solid " . $border . "}"; $c[] = $caption; diff --git a/inc/ws/Util/html5/master/class.ws.html5.compiler.php b/inc/ws/Util/html5/master/class.ws.html5.compiler.php index 3d632e314..d156e3e8f 100644 --- a/inc/ws/Util/html5/master/class.ws.html5.compiler.php +++ b/inc/ws/Util/html5/master/class.ws.html5.compiler.php @@ -293,10 +293,7 @@ class wsHTML5Compiler $this->imageFormat = $this->book->parametres->imageFormat; - wsDocument::makeHTML5FilesIfNotExists($this->pages[1]['document_id'], $this->pages[1]['document_page'], $this->imageFormat); - $firstJpeg = wsDocument::getDir($this->pages[1]['document_id']) . 'html/h150-' . $this->pages[1]['document_page'] . '.' . $this->imageFormat; - - $imagesize = CubeIT_Image::getimagesize($firstJpeg); + $imagesize = CubeIT_Image::getimagesize($this->book->getFile(1, 'jpg', 150)); $this->pdf2htmlRatio = round(($imagesize[0] * 0.48) / $this->width, 12); $this->linkScale = $this->cssScale = $this->z * min($this->optimalWidth / $this->width, $this->optimalHeight / $this->height); @@ -1782,41 +1779,6 @@ class wsHTML5Compiler $res = array(); } - protected function writeIcons() - { - $res = array(); - // Get the colors used to colorize graphics - if ($this->theme->parametres->colorizeIcons) { - $couleurI = $this->theme->parametres->couleurI; - } else { - $couleurI = 'FFFFFF'; - } - - $couleurM = $this->theme->parametres->subTextColor; - - $bookmarksDisabledColors = array('star' => $this->theme->parametres->bookmarkStarDisabledColor, 'bookmark' => $this->theme->parametres->bookmarkBackgroundColor); - $bookmarksEnabledColors = array('star' => $this->theme->parametres->bookmarkStarEnabledColor, 'bookmark' => $this->theme->parametres->bookmarkBackgroundColor); - $subTextColor = $this->theme->parametres->subTextColor; - - $arrowsColor = $this->theme->parametres->arrowsColor; - // Set the icon list with the color - $icons = array('interface-down' => $arrowsColor, 'interface-close' => $arrowsColor, - 'interface-audio-description-on' => $arrowsColor, 'interface-audio-description-off' => $arrowsColor, - 'help-fingers' => $couleurI, 'help-mouse' => $couleurI - ); - - $this->config->iconsDimensions = array(); - $makepng = !$this->supportSVG(); - $tmpdir = CubeIT_Files::tmpdir(); - foreach ($icons as $icon => $color) { - wsTools::colorizeAndRasterizeIcon($this->theme->parametres->iconSet, $icon, $color, $tmpdir, 4, $w, $h); - $this->config->iconsDimensions[$icon] = array($w, $h); - } - $this->vdir->copyDirectory($tmpdir, 'data/images'); - $this->vdir->addTemp($tmpdir); - return $res; - } - protected function writeImages() { global $core; @@ -1824,15 +1786,15 @@ class wsHTML5Compiler switch ($this->book->parametres->mobileVersion) { case 'html5-desktop': - $this->backgroundsPrefix = array('t', 'p'); + $this->backgroundsPrefix = array(true, false); $this->svg = true; break; case 'html5-images': - $this->backgroundsPrefix = array('t'); + $this->backgroundsPrefix = array(true); $this->svg = false; break; default: - $this->backgroundsPrefix = array('p'); + $this->backgroundsPrefix = array(false); $this->svg = true; break; } @@ -1841,10 +1803,8 @@ class wsHTML5Compiler $this->config->pagesDimensions = []; if ($this->book->parametres->mobileNavigationType === 'mobilefirst') { - $makeFunction = 'makeMobileFirstFilesIfNotExists'; $imdir = 'mf'; } else { - $makeFunction = 'makeHTML5FilesIfNotExists'; $imdir = 'html'; } @@ -1854,68 +1814,28 @@ class wsHTML5Compiler $thisrasterize = in_array($page, $rasterizePages); $thisimagesvg = !$thisrasterize && $this->svg; - $thisbackgroundPrefix = $thisrasterize ? ['t'] : $this->backgroundsPrefix; - - wsDocument::$makeFunction($infos['document_id'], $infos['document_page'], $this->imageFormat); + $thisbackgroundPrefix = $thisrasterize ? [true] : $this->backgroundsPrefix; foreach ($this->getResolutions() as $r) { foreach ($thisbackgroundPrefix as $backgroundsPrefix) { - $srcPrefix = $backgroundsPrefix; - if ($backgroundsPrefix === 'p') { - $srcPrefix = 'h'; - } - $source = $docdir . $imdir . '/' . $srcPrefix . $r . '-' . $infos['document_page'] . '.' . $this->imageFormat; + $source = $this->book->getFile($page, $this->imageFormat, $r, $backgroundsPrefix, true, $imdir); if ($r == 150 && file_exists($source)) { $firstDoc = $daoDoc->selectById($infos['document_id']); $d = $firstDoc->generalInfos['page'][$infos['document_page']]['size']; $this->config->pagesDimensions[$page] = array($this->cssWidth, $d[1] * ($this->cssWidth / $d[0])); } - $ok = $this->vdir->copy($source, 'data/background/' . $r . '/' . $backgroundsPrefix . $page . '.' . $this->imageFormat); - if (!$ok && $r = 300) { - $this->maxRes = 150; - } + $this->vdir->copy($source, 'data/background/' . $r . '/' . ($backgroundsPrefix ? 't' : 'p') . $page . '.' . $this->imageFormat); } } if ($thisimagesvg) { - $full = $docdir . 'html/fp' . $infos['document_page'] . '.svg'; - $fullopt = $docdir . 'html/fo' . $infos['document_page'] . '%s.svg'; - $orig = $docdir . 'html/tp' . $infos['document_page'] . '.svg'; - $opt = $docdir . 'html/to' . $infos['document_page'] . '.svg'; - - if (!file_exists($full) || filemtime($full) < 1503671520) { - if (!isset($doc) || $doc->document_id != $infos['document_id']) { - $dao = new wsDAODocument($core->con); - $doc = $dao->selectById($infos['document_id']); - } - $doc->makeSVGFile($infos['document_page']); - } - wsDocument::extractTexts($full, $orig); - wsTools::optimizeSVG($orig, $opt); - wsTools::optimizeSVG($full, $fullopt, [150, 300]); - - if (in_array($page, $this->config->vectorPages)) { - $this->vdir->copy(str_replace('%s', '-150', $fullopt), 'data/contents/p' . $page . '.svg'); - } else { - $this->vdir->copy($opt, 'data/contents/p' . $page . '.svg'); - } + $this->vdir->copy($this->book->getFile($page, 'svg', 150, true, + in_array($page, $this->config->vectorPages), 'html'), 'data/contents/p' . $page . '.svg'); } - $thumb = false; - if ($this->book->parametres->pdfThumbnails) { - $thumb = wsPDFConvert::getThumbFromPDF(WS_BOOKS . '/working/' . $this->book->book_id . '/' . $this->book->parametres->pdfThumbnails, $page, $this->imageFormat); - } - if (!$thumb) { - - $thumb = $docdir . 'p' . $infos['document_page'] . '.' . $this->imageFormat; - if (!file_exists($thumb)) { - $doc = $daoDoc->selectById($infos['document_id']); - $doc->makeMiniShot($infos['document_page']); - } - } - $this->vdir->copy($thumb, 'data/thumbnails/p' . $page . '.' . $this->imageFormat); + $this->vdir->copy($this->book->getFile($page,$this->imageFormat,'thumb',true,true,'html'), 'data/thumbnails/p' . $page . '.' . $this->imageFormat); if ($page == 1) { $this->_makeCover($docdir . 'html/t36-' . $infos['document_page'] . '.jpg'); @@ -2057,9 +1977,6 @@ class wsHTML5Compiler $header .= '}'; $res[] = $header; - //Icons - $res = array_merge($res, $this->writeIcons()); - // Logo $logo = '#logo{'; if ($this->theme->parametres->logo) { -- 2.39.5