Test Failed
Pull Request — master (#614)
by
unknown
02:15
created

Font::loadTranslateTable()   C

Complexity

Conditions 16
Paths 14

Size

Total Lines 106
Code Lines 57

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 57
CRAP Score 16

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 16
eloc 57
c 3
b 0
f 0
nc 14
nop 0
dl 0
loc 106
ccs 57
cts 57
cp 1
crap 16
rs 5.5666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @file
5
 *          This file is part of the PdfParser library.
6
 *
7
 * @author  Sébastien MALOT <[email protected]>
8
 *
9
 * @date    2017-01-03
10
 *
11
 * @license LGPLv3
12
 *
13
 * @url     <https://github.com/smalot/pdfparser>
14
 *
15
 *  PdfParser is a pdf library written in PHP, extraction oriented.
16
 *  Copyright (C) 2017 - Sébastien MALOT <[email protected]>
17
 *
18
 *  This program is free software: you can redistribute it and/or modify
19
 *  it under the terms of the GNU Lesser General Public License as published by
20
 *  the Free Software Foundation, either version 3 of the License, or
21
 *  (at your option) any later version.
22
 *
23
 *  This program is distributed in the hope that it will be useful,
24
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
25
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26
 *  GNU Lesser General Public License for more details.
27
 *
28
 *  You should have received a copy of the GNU Lesser General Public License
29
 *  along with this program.
30
 *  If not, see <http://www.pdfparser.org/sites/default/LICENSE.txt>.
31
 */
32
33
namespace Smalot\PdfParser;
34
35
use Smalot\PdfParser\Encoding\WinAnsiEncoding;
36
use Smalot\PdfParser\Exception\EncodingNotFoundException;
37
38
/**
39
 * Class Font
40
 */
41
class Font extends PDFObject
42
{
43
    public const MISSING = '?';
44
45
    /**
46
     * @var array
47
     */
48
    protected $table;
49
50
    /**
51
     * @var array
52
     */
53
    protected $tableSizes;
54
55
    /**
56
     * Caches results from uchr.
57
     *
58
     * @var array
59
     */
60
    private static $uchrCache = [];
61
62
    /**
63
     * In some PDF-files encoding could be referenced by object id but object itself does not contain
64
     * `/Type /Encoding` in its dictionary. These objects wouldn't be initialized as Encoding in
65
     * \Smalot\PdfParser\PDFObject::factory() during file parsing (they would be just PDFObject).
66
     *
67
     * Therefore, we create an instance of Encoding from them during decoding and cache this value in this property.
68
     *
69
     * @var Encoding
70
     *
71
     * @see https://github.com/smalot/pdfparser/pull/500
72
     */
73
    private $initializedEncodingByPdfObject;
74
75 43
    public function init()
76
    {
77
        // Load translate table.
78 43
        $this->loadTranslateTable();
79 43
    }
80
81 3
    public function getName(): string
82
    {
83 3
        return $this->has('BaseFont') ? (string) $this->get('BaseFont') : '[Unknown]';
84
    }
85
86 3
    public function getType(): string
87
    {
88 3
        return (string) $this->header->get('Subtype');
89
    }
90
91 2
    public function getDetails(bool $deep = true): array
92
    {
93 2
        $details = [];
94
95 2
        $details['Name'] = $this->getName();
96 2
        $details['Type'] = $this->getType();
97 2
        $details['Encoding'] = ($this->has('Encoding') ? (string) $this->get('Encoding') : 'Ansi');
98
99 2
        $details += parent::getDetails($deep);
100
101 2
        return $details;
102
    }
103
104
    /**
105
     * @return string|bool
106
     */
107 25
    public function translateChar(string $char, bool $use_default = true)
108
    {
109 25
        $dec = hexdec(bin2hex($char));
110
111 25
        if (\array_key_exists($dec, $this->table)) {
112 22
            return $this->table[$dec];
113
        }
114
115
        // fallback for decoding single-byte ANSI characters that are not in the lookup table
116 7
        $fallbackDecoded = $char;
117
        if (
118 7
            \strlen($char) < 2
119 7
            && $this->has('Encoding')
120 7
            && $this->get('Encoding') instanceof Encoding
121
        ) {
122
            try {
123 2
                if (WinAnsiEncoding::class === $this->get('Encoding')->__toString()) {
124 1
                    $fallbackDecoded = self::uchr($dec);
125
                }
126 1
            } catch (EncodingNotFoundException $e) {
127
                // Encoding->getEncodingClass() throws EncodingNotFoundException when BaseEncoding doesn't exists
128
                // See table 5.11 on PDF 1.5 specs for more info
129
            }
130
        }
131
132 7
        return $use_default ? self::MISSING : $fallbackDecoded;
133
    }
134
135
    /**
136
     * Convert unicode character code to "utf-8" encoded string.
137
     */
138 40
    public static function uchr(int $code): string
139
    {
140 40
        if (!isset(self::$uchrCache[$code])) {
141
            // html_entity_decode() will not work with UTF-16 or UTF-32 char entities,
142
            // therefore, we use mb_convert_encoding() instead
143 12
            self::$uchrCache[$code] = mb_convert_encoding("&#{$code};", 'UTF-8', 'HTML-ENTITIES');
144
        }
145
146 40
        return self::$uchrCache[$code];
147
    }
148
149
    /**
150
     * Init internal chars translation table by ToUnicode CMap.
151
     */
152 43
    public function loadTranslateTable(): array
153
    {
154 43
        if (null !== $this->table) {
155 1
            return $this->table;
156
        }
157
158 43
        $this->table = [];
159 43
        $this->tableSizes = [
160
            'from' => 1,
161
            'to' => 1,
162
        ];
163
164 43
        if ($this->has('ToUnicode')) {
165 35
            $content = $this->get('ToUnicode')->getContent();
166 35
            $matches = [];
167
168
            // Support for multiple spacerange sections
169 35
            if (preg_match_all('/begincodespacerange(?P<sections>.*?)endcodespacerange/s', $content, $matches)) {
170 35
                foreach ($matches['sections'] as $section) {
171 35
                    $regexp = '/<(?P<from>[0-9A-F]+)> *<(?P<to>[0-9A-F]+)>[ \r\n]+/is';
172
173 35
                    preg_match_all($regexp, $section, $matches);
174
175 35
                    $this->tableSizes = [
176 35
                        'from' => max(1, \strlen(current($matches['from'])) / 2),
177 35
                        'to' => max(1, \strlen(current($matches['to'])) / 2),
178
                    ];
179
180 35
                    break;
181
                }
182
            }
183
184
            // Support for multiple bfchar sections
185 35
            if (preg_match_all('/beginbfchar(?P<sections>.*?)endbfchar/s', $content, $matches)) {
186 16
                foreach ($matches['sections'] as $section) {
187 16
                    $regexp = '/<(?P<from>[0-9A-F]+)> +<(?P<to>[0-9A-F]+)>[ \r\n]+/is';
188
189 16
                    preg_match_all($regexp, $section, $matches);
190
191 16
                    $this->tableSizes['from'] = max(1, \strlen(current($matches['from'])) / 2);
192
193 16
                    foreach ($matches['from'] as $key => $from) {
194 16
                        $parts = preg_split(
195 16
                            '/([0-9A-F]{4})/i',
196 16
                            $matches['to'][$key],
197 16
                            0,
198 16
                            \PREG_SPLIT_NO_EMPTY | \PREG_SPLIT_DELIM_CAPTURE
199
                        );
200 16
                        $text = '';
201 16
                        foreach ($parts as $part) {
202 16
                            $text .= self::uchr(hexdec($part));
203
                        }
204 16
                        $this->table[hexdec($from)] = $text;
205
                    }
206
                }
207
            }
208
209
            // Support for multiple bfrange sections
210 35
            if (preg_match_all('/beginbfrange(?P<sections>.*?)endbfrange/s', $content, $matches)) {
211 26
                foreach ($matches['sections'] as $section) {
212
                    // Support for : <srcCode1> <srcCode2> <dstString>
213 26
                    $regexp = '/<(?P<from>[0-9A-F]+)> *<(?P<to>[0-9A-F]+)> *<(?P<offset>[0-9A-F]+)>[ \r\n]+/is';
214
215 26
                    preg_match_all($regexp, $section, $matches);
216
217 26
                    foreach ($matches['from'] as $key => $from) {
218 26
                        $char_from = hexdec($from);
219 26
                        $char_to = hexdec($matches['to'][$key]);
220 26
                        $offset = hexdec($matches['offset'][$key]);
221
222 26
                        for ($char = $char_from; $char <= $char_to; ++$char) {
223 26
                            $this->table[$char] = self::uchr($char - $char_from + $offset);
224
                        }
225
                    }
226
227
                    // Support for : <srcCode1> <srcCodeN> [<dstString1> <dstString2> ... <dstStringN>]
228
                    // Some PDF file has 2-byte Unicode values on new lines > added \r\n
229 26
                    $regexp = '/<(?P<from>[0-9A-F]+)> *<(?P<to>[0-9A-F]+)> *\[(?P<strings>[\r\n<>0-9A-F ]+)\][ \r\n]+/is';
230
231 26
                    preg_match_all($regexp, $section, $matches);
232
233 26
                    foreach ($matches['from'] as $key => $from) {
234 1
                        $char_from = hexdec($from);
235 1
                        $strings = [];
236
237 1
                        preg_match_all('/<(?P<string>[0-9A-F]+)> */is', $matches['strings'][$key], $strings);
238
239 1
                        foreach ($strings['string'] as $position => $string) {
240 1
                            $parts = preg_split(
241 1
                                '/([0-9A-F]{4})/i',
242
                                $string,
243 1
                                0,
244 1
                                \PREG_SPLIT_NO_EMPTY | \PREG_SPLIT_DELIM_CAPTURE
245
                            );
246 1
                            $text = '';
247 1
                            foreach ($parts as $part) {
248 1
                                $text .= self::uchr(hexdec($part));
249
                            }
250 1
                            $this->table[$char_from + $position] = $text;
251
                        }
252
                    }
253
                }
254
            }
255
        }
256
257 43
        return $this->table;
258
    }
259
260
    /**
261
     * Set custom char translation table where:
262
     * - key - integer character code;
263
     * - value - "utf-8" encoded value;
264
     *
265
     * @return void
266
     */
267 1
    public function setTable(array $table)
268
    {
269 1
        $this->table = $table;
270 1
    }
271
272
    /**
273
     * Calculate text width with data from header 'Widths'. If width of character is not found then character is added to missing array.
274
     */
275 1
    public function calculateTextWidth(string $text, array &$missing = null): ?float
276
    {
277 1
        $index_map = array_flip($this->table);
278 1
        $details = $this->getDetails();
279 1
        $widths = $details['Widths'];
280
281
        // Widths array is zero indexed but table is not. We must map them based on FirstChar and LastChar
282 1
        $width_map = array_flip(range($details['FirstChar'], $details['LastChar']));
283
284 1
        $width = null;
285 1
        $missing = [];
286 1
        $textLength = mb_strlen($text);
287 1
        for ($i = 0; $i < $textLength; ++$i) {
288 1
            $char = mb_substr($text, $i, 1);
289
            if (
290 1
                !\array_key_exists($char, $index_map)
291 1
                || !\array_key_exists($index_map[$char], $width_map)
292 1
                || !\array_key_exists($width_map[$index_map[$char]], $widths)
293
            ) {
294 1
                $missing[] = $char;
295 1
                continue;
296
            }
297 1
            $width_index = $width_map[$index_map[$char]];
298 1
            $width += $widths[$width_index];
299
        }
300
301 1
        return $width;
302
    }
303
304
    /**
305
     * Decode hexadecimal encoded string. If $add_braces is true result value would be wrapped by parentheses.
306
     */
307 46
    public static function decodeHexadecimal(string $hexa, bool $add_braces = false): string
308
    {
309
        // Special shortcut for XML content.
310 46
        if (false !== stripos($hexa, '<?xml')) {
311 2
            return $hexa;
312
        }
313
314 46
        $text = '';
315 46
        $parts = preg_split('/(<[a-f0-9]+>)/si', $hexa, -1, \PREG_SPLIT_NO_EMPTY | \PREG_SPLIT_DELIM_CAPTURE);
316
317 46
        foreach ($parts as $part) {
318 46
            if (preg_match('/^<.*>$/s', $part) && false === stripos($part, '<?xml')) {
319
                // strip line breaks
320 16
                $part = preg_replace("/[\r\n]/", '', $part);
321 16
                $part = trim($part, '<>');
322 16
                if ($add_braces) {
323 1
                    $text .= '(';
324
                }
325
326 16
                $part = pack('H*', $part);
327 16
                $text .= ($add_braces ? preg_replace('/\\\/s', '\\\\\\', $part) : $part);
328
329 16
                if ($add_braces) {
330 16
                    $text .= ')';
331
                }
332
            } else {
333 46
                $text .= $part;
334
            }
335
        }
336
337 46
        return $text;
338
    }
339
340
    /**
341
     * Decode string with octal-decoded chunks.
342
     */
343 46
    public static function decodeOctal(string $text): string
344
    {
345 46
        $parts = preg_split('/(\\\\[0-7]{3})/s', $text, -1, \PREG_SPLIT_NO_EMPTY | \PREG_SPLIT_DELIM_CAPTURE);
346 46
        $text = '';
347
348 46
        foreach ($parts as $part) {
349 46
            if (preg_match('/^\\\\[0-7]{3}$/', $part)) {
350 22
                $text .= \chr(octdec(trim($part, '\\')));
351
            } else {
352 46
                $text .= $part;
353
            }
354
        }
355
356 46
        return $text;
357
    }
358
359
    /**
360
     * Decode string with html entity encoded chars.
361
     */
362 60
    public static function decodeEntities(string $text): string
363
    {
364 60
        $parts = preg_split('/(#\d{2})/s', $text, -1, \PREG_SPLIT_NO_EMPTY | \PREG_SPLIT_DELIM_CAPTURE);
365 60
        $text = '';
366
367 60
        foreach ($parts as $part) {
368 60
            if (preg_match('/^#\d{2}$/', $part)) {
369 4
                $text .= \chr(hexdec(trim($part, '#')));
370
            } else {
371 60
                $text .= $part;
372
            }
373
        }
374
375 60
        return $text;
376
    }
377
378
    /**
379
     * Check if given string is Unicode text (by BOM);
380
     * If true - decode to "utf-8" encoded string.
381
     * Otherwise - return text as is.
382
     *
383
     * @todo Rename in next major release to make the name correspond to reality (for ex. decodeIfUnicode())
384
     */
385 46
    public static function decodeUnicode(string $text): string
386
    {
387 46
        if (preg_match('/^\xFE\xFF/i', $text)) {
388
            // Strip U+FEFF byte order marker.
389 27
            $decode = substr($text, 2);
390 27
            $text = '';
391 27
            $length = \strlen($decode);
392
393 27
            for ($i = 0; $i < $length; $i += 2) {
394 27
                $text .= self::uchr(hexdec(bin2hex(substr($decode, $i, 2))));
395
            }
396
        }
397
398 46
        return $text;
399
    }
400
401
    /**
402
     * @todo Deprecated, use $this->config->getFontSpaceLimit() instead.
403
     */
404 25
    protected function getFontSpaceLimit(): int
405
    {
406 25
        return $this->config->getFontSpaceLimit();
407
    }
408
409
    /**
410
     * Decode text by commands array.
411
     */
412 25
    public function decodeText(array $commands): string
413
    {
414 25
        $word_position = 0;
415 25
        $words = [];
416 25
        $font_space = $this->getFontSpaceLimit();
417
418 25
        foreach ($commands as $command) {
419 25
            switch ($command[PDFObject::TYPE]) {
420 25
                case 'n':
421 19
                    if ((float) trim($command[PDFObject::COMMAND]) < $font_space) {
422 11
                        $word_position = \count($words);
423
                    }
424 19
                    continue 2;
425 25
                case '<':
426
                    // Decode hexadecimal.
427 14
                    $text = self::decodeHexadecimal('<'.$command[PDFObject::COMMAND].'>');
428 14
                    break;
429
430
                default:
431
                    // Decode octal (if necessary).
432 18
                    $text = self::decodeOctal($command[PDFObject::COMMAND]);
433
            }
434
435
            // replace escaped chars
436 25
            $text = str_replace(
437 25
                ['\\\\', '\(', '\)', '\n', '\r', '\t', '\f', '\ '],
438 25
                ['\\', '(', ')', "\n", "\r", "\t", "\f", ' '],
439
                $text
440
            );
441
442
            // add content to result string
443 25
            if (isset($words[$word_position])) {
444 19
                $words[$word_position] .= $text;
445
            } else {
446 25
                $words[$word_position] = $text;
447
            }
448
        }
449
450 25
        foreach ($words as &$word) {
451 25
            $word = $this->decodeContent($word);
452
        }
453
454 25
        return implode(' ', $words);
455
    }
456
457
    /**
458
     * Decode given $text to "utf-8" encoded string.
459
     *
460
     * @param bool $unicode This parameter is deprecated and might be removed in a future release
461
     */
462 27
    public function decodeContent(string $text, bool &$unicode = null): string
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected T_VARIABLE, expecting T_STRING or T_NAME_QUALIFIED or T_NAME_FULLY_QUALIFIED or T_NAME_RELATIVE on line 462 at column 54
Loading history...
463
    {
464 27
        if ($this->has('ToUnicode')) {
465 22
            return $this->decodeContentByToUnicodeCMapOrDescendantFonts($text);
466
        }
467
468 19
        if ($this->has('Encoding')) {
469 14
            $result = $this->decodeContentByEncoding($text);
470
471 14
            if (null !== $result) {
472 14
                return $result;
473
            }
474
        }
475
476 9
        return $this->decodeContentByAutodetectIfNecessary($text);
477
    }
478
479
    /**
480
     * First try to decode $text by ToUnicode CMap.
481
     * If char translation not found in ToUnicode CMap tries:
482
     *  - If DescendantFonts exists tries to decode char by one of that fonts.
483
     *      - If have no success to decode by DescendantFonts interpret $text as a string with "Windows-1252" encoding.
484
     *  - If DescendantFonts does not exist just return "?" as decoded char.
485
     *
486
     * @todo Seems this is invalid algorithm that do not follow pdf-format specification. Must be rewritten.
487
     */
488 22
    private function decodeContentByToUnicodeCMapOrDescendantFonts(string $text): string
489
    {
490 22
        $bytes = $this->tableSizes['from'];
491
492 22
        if ($bytes) {
493 22
            $result = '';
494 22
            $length = \strlen($text);
495
496 22
            for ($i = 0; $i < $length; $i += $bytes) {
497 22
                $char = substr($text, $i, $bytes);
498
499 22
                if (false !== ($decoded = $this->translateChar($char, false))) {
500 22
                    $char = $decoded;
501
                } elseif ($this->has('DescendantFonts')) {
502
                    if ($this->get('DescendantFonts') instanceof PDFObject) {
503
                        $fonts = $this->get('DescendantFonts')->getHeader()->getElements();
504
                    } else {
505
                        $fonts = $this->get('DescendantFonts')->getContent();
506
                    }
507
                    $decoded = false;
508
509
                    foreach ($fonts as $font) {
510
                        if ($font instanceof self) {
511
                            if (false !== ($decoded = $font->translateChar($char, false))) {
512
                                $decoded = mb_convert_encoding($decoded, 'UTF-8', 'Windows-1252');
513
                                break;
514
                            }
515
                        }
516
                    }
517
518
                    if (false !== $decoded) {
519
                        $char = $decoded;
520
                    } else {
521
                        $char = mb_convert_encoding($char, 'UTF-8', 'Windows-1252');
522
                    }
523
                } else {
524
                    $char = self::MISSING;
525
                }
526
527 22
                $result .= $char;
528
            }
529
530 22
            $text = $result;
531
        }
532
533 22
        return $text;
534
    }
535
536
    /**
537
     * Decode content by any type of Encoding (dictionary's item) instance.
538
     */
539 14
    private function decodeContentByEncoding(string $text): ?string
540
    {
541 14
        $encoding = $this->get('Encoding');
542
543
        // When Encoding referenced by object id (/Encoding 520 0 R) but object itself does not contain `/Type /Encoding` in it's dictionary.
544 14
        if ($encoding instanceof PDFObject) {
545 3
            $encoding = $this->getInitializedEncodingByPdfObject($encoding);
546
        }
547
548
        // When Encoding referenced by object id (/Encoding 520 0 R) but object itself contains `/Type /Encoding` in it's dictionary.
549 14
        if ($encoding instanceof Encoding) {
550 3
            return $this->decodeContentByEncodingEncoding($text, $encoding);
551
        }
552
553
        // When Encoding is just string (/Encoding /WinAnsiEncoding)
554 11
        if ($encoding instanceof Element) { // todo: ElementString class must by used?
555 11
            return $this->decodeContentByEncodingElement($text, $encoding);
556
        }
557
558
        // don't double-encode strings already in UTF-8
559
        if (!mb_check_encoding($text, 'UTF-8')) {
560
            return mb_convert_encoding($text, 'UTF-8', 'Windows-1252');
561
        }
562
563
        return $text;
564
    }
565
566
    /**
567
     * Returns already created or create a new one if not created before Encoding instance by PDFObject instance.
568
     */
569 3
    private function getInitializedEncodingByPdfObject(PDFObject $PDFObject): Encoding
570
    {
571 3
        if (!$this->initializedEncodingByPdfObject) {
572 3
            $this->initializedEncodingByPdfObject = $this->createInitializedEncodingByPdfObject($PDFObject);
573
        }
574
575 3
        return $this->initializedEncodingByPdfObject;
576
    }
577
578
    /**
579
     * Decode content when $encoding (given by $this->get('Encoding')) is instance of Encoding.
580
     */
581 3
    private function decodeContentByEncodingEncoding(string $text, Encoding $encoding): string
582
    {
583 3
        $result = '';
584 3
        $length = \strlen($text);
585
586 3
        for ($i = 0; $i < $length; ++$i) {
587 3
            $dec_av = hexdec(bin2hex($text[$i]));
588 3
            $dec_ap = $encoding->translateChar($dec_av);
589 3
            $result .= self::uchr($dec_ap ?? $dec_av);
590
        }
591
592 3
        return $result;
593
    }
594
595
    /**
596
     * Decode content when $encoding (given by $this->get('Encoding')) is instance of Element.
597
     */
598 11
    private function decodeContentByEncodingElement(string $text, Element $encoding): ?string
599
    {
600 11
        $pdfEncodingName = $encoding->getContent();
601
602
        // mb_convert_encoding does not support MacRoman/macintosh,
603
        // so we use iconv() here
604 11
        $iconvEncodingName = $this->getIconvEncodingNameOrNullByPdfEncodingName($pdfEncodingName);
605
606 11
        return $iconvEncodingName ? iconv($iconvEncodingName, 'UTF-8//TRANSLIT//IGNORE', $text) : null;
607
    }
608
609
    /**
610
     * Convert PDF encoding name to iconv-known encoding name.
611
     */
612 11
    private function getIconvEncodingNameOrNullByPdfEncodingName(string $pdfEncodingName): ?string
613
    {
614
        $pdfToIconvEncodingNameMap = [
615 11
            'StandardEncoding' => 'ISO-8859-1',
616
            'MacRomanEncoding' => 'MACINTOSH',
617
            'WinAnsiEncoding' => 'CP1252',
618
        ];
619
620 11
        return \array_key_exists($pdfEncodingName, $pdfToIconvEncodingNameMap)
621 11
            ? $pdfToIconvEncodingNameMap[$pdfEncodingName]
622 11
            : null;
623
    }
624
625
    /**
626
     * If string seems like "utf-8" encoded string do nothing and just return given string as is.
627
     * Otherwise, interpret string as "Window-1252" encoded string.
628
     *
629
     * @return string|false
630
     */
631 9
    private function decodeContentByAutodetectIfNecessary(string $text)
632
    {
633 9
        if (mb_check_encoding($text, 'UTF-8')) {
634 9
            return $text;
635
        }
636
637 1
        return mb_convert_encoding($text, 'UTF-8', 'Windows-1252');
638
        // todo: Why exactly `Windows-1252` used?
639
    }
640
641
    /**
642
     * Create Encoding instance by PDFObject instance and init it.
643
     */
644 3
    private function createInitializedEncodingByPdfObject(PDFObject $PDFObject): Encoding
645
    {
646 3
        $encoding = $this->createEncodingByPdfObject($PDFObject);
647 3
        $encoding->init();
648
649 3
        return $encoding;
650
    }
651
652
    /**
653
     * Create Encoding instance by PDFObject instance (without init).
654
     */
655 3
    private function createEncodingByPdfObject(PDFObject $PDFObject): Encoding
656
    {
657 3
        $document = $PDFObject->getDocument();
658 3
        $header = $PDFObject->getHeader();
659 3
        $content = $PDFObject->getContent();
660 3
        $config = $PDFObject->getConfig();
661
662 3
        return new Encoding($document, $header, $content, $config);
663
    }
664
}
665