Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: core/fpdfapi/fpdf_font/cpdf_cidfont.cpp

Issue 1824033002: Split core/include/fpdfapi/fpdf_resource.h (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/fpdfapi/fpdf_font/cpdf_cidfont.h ('k') | core/fpdfapi/fpdf_font/cpdf_font.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/include/cpdf_fontencoding.h"
10 #include "core/fpdfapi/fpdf_font/ttgsubtable.h" 12 #include "core/fpdfapi/fpdf_font/ttgsubtable.h"
11 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" 13 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
12 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" 14 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
13 #include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h" 15 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
14 #include "core/fpdfapi/include/cpdf_modulemgr.h" 16 #include "core/fpdfapi/include/cpdf_modulemgr.h"
15 #include "core/fxcrt/include/fx_ext.h"
16 #include "core/include/fpdfapi/fpdf_resource.h"
17 #include "core/include/fxge/fx_freetype.h"
18 #include "core/include/fxge/fx_ge.h"
19 17
20 namespace { 18 namespace {
21 19
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}; 20 const uint16_t g_CharsetCPs[CIDSET_NUM_SETS] = {0, 936, 950, 932, 949, 1200};
26 21
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 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
288
289 bool IsValidEmbeddedCharcodeFromUnicodeCharset(CIDSet charset) {
290 switch (charset) {
291 case CIDSET_GB1:
292 case CIDSET_CNS1:
293 case CIDSET_JAPAN1:
294 case CIDSET_KOREA1:
295 return true;
296
297 default:
298 return false;
299 }
300 }
301
302 FX_DWORD EmbeddedCharcodeFromUnicode(const FXCMAP_CMap* pEmbedMap,
303 CIDSet charset,
304 FX_WCHAR unicode) {
305 if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset))
306 return 0;
307
308 CPDF_FontGlobals* pFontGlobals =
309 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
310 const uint16_t* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
311 if (!pCodes)
312 return 0;
313
314 int nCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count;
315 for (int i = 0; i < nCodes; ++i) {
316 if (pCodes[i] == unicode) {
317 FX_DWORD CharCode = FPDFAPI_CharCodeFromCID(pEmbedMap, i);
318 if (CharCode != 0) {
319 return CharCode;
320 }
321 }
322 }
323 return 0;
324 }
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 #endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
348
349 void FT_UseCIDCharmap(FXFT_Face face, int coding) {
350 int encoding;
351 switch (coding) {
352 case CIDCODING_GB:
353 encoding = FXFT_ENCODING_GB2312;
354 break;
355 case CIDCODING_BIG5:
356 encoding = FXFT_ENCODING_BIG5;
357 break;
358 case CIDCODING_JIS:
359 encoding = FXFT_ENCODING_SJIS;
360 break;
361 case CIDCODING_KOREA:
362 encoding = FXFT_ENCODING_JOHAB;
363 break;
364 default:
365 encoding = FXFT_ENCODING_UNICODE;
366 }
367 int err = FXFT_Select_Charmap(face, encoding);
368 if (err) {
369 err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE);
370 }
371 if (err && FXFT_Get_Face_Charmaps(face)) {
372 FXFT_Set_Charmap(face, *FXFT_Get_Face_Charmaps(face));
373 }
374 }
375
376 const struct CIDTransform { 22 const struct CIDTransform {
377 uint16_t CID; 23 uint16_t CID;
378 uint8_t a, b, c, d, e, f; 24 uint8_t a;
25 uint8_t b;
26 uint8_t c;
27 uint8_t d;
28 uint8_t e;
29 uint8_t f;
379 } g_Japan1_VertCIDs[] = { 30 } g_Japan1_VertCIDs[] = {
380 {97, 129, 0, 0, 127, 55, 0}, {7887, 127, 0, 0, 127, 76, 89}, 31 {97, 129, 0, 0, 127, 55, 0}, {7887, 127, 0, 0, 127, 76, 89},
381 {7888, 127, 0, 0, 127, 79, 94}, {7889, 0, 129, 127, 0, 17, 127}, 32 {7888, 127, 0, 0, 127, 79, 94}, {7889, 0, 129, 127, 0, 17, 127},
382 {7890, 0, 129, 127, 0, 17, 127}, {7891, 0, 129, 127, 0, 17, 127}, 33 {7890, 0, 129, 127, 0, 17, 127}, {7891, 0, 129, 127, 0, 17, 127},
383 {7892, 0, 129, 127, 0, 17, 127}, {7893, 0, 129, 127, 0, 17, 127}, 34 {7892, 0, 129, 127, 0, 17, 127}, {7893, 0, 129, 127, 0, 17, 127},
384 {7894, 0, 129, 127, 0, 17, 127}, {7895, 0, 129, 127, 0, 17, 127}, 35 {7894, 0, 129, 127, 0, 17, 127}, {7895, 0, 129, 127, 0, 17, 127},
385 {7896, 0, 129, 127, 0, 17, 127}, {7897, 0, 129, 127, 0, 17, 127}, 36 {7896, 0, 129, 127, 0, 17, 127}, {7897, 0, 129, 127, 0, 17, 127},
386 {7898, 0, 129, 127, 0, 17, 127}, {7899, 0, 129, 127, 0, 17, 104}, 37 {7898, 0, 129, 127, 0, 17, 127}, {7899, 0, 129, 127, 0, 17, 104},
387 {7900, 0, 129, 127, 0, 17, 127}, {7901, 0, 129, 127, 0, 17, 104}, 38 {7900, 0, 129, 127, 0, 17, 127}, {7901, 0, 129, 127, 0, 17, 104},
388 {7902, 0, 129, 127, 0, 17, 127}, {7903, 0, 129, 127, 0, 17, 127}, 39 {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
449 {8804, 0, 129, 127, 0, 19, 108}, {8805, 0, 129, 127, 0, 19, 108}, 100 {8804, 0, 129, 127, 0, 19, 108}, {8805, 0, 129, 127, 0, 19, 108},
450 {8806, 0, 129, 127, 0, 19, 108}, {8807, 0, 129, 127, 0, 19, 108}, 101 {8806, 0, 129, 127, 0, 19, 108}, {8807, 0, 129, 127, 0, 19, 108},
451 {8808, 0, 129, 127, 0, 19, 108}, {8809, 0, 129, 127, 0, 19, 108}, 102 {8808, 0, 129, 127, 0, 19, 108}, {8809, 0, 129, 127, 0, 19, 108},
452 {8810, 0, 129, 127, 0, 19, 108}, {8811, 0, 129, 127, 0, 19, 114}, 103 {8810, 0, 129, 127, 0, 19, 108}, {8811, 0, 129, 127, 0, 19, 114},
453 {8812, 0, 129, 127, 0, 19, 102}, {8813, 0, 129, 127, 0, 19, 114}, 104 {8812, 0, 129, 127, 0, 19, 102}, {8813, 0, 129, 127, 0, 19, 114},
454 {8814, 0, 129, 127, 0, 76, 102}, {8815, 0, 129, 127, 0, 13, 121}, 105 {8814, 0, 129, 127, 0, 76, 102}, {8815, 0, 129, 127, 0, 13, 121},
455 {8816, 0, 129, 127, 0, 19, 114}, {8817, 0, 129, 127, 0, 19, 127}, 106 {8816, 0, 129, 127, 0, 19, 114}, {8817, 0, 129, 127, 0, 19, 127},
456 {8818, 0, 129, 127, 0, 19, 114}, {8819, 0, 129, 127, 0, 218, 108}, 107 {8818, 0, 129, 127, 0, 19, 114}, {8819, 0, 129, 127, 0, 218, 108},
457 }; 108 };
458 109
110 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
111
112 bool IsValidEmbeddedCharcodeFromUnicodeCharset(CIDSet charset) {
113 switch (charset) {
114 case CIDSET_GB1:
115 case CIDSET_CNS1:
116 case CIDSET_JAPAN1:
117 case CIDSET_KOREA1:
118 return true;
119
120 default:
121 return false;
122 }
123 }
124
125 FX_WCHAR EmbeddedUnicodeFromCharcode(const FXCMAP_CMap* pEmbedMap,
126 CIDSet charset,
127 FX_DWORD charcode) {
128 if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset))
129 return 0;
130
131 uint16_t cid = FPDFAPI_CIDFromCharCode(pEmbedMap, charcode);
132 if (cid == 0)
133 return 0;
134
135 CPDF_FontGlobals* pFontGlobals =
136 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
137 const uint16_t* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
138 if (!pCodes)
139 return 0;
140
141 if (cid < pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count)
142 return pCodes[cid];
143 return 0;
144 }
145
146 FX_DWORD EmbeddedCharcodeFromUnicode(const FXCMAP_CMap* pEmbedMap,
147 CIDSet charset,
148 FX_WCHAR unicode) {
149 if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset))
150 return 0;
151
152 CPDF_FontGlobals* pFontGlobals =
153 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
154 const uint16_t* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
155 if (!pCodes)
156 return 0;
157
158 int nCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count;
159 for (int i = 0; i < nCodes; ++i) {
160 if (pCodes[i] == unicode) {
161 FX_DWORD CharCode = FPDFAPI_CharCodeFromCID(pEmbedMap, i);
162 if (CharCode != 0) {
163 return CharCode;
164 }
165 }
166 }
167 return 0;
168 }
169
170 #endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
171
172 void FT_UseCIDCharmap(FXFT_Face face, int coding) {
173 int encoding;
174 switch (coding) {
175 case CIDCODING_GB:
176 encoding = FXFT_ENCODING_GB2312;
177 break;
178 case CIDCODING_BIG5:
179 encoding = FXFT_ENCODING_BIG5;
180 break;
181 case CIDCODING_JIS:
182 encoding = FXFT_ENCODING_SJIS;
183 break;
184 case CIDCODING_KOREA:
185 encoding = FXFT_ENCODING_JOHAB;
186 break;
187 default:
188 encoding = FXFT_ENCODING_UNICODE;
189 }
190 int err = FXFT_Select_Charmap(face, encoding);
191 if (err) {
192 err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE);
193 }
194 if (err && FXFT_Get_Face_Charmaps(face)) {
195 FXFT_Set_Charmap(face, *FXFT_Get_Face_Charmaps(face));
196 }
197 }
198
459 int CompareCIDTransform(const void* key, const void* element) { 199 int CompareCIDTransform(const void* key, const void* element) {
460 uint16_t CID = *static_cast<const uint16_t*>(key); 200 uint16_t CID = *static_cast<const uint16_t*>(key);
461 return CID - static_cast<const struct CIDTransform*>(element)->CID; 201 return CID - static_cast<const struct CIDTransform*>(element)->CID;
462 } 202 }
463 203
464 } // namespace 204 } // namespace
465 205
466 CPDF_CMapManager::CPDF_CMapManager() {
467 m_bPrompted = FALSE;
468 FXSYS_memset(m_CID2UnicodeMaps, 0, sizeof m_CID2UnicodeMaps);
469 }
470 CPDF_CMapManager::~CPDF_CMapManager() {
471 for (const auto& pair : m_CMaps) {
472 delete pair.second;
473 }
474 m_CMaps.clear();
475 for (size_t i = 0; i < FX_ArraySize(m_CID2UnicodeMaps); ++i) {
476 delete m_CID2UnicodeMaps[i];
477 }
478 }
479 CPDF_CMap* CPDF_CMapManager::GetPredefinedCMap(const CFX_ByteString& name,
480 FX_BOOL bPromptCJK) {
481 auto it = m_CMaps.find(name);
482 if (it != m_CMaps.end()) {
483 return it->second;
484 }
485 CPDF_CMap* pCMap = LoadPredefinedCMap(name, bPromptCJK);
486 if (!name.IsEmpty()) {
487 m_CMaps[name] = pCMap;
488 }
489 return pCMap;
490 }
491 CPDF_CMap* CPDF_CMapManager::LoadPredefinedCMap(const CFX_ByteString& name,
492 FX_BOOL bPromptCJK) {
493 CPDF_CMap* pCMap = new CPDF_CMap;
494 const FX_CHAR* pname = name;
495 if (*pname == '/') {
496 pname++;
497 }
498 pCMap->LoadPredefined(this, pname, bPromptCJK);
499 return pCMap;
500 }
501
502 void CPDF_CMapManager::ReloadAll() {
503 for (const auto& pair : m_CMaps) {
504 CPDF_CMap* pCMap = pair.second;
505 pCMap->LoadPredefined(this, pair.first, FALSE);
506 }
507 for (size_t i = 0; i < FX_ArraySize(m_CID2UnicodeMaps); ++i) {
508 if (CPDF_CID2UnicodeMap* pMap = m_CID2UnicodeMaps[i]) {
509 pMap->Load(this, CIDSetFromSizeT(i), FALSE);
510 }
511 }
512 }
513 CPDF_CID2UnicodeMap* CPDF_CMapManager::GetCID2UnicodeMap(CIDSet charset,
514 FX_BOOL bPromptCJK) {
515 if (!m_CID2UnicodeMaps[charset])
516 m_CID2UnicodeMaps[charset] = LoadCID2UnicodeMap(charset, bPromptCJK);
517 return m_CID2UnicodeMaps[charset];
518 }
519 CPDF_CID2UnicodeMap* CPDF_CMapManager::LoadCID2UnicodeMap(CIDSet charset,
520 FX_BOOL bPromptCJK) {
521 CPDF_CID2UnicodeMap* pMap = new CPDF_CID2UnicodeMap();
522 if (!pMap->Initialize()) {
523 delete pMap;
524 return NULL;
525 }
526 pMap->Load(this, charset, bPromptCJK);
527 return pMap;
528 }
529 CPDF_CMapParser::CPDF_CMapParser() {
530 m_pCMap = NULL;
531 m_Status = 0;
532 m_CodeSeq = 0;
533 }
534 FX_BOOL CPDF_CMapParser::Initialize(CPDF_CMap* pCMap) {
535 m_pCMap = pCMap;
536 m_Status = 0;
537 m_CodeSeq = 0;
538 m_AddMaps.EstimateSize(0, 10240);
539 return TRUE;
540 }
541
542 void CPDF_CMapParser::ParseWord(const CFX_ByteStringC& word) {
543 if (word.IsEmpty()) {
544 return;
545 }
546 if (word == "begincidchar") {
547 m_Status = 1;
548 m_CodeSeq = 0;
549 } else if (word == "begincidrange") {
550 m_Status = 2;
551 m_CodeSeq = 0;
552 } else if (word == "endcidrange" || word == "endcidchar") {
553 m_Status = 0;
554 } else if (word == "/WMode") {
555 m_Status = 6;
556 } else if (word == "/Registry") {
557 m_Status = 3;
558 } else if (word == "/Ordering") {
559 m_Status = 4;
560 } else if (word == "/Supplement") {
561 m_Status = 5;
562 } else if (word == "begincodespacerange") {
563 m_Status = 7;
564 m_CodeSeq = 0;
565 } else if (word == "usecmap") {
566 } else if (m_Status == 1 || m_Status == 2) {
567 m_CodePoints[m_CodeSeq] = CMap_GetCode(word);
568 m_CodeSeq++;
569 FX_DWORD StartCode, EndCode;
570 uint16_t StartCID;
571 if (m_Status == 1) {
572 if (m_CodeSeq < 2) {
573 return;
574 }
575 EndCode = StartCode = m_CodePoints[0];
576 StartCID = (uint16_t)m_CodePoints[1];
577 } else {
578 if (m_CodeSeq < 3) {
579 return;
580 }
581 StartCode = m_CodePoints[0];
582 EndCode = m_CodePoints[1];
583 StartCID = (uint16_t)m_CodePoints[2];
584 }
585 if (EndCode < 0x10000) {
586 for (FX_DWORD code = StartCode; code <= EndCode; code++) {
587 m_pCMap->m_pMapping[code] = (uint16_t)(StartCID + code - StartCode);
588 }
589 } else {
590 FX_DWORD buf[2];
591 buf[0] = StartCode;
592 buf[1] = ((EndCode - StartCode) << 16) + StartCID;
593 m_AddMaps.AppendBlock(buf, sizeof buf);
594 }
595 m_CodeSeq = 0;
596 } else if (m_Status == 3) {
597 CMap_GetString(word);
598 m_Status = 0;
599 } else if (m_Status == 4) {
600 m_pCMap->m_Charset = CharsetFromOrdering(CMap_GetString(word));
601 m_Status = 0;
602 } else if (m_Status == 5) {
603 CMap_GetCode(word);
604 m_Status = 0;
605 } else if (m_Status == 6) {
606 m_pCMap->m_bVertical = CMap_GetCode(word);
607 m_Status = 0;
608 } else if (m_Status == 7) {
609 if (word == "endcodespacerange") {
610 int nSegs = m_CodeRanges.GetSize();
611 if (nSegs > 1) {
612 m_pCMap->m_CodingScheme = CPDF_CMap::MixedFourBytes;
613 m_pCMap->m_nCodeRanges = nSegs;
614 m_pCMap->m_pLeadingBytes =
615 FX_Alloc2D(uint8_t, nSegs, sizeof(CMap_CodeRange));
616 FXSYS_memcpy(m_pCMap->m_pLeadingBytes, m_CodeRanges.GetData(),
617 nSegs * sizeof(CMap_CodeRange));
618 } else if (nSegs == 1) {
619 m_pCMap->m_CodingScheme = (m_CodeRanges[0].m_CharSize == 2)
620 ? CPDF_CMap::TwoBytes
621 : CPDF_CMap::OneByte;
622 }
623 m_Status = 0;
624 } else {
625 if (word.GetLength() == 0 || word.GetAt(0) != '<') {
626 return;
627 }
628 if (m_CodeSeq % 2) {
629 CMap_CodeRange range;
630 if (CMap_GetCodeRange(range, m_LastWord, word)) {
631 m_CodeRanges.Add(range);
632 }
633 }
634 m_CodeSeq++;
635 }
636 }
637 m_LastWord = word;
638 }
639
640 // Static.
641 FX_DWORD CPDF_CMapParser::CMap_GetCode(const CFX_ByteStringC& word) {
642 int num = 0;
643 if (word.GetAt(0) == '<') {
644 for (int i = 1; i < word.GetLength() && std::isxdigit(word.GetAt(i)); ++i)
645 num = num * 16 + FXSYS_toHexDigit(word.GetAt(i));
646 return num;
647 }
648
649 for (int i = 0; i < word.GetLength() && std::isdigit(word.GetAt(i)); ++i)
650 num = num * 10 + FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(word.GetAt(i)));
651 return num;
652 }
653
654 // Static.
655 bool CPDF_CMapParser::CMap_GetCodeRange(CMap_CodeRange& range,
656 const CFX_ByteStringC& first,
657 const CFX_ByteStringC& second) {
658 if (first.GetLength() == 0 || first.GetAt(0) != '<')
659 return false;
660
661 int i;
662 for (i = 1; i < first.GetLength(); ++i) {
663 if (first.GetAt(i) == '>') {
664 break;
665 }
666 }
667 range.m_CharSize = (i - 1) / 2;
668 if (range.m_CharSize > 4)
669 return false;
670
671 for (i = 0; i < range.m_CharSize; ++i) {
672 uint8_t digit1 = first.GetAt(i * 2 + 1);
673 uint8_t digit2 = first.GetAt(i * 2 + 2);
674 range.m_Lower[i] = FXSYS_toHexDigit(digit1) * 16 + FXSYS_toHexDigit(digit2);
675 }
676
677 FX_DWORD size = second.GetLength();
678 for (i = 0; i < range.m_CharSize; ++i) {
679 uint8_t digit1 = ((FX_DWORD)i * 2 + 1 < size)
680 ? second.GetAt((FX_STRSIZE)i * 2 + 1)
681 : '0';
682 uint8_t digit2 = ((FX_DWORD)i * 2 + 2 < size)
683 ? second.GetAt((FX_STRSIZE)i * 2 + 2)
684 : '0';
685 range.m_Upper[i] = FXSYS_toHexDigit(digit1) * 16 + FXSYS_toHexDigit(digit2);
686 }
687 return true;
688 }
689
690 CPDF_CMap::CPDF_CMap() {
691 m_Charset = CIDSET_UNKNOWN;
692 m_Coding = CIDCODING_UNKNOWN;
693 m_CodingScheme = TwoBytes;
694 m_bVertical = 0;
695 m_bLoaded = FALSE;
696 m_pMapping = NULL;
697 m_pLeadingBytes = NULL;
698 m_pAddMapping = NULL;
699 m_pEmbedMap = NULL;
700 m_pUseMap = NULL;
701 m_nCodeRanges = 0;
702 }
703 CPDF_CMap::~CPDF_CMap() {
704 FX_Free(m_pMapping);
705 FX_Free(m_pAddMapping);
706 FX_Free(m_pLeadingBytes);
707 delete m_pUseMap;
708 }
709 void CPDF_CMap::Release() {
710 if (m_PredefinedCMap.IsEmpty()) {
711 delete this;
712 }
713 }
714
715 FX_BOOL CPDF_CMap::LoadPredefined(CPDF_CMapManager* pMgr,
716 const FX_CHAR* pName,
717 FX_BOOL bPromptCJK) {
718 m_PredefinedCMap = pName;
719 if (m_PredefinedCMap == "Identity-H" || m_PredefinedCMap == "Identity-V") {
720 m_Coding = CIDCODING_CID;
721 m_bVertical = pName[9] == 'V';
722 m_bLoaded = TRUE;
723 return TRUE;
724 }
725 CFX_ByteString cmapid = m_PredefinedCMap;
726 m_bVertical = cmapid.Right(1) == "V";
727 if (cmapid.GetLength() > 2) {
728 cmapid = cmapid.Left(cmapid.GetLength() - 2);
729 }
730 const CPDF_PredefinedCMap* map = nullptr;
731 for (size_t i = 0; i < FX_ArraySize(g_PredefinedCMaps); ++i) {
732 if (cmapid == CFX_ByteStringC(g_PredefinedCMaps[i].m_pName)) {
733 map = &g_PredefinedCMaps[i];
734 break;
735 }
736 }
737 if (!map)
738 return FALSE;
739
740 m_Charset = map->m_Charset;
741 m_Coding = map->m_Coding;
742 m_CodingScheme = map->m_CodingScheme;
743 if (m_CodingScheme == MixedTwoBytes) {
744 m_pLeadingBytes = FX_Alloc(uint8_t, 256);
745 for (FX_DWORD i = 0; i < map->m_LeadingSegCount; ++i) {
746 const uint8_t* segs = map->m_LeadingSegs;
747 for (int b = segs[i * 2]; b <= segs[i * 2 + 1]; ++b) {
748 m_pLeadingBytes[b] = 1;
749 }
750 }
751 }
752 FPDFAPI_FindEmbeddedCMap(pName, m_Charset, m_Coding, m_pEmbedMap);
753 if (m_pEmbedMap) {
754 m_bLoaded = TRUE;
755 return TRUE;
756 }
757 return FALSE;
758 }
759 FX_BOOL CPDF_CMap::LoadEmbedded(const uint8_t* pData, FX_DWORD size) {
760 m_pMapping = FX_Alloc(uint16_t, 65536);
761 CPDF_CMapParser parser;
762 parser.Initialize(this);
763 CPDF_SimpleParser syntax(pData, size);
764 while (1) {
765 CFX_ByteStringC word = syntax.GetWord();
766 if (word.IsEmpty()) {
767 break;
768 }
769 parser.ParseWord(word);
770 }
771 if (m_CodingScheme == MixedFourBytes && parser.m_AddMaps.GetSize()) {
772 m_pAddMapping = FX_Alloc(uint8_t, parser.m_AddMaps.GetSize() + 4);
773 *(FX_DWORD*)m_pAddMapping = parser.m_AddMaps.GetSize() / 8;
774 FXSYS_memcpy(m_pAddMapping + 4, parser.m_AddMaps.GetBuffer(),
775 parser.m_AddMaps.GetSize());
776 FXSYS_qsort(m_pAddMapping + 4, parser.m_AddMaps.GetSize() / 8, 8,
777 CompareDWORD);
778 }
779 return TRUE;
780 }
781
782 uint16_t CPDF_CMap::CIDFromCharCode(FX_DWORD charcode) const {
783 if (m_Coding == CIDCODING_CID) {
784 return (uint16_t)charcode;
785 }
786 if (m_pEmbedMap) {
787 return FPDFAPI_CIDFromCharCode(m_pEmbedMap, charcode);
788 }
789 if (!m_pMapping) {
790 return (uint16_t)charcode;
791 }
792 if (charcode >> 16) {
793 if (m_pAddMapping) {
794 void* found = FXSYS_bsearch(&charcode, m_pAddMapping + 4,
795 *(FX_DWORD*)m_pAddMapping, 8, CompareCID);
796 if (!found) {
797 if (m_pUseMap) {
798 return m_pUseMap->CIDFromCharCode(charcode);
799 }
800 return 0;
801 }
802 return (uint16_t)(((FX_DWORD*)found)[1] % 65536 + charcode -
803 *(FX_DWORD*)found);
804 }
805 if (m_pUseMap)
806 return m_pUseMap->CIDFromCharCode(charcode);
807 return 0;
808 }
809 FX_DWORD CID = m_pMapping[charcode];
810 if (!CID && m_pUseMap)
811 return m_pUseMap->CIDFromCharCode(charcode);
812 return (uint16_t)CID;
813 }
814
815 FX_DWORD CPDF_CMap::GetNextChar(const FX_CHAR* pString,
816 int nStrLen,
817 int& offset) const {
818 switch (m_CodingScheme) {
819 case OneByte:
820 return ((uint8_t*)pString)[offset++];
821 case TwoBytes:
822 offset += 2;
823 return ((uint8_t*)pString)[offset - 2] * 256 +
824 ((uint8_t*)pString)[offset - 1];
825 case MixedTwoBytes: {
826 uint8_t byte1 = ((uint8_t*)pString)[offset++];
827 if (!m_pLeadingBytes[byte1]) {
828 return byte1;
829 }
830 uint8_t byte2 = ((uint8_t*)pString)[offset++];
831 return byte1 * 256 + byte2;
832 }
833 case MixedFourBytes: {
834 uint8_t codes[4];
835 int char_size = 1;
836 codes[0] = ((uint8_t*)pString)[offset++];
837 CMap_CodeRange* pRanges = (CMap_CodeRange*)m_pLeadingBytes;
838 while (1) {
839 int ret = CheckCodeRange(codes, char_size, pRanges, m_nCodeRanges);
840 if (ret == 0) {
841 return 0;
842 }
843 if (ret == 2) {
844 FX_DWORD charcode = 0;
845 for (int i = 0; i < char_size; i++) {
846 charcode = (charcode << 8) + codes[i];
847 }
848 return charcode;
849 }
850 if (char_size == 4 || offset == nStrLen) {
851 return 0;
852 }
853 codes[char_size++] = ((uint8_t*)pString)[offset++];
854 }
855 break;
856 }
857 }
858 return 0;
859 }
860 int CPDF_CMap::GetCharSize(FX_DWORD charcode) const {
861 switch (m_CodingScheme) {
862 case OneByte:
863 return 1;
864 case TwoBytes:
865 return 2;
866 case MixedTwoBytes:
867 case MixedFourBytes:
868 if (charcode < 0x100) {
869 return 1;
870 }
871 if (charcode < 0x10000) {
872 return 2;
873 }
874 if (charcode < 0x1000000) {
875 return 3;
876 }
877 return 4;
878 }
879 return 1;
880 }
881 int CPDF_CMap::CountChar(const FX_CHAR* pString, int size) const {
882 switch (m_CodingScheme) {
883 case OneByte:
884 return size;
885 case TwoBytes:
886 return (size + 1) / 2;
887 case MixedTwoBytes: {
888 int count = 0;
889 for (int i = 0; i < size; i++) {
890 count++;
891 if (m_pLeadingBytes[((uint8_t*)pString)[i]]) {
892 i++;
893 }
894 }
895 return count;
896 }
897 case MixedFourBytes: {
898 int count = 0, offset = 0;
899 while (offset < size) {
900 GetNextChar(pString, size, offset);
901 count++;
902 }
903 return count;
904 }
905 }
906 return size;
907 }
908
909 int CPDF_CMap::AppendChar(FX_CHAR* str, FX_DWORD charcode) const {
910 switch (m_CodingScheme) {
911 case OneByte:
912 str[0] = (uint8_t)charcode;
913 return 1;
914 case TwoBytes:
915 str[0] = (uint8_t)(charcode / 256);
916 str[1] = (uint8_t)(charcode % 256);
917 return 2;
918 case MixedTwoBytes:
919 case MixedFourBytes:
920 if (charcode < 0x100) {
921 CMap_CodeRange* pRanges = (CMap_CodeRange*)m_pLeadingBytes;
922 int iSize = GetCharSizeImpl(charcode, pRanges, m_nCodeRanges);
923 if (iSize == 0) {
924 iSize = 1;
925 }
926 if (iSize > 1) {
927 FXSYS_memset(str, 0, sizeof(uint8_t) * iSize);
928 }
929 str[iSize - 1] = (uint8_t)charcode;
930 return iSize;
931 }
932 if (charcode < 0x10000) {
933 str[0] = (uint8_t)(charcode >> 8);
934 str[1] = (uint8_t)charcode;
935 return 2;
936 }
937 if (charcode < 0x1000000) {
938 str[0] = (uint8_t)(charcode >> 16);
939 str[1] = (uint8_t)(charcode >> 8);
940 str[2] = (uint8_t)charcode;
941 return 3;
942 }
943 str[0] = (uint8_t)(charcode >> 24);
944 str[1] = (uint8_t)(charcode >> 16);
945 str[2] = (uint8_t)(charcode >> 8);
946 str[3] = (uint8_t)charcode;
947 return 4;
948 }
949 return 0;
950 }
951 CPDF_CID2UnicodeMap::CPDF_CID2UnicodeMap() {
952 m_EmbeddedCount = 0;
953 }
954 CPDF_CID2UnicodeMap::~CPDF_CID2UnicodeMap() {}
955 FX_BOOL CPDF_CID2UnicodeMap::Initialize() {
956 return TRUE;
957 }
958 FX_BOOL CPDF_CID2UnicodeMap::IsLoaded() {
959 return m_EmbeddedCount != 0;
960 }
961 FX_WCHAR CPDF_CID2UnicodeMap::UnicodeFromCID(uint16_t CID) {
962 if (m_Charset == CIDSET_UNICODE) {
963 return CID;
964 }
965 if (CID < m_EmbeddedCount) {
966 return m_pEmbeddedMap[CID];
967 }
968 return 0;
969 }
970
971 void CPDF_CID2UnicodeMap::Load(CPDF_CMapManager* pMgr,
972 CIDSet charset,
973 FX_BOOL bPromptCJK) {
974 m_Charset = charset;
975 FPDFAPI_LoadCID2UnicodeMap(charset, m_pEmbeddedMap, m_EmbeddedCount);
976 }
977
978 CPDF_CIDFont::CPDF_CIDFont() 206 CPDF_CIDFont::CPDF_CIDFont()
979 : m_pCMap(nullptr), 207 : m_pCMap(nullptr),
980 m_pAllocatedCMap(nullptr), 208 m_pAllocatedCMap(nullptr),
981 m_pCID2UnicodeMap(nullptr), 209 m_pCID2UnicodeMap(nullptr),
982 m_pCIDToGIDMap(nullptr), 210 m_pCIDToGIDMap(nullptr),
983 m_bCIDIsGID(FALSE), 211 m_bCIDIsGID(FALSE),
984 m_pAnsiWidths(nullptr), 212 m_pAnsiWidths(nullptr),
985 m_bAdobeCourierStd(FALSE), 213 m_bAdobeCourierStd(FALSE),
986 m_pTTGSUBTable(nullptr) {} 214 m_pTTGSUBTable(nullptr) {}
987 215
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after
1671 899
1672 const uint8_t* CPDF_CIDFont::GetCIDTransform(uint16_t CID) const { 900 const uint8_t* CPDF_CIDFont::GetCIDTransform(uint16_t CID) const {
1673 if (m_Charset != CIDSET_JAPAN1 || m_pFontFile) 901 if (m_Charset != CIDSET_JAPAN1 || m_pFontFile)
1674 return nullptr; 902 return nullptr;
1675 903
1676 const struct CIDTransform* found = (const struct CIDTransform*)FXSYS_bsearch( 904 const struct CIDTransform* found = (const struct CIDTransform*)FXSYS_bsearch(
1677 &CID, g_Japan1_VertCIDs, FX_ArraySize(g_Japan1_VertCIDs), 905 &CID, g_Japan1_VertCIDs, FX_ArraySize(g_Japan1_VertCIDs),
1678 sizeof(g_Japan1_VertCIDs[0]), CompareCIDTransform); 906 sizeof(g_Japan1_VertCIDs[0]), CompareCIDTransform);
1679 return found ? &found->a : nullptr; 907 return found ? &found->a : nullptr;
1680 } 908 }
OLDNEW
« no previous file with comments | « core/fpdfapi/fpdf_font/cpdf_cidfont.h ('k') | core/fpdfapi/fpdf_font/cpdf_font.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698