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