/** * @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; }