swf2ass/src/ViewLayout.php

150 lines
4.7 KiB
PHP

<?php
namespace swf2ass;
class ViewLayout {
private ?ViewLayout $parent;
/** @var ViewLayout[] */
private array $depthMap = [];
private ?ObjectDefinition $object;
private ?ColorTransform $colorTransform = null;
private ?MatrixTransform $matrixTransform = null;
private int $objectId;
public function __construct(int $objectId, ?ObjectDefinition $object, ?ViewLayout $parent = null) {
$this->objectId = $objectId;
if ($object !== null and $objectId !== $object->getObjectId()) {
throw new \LogicException();
}
$this->parent = $parent;
$this->object = $object;
}
public function getObjectId(): int {
return $this->object !== null ? $this->object->getObjectId() : -1;
}
public function getObject(): ?ObjectDefinition {
return $this->object;
}
/**
* @return ViewLayout[]
*/
public function getDepthMap(): array {
return $this->depthMap;
}
public function get(int $depth): ?ViewLayout {
return $this->depthMap[$depth] ?? null;
}
public function place(int $depth, ViewLayout $ob) {
if ($this->object !== null) {
throw new \LogicException("Cannot have ObjectDefinition and children at the same time");
}
if (isset($this->depthMap[$depth]) and $this->depthMap[$depth] !== $ob) {
throw new \Exception("Depth $depth already exists: tried replacing object " . $this->depthMap[$depth]->getObjectId() . " with " . $ob->getObjectId());
}
$this->depthMap[$depth] = $ob;
}
public function replace(int $depth, ViewLayout $ob) {
if ($this->object !== null) {
throw new \LogicException("Cannot have ObjectDefinition and children at the same time");
}
$oldObject = $this->get($depth);
if ($oldObject !== null) {
$ob->colorTransform = $ob->colorTransform ?? $oldObject->colorTransform;
$ob->matrixTransform = $ob->matrixTransform ?? $oldObject->matrixTransform;
}
$this->depthMap[$depth] = $ob;
}
public function remove(int $depth) {
unset($this->depthMap[$depth]);
}
public function hasFrame(): bool {
if ($this->object !== null) {
if ($this->object instanceof MultiFrameObjectDefinition) {
if ($this->object->hasFrame()) {
return true;
}
}
} else {
foreach ($this->depthMap as $ob) {
if ($ob->hasFrame()) {
return true;
}
}
}
//TODO
return false;
}
public function getMatrixTransform(): ?MatrixTransform {
return $this->matrixTransform;
}
public function getColorTransform(): ?ColorTransform {
return $this->colorTransform;
}
public function setMatrixTransform(?MatrixTransform $transform) {
$this->matrixTransform = $transform;
}
public function setColorTransform(?ColorTransform $transform) {
$this->colorTransform = $transform;
}
public function nextFrame(ActionList $actionList): ViewFrame {
if ($this->object !== null) {
if ($this->object instanceof MultiFrameObjectDefinition) {
$frame = $this->object->nextFrame();
} else {
$frame = new ViewFrame($this->getObjectId(), $this->object->getShapeList());
}
} else {
$frame = new ViewFrame($this->getObjectId(), null);
/** @var ClippingViewLayout[] $clipMap */
$clipMap = [];
ksort($this->depthMap);
foreach ($this->depthMap as $depth => $child) {
if ($child instanceof ClippingViewLayout) {
$clipMap[$depth] = $child;
} else {
/** @var ViewFrame[] $clips */
$clips = []; //TODO: make something else?
foreach ($clipMap as $clipDepth => $clip) {
//$targetDepth = $clip->getClipDepth() + $clipDepth;
if ($clip->getClipDepth() > $depth and $clipDepth < $depth) {
$clips[$clipDepth] = $clip->nextFrame($actionList);
}
}
$f = $child->nextFrame($actionList);
if (count($clips) > 0) {
$f->setClipDepthMap($clips);
}
$frame->addChild($depth, $f);
}
}
}
$frame->setColorTransform($this->colorTransform);
$frame->setMatrixTransform($this->matrixTransform);
return $frame;
}
}