Merge pull request #1001 from PrivateBin/jdenticon
add new Jdenticon comment icon library and set it as default
This commit is contained in:
commit
968d7a19bf
@ -3,6 +3,7 @@
|
|||||||
* **1.4.1 (not yet released)**
|
* **1.4.1 (not yet released)**
|
||||||
* ADDED: Translations for Turkish, Slovak and Greek
|
* ADDED: Translations for Turkish, Slovak and Greek
|
||||||
* ADDED: S3 Storage backend (#994)
|
* ADDED: S3 Storage backend (#994)
|
||||||
|
* CHANGED: Switched to Jdenticons as the default for comment icons (#793)
|
||||||
* CHANGED: Avoid `SUPER` privilege for setting the `sql_mode` for MariaDB/MySQL (#919)
|
* CHANGED: Avoid `SUPER` privilege for setting the `sql_mode` for MariaDB/MySQL (#919)
|
||||||
* CHANGED: Upgrading libraries to: zlib 1.2.13
|
* CHANGED: Upgrading libraries to: zlib 1.2.13
|
||||||
* FIXED: Revert to CREATE INDEX without IF NOT EXISTS clauses, to support MySQL (#943)
|
* FIXED: Revert to CREATE INDEX without IF NOT EXISTS clauses, to support MySQL (#943)
|
||||||
|
@ -65,10 +65,11 @@ languageselection = false
|
|||||||
; qrcode = true
|
; qrcode = true
|
||||||
|
|
||||||
; (optional) IP based icons are a weak mechanism to detect if a comment was from
|
; (optional) IP based icons are a weak mechanism to detect if a comment was from
|
||||||
; a different user when the same username was used in a comment. It might be
|
; a different user when the same username was used in a comment. It might get
|
||||||
; used to get the IP of a non anonymous comment poster if the server salt is
|
; used to get the IP of a comment poster if the server salt is leaked and a
|
||||||
; leaked and a SHA256 HMAC rainbow table is generated for all (relevant) IPs.
|
; SHA512 HMAC rainbow table is generated for all (relevant) IPs.
|
||||||
; Can be set to one these values: "none" / "vizhash" / "identicon" (default).
|
; Can be set to one these values:
|
||||||
|
; "none" / "vizhash" / "identicon" / "jdenticon" (default).
|
||||||
; icon = "none"
|
; icon = "none"
|
||||||
|
|
||||||
; Content Security Policy headers allow a website to restrict what sources are
|
; Content Security Policy headers allow a website to restrict what sources are
|
||||||
|
@ -27,7 +27,8 @@
|
|||||||
"php" : "^5.6.0 || ^7.0 || ^8.0",
|
"php" : "^5.6.0 || ^7.0 || ^8.0",
|
||||||
"paragonie/random_compat" : "2.0.21",
|
"paragonie/random_compat" : "2.0.21",
|
||||||
"yzalis/identicon" : "2.0.0",
|
"yzalis/identicon" : "2.0.0",
|
||||||
"mlocati/ip-lib" : "1.18.0"
|
"mlocati/ip-lib" : "1.18.0",
|
||||||
|
"jdenticon/jdenticon": "^1.0"
|
||||||
},
|
},
|
||||||
"suggest" : {
|
"suggest" : {
|
||||||
"google/cloud-storage" : "1.26.1",
|
"google/cloud-storage" : "1.26.1",
|
||||||
|
667
composer.lock
generated
667
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -53,7 +53,7 @@ class Configuration
|
|||||||
'languagedefault' => '',
|
'languagedefault' => '',
|
||||||
'urlshortener' => '',
|
'urlshortener' => '',
|
||||||
'qrcode' => true,
|
'qrcode' => true,
|
||||||
'icon' => 'identicon',
|
'icon' => 'jdenticon',
|
||||||
'cspheader' => 'default-src \'none\'; base-uri \'self\'; form-action \'none\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'unsafe-eval\'; style-src \'self\'; font-src \'self\'; frame-ancestors \'none\'; img-src \'self\' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads',
|
'cspheader' => 'default-src \'none\'; base-uri \'self\'; form-action \'none\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'unsafe-eval\'; style-src \'self\'; font-src \'self\'; frame-ancestors \'none\'; img-src \'self\' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads',
|
||||||
'zerobincompatibility' => false,
|
'zerobincompatibility' => false,
|
||||||
'httpwarning' => true,
|
'httpwarning' => true,
|
||||||
|
@ -14,6 +14,7 @@ namespace PrivateBin\Model;
|
|||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Identicon\Identicon;
|
use Identicon\Identicon;
|
||||||
|
use Jdenticon\Identicon as Jdenticon;
|
||||||
use PrivateBin\Persistence\TrafficLimiter;
|
use PrivateBin\Persistence\TrafficLimiter;
|
||||||
use PrivateBin\Vizhash16x16;
|
use PrivateBin\Vizhash16x16;
|
||||||
|
|
||||||
@ -164,7 +165,17 @@ class Comment extends AbstractModel
|
|||||||
if ($icon != 'none') {
|
if ($icon != 'none') {
|
||||||
$pngdata = '';
|
$pngdata = '';
|
||||||
$hmac = TrafficLimiter::getHash();
|
$hmac = TrafficLimiter::getHash();
|
||||||
if ($icon == 'identicon') {
|
if ($icon == 'jdenticon') {
|
||||||
|
$jdenticon = new Jdenticon(array(
|
||||||
|
'hash' => $hmac,
|
||||||
|
'size' => 16,
|
||||||
|
'style' => array(
|
||||||
|
'backgroundColor' => '#fff0', // fully transparent, for dark mode
|
||||||
|
'padding' => 0,
|
||||||
|
),
|
||||||
|
));
|
||||||
|
$pngdata = $jdenticon->getImageDataUri('png');
|
||||||
|
} elseif ($icon == 'identicon') {
|
||||||
$identicon = new Identicon();
|
$identicon = new Identicon();
|
||||||
$pngdata = $identicon->getImageDataUri($hmac, 16);
|
$pngdata = $identicon->getImageDataUri($hmac, 16);
|
||||||
} elseif ($icon == 'vizhash') {
|
} elseif ($icon == 'vizhash') {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Identicon\Identicon;
|
use Jdenticon\Identicon;
|
||||||
use PrivateBin\Configuration;
|
use PrivateBin\Configuration;
|
||||||
use PrivateBin\Data\Database;
|
use PrivateBin\Data\Database;
|
||||||
use PrivateBin\Model;
|
use PrivateBin\Model;
|
||||||
@ -314,8 +314,15 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
|||||||
$comment->get();
|
$comment->get();
|
||||||
$comment->store();
|
$comment->store();
|
||||||
|
|
||||||
$identicon = new Identicon();
|
$identicon = new Identicon(array(
|
||||||
$pngdata = $identicon->getImageDataUri(TrafficLimiter::getHash(), 16);
|
'hash' => TrafficLimiter::getHash(),
|
||||||
|
'size' => 16,
|
||||||
|
'style' => array(
|
||||||
|
'backgroundColor' => '#fff0', // fully transparent, for dark mode
|
||||||
|
'padding' => 0,
|
||||||
|
),
|
||||||
|
));
|
||||||
|
$pngdata = $identicon->getImageDataUri('png');
|
||||||
$comment = current($this->_model->getPaste(Helper::getPasteId())->get()['comments']);
|
$comment = current($this->_model->getPaste(Helper::getPasteId())->get()['comments']);
|
||||||
$this->assertEquals($pngdata, $comment['meta']['icon'], 'icon gets set');
|
$this->assertEquals($pngdata, $comment['meta']['icon'], 'icon gets set');
|
||||||
}
|
}
|
||||||
|
145
vendor/composer/ClassLoader.php
vendored
145
vendor/composer/ClassLoader.php
vendored
@ -37,57 +37,130 @@ namespace Composer\Autoload;
|
|||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||||
* @see http://www.php-fig.org/psr/psr-0/
|
* @see https://www.php-fig.org/psr/psr-0/
|
||||||
* @see http://www.php-fig.org/psr/psr-4/
|
* @see https://www.php-fig.org/psr/psr-4/
|
||||||
*/
|
*/
|
||||||
class ClassLoader
|
class ClassLoader
|
||||||
{
|
{
|
||||||
|
/** @var ?string */
|
||||||
|
private $vendorDir;
|
||||||
|
|
||||||
// PSR-4
|
// PSR-4
|
||||||
|
/**
|
||||||
|
* @var array[]
|
||||||
|
* @psalm-var array<string, array<string, int>>
|
||||||
|
*/
|
||||||
private $prefixLengthsPsr4 = array();
|
private $prefixLengthsPsr4 = array();
|
||||||
|
/**
|
||||||
|
* @var array[]
|
||||||
|
* @psalm-var array<string, array<int, string>>
|
||||||
|
*/
|
||||||
private $prefixDirsPsr4 = array();
|
private $prefixDirsPsr4 = array();
|
||||||
|
/**
|
||||||
|
* @var array[]
|
||||||
|
* @psalm-var array<string, string>
|
||||||
|
*/
|
||||||
private $fallbackDirsPsr4 = array();
|
private $fallbackDirsPsr4 = array();
|
||||||
|
|
||||||
// PSR-0
|
// PSR-0
|
||||||
|
/**
|
||||||
|
* @var array[]
|
||||||
|
* @psalm-var array<string, array<string, string[]>>
|
||||||
|
*/
|
||||||
private $prefixesPsr0 = array();
|
private $prefixesPsr0 = array();
|
||||||
|
/**
|
||||||
|
* @var array[]
|
||||||
|
* @psalm-var array<string, string>
|
||||||
|
*/
|
||||||
private $fallbackDirsPsr0 = array();
|
private $fallbackDirsPsr0 = array();
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
private $useIncludePath = false;
|
private $useIncludePath = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string[]
|
||||||
|
* @psalm-var array<string, string>
|
||||||
|
*/
|
||||||
private $classMap = array();
|
private $classMap = array();
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
private $classMapAuthoritative = false;
|
private $classMapAuthoritative = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool[]
|
||||||
|
* @psalm-var array<string, bool>
|
||||||
|
*/
|
||||||
private $missingClasses = array();
|
private $missingClasses = array();
|
||||||
|
|
||||||
|
/** @var ?string */
|
||||||
private $apcuPrefix;
|
private $apcuPrefix;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var self[]
|
||||||
|
*/
|
||||||
|
private static $registeredLoaders = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ?string $vendorDir
|
||||||
|
*/
|
||||||
|
public function __construct($vendorDir = null)
|
||||||
|
{
|
||||||
|
$this->vendorDir = $vendorDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
public function getPrefixes()
|
public function getPrefixes()
|
||||||
{
|
{
|
||||||
if (!empty($this->prefixesPsr0)) {
|
if (!empty($this->prefixesPsr0)) {
|
||||||
return call_user_func_array('array_merge', $this->prefixesPsr0);
|
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
||||||
}
|
}
|
||||||
|
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array[]
|
||||||
|
* @psalm-return array<string, array<int, string>>
|
||||||
|
*/
|
||||||
public function getPrefixesPsr4()
|
public function getPrefixesPsr4()
|
||||||
{
|
{
|
||||||
return $this->prefixDirsPsr4;
|
return $this->prefixDirsPsr4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array[]
|
||||||
|
* @psalm-return array<string, string>
|
||||||
|
*/
|
||||||
public function getFallbackDirs()
|
public function getFallbackDirs()
|
||||||
{
|
{
|
||||||
return $this->fallbackDirsPsr0;
|
return $this->fallbackDirsPsr0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array[]
|
||||||
|
* @psalm-return array<string, string>
|
||||||
|
*/
|
||||||
public function getFallbackDirsPsr4()
|
public function getFallbackDirsPsr4()
|
||||||
{
|
{
|
||||||
return $this->fallbackDirsPsr4;
|
return $this->fallbackDirsPsr4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[] Array of classname => path
|
||||||
|
* @psalm-return array<string, string>
|
||||||
|
*/
|
||||||
public function getClassMap()
|
public function getClassMap()
|
||||||
{
|
{
|
||||||
return $this->classMap;
|
return $this->classMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $classMap Class to filename map
|
* @param string[] $classMap Class to filename map
|
||||||
|
* @psalm-param array<string, string> $classMap
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function addClassMap(array $classMap)
|
public function addClassMap(array $classMap)
|
||||||
{
|
{
|
||||||
@ -103,8 +176,10 @@ class ClassLoader
|
|||||||
* appending or prepending to the ones previously set for this prefix.
|
* appending or prepending to the ones previously set for this prefix.
|
||||||
*
|
*
|
||||||
* @param string $prefix The prefix
|
* @param string $prefix The prefix
|
||||||
* @param array|string $paths The PSR-0 root directories
|
* @param string[]|string $paths The PSR-0 root directories
|
||||||
* @param bool $prepend Whether to prepend the directories
|
* @param bool $prepend Whether to prepend the directories
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function add($prefix, $paths, $prepend = false)
|
public function add($prefix, $paths, $prepend = false)
|
||||||
{
|
{
|
||||||
@ -148,10 +223,12 @@ class ClassLoader
|
|||||||
* appending or prepending to the ones previously set for this namespace.
|
* appending or prepending to the ones previously set for this namespace.
|
||||||
*
|
*
|
||||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||||
* @param array|string $paths The PSR-4 base directories
|
* @param string[]|string $paths The PSR-4 base directories
|
||||||
* @param bool $prepend Whether to prepend the directories
|
* @param bool $prepend Whether to prepend the directories
|
||||||
*
|
*
|
||||||
* @throws \InvalidArgumentException
|
* @throws \InvalidArgumentException
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function addPsr4($prefix, $paths, $prepend = false)
|
public function addPsr4($prefix, $paths, $prepend = false)
|
||||||
{
|
{
|
||||||
@ -196,7 +273,9 @@ class ClassLoader
|
|||||||
* replacing any others previously set for this prefix.
|
* replacing any others previously set for this prefix.
|
||||||
*
|
*
|
||||||
* @param string $prefix The prefix
|
* @param string $prefix The prefix
|
||||||
* @param array|string $paths The PSR-0 base directories
|
* @param string[]|string $paths The PSR-0 base directories
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function set($prefix, $paths)
|
public function set($prefix, $paths)
|
||||||
{
|
{
|
||||||
@ -212,9 +291,11 @@ class ClassLoader
|
|||||||
* replacing any others previously set for this namespace.
|
* replacing any others previously set for this namespace.
|
||||||
*
|
*
|
||||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||||
* @param array|string $paths The PSR-4 base directories
|
* @param string[]|string $paths The PSR-4 base directories
|
||||||
*
|
*
|
||||||
* @throws \InvalidArgumentException
|
* @throws \InvalidArgumentException
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setPsr4($prefix, $paths)
|
public function setPsr4($prefix, $paths)
|
||||||
{
|
{
|
||||||
@ -234,6 +315,8 @@ class ClassLoader
|
|||||||
* Turns on searching the include path for class files.
|
* Turns on searching the include path for class files.
|
||||||
*
|
*
|
||||||
* @param bool $useIncludePath
|
* @param bool $useIncludePath
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setUseIncludePath($useIncludePath)
|
public function setUseIncludePath($useIncludePath)
|
||||||
{
|
{
|
||||||
@ -256,6 +339,8 @@ class ClassLoader
|
|||||||
* that have not been registered with the class map.
|
* that have not been registered with the class map.
|
||||||
*
|
*
|
||||||
* @param bool $classMapAuthoritative
|
* @param bool $classMapAuthoritative
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||||
{
|
{
|
||||||
@ -276,6 +361,8 @@ class ClassLoader
|
|||||||
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||||
*
|
*
|
||||||
* @param string|null $apcuPrefix
|
* @param string|null $apcuPrefix
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setApcuPrefix($apcuPrefix)
|
public function setApcuPrefix($apcuPrefix)
|
||||||
{
|
{
|
||||||
@ -296,25 +383,44 @@ class ClassLoader
|
|||||||
* Registers this instance as an autoloader.
|
* Registers this instance as an autoloader.
|
||||||
*
|
*
|
||||||
* @param bool $prepend Whether to prepend the autoloader or not
|
* @param bool $prepend Whether to prepend the autoloader or not
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function register($prepend = false)
|
public function register($prepend = false)
|
||||||
{
|
{
|
||||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||||
|
|
||||||
|
if (null === $this->vendorDir) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($prepend) {
|
||||||
|
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
|
||||||
|
} else {
|
||||||
|
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||||
|
self::$registeredLoaders[$this->vendorDir] = $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregisters this instance as an autoloader.
|
* Unregisters this instance as an autoloader.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function unregister()
|
public function unregister()
|
||||||
{
|
{
|
||||||
spl_autoload_unregister(array($this, 'loadClass'));
|
spl_autoload_unregister(array($this, 'loadClass'));
|
||||||
|
|
||||||
|
if (null !== $this->vendorDir) {
|
||||||
|
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the given class or interface.
|
* Loads the given class or interface.
|
||||||
*
|
*
|
||||||
* @param string $class The name of the class
|
* @param string $class The name of the class
|
||||||
* @return bool|null True if loaded, null otherwise
|
* @return true|null True if loaded, null otherwise
|
||||||
*/
|
*/
|
||||||
public function loadClass($class)
|
public function loadClass($class)
|
||||||
{
|
{
|
||||||
@ -323,6 +429,8 @@ class ClassLoader
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -367,6 +475,21 @@ class ClassLoader
|
|||||||
return $file;
|
return $file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the currently registered loaders indexed by their corresponding vendor directories.
|
||||||
|
*
|
||||||
|
* @return self[]
|
||||||
|
*/
|
||||||
|
public static function getRegisteredLoaders()
|
||||||
|
{
|
||||||
|
return self::$registeredLoaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $class
|
||||||
|
* @param string $ext
|
||||||
|
* @return string|false
|
||||||
|
*/
|
||||||
private function findFileWithExtension($class, $ext)
|
private function findFileWithExtension($class, $ext)
|
||||||
{
|
{
|
||||||
// PSR-4 lookup
|
// PSR-4 lookup
|
||||||
@ -438,6 +561,10 @@ class ClassLoader
|
|||||||
* Scope isolated include.
|
* Scope isolated include.
|
||||||
*
|
*
|
||||||
* Prevents access to $this/self from included files.
|
* Prevents access to $this/self from included files.
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @return void
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
function includeFile($file)
|
function includeFile($file)
|
||||||
{
|
{
|
||||||
|
350
vendor/composer/InstalledVersions.php
vendored
Normal file
350
vendor/composer/InstalledVersions.php
vendored
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer;
|
||||||
|
|
||||||
|
use Composer\Autoload\ClassLoader;
|
||||||
|
use Composer\Semver\VersionParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is copied in every Composer installed project and available to all
|
||||||
|
*
|
||||||
|
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
||||||
|
*
|
||||||
|
* To require its presence, you can require `composer-runtime-api ^2.0`
|
||||||
|
*/
|
||||||
|
class InstalledVersions
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var mixed[]|null
|
||||||
|
* @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}|array{}|null
|
||||||
|
*/
|
||||||
|
private static $installed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool|null
|
||||||
|
*/
|
||||||
|
private static $canGetVendors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array[]
|
||||||
|
* @psalm-var array<string, array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
|
||||||
|
*/
|
||||||
|
private static $installedByVendor = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
* @psalm-return list<string>
|
||||||
|
*/
|
||||||
|
public static function getInstalledPackages()
|
||||||
|
{
|
||||||
|
$packages = array();
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
$packages[] = array_keys($installed['versions']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (1 === \count($packages)) {
|
||||||
|
return $packages[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of all package names with a specific type e.g. 'library'
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @return string[]
|
||||||
|
* @psalm-return list<string>
|
||||||
|
*/
|
||||||
|
public static function getInstalledPackagesByType($type)
|
||||||
|
{
|
||||||
|
$packagesByType = array();
|
||||||
|
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
foreach ($installed['versions'] as $name => $package) {
|
||||||
|
if (isset($package['type']) && $package['type'] === $type) {
|
||||||
|
$packagesByType[] = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $packagesByType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given package is installed
|
||||||
|
*
|
||||||
|
* This also returns true if the package name is provided or replaced by another package
|
||||||
|
*
|
||||||
|
* @param string $packageName
|
||||||
|
* @param bool $includeDevRequirements
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isInstalled($packageName, $includeDevRequirements = true)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (isset($installed['versions'][$packageName])) {
|
||||||
|
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given package satisfies a version constraint
|
||||||
|
*
|
||||||
|
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
|
||||||
|
*
|
||||||
|
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
|
||||||
|
*
|
||||||
|
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
|
||||||
|
* @param string $packageName
|
||||||
|
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
||||||
|
{
|
||||||
|
$constraint = $parser->parseConstraints($constraint);
|
||||||
|
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
||||||
|
|
||||||
|
return $provided->matches($constraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a version constraint representing all the range(s) which are installed for a given package
|
||||||
|
*
|
||||||
|
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
|
||||||
|
* whether a given version of a package is installed, and not just whether it exists
|
||||||
|
*
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string Version constraint usable with composer/semver
|
||||||
|
*/
|
||||||
|
public static function getVersionRanges($packageName)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (!isset($installed['versions'][$packageName])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ranges = array();
|
||||||
|
if (isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||||
|
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
|
||||||
|
}
|
||||||
|
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
|
||||||
|
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
|
||||||
|
}
|
||||||
|
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
|
||||||
|
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
|
||||||
|
}
|
||||||
|
if (array_key_exists('provided', $installed['versions'][$packageName])) {
|
||||||
|
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode(' || ', $ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||||
|
*/
|
||||||
|
public static function getVersion($packageName)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (!isset($installed['versions'][$packageName])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($installed['versions'][$packageName]['version'])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $installed['versions'][$packageName]['version'];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||||
|
*/
|
||||||
|
public static function getPrettyVersion($packageName)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (!isset($installed['versions'][$packageName])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $installed['versions'][$packageName]['pretty_version'];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
|
||||||
|
*/
|
||||||
|
public static function getReference($packageName)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (!isset($installed['versions'][$packageName])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($installed['versions'][$packageName]['reference'])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $installed['versions'][$packageName]['reference'];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
|
||||||
|
*/
|
||||||
|
public static function getInstallPath($packageName)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (!isset($installed['versions'][$packageName])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
|
||||||
|
*/
|
||||||
|
public static function getRootPackage()
|
||||||
|
{
|
||||||
|
$installed = self::getInstalled();
|
||||||
|
|
||||||
|
return $installed[0]['root'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the raw installed.php data for custom implementations
|
||||||
|
*
|
||||||
|
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
||||||
|
* @return array[]
|
||||||
|
* @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
|
||||||
|
*/
|
||||||
|
public static function getRawData()
|
||||||
|
{
|
||||||
|
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
if (null === self::$installed) {
|
||||||
|
// only require the installed.php file if this file is loaded from its dumped location,
|
||||||
|
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||||
|
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||||
|
self::$installed = include __DIR__ . '/installed.php';
|
||||||
|
} else {
|
||||||
|
self::$installed = array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$installed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
||||||
|
*
|
||||||
|
* @return array[]
|
||||||
|
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
|
||||||
|
*/
|
||||||
|
public static function getAllRawData()
|
||||||
|
{
|
||||||
|
return self::getInstalled();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lets you reload the static array from another file
|
||||||
|
*
|
||||||
|
* This is only useful for complex integrations in which a project needs to use
|
||||||
|
* this class but then also needs to execute another project's autoloader in process,
|
||||||
|
* and wants to ensure both projects have access to their version of installed.php.
|
||||||
|
*
|
||||||
|
* A typical case would be PHPUnit, where it would need to make sure it reads all
|
||||||
|
* the data it needs from this class, then call reload() with
|
||||||
|
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
|
||||||
|
* the project in which it runs can then also use this class safely, without
|
||||||
|
* interference between PHPUnit's dependencies and the project's dependencies.
|
||||||
|
*
|
||||||
|
* @param array[] $data A vendor/composer/installed.php data set
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
|
||||||
|
*/
|
||||||
|
public static function reload($data)
|
||||||
|
{
|
||||||
|
self::$installed = $data;
|
||||||
|
self::$installedByVendor = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array[]
|
||||||
|
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
|
||||||
|
*/
|
||||||
|
private static function getInstalled()
|
||||||
|
{
|
||||||
|
if (null === self::$canGetVendors) {
|
||||||
|
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
|
||||||
|
}
|
||||||
|
|
||||||
|
$installed = array();
|
||||||
|
|
||||||
|
if (self::$canGetVendors) {
|
||||||
|
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||||
|
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||||
|
$installed[] = self::$installedByVendor[$vendorDir];
|
||||||
|
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||||
|
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
|
||||||
|
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
||||||
|
self::$installed = $installed[count($installed) - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === self::$installed) {
|
||||||
|
// only require the installed.php file if this file is loaded from its dumped location,
|
||||||
|
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||||
|
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||||
|
self::$installed = require __DIR__ . '/installed.php';
|
||||||
|
} else {
|
||||||
|
self::$installed = array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$installed[] = self::$installed;
|
||||||
|
|
||||||
|
return $installed;
|
||||||
|
}
|
||||||
|
}
|
39
vendor/composer/autoload_classmap.php
vendored
39
vendor/composer/autoload_classmap.php
vendored
@ -6,6 +6,7 @@ $vendorDir = dirname(dirname(__FILE__));
|
|||||||
$baseDir = dirname($vendorDir);
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
'IPLib\\Address\\AddressInterface' => $vendorDir . '/mlocati/ip-lib/src/Address/AddressInterface.php',
|
'IPLib\\Address\\AddressInterface' => $vendorDir . '/mlocati/ip-lib/src/Address/AddressInterface.php',
|
||||||
'IPLib\\Address\\AssignedRange' => $vendorDir . '/mlocati/ip-lib/src/Address/AssignedRange.php',
|
'IPLib\\Address\\AssignedRange' => $vendorDir . '/mlocati/ip-lib/src/Address/AssignedRange.php',
|
||||||
'IPLib\\Address\\IPv4' => $vendorDir . '/mlocati/ip-lib/src/Address/IPv4.php',
|
'IPLib\\Address\\IPv4' => $vendorDir . '/mlocati/ip-lib/src/Address/IPv4.php',
|
||||||
@ -28,12 +29,49 @@ return array(
|
|||||||
'Identicon\\Generator\\ImageMagickGenerator' => $vendorDir . '/yzalis/identicon/src/Identicon/Generator/ImageMagickGenerator.php',
|
'Identicon\\Generator\\ImageMagickGenerator' => $vendorDir . '/yzalis/identicon/src/Identicon/Generator/ImageMagickGenerator.php',
|
||||||
'Identicon\\Generator\\SvgGenerator' => $vendorDir . '/yzalis/identicon/src/Identicon/Generator/SvgGenerator.php',
|
'Identicon\\Generator\\SvgGenerator' => $vendorDir . '/yzalis/identicon/src/Identicon/Generator/SvgGenerator.php',
|
||||||
'Identicon\\Identicon' => $vendorDir . '/yzalis/identicon/src/Identicon/Identicon.php',
|
'Identicon\\Identicon' => $vendorDir . '/yzalis/identicon/src/Identicon/Identicon.php',
|
||||||
|
'Jdenticon\\Canvas\\Canvas' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Canvas.php',
|
||||||
|
'Jdenticon\\Canvas\\CanvasContext' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/CanvasContext.php',
|
||||||
|
'Jdenticon\\Canvas\\ColorUtils' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/ColorUtils.php',
|
||||||
|
'Jdenticon\\Canvas\\Matrix' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Matrix.php',
|
||||||
|
'Jdenticon\\Canvas\\Png\\PngBuffer' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Png/PngBuffer.php',
|
||||||
|
'Jdenticon\\Canvas\\Png\\PngEncoder' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Png/PngEncoder.php',
|
||||||
|
'Jdenticon\\Canvas\\Png\\PngPalette' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Png/PngPalette.php',
|
||||||
|
'Jdenticon\\Canvas\\Point' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Point.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\Edge' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/Edge.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\EdgeIntersection' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeIntersection.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\EdgeSuperSampleIntersection' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeSuperSampleIntersection.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\EdgeTable' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeTable.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\Layer' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/Layer.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\LayerManager' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/LayerManager.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\Rasterizer' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/Rasterizer.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\SuperSampleBuffer' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/SuperSampleBuffer.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\SuperSampleRange' => $vendorDir . '/jdenticon/jdenticon/src/Canvas/Rasterization/SuperSampleRange.php',
|
||||||
|
'Jdenticon\\Color' => $vendorDir . '/jdenticon/jdenticon/src/Color.php',
|
||||||
|
'Jdenticon\\Identicon' => $vendorDir . '/jdenticon/jdenticon/src/Identicon.php',
|
||||||
|
'Jdenticon\\IdenticonStyle' => $vendorDir . '/jdenticon/jdenticon/src/IdenticonStyle.php',
|
||||||
|
'Jdenticon\\Rendering\\AbstractRenderer' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/AbstractRenderer.php',
|
||||||
|
'Jdenticon\\Rendering\\ColorTheme' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/ColorTheme.php',
|
||||||
|
'Jdenticon\\Rendering\\IconGenerator' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/IconGenerator.php',
|
||||||
|
'Jdenticon\\Rendering\\ImagickRenderer' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/ImagickRenderer.php',
|
||||||
|
'Jdenticon\\Rendering\\InternalPngRenderer' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/InternalPngRenderer.php',
|
||||||
|
'Jdenticon\\Rendering\\Point' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/Point.php',
|
||||||
|
'Jdenticon\\Rendering\\Rectangle' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/Rectangle.php',
|
||||||
|
'Jdenticon\\Rendering\\RendererInterface' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/RendererInterface.php',
|
||||||
|
'Jdenticon\\Rendering\\SvgPath' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/SvgPath.php',
|
||||||
|
'Jdenticon\\Rendering\\SvgRenderer' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/SvgRenderer.php',
|
||||||
|
'Jdenticon\\Rendering\\Transform' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/Transform.php',
|
||||||
|
'Jdenticon\\Rendering\\TriangleDirection' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/TriangleDirection.php',
|
||||||
|
'Jdenticon\\Shapes\\Shape' => $vendorDir . '/jdenticon/jdenticon/src/Shapes/Shape.php',
|
||||||
|
'Jdenticon\\Shapes\\ShapeCategory' => $vendorDir . '/jdenticon/jdenticon/src/Shapes/ShapeCategory.php',
|
||||||
|
'Jdenticon\\Shapes\\ShapeDefinitions' => $vendorDir . '/jdenticon/jdenticon/src/Shapes/ShapeDefinitions.php',
|
||||||
|
'Jdenticon\\Shapes\\ShapePosition' => $vendorDir . '/jdenticon/jdenticon/src/Shapes/ShapePosition.php',
|
||||||
'PrivateBin\\Configuration' => $baseDir . '/lib/Configuration.php',
|
'PrivateBin\\Configuration' => $baseDir . '/lib/Configuration.php',
|
||||||
'PrivateBin\\Controller' => $baseDir . '/lib/Controller.php',
|
'PrivateBin\\Controller' => $baseDir . '/lib/Controller.php',
|
||||||
'PrivateBin\\Data\\AbstractData' => $baseDir . '/lib/Data/AbstractData.php',
|
'PrivateBin\\Data\\AbstractData' => $baseDir . '/lib/Data/AbstractData.php',
|
||||||
'PrivateBin\\Data\\Database' => $baseDir . '/lib/Data/Database.php',
|
'PrivateBin\\Data\\Database' => $baseDir . '/lib/Data/Database.php',
|
||||||
'PrivateBin\\Data\\Filesystem' => $baseDir . '/lib/Data/Filesystem.php',
|
'PrivateBin\\Data\\Filesystem' => $baseDir . '/lib/Data/Filesystem.php',
|
||||||
'PrivateBin\\Data\\GoogleCloudStorage' => $baseDir . '/lib/Data/GoogleCloudStorage.php',
|
'PrivateBin\\Data\\GoogleCloudStorage' => $baseDir . '/lib/Data/GoogleCloudStorage.php',
|
||||||
|
'PrivateBin\\Data\\S3Storage' => $baseDir . '/lib/Data/S3Storage.php',
|
||||||
'PrivateBin\\Filter' => $baseDir . '/lib/Filter.php',
|
'PrivateBin\\Filter' => $baseDir . '/lib/Filter.php',
|
||||||
'PrivateBin\\FormatV2' => $baseDir . '/lib/FormatV2.php',
|
'PrivateBin\\FormatV2' => $baseDir . '/lib/FormatV2.php',
|
||||||
'PrivateBin\\I18n' => $baseDir . '/lib/I18n.php',
|
'PrivateBin\\I18n' => $baseDir . '/lib/I18n.php',
|
||||||
@ -49,4 +87,5 @@ return array(
|
|||||||
'PrivateBin\\Request' => $baseDir . '/lib/Request.php',
|
'PrivateBin\\Request' => $baseDir . '/lib/Request.php',
|
||||||
'PrivateBin\\View' => $baseDir . '/lib/View.php',
|
'PrivateBin\\View' => $baseDir . '/lib/View.php',
|
||||||
'PrivateBin\\Vizhash16x16' => $baseDir . '/lib/Vizhash16x16.php',
|
'PrivateBin\\Vizhash16x16' => $baseDir . '/lib/Vizhash16x16.php',
|
||||||
|
'PrivateBin\\YourlsProxy' => $baseDir . '/lib/YourlsProxy.php',
|
||||||
);
|
);
|
||||||
|
1
vendor/composer/autoload_psr4.php
vendored
1
vendor/composer/autoload_psr4.php
vendored
@ -7,6 +7,7 @@ $baseDir = dirname($vendorDir);
|
|||||||
|
|
||||||
return array(
|
return array(
|
||||||
'PrivateBin\\' => array($baseDir . '/lib'),
|
'PrivateBin\\' => array($baseDir . '/lib'),
|
||||||
|
'Jdenticon\\' => array($vendorDir . '/jdenticon/jdenticon/src'),
|
||||||
'Identicon\\' => array($vendorDir . '/yzalis/identicon/src/Identicon'),
|
'Identicon\\' => array($vendorDir . '/yzalis/identicon/src/Identicon'),
|
||||||
'IPLib\\' => array($vendorDir . '/mlocati/ip-lib/src'),
|
'IPLib\\' => array($vendorDir . '/mlocati/ip-lib/src'),
|
||||||
);
|
);
|
||||||
|
15
vendor/composer/autoload_real.php
vendored
15
vendor/composer/autoload_real.php
vendored
@ -22,13 +22,15 @@ class ComposerAutoloaderInitDontChange
|
|||||||
return self::$loader;
|
return self::$loader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
require __DIR__ . '/platform_check.php';
|
||||||
|
|
||||||
spl_autoload_register(array('ComposerAutoloaderInitDontChange', 'loadClassLoader'), true, true);
|
spl_autoload_register(array('ComposerAutoloaderInitDontChange', 'loadClassLoader'), true, true);
|
||||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
|
||||||
spl_autoload_unregister(array('ComposerAutoloaderInitDontChange', 'loadClassLoader'));
|
spl_autoload_unregister(array('ComposerAutoloaderInitDontChange', 'loadClassLoader'));
|
||||||
|
|
||||||
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
||||||
if ($useStaticLoader) {
|
if ($useStaticLoader) {
|
||||||
require_once __DIR__ . '/autoload_static.php';
|
require __DIR__ . '/autoload_static.php';
|
||||||
|
|
||||||
call_user_func(\Composer\Autoload\ComposerStaticInitDontChange::getInitializer($loader));
|
call_user_func(\Composer\Autoload\ComposerStaticInitDontChange::getInitializer($loader));
|
||||||
} else {
|
} else {
|
||||||
@ -63,11 +65,16 @@ class ComposerAutoloaderInitDontChange
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $fileIdentifier
|
||||||
|
* @param string $file
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
function composerRequireDontChange($fileIdentifier, $file)
|
function composerRequireDontChange($fileIdentifier, $file)
|
||||||
{
|
{
|
||||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||||
require $file;
|
|
||||||
|
|
||||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||||
|
|
||||||
|
require $file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
47
vendor/composer/autoload_static.php
vendored
47
vendor/composer/autoload_static.php
vendored
@ -15,6 +15,10 @@ class ComposerStaticInitDontChange
|
|||||||
array (
|
array (
|
||||||
'PrivateBin\\' => 11,
|
'PrivateBin\\' => 11,
|
||||||
),
|
),
|
||||||
|
'J' =>
|
||||||
|
array (
|
||||||
|
'Jdenticon\\' => 10,
|
||||||
|
),
|
||||||
'I' =>
|
'I' =>
|
||||||
array (
|
array (
|
||||||
'Identicon\\' => 10,
|
'Identicon\\' => 10,
|
||||||
@ -27,6 +31,10 @@ class ComposerStaticInitDontChange
|
|||||||
array (
|
array (
|
||||||
0 => __DIR__ . '/../..' . '/lib',
|
0 => __DIR__ . '/../..' . '/lib',
|
||||||
),
|
),
|
||||||
|
'Jdenticon\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/jdenticon/jdenticon/src',
|
||||||
|
),
|
||||||
'Identicon\\' =>
|
'Identicon\\' =>
|
||||||
array (
|
array (
|
||||||
0 => __DIR__ . '/..' . '/yzalis/identicon/src/Identicon',
|
0 => __DIR__ . '/..' . '/yzalis/identicon/src/Identicon',
|
||||||
@ -38,6 +46,7 @@ class ComposerStaticInitDontChange
|
|||||||
);
|
);
|
||||||
|
|
||||||
public static $classMap = array (
|
public static $classMap = array (
|
||||||
|
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||||
'IPLib\\Address\\AddressInterface' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Address/AddressInterface.php',
|
'IPLib\\Address\\AddressInterface' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Address/AddressInterface.php',
|
||||||
'IPLib\\Address\\AssignedRange' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Address/AssignedRange.php',
|
'IPLib\\Address\\AssignedRange' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Address/AssignedRange.php',
|
||||||
'IPLib\\Address\\IPv4' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Address/IPv4.php',
|
'IPLib\\Address\\IPv4' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Address/IPv4.php',
|
||||||
@ -60,12 +69,49 @@ class ComposerStaticInitDontChange
|
|||||||
'Identicon\\Generator\\ImageMagickGenerator' => __DIR__ . '/..' . '/yzalis/identicon/src/Identicon/Generator/ImageMagickGenerator.php',
|
'Identicon\\Generator\\ImageMagickGenerator' => __DIR__ . '/..' . '/yzalis/identicon/src/Identicon/Generator/ImageMagickGenerator.php',
|
||||||
'Identicon\\Generator\\SvgGenerator' => __DIR__ . '/..' . '/yzalis/identicon/src/Identicon/Generator/SvgGenerator.php',
|
'Identicon\\Generator\\SvgGenerator' => __DIR__ . '/..' . '/yzalis/identicon/src/Identicon/Generator/SvgGenerator.php',
|
||||||
'Identicon\\Identicon' => __DIR__ . '/..' . '/yzalis/identicon/src/Identicon/Identicon.php',
|
'Identicon\\Identicon' => __DIR__ . '/..' . '/yzalis/identicon/src/Identicon/Identicon.php',
|
||||||
|
'Jdenticon\\Canvas\\Canvas' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Canvas.php',
|
||||||
|
'Jdenticon\\Canvas\\CanvasContext' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/CanvasContext.php',
|
||||||
|
'Jdenticon\\Canvas\\ColorUtils' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/ColorUtils.php',
|
||||||
|
'Jdenticon\\Canvas\\Matrix' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Matrix.php',
|
||||||
|
'Jdenticon\\Canvas\\Png\\PngBuffer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Png/PngBuffer.php',
|
||||||
|
'Jdenticon\\Canvas\\Png\\PngEncoder' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Png/PngEncoder.php',
|
||||||
|
'Jdenticon\\Canvas\\Png\\PngPalette' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Png/PngPalette.php',
|
||||||
|
'Jdenticon\\Canvas\\Point' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Point.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\Edge' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/Edge.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\EdgeIntersection' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeIntersection.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\EdgeSuperSampleIntersection' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeSuperSampleIntersection.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\EdgeTable' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeTable.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\Layer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/Layer.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\LayerManager' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/LayerManager.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\Rasterizer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/Rasterizer.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\SuperSampleBuffer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/SuperSampleBuffer.php',
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\SuperSampleRange' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Canvas/Rasterization/SuperSampleRange.php',
|
||||||
|
'Jdenticon\\Color' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Color.php',
|
||||||
|
'Jdenticon\\Identicon' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Identicon.php',
|
||||||
|
'Jdenticon\\IdenticonStyle' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/IdenticonStyle.php',
|
||||||
|
'Jdenticon\\Rendering\\AbstractRenderer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/AbstractRenderer.php',
|
||||||
|
'Jdenticon\\Rendering\\ColorTheme' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/ColorTheme.php',
|
||||||
|
'Jdenticon\\Rendering\\IconGenerator' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/IconGenerator.php',
|
||||||
|
'Jdenticon\\Rendering\\ImagickRenderer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/ImagickRenderer.php',
|
||||||
|
'Jdenticon\\Rendering\\InternalPngRenderer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/InternalPngRenderer.php',
|
||||||
|
'Jdenticon\\Rendering\\Point' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/Point.php',
|
||||||
|
'Jdenticon\\Rendering\\Rectangle' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/Rectangle.php',
|
||||||
|
'Jdenticon\\Rendering\\RendererInterface' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/RendererInterface.php',
|
||||||
|
'Jdenticon\\Rendering\\SvgPath' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/SvgPath.php',
|
||||||
|
'Jdenticon\\Rendering\\SvgRenderer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/SvgRenderer.php',
|
||||||
|
'Jdenticon\\Rendering\\Transform' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/Transform.php',
|
||||||
|
'Jdenticon\\Rendering\\TriangleDirection' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/TriangleDirection.php',
|
||||||
|
'Jdenticon\\Shapes\\Shape' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Shapes/Shape.php',
|
||||||
|
'Jdenticon\\Shapes\\ShapeCategory' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Shapes/ShapeCategory.php',
|
||||||
|
'Jdenticon\\Shapes\\ShapeDefinitions' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Shapes/ShapeDefinitions.php',
|
||||||
|
'Jdenticon\\Shapes\\ShapePosition' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Shapes/ShapePosition.php',
|
||||||
'PrivateBin\\Configuration' => __DIR__ . '/../..' . '/lib/Configuration.php',
|
'PrivateBin\\Configuration' => __DIR__ . '/../..' . '/lib/Configuration.php',
|
||||||
'PrivateBin\\Controller' => __DIR__ . '/../..' . '/lib/Controller.php',
|
'PrivateBin\\Controller' => __DIR__ . '/../..' . '/lib/Controller.php',
|
||||||
'PrivateBin\\Data\\AbstractData' => __DIR__ . '/../..' . '/lib/Data/AbstractData.php',
|
'PrivateBin\\Data\\AbstractData' => __DIR__ . '/../..' . '/lib/Data/AbstractData.php',
|
||||||
'PrivateBin\\Data\\Database' => __DIR__ . '/../..' . '/lib/Data/Database.php',
|
'PrivateBin\\Data\\Database' => __DIR__ . '/../..' . '/lib/Data/Database.php',
|
||||||
'PrivateBin\\Data\\Filesystem' => __DIR__ . '/../..' . '/lib/Data/Filesystem.php',
|
'PrivateBin\\Data\\Filesystem' => __DIR__ . '/../..' . '/lib/Data/Filesystem.php',
|
||||||
'PrivateBin\\Data\\GoogleCloudStorage' => __DIR__ . '/../..' . '/lib/Data/GoogleCloudStorage.php',
|
'PrivateBin\\Data\\GoogleCloudStorage' => __DIR__ . '/../..' . '/lib/Data/GoogleCloudStorage.php',
|
||||||
|
'PrivateBin\\Data\\S3Storage' => __DIR__ . '/../..' . '/lib/Data/S3Storage.php',
|
||||||
'PrivateBin\\Filter' => __DIR__ . '/../..' . '/lib/Filter.php',
|
'PrivateBin\\Filter' => __DIR__ . '/../..' . '/lib/Filter.php',
|
||||||
'PrivateBin\\FormatV2' => __DIR__ . '/../..' . '/lib/FormatV2.php',
|
'PrivateBin\\FormatV2' => __DIR__ . '/../..' . '/lib/FormatV2.php',
|
||||||
'PrivateBin\\I18n' => __DIR__ . '/../..' . '/lib/I18n.php',
|
'PrivateBin\\I18n' => __DIR__ . '/../..' . '/lib/I18n.php',
|
||||||
@ -81,6 +127,7 @@ class ComposerStaticInitDontChange
|
|||||||
'PrivateBin\\Request' => __DIR__ . '/../..' . '/lib/Request.php',
|
'PrivateBin\\Request' => __DIR__ . '/../..' . '/lib/Request.php',
|
||||||
'PrivateBin\\View' => __DIR__ . '/../..' . '/lib/View.php',
|
'PrivateBin\\View' => __DIR__ . '/../..' . '/lib/View.php',
|
||||||
'PrivateBin\\Vizhash16x16' => __DIR__ . '/../..' . '/lib/Vizhash16x16.php',
|
'PrivateBin\\Vizhash16x16' => __DIR__ . '/../..' . '/lib/Vizhash16x16.php',
|
||||||
|
'PrivateBin\\YourlsProxy' => __DIR__ . '/../..' . '/lib/YourlsProxy.php',
|
||||||
);
|
);
|
||||||
|
|
||||||
public static function getInitializer(ClassLoader $loader)
|
public static function getInitializer(ClassLoader $loader)
|
||||||
|
59
vendor/composer/installed.php
vendored
Normal file
59
vendor/composer/installed.php
vendored
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?php return array(
|
||||||
|
'root' => array(
|
||||||
|
'pretty_version' => 'dev-master',
|
||||||
|
'version' => 'dev-master',
|
||||||
|
'type' => 'project',
|
||||||
|
'install_path' => __DIR__ . '/../../',
|
||||||
|
'aliases' => array(),
|
||||||
|
'reference' => '78aa70e3ab9277172489f9d88f8fd08cc1d03c97',
|
||||||
|
'name' => 'privatebin/privatebin',
|
||||||
|
'dev' => false,
|
||||||
|
),
|
||||||
|
'versions' => array(
|
||||||
|
'jdenticon/jdenticon' => array(
|
||||||
|
'pretty_version' => '1.0.1',
|
||||||
|
'version' => '1.0.1.0',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../jdenticon/jdenticon',
|
||||||
|
'aliases' => array(),
|
||||||
|
'reference' => '994ee07293fb978f983393ffcb2c0250592a6ac4',
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'mlocati/ip-lib' => array(
|
||||||
|
'pretty_version' => '1.18.0',
|
||||||
|
'version' => '1.18.0.0',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../mlocati/ip-lib',
|
||||||
|
'aliases' => array(),
|
||||||
|
'reference' => 'c77bd0b1f3e3956c7e9661e75cb1f54ed67d95d2',
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'paragonie/random_compat' => array(
|
||||||
|
'pretty_version' => 'v2.0.21',
|
||||||
|
'version' => '2.0.21.0',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../paragonie/random_compat',
|
||||||
|
'aliases' => array(),
|
||||||
|
'reference' => '96c132c7f2f7bc3230723b66e89f8f150b29d5ae',
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'privatebin/privatebin' => array(
|
||||||
|
'pretty_version' => 'dev-master',
|
||||||
|
'version' => 'dev-master',
|
||||||
|
'type' => 'project',
|
||||||
|
'install_path' => __DIR__ . '/../../',
|
||||||
|
'aliases' => array(),
|
||||||
|
'reference' => '78aa70e3ab9277172489f9d88f8fd08cc1d03c97',
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'yzalis/identicon' => array(
|
||||||
|
'pretty_version' => '2.0.0',
|
||||||
|
'version' => '2.0.0.0',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../yzalis/identicon',
|
||||||
|
'aliases' => array(),
|
||||||
|
'reference' => 'ff5ed090129cab9bfa2a322857d4a01d107aa0ae',
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
26
vendor/composer/platform_check.php
vendored
Normal file
26
vendor/composer/platform_check.php
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// platform_check.php @generated by Composer
|
||||||
|
|
||||||
|
$issues = array();
|
||||||
|
|
||||||
|
if (!(PHP_VERSION_ID >= 50600)) {
|
||||||
|
$issues[] = 'Your Composer dependencies require a PHP version ">= 5.6.0". You are running ' . PHP_VERSION . '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($issues) {
|
||||||
|
if (!headers_sent()) {
|
||||||
|
header('HTTP/1.1 500 Internal Server Error');
|
||||||
|
}
|
||||||
|
if (!ini_get('display_errors')) {
|
||||||
|
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||||
|
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
||||||
|
} elseif (!headers_sent()) {
|
||||||
|
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trigger_error(
|
||||||
|
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
||||||
|
E_USER_ERROR
|
||||||
|
);
|
||||||
|
}
|
130
vendor/jdenticon/jdenticon/src/Canvas/Canvas.php
vendored
Normal file
130
vendor/jdenticon/jdenticon/src/Canvas/Canvas.php
vendored
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Canvas;
|
||||||
|
|
||||||
|
use Jdenticon\Canvas\Rasterization\Edge;
|
||||||
|
use Jdenticon\Canvas\Rasterization\EdgeTable;
|
||||||
|
use Jdenticon\Canvas\Rasterization\Rasterizer;
|
||||||
|
use Jdenticon\Canvas\Png\PngPalette;
|
||||||
|
use Jdenticon\Canvas\Png\PngEncoder;
|
||||||
|
use Jdenticon\Canvas\CanvasContext;
|
||||||
|
use Jdenticon\Canvas\ColorUtils;
|
||||||
|
|
||||||
|
class Canvas
|
||||||
|
{
|
||||||
|
private $edges;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new canvas with the specified dimensions given in pixels.
|
||||||
|
*
|
||||||
|
* @param integer $width Canvas width in pixels.
|
||||||
|
* @param integer $height Canvas height in pixels.
|
||||||
|
*/
|
||||||
|
public function __construct($width, $height)
|
||||||
|
{
|
||||||
|
$this->width = $width;
|
||||||
|
$this->height = $height;
|
||||||
|
$this->edges = new EdgeTable($width, $height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The width of the canvas in pixels.
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
public $width = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The height of the canvas in pixels.
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
public $height = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the background color. Allowed values are:
|
||||||
|
* - 32 bit integers on the format 0xRRGGBBAA
|
||||||
|
* - strings on the format #RGB
|
||||||
|
* - strings on the format #RRGGBB
|
||||||
|
* - strings on the format #RRGGBBAA
|
||||||
|
*
|
||||||
|
* @var integer|string
|
||||||
|
*/
|
||||||
|
public $backColor = 0x00000000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a context used to draw polygons on this canvas.
|
||||||
|
*
|
||||||
|
* @returns \Jdenticon\Canvas\CanvasContext
|
||||||
|
*/
|
||||||
|
public function getContext()
|
||||||
|
{
|
||||||
|
return new CanvasContext($this, $this->edges);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the canvas as a PNG data stream.
|
||||||
|
*
|
||||||
|
* @param array $keywords Keywords to be written to the PNG stream.
|
||||||
|
* See https://www.w3.org/TR/PNG/#11keywords.
|
||||||
|
* @returns string
|
||||||
|
*/
|
||||||
|
public function toPng($keywords = array())
|
||||||
|
{
|
||||||
|
$colorRanges = array();
|
||||||
|
|
||||||
|
Rasterizer::rasterize(
|
||||||
|
$colorRanges, $this->edges,
|
||||||
|
$this->width, $this->height);
|
||||||
|
|
||||||
|
$backColor = ColorUtils::parse($this->backColor);
|
||||||
|
if (ColorUtils::alpha($backColor) > 0) {
|
||||||
|
$isColor = false;
|
||||||
|
|
||||||
|
foreach ($colorRanges as & $value) {
|
||||||
|
if ($isColor) {
|
||||||
|
$value = ColorUtils::over($value, $backColor);
|
||||||
|
$isColor = false;
|
||||||
|
} else {
|
||||||
|
$isColor = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$palette = new PngPalette($colorRanges);
|
||||||
|
$png = new PngEncoder();
|
||||||
|
|
||||||
|
$png->writeImageHeader($this->width, $this->height, $palette->isValid ?
|
||||||
|
PngEncoder::INDEXED_COLOR : PngEncoder::TRUE_COLOR_WITH_ALPHA);
|
||||||
|
|
||||||
|
$png->writeImageGamma();
|
||||||
|
|
||||||
|
foreach ($keywords as $key => $value) {
|
||||||
|
$png->writeTextualData($key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($palette && $palette->isValid) {
|
||||||
|
$png->writePalette($palette);
|
||||||
|
$png->writeTransparency($palette);
|
||||||
|
$png->writeIndexed($colorRanges, $palette,
|
||||||
|
$this->width, $this->height);
|
||||||
|
} else {
|
||||||
|
$png->writeTrueColorWithAlpha($colorRanges,
|
||||||
|
$this->width, $this->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
$png->writeImageEnd();
|
||||||
|
return $png->getBuffer();
|
||||||
|
}
|
||||||
|
}
|
408
vendor/jdenticon/jdenticon/src/Canvas/CanvasContext.php
vendored
Normal file
408
vendor/jdenticon/jdenticon/src/Canvas/CanvasContext.php
vendored
Normal file
@ -0,0 +1,408 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Canvas;
|
||||||
|
|
||||||
|
use Jdenticon\Canvas\ColorUtils;
|
||||||
|
use Jdenticon\Canvas\CanvasState;
|
||||||
|
use Jdenticon\Canvas\Rasterization\EdgeTable;
|
||||||
|
use Jdenticon\Canvas\Rasterization\Edge;
|
||||||
|
use Jdenticon\Canvas\Matrix;
|
||||||
|
|
||||||
|
class CanvasContext
|
||||||
|
{
|
||||||
|
private $savedStates = array();
|
||||||
|
private $edges;
|
||||||
|
private $transform;
|
||||||
|
private $paths;
|
||||||
|
private $canvas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new canvas with the specified dimensions given in pixels.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Canvas\Canvas $canvas The owner canvas.
|
||||||
|
* @param array $edges The owner canvas' edge buffer.
|
||||||
|
*/
|
||||||
|
public function __construct($canvas, &$edges)
|
||||||
|
{
|
||||||
|
$this->edges = $edges;
|
||||||
|
$this->canvas = $canvas;
|
||||||
|
$this->beginPath();
|
||||||
|
$this->resetTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the fill color that is used when the fill method is called. Allowed values are:
|
||||||
|
* - 32 bit integers on the format 0xRRGGBBAA
|
||||||
|
* - strings on the format #RGB
|
||||||
|
* - strings on the format #RRGGBB
|
||||||
|
* - strings on the format #RRGGBBAA
|
||||||
|
*
|
||||||
|
* @var integer|string
|
||||||
|
*/
|
||||||
|
public $fillStyle = 0x000000ff;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the current state to the state stack.
|
||||||
|
*/
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
array_push($this->savedStates, array(
|
||||||
|
'transform' => $this->transform,
|
||||||
|
'fillStyle' => $this->fillStyle
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the last saved state of the CanvasContext.
|
||||||
|
*/
|
||||||
|
public function restore()
|
||||||
|
{
|
||||||
|
$state = array_pop($this->savedStates);
|
||||||
|
if ($state != NULL) {
|
||||||
|
$this->transform = $state['transform'];
|
||||||
|
$this->fillStyle = $state['fillStyle'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the internal path buffer and begins a new path.
|
||||||
|
*/
|
||||||
|
public function resetTransform()
|
||||||
|
{
|
||||||
|
$this->transform = new Matrix(1, 0, 0, 1, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiplies the current transformation matrix with the specified values.
|
||||||
|
*/
|
||||||
|
public function transform($a, $b, $c, $d, $e, $f)
|
||||||
|
{
|
||||||
|
if (gettype($a) != 'integer' ||
|
||||||
|
gettype($b) != 'integer' ||
|
||||||
|
gettype($c) != 'integer' ||
|
||||||
|
gettype($d) != 'integer' ||
|
||||||
|
gettype($e) != 'integer' ||
|
||||||
|
gettype($f) != 'integer'
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->transform = $this->transform->multiply($a, $b, $c, $d, $e, $f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the transformation matrix to the specified matrix.
|
||||||
|
*/
|
||||||
|
public function setTransform($a, $b, $c, $d, $e, $f)
|
||||||
|
{
|
||||||
|
if (gettype($a) != 'integer' ||
|
||||||
|
gettype($b) != 'integer' ||
|
||||||
|
gettype($c) != 'integer' ||
|
||||||
|
gettype($d) != 'integer' ||
|
||||||
|
gettype($e) != 'integer' ||
|
||||||
|
gettype($f) != 'integer'
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->transform = new Matrix($a, $b, $c, $d, $e, $f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies a translation transformation to the CanvasContext.
|
||||||
|
*
|
||||||
|
* @param float $x Distance to move in the horizontal direction in pixels.
|
||||||
|
* @param float $y Distance to move in the vertical direction in pixels.
|
||||||
|
*/
|
||||||
|
public function translate($x, $y)
|
||||||
|
{
|
||||||
|
$this->transform = $this->transform->translate($x, $y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies a scale transformation to the CanvasContext.
|
||||||
|
*
|
||||||
|
* @param float $x Scale in the horizontal direction. 1 means no scale.
|
||||||
|
* @param float $y Scale in the vertical direction. 1 means no scale.
|
||||||
|
*/
|
||||||
|
public function scale($x, $y)
|
||||||
|
{
|
||||||
|
$this->transform = $this->transform->scale($x, $y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies a rotation transformation to the canvas around its current origo.
|
||||||
|
*
|
||||||
|
* @param float $angle Angle in radians measured clockwise from the
|
||||||
|
* positive x axis.
|
||||||
|
*/
|
||||||
|
public function rotate($angle)
|
||||||
|
{
|
||||||
|
$this->transform = $this->transform->rotate($angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all existing subpaths and begins a new path.
|
||||||
|
*/
|
||||||
|
public function beginPath()
|
||||||
|
{
|
||||||
|
$this->paths = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a new subpath that begins in the same point as the start and end
|
||||||
|
* point of the previous one.
|
||||||
|
*/
|
||||||
|
public function closePath()
|
||||||
|
{
|
||||||
|
$pathsCount = count($this->paths);
|
||||||
|
if ($pathsCount > 0) {
|
||||||
|
$path = $this->paths[$pathsCount - 1];
|
||||||
|
$pathCount = count($path);
|
||||||
|
|
||||||
|
if ($pathCount > 2) {
|
||||||
|
// Close path
|
||||||
|
if ($path[0] != $path[$pathCount - 2] ||
|
||||||
|
$path[1] != $path[$pathCount - 1]
|
||||||
|
) {
|
||||||
|
$path[] = $path[0];
|
||||||
|
$path[] = $path[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Begin a new path
|
||||||
|
$this->paths[] = array($path[0], $path[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins a new subpath by moving the cursor to the specified position.
|
||||||
|
*
|
||||||
|
* @param float $x X coordinate.
|
||||||
|
* @param float $y Y coordinate.
|
||||||
|
*/
|
||||||
|
public function moveTo($x, $y)
|
||||||
|
{
|
||||||
|
$p = $this->transform->multiplyPoint($x, $y);
|
||||||
|
$this->paths[] = array($p->x, $p->y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts an edge between the last and specified position.
|
||||||
|
*
|
||||||
|
* @param float $x Target X coordinate.
|
||||||
|
* @param float $y Target Y coordinate.
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
public function lineTo($x, $y)
|
||||||
|
{
|
||||||
|
$pathsCount = count($this->paths);
|
||||||
|
if ($pathsCount == 0) {
|
||||||
|
$this->paths[] = array();
|
||||||
|
$pathsCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$p = $this->transform->multiplyPoint($x, $y);
|
||||||
|
$path = &$this->paths[$pathsCount - 1];
|
||||||
|
$path[] = $p->x;
|
||||||
|
$path[] = $p->y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an arc to the current path.
|
||||||
|
*
|
||||||
|
* @param float $x X coordinate of the center of the arc.
|
||||||
|
* @param float $y Y coordinate of the center of the arc.
|
||||||
|
* @param float $radius Radius of the arc.
|
||||||
|
* @param float $startAngle The angle in radians at which the arc starts,
|
||||||
|
* measured clockwise from the positive x axis.
|
||||||
|
* @param float $endAngle The angle in radians at which the arc end,
|
||||||
|
* measured clockwise from the positive x axis.
|
||||||
|
* @param boolean $anticlockwise Specifies whether the arc will be drawn
|
||||||
|
* counter clockwise. Default is clockwise.
|
||||||
|
*/
|
||||||
|
public function arc($x, $y, $radius, $startAngle, $endAngle, $anticlockwise)
|
||||||
|
{
|
||||||
|
$TARGET_CHORD_LENGTH_PIXELS = 3;
|
||||||
|
|
||||||
|
$sectors = floor((M_PI * $radius * 2) / $TARGET_CHORD_LENGTH_PIXELS);
|
||||||
|
if ($sectors < 9) {
|
||||||
|
$sectors = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sectorAngle = M_PI * 2 / $sectors;
|
||||||
|
|
||||||
|
if ($startAngle == $endAngle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($anticlockwise) {
|
||||||
|
$sectorAngle = -$sectorAngle;
|
||||||
|
|
||||||
|
if ($startAngle - $endAngle >= M_PI * 2) {
|
||||||
|
$endAngle = $startAngle - M_PI * 2;
|
||||||
|
} else {
|
||||||
|
// Normalize end angle so that the sweep angle is in the range
|
||||||
|
// (0, -2PI]
|
||||||
|
$endAngle +=
|
||||||
|
M_PI * 2 * ceil(($startAngle - $endAngle) /
|
||||||
|
(M_PI * 2) - 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($endAngle - $startAngle >= M_PI * 2) {
|
||||||
|
$endAngle = $startAngle + M_PI * 2;
|
||||||
|
} else {
|
||||||
|
// Normalize end angle so that the sweep angle is in the range
|
||||||
|
// (0, 2PI]
|
||||||
|
$endAngle -=
|
||||||
|
M_PI * 2 * ceil(($endAngle - $startAngle) /
|
||||||
|
(M_PI * 2) - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$dx;
|
||||||
|
$dy;
|
||||||
|
$sectors = ($endAngle - $startAngle) / $sectorAngle;
|
||||||
|
|
||||||
|
$angle = $startAngle;
|
||||||
|
|
||||||
|
for ($i = 0; $i < $sectors; $i++) {
|
||||||
|
$dx = cos($angle) * $radius;
|
||||||
|
$dy = sin($angle) * $radius;
|
||||||
|
$this->lineTo($x + $dx, $y + $dy);
|
||||||
|
$angle += $sectorAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dx = cos($endAngle) * $radius;
|
||||||
|
$dy = sin($endAngle) * $radius;
|
||||||
|
$this->lineTo($x + $dx, $y + $dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fills the specified rectangle with fully transparent black without
|
||||||
|
* affecting the current paths.
|
||||||
|
*
|
||||||
|
* @param float $x X coordinate of the left side of the rectangle.
|
||||||
|
* @param float $y Y coordinate of the top of the rectangle.
|
||||||
|
* @param float $width Width of the rectangle.
|
||||||
|
* @param float $height Height of the rectangle.
|
||||||
|
*/
|
||||||
|
public function clearRect($x, $y, $width, $height)
|
||||||
|
{
|
||||||
|
$fullCanvas = false;
|
||||||
|
|
||||||
|
if (!$this->transform->hasSkewing()) {
|
||||||
|
// Check if the whole canvas is cleared
|
||||||
|
$topLeft = $this->transform->multiplyPoint($x, $y);
|
||||||
|
if ($topLeft->x <= 0 && $topLeft->y <= 0) {
|
||||||
|
$bottomRight = $this->transform->multiplyPoint(
|
||||||
|
$x + $width, $y + $height);
|
||||||
|
if ($bottomRight->x >= $this->canvas->width &&
|
||||||
|
$bottomRight->y >= $this->canvas->height
|
||||||
|
) {
|
||||||
|
$fullCanvas = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($fullCanvas) {
|
||||||
|
$this->edges->clear();
|
||||||
|
} else {
|
||||||
|
$this->_fillRect(ColorUtils::FORCE_TRANSPARENT,
|
||||||
|
$x, $y, $width, $height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fills the specified rectangle without affecting the current paths.
|
||||||
|
*
|
||||||
|
* @param float $x X coordinate of the left side of the rectangle.
|
||||||
|
* @param float $y Y coordinate of the top of the rectangle.
|
||||||
|
* @param float $width Width of the rectangle.
|
||||||
|
* @param float $height Height of the rectangle.
|
||||||
|
*/
|
||||||
|
public function fillRect($x, $y, $width, $height)
|
||||||
|
{
|
||||||
|
$fillColor = ColorUtils::parse($this->fillStyle);
|
||||||
|
$this->_fillRect($fillColor, $x, $y, $width, $height);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fillRect($fillColor, $x, $y, $width, $height)
|
||||||
|
{
|
||||||
|
$polygonId = $this->edges->getNextPolygonId();
|
||||||
|
|
||||||
|
$points = array(
|
||||||
|
$this->transform->multiplyPoint($x, $y),
|
||||||
|
$this->transform->multiplyPoint($x + $width, $y),
|
||||||
|
$this->transform->multiplyPoint($x + $width, $y + $height),
|
||||||
|
$this->transform->multiplyPoint($x, $y + $height),
|
||||||
|
$this->transform->multiplyPoint($x, $y)
|
||||||
|
);
|
||||||
|
|
||||||
|
$pointsCount = count($points);
|
||||||
|
for ($i = 1; $i < $pointsCount; $i++) {
|
||||||
|
$this->edges->add(new Edge(
|
||||||
|
$polygonId,
|
||||||
|
$points[$i - 1]->x,
|
||||||
|
$points[$i - 1]->y,
|
||||||
|
$points[$i]->x,
|
||||||
|
$points[$i]->y,
|
||||||
|
$fillColor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fills the defined paths.
|
||||||
|
*
|
||||||
|
* @param string $windingRule The winding rule to be used for determining
|
||||||
|
* which areas are covered by the current path. Valid values are
|
||||||
|
* "evenodd" and "nonzero". Default is "nonzero".
|
||||||
|
*/
|
||||||
|
public function fill($windingRule = "nonzero")
|
||||||
|
{
|
||||||
|
$polygonId = $this->edges->getNextPolygonId();
|
||||||
|
$fillColor = ColorUtils::parse($this->fillStyle);
|
||||||
|
|
||||||
|
foreach ($this->paths as $points) {
|
||||||
|
$pointsCount = count($points);
|
||||||
|
if ($pointsCount <= 2) {
|
||||||
|
// Nothing to fill
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($i = 2; $i < $pointsCount; $i += 2) {
|
||||||
|
$this->edges->add(new Edge(
|
||||||
|
$polygonId,
|
||||||
|
$points[$i - 2],
|
||||||
|
$points[$i - 1],
|
||||||
|
$points[$i],
|
||||||
|
$points[$i + 1],
|
||||||
|
$fillColor,
|
||||||
|
$windingRule));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close path
|
||||||
|
if ($points[0] != $points[$pointsCount - 2] ||
|
||||||
|
$points[1] != $points[$pointsCount - 1]
|
||||||
|
) {
|
||||||
|
$this->edges->add(new Edge(
|
||||||
|
$polygonId,
|
||||||
|
$points[$pointsCount - 2],
|
||||||
|
$points[$pointsCount - 1],
|
||||||
|
$points[0],
|
||||||
|
$points[1],
|
||||||
|
$fillColor,
|
||||||
|
$windingRule));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
228
vendor/jdenticon/jdenticon/src/Canvas/ColorUtils.php
vendored
Normal file
228
vendor/jdenticon/jdenticon/src/Canvas/ColorUtils.php
vendored
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Canvas;
|
||||||
|
|
||||||
|
class ColorUtils
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transparent color.
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
const TRANSPARENT = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies a transparent color that will not blend with layers below the
|
||||||
|
* current layer.
|
||||||
|
*
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
const FORCE_TRANSPARENT = INF;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a color on the format 0xRRGGBBAA from the specified
|
||||||
|
* color components.
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public static function from($a, $r, $g, $b)
|
||||||
|
{
|
||||||
|
return ($r << 24) | ($g << 16) | ($b << 8) | $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the alpha component of a color.
|
||||||
|
*
|
||||||
|
* @param integer $color 32-bit color value on the format 0xRRGGBBAA.
|
||||||
|
* @return integer Alpha in the range [0, 255].
|
||||||
|
*/
|
||||||
|
public static function alpha($color)
|
||||||
|
{
|
||||||
|
return $color & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the red component of a color.
|
||||||
|
*
|
||||||
|
* @param integer $color 32-bit color value on the format 0xRRGGBBAA.
|
||||||
|
* @return integer Red component in the range [0, 255].
|
||||||
|
*/
|
||||||
|
public static function red($color)
|
||||||
|
{
|
||||||
|
return ($color >> 24) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the green component of a color.
|
||||||
|
*
|
||||||
|
* @param integer $color 32-bit color value on the format 0xRRGGBBAA.
|
||||||
|
* @return integer Green component in the range [0, 255].
|
||||||
|
*/
|
||||||
|
public static function green($color)
|
||||||
|
{
|
||||||
|
return ($color >> 16) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the blue component of a color.
|
||||||
|
*
|
||||||
|
* @param integer $color 32-bit color value on the format 0xRRGGBBAA.
|
||||||
|
* @return integer Blue component in the range [0, 255].
|
||||||
|
*/
|
||||||
|
public static function blue($color)
|
||||||
|
{
|
||||||
|
return ($color >> 8) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a color as a string.
|
||||||
|
*
|
||||||
|
* @param integer $color Color to format.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function format($color)
|
||||||
|
{
|
||||||
|
return bin2hex(pack('N', $color));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes a mix of the two specified colors, with the proportion given
|
||||||
|
* by the specified weight.
|
||||||
|
*
|
||||||
|
* @param integer $color1 First color to mix.
|
||||||
|
* @param integer $color2 Second color to mix.
|
||||||
|
* @param float $weight Weight in the range [0,1].
|
||||||
|
* 0 gives $color1, 1 gives $color2.
|
||||||
|
* @return integer Mixed color.
|
||||||
|
*/
|
||||||
|
public static function mix($color1, $color2, $weight)
|
||||||
|
{
|
||||||
|
if ($weight < 0) {
|
||||||
|
$weight = 0;
|
||||||
|
} elseif ($weight > 1) {
|
||||||
|
$weight = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$a = ($color1 & 0xff) * (1 - $weight) + ($color2 & 0xff) * $weight;
|
||||||
|
if ($a <= 0.1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$r = (
|
||||||
|
($color1 >> 24) * ($color1 & 0xff) * (1 - $weight) +
|
||||||
|
($color2 >> 24) * ($color2 & 0xff) * $weight
|
||||||
|
) / $a;
|
||||||
|
|
||||||
|
$g = (
|
||||||
|
(($color1 >> 16) & 0xff) * ($color1 & 0xff) * (1 - $weight) +
|
||||||
|
(($color2 >> 16) & 0xff) * ($color2 & 0xff) * $weight
|
||||||
|
) / $a;
|
||||||
|
|
||||||
|
$b = (
|
||||||
|
(($color1 >> 8) & 0xff) * ($color1 & 0xff) * (1 - $weight) +
|
||||||
|
(($color2 >> 8) & 0xff) * ($color2 & 0xff) * $weight
|
||||||
|
) / $a;
|
||||||
|
|
||||||
|
if ($a > 255) $a = 255;
|
||||||
|
if ($r > 255) $r = 255;
|
||||||
|
if ($g > 255) $g = 255;
|
||||||
|
if ($b > 255) $b = 255;
|
||||||
|
|
||||||
|
return ((int)$r << 24) | ((int)$g << 16) | ((int)$b << 8) | (int)$a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a value to a 32-bit color on the format 0xRRGGBBAA.
|
||||||
|
*
|
||||||
|
* @param integer|string $color The value to parse.
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public static function parse($color)
|
||||||
|
{
|
||||||
|
if (gettype($color) == "integer") {
|
||||||
|
return $color & 0xffffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
$color = "$color";
|
||||||
|
|
||||||
|
if (preg_match('/^#?[0-9a-fA-F]+$/', $color)) {
|
||||||
|
$hexColor = $color;
|
||||||
|
if ($hexColor[0] == '#') {
|
||||||
|
$hexColor = substr($hexColor, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (strlen($hexColor)) {
|
||||||
|
case 3:
|
||||||
|
$numeric = intval($hexColor, 16);
|
||||||
|
return (
|
||||||
|
(($numeric & 0xf00) << 20) |
|
||||||
|
(($numeric & 0xf00) << 16) |
|
||||||
|
(($numeric & 0x0f0) << 16) |
|
||||||
|
(($numeric & 0x0f0) << 12) |
|
||||||
|
(($numeric & 0x00f) << 12) |
|
||||||
|
(($numeric & 0x00f) << 8) |
|
||||||
|
0xff);
|
||||||
|
case 6:
|
||||||
|
return (intval($hexColor, 16) << 8) | 0xff;
|
||||||
|
case 8:
|
||||||
|
// Workaround to cope with PHP limitation of intval
|
||||||
|
$numeric =
|
||||||
|
(intval(substr($hexColor, 0, 4), 16) << 16) |
|
||||||
|
(intval(substr($hexColor, 4, 4), 16));
|
||||||
|
return $numeric;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \InvalidArgumentException("Invalid color '$color'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blends this color with another color using the over blending operation.
|
||||||
|
*
|
||||||
|
* @param integer $fore The foreground color.
|
||||||
|
* @param integer $back The background color.
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public static function over($fore, $back)
|
||||||
|
{
|
||||||
|
$foreA = ($fore & 0xff);
|
||||||
|
$backA = ($back & 0xff);
|
||||||
|
|
||||||
|
if ($foreA < 1) {
|
||||||
|
return $back;
|
||||||
|
} elseif ($foreA > 254 || $backA < 1) {
|
||||||
|
return $fore;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Source:
|
||||||
|
// https://en.wikipedia.org/wiki/Alpha_compositing#Description
|
||||||
|
$forePA = $foreA * 255;
|
||||||
|
$backPA = $backA * (255 - $foreA);
|
||||||
|
$pa = ($forePA + $backPA);
|
||||||
|
|
||||||
|
$b = (int) (
|
||||||
|
($forePA * (($fore >> 8) & 0xff) + $backPA * (($back >> 8) & 0xff)) /
|
||||||
|
$pa);
|
||||||
|
|
||||||
|
$g = (int) (
|
||||||
|
($forePA * (($fore >> 16) & 0xff) + $backPA * (($back >> 16) & 0xff)) /
|
||||||
|
$pa);
|
||||||
|
|
||||||
|
$r = (int) (
|
||||||
|
($forePA * (($fore >> 24) & 0xff) + $backPA * (($back >> 24) & 0xff)) /
|
||||||
|
$pa);
|
||||||
|
|
||||||
|
$a = (int) ($pa / 255);
|
||||||
|
|
||||||
|
return ($r << 24) | ($g << 16) | ($b << 8) | $a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
141
vendor/jdenticon/jdenticon/src/Canvas/Matrix.php
vendored
Normal file
141
vendor/jdenticon/jdenticon/src/Canvas/Matrix.php
vendored
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Canvas;
|
||||||
|
|
||||||
|
use Jdenticon\Canvas\Point;
|
||||||
|
|
||||||
|
class Matrix
|
||||||
|
{
|
||||||
|
private $a;
|
||||||
|
private $b;
|
||||||
|
private $c;
|
||||||
|
private $d;
|
||||||
|
private $e;
|
||||||
|
private $f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new transformation matrix.
|
||||||
|
*/
|
||||||
|
public function __construct($a, $b, $c, $d, $e, $f)
|
||||||
|
{
|
||||||
|
$this->a = $a;
|
||||||
|
$this->b = $b;
|
||||||
|
$this->c = $c;
|
||||||
|
$this->d = $d;
|
||||||
|
$this->e = $e;
|
||||||
|
$this->f = $f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a value determining if this matrix has skewing values.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function hasSkewing()
|
||||||
|
{
|
||||||
|
return $this->b || $this->c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a value determining if this matrix has translation values.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function hasTranslation()
|
||||||
|
{
|
||||||
|
return $this->e || $this->f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a value determining if this matrix has scaling values.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function hasScaling()
|
||||||
|
{
|
||||||
|
return $this->a != 1 || $this->d != 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new matrix based on the current matrix multiplied with the
|
||||||
|
* specified matrix values.
|
||||||
|
*
|
||||||
|
* @return \Jdenticon\Canvas\Matrix
|
||||||
|
*/
|
||||||
|
public function multiply($a, $b, $c, $d, $e, $f)
|
||||||
|
{
|
||||||
|
return new Matrix(
|
||||||
|
$this->a * $a + $this->c * $b,
|
||||||
|
$this->b * $a + $this->d * $b,
|
||||||
|
$this->a * $c + $this->c * $d,
|
||||||
|
$this->b * $c + $this->d * $d,
|
||||||
|
$this->a * $e + $this->c * $f + $this->e,
|
||||||
|
$this->b * $e + $this->d * $f + $this->f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiplies the specified point with the current matrix and returns the
|
||||||
|
* resulting point.
|
||||||
|
*
|
||||||
|
* @param float $x X coordinate.
|
||||||
|
* @param float $y Y coordinate.
|
||||||
|
* @return \Jdenticon\Canvas\Point
|
||||||
|
*/
|
||||||
|
public function multiplyPoint($x, $y)
|
||||||
|
{
|
||||||
|
return new Point(
|
||||||
|
$this->a * $x + $this->c * $y + $this->e,
|
||||||
|
$this->b * $x + $this->d * $y + $this->f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new matrix based on the current matrix with a rotation
|
||||||
|
* transformation applied.
|
||||||
|
*
|
||||||
|
* @param float $angle Rotation angle in radians.
|
||||||
|
* @return \Jdenticon\Canvas\Matrix
|
||||||
|
*/
|
||||||
|
public function rotate($angle)
|
||||||
|
{
|
||||||
|
$sin = sin($angle);
|
||||||
|
$cos = cos($angle);
|
||||||
|
return $this->multiply($cos, $sin, -$sin, $cos, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new matrix based on the current matrix with a translation
|
||||||
|
* transformation applied.
|
||||||
|
*
|
||||||
|
* @param float $x Horizontal move distance.
|
||||||
|
* @param float $y Vertical move distance.
|
||||||
|
* @return \Jdenticon\Canvas\Matrix
|
||||||
|
*/
|
||||||
|
public function translate($x, $y)
|
||||||
|
{
|
||||||
|
return $this->multiply(1, 0, 0, 1, $x, $y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new matrix based on the current matrix with a scaling
|
||||||
|
* transformation applied.
|
||||||
|
*
|
||||||
|
* @param float $x Horizontal scale.
|
||||||
|
* @param float $y Vertical scale.
|
||||||
|
* @return \Jdenticon\Canvas\Matrix
|
||||||
|
*/
|
||||||
|
public function scale($x, $y)
|
||||||
|
{
|
||||||
|
return $this->multiply($x, 0, 0, $y, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
92
vendor/jdenticon/jdenticon/src/Canvas/Png/PngBuffer.php
vendored
Normal file
92
vendor/jdenticon/jdenticon/src/Canvas/Png/PngBuffer.php
vendored
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Canvas\Png;
|
||||||
|
|
||||||
|
class PngBuffer
|
||||||
|
{
|
||||||
|
private $buffer = '';
|
||||||
|
private $chunkPreviousBuffer = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a string to the buffer.
|
||||||
|
*
|
||||||
|
* @param string $str String to write.
|
||||||
|
*/
|
||||||
|
public function writeString($str)
|
||||||
|
{
|
||||||
|
$this->buffer .= $str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a 32 bit unsigned int to the buffer in Big Endian format.
|
||||||
|
*
|
||||||
|
* @param integer $value Value to write.
|
||||||
|
*/
|
||||||
|
public function writeUInt32BE($value)
|
||||||
|
{
|
||||||
|
$this->buffer .= pack('N', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes an 8 bit unsigned int to the buffer.
|
||||||
|
*
|
||||||
|
* @param integer $value Value to write.
|
||||||
|
*/
|
||||||
|
public function writeUInt8($value)
|
||||||
|
{
|
||||||
|
$this->buffer .= pack('C', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a new PNG chunk.
|
||||||
|
*
|
||||||
|
* @param string $type Name of the chunk. Must contain exactly 4
|
||||||
|
* ASCII characters.
|
||||||
|
*/
|
||||||
|
public function startChunk($type)
|
||||||
|
{
|
||||||
|
$this->chunkPreviousBuffer = $this->buffer;
|
||||||
|
$this->buffer = $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the current PNG chunk.
|
||||||
|
*/
|
||||||
|
public function endChunk()
|
||||||
|
{
|
||||||
|
// Compute Crc32 for type + data
|
||||||
|
$data = $this->buffer;
|
||||||
|
$crc = crc32($data);
|
||||||
|
|
||||||
|
$this->buffer =
|
||||||
|
$this->chunkPreviousBuffer .
|
||||||
|
|
||||||
|
// Length
|
||||||
|
pack('N', strlen($data) - 4) .
|
||||||
|
|
||||||
|
// Content
|
||||||
|
$data .
|
||||||
|
|
||||||
|
// Crc32
|
||||||
|
pack('N', $crc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a string containing the PNG encoded data.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getBuffer()
|
||||||
|
{
|
||||||
|
return $this->buffer;
|
||||||
|
}
|
||||||
|
}
|
238
vendor/jdenticon/jdenticon/src/Canvas/Png/PngEncoder.php
vendored
Normal file
238
vendor/jdenticon/jdenticon/src/Canvas/Png/PngEncoder.php
vendored
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Canvas\Png;
|
||||||
|
|
||||||
|
use Jdenticon\Canvas\Png\PngPalette;
|
||||||
|
use Jdenticon\Canvas\Png\PngBuffer;
|
||||||
|
use Jdenticon\Canvas\ColorUtils;
|
||||||
|
|
||||||
|
class PngEncoder
|
||||||
|
{
|
||||||
|
const GRAYSCALE = 0;
|
||||||
|
const TRUE_COLOR = 2;
|
||||||
|
const INDEXED_COLOR = 3;
|
||||||
|
const GRAYSCALE_WITH_ALPHA = 4;
|
||||||
|
const TRUE_COLOR_WITH_ALPHA = 6;
|
||||||
|
|
||||||
|
private $buffer;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->buffer = new PngBuffer();
|
||||||
|
$this->buffer->writeString("\x89\x50\x4e\x47\xd\xa\x1a\xa");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes an IHDR chunk to the png data stream.
|
||||||
|
*
|
||||||
|
* @param int $width Image width in pixels.
|
||||||
|
* @param int $height Image height in pixels.
|
||||||
|
* @param int $colorType Color depth, speocfy one of the constants in
|
||||||
|
* PngEncoder.
|
||||||
|
*/
|
||||||
|
public function writeImageHeader($width, $height, $colorType)
|
||||||
|
{
|
||||||
|
$this->buffer->startChunk("IHDR");
|
||||||
|
$this->buffer->writeUInt32BE($width);
|
||||||
|
$this->buffer->writeUInt32BE($height);
|
||||||
|
$this->buffer->writeUInt8(8); // Bit depth
|
||||||
|
$this->buffer->writeUInt8($colorType);
|
||||||
|
$this->buffer->writeUInt8(0); // Compression
|
||||||
|
$this->buffer->writeUInt8(0); // Filter
|
||||||
|
$this->buffer->writeUInt8(0); // Interlace
|
||||||
|
$this->buffer->endChunk();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a gAMA chunk to the png data stream.
|
||||||
|
*
|
||||||
|
* @param int $gamma Gamma value.
|
||||||
|
*/
|
||||||
|
public function writeImageGamma($gamma = 45455)
|
||||||
|
{
|
||||||
|
$this->buffer->startChunk("gAMA");
|
||||||
|
$this->buffer->writeUInt32BE($gamma);
|
||||||
|
$this->buffer->endChunk();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes an IDAT chunk of truecolor encoded image data.
|
||||||
|
*
|
||||||
|
* @param array $colorRanges Image data on the format
|
||||||
|
* array(count0, color0, count1, color1, ...)
|
||||||
|
* @param int $width Image width in pixels.
|
||||||
|
* @param int $height Image height in pixels.
|
||||||
|
*/
|
||||||
|
public function writeTrueColorWithAlpha(
|
||||||
|
array & $colorRanges, $width, $height)
|
||||||
|
{
|
||||||
|
$this->buffer->startChunk("IDAT");
|
||||||
|
|
||||||
|
$uncompressed = '';
|
||||||
|
$count = -1;
|
||||||
|
$x = 0;
|
||||||
|
|
||||||
|
foreach ($colorRanges as $value) {
|
||||||
|
if ($count === -1) {
|
||||||
|
$count = $value;
|
||||||
|
} else {
|
||||||
|
if ($count !== 0) {
|
||||||
|
if ($x === $width) {
|
||||||
|
$x = 0;
|
||||||
|
}
|
||||||
|
if ($x === 0) {
|
||||||
|
$uncompressed .= pack('C', 0); // No filtering
|
||||||
|
}
|
||||||
|
|
||||||
|
$uncompressed .= str_repeat(pack('N', $value), $count);
|
||||||
|
$x += $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
$count = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$compressed = gzcompress($uncompressed, 2);
|
||||||
|
$this->buffer->writeString($compressed);
|
||||||
|
|
||||||
|
$this->buffer->endChunk();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes an IDAT chunk of indexed image data.
|
||||||
|
*
|
||||||
|
* @param array $colorRanges Image data on the format
|
||||||
|
* array(count0, color0, count1, color1, ...)
|
||||||
|
* @param \Jdenticon\Canvas\Png\PngPalette $palette Palette containing the
|
||||||
|
* indexed colors.
|
||||||
|
* @param int $width Image width in pixels.
|
||||||
|
* @param int $height Image height in pixels.
|
||||||
|
*/
|
||||||
|
public function writeIndexed(
|
||||||
|
array & $colorRanges,
|
||||||
|
PngPalette $palette,
|
||||||
|
$width, $height)
|
||||||
|
{
|
||||||
|
$this->buffer->startChunk("IDAT");
|
||||||
|
|
||||||
|
$uncompressed = '';
|
||||||
|
|
||||||
|
$count = -1;
|
||||||
|
$x = 0;
|
||||||
|
|
||||||
|
foreach ($colorRanges as $value) {
|
||||||
|
if ($count === -1) {
|
||||||
|
$count = $value;
|
||||||
|
} else {
|
||||||
|
if ($count !== 0) {
|
||||||
|
if ($x === $width) {
|
||||||
|
$x = 0;
|
||||||
|
}
|
||||||
|
if ($x === 0) {
|
||||||
|
$uncompressed .= pack('C', 0); // No filtering
|
||||||
|
}
|
||||||
|
|
||||||
|
$colorIndex = $palette->lookup[$value];
|
||||||
|
$uncompressed .= str_repeat(pack('C', $colorIndex), $count);
|
||||||
|
$x += $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
$count = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$compressed = gzcompress($uncompressed, 2);
|
||||||
|
$this->buffer->writeString($compressed);
|
||||||
|
|
||||||
|
$this->buffer->endChunk();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a PLTE chunk containing the indexed colors.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Canvas\Png\PngPalette $palette Palette containing the
|
||||||
|
* indexed colors.
|
||||||
|
*/
|
||||||
|
public function writePalette(PngPalette $palette)
|
||||||
|
{
|
||||||
|
if ($palette && $palette->isValid) {
|
||||||
|
$this->buffer->startChunk("PLTE");
|
||||||
|
|
||||||
|
foreach ($palette->colors as $color) {
|
||||||
|
$this->buffer->writeString(
|
||||||
|
pack('C', ($color >> 24) & 0xff) .
|
||||||
|
pack('C', ($color >> 16) & 0xff) .
|
||||||
|
pack('C', ($color >> 8) & 0xff));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->buffer->endChunk();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a tRNS chunk containing the alpha values of indexed colors.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Canvas\Png\PngPalette $palette Palette containing the
|
||||||
|
* indexed colors.
|
||||||
|
*/
|
||||||
|
public function writeTransparency(PngPalette $palette)
|
||||||
|
{
|
||||||
|
if ($palette && $palette->isValid && $palette->hasAlphaChannel) {
|
||||||
|
$this->buffer->startChunk("tRNS");
|
||||||
|
|
||||||
|
$alpha = '';
|
||||||
|
|
||||||
|
foreach ($palette->colors as $color) {
|
||||||
|
$alpha .= pack('C', $color & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->buffer->writeString($alpha);
|
||||||
|
|
||||||
|
$this->buffer->endChunk();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a tEXt chunk containing the specified strings.
|
||||||
|
*
|
||||||
|
* @param string $key Key, one of
|
||||||
|
* {@link https://www.w3.org/TR/2003/REC-PNG-20031110/#11keywords}
|
||||||
|
* @param string $value Value.
|
||||||
|
*/
|
||||||
|
public function writeTextualData($key, $value)
|
||||||
|
{
|
||||||
|
$this->buffer->startChunk("tEXt");
|
||||||
|
$this->buffer->writeString($key);
|
||||||
|
$this->buffer->writeUInt8(0);
|
||||||
|
$this->buffer->writeString($value);
|
||||||
|
$this->buffer->endChunk();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes an IEND chunk to the png data stream.
|
||||||
|
*/
|
||||||
|
public function writeImageEnd()
|
||||||
|
{
|
||||||
|
$this->buffer->startChunk("IEND");
|
||||||
|
$this->buffer->endChunk();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a binary string containing the PNG data.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getBuffer()
|
||||||
|
{
|
||||||
|
return $this->buffer->getBuffer();
|
||||||
|
}
|
||||||
|
}
|
92
vendor/jdenticon/jdenticon/src/Canvas/Png/PngPalette.php
vendored
Normal file
92
vendor/jdenticon/jdenticon/src/Canvas/Png/PngPalette.php
vendored
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Canvas\Png;
|
||||||
|
|
||||||
|
use Jdenticon\Canvas\ColorUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains the colors of a PNG color palette.
|
||||||
|
*/
|
||||||
|
class PngPalette
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Creates a PNG color palette for the specified bitmap data.
|
||||||
|
*
|
||||||
|
* @param array(integer) $colorRanges Array of interleaved values on the
|
||||||
|
* format array(count0, color0, count1, color1, ...).
|
||||||
|
*/
|
||||||
|
function __construct(& $colorRanges)
|
||||||
|
{
|
||||||
|
$lookup = array();
|
||||||
|
$colors = array();
|
||||||
|
$hasAlphaChannel = false;
|
||||||
|
$colorsCount = 0;
|
||||||
|
|
||||||
|
$count = -1;
|
||||||
|
|
||||||
|
foreach ($colorRanges as $value) {
|
||||||
|
if ($count === -1) {
|
||||||
|
$count = $value;
|
||||||
|
} else {
|
||||||
|
// Ignore empty ranges and already indexed colors
|
||||||
|
if ($count > 0 && !isset($lookup[$value])) {
|
||||||
|
if (!$hasAlphaChannel && ($value & 0xff) < 255) {
|
||||||
|
$hasAlphaChannel = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$lookup[$value] = $colorsCount++;
|
||||||
|
$colors[] = $value;
|
||||||
|
|
||||||
|
if ($colorsCount > 256) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$count = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->hasAlphaChannel = $hasAlphaChannel;
|
||||||
|
$this->colors = & $colors;
|
||||||
|
$this->lookup = & $lookup;
|
||||||
|
$this->isValid = $colorsCount <= 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies if the palette is valid to be used for encoding a PNG image.
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
public $isValid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies if the palette has any partial or fully transparent
|
||||||
|
* colors.
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
public $hasAlphaChannel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of colors in the palette.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $colors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup table from 32-bit color value to color index.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $lookup;
|
||||||
|
}
|
41
vendor/jdenticon/jdenticon/src/Canvas/Point.php
vendored
Normal file
41
vendor/jdenticon/jdenticon/src/Canvas/Point.php
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Canvas;
|
||||||
|
|
||||||
|
class Point
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* X coordinate.
|
||||||
|
*
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
public $x;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Y coordinate.
|
||||||
|
*
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
public $y;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new 2D point.
|
||||||
|
*
|
||||||
|
* @param float $x X coordinate.
|
||||||
|
* @param float $y Y coordinate.
|
||||||
|
*/
|
||||||
|
public function __construct($x, $y)
|
||||||
|
{
|
||||||
|
$this->x = $x;
|
||||||
|
$this->y = $y;
|
||||||
|
}
|
||||||
|
}
|
44
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/Edge.php
vendored
Normal file
44
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/Edge.php
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Canvas\Rasterization;
|
||||||
|
|
||||||
|
class Edge
|
||||||
|
{
|
||||||
|
public $polygonId;
|
||||||
|
public $x0;
|
||||||
|
public $x1;
|
||||||
|
public $y0;
|
||||||
|
public $y1;
|
||||||
|
public $color;
|
||||||
|
public $windingRule;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
$polygonId, $x0, $y0, $x1, $y1, $color, $windingRule = null)
|
||||||
|
{
|
||||||
|
$this->polygonId = $polygonId;
|
||||||
|
$this->x0 = $x0;
|
||||||
|
$this->x1 = $x1;
|
||||||
|
$this->y0 = $y0;
|
||||||
|
$this->y1 = $y1;
|
||||||
|
$this->color = $color;
|
||||||
|
$this->windingRule = $windingRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function intersection($y)
|
||||||
|
{
|
||||||
|
$dx =
|
||||||
|
($this->x1 - $this->x0) * ($this->y0 - $y) /
|
||||||
|
($this->y0 - $this->y1);
|
||||||
|
return $this->x0 + $dx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
27
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeIntersection.php
vendored
Normal file
27
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeIntersection.php
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Canvas\Rasterization;
|
||||||
|
|
||||||
|
class EdgeIntersection
|
||||||
|
{
|
||||||
|
public $fromX;
|
||||||
|
public $width;
|
||||||
|
public $edge;
|
||||||
|
|
||||||
|
public function __construct($fromX, $width, $edge)
|
||||||
|
{
|
||||||
|
$this->fromX = $fromX;
|
||||||
|
$this->width = $width;
|
||||||
|
$this->edge = $edge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
24
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeSuperSampleIntersection.php
vendored
Normal file
24
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeSuperSampleIntersection.php
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Canvas\Rasterization;
|
||||||
|
|
||||||
|
class EdgeSuperSampleIntersection
|
||||||
|
{
|
||||||
|
public $x;
|
||||||
|
public $edge;
|
||||||
|
|
||||||
|
public function __construct($x, $edge)
|
||||||
|
{
|
||||||
|
$this->x = $x;
|
||||||
|
$this->edge = $edge;
|
||||||
|
}
|
||||||
|
}
|
158
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeTable.php
vendored
Normal file
158
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/EdgeTable.php
vendored
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Canvas\Rasterization;
|
||||||
|
|
||||||
|
class EdgeTable
|
||||||
|
{
|
||||||
|
private $scanlines;
|
||||||
|
private $nextPolygonId;
|
||||||
|
private $width;
|
||||||
|
private $height;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps a list of edges per scanline.
|
||||||
|
*
|
||||||
|
* @param integer $width Clipping width.
|
||||||
|
* @param integer $height Clipping height.
|
||||||
|
*/
|
||||||
|
public function __construct($width, $height)
|
||||||
|
{
|
||||||
|
$this->width = $width;
|
||||||
|
$this->height = $height;
|
||||||
|
$this->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sorts the edges of each scanline in ascending x coordinates.
|
||||||
|
*/
|
||||||
|
public function clear()
|
||||||
|
{
|
||||||
|
$this->scanlines = array();
|
||||||
|
$this->nextPolygonId = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an id for the next polygon.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getNextPolygonId()
|
||||||
|
{
|
||||||
|
return $this->nextPolygonId++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the scaline for the specified Y coordinate, or NULL if there are
|
||||||
|
* no edges for the specified Y coordinate.
|
||||||
|
*
|
||||||
|
* @return array|null.
|
||||||
|
*/
|
||||||
|
public function getScanline($y)
|
||||||
|
{
|
||||||
|
return isset($this->scanlines[$y]) ? $this->scanlines[$y] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an edge to the table.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Canvas\Rasterization\Edge $edge
|
||||||
|
*/
|
||||||
|
public function add(\Jdenticon\Canvas\Rasterization\Edge $edge)
|
||||||
|
{
|
||||||
|
$minY = 0;
|
||||||
|
$maxY = 0;
|
||||||
|
|
||||||
|
if ($edge->y0 == $edge->y1) {
|
||||||
|
// Skip horizontal lines
|
||||||
|
return;
|
||||||
|
} elseif ($edge->y0 < $edge->y1) {
|
||||||
|
$minY = (int)($edge->y0);
|
||||||
|
$maxY = (int)($edge->y1 + 0.996 /* 1/255 */);
|
||||||
|
} else {
|
||||||
|
$minY = (int)($edge->y1);
|
||||||
|
$maxY = (int)($edge->y0 + 0.996 /* 1/255 */);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($maxY < 0 || $minY >= $this->height) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($minY < 0) {
|
||||||
|
$minY = 0;
|
||||||
|
}
|
||||||
|
if ($maxY > $this->height) {
|
||||||
|
$maxY = $this->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($minY < $maxY) {
|
||||||
|
$y = $minY;
|
||||||
|
$x1 = $edge->intersection($y);
|
||||||
|
|
||||||
|
while ($y < $maxY) {
|
||||||
|
$x2 = $edge->intersection($y + 1);
|
||||||
|
|
||||||
|
$fromX;
|
||||||
|
$width;
|
||||||
|
if ($x1 < $x2) {
|
||||||
|
$fromX = (int)($x1);
|
||||||
|
$width = (int)($x2 + 0.9999) - $fromX;
|
||||||
|
} else {
|
||||||
|
$fromX = (int)($x2);
|
||||||
|
$width = (int)($x1 + 0.9999) - $fromX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($fromX < 0) {
|
||||||
|
$width += $fromX;
|
||||||
|
$fromX = 0;
|
||||||
|
|
||||||
|
if ($width < 0) {
|
||||||
|
$width = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($fromX < $this->width) {
|
||||||
|
if (!isset($this->scanlines[$y])) {
|
||||||
|
$this->scanlines[$y] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->scanlines[$y][] = new EdgeIntersection(
|
||||||
|
$fromX, $width, $edge);
|
||||||
|
}
|
||||||
|
|
||||||
|
$x1 = $x2;
|
||||||
|
$y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function edge_cmp($x, $y)
|
||||||
|
{
|
||||||
|
if ($x->fromX < $y->fromX) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ($x->fromX > $y->fromX) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sorts the edges of each scanline in ascending x coordinates.
|
||||||
|
*/
|
||||||
|
public function sort()
|
||||||
|
{
|
||||||
|
foreach ($this->scanlines as $i => &$scanline) {
|
||||||
|
usort($scanline, array(
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\EdgeTable', 'edge_cmp'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/Layer.php
vendored
Normal file
30
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/Layer.php
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Canvas\Rasterization;
|
||||||
|
|
||||||
|
class Layer
|
||||||
|
{
|
||||||
|
public $polygonId;
|
||||||
|
public $color;
|
||||||
|
public $winding;
|
||||||
|
public $windingRule;
|
||||||
|
|
||||||
|
public $nextLayer;
|
||||||
|
|
||||||
|
public function __construct($polygonId, $color, $winding, $windingRule)
|
||||||
|
{
|
||||||
|
$this->polygonId = $polygonId;
|
||||||
|
$this->color = $color;
|
||||||
|
$this->winding = $winding;
|
||||||
|
$this->windingRule = $windingRule;
|
||||||
|
}
|
||||||
|
}
|
150
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/LayerManager.php
vendored
Normal file
150
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/LayerManager.php
vendored
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Canvas\Rasterization;
|
||||||
|
|
||||||
|
use Jdenticon\Canvas\ColorUtils;
|
||||||
|
use Jdenticon\Canvas\Rasterization\Layer;
|
||||||
|
use Jdenticon\Canvas\Rasterization\Edge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps track of the z-order of the currently rendered polygons,
|
||||||
|
* and computes the final color from the stack of layers.
|
||||||
|
*/
|
||||||
|
class LayerManager
|
||||||
|
{
|
||||||
|
public $topLayer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current visible color.
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
public $color;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->color = ColorUtils::TRANSPARENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies all layers in this manager to another LayerManager.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Canvas\Rasterization\LayerManager $other The
|
||||||
|
* LayerManager to copy all layers to.
|
||||||
|
*/
|
||||||
|
public function copyTo(LayerManager $other)
|
||||||
|
{
|
||||||
|
$other->color = $this->color;
|
||||||
|
|
||||||
|
$layer = $this->topLayer;
|
||||||
|
$previousCopy = null;
|
||||||
|
|
||||||
|
while ($layer !== null) {
|
||||||
|
$copy = new Layer(
|
||||||
|
$layer->polygonId,
|
||||||
|
$layer->color,
|
||||||
|
$layer->winding,
|
||||||
|
$layer->windingRule
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($previousCopy === null) {
|
||||||
|
$other->topLayer = $copy;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$previousCopy->nextLayer = $copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
$previousCopy = $copy;
|
||||||
|
$layer = $layer->nextLayer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a layer for the specified edge. The z-order is defined by its id.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Canvas\Rasterization\Edge edge
|
||||||
|
*/
|
||||||
|
public function add(Edge $edge)
|
||||||
|
{
|
||||||
|
$dwinding = $edge->y0 < $edge->y1 ? 1 : -1;
|
||||||
|
|
||||||
|
$layer = $this->topLayer;
|
||||||
|
$previousLayer = null;
|
||||||
|
|
||||||
|
while ($layer !== null) {
|
||||||
|
if ($layer->polygonId === $edge->polygonId) {
|
||||||
|
$layer->winding += $dwinding;
|
||||||
|
|
||||||
|
$inPath = $layer->windingRule == 'evenodd' ?
|
||||||
|
($layer->winding % 2 === 1) : ($layer->winding !== 0);
|
||||||
|
|
||||||
|
if (!$inPath) {
|
||||||
|
// Remove layer
|
||||||
|
if ($previousLayer === null) {
|
||||||
|
$this->topLayer = $layer->nextLayer;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$previousLayer->nextLayer = $layer->nextLayer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} elseif ($layer->polygonId < $edge->polygonId) {
|
||||||
|
// Insert here
|
||||||
|
$newLayer = new Layer(
|
||||||
|
$edge->polygonId,
|
||||||
|
$edge->color,
|
||||||
|
$dwinding,
|
||||||
|
$edge->windingRule
|
||||||
|
);
|
||||||
|
$newLayer->nextLayer = $layer;
|
||||||
|
|
||||||
|
if ($previousLayer === null) {
|
||||||
|
$this->topLayer = $newLayer;
|
||||||
|
} else {
|
||||||
|
$previousLayer->nextLayer = $newLayer;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$previousLayer = $layer;
|
||||||
|
$layer = $layer->nextLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($layer === null) {
|
||||||
|
$newLayer = new Layer(
|
||||||
|
$edge->polygonId,
|
||||||
|
$edge->color,
|
||||||
|
$dwinding,
|
||||||
|
$edge->windingRule
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($previousLayer === null) {
|
||||||
|
$this->topLayer = $newLayer;
|
||||||
|
} else {
|
||||||
|
$previousLayer->nextLayer = $newLayer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update current color
|
||||||
|
$color = ColorUtils::TRANSPARENT;
|
||||||
|
$layer = $this->topLayer;
|
||||||
|
|
||||||
|
while ($layer !== null && ($color & 0xff) < 255) {
|
||||||
|
if ($layer->color === ColorUtils::FORCE_TRANSPARENT) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$color = ColorUtils::over($layer->color, $color);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->color = $color;
|
||||||
|
}
|
||||||
|
}
|
379
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/Rasterizer.php
vendored
Normal file
379
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/Rasterizer.php
vendored
Normal file
@ -0,0 +1,379 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Canvas\Rasterization;
|
||||||
|
|
||||||
|
use Jdenticon\Canvas\ColorUtils;
|
||||||
|
use Jdenticon\Canvas\Rasterization\LayerManager;
|
||||||
|
use Jdenticon\Canvas\Rasterization\SuperSampleBuffer;
|
||||||
|
use Jdenticon\Canvas\Rasterization\SuperSampleRange;
|
||||||
|
use Jdenticon\Canvas\Rasterization\EdgeSuperSampleIntersection;
|
||||||
|
|
||||||
|
class Rasterizer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A higher number of samples per pixel horizontally does not affect the
|
||||||
|
* performance in the same way as SAMPLES_PER_PIXEL_Y, since the rasterizer
|
||||||
|
* does not scan every subpixel horizontally.
|
||||||
|
*/
|
||||||
|
const SAMPLES_PER_PIXEL_X = 10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A higher number of samples vertically means lower performance, since
|
||||||
|
* the rasterizer does a scan for every subpixel vertically.
|
||||||
|
*/
|
||||||
|
const SAMPLES_PER_PIXEL_Y = 3;
|
||||||
|
|
||||||
|
const SAMPLE_HEIGHT = 0.33333; // 1 / self::SAMPLES_PER_PIXEL_Y
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rasterizes the edges in the edge table to a list of color ranges. No
|
||||||
|
* range will span multiple scanlines.
|
||||||
|
*/
|
||||||
|
public static function rasterize(& $colorData, $edgeTable, $width, $height)
|
||||||
|
{
|
||||||
|
$edgeTable->sort();
|
||||||
|
|
||||||
|
$superSampleBuffer = new SuperSampleBuffer(
|
||||||
|
$width, self::SAMPLES_PER_PIXEL_X);
|
||||||
|
|
||||||
|
$layers = array();
|
||||||
|
$color = 0;
|
||||||
|
|
||||||
|
// Keeps track of how many of the subpixellayers that are used for
|
||||||
|
// the currently rendered scanline. Until a range requiring
|
||||||
|
// supersampling is encountered only a single layer is needed.
|
||||||
|
$usedLayers = 0;
|
||||||
|
|
||||||
|
for ($i = 0; $i < self::SAMPLES_PER_PIXEL_Y; $i++) {
|
||||||
|
$layers[] = new LayerManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($ey = 0; $ey < $height; $ey++) {
|
||||||
|
$scanline = $edgeTable->getScanline($ey);
|
||||||
|
if ($scanline === null) {
|
||||||
|
$colorData[] = $width;
|
||||||
|
$colorData[] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$superSampleRanges = self::getSuperSampleRanges($scanline, $width);
|
||||||
|
$superSampleRangeCount = count($superSampleRanges);
|
||||||
|
|
||||||
|
foreach ($layers as $layer) {
|
||||||
|
$layer->topLayer = null;
|
||||||
|
$layer->color = ColorUtils::TRANSPARENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
$usedLayers = 1;
|
||||||
|
|
||||||
|
if ($superSampleRanges[0]->fromX) {
|
||||||
|
$colorData[] = $superSampleRanges[0]->fromX;
|
||||||
|
$colorData[] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (
|
||||||
|
$rangeIndex = 0;
|
||||||
|
$rangeIndex < $superSampleRangeCount;
|
||||||
|
$rangeIndex++
|
||||||
|
) {
|
||||||
|
$superSampleRange = $superSampleRanges[$rangeIndex];
|
||||||
|
$edge = $superSampleRange->edges[0];
|
||||||
|
|
||||||
|
// If there is exactly one edge in the supersample range, and it
|
||||||
|
// is crossing the entire scanline, we can perform the
|
||||||
|
// antialiasing by integrating the edge function.
|
||||||
|
if (!isset($superSampleRange->edges[1]) && (
|
||||||
|
$edge->y0 <= $ey && $edge->y1 >= $ey + 1 ||
|
||||||
|
$edge->y0 >= $ey + 1 && $edge->y1 <= $ey
|
||||||
|
)) {
|
||||||
|
// Determine the lower and upper x value where the edge
|
||||||
|
// intersects the scanline.
|
||||||
|
$xey = $edge->intersection($ey);
|
||||||
|
$xey1 = $edge->intersection($ey + 1);
|
||||||
|
|
||||||
|
if ($xey < $xey1) {
|
||||||
|
$x0 = $xey;
|
||||||
|
$x1 = $xey1;
|
||||||
|
} else {
|
||||||
|
$x0 = $xey1;
|
||||||
|
$x1 = $xey;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rangeWidth = $x1 - $x0;
|
||||||
|
|
||||||
|
if ($usedLayers === 1) {
|
||||||
|
$subScanlineLayers = $layers[0];
|
||||||
|
$fromColor = $subScanlineLayers->color;
|
||||||
|
$subScanlineLayers->add($edge);
|
||||||
|
$toColor = $subScanlineLayers->color;
|
||||||
|
} else {
|
||||||
|
$fromColorR = 0;
|
||||||
|
$fromColorG = 0;
|
||||||
|
$fromColorB = 0;
|
||||||
|
$fromColorA = 0;
|
||||||
|
$toColorR = 0;
|
||||||
|
$toColorG = 0;
|
||||||
|
$toColorB = 0;
|
||||||
|
$toColorA = 0;
|
||||||
|
|
||||||
|
// Compute the average color of all subpixel layers
|
||||||
|
// before and after the edge intersection.
|
||||||
|
// The calculation is inlined for increased performance.
|
||||||
|
for ($i = 0; $i < $usedLayers; $i++) {
|
||||||
|
$subScanlineLayers = $layers[$i];
|
||||||
|
|
||||||
|
// Add to average from-color
|
||||||
|
$color = $subScanlineLayers->color;
|
||||||
|
$alpha = $color & 0xff;
|
||||||
|
if ($alpha > 0) {
|
||||||
|
$fromColorA += $alpha;
|
||||||
|
$fromColorR += (($color >> 24) & 0xff) * $alpha;
|
||||||
|
$fromColorG += (($color >> 16) & 0xff) * $alpha;
|
||||||
|
$fromColorB += (($color >> 8) & 0xff) * $alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the new layer
|
||||||
|
$subScanlineLayers->add($edge);
|
||||||
|
|
||||||
|
// Add to average to-color
|
||||||
|
$color = $subScanlineLayers->color;
|
||||||
|
$alpha = $color & 0xff;
|
||||||
|
if ($alpha > 0) {
|
||||||
|
$toColorA += $alpha;
|
||||||
|
$toColorR += (($color >> 24) & 0xff) * $alpha;
|
||||||
|
$toColorG += (($color >> 16) & 0xff) * $alpha;
|
||||||
|
$toColorB += (($color >> 8) & 0xff) * $alpha;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$fromColor = $fromColorA === 0 ? 0 : ColorUtils::from(
|
||||||
|
(int)($fromColorA / $usedLayers),
|
||||||
|
(int)($fromColorR / $fromColorA),
|
||||||
|
(int)($fromColorG / $fromColorA),
|
||||||
|
(int)($fromColorB / $fromColorA));
|
||||||
|
|
||||||
|
$toColor = $toColorA === 0 ? 0 : ColorUtils::from(
|
||||||
|
(int)($toColorA / $usedLayers),
|
||||||
|
(int)($toColorR / $toColorA),
|
||||||
|
(int)($toColorG / $toColorA),
|
||||||
|
(int)($toColorB / $toColorA));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render pixels
|
||||||
|
for (
|
||||||
|
$x = $superSampleRange->fromX;
|
||||||
|
$x < $superSampleRange->toXExcl;
|
||||||
|
$x++
|
||||||
|
) {
|
||||||
|
if ($x0 >= $x + 1) {
|
||||||
|
// Pixel not covered
|
||||||
|
$colorData[] = 1;
|
||||||
|
$colorData[] = $fromColor;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($x1 <= $x) {
|
||||||
|
// Pixel fully covered
|
||||||
|
$colorData[] = 1;
|
||||||
|
$colorData[] = $toColor;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// toColor coverage in the range [0.0, 1.0]
|
||||||
|
// Initialize to the fully covered range of the pixel.
|
||||||
|
$coverage = $x1 < $x + 1 ? $x + 1 - $x1 : 0;
|
||||||
|
|
||||||
|
// Compute integral for non-vertical edges
|
||||||
|
if ($rangeWidth > 0.001) {
|
||||||
|
// Range to integrate
|
||||||
|
$integralFrom = $x0 > $x ? $x0 : $x;;
|
||||||
|
$integralTo = $x1 < $x + 1 ? $x1 : $x + 1;
|
||||||
|
|
||||||
|
$coverage +=
|
||||||
|
(
|
||||||
|
(
|
||||||
|
$integralTo * $integralTo -
|
||||||
|
$integralFrom * $integralFrom
|
||||||
|
) / 2 +
|
||||||
|
$x0 * ($integralFrom - $integralTo)
|
||||||
|
) / $rangeWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
$colorData[] = 1;
|
||||||
|
$colorData[] = ColorUtils::mix(
|
||||||
|
$fromColor, $toColor, $coverage);
|
||||||
|
}
|
||||||
|
|
||||||
|
$color = $toColor;
|
||||||
|
|
||||||
|
} // /simplified antialiasing
|
||||||
|
else {
|
||||||
|
// Super sampling
|
||||||
|
$y = $ey + self::SAMPLE_HEIGHT / 2;
|
||||||
|
|
||||||
|
// Ensure all subpixel layers are initialized
|
||||||
|
while ($usedLayers < self::SAMPLES_PER_PIXEL_Y) {
|
||||||
|
$layers[0]->copyTo($layers[$usedLayers]);
|
||||||
|
$usedLayers++;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($layers as $subScanlineLayers) {
|
||||||
|
$color = $subScanlineLayers->color;
|
||||||
|
|
||||||
|
$intersections = self::getIntersections(
|
||||||
|
$superSampleRange->edges, $y);
|
||||||
|
|
||||||
|
foreach ($intersections as $intersection) {
|
||||||
|
$superSampleBuffer->add($color,
|
||||||
|
$intersection->x - $superSampleRange->fromX);
|
||||||
|
$subScanlineLayers->add($intersection->edge);
|
||||||
|
$color = $subScanlineLayers->color;
|
||||||
|
}
|
||||||
|
|
||||||
|
$superSampleBuffer->add(
|
||||||
|
$color, $superSampleRange->width + 1);
|
||||||
|
$superSampleBuffer->rewind();
|
||||||
|
|
||||||
|
$y += self::SAMPLE_HEIGHT;
|
||||||
|
} // /subpixel
|
||||||
|
|
||||||
|
// Blend subpixels
|
||||||
|
$color = $superSampleBuffer->colorAt(
|
||||||
|
$superSampleRange->width);
|
||||||
|
$superSampleBuffer->emptyTo(
|
||||||
|
$colorData, $superSampleRange->width);
|
||||||
|
|
||||||
|
//$color = end($colorData);
|
||||||
|
} // /super sampling
|
||||||
|
|
||||||
|
// Forward last color
|
||||||
|
if ($rangeIndex + 1 < $superSampleRangeCount) {
|
||||||
|
$count =
|
||||||
|
$superSampleRanges[$rangeIndex + 1]->fromX -
|
||||||
|
$superSampleRange->toXExcl;
|
||||||
|
|
||||||
|
if ($count > 0) {
|
||||||
|
$colorData[] = $count;
|
||||||
|
$colorData[] = $color;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$count = $width - $superSampleRange->toXExcl;
|
||||||
|
if ($count > 0) {
|
||||||
|
$colorData[] = $count;
|
||||||
|
$colorData[] = $color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // /range
|
||||||
|
}
|
||||||
|
|
||||||
|
return $colorData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function intersection_cmp($a, $b)
|
||||||
|
{
|
||||||
|
if ($a->x < $b->x) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($a->x > $b->x) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines what edges that intersect a horizontal line with the specified
|
||||||
|
* y coordinate. For each intersecting edge the intersecting x coordinate is
|
||||||
|
* returned.
|
||||||
|
*
|
||||||
|
* @param array $edges Array of edges in the current scanline.
|
||||||
|
* @param int $y Y coordinate of the current scanline.
|
||||||
|
* @return array Array containing EdgeSuperSampleIntersection. Objects
|
||||||
|
* are sorted ascending by x coordinate.
|
||||||
|
*/
|
||||||
|
private static function getIntersections($edges, $y)
|
||||||
|
{
|
||||||
|
$intersections = array();
|
||||||
|
|
||||||
|
foreach ($edges as $edge) {
|
||||||
|
if ($edge->y0 < $y && $edge->y1 >= $y ||
|
||||||
|
$edge->y0 >= $y && $edge->y1 < $y
|
||||||
|
) {
|
||||||
|
$x = $edge->x0 +
|
||||||
|
($edge->x1 - $edge->x0) * ($y - $edge->y0) /
|
||||||
|
($edge->y1 - $edge->y0);
|
||||||
|
|
||||||
|
$intersections[] = new EdgeSuperSampleIntersection($x, $edge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
usort($intersections, array(
|
||||||
|
'Jdenticon\\Canvas\\Rasterization\\Rasterizer',
|
||||||
|
'intersection_cmp'));
|
||||||
|
|
||||||
|
return $intersections;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines what ranges of a scanline that needs to be supersampled.
|
||||||
|
*
|
||||||
|
* @param array $scanline Array of edges in the current scanline.
|
||||||
|
* @return array Array of SuperSampleRange.
|
||||||
|
*/
|
||||||
|
private static function getSuperSampleRanges(&$scanline, $width)
|
||||||
|
{
|
||||||
|
$superSampleRanges = array();
|
||||||
|
|
||||||
|
$rangeIndex = 0;
|
||||||
|
$scanlineCount = count($scanline);
|
||||||
|
|
||||||
|
while ($rangeIndex < $scanlineCount) {
|
||||||
|
$range = $scanline[$rangeIndex];
|
||||||
|
|
||||||
|
if ($range->fromX >= $width) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$superSampleRange = new SuperSampleRange(
|
||||||
|
$range->fromX,
|
||||||
|
$range->fromX + $range->width
|
||||||
|
);
|
||||||
|
$superSampleRange->edges[] = $range->edge;
|
||||||
|
|
||||||
|
$rangeIndex++;
|
||||||
|
|
||||||
|
for ($i = $rangeIndex; $i < $scanlineCount; $i++) {
|
||||||
|
$range = $scanline[$i];
|
||||||
|
|
||||||
|
if ($range->fromX < $superSampleRange->toXExcl) {
|
||||||
|
$superSampleRange->toXExcl = max(
|
||||||
|
$superSampleRange->toXExcl,
|
||||||
|
$range->fromX + $range->width);
|
||||||
|
$superSampleRange->edges[] = $range->edge;
|
||||||
|
$rangeIndex++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$superSampleRange->toXExcl = min($superSampleRange->toXExcl, $width);
|
||||||
|
$superSampleRange->width =
|
||||||
|
$superSampleRange->toXExcl - $superSampleRange->fromX;
|
||||||
|
|
||||||
|
$superSampleRanges[] = $superSampleRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $superSampleRanges;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
198
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/SuperSampleBuffer.php
vendored
Normal file
198
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/SuperSampleBuffer.php
vendored
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Canvas\Rasterization;
|
||||||
|
|
||||||
|
use Jdenticon\Canvas\ColorUtils;
|
||||||
|
|
||||||
|
class SuperSampleBuffer
|
||||||
|
{
|
||||||
|
const IDX_COUNT = 0;
|
||||||
|
const IDX_A = 1;
|
||||||
|
const IDX_R = 2;
|
||||||
|
const IDX_G = 3;
|
||||||
|
const IDX_B = 4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a color buffer keeping an average color out of several
|
||||||
|
* color samples per pixel.
|
||||||
|
*
|
||||||
|
* @param integer $width Width of the buffer in pixels.
|
||||||
|
* @param integer $samplesPerPixel Number of samples to keep per pixel.
|
||||||
|
*/
|
||||||
|
public function __construct($width, $samplesPerPixel)
|
||||||
|
{
|
||||||
|
$this->samples = array();
|
||||||
|
$this->samplesPerPixel = $samplesPerPixel;
|
||||||
|
|
||||||
|
$this->pixelOffset = 0;
|
||||||
|
$this->subPixelOffset = 0;
|
||||||
|
|
||||||
|
$this->width = $width;
|
||||||
|
$this->used = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rewinds the cursor to the beginning of the buffer.
|
||||||
|
*/
|
||||||
|
public function rewind()
|
||||||
|
{
|
||||||
|
$this->pixelOffset = 0;
|
||||||
|
$this->subPixelOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the samples in this buffer.
|
||||||
|
*/
|
||||||
|
public function clear()
|
||||||
|
{
|
||||||
|
$this->pixelOffset = 0;
|
||||||
|
$this->subPixelOffset = 0;
|
||||||
|
$this->used = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the average color of each pixel to a specified color array.
|
||||||
|
*
|
||||||
|
* @param array $colorData The average colors will be written to this
|
||||||
|
* color array.
|
||||||
|
* @param integer $count Number of pixels to write.
|
||||||
|
*/
|
||||||
|
public function emptyTo(& $colorData, $count)
|
||||||
|
{
|
||||||
|
for ($i = 0; $i < $count; $i++) {
|
||||||
|
$sampleCount = $this->samples[$i * 5 + self::IDX_COUNT];
|
||||||
|
$a = $this->samples[$i * 5 + self::IDX_A];
|
||||||
|
$color = $sampleCount == 0 || $a == 0 ? 0 :
|
||||||
|
ColorUtils::from(
|
||||||
|
(int)($a / $sampleCount),
|
||||||
|
(int)($this->samples[$i * 5 + self::IDX_R] / $a),
|
||||||
|
(int)($this->samples[$i * 5 + self::IDX_G] / $a),
|
||||||
|
(int)($this->samples[$i * 5 + self::IDX_B] / $a)
|
||||||
|
);
|
||||||
|
|
||||||
|
$colorData[] = 1;
|
||||||
|
$colorData[] = $color;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->pixelOffset = 0;
|
||||||
|
$this->subPixelOffset = 0;
|
||||||
|
$this->used = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the average color of the pixel at a specified index.
|
||||||
|
*
|
||||||
|
* @param integer $index The index of the pixel.
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function colorAt($index)
|
||||||
|
{
|
||||||
|
$sampleCount = $this->samples[$index * 5 + self::IDX_COUNT];
|
||||||
|
$alphaSum = $this->samples[$index * 5 + self::IDX_A];
|
||||||
|
return $sampleCount == 0 || $alphaSum == 0 ? 0 :
|
||||||
|
ColorUtils::from(
|
||||||
|
(int)($alphaSum / $sampleCount),
|
||||||
|
(int)($this->samples[$index * 5 + self::IDX_R] / $alphaSum),
|
||||||
|
(int)($this->samples[$index * 5 + self::IDX_G] / $alphaSum),
|
||||||
|
(int)($this->samples[$index * 5 + self::IDX_B] / $alphaSum)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a color to the current pixel in the buffer.
|
||||||
|
*
|
||||||
|
* @param integer $count Number of samples of the color to be added to
|
||||||
|
* the buffer.
|
||||||
|
*/
|
||||||
|
private function _add($count, $a, $r, $g, $b)
|
||||||
|
{
|
||||||
|
if ($this->used < $this->pixelOffset) {
|
||||||
|
$this->used = $this->pixelOffset;
|
||||||
|
|
||||||
|
$this->samples[$this->pixelOffset * 5 + self::IDX_COUNT] = $count;
|
||||||
|
$this->samples[$this->pixelOffset * 5 + self::IDX_A] = $a * $count;
|
||||||
|
$this->samples[$this->pixelOffset * 5 + self::IDX_R] = $a * $r * $count;
|
||||||
|
$this->samples[$this->pixelOffset * 5 + self::IDX_G] = $a * $g * $count;
|
||||||
|
$this->samples[$this->pixelOffset * 5 + self::IDX_B] = $a * $b * $count;
|
||||||
|
} else {
|
||||||
|
$this->samples[$this->pixelOffset * 5 + self::IDX_COUNT] += $count;
|
||||||
|
|
||||||
|
if ($a > 0) {
|
||||||
|
$this->samples[$this->pixelOffset * 5 + self::IDX_A] += $a * $count;
|
||||||
|
$this->samples[$this->pixelOffset * 5 + self::IDX_R] += $a * $r * $count;
|
||||||
|
$this->samples[$this->pixelOffset * 5 + self::IDX_G] += $a * $g * $count;
|
||||||
|
$this->samples[$this->pixelOffset * 5 + self::IDX_B] += $a * $b * $count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a color to the buffer up until the specified x index.
|
||||||
|
*
|
||||||
|
* @param integer $color Color to write.
|
||||||
|
* @param float $untilX Samples of the color will be added the buffer until
|
||||||
|
* the cursor reaches this coordinate.
|
||||||
|
*/
|
||||||
|
public function add($color, $untilX)
|
||||||
|
{
|
||||||
|
$samplesLeft =
|
||||||
|
(int)($untilX * $this->samplesPerPixel) -
|
||||||
|
$this->subPixelOffset -
|
||||||
|
$this->pixelOffset * $this->samplesPerPixel;
|
||||||
|
|
||||||
|
// ColorUtils methods inlined for performance reasons
|
||||||
|
$a = ($color) & 0xff;
|
||||||
|
$r = ($color >> 24) & 0xff;
|
||||||
|
$g = ($color >> 16) & 0xff;
|
||||||
|
$b = ($color >> 8) & 0xff;
|
||||||
|
|
||||||
|
// First partial pixel
|
||||||
|
if ($this->subPixelOffset > 0) {
|
||||||
|
$samples = $this->samplesPerPixel - $this->subPixelOffset;
|
||||||
|
if ($samples > $samplesLeft) {
|
||||||
|
$samples = $samplesLeft;
|
||||||
|
}
|
||||||
|
$samplesLeft -= $samples;
|
||||||
|
|
||||||
|
$this->_add($samples, $a, $r, $g, $b);
|
||||||
|
|
||||||
|
$this->subPixelOffset += $samples;
|
||||||
|
if ($this->subPixelOffset == $this->samplesPerPixel) {
|
||||||
|
$this->subPixelOffset = 0;
|
||||||
|
$this->pixelOffset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Full pixels
|
||||||
|
$fullPixels = (int)($samplesLeft / $this->samplesPerPixel);
|
||||||
|
if ($fullPixels > 0) {
|
||||||
|
for ($i = 0; $i < $fullPixels; $i++) {
|
||||||
|
$this->_add($this->samplesPerPixel, $a, $r, $g, $b);
|
||||||
|
$this->pixelOffset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$samplesLeft -= $fullPixels * $this->samplesPerPixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last partial pixel
|
||||||
|
if ($samplesLeft > 0) {
|
||||||
|
$this->_add($samplesLeft, $a, $r, $g, $b);
|
||||||
|
|
||||||
|
$this->subPixelOffset += $samplesLeft;
|
||||||
|
|
||||||
|
if ($this->subPixelOffset == $this->samplesPerPixel) {
|
||||||
|
$this->subPixelOffset = 0;
|
||||||
|
$this->pixelOffset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/SuperSampleRange.php
vendored
Normal file
27
vendor/jdenticon/jdenticon/src/Canvas/Rasterization/SuperSampleRange.php
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Canvas\Rasterization;
|
||||||
|
|
||||||
|
class SuperSampleRange
|
||||||
|
{
|
||||||
|
public $fromX;
|
||||||
|
public $toXExcl;
|
||||||
|
public $edges;
|
||||||
|
public $width;
|
||||||
|
|
||||||
|
public function __construct($fromX, $toXExcl)
|
||||||
|
{
|
||||||
|
$this->fromX = $fromX;
|
||||||
|
$this->toXExcl = $toXExcl;
|
||||||
|
$this->edges = array();
|
||||||
|
}
|
||||||
|
}
|
605
vendor/jdenticon/jdenticon/src/Color.php
vendored
Normal file
605
vendor/jdenticon/jdenticon/src/Color.php
vendored
Normal file
@ -0,0 +1,605 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a 24-bit color with a 8-bit alpha channel.
|
||||||
|
*/
|
||||||
|
class Color
|
||||||
|
{
|
||||||
|
private static $lightnessCompensations = array(
|
||||||
|
0.55, 0.5, 0.5, 0.46, 0.6, 0.55, 0.55);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The red component of the color in the range [0, 255].
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $r;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The green component of the color in the range [0, 255].
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $g;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The blue component of the color in the range [0, 255].
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $b;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The alpha component of the color in the range [0, 255].
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $a;
|
||||||
|
|
||||||
|
// Users of the struct should use the static factory methods
|
||||||
|
// to create Color value.
|
||||||
|
private function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Color from an RGB value.
|
||||||
|
*
|
||||||
|
* @param int $alpha Alpha channel value in the range [0, 255].
|
||||||
|
* @param int $red Red component in the range [0, 255].
|
||||||
|
* @param int $green GReen component in the range [0, 255].
|
||||||
|
* @param int $blue Blue component in the range [0, 255].
|
||||||
|
*/
|
||||||
|
public static function fromRgb($red, $green, $blue, $alpha = 255)
|
||||||
|
{
|
||||||
|
$color = new Color();
|
||||||
|
$color->r = $red;
|
||||||
|
$color->g = $green;
|
||||||
|
$color->b = $blue;
|
||||||
|
$color->a = $alpha;
|
||||||
|
return $color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Color instance from HSL color parameters.
|
||||||
|
*
|
||||||
|
* @param float $hue Hue in the range [0, 1]
|
||||||
|
* @param float $saturation Saturation in the range [0, 1]
|
||||||
|
* @param float $lightness Lightness in the range [0, 1]
|
||||||
|
* @param float $alpha Alpha channel value in the range [0, 1].
|
||||||
|
*/
|
||||||
|
public static function fromHsl($hue, $saturation, $lightness, $alpha = 1.0)
|
||||||
|
{
|
||||||
|
if ($hue < 0) $hue = 0;
|
||||||
|
if ($hue > 1) $hue = 1;
|
||||||
|
|
||||||
|
if ($saturation < 0) $saturation = 0;
|
||||||
|
if ($saturation > 1) $saturation = 1;
|
||||||
|
|
||||||
|
if ($lightness < 0) $lightness = 0;
|
||||||
|
if ($lightness > 1) $lightness = 1;
|
||||||
|
|
||||||
|
if ($alpha < 0) $alpha = 0;
|
||||||
|
if ($alpha > 1) $alpha = 1;
|
||||||
|
|
||||||
|
// Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color
|
||||||
|
if ($saturation == 0) {
|
||||||
|
$value = (int)($lightness * 255);
|
||||||
|
return self::fromRgb($value, $value, $value, (int)($alpha * 255));
|
||||||
|
} else {
|
||||||
|
if ($lightness <= 0.5) {
|
||||||
|
$m2 = $lightness * ($saturation + 1);
|
||||||
|
} else {
|
||||||
|
$m2 = $lightness + $saturation - $lightness * $saturation;
|
||||||
|
}
|
||||||
|
|
||||||
|
$m1 = $lightness * 2 - $m2;
|
||||||
|
|
||||||
|
return self::fromRgb(
|
||||||
|
self::hueToRgb($m1, $m2, $hue * 6 + 2),
|
||||||
|
self::hueToRgb($m1, $m2, $hue * 6),
|
||||||
|
self::hueToRgb($m1, $m2, $hue * 6 - 2),
|
||||||
|
(int)($alpha * 255));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Color> instance from HSL color parameters and will compensate
|
||||||
|
* the lightness for hues that appear to be darker than others.
|
||||||
|
*
|
||||||
|
* @param float $hue Hue in the range [0, 1].
|
||||||
|
* @param float $saturation Saturation in the range [0, 1].
|
||||||
|
* @param float $lightness Lightness in the range [0, 1].
|
||||||
|
* @param float $alpha Alpha channel value in the range [0, 1].
|
||||||
|
*/
|
||||||
|
public static function fromHslCompensated($hue, $saturation, $lightness, $alpha = 1.0)
|
||||||
|
{
|
||||||
|
if ($hue < 0) $hue = 0;
|
||||||
|
if ($hue > 1) $hue = 1;
|
||||||
|
|
||||||
|
$lightnessCompensation = self::$lightnessCompensations[(int)($hue * 6 + 0.5)];
|
||||||
|
|
||||||
|
// Adjust the input lightness relative to the compensation
|
||||||
|
$lightness = $lightness < 0.5 ?
|
||||||
|
$lightness * $lightnessCompensation * 2 :
|
||||||
|
$lightnessCompensation + ($lightness - 0.5) * (1 - $lightnessCompensation) * 2;
|
||||||
|
|
||||||
|
return self::fromHsl($hue, $saturation, $lightness, $alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method for FromHsl
|
||||||
|
private static function hueToRgb($m1, $m2, $h)
|
||||||
|
{
|
||||||
|
if ($h < 0) {
|
||||||
|
$h = $h + 6;
|
||||||
|
} elseif ($h > 6) {
|
||||||
|
$h = $h - 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($h < 1) {
|
||||||
|
$r = $m1 + ($m2 - $m1) * $h;
|
||||||
|
} elseif ($h < 3) {
|
||||||
|
$r = $m2;
|
||||||
|
} elseif ($h < 4) {
|
||||||
|
$r = $m1 + ($m2 - $m1) * (4 - $h);
|
||||||
|
} else {
|
||||||
|
$r = $m1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)(255 * $r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the argb value of this color.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function toRgba()
|
||||||
|
{
|
||||||
|
return
|
||||||
|
($this->r << 24) |
|
||||||
|
($this->g << 16) |
|
||||||
|
($this->b << 8) |
|
||||||
|
($this->a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a hexadecimal representation of this color on the format #rrggbbaa.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return '#' . bin2hex(pack('N', $this->toRgba()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a hexadecimal representation of this color on the format #rrggbbaa.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function toHexString($length = 8)
|
||||||
|
{
|
||||||
|
if ($length === 8) {
|
||||||
|
return $this->__toString();
|
||||||
|
}
|
||||||
|
return '#' . substr(bin2hex(pack('N', $this->toRgba())), 0, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to parse a value as a Color.
|
||||||
|
*
|
||||||
|
* @param mixed $value Value to parse.
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* @return \Jdenticon\Color
|
||||||
|
*/
|
||||||
|
public static function parse($value) {
|
||||||
|
if ($value instanceof Color) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = strtolower("$value");
|
||||||
|
|
||||||
|
if (preg_match('/^#?[0-9a-f]{3,8}$/', $value) &&
|
||||||
|
self::parseHexColor($value, $result)
|
||||||
|
) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match(
|
||||||
|
'/^rgba?\\(([^,]+),([^,]+),([^,]+)(?:,([^,]+))?\\)$/',
|
||||||
|
$value, $matches) &&
|
||||||
|
self::parseRgbComponent($matches[1], $r) &&
|
||||||
|
self::parseRgbComponent($matches[2], $g) &&
|
||||||
|
self::parseRgbComponent($matches[3], $b) &&
|
||||||
|
self::parseAlpha(isset($matches[4]) ? $matches[4] : null, $a)
|
||||||
|
) {
|
||||||
|
return self::fromRgb($r, $g, $b, (int)(255 * $a));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match(
|
||||||
|
'/^hsla?\\(([^,]+),([^,]+),([^,]+)(?:,([^,]+))?\\)$/',
|
||||||
|
$value, $matches) &&
|
||||||
|
self::parseHue($matches[1], $h) &&
|
||||||
|
self::parsePercent($matches[2], $s) &&
|
||||||
|
self::parsePercent($matches[3], $l) &&
|
||||||
|
self::parseAlpha(isset($matches[4]) ? $matches[4] : null, $a)
|
||||||
|
) {
|
||||||
|
return self::fromHsl($h, $s, $l, $a);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = self::parseNamedColor($value);
|
||||||
|
if ($result !== null) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
"Cannot parse '$value' as a color.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a percent value.
|
||||||
|
*
|
||||||
|
* @param string $input Input string.
|
||||||
|
* @param float $result Resulting value in range [0, 1].
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
private static function parsePercent($input, &$result)
|
||||||
|
{
|
||||||
|
// Detect and remove percent sign
|
||||||
|
if (preg_match('/^\\s*(\\d*(?:\\.\\d*)?)%\\s*$/', $input, $matches)) {
|
||||||
|
$result = floatval($matches[1]) / 100;
|
||||||
|
|
||||||
|
if ($result < 0) $result = 0;
|
||||||
|
if ($result > 1) $result = 1;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses an alpha value.
|
||||||
|
*
|
||||||
|
* @param string $input Input string.
|
||||||
|
* @param float $result Resulting alpha in range [0, 1].
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
private static function parseAlpha($input, &$result)
|
||||||
|
{
|
||||||
|
if ($input === null ||
|
||||||
|
$input === ''
|
||||||
|
) {
|
||||||
|
$result = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match('/^\\s*(\\d*(?:\\.\\d*)?)(%?)\\s*$/', $input, $matches)) {
|
||||||
|
$result = floatval($matches[1]);
|
||||||
|
|
||||||
|
// Percentage
|
||||||
|
if ($matches[2] !== '') {
|
||||||
|
$result = $result / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($result < 0) $result = 0;
|
||||||
|
if ($result > 1) $result = 1;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses an RGB component.
|
||||||
|
*
|
||||||
|
* @param string $input Input string.
|
||||||
|
* @param float $result Hue in range [0, 255].
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
private static function parseRgbComponent($input, &$result)
|
||||||
|
{
|
||||||
|
if (preg_match('/^\\s*(\\d*(?:\\.\\d*)?)(%?)\\s*$/', $input, $matches)) {
|
||||||
|
$result = floatval($matches[1]);
|
||||||
|
|
||||||
|
if ($matches[2] === '%') {
|
||||||
|
$result = 255 * $result / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = (int)$result;
|
||||||
|
|
||||||
|
if ($result < 0) $result = 0;
|
||||||
|
if ($result > 255) $result = 255;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a hue component.
|
||||||
|
*
|
||||||
|
* @param string $input Input string.
|
||||||
|
* @param float $result Hue in range [0, 1].
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
private static function parseHue($input, &$result)
|
||||||
|
{
|
||||||
|
if (preg_match(
|
||||||
|
'/^\s*(\d*(?:\.\d*)?)(deg|grad|rad|turn|)\s*$/',
|
||||||
|
$input, $matches)
|
||||||
|
) {
|
||||||
|
$result = floatval($matches[1]);
|
||||||
|
|
||||||
|
// Percentage
|
||||||
|
switch ($matches[2]) {
|
||||||
|
case "grad":
|
||||||
|
// Gradians: range 0 - 400
|
||||||
|
$result = $result / 400;
|
||||||
|
break;
|
||||||
|
case "rad":
|
||||||
|
// Radians: range 0 - 2pi
|
||||||
|
$result = $result / M_PI / 2;
|
||||||
|
break;
|
||||||
|
case "turn":
|
||||||
|
// Turns: range 0 - 1
|
||||||
|
$result = $result;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Degree: range 0 - 360
|
||||||
|
$result = $result / 360;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = fmod($result, 1);
|
||||||
|
|
||||||
|
if ($result < 0) {
|
||||||
|
$result += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a hex color string.
|
||||||
|
*
|
||||||
|
* @param string $input Input string.
|
||||||
|
* @param float $result Hue in range [0, 1].
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
private static function parseHexColor($input, &$result)
|
||||||
|
{
|
||||||
|
if ($input[0] === '#') {
|
||||||
|
$input = substr($input, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// intval does not support unsigned 32-bit integers
|
||||||
|
// so we need to parse large numbers stepwise
|
||||||
|
$numeric24bit = intval(substr($input, 0, 6), 16);
|
||||||
|
$alpha8bit = intval(substr($input, 6, 2), 16);
|
||||||
|
|
||||||
|
switch (strlen($input)) {
|
||||||
|
case 3:
|
||||||
|
$result = self::fromRgb(
|
||||||
|
(($numeric24bit & 0xf00) >> 8) |
|
||||||
|
(($numeric24bit & 0xf00) >> 4),
|
||||||
|
(($numeric24bit & 0x0f0) >> 4) |
|
||||||
|
(($numeric24bit & 0x0f0)),
|
||||||
|
(($numeric24bit & 0x00f) << 4) |
|
||||||
|
(($numeric24bit & 0x00f))
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
$result = self::fromRgb(
|
||||||
|
(($numeric24bit & 0xf000) >> 12) |
|
||||||
|
(($numeric24bit & 0xf000) >> 8),
|
||||||
|
(($numeric24bit & 0x0f00) >> 8) |
|
||||||
|
(($numeric24bit & 0x0f00) >> 4),
|
||||||
|
(($numeric24bit & 0x00f0) >> 4) |
|
||||||
|
(($numeric24bit & 0x00f0)),
|
||||||
|
(($numeric24bit & 0x000f) << 4) |
|
||||||
|
(($numeric24bit & 0x000f))
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
$result = self::fromRgb(
|
||||||
|
0xff & ($numeric24bit >> 16),
|
||||||
|
0xff & ($numeric24bit >> 8),
|
||||||
|
0xff & ($numeric24bit)
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
$result = self::fromRgb(
|
||||||
|
0xff & ($numeric24bit >> 16),
|
||||||
|
0xff & ($numeric24bit >> 8),
|
||||||
|
0xff & ($numeric24bit),
|
||||||
|
0xff & ($alpha8bit)
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks up a named color to a Color instance.
|
||||||
|
*
|
||||||
|
* @param string $input Input string.
|
||||||
|
*
|
||||||
|
* @return \Jdenticon\Color
|
||||||
|
*/
|
||||||
|
private static function parseNamedColor($input)
|
||||||
|
{
|
||||||
|
// Source: https://www.w3.org/TR/css-color-4/#named-colors
|
||||||
|
switch ($input) {
|
||||||
|
case 'aliceblue': return self::fromRgb(240,248,255);
|
||||||
|
case 'antiquewhite': return self::fromRgb(250,235,215);
|
||||||
|
case 'aqua': return self::fromRgb(0,255,255);
|
||||||
|
case 'aquamarine': return self::fromRgb(127,255,212);
|
||||||
|
case 'azure': return self::fromRgb(240,255,255);
|
||||||
|
case 'beige': return self::fromRgb(245,245,220);
|
||||||
|
case 'bisque': return self::fromRgb(255,228,196);
|
||||||
|
case 'black': return self::fromRgb(0,0,0);
|
||||||
|
case 'blanchedalmond': return self::fromRgb(255,235,205);
|
||||||
|
case 'blue': return self::fromRgb(0,0,255);
|
||||||
|
case 'blueviolet': return self::fromRgb(138,43,226);
|
||||||
|
case 'brown': return self::fromRgb(165,42,42);
|
||||||
|
case 'burlywood': return self::fromRgb(222,184,135);
|
||||||
|
case 'cadetblue': return self::fromRgb(95,158,160);
|
||||||
|
case 'chartreuse': return self::fromRgb(127,255,0);
|
||||||
|
case 'chocolate': return self::fromRgb(210,105,30);
|
||||||
|
case 'coral': return self::fromRgb(255,127,80);
|
||||||
|
case 'cornflowerblue': return self::fromRgb(100,149,237);
|
||||||
|
case 'cornsilk': return self::fromRgb(255,248,220);
|
||||||
|
case 'crimson': return self::fromRgb(220,20,60);
|
||||||
|
case 'cyan': return self::fromRgb(0,255,255);
|
||||||
|
case 'darkblue': return self::fromRgb(0,0,139);
|
||||||
|
case 'darkcyan': return self::fromRgb(0,139,139);
|
||||||
|
case 'darkgoldenrod': return self::fromRgb(184,134,11);
|
||||||
|
case 'darkgray': return self::fromRgb(169,169,169);
|
||||||
|
case 'darkgreen': return self::fromRgb(0,100,0);
|
||||||
|
case 'darkgrey': return self::fromRgb(169,169,169);
|
||||||
|
case 'darkkhaki': return self::fromRgb(189,183,107);
|
||||||
|
case 'darkmagenta': return self::fromRgb(139,0,139);
|
||||||
|
case 'darkolivegreen': return self::fromRgb(85,107,47);
|
||||||
|
case 'darkorange': return self::fromRgb(255,140,0);
|
||||||
|
case 'darkorchid': return self::fromRgb(153,50,204);
|
||||||
|
case 'darkred': return self::fromRgb(139,0,0);
|
||||||
|
case 'darksalmon': return self::fromRgb(233,150,122);
|
||||||
|
case 'darkseagreen': return self::fromRgb(143,188,143);
|
||||||
|
case 'darkslateblue': return self::fromRgb(72,61,139);
|
||||||
|
case 'darkslategray': return self::fromRgb(47,79,79);
|
||||||
|
case 'darkslategrey': return self::fromRgb(47,79,79);
|
||||||
|
case 'darkturquoise': return self::fromRgb(0,206,209);
|
||||||
|
case 'darkviolet': return self::fromRgb(148,0,211);
|
||||||
|
case 'deeppink': return self::fromRgb(255,20,147);
|
||||||
|
case 'deepskyblue': return self::fromRgb(0,191,255);
|
||||||
|
case 'dimgray': return self::fromRgb(105,105,105);
|
||||||
|
case 'dimgrey': return self::fromRgb(105,105,105);
|
||||||
|
case 'dodgerblue': return self::fromRgb(30,144,255);
|
||||||
|
case 'firebrick': return self::fromRgb(178,34,34);
|
||||||
|
case 'floralwhite': return self::fromRgb(255,250,240);
|
||||||
|
case 'forestgreen': return self::fromRgb(34,139,34);
|
||||||
|
case 'fuchsia': return self::fromRgb(255,0,255);
|
||||||
|
case 'gainsboro': return self::fromRgb(220,220,220);
|
||||||
|
case 'ghostwhite': return self::fromRgb(248,248,255);
|
||||||
|
case 'gold': return self::fromRgb(255,215,0);
|
||||||
|
case 'goldenrod': return self::fromRgb(218,165,32);
|
||||||
|
case 'gray': return self::fromRgb(128,128,128);
|
||||||
|
case 'green': return self::fromRgb(0,128,0);
|
||||||
|
case 'greenyellow': return self::fromRgb(173,255,47);
|
||||||
|
case 'grey': return self::fromRgb(128,128,128);
|
||||||
|
case 'honeydew': return self::fromRgb(240,255,240);
|
||||||
|
case 'hotpink': return self::fromRgb(255,105,180);
|
||||||
|
case 'indianred': return self::fromRgb(205,92,92);
|
||||||
|
case 'indigo': return self::fromRgb(75,0,130);
|
||||||
|
case 'ivory': return self::fromRgb(255,255,240);
|
||||||
|
case 'khaki': return self::fromRgb(240,230,140);
|
||||||
|
case 'lavender': return self::fromRgb(230,230,250);
|
||||||
|
case 'lavenderblush': return self::fromRgb(255,240,245);
|
||||||
|
case 'lawngreen': return self::fromRgb(124,252,0);
|
||||||
|
case 'lemonchiffon': return self::fromRgb(255,250,205);
|
||||||
|
case 'lightblue': return self::fromRgb(173,216,230);
|
||||||
|
case 'lightcoral': return self::fromRgb(240,128,128);
|
||||||
|
case 'lightcyan': return self::fromRgb(224,255,255);
|
||||||
|
case 'lightgoldenrodyellow': return self::fromRgb(250,250,210);
|
||||||
|
case 'lightgray': return self::fromRgb(211,211,211);
|
||||||
|
case 'lightgreen': return self::fromRgb(144,238,144);
|
||||||
|
case 'lightgrey': return self::fromRgb(211,211,211);
|
||||||
|
case 'lightpink': return self::fromRgb(255,182,193);
|
||||||
|
case 'lightsalmon': return self::fromRgb(255,160,122);
|
||||||
|
case 'lightseagreen': return self::fromRgb(32,178,170);
|
||||||
|
case 'lightskyblue': return self::fromRgb(135,206,250);
|
||||||
|
case 'lightslategray': return self::fromRgb(119,136,153);
|
||||||
|
case 'lightslategrey': return self::fromRgb(119,136,153);
|
||||||
|
case 'lightsteelblue': return self::fromRgb(176,196,222);
|
||||||
|
case 'lightyellow': return self::fromRgb(255,255,224);
|
||||||
|
case 'lime': return self::fromRgb(0,255,0);
|
||||||
|
case 'limegreen': return self::fromRgb(50,205,50);
|
||||||
|
case 'linen': return self::fromRgb(250,240,230);
|
||||||
|
case 'magenta': return self::fromRgb(255,0,255);
|
||||||
|
case 'maroon': return self::fromRgb(128,0,0);
|
||||||
|
case 'mediumaquamarine': return self::fromRgb(102,205,170);
|
||||||
|
case 'mediumblue': return self::fromRgb(0,0,205);
|
||||||
|
case 'mediumorchid': return self::fromRgb(186,85,211);
|
||||||
|
case 'mediumpurple': return self::fromRgb(147,112,219);
|
||||||
|
case 'mediumseagreen': return self::fromRgb(60,179,113);
|
||||||
|
case 'mediumslateblue': return self::fromRgb(123,104,238);
|
||||||
|
case 'mediumspringgreen': return self::fromRgb(0,250,154);
|
||||||
|
case 'mediumturquoise': return self::fromRgb(72,209,204);
|
||||||
|
case 'mediumvioletred': return self::fromRgb(199,21,133);
|
||||||
|
case 'midnightblue': return self::fromRgb(25,25,112);
|
||||||
|
case 'mintcream': return self::fromRgb(245,255,250);
|
||||||
|
case 'mistyrose': return self::fromRgb(255,228,225);
|
||||||
|
case 'moccasin': return self::fromRgb(255,228,181);
|
||||||
|
case 'navajowhite': return self::fromRgb(255,222,173);
|
||||||
|
case 'navy': return self::fromRgb(0,0,128);
|
||||||
|
case 'oldlace': return self::fromRgb(253,245,230);
|
||||||
|
case 'olive': return self::fromRgb(128,128,0);
|
||||||
|
case 'olivedrab': return self::fromRgb(107,142,35);
|
||||||
|
case 'orange': return self::fromRgb(255,165,0);
|
||||||
|
case 'orangered': return self::fromRgb(255,69,0);
|
||||||
|
case 'orchid': return self::fromRgb(218,112,214);
|
||||||
|
case 'palegoldenrod': return self::fromRgb(238,232,170);
|
||||||
|
case 'palegreen': return self::fromRgb(152,251,152);
|
||||||
|
case 'paleturquoise': return self::fromRgb(175,238,238);
|
||||||
|
case 'palevioletred': return self::fromRgb(219,112,147);
|
||||||
|
case 'papayawhip': return self::fromRgb(255,239,213);
|
||||||
|
case 'peachpuff': return self::fromRgb(255,218,185);
|
||||||
|
case 'peru': return self::fromRgb(205,133,63);
|
||||||
|
case 'pink': return self::fromRgb(255,192,203);
|
||||||
|
case 'plum': return self::fromRgb(221,160,221);
|
||||||
|
case 'powderblue': return self::fromRgb(176,224,230);
|
||||||
|
case 'purple': return self::fromRgb(128,0,128);
|
||||||
|
case 'rebeccapurple': return self::fromRgb(102,51,153);
|
||||||
|
case 'red': return self::fromRgb(255,0,0);
|
||||||
|
case 'rosybrown': return self::fromRgb(188,143,143);
|
||||||
|
case 'royalblue': return self::fromRgb(65,105,225);
|
||||||
|
case 'saddlebrown': return self::fromRgb(139,69,19);
|
||||||
|
case 'salmon': return self::fromRgb(250,128,114);
|
||||||
|
case 'sandybrown': return self::fromRgb(244,164,96);
|
||||||
|
case 'seagreen': return self::fromRgb(46,139,87);
|
||||||
|
case 'seashell': return self::fromRgb(255,245,238);
|
||||||
|
case 'sienna': return self::fromRgb(160,82,45);
|
||||||
|
case 'silver': return self::fromRgb(192,192,192);
|
||||||
|
case 'skyblue': return self::fromRgb(135,206,235);
|
||||||
|
case 'slateblue': return self::fromRgb(106,90,205);
|
||||||
|
case 'slategray': return self::fromRgb(112,128,144);
|
||||||
|
case 'slategrey': return self::fromRgb(112,128,144);
|
||||||
|
case 'snow': return self::fromRgb(255,250,250);
|
||||||
|
case 'springgreen': return self::fromRgb(0,255,127);
|
||||||
|
case 'steelblue': return self::fromRgb(70,130,180);
|
||||||
|
case 'tan': return self::fromRgb(210,180,140);
|
||||||
|
case 'teal': return self::fromRgb(0,128,128);
|
||||||
|
case 'thistle': return self::fromRgb(216,191,216);
|
||||||
|
case 'tomato': return self::fromRgb(255,99,71);
|
||||||
|
case 'transparent': return self::fromRgb(0,0,0,0);
|
||||||
|
case 'turquoise': return self::fromRgb(64,224,208);
|
||||||
|
case 'violet': return self::fromRgb(238,130,238);
|
||||||
|
case 'wheat': return self::fromRgb(245,222,179);
|
||||||
|
case 'white': return self::fromRgb(255,255,255);
|
||||||
|
case 'whitesmoke': return self::fromRgb(245,245,245);
|
||||||
|
case 'yellow': return self::fromRgb(255,255,0);
|
||||||
|
case 'yellowgreen': return self::fromRgb(154,205,50);
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
492
vendor/jdenticon/jdenticon/src/Identicon.php
vendored
Normal file
492
vendor/jdenticon/jdenticon/src/Identicon.php
vendored
Normal file
@ -0,0 +1,492 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon;
|
||||||
|
|
||||||
|
use Jdenticon\IdenticonStyle;
|
||||||
|
use Jdenticon\Rendering\Rectangle;
|
||||||
|
use Jdenticon\Rendering\RendererInterface;
|
||||||
|
use Jdenticon\Rendering\IconGenerator;
|
||||||
|
use Jdenticon\Rendering\InternalPngRenderer;
|
||||||
|
use Jdenticon\Rendering\ImagickRenderer;
|
||||||
|
use Jdenticon\Rendering\SvgRenderer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an identicon and its style. This is the entry class to Jdenticon.
|
||||||
|
*/
|
||||||
|
class Identicon
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
private $value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
private $valueSet = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defaults to hash of an empty string.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $hash = 'da39a3ee5e6b4b0d3255bfef95601890afd80709';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $size = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Jdenticon\Rendering\IconGenerator
|
||||||
|
*/
|
||||||
|
private $iconGenerator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Jdenticon\IdenticonStyle
|
||||||
|
*/
|
||||||
|
private $style;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $enableImageMagick;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an Identicon instance with the specified hash.
|
||||||
|
*
|
||||||
|
* @param string $hash A binary string containing the hash that will be used
|
||||||
|
* as base for this icon. The hash must contain at least 6 bytes.
|
||||||
|
* @param int|float|double $size The size of the icon in pixels (the icon
|
||||||
|
* is quadratic).
|
||||||
|
*/
|
||||||
|
public function __construct($options = null)
|
||||||
|
{
|
||||||
|
$this->iconGenerator = IconGenerator::getDefaultGenerator();
|
||||||
|
|
||||||
|
if ($options !== null) {
|
||||||
|
$this->setOptions($options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->style === null) {
|
||||||
|
$this->style = new IdenticonStyle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an Identicon instance from a specified hash.
|
||||||
|
*
|
||||||
|
* @param string $hash A binary string containing the hash that will be used
|
||||||
|
* as base for this icon. The hash must contain at least 6 bytes.
|
||||||
|
* @param int $size The size of the icon in pixels (the icon is quadratic).
|
||||||
|
* @return \Jdenticon\Identicon
|
||||||
|
*/
|
||||||
|
public static function fromHash($hash, $size)
|
||||||
|
{
|
||||||
|
return new Identicon(array('hash' => $hash, 'size' => $size));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an Identicon instance from a specified value.
|
||||||
|
*
|
||||||
|
* @param mixed $value The value that will be used as base for this icon.
|
||||||
|
* The value will be converted to a UTF8 encoded string and then hashed
|
||||||
|
* using SHA1.
|
||||||
|
* @param int $size The size of the icon in pixels (the icon is quadratic).
|
||||||
|
* @return \Jdenticon\Identicon
|
||||||
|
*/
|
||||||
|
public static function fromValue($value, $size)
|
||||||
|
{
|
||||||
|
return new Identicon(array('value' => $value, 'size' => $size));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an associative array of all options of this identicon.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getOptions()
|
||||||
|
{
|
||||||
|
$options = array();
|
||||||
|
|
||||||
|
if ($this->valueSet) {
|
||||||
|
$options['value'] = $this->getValue();
|
||||||
|
} elseif ($this->hash !== null) {
|
||||||
|
$options['hash'] = $this->getHash();
|
||||||
|
}
|
||||||
|
|
||||||
|
$options['size'] = $this->getSize();
|
||||||
|
$options['style'] = $this->getStyle()->getOptions();
|
||||||
|
|
||||||
|
if ($this->enableImageMagick !== null) {
|
||||||
|
$options['enableImageMagick'] = $this->getEnableImageMagick();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->iconGenerator !== IconGenerator::getDefaultGenerator()) {
|
||||||
|
$options['iconGenerator'] = $this->getIconGenerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets options in this identicon by specifying an associative array of
|
||||||
|
* option values.
|
||||||
|
*
|
||||||
|
* @param array $options Options to set.
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setOptions(array $options)
|
||||||
|
{
|
||||||
|
foreach ($options as $key => $value) {
|
||||||
|
$this->__set($key, $value);
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __get($name)
|
||||||
|
{
|
||||||
|
switch (strtolower($name)) {
|
||||||
|
case 'size':
|
||||||
|
return $this->getSize();
|
||||||
|
case 'hash':
|
||||||
|
return $this->getHash();
|
||||||
|
case 'value':
|
||||||
|
return $this->getValue();
|
||||||
|
case 'style':
|
||||||
|
return $this->getStyle();
|
||||||
|
case 'icongenerator':
|
||||||
|
return $this->getIconGenerator();
|
||||||
|
case 'enableimagemagick':
|
||||||
|
return $this->getEnableImageMagick();
|
||||||
|
default:
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
"Unknown Identicon option '$name'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __set($name, $value)
|
||||||
|
{
|
||||||
|
switch (strtolower($name)) {
|
||||||
|
case 'size':
|
||||||
|
$this->setSize($value);
|
||||||
|
break;
|
||||||
|
case 'hash':
|
||||||
|
$this->setHash($value);
|
||||||
|
break;
|
||||||
|
case 'value':
|
||||||
|
$this->setValue($value);
|
||||||
|
break;
|
||||||
|
case 'style':
|
||||||
|
$this->setStyle($value);
|
||||||
|
break;
|
||||||
|
case 'icongenerator':
|
||||||
|
$this->setIconGenerator($value);
|
||||||
|
break;
|
||||||
|
case 'enableimagemagick':
|
||||||
|
$this->setEnableImageMagick($value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
"Unknown Identicon option '$name'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the size of the icon in pixels.
|
||||||
|
*/
|
||||||
|
public function getSize()
|
||||||
|
{
|
||||||
|
return $this->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the size of this icon in pixels.
|
||||||
|
*
|
||||||
|
* @param int|float|double $size The width and height of the icon.
|
||||||
|
*/
|
||||||
|
public function setSize($size)
|
||||||
|
{
|
||||||
|
if (!is_numeric($size) || $size < 1) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
"An invalid identicon size was specified. ".
|
||||||
|
"A numeric value >= 1 was expected. Specified value: $size.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->size = (int)$size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the size of the icon in pixels.
|
||||||
|
*/
|
||||||
|
public function getEnableImageMagick()
|
||||||
|
{
|
||||||
|
// Enable ImageMagick on PHP < 7. On PHP 7 the performance increase
|
||||||
|
// is not as obvious as on PHP 5. Since the ImageMagick renderer has a
|
||||||
|
// lot of quirks, we don't want to use it unless really needed.
|
||||||
|
if ($this->enableImageMagick === null) {
|
||||||
|
return PHP_MAJOR_VERSION < 7 && extension_loaded('imagick');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->enableImageMagick;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether ImageMagick should be used to generate PNG icons.
|
||||||
|
*
|
||||||
|
* @param bool $enable true to enable ImageMagick.
|
||||||
|
*/
|
||||||
|
public function setEnableImageMagick($enable)
|
||||||
|
{
|
||||||
|
if (!is_bool($enable)) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
"enableImageMagick can only assume boolean values. Specified value: $enable.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that the Imagick extension is installed
|
||||||
|
if ($enable && !extension_loaded('imagick')) {
|
||||||
|
throw new \Exception(
|
||||||
|
'Failed to enable ImageMagick. '.
|
||||||
|
'The Imagick PHP extension was not found on this system.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->enableImageMagick = $enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@see IconGenerator} used to generate icons.
|
||||||
|
*
|
||||||
|
* @return \Jdenticon\Rendering\IconGenerator
|
||||||
|
*/
|
||||||
|
public function getIconGenerator()
|
||||||
|
{
|
||||||
|
return $this->iconGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@see IconGenerator} used to generate icons.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Rendering\IconGenerator $iconGenerator Icon generator
|
||||||
|
* that will render the shapes of the identicon.
|
||||||
|
* @return \Jdenticon\Identicon
|
||||||
|
*/
|
||||||
|
public function setIconGenerator(IconGenerator $iconGenerator)
|
||||||
|
{
|
||||||
|
if ($iconGenerator === null) {
|
||||||
|
$iconGenerator = IconGenerator::getDefaultGenerator();
|
||||||
|
}
|
||||||
|
$this->iconGenerator = $iconGenerator;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets or sets the style of the icon.
|
||||||
|
*
|
||||||
|
* @return \Jdenticon\IdenticonStyle
|
||||||
|
*/
|
||||||
|
public function getStyle()
|
||||||
|
{
|
||||||
|
return $this->style;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets or sets the style of the icon.
|
||||||
|
*
|
||||||
|
* @param array|\Jdenticon\IdenticonStyle $style The new style of the icon.
|
||||||
|
* NULL will revert the identicon to use the default style.
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setStyle($style)
|
||||||
|
{
|
||||||
|
if ($style == null) {
|
||||||
|
$this->style = new IdenticonStyle();
|
||||||
|
} elseif ($style instanceof IdenticonStyle) {
|
||||||
|
$this->style = $style;
|
||||||
|
} elseif (is_array($style)) {
|
||||||
|
$this->style = new IdenticonStyle($style);
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
"Invalid indenticon style was specified. ".
|
||||||
|
"Allowed values are IdenticonStyle instances and associative ".
|
||||||
|
"arrays containing IdenticonStyle options.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a binary string containing the hash that is used as base for this
|
||||||
|
* icon.
|
||||||
|
*/
|
||||||
|
public function getHash()
|
||||||
|
{
|
||||||
|
return $this->hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a binary string containing the hash that is used as base for this
|
||||||
|
* icon. The string should contain at least 6 bytes.
|
||||||
|
*
|
||||||
|
* @param string $hash Binary string containing the hash.
|
||||||
|
*/
|
||||||
|
public function setHash($hash)
|
||||||
|
{
|
||||||
|
if (!is_string($hash)) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
'An invalid $hash was passed to Identicon. ' .
|
||||||
|
'A binary string was expected.');
|
||||||
|
}
|
||||||
|
if (strlen($hash) < 6) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
'An invalid $hash was passed to Identicon. ' .
|
||||||
|
'The hash was expected to contain at least 6 bytes.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->hash = $hash;
|
||||||
|
$this->value = null;
|
||||||
|
$this->valueSet = false;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a binary string containing the hash that is used as base for this
|
||||||
|
* icon.
|
||||||
|
*/
|
||||||
|
public function getValue()
|
||||||
|
{
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a value that will be used as base for this icon. The value will
|
||||||
|
* be converted to a string and then hashed using SHA1.
|
||||||
|
*
|
||||||
|
* @param mixed $value Value that will be hashed.
|
||||||
|
*/
|
||||||
|
public function setValue($value)
|
||||||
|
{
|
||||||
|
$this->hash = sha1("$value");
|
||||||
|
$this->value = $value;
|
||||||
|
$this->valueSet = true;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the bounds of the icon excluding its padding.
|
||||||
|
*
|
||||||
|
* @return \Jdenticon\Rendering\Rectangle
|
||||||
|
*/
|
||||||
|
public function getIconBounds()
|
||||||
|
{
|
||||||
|
// Round padding to nearest integer
|
||||||
|
$padding = (int)($this->style->getPadding() * $this->size + 0.5);
|
||||||
|
|
||||||
|
return new Rectangle(
|
||||||
|
$padding, $padding,
|
||||||
|
$this->size - $padding * 2,
|
||||||
|
$this->size - $padding * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getRenderer($imageFormat)
|
||||||
|
{
|
||||||
|
switch (strtolower($imageFormat)) {
|
||||||
|
case 'svg':
|
||||||
|
return new SvgRenderer($this->size, $this->size);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return $this->getEnableImageMagick() ?
|
||||||
|
new ImagickRenderer($this->size, $this->size) :
|
||||||
|
new InternalPngRenderer($this->size, $this->size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws this icon using a specified renderer.
|
||||||
|
*
|
||||||
|
* This method is only intended for usage with custom renderers. A custom
|
||||||
|
* renderer could as an example render an Identicon in a file format not
|
||||||
|
* natively supported by Jdenticon. To implement a new file format,
|
||||||
|
* implement {@see \Jdenticon\Rendering\RendererInterface}.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Rendering\RendererInterface $renderer The renderer used
|
||||||
|
* to render this icon.
|
||||||
|
* @param \Jdenticon\Rendering\Rectangle $rect The bounds of the rendered
|
||||||
|
* icon. No padding will be applied to the rectangle. If the parameter
|
||||||
|
* is omitted, the rectangle is calculated from the current icon
|
||||||
|
* size and padding.
|
||||||
|
*/
|
||||||
|
public function draw(
|
||||||
|
\Jdenticon\Rendering\RendererInterface $renderer,
|
||||||
|
\Jdenticon\Rendering\Rectangle $rect = null)
|
||||||
|
{
|
||||||
|
if ($rect === null) {
|
||||||
|
$rect = $this->getIconBounds();
|
||||||
|
}
|
||||||
|
$this->iconGenerator->generate(
|
||||||
|
$renderer, $rect, $this->style, $this->hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the icon directly to the page output.
|
||||||
|
*
|
||||||
|
* The method will set the 'Content-Type' HTTP header. You are recommended
|
||||||
|
* to set an appropriate 'Cache-Control' header before calling this method
|
||||||
|
* to ensure the icon is cached client side.
|
||||||
|
*
|
||||||
|
* @param string $imageFormat The image format of the output.
|
||||||
|
* Supported values are 'png' and 'svg'.
|
||||||
|
*/
|
||||||
|
public function displayImage($imageFormat = 'png')
|
||||||
|
{
|
||||||
|
$renderer = $this->getRenderer($imageFormat);
|
||||||
|
$this->draw($renderer, $this->getIconBounds());
|
||||||
|
$mimeType = $renderer->getMimeType();
|
||||||
|
$data = $renderer->getData();
|
||||||
|
header("Content-Type: $mimeType");
|
||||||
|
echo $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the icon to a binary string.
|
||||||
|
*
|
||||||
|
* @param string $imageFormat The image format of the output string.
|
||||||
|
* Supported values are 'png' and 'svg'.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getImageData($imageFormat = 'png')
|
||||||
|
{
|
||||||
|
$renderer = $this->getRenderer($imageFormat);
|
||||||
|
$this->draw($renderer, $this->getIconBounds());
|
||||||
|
return $renderer->getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the icon as a data URI. It is recommended to avoid using this
|
||||||
|
* method unless really necessary, since it will effectively disable client
|
||||||
|
* caching of generated icons, and will also cause the same icon to be
|
||||||
|
* rendered multiple times, when used multiple times on a single page.
|
||||||
|
*
|
||||||
|
* @param string $imageFormat The image format of the data URI.
|
||||||
|
* Supported values are 'png' and 'svg'.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getImageDataUri($imageFormat = 'png')
|
||||||
|
{
|
||||||
|
$renderer = $this->getRenderer($imageFormat);
|
||||||
|
$this->draw($renderer, $this->getIconBounds());
|
||||||
|
$mimeType = $renderer->getMimeType();
|
||||||
|
$base64 = base64_encode($renderer->getData());
|
||||||
|
return "data:$mimeType;base64,$base64";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
460
vendor/jdenticon/jdenticon/src/IdenticonStyle.php
vendored
Normal file
460
vendor/jdenticon/jdenticon/src/IdenticonStyle.php
vendored
Normal file
@ -0,0 +1,460 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon;
|
||||||
|
|
||||||
|
use Jdenticon\Color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the color style of an identicon.
|
||||||
|
*/
|
||||||
|
class IdenticonStyle
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Jdenticon\Color
|
||||||
|
*/
|
||||||
|
private $backgroundColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
private $padding;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
private $colorSaturation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
private $grayscaleSaturation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array(float)
|
||||||
|
*/
|
||||||
|
private $colorLightness;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array(float)
|
||||||
|
*/
|
||||||
|
private $grayscaleLightness;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array(integer)
|
||||||
|
*/
|
||||||
|
private $hues;
|
||||||
|
|
||||||
|
public function __construct(array $options = null)
|
||||||
|
{
|
||||||
|
$this->backgroundColor = self::getDefaultBackgroundColor();
|
||||||
|
$this->padding = self::getDefaultPadding();
|
||||||
|
$this->colorSaturation = self::getDefaultColorSaturation();
|
||||||
|
$this->grayscaleSaturation = self::getDefaultGrayscaleSaturation();
|
||||||
|
$this->colorLightness = self::getDefaultColorLightness();
|
||||||
|
$this->grayscaleLightness = self::getDefaultGrayscaleLightness();
|
||||||
|
|
||||||
|
if ($options !== null) {
|
||||||
|
$this->setOptions($options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an associative array of all options of this style.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getOptions()
|
||||||
|
{
|
||||||
|
$options = array();
|
||||||
|
|
||||||
|
$options['backgroundColor'] = $this->getBackgroundColor()->__toString();
|
||||||
|
$options['padding'] = $this->getPadding();
|
||||||
|
$options['colorSaturation'] = $this->getColorSaturation();
|
||||||
|
$options['grayscaleSaturation'] = $this->getGrayscaleSaturation();
|
||||||
|
$options['colorLightness'] = $this->getColorLightness();
|
||||||
|
$options['grayscaleLightness'] = $this->getGrayscaleLightness();
|
||||||
|
|
||||||
|
if ($this->hues !== null) {
|
||||||
|
$options['hues'] = $this->getHues();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets options in this style by specifying an associative array of option
|
||||||
|
* values.
|
||||||
|
*
|
||||||
|
* @param array $options Options to set.
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setOptions(array $options)
|
||||||
|
{
|
||||||
|
foreach ($options as $key => $value) {
|
||||||
|
$this->__set($key, $value);
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __get($name)
|
||||||
|
{
|
||||||
|
switch (strtolower($name)) {
|
||||||
|
case 'backgroundcolor':
|
||||||
|
return $this->getBackgroundColor();
|
||||||
|
case 'padding':
|
||||||
|
return $this->getPadding();
|
||||||
|
case 'colorsaturation':
|
||||||
|
return $this->getColorSaturation();
|
||||||
|
case 'grayscalesaturation':
|
||||||
|
return $this->getGrayscaleSaturation();
|
||||||
|
case 'colorlightness':
|
||||||
|
return $this->getColorLightness();
|
||||||
|
case 'grayscalelightness':
|
||||||
|
return $this->getGrayscaleLightness();
|
||||||
|
case 'hues':
|
||||||
|
return $this->getHues();
|
||||||
|
default:
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
"Unknown IdenticonStyle option '$name'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __set($name, $value)
|
||||||
|
{
|
||||||
|
switch (strtolower($name)) {
|
||||||
|
case 'backgroundcolor':
|
||||||
|
$this->setBackgroundColor($value);
|
||||||
|
break;
|
||||||
|
case 'padding':
|
||||||
|
$this->setPadding($value);
|
||||||
|
break;
|
||||||
|
case 'colorsaturation':
|
||||||
|
$this->setColorSaturation($value);
|
||||||
|
break;
|
||||||
|
case 'grayscalesaturation':
|
||||||
|
$this->setGrayscaleSaturation($value);
|
||||||
|
break;
|
||||||
|
case 'colorlightness':
|
||||||
|
$this->setColorLightness($value);
|
||||||
|
break;
|
||||||
|
case 'grayscalelightness':
|
||||||
|
$this->setGrayscaleLightness($value);
|
||||||
|
break;
|
||||||
|
case 'hues':
|
||||||
|
$this->setHues($value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
"Unknown IdenticonStyle option '$name'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes a hue to the first turn [0, 360).
|
||||||
|
*
|
||||||
|
* @param mixed $hue
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
private static function normalizeHue($hue)
|
||||||
|
{
|
||||||
|
if (!is_numeric($hue)) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
"'$hue' is not a valid hue.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$hue = $hue % 360;
|
||||||
|
if ($hue < 0) {
|
||||||
|
$hue += 360;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $hue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an array of allowed hues, or null if there are no restrictions.
|
||||||
|
*
|
||||||
|
* @return array(int)|null
|
||||||
|
*/
|
||||||
|
public function getHues()
|
||||||
|
{
|
||||||
|
return $this->hues;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the allowed hues of generated icons.
|
||||||
|
*
|
||||||
|
* @param array(integer)|integer|null $value A hue specified in degrees,
|
||||||
|
* or an array of hues specified in degrees. If set to null, the hue
|
||||||
|
* list is cleared.
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setHues($value)
|
||||||
|
{
|
||||||
|
$hues = array();
|
||||||
|
|
||||||
|
if ($value !== null) {
|
||||||
|
if (is_array($value)) {
|
||||||
|
foreach ($value as $hue) {
|
||||||
|
$hues[] = self::normalizeHue($hue);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$hues[] = self::normalizeHue($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->hues = empty($hues) ? null : $hues;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the padding of an icon in percents in the range [0.0, 0.4].
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function getPadding()
|
||||||
|
{
|
||||||
|
return $this->padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the padding of an icon in percents.
|
||||||
|
*
|
||||||
|
* @param float $value New padding in the range [0.0, 0.4].
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setPadding($value)
|
||||||
|
{
|
||||||
|
if (!is_numeric($value) || $value < 0 || $value > 0.4) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
"Padding '$value' out of range. ".
|
||||||
|
"Values in the range [0.0, 0.4] are allowed.");
|
||||||
|
}
|
||||||
|
$this->padding = (float)$value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the color of the identicon background.
|
||||||
|
*
|
||||||
|
* @return \Jdenticon\Color
|
||||||
|
*/
|
||||||
|
public function getBackgroundColor()
|
||||||
|
{
|
||||||
|
return $this->backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the color of the identicon background.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Color|string $value New background color.
|
||||||
|
* @return \Jdenticon\IdenticonStyle
|
||||||
|
*/
|
||||||
|
public function setBackgroundColor($value)
|
||||||
|
{
|
||||||
|
if ($value instanceof Color) {
|
||||||
|
$this->backgroundColor = $value;
|
||||||
|
} else {
|
||||||
|
$this->backgroundColor = Color::parse($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the saturation of the originally grayscale identicon shapes.
|
||||||
|
*
|
||||||
|
* @return float Saturation in the range [0.0, 1.0].
|
||||||
|
*/
|
||||||
|
public function getGrayscaleSaturation()
|
||||||
|
{
|
||||||
|
return $this->grayscaleSaturation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the saturation of the originally grayscale identicon shapes.
|
||||||
|
*
|
||||||
|
* @param $value float Saturation in the range [0.0, 1.0].
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setGrayscaleSaturation($value)
|
||||||
|
{
|
||||||
|
if (!is_numeric($value) ||
|
||||||
|
$value < 0 || $value > 1
|
||||||
|
) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
"The grayscale saturation was invalid. ".
|
||||||
|
"Only values in the range [0.0, 1.0] are allowed.");
|
||||||
|
}
|
||||||
|
$this->grayscaleSaturation = (float)$value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the saturation of the colored identicon shapes.
|
||||||
|
*
|
||||||
|
* @return float Saturation in the range [0.0, 1.0].
|
||||||
|
*/
|
||||||
|
public function getColorSaturation()
|
||||||
|
{
|
||||||
|
return $this->colorSaturation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the saturation of the colored identicon shapes.
|
||||||
|
*
|
||||||
|
* @param $value float Saturation in the range [0.0, 1.0].
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setColorSaturation($value)
|
||||||
|
{
|
||||||
|
if (!is_numeric($value) ||
|
||||||
|
$value < 0 || $value > 1
|
||||||
|
) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
"The color saturation was invalid. ".
|
||||||
|
"Only values in the range [0.0, 1.0] are allowed.");
|
||||||
|
}
|
||||||
|
$this->colorSaturation = (float)$value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value of the ColorLightness property.
|
||||||
|
*
|
||||||
|
* @return array(float, float)
|
||||||
|
*/
|
||||||
|
public function getColorLightness()
|
||||||
|
{
|
||||||
|
return $this->colorLightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of the ColorLightness property.
|
||||||
|
*
|
||||||
|
* @param $value array(float, float) Lightness range.
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setColorLightness($value)
|
||||||
|
{
|
||||||
|
if (!is_array($value) ||
|
||||||
|
!array_key_exists(0, $value) ||
|
||||||
|
!array_key_exists(1, $value) ||
|
||||||
|
!is_numeric($value[0]) ||
|
||||||
|
!is_numeric($value[1]) ||
|
||||||
|
$value[0] < 0 || $value[0] > 1 ||
|
||||||
|
$value[1] < 0 || $value[1] > 1
|
||||||
|
) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
"The value passed to setColorLightness was invalid. ".
|
||||||
|
"Please check the documentation.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->colorLightness = array((float)$value[0], (float)$value[1]);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value of the GrayscaleLightness property.
|
||||||
|
*
|
||||||
|
* @return array(float, float)
|
||||||
|
*/
|
||||||
|
public function getGrayscaleLightness()
|
||||||
|
{
|
||||||
|
return $this->grayscaleLightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of the GrayscaleLightness property.
|
||||||
|
*
|
||||||
|
* @param $value array(float, float) Lightness range.
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setGrayscaleLightness($value)
|
||||||
|
{
|
||||||
|
if (!is_array($value) ||
|
||||||
|
!array_key_exists(0, $value) ||
|
||||||
|
!array_key_exists(1, $value) ||
|
||||||
|
!is_numeric($value[0]) ||
|
||||||
|
!is_numeric($value[1]) ||
|
||||||
|
$value[0] < 0 || $value[0] > 1 ||
|
||||||
|
$value[1] < 0 || $value[1] > 1
|
||||||
|
) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
"The value passed to setGrayscaleLightness was invalid. ".
|
||||||
|
"Please check the documentation.");
|
||||||
|
}
|
||||||
|
$this->grayscaleLightness = array((float)$value[0], (float)$value[1]);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the default value of the BackgroundColor property. Resolves to transparent.
|
||||||
|
*
|
||||||
|
* @return \Jdenticon\Color
|
||||||
|
*/
|
||||||
|
public static function getDefaultBackgroundColor()
|
||||||
|
{
|
||||||
|
return Color::fromRgb(255, 255, 255, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the default value of the Padding property. Resolves to 0.08.
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public static function getDefaultPadding()
|
||||||
|
{
|
||||||
|
return 0.08;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the default value of the ColorSaturation property. Resolves to 0.5.
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public static function getDefaultColorSaturation()
|
||||||
|
{
|
||||||
|
return 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the default value of the GrayscaleSaturation property. Resolves to 0.
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public static function getDefaultGrayscaleSaturation()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the default value of the ColorLightness property. Resolves to [0.4, 0.8].
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getDefaultColorLightness()
|
||||||
|
{
|
||||||
|
return array(0.4, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the default value of the GrayscaleLightness property. Resolves to [0.3, 0.9].
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getDefaultGrayscaleLightness()
|
||||||
|
{
|
||||||
|
return array(0.3, 0.9);
|
||||||
|
}
|
||||||
|
}
|
209
vendor/jdenticon/jdenticon/src/Rendering/AbstractRenderer.php
vendored
Normal file
209
vendor/jdenticon/jdenticon/src/Rendering/AbstractRenderer.php
vendored
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Rendering;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for rendering shapes in an identicon. Implement this class to e.g.
|
||||||
|
* support a new file format that is not natively supported by Jdenticon. To
|
||||||
|
* invoke the new Renderer, pass the renderer as an argument to the
|
||||||
|
* {@see \Jdenticon\Identicon::Draw} method.
|
||||||
|
*/
|
||||||
|
abstract class AbstractRenderer implements RendererInterface
|
||||||
|
{
|
||||||
|
private $transform;
|
||||||
|
protected $backgroundColor;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->transform = Transform::getEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current transform that will be applied on all coordinates before
|
||||||
|
* being rendered to the target image.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Rendering\Transform $transform The transform to set.
|
||||||
|
* If NULL is specified any existing transform is removed.
|
||||||
|
*/
|
||||||
|
public function setTransform(\Jdenticon\Rendering\Transform $transform)
|
||||||
|
{
|
||||||
|
$this->transform = $transform === null ?
|
||||||
|
Transform::getEmpty() : $transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current transform that will be applied on all coordinates before
|
||||||
|
* being rendered to the target image.
|
||||||
|
*
|
||||||
|
* @return \Jdenticon\Rendering\Transform
|
||||||
|
*/
|
||||||
|
public function getTransform()
|
||||||
|
{
|
||||||
|
return $this->transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a polygon without translating its coordinates.
|
||||||
|
*
|
||||||
|
* @param array $points An array of the points that the polygon consists of.
|
||||||
|
*/
|
||||||
|
abstract protected function addPolygonNoTransform($points);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a circle without translating its coordinates.
|
||||||
|
*
|
||||||
|
* @param float $x The x-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $y The y-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $size The size of the bounding rectangle.
|
||||||
|
* @param bool $counterClockwise If true the circle will be drawn
|
||||||
|
* counter clockwise.
|
||||||
|
*/
|
||||||
|
abstract protected function addCircleNoTransform($x, $y, $size, $counterClockwise);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the background color of the image.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Color $color The image background color.
|
||||||
|
*/
|
||||||
|
public function setBackgroundColor(\Jdenticon\Color $color)
|
||||||
|
{
|
||||||
|
$this->backgroundColor = $color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the background color of the image.
|
||||||
|
*
|
||||||
|
* @return \Jdenticon\Color
|
||||||
|
*/
|
||||||
|
public function getBackgroundColor()
|
||||||
|
{
|
||||||
|
return $this->backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addPolygonCore(array $points, $invert)
|
||||||
|
{
|
||||||
|
$transformedPoints = array();
|
||||||
|
foreach ($points as $point) {
|
||||||
|
$transformedPoints[] =
|
||||||
|
$this->transform->transformPoint($point->x, $point->y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($invert) {
|
||||||
|
$transformedPoints = array_reverse($transformedPoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
//var_dump($transformedPoints);
|
||||||
|
|
||||||
|
$this->addPolygonNoTransform($transformedPoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a rectangle to the image.
|
||||||
|
*
|
||||||
|
* @param float $x The x-coordinate of the rectangle upper-left corner.
|
||||||
|
* @param float $y The y-coordinate of the rectangle upper-left corner.
|
||||||
|
* @param float $width The width of the rectangle.
|
||||||
|
* @param float $height The height of the rectangle.
|
||||||
|
* @param bool $invert If true the area of the rectangle will be removed
|
||||||
|
* from the filled area.
|
||||||
|
*/
|
||||||
|
public function addRectangle($x, $y, $width, $height, $invert = false)
|
||||||
|
{
|
||||||
|
$this->addPolygonCore(array(
|
||||||
|
new Point($x, $y),
|
||||||
|
new Point($x + $width, $y),
|
||||||
|
new Point($x + $width, $y + $height),
|
||||||
|
new Point($x, $y + $height),
|
||||||
|
), $invert);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a circle to the image.
|
||||||
|
*
|
||||||
|
* @param float $x The x-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $y The y-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $size The size of the bounding rectangle.
|
||||||
|
* @param bool $invert If true the area of the circle will be removed
|
||||||
|
* from the filled area.
|
||||||
|
*/
|
||||||
|
public function addCircle($x, $y, $size, $invert = false)
|
||||||
|
{
|
||||||
|
$northWest = $this->transform->transformPoint($x, $y, $size, $size);
|
||||||
|
$this->addCircleNoTransform($northWest->x, $northWest->y, $size, $invert);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a polygon to the image.
|
||||||
|
*
|
||||||
|
* @param array $points Array of points that the polygon consists of.
|
||||||
|
* @param bool $invert If true the area of the polygon will be removed
|
||||||
|
* from the filled area.
|
||||||
|
*/
|
||||||
|
public function addPolygon($points, $invert = false)
|
||||||
|
{
|
||||||
|
$this->addPolygonCore($points, $invert);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a triangle to the image.
|
||||||
|
*
|
||||||
|
* @param float $x The x-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $y The y-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $width The width of the bounding rectangle.
|
||||||
|
* @param float $height The height of the bounding rectangle.
|
||||||
|
* @param float $direction The direction of the 90 degree corner of the
|
||||||
|
* triangle.
|
||||||
|
* @param bool $invert If true the area of the triangle will be removed
|
||||||
|
* from the filled area.
|
||||||
|
*/
|
||||||
|
public function addTriangle($x, $y, $width, $height, $direction, $invert = false)
|
||||||
|
{
|
||||||
|
$points = array(
|
||||||
|
new Point($x + $width, $y),
|
||||||
|
new Point($x + $width, $y + $height),
|
||||||
|
new Point($x, $y + $height),
|
||||||
|
new Point($x, $y)
|
||||||
|
);
|
||||||
|
|
||||||
|
array_splice($points, $direction, 1);
|
||||||
|
|
||||||
|
$this->addPolygonCore($points, $invert);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a rhombus to the image.
|
||||||
|
*
|
||||||
|
* @param float $x The x-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $y The y-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $width The width of the bounding rectangle.
|
||||||
|
* @param float $height The height of the bounding rectangle.
|
||||||
|
* @param bool $invert If true the area of the rhombus will be removed
|
||||||
|
* from the filled area.
|
||||||
|
*/
|
||||||
|
public function addRhombus($x, $y, $width, $height, $invert = false)
|
||||||
|
{
|
||||||
|
$this->addPolygonCore(array(
|
||||||
|
new Point($x + $width / 2, $y),
|
||||||
|
new Point($x + $width, $y + $height / 2),
|
||||||
|
new Point($x + $width / 2, $y + $height),
|
||||||
|
new Point($x, $y + $height / 2),
|
||||||
|
), $invert);
|
||||||
|
}
|
||||||
|
}
|
84
vendor/jdenticon/jdenticon/src/Rendering/ColorTheme.php
vendored
Normal file
84
vendor/jdenticon/jdenticon/src/Rendering/ColorTheme.php
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Rendering;
|
||||||
|
|
||||||
|
use Jdenticon\Color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the colors to be used in an identicon.
|
||||||
|
*/
|
||||||
|
class ColorTheme
|
||||||
|
{
|
||||||
|
private $darkGray;
|
||||||
|
private $midColor;
|
||||||
|
private $lightGray;
|
||||||
|
private $lightColor;
|
||||||
|
private $darkColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new ColorTheme.
|
||||||
|
*
|
||||||
|
* @param float $hue The hue of the colored shapes in the range [0, 1].
|
||||||
|
* @param \Jdenticon\IdenticonStyle $style The style that specifies the
|
||||||
|
* lightness and saturation of the icon.
|
||||||
|
*/
|
||||||
|
public function __construct($hue, \Jdenticon\IdenticonStyle $style)
|
||||||
|
{
|
||||||
|
$grayscaleLightness = $style->getGrayscaleLightness();
|
||||||
|
$colorLightness = $style->getColorLightness();
|
||||||
|
$hues = $style->getHues();
|
||||||
|
|
||||||
|
if ($hues !== null) {
|
||||||
|
// $hue is in the range [0, 1]
|
||||||
|
// Multiply with 0.999 to change the range to [0, 1)
|
||||||
|
$hueIndex = (int)($hue * 0.999 * count($hues));
|
||||||
|
$hue = (float)$hues[$hueIndex] / 360;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->darkGray = Color::fromHslCompensated(
|
||||||
|
$hue, $style->getGrayscaleSaturation(), $grayscaleLightness[0]);
|
||||||
|
$this->midColor = Color::fromHslCompensated(
|
||||||
|
$hue, $style->getColorSaturation(), ($colorLightness[0] + $colorLightness[1]) / 2);
|
||||||
|
$this->lightGray = Color::fromHslCompensated(
|
||||||
|
$hue, $style->getGrayscaleSaturation(), $grayscaleLightness[1]);
|
||||||
|
$this->lightColor = Color::fromHslCompensated(
|
||||||
|
$hue, $style->getColorSaturation(), $colorLightness[1]);
|
||||||
|
$this->darkColor = Color::fromHslCompensated(
|
||||||
|
$hue, $style->getColorSaturation(), $colorLightness[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a color from this color theme by index.
|
||||||
|
*
|
||||||
|
* @param int $index Color index in the range [0, getCount()).
|
||||||
|
* @return Jdenticon\Color
|
||||||
|
*/
|
||||||
|
public function getByIndex($index)
|
||||||
|
{
|
||||||
|
if ($index === 0) return $this->darkGray;
|
||||||
|
if ($index === 1) return $this->midColor;
|
||||||
|
if ($index === 2) return $this->lightGray;
|
||||||
|
if ($index === 3) return $this->lightColor;
|
||||||
|
if ($index === 4) return $this->darkColor;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of available colors in this theme.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getCount()
|
||||||
|
{
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
}
|
290
vendor/jdenticon/jdenticon/src/Rendering/IconGenerator.php
vendored
Normal file
290
vendor/jdenticon/jdenticon/src/Rendering/IconGenerator.php
vendored
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Rendering;
|
||||||
|
|
||||||
|
use Jdenticon\Shapes\Shape;
|
||||||
|
use Jdenticon\Shapes\ShapeCategory;
|
||||||
|
use Jdenticon\Shapes\ShapeDefinitions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates identicons and render them to a
|
||||||
|
* {@link \Jdenticon\Rendering\RendererInterface}. This class dictates what
|
||||||
|
* shapes will be used in the generated icons. If you intend to customize the
|
||||||
|
* appearance of generated icons you probably wants to either subclass or modify
|
||||||
|
* this class.
|
||||||
|
*/
|
||||||
|
class IconGenerator
|
||||||
|
{
|
||||||
|
private $defaultShapes;
|
||||||
|
private static $instance;
|
||||||
|
|
||||||
|
protected function __construct()
|
||||||
|
{
|
||||||
|
$this->defaultShapes = array(
|
||||||
|
// Sides
|
||||||
|
new ShapeCategory(
|
||||||
|
/*$colorIndex=*/ 8,
|
||||||
|
/*$shapes=*/ ShapeDefinitions::getOuterShapes(),
|
||||||
|
/*$shapeIndex=*/ 2,
|
||||||
|
/*$rotationIndex=*/ 3,
|
||||||
|
/*$positions=*/ array(1,0, 2,0, 2,3, 1,3, 0,1, 3,1, 3,2, 0,2)
|
||||||
|
),
|
||||||
|
|
||||||
|
// Corners
|
||||||
|
new ShapeCategory(
|
||||||
|
/*$colorIndex=*/ 9,
|
||||||
|
/*$shapes=*/ ShapeDefinitions::getOuterShapes(),
|
||||||
|
/*$shapeIndex=*/ 4,
|
||||||
|
/*$rotationIndex=*/ 5,
|
||||||
|
/*$positions=*/ array(0,0, 3,0, 3,3, 0,3)
|
||||||
|
),
|
||||||
|
|
||||||
|
// Center
|
||||||
|
new ShapeCategory(
|
||||||
|
/*$colorIndex=*/ 10,
|
||||||
|
/*$shapes=*/ ShapeDefinitions::getCenterShapes(),
|
||||||
|
/*$shapeIndex=*/ 1,
|
||||||
|
/*$rotationIndex=*/ null,
|
||||||
|
/*$positions=*/ array(1,1, 2,1, 2,2, 1,2)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getDefaultGenerator()
|
||||||
|
{
|
||||||
|
if (self::$instance === null) {
|
||||||
|
self::$instance = new IconGenerator();
|
||||||
|
}
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of cells in each direction of the icons generated by
|
||||||
|
* this IconGenerator.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getCellCount()
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the hue to be used in an icon for the specified hash.
|
||||||
|
*
|
||||||
|
* @return float Hue in the range [0, 1].
|
||||||
|
*/
|
||||||
|
protected static function getHue($hash)
|
||||||
|
{
|
||||||
|
$value = hexdec(substr($hash, -7));
|
||||||
|
return $value / 0xfffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether $newValue is duplicated in $source if all values
|
||||||
|
* in $duplicateValues are determined to be equal.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private static function isDuplicate(
|
||||||
|
array $source, $newValue,
|
||||||
|
array $duplicateValues)
|
||||||
|
{
|
||||||
|
if (in_array($newValue, $duplicateValues, true)) {
|
||||||
|
foreach ($duplicateValues as $value) {
|
||||||
|
if (in_array($value, $source, true)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the specified octet from a byte array.
|
||||||
|
*
|
||||||
|
* @param string $hash The hexstring from which the octet will be retrieved.
|
||||||
|
* @param int $index The zero-based index of the octet to be returned.
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
protected static function getOctet($hash, $index)
|
||||||
|
{
|
||||||
|
return hexdec($hash[$index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an array of the shape categories to be rendered in icons generated
|
||||||
|
* by this IconGenerator.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getCategories()
|
||||||
|
{
|
||||||
|
return $this->defaultShapes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an enumeration of individual shapes to be rendered in an icon for a
|
||||||
|
* specific hash.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Rendering\ColorTheme $colorTheme A color theme
|
||||||
|
* specifying the colors to be used in the icon.
|
||||||
|
* @param string $hash The hash for which the shapes will be returned.
|
||||||
|
* @return array(Jdenticon\Shapes\Shape)
|
||||||
|
*/
|
||||||
|
protected function getShapes($colorTheme, $hash)
|
||||||
|
{
|
||||||
|
$usedColorThemeIndexes = array();
|
||||||
|
$categories = self::getCategories();
|
||||||
|
$shapes = array();
|
||||||
|
$colorCount = $colorTheme->getCount();
|
||||||
|
|
||||||
|
foreach ($categories as $category) {
|
||||||
|
$colorThemeIndex =
|
||||||
|
self::getOctet($hash, $category->colorIndex) % $colorCount;
|
||||||
|
|
||||||
|
if (self::isDuplicate(
|
||||||
|
// Disallow dark gray and dark color combo
|
||||||
|
$usedColorThemeIndexes, $colorThemeIndex, array(0, 4)) ||
|
||||||
|
self::isDuplicate(
|
||||||
|
// Disallow light gray and light color combo
|
||||||
|
$usedColorThemeIndexes, $colorThemeIndex, array(2, 3))
|
||||||
|
) {
|
||||||
|
$colorThemeIndex = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$usedColorThemeIndexes[] = $colorThemeIndex;
|
||||||
|
|
||||||
|
$startRotationIndex = $category->rotationIndex === null ?
|
||||||
|
0 : self::getOctet($hash, $category->rotationIndex);
|
||||||
|
$shapeIndex =
|
||||||
|
self::getOctet($hash, $category->shapeIndex) %
|
||||||
|
count($category->shapes);
|
||||||
|
$shape = $category->shapes[$shapeIndex];
|
||||||
|
|
||||||
|
$shapes[] = new Shape(
|
||||||
|
/*$definition=*/ $shape,
|
||||||
|
/*$color=*/ $colorTheme->getByIndex($colorThemeIndex),
|
||||||
|
/*$positions=*/ $category->positions,
|
||||||
|
/*$startRotationIndex=*/ $startRotationIndex
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $shapes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a quadratic copy of the specified
|
||||||
|
* {@link \Jdenticon\Rendering\Rectangle} with a multiple of the cell count
|
||||||
|
* as size.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Rendering\Rectangle $rect The rectangle to be
|
||||||
|
* normalized.
|
||||||
|
*/
|
||||||
|
protected function normalizeRectangle(\Jdenticon\Rendering\Rectangle $rect)
|
||||||
|
{
|
||||||
|
$size = (int)min($rect->width, $rect->height);
|
||||||
|
|
||||||
|
// Make size a multiple of the cell count
|
||||||
|
$size -= $size % $this->getCellCount();
|
||||||
|
|
||||||
|
return new Rectangle(
|
||||||
|
(int)($rect->x + ($rect->width - $size) / 2),
|
||||||
|
(int)($rect->y + ($rect->height - $size) / 2),
|
||||||
|
$size,
|
||||||
|
$size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the background of an icon.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Rendering\RendererInterface $renderer The renderer to
|
||||||
|
* be used for rendering the icon on the target surface.
|
||||||
|
* @param \Jdenticon\Rendering\Rectangle $rect The outer bounds of the icon.
|
||||||
|
* @param \Jdenticon\IdenticonStyle $style The style of the icon.
|
||||||
|
* @param \Jdenticon\Rendering\ColorTheme $colorTheme A color theme
|
||||||
|
* specifying the colors to be used in the icon.
|
||||||
|
* @param string $hash The hash to be used as basis for the generated icon.
|
||||||
|
*/
|
||||||
|
protected function renderBackground(
|
||||||
|
\Jdenticon\Rendering\RendererInterface $renderer,
|
||||||
|
\Jdenticon\Rendering\Rectangle $rect,
|
||||||
|
\Jdenticon\IdenticonStyle $style,
|
||||||
|
\Jdenticon\Rendering\ColorTheme $colorTheme,
|
||||||
|
$hash)
|
||||||
|
{
|
||||||
|
$renderer->setBackgroundColor($style->getBackgroundColor());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the foreground of an icon.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Rendering\RendererInterface $renderer The renderer to
|
||||||
|
* be used for rendering the icon on the target surface.
|
||||||
|
* @param \Jdenticon\Rendering\Rectangle $rect The outer bounds of the icon.
|
||||||
|
* @param \Jdenticon\IdenticonStyle $style The style of the icon.
|
||||||
|
* @param \Jdenticon\Rendering\ColorTheme $colorTheme A color theme
|
||||||
|
* specifying the colors to be used in the icon.
|
||||||
|
* @param string $hash The hash to be used as basis for the generated icon.
|
||||||
|
*/
|
||||||
|
protected function renderForeground(
|
||||||
|
\Jdenticon\Rendering\RendererInterface $renderer,
|
||||||
|
\Jdenticon\Rendering\Rectangle $rect,
|
||||||
|
\Jdenticon\IdenticonStyle $style,
|
||||||
|
\Jdenticon\Rendering\ColorTheme $colorTheme,
|
||||||
|
$hash)
|
||||||
|
{
|
||||||
|
// Ensure rect is quadratic and a multiple of the cell count
|
||||||
|
$normalizedRect = $this->normalizeRectangle($rect);
|
||||||
|
$cellSize = $normalizedRect->width / $this->getCellCount();
|
||||||
|
|
||||||
|
foreach ($this->getShapes($colorTheme, $hash) as $shape) {
|
||||||
|
$rotation = $shape->startRotationIndex;
|
||||||
|
|
||||||
|
$renderer->beginShape($shape->color);
|
||||||
|
|
||||||
|
$positionCount = count($shape->positions);
|
||||||
|
for ($i = 0; $i + 1 < $positionCount; $i += 2) {
|
||||||
|
$renderer->setTransform(new Transform(
|
||||||
|
$normalizedRect->x + $shape->positions[$i + 0] * $cellSize,
|
||||||
|
$normalizedRect->y + $shape->positions[$i + 1] * $cellSize,
|
||||||
|
$cellSize, $rotation++ % 4));
|
||||||
|
|
||||||
|
$shape->definition->__invoke($renderer, $cellSize, $i / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
$renderer->endShape();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates an identicon for the specified hash.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Rendering\RendererInterface $renderer The renderer to
|
||||||
|
* be used for rendering the icon on the target surface.
|
||||||
|
* @param \Jdenticon\Rendering\Rectangle $rect The outer bounds of the icon.
|
||||||
|
* @param \Jdenticon\IdenticonStyle $style The style of the icon.
|
||||||
|
* @param string $hash The hash to be used as basis for the generated icon.
|
||||||
|
*/
|
||||||
|
public function generate(
|
||||||
|
\Jdenticon\Rendering\RendererInterface $renderer,
|
||||||
|
\Jdenticon\Rendering\Rectangle $rect,
|
||||||
|
\Jdenticon\IdenticonStyle $style,
|
||||||
|
$hash)
|
||||||
|
{
|
||||||
|
$hue = self::getHue($hash);
|
||||||
|
$colorTheme = new ColorTheme($hue, $style);
|
||||||
|
|
||||||
|
$this->renderBackground($renderer, $rect, $style, $colorTheme, $hash);
|
||||||
|
$this->renderForeground($renderer, $rect, $style, $colorTheme, $hash);
|
||||||
|
}
|
||||||
|
}
|
296
vendor/jdenticon/jdenticon/src/Rendering/ImagickRenderer.php
vendored
Normal file
296
vendor/jdenticon/jdenticon/src/Rendering/ImagickRenderer.php
vendored
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
<?php
|
||||||
|
namespace Jdenticon\Rendering;
|
||||||
|
|
||||||
|
class ImagickRendererLine
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Creates a new line from a vector.
|
||||||
|
*
|
||||||
|
* @param float $x0 Vector start x coordinate.
|
||||||
|
* @param float $y0 Vector start y coordinate.
|
||||||
|
* @param float $x1 Vector end x coordinate.
|
||||||
|
* @param float $y1 Vector end y coordinate.
|
||||||
|
*/
|
||||||
|
public static function fromVector($x0, $y0, $x1, $y1)
|
||||||
|
{
|
||||||
|
$line = new ImagickRendererLine();
|
||||||
|
|
||||||
|
$line->Px = $x0;
|
||||||
|
$line->Py = $y0;
|
||||||
|
|
||||||
|
$line->rx = $x1 - $x0;
|
||||||
|
$line->ry = $y1 - $y0;
|
||||||
|
|
||||||
|
return $line;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the line to the right relative the direction vector.
|
||||||
|
*
|
||||||
|
* @param float $distance The number of pixels to move the line.
|
||||||
|
*/
|
||||||
|
public function moveRight($distance)
|
||||||
|
{
|
||||||
|
// Ortogonal direction vector
|
||||||
|
$rx = -$this->ry;
|
||||||
|
$ry = $this->rx;
|
||||||
|
|
||||||
|
$multiplier = $distance / sqrt($rx * $rx + $ry * $ry);
|
||||||
|
|
||||||
|
$this->Px += $rx * $multiplier;
|
||||||
|
$this->Py += $ry * $multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the point at which two lines intersect.
|
||||||
|
*
|
||||||
|
* @return Point|null
|
||||||
|
*/
|
||||||
|
public static function intersection(
|
||||||
|
ImagickRendererLine $l1,
|
||||||
|
ImagickRendererLine $l2
|
||||||
|
) {
|
||||||
|
$rs = $l1->rx * $l2->ry - $l1->ry * $l2->rx;
|
||||||
|
|
||||||
|
if ($rs == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$u = (($l2->Px - $l1->Px) * $l1->ry - ($l2->Py - $l1->Py) * $l1->rx) / $rs;
|
||||||
|
|
||||||
|
return new Point(
|
||||||
|
$l2->Px + $u * $l2->rx,
|
||||||
|
$l2->Py + $u * $l2->ry
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* X coordiate of a point on the line.
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
public $Px;
|
||||||
|
/**
|
||||||
|
* Y coordiate of a point on the line.
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
public $Py;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* X component of the direction vector.
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
public $rx;
|
||||||
|
/**
|
||||||
|
* Y component of the direction vector.
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
public $ry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders icons as PNG using ImageMagick.
|
||||||
|
*
|
||||||
|
* Unfortunately the ImageMagick vector renderer has a lot of quirks that
|
||||||
|
* we need to accomodate. The most obvious is that the renderer always render
|
||||||
|
* all polygons 1/2 pixel too large. This behavior is documented here:
|
||||||
|
* http://www.imagemagick.org/Usage/draw/#bounds
|
||||||
|
*
|
||||||
|
* To prevent this we shrink all polygons with 1/2 pixels before passing them
|
||||||
|
* to ImageMagick.
|
||||||
|
*
|
||||||
|
* Another quirk is that if the polygon including the 1/2 pixel invisible border
|
||||||
|
* align perfectly to the pixel grid, white pixels will appear near edge
|
||||||
|
* intersections. Paths containing arcs will sometimes appear with horizontal
|
||||||
|
* lines drawn to the right side of the image.
|
||||||
|
*
|
||||||
|
* To prevent this (in most cases) we add 0.00013 to all coordinates.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ImagickRenderer extends AbstractRenderer
|
||||||
|
{
|
||||||
|
private $draw;
|
||||||
|
private $polygon;
|
||||||
|
private $width;
|
||||||
|
private $height;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constant is added to all coordinates to avoid white pixels
|
||||||
|
* that sometimes appear near edge intersections when a polygon including
|
||||||
|
* its 1/2 invisible border is perfectly aligned to the pixel grid.
|
||||||
|
*/
|
||||||
|
const PREVENT_WHITE_PIXELS_OFFSET = -0.00013;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance of the class ImagickRenderer.
|
||||||
|
*
|
||||||
|
* @param int $width The width of the icon in pixels.
|
||||||
|
* @param int $height The height of the icon in pixels.
|
||||||
|
*/
|
||||||
|
public function __construct($width, $height)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->draw = new \ImagickDraw();
|
||||||
|
$this->draw->setStrokeWidth(1);
|
||||||
|
|
||||||
|
$this->width = $width;
|
||||||
|
$this->height = $height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the MIME type of the renderer output.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getMimeType()
|
||||||
|
{
|
||||||
|
return 'image/png';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a circle without translating its coordinates.
|
||||||
|
*
|
||||||
|
* @param float $x The x-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $y The y-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $size The size of the bounding rectangle.
|
||||||
|
* @param bool $counterClockwise If true the circle will be drawn
|
||||||
|
* counter clockwise.
|
||||||
|
*/
|
||||||
|
protected function addCircleNoTransform($x, $y, $size, $counterClockwise)
|
||||||
|
{
|
||||||
|
if ($counterClockwise) {
|
||||||
|
$x -= $size + 0.5;
|
||||||
|
$y -= 1;
|
||||||
|
} else {
|
||||||
|
$size -= 1;
|
||||||
|
$y -= 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
$radius = $size / 2;
|
||||||
|
$this->draw->pathMoveToAbsolute(
|
||||||
|
$x + $size + self::PREVENT_WHITE_PIXELS_OFFSET,
|
||||||
|
$y + $radius + self::PREVENT_WHITE_PIXELS_OFFSET);
|
||||||
|
$this->draw->pathEllipticArcRelative($radius, $radius,
|
||||||
|
M_PI * 2, true, $counterClockwise, 0, 1);
|
||||||
|
$this->draw->pathClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a polygon without translating its coordinates.
|
||||||
|
*
|
||||||
|
* @param array $points An array of the points that the polygon consists of.
|
||||||
|
*/
|
||||||
|
protected function addPolygonNoTransform($points)
|
||||||
|
{
|
||||||
|
$firstPoint = $points[0];
|
||||||
|
$lastPoint = end($points);
|
||||||
|
|
||||||
|
// Ensure polygon is closed
|
||||||
|
if ($firstPoint->x != $lastPoint->x ||
|
||||||
|
$firstPoint->y != $lastPoint->y
|
||||||
|
) {
|
||||||
|
$points[] = $firstPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine if polygon is an outer ring
|
||||||
|
// (source: https://stackoverflow.com/a/1165943)
|
||||||
|
$sum = 0;
|
||||||
|
$previousPoint = null;
|
||||||
|
|
||||||
|
foreach ($points as $point) {
|
||||||
|
if ($previousPoint !== null) {
|
||||||
|
$sum += ($point->x - $previousPoint->x) * ($point->y + $previousPoint->y);
|
||||||
|
}
|
||||||
|
$previousPoint = $point;
|
||||||
|
}
|
||||||
|
|
||||||
|
$isOuterRing = $sum < 0;
|
||||||
|
|
||||||
|
// ImageMagick draws all polygons 1 pixel too large. To prevent this,
|
||||||
|
// shrink polygons by 1 pixel.
|
||||||
|
$lines = array();
|
||||||
|
$previousPoint = null;
|
||||||
|
|
||||||
|
// Transform all edges to lines.
|
||||||
|
foreach ($points as $point) {
|
||||||
|
if ($previousPoint !== null) {
|
||||||
|
$lines[] = $line = ImagickRendererLine::fromVector(
|
||||||
|
$previousPoint->x, $previousPoint->y,
|
||||||
|
$point->x, $point->y
|
||||||
|
);
|
||||||
|
|
||||||
|
// ImageMagick draws a 1px border along the outer ring. To
|
||||||
|
// prevent the border overlaps inner rings too close to the
|
||||||
|
// outer ring, only inflate inner rings by 1/4 pixel.
|
||||||
|
$line->moveRight($isOuterRing ? 0.5 : 0.25);
|
||||||
|
}
|
||||||
|
$previousPoint = $point;
|
||||||
|
}
|
||||||
|
|
||||||
|
$first = true;
|
||||||
|
$previousLine = end($lines);
|
||||||
|
|
||||||
|
// Reconstruct point array from line intersections and draw the polygon
|
||||||
|
foreach ($lines as $line) {
|
||||||
|
$points[] = $point = ImagickRendererLine::intersection($previousLine, $line);
|
||||||
|
|
||||||
|
// Subtract 1/2 pixel to align the shapes to the pixel grid.
|
||||||
|
if ($first) {
|
||||||
|
$this->draw->pathMoveToAbsolute(
|
||||||
|
$point->x - 0.5 + self::PREVENT_WHITE_PIXELS_OFFSET,
|
||||||
|
$point->y - 0.5 + self::PREVENT_WHITE_PIXELS_OFFSET);
|
||||||
|
|
||||||
|
$first = false;
|
||||||
|
} else {
|
||||||
|
$this->draw->pathLineToAbsolute(
|
||||||
|
$point->x - 0.5 + self::PREVENT_WHITE_PIXELS_OFFSET,
|
||||||
|
$point->y - 0.5 + self::PREVENT_WHITE_PIXELS_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
$previousLine = $line;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->draw->pathClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins a new shape. The shape should be ended with a call to endShape.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Color $color The color of the shape.
|
||||||
|
*/
|
||||||
|
public function beginShape(\Jdenticon\Color $color)
|
||||||
|
{
|
||||||
|
$this->draw->setFillColor($color->__toString());
|
||||||
|
$this->draw->pathStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends the currently drawn shape.
|
||||||
|
*/
|
||||||
|
public function endShape()
|
||||||
|
{
|
||||||
|
$this->draw->pathFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders this image as a PNG data stream.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getData()
|
||||||
|
{
|
||||||
|
$imagick = new \Imagick();
|
||||||
|
$imagick->newImage($this->width, $this->height, $this->backgroundColor->__toString());
|
||||||
|
$imagick->setImageFormat('png');
|
||||||
|
|
||||||
|
if (method_exists($imagick, 'setImageProperty')) {
|
||||||
|
$imagick->setImageProperty('Software', 'Jdenticon');
|
||||||
|
} else {
|
||||||
|
$imagick->setImageAttribute('Software', 'Jdenticon');
|
||||||
|
}
|
||||||
|
|
||||||
|
$imagick->drawImage($this->draw);
|
||||||
|
return $imagick->getImageBlob();
|
||||||
|
}
|
||||||
|
}
|
123
vendor/jdenticon/jdenticon/src/Rendering/InternalPngRenderer.php
vendored
Normal file
123
vendor/jdenticon/jdenticon/src/Rendering/InternalPngRenderer.php
vendored
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Rendering;
|
||||||
|
|
||||||
|
use Jdenticon\Canvas\Canvas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders icons as PNG using the internal vector rasterizer.
|
||||||
|
*/
|
||||||
|
class InternalPngRenderer extends AbstractRenderer
|
||||||
|
{
|
||||||
|
private $canvas;
|
||||||
|
private $ctx;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance of the class ImagickRenderer.
|
||||||
|
*
|
||||||
|
* @param int $width The width of the icon in pixels.
|
||||||
|
* @param int $height The height of the icon in pixels.
|
||||||
|
*/
|
||||||
|
public function __construct($width, $height)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->canvas = new Canvas($width, $height);
|
||||||
|
$this->ctx = $this->canvas->getContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the MIME type of the renderer output.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getMimeType()
|
||||||
|
{
|
||||||
|
return 'image/png';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a circle without translating its coordinates.
|
||||||
|
*
|
||||||
|
* @param float $x The x-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $y The y-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $size The size of the bounding rectangle.
|
||||||
|
* @param bool $counterClockwise If true the circle will be drawn
|
||||||
|
* counter clockwise.
|
||||||
|
*/
|
||||||
|
protected function addCircleNoTransform($x, $y, $size, $counterClockwise)
|
||||||
|
{
|
||||||
|
$radius = $size / 2;
|
||||||
|
$this->ctx->moveTo($x + $size, $y + $radius);
|
||||||
|
$this->ctx->arc(
|
||||||
|
$x + $radius, $y + $radius,
|
||||||
|
$radius, 0, M_PI * 2,
|
||||||
|
$counterClockwise);
|
||||||
|
$this->ctx->closePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a polygon without translating its coordinates.
|
||||||
|
*
|
||||||
|
* @param array $points An array of the points that the polygon consists of.
|
||||||
|
*/
|
||||||
|
protected function addPolygonNoTransform($points)
|
||||||
|
{
|
||||||
|
$pointCount = count($points);
|
||||||
|
$this->ctx->moveTo($points[0]->x, $points[0]->y);
|
||||||
|
for ($i = 1; $i < $pointCount; $i++) {
|
||||||
|
$this->ctx->lineTo($points[$i]->x, $points[$i]->y);
|
||||||
|
}
|
||||||
|
$this->ctx->closePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the background color of the icon.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Color $color The background color.
|
||||||
|
*/
|
||||||
|
public function setBackgroundColor(\Jdenticon\Color $color)
|
||||||
|
{
|
||||||
|
parent::setBackgroundColor($color);
|
||||||
|
$this->canvas->backColor = $this->backgroundColor->toRgba();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins a new shape. The shape should be ended with a call to endShape.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Color $color The color of the shape.
|
||||||
|
*/
|
||||||
|
public function beginShape(\Jdenticon\Color $color)
|
||||||
|
{
|
||||||
|
$this->ctx->fillStyle = $color->toRgba();
|
||||||
|
$this->ctx->beginPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends the currently drawn shape.
|
||||||
|
*/
|
||||||
|
public function endShape()
|
||||||
|
{
|
||||||
|
$this->ctx->fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the output from the renderer.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getData()
|
||||||
|
{
|
||||||
|
return $this->canvas->toPng(array('Software' => 'Jdenticon'));
|
||||||
|
}
|
||||||
|
}
|
54
vendor/jdenticon/jdenticon/src/Rendering/Point.php
vendored
Normal file
54
vendor/jdenticon/jdenticon/src/Rendering/Point.php
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Rendering;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A 2D coordinate.
|
||||||
|
*/
|
||||||
|
class Point
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Creates a new Point.
|
||||||
|
*
|
||||||
|
* @param float $x X coordinate.
|
||||||
|
* @param float $y Y coordinate.
|
||||||
|
*/
|
||||||
|
public function __construct($x, $y)
|
||||||
|
{
|
||||||
|
$this->x = $x;
|
||||||
|
$this->y = $y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The X coordinate of this point.
|
||||||
|
*
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
public $x;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Y coordinate of this point.
|
||||||
|
*
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
public $y;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a string representation of the point.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return $this->x + ", " + $this->y;
|
||||||
|
}
|
||||||
|
}
|
60
vendor/jdenticon/jdenticon/src/Rendering/Rectangle.php
vendored
Normal file
60
vendor/jdenticon/jdenticon/src/Rendering/Rectangle.php
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Rendering;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the bounds of a 2D rectangle.
|
||||||
|
*/
|
||||||
|
class Rectangle
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The X coordinate of the left side of the rectangle.
|
||||||
|
*
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
public $x;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Y coordinate of the top side of the rectangle.
|
||||||
|
*
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
public $y;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The width of the rectangle.
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
public $width;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The height of the rectangle.
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
public $height;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Rectangle.
|
||||||
|
*
|
||||||
|
* @param float $x The X coordinate of the left edge of the rectangle.
|
||||||
|
* @param float $y The Y coordinate of the top edge of the rectangle.
|
||||||
|
* @param float $width The width of the rectangle.
|
||||||
|
* @param float $height The height of the rectangle.
|
||||||
|
*/
|
||||||
|
public function __construct($x, $y, $width, $height)
|
||||||
|
{
|
||||||
|
$this->x = $x;
|
||||||
|
$this->y = $y;
|
||||||
|
$this->width = $width;
|
||||||
|
$this->height = $height;
|
||||||
|
}
|
||||||
|
}
|
141
vendor/jdenticon/jdenticon/src/Rendering/RendererInterface.php
vendored
Normal file
141
vendor/jdenticon/jdenticon/src/Rendering/RendererInterface.php
vendored
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Rendering;
|
||||||
|
|
||||||
|
use Jdenticon\Color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for an identicon renderer.
|
||||||
|
*/
|
||||||
|
interface RendererInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Sets the current transform that will be applied on all coordinates before
|
||||||
|
* being rendered to the target image.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Rendering\Transform $transform The transform to set.
|
||||||
|
* If NULL is specified any existing transform is removed.
|
||||||
|
*/
|
||||||
|
public function setTransform(\Jdenticon\Rendering\Transform $transform);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current transform that will be applied on all coordinates before
|
||||||
|
* being rendered to the target image.
|
||||||
|
*
|
||||||
|
* @return \Jdenticon\Rendering\Transform
|
||||||
|
*/
|
||||||
|
public function getTransform();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the background color of the image.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Color $color The image background color.
|
||||||
|
*/
|
||||||
|
public function setBackgroundColor(Color $color);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the background color of the image.
|
||||||
|
*
|
||||||
|
* @return \Jdenticon\Color
|
||||||
|
*/
|
||||||
|
public function getBackgroundColor();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the MIME type of the renderer output.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getMimeType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins a new shape. The shape should be ended with a call to endShape.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Color $color The color of the shape.
|
||||||
|
*/
|
||||||
|
public function beginShape(Color $color);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends the currently drawn shape.
|
||||||
|
*/
|
||||||
|
public function endShape();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a rectangle to the image.
|
||||||
|
*
|
||||||
|
* @param float $x The x-coordinate of the rectangle upper-left corner.
|
||||||
|
* @param float $y The y-coordinate of the rectangle upper-left corner.
|
||||||
|
* @param float $width The width of the rectangle.
|
||||||
|
* @param float $height The height of the rectangle.
|
||||||
|
* @param bool $invert If true the area of the rectangle will be removed
|
||||||
|
* from the filled area.
|
||||||
|
*/
|
||||||
|
public function addRectangle($x, $y, $width, $height, $invert = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a circle to the image.
|
||||||
|
*
|
||||||
|
* @param float $x The x-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $y The y-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $size The size of the bounding rectangle.
|
||||||
|
* @param bool $invert If true the area of the circle will be removed from
|
||||||
|
* the filled area.
|
||||||
|
*/
|
||||||
|
public function addCircle($x, $y, $size, $invert = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a polygon to the image.
|
||||||
|
*
|
||||||
|
* @param array $points Array of points that the polygon consists of.
|
||||||
|
* @param bool $invert If true the area of the polygon will be removed from
|
||||||
|
* the filled area.
|
||||||
|
*/
|
||||||
|
public function addPolygon($points, $invert = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a triangle to the image.
|
||||||
|
*
|
||||||
|
* @param float $x The x-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $y The y-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $width The width of the bounding rectangle.
|
||||||
|
* @param float $height The height of the bounding rectangle.
|
||||||
|
* @param float $direction The direction of the 90 degree corner of
|
||||||
|
* the triangle.
|
||||||
|
* @param bool $invert If true the area of the triangle will be removed
|
||||||
|
* from the filled area.
|
||||||
|
*/
|
||||||
|
public function addTriangle($x, $y, $width, $height, $direction, $invert = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a rhombus to the image.
|
||||||
|
*
|
||||||
|
* @param float $x The x-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $y The y-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $width The width of the bounding rectangle.
|
||||||
|
* @param float $height The height of the bounding rectangle.
|
||||||
|
* @param bool $invert If true the area of the rhombus will be removed
|
||||||
|
* from the filled area.
|
||||||
|
*/
|
||||||
|
public function addRhombus($x, $y, $width, $height, $invert = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the output from the renderer.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getData();
|
||||||
|
}
|
83
vendor/jdenticon/jdenticon/src/Rendering/SvgPath.php
vendored
Normal file
83
vendor/jdenticon/jdenticon/src/Rendering/SvgPath.php
vendored
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Rendering;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a SVG path element.
|
||||||
|
*/
|
||||||
|
class SvgPath
|
||||||
|
{
|
||||||
|
private $dataString;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->dataString = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a circle to the SVG.
|
||||||
|
*
|
||||||
|
* @param float $x X coordinate of the left side of the containing rectangle.
|
||||||
|
* @param float $y Y coordinate of the top side of the containing rectangle.
|
||||||
|
* @param float $size The diameter of the circle.
|
||||||
|
* @param bool $counterClockwise If true the circle will be drawn counter
|
||||||
|
* clockwise. This affects the rendering since the evenodd filling rule
|
||||||
|
* is used by Jdenticon.
|
||||||
|
*/
|
||||||
|
public function addCircle($x, $y, $size, $counterClockwise)
|
||||||
|
{
|
||||||
|
$sweepFlag = $counterClockwise ? '0' : '1';
|
||||||
|
$radiusAsString = number_format($size / 2, 2, '.', '');
|
||||||
|
|
||||||
|
$this->dataString .=
|
||||||
|
'M'. number_format($x, 2, '.', '') .' '.
|
||||||
|
number_format($y + $size / 2, 2, '.', '').
|
||||||
|
'a'. $radiusAsString .','. $radiusAsString .' 0 1,'.
|
||||||
|
$sweepFlag .' '. number_format($size, 2, '.', '') .',0'.
|
||||||
|
'a'. $radiusAsString .','. $radiusAsString .' 0 1,'.
|
||||||
|
$sweepFlag .' '. number_format(-$size, 2, '.', '') .',0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a polygon to the SVG.
|
||||||
|
*
|
||||||
|
* @param array(\Jdenticon\Rendering\Point) $points The corners of the
|
||||||
|
* polygon.
|
||||||
|
*/
|
||||||
|
public function addPolygon($points)
|
||||||
|
{
|
||||||
|
$pointCount = count($points);
|
||||||
|
|
||||||
|
$this->dataString .= 'M'.
|
||||||
|
number_format($points[0]->x, 2, '.', '') .' '.
|
||||||
|
number_format($points[0]->y, 2, '.', '');
|
||||||
|
|
||||||
|
for ($i = 1; $i < $pointCount; $i++) {
|
||||||
|
$this->dataString .= 'L'.
|
||||||
|
number_format($points[$i]->x, 2, '.', '') .' '.
|
||||||
|
number_format($points[$i]->y, 2, '.', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dataString .= 'Z';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the path as a SVG path string.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return $this->dataString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
133
vendor/jdenticon/jdenticon/src/Rendering/SvgRenderer.php
vendored
Normal file
133
vendor/jdenticon/jdenticon/src/Rendering/SvgRenderer.php
vendored
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Rendering;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders icons as SVG paths.
|
||||||
|
*/
|
||||||
|
class SvgRenderer extends AbstractRenderer
|
||||||
|
{
|
||||||
|
private $pathsByColor = array();
|
||||||
|
private $path;
|
||||||
|
private $width;
|
||||||
|
private $height;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new SvgRenderer.
|
||||||
|
*
|
||||||
|
* @param int $width The width of the icon in pixels.
|
||||||
|
* @param int $height The height of the icon in pixels.
|
||||||
|
*/
|
||||||
|
public function __construct($width, $height)
|
||||||
|
{
|
||||||
|
$this->width = $width;
|
||||||
|
$this->height = $height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the MIME type of the renderer output.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getMimeType()
|
||||||
|
{
|
||||||
|
return 'image/svg+xml';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a circle without translating its coordinates.
|
||||||
|
*
|
||||||
|
* @param float $x The x-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $y The y-coordinate of the bounding rectangle
|
||||||
|
* upper-left corner.
|
||||||
|
* @param float $size The size of the bounding rectangle.
|
||||||
|
* @param bool $counterClockwise If true the circle will be drawn
|
||||||
|
* counter clockwise.
|
||||||
|
*/
|
||||||
|
protected function addCircleNoTransform($x, $y, $size, $counterClockwise)
|
||||||
|
{
|
||||||
|
$this->path->addCircle($x, $y, $size, $counterClockwise);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a polygon without translating its coordinates.
|
||||||
|
*
|
||||||
|
* @param array $points An array of the points that the polygon consists of.
|
||||||
|
*/
|
||||||
|
protected function addPolygonNoTransform($points)
|
||||||
|
{
|
||||||
|
$this->path->addPolygon($points);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins a new shape. The shape should be ended with a call to endShape.
|
||||||
|
*
|
||||||
|
* @param \Jdenticon\Color $color The color of the shape.
|
||||||
|
*/
|
||||||
|
public function beginShape(\Jdenticon\Color $color)
|
||||||
|
{
|
||||||
|
$colorString = $color->toHexString(6);
|
||||||
|
|
||||||
|
if (isset($this->pathsByColor[$colorString])) {
|
||||||
|
$this->path = $this->pathsByColor[$colorString];
|
||||||
|
} else {
|
||||||
|
$this->path = new SvgPath();
|
||||||
|
$this->pathsByColor[$colorString] = $this->path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends the currently drawn shape.
|
||||||
|
*/
|
||||||
|
public function endShape()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates an SVG string of the renderer output.
|
||||||
|
*
|
||||||
|
* @param bool $fragment If true an SVG string without the root svg element
|
||||||
|
* will be rendered.
|
||||||
|
*/
|
||||||
|
public function getData($fragment = false)
|
||||||
|
{
|
||||||
|
$svg = '';
|
||||||
|
$widthAsString = number_format($this->width, 0, '.', '');
|
||||||
|
$heightAsString = number_format($this->height, 0, '.', '');
|
||||||
|
|
||||||
|
if (!$fragment) {
|
||||||
|
$svg .= '<svg xmlns="http://www.w3.org/2000/svg" width="' .
|
||||||
|
$widthAsString .'" height="'. $heightAsString .'" viewBox="0 0 '.
|
||||||
|
$widthAsString .' '. $heightAsString .
|
||||||
|
'" preserveAspectRatio="xMidYMid meet">';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->backgroundColor->a > 0) {
|
||||||
|
$opacity = (float)$this->backgroundColor->a / 255;
|
||||||
|
$svg .= '<rect fill="'. $this->backgroundColor->toHexString(6) .
|
||||||
|
'" fill-opacity="'. number_format($opacity, 2, '.', '').
|
||||||
|
'" x="0" y="0" width="'. $widthAsString .'" height="'.
|
||||||
|
$heightAsString .'"/>';
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->pathsByColor as $color => $path) {
|
||||||
|
$svg .= "<path fill=\"$color\" d=\"$path\"/>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$fragment) {
|
||||||
|
$svg .= '</svg>';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $svg;
|
||||||
|
}
|
||||||
|
}
|
79
vendor/jdenticon/jdenticon/src/Rendering/Transform.php
vendored
Normal file
79
vendor/jdenticon/jdenticon/src/Rendering/Transform.php
vendored
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Rendering;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Translates and rotates a point before being rendered.
|
||||||
|
*/
|
||||||
|
class Transform
|
||||||
|
{
|
||||||
|
private $x;
|
||||||
|
private $y;
|
||||||
|
private $size;
|
||||||
|
private $rotation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Transform.
|
||||||
|
*
|
||||||
|
* @param float $x The x-coordinate of the upper left corner of the
|
||||||
|
* transformed rectangle.
|
||||||
|
* @param float $y The y-coordinate of the upper left corner of the
|
||||||
|
* transformed rectangle.
|
||||||
|
* @param float $size The size of the transformed rectangle.
|
||||||
|
* @param integer $rotation Rotation specified as
|
||||||
|
* 0 = 0 rad, 1 = 0.5π rad, 2 = π rad, 3 = 1.5π rad.
|
||||||
|
*/
|
||||||
|
public function __construct($x, $y, $size, $rotation)
|
||||||
|
{
|
||||||
|
$this->x = $x;
|
||||||
|
$this->y = $y;
|
||||||
|
$this->size = $size;
|
||||||
|
$this->rotation = $rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a noop transform.
|
||||||
|
*
|
||||||
|
* @return \Jdenticon\Rendering\Transform
|
||||||
|
*/
|
||||||
|
public static function getEmpty()
|
||||||
|
{
|
||||||
|
return new Transform(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms the specified point based on the translation and rotation
|
||||||
|
* specification for this Transform.
|
||||||
|
*
|
||||||
|
* @param float $x x-coordinate
|
||||||
|
* @param float $y y-coordinate
|
||||||
|
* @param float $width The width of the transformed rectangle. If greater
|
||||||
|
* than 0, this will ensure the returned point is of the upper left
|
||||||
|
* corner of the transformed rectangle.
|
||||||
|
* @param float $height The height of the transformed rectangle. If greater
|
||||||
|
* than 0, this will ensure the returned point is of the upper left
|
||||||
|
* corner of the transformed rectangle.
|
||||||
|
* @return \Jdenticon\Rendering\Point
|
||||||
|
*/
|
||||||
|
public function transformPoint($x, $y, $width = 0, $height = 0)
|
||||||
|
{
|
||||||
|
$right = $this->x + $this->size;
|
||||||
|
$bottom = $this->y + $this->size;
|
||||||
|
|
||||||
|
switch ($this->rotation) {
|
||||||
|
case 1: return new Point($right - $y - $height, $this->y + $x);
|
||||||
|
case 2: return new Point($right - $x - $width, $bottom - $y - $height);
|
||||||
|
case 3: return new Point($this->x + $y, $bottom - $x - $width);
|
||||||
|
default: return new Point($this->x + $x, $this->y + $y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
vendor/jdenticon/jdenticon/src/Rendering/TriangleDirection.php
vendored
Normal file
35
vendor/jdenticon/jdenticon/src/Rendering/TriangleDirection.php
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Rendering;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies in what direction the 90 degree angle of a triangle is pointing.
|
||||||
|
*/
|
||||||
|
class TriangleDirection
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The 90 degree angle is pointing to South West.
|
||||||
|
*/
|
||||||
|
const SOUTH_WEST = 0;
|
||||||
|
/**
|
||||||
|
* The 90 degree angle is pointing to North West.
|
||||||
|
*/
|
||||||
|
const NORTH_WEST = 1;
|
||||||
|
/**
|
||||||
|
* The 90 degree angle is pointing to North East.
|
||||||
|
*/
|
||||||
|
const NORTH_EAST = 2;
|
||||||
|
/**
|
||||||
|
* The 90 degree angle is pointing to South East.
|
||||||
|
*/
|
||||||
|
const SOUTH_EAST = 3;
|
||||||
|
}
|
62
vendor/jdenticon/jdenticon/src/Shapes/Shape.php
vendored
Normal file
62
vendor/jdenticon/jdenticon/src/Shapes/Shape.php
vendored
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Shapes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a shape to be rendered in an icon. These instances are
|
||||||
|
* hash specific.
|
||||||
|
*/
|
||||||
|
class Shape
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The shape definition to be used to render the shape.
|
||||||
|
*
|
||||||
|
* @var function(
|
||||||
|
* \Jdenticon\Rendering\RendererInterface $renderer,
|
||||||
|
* \Jdenticon\Shapes\ShapePosition $cell,
|
||||||
|
* int $index)
|
||||||
|
*/
|
||||||
|
public $definition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fill color of the shape.
|
||||||
|
*
|
||||||
|
* @var Jdenticon\Color
|
||||||
|
*/
|
||||||
|
public $color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The positions in which the shape will be rendered.
|
||||||
|
*
|
||||||
|
* @var array(\Jdenticon\Shapes\ShapePosition)
|
||||||
|
*/
|
||||||
|
public $positions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The rotation index of the icon in the first position.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $startRotationIndex;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
$definition,
|
||||||
|
\Jdenticon\Color $color,
|
||||||
|
array $positions,
|
||||||
|
$startRotationIndex)
|
||||||
|
{
|
||||||
|
$this->definition = $definition;
|
||||||
|
$this->color = $color;
|
||||||
|
$this->positions = $positions;
|
||||||
|
$this->startRotationIndex = $startRotationIndex;
|
||||||
|
}
|
||||||
|
}
|
71
vendor/jdenticon/jdenticon/src/Shapes/ShapeCategory.php
vendored
Normal file
71
vendor/jdenticon/jdenticon/src/Shapes/ShapeCategory.php
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Shapes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a category of shapes that can be rendered in an icon. These
|
||||||
|
* instances are not hash specific.
|
||||||
|
*/
|
||||||
|
class ShapeCategory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The index of the hash octet determining the color of shapes in this
|
||||||
|
* category.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $colorIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of possible shape definitions in this category.
|
||||||
|
*
|
||||||
|
* @var array(function(
|
||||||
|
* \Jdenticon\Rendering\RendererInterface $renderer,
|
||||||
|
* \Jdenticon\Shapes\ShapePosition $cell,
|
||||||
|
* int $index))
|
||||||
|
*/
|
||||||
|
public $shapes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of the hash octet determining which of the shape definitions
|
||||||
|
* that will be used for a particular hash.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $shapeIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of the hash octet determining the rotation index of the shape
|
||||||
|
* in the first position.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $rotationIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The positions in which the shapes of this category will be rendered.
|
||||||
|
*
|
||||||
|
* @var array(int)
|
||||||
|
*/
|
||||||
|
public $positions;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
$colorIndex, array $shapes, $shapeIndex, $rotationIndex, array $positions)
|
||||||
|
{
|
||||||
|
$this->colorIndex = $colorIndex;
|
||||||
|
$this->shapes = $shapes;
|
||||||
|
$this->shapeIndex = $shapeIndex;
|
||||||
|
$this->rotationIndex = $rotationIndex;
|
||||||
|
$this->positions = $positions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
243
vendor/jdenticon/jdenticon/src/Shapes/ShapeDefinitions.php
vendored
Normal file
243
vendor/jdenticon/jdenticon/src/Shapes/ShapeDefinitions.php
vendored
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Shapes;
|
||||||
|
|
||||||
|
use Jdenticon\Rendering\Point;
|
||||||
|
use Jdenticon\Rendering\TriangleDirection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides definitions for the default shapes used in identicons.
|
||||||
|
*/
|
||||||
|
class ShapeDefinitions
|
||||||
|
{
|
||||||
|
private static $outerShapes;
|
||||||
|
private static $centerShapes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an array of all possible outer shapes. Do not modify the returned
|
||||||
|
* array.
|
||||||
|
*
|
||||||
|
* @return array(\Jdenticon\Rendering\Shape)
|
||||||
|
*/
|
||||||
|
public static function getOuterShapes()
|
||||||
|
{
|
||||||
|
if (self::$outerShapes === null) {
|
||||||
|
self::$outerShapes = self::createOuterShapes();
|
||||||
|
}
|
||||||
|
return self::$outerShapes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an array of all possible center shapes. Do not modify the returned
|
||||||
|
* array.
|
||||||
|
*
|
||||||
|
* @return array(\Jdenticon\Rendering\Shape)
|
||||||
|
*/
|
||||||
|
public static function getCenterShapes()
|
||||||
|
{
|
||||||
|
if (self::$centerShapes === null) {
|
||||||
|
self::$centerShapes = self::createCenterShapes();
|
||||||
|
}
|
||||||
|
return self::$centerShapes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function createOuterShapes()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$renderer->addTriangle(0, 0, $cell, $cell, 0);
|
||||||
|
},
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$renderer->addTriangle(0, $cell / 2, $cell, $cell / 2, 0);
|
||||||
|
},
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$renderer->addRhombus(0, 0, $cell, $cell);
|
||||||
|
},
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$m = $cell / 6;
|
||||||
|
$renderer->addCircle($m, $m, $cell - 2 * $m);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function createCenterShapes()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$k = $cell * 0.42;
|
||||||
|
$renderer->addPolygon(array(
|
||||||
|
new Point(0, 0),
|
||||||
|
new Point($cell, 0),
|
||||||
|
new Point($cell, $cell - $k * 2),
|
||||||
|
new Point($cell - $k, $cell),
|
||||||
|
new Point(0, $cell)
|
||||||
|
));
|
||||||
|
},
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$w = (int)($cell * 0.5);
|
||||||
|
$h = (int)($cell * 0.8);
|
||||||
|
$renderer->addTriangle(
|
||||||
|
$cell - $w, 0, $w, $h,
|
||||||
|
TriangleDirection::NORTH_EAST);
|
||||||
|
},
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$s = (int)($cell / 3);
|
||||||
|
$renderer->addRectangle($s, $s, $cell - $s, $cell - $s);
|
||||||
|
},
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$tmp = $cell * 0.1;
|
||||||
|
|
||||||
|
if ($tmp > 1) {
|
||||||
|
// large icon => truncate decimals
|
||||||
|
$inner = (int)$tmp;
|
||||||
|
} elseif ($tmp > 0.5) {
|
||||||
|
// medium size icon => fixed width
|
||||||
|
$inner = 1;
|
||||||
|
} else {
|
||||||
|
// small icon => anti-aliased border
|
||||||
|
$inner = $tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use fixed outer border widths in small icons to ensure
|
||||||
|
// the border is drawn
|
||||||
|
if ($cell < 6) {
|
||||||
|
$outer = 1;
|
||||||
|
} elseif ($cell < 8) {
|
||||||
|
$outer = 2;
|
||||||
|
} else {
|
||||||
|
$outer = (int)($cell / 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
$renderer->addRectangle(
|
||||||
|
$outer, $outer,
|
||||||
|
$cell - $inner - $outer, $cell - $inner - $outer);
|
||||||
|
},
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$m = (int)($cell * 0.15);
|
||||||
|
$s = (int)($cell * 0.5);
|
||||||
|
$renderer->addCircle($cell - $s - $m, $cell - $s - $m, $s);
|
||||||
|
},
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$inner = $cell * 0.1;
|
||||||
|
$outer = $inner * 4;
|
||||||
|
|
||||||
|
// Align edge to nearest pixel in large icons
|
||||||
|
if ($outer > 3) {
|
||||||
|
$outer = (int)$outer;
|
||||||
|
}
|
||||||
|
|
||||||
|
$renderer->addRectangle(0, 0, $cell, $cell);
|
||||||
|
$renderer->addPolygon(array(
|
||||||
|
new Point($outer, $outer),
|
||||||
|
new Point($cell - $inner, $outer),
|
||||||
|
new Point($outer + ($cell - $outer - $inner) / 2,
|
||||||
|
$cell - $inner)
|
||||||
|
), true);
|
||||||
|
},
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$renderer->addPolygon(array(
|
||||||
|
new Point(0, 0),
|
||||||
|
new Point($cell, 0),
|
||||||
|
new Point($cell, $cell * 0.7),
|
||||||
|
new Point($cell * 0.4, $cell * 0.4),
|
||||||
|
new Point($cell * 0.7, $cell),
|
||||||
|
new Point(0, $cell)
|
||||||
|
));
|
||||||
|
},
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$renderer->addTriangle(
|
||||||
|
$cell / 2, $cell / 2, $cell / 2, $cell / 2,
|
||||||
|
TriangleDirection::SOUTH_EAST);
|
||||||
|
},
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$renderer->addPolygon(array(
|
||||||
|
new Point(0, 0),
|
||||||
|
new Point($cell, 0),
|
||||||
|
new Point($cell, $cell / 2),
|
||||||
|
new Point($cell / 2, $cell),
|
||||||
|
new Point(0, $cell)
|
||||||
|
));
|
||||||
|
},
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$tmp = $cell * 0.14;
|
||||||
|
|
||||||
|
if ($cell < 8) {
|
||||||
|
// small icon => anti-aliased border
|
||||||
|
$inner = $tmp;
|
||||||
|
} else {
|
||||||
|
// large icon => truncate decimals
|
||||||
|
$inner = (int)$tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use fixed outer border widths in small icons to ensure
|
||||||
|
// the border is drawn
|
||||||
|
if ($cell < 4) {
|
||||||
|
$outer = 1;
|
||||||
|
} elseif ($cell < 6) {
|
||||||
|
$outer = 2;
|
||||||
|
} else {
|
||||||
|
$outer = (int)($cell * 0.35);
|
||||||
|
}
|
||||||
|
|
||||||
|
$renderer->addRectangle(0, 0, $cell, $cell);
|
||||||
|
$renderer->addRectangle(
|
||||||
|
$outer, $outer,
|
||||||
|
$cell - $outer - $inner, $cell - $outer - $inner, true);
|
||||||
|
},
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$inner = $cell * 0.12;
|
||||||
|
$outer = $inner * 3;
|
||||||
|
|
||||||
|
$renderer->addRectangle(0, 0, $cell, $cell);
|
||||||
|
$renderer->addCircle($outer, $outer, $cell - $inner - $outer,
|
||||||
|
true);
|
||||||
|
},
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$renderer->addTriangle(
|
||||||
|
$cell / 2, $cell / 2, $cell / 2, $cell / 2,
|
||||||
|
TriangleDirection::SOUTH_EAST);
|
||||||
|
},
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$m = $cell * 0.25;
|
||||||
|
|
||||||
|
$renderer->addRectangle(0, 0, $cell, $cell);
|
||||||
|
$renderer->addRhombus($m, $m, $cell - $m, $cell - $m, true);
|
||||||
|
},
|
||||||
|
function ($renderer, $cell, $index)
|
||||||
|
{
|
||||||
|
$m = $cell * 0.4;
|
||||||
|
$s = $cell * 1.2;
|
||||||
|
|
||||||
|
if ($index != 0) {
|
||||||
|
$renderer->addCircle($m, $m, $s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
45
vendor/jdenticon/jdenticon/src/Shapes/ShapePosition.php
vendored
Normal file
45
vendor/jdenticon/jdenticon/src/Shapes/ShapePosition.php
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Jdenticon for PHP.
|
||||||
|
* https://github.com/dmester/jdenticon-php/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Daniel Mester Pirttijärvi
|
||||||
|
*
|
||||||
|
* For full license information, please see the LICENSE file that was
|
||||||
|
* distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Jdenticon\Shapes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies in which cell a shape will be rendered.
|
||||||
|
*/
|
||||||
|
class ShapePosition
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The horizontal cell index measured left to right.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $x;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The vertical cell index measured from the top.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $y;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new ShapePosition instance.
|
||||||
|
*
|
||||||
|
* @param int $x The x-coordinate of the containing cell.
|
||||||
|
* @param int $y The y-coordinate of the containing cell.
|
||||||
|
*/
|
||||||
|
public function __construct($x, $y)
|
||||||
|
{
|
||||||
|
$this->x = $x;
|
||||||
|
$this->y = $y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user