1 // Copyright 2014 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 "../../../include/fpdfapi/fpdf_module.h" 8 #include "../../../include/fpdfapi/fpdf_page.h" 9 #include "font_int.h" 10 #include "../fpdf_cmaps/cmap_int.h" 11 #include "../../../include/fxge/fx_ge.h" 12 #include "../../../include/fxge/fx_freetype.h" 13 extern FX_DWORD FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode); 14 extern FX_LPVOID FXFC_LoadPackage(FX_LPCSTR name); 15 extern FX_BOOL FXFC_LoadFile(FX_LPVOID pPackage, FX_LPCSTR name, FX_LPBYTE& pBuffer, FX_DWORD& size); 16 extern void FXFC_ClosePackage(FX_LPVOID pPackage); 17 extern short TT2PDF(int m, FXFT_Face face); 18 extern FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id); 19 extern FX_LPCSTR GetAdobeCharName(int iBaseEncoding, const CFX_ByteString* pCharNames, int charcode); 20 CPDF_CMapManager::CPDF_CMapManager() 21 { 22 #ifndef _FPDFAPI_MINI_ 23 m_bPrompted = FALSE; 24 m_pPackage = NULL; 25 #endif 26 FXSYS_memset32(m_CID2UnicodeMaps, 0, sizeof m_CID2UnicodeMaps); 27 } 28 CPDF_CMapManager::~CPDF_CMapManager() 29 { 30 DropAll(FALSE); 31 #ifndef _FPDFAPI_MINI_ 32 if (m_pPackage) { 33 FXFC_ClosePackage(m_pPackage); 34 } 35 #endif 36 } 37 #ifndef _FPDFAPI_MINI_ 38 FX_LPVOID CPDF_CMapManager::GetPackage(FX_BOOL bPrompt) 39 { 40 #ifndef FOXIT_CHROME_BUILD 41 if (m_pPackage == NULL) { 42 CFX_ByteString filename = CPDF_ModuleMgr::Get()->GetModuleFilePath(ADDIN_NAME_CJK, "FPDFCJK.BIN"); 43 m_pPackage = FXFC_LoadPackage(filename); 44 if (bPrompt && m_pPackage == NULL && !m_bPrompted) { 45 m_bPrompted = TRUE; 46 if (!CPDF_ModuleMgr::Get()->DownloadModule(ADDIN_NAME_CJK)) { 47 return NULL; 48 } 49 m_pPackage = FXFC_LoadPackage(filename); 50 } 51 } 52 #endif 53 return m_pPackage; 54 } 55 #endif 56 CPDF_CMap* CPDF_CMapManager::GetPredefinedCMap(const CFX_ByteString& name, FX_BOOL bPromptCJK) 57 { 58 CPDF_CMap* pCMap; 59 if (m_CMaps.Lookup(name, (FX_LPVOID&)pCMap)) { 60 return pCMap; 61 } 62 pCMap = LoadPredefinedCMap(name, bPromptCJK); 63 if (name.IsEmpty()) { 64 return pCMap; 65 } 66 m_CMaps.SetAt(name, pCMap); 67 return pCMap; 68 } 69 CPDF_CMap* CPDF_CMapManager::LoadPredefinedCMap(const CFX_ByteString& name, FX_BOOL bPromptCJK) 70 { 71 CPDF_CMap* pCMap = FX_NEW CPDF_CMap; 72 FX_LPCSTR pname = name; 73 if (*pname == '/') { 74 pname ++; 75 } 76 pCMap->LoadPredefined(this, pname, bPromptCJK); 77 return pCMap; 78 } 79 const FX_LPCSTR g_CharsetNames[] = {NULL, "GB1", "CNS1", "Japan1", "Korea1", "UCS", NULL}; 80 const int g_CharsetCPs[] = {0, 936, 950, 932, 949, 1200, 0}; 81 int _CharsetFromOrdering(const CFX_ByteString& Ordering) 82 { 83 int charset = 1; 84 while (g_CharsetNames[charset] && Ordering != CFX_ByteStringC(g_CharsetNames[charset])) { 85 charset ++; 86 } 87 if (g_CharsetNames[charset] == NULL) { 88 return CIDSET_UNKNOWN; 89 } 90 return charset; 91 } 92 void CPDF_CMapManager::ReloadAll() 93 { 94 DropAll(TRUE); 95 } 96 void CPDF_CMapManager::DropAll(FX_BOOL bReload) 97 { 98 FX_POSITION pos = m_CMaps.GetStartPosition(); 99 while (pos) { 100 CFX_ByteString name; 101 CPDF_CMap* pCMap; 102 m_CMaps.GetNextAssoc(pos, name, (FX_LPVOID&)pCMap); 103 if (pCMap == NULL) { 104 continue; 105 } 106 if (bReload) { 107 pCMap->LoadPredefined(this, name, FALSE); 108 } else { 109 delete pCMap; 110 } 111 } 112 for (int i = 0; i < sizeof m_CID2UnicodeMaps / sizeof(CPDF_CID2UnicodeMap*); i ++) { 113 CPDF_CID2UnicodeMap* pMap = m_CID2UnicodeMaps[i]; 114 if (pMap == NULL) { 115 continue; 116 } 117 if (bReload) { 118 pMap->Load(this, i, FALSE); 119 } else { 120 delete pMap; 121 } 122 } 123 } 124 CPDF_CID2UnicodeMap* CPDF_CMapManager::GetCID2UnicodeMap(int charset, FX_BOOL bPromptCJK) 125 { 126 if (m_CID2UnicodeMaps[charset] == NULL) { 127 m_CID2UnicodeMaps[charset] = LoadCID2UnicodeMap(charset, bPromptCJK); 128 } 129 return m_CID2UnicodeMaps[charset]; 130 } 131 CPDF_CID2UnicodeMap* CPDF_CMapManager::LoadCID2UnicodeMap(int charset, FX_BOOL bPromptCJK) 132 { 133 CPDF_CID2UnicodeMap* pMap = FX_NEW CPDF_CID2UnicodeMap(); 134 if (!pMap->Initialize()) { 135 delete pMap; 136 return NULL; 137 } 138 pMap->Load(this, charset, bPromptCJK); 139 return pMap; 140 } 141 CPDF_CMapParser::CPDF_CMapParser() 142 { 143 m_pCMap = NULL; 144 m_Status = 0; 145 m_CodeSeq = 0; 146 } 147 FX_BOOL CPDF_CMapParser::Initialize(CPDF_CMap* pCMap) 148 { 149 m_pCMap = pCMap; 150 m_Status = 0; 151 m_CodeSeq = 0; 152 m_AddMaps.EstimateSize(0, 10240); 153 return TRUE; 154 } 155 static FX_DWORD CMap_GetCode(FX_BSTR word) 156 { 157 int num = 0; 158 if (word.GetAt(0) == '<') { 159 for (int i = 1; i < word.GetLength(); i ++) { 160 FX_BYTE digit = word.GetAt(i); 161 if (digit >= '0' && digit <= '9') { 162 digit = digit - '0'; 163 } else if (digit >= 'a' && digit <= 'f') { 164 digit = digit - 'a' + 10; 165 } else if (digit >= 'A' && digit <= 'F') { 166 digit = digit - 'A' + 10; 167 } else { 168 return num; 169 } 170 num = num * 16 + digit; 171 } 172 } else { 173 for (int i = 0; i < word.GetLength(); i ++) { 174 if (word.GetAt(i) < '0' || word.GetAt(i) > '9') { 175 return num; 176 } 177 num = num * 10 + word.GetAt(i) - '0'; 178 } 179 } 180 return num; 181 } 182 static FX_BOOL _CMap_GetCodeRange(_CMap_CodeRange& range, FX_BSTR first, FX_BSTR second) 183 { 184 if (first.GetLength() == 0 || first.GetAt(0) != '<') { 185 return FALSE; 186 } 187 int num = 0; 188 int i; 189 for (i = 1; i < first.GetLength(); i ++) 190 if (first.GetAt(i) == '>') { 191 break; 192 } 193 range.m_CharSize = (i - 1) / 2; 194 if (range.m_CharSize > 4) { 195 return FALSE; 196 } 197 for (i = 0; i < range.m_CharSize; i ++) { 198 FX_BYTE digit1 = first.GetAt(i * 2 + 1); 199 FX_BYTE digit2 = first.GetAt(i * 2 + 2); 200 FX_BYTE byte = (digit1 >= '0' && digit1 <= '9') ? (digit1 - '0') : ((digit1 & 0xdf) - 'A' + 10); 201 byte = byte * 16 + ((digit2 >= '0' && digit2 <= '9') ? (digit2 - '0') : ((digit2 & 0xdf) - 'A' + 10)); 202 range.m_Lower[i] = byte; 203 } 204 FX_DWORD size = second.GetLength(); 205 for (i = 0; i < range.m_CharSize; i ++) { 206 FX_BYTE digit1 = ((FX_DWORD)i * 2 + 1 < size) ? second.GetAt((FX_STRSIZE)i * 2 + 1) : 0; 207 FX_BYTE digit2 = ((FX_DWORD)i * 2 + 2 < size) ? second.GetAt((FX_STRSIZE)i * 2 + 2) : 0; 208 FX_BYTE byte = (digit1 >= '0' && digit1 <= '9') ? (digit1 - '0') : ((digit1 & 0xdf) - 'A' + 10); 209 byte = byte * 16 + ((digit2 >= '0' && digit2 <= '9') ? (digit2 - '0') : ((digit2 & 0xdf) - 'A' + 10)); 210 range.m_Upper[i] = byte; 211 } 212 return TRUE; 213 } 214 static CFX_ByteString CMap_GetString(FX_BSTR word) 215 { 216 return word.Mid(1, word.GetLength() - 2); 217 } 218 void CPDF_CMapParser::ParseWord(FX_BSTR word) 219 { 220 if (word.IsEmpty()) { 221 return; 222 } 223 if (word == FX_BSTRC("begincidchar")) { 224 m_Status = 1; 225 m_CodeSeq = 0; 226 } else if (word == FX_BSTRC("begincidrange")) { 227 m_Status = 2; 228 m_CodeSeq = 0; 229 } else if (word == FX_BSTRC("endcidrange") || word == FX_BSTRC("endcidchar")) { 230 m_Status = 0; 231 } else if (word == FX_BSTRC("/WMode")) { 232 m_Status = 6; 233 } else if (word == FX_BSTRC("/Registry")) { 234 m_Status = 3; 235 } else if (word == FX_BSTRC("/Ordering")) { 236 m_Status = 4; 237 } else if (word == FX_BSTRC("/Supplement")) { 238 m_Status = 5; 239 } else if (word == FX_BSTRC("begincodespacerange")) { 240 m_Status = 7; 241 m_CodeSeq = 0; 242 } else if (word == FX_BSTRC("usecmap")) { 243 } else if (m_Status == 1 || m_Status == 2) { 244 m_CodePoints[m_CodeSeq] = CMap_GetCode(word); 245 m_CodeSeq ++; 246 FX_DWORD StartCode, EndCode; 247 FX_WORD StartCID; 248 if (m_Status == 1) { 249 if (m_CodeSeq < 2) { 250 return; 251 } 252 EndCode = StartCode = m_CodePoints[0]; 253 StartCID = (FX_WORD)m_CodePoints[1]; 254 } else { 255 if (m_CodeSeq < 3) { 256 return; 257 } 258 StartCode = m_CodePoints[0]; 259 EndCode = m_CodePoints[1]; 260 StartCID = (FX_WORD)m_CodePoints[2]; 261 } 262 if (EndCode < 0x10000) { 263 for (FX_DWORD code = StartCode; code <= EndCode; code ++) { 264 m_pCMap->m_pMapping[code] = (FX_WORD)(StartCID + code - StartCode); 265 } 266 } else { 267 FX_DWORD buf[2]; 268 buf[0] = StartCode; 269 buf[1] = ((EndCode - StartCode) << 16) + StartCID; 270 m_AddMaps.AppendBlock(buf, sizeof buf); 271 } 272 m_CodeSeq = 0; 273 } else if (m_Status == 3) { 274 CMap_GetString(word); 275 m_Status = 0; 276 } else if (m_Status == 4) { 277 m_pCMap->m_Charset = _CharsetFromOrdering(CMap_GetString(word)); 278 m_Status = 0; 279 } else if (m_Status == 5) { 280 CMap_GetCode(word); 281 m_Status = 0; 282 } else if (m_Status == 6) { 283 m_pCMap->m_bVertical = CMap_GetCode(word); 284 m_Status = 0; 285 } else if (m_Status == 7) { 286 if (word == FX_BSTRC("endcodespacerange")) { 287 int nSegs = m_CodeRanges.GetSize(); 288 if (nSegs > 1) { 289 m_pCMap->m_CodingScheme = CPDF_CMap::MixedFourBytes; 290 m_pCMap->m_nCodeRanges = nSegs; 291 m_pCMap->m_pLeadingBytes = FX_Alloc(FX_BYTE, nSegs * sizeof(_CMap_CodeRange)); 292 FXSYS_memcpy32(m_pCMap->m_pLeadingBytes, m_CodeRanges.GetData(), nSegs * sizeof(_CMap_CodeRange)); 293 } else if (nSegs == 1) { 294 m_pCMap->m_CodingScheme = (m_CodeRanges[0].m_CharSize == 2) ? CPDF_CMap::TwoBytes : CPDF_CMap::OneByte; 295 } 296 m_Status = 0; 297 } else { 298 if (word.GetLength() == 0 || word.GetAt(0) != '<') { 299 return; 300 } 301 if (m_CodeSeq % 2) { 302 _CMap_CodeRange range; 303 if (_CMap_GetCodeRange(range, m_LastWord, word)) { 304 m_CodeRanges.Add(range); 305 } 306 } 307 m_CodeSeq ++; 308 } 309 } 310 m_LastWord = word; 311 } 312 CPDF_CMap::CPDF_CMap() 313 { 314 m_Charset = CIDSET_UNKNOWN; 315 m_Coding = CIDCODING_UNKNOWN; 316 m_CodingScheme = TwoBytes; 317 m_bVertical = 0; 318 m_bLoaded = FALSE; 319 m_pMapping = NULL; 320 m_pLeadingBytes = NULL; 321 m_pAddMapping = NULL; 322 m_pEmbedMap = NULL; 323 m_pUseMap = NULL; 324 m_nCodeRanges = 0; 325 } 326 CPDF_CMap::~CPDF_CMap() 327 { 328 if (m_pMapping) { 329 FX_Free(m_pMapping); 330 } 331 if (m_pAddMapping) { 332 FX_Free(m_pAddMapping); 333 } 334 if (m_pLeadingBytes) { 335 FX_Free(m_pLeadingBytes); 336 } 337 if (m_pUseMap) { 338 delete m_pUseMap; 339 } 340 } 341 void CPDF_CMap::Release() 342 { 343 if (m_PredefinedCMap.IsEmpty()) { 344 delete this; 345 } 346 } 347 const CPDF_PredefinedCMap g_PredefinedCMaps[] = { 348 { "GB-EUC", CIDSET_GB1, CIDCODING_GB, CPDF_CMap::MixedTwoBytes, 1, {0xa1, 0xfe} }, 349 { "GBpc-EUC", CIDSET_GB1, CIDCODING_GB, CPDF_CMap::MixedTwoBytes, 1, {0xa1, 0xfc} }, 350 { "GBK-EUC", CIDSET_GB1, CIDCODING_GB, CPDF_CMap::MixedTwoBytes, 1, {0x81, 0xfe} }, 351 { "GBKp-EUC", CIDSET_GB1, CIDCODING_GB, CPDF_CMap::MixedTwoBytes, 1, {0x81, 0xfe} }, 352 { "GBK2K-EUC", CIDSET_GB1, CIDCODING_GB, CPDF_CMap::MixedTwoBytes, 1, {0x81, 0xfe} }, 353 { "GBK2K", CIDSET_GB1, CIDCODING_GB, CPDF_CMap::MixedTwoBytes, 1, {0x81, 0xfe} }, 354 { "UniGB-UCS2", CIDSET_GB1, CIDCODING_UCS2, CPDF_CMap::TwoBytes }, 355 { "UniGB-UTF16", CIDSET_GB1, CIDCODING_UTF16, CPDF_CMap::TwoBytes }, 356 { "B5pc", CIDSET_CNS1, CIDCODING_BIG5, CPDF_CMap::MixedTwoBytes, 1, {0xa1, 0xfc} }, 357 { "HKscs-B5", CIDSET_CNS1, CIDCODING_BIG5, CPDF_CMap::MixedTwoBytes, 1, {0x88, 0xfe} }, 358 { "ETen-B5", CIDSET_CNS1, CIDCODING_BIG5, CPDF_CMap::MixedTwoBytes, 1, {0xa1, 0xfe} }, 359 { "ETenms-B5", CIDSET_CNS1, CIDCODING_BIG5, CPDF_CMap::MixedTwoBytes, 1, {0xa1, 0xfe} }, 360 { "UniCNS-UCS2", CIDSET_CNS1, CIDCODING_UCS2, CPDF_CMap::TwoBytes }, 361 { "UniCNS-UTF16", CIDSET_CNS1, CIDCODING_UTF16, CPDF_CMap::TwoBytes }, 362 { "83pv-RKSJ", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::MixedTwoBytes, 2, {0x81, 0x9f, 0xe0, 0xfc} }, 363 { "90ms-RKSJ", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::MixedTwoBytes, 2, {0x81, 0x9f, 0xe0, 0xfc} }, 364 { "90msp-RKSJ", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::MixedTwoBytes, 2, {0x81, 0x9f, 0xe0, 0xfc} }, 365 { "90pv-RKSJ", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::MixedTwoBytes, 2, {0x81, 0x9f, 0xe0, 0xfc} }, 366 { "Add-RKSJ", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::MixedTwoBytes, 2, {0x81, 0x9f, 0xe0, 0xfc} }, 367 { "EUC", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::MixedTwoBytes, 2, {0x8e, 0x8e, 0xa1, 0xfe} }, 368 { "H", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::TwoBytes, 1, {0x21, 0x7e} }, 369 { "V", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::TwoBytes, 1, {0x21, 0x7e} }, 370 { "Ext-RKSJ", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::MixedTwoBytes, 2, {0x81, 0x9f, 0xe0, 0xfc} }, 371 { "UniJIS-UCS2", CIDSET_JAPAN1, CIDCODING_UCS2, CPDF_CMap::TwoBytes }, 372 { "UniJIS-UCS2-HW", CIDSET_JAPAN1, CIDCODING_UCS2, CPDF_CMap::TwoBytes }, 373 { "UniJIS-UTF16", CIDSET_JAPAN1, CIDCODING_UTF16, CPDF_CMap::TwoBytes }, 374 { "KSC-EUC", CIDSET_KOREA1, CIDCODING_KOREA, CPDF_CMap::MixedTwoBytes, 1, {0xa1, 0xfe} }, 375 { "KSCms-UHC", CIDSET_KOREA1, CIDCODING_KOREA, CPDF_CMap::MixedTwoBytes, 1, {0x81, 0xfe} }, 376 { "KSCms-UHC-HW", CIDSET_KOREA1, CIDCODING_KOREA, CPDF_CMap::MixedTwoBytes, 1, {0x81, 0xfe} }, 377 { "KSCpc-EUC", CIDSET_KOREA1, CIDCODING_KOREA, CPDF_CMap::MixedTwoBytes, 1, {0xa1, 0xfd} }, 378 { "UniKS-UCS2", CIDSET_KOREA1, CIDCODING_UCS2, CPDF_CMap::TwoBytes }, 379 { "UniKS-UTF16", CIDSET_KOREA1, CIDCODING_UTF16, CPDF_CMap::TwoBytes }, 380 { NULL, 0, 0 } 381 }; 382 extern void FPDFAPI_FindEmbeddedCMap(const char* name, int charset, int coding, const FXCMAP_CMap*& pMap); 383 extern FX_WORD FPDFAPI_CIDFromCharCode(const FXCMAP_CMap* pMap, FX_DWORD charcode); 384 FX_BOOL CPDF_CMap::LoadPredefined(CPDF_CMapManager* pMgr, FX_LPCSTR pName, FX_BOOL bPromptCJK) 385 { 386 m_PredefinedCMap = pName; 387 if (m_PredefinedCMap == FX_BSTRC("Identity-H") || m_PredefinedCMap == FX_BSTRC("Identity-V")) { 388 m_Coding = CIDCODING_CID; 389 m_bVertical = pName[9] == 'V'; 390 m_bLoaded = TRUE; 391 return TRUE; 392 } 393 CFX_ByteString cmapid = m_PredefinedCMap; 394 m_bVertical = cmapid.Right(1) == FX_BSTRC("V"); 395 if (cmapid.GetLength() > 2) { 396 cmapid = cmapid.Left(cmapid.GetLength() - 2); 397 } 398 int index = 0; 399 while (1) { 400 if (g_PredefinedCMaps[index].m_pName == NULL) { 401 return FALSE; 402 } 403 if (cmapid == CFX_ByteStringC(g_PredefinedCMaps[index].m_pName)) { 404 break; 405 } 406 index ++; 407 } 408 const CPDF_PredefinedCMap& map = g_PredefinedCMaps[index]; 409 m_Charset = map.m_Charset; 410 m_Coding = map.m_Coding; 411 m_CodingScheme = map.m_CodingScheme; 412 if (m_CodingScheme == MixedTwoBytes) { 413 m_pLeadingBytes = FX_Alloc(FX_BYTE, 256); 414 FXSYS_memset32(m_pLeadingBytes, 0, 256); 415 for (FX_DWORD i = 0; i < map.m_LeadingSegCount; i ++) { 416 for (int b = map.m_LeadingSegs[i * 2]; b <= map.m_LeadingSegs[i * 2 + 1]; b ++) { 417 m_pLeadingBytes[b] = 1; 418 } 419 } 420 } 421 FPDFAPI_FindEmbeddedCMap(pName, m_Charset, m_Coding, m_pEmbedMap); 422 if (m_pEmbedMap) { 423 m_bLoaded = TRUE; 424 return TRUE; 425 } 426 #ifndef _FPDFAPI_MINI_ 427 FX_LPVOID pPackage = pMgr->GetPackage(bPromptCJK); 428 FX_LPBYTE pBuffer; 429 FX_DWORD size; 430 if (pPackage == NULL || !FXFC_LoadFile(pPackage, m_PredefinedCMap, pBuffer, size)) { 431 return FALSE; 432 } 433 m_pMapping = FX_Alloc(FX_WORD, 65536); 434 FXSYS_memset32(m_pMapping, 0, 65536 * sizeof(FX_WORD)); 435 FX_DWORD dwRecodeEndPos = 0; 436 if (pBuffer[5] == 0) { 437 FX_DWORD dwStartIndex = *(FX_DWORD*)(pBuffer + 8); 438 FX_DWORD dwRecordCount = *(FX_DWORD*)(pBuffer + 16); 439 FX_DWORD dwDataOffset = *(FX_DWORD*)(pBuffer + 20); 440 if (dwRecordCount * 2 + dwStartIndex * 2 < 65536) { 441 FXSYS_memcpy32(m_pMapping + dwStartIndex * 2, pBuffer + dwDataOffset, dwRecordCount * 2); 442 } 443 dwRecodeEndPos = dwDataOffset + dwRecordCount * 2; 444 } else if (pBuffer[5] == 2) { 445 FX_DWORD nSegments = *(FX_DWORD*)(pBuffer + 16); 446 FX_DWORD dwDataOffset = *(FX_DWORD*)(pBuffer + 20); 447 dwRecodeEndPos = dwDataOffset + 6 * nSegments; 448 for (FX_DWORD i = 0; i < nSegments; i ++) { 449 FX_LPBYTE pRecord = pBuffer + dwDataOffset + i * 6; 450 FX_WORD IndexStart = *(FX_WORD*)pRecord; 451 FX_WORD IndexCount = *(FX_WORD*)(pRecord + 2); 452 FX_WORD CodeStart = *(FX_WORD*)(pRecord + 4); 453 if (IndexStart + IndexCount < 65536) 454 for (FX_DWORD j = 0; j < IndexCount; j ++) { 455 m_pMapping[IndexStart + j ] = (FX_WORD)(CodeStart + j); 456 } 457 } 458 } 459 if (dwRecodeEndPos < size) { 460 FX_DWORD dwMapLen = *(FX_DWORD*)(pBuffer + dwRecodeEndPos); 461 if (dwMapLen) { 462 m_pUseMap = FX_NEW CPDF_CMap; 463 CFX_ByteString bsName(pBuffer + dwRecodeEndPos + 4 , dwMapLen); 464 if (m_pUseMap) { 465 m_pUseMap->LoadPredefined(pMgr, bsName, bPromptCJK); 466 } 467 } 468 } 469 FX_Free(pBuffer); 470 m_bLoaded = TRUE; 471 #endif 472 return TRUE; 473 } 474 extern "C" { 475 static int compare_dword(const void* data1, const void* data2) 476 { 477 return (*(FX_DWORD*)data1) - (*(FX_DWORD*)data2); 478 } 479 }; 480 FX_BOOL CPDF_CMap::LoadEmbedded(FX_LPCBYTE pData, FX_DWORD size) 481 { 482 m_pMapping = FX_Alloc(FX_WORD, 65536); 483 FXSYS_memset32(m_pMapping, 0, 65536 * sizeof(FX_WORD)); 484 CPDF_CMapParser parser; 485 parser.Initialize(this); 486 CPDF_SimpleParser syntax(pData, size); 487 while (1) { 488 CFX_ByteStringC word = syntax.GetWord(); 489 if (word.IsEmpty()) { 490 break; 491 } 492 parser.ParseWord(word); 493 } 494 if (m_CodingScheme == MixedFourBytes && parser.m_AddMaps.GetSize()) { 495 m_pAddMapping = FX_Alloc(FX_BYTE, parser.m_AddMaps.GetSize() + 4); 496 *(FX_DWORD*)m_pAddMapping = parser.m_AddMaps.GetSize() / 8; 497 FXSYS_memcpy32(m_pAddMapping + 4, parser.m_AddMaps.GetBuffer(), parser.m_AddMaps.GetSize()); 498 FXSYS_qsort(m_pAddMapping + 4, parser.m_AddMaps.GetSize() / 8, 8, compare_dword); 499 } 500 return TRUE; 501 } 502 extern "C" { 503 static int compareCID(const void* key, const void* element) 504 { 505 if ((*(FX_DWORD*)key) < (*(FX_DWORD*)element)) { 506 return -1; 507 } 508 if ((*(FX_DWORD*)key) > (*(FX_DWORD*)element) + ((FX_DWORD*)element)[1] / 65536) { 509 return 1; 510 } 511 return 0; 512 } 513 }; 514 FX_WORD CPDF_CMap::CIDFromCharCode(FX_DWORD charcode) const 515 { 516 if (m_Coding == CIDCODING_CID) { 517 return (FX_WORD)charcode; 518 } 519 if (m_pEmbedMap) { 520 return FPDFAPI_CIDFromCharCode(m_pEmbedMap, charcode); 521 } 522 if (m_pMapping == NULL) { 523 return (FX_WORD)charcode; 524 } 525 if (charcode >> 16) { 526 if (m_pAddMapping) { 527 void* found = FXSYS_bsearch(&charcode, m_pAddMapping + 4, *(FX_DWORD*)m_pAddMapping, 8, compareCID); 528 if (found == NULL) { 529 if (m_pUseMap) { 530 return m_pUseMap->CIDFromCharCode(charcode); 531 } 532 return 0; 533 } 534 return (FX_WORD)(((FX_DWORD*)found)[1] % 65536 + charcode - * (FX_DWORD*)found); 535 } 536 if (m_pUseMap) { 537 return m_pUseMap->CIDFromCharCode(charcode); 538 } 539 return 0; 540 } 541 FX_DWORD CID = m_pMapping[charcode]; 542 if (!CID && m_pUseMap) { 543 return m_pUseMap->CIDFromCharCode(charcode); 544 } 545 return (FX_WORD)CID; 546 } 547 static int _CheckCodeRange(FX_LPBYTE codes, int size, _CMap_CodeRange* pRanges, int nRanges) 548 { 549 int iSeg = nRanges - 1; 550 while (iSeg >= 0) { 551 if (pRanges[iSeg].m_CharSize < size) { 552 iSeg --; 553 continue; 554 } 555 int iChar = 0; 556 while (iChar < size) { 557 if (codes[iChar] < pRanges[iSeg].m_Lower[iChar] || 558 codes[iChar] > pRanges[iSeg].m_Upper[iChar]) { 559 break; 560 } 561 iChar ++; 562 } 563 if (iChar == pRanges[iSeg].m_CharSize) { 564 return 2; 565 } 566 if (iChar) { 567 if (size == pRanges[iSeg].m_CharSize) { 568 return 2; 569 } 570 return 1; 571 } 572 iSeg --; 573 } 574 return 0; 575 } 576 FX_DWORD CPDF_CMap::GetNextChar(FX_LPCSTR pString, int& offset) const 577 { 578 switch (m_CodingScheme) { 579 case OneByte: 580 return ((FX_LPBYTE)pString)[offset++]; 581 case TwoBytes: 582 offset += 2; 583 return ((FX_LPBYTE)pString)[offset - 2] * 256 + ((FX_LPBYTE)pString)[offset - 1]; 584 case MixedTwoBytes: { 585 FX_BYTE byte1 = ((FX_LPBYTE)pString)[offset++]; 586 if (!m_pLeadingBytes[byte1]) { 587 return byte1; 588 } 589 FX_BYTE byte2 = ((FX_LPBYTE)pString)[offset++]; 590 return byte1 * 256 + byte2; 591 } 592 case MixedFourBytes: { 593 FX_BYTE codes[4]; 594 int char_size = 1; 595 codes[0] = ((FX_LPBYTE)pString)[offset++]; 596 _CMap_CodeRange* pRanges = (_CMap_CodeRange*)m_pLeadingBytes; 597 while (1) { 598 int ret = _CheckCodeRange(codes, char_size, pRanges, m_nCodeRanges); 599 if (ret == 0) { 600 return 0; 601 } 602 if (ret == 2) { 603 FX_DWORD charcode = 0; 604 for (int i = 0; i < char_size; i ++) { 605 charcode = (charcode << 8) + codes[i]; 606 } 607 return charcode; 608 } 609 if (char_size == 4) { 610 return 0; 611 } 612 codes[char_size ++] = ((FX_LPBYTE)pString)[offset++]; 613 } 614 break; 615 } 616 } 617 return 0; 618 } 619 int CPDF_CMap::GetCharSize(FX_DWORD charcode) const 620 { 621 switch (m_CodingScheme) { 622 case OneByte: 623 return 1; 624 case TwoBytes: 625 return 2; 626 case MixedTwoBytes: 627 case MixedFourBytes: 628 if (charcode < 0x100) { 629 return 1; 630 } 631 if (charcode < 0x10000) { 632 return 2; 633 } 634 if (charcode < 0x1000000) { 635 return 3; 636 } 637 return 4; 638 } 639 return 1; 640 } 641 int CPDF_CMap::CountChar(FX_LPCSTR pString, int size) const 642 { 643 switch (m_CodingScheme) { 644 case OneByte: 645 return size; 646 case TwoBytes: 647 return (size + 1) / 2; 648 case MixedTwoBytes: { 649 int count = 0; 650 for (int i = 0; i < size; i ++) { 651 count ++; 652 if (m_pLeadingBytes[((FX_LPBYTE)pString)[i]]) { 653 i ++; 654 } 655 } 656 return count; 657 } 658 case MixedFourBytes: { 659 int count = 0, offset = 0; 660 while (offset < size) { 661 GetNextChar(pString, offset); 662 count ++; 663 } 664 return count; 665 } 666 } 667 return size; 668 } 669 int _GetCharSize(FX_DWORD charcode, _CMap_CodeRange* pRanges, int iRangesSize) 670 { 671 if (!iRangesSize) { 672 return 1; 673 } 674 FX_BYTE codes[4]; 675 codes[0] = codes[1] = 0x00; 676 codes[2] = (FX_BYTE)(charcode >> 8 & 0xFF); 677 codes[3] = (FX_BYTE)charcode; 678 int offset = 0, size = 4; 679 for (int i = 0; i < 4; ++i) { 680 int iSeg = iRangesSize - 1; 681 while (iSeg >= 0) { 682 if (pRanges[iSeg].m_CharSize < size) { 683 iSeg --; 684 continue; 685 } 686 int iChar = 0; 687 while (iChar < size) { 688 if (codes[offset + iChar] < pRanges[iSeg].m_Lower[iChar] || 689 codes[offset + iChar] > pRanges[iSeg].m_Upper[iChar]) { 690 break; 691 } 692 iChar ++; 693 } 694 if (iChar == pRanges[iSeg].m_CharSize) { 695 return size; 696 } 697 iSeg --; 698 } 699 size --; 700 offset ++; 701 } 702 return 1; 703 } 704 int CPDF_CMap::AppendChar(FX_LPSTR str, FX_DWORD charcode) const 705 { 706 switch (m_CodingScheme) { 707 case OneByte: 708 str[0] = (FX_BYTE)charcode; 709 return 1; 710 case TwoBytes: 711 str[0] = (FX_BYTE)(charcode / 256); 712 str[1] = (FX_BYTE)(charcode % 256); 713 return 2; 714 case MixedTwoBytes: 715 case MixedFourBytes: 716 if (charcode < 0x100) { 717 _CMap_CodeRange* pRanges = (_CMap_CodeRange*)m_pLeadingBytes; 718 int iSize = _GetCharSize(charcode, pRanges, m_nCodeRanges); 719 if (iSize == 0) { 720 iSize = 1; 721 } 722 if (iSize > 1) { 723 FXSYS_memset32(str, 0, sizeof(FX_BYTE) * iSize); 724 } 725 str[iSize - 1] = (FX_BYTE)charcode; 726 return iSize; 727 } else if (charcode < 0x10000) { 728 str[0] = (FX_BYTE)(charcode >> 8); 729 str[1] = (FX_BYTE)charcode; 730 return 2; 731 } else if (charcode < 0x1000000) { 732 str[0] = (FX_BYTE)(charcode >> 16); 733 str[1] = (FX_BYTE)(charcode >> 8); 734 str[2] = (FX_BYTE)charcode; 735 return 3; 736 } else { 737 str[0] = (FX_BYTE)(charcode >> 24); 738 str[1] = (FX_BYTE)(charcode >> 16); 739 str[2] = (FX_BYTE)(charcode >> 8); 740 str[3] = (FX_BYTE)charcode; 741 return 4; 742 } 743 } 744 return 0; 745 } 746 CPDF_CID2UnicodeMap::CPDF_CID2UnicodeMap() 747 { 748 m_EmbeddedCount = 0; 749 #ifndef _FPDFAPI_MINI_ 750 m_pExternalMap = NULL; 751 #endif 752 } 753 CPDF_CID2UnicodeMap::~CPDF_CID2UnicodeMap() 754 { 755 #ifndef _FPDFAPI_MINI_ 756 if (m_pExternalMap) { 757 delete m_pExternalMap; 758 } 759 #endif 760 } 761 FX_BOOL CPDF_CID2UnicodeMap::Initialize() 762 { 763 #ifndef _FPDFAPI_MINI_ 764 m_pExternalMap = FX_NEW CPDF_FXMP; 765 #endif 766 return TRUE; 767 } 768 FX_BOOL CPDF_CID2UnicodeMap::IsLoaded() 769 { 770 #ifdef _FPDFAPI_MINI_ 771 return m_EmbeddedCount != 0; 772 #else 773 return m_EmbeddedCount != 0 || (m_pExternalMap != NULL && m_pExternalMap->IsLoaded()); 774 #endif 775 } 776 FX_WCHAR CPDF_CID2UnicodeMap::UnicodeFromCID(FX_WORD CID) 777 { 778 if (m_Charset == CIDSET_UNICODE) { 779 return CID; 780 } 781 if (CID < m_EmbeddedCount) { 782 return m_pEmbeddedMap[CID]; 783 } 784 #ifdef _FPDFAPI_MINI_ 785 return 0; 786 #else 787 FX_LPCBYTE record = m_pExternalMap->GetRecord(CID); 788 if (record == NULL) { 789 return 0; 790 } 791 return *(FX_WORD*)record; 792 #endif 793 } 794 void FPDFAPI_LoadCID2UnicodeMap(int charset, const FX_WORD*& pMap, FX_DWORD& count); 795 void CPDF_CID2UnicodeMap::Load(CPDF_CMapManager* pMgr, int charset, FX_BOOL bPromptCJK) 796 { 797 m_Charset = charset; 798 FPDFAPI_LoadCID2UnicodeMap(charset, m_pEmbeddedMap, m_EmbeddedCount); 799 if (m_EmbeddedCount) { 800 return; 801 } 802 #ifndef _FPDFAPI_MINI_ 803 FX_LPVOID pPackage = pMgr->GetPackage(bPromptCJK); 804 if (pPackage == NULL) { 805 return; 806 } 807 m_pExternalMap->LoadFile(pPackage, FX_BSTRC("CIDInfo_") + g_CharsetNames[charset]); 808 #endif 809 } 810 #include "ttgsubtable.h" 811 CPDF_CIDFont::CPDF_CIDFont() 812 { 813 m_pCMap = NULL; 814 m_pAllocatedCMap = NULL; 815 m_pCID2UnicodeMap = NULL; 816 m_pAnsiWidths = NULL; 817 m_pCIDToGIDMap = NULL; 818 m_bCIDIsGID = FALSE; 819 m_bAdobeCourierStd = FALSE; 820 m_pTTGSUBTable = NULL; 821 FXSYS_memset8(m_CharBBox, 0xff, 256 * sizeof(FX_SMALL_RECT)); 822 } 823 CPDF_CIDFont::~CPDF_CIDFont() 824 { 825 if (m_pAnsiWidths) { 826 FX_Free(m_pAnsiWidths); 827 } 828 if (m_pAllocatedCMap) { 829 delete m_pAllocatedCMap; 830 } 831 if (m_pCIDToGIDMap) { 832 delete m_pCIDToGIDMap; 833 } 834 if (m_pTTGSUBTable) { 835 delete m_pTTGSUBTable; 836 } 837 } 838 FX_WORD CPDF_CIDFont::CIDFromCharCode(FX_DWORD charcode) const 839 { 840 if (m_pCMap == NULL) { 841 return (FX_WORD)charcode; 842 } 843 return m_pCMap->CIDFromCharCode(charcode); 844 } 845 FX_BOOL CPDF_CIDFont::IsVertWriting() const 846 { 847 return m_pCMap ? m_pCMap->IsVertWriting() : FALSE; 848 } 849 extern FX_DWORD FPDFAPI_CharCodeFromCID(const FXCMAP_CMap* pMap, FX_WORD cid); 850 static FX_DWORD _EmbeddedCharcodeFromUnicode(const FXCMAP_CMap* pEmbedMap, int charset, FX_WCHAR unicode) 851 { 852 if (charset <= 0 || charset > 4) { 853 return 0; 854 } 855 CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); 856 const FX_WORD* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap; 857 if (pCodes == NULL) { 858 return 0; 859 } 860 int nCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count; 861 for (int i = 0; i < nCodes; i++) { 862 if (pCodes[i] == unicode) { 863 FX_DWORD CharCode = FPDFAPI_CharCodeFromCID(pEmbedMap, i); 864 if (CharCode == 0) { 865 continue; 866 } 867 return CharCode; 868 } 869 } 870 return 0; 871 } 872 static FX_WCHAR _EmbeddedUnicodeFromCharcode(const FXCMAP_CMap* pEmbedMap, int charset, FX_DWORD charcode) 873 { 874 if (charset <= 0 || charset > 4) { 875 return 0; 876 } 877 FX_WORD cid = FPDFAPI_CIDFromCharCode(pEmbedMap, charcode); 878 if (cid == 0) { 879 return 0; 880 } 881 CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); 882 const FX_WORD* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap; 883 if (pCodes == NULL) { 884 return 0; 885 } 886 if (cid < pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count) { 887 return pCodes[cid]; 888 } 889 return 0; 890 } 891 FX_WCHAR CPDF_CIDFont::_UnicodeFromCharCode(FX_DWORD charcode) const 892 { 893 switch (m_pCMap->m_Coding) { 894 case CIDCODING_UCS2: 895 case CIDCODING_UTF16: 896 return (FX_WCHAR)charcode; 897 case CIDCODING_CID: 898 if (m_pCID2UnicodeMap == NULL || !m_pCID2UnicodeMap->IsLoaded()) { 899 return 0; 900 } 901 return m_pCID2UnicodeMap->UnicodeFromCID((FX_WORD)charcode); 902 } 903 if (!m_pCMap->IsLoaded() || m_pCID2UnicodeMap == NULL || !m_pCID2UnicodeMap->IsLoaded()) { 904 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 905 FX_WCHAR unicode; 906 int charsize = 1; 907 if (charcode > 255) { 908 charcode = (charcode % 256) * 256 + (charcode / 256); 909 charsize = 2; 910 } 911 int ret = FXSYS_MultiByteToWideChar(g_CharsetCPs[m_pCMap->m_Coding], 0, (FX_LPCSTR)&charcode, charsize, &unicode, 1); 912 if (ret != 1) { 913 return 0; 914 } 915 return unicode; 916 #endif 917 if (m_pCMap->m_pEmbedMap) { 918 return _EmbeddedUnicodeFromCharcode(m_pCMap->m_pEmbedMap, m_pCMap->m_Charset, charcode); 919 } else { 920 return 0; 921 } 922 } 923 return m_pCID2UnicodeMap->UnicodeFromCID(CIDFromCharCode(charcode)); 924 } 925 FX_DWORD CPDF_CIDFont::_CharCodeFromUnicode(FX_WCHAR unicode) const 926 { 927 switch (m_pCMap->m_Coding) { 928 case CIDCODING_UNKNOWN: 929 return 0; 930 case CIDCODING_UCS2: 931 case CIDCODING_UTF16: 932 return unicode; 933 case CIDCODING_CID: { 934 if (m_pCID2UnicodeMap == NULL || !m_pCID2UnicodeMap->IsLoaded()) { 935 return 0; 936 } 937 FX_DWORD CID = 0; 938 while (CID < 65536) { 939 FX_WCHAR this_unicode = m_pCID2UnicodeMap->UnicodeFromCID((FX_WORD)CID); 940 if (this_unicode == unicode) { 941 return CID; 942 } 943 CID ++; 944 } 945 break; 946 } 947 } 948 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 949 FX_BYTE buffer[32]; 950 int ret = FXSYS_WideCharToMultiByte(g_CharsetCPs[m_pCMap->m_Coding], 0, &unicode, 1, (char*)buffer, 4, NULL, NULL); 951 if (ret == 1) { 952 return buffer[0]; 953 } else if (ret == 2) { 954 return buffer[0] * 256 + buffer[1]; 955 } 956 return 0; 957 #endif 958 if (unicode < 0x80) { 959 return (FX_DWORD)unicode; 960 } else { 961 if (m_pCMap->m_pEmbedMap) { 962 return _EmbeddedCharcodeFromUnicode(m_pCMap->m_pEmbedMap, m_pCMap->m_Charset, unicode); 963 } else { 964 return 0; 965 } 966 } 967 } 968 static void FT_UseCIDCharmap(FXFT_Face face, int coding) 969 { 970 int encoding; 971 switch (coding) { 972 case CIDCODING_GB: 973 encoding = FXFT_ENCODING_GB2312; 974 break; 975 case CIDCODING_BIG5: 976 encoding = FXFT_ENCODING_BIG5; 977 break; 978 case CIDCODING_JIS: 979 encoding = FXFT_ENCODING_SJIS; 980 break; 981 case CIDCODING_KOREA: 982 encoding = FXFT_ENCODING_JOHAB; 983 break; 984 default: 985 encoding = FXFT_ENCODING_UNICODE; 986 } 987 int err = FXFT_Select_Charmap(face, encoding); 988 if (err) { 989 err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE); 990 } 991 if (err && FXFT_Get_Face_Charmaps(face)) { 992 FXFT_Set_Charmap(face, *FXFT_Get_Face_Charmaps(face)); 993 } 994 } 995 FX_BOOL CPDF_CIDFont::_Load() 996 { 997 if (m_pFontDict->GetString(FX_BSTRC("Subtype")) == FX_BSTRC("TrueType")) { 998 return LoadGB2312(); 999 } 1000 CPDF_Array* pFonts = m_pFontDict->GetArray(FX_BSTRC("DescendantFonts")); 1001 if (pFonts == NULL) { 1002 return FALSE; 1003 } 1004 if (pFonts->GetCount() != 1) { 1005 return FALSE; 1006 } 1007 CPDF_Dictionary* pCIDFontDict = pFonts->GetDict(0); 1008 if (pCIDFontDict == NULL) { 1009 return FALSE; 1010 } 1011 m_BaseFont = pCIDFontDict->GetString(FX_BSTRC("BaseFont")); 1012 if ((m_BaseFont.Compare("CourierStd") == 0 || m_BaseFont.Compare("CourierStd-Bold") == 0 1013 || m_BaseFont.Compare("CourierStd-BoldOblique") == 0 || m_BaseFont.Compare("CourierStd-Oblique") == 0) 1014 && !IsEmbedded()) { 1015 m_bAdobeCourierStd = TRUE; 1016 } 1017 CPDF_Dictionary* pFontDesc = pCIDFontDict->GetDict(FX_BSTRC("FontDescriptor")); 1018 if (pFontDesc) { 1019 LoadFontDescriptor(pFontDesc); 1020 } 1021 CPDF_Object* pEncoding = m_pFontDict->GetElementValue(FX_BSTRC("Encoding")); 1022 if (pEncoding == NULL) { 1023 return FALSE; 1024 } 1025 CFX_ByteString subtype = pCIDFontDict->GetString(FX_BSTRC("Subtype")); 1026 m_bType1 = FALSE; 1027 if (subtype == FX_BSTRC("CIDFontType0")) { 1028 m_bType1 = TRUE; 1029 } 1030 if (pEncoding->GetType() == PDFOBJ_NAME) { 1031 CFX_ByteString cmap = pEncoding->GetString(); 1032 m_pCMap = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals()->m_CMapManager.GetPredefinedCMap(cmap, 1033 m_pFontFile && m_bType1); 1034 } else if (pEncoding->GetType() == PDFOBJ_STREAM) { 1035 m_pAllocatedCMap = m_pCMap = FX_NEW CPDF_CMap; 1036 CPDF_Stream* pStream = (CPDF_Stream*)pEncoding; 1037 CPDF_StreamAcc acc; 1038 acc.LoadAllData(pStream, FALSE); 1039 m_pCMap->LoadEmbedded(acc.GetData(), acc.GetSize()); 1040 } else { 1041 return FALSE; 1042 } 1043 if (m_pCMap == NULL) { 1044 return FALSE; 1045 } 1046 m_Charset = m_pCMap->m_Charset; 1047 if (m_Charset == CIDSET_UNKNOWN) { 1048 CPDF_Dictionary* pCIDInfo = pCIDFontDict->GetDict(FX_BSTRC("CIDSystemInfo")); 1049 if (pCIDInfo) { 1050 m_Charset = _CharsetFromOrdering(pCIDInfo->GetString(FX_BSTRC("Ordering"))); 1051 } 1052 } 1053 if (m_Charset != CIDSET_UNKNOWN) 1054 m_pCID2UnicodeMap = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals()->m_CMapManager.GetCID2UnicodeMap(m_Charset, 1055 m_pFontFile == NULL && (m_pCMap->m_Coding == CIDCODING_CID || pCIDFontDict->KeyExist(FX_BSTRC("W")))); 1056 if (m_Font.GetFace()) { 1057 if (m_bType1) { 1058 FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE); 1059 } else { 1060 FT_UseCIDCharmap(m_Font.GetFace(), m_pCMap->m_Coding); 1061 } 1062 } 1063 m_DefaultWidth = pCIDFontDict->GetInteger(FX_BSTRC("DW"), 1000); 1064 CPDF_Array* pWidthArray = pCIDFontDict->GetArray(FX_BSTRC("W")); 1065 if (pWidthArray) { 1066 LoadMetricsArray(pWidthArray, m_WidthList, 1); 1067 } 1068 if (!IsEmbedded()) { 1069 LoadSubstFont(); 1070 } 1071 if (1) { 1072 if (m_pFontFile || (GetSubstFont()->m_SubstFlags & FXFONT_SUBST_EXACT)) { 1073 CPDF_Object* pmap = pCIDFontDict->GetElementValue(FX_BSTRC("CIDToGIDMap")); 1074 if (pmap) { 1075 if (pmap->GetType() == PDFOBJ_STREAM) { 1076 m_pCIDToGIDMap = FX_NEW CPDF_StreamAcc; 1077 m_pCIDToGIDMap->LoadAllData((CPDF_Stream*)pmap, FALSE); 1078 } else if (pmap->GetString() == FX_BSTRC("Identity")) { 1079 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 1080 if (m_pFontFile) { 1081 m_bCIDIsGID = TRUE; 1082 } 1083 #else 1084 m_bCIDIsGID = TRUE; 1085 #endif 1086 } 1087 } 1088 } 1089 } 1090 CheckFontMetrics(); 1091 if (IsVertWriting()) { 1092 pWidthArray = pCIDFontDict->GetArray(FX_BSTRC("W2")); 1093 if (pWidthArray) { 1094 LoadMetricsArray(pWidthArray, m_VertMetrics, 3); 1095 } 1096 CPDF_Array* pDefaultArray = pCIDFontDict->GetArray(FX_BSTRC("DW2")); 1097 if (pDefaultArray) { 1098 m_DefaultVY = pDefaultArray->GetInteger(0); 1099 m_DefaultW1 = pDefaultArray->GetInteger(1); 1100 } else { 1101 m_DefaultVY = 880; 1102 m_DefaultW1 = -1000; 1103 } 1104 } 1105 return TRUE; 1106 } 1107 FX_FLOAT _CIDTransformToFloat(FX_BYTE ch) 1108 { 1109 if (ch < 128) { 1110 return ch * 1.0f / 127; 1111 } 1112 return (-255 + ch) * 1.0f / 127; 1113 } 1114 void CPDF_CIDFont::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level) 1115 { 1116 if (charcode < 256 && m_CharBBox[charcode].Right != -1) { 1117 rect.bottom = m_CharBBox[charcode].Bottom; 1118 rect.left = m_CharBBox[charcode].Left; 1119 rect.right = m_CharBBox[charcode].Right; 1120 rect.top = m_CharBBox[charcode].Top; 1121 return; 1122 } 1123 FX_BOOL bVert = FALSE; 1124 int glyph_index = GlyphFromCharCode(charcode, &bVert); 1125 if (m_Font.m_Face == NULL) { 1126 rect = FX_RECT(0, 0, 0, 0); 1127 } else { 1128 rect.left = rect.bottom = rect.right = rect.top = 0; 1129 FXFT_Face face = m_Font.m_Face; 1130 if (FXFT_Is_Face_Tricky(face)) { 1131 int err = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); 1132 if (!err) { 1133 FXFT_BBox cbox; 1134 FXFT_Glyph glyph; 1135 err = FXFT_Get_Glyph(((FXFT_Face)face)->glyph, &glyph); 1136 if (!err) { 1137 FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox); 1138 int pixel_size_x = ((FXFT_Face)face)->size->metrics.x_ppem; 1139 int pixel_size_y = ((FXFT_Face)face)->size->metrics.y_ppem; 1140 if (pixel_size_x == 0 || pixel_size_y == 0) { 1141 rect.left = cbox.xMin; 1142 rect.right = cbox.xMax; 1143 rect.top = cbox.yMax; 1144 rect.bottom = cbox.yMin; 1145 } else { 1146 rect.left = cbox.xMin * 1000 / pixel_size_x; 1147 rect.right = cbox.xMax * 1000 / pixel_size_x; 1148 rect.top = cbox.yMax * 1000 / pixel_size_y; 1149 rect.bottom = cbox.yMin * 1000 / pixel_size_y; 1150 } 1151 if (rect.top > FXFT_Get_Face_Ascender(face)) { 1152 rect.top = FXFT_Get_Face_Ascender(face); 1153 } 1154 if (rect.bottom < FXFT_Get_Face_Descender(face)) { 1155 rect.bottom = FXFT_Get_Face_Descender(face); 1156 } 1157 FXFT_Done_Glyph(glyph); 1158 } 1159 } 1160 } else { 1161 int err = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_NO_SCALE); 1162 if (err == 0) { 1163 rect.left = TT2PDF(FXFT_Get_Glyph_HoriBearingX(face), face); 1164 rect.right = TT2PDF(FXFT_Get_Glyph_HoriBearingX(face) + FXFT_Get_Glyph_Width(face), face); 1165 rect.top = TT2PDF(FXFT_Get_Glyph_HoriBearingY(face), face); 1166 rect.top += rect.top / 64; 1167 rect.bottom = TT2PDF(FXFT_Get_Glyph_HoriBearingY(face) - FXFT_Get_Glyph_Height(face), face); 1168 } 1169 } 1170 } 1171 if (m_pFontFile == NULL && m_Charset == CIDSET_JAPAN1) { 1172 FX_WORD CID = CIDFromCharCode(charcode); 1173 FX_LPCBYTE pTransform = GetCIDTransform(CID); 1174 if (pTransform && !bVert) { 1175 CFX_AffineMatrix matrix(_CIDTransformToFloat(pTransform[0]), _CIDTransformToFloat(pTransform[1]), 1176 _CIDTransformToFloat(pTransform[2]), _CIDTransformToFloat(pTransform[3]), 1177 _CIDTransformToFloat(pTransform[4]) * 1000 , _CIDTransformToFloat(pTransform[5]) * 1000); 1178 CFX_FloatRect rect_f(rect); 1179 rect_f.Transform(&matrix); 1180 rect = rect_f.GetOutterRect(); 1181 } 1182 } 1183 if (charcode < 256) { 1184 m_CharBBox[charcode].Bottom = (short)rect.bottom; 1185 m_CharBBox[charcode].Left = (short)rect.left; 1186 m_CharBBox[charcode].Right = (short)rect.right; 1187 m_CharBBox[charcode].Top = (short)rect.top; 1188 } 1189 } 1190 int CPDF_CIDFont::GetCharWidthF(FX_DWORD charcode, int level) 1191 { 1192 if (m_pAnsiWidths && charcode < 0x80) { 1193 return m_pAnsiWidths[charcode]; 1194 } 1195 FX_WORD cid = CIDFromCharCode(charcode); 1196 int size = m_WidthList.GetSize(); 1197 FX_DWORD* list = m_WidthList.GetData(); 1198 for (int i = 0; i < size; i += 3) { 1199 if (cid >= list[i] && cid <= list[i + 1]) { 1200 return (int)list[i + 2]; 1201 } 1202 } 1203 return m_DefaultWidth; 1204 } 1205 short CPDF_CIDFont::GetVertWidth(FX_WORD CID) const 1206 { 1207 FX_DWORD vertsize = m_VertMetrics.GetSize() / 5; 1208 if (vertsize == 0) { 1209 return m_DefaultW1; 1210 } 1211 const FX_DWORD* pTable = m_VertMetrics.GetData(); 1212 for (FX_DWORD i = 0; i < vertsize; i ++) 1213 if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) { 1214 return (short)(int)pTable[i * 5 + 2]; 1215 } 1216 return m_DefaultW1; 1217 } 1218 void CPDF_CIDFont::GetVertOrigin(FX_WORD CID, short& vx, short &vy) const 1219 { 1220 FX_DWORD vertsize = m_VertMetrics.GetSize() / 5; 1221 if (vertsize) { 1222 const FX_DWORD* pTable = m_VertMetrics.GetData(); 1223 for (FX_DWORD i = 0; i < vertsize; i ++) 1224 if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) { 1225 vx = (short)(int)pTable[i * 5 + 3]; 1226 vy = (short)(int)pTable[i * 5 + 4]; 1227 return; 1228 } 1229 } 1230 FX_DWORD dwWidth = m_DefaultWidth; 1231 int size = m_WidthList.GetSize(); 1232 const FX_DWORD* list = m_WidthList.GetData(); 1233 for (int i = 0; i < size; i += 3) { 1234 if (CID >= list[i] && CID <= list[i + 1]) { 1235 dwWidth = (FX_WORD)list[i + 2]; 1236 break; 1237 } 1238 } 1239 vx = (short)dwWidth / 2; 1240 vy = (short)m_DefaultVY; 1241 } 1242 int CPDF_CIDFont::GetGlyphIndex(FX_DWORD unicode, FX_BOOL *pVertGlyph) 1243 { 1244 if (pVertGlyph) { 1245 *pVertGlyph = FALSE; 1246 } 1247 int index = FXFT_Get_Char_Index(m_Font.m_Face, unicode ); 1248 if (unicode == 0x2502) { 1249 return index; 1250 } 1251 if (index && IsVertWriting()) { 1252 if (m_pTTGSUBTable) { 1253 TT_uint32_t vindex = 0; 1254 m_pTTGSUBTable->GetVerticalGlyph(index, &vindex); 1255 if (vindex) { 1256 index = vindex; 1257 if (pVertGlyph) { 1258 *pVertGlyph = TRUE; 1259 } 1260 } 1261 return index; 1262 } 1263 if (NULL == m_Font.m_pGsubData) { 1264 unsigned long length = 0; 1265 int error = FXFT_Load_Sfnt_Table( m_Font.m_Face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0, NULL, &length); 1266 if (!error) { 1267 m_Font.m_pGsubData = (unsigned char*)FX_Alloc(FX_BYTE, length); 1268 } 1269 } 1270 int error = FXFT_Load_Sfnt_Table( m_Font.m_Face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0, m_Font.m_pGsubData, NULL); 1271 if (!error && m_Font.m_pGsubData) { 1272 m_pTTGSUBTable = FX_NEW CFX_CTTGSUBTable; 1273 m_pTTGSUBTable->LoadGSUBTable((FT_Bytes)m_Font.m_pGsubData); 1274 TT_uint32_t vindex = 0; 1275 m_pTTGSUBTable->GetVerticalGlyph(index, &vindex); 1276 if (vindex) { 1277 index = vindex; 1278 if (pVertGlyph) { 1279 *pVertGlyph = TRUE; 1280 } 1281 } 1282 } 1283 return index; 1284 } 1285 if (pVertGlyph) { 1286 *pVertGlyph = FALSE; 1287 } 1288 return index; 1289 } 1290 int CPDF_CIDFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL *pVertGlyph) 1291 { 1292 if (pVertGlyph) { 1293 *pVertGlyph = FALSE; 1294 } 1295 if (m_pFontFile == NULL && m_pCIDToGIDMap == NULL) { 1296 FX_WORD cid = CIDFromCharCode(charcode); 1297 FX_WCHAR unicode = 0; 1298 if (m_bCIDIsGID) { 1299 #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ 1300 return cid; 1301 #else 1302 if (m_Flags & PDFFONT_SYMBOLIC) { 1303 return cid; 1304 } 1305 CFX_WideString uni_str = UnicodeFromCharCode(charcode); 1306 if (uni_str.IsEmpty()) { 1307 return cid; 1308 } 1309 unicode = uni_str.GetAt(0); 1310 #endif 1311 } else { 1312 if (cid && m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded()) { 1313 unicode = m_pCID2UnicodeMap->UnicodeFromCID(cid); 1314 } 1315 if (unicode == 0) { 1316 unicode = _UnicodeFromCharCode(charcode); 1317 } 1318 if (unicode == 0 && !(m_Flags & PDFFONT_SYMBOLIC)) { 1319 unicode = UnicodeFromCharCode(charcode).GetAt(0); 1320 } 1321 } 1322 if (unicode == 0) { 1323 if (!m_bAdobeCourierStd) { 1324 return charcode == 0 ? -1 : (int)charcode; 1325 } 1326 charcode += 31; 1327 int index = 0, iBaseEncoding; 1328 FX_BOOL bMSUnicode = FT_UseTTCharmap(m_Font.m_Face, 3, 1); 1329 FX_BOOL bMacRoman = FALSE; 1330 if (!bMSUnicode) { 1331 bMacRoman = FT_UseTTCharmap(m_Font.m_Face, 1, 0); 1332 } 1333 iBaseEncoding = PDFFONT_ENCODING_STANDARD; 1334 if (bMSUnicode) { 1335 iBaseEncoding = PDFFONT_ENCODING_WINANSI; 1336 } else if (bMacRoman) { 1337 iBaseEncoding = PDFFONT_ENCODING_MACROMAN; 1338 } 1339 FX_LPCSTR name = GetAdobeCharName(iBaseEncoding, NULL, charcode); 1340 if (name == NULL) { 1341 return charcode == 0 ? -1 : (int)charcode; 1342 } 1343 FX_WORD unicode = PDF_UnicodeFromAdobeName(name); 1344 if (unicode) { 1345 if (bMSUnicode) { 1346 index = FXFT_Get_Char_Index(m_Font.m_Face, unicode); 1347 } else if (bMacRoman) { 1348 FX_DWORD maccode = FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, unicode); 1349 index = !maccode ? FXFT_Get_Name_Index(m_Font.m_Face, (char *)name) : FXFT_Get_Char_Index(m_Font.m_Face, maccode); 1350 } else { 1351 return FXFT_Get_Char_Index(m_Font.m_Face, unicode); 1352 } 1353 } else { 1354 return charcode == 0 ? -1 : (int)charcode; 1355 } 1356 if (index == 0 || index == 0xffff) { 1357 return charcode == 0 ? -1 : (int)charcode; 1358 } else { 1359 return index; 1360 } 1361 } 1362 if (m_Charset == CIDSET_JAPAN1) { 1363 if (unicode == '\\') { 1364 unicode = '/'; 1365 } 1366 #if !defined(_FPDFAPI_MINI_) && _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ 1367 else if (unicode == 0xa5) { 1368 unicode = 0x5c; 1369 } 1370 #endif 1371 } 1372 if (m_Font.m_Face == NULL) { 1373 return unicode; 1374 } 1375 int err = FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE); 1376 if (err != 0) { 1377 int i; 1378 for (i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.m_Face); i ++) { 1379 FX_DWORD ret = FT_CharCodeFromUnicode(FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(m_Font.m_Face)[i]), (FX_WCHAR)charcode); 1380 if (ret == 0) { 1381 continue; 1382 } 1383 FXFT_Set_Charmap(m_Font.m_Face, FXFT_Get_Face_Charmaps(m_Font.m_Face)[i]); 1384 unicode = (FX_WCHAR)ret; 1385 break; 1386 } 1387 if (i == FXFT_Get_Face_CharmapCount(m_Font.m_Face) && i) { 1388 FXFT_Set_Charmap(m_Font.m_Face, FXFT_Get_Face_Charmaps(m_Font.m_Face)[0]); 1389 unicode = (FX_WCHAR)charcode; 1390 } 1391 } 1392 if (FXFT_Get_Face_Charmap(m_Font.m_Face)) { 1393 int index = GetGlyphIndex(unicode, pVertGlyph); 1394 if (index == 0) { 1395 return -1; 1396 } 1397 return index; 1398 } 1399 return unicode ; 1400 } 1401 if (m_Font.m_Face == NULL) { 1402 return -1; 1403 } 1404 FX_WORD cid = CIDFromCharCode(charcode); 1405 if (m_bType1) { 1406 if (NULL == m_pCIDToGIDMap) { 1407 return cid; 1408 } 1409 } else { 1410 if (m_pCIDToGIDMap == NULL) { 1411 if (m_pFontFile && m_pCMap->m_pMapping == NULL) { 1412 return cid; 1413 } 1414 if (m_pCMap->m_Coding == CIDCODING_UNKNOWN || FXFT_Get_Face_Charmap(m_Font.m_Face) == NULL) { 1415 return cid; 1416 } 1417 if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmap(m_Font.m_Face)) == FXFT_ENCODING_UNICODE) { 1418 CFX_WideString unicode_str = UnicodeFromCharCode(charcode); 1419 if (unicode_str.IsEmpty()) { 1420 return -1; 1421 } 1422 charcode = unicode_str.GetAt(0); 1423 } 1424 return GetGlyphIndex(charcode, pVertGlyph); 1425 } 1426 } 1427 FX_DWORD byte_pos = cid * 2; 1428 if (byte_pos + 2 > m_pCIDToGIDMap->GetSize()) { 1429 return -1; 1430 } 1431 FX_LPCBYTE pdata = m_pCIDToGIDMap->GetData() + byte_pos; 1432 return pdata[0] * 256 + pdata[1]; 1433 } 1434 FX_DWORD CPDF_CIDFont::GetNextChar(FX_LPCSTR pString, int& offset) const 1435 { 1436 return m_pCMap->GetNextChar(pString, offset); 1437 } 1438 int CPDF_CIDFont::GetCharSize(FX_DWORD charcode) const 1439 { 1440 return m_pCMap->GetCharSize(charcode); 1441 } 1442 int CPDF_CIDFont::CountChar(FX_LPCSTR pString, int size) const 1443 { 1444 return m_pCMap->CountChar(pString, size); 1445 } 1446 int CPDF_CIDFont::AppendChar(FX_LPSTR str, FX_DWORD charcode) const 1447 { 1448 return m_pCMap->AppendChar(str, charcode); 1449 } 1450 FX_BOOL CPDF_CIDFont::IsUnicodeCompatible() const 1451 { 1452 if (!m_pCMap->IsLoaded() || m_pCID2UnicodeMap == NULL || !m_pCID2UnicodeMap->IsLoaded()) { 1453 return m_pCMap->m_Coding != CIDCODING_UNKNOWN; 1454 } 1455 return TRUE; 1456 } 1457 FX_BOOL CPDF_CIDFont::IsFontStyleFromCharCode(FX_DWORD charcode) const 1458 { 1459 return TRUE; 1460 } 1461 void CPDF_CIDFont::LoadSubstFont() 1462 { 1463 m_Font.LoadSubst(m_BaseFont, !m_bType1, m_Flags, m_StemV * 5, m_ItalicAngle, g_CharsetCPs[m_Charset], IsVertWriting()); 1464 } 1465 void CPDF_CIDFont::LoadMetricsArray(CPDF_Array* pArray, CFX_DWordArray& result, int nElements) 1466 { 1467 int width_status = 0; 1468 int iCurElement = 0; 1469 int first_code = 0, last_code; 1470 FX_DWORD count = pArray->GetCount(); 1471 for (FX_DWORD i = 0; i < count; i ++) { 1472 CPDF_Object* pObj = pArray->GetElementValue(i); 1473 if (pObj == NULL) { 1474 continue; 1475 } 1476 if (pObj->GetType() == PDFOBJ_ARRAY) { 1477 if (width_status != 1) { 1478 return; 1479 } 1480 CPDF_Array* pArray = (CPDF_Array*)pObj; 1481 FX_DWORD count = pArray->GetCount(); 1482 for (FX_DWORD j = 0; j < count; j += nElements) { 1483 result.Add(first_code); 1484 result.Add(first_code); 1485 for (int k = 0; k < nElements; k ++) { 1486 result.Add(pArray->GetInteger(j + k)); 1487 } 1488 first_code ++; 1489 } 1490 width_status = 0; 1491 } else { 1492 if (width_status == 0) { 1493 first_code = pObj->GetInteger(); 1494 width_status = 1; 1495 } else if (width_status == 1) { 1496 last_code = pObj->GetInteger(); 1497 width_status = 2; 1498 iCurElement = 0; 1499 } else { 1500 if (!iCurElement) { 1501 result.Add(first_code); 1502 result.Add(last_code); 1503 } 1504 result.Add(pObj->GetInteger()); 1505 iCurElement ++; 1506 if (iCurElement == nElements) { 1507 width_status = 0; 1508 } 1509 } 1510 } 1511 } 1512 } 1513 FX_BOOL CPDF_CIDFont::LoadGB2312() 1514 { 1515 m_BaseFont = m_pFontDict->GetString(FX_BSTRC("BaseFont")); 1516 CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict(FX_BSTRC("FontDescriptor")); 1517 if (pFontDesc) { 1518 LoadFontDescriptor(pFontDesc); 1519 } 1520 m_Charset = CIDSET_GB1; 1521 m_bType1 = FALSE; 1522 m_pCMap = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals()->m_CMapManager.GetPredefinedCMap( 1523 FX_BSTRC("GBK-EUC-H"), FALSE); 1524 m_pCID2UnicodeMap = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals()->m_CMapManager.GetCID2UnicodeMap(m_Charset, FALSE); 1525 if (!IsEmbedded()) { 1526 LoadSubstFont(); 1527 } 1528 CheckFontMetrics(); 1529 m_DefaultWidth = 1000; 1530 m_pAnsiWidths = FX_Alloc(FX_WORD, 128); 1531 FXSYS_memset32(m_pAnsiWidths, 0, 128 * sizeof(FX_WORD)); 1532 for (int i = 32; i < 127; i ++) { 1533 m_pAnsiWidths[i] = 500; 1534 } 1535 return TRUE; 1536 } 1537 const struct _CIDTransform { 1538 FX_WORD CID; 1539 FX_BYTE a, b, c, d, e, f; 1540 } 1541 Japan1_VertCIDs[] = { 1542 {97, 129, 0, 0, 127, 55, 0}, 1543 {7887, 127, 0, 0, 127, 76, 89}, 1544 {7888, 127, 0, 0, 127, 79, 94}, 1545 {7889, 0, 129, 127, 0, 17, 127}, 1546 {7890, 0, 129, 127, 0, 17, 127}, 1547 {7891, 0, 129, 127, 0, 17, 127}, 1548 {7892, 0, 129, 127, 0, 17, 127}, 1549 {7893, 0, 129, 127, 0, 17, 127}, 1550 {7894, 0, 129, 127, 0, 17, 127}, 1551 {7895, 0, 129, 127, 0, 17, 127}, 1552 {7896, 0, 129, 127, 0, 17, 127}, 1553 {7897, 0, 129, 127, 0, 17, 127}, 1554 {7898, 0, 129, 127, 0, 17, 127}, 1555 {7899, 0, 129, 127, 0, 17, 104}, 1556 {7900, 0, 129, 127, 0, 17, 127}, 1557 {7901, 0, 129, 127, 0, 17, 104}, 1558 {7902, 0, 129, 127, 0, 17, 127}, 1559 {7903, 0, 129, 127, 0, 17, 127}, 1560 {7904, 0, 129, 127, 0, 17, 127}, 1561 {7905, 0, 129, 127, 0, 17, 114}, 1562 {7906, 0, 129, 127, 0, 17, 127}, 1563 {7907, 0, 129, 127, 0, 17, 127}, 1564 {7908, 0, 129, 127, 0, 17, 127}, 1565 {7909, 0, 129, 127, 0, 17, 127}, 1566 {7910, 0, 129, 127, 0, 17, 127}, 1567 {7911, 0, 129, 127, 0, 17, 127}, 1568 {7912, 0, 129, 127, 0, 17, 127}, 1569 {7913, 0, 129, 127, 0, 17, 127}, 1570 {7914, 0, 129, 127, 0, 17, 127}, 1571 {7915, 0, 129, 127, 0, 17, 114}, 1572 {7916, 0, 129, 127, 0, 17, 127}, 1573 {7917, 0, 129, 127, 0, 17, 127}, 1574 {7918, 127, 0, 0, 127, 18, 25}, 1575 {7919, 127, 0, 0, 127, 18, 25}, 1576 {7920, 127, 0, 0, 127, 18, 25}, 1577 {7921, 127, 0, 0, 127, 18, 25}, 1578 {7922, 127, 0, 0, 127, 18, 25}, 1579 {7923, 127, 0, 0, 127, 18, 25}, 1580 {7924, 127, 0, 0, 127, 18, 25}, 1581 {7925, 127, 0, 0, 127, 18, 25}, 1582 {7926, 127, 0, 0, 127, 18, 25}, 1583 {7927, 127, 0, 0, 127, 18, 25}, 1584 {7928, 127, 0, 0, 127, 18, 25}, 1585 {7929, 127, 0, 0, 127, 18, 25}, 1586 {7930, 127, 0, 0, 127, 18, 25}, 1587 {7931, 127, 0, 0, 127, 18, 25}, 1588 {7932, 127, 0, 0, 127, 18, 25}, 1589 {7933, 127, 0, 0, 127, 18, 25}, 1590 {7934, 127, 0, 0, 127, 18, 25}, 1591 {7935, 127, 0, 0, 127, 18, 25}, 1592 {7936, 127, 0, 0, 127, 18, 25}, 1593 {7937, 127, 0, 0, 127, 18, 25}, 1594 {7938, 127, 0, 0, 127, 18, 25}, 1595 {7939, 127, 0, 0, 127, 18, 25}, 1596 {8720, 0, 129, 127, 0, 19, 102}, 1597 {8721, 0, 129, 127, 0, 13, 127}, 1598 {8722, 0, 129, 127, 0, 19, 108}, 1599 {8723, 0, 129, 127, 0, 19, 102}, 1600 {8724, 0, 129, 127, 0, 19, 102}, 1601 {8725, 0, 129, 127, 0, 19, 102}, 1602 {8726, 0, 129, 127, 0, 19, 102}, 1603 {8727, 0, 129, 127, 0, 19, 102}, 1604 {8728, 0, 129, 127, 0, 19, 114}, 1605 {8729, 0, 129, 127, 0, 19, 114}, 1606 {8730, 0, 129, 127, 0, 38, 108}, 1607 {8731, 0, 129, 127, 0, 13, 108}, 1608 {8732, 0, 129, 127, 0, 19, 108}, 1609 {8733, 0, 129, 127, 0, 19, 108}, 1610 {8734, 0, 129, 127, 0, 19, 108}, 1611 {8735, 0, 129, 127, 0, 19, 108}, 1612 {8736, 0, 129, 127, 0, 19, 102}, 1613 {8737, 0, 129, 127, 0, 19, 102}, 1614 {8738, 0, 129, 127, 0, 19, 102}, 1615 {8739, 0, 129, 127, 0, 19, 102}, 1616 {8740, 0, 129, 127, 0, 19, 102}, 1617 {8741, 0, 129, 127, 0, 19, 102}, 1618 {8742, 0, 129, 127, 0, 19, 102}, 1619 {8743, 0, 129, 127, 0, 19, 102}, 1620 {8744, 0, 129, 127, 0, 19, 102}, 1621 {8745, 0, 129, 127, 0, 19, 102}, 1622 {8746, 0, 129, 127, 0, 19, 114}, 1623 {8747, 0, 129, 127, 0, 19, 114}, 1624 {8748, 0, 129, 127, 0, 19, 102}, 1625 {8749, 0, 129, 127, 0, 19, 102}, 1626 {8750, 0, 129, 127, 0, 19, 102}, 1627 {8751, 0, 129, 127, 0, 19, 102}, 1628 {8752, 0, 129, 127, 0, 19, 102}, 1629 {8753, 0, 129, 127, 0, 19, 102}, 1630 {8754, 0, 129, 127, 0, 19, 102}, 1631 {8755, 0, 129, 127, 0, 19, 102}, 1632 {8756, 0, 129, 127, 0, 19, 102}, 1633 {8757, 0, 129, 127, 0, 19, 102}, 1634 {8758, 0, 129, 127, 0, 19, 102}, 1635 {8759, 0, 129, 127, 0, 19, 102}, 1636 {8760, 0, 129, 127, 0, 19, 102}, 1637 {8761, 0, 129, 127, 0, 19, 102}, 1638 {8762, 0, 129, 127, 0, 19, 102}, 1639 {8763, 0, 129, 127, 0, 19, 102}, 1640 {8764, 0, 129, 127, 0, 19, 102}, 1641 {8765, 0, 129, 127, 0, 19, 102}, 1642 {8766, 0, 129, 127, 0, 19, 102}, 1643 {8767, 0, 129, 127, 0, 19, 102}, 1644 {8768, 0, 129, 127, 0, 19, 102}, 1645 {8769, 0, 129, 127, 0, 19, 102}, 1646 {8770, 0, 129, 127, 0, 19, 102}, 1647 {8771, 0, 129, 127, 0, 19, 102}, 1648 {8772, 0, 129, 127, 0, 19, 102}, 1649 {8773, 0, 129, 127, 0, 19, 102}, 1650 {8774, 0, 129, 127, 0, 19, 102}, 1651 {8775, 0, 129, 127, 0, 19, 102}, 1652 {8776, 0, 129, 127, 0, 19, 102}, 1653 {8777, 0, 129, 127, 0, 19, 102}, 1654 {8778, 0, 129, 127, 0, 19, 102}, 1655 {8779, 0, 129, 127, 0, 19, 114}, 1656 {8780, 0, 129, 127, 0, 19, 108}, 1657 {8781, 0, 129, 127, 0, 19, 114}, 1658 {8782, 0, 129, 127, 0, 13, 114}, 1659 {8783, 0, 129, 127, 0, 19, 108}, 1660 {8784, 0, 129, 127, 0, 13, 114}, 1661 {8785, 0, 129, 127, 0, 19, 108}, 1662 {8786, 0, 129, 127, 0, 19, 108}, 1663 {8787, 0, 129, 127, 0, 19, 108}, 1664 {8788, 0, 129, 127, 0, 19, 108}, 1665 {8789, 0, 129, 127, 0, 19, 108}, 1666 {8790, 0, 129, 127, 0, 19, 108}, 1667 {8791, 0, 129, 127, 0, 19, 108}, 1668 {8792, 0, 129, 127, 0, 19, 108}, 1669 {8793, 0, 129, 127, 0, 19, 108}, 1670 {8794, 0, 129, 127, 0, 19, 108}, 1671 {8795, 0, 129, 127, 0, 19, 108}, 1672 {8796, 0, 129, 127, 0, 19, 108}, 1673 {8797, 0, 129, 127, 0, 19, 108}, 1674 {8798, 0, 129, 127, 0, 19, 108}, 1675 {8799, 0, 129, 127, 0, 19, 108}, 1676 {8800, 0, 129, 127, 0, 19, 108}, 1677 {8801, 0, 129, 127, 0, 19, 108}, 1678 {8802, 0, 129, 127, 0, 19, 108}, 1679 {8803, 0, 129, 127, 0, 19, 108}, 1680 {8804, 0, 129, 127, 0, 19, 108}, 1681 {8805, 0, 129, 127, 0, 19, 108}, 1682 {8806, 0, 129, 127, 0, 19, 108}, 1683 {8807, 0, 129, 127, 0, 19, 108}, 1684 {8808, 0, 129, 127, 0, 19, 108}, 1685 {8809, 0, 129, 127, 0, 19, 108}, 1686 {8810, 0, 129, 127, 0, 19, 108}, 1687 {8811, 0, 129, 127, 0, 19, 114}, 1688 {8812, 0, 129, 127, 0, 19, 102}, 1689 {8813, 0, 129, 127, 0, 19, 114}, 1690 {8814, 0, 129, 127, 0, 76, 102}, 1691 {8815, 0, 129, 127, 0, 13, 121}, 1692 {8816, 0, 129, 127, 0, 19, 114}, 1693 {8817, 0, 129, 127, 0, 19, 127}, 1694 {8818, 0, 129, 127, 0, 19, 114}, 1695 {8819, 0, 129, 127, 0, 218, 108}, 1696 }; 1697 FX_LPCBYTE CPDF_CIDFont::GetCIDTransform(FX_WORD CID) const 1698 { 1699 if (m_Charset != CIDSET_JAPAN1 || m_pFontFile != NULL) { 1700 return NULL; 1701 } 1702 int begin = 0; 1703 int end = sizeof Japan1_VertCIDs / sizeof(struct _CIDTransform) - 1; 1704 while (begin <= end) { 1705 int middle = (begin + end) / 2; 1706 FX_WORD middlecode = Japan1_VertCIDs[middle].CID; 1707 if (middlecode > CID) { 1708 end = middle - 1; 1709 } else if (middlecode < CID) { 1710 begin = middle + 1; 1711 } else { 1712 return &Japan1_VertCIDs[middle].a; 1713 } 1714 } 1715 return NULL; 1716 } 1717