File Coverage

src/pdfmake_encoding.c
Criterion Covered Total %
statement 50 176 28.4
branch 27 152 17.7
condition n/a
subroutine n/a
pod n/a
total 77 328 23.4


line stmt bran cond sub pod time code
1             /*
2             * pdfmake_encoding.c - PDF character encoding tables
3             *
4             * Standard encoding tables mapping character codes (0-255) to Unicode.
5             * Used for text rendering when fonts use these encodings.
6             *
7             * Reference: PDF 32000-1:2008 Annex D
8             */
9              
10             #include "pdfmake_text.h"
11             #include "pdfmake_font.h"
12             #include
13              
14             /*
15             * 0xFFFF indicates undefined character
16             */
17             #define UNDEF 0xFFFF
18              
19             /*============================================================================
20             * Standard Encoding (Appendix D.1)
21             *==========================================================================*/
22              
23             const uint16_t pdfmake_encoding_standard[256] = {
24             /* 0x00-0x0F */
25             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
26             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
27             /* 0x10-0x1F */
28             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
29             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
30             /* 0x20-0x2F */
31             0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x2019,
32             0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
33             /* 0x30-0x3F */
34             0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
35             0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
36             /* 0x40-0x4F */
37             0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
38             0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
39             /* 0x50-0x5F */
40             0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
41             0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
42             /* 0x60-0x6F */
43             0x2018, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
44             0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
45             /* 0x70-0x7F */
46             0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
47             0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, UNDEF,
48             /* 0x80-0x8F */
49             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
50             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
51             /* 0x90-0x9F */
52             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
53             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
54             /* 0xA0-0xAF */
55             UNDEF, 0x00A1, 0x00A2, 0x00A3, 0x2044, 0x00A5, 0x0192, 0x00A7,
56             0x00A4, 0x0027, 0x201C, 0x00AB, 0x2039, 0x203A, 0xFB01, 0xFB02,
57             /* 0xB0-0xBF */
58             UNDEF, 0x2013, 0x2020, 0x2021, 0x00B7, UNDEF, 0x00B6, 0x2022,
59             0x201A, 0x201E, 0x201D, 0x00BB, 0x2026, 0x2030, UNDEF, 0x00BF,
60             /* 0xC0-0xCF */
61             UNDEF, 0x0060, 0x00B4, 0x02C6, 0x02DC, 0x00AF, 0x02D8, 0x02D9,
62             0x00A8, UNDEF, 0x02DA, 0x00B8, UNDEF, 0x02DD, 0x02DB, 0x02C7,
63             /* 0xD0-0xDF */
64             0x2014, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
65             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
66             /* 0xE0-0xEF */
67             UNDEF, 0x00C6, UNDEF, 0x00AA, UNDEF, UNDEF, UNDEF, UNDEF,
68             0x0141, 0x00D8, 0x0152, 0x00BA, UNDEF, UNDEF, UNDEF, UNDEF,
69             /* 0xF0-0xFF */
70             UNDEF, 0x00E6, UNDEF, UNDEF, UNDEF, 0x0131, UNDEF, UNDEF,
71             0x0142, 0x00F8, 0x0153, 0x00DF, UNDEF, UNDEF, UNDEF, UNDEF,
72             };
73              
74             /*============================================================================
75             * WinAnsi Encoding (Appendix D.2)
76             *==========================================================================*/
77              
78             const uint16_t pdfmake_encoding_winansi[256] = {
79             /* 0x00-0x0F */
80             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
81             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
82             /* 0x10-0x1F */
83             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
84             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
85             /* 0x20-0x2F */
86             0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
87             0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
88             /* 0x30-0x3F */
89             0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
90             0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
91             /* 0x40-0x4F */
92             0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
93             0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
94             /* 0x50-0x5F */
95             0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
96             0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
97             /* 0x60-0x6F */
98             0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
99             0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
100             /* 0x70-0x7F */
101             0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
102             0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x2022,
103             /* 0x80-0x8F */
104             0x20AC, 0x2022, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
105             0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x2022, 0x017D, 0x2022,
106             /* 0x90-0x9F */
107             0x2022, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
108             0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x2022, 0x017E, 0x0178,
109             /* 0xA0-0xAF */
110             0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
111             0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
112             /* 0xB0-0xBF */
113             0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
114             0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
115             /* 0xC0-0xCF */
116             0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
117             0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
118             /* 0xD0-0xDF */
119             0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
120             0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
121             /* 0xE0-0xEF */
122             0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
123             0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
124             /* 0xF0-0xFF */
125             0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
126             0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF,
127             };
128              
129             /*============================================================================
130             * MacRoman Encoding (Appendix D.3)
131             *==========================================================================*/
132              
133             const uint16_t pdfmake_encoding_macroman[256] = {
134             /* 0x00-0x0F */
135             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
136             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
137             /* 0x10-0x1F */
138             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
139             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
140             /* 0x20-0x2F */
141             0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
142             0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
143             /* 0x30-0x3F */
144             0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
145             0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
146             /* 0x40-0x4F */
147             0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
148             0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
149             /* 0x50-0x5F */
150             0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
151             0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
152             /* 0x60-0x6F */
153             0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
154             0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
155             /* 0x70-0x7F */
156             0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
157             0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, UNDEF,
158             /* 0x80-0x8F */
159             0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1,
160             0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8,
161             /* 0x90-0x9F */
162             0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3,
163             0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC,
164             /* 0xA0-0xAF */
165             0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF,
166             0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8,
167             /* 0xB0-0xBF */
168             0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211,
169             0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x03A9, 0x00E6, 0x00F8,
170             /* 0xC0-0xCF */
171             0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB,
172             0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153,
173             /* 0xD0-0xDF */
174             0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA,
175             0x00FF, 0x0178, 0x2044, 0x20AC, 0x2039, 0x203A, 0xFB01, 0xFB02,
176             /* 0xE0-0xEF */
177             0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1,
178             0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4,
179             /* 0xF0-0xFF */
180             0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC,
181             0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7,
182             };
183              
184             /*============================================================================
185             * Symbol Encoding (Appendix D.5)
186             *==========================================================================*/
187              
188             const uint16_t pdfmake_encoding_symbol[256] = {
189             /* 0x00-0x0F */
190             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
191             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
192             /* 0x10-0x1F */
193             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
194             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
195             /* 0x20-0x2F */
196             0x0020, 0x0021, 0x2200, 0x0023, 0x2203, 0x0025, 0x0026, 0x220B,
197             0x0028, 0x0029, 0x2217, 0x002B, 0x002C, 0x2212, 0x002E, 0x002F,
198             /* 0x30-0x3F */
199             0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
200             0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
201             /* 0x40-0x4F */
202             0x2245, 0x0391, 0x0392, 0x03A7, 0x0394, 0x0395, 0x03A6, 0x0393,
203             0x0397, 0x0399, 0x03D1, 0x039A, 0x039B, 0x039C, 0x039D, 0x039F,
204             /* 0x50-0x5F */
205             0x03A0, 0x0398, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03C2, 0x03A9,
206             0x039E, 0x03A8, 0x0396, 0x005B, 0x2234, 0x005D, 0x22A5, 0x005F,
207             /* 0x60-0x6F */
208             0xF8E5, 0x03B1, 0x03B2, 0x03C7, 0x03B4, 0x03B5, 0x03C6, 0x03B3,
209             0x03B7, 0x03B9, 0x03D5, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BF,
210             /* 0x70-0x7F */
211             0x03C0, 0x03B8, 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03D6, 0x03C9,
212             0x03BE, 0x03C8, 0x03B6, 0x007B, 0x007C, 0x007D, 0x223C, UNDEF,
213             /* 0x80-0x8F */
214             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
215             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
216             /* 0x90-0x9F */
217             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
218             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
219             /* 0xA0-0xAF */
220             0x20AC, 0x03D2, 0x2032, 0x2264, 0x2044, 0x221E, 0x0192, 0x2663,
221             0x2666, 0x2665, 0x2660, 0x2194, 0x2190, 0x2191, 0x2192, 0x2193,
222             /* 0xB0-0xBF */
223             0x00B0, 0x00B1, 0x2033, 0x2265, 0x00D7, 0x221D, 0x2202, 0x2022,
224             0x00F7, 0x2260, 0x2261, 0x2248, 0x2026, 0xF8E6, 0xF8E7, 0x21B5,
225             /* 0xC0-0xCF */
226             0x2135, 0x2111, 0x211C, 0x2118, 0x2297, 0x2295, 0x2205, 0x2229,
227             0x222A, 0x2283, 0x2287, 0x2284, 0x2282, 0x2286, 0x2208, 0x2209,
228             /* 0xD0-0xDF */
229             0x2220, 0x2207, 0xF6DA, 0xF6D9, 0xF6DB, 0x220F, 0x221A, 0x22C5,
230             0x00AC, 0x2227, 0x2228, 0x21D4, 0x21D0, 0x21D1, 0x21D2, 0x21D3,
231             /* 0xE0-0xEF */
232             0x25CA, 0x2329, 0xF8E8, 0xF8E9, 0xF8EA, 0x2211, 0xF8EB, 0xF8EC,
233             0xF8ED, 0xF8EE, 0xF8EF, 0xF8F0, 0xF8F1, 0xF8F2, 0xF8F3, 0xF8F4,
234             /* 0xF0-0xFF */
235             UNDEF, 0x232A, 0x222B, 0x2320, 0xF8F5, 0x2321, 0xF8F6, 0xF8F7,
236             0xF8F8, 0xF8F9, 0xF8FA, 0xF8FB, 0xF8FC, 0xF8FD, 0xF8FE, UNDEF,
237             };
238              
239             /*============================================================================
240             * ZapfDingbats Encoding (Appendix D.6)
241             *==========================================================================*/
242              
243             const uint16_t pdfmake_encoding_zapfdingbats[256] = {
244             /* 0x00-0x0F */
245             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
246             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
247             /* 0x10-0x1F */
248             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
249             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
250             /* 0x20-0x2F */
251             0x0020, 0x2701, 0x2702, 0x2703, 0x2704, 0x260E, 0x2706, 0x2707,
252             0x2708, 0x2709, 0x261B, 0x261E, 0x270C, 0x270D, 0x270E, 0x270F,
253             /* 0x30-0x3F */
254             0x2710, 0x2711, 0x2712, 0x2713, 0x2714, 0x2715, 0x2716, 0x2717,
255             0x2718, 0x2719, 0x271A, 0x271B, 0x271C, 0x271D, 0x271E, 0x271F,
256             /* 0x40-0x4F */
257             0x2720, 0x2721, 0x2722, 0x2723, 0x2724, 0x2725, 0x2726, 0x2727,
258             0x2605, 0x2729, 0x272A, 0x272B, 0x272C, 0x272D, 0x272E, 0x272F,
259             /* 0x50-0x5F */
260             0x2730, 0x2731, 0x2732, 0x2733, 0x2734, 0x2735, 0x2736, 0x2737,
261             0x2738, 0x2739, 0x273A, 0x273B, 0x273C, 0x273D, 0x273E, 0x273F,
262             /* 0x60-0x6F */
263             0x2740, 0x2741, 0x2742, 0x2743, 0x2744, 0x2745, 0x2746, 0x2747,
264             0x2748, 0x2749, 0x274A, 0x274B, 0x25CF, 0x274D, 0x25A0, 0x274F,
265             /* 0x70-0x7F */
266             0x2750, 0x2751, 0x2752, 0x25B2, 0x25BC, 0x25C6, 0x2756, 0x25D7,
267             0x2758, 0x2759, 0x275A, 0x275B, 0x275C, 0x275D, 0x275E, UNDEF,
268             /* 0x80-0x8F */
269             0xF8D7, 0xF8D8, 0xF8D9, 0xF8DA, 0xF8DB, 0xF8DC, 0xF8DD, 0xF8DE,
270             0xF8DF, 0xF8E0, 0xF8E1, 0xF8E2, 0xF8E3, 0xF8E4, UNDEF, UNDEF,
271             /* 0x90-0x9F */
272             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
273             UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF,
274             /* 0xA0-0xAF */
275             UNDEF, 0x2761, 0x2762, 0x2763, 0x2764, 0x2765, 0x2766, 0x2767,
276             0x2663, 0x2666, 0x2665, 0x2660, 0x2460, 0x2461, 0x2462, 0x2463,
277             /* 0xB0-0xBF */
278             0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, 0x2776, 0x2777,
279             0x2778, 0x2779, 0x277A, 0x277B, 0x277C, 0x277D, 0x277E, 0x277F,
280             /* 0xC0-0xCF */
281             0x2780, 0x2781, 0x2782, 0x2783, 0x2784, 0x2785, 0x2786, 0x2787,
282             0x2788, 0x2789, 0x278A, 0x278B, 0x278C, 0x278D, 0x278E, 0x278F,
283             /* 0xD0-0xDF */
284             0x2790, 0x2791, 0x2792, 0x2793, 0x2794, 0x2192, 0x2194, 0x2195,
285             0x2798, 0x2799, 0x279A, 0x279B, 0x279C, 0x279D, 0x279E, 0x279F,
286             /* 0xE0-0xEF */
287             0x27A0, 0x27A1, 0x27A2, 0x27A3, 0x27A4, 0x27A5, 0x27A6, 0x27A7,
288             0x27A8, 0x27A9, 0x27AA, 0x27AB, 0x27AC, 0x27AD, 0x27AE, 0x27AF,
289             /* 0xF0-0xFF */
290             UNDEF, 0x27B1, 0x27B2, 0x27B3, 0x27B4, 0x27B5, 0x27B6, 0x27B7,
291             0x27B8, 0x27B9, 0x27BA, 0x27BB, 0x27BC, 0x27BD, 0x27BE, UNDEF,
292             };
293              
294             /*============================================================================
295             * Encoding Lookup
296             *==========================================================================*/
297              
298 0           const uint16_t *pdfmake_encoding_get(const char *name)
299             {
300 0 0         if (!name) return NULL;
301            
302 0 0         if (strcmp(name, "StandardEncoding") == 0 ||
303 0 0         strcmp(name, "Standard") == 0) {
304 0           return pdfmake_encoding_standard;
305             }
306 0 0         if (strcmp(name, "WinAnsiEncoding") == 0 ||
307 0 0         strcmp(name, "WinAnsi") == 0) {
308 0           return pdfmake_encoding_winansi;
309             }
310 0 0         if (strcmp(name, "MacRomanEncoding") == 0 ||
311 0 0         strcmp(name, "MacRoman") == 0) {
312 0           return pdfmake_encoding_macroman;
313             }
314 0 0         if (strcmp(name, "SymbolEncoding") == 0 ||
315 0 0         strcmp(name, "Symbol") == 0) {
316 0           return pdfmake_encoding_symbol;
317             }
318 0 0         if (strcmp(name, "ZapfDingbatsEncoding") == 0 ||
319 0 0         strcmp(name, "ZapfDingbats") == 0) {
320 0           return pdfmake_encoding_zapfdingbats;
321             }
322            
323 0           return NULL;
324             }
325              
326             /*============================================================================
327             * Character to Glyph Mapping
328             *==========================================================================*/
329              
330 0           uint16_t pdfmake_text_char_to_glyph(pdfmake_font_t *font, uint32_t charcode)
331             {
332 0 0         if (!font) return 0;
333            
334             /* TrueType: use cmap lookup */
335 0 0         if (font->type == PDFMAKE_FONT_TRUETYPE ||
336 0 0         font->type == PDFMAKE_FONT_CID_TRUETYPE) {
337 0 0         if (font->ttf) {
338 0           return pdfmake_ttf_cmap_lookup(font->ttf, charcode);
339             }
340 0           return 0;
341             }
342            
343             /* Standard 14: char code is typically the glyph index for WinAnsi */
344 0 0         if (font->type == PDFMAKE_FONT_TYPE1) {
345             /* For Standard 14, char code is glyph ID in WinAnsi encoding */
346 0 0         if (charcode < 256) {
347 0           return (uint16_t)charcode;
348             }
349 0           return 0;
350             }
351            
352 0           return 0;
353             }
354              
355 0           uint16_t pdfmake_text_unicode_to_glyph(pdfmake_font_t *font, uint32_t unicode)
356             {
357             int i;
358              
359 0 0         if (!font) return 0;
360            
361             /* TrueType: use cmap lookup (Unicode cmap) */
362 0 0         if (font->type == PDFMAKE_FONT_TRUETYPE ||
363 0 0         font->type == PDFMAKE_FONT_CID_TRUETYPE) {
364 0 0         if (font->ttf) {
365 0           return pdfmake_ttf_cmap_lookup(font->ttf, unicode);
366             }
367 0           return 0;
368             }
369            
370             /* Standard 14: find Unicode in WinAnsi encoding */
371 0 0         if (font->type == PDFMAKE_FONT_TYPE1) {
372             /* Search WinAnsi for matching Unicode */
373 0 0         for (i = 0; i < 256; i++) {
374 0 0         if (pdfmake_encoding_winansi[i] == unicode) {
375 0           return (uint16_t)i;
376             }
377             }
378             /* Not found - return .notdef */
379 0           return 0;
380             }
381            
382 0           return 0;
383             }
384              
385             /*============================================================================
386             * UTF-8 Decoding Helper
387             *==========================================================================*/
388              
389             /*
390             * Decode one UTF-8 character.
391             * Returns Unicode codepoint and advances *p.
392             * Returns 0xFFFD (replacement char) on error.
393             */
394 0           static uint32_t utf8_decode(const uint8_t **p, const uint8_t *end)
395             {
396             uint8_t c;
397             uint8_t c2;
398             uint8_t c3;
399             uint8_t c4;
400              
401 0 0         if (*p >= end) return 0xFFFD;
402            
403 0           c = *(*p)++;
404            
405 0 0         if (c < 0x80) {
406 0           return c;
407             }
408            
409 0 0         if ((c & 0xE0) == 0xC0) {
410             /* 2-byte sequence */
411 0 0         if (*p >= end) return 0xFFFD;
412 0           c2 = *(*p)++;
413 0 0         if ((c2 & 0xC0) != 0x80) return 0xFFFD;
414 0           return ((c & 0x1F) << 6) | (c2 & 0x3F);
415             }
416            
417 0 0         if ((c & 0xF0) == 0xE0) {
418             /* 3-byte sequence */
419 0 0         if (*p + 1 >= end) return 0xFFFD;
420 0           c2 = *(*p)++;
421 0           c3 = *(*p)++;
422 0 0         if ((c2 & 0xC0) != 0x80 || (c3 & 0xC0) != 0x80) return 0xFFFD;
    0          
423 0           return ((c & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F);
424             }
425            
426 0 0         if ((c & 0xF8) == 0xF0) {
427             /* 4-byte sequence */
428 0 0         if (*p + 2 >= end) return 0xFFFD;
429 0           c2 = *(*p)++;
430 0           c3 = *(*p)++;
431 0           c4 = *(*p)++;
432 0 0         if ((c2 & 0xC0) != 0x80 || (c3 & 0xC0) != 0x80 ||
    0          
433 0 0         (c4 & 0xC0) != 0x80) return 0xFFFD;
434 0           return ((c & 0x07) << 18) | ((c2 & 0x3F) << 12) |
435 0           ((c3 & 0x3F) << 6) | (c4 & 0x3F);
436             }
437            
438 0           return 0xFFFD;
439             }
440              
441             /*============================================================================
442             * Glyph Width Functions
443             *==========================================================================*/
444              
445 0           double pdfmake_text_glyph_advance(
446             pdfmake_font_t *font,
447             uint16_t glyph_id,
448             double font_size)
449             {
450 0           int units_per_em = 1000; /* Default */
451 0           int advance_width = 0;
452              
453 0 0         if (!font) return 0.0;
454            
455 0 0         if (font->type == PDFMAKE_FONT_TRUETYPE ||
456 0 0         font->type == PDFMAKE_FONT_CID_TRUETYPE) {
457 0 0         if (font->ttf) {
458 0           units_per_em = font->ttf->units_per_em;
459 0           advance_width = pdfmake_ttf_glyph_advance(font->ttf, glyph_id);
460             }
461 0 0         } else if (font->type == PDFMAKE_FONT_TYPE1) {
462             /* Standard 14: widths are already in 1/1000 em */
463 0           advance_width = pdfmake_std14_width(font->std14_id, glyph_id);
464 0           units_per_em = 1000;
465             }
466            
467 0           return (advance_width * font_size) / units_per_em;
468             }
469              
470 0           double pdfmake_text_string_width(
471             pdfmake_text_state_t *ts,
472             const uint8_t *text,
473             size_t len)
474             {
475             double width;
476             const uint8_t *p;
477             const uint8_t *end;
478             uint32_t unicode;
479             uint16_t glyph_id;
480             double glyph_width;
481              
482 0 0         if (!ts || !text || !ts->font) return 0.0;
    0          
    0          
483            
484 0           width = 0.0;
485 0           p = text;
486 0           end = text + len;
487            
488 0 0         while (p < end) {
489 0           unicode = utf8_decode(&p, end);
490 0 0         if (unicode == 0xFFFD) continue;
491            
492 0           glyph_id = pdfmake_text_unicode_to_glyph(ts->font, unicode);
493 0           glyph_width = pdfmake_text_glyph_advance(ts->font, glyph_id,
494             ts->font_size);
495            
496 0           width += glyph_width;
497 0           width += ts->char_spacing;
498            
499             /* Word spacing for ASCII space */
500 0 0         if (unicode == 0x0020) {
501 0           width += ts->word_spacing;
502             }
503             }
504            
505             /* Apply horizontal scaling */
506 0           width *= ts->horiz_scale;
507            
508 0           return width;
509             }
510              
511             /*============================================================================
512             * Font encoding API (Phase 2)
513             *
514             * Resolves a font's /Encoding to a byte->Unicode map, applying /Differences
515             * overlays via the Adobe Glyph List.
516             *==========================================================================*/
517              
518             #include "pdfmake_font_encoding.h"
519             #include "pdfmake_glyphlist.h"
520              
521             /* Fill a 256-entry map from a base table (0xFFFF = undefined in the
522             * existing tables; translate to 0 for the new API). */
523 149           static void fill_from_table(pdfmake_font_encoding_t *enc,
524             const uint16_t *src)
525             {
526             int i;
527             uint16_t v;
528 38293 100         for (i = 0; i < 256; i++) {
529 38144           v = src[i];
530 38144 100         enc->map[i] = (v == 0xFFFF) ? 0 : v;
531             }
532 149           }
533              
534 128           void pdfmake_font_encoding_init_standard(pdfmake_font_encoding_t *enc) {
535 128           fill_from_table(enc, pdfmake_encoding_standard);
536 128           }
537 21           void pdfmake_font_encoding_init_winansi(pdfmake_font_encoding_t *enc) {
538 21           fill_from_table(enc, pdfmake_encoding_winansi);
539 21           }
540 0           void pdfmake_font_encoding_init_macroman(pdfmake_font_encoding_t *enc) {
541 0           fill_from_table(enc, pdfmake_encoding_macroman);
542 0           }
543 0           void pdfmake_font_encoding_init_macexpert(pdfmake_font_encoding_t *enc) {
544             /* MacExpertEncoding has no full table here — approximate with Standard.
545             * This is rare in modern PDFs. */
546 0           fill_from_table(enc, pdfmake_encoding_standard);
547 0           }
548 0           void pdfmake_font_encoding_init_symbol(pdfmake_font_encoding_t *enc) {
549 0           fill_from_table(enc, pdfmake_encoding_symbol);
550 0           }
551 0           void pdfmake_font_encoding_init_zapfdingbats(pdfmake_font_encoding_t *enc) {
552 0           fill_from_table(enc, pdfmake_encoding_zapfdingbats);
553 0           }
554              
555 21           int pdfmake_font_encoding_init_by_name(pdfmake_font_encoding_t *enc,
556             const char *name)
557             {
558 21 50         if (!enc) return 0;
559 21 50         if (!name) {
560 0           pdfmake_font_encoding_init_winansi(enc);
561 0           return 0;
562             }
563 21 50         if (strcmp(name, "StandardEncoding") == 0) {
564 0           pdfmake_font_encoding_init_standard(enc); return 1;
565             }
566 21 50         if (strcmp(name, "WinAnsiEncoding") == 0) {
567 21           pdfmake_font_encoding_init_winansi(enc); return 1;
568             }
569 0 0         if (strcmp(name, "MacRomanEncoding") == 0) {
570 0           pdfmake_font_encoding_init_macroman(enc); return 1;
571             }
572 0 0         if (strcmp(name, "MacExpertEncoding") == 0) {
573 0           pdfmake_font_encoding_init_macexpert(enc); return 1;
574             }
575 0 0         if (strcmp(name, "SymbolEncoding") == 0) {
576 0           pdfmake_font_encoding_init_symbol(enc); return 1;
577             }
578 0 0         if (strcmp(name, "ZapfDingbatsEncoding") == 0) {
579 0           pdfmake_font_encoding_init_zapfdingbats(enc); return 1;
580             }
581             /* Unknown: fall back to WinAnsi */
582 0           pdfmake_font_encoding_init_winansi(enc);
583 0           return 0;
584             }
585              
586             /* Apply a /Differences array to an existing base-filled encoding.
587             *
588             * [ 32 /space /exclam /quotedbl 65 /A /B /C ]
589             *
590             * Each integer sets the "next code"; each name that follows assigns that
591             * name to the current code and advances.
592             */
593 14           static void apply_differences(pdfmake_arena_t *arena,
594             pdfmake_obj_t *diff_arr,
595             pdfmake_font_encoding_t *enc)
596             {
597             size_t n;
598             int code;
599             size_t i;
600             pdfmake_obj_t *item;
601             const char *glyph;
602             uint32_t cp;
603              
604 14 50         if (!diff_arr || diff_arr->kind != PDFMAKE_ARRAY) return;
    50          
605              
606 14           n = pdfmake_array_len(diff_arr);
607 14           code = 0;
608 56 100         for (i = 0; i < n; i++) {
609 42           item = pdfmake_array_get(diff_arr, i);
610 42 50         if (!item) continue;
611              
612 42 100         if (item->kind == PDFMAKE_INT) {
613 14           code = (int)item->as.i;
614 14           continue;
615             }
616 28 50         if (item->kind != PDFMAKE_NAME) continue;
617              
618 28           glyph = pdfmake_get_name_bytes(arena, item);
619 28 50         if (!glyph) { code++; continue; }
620              
621 28 50         if (code >= 0 && code < 256) {
    50          
622 28           cp = pdfmake_glyphname_to_unicode(glyph);
623             /* If glyph name unknown, leave whatever was there from the base */
624 28 50         if (cp) enc->map[code] = cp;
625             }
626 28           code++;
627             }
628             }
629              
630 35           int pdfmake_font_encoding_from_dict(
631             pdfmake_arena_t *arena,
632             pdfmake_obj_t *encoding_obj,
633             pdfmake_font_encoding_t *out)
634             {
635             const char *name;
636             uint32_t be_key;
637             pdfmake_obj_t *be;
638             uint32_t diff_key;
639             pdfmake_obj_t *diff;
640              
641 35 50         if (!out) return -1;
642              
643             /* Default to StandardEncoding per spec (Type1 default) */
644 35           pdfmake_font_encoding_init_standard(out);
645              
646 35 50         if (!encoding_obj) return 0;
647              
648 35 100         if (encoding_obj->kind == PDFMAKE_NAME) {
649 21           name = pdfmake_get_name_bytes(arena, encoding_obj);
650 21           pdfmake_font_encoding_init_by_name(out, name);
651 21           return 0;
652             }
653              
654 14 50         if (encoding_obj->kind == PDFMAKE_DICT) {
655             /* /BaseEncoding */
656 14           be_key = pdfmake_arena_intern_name(arena, "BaseEncoding", 12);
657 14           be = pdfmake_dict_get(encoding_obj, be_key);
658 14 50         if (be && be->kind == PDFMAKE_NAME) {
    0          
659 0           name = pdfmake_get_name_bytes(arena, be);
660 0           pdfmake_font_encoding_init_by_name(out, name);
661             }
662             /* /Differences */
663 14           diff_key = pdfmake_arena_intern_name(arena, "Differences", 11);
664 14           diff = pdfmake_dict_get(encoding_obj, diff_key);
665 14 50         if (diff) apply_differences(arena, diff, out);
666 14           return 0;
667             }
668              
669             /* Unknown shape: leave StandardEncoding */
670 0           return -1;
671             }