Skip to content
Snippets Groups Projects
Commit c5387d9f authored by Demian Katz's avatar Demian Katz
Browse files

More refactoring; added "initial" textMode setting.

parent 1e2a693c
No related merge requests found
......@@ -613,8 +613,9 @@ coverimagesCache = true
; These settings control the image to display when no book cover is available.
; If makeDynamicCovers is not false and the GD library is installed, VuFind will draw
; cover images on the fly. Possible values: false, solid, grid. See [DynamicCovers]
; below for more settings.
; cover images on the fly. See [DynamicCovers] below for more settings. If set to
; a non-Boolean value, for legacy reasons, the makeDynamicCovers setting will
; be used as the backgroundMode setting of [DynamicCovers] if that setting is unset.
;makeDynamicCovers = true
; Otherwise, you can use noCoverAvailableImage to specify a
......@@ -667,19 +668,33 @@ authors = Wikipedia
; This section controls the behavior of the cover generator when makeDynamicCovers
; above is non-false.
[DynamicCovers]
; This controls the background layer of the generated image; options:
; - solid: display a solid color
; - grid: display a symmetrical random pattern seeded by title/callnumber
;backgroundMode = grid
; This controls the text layer of the generated image; options:
; - default: display a title at the top and an author at the bottom
; - initial: display only the first letter of the title as a stylized initial
;textMode = default
; Font files specified here should exist in the css/font subdirectory of a theme.
; Some options are available by default inside the root theme.
;authorFont = "Roboto-Light.ttf"
;titleFont = "RobotoCondensed-Bold.ttf"
; Covers are generated using title and author name; VuFind will try to display
; everything by doing the following: break the title into lines, and if the title
; is too long (more than maxTitleLines lines), it will display ellipses at the last
; line.
; In 'default' textMode, covers are generated using title and author name; VuFind
; will try to display everything by doing the following: break the title into
; lines, and if the title is too long (more than maxTitleLines lines), it will
; display ellipses at the last line.
;
; All text will be drawn using the specified textAlign alignment value using the
; relevant titleFontSize or authorFontSize setting, except that author names will
; be reduced to the minAuthorFontSize option if needed, and if that doesn't make
; it fit, text will be aligned left and truncated.
;
; When using 'initial' textMode, maxTitleLines and author-related settings are
; ignored as they do not apply.
;textAlign = center
;titleFontSize = 9
;authorFontSize = 8
......@@ -693,12 +708,12 @@ authors = Wikipedia
; - authorFillColor,titleFillColor: the main color used
; - authorBorderColor,titleBorderColor: the color used to make a border; "none" is
; a legal option in addition to colors.
; - baseColor: When using grid covers, you may also choose a base color drawn
; - baseColor: When using grid backgrounds, you may also choose a base color drawn
; beneath the grid. Default is white.
; - accentColor: When using solid covers, this is the background color; when using
; grid covers, this is the color of the grid pattern beneath the text. You may
; set this to "random" to select a random color seeded with text from the cover
; and adjusted with the "lightness" and "saturation" settings below.
; - accentColor: When using solid backgrounds, this is the background color; when
; using grid backgrounds, this is the color of the grid pattern beneath the text.
; You may set this to "random" to select a random color seeded with text from
; the cover and adjusted with the "lightness" and "saturation" settings below.
;titleFillColor = black
;titleBorderColor = none
;authorFillColor = white
......
......@@ -111,7 +111,8 @@ class Generator
{
$this->themeTools = $themeTools;
$default = [
'mode' => 'grid',
'backgroundMode' => 'grid',
'textMode' => 'default',
'authorFont' => 'DroidSerif-Bold.ttf',
'titleFontSize' => 7,
'authorFontSize' => 6,
......@@ -265,19 +266,108 @@ class Generator
*/
public function generate($title, $author, $callnumber = null)
{
switch (strtolower($this->settings->mode)) {
case 'solid':
$this->generateSolid($title, $author, $callnumber);
case 'grid':
default:
$this->generateGrid($title, $author, $callnumber);
}
// Generate seed from callnumber, title back up
$seed = $this->createSeed($title, $callnumber);
// Build the image
$this->drawBackgroundLayer($seed);
$this->drawTextLayer($title, $author);
// Render the image
$png = $this->renderPng();
$this->destroyImage();
return $png;
}
/**
* Draw the background behind the text.
*
* @param int $seed Seed value
*
* @return void
*/
protected function drawBackgroundLayer($seed)
{
// Construct a method name using the mode setting; if the method is not
// defined, use the default drawGridBackground().
$mode = ucwords(strtolower($this->settings->backgroundMode));
$method = "draw{$mode}Background";
return method_exists($this, $method)
? $this->$method($seed) : $this->drawGridBackground($seed);
}
/**
* Position the text on the image.
*
* @param string $title Title of the book
* @param string $author Author of the book
*
* @return void
*/
protected function drawTextLayer($title, $author)
{
// Construct a method name using the mode setting; if the method is not
// defined, use the default drawGridBackground().
$mode = ucwords(strtolower($this->settings->textMode));
$method = "draw{$mode}Text";
return method_exists($this, $method)
? $this->$method($title, $author)
: $this->drawDefaultText($title, $author);
}
/**
* Position the text on the image using default rules.
*
* @param string $title Title of the book
* @param string $author Author of the book
*
* @return void
*/
protected function drawDefaultText($title, $author)
{
if (null !== $title) {
$this->drawTitle($title, $this->height / 8);
}
if (null !== $author) {
$this->drawAuthor($author);
}
}
/**
* Position the text on the image using "initials" rules.
*
* @param string $title Title of the book
* @param string $author Author of the book
*
* @return void
*/
protected function drawInitialText($title, $author)
{
// Get the first letter of title or author...
$initial = mb_substr($title . $author, 0, 1, 'UTF-8');
// Get the height of a character with no descenders:
$heightWithoutDescenders = $this->textHeight(
'O', $this->settings->titleFont, $this->settings->titleFontSize
);
// Get the height of the currently selected character:
$textHeight = $this->textHeight(
$initial, $this->settings->titleFont, $this->settings->titleFontSize
);
// Draw the letter...
$this->drawText(
$initial,
$heightWithoutDescenders + ($this->height - $textHeight) / 2,
$this->settings->titleFont,
$this->settings->titleFontSize,
$this->titleFillColor,
$this->titleBorderColor,
$this->settings->textAlign
);
}
/**
* Generate an accent color from a seed value.
*
......@@ -301,17 +391,12 @@ class Generator
/**
* Generates a solid color background, ala Google
*
* @param string $title Title of the book
* @param string $author Author of the book
* @param string $callnumber Callnumber of the book
* @param int $seed Seed value
*
* @return void
*/
protected function generateSolid($title, $author, $callnumber)
protected function drawSolidBackground($seed)
{
// Generate seed from callnumber, title back up
$seed = $this->createSeed($title, $callnumber);
// Fill solid color
imagefilledrectangle(
$this->im,
......@@ -321,34 +406,19 @@ class Generator
$this->height,
$this->getAccentColor($seed)
);
$this->drawTitle($title, $this->height / 8);
$this->drawAuthor($author);
}
/**
* Generates a grid of colors as primary feature
*
* @param string $title Title of the book
* @param string $author Author of the book
* @param string $callnumber Callnumber of the book
* @param int $seed Seed value
*
* @return void
*/
protected function generateGrid($title, $author, $callnumber)
protected function drawGridBackground($seed)
{
// Generate seed from callnumber, title back up
$seed = $this->createSeed($title, $callnumber);
// Render the grid
$pattern = $this->createPattern($seed);
$this->render($pattern, $this->getAccentColor($seed));
if (null !== $title) {
$this->drawTitle($title, $this->height / 8);
}
if (null !== $author) {
$this->drawAuthor($author);
}
$this->renderGrid($this->createPattern($seed), $this->getAccentColor($seed));
}
/**
......@@ -533,7 +603,7 @@ class Generator
* @param string $font Full font path
* @param string $size Size of the font
*
* @return string file path
* @return int
*/
protected function textWidth($text, $font, $size)
{
......@@ -541,16 +611,31 @@ class Generator
return $p[2] - $p[0];
}
/**
* Returns the height a string would render to
*
* @param string $text Text to test
* @param string $font Full font path
* @param string $size Size of the font
*
* @return int
*/
protected function textHeight($text, $font, $size)
{
$p = imagettfbbox($size, 0, $font, $text);
return $p[1] - $p[5];
}
/**
* Simulate outlined text
*
* @param string $text Text to render
* @param int $y Top position
* @param string $font Full path to font
* @param int $fontSize Size of the font
* @param GCColor $mcolor Main text color
* @param GCColor $scolor Secondary border color
* @param string $align 'left','center','right'
* @param string $text Text to render
* @param int $y Top position
* @param string $font Full path to font
* @param int $fontSize Size of the font
* @param int $mcolor Main text color
* @param int $scolor Secondary border color
* @param string $align 'left','center','right'
*
* @return void
*/
......@@ -606,12 +691,12 @@ class Generator
* Convert 16 long binary string to 8x8 color grid
* Reflects vertically and horizontally
*
* @param string $bc Binary string of pattern
* @param GCColor $color Fill color
* @param string $bc Binary string of pattern
* @param int $color Fill color
*
* @return void
*/
protected function render($bc, $color)
protected function renderGrid($bc, $color)
{
$halfWidth = $this->width / 2;
$halfHeight = $this->height / 2;
......@@ -648,7 +733,7 @@ class Generator
* @param int $s Saturation (0-255)
* @param int $v Lightness (0-255)
*
* @return GCColor
* @return int
*/
protected function makeHSBColor($h, $s, $v)
{
......
......@@ -158,8 +158,11 @@ class Loader extends \VuFind\ImageLoader
{
$settings = isset($this->config->DynamicCovers)
? $this->config->DynamicCovers->toArray() : [];
$settings['mode'] = isset($this->config->Content->makeDynamicCovers)
? $this->config->Content->makeDynamicCovers : false;
if (!isset($settings['backgroundMode'])
&& isset($this->config->Content->makeDynamicCovers)
) {
$settings['backgroundMode'] = $this->config->Content->makeDynamicCovers;
}
return new \VuFind\Cover\Generator($this->themeTools, $settings);
}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment