/vendor/phenx/php-svg-lib/src/Svg/Style.php
PHP | 485 lines | 396 code | 55 blank | 34 comment | 34 complexity | 14ae890241ac59494b25dbe136286837 MD5 | raw file
Possible License(s): Apache-2.0, AGPL-1.0, GPL-2.0, LGPL-3.0, BSD-3-Clause, Unlicense, MPL-2.0, GPL-3.0, LGPL-2.1
- <?php
- /**
- * @package php-svg-lib
- * @link http://github.com/PhenX/php-svg-lib
- * @author Fabien Ménager <fabien.menager@gmail.com>
- * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
- */
- namespace Svg;
- use Svg\Tag\AbstractTag;
- class Style
- {
- const TYPE_COLOR = 1;
- const TYPE_LENGTH = 2;
- const TYPE_NAME = 3;
- const TYPE_ANGLE = 4;
- const TYPE_NUMBER = 5;
- public $color;
- public $opacity;
- public $fill;
- public $fillOpacity;
- public $fillRule;
- public $stroke;
- public $strokeOpacity;
- public $strokeLinecap;
- public $strokeLinejoin;
- public $strokeMiterlimit;
- public $strokeWidth;
- public $strokeDasharray;
- public $strokeDashoffset;
- public $fontFamily = 'serif';
- public $fontSize = 12;
- public $fontWeight = 'normal';
- public $fontStyle = 'normal';
- public $textAnchor = 'start';
- protected function getStyleMap()
- {
- return array(
- 'color' => array('color', self::TYPE_COLOR),
- 'opacity' => array('opacity', self::TYPE_NUMBER),
- 'fill' => array('fill', self::TYPE_COLOR),
- 'fill-opacity' => array('fillOpacity', self::TYPE_NUMBER),
- 'fill-rule' => array('fillRule', self::TYPE_NAME),
- 'stroke' => array('stroke', self::TYPE_COLOR),
- 'stroke-dasharray' => array('strokeDasharray', self::TYPE_NAME),
- 'stroke-dashoffset' => array('strokeDashoffset', self::TYPE_NUMBER),
- 'stroke-linecap' => array('strokeLinecap', self::TYPE_NAME),
- 'stroke-linejoin' => array('strokeLinejoin', self::TYPE_NAME),
- 'stroke-miterlimit' => array('strokeMiterlimit', self::TYPE_NUMBER),
- 'stroke-opacity' => array('strokeOpacity', self::TYPE_NUMBER),
- 'stroke-width' => array('strokeWidth', self::TYPE_NUMBER),
- 'font-family' => array('fontFamily', self::TYPE_NAME),
- 'font-size' => array('fontSize', self::TYPE_NUMBER),
- 'font-weight' => array('fontWeight', self::TYPE_NUMBER),
- 'font-style' => array('fontStyle', self::TYPE_NAME),
- 'text-anchor' => array('textAnchor', self::TYPE_NAME),
- );
- }
- /**
- * @param $attributes
- *
- * @return Style
- */
- public function fromAttributes($attributes)
- {
- $this->fillStyles($attributes);
- if (isset($attributes["style"])) {
- $styles = self::parseCssStyle($attributes["style"]);
- $this->fillStyles($styles);
- }
- }
- public function inherit(AbstractTag $tag) {
- $group = $tag->getParentGroup();
- if ($group) {
- $parent_style = $group->getStyle();
- foreach ($parent_style as $_key => $_value) {
- if ($_value !== null) {
- $this->$_key = $_value;
- }
- }
- }
- }
- protected function fillStyles($styles)
- {
- foreach ($this->getStyleMap() as $from => $spec) {
- if (isset($styles[$from])) {
- list($to, $type) = $spec;
- $value = null;
- switch ($type) {
- case self::TYPE_COLOR:
- $value = self::parseColor($styles[$from]);
- break;
- case self::TYPE_NUMBER:
- $value = ($styles[$from] === null) ? null : (float)$styles[$from];
- break;
- default:
- $value = $styles[$from];
- }
- if ($value !== null) {
- $this->$to = $value;
- }
- }
- }
- }
- static function parseColor($color)
- {
- $color = strtolower(trim($color));
- $parts = preg_split('/\s+/', $color, 2);
- if (count($parts) == 2) {
- $color = $parts[1];
- }
- else {
- $color = $parts[0];
- }
- if ($color === "none") {
- return "none";
- }
- // SVG color name
- if (isset(self::$colorNames[$color])) {
- return self::parseHexColor(self::$colorNames[$color]);
- }
- // Hex color
- if ($color[0] === "#") {
- return self::parseHexColor($color);
- }
- // RGB color
- if (strpos($color, "rgb") !== false) {
- return self::getTriplet($color);
- }
- // RGB color
- if (strpos($color, "hsl") !== false) {
- $triplet = self::getTriplet($color, true);
- if ($triplet == null) {
- return null;
- }
- list($h, $s, $l) = $triplet;
- $r = $l;
- $g = $l;
- $b = $l;
- $v = ($l <= 0.5) ? ($l * (1.0 + $s)) : ($l + $s - $l * $s);
- if ($v > 0) {
- $m = $l + $l - $v;
- $sv = ($v - $m) / $v;
- $h *= 6.0;
- $sextant = floor($h);
- $fract = $h - $sextant;
- $vsf = $v * $sv * $fract;
- $mid1 = $m + $vsf;
- $mid2 = $v - $vsf;
- switch ($sextant) {
- case 0:
- $r = $v;
- $g = $mid1;
- $b = $m;
- break;
- case 1:
- $r = $mid2;
- $g = $v;
- $b = $m;
- break;
- case 2:
- $r = $m;
- $g = $v;
- $b = $mid1;
- break;
- case 3:
- $r = $m;
- $g = $mid2;
- $b = $v;
- break;
- case 4:
- $r = $mid1;
- $g = $m;
- $b = $v;
- break;
- case 5:
- $r = $v;
- $g = $m;
- $b = $mid2;
- break;
- }
- }
- return array(
- $r * 255.0,
- $g * 255.0,
- $b * 255.0,
- );
- }
- return null;
- }
- static function getTriplet($color, $percent = false) {
- $i = strpos($color, "(");
- $j = strpos($color, ")");
- // Bad color value
- if ($i === false || $j === false) {
- return null;
- }
- $triplet = preg_split("/\\s*,\\s*/", trim(substr($color, $i + 1, $j - $i - 1)));
- if (count($triplet) != 3) {
- return null;
- }
- foreach (array_keys($triplet) as $c) {
- $triplet[$c] = trim($triplet[$c]);
- if ($percent) {
- if ($triplet[$c][strlen($triplet[$c]) - 1] === "%") {
- $triplet[$c] = $triplet[$c] / 100;
- }
- else {
- $triplet[$c] = $triplet[$c] / 255;
- }
- }
- else {
- if ($triplet[$c][strlen($triplet[$c]) - 1] === "%") {
- $triplet[$c] = round($triplet[$c] * 2.55);
- }
- }
- }
- return $triplet;
- }
- static function parseHexColor($hex)
- {
- $c = array(0, 0, 0);
- // #FFFFFF
- if (isset($hex[6])) {
- $c[0] = hexdec(substr($hex, 1, 2));
- $c[1] = hexdec(substr($hex, 3, 2));
- $c[2] = hexdec(substr($hex, 5, 2));
- } else {
- $c[0] = hexdec($hex[1] . $hex[1]);
- $c[1] = hexdec($hex[2] . $hex[2]);
- $c[2] = hexdec($hex[3] . $hex[3]);
- }
- return $c;
- }
- /**
- * Simple CSS parser
- *
- * @param $style
- *
- * @return array
- */
- static function parseCssStyle($style)
- {
- $matches = array();
- preg_match_all("/([a-z-]+)\\s*:\\s*([^;$]+)/si", $style, $matches, PREG_SET_ORDER);
- $styles = array();
- foreach ($matches as $match) {
- $styles[$match[1]] = $match[2];
- }
- return $styles;
- }
- /**
- * Convert a size to a float
- *
- * @param string $size SVG size
- * @param float $dpi DPI
- * @param float $fontsize Reference font size
- *
- * @return float|null
- */
- static function convertSize($size, $dpi = 72.0, $fontsize = 11.0) {
- $size = trim(strtolower($size));
- if (is_numeric($size)) {
- return $size;
- }
- if ($pos = strpos($size, "px")) {
- return floatval(substr($size, 0, $pos));
- }
- if ($pos = strpos($size, "pt")) {
- return floatval(substr($size, 0, $pos));
- }
- if ($pos = strpos($size, "%")) {
- return $fontsize * substr($size, 0, $pos) / 100;
- }
- if ($pos = strpos($size, "em")) {
- return $fontsize * substr($size, 0, $pos);
- }
- // TODO cm, mm, pc, in, etc
- return null;
- }
- static $colorNames = array(
- 'antiquewhite' => '#FAEBD7',
- 'aqua' => '#00FFFF',
- 'aquamarine' => '#7FFFD4',
- 'beige' => '#F5F5DC',
- 'black' => '#000000',
- 'blue' => '#0000FF',
- 'brown' => '#A52A2A',
- 'cadetblue' => '#5F9EA0',
- 'chocolate' => '#D2691E',
- 'cornflowerblue' => '#6495ED',
- 'crimson' => '#DC143C',
- 'darkblue' => '#00008B',
- 'darkgoldenrod' => '#B8860B',
- 'darkgreen' => '#006400',
- 'darkmagenta' => '#8B008B',
- 'darkorange' => '#FF8C00',
- 'darkred' => '#8B0000',
- 'darkseagreen' => '#8FBC8F',
- 'darkslategray' => '#2F4F4F',
- 'darkviolet' => '#9400D3',
- 'deepskyblue' => '#00BFFF',
- 'dodgerblue' => '#1E90FF',
- 'firebrick' => '#B22222',
- 'forestgreen' => '#228B22',
- 'fuchsia' => '#FF00FF',
- 'gainsboro' => '#DCDCDC',
- 'gold' => '#FFD700',
- 'gray' => '#808080',
- 'green' => '#008000',
- 'greenyellow' => '#ADFF2F',
- 'hotpink' => '#FF69B4',
- 'indigo' => '#4B0082',
- 'khaki' => '#F0E68C',
- 'lavenderblush' => '#FFF0F5',
- 'lemonchiffon' => '#FFFACD',
- 'lightcoral' => '#F08080',
- 'lightgoldenrodyellow' => '#FAFAD2',
- 'lightgreen' => '#90EE90',
- 'lightsalmon' => '#FFA07A',
- 'lightskyblue' => '#87CEFA',
- 'lightslategray' => '#778899',
- 'lightyellow' => '#FFFFE0',
- 'lime' => '#00FF00',
- 'limegreen' => '#32CD32',
- 'magenta' => '#FF00FF',
- 'maroon' => '#800000',
- 'mediumaquamarine' => '#66CDAA',
- 'mediumorchid' => '#BA55D3',
- 'mediumseagreen' => '#3CB371',
- 'mediumspringgreen' => '#00FA9A',
- 'mediumvioletred' => '#C71585',
- 'midnightblue' => '#191970',
- 'mintcream' => '#F5FFFA',
- 'moccasin' => '#FFE4B5',
- 'navy' => '#000080',
- 'olive' => '#808000',
- 'orange' => '#FFA500',
- 'orchid' => '#DA70D6',
- 'palegreen' => '#98FB98',
- 'palevioletred' => '#D87093',
- 'peachpuff' => '#FFDAB9',
- 'pink' => '#FFC0CB',
- 'powderblue' => '#B0E0E6',
- 'purple' => '#800080',
- 'red' => '#FF0000',
- 'royalblue' => '#4169E1',
- 'salmon' => '#FA8072',
- 'seagreen' => '#2E8B57',
- 'sienna' => '#A0522D',
- 'silver' => '#C0C0C0',
- 'skyblue' => '#87CEEB',
- 'slategray' => '#708090',
- 'springgreen' => '#00FF7F',
- 'steelblue' => '#4682B4',
- 'tan' => '#D2B48C',
- 'teal' => '#008080',
- 'thistle' => '#D8BFD8',
- 'turquoise' => '#40E0D0',
- 'violetred' => '#D02090',
- 'white' => '#FFFFFF',
- 'yellow' => '#FFFF00',
- 'aliceblue' => '#f0f8ff',
- 'azure' => '#f0ffff',
- 'bisque' => '#ffe4c4',
- 'blanchedalmond' => '#ffebcd',
- 'blueviolet' => '#8a2be2',
- 'burlywood' => '#deb887',
- 'chartreuse' => '#7fff00',
- 'coral' => '#ff7f50',
- 'cornsilk' => '#fff8dc',
- 'cyan' => '#00ffff',
- 'darkcyan' => '#008b8b',
- 'darkgray' => '#a9a9a9',
- 'darkgrey' => '#a9a9a9',
- 'darkkhaki' => '#bdb76b',
- 'darkolivegreen' => '#556b2f',
- 'darkorchid' => '#9932cc',
- 'darksalmon' => '#e9967a',
- 'darkslateblue' => '#483d8b',
- 'darkslategrey' => '#2f4f4f',
- 'darkturquoise' => '#00ced1',
- 'deeppink' => '#ff1493',
- 'dimgray' => '#696969',
- 'dimgrey' => '#696969',
- 'floralwhite' => '#fffaf0',
- 'ghostwhite' => '#f8f8ff',
- 'goldenrod' => '#daa520',
- 'grey' => '#808080',
- 'honeydew' => '#f0fff0',
- 'indianred' => '#cd5c5c',
- 'ivory' => '#fffff0',
- 'lavender' => '#e6e6fa',
- 'lawngreen' => '#7cfc00',
- 'lightblue' => '#add8e6',
- 'lightcyan' => '#e0ffff',
- 'lightgray' => '#d3d3d3',
- 'lightgrey' => '#d3d3d3',
- 'lightpink' => '#ffb6c1',
- 'lightseagreen' => '#20b2aa',
- 'lightslategrey' => '#778899',
- 'lightsteelblue' => '#b0c4de',
- 'linen' => '#faf0e6',
- 'mediumblue' => '#0000cd',
- 'mediumpurple' => '#9370db',
- 'mediumslateblue' => '#7b68ee',
- 'mediumturquoise' => '#48d1cc',
- 'mistyrose' => '#ffe4e1',
- 'navajowhite' => '#ffdead',
- 'oldlace' => '#fdf5e6',
- 'olivedrab' => '#6b8e23',
- 'orangered' => '#ff4500',
- 'palegoldenrod' => '#eee8aa',
- 'paleturquoise' => '#afeeee',
- 'papayawhip' => '#ffefd5',
- 'peru' => '#cd853f',
- 'plum' => '#dda0dd',
- 'rosybrown' => '#bc8f8f',
- 'saddlebrown' => '#8b4513',
- 'sandybrown' => '#f4a460',
- 'seashell' => '#fff5ee',
- 'slateblue' => '#6a5acd',
- 'slategrey' => '#708090',
- 'snow' => '#fffafa',
- 'tomato' => '#ff6347',
- 'violet' => '#ee82ee',
- 'wheat' => '#f5deb3',
- 'whitesmoke' => '#f5f5f5',
- 'yellowgreen' => '#9acd32',
- );
- }