* @package cleversvg * @subpackage elements */ class csBaseElement { protected $dom_document = null, $attributes = array(), $styles = array(), $transforms = array(), $xml_node_name = 'unknown'; /** * Manage object cloning * */ public function __clone() { $this->deteleAttribute('id'); } /** * Adds a transformation to current shape * * @param string $type Transform type (matrix, translate, etc...) * @param array $params Parameters of transformation * @link http://www.w3.org/TR/SVG11/coords.html#TransformAttribute */ protected function addTransform($type, $params=array()) { static $types = array('matrix', 'translate', 'scale', 'rotate', 'skewX', 'skewY'); if (!in_array($type, $types)) { throw new csException(sprintf('"%s" is not a valid transform type', $type)); } $this->transforms[$type] = $params; } /** * Computes DOMXML Node * * @param boolean $embedded Is SVG element embedded ? * @return DOMElement */ protected function compile($embedded=false) { $dom = $this->getDomDocument(); $element_node = $dom->createElement($this->getElementName($embedded)); // Attributes foreach ($this->attributes as $attr_name => $attr_value) { if (!is_null($attr_value)) { switch ($attr_name) { case 'style': $styles = array(); if (is_array($attr_value)) { foreach ($attr_value as $style_name => $style_value) { $styles[] = sprintf('%s: %s', $style_name, (string)$style_value); } } if (count($styles) > 0) { $element_node->setAttribute('style', implode('; ', $styles)); } break; default: $element_node->setAttribute($attr_name, $attr_value); break; } } } // Transformations, if any if (count($this->transforms) > 0) { $transforms = array(); foreach ($this->transforms as $transform_name => $transform_params) { $transforms[] = sprintf('%s(%s)', $transform_name, implode(',', $transform_params)); } $element_node->setAttribute('transform', implode(' ', $transforms)); } return $element_node; } /** * Gets the current depth * * @return mixed (int depth or NULL) */ public function getDepth() { if (array_key_exists('style', $this->attributes) && array_key_exists('z-index', $this->attributes['style'])) { return (int) $this->attributes['style']['z-index']; } else { return null; } } /** * Returns a DOM DOcument * * @return DOMDocument */ public function getDomDocument() { if (is_null($this->dom_document)) { $this->dom_document = new DOMDocument('1.0', 'UTF-8'); } return $this->dom_document; } /** * Gets the node name of current SVG element * * @param boolean $embedded * @return string */ public function getElementName($embedded = false) { if ($embedded === true) { $node_name = 'svg:'.$this->xml_node_name; } else { $node_name = $this->xml_node_name; } return $node_name; } /** * Specifies a transformation in the form of a transformation matrix of * six values * * @param int $a * @param int $b * @param int $c * @param int $d * @param int $e * @param int $f */ public function matrix($a, $b, $c, $d, $e, $f) { $this->addTransform('matrix', array($a, $b, $c, $d, $e, $f)); } /** * Rotates shape * * @param int $angle * @param int $cx * @param int $cy */ public function rotate($angle, $cx=0, $cy=0) { $this->addTransform('rotate', array($angle, $cx, $cy)); } /** * Scales shape * * @param int $xscale * @param int $yscale */ public function scale($xscale, $yscale=null) { $params = array($xscale); if ($yscale) { $params[] = $yscale; } $this->addTransform('scale', $params); } /** * Specifies a skew transformation along the x-axis * * @param int $angle */ public function skewX($angle) { $this->addTransform('skewX', array($angle)); } /** * Specifies a skew transformation along the y-axis * * @param int $angle */ public function skewY($angle) { $this->addTransform('skewY', array($angle)); } /** * Translates shape * * @param int $tx * @param int $ty */ public function translate($tx, $ty=null) { $params = array($tx); if ($ty) { $params[] = $ty; } $this->addTransform('translate', $params); } /** * Deletes an attribute * */ protected function deteleAttribute($name) { if (array_key_exists($name, $this->attributes)) { unset($this->attributes[$name]); } } /** * Sets an attribute for current element * * @param string $name * @param mixed $value * @param string $default Default value */ protected function setAttribute($name, $value, $default=null) { if (!is_null($default) && is_null($value)) { $value = $default; } if (!is_null($value)) { $this->attributes[strtolower($name)] = $value; } } /** * Sets the depth of object * * @param int $depth */ public function setDepth($depth) { if (is_null($depth)) { unset($this->attributes['style']['z-index']); } elseif (is_int($depth)) { $this->attributes['style']['z-index'] = (string) $depth; } } /** * Gets the DOM id of current element tag * * @return mixed (string id or NULL) */ public function getId() { if (isset($this->attributes['id'])) { return $this->attributes['id']; } else { return null; } } /** * Sets the DOM id of current element tag * * @param string $id */ public function setId($id) { if (is_string($id) && trim($id) != '') { $this->setAttribute('id', $id); } } /** * Sets a SVG style via an associative array * * @param array $style */ public function setStyle($style) { // Styles properties bellow should be treated as attributes and not // in a style attribute (FF 1.5 compat) $convert_styles = array('stroke', 'stroke-width', 'fill'); foreach ($style as $style_name => $style_value) { if (in_array($style_name, $convert_styles)) { $this->setAttribute($style_name, $style_value); unset($style[$style_name]); } } if (count($style) > 0) { $this->setAttribute('style', $style); } } }