swf2ass/src/ass/drawingTag.php

83 lines
3.1 KiB
PHP

<?php
namespace swf2ass\ass;
use swf2ass\Constants;
use swf2ass\CubicCurveRecord;
use swf2ass\CubicSplineCurveRecord;
use swf2ass\LineRecord;
use swf2ass\LineStyleRecord;
use swf2ass\MatrixTransform;
use swf2ass\MoveRecord;
use swf2ass\QuadraticCurveRecord;
use swf2ass\Record;
use swf2ass\Shape;
use swf2ass\StyleRecord;
abstract class drawingTag implements ASSTag {
const PRECISION = 2;
protected Shape $shape;
public function __construct(Shape $shape) {
$this->shape = $shape;
}
public function applyMatrixTransform(MatrixTransform $transform): drawingTag {
return new $this($transform->applyToShape($this->shape));
}
/**
* @return string[]
*/
protected function getCommands(): array {
$commands = [];
/** @var ?Record $lastEdge */
$lastEdge = null;
foreach ($this->shape->edges as $edge) {
if ($edge instanceof MoveRecord) {
$coords = $edge->coord->toPixel();
$commands[] = "m " . round($coords->x, self::PRECISION) . " " . round($coords->y, self::PRECISION) . " ";
} else if ($edge instanceof LineRecord) {
$coords = $edge->coord->toPixel();
$commands[] = "l " . round($coords->x, self::PRECISION) . " " . round($coords->y, self::PRECISION) . " ";
} else if ($edge instanceof QuadraticCurveRecord or $edge instanceof CubicCurveRecord or $edge instanceof CubicSplineCurveRecord) {
if ($edge instanceof QuadraticCurveRecord) {
$edge = CubicCurveRecord::fromQuadraticRecord($edge);
}
if ($edge instanceof CubicCurveRecord) {
$control1 = $edge->control1->toPixel();
$control2 = $edge->control2->toPixel();
$anchor = $edge->anchor->toPixel();
$commands[] = "b " . round($control1->x, self::PRECISION) . " " . round($control1->y, self::PRECISION) . " " . round($control2->x, self::PRECISION) . " " . round($control2->y, self::PRECISION) . " " . round($anchor->x, self::PRECISION) . " " . round($anchor->y, self::PRECISION) . " ";
}
//TODO
if ($edge instanceof CubicSplineCurveRecord) {
$anchor = $edge->anchor->toPixel();
$controlPoints = [];
foreach ($edge->control as $control) {
$control = $control->toPixel();
$controlPoints[] = round($control->x, self::PRECISION) . " " . round($control->y, self::PRECISION);
}
$commands[] = "s " . implode(" ", $controlPoints) . " " . round($anchor->x, self::PRECISION) . " " . round($anchor->y, self::PRECISION) . " ";
}
} else {
var_dump($edge);
throw new \Exception("Invalid edge " . get_class($edge));
}
$lastEdge = $edge;
}
return $commands;
}
public function equals(ASSTag $tag): bool {
return $tag instanceof $this and $this->encode() === $tag->encode();
}
}