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