Proper clips from parent object creation, they are now processed at a later stage
This commit is contained in:
parent
fa58baceda
commit
4e87f108e9
17
src/ClippingFrame.php
Normal file
17
src/ClippingFrame.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace swf2ass;
|
||||
|
||||
|
||||
class ClippingFrame extends ViewFrame {
|
||||
|
||||
private int $clipDepth;
|
||||
public function __construct(int $objectId, int $clipDepth, ?DrawPathList $drawPathList) {
|
||||
$this->clipDepth = $clipDepth;
|
||||
parent::__construct($objectId, $drawPathList);
|
||||
}
|
||||
|
||||
public function getClipDepth() : int{
|
||||
return $this->clipDepth;
|
||||
}
|
||||
}
|
|
@ -14,4 +14,18 @@ class ClippingViewLayout extends ViewLayout {
|
|||
public function getClipDepth(): int {
|
||||
return $this->clipDepth;
|
||||
}
|
||||
|
||||
public function nextFrame(ActionList $actionList): ClippingFrame {
|
||||
$frame = parent::nextFrame($actionList);
|
||||
|
||||
$clip = new ClippingFrame($frame->getObjectId(), $this->getClipDepth(), $frame->getDrawPathList());
|
||||
|
||||
foreach ($frame->getDepthMap() as $depth => $f){
|
||||
$clip->addChild($depth, $f);
|
||||
}
|
||||
$clip->setColorTransform($frame->getColorTransform());
|
||||
$clip->setMatrixTransform($frame->getMatrixTransform());
|
||||
|
||||
return $clip;
|
||||
}
|
||||
}
|
|
@ -21,6 +21,10 @@ class RenderedObject {
|
|||
$this->clip = $clip;
|
||||
}
|
||||
|
||||
public function setClipPath(?ClipPath $path){
|
||||
$this->clip = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
*/
|
||||
|
|
|
@ -7,8 +7,7 @@ class ViewFrame {
|
|||
private int $objectId;
|
||||
/** @var ViewFrame[] */
|
||||
private array $depthMap = [];
|
||||
/** @var ViewFrame[] */
|
||||
private ?array $clipDepthMap = null;
|
||||
|
||||
private ?DrawPathList $drawPathList;
|
||||
|
||||
private ?ColorTransform $colorTransform = null;
|
||||
|
@ -19,22 +18,14 @@ class ViewFrame {
|
|||
$this->drawPathList = $drawPathList;
|
||||
}
|
||||
|
||||
public function getDrawPathList() : ?DrawPathList{
|
||||
return $this->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();
|
||||
|
@ -81,36 +72,50 @@ class ViewFrame {
|
|||
|
||||
$renderedFrame = new RenderedFrame();
|
||||
|
||||
$clipPath = null;
|
||||
if ($this->clipDepthMap !== null) {
|
||||
$colorIdentity = ColorTransform::identity();
|
||||
$matrixIdentity = $parentMatrix;
|
||||
foreach ($this->clipDepthMap as $clipDepth => $clipFrame) {
|
||||
//TODO: detect rectangle clips?
|
||||
//TODO: clip clips?
|
||||
foreach ($clipFrame->render($clipDepth, $depthChain, $colorIdentity, $matrixIdentity)->getObjects() as $clipObject) {
|
||||
$clipShape = new ClipPath();
|
||||
foreach ($clipObject->drawPathList->commands as $p) {
|
||||
if($p->style instanceof FillStyleRecord){ //Only clip with fills
|
||||
$s = $p->commands->flatten();
|
||||
if($s->getArea() > Constants::EPSILON){
|
||||
$clipShape->addShape($s);
|
||||
if ($this->drawPathList !== null) {
|
||||
$renderedFrame->add(new RenderedObject($depthChain, $this->getObjectId(), $this->drawPathList, $colorTransform ?? ColorTransform::identity(), $matrixTransform ?? MatrixTransform::identity(), null));
|
||||
} else {
|
||||
/** @var ClippingFrame[] $clipMap */
|
||||
$clipMap = [];
|
||||
/** @var ClipPath $clipPaths */
|
||||
$clipPaths = [];
|
||||
|
||||
foreach ($this->depthMap as $depth => $frame) { //Do not require ordering
|
||||
if ($frame instanceof ClippingFrame) { //Process clips as they come
|
||||
$clipMap[$depth] = $frame;
|
||||
$clipPath = null;
|
||||
foreach ($frame->render($depth, $depthChain, $colorTransform, $matrixTransform)->getObjects() as $clipObject) {
|
||||
$clipShape = new ClipPath();
|
||||
foreach ($clipObject->drawPathList->commands as $p) {
|
||||
if ($p->style instanceof FillStyleRecord) { //Only clip with fills
|
||||
$clipShape->addShape($p->commands);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($clipShape->shapes) > 0) {
|
||||
$clipShape = $clipShape->applyMatrixTransform($clipObject->matrixTransform);
|
||||
$clipPath = $clipPath === null ? $clipShape : $clipShape->intersect($clipPath);
|
||||
}
|
||||
}
|
||||
|
||||
if(count($clipShape->shapes) > 0){
|
||||
$clipShape = $clipShape->applyMatrixTransform($clipObject->matrixTransform);
|
||||
$clipPath = $clipPath === null ? $clipShape : $clipShape->intersect($clipPath);
|
||||
if ($clipPath !== null) {
|
||||
$clipPaths[$depth] = $clipPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->drawPathList !== null) {
|
||||
$renderedFrame->add(new RenderedObject($depthChain, $this->getObjectId(), $this->drawPathList, $colorTransform ?? ColorTransform::identity(), $matrixTransform ?? MatrixTransform::identity(), $clipPath));
|
||||
} else {
|
||||
foreach ($this->depthMap as $depth => $frame) {
|
||||
if($frame instanceof ClippingFrame){ //Already processed
|
||||
continue;
|
||||
}
|
||||
|
||||
$clipPath = null;
|
||||
foreach ($clipMap as $clipDepth => $clip) {
|
||||
if ($clip->getClipDepth() > $depth and $clipDepth < $depth) {
|
||||
$clipPath = $clipPath === null ? $clipPaths[$clipDepth] : $clipShape->intersect($clipPath);
|
||||
}
|
||||
}
|
||||
|
||||
$objects = $frame->render($depth, $depthChain, $colorTransform, $matrixTransform)->getObjects();
|
||||
foreach ($objects as $object) {
|
||||
if ($object->clip !== null and $clipPath !== null) {
|
||||
|
|
|
@ -117,33 +117,12 @@ class ViewLayout {
|
|||
}
|
||||
} else {
|
||||
$frame = new ViewFrame($this->getObjectId(), null);
|
||||
/** @var ClippingViewLayout[] $clipMap */
|
||||
$clipMap = [];
|
||||
/** @var ViewFrame[] $clipFrame */
|
||||
$clipFrame = [];
|
||||
|
||||
ksort($this->depthMap);
|
||||
|
||||
foreach ($this->depthMap as $depth => $child) {
|
||||
if ($child instanceof ClippingViewLayout) {
|
||||
$clipMap[$depth] = $child;
|
||||
$clipFrame[$depth] = $child->nextFrame($actionList);
|
||||
} 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] = $clipFrame[$clipDepth];
|
||||
}
|
||||
}
|
||||
|
||||
$f = $child->nextFrame($actionList);
|
||||
if (count($clips) > 0) {
|
||||
$f->setClipDepthMap($clips);
|
||||
}
|
||||
$frame->addChild($depth, $f);
|
||||
}
|
||||
$f = $child->nextFrame($actionList);
|
||||
$frame->addChild($depth, $f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue