swf2ass/src/ViewFrame.php

113 lines
3.7 KiB
PHP

<?php
namespace swf2ass;
class ViewFrame {
private int $objectId;
/** @var ViewFrame[] */
private array $depthMap = [];
/** @var ViewFrame[] */
private ?array $clipDepthMap = null;
private ?DrawPathList $drawPathList;
private ?ColorTransform $colorTransform = null;
private ?MatrixTransform $matrixTransform = null;
public function __construct(int $objectId, ?DrawPathList $drawPathList) {
$this->objectId = $objectId;
$this->drawPathList = $drawPathList;
}
public function getObjectId(): int {
return $this->objectId;
}
public function setClipDepthMap(array $clipDepthMap) {
$this->clipDepthMap = $clipDepthMap;
//TODO: process this
}
/**
* @return ViewFrame[]|null
*/
public function getClipDepthMap(): ?array {
return $this->clipDepthMap;
}
public function addChild(int $depth, ViewFrame $frame) {
if ($this->drawPathList !== null) {
throw new \Exception();
}
$this->depthMap[$depth] = $frame;
}
/**
* @return ViewFrame[]
*/
public function getDepthMap(): array {
return $this->depthMap;
}
public function setColorTransform(?ColorTransform $transform) {
$this->colorTransform = $transform;
}
public function setMatrixTransform(?MatrixTransform $transform) {
$this->matrixTransform = $transform;
}
public function getColorTransform(): ?ColorTransform {
return $this->colorTransform;
}
public function getMatrixTransform(): ?MatrixTransform {
return $this->matrixTransform;
}
public function render(int $baseDepth, array $depthChain, ColorTransform $parentColor, MatrixTransform $parentMatrix): RenderedFrame {
$depthChain[] = $baseDepth;
$matrixTransform = $this->matrixTransform !== null ? $parentMatrix->combine($this->matrixTransform) : $parentMatrix;
$colorTransform = $this->colorTransform !== null ? $parentColor->combine($this->colorTransform) : $parentColor;
$renderedFrame = new RenderedFrame();
$clipShape = null;
if ($this->clipDepthMap !== null) {
$colorIdentity = ColorTransform::identity();
$matrixIdentity = MatrixTransform::identity();
$clipShape = new Shape();
foreach ($this->clipDepthMap as $clipDepth => $clipFrame) {
//TODO: detect rectangle clips? for \iclip
//TODO: add \clip for bounds
foreach ($clipFrame->render($clipDepth, $depthChain, $colorIdentity, $matrixIdentity)->getObjects() as $clipObject) {
foreach ($clipObject->drawPathList->commands as $clipPath) {
//TODO: is transform here needed?
$clipShape = $clipShape->merge($clipObject->matrixTransform->applyToShape($clipPath->commands));
}
}
}
}
if ($this->drawPathList !== null) {
$renderedFrame->add(new RenderedObject($depthChain, $this->getObjectId(), $this->drawPathList, $colorTransform, $matrixTransform, $clipShape));
} else {
foreach ($this->depthMap as $depth => $frame) {
$objects = $frame->render($depth, $depthChain, $colorTransform, $matrixTransform)->getObjects();
foreach ($objects as $object) {
if ($object->clip !== null and $clipShape !== null) {
$object->clip = $object->clip->merge($clipShape);
} else if ($clipShape !== null) {
$object->clip = $clipShape;
}
$renderedFrame->add($object);
}
}
}
return $renderedFrame;
}
}