swf2ass/src/ass/drawingTag.php

97 lines
4.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, bool $applyTranslation = true): drawingTag {
return new $this($transform->applyToShape($this->shape, $applyTranslation));
}
/**
* @return string[]
*/
protected function getCommands(float $scale = 1, int $precision = self::PRECISION): array {
$commands = [];
/** @var ?Record $lastEdge */
$lastEdge = null;
foreach ($this->shape->getRecords() as $edge) {
if($lastEdge === null){
if(!($edge instanceof MoveRecord)){
$coords = $edge->getStart()->multiply($scale / Constants::TWIP_SIZE);
$commands[] = "m " . round($coords->x, $precision) . " " . round($coords->y, $precision);
}
}else if(!$lastEdge->getEnd()->equals($edge->getStart()) and !($edge instanceof MoveRecord)){
$coords = $edge->getStart()->multiply($scale / Constants::TWIP_SIZE);
$commands[] = "m " . round($coords->x, $precision) . " " . round($coords->y, $precision);
$lastEdge = null;
}
if ($edge instanceof MoveRecord) {
$coords = $edge->to->multiply($scale / Constants::TWIP_SIZE);
$commands[] = "m " . round($coords->x, $precision) . " " . round($coords->y, $precision);
} else if ($edge instanceof LineRecord) {
$coords = $edge->to->multiply($scale / Constants::TWIP_SIZE);
$commands[] = ($lastEdge instanceof $edge ? "" : "l ") . round($coords->x, $precision) . " " . round($coords->y, $precision);
} else if ($edge instanceof QuadraticCurveRecord or $edge instanceof CubicCurveRecord or $edge instanceof CubicSplineCurveRecord) {
if ($edge instanceof QuadraticCurveRecord) {
$edge = CubicCurveRecord::fromQuadraticRecord($edge);
//TODO: check "q" command
}
if ($edge instanceof CubicCurveRecord) {
$control1 = $edge->control1->multiply($scale / Constants::TWIP_SIZE);
$control2 = $edge->control2->multiply($scale / Constants::TWIP_SIZE);
$anchor = $edge->anchor->multiply($scale / Constants::TWIP_SIZE);
$commands[] = ($lastEdge instanceof $edge ? "" : "b ") . round($control1->x, $precision) . " " . round($control1->y, $precision) . " " . round($control2->x, $precision) . " " . round($control2->y, $precision) . " " . round($anchor->x, $precision) . " " . round($anchor->y, $precision);
}
//TODO
if ($edge instanceof CubicSplineCurveRecord) {
$anchor = $edge->anchor->multiply($scale / Constants::TWIP_SIZE);
$controlPoints = [];
foreach ($edge->control as $control) {
$control = $control->multiply($scale / Constants::TWIP_SIZE);
$controlPoints[] = round($control->x, $precision) . " " . round($control->y, $precision);
}
$commands[] = "s " . implode(" ", $controlPoints) . " " . round($anchor->x, $precision) . " " . round($anchor->y, $precision);
$commands[] = "c";
}
} else {
var_dump($edge);
throw new \Exception("Invalid edge " . get_class($edge));
}
$lastEdge = $edge; //TODO
}
return $commands;
}
public function equals(ASSTag $tag): bool {
return $tag instanceof $this and $this->shape->equals($tag->shape);
}
}