Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
PredefinedCMap
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
2 / 2
16
100.00% covered (success)
100.00%
1 / 1
 getCIDSystemInfo
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
15
 isPredefined
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Phpdftk\Encoding;
6
7/**
8 * Predefined CMap names for CJK font encoding — ISO 32000-2 §9.7.5.
9 *
10 * These CMap names are built into conforming PDF viewers and don't need
11 * to be embedded as CMap streams. They map character codes to CIDs for
12 * the four Adobe CJK character collections.
13 *
14 * Use these with Type0Font as the /Encoding value when working with
15 * CJK fonts that follow the standard Adobe CID collections.
16 */
17final class PredefinedCMap
18{
19    // -----------------------------------------------------------------------
20    // Adobe-Japan1 (Japanese)
21    // -----------------------------------------------------------------------
22    public const JAPAN_EUC = '83pv-RKSJ-H';
23    public const JAPAN_SJIS_H = '90ms-RKSJ-H';
24    public const JAPAN_SJIS_V = '90ms-RKSJ-V';
25    public const JAPAN_UCS2_H = 'UniJIS-UCS2-H';
26    public const JAPAN_UCS2_V = 'UniJIS-UCS2-V';
27    public const JAPAN_UTF16_H = 'UniJIS-UTF16-H';
28    public const JAPAN_UTF16_V = 'UniJIS-UTF16-V';
29
30    // -----------------------------------------------------------------------
31    // Adobe-Korea1 (Korean)
32    // -----------------------------------------------------------------------
33    public const KOREA_UHC_H = 'KSCms-UHC-H';
34    public const KOREA_UHC_V = 'KSCms-UHC-V';
35    public const KOREA_UCS2_H = 'UniKS-UCS2-H';
36    public const KOREA_UCS2_V = 'UniKS-UCS2-V';
37    public const KOREA_UTF16_H = 'UniKS-UTF16-H';
38    public const KOREA_UTF16_V = 'UniKS-UTF16-V';
39
40    // -----------------------------------------------------------------------
41    // Adobe-GB1 (Simplified Chinese)
42    // -----------------------------------------------------------------------
43    public const GB_GBK_H = 'GBK-EUC-H';
44    public const GB_GBK_V = 'GBK-EUC-V';
45    public const GB_UCS2_H = 'UniGB-UCS2-H';
46    public const GB_UCS2_V = 'UniGB-UCS2-V';
47    public const GB_UTF16_H = 'UniGB-UTF16-H';
48    public const GB_UTF16_V = 'UniGB-UTF16-V';
49
50    // -----------------------------------------------------------------------
51    // Adobe-CNS1 (Traditional Chinese)
52    // -----------------------------------------------------------------------
53    public const CNS_BIG5_H = 'ETen-B5-H';
54    public const CNS_BIG5_V = 'ETen-B5-V';
55    public const CNS_UCS2_H = 'UniCNS-UCS2-H';
56    public const CNS_UCS2_V = 'UniCNS-UCS2-V';
57    public const CNS_UTF16_H = 'UniCNS-UTF16-H';
58    public const CNS_UTF16_V = 'UniCNS-UTF16-V';
59
60    // -----------------------------------------------------------------------
61    // Identity mappings (already used, listed for completeness)
62    // -----------------------------------------------------------------------
63    public const IDENTITY_H = 'Identity-H';
64    public const IDENTITY_V = 'Identity-V';
65
66    /**
67     * Get the CIDSystemInfo registry/ordering/supplement for a CMap name.
68     *
69     * @return array{registry: string, ordering: string, supplement: int}|null
70     */
71    public static function getCIDSystemInfo(string $cmapName): ?array
72    {
73        if (str_contains($cmapName, 'Japan') || str_contains($cmapName, 'JIS') || str_contains($cmapName, 'RKSJ') || str_contains($cmapName, 'pv-RKSJ')) {
74            return ['registry' => 'Adobe', 'ordering' => 'Japan1', 'supplement' => 6];
75        }
76        if (str_contains($cmapName, 'Korea') || str_contains($cmapName, 'KS') || str_contains($cmapName, 'UniKS')) {
77            return ['registry' => 'Adobe', 'ordering' => 'Korea1', 'supplement' => 2];
78        }
79        if (str_contains($cmapName, 'GB') || str_contains($cmapName, 'UniGB')) {
80            return ['registry' => 'Adobe', 'ordering' => 'GB1', 'supplement' => 5];
81        }
82        if (str_contains($cmapName, 'CNS') || str_contains($cmapName, 'B5') || str_contains($cmapName, 'UniCNS')) {
83            return ['registry' => 'Adobe', 'ordering' => 'CNS1', 'supplement' => 7];
84        }
85        if ($cmapName === 'Identity-H' || $cmapName === 'Identity-V') {
86            return ['registry' => 'Adobe', 'ordering' => 'Identity', 'supplement' => 0];
87        }
88        return null;
89    }
90
91    /**
92     * Check if a CMap name is a predefined CMap (built into PDF viewers).
93     */
94    public static function isPredefined(string $cmapName): bool
95    {
96        return self::getCIDSystemInfo($cmapName) !== null;
97    }
98}