Skip to content

Commit 5e2be93

Browse files
authored
Simplify text segment decoding by reusing binaryString (#435)
1 parent ba2faa5 commit 5e2be93

3 files changed

Lines changed: 35 additions & 46 deletions

File tree

src/Document/ContentStream/PositionedText/PositionedTextElement.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@ public function getFont(Document $document, Page $page): Font {
2828
/** @throws ParseFailureException */
2929
public function getText(Document $document, Page $page): string {
3030
$font = $this->getFont($document, $page);
31+
$differences = $font->getDifferences();
32+
$encoding = $font->getEncoding();
33+
$toUnicodeCMap = $font->getToUnicodeCMap() ?? $font->getToUnicodeCMapDescendantFont();
3134

3235
$string = '';
3336
foreach ($this->textSegments as $textSegment) {
34-
$string .= $textSegment->getText($font);
37+
$string .= $textSegment->getText($differences, $encoding, $toUnicodeCMap);
3538
}
3639

3740
return $string;

src/Document/ContentStream/PositionedText/TextSegment/TextSegment.php

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
namespace PrinsFrank\PdfParser\Document\ContentStream\PositionedText\TextSegment;
44

5+
use PrinsFrank\PdfParser\Document\CMap\ToUnicode\ToUnicodeCMap;
6+
use PrinsFrank\PdfParser\Document\Dictionary\DictionaryValue\Array\DifferencesArrayValue;
57
use PrinsFrank\PdfParser\Document\Dictionary\DictionaryValue\Name\EncodingNameValue;
68
use PrinsFrank\PdfParser\Document\Dictionary\DictionaryValue\TextString\TextStringValue;
7-
use PrinsFrank\PdfParser\Document\Object\Decorator\Font;
89
use PrinsFrank\PdfParser\Exception\ParseFailureException;
910

1011
readonly class TextSegment {
@@ -13,34 +14,19 @@ public function __construct(
1314
public int|float|null $offset,
1415
) {}
1516

16-
public function getText(Font $font): string {
17-
$text = '';
18-
if (str_starts_with($this->textString->textStringValue, '(') && str_ends_with($this->textString->textStringValue, ')')) {
19-
$unescapedChars = $this->textString->getBinaryString();
20-
if (strlen($unescapedChars) === 1 && ($glyph = $font->getDifferences()?->getGlyph(ord($unescapedChars))) !== null) {
21-
$chars = $glyph->getChar();
22-
} elseif (in_array($encoding = $font->getEncoding(), [EncodingNameValue::MacExpertEncoding, EncodingNameValue::WinAnsiEncoding], true) && $font->getDifferences() === null) {
23-
$chars = $encoding->decodeString($unescapedChars);
24-
} elseif (($toUnicodeCMap = $font->getToUnicodeCMap() ?? $font->getToUnicodeCMapDescendantFont()) !== null) {
25-
$chars = $toUnicodeCMap->textToUnicode(bin2hex($unescapedChars));
26-
} elseif ($encoding !== null) {
27-
$chars = $encoding->decodeString($unescapedChars);
28-
} else {
29-
$chars = $unescapedChars;
30-
}
31-
32-
$text .= $chars;
33-
} elseif (str_starts_with($this->textString->textStringValue, '<') && str_ends_with($this->textString->textStringValue, '>')) {
34-
$chars = substr($this->textString->textStringValue, 1, -1);
35-
if (($toUnicodeCMap = $font->getToUnicodeCMap() ?? $font->getToUnicodeCMapDescendantFont()) !== null) {
36-
$text .= $toUnicodeCMap->textToUnicode($chars);
37-
} elseif (($encoding = $font->getEncoding()) !== null) {
38-
$text .= $encoding->decodeString(implode('', array_map(fn(string $character) => mb_chr((int) hexdec($character)), str_split($chars, 2))));
39-
} else {
40-
$text .= EncodingNameValue::IdentityH->decodeString($chars);
41-
}
17+
public function getText(?DifferencesArrayValue $differences, ?EncodingNameValue $encoding, ?ToUnicodeCMap $toUnicodeCMap): string {
18+
$binaryString = $this->textString->getBinaryString();
19+
if (strlen($binaryString) === 1 && ($glyph = $differences?->getGlyph(ord($binaryString))) !== null) {
20+
$text = $glyph->getChar();
21+
} elseif (in_array($encoding, [EncodingNameValue::MacExpertEncoding, EncodingNameValue::WinAnsiEncoding], true)
22+
&& $differences === null) {
23+
$text = $encoding->decodeString($binaryString);
24+
} elseif ($toUnicodeCMap !== null) {
25+
$text = $toUnicodeCMap->textToUnicode(bin2hex($binaryString));
26+
} elseif ($encoding !== null) {
27+
$text = $encoding->decodeString($binaryString);
4228
} else {
43-
throw new ParseFailureException(sprintf('Unrecognized character group format "%s"', $this->textString->textStringValue));
29+
$text = $binaryString;
4430
}
4531

4632
if ($this->offset !== null && $this->offset < -100) {

tests/Samples/files/issue-235/contents.yml

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,9 +1310,9 @@ pages:
13101310
13111311
Mützen- Erste Dienstgradgruppe ,Feuerwehrfrau oder Feuerwehrmannʻ:
13121312
kordel
1313-
tzkd,et,cz,cs ,zweiilrfbig
1314-
k tzsplieodrkkti.
1315-
Zwteistar , Brdistindraistʻ:
1313+
Mützenkordel, gedreht, schwarz, Durchmesser 6 mm, an zwei silberfarbig ge-
1314+
körnten Mützensplinten oder Druckknöpfen befestigt.
1315+
Zweite Dienstgradgruppe , Brandmeisterin oder Brandmeisterʻ:
13161316
– Mützenkordel, gedreht, silberfarbig, Durchmesser 6 mm, an zwei silberfarbig ge-
13171317
körnten Mützensplinten oder Druckknöpfen befestigt.
13181318
Dritte Dienstgradgruppe , Brandinspektorin oder Brandinspektorʻ:
@@ -1985,24 +1985,24 @@ pages:
19851985
Teil A
19861986
Feuerwehrhelmkennzeichnung nach Ausbildung
19871987
Kennzeichnung Voraussetzung
1988-
roter Punkt, Mitglied mit Abschluss des Ausbildungslehrgangs ,Atemschutzgeräteträgerʻ u
1989-
oder wtAd Atectzrrinn Atectzr
1990-
schwarzes ,Aʻ trrwDV 7
1988+
roter Punkt, Mitglied mit Abschluss des Ausbildungslehrgangs ,Atemschutzgeräteträgerʻ und
1989+
oder weitere Anforderungen an Atemschutzgeräteträgerinnen und Atemschutzgeräte-
1990+
schwarzes ,Aʻ träger nach der FwDV 7
19911991
grüner Punkt, Mitglied mit Abschluss des Ausbildungslehrgangs ,Chemikalienschutzanzugträgerʻ
1992-
oder wtArn AtectzrrinAtectzre-
1993-
schwarzes ,CSAʻ trrwDV 7
1992+
oder und weitere Anforderungen Atemschutzgeräteträgerinnen und Atemschutzgeräte-
1993+
schwarzes ,CSAʻ träger nach der FwDV 7
19941994
ein roter Streifen Mitglied mit Abschluss des Ausbildungslehrgangs ,Gruppenführerʻ
19951995
auf beiden
19961996
Helmseiten
1997-
zwetreifetgli tcs Aldlrg ,Zfrʻ
1998-
f
1999-
Heit
2000-
roti tgliit Acs Aldlrg ,Vsfrʻ
2001-
i CkalisctzatrinChikisctzaträristinzzlic
2002-
Kchnalstsctzrrindtectzrric frlic
2003-
DiKchnfgtctenr Afüu:
2004-
Strf: lgnmoch
2005-
Ri hh.
1997+
zwei rote Streifen Mitglied mit Abschluss des Ausbildungslehrgangs ,Zugführerʻ
1998+
auf beiden
1999+
Helmseiten
2000+
ein roter Ring Mitglied mit Abschluss des Ausbildungslehrgangs ,Verbandsführerʻ
2001+
Bei Chemikalienschutzanzugträgerinnen und Chemikalienschutzanzugträgern ist eine zusätzliche
2002+
Kennzeichnung als Atemschutzgeräteträgerin oder Atemschutzgeräteträger nicht erforderlich.
2003+
Die Kennzeichnung erfolgt in nachstehender Ausführung:
2004+
1. Streifen: 70 mm lang und 10 mm hoch
2005+
2. Ringe: 10 mm hoch.
20062006
Teil B
20072007
Feuerwehrhelmkennzeichnung nach Regelfunktion
20082008
Kennzeichnung Voraussetzung

0 commit comments

Comments
 (0)