OLD | NEW |
---|---|
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2016 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "core/fpdfapi/fpdf_font/font_int.h" | 7 #include "core/fpdfapi/fpdf_font/cpdf_cidfont.h" |
8 | 8 |
9 #include "core/fpdfapi/fpdf_cmaps/cmap_int.h" | 9 #include "core/fpdfapi/fpdf_cmaps/cmap_int.h" |
10 #include "core/fpdfapi/fpdf_font/font_int.h" | |
11 #include "core/fpdfapi/fpdf_font/font_int.h" | |
Tom Sepez
2016/03/22 16:55:52
duplicated.
dsinclair
2016/03/23 00:00:25
Done.
| |
12 #include "core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h" | |
10 #include "core/fpdfapi/fpdf_font/ttgsubtable.h" | 13 #include "core/fpdfapi/fpdf_font/ttgsubtable.h" |
11 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" | 14 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
12 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" | 15 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" |
13 #include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h" | 16 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" |
14 #include "core/fpdfapi/include/cpdf_modulemgr.h" | 17 #include "core/fpdfapi/include/cpdf_modulemgr.h" |
15 #include "core/include/fpdfapi/fpdf_resource.h" | |
16 #include "core/include/fxcrt/fx_ext.h" | |
17 #include "core/include/fxge/fx_freetype.h" | |
18 #include "core/include/fxge/fx_ge.h" | |
19 | 18 |
20 namespace { | 19 namespace { |
21 | 20 |
22 const FX_CHAR* const g_CharsetNames[CIDSET_NUM_SETS] = { | |
23 nullptr, "GB1", "CNS1", "Japan1", "Korea1", "UCS"}; | |
24 | |
25 const uint16_t g_CharsetCPs[CIDSET_NUM_SETS] = {0, 936, 950, 932, 949, 1200}; | 21 const uint16_t g_CharsetCPs[CIDSET_NUM_SETS] = {0, 936, 950, 932, 949, 1200}; |
26 | 22 |
27 class CPDF_PredefinedCMap { | |
28 public: | |
29 const FX_CHAR* m_pName; | |
30 CIDSet m_Charset; | |
31 CIDCoding m_Coding; | |
32 CPDF_CMap::CodingScheme m_CodingScheme; | |
33 uint8_t m_LeadingSegCount; | |
34 uint8_t m_LeadingSegs[4]; | |
35 }; | |
36 | |
37 const CPDF_PredefinedCMap g_PredefinedCMaps[] = { | |
38 {"GB-EUC", | |
39 CIDSET_GB1, | |
40 CIDCODING_GB, | |
41 CPDF_CMap::MixedTwoBytes, | |
42 1, | |
43 {0xa1, 0xfe}}, | |
44 {"GBpc-EUC", | |
45 CIDSET_GB1, | |
46 CIDCODING_GB, | |
47 CPDF_CMap::MixedTwoBytes, | |
48 1, | |
49 {0xa1, 0xfc}}, | |
50 {"GBK-EUC", | |
51 CIDSET_GB1, | |
52 CIDCODING_GB, | |
53 CPDF_CMap::MixedTwoBytes, | |
54 1, | |
55 {0x81, 0xfe}}, | |
56 {"GBKp-EUC", | |
57 CIDSET_GB1, | |
58 CIDCODING_GB, | |
59 CPDF_CMap::MixedTwoBytes, | |
60 1, | |
61 {0x81, 0xfe}}, | |
62 {"GBK2K-EUC", | |
63 CIDSET_GB1, | |
64 CIDCODING_GB, | |
65 CPDF_CMap::MixedTwoBytes, | |
66 1, | |
67 {0x81, 0xfe}}, | |
68 {"GBK2K", | |
69 CIDSET_GB1, | |
70 CIDCODING_GB, | |
71 CPDF_CMap::MixedTwoBytes, | |
72 1, | |
73 {0x81, 0xfe}}, | |
74 {"UniGB-UCS2", CIDSET_GB1, CIDCODING_UCS2, CPDF_CMap::TwoBytes, 0, {}}, | |
75 {"UniGB-UTF16", CIDSET_GB1, CIDCODING_UTF16, CPDF_CMap::TwoBytes, 0, {}}, | |
76 {"B5pc", | |
77 CIDSET_CNS1, | |
78 CIDCODING_BIG5, | |
79 CPDF_CMap::MixedTwoBytes, | |
80 1, | |
81 {0xa1, 0xfc}}, | |
82 {"HKscs-B5", | |
83 CIDSET_CNS1, | |
84 CIDCODING_BIG5, | |
85 CPDF_CMap::MixedTwoBytes, | |
86 1, | |
87 {0x88, 0xfe}}, | |
88 {"ETen-B5", | |
89 CIDSET_CNS1, | |
90 CIDCODING_BIG5, | |
91 CPDF_CMap::MixedTwoBytes, | |
92 1, | |
93 {0xa1, 0xfe}}, | |
94 {"ETenms-B5", | |
95 CIDSET_CNS1, | |
96 CIDCODING_BIG5, | |
97 CPDF_CMap::MixedTwoBytes, | |
98 1, | |
99 {0xa1, 0xfe}}, | |
100 {"UniCNS-UCS2", CIDSET_CNS1, CIDCODING_UCS2, CPDF_CMap::TwoBytes, 0, {}}, | |
101 {"UniCNS-UTF16", CIDSET_CNS1, CIDCODING_UTF16, CPDF_CMap::TwoBytes, 0, {}}, | |
102 {"83pv-RKSJ", | |
103 CIDSET_JAPAN1, | |
104 CIDCODING_JIS, | |
105 CPDF_CMap::MixedTwoBytes, | |
106 2, | |
107 {0x81, 0x9f, 0xe0, 0xfc}}, | |
108 {"90ms-RKSJ", | |
109 CIDSET_JAPAN1, | |
110 CIDCODING_JIS, | |
111 CPDF_CMap::MixedTwoBytes, | |
112 2, | |
113 {0x81, 0x9f, 0xe0, 0xfc}}, | |
114 {"90msp-RKSJ", | |
115 CIDSET_JAPAN1, | |
116 CIDCODING_JIS, | |
117 CPDF_CMap::MixedTwoBytes, | |
118 2, | |
119 {0x81, 0x9f, 0xe0, 0xfc}}, | |
120 {"90pv-RKSJ", | |
121 CIDSET_JAPAN1, | |
122 CIDCODING_JIS, | |
123 CPDF_CMap::MixedTwoBytes, | |
124 2, | |
125 {0x81, 0x9f, 0xe0, 0xfc}}, | |
126 {"Add-RKSJ", | |
127 CIDSET_JAPAN1, | |
128 CIDCODING_JIS, | |
129 CPDF_CMap::MixedTwoBytes, | |
130 2, | |
131 {0x81, 0x9f, 0xe0, 0xfc}}, | |
132 {"EUC", | |
133 CIDSET_JAPAN1, | |
134 CIDCODING_JIS, | |
135 CPDF_CMap::MixedTwoBytes, | |
136 2, | |
137 {0x8e, 0x8e, 0xa1, 0xfe}}, | |
138 {"H", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::TwoBytes, 1, {0x21, 0x7e}}, | |
139 {"V", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::TwoBytes, 1, {0x21, 0x7e}}, | |
140 {"Ext-RKSJ", | |
141 CIDSET_JAPAN1, | |
142 CIDCODING_JIS, | |
143 CPDF_CMap::MixedTwoBytes, | |
144 2, | |
145 {0x81, 0x9f, 0xe0, 0xfc}}, | |
146 {"UniJIS-UCS2", CIDSET_JAPAN1, CIDCODING_UCS2, CPDF_CMap::TwoBytes, 0, {}}, | |
147 {"UniJIS-UCS2-HW", | |
148 CIDSET_JAPAN1, | |
149 CIDCODING_UCS2, | |
150 CPDF_CMap::TwoBytes, | |
151 0, | |
152 {}}, | |
153 {"UniJIS-UTF16", | |
154 CIDSET_JAPAN1, | |
155 CIDCODING_UTF16, | |
156 CPDF_CMap::TwoBytes, | |
157 0, | |
158 {}}, | |
159 {"KSC-EUC", | |
160 CIDSET_KOREA1, | |
161 CIDCODING_KOREA, | |
162 CPDF_CMap::MixedTwoBytes, | |
163 1, | |
164 {0xa1, 0xfe}}, | |
165 {"KSCms-UHC", | |
166 CIDSET_KOREA1, | |
167 CIDCODING_KOREA, | |
168 CPDF_CMap::MixedTwoBytes, | |
169 1, | |
170 {0x81, 0xfe}}, | |
171 {"KSCms-UHC-HW", | |
172 CIDSET_KOREA1, | |
173 CIDCODING_KOREA, | |
174 CPDF_CMap::MixedTwoBytes, | |
175 1, | |
176 {0x81, 0xfe}}, | |
177 {"KSCpc-EUC", | |
178 CIDSET_KOREA1, | |
179 CIDCODING_KOREA, | |
180 CPDF_CMap::MixedTwoBytes, | |
181 1, | |
182 {0xa1, 0xfd}}, | |
183 {"UniKS-UCS2", CIDSET_KOREA1, CIDCODING_UCS2, CPDF_CMap::TwoBytes, 0, {}}, | |
184 {"UniKS-UTF16", CIDSET_KOREA1, CIDCODING_UTF16, CPDF_CMap::TwoBytes, 0, {}}, | |
185 }; | |
186 | |
187 CIDSet CIDSetFromSizeT(size_t index) { | |
188 if (index >= CIDSET_NUM_SETS) { | |
189 NOTREACHED(); | |
190 return CIDSET_UNKNOWN; | |
191 } | |
192 return static_cast<CIDSet>(index); | |
193 } | |
194 | |
195 CIDSet CharsetFromOrdering(const CFX_ByteString& ordering) { | |
196 for (size_t charset = 1; charset < FX_ArraySize(g_CharsetNames); ++charset) { | |
197 if (ordering == CFX_ByteStringC(g_CharsetNames[charset])) | |
198 return CIDSetFromSizeT(charset); | |
199 } | |
200 return CIDSET_UNKNOWN; | |
201 } | |
202 | |
203 CFX_ByteString CMap_GetString(const CFX_ByteStringC& word) { | |
204 return word.Mid(1, word.GetLength() - 2); | |
205 } | |
206 | |
207 int CompareDWORD(const void* data1, const void* data2) { | |
208 return (*(FX_DWORD*)data1) - (*(FX_DWORD*)data2); | |
209 } | |
210 | |
211 int CompareCID(const void* key, const void* element) { | |
212 if ((*(FX_DWORD*)key) < (*(FX_DWORD*)element)) { | |
213 return -1; | |
214 } | |
215 if ((*(FX_DWORD*)key) > | |
216 (*(FX_DWORD*)element) + ((FX_DWORD*)element)[1] / 65536) { | |
217 return 1; | |
218 } | |
219 return 0; | |
220 } | |
221 | |
222 int CheckCodeRange(uint8_t* codes, | |
223 int size, | |
224 CMap_CodeRange* pRanges, | |
225 int nRanges) { | |
226 int iSeg = nRanges - 1; | |
227 while (iSeg >= 0) { | |
228 if (pRanges[iSeg].m_CharSize < size) { | |
229 --iSeg; | |
230 continue; | |
231 } | |
232 int iChar = 0; | |
233 while (iChar < size) { | |
234 if (codes[iChar] < pRanges[iSeg].m_Lower[iChar] || | |
235 codes[iChar] > pRanges[iSeg].m_Upper[iChar]) { | |
236 break; | |
237 } | |
238 ++iChar; | |
239 } | |
240 if (iChar == pRanges[iSeg].m_CharSize) | |
241 return 2; | |
242 | |
243 if (iChar) | |
244 return (size == pRanges[iSeg].m_CharSize) ? 2 : 1; | |
245 iSeg--; | |
246 } | |
247 return 0; | |
248 } | |
249 | |
250 int GetCharSizeImpl(FX_DWORD charcode, | |
251 CMap_CodeRange* pRanges, | |
252 int iRangesSize) { | |
253 if (!iRangesSize) | |
254 return 1; | |
255 | |
256 uint8_t codes[4]; | |
257 codes[0] = codes[1] = 0x00; | |
258 codes[2] = (uint8_t)(charcode >> 8 & 0xFF); | |
259 codes[3] = (uint8_t)charcode; | |
260 int offset = 0; | |
261 int size = 4; | |
262 for (int i = 0; i < 4; ++i) { | |
263 int iSeg = iRangesSize - 1; | |
264 while (iSeg >= 0) { | |
265 if (pRanges[iSeg].m_CharSize < size) { | |
266 --iSeg; | |
267 continue; | |
268 } | |
269 int iChar = 0; | |
270 while (iChar < size) { | |
271 if (codes[offset + iChar] < pRanges[iSeg].m_Lower[iChar] || | |
272 codes[offset + iChar] > pRanges[iSeg].m_Upper[iChar]) { | |
273 break; | |
274 } | |
275 ++iChar; | |
276 } | |
277 if (iChar == pRanges[iSeg].m_CharSize) | |
278 return size; | |
279 --iSeg; | |
280 } | |
281 --size; | |
282 ++offset; | |
283 } | |
284 return 1; | |
285 } | |
286 | |
287 bool IsValidEmbeddedCharcodeFromUnicodeCharset(CIDSet charset) { | |
288 switch (charset) { | |
289 case CIDSET_GB1: | |
290 case CIDSET_CNS1: | |
291 case CIDSET_JAPAN1: | |
292 case CIDSET_KOREA1: | |
293 return true; | |
294 | |
295 default: | |
296 return false; | |
297 } | |
298 } | |
299 | |
300 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ | |
301 FX_DWORD EmbeddedCharcodeFromUnicode(const FXCMAP_CMap* pEmbedMap, | |
302 CIDSet charset, | |
303 FX_WCHAR unicode) { | |
304 if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset)) | |
305 return 0; | |
306 | |
307 CPDF_FontGlobals* pFontGlobals = | |
308 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); | |
309 const uint16_t* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap; | |
310 if (!pCodes) | |
311 return 0; | |
312 | |
313 int nCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count; | |
314 for (int i = 0; i < nCodes; ++i) { | |
315 if (pCodes[i] == unicode) { | |
316 FX_DWORD CharCode = FPDFAPI_CharCodeFromCID(pEmbedMap, i); | |
317 if (CharCode != 0) { | |
318 return CharCode; | |
319 } | |
320 } | |
321 } | |
322 return 0; | |
323 } | |
324 #endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ | |
325 | |
326 FX_WCHAR EmbeddedUnicodeFromCharcode(const FXCMAP_CMap* pEmbedMap, | |
327 CIDSet charset, | |
328 FX_DWORD charcode) { | |
329 if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset)) | |
330 return 0; | |
331 | |
332 uint16_t cid = FPDFAPI_CIDFromCharCode(pEmbedMap, charcode); | |
333 if (cid == 0) | |
334 return 0; | |
335 | |
336 CPDF_FontGlobals* pFontGlobals = | |
337 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); | |
338 const uint16_t* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap; | |
339 if (!pCodes) | |
340 return 0; | |
341 | |
342 if (cid < pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count) | |
343 return pCodes[cid]; | |
344 return 0; | |
345 } | |
346 | |
347 void FT_UseCIDCharmap(FXFT_Face face, int coding) { | |
348 int encoding; | |
349 switch (coding) { | |
350 case CIDCODING_GB: | |
351 encoding = FXFT_ENCODING_GB2312; | |
352 break; | |
353 case CIDCODING_BIG5: | |
354 encoding = FXFT_ENCODING_BIG5; | |
355 break; | |
356 case CIDCODING_JIS: | |
357 encoding = FXFT_ENCODING_SJIS; | |
358 break; | |
359 case CIDCODING_KOREA: | |
360 encoding = FXFT_ENCODING_JOHAB; | |
361 break; | |
362 default: | |
363 encoding = FXFT_ENCODING_UNICODE; | |
364 } | |
365 int err = FXFT_Select_Charmap(face, encoding); | |
366 if (err) { | |
367 err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE); | |
368 } | |
369 if (err && FXFT_Get_Face_Charmaps(face)) { | |
370 FXFT_Set_Charmap(face, *FXFT_Get_Face_Charmaps(face)); | |
371 } | |
372 } | |
373 | |
374 const struct CIDTransform { | 23 const struct CIDTransform { |
375 uint16_t CID; | 24 uint16_t CID; |
376 uint8_t a, b, c, d, e, f; | 25 uint8_t a, b, c, d, e, f; |
Tom Sepez
2016/03/22 16:55:53
nit: one per line while were at it if you like.
dsinclair
2016/03/23 00:00:25
Done.
| |
377 } g_Japan1_VertCIDs[] = { | 26 } g_Japan1_VertCIDs[] = { |
378 {97, 129, 0, 0, 127, 55, 0}, {7887, 127, 0, 0, 127, 76, 89}, | 27 {97, 129, 0, 0, 127, 55, 0}, {7887, 127, 0, 0, 127, 76, 89}, |
379 {7888, 127, 0, 0, 127, 79, 94}, {7889, 0, 129, 127, 0, 17, 127}, | 28 {7888, 127, 0, 0, 127, 79, 94}, {7889, 0, 129, 127, 0, 17, 127}, |
380 {7890, 0, 129, 127, 0, 17, 127}, {7891, 0, 129, 127, 0, 17, 127}, | 29 {7890, 0, 129, 127, 0, 17, 127}, {7891, 0, 129, 127, 0, 17, 127}, |
381 {7892, 0, 129, 127, 0, 17, 127}, {7893, 0, 129, 127, 0, 17, 127}, | 30 {7892, 0, 129, 127, 0, 17, 127}, {7893, 0, 129, 127, 0, 17, 127}, |
382 {7894, 0, 129, 127, 0, 17, 127}, {7895, 0, 129, 127, 0, 17, 127}, | 31 {7894, 0, 129, 127, 0, 17, 127}, {7895, 0, 129, 127, 0, 17, 127}, |
383 {7896, 0, 129, 127, 0, 17, 127}, {7897, 0, 129, 127, 0, 17, 127}, | 32 {7896, 0, 129, 127, 0, 17, 127}, {7897, 0, 129, 127, 0, 17, 127}, |
384 {7898, 0, 129, 127, 0, 17, 127}, {7899, 0, 129, 127, 0, 17, 104}, | 33 {7898, 0, 129, 127, 0, 17, 127}, {7899, 0, 129, 127, 0, 17, 104}, |
385 {7900, 0, 129, 127, 0, 17, 127}, {7901, 0, 129, 127, 0, 17, 104}, | 34 {7900, 0, 129, 127, 0, 17, 127}, {7901, 0, 129, 127, 0, 17, 104}, |
386 {7902, 0, 129, 127, 0, 17, 127}, {7903, 0, 129, 127, 0, 17, 127}, | 35 {7902, 0, 129, 127, 0, 17, 127}, {7903, 0, 129, 127, 0, 17, 127}, |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
447 {8804, 0, 129, 127, 0, 19, 108}, {8805, 0, 129, 127, 0, 19, 108}, | 96 {8804, 0, 129, 127, 0, 19, 108}, {8805, 0, 129, 127, 0, 19, 108}, |
448 {8806, 0, 129, 127, 0, 19, 108}, {8807, 0, 129, 127, 0, 19, 108}, | 97 {8806, 0, 129, 127, 0, 19, 108}, {8807, 0, 129, 127, 0, 19, 108}, |
449 {8808, 0, 129, 127, 0, 19, 108}, {8809, 0, 129, 127, 0, 19, 108}, | 98 {8808, 0, 129, 127, 0, 19, 108}, {8809, 0, 129, 127, 0, 19, 108}, |
450 {8810, 0, 129, 127, 0, 19, 108}, {8811, 0, 129, 127, 0, 19, 114}, | 99 {8810, 0, 129, 127, 0, 19, 108}, {8811, 0, 129, 127, 0, 19, 114}, |
451 {8812, 0, 129, 127, 0, 19, 102}, {8813, 0, 129, 127, 0, 19, 114}, | 100 {8812, 0, 129, 127, 0, 19, 102}, {8813, 0, 129, 127, 0, 19, 114}, |
452 {8814, 0, 129, 127, 0, 76, 102}, {8815, 0, 129, 127, 0, 13, 121}, | 101 {8814, 0, 129, 127, 0, 76, 102}, {8815, 0, 129, 127, 0, 13, 121}, |
453 {8816, 0, 129, 127, 0, 19, 114}, {8817, 0, 129, 127, 0, 19, 127}, | 102 {8816, 0, 129, 127, 0, 19, 114}, {8817, 0, 129, 127, 0, 19, 127}, |
454 {8818, 0, 129, 127, 0, 19, 114}, {8819, 0, 129, 127, 0, 218, 108}, | 103 {8818, 0, 129, 127, 0, 19, 114}, {8819, 0, 129, 127, 0, 218, 108}, |
455 }; | 104 }; |
456 | 105 |
106 bool IsValidEmbeddedCharcodeFromUnicodeCharset(CIDSet charset) { | |
107 switch (charset) { | |
108 case CIDSET_GB1: | |
109 case CIDSET_CNS1: | |
110 case CIDSET_JAPAN1: | |
111 case CIDSET_KOREA1: | |
112 return true; | |
113 | |
114 default: | |
115 return false; | |
116 } | |
117 } | |
118 | |
119 FX_WCHAR EmbeddedUnicodeFromCharcode(const FXCMAP_CMap* pEmbedMap, | |
120 CIDSet charset, | |
121 FX_DWORD charcode) { | |
122 if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset)) | |
123 return 0; | |
124 | |
125 uint16_t cid = FPDFAPI_CIDFromCharCode(pEmbedMap, charcode); | |
126 if (cid == 0) | |
127 return 0; | |
128 | |
129 CPDF_FontGlobals* pFontGlobals = | |
130 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); | |
131 const uint16_t* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap; | |
132 if (!pCodes) | |
133 return 0; | |
134 | |
135 if (cid < pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count) | |
136 return pCodes[cid]; | |
137 return 0; | |
138 } | |
139 | |
140 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ | |
141 FX_DWORD EmbeddedCharcodeFromUnicode(const FXCMAP_CMap* pEmbedMap, | |
142 CIDSet charset, | |
143 FX_WCHAR unicode) { | |
144 if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset)) | |
145 return 0; | |
146 | |
147 CPDF_FontGlobals* pFontGlobals = | |
148 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); | |
149 const uint16_t* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap; | |
150 if (!pCodes) | |
151 return 0; | |
152 | |
153 int nCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count; | |
154 for (int i = 0; i < nCodes; ++i) { | |
155 if (pCodes[i] == unicode) { | |
156 FX_DWORD CharCode = FPDFAPI_CharCodeFromCID(pEmbedMap, i); | |
157 if (CharCode != 0) { | |
158 return CharCode; | |
159 } | |
160 } | |
161 } | |
162 return 0; | |
163 } | |
164 #endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ | |
165 | |
166 void FT_UseCIDCharmap(FXFT_Face face, int coding) { | |
167 int encoding; | |
168 switch (coding) { | |
169 case CIDCODING_GB: | |
170 encoding = FXFT_ENCODING_GB2312; | |
171 break; | |
172 case CIDCODING_BIG5: | |
173 encoding = FXFT_ENCODING_BIG5; | |
174 break; | |
175 case CIDCODING_JIS: | |
176 encoding = FXFT_ENCODING_SJIS; | |
177 break; | |
178 case CIDCODING_KOREA: | |
179 encoding = FXFT_ENCODING_JOHAB; | |
180 break; | |
181 default: | |
182 encoding = FXFT_ENCODING_UNICODE; | |
183 } | |
184 int err = FXFT_Select_Charmap(face, encoding); | |
185 if (err) { | |
186 err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE); | |
187 } | |
188 if (err && FXFT_Get_Face_Charmaps(face)) { | |
189 FXFT_Set_Charmap(face, *FXFT_Get_Face_Charmaps(face)); | |
190 } | |
191 } | |
192 | |
457 int CompareCIDTransform(const void* key, const void* element) { | 193 int CompareCIDTransform(const void* key, const void* element) { |
458 uint16_t CID = *static_cast<const uint16_t*>(key); | 194 uint16_t CID = *static_cast<const uint16_t*>(key); |
459 return CID - static_cast<const struct CIDTransform*>(element)->CID; | 195 return CID - static_cast<const struct CIDTransform*>(element)->CID; |
460 } | 196 } |
461 | 197 |
462 } // namespace | 198 } // namespace |
463 | 199 |
464 CPDF_CMapManager::CPDF_CMapManager() { | |
465 m_bPrompted = FALSE; | |
466 FXSYS_memset(m_CID2UnicodeMaps, 0, sizeof m_CID2UnicodeMaps); | |
467 } | |
468 CPDF_CMapManager::~CPDF_CMapManager() { | |
469 for (const auto& pair : m_CMaps) { | |
470 delete pair.second; | |
471 } | |
472 m_CMaps.clear(); | |
473 for (size_t i = 0; i < FX_ArraySize(m_CID2UnicodeMaps); ++i) { | |
474 delete m_CID2UnicodeMaps[i]; | |
475 } | |
476 } | |
477 CPDF_CMap* CPDF_CMapManager::GetPredefinedCMap(const CFX_ByteString& name, | |
478 FX_BOOL bPromptCJK) { | |
479 auto it = m_CMaps.find(name); | |
480 if (it != m_CMaps.end()) { | |
481 return it->second; | |
482 } | |
483 CPDF_CMap* pCMap = LoadPredefinedCMap(name, bPromptCJK); | |
484 if (!name.IsEmpty()) { | |
485 m_CMaps[name] = pCMap; | |
486 } | |
487 return pCMap; | |
488 } | |
489 CPDF_CMap* CPDF_CMapManager::LoadPredefinedCMap(const CFX_ByteString& name, | |
490 FX_BOOL bPromptCJK) { | |
491 CPDF_CMap* pCMap = new CPDF_CMap; | |
492 const FX_CHAR* pname = name; | |
493 if (*pname == '/') { | |
494 pname++; | |
495 } | |
496 pCMap->LoadPredefined(this, pname, bPromptCJK); | |
497 return pCMap; | |
498 } | |
499 | |
500 void CPDF_CMapManager::ReloadAll() { | |
501 for (const auto& pair : m_CMaps) { | |
502 CPDF_CMap* pCMap = pair.second; | |
503 pCMap->LoadPredefined(this, pair.first, FALSE); | |
504 } | |
505 for (size_t i = 0; i < FX_ArraySize(m_CID2UnicodeMaps); ++i) { | |
506 if (CPDF_CID2UnicodeMap* pMap = m_CID2UnicodeMaps[i]) { | |
507 pMap->Load(this, CIDSetFromSizeT(i), FALSE); | |
508 } | |
509 } | |
510 } | |
511 CPDF_CID2UnicodeMap* CPDF_CMapManager::GetCID2UnicodeMap(CIDSet charset, | |
512 FX_BOOL bPromptCJK) { | |
513 if (!m_CID2UnicodeMaps[charset]) | |
514 m_CID2UnicodeMaps[charset] = LoadCID2UnicodeMap(charset, bPromptCJK); | |
515 return m_CID2UnicodeMaps[charset]; | |
516 } | |
517 CPDF_CID2UnicodeMap* CPDF_CMapManager::LoadCID2UnicodeMap(CIDSet charset, | |
518 FX_BOOL bPromptCJK) { | |
519 CPDF_CID2UnicodeMap* pMap = new CPDF_CID2UnicodeMap(); | |
520 if (!pMap->Initialize()) { | |
521 delete pMap; | |
522 return NULL; | |
523 } | |
524 pMap->Load(this, charset, bPromptCJK); | |
525 return pMap; | |
526 } | |
527 CPDF_CMapParser::CPDF_CMapParser() { | |
528 m_pCMap = NULL; | |
529 m_Status = 0; | |
530 m_CodeSeq = 0; | |
531 } | |
532 FX_BOOL CPDF_CMapParser::Initialize(CPDF_CMap* pCMap) { | |
533 m_pCMap = pCMap; | |
534 m_Status = 0; | |
535 m_CodeSeq = 0; | |
536 m_AddMaps.EstimateSize(0, 10240); | |
537 return TRUE; | |
538 } | |
539 | |
540 void CPDF_CMapParser::ParseWord(const CFX_ByteStringC& word) { | |
541 if (word.IsEmpty()) { | |
542 return; | |
543 } | |
544 if (word == "begincidchar") { | |
545 m_Status = 1; | |
546 m_CodeSeq = 0; | |
547 } else if (word == "begincidrange") { | |
548 m_Status = 2; | |
549 m_CodeSeq = 0; | |
550 } else if (word == "endcidrange" || word == "endcidchar") { | |
551 m_Status = 0; | |
552 } else if (word == "/WMode") { | |
553 m_Status = 6; | |
554 } else if (word == "/Registry") { | |
555 m_Status = 3; | |
556 } else if (word == "/Ordering") { | |
557 m_Status = 4; | |
558 } else if (word == "/Supplement") { | |
559 m_Status = 5; | |
560 } else if (word == "begincodespacerange") { | |
561 m_Status = 7; | |
562 m_CodeSeq = 0; | |
563 } else if (word == "usecmap") { | |
564 } else if (m_Status == 1 || m_Status == 2) { | |
565 m_CodePoints[m_CodeSeq] = CMap_GetCode(word); | |
566 m_CodeSeq++; | |
567 FX_DWORD StartCode, EndCode; | |
568 uint16_t StartCID; | |
569 if (m_Status == 1) { | |
570 if (m_CodeSeq < 2) { | |
571 return; | |
572 } | |
573 EndCode = StartCode = m_CodePoints[0]; | |
574 StartCID = (uint16_t)m_CodePoints[1]; | |
575 } else { | |
576 if (m_CodeSeq < 3) { | |
577 return; | |
578 } | |
579 StartCode = m_CodePoints[0]; | |
580 EndCode = m_CodePoints[1]; | |
581 StartCID = (uint16_t)m_CodePoints[2]; | |
582 } | |
583 if (EndCode < 0x10000) { | |
584 for (FX_DWORD code = StartCode; code <= EndCode; code++) { | |
585 m_pCMap->m_pMapping[code] = (uint16_t)(StartCID + code - StartCode); | |
586 } | |
587 } else { | |
588 FX_DWORD buf[2]; | |
589 buf[0] = StartCode; | |
590 buf[1] = ((EndCode - StartCode) << 16) + StartCID; | |
591 m_AddMaps.AppendBlock(buf, sizeof buf); | |
592 } | |
593 m_CodeSeq = 0; | |
594 } else if (m_Status == 3) { | |
595 CMap_GetString(word); | |
596 m_Status = 0; | |
597 } else if (m_Status == 4) { | |
598 m_pCMap->m_Charset = CharsetFromOrdering(CMap_GetString(word)); | |
599 m_Status = 0; | |
600 } else if (m_Status == 5) { | |
601 CMap_GetCode(word); | |
602 m_Status = 0; | |
603 } else if (m_Status == 6) { | |
604 m_pCMap->m_bVertical = CMap_GetCode(word); | |
605 m_Status = 0; | |
606 } else if (m_Status == 7) { | |
607 if (word == "endcodespacerange") { | |
608 int nSegs = m_CodeRanges.GetSize(); | |
609 if (nSegs > 1) { | |
610 m_pCMap->m_CodingScheme = CPDF_CMap::MixedFourBytes; | |
611 m_pCMap->m_nCodeRanges = nSegs; | |
612 m_pCMap->m_pLeadingBytes = | |
613 FX_Alloc2D(uint8_t, nSegs, sizeof(CMap_CodeRange)); | |
614 FXSYS_memcpy(m_pCMap->m_pLeadingBytes, m_CodeRanges.GetData(), | |
615 nSegs * sizeof(CMap_CodeRange)); | |
616 } else if (nSegs == 1) { | |
617 m_pCMap->m_CodingScheme = (m_CodeRanges[0].m_CharSize == 2) | |
618 ? CPDF_CMap::TwoBytes | |
619 : CPDF_CMap::OneByte; | |
620 } | |
621 m_Status = 0; | |
622 } else { | |
623 if (word.GetLength() == 0 || word.GetAt(0) != '<') { | |
624 return; | |
625 } | |
626 if (m_CodeSeq % 2) { | |
627 CMap_CodeRange range; | |
628 if (CMap_GetCodeRange(range, m_LastWord, word)) { | |
629 m_CodeRanges.Add(range); | |
630 } | |
631 } | |
632 m_CodeSeq++; | |
633 } | |
634 } | |
635 m_LastWord = word; | |
636 } | |
637 | |
638 // Static. | |
639 FX_DWORD CPDF_CMapParser::CMap_GetCode(const CFX_ByteStringC& word) { | |
640 int num = 0; | |
641 if (word.GetAt(0) == '<') { | |
642 for (int i = 1; i < word.GetLength() && std::isxdigit(word.GetAt(i)); ++i) | |
643 num = num * 16 + FXSYS_toHexDigit(word.GetAt(i)); | |
644 return num; | |
645 } | |
646 | |
647 for (int i = 0; i < word.GetLength() && std::isdigit(word.GetAt(i)); ++i) | |
648 num = num * 10 + FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(word.GetAt(i))); | |
649 return num; | |
650 } | |
651 | |
652 // Static. | |
653 bool CPDF_CMapParser::CMap_GetCodeRange(CMap_CodeRange& range, | |
654 const CFX_ByteStringC& first, | |
655 const CFX_ByteStringC& second) { | |
656 if (first.GetLength() == 0 || first.GetAt(0) != '<') | |
657 return false; | |
658 | |
659 int i; | |
660 for (i = 1; i < first.GetLength(); ++i) { | |
661 if (first.GetAt(i) == '>') { | |
662 break; | |
663 } | |
664 } | |
665 range.m_CharSize = (i - 1) / 2; | |
666 if (range.m_CharSize > 4) | |
667 return false; | |
668 | |
669 for (i = 0; i < range.m_CharSize; ++i) { | |
670 uint8_t digit1 = first.GetAt(i * 2 + 1); | |
671 uint8_t digit2 = first.GetAt(i * 2 + 2); | |
672 range.m_Lower[i] = FXSYS_toHexDigit(digit1) * 16 + FXSYS_toHexDigit(digit2); | |
673 } | |
674 | |
675 FX_DWORD size = second.GetLength(); | |
676 for (i = 0; i < range.m_CharSize; ++i) { | |
677 uint8_t digit1 = ((FX_DWORD)i * 2 + 1 < size) | |
678 ? second.GetAt((FX_STRSIZE)i * 2 + 1) | |
679 : '0'; | |
680 uint8_t digit2 = ((FX_DWORD)i * 2 + 2 < size) | |
681 ? second.GetAt((FX_STRSIZE)i * 2 + 2) | |
682 : '0'; | |
683 range.m_Upper[i] = FXSYS_toHexDigit(digit1) * 16 + FXSYS_toHexDigit(digit2); | |
684 } | |
685 return true; | |
686 } | |
687 | |
688 CPDF_CMap::CPDF_CMap() { | |
689 m_Charset = CIDSET_UNKNOWN; | |
690 m_Coding = CIDCODING_UNKNOWN; | |
691 m_CodingScheme = TwoBytes; | |
692 m_bVertical = 0; | |
693 m_bLoaded = FALSE; | |
694 m_pMapping = NULL; | |
695 m_pLeadingBytes = NULL; | |
696 m_pAddMapping = NULL; | |
697 m_pEmbedMap = NULL; | |
698 m_pUseMap = NULL; | |
699 m_nCodeRanges = 0; | |
700 } | |
701 CPDF_CMap::~CPDF_CMap() { | |
702 FX_Free(m_pMapping); | |
703 FX_Free(m_pAddMapping); | |
704 FX_Free(m_pLeadingBytes); | |
705 delete m_pUseMap; | |
706 } | |
707 void CPDF_CMap::Release() { | |
708 if (m_PredefinedCMap.IsEmpty()) { | |
709 delete this; | |
710 } | |
711 } | |
712 | |
713 FX_BOOL CPDF_CMap::LoadPredefined(CPDF_CMapManager* pMgr, | |
714 const FX_CHAR* pName, | |
715 FX_BOOL bPromptCJK) { | |
716 m_PredefinedCMap = pName; | |
717 if (m_PredefinedCMap == "Identity-H" || m_PredefinedCMap == "Identity-V") { | |
718 m_Coding = CIDCODING_CID; | |
719 m_bVertical = pName[9] == 'V'; | |
720 m_bLoaded = TRUE; | |
721 return TRUE; | |
722 } | |
723 CFX_ByteString cmapid = m_PredefinedCMap; | |
724 m_bVertical = cmapid.Right(1) == "V"; | |
725 if (cmapid.GetLength() > 2) { | |
726 cmapid = cmapid.Left(cmapid.GetLength() - 2); | |
727 } | |
728 const CPDF_PredefinedCMap* map = nullptr; | |
729 for (size_t i = 0; i < FX_ArraySize(g_PredefinedCMaps); ++i) { | |
730 if (cmapid == CFX_ByteStringC(g_PredefinedCMaps[i].m_pName)) { | |
731 map = &g_PredefinedCMaps[i]; | |
732 break; | |
733 } | |
734 } | |
735 if (!map) | |
736 return FALSE; | |
737 | |
738 m_Charset = map->m_Charset; | |
739 m_Coding = map->m_Coding; | |
740 m_CodingScheme = map->m_CodingScheme; | |
741 if (m_CodingScheme == MixedTwoBytes) { | |
742 m_pLeadingBytes = FX_Alloc(uint8_t, 256); | |
743 for (FX_DWORD i = 0; i < map->m_LeadingSegCount; ++i) { | |
744 const uint8_t* segs = map->m_LeadingSegs; | |
745 for (int b = segs[i * 2]; b <= segs[i * 2 + 1]; ++b) { | |
746 m_pLeadingBytes[b] = 1; | |
747 } | |
748 } | |
749 } | |
750 FPDFAPI_FindEmbeddedCMap(pName, m_Charset, m_Coding, m_pEmbedMap); | |
751 if (m_pEmbedMap) { | |
752 m_bLoaded = TRUE; | |
753 return TRUE; | |
754 } | |
755 return FALSE; | |
756 } | |
757 FX_BOOL CPDF_CMap::LoadEmbedded(const uint8_t* pData, FX_DWORD size) { | |
758 m_pMapping = FX_Alloc(uint16_t, 65536); | |
759 CPDF_CMapParser parser; | |
760 parser.Initialize(this); | |
761 CPDF_SimpleParser syntax(pData, size); | |
762 while (1) { | |
763 CFX_ByteStringC word = syntax.GetWord(); | |
764 if (word.IsEmpty()) { | |
765 break; | |
766 } | |
767 parser.ParseWord(word); | |
768 } | |
769 if (m_CodingScheme == MixedFourBytes && parser.m_AddMaps.GetSize()) { | |
770 m_pAddMapping = FX_Alloc(uint8_t, parser.m_AddMaps.GetSize() + 4); | |
771 *(FX_DWORD*)m_pAddMapping = parser.m_AddMaps.GetSize() / 8; | |
772 FXSYS_memcpy(m_pAddMapping + 4, parser.m_AddMaps.GetBuffer(), | |
773 parser.m_AddMaps.GetSize()); | |
774 FXSYS_qsort(m_pAddMapping + 4, parser.m_AddMaps.GetSize() / 8, 8, | |
775 CompareDWORD); | |
776 } | |
777 return TRUE; | |
778 } | |
779 | |
780 uint16_t CPDF_CMap::CIDFromCharCode(FX_DWORD charcode) const { | |
781 if (m_Coding == CIDCODING_CID) { | |
782 return (uint16_t)charcode; | |
783 } | |
784 if (m_pEmbedMap) { | |
785 return FPDFAPI_CIDFromCharCode(m_pEmbedMap, charcode); | |
786 } | |
787 if (!m_pMapping) { | |
788 return (uint16_t)charcode; | |
789 } | |
790 if (charcode >> 16) { | |
791 if (m_pAddMapping) { | |
792 void* found = FXSYS_bsearch(&charcode, m_pAddMapping + 4, | |
793 *(FX_DWORD*)m_pAddMapping, 8, CompareCID); | |
794 if (!found) { | |
795 if (m_pUseMap) { | |
796 return m_pUseMap->CIDFromCharCode(charcode); | |
797 } | |
798 return 0; | |
799 } | |
800 return (uint16_t)(((FX_DWORD*)found)[1] % 65536 + charcode - | |
801 *(FX_DWORD*)found); | |
802 } | |
803 if (m_pUseMap) | |
804 return m_pUseMap->CIDFromCharCode(charcode); | |
805 return 0; | |
806 } | |
807 FX_DWORD CID = m_pMapping[charcode]; | |
808 if (!CID && m_pUseMap) | |
809 return m_pUseMap->CIDFromCharCode(charcode); | |
810 return (uint16_t)CID; | |
811 } | |
812 | |
813 FX_DWORD CPDF_CMap::GetNextChar(const FX_CHAR* pString, | |
814 int nStrLen, | |
815 int& offset) const { | |
816 switch (m_CodingScheme) { | |
817 case OneByte: | |
818 return ((uint8_t*)pString)[offset++]; | |
819 case TwoBytes: | |
820 offset += 2; | |
821 return ((uint8_t*)pString)[offset - 2] * 256 + | |
822 ((uint8_t*)pString)[offset - 1]; | |
823 case MixedTwoBytes: { | |
824 uint8_t byte1 = ((uint8_t*)pString)[offset++]; | |
825 if (!m_pLeadingBytes[byte1]) { | |
826 return byte1; | |
827 } | |
828 uint8_t byte2 = ((uint8_t*)pString)[offset++]; | |
829 return byte1 * 256 + byte2; | |
830 } | |
831 case MixedFourBytes: { | |
832 uint8_t codes[4]; | |
833 int char_size = 1; | |
834 codes[0] = ((uint8_t*)pString)[offset++]; | |
835 CMap_CodeRange* pRanges = (CMap_CodeRange*)m_pLeadingBytes; | |
836 while (1) { | |
837 int ret = CheckCodeRange(codes, char_size, pRanges, m_nCodeRanges); | |
838 if (ret == 0) { | |
839 return 0; | |
840 } | |
841 if (ret == 2) { | |
842 FX_DWORD charcode = 0; | |
843 for (int i = 0; i < char_size; i++) { | |
844 charcode = (charcode << 8) + codes[i]; | |
845 } | |
846 return charcode; | |
847 } | |
848 if (char_size == 4 || offset == nStrLen) { | |
849 return 0; | |
850 } | |
851 codes[char_size++] = ((uint8_t*)pString)[offset++]; | |
852 } | |
853 break; | |
854 } | |
855 } | |
856 return 0; | |
857 } | |
858 int CPDF_CMap::GetCharSize(FX_DWORD charcode) const { | |
859 switch (m_CodingScheme) { | |
860 case OneByte: | |
861 return 1; | |
862 case TwoBytes: | |
863 return 2; | |
864 case MixedTwoBytes: | |
865 case MixedFourBytes: | |
866 if (charcode < 0x100) { | |
867 return 1; | |
868 } | |
869 if (charcode < 0x10000) { | |
870 return 2; | |
871 } | |
872 if (charcode < 0x1000000) { | |
873 return 3; | |
874 } | |
875 return 4; | |
876 } | |
877 return 1; | |
878 } | |
879 int CPDF_CMap::CountChar(const FX_CHAR* pString, int size) const { | |
880 switch (m_CodingScheme) { | |
881 case OneByte: | |
882 return size; | |
883 case TwoBytes: | |
884 return (size + 1) / 2; | |
885 case MixedTwoBytes: { | |
886 int count = 0; | |
887 for (int i = 0; i < size; i++) { | |
888 count++; | |
889 if (m_pLeadingBytes[((uint8_t*)pString)[i]]) { | |
890 i++; | |
891 } | |
892 } | |
893 return count; | |
894 } | |
895 case MixedFourBytes: { | |
896 int count = 0, offset = 0; | |
897 while (offset < size) { | |
898 GetNextChar(pString, size, offset); | |
899 count++; | |
900 } | |
901 return count; | |
902 } | |
903 } | |
904 return size; | |
905 } | |
906 | |
907 int CPDF_CMap::AppendChar(FX_CHAR* str, FX_DWORD charcode) const { | |
908 switch (m_CodingScheme) { | |
909 case OneByte: | |
910 str[0] = (uint8_t)charcode; | |
911 return 1; | |
912 case TwoBytes: | |
913 str[0] = (uint8_t)(charcode / 256); | |
914 str[1] = (uint8_t)(charcode % 256); | |
915 return 2; | |
916 case MixedTwoBytes: | |
917 case MixedFourBytes: | |
918 if (charcode < 0x100) { | |
919 CMap_CodeRange* pRanges = (CMap_CodeRange*)m_pLeadingBytes; | |
920 int iSize = GetCharSizeImpl(charcode, pRanges, m_nCodeRanges); | |
921 if (iSize == 0) { | |
922 iSize = 1; | |
923 } | |
924 if (iSize > 1) { | |
925 FXSYS_memset(str, 0, sizeof(uint8_t) * iSize); | |
926 } | |
927 str[iSize - 1] = (uint8_t)charcode; | |
928 return iSize; | |
929 } | |
930 if (charcode < 0x10000) { | |
931 str[0] = (uint8_t)(charcode >> 8); | |
932 str[1] = (uint8_t)charcode; | |
933 return 2; | |
934 } | |
935 if (charcode < 0x1000000) { | |
936 str[0] = (uint8_t)(charcode >> 16); | |
937 str[1] = (uint8_t)(charcode >> 8); | |
938 str[2] = (uint8_t)charcode; | |
939 return 3; | |
940 } | |
941 str[0] = (uint8_t)(charcode >> 24); | |
942 str[1] = (uint8_t)(charcode >> 16); | |
943 str[2] = (uint8_t)(charcode >> 8); | |
944 str[3] = (uint8_t)charcode; | |
945 return 4; | |
946 } | |
947 return 0; | |
948 } | |
949 CPDF_CID2UnicodeMap::CPDF_CID2UnicodeMap() { | |
950 m_EmbeddedCount = 0; | |
951 } | |
952 CPDF_CID2UnicodeMap::~CPDF_CID2UnicodeMap() {} | |
953 FX_BOOL CPDF_CID2UnicodeMap::Initialize() { | |
954 return TRUE; | |
955 } | |
956 FX_BOOL CPDF_CID2UnicodeMap::IsLoaded() { | |
957 return m_EmbeddedCount != 0; | |
958 } | |
959 FX_WCHAR CPDF_CID2UnicodeMap::UnicodeFromCID(uint16_t CID) { | |
960 if (m_Charset == CIDSET_UNICODE) { | |
961 return CID; | |
962 } | |
963 if (CID < m_EmbeddedCount) { | |
964 return m_pEmbeddedMap[CID]; | |
965 } | |
966 return 0; | |
967 } | |
968 | |
969 void CPDF_CID2UnicodeMap::Load(CPDF_CMapManager* pMgr, | |
970 CIDSet charset, | |
971 FX_BOOL bPromptCJK) { | |
972 m_Charset = charset; | |
973 FPDFAPI_LoadCID2UnicodeMap(charset, m_pEmbeddedMap, m_EmbeddedCount); | |
974 } | |
975 | |
976 CPDF_CIDFont::CPDF_CIDFont() | 200 CPDF_CIDFont::CPDF_CIDFont() |
977 : m_pCMap(nullptr), | 201 : m_pCMap(nullptr), |
978 m_pAllocatedCMap(nullptr), | 202 m_pAllocatedCMap(nullptr), |
979 m_pCID2UnicodeMap(nullptr), | 203 m_pCID2UnicodeMap(nullptr), |
980 m_pCIDToGIDMap(nullptr), | 204 m_pCIDToGIDMap(nullptr), |
981 m_bCIDIsGID(FALSE), | 205 m_bCIDIsGID(FALSE), |
982 m_pAnsiWidths(nullptr), | 206 m_pAnsiWidths(nullptr), |
983 m_bAdobeCourierStd(FALSE), | 207 m_bAdobeCourierStd(FALSE), |
984 m_pTTGSUBTable(nullptr) {} | 208 m_pTTGSUBTable(nullptr) {} |
985 | 209 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1071 return 0; | 295 return 0; |
1072 case CIDCODING_UCS2: | 296 case CIDCODING_UCS2: |
1073 case CIDCODING_UTF16: | 297 case CIDCODING_UTF16: |
1074 return unicode; | 298 return unicode; |
1075 case CIDCODING_CID: { | 299 case CIDCODING_CID: { |
1076 if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) { | 300 if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) { |
1077 return 0; | 301 return 0; |
1078 } | 302 } |
1079 FX_DWORD CID = 0; | 303 FX_DWORD CID = 0; |
1080 while (CID < 65536) { | 304 while (CID < 65536) { |
1081 FX_WCHAR this_unicode = | 305 FX_WCHAR this_unicode = m_pCID2UnicodeMap->UnicodeFromCID((uint16_t)CID) ; |
Tom Sepez
2016/03/22 16:55:52
nit: 80 cols.
dsinclair
2016/03/23 00:00:25
Done.
| |
1082 m_pCID2UnicodeMap->UnicodeFromCID((uint16_t)CID); | |
1083 if (this_unicode == unicode) { | 306 if (this_unicode == unicode) { |
1084 return CID; | 307 return CID; |
1085 } | 308 } |
1086 CID++; | 309 CID++; |
1087 } | 310 } |
1088 break; | 311 break; |
1089 } | 312 } |
1090 } | 313 } |
1091 | 314 |
1092 if (unicode < 0x80) { | 315 if (unicode < 0x80) { |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1578 } | 801 } |
1579 void CPDF_CIDFont::LoadSubstFont() { | 802 void CPDF_CIDFont::LoadSubstFont() { |
1580 m_Font.LoadSubst(m_BaseFont, !m_bType1, m_Flags, m_StemV * 5, m_ItalicAngle, | 803 m_Font.LoadSubst(m_BaseFont, !m_bType1, m_Flags, m_StemV * 5, m_ItalicAngle, |
1581 g_CharsetCPs[m_Charset], IsVertWriting()); | 804 g_CharsetCPs[m_Charset], IsVertWriting()); |
1582 } | 805 } |
1583 void CPDF_CIDFont::LoadMetricsArray(CPDF_Array* pArray, | 806 void CPDF_CIDFont::LoadMetricsArray(CPDF_Array* pArray, |
1584 CFX_DWordArray& result, | 807 CFX_DWordArray& result, |
1585 int nElements) { | 808 int nElements) { |
1586 int width_status = 0; | 809 int width_status = 0; |
1587 int iCurElement = 0; | 810 int iCurElement = 0; |
1588 int first_code = 0; | 811 int first_code = 0, last_code; |
Tom Sepez
2016/03/22 16:55:52
nit: one per line like before?
dsinclair
2016/03/23 00:00:25
Sigh, bad merge.
| |
1589 int last_code = 0; | |
1590 FX_DWORD count = pArray->GetCount(); | 812 FX_DWORD count = pArray->GetCount(); |
1591 for (FX_DWORD i = 0; i < count; i++) { | 813 for (FX_DWORD i = 0; i < count; i++) { |
1592 CPDF_Object* pObj = pArray->GetElementValue(i); | 814 CPDF_Object* pObj = pArray->GetElementValue(i); |
1593 if (!pObj) | 815 if (!pObj) |
1594 continue; | 816 continue; |
1595 | 817 |
1596 if (CPDF_Array* pArray = pObj->AsArray()) { | 818 if (CPDF_Array* pArray = pObj->AsArray()) { |
1597 if (width_status != 1) | 819 if (width_status != 1) |
1598 return; | 820 return; |
1599 | 821 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1668 | 890 |
1669 const uint8_t* CPDF_CIDFont::GetCIDTransform(uint16_t CID) const { | 891 const uint8_t* CPDF_CIDFont::GetCIDTransform(uint16_t CID) const { |
1670 if (m_Charset != CIDSET_JAPAN1 || m_pFontFile) | 892 if (m_Charset != CIDSET_JAPAN1 || m_pFontFile) |
1671 return nullptr; | 893 return nullptr; |
1672 | 894 |
1673 const struct CIDTransform* found = (const struct CIDTransform*)FXSYS_bsearch( | 895 const struct CIDTransform* found = (const struct CIDTransform*)FXSYS_bsearch( |
1674 &CID, g_Japan1_VertCIDs, FX_ArraySize(g_Japan1_VertCIDs), | 896 &CID, g_Japan1_VertCIDs, FX_ArraySize(g_Japan1_VertCIDs), |
1675 sizeof(g_Japan1_VertCIDs[0]), CompareCIDTransform); | 897 sizeof(g_Japan1_VertCIDs[0]), CompareCIDTransform); |
1676 return found ? &found->a : nullptr; | 898 return found ? &found->a : nullptr; |
1677 } | 899 } |
OLD | NEW |