first commit

This commit is contained in:
2023-09-01 00:37:57 -07:00
commit 9caab8ce68
602 changed files with 33485 additions and 0 deletions

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Daniel Mester Pirttijärvi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,60 @@
# [Jdenticon-php](https://jdenticon.com)
PHP library for generating highly recognizable identicons.
![Sample identicons](https://jdenticon.com/hosted/github-samples.png)
[![Test Status](https://github.com/dmester/jdenticon-php/workflows/Tests/badge.svg)](https://github.com/dmester/jdenticon-php/actions)
[![Total Downloads](https://poser.pugx.org/jdenticon/jdenticon/downloads)](https://packagist.org/packages/jdenticon/jdenticon)
## Features
Jdenticon-php is a PHP port of the JavaScript library [Jdenticon](https://github.com/dmester/jdenticon).
* Renders identicons as PNG or SVG with no extension requirements.
* Runs on PHP 5.3 and later.
## Live demo
https://jdenticon.com
## Getting started
Using Jdenticon is simple. Follow the steps below to integrate Jdenticon into your website.
### 1. Install the Jdenticon Composer package
The easiest way to get started using Jdenticon for PHP is to install the Jdenticon Composer package.
```
composer require jdenticon/jdenticon
```
### 2. Create a php file that will serve an icon
Now create a file that you call icon.php and place it in the root of your application. Add the following content to the file.
```PHP
<?php
include_once("vendor/autoload.php");
// Set max-age to a week to benefit from client caching (this is optional)
header('Cache-Control: max-age=604800');
// Parse query string parameters
$value = $_GET['value'];
$size = min(max(intval($_GET['size']), 20), 500);
// Render icon
$icon = new \Jdenticon\Identicon();
$icon->setValue($value);
$icon->setSize($size);
$icon->displayImage('png');
```
### 3. Use icon.php
Open up your favourite browser and navigate to http://localhost:PORT/icon.php?size=100&value=anything.
An identicon should be displayed. Try to change the url parameters to see the difference in the generated icon.
## Other resources
### API documentation
For more usage examples and API documentation, please see:
https://jdenticon.com/php-api.html
## License
Jdenticon-php is released under the [MIT license](https://github.com/dmester/jdenticon-php/blob/master/LICENSE).

View File

@ -0,0 +1,673 @@
<?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 Avatar_Privacy\Vendor\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 & 0xf0) >> 4 | $numeric24bit & 0xf0, ($numeric24bit & 0xf) << 4 | $numeric24bit & 0xf);
return \true;
case 4:
$result = self::fromRgb(($numeric24bit & 0xf000) >> 12 | ($numeric24bit & 0xf000) >> 8, ($numeric24bit & 0xf00) >> 8 | ($numeric24bit & 0xf00) >> 4, ($numeric24bit & 0xf0) >> 4 | $numeric24bit & 0xf0, ($numeric24bit & 0xf) << 4 | $numeric24bit & 0xf);
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;
}
}
}

View File

@ -0,0 +1,421 @@
<?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 Avatar_Privacy\Vendor\Jdenticon;
use Avatar_Privacy\Vendor\Jdenticon\IdenticonStyle;
use Avatar_Privacy\Vendor\Jdenticon\Rendering\Rectangle;
use Avatar_Privacy\Vendor\Jdenticon\Rendering\RendererInterface;
use Avatar_Privacy\Vendor\Jdenticon\Rendering\IconGenerator;
use Avatar_Privacy\Vendor\Jdenticon\Rendering\InternalPngRenderer;
use Avatar_Privacy\Vendor\Jdenticon\Rendering\ImagickRenderer;
use Avatar_Privacy\Vendor\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(\Avatar_Privacy\Vendor\Jdenticon\Rendering\RendererInterface $renderer, \Avatar_Privacy\Vendor\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}";
}
}

View File

@ -0,0 +1,384 @@
<?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 Avatar_Privacy\Vendor\Jdenticon;
use Avatar_Privacy\Vendor\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);
}
}

View File

@ -0,0 +1,174 @@
<?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 Avatar_Privacy\Vendor\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(\Avatar_Privacy\Vendor\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.
*/
protected abstract 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.
*/
protected abstract function addCircleNoTransform($x, $y, $size, $counterClockwise);
/**
* Sets the background color of the image.
*
* @param \Jdenticon\Color $color The image background color.
*/
public function setBackgroundColor(\Avatar_Privacy\Vendor\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);
}
}

View 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 Avatar_Privacy\Vendor\Jdenticon\Rendering;
use Avatar_Privacy\Vendor\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, \Avatar_Privacy\Vendor\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;
}
}

View File

@ -0,0 +1,257 @@
<?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 Avatar_Privacy\Vendor\Jdenticon\Rendering;
use Avatar_Privacy\Vendor\Jdenticon\Shapes\Shape;
use Avatar_Privacy\Vendor\Jdenticon\Shapes\ShapeCategory;
use Avatar_Privacy\Vendor\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(\Avatar_Privacy\Vendor\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(\Avatar_Privacy\Vendor\Jdenticon\Rendering\RendererInterface $renderer, \Avatar_Privacy\Vendor\Jdenticon\Rendering\Rectangle $rect, \Avatar_Privacy\Vendor\Jdenticon\IdenticonStyle $style, \Avatar_Privacy\Vendor\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(\Avatar_Privacy\Vendor\Jdenticon\Rendering\RendererInterface $renderer, \Avatar_Privacy\Vendor\Jdenticon\Rendering\Rectangle $rect, \Avatar_Privacy\Vendor\Jdenticon\IdenticonStyle $style, \Avatar_Privacy\Vendor\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(\Avatar_Privacy\Vendor\Jdenticon\Rendering\RendererInterface $renderer, \Avatar_Privacy\Vendor\Jdenticon\Rendering\Rectangle $rect, \Avatar_Privacy\Vendor\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);
}
}

View File

@ -0,0 +1,51 @@
<?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 Avatar_Privacy\Vendor\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;
}
}

View File

@ -0,0 +1,56 @@
<?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 Avatar_Privacy\Vendor\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;
}
}

View File

@ -0,0 +1,128 @@
<?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 Avatar_Privacy\Vendor\Jdenticon\Rendering;
use Avatar_Privacy\Vendor\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(\Avatar_Privacy\Vendor\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();
}

View File

@ -0,0 +1,64 @@
<?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 Avatar_Privacy\Vendor\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;
}
}

View File

@ -0,0 +1,114 @@
<?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 Avatar_Privacy\Vendor\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(\Avatar_Privacy\Vendor\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;
}
}

View 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 Avatar_Privacy\Vendor\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);
}
}
}

View 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 Avatar_Privacy\Vendor\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;
}

View 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 Avatar_Privacy\Vendor\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, \Avatar_Privacy\Vendor\Jdenticon\Color $color, array $positions, $startRotationIndex)
{
$this->definition = $definition;
$this->color = $color;
$this->positions = $positions;
$this->startRotationIndex = $startRotationIndex;
}
}

View File

@ -0,0 +1,64 @@
<?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 Avatar_Privacy\Vendor\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;
}
}

View File

@ -0,0 +1,154 @@
<?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 Avatar_Privacy\Vendor\Jdenticon\Shapes;
use Avatar_Privacy\Vendor\Jdenticon\Rendering\Point;
use Avatar_Privacy\Vendor\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);
}
});
}
}

View File

@ -0,0 +1,42 @@
<?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 Avatar_Privacy\Vendor\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;
}
}