docunit = $unit; $eng = new IPdfWriterEngine( $this->docunit, $this->unicode, false, true, $this->pdfamode, null, $this->fileOptions(), ); $eng->pagecontexthook = $this->ambientPageContent(...); $this->eng = $eng; $this->kratio = $eng->toPoints(1.0); $css = <<eng->addGlobalCSS($css); } /** * Registers a PDF given as a binary string as an import source (replaces FPDI's setSourceFile). * * @return string the source ID to be passed to the other import methods * * @throws \Com\Tecnick\Pdf\Import\ImportException */ public function importPdfSource(string $data): string { return $this->engine()->setImportSourceData($data); } /** * @throws \Com\Tecnick\Pdf\Import\ImportException */ public function getImportedPageCount(string $sourceId): int { return $this->engine()->getSourcePageCount($sourceId); } /** * @throws \Com\Tecnick\Pdf\Import\ImportException */ public function importPdfPage(string $sourceId, int $pageNo): PageTemplateInterface { return $this->engine()->importPage($sourceId, $pageNo); } /** * Returns the size of an imported page in user units (mm). * * @return array{width: float, height: float, orientation: string} */ public function getImportedPageSize(PageTemplateInterface $page): array { $width = $this->engine()->toUnit($page->getWidth()); $height = $this->engine()->toUnit($page->getHeight()); return [ 'width' => $width, 'height' => $height, 'orientation' => ($width > $height ? 'L' : 'P'), ]; } /** * Places an imported page onto the current page (replaces FPDI's useTemplate). * Coordinates and sizes are given in user units (mm); if width/height are omitted, * the original size of the imported page is used. */ public function useImportedPage(PageTemplateInterface $page, float $x = 0, float $y = 0, ?float $width = null, ?float $height = null): void { $this->engine()->useImportedPage($page, $x, $y, $width, $height); } /** * This adds
-tags where necessary. * Test cases are collected in the "Listen-Test"-motion. * Check in the TCPDF-generated PDF that line numbers match the lines. * * @param string[] $linesArr * * @return string[] */ private function printMotionToPDFAddLinebreaks(array $linesArr): array { for ($i = 1; $i < count($linesArr); $i++) { // Does this line start with an ol/ul/li? if (!preg_match('/^<(ol|ul|li)/siu', $linesArr[$i])) { continue; } // Does the previous line end a block element? If not, we need the extra BR if (!preg_match('/<\/(div|p|blockquote|ul|ol|h1|h2|h3|h4|h5|h6)>$/siu', $linesArr[$i - 1])) { $linesArr[$i] = '
' . $linesArr[$i]; } } return $linesArr; } public function getMotionFont(?MotionSection $section): string { if ($section && $section->getSettings()->fixedWidth) { return 'dejavusansmono'; } else { return 'helvetica'; } } public function getMotionFontSize(?MotionSection $section): int { if ($section) { $lineLength = $section->getConsultation()->getSettings()->lineLength; return ($lineLength > 70 ? 10 : 11); } else { return 10; } } /** * Prints the lines of one paragraph of a motion text section, optionally with line numbers on the left. * The line number column has a width of $lineNumberWidth (starting at $x), the text is printed right next to it. * If $firstLineNumber is null, no line numbers are printed. * * @param string[] $lines * @return int|null The line number following the last line of this paragraph */ public function printMotionParagraphLines(array $lines, ?int $firstLineNumber, float $x, float $lineNumberWidth, float $textWidth, string $fontName, float $textSize): ?int { $linesArr = []; foreach ($lines as $line) { $line = str_replace('###LINENUMBER###', '', $line); $line = preg_replace('/
\s*$/siu', '', $line); $linesArr[] = $line . ''; } // Hint about
  • s: The spacing between list items is created by

  • -markup. // This obviously is incorrect according to HTML, but is rendered correctly neverless. // We just have to take care about additional spacing for the line numbers in these cases. $linenr = $firstLineNumber; if ($linenr !== null) { $lineNos = []; for ($i = 0; $i < count($lines); $i++) { if (preg_match('/^<(ul|ol|li)/siu', $linesArr[$i])) { $lineNos[] = ''; // Just for having an additional
    } $lineNos[] = $linenr++; } $text2 = implode('
    ', $lineNos); } else { $text2 = ''; } $page = $this->getPage(); $y = $this->getY(); $this->SetFont($fontName, '', $textSize * 2 / 3); $this->SetTextColor(100, 100, 100); $this->setCellHeightRatio(2.23); $this->writeHTMLCell($lineNumberWidth, 0, $x, $y, $text2, 0, 0, false, true, '', true); $this->setPage($page); $this->SetFont($fontName, '', $textSize); $this->SetTextColor(0, 0, 0); $this->setCellHeightRatio(1.5); $linesArr = $this->printMotionToPDFAddLinebreaks($linesArr); $text1 = implode('
    ', $linesArr); $text1 = str_replace('



  • TCPDF can only handle // for striking through text $text1 = preg_replace('/(.*)<\/span>/iUs', '${1}', $text1); // instead of TCPDF can only handle // for underlined text $text1 = preg_replace('/(.*)<\/span>/iUs', '${1}', $text1); $this->writeHTMLCell($textWidth, 0, $x + $lineNumberWidth, $y, $text1, 0, 1, false, true, '', true); return $linenr; } public function printMotionSection(MotionSection $section): void { $linenr = $section->getFirstLineNumber(); $textSize = $this->getMotionFontSize($section); $fontName = $this->getMotionFont($section); $this->SetFont($fontName, '', $textSize); $this->Ln(7); $hasLineNumbers = !!$section->getSettings()->lineNumbers; if ($section->getSettings()->fixedWidth || $hasLineNumbers) { $paragraphs = $section->getTextParagraphObjects($hasLineNumbers); foreach ($paragraphs as $paragraph) { $linenr = $this->printMotionParagraphLines($paragraph->lines, $hasLineNumbers ? $linenr : null, 12, 12, 173, $fontName, $textSize); $this->Ln(7); } } else { $paras = $section->getTextParagraphLines(); foreach ($paras as $para) { $html = str_replace('###LINENUMBER###', '', implode('', $para->lines)); $html = str_replace('', '
    ', $html); $html = str_replace('getY(); $this->writeHTMLCell(12, 0, 12, $y, '', 0, 0, false, true, '', true); $this->writeHTMLCell(173, 0, 24, null, $html, 0, 1, false, true, '', true); $this->Ln(7); } } } }