예제 #1
0
 /**
  * @param string $path
  * @return VMLPath
  */
 public static function fromSVG($path)
 {
     $vml = new VMLPath();
     $matches = array();
     if (!preg_match_all('/([a-zA-Z])([0-9. \\-,]*)/', $path, $matches, PREG_SET_ORDER)) {
         return $vml;
     }
     $at = (object) array('x' => 0, 'y' => 0);
     $cp = (object) array('x' => 0, 'y' => 0);
     $previous = null;
     $zm = false;
     for (; $set = current($matches); next($matches)) {
         list($cmd, $coords) = array($set[1], array_map('floatval', preg_split('/(?:,|\\s+)/', trim($set[2]))));
         switch ($cmd) {
             case 'z':
             case 'Z':
                 if (strcasecmp($previous, 'm') === 0) {
                     $vml->pop();
                 }
                 if ($zm) {
                     $vml->pop();
                 }
                 $vml->closePath();
                 break;
             case 'M':
                 if (strcasecmp($previous, 'm') === 0) {
                     $vml->pop();
                 }
                 $vml->moveTo($at->x = $coords[0], $at->y = $coords[1]);
                 break;
             case 'L':
                 $vml->lineTo($at->x = $coords[0], $at->y = $coords[1]);
                 break;
             case 'l':
                 $vml->lineTo($at->x += $coords[0], $at->y += $coords[1]);
                 break;
             case 'H':
                 $vml->lineTo($at->x = $coords[0], $at->y);
                 break;
             case 'h':
                 $vml->lineTo($at->x += $coords[0], $at->y);
                 break;
             case 'V':
                 $vml->lineTo($at->x, $at->y = $coords[0]);
                 break;
             case 'v':
                 $vml->lineTo($at->x, $at->y += $coords[0]);
                 break;
             case 'C':
                 $vml->bezierCurveTo($coords[0], $coords[1], $cp->x = $coords[2], $cp->y = $coords[3], $at->x = $coords[4], $at->y = $coords[5]);
                 break;
             case 'c':
                 $vml->bezierCurveTo($at->x + $coords[0], $at->y + $coords[1], $cp->x = $at->x + $coords[2], $cp->y = $at->y + $coords[3], $at->x += $coords[4], $at->y += $coords[5]);
                 break;
             case 'S':
                 if (!$previous || !preg_match('/^[CcSs]$/', $previous)) {
                     $cp->x = $at->x;
                     $cp->y = $at->y;
                 }
                 $vml->bezierCurveTo($at->x + ($at->x - $cp->x), $at->y + ($at->y - $cp->y), $cp->x = $coords[0], $cp->y = $coords[1], $at->x = $coords[2], $at->y = $coords[3]);
                 break;
             case 's':
                 if (!$previous || !preg_match('/^[CcSs]$/', $previous)) {
                     $cp->x = $at->x;
                     $cp->y = $at->y;
                 }
                 $vml->bezierCurveTo($at->x + ($at->x - $cp->x), $at->y + ($at->y - $cp->y), $cp->x = $at->x + $coords[0], $cp->y = $at->y + $coords[1], $at->x += $coords[2], $at->y += $coords[3]);
                 break;
             case 'Q':
                 $vml->quadraticCurveTo($cp->x = $coords[0], $cp->y = $coords[1], $at->x = $coords[2], $at->y = $coords[3]);
                 break;
             case 'q':
                 $vml->quadraticCurveTo($cp->x = $at->x + $coords[0], $cp->y = $at->y + $coords[1], $at->x += $coords[2], $at->y += $coords[3]);
                 break;
             case 'T':
                 if (!$previous || !preg_match('/^[QqTt]$/', $previous)) {
                     $cp->x = $at->x;
                     $cp->y = $at->y;
                 }
                 $vml->quadraticCurveTo($cp->x = $at->x + ($at->x - $cp->x), $cp->y = $at->y + ($at->y - $cp->y), $at->x = $coords[0], $at->y = $coords[1]);
                 break;
             case 't':
                 if (!$previous || !preg_match('/^[QqTt]$/', $previous)) {
                     $cp->x = $at->x;
                     $cp->y = $at->y;
                 }
                 $vml->quadraticCurveTo($cp->x = $at->x + ($at->x - $cp->x), $cp->y = $at->y + ($at->y - $cp->y), $at->x += $coords[0], $at->y += $coords[1]);
                 break;
             case 'A':
             case 'a':
                 break;
         }
         $zm = strcasecmp($cmd, 'm') === 0 && strcasecmp($previous, 'z') === 0;
         $previous = $cmd;
     }
     $vml->endPath();
     return $vml;
 }