From: Vincent Vanwaelscappel Date: Thu, 23 Sep 2021 17:50:36 +0000 (+0200) Subject: wip #4697 @1 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=f211243f3d3b35594a0b4092ba31f768e056f36b;p=fluidbook_tools.git wip #4697 @1 --- diff --git a/src/Compiler/Compiler.php b/src/Compiler/Compiler.php index 4e6d139..6f75227 100644 --- a/src/Compiler/Compiler.php +++ b/src/Compiler/Compiler.php @@ -7,7 +7,6 @@ use Cubist\Util\PHP; use Exception; use Fluidbook\Tools\Jobs\ProcessFile; use Fluidbook\Tools\Jobs\ProcessPage; -use Fluidbook\Tools\Links\Link; use Fluidbook\Tools\PDF\Document; use Fluidbook\Tools\Search\SearchIndex; use Illuminate\Bus\Queueable; @@ -25,6 +24,7 @@ class Compiler implements ShouldQueue, ShouldBeUnique use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; use Links; + use Styles; /** @var VirtualDirectory */ protected $vdir; @@ -214,7 +214,7 @@ class Compiler implements ShouldQueue, ShouldBeUnique $this->compileDimensions(); $this->compilePageNumbers(); $this->compileChapters(); - $this->config->links = $this->compileLinks(); + $this->compileLinks(); $c = 'var SETTINGS=' . json_encode($this->config, JSON_THROW_ON_ERROR) . ';'; $this->vdir->file_put_contents('data/datas.js', $c); @@ -277,11 +277,13 @@ class Compiler implements ShouldQueue, ShouldBeUnique return $this->getWidth() * $this->getHeight(); } - public function getWidth(){ + public function getWidth() + { return $this->getSourceOfPage(1)->getSource()->getDocument()->getWidth(); } - public function getHeight(){ + public function getHeight() + { return $this->getSourceOfPage(1)->getSource()->getDocument()->getHeight(); } diff --git a/src/Compiler/Links.php b/src/Compiler/Links.php index 58bc22f..0044da6 100644 --- a/src/Compiler/Links.php +++ b/src/Compiler/Links.php @@ -218,7 +218,7 @@ trait Links ); } - if (isset($this->writeLinksData) && $this->writeLinksData) { + if (!isset($this->writeLinksData) || $this->writeLinksData) { $this->config->linksData = $allLinksData; } $this->config->gamifyCoins = $gamifyCoins; diff --git a/src/Compiler/Styles.php b/src/Compiler/Styles.php new file mode 100644 index 0000000..dba98d6 --- /dev/null +++ b/src/Compiler/Styles.php @@ -0,0 +1,329 @@ +addFontKit('OpenSans'); + + $lessContents = ''; + + $this->lessVariables['font'] = $this->_font($this->config->interfaceFont); + $this->lessVariables['text-transform'] = $this->_themeBoolean($this->config->interfaceFontUppercase) ? 'uppercase' : 'inherit'; + + $this->lessVariables['css-scale'] = $this->cssScale; + + $this->lessVariables['slider-background'] = Color::colorToCSS(!$this->config->sliderBackground ? 'rgba(0,0,0,0.1)' : $this->config->sliderBackground); + $this->lessVariables['slider-handle'] = Color::colorToCSS(!$this->config->sliderHandle ? '#ffffff' : $this->config->sliderHandle); + $this->lessVariables['slider-display'] = $this->_lessBoolean($this->config->pagesBar); + $this->lessVariables['slider-thumb-background'] = Color::colorToCSS($this->config->pageBarThumbBack); + $this->lessVariables['pages-background'] = $this->config->forceWhiteBackground ? '#ffffff' : 'transparent'; + + + // General theme + $cssWidth = $this->cssWidth; + $cssHeight = $this->cssHeight; + $cssScale = $this->cssScale; + $w2 = ($cssWidth * 2) . 'px'; + $h = $cssHeight . 'px'; + + $wm = ($this->getWidth() * $this->multiply) . 'px'; + $hm = ($this->getHeight() * $this->multiply) . 'px'; + $w = $cssWidth . 'px'; + $offsetLeft = round(($this->optimalWidth - $cssWidth) / 2, 3); + $offsetLeft2 = $offsetLeft * 2; + $offsetTop = round(($this->optimalHeight - $cssHeight) / 2, 3); + $navTop = ($cssHeight - 40 - 100) / 2; + $leftOfRightPage = (floor($cssWidth) - 1) . 'px'; + + $this->lessVariables['z'] = $this->z; + $this->lessVariables['book-page-width'] = $w; + + if ($this->config->correctCenter && !$this->isMobileFirst()) { + $this->lessVariables['book-page-correct-width'] = ceil($w) + 1; + $this->lessVariables['book-page-correct-height'] = ceil($h) + 1; + } else { + $this->lessVariables['book-page-correct-width'] = $w; + $this->lessVariables['book-page-correct-height'] = $h; + } + + + $this->lessVariables['book-page-height'] = $h; + $this->lessVariables['book-page-ratio'] = floatval($w) / floatval($h); + + $this->lessVariables['page-shade-opacity'] = min(1, $this->config->shadeAlpha / 50); + $c = new Color($this->config->bookShadeColor); + $this->lessVariables['shadow-opacity'] = $c->getAlpha() * 1.2; + $this->lessVariables['edges-display'] = $this->_lessBoolean($this->config->usePageEdges); + $this->lessVariables['edge-left-offset'] = 0; + $this->lessVariables['edge-right-offset'] = 0; + $this->lessVariables['edges-opacity'] = 1; + + + $this->lessVariables['page-number-color'] = Color::colorToCSS($this->config->colorPageNumber); + $this->lessVariables['display-page-number'] = $this->_lessBoolean($this->config->displayPageNumber); + $this->lessVariables['page-transition-duration'] = $this->config->mobileTransitionDuration . 's'; + + $corrText = $this->isMobileFirst() ? 0 : 4; + + if ($this->cssSVGScale != 1) { + $texts = '.texts{' . wsHTML5::writeCSSUA('transform-origin', 'top left') . ';'; + $texts .= wsHTML5::writeCSSUA('transform', 'scale(' . round((1 / $this->multiply) * $cssScale * $this->cssSVGScale, 3) . ')') . ';'; + $texts .= 'width:' . ($wm / $this->cssSVGScale) . 'px; max-width:' . ($wm / $this->cssSVGScale) . 'px;'; + $texts .= 'height:' . ($hm / $this->cssSVGScale) . 'px; max-height:' . ($hm / $this->cssSVGScale) . 'px;'; + $texts .= '}'; + } else { + $texts = '.texts{width:' . floor(floatval($w) + $corrText) . 'px;height:' . floor(floatval($h) + $corrText) . 'px;}'; + } + + $res[] = $texts; + + // Theme + $shade = '.page .shade{'; + $shade .= 'opacity:' . min(($this->config->shadeAlpha * 2) / 100, 1) . ';'; + $shade .= '}'; + $res[] = $shade; + + // SVG + $res[] = 'svg .fill-c-menu-back{fill:' . Color::colorToCSS($this->config->couleurB) . ';}'; + $res[] = 'svg .fill-c-menu-text{fill:' . Color::colorToCSS($this->config->subTextColor) . ';}'; + + // Background + $res[] = $this->_cssBackground(); + + // Archives + // Header + $header = 'header{'; + $header .= 'height:' . $this->config->menuHeight . 'px;'; + if ($mi = $this->checkThemeImage($this->config->menuImage)) { + $this->vdir->copy($mi, 'data/images/' . $this->config->menuImage); + $header .= 'background-image:url(../images/' . $this->config->menuImage . ');'; + $header .= 'background-repeat:no-repeat;'; + $header .= 'background-size:100% ' . $this->config->menuHeight . 'px;'; + } else { + // Force redo + $header .= 'background-color:' . Color::colorToCSS($this->config->menuColor) . ';'; + } + $header .= '}'; + $res[] = $header; + + // Logo + $logo = '#logo{'; + if ($l = $this->checkThemeImage($this->config->logo)) { + $this->vdir->copy($l, 'data/images/' . $this->config->logo); + $dim = CubeIT_Image::getimagesize($l); + $logo .= 'background-image:url(../images/' . $this->config->logo . ');width:' . $dim[0] . 'px;height:' . $dim[1] . 'px;'; + } + $logo .= '}'; + $res[] = $logo; + + // Credits + $res[] = 'footer,footer a{color:' . Color::colorToCSS($this->config->creditsColor) . ';}'; + + // Arrows + $this->lessVariables['arrows-background'] = Color::colorToCSS($this->config->couleurA); + $this->lessVariables['arrows-color'] = Color::colorToCSS($this->config->arrowsColor); + + // Loader + $this->lessVariables['loader-background-color'] = Color::colorToCSS($this->config->couleurL); + $this->lessVariables['loader-foreground-color'] = Color::colorToCSS($this->config->loadingSecColor); + + // Audio description buttons + $this->lessVariables['audiodescription-background'] = Color::colorToCSS($this->config->couleurA); + $this->lessVariables['audiodescription-color'] = Color::colorToCSS($this->config->couleurA); + + // Links Styles + $this->lessVariables['links-color'] = Color::colorToCSS($this->config->linksColor); + $this->lessVariables['inlineslideshow-transition-time'] = ((float)$this->config->inlineSlideshowTransitionDuration * 1000) . 'ms'; + $this->lessVariables['slideshow-caption-size'] = $this->config->slideshowCaptionSize ?: '16px'; + + $res = array_merge($res, $links); + + // Bookmarks + if (!isset($this->config->bookmarkCornerSize)) { + $this->config->bookmarkCornerSize = 10; + } + + $this->lessVariables['bookmark-star-disabled-color'] = Color::colorToCSS($this->config->bookmarkStarDisabledColor); + $this->lessVariables['bookmark-star-enabled-color'] = Color::colorToCSS($this->config->bookmarkStarEnabledColor); + $this->lessVariables['bookmark-color'] = Color::colorToCSS($this->config->bookmarkBackgroundColor); + $this->lessVariables['bookmark-corner-size'] = round($this->getWidth() * $this->config->bookmarkCornerSize * 0.0075 * $this->z) . 'px'; + $this->lessVariables['bookmark-corner-offset'] = $this->config->bookmarkOffset . 'px'; + + // Menus + $menuColor = new Color($this->config->couleurB); + $menuColor->setAlpha(1); + $menuTextColor = Color::colorToCSS($this->config->subTextColor); + $menuBreakpoint = empty($this->config->menuBreakpoint) ? '1023px' : $this->config->menuBreakpoint; + + $this->lessVariables['menu-breakpoint'] = $menuBreakpoint; + $this->lessVariables['menu-background'] = $menuColor->toCSS(); + if ($this->config->subSecondaryColor) { + $this->lessVariables['menu-button-background'] = Color::colorToCSS($this->config->subSecondaryColor); + } else { + $this->lessVariables['menu-background-green'] = 'max(45, min(255-45, green(@menu-background)))'; + $this->lessVariables['menu-background-red'] = 'max(45, min(255-45, red(@menu-background)))'; + $this->lessVariables['menu-background-blue'] = 'max(45, min(255-45, blue(@menu-background)))'; + $this->lessVariables['menu-button-background'] = 'overlay(rgb(@menu-background-red, @menu-background-green, @menu-background-blue), #c0c0c0)'; + } + + $this->lessVariables['menu-text'] = $menuTextColor; + $this->lessVariables['menu-field-background'] = Color::colorToCSS($this->config->subFieldColor); + $this->lessVariables['menu-field-text'] = Color::colorToCSS($this->config->subTextFieldColor); + $this->lessVariables['menu-select-background'] = Color::colorToCSS($this->config->subSelectColor); + $this->lessVariables['menu-select-text'] = Color::colorToCSS($this->config->subTextSelectColor); + $this->lessVariables['icon-color'] = Color::colorToCSS($this->config->couleurI); + $this->lessVariables['menu-overlay'] = Color::colorToCSS($this->config->popupVideoOverlay); + + // Chapters + $this->lessVariables['menu-chapters-columns-count'] = max(1, min(6, $this->config->chaptersColumns)); + $this->lessVariables['menu-chapters-columns-width'] = $this->config->chaptersColMaxWidth; + $this->lessVariables['menu-chapters-font-size'] = $this->config->chaptersFontSize; + + foreach ($this->book->chapters as $chapter) { + if (substr($chapter->page, 0, 1) != '#') { + continue; + } + if ($chapter->color == '') { + continue; + } + $color = trim($chapter->color, '#'); + $lessContents .= '.mview.c_' . $color . '{.menu-color(' . Color::colorToCSS($color) . ');}'; + } + + // Archives + if ($this->config->externalArchivesBack) { + $this->vdir->copy($this->wdir . '/' . $this->config->externalArchivesBack, 'data/images/' . $this->config->externalArchivesBack); + $res[] = '.mview.archives{background-image:url("../images/' . $this->config->externalArchivesBack . '");}'; + } + + # Index + $thumbw = $this->config->mobileNavigationType === 'portrait' ? 200 : 100; + $this->lessVariables['thumb-width'] = $thumbw . 'px'; + $ratio = $this->getWidth() / $this->getHeight(); + $thumbh = round($thumbw / $ratio); + $this->config->thumbWidth = $thumbw; + $this->config->thumbHeight = $thumbh; + + $this->lessVariables['thumb-height'] = $thumbh . 'px'; + + #tooltip + $this->lessVariables['tooltip-background'] = Color::colorToCSS($this->config->tooltipBackColor); + $this->lessVariables['tooltip-color'] = Color::colorToCSS($this->config->tooltipTextColor); + $this->lessVariables['tooltip-font-size'] = 14 * (($this->config->tooltipTextSize ?: 100) / 100); + + #Videos + if ($this->config->bigPlayImage) { + $this->lessVariables['video-bigplay-image'] = '~"../data/links/' . $this->config->bigPlayImage . '"'; + $this->vdir->copy($this->wdir . '/' . $this->config->bigPlayImage, 'data/links/' . $this->config->bigPlayImage); + } else { + $this->lessVariables['video-bigplay-image'] = '~"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMTMuNCAxMTMuNCI+PHN0eWxlPi5zdDB7b3BhY2l0eTowLjg7fSAuc3Qxe2ZpbGw6I0ZGRkZGRjt9PC9zdHlsZT48cGF0aCBjbGFzcz0ic3QwIiBkPSJNMTEwLjUgMTEzLjRIMi45Yy0xLjYgMC0yLjktMS4zLTIuOS0yLjlWMi45QzAgMS4zIDEuMyAwIDIuOSAwaDEwNy42YzEuNiAwIDIuOSAxLjMgMi45IDIuOXYxMDcuNmMwIDEuNi0xLjMgMi45LTIuOSAyLjl6Ii8+PHBhdGggY2xhc3M9InN0MSIgZD0iTTQ1LjggMzcuOGwzMS41IDE3LjljLjguNS44IDEuNiAwIDIuMUw0NS44IDc1LjZjLS44LjUtMS44LS4xLTEuOC0xVjM4LjhjMC0uOSAxLTEuNSAxLjgtMXoiLz48L3N2Zz4="'; + } + + #fonts + foreach ($this->cssfont as $hash => $item) { + $res[] = '@font-face{font-family: "' . $hash . '";src:url("../../data/fonts/' . $hash . '.woff") format("woff");}'; + } + + if ($this->config->textPopupStylesheet) { + $res[] = file_get_contents($this->wdir . '/' . $this->config->textPopupStylesheet); + } + + $this->compileLess($this->lessVariables, $lessContents); + $this->stylesheets[] = 'data/style/style.css'; + $this->vdir->file_put_contents('data/style/style.css', implode("\n", $res)); + + } + + protected function compileLess($variables, $lessContents = '') + { + if ($this->widget) { + $this->lessFiles[] = 'widget'; + } + foreach ($this->specialCSS as $s) { + $this->lessFiles[] = 'special/' . $s; + } + + $tmp = CubeIT_Files::tmpdir(); + + $from = $this->assets . '/style/*'; + `cp -r $from $tmp`; + + $bookVariables = array(); + foreach ($variables as $k => $v) { + $bookVariables[] = '@' . trim($k) . ':' . $v . ';'; + } + file_put_contents($tmp . '/book-variables.less', implode("\n", $bookVariables)); + file_put_contents($tmp . '/additional.less', $lessContents); + + foreach ($this->lessFiles as $f) { + $source_less = $this->assets . '/style/' . $f . '.less'; + $destination_less = $tmp . '/' . $f . '.less'; + $destination_css = $tmp . '/' . $f . '.css'; + + if (!file_exists($source_less)) { + die($source_less); + continue; + } + + $dir = dirname($destination_css); + + if (file_exists($dir) && !is_dir($dir)) { + unlink($dir); + } + // LESS file might be in a subfolder, so create if it doesn't exist + if (!file_exists($dir)) { + mkdir($dir, 0777, true); + } + + // Less files must be copied to temporary directory so they'll + // have access to the variables generated in book-variables.less + copy($source_less, $destination_less); + $less = new CommandLine('lessc'); + $less->setArg(null, $destination_less); + $less->setArg(null, $destination_css); + $less->execute(); + if (!file_exists($destination_css)) { + die($less->getOutput()); + continue; + } + $this->vdir->copy($destination_css, 'style/' . $f . '.css'); + if ($f != 'widget') { + $this->stylesheets[] = 'style/' . $f . '.css'; + } + } + } + + protected function checkThemeImage($path) + { + $path = trim($path); + $path = trim($path, '/'); + if (!$path) { + return false; + } + $p = $this->themeRoot . '/' . $path; + if (file_exists($p)) { + return $p; + } + $po = str_replace('.svg', '.o.svg', $p); + if (file_exists($po)) { + copy($po, $p); + return $p; + } + return false; + } + + protected function _themeBoolean($v): bool + { + return !(null === $v || $v === '0' || $v === 0 || $v === false || !$v); + } +}