示例#1
0
 /**
  * Handles rendering the element on the pdf.
  *
  * @param pdf $pdf the pdf object
  * @param bool $preview true if it is a preview, false otherwise
  */
 public function render($pdf, $preview)
 {
     $colour = TCPDF_COLORS::convertHTMLColorToDec($this->element->colour, $colour);
     $pdf->SetLineStyle(array('width' => $this->element->data, 'color' => $colour));
     $pdf->Line(0, 0, $pdf->getPageWidth(), 0);
     $pdf->Line($pdf->getPageWidth(), 0, $pdf->getPageWidth(), $pdf->getPageHeight());
     $pdf->Line(0, $pdf->getPageHeight(), $pdf->getPageWidth(), $pdf->getPageHeight());
     $pdf->Line(0, 0, 0, $pdf->getPageHeight());
 }
示例#2
0
 /**
  * Sets the opening SVG element handler function for the XML parser. (*** TO BE COMPLETED ***)
  * @param $parser (resource) The first parameter, parser, is a reference to the XML parser calling the handler.
  * @param $name (string) The second parameter, name, contains the name of the element for which this handler is called. If case-folding is in effect for this parser, the element name will be in uppercase letters.
  * @param $attribs (array) The third parameter, attribs, contains an associative array with the element's attributes (if any). The keys of this array are the attribute names, the values are the attribute values. Attribute names are case-folded on the same criteria as element names. Attribute values are not case-folded. The original order of the attributes can be retrieved by walking through attribs the normal way, using each(). The first key in the array was the first attribute, and so on.
  * @param $ctm (array) tranformation matrix for clipping mode (starting transformation matrix).
  * @author Nicola Asuni
  * @since 5.0.000 (2010-05-02)
  * @protected
  */
 protected function startSVGElementHandler($parser, $name, $attribs, $ctm = array())
 {
     // check if we are in clip mode
     if ($this->svgclipmode) {
         $this->svgclippaths[$this->svgclipid][] = array('name' => $name, 'attribs' => $attribs, 'tm' => $this->svgcliptm[$this->svgclipid]);
         return;
     }
     if ($this->svgdefsmode and !in_array($name, array('clipPath', 'linearGradient', 'radialGradient', 'stop'))) {
         if (!isset($attribs['id'])) {
             $attribs['id'] = 'DF_' . (count($this->svgdefs) + 1);
         }
         $this->svgdefs[$attribs['id']] = array('name' => $name, 'attribs' => $attribs);
         return;
     }
     $clipping = false;
     if ($parser == 'clip-path') {
         // set clipping mode
         $clipping = true;
     }
     // get styling properties
     $prev_svgstyle = $this->svgstyles[count($this->svgstyles) - 1];
     // previous style
     $svgstyle = $this->svgstyles[0];
     // set default style
     if ($clipping and !isset($attribs['fill']) and (!isset($attribs['style']) or !preg_match('/[;\\"\\s]{1}fill[\\s]*:[\\s]*([^;\\"]*)/si', $attribs['style'], $attrval))) {
         // default fill attribute for clipping
         $attribs['fill'] = 'none';
     }
     if (isset($attribs['style']) and !TCPDF_STATIC::empty_string($attribs['style'])) {
         // fix style for regular expression
         $attribs['style'] = ';' . $attribs['style'];
     }
     foreach ($prev_svgstyle as $key => $val) {
         if (in_array($key, TCPDF_IMAGES::$svginheritprop)) {
             // inherit previous value
             $svgstyle[$key] = $val;
         }
         if (isset($attribs[$key]) and !TCPDF_STATIC::empty_string($attribs[$key])) {
             // specific attribute settings
             if ($attribs[$key] == 'inherit') {
                 $svgstyle[$key] = $val;
             } else {
                 $svgstyle[$key] = $attribs[$key];
             }
         } elseif (isset($attribs['style']) and !TCPDF_STATIC::empty_string($attribs['style'])) {
             // CSS style syntax
             $attrval = array();
             if (preg_match('/[;\\"\\s]{1}' . $key . '[\\s]*:[\\s]*([^;\\"]*)/si', $attribs['style'], $attrval) and isset($attrval[1])) {
                 if ($attrval[1] == 'inherit') {
                     $svgstyle[$key] = $val;
                 } else {
                     $svgstyle[$key] = $attrval[1];
                 }
             }
         }
     }
     // transformation matrix
     if (!empty($ctm)) {
         $tm = $ctm;
     } else {
         //$tm = $this->svgstyles[(count($this->svgstyles) - 1)]['transfmatrix'];
         $tm = array(1, 0, 0, 1, 0, 0);
     }
     if (isset($attribs['transform']) and !empty($attribs['transform'])) {
         $tm = TCPDF_STATIC::getTransformationMatrixProduct($tm, TCPDF_STATIC::getSVGTransformMatrix($attribs['transform']));
     }
     $svgstyle['transfmatrix'] = $tm;
     $invisible = false;
     if ($svgstyle['visibility'] == 'hidden' or $svgstyle['visibility'] == 'collapse' or $svgstyle['display'] == 'none') {
         // the current graphics element is invisible (nothing is painted)
         $invisible = true;
     }
     // process tag
     switch ($name) {
         case 'defs':
             $this->svgdefsmode = true;
             break;
             // clipPath
         // clipPath
         case 'clipPath':
             if ($invisible) {
                 break;
             }
             $this->svgclipmode = true;
             if (!isset($attribs['id'])) {
                 $attribs['id'] = 'CP_' . (count($this->svgcliptm) + 1);
             }
             $this->svgclipid = $attribs['id'];
             $this->svgclippaths[$this->svgclipid] = array();
             $this->svgcliptm[$this->svgclipid] = $tm;
             break;
         case 'svg':
             // start of SVG object
             break;
         case 'g':
             // group together related graphics elements
             array_push($this->svgstyles, $svgstyle);
             $this->StartTransform();
             $this->SVGTransform($tm);
             $this->setSVGStyles($svgstyle, $prev_svgstyle);
             break;
         case 'linearGradient':
             if ($this->pdfa_mode) {
                 break;
             }
             if (!isset($attribs['id'])) {
                 $attribs['id'] = 'GR_' . (count($this->svggradients) + 1);
             }
             $this->svggradientid = $attribs['id'];
             $this->svggradients[$this->svggradientid] = array();
             $this->svggradients[$this->svggradientid]['type'] = 2;
             $this->svggradients[$this->svggradientid]['stops'] = array();
             if (isset($attribs['gradientUnits'])) {
                 $this->svggradients[$this->svggradientid]['gradientUnits'] = $attribs['gradientUnits'];
             } else {
                 $this->svggradients[$this->svggradientid]['gradientUnits'] = 'objectBoundingBox';
             }
             //$attribs['spreadMethod']
             if (!isset($attribs['x1']) and !isset($attribs['y1']) and !isset($attribs['x2']) and !isset($attribs['y2']) or (isset($attribs['x1']) and substr($attribs['x1'], -1) == '%' or isset($attribs['y1']) and substr($attribs['y1'], -1) == '%' or isset($attribs['x2']) and substr($attribs['x2'], -1) == '%' or isset($attribs['y2']) and substr($attribs['y2'], -1) == '%')) {
                 $this->svggradients[$this->svggradientid]['mode'] = 'percentage';
             } else {
                 $this->svggradients[$this->svggradientid]['mode'] = 'measure';
             }
             $x1 = isset($attribs['x1']) ? $attribs['x1'] : '0';
             $y1 = isset($attribs['y1']) ? $attribs['y1'] : '0';
             $x2 = isset($attribs['x2']) ? $attribs['x2'] : '100';
             $y2 = isset($attribs['y2']) ? $attribs['y2'] : '0';
             if (isset($attribs['gradientTransform'])) {
                 $this->svggradients[$this->svggradientid]['gradientTransform'] = TCPDF_STATIC::getSVGTransformMatrix($attribs['gradientTransform']);
             }
             $this->svggradients[$this->svggradientid]['coords'] = array($x1, $y1, $x2, $y2);
             if (isset($attribs['xlink:href']) and !empty($attribs['xlink:href'])) {
                 // gradient is defined on another place
                 $this->svggradients[$this->svggradientid]['xref'] = substr($attribs['xlink:href'], 1);
             }
             break;
         case 'radialGradient':
             if ($this->pdfa_mode) {
                 break;
             }
             if (!isset($attribs['id'])) {
                 $attribs['id'] = 'GR_' . (count($this->svggradients) + 1);
             }
             $this->svggradientid = $attribs['id'];
             $this->svggradients[$this->svggradientid] = array();
             $this->svggradients[$this->svggradientid]['type'] = 3;
             $this->svggradients[$this->svggradientid]['stops'] = array();
             if (isset($attribs['gradientUnits'])) {
                 $this->svggradients[$this->svggradientid]['gradientUnits'] = $attribs['gradientUnits'];
             } else {
                 $this->svggradients[$this->svggradientid]['gradientUnits'] = 'objectBoundingBox';
             }
             //$attribs['spreadMethod']
             if (!isset($attribs['cx']) and !isset($attribs['cy']) or (isset($attribs['cx']) and substr($attribs['cx'], -1) == '%' or isset($attribs['cy']) and substr($attribs['cy'], -1) == '%')) {
                 $this->svggradients[$this->svggradientid]['mode'] = 'percentage';
             } else {
                 $this->svggradients[$this->svggradientid]['mode'] = 'measure';
             }
             $cx = isset($attribs['cx']) ? $attribs['cx'] : 0.5;
             $cy = isset($attribs['cy']) ? $attribs['cy'] : 0.5;
             $fx = isset($attribs['fx']) ? $attribs['fx'] : $cx;
             $fy = isset($attribs['fy']) ? $attribs['fy'] : $cy;
             $r = isset($attribs['r']) ? $attribs['r'] : 0.5;
             if (isset($attribs['gradientTransform'])) {
                 $this->svggradients[$this->svggradientid]['gradientTransform'] = TCPDF_STATIC::getSVGTransformMatrix($attribs['gradientTransform']);
             }
             $this->svggradients[$this->svggradientid]['coords'] = array($cx, $cy, $fx, $fy, $r);
             if (isset($attribs['xlink:href']) and !empty($attribs['xlink:href'])) {
                 // gradient is defined on another place
                 $this->svggradients[$this->svggradientid]['xref'] = substr($attribs['xlink:href'], 1);
             }
             break;
         case 'stop':
             // gradient stops
             if (substr($attribs['offset'], -1) == '%') {
                 $offset = floatval(substr($attribs['offset'], -1)) / 100;
             } else {
                 $offset = floatval($attribs['offset']);
                 if ($offset > 1) {
                     $offset /= 100;
                 }
             }
             $stop_color = isset($svgstyle['stop-color']) ? TCPDF_COLORS::convertHTMLColorToDec($svgstyle['stop-color'], $this->spot_colors) : 'black';
             $opacity = isset($svgstyle['stop-opacity']) ? $svgstyle['stop-opacity'] : 1;
             $this->svggradients[$this->svggradientid]['stops'][] = array('offset' => $offset, 'color' => $stop_color, 'opacity' => $opacity);
             break;
             // paths
         // paths
         case 'path':
             if ($invisible) {
                 break;
             }
             if (isset($attribs['d'])) {
                 $d = trim($attribs['d']);
                 if (!empty($d)) {
                     if ($clipping) {
                         $this->SVGTransform($tm);
                         $this->SVGPath($d, 'CNZ');
                     } else {
                         $this->StartTransform();
                         $this->SVGTransform($tm);
                         $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, 0, 0, 1, 1, 'SVGPath', array($d, 'CNZ'));
                         if (!empty($obstyle)) {
                             $this->SVGPath($d, $obstyle);
                         }
                         $this->StopTransform();
                     }
                 }
             }
             break;
             // shapes
         // shapes
         case 'rect':
             if ($invisible) {
                 break;
             }
             $x = isset($attribs['x']) ? $this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false) : 0;
             $y = isset($attribs['y']) ? $this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false) : 0;
             $w = isset($attribs['width']) ? $this->getHTMLUnitToUnits($attribs['width'], 0, $this->svgunit, false) : 0;
             $h = isset($attribs['height']) ? $this->getHTMLUnitToUnits($attribs['height'], 0, $this->svgunit, false) : 0;
             $rx = isset($attribs['rx']) ? $this->getHTMLUnitToUnits($attribs['rx'], 0, $this->svgunit, false) : 0;
             $ry = isset($attribs['ry']) ? $this->getHTMLUnitToUnits($attribs['ry'], 0, $this->svgunit, false) : $rx;
             if ($clipping) {
                 $this->SVGTransform($tm);
                 $this->RoundedRectXY($x, $y, $w, $h, $rx, $ry, '1111', 'CNZ', array(), array());
             } else {
                 $this->StartTransform();
                 $this->SVGTransform($tm);
                 $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'RoundedRectXY', array($x, $y, $w, $h, $rx, $ry, '1111', 'CNZ'));
                 if (!empty($obstyle)) {
                     $this->RoundedRectXY($x, $y, $w, $h, $rx, $ry, '1111', $obstyle, array(), array());
                 }
                 $this->StopTransform();
             }
             break;
         case 'circle':
             if ($invisible) {
                 break;
             }
             $r = isset($attribs['r']) ? $this->getHTMLUnitToUnits($attribs['r'], 0, $this->svgunit, false) : 0;
             $cx = isset($attribs['cx']) ? $this->getHTMLUnitToUnits($attribs['cx'], 0, $this->svgunit, false) : (isset($attribs['x']) ? $this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false) : 0);
             $cy = isset($attribs['cy']) ? $this->getHTMLUnitToUnits($attribs['cy'], 0, $this->svgunit, false) : (isset($attribs['y']) ? $this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false) : 0);
             $x = $cx - $r;
             $y = $cy - $r;
             $w = 2 * $r;
             $h = $w;
             if ($clipping) {
                 $this->SVGTransform($tm);
                 $this->Circle($cx, $cy, $r, 0, 360, 'CNZ', array(), array(), 8);
             } else {
                 $this->StartTransform();
                 $this->SVGTransform($tm);
                 $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Circle', array($cx, $cy, $r, 0, 360, 'CNZ'));
                 if (!empty($obstyle)) {
                     $this->Circle($cx, $cy, $r, 0, 360, $obstyle, array(), array(), 8);
                 }
                 $this->StopTransform();
             }
             break;
         case 'ellipse':
             if ($invisible) {
                 break;
             }
             $rx = isset($attribs['rx']) ? $this->getHTMLUnitToUnits($attribs['rx'], 0, $this->svgunit, false) : 0;
             $ry = isset($attribs['ry']) ? $this->getHTMLUnitToUnits($attribs['ry'], 0, $this->svgunit, false) : 0;
             $cx = isset($attribs['cx']) ? $this->getHTMLUnitToUnits($attribs['cx'], 0, $this->svgunit, false) : (isset($attribs['x']) ? $this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false) : 0);
             $cy = isset($attribs['cy']) ? $this->getHTMLUnitToUnits($attribs['cy'], 0, $this->svgunit, false) : (isset($attribs['y']) ? $this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false) : 0);
             $x = $cx - $rx;
             $y = $cy - $ry;
             $w = 2 * $rx;
             $h = 2 * $ry;
             if ($clipping) {
                 $this->SVGTransform($tm);
                 $this->Ellipse($cx, $cy, $rx, $ry, 0, 0, 360, 'CNZ', array(), array(), 8);
             } else {
                 $this->StartTransform();
                 $this->SVGTransform($tm);
                 $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Ellipse', array($cx, $cy, $rx, $ry, 0, 0, 360, 'CNZ'));
                 if (!empty($obstyle)) {
                     $this->Ellipse($cx, $cy, $rx, $ry, 0, 0, 360, $obstyle, array(), array(), 8);
                 }
                 $this->StopTransform();
             }
             break;
         case 'line':
             if ($invisible) {
                 break;
             }
             $x1 = isset($attribs['x1']) ? $this->getHTMLUnitToUnits($attribs['x1'], 0, $this->svgunit, false) : 0;
             $y1 = isset($attribs['y1']) ? $this->getHTMLUnitToUnits($attribs['y1'], 0, $this->svgunit, false) : 0;
             $x2 = isset($attribs['x2']) ? $this->getHTMLUnitToUnits($attribs['x2'], 0, $this->svgunit, false) : 0;
             $y2 = isset($attribs['y2']) ? $this->getHTMLUnitToUnits($attribs['y2'], 0, $this->svgunit, false) : 0;
             $x = $x1;
             $y = $y1;
             $w = abs($x2 - $x1);
             $h = abs($y2 - $y1);
             if (!$clipping) {
                 $this->StartTransform();
                 $this->SVGTransform($tm);
                 $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Line', array($x1, $y1, $x2, $y2));
                 $this->Line($x1, $y1, $x2, $y2);
                 $this->StopTransform();
             }
             break;
         case 'polyline':
         case 'polygon':
             if ($invisible) {
                 break;
             }
             $points = isset($attribs['points']) ? $attribs['points'] : '0 0';
             $points = trim($points);
             // note that point may use a complex syntax not covered here
             $points = preg_split('/[\\,\\s]+/si', $points);
             if (count($points) < 4) {
                 break;
             }
             $p = array();
             $xmin = 2147483647;
             $xmax = 0;
             $ymin = 2147483647;
             $ymax = 0;
             foreach ($points as $key => $val) {
                 $p[$key] = $this->getHTMLUnitToUnits($val, 0, $this->svgunit, false);
                 if ($key % 2 == 0) {
                     // X coordinate
                     $xmin = min($xmin, $p[$key]);
                     $xmax = max($xmax, $p[$key]);
                 } else {
                     // Y coordinate
                     $ymin = min($ymin, $p[$key]);
                     $ymax = max($ymax, $p[$key]);
                 }
             }
             $x = $xmin;
             $y = $ymin;
             $w = $xmax - $xmin;
             $h = $ymax - $ymin;
             if ($name == 'polyline') {
                 $this->StartTransform();
                 $this->SVGTransform($tm);
                 $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'PolyLine', array($p, 'CNZ'));
                 if (!empty($obstyle)) {
                     $this->PolyLine($p, $obstyle, array(), array());
                 }
                 $this->StopTransform();
             } else {
                 // polygon
                 if ($clipping) {
                     $this->SVGTransform($tm);
                     $this->Polygon($p, 'CNZ', array(), array(), true);
                 } else {
                     $this->StartTransform();
                     $this->SVGTransform($tm);
                     $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Polygon', array($p, 'CNZ'));
                     if (!empty($obstyle)) {
                         $this->Polygon($p, $obstyle, array(), array(), true);
                     }
                     $this->StopTransform();
                 }
             }
             break;
             // image
         // image
         case 'image':
             if ($invisible) {
                 break;
             }
             if (!isset($attribs['xlink:href']) or empty($attribs['xlink:href'])) {
                 break;
             }
             $x = isset($attribs['x']) ? $this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false) : 0;
             $y = isset($attribs['y']) ? $this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false) : 0;
             $w = isset($attribs['width']) ? $this->getHTMLUnitToUnits($attribs['width'], 0, $this->svgunit, false) : 0;
             $h = isset($attribs['height']) ? $this->getHTMLUnitToUnits($attribs['height'], 0, $this->svgunit, false) : 0;
             $img = $attribs['xlink:href'];
             if (!$clipping) {
                 $this->StartTransform();
                 $this->SVGTransform($tm);
                 $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h);
                 if (preg_match('/^data:image\\/[^;]+;base64,/', $img, $m) > 0) {
                     // embedded image encoded as base64
                     $img = '@' . base64_decode(substr($img, strlen($m[0])));
                 } else {
                     // fix image path
                     if (!TCPDF_STATIC::empty_string($this->svgdir) and ($img[0] == '.' or basename($img) == $img)) {
                         // replace relative path with full server path
                         $img = $this->svgdir . '/' . $img;
                     }
                     if ($img[0] == '/' and !empty($_SERVER['DOCUMENT_ROOT']) and $_SERVER['DOCUMENT_ROOT'] != '/') {
                         $findroot = strpos($img, $_SERVER['DOCUMENT_ROOT']);
                         if ($findroot === false or $findroot > 1) {
                             if (substr($_SERVER['DOCUMENT_ROOT'], -1) == '/') {
                                 $img = substr($_SERVER['DOCUMENT_ROOT'], 0, -1) . $img;
                             } else {
                                 $img = $_SERVER['DOCUMENT_ROOT'] . $img;
                             }
                         }
                     }
                     $img = urldecode($img);
                     $testscrtype = @parse_url($img);
                     if (!isset($testscrtype['query']) or empty($testscrtype['query'])) {
                         // convert URL to server path
                         $img = str_replace(K_PATH_URL, K_PATH_MAIN, $img);
                     }
                 }
                 // get image type
                 $imgtype = TCPDF_IMAGES::getImageFileType($img);
                 if ($imgtype == 'eps' or $imgtype == 'ai') {
                     $this->ImageEps($img, $x, $y, $w, $h);
                 } elseif ($imgtype == 'svg') {
                     $this->ImageSVG($img, $x, $y, $w, $h);
                 } else {
                     $this->Image($img, $x, $y, $w, $h);
                 }
                 $this->StopTransform();
             }
             break;
             // text
         // text
         case 'text':
         case 'tspan':
             // only basic support - advanced features must be implemented
             $this->svgtextmode['invisible'] = $invisible;
             if ($invisible) {
                 break;
             }
             array_push($this->svgstyles, $svgstyle);
             if (isset($attribs['x'])) {
                 $x = $this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false);
             } elseif ($name == 'tspan') {
                 $x = $this->x;
             } else {
                 $x = 0;
             }
             if (isset($attribs['dx'])) {
                 $x += $this->getHTMLUnitToUnits($attribs['dx'], 0, $this->svgunit, false);
             }
             if (isset($attribs['y'])) {
                 $y = $this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false);
             } elseif ($name == 'tspan') {
                 $y = $this->y;
             } else {
                 $y = 0;
             }
             if (isset($attribs['dy'])) {
                 $y += $this->getHTMLUnitToUnits($attribs['dy'], 0, $this->svgunit, false);
             }
             $svgstyle['text-color'] = $svgstyle['fill'];
             $this->svgtext = '';
             if (isset($svgstyle['text-anchor'])) {
                 $this->svgtextmode['text-anchor'] = $svgstyle['text-anchor'];
             } else {
                 $this->svgtextmode['text-anchor'] = 'start';
             }
             if (isset($svgstyle['direction'])) {
                 if ($svgstyle['direction'] == 'rtl') {
                     $this->svgtextmode['rtl'] = true;
                 } else {
                     $this->svgtextmode['rtl'] = false;
                 }
             } else {
                 $this->svgtextmode['rtl'] = false;
             }
             if (isset($svgstyle['stroke']) and $svgstyle['stroke'] != 'none' and isset($svgstyle['stroke-width']) and $svgstyle['stroke-width'] > 0) {
                 $this->svgtextmode['stroke'] = $this->getHTMLUnitToUnits($svgstyle['stroke-width'], 0, $this->svgunit, false);
             } else {
                 $this->svgtextmode['stroke'] = false;
             }
             $this->StartTransform();
             $this->SVGTransform($tm);
             $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, 1, 1);
             $this->x = $x;
             $this->y = $y;
             break;
             // use
         // use
         case 'use':
             if (isset($attribs['xlink:href']) and !empty($attribs['xlink:href'])) {
                 $svgdefid = substr($attribs['xlink:href'], 1);
                 if (isset($this->svgdefs[$svgdefid])) {
                     $use = $this->svgdefs[$svgdefid];
                     if (isset($attribs['xlink:href'])) {
                         unset($attribs['xlink:href']);
                     }
                     if (isset($attribs['id'])) {
                         unset($attribs['id']);
                     }
                     $attribs = array_merge($attribs, $use['attribs']);
                     $this->startSVGElementHandler($parser, $use['name'], $attribs);
                 }
             }
             break;
         default:
             break;
     }
     // end of switch
 }
示例#3
0
 public function Footer()
 {
     if ($this->vendor->vendor_letter_footer == 1) {
         $footertxt = '<style>' . $this->css . '</style>';
         $footertxt .= '<div id="vmdoc-footer" class="vmdoc-footer">' . $this->replace_variables($this->vendor->vendor_letter_footer_html) . '</div>';
         $currentCHRF = $this->getCellHeightRatio();
         $this->setCellHeightRatio($this->vendor->vendor_letter_footer_cell_height_ratio);
         if (!class_exists('JFile')) {
             require VMPATH_LIBS . DS . 'joomla' . DS . 'filesystem' . DS . 'file.php';
         }
         $this->tcpdf6 = JFile::exists(VMPATH_LIBS . DS . 'tcpdf' . DS . 'include' . DS . 'tcpdf_colors.php');
         if ($this->tcpdf6) {
             $this->tcpdf6 = method_exists('TCPDF', 'getAllSpotColors');
         }
         if ($this->tcpdf6) {
             $getAllSpotColors = TCPDF::getAllSpotColors();
             $vlfooterlcolor = TCPDF_COLORS::convertHTMLColorToDec($this->vendor->vendor_letter_footer_line_color, $getAllSpotColors);
         } else {
             $vlfooterlcolor = $this->convertHTMLColorToDec($this->vendor->vendor_letter_footer_line_color);
         }
         //set style for cell border
         $border = 0;
         if ($this->vendor->vendor_letter_footer_line == 1) {
             $line_width = 0.85 / $this->getScaleFactor();
             $this->SetLineStyle(array('width' => $line_width, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $vlfooterlcolor));
             $border = 'T';
         }
         // TODO: Implement cell_height
         // 				$cell_height = round(($this->getCellHeightRatio() * $footerfont[2]) / $this->getScaleFactor(), 2);
         $cell_height = 1;
         $this->writeHTMLCell(0, $cell_height, '', '', $footertxt, $border, 1, 0, true, '', true);
         // Set it back
         $this->setCellHeightRatio($currentCHRF);
     }
 }
	/**
	 * Sets the opening SVG element handler function for the XML parser. (*** TO BE COMPLETED ***)
	 * @param $parser (resource) The first parameter, parser, is a reference to the XML parser calling the handler.
	 * @param $name (string) The second parameter, name, contains the name of the element for which this handler is called. If case-folding is in effect for this parser, the element name will be in uppercase letters.
	 * @param $attribs (array) The third parameter, attribs, contains an associative array with the element's attributes (if any). The keys of this array are the attribute names, the values are the attribute values. Attribute names are case-folded on the same criteria as element names. Attribute values are not case-folded. The original order of the attributes can be retrieved by walking through attribs the normal way, using each(). The first key in the array was the first attribute, and so on.
	 * @param $ctm (array) tranformation matrix for clipping mode (starting transformation matrix).
	 * @author Nicola Asuni
	 * @since 5.0.000 (2010-05-02)
	 * @protected
	 */
	protected function startSVGElementHandler($parser, $name, $attribs, $ctm=array()) {
		$name = $this->removeTagNamespace($name);
		// check if we are in clip mode
		if ($this->svgclipmode) {
			$this->svgclippaths[$this->svgclipid][] = array('name' => $name, 'attribs' => $attribs, 'tm' => $this->svgcliptm[$this->svgclipid]);
			return;
		}
		if ($this->svgdefsmode AND !in_array($name, array('clipPath', 'linearGradient', 'radialGradient', 'stop'))) {
			if (isset($attribs['id'])) {
				$attribs['child_elements'] = array();
				$this->svgdefs[$attribs['id']] = array('name' => $name, 'attribs' => $attribs);
				return;
			}
			if (end($this->svgdefs) !== FALSE) {
				$last_svgdefs_id = key($this->svgdefs);
				if (isset($this->svgdefs[$last_svgdefs_id]['attribs']['child_elements'])) {
					$attribs['id'] = 'DF_'.(count($this->svgdefs[$last_svgdefs_id]['attribs']['child_elements']) + 1);
					$this->svgdefs[$last_svgdefs_id]['attribs']['child_elements'][$attribs['id']] = array('name' => $name, 'attribs' => $attribs);
					return;
				}
			}
			return;
		}
		$clipping = false;
		if ($parser == 'clip-path') {
			// set clipping mode
			$clipping = true;
		}
		// get styling properties
		$prev_svgstyle = $this->svgstyles[max(0,(count($this->svgstyles) - 1))]; // previous style
		$svgstyle = $this->svgstyles[0]; // set default style
		if ($clipping AND !isset($attribs['fill']) AND (!isset($attribs['style']) OR (!preg_match('/[;\"\s]{1}fill[\s]*:[\s]*([^;\"]*)/si', $attribs['style'], $attrval)))) {
			// default fill attribute for clipping
			$attribs['fill'] = 'none';
		}
		if (isset($attribs['style']) AND !TCPDF_STATIC::empty_string($attribs['style']) AND ($attribs['style'][0] != ';')) {
			// fix style for regular expression
			$attribs['style'] = ';'.$attribs['style'];
		}
		foreach ($prev_svgstyle as $key => $val) {
			if (in_array($key, TCPDF_IMAGES::$svginheritprop)) {
				// inherit previous value
				$svgstyle[$key] = $val;
			}
			if (isset($attribs[$key]) AND !TCPDF_STATIC::empty_string($attribs[$key])) {
				// specific attribute settings
				if ($attribs[$key] == 'inherit') {
					$svgstyle[$key] = $val;
				} else {
					$svgstyle[$key] = $attribs[$key];
				}
			} elseif (isset($attribs['style']) AND !TCPDF_STATIC::empty_string($attribs['style'])) {
				// CSS style syntax
				$attrval = array();
				if (preg_match('/[;\"\s]{1}'.$key.'[\s]*:[\s]*([^;\"]*)/si', $attribs['style'], $attrval) AND isset($attrval[1])) {
					if ($attrval[1] == 'inherit') {
						$svgstyle[$key] = $val;
					} else {
						$svgstyle[$key] = $attrval[1];
					}
				}
			}
		}
		// transformation matrix
		if (!empty($ctm)) {
			$tm = $ctm;
		} else {
			$tm = array(1,0,0,1,0,0);
		}
		if (isset($attribs['transform']) AND !empty($attribs['transform'])) {
			$tm = TCPDF_STATIC::getTransformationMatrixProduct($tm, TCPDF_STATIC::getSVGTransformMatrix($attribs['transform']));
		}
		$svgstyle['transfmatrix'] = $tm;
		$invisible = false;
		if (($svgstyle['visibility'] == 'hidden') OR ($svgstyle['visibility'] == 'collapse') OR ($svgstyle['display'] == 'none')) {
			// the current graphics element is invisible (nothing is painted)
			$invisible = true;
		}
		// process tag
		switch($name) {
			case 'defs': {
				$this->svgdefsmode = true;
				break;
			}
			// clipPath
			case 'clipPath': {
				if ($invisible) {
					break;
				}
				$this->svgclipmode = true;
				if (!isset($attribs['id'])) {
					$attribs['id'] = 'CP_'.(count($this->svgcliptm) + 1);
				}
				$this->svgclipid = $attribs['id'];
				$this->svgclippaths[$this->svgclipid] = array();
				$this->svgcliptm[$this->svgclipid] = $tm;
				break;
			}
			case 'svg': {
				// start of SVG object
				if(++$this->svg_tag_depth <= 1) {
					break;
				}
				// inner SVG
				array_push($this->svgstyles, $svgstyle);
				$this->StartTransform();
				$svgX = (isset($attribs['x'])?$attribs['x']:0);
				$svgY = (isset($attribs['y'])?$attribs['y']:0);
				$svgW = (isset($attribs['width'])?$attribs['width']:0);
				$svgH = (isset($attribs['height'])?$attribs['height']:0);
				// set x, y position using transform matrix
				$tm = TCPDF_STATIC::getTransformationMatrixProduct($tm, array( 1, 0, 0, 1, $svgX, $svgY));
				$this->SVGTransform($tm);
				// set clipping for width and height
				$x = 0;
				$y = 0;
				$w = (isset($attribs['width'])?$this->getHTMLUnitToUnits($attribs['width'], 0, $this->svgunit, false):$this->w);
				$h = (isset($attribs['height'])?$this->getHTMLUnitToUnits($attribs['height'], 0, $this->svgunit, false):$this->h);
				// draw clipping rect
				$this->Rect($x, $y, $w, $h, 'CNZ', array(), array());
				// parse viewbox, calculate extra transformation matrix
				if (isset($attribs['viewBox'])) {
					$tmp = array();
					preg_match_all("/[0-9]+/", $attribs['viewBox'], $tmp);
					$tmp = $tmp[0];
					if (sizeof($tmp) == 4) {
						$vx = $tmp[0];
						$vy = $tmp[1];
						$vw = $tmp[2];
						$vh = $tmp[3];
						// get aspect ratio
						$tmp = array();
						$aspectX = 'xMid';
						$aspectY = 'YMid';
						$fit = 'meet';
						if (isset($attribs['preserveAspectRatio'])) {
							if($attribs['preserveAspectRatio'] == 'none') {
								$fit = 'none';
							} else {
								preg_match_all('/[a-zA-Z]+/', $attribs['preserveAspectRatio'], $tmp);
								$tmp = $tmp[0];
								if ((sizeof($tmp) == 2) AND (strlen($tmp[0]) == 8) AND (in_array($tmp[1], array('meet', 'slice', 'none')))) {
									$aspectX = substr($tmp[0], 0, 4);
									$aspectY = substr($tmp[0], 4, 4);
									$fit = $tmp[1];
								}
							}
						}
						$wr = ($svgW / $vw);
						$hr = ($svgH / $vh);
						$ax = $ay = 0;
						if ((($fit == 'meet') AND ($hr < $wr)) OR (($fit == 'slice') AND ($hr > $wr))) {
							if ($aspectX == 'xMax') {
								$ax = (($vw * ($wr / $hr)) - $vw);
							}
							if ($aspectX == 'xMid') {
								$ax = ((($vw * ($wr / $hr)) - $vw) / 2);
							}
							$wr = $hr;
						} elseif ((($fit == 'meet') AND ($hr > $wr)) OR (($fit == 'slice') AND ($hr < $wr))) {
							if ($aspectY == 'YMax') {
								$ay = (($vh * ($hr / $wr)) - $vh);
							}
							if ($aspectY == 'YMid') {
								$ay = ((($vh * ($hr / $wr)) - $vh) / 2);
							}
							$hr = $wr;
						}
						$newtm = array($wr, 0, 0, $hr, (($wr * ($ax - $vx)) - $svgX), (($hr * ($ay - $vy)) - $svgY));
						$tm = TCPDF_STATIC::getTransformationMatrixProduct($tm, $newtm);
						$this->SVGTransform($tm);
					}
				}
				$this->setSVGStyles($svgstyle, $prev_svgstyle);
				break;
			}
			case 'g': {
				// group together related graphics elements
				array_push($this->svgstyles, $svgstyle);
				$this->StartTransform();
				$x = (isset($attribs['x'])?$attribs['x']:0);
				$y = (isset($attribs['y'])?$attribs['y']:0);
				$w = 1;//(isset($attribs['width'])?$attribs['width']:1);
				$h = 1;//(isset($attribs['height'])?$attribs['height']:1);
				$tm = TCPDF_STATIC::getTransformationMatrixProduct($tm, array($w, 0, 0, $h, $x, $y));
				$this->SVGTransform($tm);
				$this->setSVGStyles($svgstyle, $prev_svgstyle);
				break;
			}
			case 'linearGradient': {
				if ($this->pdfa_mode) {
					break;
				}
				if (!isset($attribs['id'])) {
					$attribs['id'] = 'GR_'.(count($this->svggradients) + 1);
				}
				$this->svggradientid = $attribs['id'];
				$this->svggradients[$this->svggradientid] = array();
				$this->svggradients[$this->svggradientid]['type'] = 2;
				$this->svggradients[$this->svggradientid]['stops'] = array();
				if (isset($attribs['gradientUnits'])) {
					$this->svggradients[$this->svggradientid]['gradientUnits'] = $attribs['gradientUnits'];
				} else {
					$this->svggradients[$this->svggradientid]['gradientUnits'] = 'objectBoundingBox';
				}
				//$attribs['spreadMethod']
				if (((!isset($attribs['x1'])) AND (!isset($attribs['y1'])) AND (!isset($attribs['x2'])) AND (!isset($attribs['y2'])))
					OR ((isset($attribs['x1']) AND (substr($attribs['x1'], -1) == '%'))
						OR (isset($attribs['y1']) AND (substr($attribs['y1'], -1) == '%'))
						OR (isset($attribs['x2']) AND (substr($attribs['x2'], -1) == '%'))
						OR (isset($attribs['y2']) AND (substr($attribs['y2'], -1) == '%')))) {
					$this->svggradients[$this->svggradientid]['mode'] = 'percentage';
				} else {
					$this->svggradients[$this->svggradientid]['mode'] = 'measure';
				}
				$x1 = (isset($attribs['x1'])?$attribs['x1']:'0');
				$y1 = (isset($attribs['y1'])?$attribs['y1']:'0');
				$x2 = (isset($attribs['x2'])?$attribs['x2']:'100');
				$y2 = (isset($attribs['y2'])?$attribs['y2']:'0');
				if (isset($attribs['gradientTransform'])) {
					$this->svggradients[$this->svggradientid]['gradientTransform'] = TCPDF_STATIC::getSVGTransformMatrix($attribs['gradientTransform']);
				}
				$this->svggradients[$this->svggradientid]['coords'] = array($x1, $y1, $x2, $y2);
				if (isset($attribs['xlink:href']) AND !empty($attribs['xlink:href'])) {
					// gradient is defined on another place
					$this->svggradients[$this->svggradientid]['xref'] = substr($attribs['xlink:href'], 1);
				}
				break;
			}
			case 'radialGradient': {
				if ($this->pdfa_mode) {
					break;
				}
				if (!isset($attribs['id'])) {
					$attribs['id'] = 'GR_'.(count($this->svggradients) + 1);
				}
				$this->svggradientid = $attribs['id'];
				$this->svggradients[$this->svggradientid] = array();
				$this->svggradients[$this->svggradientid]['type'] = 3;
				$this->svggradients[$this->svggradientid]['stops'] = array();
				if (isset($attribs['gradientUnits'])) {
					$this->svggradients[$this->svggradientid]['gradientUnits'] = $attribs['gradientUnits'];
				} else {
					$this->svggradients[$this->svggradientid]['gradientUnits'] = 'objectBoundingBox';
				}
				//$attribs['spreadMethod']
				if (((!isset($attribs['cx'])) AND (!isset($attribs['cy'])))
					OR ((isset($attribs['cx']) AND (substr($attribs['cx'], -1) == '%'))
					OR (isset($attribs['cy']) AND (substr($attribs['cy'], -1) == '%')))) {
					$this->svggradients[$this->svggradientid]['mode'] = 'percentage';
				} elseif (isset($attribs['r']) AND is_numeric($attribs['r']) AND ($attribs['r']) <= 1) {
					$this->svggradients[$this->svggradientid]['mode'] = 'ratio';
				} else {
					$this->svggradients[$this->svggradientid]['mode'] = 'measure';
				}
				$cx = (isset($attribs['cx']) ? $attribs['cx'] : 0.5);
				$cy = (isset($attribs['cy']) ? $attribs['cy'] : 0.5);
				$fx = (isset($attribs['fx']) ? $attribs['fx'] : $cx);
				$fy = (isset($attribs['fy']) ? $attribs['fy'] : $cy);
				$r = (isset($attribs['r']) ? $attribs['r'] : 0.5);
				if (isset($attribs['gradientTransform'])) {
					$this->svggradients[$this->svggradientid]['gradientTransform'] = TCPDF_STATIC::getSVGTransformMatrix($attribs['gradientTransform']);
				}
				$this->svggradients[$this->svggradientid]['coords'] = array($cx, $cy, $fx, $fy, $r);
				if (isset($attribs['xlink:href']) AND !empty($attribs['xlink:href'])) {
					// gradient is defined on another place
					$this->svggradients[$this->svggradientid]['xref'] = substr($attribs['xlink:href'], 1);
				}
				break;
			}
			case 'stop': {
				// gradient stops
				if (substr($attribs['offset'], -1) == '%') {
					$offset = floatval(substr($attribs['offset'], -1)) / 100;
				} else {
					$offset = floatval($attribs['offset']);
					if ($offset > 1) {
						$offset /= 100;
					}
				}
				$stop_color = isset($svgstyle['stop-color'])?TCPDF_COLORS::convertHTMLColorToDec($svgstyle['stop-color'], $this->spot_colors):'black';
				$opacity = isset($svgstyle['stop-opacity'])?$svgstyle['stop-opacity']:1;
				$this->svggradients[$this->svggradientid]['stops'][] = array('offset' => $offset, 'color' => $stop_color, 'opacity' => $opacity);
				break;
			}
			// paths
			case 'path': {
				if ($invisible) {
					break;
				}
				if (isset($attribs['d'])) {
					$d = trim($attribs['d']);
					if (!empty($d)) {
						$x = (isset($attribs['x'])?$attribs['x']:0);
						$y = (isset($attribs['y'])?$attribs['y']:0);
						$w = (isset($attribs['width'])?$attribs['width']:1);
						$h = (isset($attribs['height'])?$attribs['height']:1);
						$tm = TCPDF_STATIC::getTransformationMatrixProduct($tm, array($w, 0, 0, $h, $x, $y));
						if ($clipping) {
							$this->SVGTransform($tm);
							$this->SVGPath($d, 'CNZ');
						} else {
							$this->StartTransform();
							$this->SVGTransform($tm);
							$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'SVGPath', array($d, 'CNZ'));
							if (!empty($obstyle)) {
								$this->SVGPath($d, $obstyle);
							}
							$this->StopTransform();
						}
					}
				}
				break;
			}
			// shapes
			case 'rect': {
				if ($invisible) {
					break;
				}
				$x = (isset($attribs['x'])?$this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false):0);
				$y = (isset($attribs['y'])?$this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false):0);
				$w = (isset($attribs['width'])?$this->getHTMLUnitToUnits($attribs['width'], 0, $this->svgunit, false):0);
				$h = (isset($attribs['height'])?$this->getHTMLUnitToUnits($attribs['height'], 0, $this->svgunit, false):0);
				$rx = (isset($attribs['rx'])?$this->getHTMLUnitToUnits($attribs['rx'], 0, $this->svgunit, false):0);
				$ry = (isset($attribs['ry'])?$this->getHTMLUnitToUnits($attribs['ry'], 0, $this->svgunit, false):$rx);
				if ($clipping) {
					$this->SVGTransform($tm);
					$this->RoundedRectXY($x, $y, $w, $h, $rx, $ry, '1111', 'CNZ', array(), array());
				} else {
					$this->StartTransform();
					$this->SVGTransform($tm);
					$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'RoundedRectXY', array($x, $y, $w, $h, $rx, $ry, '1111', 'CNZ'));
					if (!empty($obstyle)) {
						$this->RoundedRectXY($x, $y, $w, $h, $rx, $ry, '1111', $obstyle, array(), array());
					}
					$this->StopTransform();
				}
				break;
			}
			case 'circle': {
				if ($invisible) {
					break;
				}
				$r = (isset($attribs['r']) ? $this->getHTMLUnitToUnits($attribs['r'], 0, $this->svgunit, false) : 0);
				$cx = (isset($attribs['cx']) ? $this->getHTMLUnitToUnits($attribs['cx'], 0, $this->svgunit, false) : (isset($attribs['x']) ? $this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false) : 0));
				$cy = (isset($attribs['cy']) ? $this->getHTMLUnitToUnits($attribs['cy'], 0, $this->svgunit, false) : (isset($attribs['y']) ? $this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false) : 0));
				$x = ($cx - $r);
				$y = ($cy - $r);
				$w = (2 * $r);
				$h = $w;
				if ($clipping) {
					$this->SVGTransform($tm);
					$this->Circle($cx, $cy, $r, 0, 360, 'CNZ', array(), array(), 8);
				} else {
					$this->StartTransform();
					$this->SVGTransform($tm);
					$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Circle', array($cx, $cy, $r, 0, 360, 'CNZ'));
					if (!empty($obstyle)) {
						$this->Circle($cx, $cy, $r, 0, 360, $obstyle, array(), array(), 8);
					}
					$this->StopTransform();
				}
				break;
			}
			case 'ellipse': {
				if ($invisible) {
					break;
				}
				$rx = (isset($attribs['rx']) ? $this->getHTMLUnitToUnits($attribs['rx'], 0, $this->svgunit, false) : 0);
				$ry = (isset($attribs['ry']) ? $this->getHTMLUnitToUnits($attribs['ry'], 0, $this->svgunit, false) : 0);
				$cx = (isset($attribs['cx']) ? $this->getHTMLUnitToUnits($attribs['cx'], 0, $this->svgunit, false) : (isset($attribs['x']) ? $this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false) : 0));
				$cy = (isset($attribs['cy']) ? $this->getHTMLUnitToUnits($attribs['cy'], 0, $this->svgunit, false) : (isset($attribs['y']) ? $this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false) : 0));
				$x = ($cx - $rx);
				$y = ($cy - $ry);
				$w = (2 * $rx);
				$h = (2 * $ry);
				if ($clipping) {
					$this->SVGTransform($tm);
					$this->Ellipse($cx, $cy, $rx, $ry, 0, 0, 360, 'CNZ', array(), array(), 8);
				} else {
					$this->StartTransform();
					$this->SVGTransform($tm);
					$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Ellipse', array($cx, $cy, $rx, $ry, 0, 0, 360, 'CNZ'));
					if (!empty($obstyle)) {
						$this->Ellipse($cx, $cy, $rx, $ry, 0, 0, 360, $obstyle, array(), array(), 8);
					}
					$this->StopTransform();
				}
				break;
			}
			case 'line': {
				if ($invisible) {
					break;
				}
				$x1 = (isset($attribs['x1'])?$this->getHTMLUnitToUnits($attribs['x1'], 0, $this->svgunit, false):0);
				$y1 = (isset($attribs['y1'])?$this->getHTMLUnitToUnits($attribs['y1'], 0, $this->svgunit, false):0);
				$x2 = (isset($attribs['x2'])?$this->getHTMLUnitToUnits($attribs['x2'], 0, $this->svgunit, false):0);
				$y2 = (isset($attribs['y2'])?$this->getHTMLUnitToUnits($attribs['y2'], 0, $this->svgunit, false):0);
				$x = $x1;
				$y = $y1;
				$w = abs($x2 - $x1);
				$h = abs($y2 - $y1);
				if (!$clipping) {
					$this->StartTransform();
					$this->SVGTransform($tm);
					$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Line', array($x1, $y1, $x2, $y2));
					$this->Line($x1, $y1, $x2, $y2);
					$this->StopTransform();
				}
				break;
			}
			case 'polyline':
			case 'polygon': {
				if ($invisible) {
					break;
				}
				$points = (isset($attribs['points'])?$attribs['points']:'0 0');
				$points = trim($points);
				// note that point may use a complex syntax not covered here
				$points = preg_split('/[\,\s]+/si', $points);
				if (count($points) < 4) {
					break;
				}
				$p = array();
				$xmin = 2147483647;
				$xmax = 0;
				$ymin = 2147483647;
				$ymax = 0;
				foreach ($points as $key => $val) {
					$p[$key] = $this->getHTMLUnitToUnits($val, 0, $this->svgunit, false);
					if (($key % 2) == 0) {
						// X coordinate
						$xmin = min($xmin, $p[$key]);
						$xmax = max($xmax, $p[$key]);
					} else {
						// Y coordinate
						$ymin = min($ymin, $p[$key]);
						$ymax = max($ymax, $p[$key]);
					}
				}
				$x = $xmin;
				$y = $ymin;
				$w = ($xmax - $xmin);
				$h = ($ymax - $ymin);
				if ($name == 'polyline') {
					$this->StartTransform();
					$this->SVGTransform($tm);
					$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'PolyLine', array($p, 'CNZ'));
					if (!empty($obstyle)) {
						$this->PolyLine($p, $obstyle, array(), array());
					}
					$this->StopTransform();
				} else { // polygon
					if ($clipping) {
						$this->SVGTransform($tm);
						$this->Polygon($p, 'CNZ', array(), array(), true);
					} else {
						$this->StartTransform();
						$this->SVGTransform($tm);
						$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Polygon', array($p, 'CNZ'));
						if (!empty($obstyle)) {
							$this->Polygon($p, $obstyle, array(), array(), true);
						}
						$this->StopTransform();
					}
				}
				break;
			}
			// image
			case 'image': {
				if ($invisible) {
					break;
				}
				if (!isset($attribs['xlink:href']) OR empty($attribs['xlink:href'])) {
					break;
				}
				$x = (isset($attribs['x'])?$this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false):0);
				$y = (isset($attribs['y'])?$this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false):0);
				$w = (isset($attribs['width'])?$this->getHTMLUnitToUnits($attribs['width'], 0, $this->svgunit, false):0);
				$h = (isset($attribs['height'])?$this->getHTMLUnitToUnits($attribs['height'], 0, $this->svgunit, false):0);
				$img = $attribs['xlink:href'];
				if (!$clipping) {
					$this->StartTransform();
					$this->SVGTransform($tm);
					$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h);
					if (preg_match('/^data:image\/[^;]+;base64,/', $img, $m) > 0) {
						// embedded image encoded as base64
						$img = '@'.base64_decode(substr($img, strlen($m[0])));
					} else {
						// fix image path
						if (!TCPDF_STATIC::empty_string($this->svgdir) AND (($img[0] == '.') OR (basename($img) == $img))) {
							// replace relative path with full server path
							$img = $this->svgdir.'/'.$img;
						}
						if (($img[0] == '/') AND !empty($_SERVER['DOCUMENT_ROOT']) AND ($_SERVER['DOCUMENT_ROOT'] != '/')) {
							$findroot = strpos($img, $_SERVER['DOCUMENT_ROOT']);
							if (($findroot === false) OR ($findroot > 1)) {
								if (substr($_SERVER['DOCUMENT_ROOT'], -1) == '/') {
									$img = substr($_SERVER['DOCUMENT_ROOT'], 0, -1).$img;
								} else {
									$img = $_SERVER['DOCUMENT_ROOT'].$img;
								}
							}
						}
						$img = urldecode($img);
						$testscrtype = @parse_url($img);
						if (!isset($testscrtype['query']) OR empty($testscrtype['query'])) {
							// convert URL to server path
							$img = str_replace(K_PATH_URL, K_PATH_MAIN, $img);
						}
					}
					// get image type
					$imgtype = TCPDF_IMAGES::getImageFileType($img);
					if (($imgtype == 'eps') OR ($imgtype == 'ai')) {
						$this->ImageEps($img, $x, $y, $w, $h);
					} elseif ($imgtype == 'svg') {
						// store SVG vars
						$svggradients = $this->svggradients;
						$svggradientid = $this->svggradientid;
						$svgdefsmode = $this->svgdefsmode;
						$svgdefs = $this->svgdefs;
						$svgclipmode = $this->svgclipmode;
						$svgclippaths = $this->svgclippaths;
						$svgcliptm = $this->svgcliptm;
						$svgclipid = $this->svgclipid;
						$svgtext = $this->svgtext;
						$svgtextmode = $this->svgtextmode;
						$this->ImageSVG($img, $x, $y, $w, $h);
						// restore SVG vars
						$this->svggradients = $svggradients;
						$this->svggradientid = $svggradientid;
						$this->svgdefsmode = $svgdefsmode;
						$this->svgdefs = $svgdefs;
						$this->svgclipmode = $svgclipmode;
						$this->svgclippaths = $svgclippaths;
						$this->svgcliptm = $svgcliptm;
						$this->svgclipid = $svgclipid;
						$this->svgtext = $svgtext;
						$this->svgtextmode = $svgtextmode;
					} else {
						$this->Image($img, $x, $y, $w, $h);
					}
					$this->StopTransform();
				}
				break;
			}
			// text
			case 'text':
			case 'tspan': {
				if (isset($this->svgtextmode['text-anchor']) AND !empty($this->svgtext)) {
					// @TODO: unsupported feature
				}
				// only basic support - advanced features must be implemented
				$this->svgtextmode['invisible'] = $invisible;
				if ($invisible) {
					break;
				}
				array_push($this->svgstyles, $svgstyle);
				if (isset($attribs['x'])) {
					$x = $this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false);
				} elseif ($name == 'tspan') {
					$x = $this->x;
				} else {
					$x = 0;
				}
				if (isset($attribs['dx'])) {
					$x += $this->getHTMLUnitToUnits($attribs['dx'], 0, $this->svgunit, false);
				}
				if (isset($attribs['y'])) {
					$y = $this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false);
				} elseif ($name == 'tspan') {
					$y = $this->y;
				} else {
					$y = 0;
				}
				if (isset($attribs['dy'])) {
					$y += $this->getHTMLUnitToUnits($attribs['dy'], 0, $this->svgunit, false);
				}
				$svgstyle['text-color'] = $svgstyle['fill'];
				$this->svgtext = '';
				if (isset($svgstyle['text-anchor'])) {
					$this->svgtextmode['text-anchor'] = $svgstyle['text-anchor'];
				} else {
					$this->svgtextmode['text-anchor'] = 'start';
				}
				if (isset($svgstyle['direction'])) {
					if ($svgstyle['direction'] == 'rtl') {
						$this->svgtextmode['rtl'] = true;
					} else {
						$this->svgtextmode['rtl'] = false;
					}
				} else {
					$this->svgtextmode['rtl'] = false;
				}
				if (isset($svgstyle['stroke']) AND ($svgstyle['stroke'] != 'none') AND isset($svgstyle['stroke-width']) AND ($svgstyle['stroke-width'] > 0)) {
					$this->svgtextmode['stroke'] = $this->getHTMLUnitToUnits($svgstyle['stroke-width'], 0, $this->svgunit, false);
				} else {
					$this->svgtextmode['stroke'] = false;
				}
				$this->StartTransform();
				$this->SVGTransform($tm);
				$obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, 1, 1);
				$this->x = $x;
				$this->y = $y;
				break;
			}
			// use
			case 'use': {
				if (isset($attribs['xlink:href']) AND !empty($attribs['xlink:href'])) {
					$svgdefid = substr($attribs['xlink:href'], 1);
					if (isset($this->svgdefs[$svgdefid])) {
						$use = $this->svgdefs[$svgdefid];
						if (isset($attribs['xlink:href'])) {
							unset($attribs['xlink:href']);
						}
						if (isset($attribs['id'])) {
							unset($attribs['id']);
						}
						if (isset($use['attribs']['x']) AND isset($attribs['x'])) {
							$attribs['x'] += $use['attribs']['x'];
						}
						if (isset($use['attribs']['y']) AND isset($attribs['y'])) {
							$attribs['y'] += $use['attribs']['y'];
						}
						if (empty($attribs['style'])) {
							$attribs['style'] = '';
						}
						if (!empty($use['attribs']['style'])) {
							// merge styles
							$attribs['style'] = str_replace(';;',';',';'.$use['attribs']['style'].$attribs['style']);
						}
						$attribs = array_merge($use['attribs'], $attribs);
						$this->startSVGElementHandler($parser, $use['name'], $attribs);
						return;
					}
				}
				break;
			}
			default: {
				break;
			}
		} // end of switch
		// process child elements
		if (!empty($attribs['child_elements'])) {
			$child_elements = $attribs['child_elements'];
			unset($attribs['child_elements']);
			foreach($child_elements as $child_element) {
				if (empty($child_element['attribs']['closing_tag'])) {
					$this->startSVGElementHandler('child-tag', $child_element['name'], $child_element['attribs']);
				} else {
					if (isset($child_element['attribs']['content'])) {
						$this->svgtext = $child_element['attribs']['content'];
					}
					$this->endSVGElementHandler('child-tag', $child_element['name']);
				}
			}
		}
	}
示例#5
0
 /**
  * Convert JavaScript form fields properties array to Annotation Properties array.
  * @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference.
  * @param $spot_colors (array) Reference to spot colors array.
  * @param $rtl (boolean) True if in Right-To-Left text direction mode, false otherwise.
  * @return array of annotation properties
  * @author Nicola Asuni
  * @since 4.8.000 (2009-09-06)
  * @public static
  */
 public static function getAnnotOptFromJSProp($prop, &$spot_colors, $rtl = false)
 {
     if (isset($prop['aopt']) and is_array($prop['aopt'])) {
         // the annotation options area lready defined
         return $prop['aopt'];
     }
     $opt = array();
     // value to be returned
     // alignment: Controls how the text is laid out within the text field.
     if (isset($prop['alignment'])) {
         switch ($prop['alignment']) {
             case 'left':
                 $opt['q'] = 0;
                 break;
             case 'center':
                 $opt['q'] = 1;
                 break;
             case 'right':
                 $opt['q'] = 2;
                 break;
             default:
                 $opt['q'] = $rtl ? 2 : 0;
                 break;
         }
     }
     // lineWidth: Specifies the thickness of the border when stroking the perimeter of a field's rectangle.
     if (isset($prop['lineWidth'])) {
         $linewidth = intval($prop['lineWidth']);
     } else {
         $linewidth = 1;
     }
     // borderStyle: The border style for a field.
     if (isset($prop['borderStyle'])) {
         switch ($prop['borderStyle']) {
             case 'border.d':
             case 'dashed':
                 $opt['border'] = array(0, 0, $linewidth, array(3, 2));
                 $opt['bs'] = array('w' => $linewidth, 's' => 'D', 'd' => array(3, 2));
                 break;
             case 'border.b':
             case 'beveled':
                 $opt['border'] = array(0, 0, $linewidth);
                 $opt['bs'] = array('w' => $linewidth, 's' => 'B');
                 break;
             case 'border.i':
             case 'inset':
                 $opt['border'] = array(0, 0, $linewidth);
                 $opt['bs'] = array('w' => $linewidth, 's' => 'I');
                 break;
             case 'border.u':
             case 'underline':
                 $opt['border'] = array(0, 0, $linewidth);
                 $opt['bs'] = array('w' => $linewidth, 's' => 'U');
                 break;
             case 'border.s':
             case 'solid':
                 $opt['border'] = array(0, 0, $linewidth);
                 $opt['bs'] = array('w' => $linewidth, 's' => 'S');
                 break;
             default:
                 break;
         }
     }
     if (isset($prop['border']) and is_array($prop['border'])) {
         $opt['border'] = $prop['border'];
     }
     if (!isset($opt['mk'])) {
         $opt['mk'] = array();
     }
     if (!isset($opt['mk']['if'])) {
         $opt['mk']['if'] = array();
     }
     $opt['mk']['if']['a'] = array(0.5, 0.5);
     // buttonAlignX: Controls how space is distributed from the left of the button face with respect to the icon.
     if (isset($prop['buttonAlignX'])) {
         $opt['mk']['if']['a'][0] = $prop['buttonAlignX'];
     }
     // buttonAlignY: Controls how unused space is distributed from the bottom of the button face with respect to the icon.
     if (isset($prop['buttonAlignY'])) {
         $opt['mk']['if']['a'][1] = $prop['buttonAlignY'];
     }
     // buttonFitBounds: If true, the extent to which the icon may be scaled is set to the bounds of the button field.
     if (isset($prop['buttonFitBounds']) and $prop['buttonFitBounds'] == 'true') {
         $opt['mk']['if']['fb'] = true;
     }
     // buttonScaleHow: Controls how the icon is scaled (if necessary) to fit inside the button face.
     if (isset($prop['buttonScaleHow'])) {
         switch ($prop['buttonScaleHow']) {
             case 'scaleHow.proportional':
                 $opt['mk']['if']['s'] = 'P';
                 break;
             case 'scaleHow.anamorphic':
                 $opt['mk']['if']['s'] = 'A';
                 break;
         }
     }
     // buttonScaleWhen: Controls when an icon is scaled to fit inside the button face.
     if (isset($prop['buttonScaleWhen'])) {
         switch ($prop['buttonScaleWhen']) {
             case 'scaleWhen.always':
                 $opt['mk']['if']['sw'] = 'A';
                 break;
             case 'scaleWhen.never':
                 $opt['mk']['if']['sw'] = 'N';
                 break;
             case 'scaleWhen.tooBig':
                 $opt['mk']['if']['sw'] = 'B';
                 break;
             case 'scaleWhen.tooSmall':
                 $opt['mk']['if']['sw'] = 'S';
                 break;
         }
     }
     // buttonPosition: Controls how the text and the icon of the button are positioned with respect to each other within the button face.
     if (isset($prop['buttonPosition'])) {
         switch ($prop['buttonPosition']) {
             case 0:
             case 'position.textOnly':
                 $opt['mk']['tp'] = 0;
                 break;
             case 1:
             case 'position.iconOnly':
                 $opt['mk']['tp'] = 1;
                 break;
             case 2:
             case 'position.iconTextV':
                 $opt['mk']['tp'] = 2;
                 break;
             case 3:
             case 'position.textIconV':
                 $opt['mk']['tp'] = 3;
                 break;
             case 4:
             case 'position.iconTextH':
                 $opt['mk']['tp'] = 4;
                 break;
             case 5:
             case 'position.textIconH':
                 $opt['mk']['tp'] = 5;
                 break;
             case 6:
             case 'position.overlay':
                 $opt['mk']['tp'] = 6;
                 break;
         }
     }
     // fillColor: Specifies the background color for a field.
     if (isset($prop['fillColor'])) {
         if (is_array($prop['fillColor'])) {
             $opt['mk']['bg'] = $prop['fillColor'];
         } else {
             $opt['mk']['bg'] = TCPDF_COLORS::convertHTMLColorToDec($prop['fillColor'], $spot_colors);
         }
     }
     // strokeColor: Specifies the stroke color for a field that is used to stroke the rectangle of the field with a line as large as the line width.
     if (isset($prop['strokeColor'])) {
         if (is_array($prop['strokeColor'])) {
             $opt['mk']['bc'] = $prop['strokeColor'];
         } else {
             $opt['mk']['bc'] = TCPDF_COLORS::convertHTMLColorToDec($prop['strokeColor'], $spot_colors);
         }
     }
     // rotation: The rotation of a widget in counterclockwise increments.
     if (isset($prop['rotation'])) {
         $opt['mk']['r'] = $prop['rotation'];
     }
     // charLimit: Limits the number of characters that a user can type into a text field.
     if (isset($prop['charLimit'])) {
         $opt['maxlen'] = intval($prop['charLimit']);
     }
     if (!isset($ff)) {
         $ff = 0;
         // default value
     }
     // readonly: The read-only characteristic of a field. If a field is read-only, the user can see the field but cannot change it.
     if (isset($prop['readonly']) and $prop['readonly'] == 'true') {
         $ff += 1 << 0;
     }
     // required: Specifies whether a field requires a value.
     if (isset($prop['required']) and $prop['required'] == 'true') {
         $ff += 1 << 1;
     }
     // multiline: Controls how text is wrapped within the field.
     if (isset($prop['multiline']) and $prop['multiline'] == 'true') {
         $ff += 1 << 12;
     }
     // password: Specifies whether the field should display asterisks when data is entered in the field.
     if (isset($prop['password']) and $prop['password'] == 'true') {
         $ff += 1 << 13;
     }
     // NoToggleToOff: If set, exactly one radio button shall be selected at all times; selecting the currently selected button has no effect.
     if (isset($prop['NoToggleToOff']) and $prop['NoToggleToOff'] == 'true') {
         $ff += 1 << 14;
     }
     // Radio: If set, the field is a set of radio buttons.
     if (isset($prop['Radio']) and $prop['Radio'] == 'true') {
         $ff += 1 << 15;
     }
     // Pushbutton: If set, the field is a pushbutton that does not retain a permanent value.
     if (isset($prop['Pushbutton']) and $prop['Pushbutton'] == 'true') {
         $ff += 1 << 16;
     }
     // Combo: If set, the field is a combo box; if clear, the field is a list box.
     if (isset($prop['Combo']) and $prop['Combo'] == 'true') {
         $ff += 1 << 17;
     }
     // editable: Controls whether a combo box is editable.
     if (isset($prop['editable']) and $prop['editable'] == 'true') {
         $ff += 1 << 18;
     }
     // Sort: If set, the field's option items shall be sorted alphabetically.
     if (isset($prop['Sort']) and $prop['Sort'] == 'true') {
         $ff += 1 << 19;
     }
     // fileSelect: If true, sets the file-select flag in the Options tab of the text field (Field is Used for File Selection).
     if (isset($prop['fileSelect']) and $prop['fileSelect'] == 'true') {
         $ff += 1 << 20;
     }
     // multipleSelection: If true, indicates that a list box allows a multiple selection of items.
     if (isset($prop['multipleSelection']) and $prop['multipleSelection'] == 'true') {
         $ff += 1 << 21;
     }
     // doNotSpellCheck: If true, spell checking is not performed on this editable text field.
     if (isset($prop['doNotSpellCheck']) and $prop['doNotSpellCheck'] == 'true') {
         $ff += 1 << 22;
     }
     // doNotScroll: If true, the text field does not scroll and the user, therefore, is limited by the rectangular region designed for the field.
     if (isset($prop['doNotScroll']) and $prop['doNotScroll'] == 'true') {
         $ff += 1 << 23;
     }
     // comb: If set to true, the field background is drawn as series of boxes (one for each character in the value of the field) and each character of the content is drawn within those boxes. The number of boxes drawn is determined from the charLimit property. It applies only to text fields. The setter will also raise if any of the following field properties are also set multiline, password, and fileSelect. A side-effect of setting this property is that the doNotScroll property is also set.
     if (isset($prop['comb']) and $prop['comb'] == 'true') {
         $ff += 1 << 24;
     }
     // radiosInUnison: If false, even if a group of radio buttons have the same name and export value, they behave in a mutually exclusive fashion, like HTML radio buttons.
     if (isset($prop['radiosInUnison']) and $prop['radiosInUnison'] == 'true') {
         $ff += 1 << 25;
     }
     // richText: If true, the field allows rich text formatting.
     if (isset($prop['richText']) and $prop['richText'] == 'true') {
         $ff += 1 << 25;
     }
     // commitOnSelChange: Controls whether a field value is committed after a selection change.
     if (isset($prop['commitOnSelChange']) and $prop['commitOnSelChange'] == 'true') {
         $ff += 1 << 26;
     }
     $opt['ff'] = $ff;
     // defaultValue: The default value of a field - that is, the value that the field is set to when the form is reset.
     if (isset($prop['defaultValue'])) {
         $opt['dv'] = $prop['defaultValue'];
     }
     $f = 4;
     // default value for annotation flags
     // readonly: The read-only characteristic of a field. If a field is read-only, the user can see the field but cannot change it.
     if (isset($prop['readonly']) and $prop['readonly'] == 'true') {
         $f += 1 << 6;
     }
     // display: Controls whether the field is hidden or visible on screen and in print.
     if (isset($prop['display'])) {
         if ($prop['display'] == 'display.visible') {
             //
         } elseif ($prop['display'] == 'display.hidden') {
             $f += 1 << 1;
         } elseif ($prop['display'] == 'display.noPrint') {
             $f -= 1 << 2;
         } elseif ($prop['display'] == 'display.noView') {
             $f += 1 << 5;
         }
     }
     $opt['f'] = $f;
     // currentValueIndices: Reads and writes single or multiple values of a list box or combo box.
     if (isset($prop['currentValueIndices']) and is_array($prop['currentValueIndices'])) {
         $opt['i'] = $prop['currentValueIndices'];
     }
     // value: The value of the field data that the user has entered.
     if (isset($prop['value'])) {
         if (is_array($prop['value'])) {
             $opt['opt'] = array();
             foreach ($prop['value'] as $key => $optval) {
                 // exportValues: An array of strings representing the export values for the field.
                 if (isset($prop['exportValues'][$key])) {
                     $opt['opt'][$key] = array($prop['exportValues'][$key], $prop['value'][$key]);
                 } else {
                     $opt['opt'][$key] = $prop['value'][$key];
                 }
             }
         } else {
             $opt['v'] = $prop['value'];
         }
     }
     // richValue: This property specifies the text contents and formatting of a rich text field.
     if (isset($prop['richValue'])) {
         $opt['rv'] = $prop['richValue'];
     }
     // submitName: If nonempty, used during form submission instead of name. Only applicable if submitting in HTML format (that is, URL-encoded).
     if (isset($prop['submitName'])) {
         $opt['tm'] = $prop['submitName'];
     }
     // name: Fully qualified field name.
     if (isset($prop['name'])) {
         $opt['t'] = $prop['name'];
     }
     // userName: The user name (short description string) of the field.
     if (isset($prop['userName'])) {
         $opt['tu'] = $prop['userName'];
     }
     // highlight: Defines how a button reacts when a user clicks it.
     if (isset($prop['highlight'])) {
         switch ($prop['highlight']) {
             case 'none':
             case 'highlight.n':
                 $opt['h'] = 'N';
                 break;
             case 'invert':
             case 'highlight.i':
                 $opt['h'] = 'i';
                 break;
             case 'push':
             case 'highlight.p':
                 $opt['h'] = 'P';
                 break;
             case 'outline':
             case 'highlight.o':
                 $opt['h'] = 'O';
                 break;
         }
     }
     // Unsupported options:
     // - calcOrderIndex: Changes the calculation order of fields in the document.
     // - delay: Delays the redrawing of a field's appearance.
     // - defaultStyle: This property defines the default style attributes for the form field.
     // - style: Allows the user to set the glyph style of a check box or radio button.
     // - textColor, textFont, textSize
     return $opt;
 }
示例#6
0
 /**
  * Prints Gannt chart for passed task data
  *
  * @param mixed $tcpdf_obj TCPDF instance
  */
 public function Render($data = null)
 {
     if ($data && is_array($data)) {
         $this->setData($data);
     }
     if (!$this->_tcpdf instanceof TCPDF) {
         $this->_error_message = 'Passed parameter is not TCPDF instance, rendering impossible!';
         return false;
     }
     $this->_saveCurrentPdfState();
     #  $curfontSize = $this->_tcpdf->getFontSize();
     $this->_tcpdf->setPageUnit('mm');
     # we work in millimeters!
     $width = (double) $this->_dim[0];
     $startx = floatval($this->_pos[0]);
     $starty = floatval($this->_pos[1]);
     $height = (double) $this->_dim[1];
     $endy = min($this->_tcpdf->getPageHeight(), $starty + $height);
     $height = $endy - $starty;
     $drange = array(0, 0);
     if (isset($this->_data['daterange'])) {
         $drarr = is_string($this->_data['daterange']) ? explode(',', $this->_data['daterange']) : $this->_data['daterange'];
         $drange[0] = $drarr[0];
         if (isset($drarr[1])) {
             $drange[1] = $drarr[1];
         }
     }
     $datestart = $drange[0] ? self::char2date($drange[0]) : 0;
     $dateend = $drange[1] ? self::char2date($drange[1]) : 0;
     $auto_start = $datestart == 0;
     $auto_end = $dateend == 0;
     $rawdata = array();
     # Create "raw data" for rendering
     if (isset($this->_data['items']) && is_array($this->_data['items'])) {
         foreach ($this->_data['items'] as $rawno => $item) {
             $item_id = isset($item['id']) ? $item['id'] : 'item_' . $rawno;
             $descr = isset($item['description']) ? $item['description'] : $item_id;
             $dt1 = isset($item['datestart']) ? self::char2date($item['datestart']) : 0;
             $depend = isset($item['dependencies']) ? $item['dependencies'] : '';
             $dt2 = isset($item['dateend']) ? self::char2date($item['datestart']) : 0;
             $days = isset($item['workdays']) ? intval($item['workdays']) : false;
             $progress = isset($item['progress']) ? floatval($item['progress']) : 1;
             $members = isset($item['members']) ? $item['members'] : '';
             $color = isset($item['color']) ? $item['color'] : '';
             $mcolor = isset($item['mcolor']) ? $item['mcolor'] : '';
             $mstone = isset($item['milestone']) ? $item['milestone'] : false;
             if (isset($item['dateend']) && !empty($dt1)) {
                 $dt2 = self::char2date($item['dateend']);
                 if ($dt1 > 0) {
                     $days = self::daysBetween($dt1, $dt2) + 1;
                 }
                 # jan.01..jan.02 = 2 workdays: (1 day difference)
             }
             if ($dt1 > 0 && $days > 0 && empty($dt2)) {
                 $dt2 = self::addDays($dt1, $days - 1);
             }
             if (!$item_id) {
                 continue;
             }
             # empty ID not allowed
             if ($dt1 > 0 && $dt2 >= $dt2 or $days > 0 && !empty($depend)) {
                 $rawdata[$item_id] = array('id' => $item_id, 'description' => $descr, 'datestart' => $dt1, 'dateend' => $dt2, 'workdays' => $days, 'dependencies' => $depend, 'progress' => $progress, 'members' => $members, 'color' => $color, 'mcolor' => $mcolor, 'milestone' => $mstone);
             }
         }
     }
     # adjust start dates of "dependent" tasks, by shifting them after "parent" tasks
     $b_dependencies = false;
     foreach ($rawdata as $itemid => $rd) {
         $dt1 = $rd['datestart'];
         $dt2 = $rd['dateend'];
         if (!empty($rd['dependencies'])) {
             $darr = is_string($rd['dependencies']) ? explode(',', $rd['dependencies']) : $rd['dependencies'];
             if (!empty($darr[0])) {
                 foreach ($darr as $taskid) {
                     $b_dependencies = true;
                     if ($taskid != $itemid && isset($rawdata[$taskid]['dateend'])) {
                         $dt1 = $rawdata[$itemid]['datestart'] = max($rawdata[$itemid]['datestart'], $rawdata[$taskid]['dateend'] + 86400);
                         $dt2 = $rawdata[$itemid]['dateend'] = $rawdata[$itemid]['datestart'] + 86400 * ($rawdata[$itemid]['workdays'] - 1);
                         # auto-detect start and end date of a chart
                     }
                 }
             }
         }
         if ($auto_start) {
             $datestart = $datestart == 0 ? $dt1 : min($datestart, $dt1);
         }
         if ($auto_end) {
             $dateend = $dateend == 0 ? $dt2 : max($dateend, $dt2);
         }
         if (!empty($rd['milestone'])) {
             $ds = $rawdata[$itemid]['datestart'];
             if (isset($this->_milestones[$ds])) {
                 $this->_milestones[$ds][] = $rd['milestone'];
             } else {
                 $this->_milestones[$ds] = array($rd['milestone']);
             }
             # if two or more milestones have the same start date, they will be joined into one, and it's title name will contain all titles
         }
     }
     if ($auto_start) {
         # make shure area starts with 1 day of month
         $dom = date('d', $datestart);
         if ($dom > 1) {
             $datestart -= 86400 * ($dom - 1);
         }
     }
     if ($auto_end) {
         # make shure timeline finishes at 1st day of next month after the last task completion
         while (date('d', $dateend) != 1) {
             $dateend += 86400;
         }
     }
     #        $this->_tcpdf->Line(($startx-2),$starty,$startx-2, $endy); # debug line
     # Now $rawdata ready to render, date range calculated ($datestart, $dateend)
     if ($width <= 0) {
         # if positive width not defined, stretch rendering to ALL available area.
         $width = $this->_tcpdf->getPageWidth() - $startx - self::DEFAULT_MARGIN;
     }
     if ($height <= 0) {
         # the same with height
         $height = $this->_tcpdf->getPageHeight() - $starty - self::DEFAULT_MARGIN;
     }
     # auto-convert title to UTF-8 if needed.
     $title = isset($this->_data['title']) ? $this->_convertCset(trim($this->_data['title'])) : '';
     $shift = $ms_height = 0;
     if ($title) {
         $shift = 8;
         $this->_tcpdf->SetFont('', '', floatval($this->_config['title_fontsize']));
         $this->_tcpdf->MultiCell($width, $height, $title, 0, 'C', 0, 1, $startx, $starty);
     }
     if (count($this->_milestones)) {
         $ms_height = $this->_config['ms_height'];
         if ($ms_height < 1) {
             $ms_height = $height * $ms_height;
         }
     }
     if ($height - $shift - $ms_height < 16) {
         $this->_error_message = 'Too small height to render Gantt chart !';
         return false;
     }
     $descWidth = $this->_config['descr_width'] < 1.0 ? round($width * $this->_config['descr_width'], 2) : floatval($this->_config['descr_width']);
     $timeline_x = $startx + $descWidth + 0.2;
     $timelineWidth = $width - $descWidth - 0.2;
     $ms_size = round($ms_height / 4, 2);
     $max_x = $startx + $width;
     $rgbText = TCPDF_COLORS::convertHTMLColorToDec($this->_config['text_color'], $spotc);
     $rgbGrid = TCPDF_COLORS::convertHTMLColorToDec($this->_config['grid_color'], $spotc);
     $rgbFill = TCPDF_COLORS::convertHTMLColorToDec($this->_config['box_bgcolor'], $spotc);
     $rgbFill2 = TCPDF_COLORS::convertHTMLColorToDec($this->_config['box_bgcolor2'], $spotc);
     $rgbBorder = TCPDF_COLORS::convertHTMLColorToDec($this->_config['box_border'], $spotc);
     $msFill = TCPDF_COLORS::convertHTMLColorToDec($this->_config['ms_color'], $spotc);
     $rgbShade = $this->_config['shade_color'] ? TCPDF_COLORS::convertHTMLColorToDec($this->_config['shade_color'], $spotc) : FALSE;
     $lineStyle = array('width' => 0.1, 'dash' => 0, 'color' => $rgbGrid);
     $height -= $shift + $ms_height;
     if ($ms_height > 0) {
         $this->_tcpdf->SetFillColorArray($rgbFill);
         $this->_tcpdf->SetDrawColorArray($rgbGrid);
     }
     $grid_y = $starty + $shift;
     $milestone_y = $grid_y + $ms_height / 2;
     $timeline_y = $grid_y + $ms_height;
     # gannt timeline top pos (first task row)
     $step_y = round($height / count($rawdata), 2);
     # one row height in the grid
     $rgbBg = $this->_config['bgcolor'] ? TCPDF_COLORS::convertHTMLColorToDec($this->_config['bgcolor'], $spotc) : FALSE;
     #        $boxBorderStyle = array('width' => 0.1,  'dash' => 0, 'color' => $rgbBorder);
     $this->_tcpdf->SetDrawColorArray($rgbGrid);
     if ($rgbBg) {
         $this->_tcpdf->SetFillColorArray($rgbBg);
         $this->_tcpdf->Rect($startx, $grid_y, $width, $height + $ms_height, 'DF');
     } else {
         $this->_tcpdf->Rect($startx, $grid_y, $width, $height + $ms_height, '', $lineStyle, array());
     }
     if ($descWidth > 0) {
         $this->_tcpdf->Line($startx + $descWidth, $grid_y, $timeline_x, $grid_y + $height + $ms_height, $lineStyle);
     }
     $dayWidth = round(($max_x - $timeline_x) / ($dateend - $datestart) * 86400, 3);
     # Draw all vertical bars for month beginnings, and their dates at the bottom:
     $dtstart = date($this->_config['dateformat'], $datestart);
     if (date('d', $datestart) == 1) {
         $this->_tcpdf->SetTextColorArray($rgbText);
         $this->_tcpdf->SetFont('', '', floatval($this->_config['dates_fontsize']));
         $this->_tcpdf->Text($timeline_x - 0.8, $grid_y - 3.2, $dtstart);
     }
     $curdt = $datestart;
     $dt_posx = 0;
     while ($curdt < $dateend) {
         if (date('d', $curdt) == 1) {
             $curdt += 26 * 86400;
         }
         while (date('d', $curdt) != 1) {
             $curdt += 86400;
         }
         $dt_posx = round($timelineWidth * ($curdt - $datestart) / ($dateend - $datestart), 3);
         $strdate = date($this->_config['dateformat'], $curdt);
         if ($timeline_x + $dt_posx > $width) {
             break;
         }
         $this->_tcpdf->Text($timeline_x + $dt_posx - 0.8, $grid_y - 3.2, $strdate);
         $this->_tcpdf->Line($timeline_x + $dt_posx, $grid_y, $timeline_x + $dt_posx, $timeline_y + $height, $lineStyle);
     }
     $kk = 0;
     $coords = array();
     if (count($this->_milestones) && $descWidth > 0) {
         $this->_tcpdf->SetFont('', '', floatval($this->_config['taskdescr_fontsize']));
         $this->_tcpdf->MultiCell($descWidth - 2, 5, $this->_convertCset($this->_locStrings['milestones']), 0, 'L', 0, 1, $startx, $milestone_y - $ms_height * 0.4);
     }
     # draw tasks on timeline
     foreach ($rawdata as $itemid => $rd) {
         $posy = $timeline_y + $step_y * $kk;
         $this->_tcpdf->Line($startx, $posy, $startx + $width, $posy, $lineStyle);
         $rdescr = (self::$_show_taskid ? $itemid . ':' : '') . $this->_convertCset($rd['description']);
         $this->_tcpdf->SetFont('', '', $this->_config['taskdescr_fontsize']);
         if (!empty($rd['color'])) {
             $mrgb = TCPDF_COLORS::convertHTMLColorToDec($rd['color'], $spotc);
             $this->_tcpdf->SetTextColorArray($mrgb);
         } else {
             $this->_tcpdf->SetTextColorArray($rgbText);
         }
         # task description
         if ($descWidth > 0) {
             $this->_tcpdf->MultiCell($descWidth - 2, $step_y / 2, $rdescr, 0, 'L', 0, 1, $startx, $timeline_y + $step_y * $kk + 0.1);
             # working people
             if (!empty($rd['members'])) {
                 # print working people list for the task
                 $memb = is_string($rd['members']) ? explode(',', $rd['members']) : $rd['members'];
                 foreach ($memb as $k => $v) {
                     $memb[$k] = $this->_convertCset($v);
                 }
                 $this->_tcpdf->SetFont('', '', $this->_config['members_fontsize']);
                 $max_h = $step_y - 4.2;
                 if (!empty($rd['mcolor'])) {
                     $mrgb = TCPDF_COLORS::convertHTMLColorToDec($rd['mcolor'], $spotc);
                     $this->_tcpdf->SetTextColorArray($mrgb);
                 }
                 $this->_tcpdf->MultiCell($descWidth - 2, $step_y * 0.6, implode(", ", $memb), 0, 'L', 0, 1, $startx + 3.0, $timeline_y + $step_y * ($kk + 0.3), true, 0, 0, true, $max_h, true);
                 $this->_tcpdf->SetTextColorArray($rgbText);
             }
         }
         # Draw task box on timeline
         $posx1 = round($timelineWidth * ($rd['datestart'] - $datestart) / ($dateend - $datestart), 3);
         $w = round($timelineWidth * ($rd['dateend'] - $datestart) / ($dateend - $datestart), 3) - $posx1 + $dayWidth;
         $rect_x1 = $timeline_x + $posx1;
         # intent
         $rect_x2 = $rect_x1 + $w;
         # intent ending position
         $real_x1 = max($rect_x1, $timeline_x);
         $real_x2 = min($rect_x2, $max_x);
         $real_w = $real_x2 - $real_x1;
         $coords[$itemid] = array($real_x1, $posy + $step_y * 0.2, $real_x2);
         # start x,y and end x, to draw arrows later
         if ($rect_x1 >= $timeline_x && $rect_x1 <= $max_x or $rect_x2 >= $timeline_x && $rect_x2 <= $max_x or $real_x1 < $real_x2) {
             # <4>
             #            if($real_x1 < $real_x2) { # <4> all or a part of task is inside timeline
             # draw shadows ? (shade_color)
             if ($rgbShade) {
                 $this->_tcpdf->SetFillColorArray($rgbShade);
                 $shade_x = max($rect_x1 + floatval($this->_config['shade_offsetx']), $timeline_x);
                 $shade_x2 = min($rect_x2 + floatval($this->_config['shade_offsetx']), $max_x);
                 $shade_w = $shade_x2 - $shade_x;
                 $this->_tcpdf->Rect($shade_x, $posy + $step_y * 0.2 + floatval($this->_config['shade_offsety']), $shade_w, $step_y * 0.57, 'F');
             }
             if (!empty($this->_milestones[$rd['datestart']]) && $rect_x1 == $real_x1) {
                 # draw milestone at this date (if task starts inside timeline)
                 $this->_tcpdf->SetDrawColorArray($rgbGrid);
                 $this->_tcpdf->Line($rect_x1, $milestone_y, $rect_x1, $posy);
                 # vertical line from milestone to task bar
                 $this->_tcpdf->SetFillColorArray($msFill);
                 $this->_tcpdf->SetDrawColorArray($rgbBorder);
                 $p = array($real_x1, $milestone_y + $ms_size, $real_x1 - $ms_size, $milestone_y, $real_x1, $milestone_y - $ms_size, $real_x1 + $ms_size, $milestone_y);
                 $this->_tcpdf->Polygon($p, 'DF');
                 $ms_title = '';
                 #Print milestone title
                 foreach ($this->_milestones[$rd['datestart']] as $ttl) {
                     if ($ttl != '1') {
                         $ms_title .= ($ms_title ? '/' : '') . $ttl;
                     }
                 }
                 $ms_x = $real_x1 + $ms_size;
                 $ms_w = $max_x - $ms_x;
                 if ($ms_title != '' and $ms_x < $max_x) {
                     $this->_tcpdf->SetFont('', '', floatval($this->_config['ms_fontsize']));
                     #                        $this->_printClipped($this->_convertCset($ms_title),$ms_x,($milestone_y-$ms_height*0.2),$ms_w,$ms_height);
                     $this->_tcpdf->MultiCell($ms_w, 3, $this->_convertCset($ms_title), 0, 'L', 0, 1, $ms_x, $milestone_y - $ms_height * 0.6, true, 0, 0, true, $ms_height, true);
                     #                        $this->_tcpdf->Text($real_x1+$ms_size, ($milestone_y-$ms_height*0.2), $this->_convertCset($ms_title));
                 }
             }
             $this->_tcpdf->SetDrawColorArray($rgbBorder);
             $this->_tcpdf->SetFillColorArray($rgbFill);
             $this->_tcpdf->Rect($real_x1, $posy + $step_y * 0.2, $real_w, $step_y * 0.57, 'DF');
             if ($rect_x1 == $real_x1) {
                 # print task date/days only when start date inside timeline
                 $outstr = date($this->_config['dateformat2'], $rd['datestart']);
                 if ($this->_config['show_taskdays']) {
                     $outstr .= ($outstr ? ', ' : '') . sprintf($this->_locStrings['days'], $rd['workdays']);
                 }
                 $this->_tcpdf->SetFont('', '', floatval($this->_config['dates_fontsize']));
                 $this->_tcpdf->Text($timeline_x + $posx1 - 1.0, $posy + $step_y * 0.2 - 2.5, $outstr);
             }
             if ($rd['progress'] < 1) {
                 # draw progress bar inside task
                 $prg_x = $rect_x1 + $w * $rd['progress'] + 0.6;
                 $prg_w = $w * (1 - $rd['progress']) - 1.2;
                 $prg_x2 = min($max_x, $prg_x + $prg_w);
                 $prg_w = $prg_x2 - $prg_x;
                 $prg_rx = max($timeline_x, $prg_x);
                 # real start pos (if tasks starts outside timeline)
                 $prg_w = $prg_x2 - $prg_rx;
                 # real progress width
                 $this->_tcpdf->SetFillColorArray($rgbFill2);
                 $this->_tcpdf->Rect($prg_rx, $posy + $step_y * 0.2 + 0.5, $prg_w, $step_y * 0.57 - 1.0, 'F');
                 $this->_tcpdf->SetFillColorArray($rgbFill);
                 # back to main fill color
                 $strprc = round($rd['progress'] * 100, 2) . ' %';
                 # text representation of completed percent
                 $this->_tcpdf->MultiCell($real_w, 8, $strprc, 0, 'C', 0, 1, $real_x1, $posy + $step_y * 0.3);
             }
         }
         #<4>
         $kk++;
     }
     if ($b_dependencies) {
         # draw arrows from "parent" tasks
         $rgbColor = TCPDF_COLORS::convertHTMLColorToDec($this->_config['arrow_color'], $spotc);
         $this->_tcpdf->SetDrawColorArray($rgbColor);
         $this->_tcpdf->SetFillColorArray($rgbColor);
         $this->_tcpdf->SetLineWidth(0.1);
         // mm
         foreach ($rawdata as $itemid => $rd) {
             if (!empty($rd['dependencies'])) {
                 $darr = is_string($rd['dependencies']) ? explode(',', $rd['dependencies']) : $rd['dependencies'];
                 $b_arr = false;
                 if ($rd['datestart'] >= $datestart && !empty($darr[0])) {
                     foreach ($darr as $taskid) {
                         if (isset($coords[$taskid][0]) && $coords[$taskid][2] < $max_x) {
                             $y_2 = round($coords[$taskid][1] + $step_y * 0.3, 3);
                             $x_2 = max($timeline_x, $coords[$itemid][0] + 1.0);
                             if ($x_2 <= $max_x) {
                                 $poly = array(max($timeline_x, $coords[$taskid][2] + 0.2), $y_2, $x_2 - 0.8, $y_2, $x_2, $y_2 + 0.8, $x_2, $coords[$itemid][1] - 2);
                             } else {
                                 # task ends outside timeline, so draw only horiz.fragment of reference arrow
                                 $poly = array(max($timeline_x, $coords[$taskid][2] + 0.2), $y_2, $max_x, $y_2);
                             }
                             $this->_tcpdf->Polygon($poly, '', array(), array(), false);
                             if (!$b_arr) {
                                 $b_arr = TRUE;
                                 $ary = $coords[$itemid][1] - 2;
                                 $p = array($x_2, $ary, $x_2 + $step_y * 0.07000000000000001, $ary - $step_y * 0.2, $x_2 - $step_y * 0.07000000000000001, $ary - $step_y * 0.2);
                                 $this->_tcpdf->Polygon($p, 'F', array(), array(), true);
                             }
                         }
                     }
                 }
             }
         }
     }
     #restore PDF initial parameters
     $this->_restorePdfState();
     # $this->_tcpdf->setFont('','',$curfontSize);
     return true;
 }
 /**
  * Common behaviour for rendering specified content on the pdf.
  *
  * @param pdf $pdf the pdf object
  * @param string $content the content to render
  */
 public function render_content($pdf, $content)
 {
     list($font, $attr) = $this->get_font();
     $pdf->setFont($font, $attr, $this->element->size);
     $fontcolour = TCPDF_COLORS::convertHTMLColorToDec($this->element->colour, $fontcolour);
     $pdf->SetTextColor($fontcolour['R'], $fontcolour['G'], $fontcolour['B']);
     $x = $this->element->posx;
     $y = $this->element->posy;
     $w = $this->element->width;
     $align = $this->element->align;
     $refpoint = $this->element->refpoint;
     $actualwidth = $pdf->GetStringWidth($content);
     if ($w and $w < $actualwidth) {
         $actualwidth = $w;
     }
     switch ($refpoint) {
         case CUSTOMCERT_REF_POINT_TOPRIGHT:
             $x = $this->element->posx - $actualwidth;
             if ($x < 0) {
                 $x = 0;
                 $w = $this->element->posx;
             } else {
                 $w = $actualwidth;
             }
             break;
         case CUSTOMCERT_REF_POINT_TOPCENTER:
             $x = $this->element->posx - $actualwidth / 2;
             if ($x < 0) {
                 $x = 0;
                 $w = $this->element->posx * 2;
             } else {
                 $w = $actualwidth;
             }
             break;
     }
     if ($w) {
         $w += 0.0001;
     }
     $pdf->setCellPaddings(0, 0, 0, 0);
     $pdf->writeHTMLCell($w, 0, $x, $y, $content, 0, 0, false, true, $align);
 }
示例#8
0
文件: ixmlpdf.php 项目: dapepe/tymio
 public function pdf_convertColor($color)
 {
     return \TCPDF_COLORS::convertHTMLColorToDec($color, $this->spot_colors);
 }