1 // Copyright 2016 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "core/fpdfapi/font/cpdf_cidfont.h"
8
9 #include <algorithm>
10 #include <limits>
11 #include <vector>
12
13 #include "core/fpdfapi/cmaps/cmap_int.h"
14 #include "core/fpdfapi/cpdf_modulemgr.h"
15 #include "core/fpdfapi/font/cfx_cttgsubtable.h"
16 #include "core/fpdfapi/font/cpdf_cid2unicodemap.h"
17 #include "core/fpdfapi/font/cpdf_cmap.h"
18 #include "core/fpdfapi/font/cpdf_cmapparser.h"
19 #include "core/fpdfapi/font/cpdf_fontencoding.h"
20 #include "core/fpdfapi/page/cpdf_pagemodule.h"
21 #include "core/fpdfapi/parser/cpdf_array.h"
22 #include "core/fpdfapi/parser/cpdf_dictionary.h"
23 #include "core/fpdfapi/parser/cpdf_stream_acc.h"
24 #include "third_party/base/numerics/safe_math.h"
25 #include "third_party/base/ptr_util.h"
26 #include "third_party/base/stl_util.h"
27
28 namespace {
29
30 const uint16_t g_CharsetCPs[CIDSET_NUM_SETS] = {0, 936, 950, 932, 949, 1200};
31
32 const struct CIDTransform {
33 uint16_t cid;
34 uint8_t a;
35 uint8_t b;
36 uint8_t c;
37 uint8_t d;
38 uint8_t e;
39 uint8_t f;
40 } g_Japan1_VertCIDs[] = {
41 {97, 129, 0, 0, 127, 55, 0}, {7887, 127, 0, 0, 127, 76, 89},
42 {7888, 127, 0, 0, 127, 79, 94}, {7889, 0, 129, 127, 0, 17, 127},
43 {7890, 0, 129, 127, 0, 17, 127}, {7891, 0, 129, 127, 0, 17, 127},
44 {7892, 0, 129, 127, 0, 17, 127}, {7893, 0, 129, 127, 0, 17, 127},
45 {7894, 0, 129, 127, 0, 17, 127}, {7895, 0, 129, 127, 0, 17, 127},
46 {7896, 0, 129, 127, 0, 17, 127}, {7897, 0, 129, 127, 0, 17, 127},
47 {7898, 0, 129, 127, 0, 17, 127}, {7899, 0, 129, 127, 0, 17, 104},
48 {7900, 0, 129, 127, 0, 17, 127}, {7901, 0, 129, 127, 0, 17, 104},
49 {7902, 0, 129, 127, 0, 17, 127}, {7903, 0, 129, 127, 0, 17, 127},
50 {7904, 0, 129, 127, 0, 17, 127}, {7905, 0, 129, 127, 0, 17, 114},
51 {7906, 0, 129, 127, 0, 17, 127}, {7907, 0, 129, 127, 0, 17, 127},
52 {7908, 0, 129, 127, 0, 17, 127}, {7909, 0, 129, 127, 0, 17, 127},
53 {7910, 0, 129, 127, 0, 17, 127}, {7911, 0, 129, 127, 0, 17, 127},
54 {7912, 0, 129, 127, 0, 17, 127}, {7913, 0, 129, 127, 0, 17, 127},
55 {7914, 0, 129, 127, 0, 17, 127}, {7915, 0, 129, 127, 0, 17, 114},
56 {7916, 0, 129, 127, 0, 17, 127}, {7917, 0, 129, 127, 0, 17, 127},
57 {7918, 127, 0, 0, 127, 18, 25}, {7919, 127, 0, 0, 127, 18, 25},
58 {7920, 127, 0, 0, 127, 18, 25}, {7921, 127, 0, 0, 127, 18, 25},
59 {7922, 127, 0, 0, 127, 18, 25}, {7923, 127, 0, 0, 127, 18, 25},
60 {7924, 127, 0, 0, 127, 18, 25}, {7925, 127, 0, 0, 127, 18, 25},
61 {7926, 127, 0, 0, 127, 18, 25}, {7927, 127, 0, 0, 127, 18, 25},
62 {7928, 127, 0, 0, 127, 18, 25}, {7929, 127, 0, 0, 127, 18, 25},
63 {7930, 127, 0, 0, 127, 18, 25}, {7931, 127, 0, 0, 127, 18, 25},
64 {7932, 127, 0, 0, 127, 18, 25}, {7933, 127, 0, 0, 127, 18, 25},
65 {7934, 127, 0, 0, 127, 18, 25}, {7935, 127, 0, 0, 127, 18, 25},
66 {7936, 127, 0, 0, 127, 18, 25}, {7937, 127, 0, 0, 127, 18, 25},
67 {7938, 127, 0, 0, 127, 18, 25}, {7939, 127, 0, 0, 127, 18, 25},
68 {8720, 0, 129, 127, 0, 19, 102}, {8721, 0, 129, 127, 0, 13, 127},
69 {8722, 0, 129, 127, 0, 19, 108}, {8723, 0, 129, 127, 0, 19, 102},
70 {8724, 0, 129, 127, 0, 19, 102}, {8725, 0, 129, 127, 0, 19, 102},
71 {8726, 0, 129, 127, 0, 19, 102}, {8727, 0, 129, 127, 0, 19, 102},
72 {8728, 0, 129, 127, 0, 19, 114}, {8729, 0, 129, 127, 0, 19, 114},
73 {8730, 0, 129, 127, 0, 38, 108}, {8731, 0, 129, 127, 0, 13, 108},
74 {8732, 0, 129, 127, 0, 19, 108}, {8733, 0, 129, 127, 0, 19, 108},
75 {8734, 0, 129, 127, 0, 19, 108}, {8735, 0, 129, 127, 0, 19, 108},
76 {8736, 0, 129, 127, 0, 19, 102}, {8737, 0, 129, 127, 0, 19, 102},
77 {8738, 0, 129, 127, 0, 19, 102}, {8739, 0, 129, 127, 0, 19, 102},
78 {8740, 0, 129, 127, 0, 19, 102}, {8741, 0, 129, 127, 0, 19, 102},
79 {8742, 0, 129, 127, 0, 19, 102}, {8743, 0, 129, 127, 0, 19, 102},
80 {8744, 0, 129, 127, 0, 19, 102}, {8745, 0, 129, 127, 0, 19, 102},
81 {8746, 0, 129, 127, 0, 19, 114}, {8747, 0, 129, 127, 0, 19, 114},
82 {8748, 0, 129, 127, 0, 19, 102}, {8749, 0, 129, 127, 0, 19, 102},
83 {8750, 0, 129, 127, 0, 19, 102}, {8751, 0, 129, 127, 0, 19, 102},
84 {8752, 0, 129, 127, 0, 19, 102}, {8753, 0, 129, 127, 0, 19, 102},
85 {8754, 0, 129, 127, 0, 19, 102}, {8755, 0, 129, 127, 0, 19, 102},
86 {8756, 0, 129, 127, 0, 19, 102}, {8757, 0, 129, 127, 0, 19, 102},
87 {8758, 0, 129, 127, 0, 19, 102}, {8759, 0, 129, 127, 0, 19, 102},
88 {8760, 0, 129, 127, 0, 19, 102}, {8761, 0, 129, 127, 0, 19, 102},
89 {8762, 0, 129, 127, 0, 19, 102}, {8763, 0, 129, 127, 0, 19, 102},
90 {8764, 0, 129, 127, 0, 19, 102}, {8765, 0, 129, 127, 0, 19, 102},
91 {8766, 0, 129, 127, 0, 19, 102}, {8767, 0, 129, 127, 0, 19, 102},
92 {8768, 0, 129, 127, 0, 19, 102}, {8769, 0, 129, 127, 0, 19, 102},
93 {8770, 0, 129, 127, 0, 19, 102}, {8771, 0, 129, 127, 0, 19, 102},
94 {8772, 0, 129, 127, 0, 19, 102}, {8773, 0, 129, 127, 0, 19, 102},
95 {8774, 0, 129, 127, 0, 19, 102}, {8775, 0, 129, 127, 0, 19, 102},
96 {8776, 0, 129, 127, 0, 19, 102}, {8777, 0, 129, 127, 0, 19, 102},
97 {8778, 0, 129, 127, 0, 19, 102}, {8779, 0, 129, 127, 0, 19, 114},
98 {8780, 0, 129, 127, 0, 19, 108}, {8781, 0, 129, 127, 0, 19, 114},
99 {8782, 0, 129, 127, 0, 13, 114}, {8783, 0, 129, 127, 0, 19, 108},
100 {8784, 0, 129, 127, 0, 13, 114}, {8785, 0, 129, 127, 0, 19, 108},
101 {8786, 0, 129, 127, 0, 19, 108}, {8787, 0, 129, 127, 0, 19, 108},
102 {8788, 0, 129, 127, 0, 19, 108}, {8789, 0, 129, 127, 0, 19, 108},
103 {8790, 0, 129, 127, 0, 19, 108}, {8791, 0, 129, 127, 0, 19, 108},
104 {8792, 0, 129, 127, 0, 19, 108}, {8793, 0, 129, 127, 0, 19, 108},
105 {8794, 0, 129, 127, 0, 19, 108}, {8795, 0, 129, 127, 0, 19, 108},
106 {8796, 0, 129, 127, 0, 19, 108}, {8797, 0, 129, 127, 0, 19, 108},
107 {8798, 0, 129, 127, 0, 19, 108}, {8799, 0, 129, 127, 0, 19, 108},
108 {8800, 0, 129, 127, 0, 19, 108}, {8801, 0, 129, 127, 0, 19, 108},
109 {8802, 0, 129, 127, 0, 19, 108}, {8803, 0, 129, 127, 0, 19, 108},
110 {8804, 0, 129, 127, 0, 19, 108}, {8805, 0, 129, 127, 0, 19, 108},
111 {8806, 0, 129, 127, 0, 19, 108}, {8807, 0, 129, 127, 0, 19, 108},
112 {8808, 0, 129, 127, 0, 19, 108}, {8809, 0, 129, 127, 0, 19, 108},
113 {8810, 0, 129, 127, 0, 19, 108}, {8811, 0, 129, 127, 0, 19, 114},
114 {8812, 0, 129, 127, 0, 19, 102}, {8813, 0, 129, 127, 0, 19, 114},
115 {8814, 0, 129, 127, 0, 76, 102}, {8815, 0, 129, 127, 0, 13, 121},
116 {8816, 0, 129, 127, 0, 19, 114}, {8817, 0, 129, 127, 0, 19, 127},
117 {8818, 0, 129, 127, 0, 19, 114}, {8819, 0, 129, 127, 0, 218, 108},
118 };
119
120 // Boundary values to avoid integer overflow when multiplied by 1000.
121 const long kMinCBox = -2147483;
122 const long kMaxCBox = 2147483;
123
GetFontGlobals()124 CPDF_FontGlobals* GetFontGlobals() {
125 return CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
126 }
127
128 #if _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
129
IsValidEmbeddedCharcodeFromUnicodeCharset(CIDSet charset)130 bool IsValidEmbeddedCharcodeFromUnicodeCharset(CIDSet charset) {
131 switch (charset) {
132 case CIDSET_GB1:
133 case CIDSET_CNS1:
134 case CIDSET_JAPAN1:
135 case CIDSET_KOREA1:
136 return true;
137
138 default:
139 return false;
140 }
141 }
142
EmbeddedUnicodeFromCharcode(const FXCMAP_CMap * pEmbedMap,CIDSet charset,uint32_t charcode)143 wchar_t EmbeddedUnicodeFromCharcode(const FXCMAP_CMap* pEmbedMap,
144 CIDSet charset,
145 uint32_t charcode) {
146 if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset))
147 return 0;
148
149 uint16_t cid = FPDFAPI_CIDFromCharCode(pEmbedMap, charcode);
150 if (!cid)
151 return 0;
152
153 const uint16_t* map;
154 uint32_t count;
155 std::tie(count, map) = GetFontGlobals()->GetEmbeddedToUnicode(charset);
156 if (map && cid < count)
157 return map[cid];
158 return 0;
159 }
160
EmbeddedCharcodeFromUnicode(const FXCMAP_CMap * pEmbedMap,CIDSet charset,wchar_t unicode)161 uint32_t EmbeddedCharcodeFromUnicode(const FXCMAP_CMap* pEmbedMap,
162 CIDSet charset,
163 wchar_t unicode) {
164 if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset))
165 return 0;
166
167 const uint16_t* map;
168 uint32_t count;
169 std::tie(count, map) = GetFontGlobals()->GetEmbeddedToUnicode(charset);
170 if (!map)
171 return 0;
172
173 for (uint32_t i = 0; i < count; ++i) {
174 if (map[i] == unicode) {
175 uint32_t charCode = FPDFAPI_CharCodeFromCID(pEmbedMap, i);
176 if (charCode)
177 return charCode;
178 }
179 }
180 return 0;
181 }
182
183 #endif // _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
184
FT_UseCIDCharmap(FXFT_Face face,int coding)185 void FT_UseCIDCharmap(FXFT_Face face, int coding) {
186 int encoding;
187 switch (coding) {
188 case CIDCODING_GB:
189 encoding = FXFT_ENCODING_GB2312;
190 break;
191 case CIDCODING_BIG5:
192 encoding = FXFT_ENCODING_BIG5;
193 break;
194 case CIDCODING_JIS:
195 encoding = FXFT_ENCODING_SJIS;
196 break;
197 case CIDCODING_KOREA:
198 encoding = FXFT_ENCODING_JOHAB;
199 break;
200 default:
201 encoding = FXFT_ENCODING_UNICODE;
202 }
203 int err = FXFT_Select_Charmap(face, encoding);
204 if (err)
205 err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE);
206 if (err && FXFT_Get_Face_Charmaps(face))
207 FXFT_Set_Charmap(face, *FXFT_Get_Face_Charmaps(face));
208 }
209
IsMetricForCID(const uint32_t * pEntry,uint16_t CID)210 bool IsMetricForCID(const uint32_t* pEntry, uint16_t CID) {
211 return pEntry[0] <= CID && pEntry[1] >= CID;
212 }
213
214 } // namespace
215
CPDF_CIDFont()216 CPDF_CIDFont::CPDF_CIDFont()
217 : m_pCID2UnicodeMap(nullptr),
218 m_bCIDIsGID(false),
219 m_bAnsiWidthsFixed(false),
220 m_bAdobeCourierStd(false) {
221 for (size_t i = 0; i < FX_ArraySize(m_CharBBox); ++i)
222 m_CharBBox[i] = FX_RECT(-1, -1, -1, -1);
223 }
224
~CPDF_CIDFont()225 CPDF_CIDFont::~CPDF_CIDFont() {}
226
IsCIDFont() const227 bool CPDF_CIDFont::IsCIDFont() const {
228 return true;
229 }
230
AsCIDFont() const231 const CPDF_CIDFont* CPDF_CIDFont::AsCIDFont() const {
232 return this;
233 }
234
AsCIDFont()235 CPDF_CIDFont* CPDF_CIDFont::AsCIDFont() {
236 return this;
237 }
238
CIDFromCharCode(uint32_t charcode) const239 uint16_t CPDF_CIDFont::CIDFromCharCode(uint32_t charcode) const {
240 return m_pCMap ? m_pCMap->CIDFromCharCode(charcode)
241 : static_cast<uint16_t>(charcode);
242 }
243
IsVertWriting() const244 bool CPDF_CIDFont::IsVertWriting() const {
245 return m_pCMap && m_pCMap->IsVertWriting();
246 }
247
UnicodeFromCharCode(uint32_t charcode) const248 WideString CPDF_CIDFont::UnicodeFromCharCode(uint32_t charcode) const {
249 WideString str = CPDF_Font::UnicodeFromCharCode(charcode);
250 if (!str.IsEmpty())
251 return str;
252 wchar_t ret = GetUnicodeFromCharCode(charcode);
253 return ret ? ret : WideString();
254 }
255
GetUnicodeFromCharCode(uint32_t charcode) const256 wchar_t CPDF_CIDFont::GetUnicodeFromCharCode(uint32_t charcode) const {
257 switch (m_pCMap->GetCoding()) {
258 case CIDCODING_UCS2:
259 case CIDCODING_UTF16:
260 return static_cast<wchar_t>(charcode);
261 case CIDCODING_CID:
262 if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded())
263 return 0;
264 return m_pCID2UnicodeMap->UnicodeFromCID(static_cast<uint16_t>(charcode));
265 }
266 if (m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded() && m_pCMap->IsLoaded())
267 return m_pCID2UnicodeMap->UnicodeFromCID(CIDFromCharCode(charcode));
268
269 #if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
270 wchar_t unicode;
271 int charsize = 1;
272 if (charcode > 255) {
273 charcode = (charcode % 256) * 256 + (charcode / 256);
274 charsize = 2;
275 }
276 int ret = FXSYS_MultiByteToWideChar(g_CharsetCPs[m_pCMap->GetCoding()], 0,
277 reinterpret_cast<const char*>(&charcode),
278 charsize, &unicode, 1);
279 return ret == 1 ? unicode : 0;
280 #else
281 if (!m_pCMap->GetEmbedMap())
282 return 0;
283 return EmbeddedUnicodeFromCharcode(m_pCMap->GetEmbedMap(),
284 m_pCMap->GetCharset(), charcode);
285 #endif
286 }
287
CharCodeFromUnicode(wchar_t unicode) const288 uint32_t CPDF_CIDFont::CharCodeFromUnicode(wchar_t unicode) const {
289 uint32_t charcode = CPDF_Font::CharCodeFromUnicode(unicode);
290 if (charcode)
291 return charcode;
292 switch (m_pCMap->GetCoding()) {
293 case CIDCODING_UNKNOWN:
294 return 0;
295 case CIDCODING_UCS2:
296 case CIDCODING_UTF16:
297 return unicode;
298 case CIDCODING_CID: {
299 if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded())
300 return 0;
301 uint32_t CID = 0;
302 while (CID < 65536) {
303 wchar_t this_unicode =
304 m_pCID2UnicodeMap->UnicodeFromCID(static_cast<uint16_t>(CID));
305 if (this_unicode == unicode)
306 return CID;
307 CID++;
308 }
309 break;
310 }
311 }
312
313 if (unicode < 0x80)
314 return static_cast<uint32_t>(unicode);
315 if (m_pCMap->GetCoding() == CIDCODING_CID)
316 return 0;
317 #if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
318 uint8_t buffer[32];
319 int ret = FXSYS_WideCharToMultiByte(
320 g_CharsetCPs[m_pCMap->GetCoding()], 0, &unicode, 1,
321 reinterpret_cast<char*>(buffer), 4, nullptr, nullptr);
322 if (ret == 1)
323 return buffer[0];
324 if (ret == 2)
325 return buffer[0] * 256 + buffer[1];
326 #else
327 if (m_pCMap->GetEmbedMap()) {
328 return EmbeddedCharcodeFromUnicode(m_pCMap->GetEmbedMap(),
329 m_pCMap->GetCharset(), unicode);
330 }
331 #endif
332 return 0;
333 }
334
Load()335 bool CPDF_CIDFont::Load() {
336 if (m_pFontDict->GetStringFor("Subtype") == "TrueType") {
337 LoadGB2312();
338 return true;
339 }
340
341 CPDF_Array* pFonts = m_pFontDict->GetArrayFor("DescendantFonts");
342 if (!pFonts || pFonts->GetCount() != 1)
343 return false;
344
345 CPDF_Dictionary* pCIDFontDict = pFonts->GetDictAt(0);
346 if (!pCIDFontDict)
347 return false;
348
349 m_BaseFont = pCIDFontDict->GetStringFor("BaseFont");
350 if ((m_BaseFont.Compare("CourierStd") == 0 ||
351 m_BaseFont.Compare("CourierStd-Bold") == 0 ||
352 m_BaseFont.Compare("CourierStd-BoldOblique") == 0 ||
353 m_BaseFont.Compare("CourierStd-Oblique") == 0) &&
354 !IsEmbedded()) {
355 m_bAdobeCourierStd = true;
356 }
357 CPDF_Dictionary* pFontDesc = pCIDFontDict->GetDictFor("FontDescriptor");
358 if (pFontDesc)
359 LoadFontDescriptor(pFontDesc);
360
361 CPDF_Object* pEncoding = m_pFontDict->GetDirectObjectFor("Encoding");
362 if (!pEncoding)
363 return false;
364
365 ByteString subtype = pCIDFontDict->GetStringFor("Subtype");
366 m_bType1 = (subtype == "CIDFontType0");
367
368 CPDF_CMapManager* manager = GetFontGlobals()->GetCMapManager();
369 if (pEncoding->IsName()) {
370 ByteString cmap = pEncoding->GetString();
371 bool bPromptCJK = m_pFontFile && m_bType1;
372 m_pCMap = manager->GetPredefinedCMap(cmap, bPromptCJK);
373 if (!m_pCMap)
374 return false;
375 } else if (CPDF_Stream* pStream = pEncoding->AsStream()) {
376 auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
377 pAcc->LoadAllDataFiltered();
378 m_pCMap = pdfium::MakeRetain<CPDF_CMap>();
379 m_pCMap->LoadEmbedded(pAcc->GetData(), pAcc->GetSize());
380 } else {
381 return false;
382 }
383
384 m_Charset = m_pCMap->GetCharset();
385 if (m_Charset == CIDSET_UNKNOWN) {
386 CPDF_Dictionary* pCIDInfo = pCIDFontDict->GetDictFor("CIDSystemInfo");
387 if (pCIDInfo) {
388 m_Charset = CPDF_CMapParser::CharsetFromOrdering(
389 pCIDInfo->GetStringFor("Ordering").AsStringView());
390 }
391 }
392 if (m_Charset != CIDSET_UNKNOWN) {
393 bool bPromptCJK = !m_pFontFile && (m_pCMap->GetCoding() == CIDCODING_CID ||
394 pCIDFontDict->KeyExist("W"));
395 m_pCID2UnicodeMap = manager->GetCID2UnicodeMap(m_Charset, bPromptCJK);
396 }
397 if (m_Font.GetFace()) {
398 if (m_bType1)
399 FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE);
400 else
401 FT_UseCIDCharmap(m_Font.GetFace(), m_pCMap->GetCoding());
402 }
403 m_DefaultWidth = pCIDFontDict->GetIntegerFor("DW", 1000);
404 CPDF_Array* pWidthArray = pCIDFontDict->GetArrayFor("W");
405 if (pWidthArray)
406 LoadMetricsArray(pWidthArray, &m_WidthList, 1);
407 if (!IsEmbedded())
408 LoadSubstFont();
409
410 if (m_pFontFile) {
411 CPDF_Object* pmap = pCIDFontDict->GetDirectObjectFor("CIDToGIDMap");
412 if (pmap) {
413 if (CPDF_Stream* pStream = pmap->AsStream()) {
414 m_pStreamAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
415 m_pStreamAcc->LoadAllDataFiltered();
416 } else if (pmap->GetString() == "Identity") {
417 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
418 if (m_pFontFile)
419 m_bCIDIsGID = true;
420 #else
421 m_bCIDIsGID = true;
422 #endif
423 }
424 }
425 }
426
427 CheckFontMetrics();
428 if (IsVertWriting()) {
429 pWidthArray = pCIDFontDict->GetArrayFor("W2");
430 if (pWidthArray)
431 LoadMetricsArray(pWidthArray, &m_VertMetrics, 3);
432 CPDF_Array* pDefaultArray = pCIDFontDict->GetArrayFor("DW2");
433 if (pDefaultArray) {
434 m_DefaultVY = pDefaultArray->GetIntegerAt(0);
435 m_DefaultW1 = pDefaultArray->GetIntegerAt(1);
436 } else {
437 m_DefaultVY = 880;
438 m_DefaultW1 = -1000;
439 }
440 }
441 return true;
442 }
443
GetCharBBox(uint32_t charcode)444 FX_RECT CPDF_CIDFont::GetCharBBox(uint32_t charcode) {
445 if (charcode < 256 && m_CharBBox[charcode].right != -1)
446 return m_CharBBox[charcode];
447
448 FX_RECT rect;
449 bool bVert = false;
450 int glyph_index = GlyphFromCharCode(charcode, &bVert);
451 FXFT_Face face = m_Font.GetFace();
452 if (face) {
453 if (FXFT_Is_Face_Tricky(face)) {
454 int err = FXFT_Load_Glyph(face, glyph_index,
455 FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
456 if (!err) {
457 FXFT_Glyph glyph;
458 err = FXFT_Get_Glyph(((FXFT_Face)face)->glyph, &glyph);
459 if (!err) {
460 FXFT_BBox cbox;
461 FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox);
462 cbox.xMin = pdfium::clamp(cbox.xMin, kMinCBox, kMaxCBox);
463 cbox.xMax = pdfium::clamp(cbox.xMax, kMinCBox, kMaxCBox);
464 cbox.yMin = pdfium::clamp(cbox.yMin, kMinCBox, kMaxCBox);
465 cbox.yMax = pdfium::clamp(cbox.yMax, kMinCBox, kMaxCBox);
466 int pixel_size_x = ((FXFT_Face)face)->size->metrics.x_ppem;
467 int pixel_size_y = ((FXFT_Face)face)->size->metrics.y_ppem;
468 if (pixel_size_x == 0 || pixel_size_y == 0) {
469 rect = FX_RECT(cbox.xMin, cbox.yMax, cbox.xMax, cbox.yMin);
470 } else {
471 rect = FX_RECT(cbox.xMin * 1000 / pixel_size_x,
472 cbox.yMax * 1000 / pixel_size_y,
473 cbox.xMax * 1000 / pixel_size_x,
474 cbox.yMin * 1000 / pixel_size_y);
475 }
476 rect.top = std::min(rect.top,
477 static_cast<int>(FXFT_Get_Face_Ascender(face)));
478 rect.bottom = std::max(
479 rect.bottom, static_cast<int>(FXFT_Get_Face_Descender(face)));
480 FXFT_Done_Glyph(glyph);
481 }
482 }
483 } else {
484 int err = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_NO_SCALE);
485 if (err == 0) {
486 rect = FX_RECT(TT2PDF(FXFT_Get_Glyph_HoriBearingX(face), face),
487 TT2PDF(FXFT_Get_Glyph_HoriBearingY(face), face),
488 TT2PDF(FXFT_Get_Glyph_HoriBearingX(face) +
489 FXFT_Get_Glyph_Width(face),
490 face),
491 TT2PDF(FXFT_Get_Glyph_HoriBearingY(face) -
492 FXFT_Get_Glyph_Height(face),
493 face));
494 rect.top += rect.top / 64;
495 }
496 }
497 }
498 if (!m_pFontFile && m_Charset == CIDSET_JAPAN1) {
499 uint16_t CID = CIDFromCharCode(charcode);
500 const uint8_t* pTransform = GetCIDTransform(CID);
501 if (pTransform && !bVert) {
502 CFX_Matrix matrix(CIDTransformToFloat(pTransform[0]),
503 CIDTransformToFloat(pTransform[1]),
504 CIDTransformToFloat(pTransform[2]),
505 CIDTransformToFloat(pTransform[3]),
506 CIDTransformToFloat(pTransform[4]) * 1000,
507 CIDTransformToFloat(pTransform[5]) * 1000);
508 rect = matrix.TransformRect(CFX_FloatRect(rect)).GetOuterRect();
509 }
510 }
511 if (charcode < 256)
512 m_CharBBox[charcode] = rect;
513
514 return rect;
515 }
516
GetCharWidthF(uint32_t charcode)517 int CPDF_CIDFont::GetCharWidthF(uint32_t charcode) {
518 if (charcode < 0x80 && m_bAnsiWidthsFixed)
519 return (charcode >= 32 && charcode < 127) ? 500 : 0;
520
521 uint16_t cid = CIDFromCharCode(charcode);
522 size_t size = m_WidthList.size();
523 const uint32_t* pList = m_WidthList.data();
524 for (size_t i = 0; i < size; i += 3) {
525 const uint32_t* pEntry = pList + i;
526 if (IsMetricForCID(pEntry, cid))
527 return static_cast<int>(pEntry[2]);
528 }
529 return m_DefaultWidth;
530 }
531
GetVertWidth(uint16_t CID) const532 short CPDF_CIDFont::GetVertWidth(uint16_t CID) const {
533 size_t vertsize = m_VertMetrics.size() / 5;
534 if (vertsize) {
535 const uint32_t* pTable = m_VertMetrics.data();
536 for (size_t i = 0; i < vertsize; i++) {
537 const uint32_t* pEntry = pTable + (i * 5);
538 if (IsMetricForCID(pEntry, CID))
539 return static_cast<short>(pEntry[2]);
540 }
541 }
542 return m_DefaultW1;
543 }
544
GetVertOrigin(uint16_t CID,short & vx,short & vy) const545 void CPDF_CIDFont::GetVertOrigin(uint16_t CID, short& vx, short& vy) const {
546 size_t vertsize = m_VertMetrics.size() / 5;
547 if (vertsize) {
548 const uint32_t* pTable = m_VertMetrics.data();
549 for (size_t i = 0; i < vertsize; i++) {
550 const uint32_t* pEntry = pTable + (i * 5);
551 if (IsMetricForCID(pEntry, CID)) {
552 vx = static_cast<short>(pEntry[3]);
553 vy = static_cast<short>(pEntry[4]);
554 return;
555 }
556 }
557 }
558 uint32_t dwWidth = m_DefaultWidth;
559 size_t size = m_WidthList.size();
560 const uint32_t* pList = m_WidthList.data();
561 for (size_t i = 0; i < size; i += 3) {
562 const uint32_t* pEntry = pList + i;
563 if (IsMetricForCID(pEntry, CID)) {
564 dwWidth = pEntry[2];
565 break;
566 }
567 }
568 vx = static_cast<short>(dwWidth) / 2;
569 vy = m_DefaultVY;
570 }
571
GetGlyphIndex(uint32_t unicode,bool * pVertGlyph)572 int CPDF_CIDFont::GetGlyphIndex(uint32_t unicode, bool* pVertGlyph) {
573 if (pVertGlyph)
574 *pVertGlyph = false;
575
576 FXFT_Face face = m_Font.GetFace();
577 int index = FXFT_Get_Char_Index(face, unicode);
578 if (unicode == 0x2502)
579 return index;
580
581 if (!index || !IsVertWriting())
582 return index;
583
584 if (m_pTTGSUBTable)
585 return GetVerticalGlyph(index, pVertGlyph);
586
587 if (!m_Font.GetSubData()) {
588 unsigned long length = 0;
589 int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0,
590 nullptr, &length);
591 if (!error)
592 m_Font.SetSubData(FX_Alloc(uint8_t, length));
593 }
594 int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0,
595 m_Font.GetSubData(), nullptr);
596 if (error || !m_Font.GetSubData())
597 return index;
598
599 m_pTTGSUBTable = pdfium::MakeUnique<CFX_CTTGSUBTable>();
600 m_pTTGSUBTable->LoadGSUBTable((FT_Bytes)m_Font.GetSubData());
601 return GetVerticalGlyph(index, pVertGlyph);
602 }
603
GetVerticalGlyph(int index,bool * pVertGlyph)604 int CPDF_CIDFont::GetVerticalGlyph(int index, bool* pVertGlyph) {
605 uint32_t vindex = 0;
606 m_pTTGSUBTable->GetVerticalGlyph(index, &vindex);
607 if (!vindex)
608 return index;
609
610 index = vindex;
611 if (pVertGlyph)
612 *pVertGlyph = true;
613 return index;
614 }
615
GlyphFromCharCode(uint32_t charcode,bool * pVertGlyph)616 int CPDF_CIDFont::GlyphFromCharCode(uint32_t charcode, bool* pVertGlyph) {
617 if (pVertGlyph)
618 *pVertGlyph = false;
619
620 if (!m_pFontFile && !m_pStreamAcc) {
621 uint16_t cid = CIDFromCharCode(charcode);
622 wchar_t unicode = 0;
623 if (m_bCIDIsGID) {
624 #if _FX_PLATFORM_ != _FX_PLATFORM_APPLE_
625 return cid;
626 #else
627 if (FontStyleIsSymbolic(m_Flags))
628 return cid;
629
630 WideString uni_str = UnicodeFromCharCode(charcode);
631 if (uni_str.IsEmpty())
632 return cid;
633
634 unicode = uni_str[0];
635 #endif
636 } else {
637 if (cid && m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded())
638 unicode = m_pCID2UnicodeMap->UnicodeFromCID(cid);
639 if (unicode == 0)
640 unicode = GetUnicodeFromCharCode(charcode);
641 if (unicode == 0) {
642 WideString unicode_str = UnicodeFromCharCode(charcode);
643 if (!unicode_str.IsEmpty())
644 unicode = unicode_str[0];
645 }
646 }
647 FXFT_Face face = m_Font.GetFace();
648 if (unicode == 0) {
649 if (!m_bAdobeCourierStd)
650 return charcode ? static_cast<int>(charcode) : -1;
651
652 charcode += 31;
653 bool bMSUnicode = FT_UseTTCharmap(face, 3, 1);
654 bool bMacRoman = !bMSUnicode && FT_UseTTCharmap(face, 1, 0);
655 int iBaseEncoding = PDFFONT_ENCODING_STANDARD;
656 if (bMSUnicode)
657 iBaseEncoding = PDFFONT_ENCODING_WINANSI;
658 else if (bMacRoman)
659 iBaseEncoding = PDFFONT_ENCODING_MACROMAN;
660 const char* name =
661 GetAdobeCharName(iBaseEncoding, std::vector<ByteString>(), charcode);
662 if (!name)
663 return charcode ? static_cast<int>(charcode) : -1;
664
665 int index = 0;
666 uint16_t name_unicode = PDF_UnicodeFromAdobeName(name);
667 if (!name_unicode)
668 return charcode ? static_cast<int>(charcode) : -1;
669
670 if (iBaseEncoding == PDFFONT_ENCODING_STANDARD)
671 return FXFT_Get_Char_Index(face, name_unicode);
672
673 if (iBaseEncoding == PDFFONT_ENCODING_WINANSI) {
674 index = FXFT_Get_Char_Index(face, name_unicode);
675 } else {
676 ASSERT(iBaseEncoding == PDFFONT_ENCODING_MACROMAN);
677 uint32_t maccode =
678 FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, name_unicode);
679 index = maccode ? FXFT_Get_Char_Index(face, maccode)
680 : FXFT_Get_Name_Index(face, const_cast<char*>(name));
681 }
682 if (index == 0 || index == 0xffff)
683 return charcode ? static_cast<int>(charcode) : -1;
684 return index;
685 }
686 if (m_Charset == CIDSET_JAPAN1) {
687 if (unicode == '\\') {
688 unicode = '/';
689 #if _FX_PLATFORM_ != _FX_PLATFORM_APPLE_
690 } else if (unicode == 0xa5) {
691 unicode = 0x5c;
692 #endif
693 }
694 }
695 if (!face)
696 return unicode;
697
698 int err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE);
699 if (err) {
700 int i;
701 for (i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) {
702 uint32_t ret = FT_CharCodeFromUnicode(
703 FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i]),
704 static_cast<wchar_t>(charcode));
705 if (ret == 0)
706 continue;
707 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]);
708 unicode = static_cast<wchar_t>(ret);
709 break;
710 }
711 if (i == FXFT_Get_Face_CharmapCount(face) && i) {
712 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);
713 unicode = static_cast<wchar_t>(charcode);
714 }
715 }
716 if (FXFT_Get_Face_Charmap(face)) {
717 int index = GetGlyphIndex(unicode, pVertGlyph);
718 return index != 0 ? index : -1;
719 }
720 return unicode;
721 }
722
723 if (!m_Font.GetFace())
724 return -1;
725
726 uint16_t cid = CIDFromCharCode(charcode);
727 if (!m_pStreamAcc) {
728 if (m_bType1)
729 return cid;
730 if (m_pFontFile && m_pCMap->IsDirectCharcodeToCIDTableIsEmpty())
731 return cid;
732 if (m_pCMap->GetCoding() == CIDCODING_UNKNOWN ||
733 !FXFT_Get_Face_Charmap(m_Font.GetFace())) {
734 return cid;
735 }
736 if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmap(m_Font.GetFace())) ==
737 FXFT_ENCODING_UNICODE) {
738 WideString unicode_str = UnicodeFromCharCode(charcode);
739 if (unicode_str.IsEmpty())
740 return -1;
741
742 charcode = unicode_str[0];
743 }
744 return GetGlyphIndex(charcode, pVertGlyph);
745 }
746 uint32_t byte_pos = cid * 2;
747 if (byte_pos + 2 > m_pStreamAcc->GetSize())
748 return -1;
749
750 const uint8_t* pdata = m_pStreamAcc->GetData() + byte_pos;
751 return pdata[0] * 256 + pdata[1];
752 }
753
GetNextChar(const char * pString,int nStrLen,int & offset) const754 uint32_t CPDF_CIDFont::GetNextChar(const char* pString,
755 int nStrLen,
756 int& offset) const {
757 return m_pCMap->GetNextChar(pString, nStrLen, offset);
758 }
759
GetCharSize(uint32_t charcode) const760 int CPDF_CIDFont::GetCharSize(uint32_t charcode) const {
761 return m_pCMap->GetCharSize(charcode);
762 }
763
CountChar(const char * pString,int size) const764 int CPDF_CIDFont::CountChar(const char* pString, int size) const {
765 return m_pCMap->CountChar(pString, size);
766 }
767
AppendChar(char * str,uint32_t charcode) const768 int CPDF_CIDFont::AppendChar(char* str, uint32_t charcode) const {
769 return m_pCMap->AppendChar(str, charcode);
770 }
771
IsUnicodeCompatible() const772 bool CPDF_CIDFont::IsUnicodeCompatible() const {
773 if (m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded() && m_pCMap->IsLoaded())
774 return true;
775 return m_pCMap->GetCoding() != CIDCODING_UNKNOWN;
776 }
777
LoadSubstFont()778 void CPDF_CIDFont::LoadSubstFont() {
779 pdfium::base::CheckedNumeric<int> safeStemV(m_StemV);
780 safeStemV *= 5;
781 m_Font.LoadSubst(m_BaseFont, !m_bType1, m_Flags,
782 safeStemV.ValueOrDefault(FXFONT_FW_NORMAL), m_ItalicAngle,
783 g_CharsetCPs[m_Charset], IsVertWriting());
784 }
785
LoadMetricsArray(CPDF_Array * pArray,std::vector<uint32_t> * result,int nElements)786 void CPDF_CIDFont::LoadMetricsArray(CPDF_Array* pArray,
787 std::vector<uint32_t>* result,
788 int nElements) {
789 int width_status = 0;
790 int iCurElement = 0;
791 uint32_t first_code = 0;
792 uint32_t last_code = 0;
793 for (size_t i = 0; i < pArray->GetCount(); i++) {
794 CPDF_Object* pObj = pArray->GetDirectObjectAt(i);
795 if (!pObj)
796 continue;
797
798 if (CPDF_Array* pObjArray = pObj->AsArray()) {
799 if (width_status != 1)
800 return;
801 if (first_code >
802 std::numeric_limits<uint32_t>::max() - pObjArray->GetCount()) {
803 width_status = 0;
804 continue;
805 }
806
807 for (size_t j = 0; j < pObjArray->GetCount(); j += nElements) {
808 result->push_back(first_code);
809 result->push_back(first_code);
810 for (int k = 0; k < nElements; k++)
811 result->push_back(pObjArray->GetIntegerAt(j + k));
812 first_code++;
813 }
814 width_status = 0;
815 } else {
816 if (width_status == 0) {
817 first_code = pObj->GetInteger();
818 width_status = 1;
819 } else if (width_status == 1) {
820 last_code = pObj->GetInteger();
821 width_status = 2;
822 iCurElement = 0;
823 } else {
824 if (!iCurElement) {
825 result->push_back(first_code);
826 result->push_back(last_code);
827 }
828 result->push_back(pObj->GetInteger());
829 iCurElement++;
830 if (iCurElement == nElements)
831 width_status = 0;
832 }
833 }
834 }
835 }
836
837 // static
CIDTransformToFloat(uint8_t ch)838 float CPDF_CIDFont::CIDTransformToFloat(uint8_t ch) {
839 return (ch < 128 ? ch : ch - 255) * (1.0f / 127);
840 }
841
LoadGB2312()842 void CPDF_CIDFont::LoadGB2312() {
843 m_BaseFont = m_pFontDict->GetStringFor("BaseFont");
844 CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictFor("FontDescriptor");
845 if (pFontDesc)
846 LoadFontDescriptor(pFontDesc);
847
848 m_Charset = CIDSET_GB1;
849 m_bType1 = false;
850
851 CPDF_CMapManager* manager = GetFontGlobals()->GetCMapManager();
852 m_pCMap = manager->GetPredefinedCMap("GBK-EUC-H", false);
853 m_pCID2UnicodeMap = manager->GetCID2UnicodeMap(m_Charset, false);
854 if (!IsEmbedded())
855 LoadSubstFont();
856
857 CheckFontMetrics();
858 m_DefaultWidth = 1000;
859 m_bAnsiWidthsFixed = true;
860 }
861
GetCIDTransform(uint16_t CID) const862 const uint8_t* CPDF_CIDFont::GetCIDTransform(uint16_t CID) const {
863 if (m_Charset != CIDSET_JAPAN1 || m_pFontFile)
864 return nullptr;
865
866 const auto* pEnd = g_Japan1_VertCIDs + FX_ArraySize(g_Japan1_VertCIDs);
867 const auto* pTransform = std::lower_bound(
868 g_Japan1_VertCIDs, pEnd, CID,
869 [](const CIDTransform& entry, uint16_t cid) { return entry.cid < cid; });
870 return (pTransform < pEnd && CID == pTransform->cid) ? &pTransform->a
871 : nullptr;
872 }
873