]> _ Git - cubeextranet.git/commitdiff
(no commit message)
authorvincent@cubedesigners.com <vincent@cubedesigners.com@f5622870-0f3c-0410-866d-9cb505b7a8ef>
Wed, 13 Jul 2011 18:56:34 +0000 (18:56 +0000)
committervincent@cubedesigners.com <vincent@cubedesigners.com@f5622870-0f3c-0410-866d-9cb505b7a8ef>
Wed, 13 Jul 2011 18:56:34 +0000 (18:56 +0000)
inc/ws/Controlleur/class.ws.flash.php
inc/ws/Util/_common.php
inc/ws/Util/class.ws.tools.php [new file with mode: 0644]
inc/ws/Util/packager/_common.php
inc/ws/Util/packager/class.ws.packager.html5.php [deleted file]
inc/ws/Util/packager/class.ws.packager.php
inc/ws/Util/packager/html5/class.ws.packager.html5.php [new file with mode: 0644]

index 1432e34920d77abe534083675a52da27dca5eab4..6d07dc57ccf38b7b08f6e21d4dbc082d80496d23 100644 (file)
@@ -181,6 +181,10 @@ class wsFlash extends cubeFlashGateway {
                        }\r
                        $dest = $dir . $fname;\r
                        move_uploaded_file($infos['tmp_name'], $dest);\r
+                       if (in_array(strtolower(files::getExtension($dest)), array('flv', 'f4v', 'mp4'))) {\r
+                               // convert uploaded file as webvideo (ogv and mp4)\r
+                               wsTools::encodeWebVideos($dest, null, true, false);\r
+                       }\r
                        $this->xml->addChild('file', $fname);\r
                        return;\r
                }\r
index ce25bae62a0294964fd6df089d821caa96ef6689..d13335f27c6f5d0142a257d45bf99f93a7e36ee0 100644 (file)
@@ -1,4 +1,5 @@
 <?php\r
+\r
 include_once(dirname(__FILE__) . '/packager/_common.php');\r
 $__autoload['wsSWF2HTML'] = dirname(__FILE__) . '/class.ws.swf2html.php';\r
 $__autoload['wsSWF2HTMLTag'] = dirname(__FILE__) . '/class.ws.swf2html.php';\r
@@ -7,5 +8,5 @@ $__autoload['wsSWF2HTMLFont'] = dirname(__FILE__) . '/class.ws.swf2html.php';
 $__autoload['wsSWF2HTMLParagraph'] = dirname(__FILE__) . '/class.ws.swf2html.php';\r
 $__autoload['wsSWF2HTMLMatrix'] = dirname(__FILE__) . '/class.ws.swf2html.php';\r
 $__autoload['wsSecureSWF'] = dirname(__FILE__) . '/class.ws.secure.swf.php';\r
-\r
+$__autoload['wsTools'] = dirname(__FILE__) . '/class.ws.tools.php';\r
 ?>
\ No newline at end of file
diff --git a/inc/ws/Util/class.ws.tools.php b/inc/ws/Util/class.ws.tools.php
new file mode 100644 (file)
index 0000000..faf132a
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+
+class wsTools {
+
+       public static function encodeWebVideos($file, $dir=null, $async=true, $force=false) {
+               if (is_null($dir)) {
+                       $dir = dirname($file);
+               }
+               $log = $dir . '/' . cubeFiles::getName($file) . '.log';
+
+               if (!$force && file_exists($log)) {
+                       return;
+               }
+
+               $webvideo = new cubeCommandLine('webvideo', $log);
+               $webvideo->setPath(CONVERTER_PATH);
+               if ($async) {
+                       $webvideo->setNohup(true);
+               }
+               $webvideo->setArg(null, $dest);
+               $webvideo->setArg(null, $dir);
+               $webvideo->execute();
+       }
+
+       public static function colorizeAndRasterizeIcon($iconSet, $icon, $color, $dest, $scale, &$w, &$h) {
+               // Init directory
+               $color = ltrim($color, '#');
+               $dirColorized = WS_ICONS . '/' . $iconSet . '/mobile/' . $color . '/';
+               if (!file_exists($dirColorized)) {
+                       mkdir($dirColorized, 0777, true);
+               }
+
+
+               // SVG
+               $svgRef = WS_ICONS . '/' . $iconSet . '/mobile/' . $icon . '.svg';
+               $svgColorized = $dirColorized . '/' . $icon . '.svg';
+
+               if (!file_exists($svgColorized) || filemtime($svgColorized) <= filemtime($svgRef)) {
+                       $svg = file_get_contents($svgRef);
+                       // Colorize it
+                       $svg = str_replace('$colorize', '#' . $color, $svg);
+                       file_put_contents($svgColorized, $svg);
+               }
+               copy($svgColorized, $dest . '/' . $icon . '.svg');
+
+               // PNG
+               $png = $dirColorized . '/' . $icon . '.png';
+               if (!file_exists($png) || filemtime($png) <= filemtime($svgColorized)) {
+                       $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('/usr/local/batik/batik-rasterizer');
+                       $batik->setArg('d', $dirColorized);
+                       $batik->setArg('m', 'image/png');
+                       if ($scale != 1) {
+                               $batik->setArg('w', $w * $scale);
+                               $batik->setArg('h', $h * $scale);
+                       }
+                       $batik->setManualArg($svgColorized);
+                       $batik->execute();
+               }
+               copy($png, $dest . '/' . $icon . '.png');
+       }
+
+}
+
+?>
index 17aca9b37dcab19e2ddafe63f4e05c402cd55c9b..caa932b1314373b25fa1273585ee9f45a063295c 100644 (file)
@@ -1,7 +1,7 @@
 <?php\r
 $__autoload['wsPackager'] = dirname(__FILE__) . '/class.ws.packager.php';\r
 $__autoload['wsPackagerHTML'] = dirname(__FILE__) . '/class.ws.packager.html.php';\r
-$__autoload['wsPackagerHTML5'] = dirname(__FILE__) . '/class.ws.packager.html5.php';\r
+$__autoload['wsPackagerHTML5'] = dirname(__FILE__) . '/html5/class.ws.packager.html5.php';\r
 $__autoload['wsPackagerWinEXE'] = dirname(__FILE__) . '/class.ws.packager.win.exe.php';\r
 $__autoload['wsPackagerWinCD'] = dirname(__FILE__) . '/class.ws.packager.win.cd.php';\r
 $__autoload['wsPackagerMacEXE'] = dirname(__FILE__) . '/class.ws.packager.mac.exe.php';\r
diff --git a/inc/ws/Util/packager/class.ws.packager.html5.php b/inc/ws/Util/packager/class.ws.packager.html5.php
deleted file mode 100644 (file)
index d5dd686..0000000
+++ /dev/null
@@ -1,591 +0,0 @@
-<?php\r
-\r
-class wsPackagerHTML5 extends wsPackager {\r
-\r
-       protected $layouts = array();\r
-       protected $cssSize = array();\r
-       protected $cssColor = array();\r
-       protected $cssOpacity = array();\r
-       protected $cssFont = array();\r
-       protected $cssWordSpacing = array();\r
-       protected $cssLetterSpacing = array();\r
-       protected $cssRotation = array();\r
-       protected $cssX = array();\r
-       protected $cssY = array();\r
-       protected $pdf2htmlRatio;\r
-       protected $scale;\r
-       protected $multiply;\r
-       protected $div = array();\r
-       protected static $resolutions = array(36, 72, 150);\r
-       protected static $uaPrefixes = array('-moz-', '-webkit-', '-o-', '-ms-', '');\r
-\r
-       public function __construct($book_id) {\r
-               parent::__construct($book_id);\r
-               $this->version = 'html5';\r
-       }\r
-\r
-       protected function preparePackage() {\r
-               parent::preparePackage();\r
-\r
-               foreach ($this->pages as $page => $infos) {\r
-                       $file = WS_DOCS . '/' . $infos['document_id'] . '/html/p' . $infos['document_page'] . '.layout';\r
-                       if (file_exists($file)) {\r
-                               $this->layouts[$page] = simplexml_load_file($file, null, LIBXML_ERR_WARNING);\r
-                       }\r
-               }\r
-\r
-               $imagesize = getimagesize(WS_DOCS . '/' . $this->pages[1]['document_id'] . '/html/h72-' . $this->pages[1]['document_page'] . '.jpg');\r
-               $this->pdf2htmlRatio = $imagesize[0] / $this->layouts[1]['width'];\r
-               $this->scale = 4;\r
-               $this->multiply = $this->pdf2htmlRatio * $this->scale;\r
-\r
-               $this->createHTML();\r
-       }\r
-\r
-       public function makePackage() {\r
-               parent::makePackage();\r
-               return $this->zip();\r
-       }\r
-\r
-       protected function createHTML() {\r
-               foreach ($this->layouts as $page => $layout) {\r
-                       $this->div[$page] = array();\r
-                       $document_id = $this->pages[$page]['document_id'];\r
-                       foreach ($layout->l as $line) {\r
-                               $this->div[$page][] = $this->addLine($line, $document_id);\r
-                       }\r
-               }\r
-               mkdir($this->vdir . '/data/images', 0777, true);\r
-               mkdir($this->vdir . '/data/contents', 0777, true);\r
-               mkdir($this->vdir . '/data/background', 0777, true);\r
-               mkdir($this->vdir . '/data/style', 0777, true);\r
-\r
-               foreach ($this->div as $n => $page) {\r
-                       file_put_contents($this->vdir . '/data/contents/p' . $n . '.html', $this->writePage($page));\r
-               }\r
-               $this->writeFonts();\r
-               $this->writeImages();\r
-               $this->writeCSS($this->vdir . '/data/style/style_%d.css');\r
-\r
-               file_put_contents($this->vdir . '/data/datas.js', $this->writeConfig());\r
-       }\r
-\r
-       protected function writeConfig() {\r
-               $config = cubeObject::merge($this->book->parametres->toStandardObject(), $this->theme->parametres->toStandardObject());\r
-               $config->id = $this->book->book_id;\r
-               return 'DATAS=' . json_encode($config) . ';';\r
-       }\r
-\r
-       protected function writeFonts() {\r
-               $fext = array('ttf', 'eot', 'svg', 'svgz', 'woff');\r
-               foreach ($this->cssFont as $font => $index) {\r
-                       list($font, $document_id) = explode('//', $font);\r
-                       foreach ($fext as $ext) {\r
-                               copy(WS_DOCS . '/' . $document_id . "/fonts/web/" . $font . '.' . $ext, $this->vdir . '/data/style/F' . $index . '.' . $ext);\r
-                       }\r
-               }\r
-       }\r
-\r
-       protected function writeIcons() {\r
-               $res = array();\r
-               // Get the colors used to colorize graphics\r
-               if ($this->theme->parametres->colorizeIcons) {\r
-                       $couleurI = '#' . $this->theme->parametres->couleurI;\r
-               } else {\r
-                       $couleurI = '#FFFFFF';\r
-               }\r
-               $arrowsColor = '#' . $this->theme->parametres->arrowsColor;\r
-               // Set the icon list with the color\r
-               $icons = array('nav-bookmark' => $couleurI, 'nav-friend' => $couleurI, 'nav-help' => $couleurI, 'nav-index' => $couleurI, 'nav-sommaire' => $couleurI,\r
-                       'next' => $arrowsColor, 'previous' => $arrowsColor, 'search' => $couleurI);\r
-\r
-               foreach ($icons as $icon => $color) {\r
-                       // Get content of the svg\r
-                       $svg = file_get_contents(WS_ICONS . '/' . $this->theme->parametres->iconSet . '/mobile/' . $icon . '.svg');\r
-                       // Colorize it\r
-                       $svg = str_replace('$colorize', $color, $svg);\r
-                       // Write the file\r
-                       file_put_contents($this->vdir . '/data/images/' . $icon . '.svg', $svg);\r
-                       $svg = simplexml_load_string($svg);\r
-                       $w = (string) $svg['width'];\r
-                       $h = (string) $svg['height'];\r
-                       $w = rtrim($w, 'px');\r
-                       $h = rtrim($h, 'px');\r
-                       // Finally rasterize it\r
-                       $this->rasterizeSVG($this->vdir . '/data/images/' . $icon . '.svg', 'image/png', $w, $h, 4);\r
-                       $res[] = '#icon-' . $icon . '{width:' . $w . 'px;height:' . $h . 'px;background-image:url(data/images/' . $icon . '.svg), url(data/images/' . $icon . '.png);background-repeat:no-repeat;background-size:' . $w . 'px ' . $h . 'px}';\r
-               }\r
-               return $res;\r
-       }\r
-\r
-       protected function rasterizeSVG($file, $type, $w, $h, $scale=1) {\r
-               $batik = new cubeCommandLine('/usr/local/batik/batik-rasterizer');\r
-               $batik->setArg('d', $this->vdir . '/data/images');\r
-               $batik->setArg('m', 'image/png');\r
-               if ($scale != 1) {\r
-                       $batik->setArg('w', $w * $scale);\r
-                       $batik->setArg('h', $h * $scale);\r
-               }\r
-               $batik->setManualArg($file);\r
-               $batik->execute();\r
-       }\r
-\r
-       protected function writeImages() {\r
-\r
-               foreach (self::$resolutions as $r) {\r
-                       mkdir($this->vdir . '/data/background/' . $r, 0777);\r
-               }\r
-               foreach ($this->pages as $page => $infos) {\r
-                       foreach (self::$resolutions as $r) {\r
-                               copy(WS_DOCS . '/' . $infos['document_id'] . '/html/h' . $r . '-' . $infos['document_page'] . '.jpg', $this->vdir . '/data/background/' . $r . '/p' . $page . '.jpg');\r
-                       }\r
-               }\r
-       }\r
-\r
-       protected function writePage($page) {\r
-               $res = '';\r
-               foreach ($page as $line) {\r
-                       $res .= $this->writeLine($line);\r
-               }\r
-               return $res;\r
-       }\r
-\r
-       protected function writeLine($line) {\r
-               $line['x'] = $this->getCSSX($line['x'] * $this->multiply);\r
-               $line['y'] = $this->getCSSY($line['y'] * $this->multiply);\r
-\r
-               $class = array('l');\r
-               if (!is_null($line['rotation'])) {\r
-                       $class[] = 'r' . $line['rotation'];\r
-               }\r
-               if (!is_null($line['x'])) {\r
-                       $class[] = 'x' . $line['x'];\r
-               }\r
-               if (!is_null($line['y'])) {\r
-                       $class[] = 'y' . $line['y'];\r
-               }\r
-               $class = implode(' ', $class);\r
-\r
-\r
-               $res = '<div class="' . $class . '">';\r
-               foreach ($line['groups'] as $group) {\r
-                       $res.=$this->writeGroup($group);\r
-               }\r
-               $res.='</div>';\r
-               return $res;\r
-       }\r
-\r
-       protected function writeGroup($group) {\r
-               if ($group === false) {\r
-                       return '';\r
-               }\r
-\r
-               $group['y'] = $this->getCSSY($group['y'] * $this->multiply);\r
-               $group['x'] = $this->getCSSX($group['x'] * $this->multiply);\r
-\r
-               $class = array('g');\r
-               if (!is_null($group['color'])) {\r
-                       $class[] = 'c' . $group['color'];\r
-               }\r
-               if (!is_null($group['size'])) {\r
-                       $class[] = 's' . $group['size'];\r
-               }\r
-               if (!is_null($group['font'])) {\r
-                       $class[] = 'f' . $group['font'];\r
-               }\r
-               if (!is_null($group['x'])) {\r
-                       $class[] = 'x' . $group['x'];\r
-               }\r
-               if (!is_null($group['y'])) {\r
-                       $class[] = 'y' . $group['y'];\r
-               }\r
-               if (!is_null($group['letterspacing'])) {\r
-                       $class[] = 'l' . $group['letterspacing'];\r
-               }\r
-               if (!is_null($group['wordspacing'])) {\r
-                       $class[] = 'w' . $group['wordspacing'];\r
-               }\r
-               $class = implode(' ', $class);\r
-\r
-               $res = '<div class="' . $class . '">';\r
-               foreach ($group['spans'] as $span) {\r
-                       $res.=$this->writeSpan($span);\r
-               }\r
-               $res.='</div>';\r
-               return $res;\r
-       }\r
-\r
-       protected function writeSpan($span) {\r
-               if ($span === false) {\r
-                       return '';\r
-               }\r
-\r
-               return self::escapeHTML($span['text']);\r
-       }\r
-\r
-       protected function writeCSS($file) {\r
-               $res = array();\r
-\r
-               // General theme\r
-               $h = $this->book->parametres->height . 'px';\r
-               $w2 = ($this->book->parametres->width * 2) . 'px';\r
-               $w = $this->book->parametres->width . 'px';\r
-               $wm = ($this->book->parametres->width * $this->multiply) . 'px';\r
-               $hm = ($this->book->parametres->height * $this->multiply) . 'px';\r
-\r
-\r
-               $navTop = ($this->book->parametres->height - 40 - 100) / 2;\r
-               $res[] = '.portrait #pages,.portrait .doublePage.page,.page,.portrait #shadow,#shadow.single{width:' . $w . ';max-width:' . $w . ';height:' . $h . ';max-height:' . $h . '}';\r
-               $res[] = '.background{' . $this->writeCSSUA('transform-origin', 'top left') . ';}';\r
-               foreach (self::$resolutions as $r) {\r
-                       $ratio = 72 / $r;\r
-                       $wr = $this->book->parametres->width / $ratio;\r
-                       $hr = $this->book->parametres->height / $ratio;\r
-\r
-                       $br = '.background.r' . $r . '{';\r
-                       if ($ratio != 1) {\r
-                               $br.=$this->writeCSSUA('transform', 'scale(' . $ratio . ')') . ';';\r
-                       }\r
-                       $br.='width:' . $wr . 'px;height:' . $hr . 'px;}';\r
-                       $res[] = $br;\r
-               }\r
-               $res[] = '.doublePage,#pages,.landscape #shadow.double{width:' . $w2 . ';max-width:' . $w2 . ';height:' . $h . ';max-height:' . $h . '}';\r
-               $res[] = '.landscape #shadow.single.right{left: ' . $w . ';}';\r
-               $res[] = '.landscape .page.right{left:' . $w . '}';\r
-               $texts = '.texts{' . $this->writeCSSUA('transform-origin', 'top left') . ';';\r
-               $texts.=$this->writeCSSUA('transform', 'scale(' . (1 / $this->multiply) . ')') . ';';\r
-               $texts.='width:' . $wm . '; max-width:' . $wm . ';';\r
-               $texts.='height:' . $hm . '; max-height:' . $hm . ';';\r
-               $texts.='}';\r
-               $res[] = $texts;\r
-\r
-               // Theme\r
-               // Background\r
-               $body = '#main{';\r
-               $body.='background-color:#' . $this->theme->parametres->backgroundColor . ';';\r
-               switch ($this->theme->parametres->repeat) {\r
-                       case wsTheme::REPEAT:\r
-                               $body.='background-repeat:repeat;';\r
-                               break;\r
-                       case wsTheme::NONE:\r
-                               $body.='background-repeat:no-repeat;';\r
-                               break;\r
-                       case wsTheme::RATIO:\r
-                               $body.='background-repeat:no-repeat;';\r
-                               break;\r
-                       case wsTheme::STRETCH:\r
-                               $body.='background-repeat:no-repeat;';\r
-                               $body.='background-size:100% 100%;';\r
-                               break;\r
-               }\r
-               if ($this->theme->parametres->backgroundImage != '') {\r
-                       copy($this->themeRoot . '/' . $this->theme->parametres->backgroundImage, $this->vdir . '/data/images/' . $this->theme->parametres->backgroundImage);\r
-                       $body.='background-image:url(../images/' . $this->theme->parametres->backgroundImage . ');';\r
-                       $body.='background-position:';\r
-\r
-\r
-                       switch ($this->theme->parametres->backgroundVAlign) {\r
-                               case wsTheme::TOP:\r
-                                       $body.='top';\r
-                                       break;\r
-                               case wsTheme::MIDDLE:\r
-                                       $body.='center';\r
-                                       break;\r
-                               case wsTheme::BOTTOM:\r
-                                       $body.='bottom';\r
-                                       break;\r
-                       }\r
-                       $body.=' ';\r
-                       switch ($this->theme->parametres->backgroundHAlign) {\r
-                               case wsTheme::LEFT:\r
-                                       $body.='left';\r
-                                       break;\r
-                               case wsTheme::CENTER:\r
-                                       $body.='center';\r
-                                       break;\r
-                               case wsTheme::RIGHT:\r
-                                       $body.='right';\r
-                                       break;\r
-                       }\r
-                       $body.=';';\r
-               }\r
-\r
-               $body.='}';\r
-               $res[] = $body;\r
-\r
-               // Header\r
-               $header = '#header{';\r
-               $header.='height:' . $this->theme->parametres->menuHeight . 'px;';\r
-               $header.='background-color:' . self::colorToCSS($this->theme->parametres->menuColor) . ';';\r
-               if ($this->theme->parametres->menuImage != '') {\r
-                       copy($this->themeRoot . '/' . $this->theme->parametres->menuImage, $this->vdir . '/data/images/' . $this->theme->parametres->menuImage);\r
-                       $header.='background-image:url(../images/' . $this->theme->parametres->menuImage . ');';\r
-                       $header.='background-repeat:no-repeat;';\r
-                       $header.='background-size:100% ' . $this->theme->parametres->menuHeight . 'px;';\r
-               }\r
-               $header.='}';\r
-               $res[] = $header;\r
-\r
-               //Icons\r
-               $res = array_merge($res, $this->writeIcons());\r
-\r
-               // Logo\r
-               $logo = '#logo{';\r
-               if ($this->theme->parametres->logo) {\r
-                       copy($this->themeRoot . '/' . $this->theme->parametres->logo, $this->vdir . '/data/images/' . $this->theme->parametres->logo);\r
-                       $dim = getimagesize($this->vdir . '/data/images/' . $this->theme->parametres->logo);\r
-                       $logo.='background-image:url(../images/' . $this->theme->parametres->logo . ');width:' . $dim[0] . 'px;height:' . $dim[1] . 'px;';\r
-               }\r
-               $logo.='}';\r
-               $res[] = $logo;\r
-\r
-               // Credits\r
-               $res[] = '#credits,#credits a{color:' . self::colorToCSS($this->theme->parametres->creditsColor) . ';}';\r
-\r
-               // Arrows\r
-               $res[] = '#next,#previous{background-color:' . self::colorToCSS($this->theme->parametres->couleurA) . ';}';\r
-               // Book shadow\r
-               $shadowColor = self::colorToCSS($this->theme->parametres->bookShadeColor);\r
-               if ($shadowColor != 'transparent') {\r
-                       $res[] = '#shadow{' . $this->writeCSSUA('box-shadow', '0 0 20px ' . $shadowColor) . '}';\r
-               }\r
-\r
-               // Pages styles\r
-               foreach ($this->cssColor as $color => $index) {\r
-                       $res[] = '.c' . $index . '{color:#' . $color . '}';\r
-               }\r
-\r
-               foreach ($this->cssSize as $size => $index) {\r
-                       $res[] = '.s' . $index . '{font-size:' . $size . 'px}';\r
-               }\r
-\r
-               foreach ($this->cssLetterSpacing as $letterspacing => $index) {\r
-                       $res[] = '.l' . $index . '{letter-spacing:' . $letterspacing . 'em}';\r
-               }\r
-\r
-               foreach ($this->cssWordSpacing as $wordspacing => $index) {\r
-                       $res[] = '.w' . $index . '{word-spacing:' . $wordspacing . 'em}';\r
-               }\r
-\r
-               foreach ($this->cssX as $x => $index) {\r
-                       $res[] = '.x' . $index . '{left:' . $x . 'px}';\r
-               }\r
-\r
-               foreach ($this->cssY as $y => $index) {\r
-                       $res[] = '.y' . $index . '{top:' . $y . 'px}';\r
-               }\r
-\r
-               foreach ($this->cssRotation as $rotation => $index) {\r
-                       $rotation*= - 1;\r
-\r
-\r
-                       $to = 'transform-origin:left top;';\r
-\r
-                       $css = '.r' . $index . '{';\r
-                       $css.=self::writeCSSUA('transform', 'rotate(' . $rotation . 'deg)') . ';';\r
-                       $css.=self::writeCSSUA('transform-origin', 'left top');\r
-                       $css.='}';\r
-                       $res[] = $css;\r
-               }\r
-\r
-               foreach ($this->cssFont as $font => $index) {\r
-                       list($font, $document_id) = explode('//', $font);\r
-                       $res[] = "@font-face{font-family:F" . $index . ";src:url('F" . $index . ".eot');src:url('F" . $index . ".eot?#iefix') format('eot'),url('F" . $index . ".ttf') format('truetype'),url('F" . $index . ".svgz#" . $font . "') format('svgz'),url('F" . $index . ".svg#" . $font . "') format('svg')}";\r
-                       $res[] = '.f' . $index . '{font-family:F' . $index . ',Arial,Helvetica}';\r
-               }\r
-\r
-               $res = array_chunk($res, 4000);\r
-               foreach ($res as $k => $css) {\r
-                       file_put_contents(sprintf($file, $k), implode("\n", $css));\r
-               }\r
-       }\r
-\r
-       protected function writeCSSUA($property, $value) {\r
-               $res = array();\r
-               foreach (self::$uaPrefixes as $prefix) {\r
-                       $res[] = $prefix . $property . ':' . $value;\r
-               }\r
-               return implode(';', $res);\r
-       }\r
-\r
-       protected function addLine($line, $document_id) {\r
-               $res = array();\r
-               foreach ($line->a as $group) {\r
-                       $res[] = $this->addGroup($group, $document_id);\r
-               }\r
-               return array('x' => $this->normalizeFloatValue($line['x']),\r
-                       'y' => $this->normalizeFloatValue($line['y']),\r
-                       'rotation' => $this->getCSSRotation($this->normalizeFloatValue($line['rotation'], 0)),\r
-                       "groups" => $res);\r
-       }\r
-\r
-       protected function addGroup($group, $document_id) {\r
-               $alpha = intval(substr($group['color'], 1, 2), 16);\r
-               if ($alpha == 0) {\r
-                       return false;\r
-               }\r
-\r
-               $res = array();\r
-\r
-               $first = true;\r
-               foreach ($group->s as $span) {\r
-                       if ($first) {\r
-                               $x = $span['x'];\r
-                               $first = false;\r
-                       }\r
-                       $newSpan = $this->addSpan($span, $document_id);\r
-\r
-                       array_push($res, $newSpan);\r
-               }\r
-\r
-               return array(\r
-                       'color' => $this->getCSSColor($group['color']),\r
-                       'size' => $this->getCSSSize($group['size']),\r
-                       'font' => $this->getCSSFont($group['font'], $document_id),\r
-                       'letterspacing' => $this->getCSSLetterSpacing($group['letterspacing']),\r
-                       'wordspacing' => $this->getCSSWordSpacing($group['wordspacing']),\r
-                       'y' => ($group['size']) / -1.2,\r
-                       'x' => $x,\r
-                       'spans' => $res);\r
-       }\r
-\r
-       protected function addSpan($span, $document_id) {\r
-\r
-               $text = (string) $span;\r
-               if ($text == '') {\r
-                       return false;\r
-               }\r
-               return array('text' => $text);\r
-       }\r
-\r
-       protected function getCSSSize(&$size) {\r
-               $size = $this->normalizeFloatValue($size * $this->multiply, 3);\r
-               $sizer = $size;\r
-               return $this->getIndex($sizer, $this->cssSize);\r
-       }\r
-\r
-       protected function getCSSFont($font, $document_id) {\r
-               return $this->getIndex($font . "//" . $document_id, $this->cssFont);\r
-       }\r
-\r
-       protected function getCSSColor($color) {\r
-               $color = trim($color, '#');\r
-               if (strlen($color) > 6) {\r
-                       $color = substr($color, 2, 6);\r
-               }\r
-               if ($color == '000000') {\r
-                       return null;\r
-               }\r
-               return $this->getIndex($color, $this->cssColor);\r
-       }\r
-\r
-       protected function getCSSLetterSpacing($letterspacing) {\r
-\r
-               $letterspacing = $this->normalizeFloatValue($letterspacing, 5);\r
-\r
-               if ($letterspacing == 0) {\r
-                       return null;\r
-               }\r
-               return $this->getIndex($letterspacing, $this->cssLetterSpacing);\r
-       }\r
-\r
-       protected function getCSSWordSpacing($wordspacing) {\r
-               $wordspacing = $this->normalizeFloatValue($wordspacing, 5);\r
-\r
-               if ($wordspacing == 0) {\r
-                       return null;\r
-               }\r
-               return $this->getIndex($wordspacing, $this->cssWordSpacing);\r
-       }\r
-\r
-       protected function getCSSRotation($rotation) {\r
-               $rotation = $this->normalizeFloatValue($rotation, 0);\r
-               if ($rotation == 0) {\r
-                       return null;\r
-               }\r
-               return $this->getIndex($rotation, $this->cssRotation);\r
-       }\r
-\r
-       protected function getCSSX($x) {\r
-               $x = round($x);\r
-               if ($x == 0) {\r
-                       return null;\r
-               }\r
-               return $this->getIndex($x, $this->cssX);\r
-       }\r
-\r
-       protected function getCSSY($y) {\r
-               $y = round($y);\r
-               if ($y == 0) {\r
-                       return null;\r
-               }\r
-               return $this->getIndex($y, $this->cssY);\r
-       }\r
-\r
-       protected function getIndex($value, &$tab) {\r
-               $value = (string) $value;\r
-               if (isset($tab[$value])) {\r
-                       return $tab[$value];\r
-               }\r
-               $res = $this->base62(count($tab));\r
-               $tab[$value] = $res;\r
-               return $res;\r
-       }\r
-\r
-       protected function normalizeFloatValue($value, $round=3) {\r
-               $value = str_replace(',', '.', $value);\r
-               $value = (float) $value;\r
-               $value = round($value, $round);\r
-               return $value;\r
-       }\r
-\r
-       protected function base62($val) {\r
-               $chars = '0123456789abcdefghijklmnopqrstuvwxyz';\r
-               $base = strlen($chars);\r
-               $str = '';\r
-               do {\r
-                       $i = $val % $base;\r
-                       $str = $chars[$i] . $str;\r
-                       $val = ($val - $i) / $base;\r
-               } while ($val > 0);\r
-               return $str;\r
-       }\r
-\r
-       public static function escapeHTML($in) {\r
-               $in = htmlentities($in, ENT_NOQUOTES, "UTF-8");\r
-               $in = str_replace('&thinsp;', '', $in);\r
-\r
-               return $in;\r
-       }\r
-\r
-       public function __destruct() {\r
-               \r
-       }\r
-\r
-       public static function colorToCSS($color) {\r
-               if (strlen($color) == 6) {\r
-                       return '#' . $color;\r
-               } else {\r
-                       $alpha = substr($color, 0, 2);\r
-                       $red = substr($color, 2, 2);\r
-                       $green = substr($color, 4, 2);\r
-                       $blue = substr($color, 6, 2);\r
-\r
-                       $components = array('alpha', 'red', 'green', 'blue');\r
-                       foreach ($components as $k => $name) {\r
-                               $hex = substr($color, $k * 2, 2);\r
-                               $$name = intval($hex, 16);\r
-                       }\r
-                       $alpha/=255;\r
-                       if ($alpha == 0) {\r
-                               return 'transparent';\r
-                       } elseif ($alpha == 1) {\r
-                               return '#' . substr($color, 2, 6);\r
-                       }\r
-                       return 'rgba(' . $red . ',' . $green . ',' . $blue . ',' . $alpha . ')';\r
-               }\r
-       }\r
-\r
-}\r
-\r
-?>
\ No newline at end of file
index b919885661d2a40ebdfca1d127fa05808e2a435f..00543ecbbd7a6112f02a5d821b4e49da9d029dd1 100644 (file)
@@ -10,6 +10,7 @@ class wsPackager {
        protected $version;\r
        protected $book_id;\r
        protected $themeRoot;\r
+       protected $daoBook;\r
 \r
        public static function package($book_id, $version) {\r
                if ($version == 'html') {\r
@@ -40,9 +41,9 @@ class wsPackager {
                        mkdir($this->dir, 0777, true);\r
                }\r
 \r
-               $daoBook = new wsDAOBook($core->con);\r
-               $this->book = $daoBook->selectById($book_id);\r
-               $this->pages = $daoBook->getPagesOfBook($book_id);\r
+               $this->daoBook = new wsDAOBook($core->con);\r
+               $this->book = $this->daoBook->selectById($book_id);\r
+               $this->pages = $this->daoBook->getPagesOfBook($book_id);\r
 \r
                $daoTheme = new wsDAOTheme($core->con);\r
                $this->theme = $daoTheme->getThemeOfBook($book_id, true);\r
diff --git a/inc/ws/Util/packager/html5/class.ws.packager.html5.php b/inc/ws/Util/packager/html5/class.ws.packager.html5.php
new file mode 100644 (file)
index 0000000..3defc0a
--- /dev/null
@@ -0,0 +1,578 @@
+<?php\r
+\r
+class wsPackagerHTML5 extends wsPackager {\r
+\r
+       protected $layouts = array();\r
+       protected $cssSize = array();\r
+       protected $cssColor = array();\r
+       protected $cssOpacity = array();\r
+       protected $cssFont = array();\r
+       protected $cssWordSpacing = array();\r
+       protected $cssLetterSpacing = array();\r
+       protected $cssRotation = array();\r
+       protected $cssX = array();\r
+       protected $cssY = array();\r
+       protected $pdf2htmlRatio;\r
+       protected $scale;\r
+       protected $multiply;\r
+       protected $div = array();\r
+       protected static $resolutions = array(36, 72, 150);\r
+       protected static $uaPrefixes = array('-moz-', '-webkit-', '-o-', '-ms-', '');\r
+\r
+       public function __construct($book_id) {\r
+               parent::__construct($book_id);\r
+               $this->version = 'html5';\r
+       }\r
+\r
+       protected function preparePackage() {\r
+               parent::preparePackage();\r
+\r
+               foreach ($this->pages as $page => $infos) {\r
+                       $file = WS_DOCS . '/' . $infos['document_id'] . '/html/p' . $infos['document_page'] . '.layout';\r
+                       if (file_exists($file)) {\r
+                               $this->layouts[$page] = simplexml_load_file($file, null, LIBXML_ERR_WARNING);\r
+                       }\r
+               }\r
+\r
+               $imagesize = getimagesize(WS_DOCS . '/' . $this->pages[1]['document_id'] . '/html/h72-' . $this->pages[1]['document_page'] . '.jpg');\r
+               $this->pdf2htmlRatio = $imagesize[0] / $this->layouts[1]['width'];\r
+               $this->scale = 4;\r
+               $this->multiply = $this->pdf2htmlRatio * $this->scale;\r
+\r
+               $this->createHTML();\r
+       }\r
+\r
+       public function makePackage() {\r
+               parent::makePackage();\r
+               return $this->zip();\r
+       }\r
+\r
+       protected function createHTML() {\r
+               foreach ($this->layouts as $page => $layout) {\r
+                       $this->div[$page] = array();\r
+                       $document_id = $this->pages[$page]['document_id'];\r
+                       foreach ($layout->l as $line) {\r
+                               $this->div[$page][] = $this->addLine($line, $document_id);\r
+                       }\r
+               }\r
+               mkdir($this->vdir . '/data/images', 0777, true);\r
+               mkdir($this->vdir . '/data/contents', 0777, true);\r
+               mkdir($this->vdir . '/data/background', 0777, true);\r
+               mkdir($this->vdir . '/data/style', 0777, true);\r
+\r
+               foreach ($this->div as $n => $page) {\r
+                       file_put_contents($this->vdir . '/data/contents/p' . $n . '.html', $this->writePage($page));\r
+               }\r
+               $this->writeFonts();\r
+               $this->writeImages();\r
+               $this->writeLinks();\r
+               $this->writeCSS($this->vdir . '/data/style/style_%d.css');\r
+\r
+               file_put_contents($this->vdir . '/data/datas.js', $this->writeConfig());\r
+       }\r
+\r
+       protected function writeLinks() {\r
+               global $core;\r
+               $daoDoc = new wsDAODocument($core->con);\r
+               $daoDoc->getLinksAndRulers($this->book_id, $links, $rulers);\r
+\r
+               foreach ($links as $link) {\r
+                       fb($link);\r
+               }\r
+       }\r
+\r
+       protected function writeConfig() {\r
+               $config = cubeObject::merge($this->book->parametres->toStandardObject(), $this->theme->parametres->toStandardObject());\r
+               $config->id = $this->book->book_id;\r
+               return 'DATAS=' . json_encode($config) . ';';\r
+       }\r
+\r
+       protected function writeFonts() {\r
+               $fext = array('ttf', 'eot', 'svg', 'svgz', 'woff');\r
+               foreach ($this->cssFont as $font => $index) {\r
+                       list($font, $document_id) = explode('//', $font);\r
+                       foreach ($fext as $ext) {\r
+                               copy(WS_DOCS . '/' . $document_id . "/fonts/web/" . $font . '.' . $ext, $this->vdir . '/data/style/F' . $index . '.' . $ext);\r
+                       }\r
+               }\r
+       }\r
+\r
+       protected function writeIcons() {\r
+               $res = array();\r
+               // Get the colors used to colorize graphics\r
+               if ($this->theme->parametres->colorizeIcons) {\r
+                       $couleurI = '#' . $this->theme->parametres->couleurI;\r
+               } else {\r
+                       $couleurI = '#FFFFFF';\r
+               }\r
+               $arrowsColor = '#' . $this->theme->parametres->arrowsColor;\r
+               // Set the icon list with the color\r
+               $icons = array('nav-bookmark' => $couleurI, 'nav-friend' => $couleurI, 'nav-help' => $couleurI, 'nav-index' => $couleurI, 'nav-sommaire' => $couleurI,\r
+                       'next' => $arrowsColor, 'previous' => $arrowsColor, 'search' => $couleurI);\r
+\r
+               foreach ($icons as $icon => $color) {\r
+                       wsTools::colorizeAndRasterizeIcon($this->theme->parametres->iconSet, $icon, $color, $this->vdir . '/data/images/',4, $w, $h);\r
+                       $res[] = '#icon-' . $icon . '{width:' . $w . 'px;height:' . $h . 'px;background-image:url(data/images/' . $icon . '.svg), url(data/images/' . $icon . '.png);background-repeat:no-repeat;background-size:' . $w . 'px ' . $h . 'px}';\r
+               }\r
+               return $res;\r
+       }\r
+\r
+       protected function writeImages() {\r
+\r
+               foreach (self::$resolutions as $r) {\r
+                       mkdir($this->vdir . '/data/background/' . $r, 0777);\r
+               }\r
+               foreach ($this->pages as $page => $infos) {\r
+                       foreach (self::$resolutions as $r) {\r
+                               copy(WS_DOCS . '/' . $infos['document_id'] . '/html/h' . $r . '-' . $infos['document_page'] . '.jpg', $this->vdir . '/data/background/' . $r . '/p' . $page . '.jpg');\r
+                       }\r
+               }\r
+       }\r
+\r
+       protected function writePage($page) {\r
+               $res = '';\r
+               foreach ($page as $line) {\r
+                       $res .= $this->writeLine($line);\r
+               }\r
+               return $res;\r
+       }\r
+\r
+       protected function writeLine($line) {\r
+               $line['x'] = $this->getCSSX($line['x'] * $this->multiply);\r
+               $line['y'] = $this->getCSSY($line['y'] * $this->multiply);\r
+\r
+               $class = array('l');\r
+               if (!is_null($line['rotation'])) {\r
+                       $class[] = 'r' . $line['rotation'];\r
+               }\r
+               if (!is_null($line['x'])) {\r
+                       $class[] = 'x' . $line['x'];\r
+               }\r
+               if (!is_null($line['y'])) {\r
+                       $class[] = 'y' . $line['y'];\r
+               }\r
+               $class = implode(' ', $class);\r
+\r
+\r
+               $res = '<div class="' . $class . '">';\r
+               foreach ($line['groups'] as $group) {\r
+                       $res.=$this->writeGroup($group);\r
+               }\r
+               $res.='</div>';\r
+               return $res;\r
+       }\r
+\r
+       protected function writeGroup($group) {\r
+               if ($group === false) {\r
+                       return '';\r
+               }\r
+\r
+               $group['y'] = $this->getCSSY($group['y'] * $this->multiply);\r
+               $group['x'] = $this->getCSSX($group['x'] * $this->multiply);\r
+\r
+               $class = array('g');\r
+               if (!is_null($group['color'])) {\r
+                       $class[] = 'c' . $group['color'];\r
+               }\r
+               if (!is_null($group['size'])) {\r
+                       $class[] = 's' . $group['size'];\r
+               }\r
+               if (!is_null($group['font'])) {\r
+                       $class[] = 'f' . $group['font'];\r
+               }\r
+               if (!is_null($group['x'])) {\r
+                       $class[] = 'x' . $group['x'];\r
+               }\r
+               if (!is_null($group['y'])) {\r
+                       $class[] = 'y' . $group['y'];\r
+               }\r
+               if (!is_null($group['letterspacing'])) {\r
+                       $class[] = 'l' . $group['letterspacing'];\r
+               }\r
+               if (!is_null($group['wordspacing'])) {\r
+                       $class[] = 'w' . $group['wordspacing'];\r
+               }\r
+               $class = implode(' ', $class);\r
+\r
+               $res = '<div class="' . $class . '">';\r
+               foreach ($group['spans'] as $span) {\r
+                       $res.=$this->writeSpan($span);\r
+               }\r
+               $res.='</div>';\r
+               return $res;\r
+       }\r
+\r
+       protected function writeSpan($span) {\r
+               if ($span === false) {\r
+                       return '';\r
+               }\r
+\r
+               return self::escapeHTML($span['text']);\r
+       }\r
+\r
+       protected function writeCSS($file) {\r
+               $res = array();\r
+\r
+               // General theme\r
+               $h = $this->book->parametres->height . 'px';\r
+               $w2 = ($this->book->parametres->width * 2) . 'px';\r
+               $w = $this->book->parametres->width . 'px';\r
+               $wm = ($this->book->parametres->width * $this->multiply) . 'px';\r
+               $hm = ($this->book->parametres->height * $this->multiply) . 'px';\r
+\r
+\r
+               $navTop = ($this->book->parametres->height - 40 - 100) / 2;\r
+               $res[] = '.portrait #pages,.portrait .doublePage.page,.page,.portrait #shadow,#shadow.single{width:' . $w . ';max-width:' . $w . ';height:' . $h . ';max-height:' . $h . '}';\r
+               $res[] = '.background{' . $this->writeCSSUA('transform-origin', 'top left') . ';}';\r
+               foreach (self::$resolutions as $r) {\r
+                       $ratio = 72 / $r;\r
+                       $wr = $this->book->parametres->width / $ratio;\r
+                       $hr = $this->book->parametres->height / $ratio;\r
+\r
+                       $br = '.background.r' . $r . '{';\r
+                       if ($ratio != 1) {\r
+                               $br.=$this->writeCSSUA('transform', 'scale(' . $ratio . ')') . ';';\r
+                       }\r
+                       $br.='width:' . $wr . 'px;height:' . $hr . 'px;}';\r
+                       $res[] = $br;\r
+               }\r
+               $res[] = '.doublePage,#pages,.landscape #shadow.double{width:' . $w2 . ';max-width:' . $w2 . ';height:' . $h . ';max-height:' . $h . '}';\r
+               $res[] = '.landscape #shadow.single.right{left: ' . $w . ';}';\r
+               $res[] = '.landscape .page.right{left:' . $w . '}';\r
+               $texts = '.texts{' . $this->writeCSSUA('transform-origin', 'top left') . ';';\r
+               $texts.=$this->writeCSSUA('transform', 'scale(' . (1 / $this->multiply) . ')') . ';';\r
+               $texts.='width:' . $wm . '; max-width:' . $wm . ';';\r
+               $texts.='height:' . $hm . '; max-height:' . $hm . ';';\r
+               $texts.='}';\r
+               $res[] = $texts;\r
+\r
+               // Theme\r
+               // Background\r
+               $body = '#main{';\r
+               $body.='background-color:#' . $this->theme->parametres->backgroundColor . ';';\r
+               switch ($this->theme->parametres->repeat) {\r
+                       case wsTheme::REPEAT:\r
+                               $body.='background-repeat:repeat;';\r
+                               break;\r
+                       case wsTheme::NONE:\r
+                               $body.='background-repeat:no-repeat;';\r
+                               break;\r
+                       case wsTheme::RATIO:\r
+                               $body.='background-repeat:no-repeat;';\r
+                               break;\r
+                       case wsTheme::STRETCH:\r
+                               $body.='background-repeat:no-repeat;';\r
+                               $body.='background-size:100% 100%;';\r
+                               break;\r
+               }\r
+               if ($this->theme->parametres->backgroundImage != '') {\r
+                       copy($this->themeRoot . '/' . $this->theme->parametres->backgroundImage, $this->vdir . '/data/images/' . $this->theme->parametres->backgroundImage);\r
+                       $body.='background-image:url(../images/' . $this->theme->parametres->backgroundImage . ');';\r
+                       $body.='background-position:';\r
+\r
+\r
+                       switch ($this->theme->parametres->backgroundVAlign) {\r
+                               case wsTheme::TOP:\r
+                                       $body.='top';\r
+                                       break;\r
+                               case wsTheme::MIDDLE:\r
+                                       $body.='center';\r
+                                       break;\r
+                               case wsTheme::BOTTOM:\r
+                                       $body.='bottom';\r
+                                       break;\r
+                       }\r
+                       $body.=' ';\r
+                       switch ($this->theme->parametres->backgroundHAlign) {\r
+                               case wsTheme::LEFT:\r
+                                       $body.='left';\r
+                                       break;\r
+                               case wsTheme::CENTER:\r
+                                       $body.='center';\r
+                                       break;\r
+                               case wsTheme::RIGHT:\r
+                                       $body.='right';\r
+                                       break;\r
+                       }\r
+                       $body.=';';\r
+               }\r
+\r
+               $body.='}';\r
+               $res[] = $body;\r
+\r
+               // Header\r
+               $header = '#header{';\r
+               $header.='height:' . $this->theme->parametres->menuHeight . 'px;';\r
+               $header.='background-color:' . self::colorToCSS($this->theme->parametres->menuColor) . ';';\r
+               if ($this->theme->parametres->menuImage != '') {\r
+                       copy($this->themeRoot . '/' . $this->theme->parametres->menuImage, $this->vdir . '/data/images/' . $this->theme->parametres->menuImage);\r
+                       $header.='background-image:url(../images/' . $this->theme->parametres->menuImage . ');';\r
+                       $header.='background-repeat:no-repeat;';\r
+                       $header.='background-size:100% ' . $this->theme->parametres->menuHeight . 'px;';\r
+               }\r
+               $header.='}';\r
+               $res[] = $header;\r
+\r
+               //Icons\r
+               $res = array_merge($res, $this->writeIcons());\r
+\r
+               // Logo\r
+               $logo = '#logo{';\r
+               if ($this->theme->parametres->logo) {\r
+                       copy($this->themeRoot . '/' . $this->theme->parametres->logo, $this->vdir . '/data/images/' . $this->theme->parametres->logo);\r
+                       $dim = getimagesize($this->vdir . '/data/images/' . $this->theme->parametres->logo);\r
+                       $logo.='background-image:url(../images/' . $this->theme->parametres->logo . ');width:' . $dim[0] . 'px;height:' . $dim[1] . 'px;';\r
+               }\r
+               $logo.='}';\r
+               $res[] = $logo;\r
+\r
+               // Credits\r
+               $res[] = '#credits,#credits a{color:' . self::colorToCSS($this->theme->parametres->creditsColor) . ';}';\r
+\r
+               // Arrows\r
+               $res[] = '#next,#previous{background-color:' . self::colorToCSS($this->theme->parametres->couleurA) . ';}';\r
+               // Book shadow\r
+               $shadowColor = self::colorToCSS($this->theme->parametres->bookShadeColor);\r
+               if ($shadowColor != 'transparent') {\r
+                       $res[] = '#shadow{' . $this->writeCSSUA('box-shadow', '0 0 20px ' . $shadowColor) . '}';\r
+               }\r
+\r
+               // Pages styles\r
+               foreach ($this->cssColor as $color => $index) {\r
+                       $res[] = '.c' . $index . '{color:#' . $color . '}';\r
+               }\r
+\r
+               foreach ($this->cssSize as $size => $index) {\r
+                       $res[] = '.s' . $index . '{font-size:' . $size . 'px}';\r
+               }\r
+\r
+               foreach ($this->cssLetterSpacing as $letterspacing => $index) {\r
+                       $res[] = '.l' . $index . '{letter-spacing:' . $letterspacing . 'em}';\r
+               }\r
+\r
+               foreach ($this->cssWordSpacing as $wordspacing => $index) {\r
+                       $res[] = '.w' . $index . '{word-spacing:' . $wordspacing . 'em}';\r
+               }\r
+\r
+               foreach ($this->cssX as $x => $index) {\r
+                       $res[] = '.x' . $index . '{left:' . $x . 'px}';\r
+               }\r
+\r
+               foreach ($this->cssY as $y => $index) {\r
+                       $res[] = '.y' . $index . '{top:' . $y . 'px}';\r
+               }\r
+\r
+               foreach ($this->cssRotation as $rotation => $index) {\r
+                       $rotation*= - 1;\r
+\r
+\r
+                       $to = 'transform-origin:left top;';\r
+\r
+                       $css = '.r' . $index . '{';\r
+                       $css.=self::writeCSSUA('transform', 'rotate(' . $rotation . 'deg)') . ';';\r
+                       $css.=self::writeCSSUA('transform-origin', 'left top');\r
+                       $css.='}';\r
+                       $res[] = $css;\r
+               }\r
+\r
+               foreach ($this->cssFont as $font => $index) {\r
+                       list($font, $document_id) = explode('//', $font);\r
+                       $res[] = "@font-face{font-family:F" . $index . ";src:url('F" . $index . ".eot');src:url('F" . $index . ".eot?#iefix') format('eot'),url('F" . $index . ".ttf') format('truetype'),url('F" . $index . ".svgz#" . $font . "') format('svgz'),url('F" . $index . ".svg#" . $font . "') format('svg')}";\r
+                       $res[] = '.f' . $index . '{font-family:F' . $index . ',Arial,Helvetica}';\r
+               }\r
+\r
+               $res = array_chunk($res, 4000);\r
+               foreach ($res as $k => $css) {\r
+                       file_put_contents(sprintf($file, $k), implode("\n", $css));\r
+               }\r
+       }\r
+\r
+       protected function writeCSSUA($property, $value) {\r
+               $res = array();\r
+               foreach (self::$uaPrefixes as $prefix) {\r
+                       $res[] = $prefix . $property . ':' . $value;\r
+               }\r
+               return implode(';', $res);\r
+       }\r
+\r
+       protected function addLine($line, $document_id) {\r
+               $res = array();\r
+               foreach ($line->a as $group) {\r
+                       $res[] = $this->addGroup($group, $document_id);\r
+               }\r
+               return array('x' => $this->normalizeFloatValue($line['x']),\r
+                       'y' => $this->normalizeFloatValue($line['y']),\r
+                       'rotation' => $this->getCSSRotation($this->normalizeFloatValue($line['rotation'], 0)),\r
+                       "groups" => $res);\r
+       }\r
+\r
+       protected function addGroup($group, $document_id) {\r
+               $alpha = intval(substr($group['color'], 1, 2), 16);\r
+               if ($alpha == 0) {\r
+                       return false;\r
+               }\r
+\r
+               $res = array();\r
+\r
+               $first = true;\r
+               foreach ($group->s as $span) {\r
+                       if ($first) {\r
+                               $x = $span['x'];\r
+                               $first = false;\r
+                       }\r
+                       $newSpan = $this->addSpan($span, $document_id);\r
+\r
+                       array_push($res, $newSpan);\r
+               }\r
+\r
+               return array(\r
+                       'color' => $this->getCSSColor($group['color']),\r
+                       'size' => $this->getCSSSize($group['size']),\r
+                       'font' => $this->getCSSFont($group['font'], $document_id),\r
+                       'letterspacing' => $this->getCSSLetterSpacing($group['letterspacing']),\r
+                       'wordspacing' => $this->getCSSWordSpacing($group['wordspacing']),\r
+                       'y' => ($group['size']) / -1.2,\r
+                       'x' => $x,\r
+                       'spans' => $res);\r
+       }\r
+\r
+       protected function addSpan($span, $document_id) {\r
+\r
+               $text = (string) $span;\r
+               if ($text == '') {\r
+                       return false;\r
+               }\r
+               return array('text' => $text);\r
+       }\r
+\r
+       protected function getCSSSize(&$size) {\r
+               $size = $this->normalizeFloatValue($size * $this->multiply, 3);\r
+               $sizer = $size;\r
+               return $this->getIndex($sizer, $this->cssSize);\r
+       }\r
+\r
+       protected function getCSSFont($font, $document_id) {\r
+               return $this->getIndex($font . "//" . $document_id, $this->cssFont);\r
+       }\r
+\r
+       protected function getCSSColor($color) {\r
+               $color = trim($color, '#');\r
+               if (strlen($color) > 6) {\r
+                       $color = substr($color, 2, 6);\r
+               }\r
+               if ($color == '000000') {\r
+                       return null;\r
+               }\r
+               return $this->getIndex($color, $this->cssColor);\r
+       }\r
+\r
+       protected function getCSSLetterSpacing($letterspacing) {\r
+\r
+               $letterspacing = $this->normalizeFloatValue($letterspacing, 5);\r
+\r
+               if ($letterspacing == 0) {\r
+                       return null;\r
+               }\r
+               return $this->getIndex($letterspacing, $this->cssLetterSpacing);\r
+       }\r
+\r
+       protected function getCSSWordSpacing($wordspacing) {\r
+               $wordspacing = $this->normalizeFloatValue($wordspacing, 5);\r
+\r
+               if ($wordspacing == 0) {\r
+                       return null;\r
+               }\r
+               return $this->getIndex($wordspacing, $this->cssWordSpacing);\r
+       }\r
+\r
+       protected function getCSSRotation($rotation) {\r
+               $rotation = $this->normalizeFloatValue($rotation, 0);\r
+               if ($rotation == 0) {\r
+                       return null;\r
+               }\r
+               return $this->getIndex($rotation, $this->cssRotation);\r
+       }\r
+\r
+       protected function getCSSX($x) {\r
+               $x = round($x);\r
+               if ($x == 0) {\r
+                       return null;\r
+               }\r
+               return $this->getIndex($x, $this->cssX);\r
+       }\r
+\r
+       protected function getCSSY($y) {\r
+               $y = round($y);\r
+               if ($y == 0) {\r
+                       return null;\r
+               }\r
+               return $this->getIndex($y, $this->cssY);\r
+       }\r
+\r
+       protected function getIndex($value, &$tab) {\r
+               $value = (string) $value;\r
+               if (isset($tab[$value])) {\r
+                       return $tab[$value];\r
+               }\r
+               $res = $this->base62(count($tab));\r
+               $tab[$value] = $res;\r
+               return $res;\r
+       }\r
+\r
+       protected function normalizeFloatValue($value, $round=3) {\r
+               $value = str_replace(',', '.', $value);\r
+               $value = (float) $value;\r
+               $value = round($value, $round);\r
+               return $value;\r
+       }\r
+\r
+       protected function base62($val) {\r
+               $chars = '0123456789abcdefghijklmnopqrstuvwxyz';\r
+               $base = strlen($chars);\r
+               $str = '';\r
+               do {\r
+                       $i = $val % $base;\r
+                       $str = $chars[$i] . $str;\r
+                       $val = ($val - $i) / $base;\r
+               } while ($val > 0);\r
+               return $str;\r
+       }\r
+\r
+       public static function escapeHTML($in) {\r
+               $in = htmlentities($in, ENT_NOQUOTES, "UTF-8");\r
+               $in = str_replace('&thinsp;', '', $in);\r
+\r
+               return $in;\r
+       }\r
+\r
+       public function __destruct() {\r
+               \r
+       }\r
+\r
+       public static function colorToCSS($color) {\r
+               if (strlen($color) == 6) {\r
+                       return '#' . $color;\r
+               } else {\r
+                       $alpha = substr($color, 0, 2);\r
+                       $red = substr($color, 2, 2);\r
+                       $green = substr($color, 4, 2);\r
+                       $blue = substr($color, 6, 2);\r
+\r
+                       $components = array('alpha', 'red', 'green', 'blue');\r
+                       foreach ($components as $k => $name) {\r
+                               $hex = substr($color, $k * 2, 2);\r
+                               $$name = intval($hex, 16);\r
+                       }\r
+                       $alpha/=255;\r
+                       if ($alpha == 0) {\r
+                               return 'transparent';\r
+                       } elseif ($alpha == 1) {\r
+                               return '#' . substr($color, 2, 6);\r
+                       }\r
+                       return 'rgba(' . $red . ',' . $green . ',' . $blue . ',' . $alpha . ')';\r
+               }\r
+       }\r
+\r
+}\r
+\r
+?>
\ No newline at end of file