diff --git a/src/Document/ContentStream/PositionedText/PositionedTextElement.php b/src/Document/ContentStream/PositionedText/PositionedTextElement.php index 4fcee351..628b3759 100644 --- a/src/Document/ContentStream/PositionedText/PositionedTextElement.php +++ b/src/Document/ContentStream/PositionedText/PositionedTextElement.php @@ -4,7 +4,6 @@ use PrinsFrank\PdfParser\Document\ContentStream\PositionedText\TextSegment\TextSegment; use PrinsFrank\PdfParser\Document\Object\Decorator\Font; -use PrinsFrank\PdfParser\Document\Object\Decorator\Page; use PrinsFrank\PdfParser\Exception\ParseFailureException; readonly class PositionedTextElement { @@ -18,21 +17,12 @@ public function __construct( public TextState $textState, ) {} - public function getFont(Page $page): Font { - if ($this->textState->fontName === null) { - throw new ParseFailureException('Unable to locate font for text element'); - } - - return $page->getFont($this->textState->fontName) - ?? throw new ParseFailureException(sprintf('Unable to locate font with reference "/%s"', $this->textState->fontName->value)); - } - /** @throws ParseFailureException */ - public function getText(Page $page): string { - $font = $this->getFont($page); + public function getText(Font $font): string { $differences = $font->getDifferences(); $encoding = $font->getEncoding(); - $toUnicodeCMap = $font->getToUnicodeCMap() ?? $font->getToUnicodeCMapDescendantFont(); + $toUnicodeCMap = $font->getToUnicodeCMap() + ?? $font->getToUnicodeCMapDescendantFont(); $text = ''; $previousOffset = null; diff --git a/src/Extraction/MarkdownExtractor.php b/src/Extraction/MarkdownExtractor.php index 69d271ef..955b717c 100644 --- a/src/Extraction/MarkdownExtractor.php +++ b/src/Extraction/MarkdownExtractor.php @@ -13,6 +13,7 @@ use PrinsFrank\MarkDownDom\Node\Inline\Text; use PrinsFrank\PdfParser\Document\ContentStream\PositionedText\PositionedTextElement; use PrinsFrank\PdfParser\Document\Object\Decorator\Page; +use PrinsFrank\PdfParser\Exception\ParseFailureException; use PrinsFrank\PdfParser\Exception\PdfParserException; use PrinsFrank\PdfParser\Extraction\SpaceDetection\SpaceDetector; use PrinsFrank\PdfParser\Extraction\TextGrouping\LineGrouping\TextOverlapStrategy; @@ -25,7 +26,7 @@ class MarkdownExtractor { public static function extractContent(array $positionedTextElements, Page $page): Document { $lineGroupedElements = TextOverlapStrategy::group($positionedTextElements); - $blockNodes = $inLineNodes = []; + $blockNodes = $inLineNodes = $fontCache = []; $textBuffer = ''; $previousElementIsBold = $previousElementIsItalic = false; $previousHeadingLevel = null; @@ -48,8 +49,13 @@ public static function extractContent(array $positionedTextElements, Page $page) $previousFontOnLine = null; $previousTextElementEndsWithSpace = false; foreach ($positionedTextElementsForLine as $positionedTextElement) { - $elementText = $positionedTextElement->getText($page); - $font = $positionedTextElement->getFont($page); + if ($positionedTextElement->textState->fontName === null) { + throw new ParseFailureException('Unable to locate font'); + } + + $font = $fontCache[$positionedTextElement->textState->fontName->value] ??= $page->getFont($positionedTextElement->textState->fontName) + ?? throw new ParseFailureException(sprintf('Unable to locate font with reference "/%s"', $positionedTextElement->textState->fontName->value)); + $elementText = $positionedTextElement->getText($font); if ($elementText === '') { $previousTextElementOnLine = $positionedTextElement; $previousFontOnLine = $font; diff --git a/src/Extraction/TextExtractor.php b/src/Extraction/TextExtractor.php index 1ddba7ec..d2b74c53 100644 --- a/src/Extraction/TextExtractor.php +++ b/src/Extraction/TextExtractor.php @@ -4,6 +4,7 @@ use PrinsFrank\PdfParser\Document\ContentStream\PositionedText\PositionedTextElement; use PrinsFrank\PdfParser\Document\Object\Decorator\Page; +use PrinsFrank\PdfParser\Exception\ParseFailureException; use PrinsFrank\PdfParser\Exception\PdfParserException; use PrinsFrank\PdfParser\Extraction\SpaceDetection\SpaceDetector; use PrinsFrank\PdfParser\Extraction\TextGrouping\LineGrouping\TextOverlapStrategy; @@ -16,6 +17,7 @@ class TextExtractor { public static function extractContent(array $positionedTextElements, Page $page): string { $lineGroupedElements = TextOverlapStrategy::group($positionedTextElements); + $fontCache = []; $textBuffer = ''; foreach ($lineGroupedElements as $i => $positionedTextElementsForLine) { if ($i !== 0) { @@ -26,8 +28,13 @@ public static function extractContent(array $positionedTextElements, Page $page) $previousFontOnLine = null; $previousTextElementEndsWithSpace = false; foreach ($positionedTextElementsForLine as $positionedTextElement) { - $elementText = $positionedTextElement->getText($page); - $font = $positionedTextElement->getFont($page); + if ($positionedTextElement->textState->fontName === null) { + throw new ParseFailureException('Unable to locate font'); + } + + $font = $fontCache[$positionedTextElement->textState->fontName->value] ??= $page->getFont($positionedTextElement->textState->fontName) + ?? throw new ParseFailureException(sprintf('Unable to locate font with reference "/%s"', $positionedTextElement->textState->fontName->value)); + $elementText = $positionedTextElement->getText($font); if ($elementText === '') { $previousTextElementOnLine = $positionedTextElement; $previousFontOnLine = $font;