예제 #1
0
 public function format(Node $node, Document $document)
 {
     $node->convertRelativeWidthsOfColumns();
     $node->reduceColumnsWidthsByMargins();
     $columnsWidths = $node->getWidthsOfColumns();
     $columnsMarginsLeft = $node->getMarginsLeftOfColumns();
     $columnsMarginsRight = $node->getMarginsRightOfColumns();
     $numberOfColumns = $node->getNumberOfColumns();
     $totalColumnsWidth = array_sum($columnsWidths);
     $tableWidth = $node->getWidth();
     $enlargeColumnWidth = $numberOfColumns ? ($tableWidth - $totalColumnsWidth) / count($columnsWidths) : 0;
     foreach ($columnsWidths as $index => $width) {
         $columnsWidths[$index] += $enlargeColumnWidth;
     }
     foreach ($node->getChildren() as $row) {
         foreach ($row->getChildren() as $cell) {
             $column = $cell->getNumberOfColumn();
             $colspan = $cell->getColspan();
             $newWidth = 0;
             for ($i = 0; $i < $colspan; $i++) {
                 $newWidth += $columnsWidths[$column + $i];
             }
             $horizontalPaddings = $cell->getPaddingLeft() + $cell->getPaddingRight();
             $cell->setWidth($newWidth - $horizontalPaddings);
             $cell->setMarginLeft($columnsMarginsLeft[$column]);
             $cell->setMarginRight($columnsMarginsRight[$column + $colspan - 1]);
         }
     }
 }
 public function format(Nodes\Node $node, Document $document)
 {
     $minX = $maxX = $minY = $maxY = null;
     foreach ($node->getChildren() as $child) {
         $firstPoint = $child->getFirstPoint();
         $diagonalPoint = $child->getDiagonalPoint();
         $childMinX = $firstPoint->getX() - $child->getMarginLeft();
         $childMaxX = $diagonalPoint->getX() + $child->getMarginRight();
         $childMinY = $diagonalPoint->getY() - $child->getMarginBottom();
         $childMaxY = $firstPoint->getY() + $child->getMarginTop();
         $maxX = $this->changeValueIfIsLess($maxX, $childMaxX);
         $maxY = $this->changeValueIfIsLess($maxY, $childMaxY);
         $minX = $this->changeValueIfIsGreater($minX, $childMinX);
         $minY = $this->changeValueIfIsGreater($minY, $childMinY);
     }
     $paddingVertical = $node->getPaddingTop() + $node->getPaddingBottom();
     $paddingHorizontal = $node->getPaddingLeft() + $node->getPaddingRight();
     $realHeight = $paddingVertical + ($maxY - $minY);
     $realWidth = $paddingHorizontal + ($maxX - $minX);
     if ($realHeight > $node->getHeight()) {
         $node->setHeight($realHeight);
     }
     if ($node->isInline() || $realWidth > $node->getWidth()) {
         $node->setWidth($realWidth);
     }
 }
 private function getMinimumYCoordOfChildren(Node $node)
 {
     $minYCoord = $node->getFirstPoint()->getY() - $node->getPaddingTop();
     foreach ($node->getChildren() as $child) {
         $minYCoord = min($minYCoord, $child->getDiagonalPoint()->getY());
     }
     return $minYCoord;
 }
예제 #4
0
 private function designateLinesOfWords(Node $node)
 {
     $currentPoint = $node->getFirstPoint();
     $partsOfLine = array();
     $yTranslation = 0;
     $line = new Line($node, 0, $yTranslation);
     foreach ($node->getChildren() as $textNode) {
         $words = $textNode->getWords();
         $wordsSizes = $textNode->getWordsSizes();
         $currentWordLine = array();
         $currentWidthOfLine = 0;
         $numberOfWords = count($words);
         $first = true;
         $lineWidth = 0;
         foreach ($words as $index => $word) {
             $wordSize = $wordsSizes[$index];
             $newLineWidth = $currentWidthOfLine + $wordSize;
             $endXCoord = $newLineWidth + $currentPoint->getX();
             $maxLineXCoord = $this->getMaxXCoord($node);
             $isEndOfLine = $endXCoord > $maxLineXCoord;
             if ($isEndOfLine) {
                 if ($currentWordLine) {
                     $partOfLine = new LinePart($currentWordLine, $currentWidthOfLine, $currentPoint->getX() - $node->getFirstPoint()->getX(), $textNode);
                     $partsOfLine[] = $partOfLine;
                     $line->addParts($partsOfLine);
                     $node->addLine($line);
                     $yTranslation += $line->getHeight();
                     $line = new Line($node, 0, $yTranslation);
                     $partsOfLine = array();
                     $currentWidthOfLine = 0;
                     $currentWordLine = array();
                 } else {
                     $line->addParts($partsOfLine);
                     $node->addLine($line);
                     $yTranslation += $line->getHeight();
                     $line = new Line($node, 0, $yTranslation);
                     $partsOfLine = array();
                 }
                 $currentPoint = Point::getInstance($node->getFirstPoint()->getX(), 0);
             }
             $currentWidthOfLine = $currentWidthOfLine + $wordSize;
             $currentWordLine[] = $word;
         }
         if ($currentWordLine) {
             $partOfLine = new LinePart($currentWordLine, $currentWidthOfLine, $currentPoint->getX() - $node->getFirstPoint()->getX(), $textNode);
             $partsOfLine[] = $partOfLine;
             $currentPoint = $currentPoint->translate($currentWidthOfLine, 0);
         }
     }
     if ($partsOfLine) {
         $yTranslation += $line->getHeight();
         $line = new Line($node, 0, $yTranslation);
         $line->addParts($partsOfLine);
         $node->addLine($line);
     }
 }
예제 #5
0
 public function format(Node $node, Document $document)
 {
     if (!$node instanceof Page) {
         throw new InvalidArgumentException('ElasticPageFormatter works only with PHPPdf\\Core\\Node\\Page class.');
     }
     $lastChild = null;
     foreach ($node->getChildren() as $child) {
         if (!$lastChild || $lastChild->getDiagonalPoint()->getY() - $lastChild->getMarginBottom() > $child->getDiagonalPoint()->getY() - $child->getMarginBottom()) {
             $lastChild = $child;
         }
     }
     $lastNodeYCoord = $lastChild ? $lastChild->getDiagonalPoint()->getY() - $lastChild->getMarginBottom() : $node->getRealHeight();
     $height = $node->getRealHeight() - $lastNodeYCoord + $node->getMarginBottom();
     $translate = $node->getRealHeight() - $height;
     $node->setPageSize($node->getRealWidth(), $height);
     foreach ($node->getChildren() as $child) {
         $child->translate(0, $translate);
     }
     $node->removeGraphicsContext();
 }
 public function format(Node $node, Document $document)
 {
     $this->lastVerticalTranslation = 0;
     $nodes = $node instanceof ColumnableContainer ? array($node) : $node->getChildren();
     foreach ($nodes as $node) {
         if ($node instanceof ColumnableContainer) {
             $container = $this->moveAllChildrenToSingleContainer($node);
             $this->breakContainerIntoColumns($node, $container);
             $this->resizeColumnableContainer($node);
             $this->staticBreakYCoord = null;
             $this->stopBreaking = false;
         }
     }
 }
예제 #7
0
 public function format(Node $node, Document $document)
 {
     $boundary = $node->getBoundary();
     $verticalMargins = $node->getMarginsBottomOfCells() + $node->getMarginsTopOfCells();
     $newHeight = $node->getMaxHeightOfCells() + $verticalMargins;
     $heightDiff = $newHeight - $node->getHeight();
     $boundary->pointTranslate(2, 0, $heightDiff)->pointTranslate(3, 0, $heightDiff);
     $node->setHeight($newHeight);
     foreach ((array) $node->getChildren() as $cell) {
         $heightDiff = $node->getMaxHeightOfCells() - $cell->getHeight();
         $cell->setHeight($node->getMaxHeightOfCells());
         $cell->getBoundary()->pointTranslate(2, 0, $heightDiff)->pointTranslate(3, 0, $heightDiff);
         $cell->translate(0, $node->getMarginsTopOfCells());
     }
 }
예제 #8
0
 public function format(Node $node, Document $document)
 {
     $widthsOfColumns = $node->getWidthsOfColumns();
     $tableWidth = $node->getWidthWithoutPaddings();
     $marginsLeft = $node->getMarginsLeftOfColumns();
     $marginsRight = $node->getMarginsRightOfColumns();
     $minWidthsOfColumns = $node->getMinWidthsOfColumns();
     $totalWidth = array_sum($widthsOfColumns);
     $totalMargins = array_sum($marginsLeft) + array_sum($marginsRight);
     $verticalAlignFormatter = $document->getFormatter('PHPPdf\\Core\\Formatter\\VerticalAlignFormatter');
     foreach ($node->getChildren() as $row) {
         $diffBetweenTableAndColumnsWidths = $tableWidth - $totalWidth - $totalMargins;
         $translate = 0;
         foreach ($row->getChildren() as $cell) {
             $column = $cell->getNumberOfColumn();
             $colspan = $cell->getColspan();
             $minWidth = $newWidth = 0;
             for ($i = 0; $i < $colspan; $i++) {
                 $realColumn = $column + $i;
                 $minWidth += $minWidthsOfColumns[$realColumn];
                 $newWidth += $widthsOfColumns[$realColumn];
                 if ($i > 0) {
                     $margins = $marginsRight[$realColumn] + $marginsLeft[$realColumn];
                     $minWidth += $margins;
                     $newWidth += $margins;
                 }
             }
             $diffBetweenNewAndMinWidth = $newWidth - $minWidth;
             if ($diffBetweenTableAndColumnsWidths < 0 && -$diffBetweenTableAndColumnsWidths >= $diffBetweenNewAndMinWidth) {
                 $newWidth = $minWidth;
                 $diffBetweenTableAndColumnsWidths += $diffBetweenNewAndMinWidth;
             } elseif ($diffBetweenTableAndColumnsWidths < 0) {
                 $newWidth += $diffBetweenTableAndColumnsWidths;
                 $diffBetweenTableAndColumnsWidths = 0;
             }
             $cell->convertScalarAttribute('width', $tableWidth);
             $currentWidth = $cell->getWidth();
             $diff = $newWidth - $currentWidth;
             $minWidth = $cell->getMinWidth();
             $cell->setWidth($newWidth);
             $translate += $marginsLeft[$column];
             $cell->translate($translate, 0);
             $cell->resize($diff, 0);
             $translate += $newWidth + $marginsRight[$column];
             $verticalAlignFormatter->format($cell, $document);
         }
     }
 }
예제 #9
0
 public function format(Node $node, Document $document)
 {
     $children = $node->getChildren();
     $attributesSnapshot = $node->getAttributesSnapshot();
     $parentBottomYCoord = null;
     $positionCorrection = false;
     foreach ($children as $child) {
         $translateX = $translateY = 0;
         list($x, $y) = $child->getStartDrawingPoint();
         if ($this->hasFloat($child)) {
             $sibling = $this->getPreviousSiblingWithFloat($child, $child->getFloat());
             list($orgX, $orgY) = $child->getStartDrawingPoint();
             if (!$sibling) {
                 $previousSibling = $child->getPreviousSibling();
                 if ($previousSibling) {
                     $y = $previousSibling->getDiagonalPoint()->getY() - $previousSibling->getMarginBottom() - $child->getMarginTop() - $child->getPaddingTop();
                 }
             }
             $this->setNodesWithFloatPosition($child, $x, $y, $sibling);
             $translateX = $x - $orgX;
             $translateY = -($y - $orgY);
         } elseif ($positionCorrection) {
             $siblings = $child->getSiblings();
             $minYCoord = null;
             $previousSiblingWithMinBottomYCoord = null;
             foreach ($siblings as $sib) {
                 if ($sib === $child) {
                     break;
                 }
                 $previousSibling = $sib;
                 $bottomYCoord = $previousSibling->getDiagonalPoint()->getY() - $previousSibling->getMarginBottom();
                 if ($minYCoord === null || $bottomYCoord < $minYCoord) {
                     $minYCoord = $bottomYCoord;
                     $previousSiblingWithMinBottomYCoord = $previousSibling;
                 }
             }
             if ($minYCoord !== null) {
                 $translateY = -($minYCoord - $y - $child->getMarginTop() - $child->getPaddingTop());
                 if ($child->isInline() && $previousSiblingWithMinBottomYCoord->isInline()) {
                     $translateY -= $child instanceof Text ? $child->getLineHeightRecursively() : $child->getHeight();
                 }
             }
         }
         if ($translateX || $translateY) {
             $child->translate($translateX, $translateY);
         }
         $childBottomYCoord = $child->getDiagonalPoint()->getY() - $child->getMarginBottom();
         if ($parentBottomYCoord === null || $childBottomYCoord < $parentBottomYCoord) {
             $parentBottomYCoord = $childBottomYCoord;
         }
         if ($translateY) {
             $positionCorrection = true;
         }
     }
     if ($positionCorrection && $parentBottomYCoord && !$node->getAttribute('static-size')) {
         $parentTranslate = $node->getDiagonalPoint()->getY() - $parentBottomYCoord + $node->getPaddingBottom();
         $newHeight = $node->getHeight() + $parentTranslate;
         $oldHeight = isset($attributesSnapshot['height']) ? $attributesSnapshot['height'] : 0;
         if ($newHeight < $oldHeight) {
             $parentTranslate += $oldHeight - $newHeight;
             $newHeight = $oldHeight;
         }
         $node->setHeight($newHeight);
         $node->getBoundary()->pointTranslate(2, 0, $parentTranslate);
         $node->getBoundary()->pointTranslate(3, 0, $parentTranslate);
     }
 }
예제 #10
0
 public function format(Nodes\Node $node, \PHPPdf\Core\Document $document)
 {
     foreach ($node->getChildren() as $child) {
         $child->format($document);
     }
 }