protected function doBreakAt($height) { $linesToMove = array(); $numberOfLines = count($this->lines); foreach ($this->lines as $i => $line) { $lineEnd = $line->getYTranslation() + $line->getHeight(); if ($lineEnd > $height) { $linesToMove[] = $line; unset($this->lines[$i]); } } if (!$linesToMove || count($linesToMove) == $numberOfLines) { return null; } $firstLineToMove = current($linesToMove); $yTranslation = $height - $firstLineToMove->getYTranslation(); $height = $firstLineToMove->getYTranslation(); $paragraphProduct = Node::doBreakAt($height); $paragraphProduct->removeAll(); $replaceText = array(); $textsToMove = array(); foreach ($firstLineToMove->getParts() as $part) { $text = $part->getText(); $textHeight = $text->getFirstPoint()->getY() - ($this->getFirstPoint()->getY() - $height); $textProduct = $text->breakAt($textHeight); if ($textProduct) { $replaceText[spl_object_hash($text)] = $textProduct; $paragraphProduct->add($textProduct); $part->setText($textProduct); } else { $replaceText[spl_object_hash($text)] = $text; $textsToMove[spl_object_hash($text)] = $text; } } foreach ($linesToMove as $line) { $line->setYTranslation($line->getYTranslation() - $height); $line->setParagraph($paragraphProduct); $paragraphProduct->addLine($line); } array_shift($linesToMove); foreach ($linesToMove as $line) { foreach ($line->getParts() as $part) { $text = $part->getText(); $hash = spl_object_hash($text); if (isset($replaceText[$hash])) { $part->setText($replaceText[$hash]); } else { $textsToMove[$hash] = $text; } } } foreach ($textsToMove as $text) { $this->remove($text); $paragraphProduct->add($text); } $paragraphProduct->translate(0, $yTranslation); $paragraphProduct->resize(0, -$yTranslation); $paragraphProduct->resize(0, $yTranslation); return $paragraphProduct; }
/** * Breaks compose node. * * @todo refactoring * * @param integer $height * @return \PHPPdf\Core\Node\Node */ protected function doBreakAt($height) { $brokenCompose = parent::doBreakAt($height); if (!$brokenCompose) { return null; } $childrenToBreak = array(); $childrenToMove = array(); $breakLine = $this->getFirstPoint()->getY() - $height; foreach ($this->getChildren() as $child) { $childStart = $child->getFirstPoint()->getY(); $childEnd = $child->getDiagonalPoint()->getY(); if ($breakLine < $childStart && $breakLine > $childEnd) { $childrenToBreak[] = $child; } elseif ($breakLine >= $childStart) { $childrenToMove[] = $child; } } $breakProducts = array(); $translates = array(0); foreach ($childrenToBreak as $child) { $childStart = $child->getFirstPoint()->getY(); $childEnd = $child->getDiagonalPoint()->getY(); $childBreakingLine = $childStart - $breakLine; $originalChildHeight = $child->getHeight(); $breakingProduct = $child->breakAt($childBreakingLine); $yChildStart = $child->getFirstPoint()->getY(); $yChildEnd = $child->getDiagonalPoint()->getY(); if ($breakingProduct) { $heightAfterBreaking = $breakingProduct->getHeight() + $child->getHeight(); $translate = $heightAfterBreaking - $originalChildHeight; $translates[] = $translate + ($yChildEnd - $breakingProduct->getFirstPoint()->getY()); $breakProducts[] = $breakingProduct; } else { $translates[] = $yChildStart - $yChildEnd - ($child->getHeight() - $childBreakingLine); array_unshift($childrenToMove, $child); } } $brokenCompose->removeAll(); $breakProducts = array_merge($breakProducts, $childrenToMove); foreach ($breakProducts as $child) { $brokenCompose->add($child); } $translate = \max($translates); $boundary = $brokenCompose->getBoundary(); $points = $brokenCompose->getBoundary()->getPoints(); $brokenCompose->setHeight($brokenCompose->getHeight() + $translate); $boundary->reset(); $boundary->setNext($points[0])->setNext($points[1])->setNext($points[2]->translate(0, $translate))->setNext($points[3]->translate(0, $translate))->close(); foreach ($childrenToMove as $child) { $child->translate(0, $translate); } return $brokenCompose; }