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