Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
41 / 41
100.00% covered (success)
100.00%
1 / 1
CRAP
100.00% covered (success)
100.00%
1 / 1
Os2
100.00% covered (success)
100.00%
41 / 41
100.00% covered (success)
100.00%
1 / 1
12
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
41 / 41
100.00% covered (success)
100.00%
1 / 1
12
1<?php
2declare(strict_types=1);
3/**
4 * Pop PHP Framework (https://www.popphp.org/)
5 *
6 * @link       https://github.com/popphp/popphp-framework
7 * @author     Nick Sagona, III <nick@popphp.org>
8 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
9 * @license    https://www.popphp.org/license     New BSD License
10 */
11
12/**
13 * @namespace
14 */
15namespace Pop\Pdf\Build\Font\TrueType\Table;
16
17use Pop\Pdf\Build\Font;
18use Pop\Utils\ArrayObject as Data;
19use Pop\Utils\Exception;
20
21/**
22 * OS/2 table class
23 *
24 * @category   Pop
25 * @package    Pop\Pdf
26 * @author     Nick Sagona, III <nick@popphp.org>
27 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
28 * @license    https://www.popphp.org/license     New BSD License
29 * @version    6.0.0
30 */
31class Os2 extends AbstractTable
32{
33
34    /**
35     * Font table properties
36     * @var array
37     */
38    protected array $properties = [
39        'capHeight'  => 0,
40        'embeddable' => true,
41        'flags'      => null
42    ];
43
44    /**
45     * Constructor
46     *
47     * Instantiate a OTF 'OS/2' table object.
48     *
49     * @param Font\TrueType $font
50     * @throws Exception
51     */
52    public function __construct(Font\TrueType $font)
53    {
54        $this->properties['flags'] = new Data([
55            'isFixedPitch'  => false,
56            'isSerif'       => false,
57            'isSymbolic'    => false,
58            'isScript'      => false,
59            'isNonSymbolic' => false,
60            'isItalic'      => false,
61            'isAllCap'      => false,
62            'isSmallCap'    => false,
63            'isForceBold'   => false
64        ]);
65
66        $bytePos = $font->tableInfo['OS/2']->offset + 8;
67        $ary     = unpack("nfsType", $font->read($bytePos, 2));
68        $this->properties['embeddable'] = (($ary['fsType'] != 2) && (($ary['fsType'] & 0x200) == 0));
69
70        $bytePos = $font->tableInfo['OS/2']->offset + 30;
71        $ary     = unpack("nfamily_class", $font->read($bytePos, 2));
72        $familyClass = ($font->shiftToSigned($ary['family_class']) >> 8);
73
74        if ((($familyClass >= 1) && ($familyClass <= 5)) || ($familyClass == 7)) {
75            $this->properties['flags']['isSerif'] = true;
76        } else if ($familyClass == 8) {
77            $this->properties['flags']['isSerif'] = false;
78        }
79        if ($familyClass == 10) {
80            $this->properties['flags']['isScript'] = true;
81        }
82        if ($familyClass == 12) {
83            $this->properties['flags']['isSymbolic']    = true;
84            $this->properties['flags']['isNonSymbolic'] = false;
85        } else {
86            $this->properties['flags']['isSymbolic']    = false;
87            $this->properties['flags']['isNonSymbolic'] = true;
88        }
89
90        // Unicode bit-sniffing may not be necessary.
91        $bytePos += 3;
92        $ary = unpack(
93            'NunicodeRange1/' .
94            'NunicodeRange2/' .
95            'NunicodeRange3/' .
96            'NunicodeRange4', $font->read($bytePos, 16)
97        );
98
99        if (($ary['unicodeRange1'] == 1) && ($ary['unicodeRange2'] == 0) && ($ary['unicodeRange3'] == 0) && ($ary['unicodeRange4'] == 0)) {
100            $this->properties['flags']['isSymbolic']    = false;
101            $this->properties['flags']['isNonSymbolic'] = true;
102        }
103
104        $bytePos = $font->tableInfo['OS/2']->offset + 76;
105        $ary = unpack("ncap/", $font->read($bytePos, 2));
106        $this->properties['flags']['capHeight'] = $font->toEmSpace($font->shiftToSigned($ary['cap']));
107    }
108
109}