Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.74% covered (success)
95.74%
45 / 47
50.00% covered (warning)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
Cmap
95.74% covered (success)
95.74%
45 / 47
50.00% covered (warning)
50.00%
1 / 2
15
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 parseSubTables
95.00% covered (success)
95.00%
38 / 40
0.00% covered (danger)
0.00%
0 / 1
14
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Pdf\Build\Font\TrueType\Table;
15
16use Pop\Pdf\Build\Font;
17
18use Pop\Utils\ArrayObject as Data;
19
20/**
21 * CMAP table class
22 *
23 * @category   Pop
24 * @package    Pop\Pdf
25 * @author     Nick Sagona, III <dev@nolainteractive.com>
26 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
27 * @license    http://www.popphp.org/license     New BSD License
28 * @version    5.0.0
29 */
30class Cmap extends AbstractTable
31{
32
33    /**
34     * Font table properties
35     * @var array
36     */
37    protected array $properties = [
38        'header'    => null,
39        'subTables' => []
40    ];
41
42    /**
43     * Constructor
44     *
45     * Instantiate a TTF 'cmap' table object.
46     *
47     * @param  Font\TrueType $font
48     */
49    public function __construct(Font\TrueType $font)
50    {
51        $bytePos = $font->tableInfo['cmap']->offset;
52
53        // Get the CMAP header data.
54        $cmapTableHeader = unpack(
55            'ntableVersion/' .
56            'nnumberOfTables', $font->read($bytePos, 4)
57        );
58
59        $this->properties['header'] = new Data($cmapTableHeader);
60        $this->parseSubTables($font);
61    }
62
63    /**
64     * Method to parse the CMAP sub-tables.
65     *
66     * @param  \Pop\Pdf\Build\Font\TrueType $font
67     * @return void
68     */
69    protected function parseSubTables(\Pop\Pdf\Build\Font\TrueType $font): void
70    {
71        $bytePos = $font->tableInfo['cmap']->offset + 4;
72
73        // Get each of the sub-table's data.
74        for ($i = 0; $i < $this->properties['header']->numberOfTables; $i++) {
75            $ary = unpack(
76                'nplatformId/' .
77                'nencodingId/' .
78                'Noffset', $font->read($bytePos, 8)
79            );
80            if (($ary['platformId'] == 0) && ($ary['encodingId'] == 0)) {
81                $ary['encoding'] = 'Unicode 2.0';
82            } else if (($ary['platformId'] == 0) && ($ary['encodingId'] == 3)) {
83                $ary['encoding'] = 'Unicode';
84            } else if (($ary['platformId'] == 3) && ($ary['encodingId'] == 1)) {
85                $ary['encoding'] = 'Microsoft Unicode';
86            } else if (($ary['platformId'] == 1) && ($ary['encodingId'] == 0)) {
87                $ary['encoding'] = 'Mac Roman';
88            } else {
89                $ary['encoding'] = 'Unknown';
90            }
91            $this->properties['subTables'][] = new Data($ary);
92            $bytePos += 8;
93        }
94
95        // Parse each of the sub-table's data.
96        foreach ($this->properties['subTables'] as $key => $subTable) {
97            $bytePos = $font->tableInfo['cmap']->offset + $subTable->offset;
98            $ary = unpack(
99                'nformat/' .
100                'nlength/' .
101                'nlanguage', $font->read($bytePos, 6)
102            );
103            $this->properties['subTables'][$key]->format = $ary['format'];
104            $this->properties['subTables'][$key]->length = $ary['length'];
105            $this->properties['subTables'][$key]->language = $ary['language'];
106            $bytePos += 6;
107            $this->properties['subTables'][$key]->data = $font->read($bytePos, $ary['length'] - 6);
108            switch ($this->properties['subTables'][$key]->format) {
109                case 0:
110                    $this->properties['subTables'][$key]->parsed = Cmap\ByteEncoding::parseData($this->properties['subTables'][$key]->data);
111                    break;
112                case 4:
113                    $this->properties['subTables'][$key]->parsed = Cmap\SegmentToDelta::parseData($this->properties['subTables'][$key]->data);
114                    break;
115                case 6:
116                    $this->properties['subTables'][$key]->parsed = Cmap\TrimmedTable::parseData($this->properties['subTables'][$key]->data);
117                    break;
118            }
119        }
120    }
121
122}