swf2ass/src/StyleContainer.php

214 lines
9.4 KiB
PHP

<?php
namespace swf2ass;
class StyleContainer {
public $frx = null, $fry = null;
public $fscx = null, $fscy = null;
public $fax = null, $fay = null;
public ?Vector2 $pos = null;
/** @var ?Vector2[] */
public $move = null;
public ?Color $color1 = null;
public ?Color $color3 = null;
/** @var ?Color */
public $original_color1 = null;
/** @var ?Color */
public $original_color3 = null;
public $bord = null;
public $shad = null;
public $moveTransitionStart = null;
public $moveTransitionEnd = null;
public $transitionStart = null;
public $transitionEnd = null;
public function resetTransformedStyles() {
$this->frx = $this->fry = $this->fscx = $this->fscy = $this->fax = $this->fay;
$this->color1 = $this->original_color1;
$this->color3 = $this->original_color3;
$this->pos = null;
$this->move = null;
$this->transitionStart = null;
$this->transitionEnd = null;
$this->moveTransitionStart = null;
$this->moveTransitionEnd = null;
}
public function isEqualishPosition(StyleContainer $container) {
$pos = $this->move !== null ? $this->move[1] : $this->pos;
return $pos === $container->pos or ($pos !== null and $container->pos !== null and $pos->equals($container->pos));
}
public function isEqualish(StyleContainer $container, $checkPos = true) {
if ($checkPos and !$this->isEqualishPosition($container)) {
return false;
}
foreach (get_object_vars($this) as $k => $value) {
if ($k === "move" or $k === "pos" or $k === "transitionStart" or $k === "transitionEnd" or $k === "moveTransitionStart" or $k === "moveTransitionEnd") {
} elseif ($k === "color1" or $k === "color3" or $k === "original_color1" or $k === "original_color3") {
if (!(($container->{$k} !== null and $value !== null and $container->{$k}->equals($value)) or $container->{$k} === $value)) {
return false;
}
} else if ($container->{$k} !== $value) {
return false;
}
}
return true;
}
public function toString($startFrame = 0, $frameDuration = 1 / 60, StyleContainer $prevValues = null, $outputEmpty = true) {
$a = "";
if ($this->pos !== null and !($prevValues !== null and $prevValues->pos !== null and !$prevValues->pos->equals($this->pos))) {
$p = $this->pos->toPixel();
$a .= "\\pos(" . round($p->x, 2) . "," . round($p->y, 2) . ")";
}
if ($this->move !== null) {
$p1 = $this->move[0]->toPixel();
$p2 = $this->move[1]->toPixel();
$a .= "\\move(" . round($p1->x, 2) . "," . round($p1->y, 2) . "," . round($p2->x, 2) . "," . round($p2->y, 2);
if ($this->moveTransitionStart !== null) {
$a .= "," . round(($this->moveTransitionStart - $startFrame) * $frameDuration * 1000) . "," . round((($this->moveTransitionEnd ?? $this->moveTransitionStart) - $startFrame) * $frameDuration * 1000);
}
$a .= ")";
}
if ($this->transitionStart !== null) {
$a .= "\\t(" . round(($this->transitionStart - $startFrame) * $frameDuration * 1000) . "," . round(($this->transitionEnd ?? $this->transitionStart) * $frameDuration * 1000);
}
foreach (get_object_vars($this) as $k => $value) {
if ($k === "move" or $k === "pos" or $k === "transitionStart" or $k === "transitionEnd" or $k === "moveTransitionStart" or $k === "moveTransitionEnd" or $k === "original_color1" or $k === "original_color3") {
} elseif ($k === "color1") {
if ($prevValues !== null and $prevValues->{$k} !== null and $prevValues->{$k}->equals($value)) {
continue;
}
if ($value !== null) {
$a .= "\\1c&H" . strtoupper(Utils::padHex(dechex($value->b ?? 0))) . strtoupper(Utils::padHex(dechex($value->g ?? 0))) . strtoupper(Utils::padHex(dechex($value->r ?? 0))) . "&\\1a&H" . strtoupper(Utils::padHex(dechex($value->alpha ?? 0))) . "&";
} else if ($outputEmpty) {
$a .= "\\1a&HFF&";
}
} elseif ($k === "color3") {
if ($prevValues !== null and $prevValues->{$k} !== null and $prevValues->{$k}->equals($value)) {
continue;
}
if ($value !== null) {
$a .= "\\3c&H" . strtoupper(Utils::padHex(dechex($value->b ?? 0))) . strtoupper(Utils::padHex(dechex($value->g ?? 0))) . strtoupper(Utils::padHex(dechex($value->r ?? 0))) . "&\\3a&H" . strtoupper(Utils::padHex(dechex($value->alpha ?? 0))) . "&";
} else if ($outputEmpty) {
$a .= "\\3a&HFF&";
}
} else {
if ($prevValues !== null and $prevValues->{$k} !== null and $prevValues->{$k} === $value) {
continue;
}
if ($value !== null) {
$a .= "\\$k$value";
}
}
}
if ($this->transitionStart !== null) {
$a .= ")";
}
return $a;
}
public function doTransitionTo(StyleContainer $style, $transitionStart, $transitionEnd, $moveTransitionStart, $moveTransitionEnd) {
$firstStyle = $this;
$secondStyle = clone $style;
if ($firstStyle->move !== null) {
if ($firstStyle->isEqualishPosition($secondStyle)) {
$secondStyle->pos = $firstStyle->pos;
$secondStyle->move = $firstStyle->move;
$secondStyle->moveTransitionStart = $firstStyle->moveTransitionStart;
$secondStyle->moveTransitionEnd = $firstStyle->moveTransitionEnd;
$firstStyle->pos = null;
$firstStyle->move = null;
$firstStyle->moveTransitionStart = null;
$firstStyle->moveTransitionEnd = null;
} else if (ADVANCED_MOTION_INTERPOLATION and $firstStyle->transitionEnd !== null and $transitionEnd !== null) {
$diffA = $firstStyle->move[1]->sub($firstStyle->move[0])->divide($firstStyle->moveTransitionEnd - $firstStyle->moveTransitionStart);
$diffB = $secondStyle->pos->sub($firstStyle->move[0])->divide($moveTransitionEnd - $firstStyle->moveTransitionStart);
$diff = $diffA->sub($diffB);
if (abs($diff->x) <= 1 and abs($diff->y) <= 1) { //Eh, close enough, it's linear!
$move = $firstStyle->move;
$move[1] = $secondStyle->pos;
$moveTransitionStart = $firstStyle->moveTransitionStart;
if ($firstStyle->isEqualish($secondStyle, false)) {
$firstStyle->pos = null;
$firstStyle->move = $move;
$firstStyle->moveTransitionStart = $moveTransitionStart;
$firstStyle->moveTransitionEnd = $moveTransitionEnd;
return true;
} else {
$firstStyle->pos = null;
$firstStyle->move = null;
$firstStyle->moveTransitionStart = null;
$firstStyle->moveTransitionEnd = null;
$secondStyle->pos = null;
$secondStyle->move = $move;
$secondStyle->moveTransitionStart = $moveTransitionStart;
$secondStyle->moveTransitionEnd = $moveTransitionEnd;
}
} else {
return false;
}
} else {
return false;
}
} else if ($firstStyle->pos !== null and $secondStyle->pos !== null) {
if ($firstStyle->isEqualishPosition($secondStyle)) {
$secondStyle->pos = $firstStyle->pos;
$secondStyle->move = $firstStyle->move;
$secondStyle->moveTransitionStart = $firstStyle->moveTransitionStart;
$secondStyle->moveTransitionEnd = $firstStyle->moveTransitionEnd;
$firstStyle->pos = null;
$firstStyle->move = null;
$firstStyle->moveTransitionStart = null;
$firstStyle->moveTransitionEnd = null;
} else {
$secondStyle->move = [$firstStyle->pos, $secondStyle->pos];
$secondStyle->moveTransitionStart = $moveTransitionStart;
$secondStyle->moveTransitionEnd = $moveTransitionEnd;
$secondStyle->pos = null;
$firstStyle->pos = null;
}
}
$secondStyle->transitionStart = $transitionStart;
$secondStyle->transitionEnd = $transitionEnd;
foreach (get_object_vars($firstStyle) as $k => $value) {
if ($k === "move" or $k === "pos" or $k === "transitionStart" or $k === "transitionEnd" or $k === "moveTransitionStart" or $k === "moveTransitionEnd" or $k === "original_color1" or $k === "original_color3") {
} elseif ($k === "color1" or $k === "color3") {
if ($value !== null and $secondStyle->{$k} !== null and $value->equals($secondStyle->{$k})) {
$secondStyle->{$k} = null;
}
} elseif ($value === $secondStyle->{$k}) {
$secondStyle->{$k} = null;
}
}
return $secondStyle;
}
}