| 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 "core/fpdfapi/fpdf_font/font_int.h" | 7 #include "core/fpdfapi/fpdf_font/font_int.h" |
| 8 | 8 |
| 9 #include "core/fpdfapi/fpdf_cmaps/cmap_int.h" | 9 #include "core/fpdfapi/fpdf_cmaps/cmap_int.h" |
| 10 #include "core/fpdfapi/fpdf_font/ttgsubtable.h" | 10 #include "core/fpdfapi/fpdf_font/ttgsubtable.h" |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 | 299 |
| 300 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ | 300 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ |
| 301 FX_DWORD EmbeddedCharcodeFromUnicode(const FXCMAP_CMap* pEmbedMap, | 301 FX_DWORD EmbeddedCharcodeFromUnicode(const FXCMAP_CMap* pEmbedMap, |
| 302 CIDSet charset, | 302 CIDSet charset, |
| 303 FX_WCHAR unicode) { | 303 FX_WCHAR unicode) { |
| 304 if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset)) | 304 if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset)) |
| 305 return 0; | 305 return 0; |
| 306 | 306 |
| 307 CPDF_FontGlobals* pFontGlobals = | 307 CPDF_FontGlobals* pFontGlobals = |
| 308 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); | 308 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); |
| 309 const FX_WORD* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap; | 309 const uint16_t* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap; |
| 310 if (!pCodes) | 310 if (!pCodes) |
| 311 return 0; | 311 return 0; |
| 312 | 312 |
| 313 int nCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count; | 313 int nCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count; |
| 314 for (int i = 0; i < nCodes; ++i) { | 314 for (int i = 0; i < nCodes; ++i) { |
| 315 if (pCodes[i] == unicode) { | 315 if (pCodes[i] == unicode) { |
| 316 FX_DWORD CharCode = FPDFAPI_CharCodeFromCID(pEmbedMap, i); | 316 FX_DWORD CharCode = FPDFAPI_CharCodeFromCID(pEmbedMap, i); |
| 317 if (CharCode != 0) { | 317 if (CharCode != 0) { |
| 318 return CharCode; | 318 return CharCode; |
| 319 } | 319 } |
| 320 } | 320 } |
| 321 } | 321 } |
| 322 return 0; | 322 return 0; |
| 323 } | 323 } |
| 324 #endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ | 324 #endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ |
| 325 | 325 |
| 326 FX_WCHAR EmbeddedUnicodeFromCharcode(const FXCMAP_CMap* pEmbedMap, | 326 FX_WCHAR EmbeddedUnicodeFromCharcode(const FXCMAP_CMap* pEmbedMap, |
| 327 CIDSet charset, | 327 CIDSet charset, |
| 328 FX_DWORD charcode) { | 328 FX_DWORD charcode) { |
| 329 if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset)) | 329 if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset)) |
| 330 return 0; | 330 return 0; |
| 331 | 331 |
| 332 FX_WORD cid = FPDFAPI_CIDFromCharCode(pEmbedMap, charcode); | 332 uint16_t cid = FPDFAPI_CIDFromCharCode(pEmbedMap, charcode); |
| 333 if (cid == 0) | 333 if (cid == 0) |
| 334 return 0; | 334 return 0; |
| 335 | 335 |
| 336 CPDF_FontGlobals* pFontGlobals = | 336 CPDF_FontGlobals* pFontGlobals = |
| 337 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); | 337 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); |
| 338 const FX_WORD* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap; | 338 const uint16_t* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap; |
| 339 if (!pCodes) | 339 if (!pCodes) |
| 340 return 0; | 340 return 0; |
| 341 | 341 |
| 342 if (cid < pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count) | 342 if (cid < pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count) |
| 343 return pCodes[cid]; | 343 return pCodes[cid]; |
| 344 return 0; | 344 return 0; |
| 345 } | 345 } |
| 346 | 346 |
| 347 void FT_UseCIDCharmap(FXFT_Face face, int coding) { | 347 void FT_UseCIDCharmap(FXFT_Face face, int coding) { |
| 348 int encoding; | 348 int encoding; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 365 int err = FXFT_Select_Charmap(face, encoding); | 365 int err = FXFT_Select_Charmap(face, encoding); |
| 366 if (err) { | 366 if (err) { |
| 367 err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE); | 367 err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE); |
| 368 } | 368 } |
| 369 if (err && FXFT_Get_Face_Charmaps(face)) { | 369 if (err && FXFT_Get_Face_Charmaps(face)) { |
| 370 FXFT_Set_Charmap(face, *FXFT_Get_Face_Charmaps(face)); | 370 FXFT_Set_Charmap(face, *FXFT_Get_Face_Charmaps(face)); |
| 371 } | 371 } |
| 372 } | 372 } |
| 373 | 373 |
| 374 const struct CIDTransform { | 374 const struct CIDTransform { |
| 375 FX_WORD CID; | 375 uint16_t CID; |
| 376 uint8_t a, b, c, d, e, f; | 376 uint8_t a, b, c, d, e, f; |
| 377 } g_Japan1_VertCIDs[] = { | 377 } g_Japan1_VertCIDs[] = { |
| 378 {97, 129, 0, 0, 127, 55, 0}, {7887, 127, 0, 0, 127, 76, 89}, | 378 {97, 129, 0, 0, 127, 55, 0}, {7887, 127, 0, 0, 127, 76, 89}, |
| 379 {7888, 127, 0, 0, 127, 79, 94}, {7889, 0, 129, 127, 0, 17, 127}, | 379 {7888, 127, 0, 0, 127, 79, 94}, {7889, 0, 129, 127, 0, 17, 127}, |
| 380 {7890, 0, 129, 127, 0, 17, 127}, {7891, 0, 129, 127, 0, 17, 127}, | 380 {7890, 0, 129, 127, 0, 17, 127}, {7891, 0, 129, 127, 0, 17, 127}, |
| 381 {7892, 0, 129, 127, 0, 17, 127}, {7893, 0, 129, 127, 0, 17, 127}, | 381 {7892, 0, 129, 127, 0, 17, 127}, {7893, 0, 129, 127, 0, 17, 127}, |
| 382 {7894, 0, 129, 127, 0, 17, 127}, {7895, 0, 129, 127, 0, 17, 127}, | 382 {7894, 0, 129, 127, 0, 17, 127}, {7895, 0, 129, 127, 0, 17, 127}, |
| 383 {7896, 0, 129, 127, 0, 17, 127}, {7897, 0, 129, 127, 0, 17, 127}, | 383 {7896, 0, 129, 127, 0, 17, 127}, {7897, 0, 129, 127, 0, 17, 127}, |
| 384 {7898, 0, 129, 127, 0, 17, 127}, {7899, 0, 129, 127, 0, 17, 104}, | 384 {7898, 0, 129, 127, 0, 17, 127}, {7899, 0, 129, 127, 0, 17, 104}, |
| 385 {7900, 0, 129, 127, 0, 17, 127}, {7901, 0, 129, 127, 0, 17, 104}, | 385 {7900, 0, 129, 127, 0, 17, 127}, {7901, 0, 129, 127, 0, 17, 104}, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 {8806, 0, 129, 127, 0, 19, 108}, {8807, 0, 129, 127, 0, 19, 108}, | 448 {8806, 0, 129, 127, 0, 19, 108}, {8807, 0, 129, 127, 0, 19, 108}, |
| 449 {8808, 0, 129, 127, 0, 19, 108}, {8809, 0, 129, 127, 0, 19, 108}, | 449 {8808, 0, 129, 127, 0, 19, 108}, {8809, 0, 129, 127, 0, 19, 108}, |
| 450 {8810, 0, 129, 127, 0, 19, 108}, {8811, 0, 129, 127, 0, 19, 114}, | 450 {8810, 0, 129, 127, 0, 19, 108}, {8811, 0, 129, 127, 0, 19, 114}, |
| 451 {8812, 0, 129, 127, 0, 19, 102}, {8813, 0, 129, 127, 0, 19, 114}, | 451 {8812, 0, 129, 127, 0, 19, 102}, {8813, 0, 129, 127, 0, 19, 114}, |
| 452 {8814, 0, 129, 127, 0, 76, 102}, {8815, 0, 129, 127, 0, 13, 121}, | 452 {8814, 0, 129, 127, 0, 76, 102}, {8815, 0, 129, 127, 0, 13, 121}, |
| 453 {8816, 0, 129, 127, 0, 19, 114}, {8817, 0, 129, 127, 0, 19, 127}, | 453 {8816, 0, 129, 127, 0, 19, 114}, {8817, 0, 129, 127, 0, 19, 127}, |
| 454 {8818, 0, 129, 127, 0, 19, 114}, {8819, 0, 129, 127, 0, 218, 108}, | 454 {8818, 0, 129, 127, 0, 19, 114}, {8819, 0, 129, 127, 0, 218, 108}, |
| 455 }; | 455 }; |
| 456 | 456 |
| 457 int CompareCIDTransform(const void* key, const void* element) { | 457 int CompareCIDTransform(const void* key, const void* element) { |
| 458 FX_WORD CID = *static_cast<const FX_WORD*>(key); | 458 uint16_t CID = *static_cast<const uint16_t*>(key); |
| 459 return CID - static_cast<const struct CIDTransform*>(element)->CID; | 459 return CID - static_cast<const struct CIDTransform*>(element)->CID; |
| 460 } | 460 } |
| 461 | 461 |
| 462 } // namespace | 462 } // namespace |
| 463 | 463 |
| 464 CPDF_CMapManager::CPDF_CMapManager() { | 464 CPDF_CMapManager::CPDF_CMapManager() { |
| 465 m_bPrompted = FALSE; | 465 m_bPrompted = FALSE; |
| 466 FXSYS_memset(m_CID2UnicodeMaps, 0, sizeof m_CID2UnicodeMaps); | 466 FXSYS_memset(m_CID2UnicodeMaps, 0, sizeof m_CID2UnicodeMaps); |
| 467 } | 467 } |
| 468 CPDF_CMapManager::~CPDF_CMapManager() { | 468 CPDF_CMapManager::~CPDF_CMapManager() { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 } else if (word == "/Supplement") { | 558 } else if (word == "/Supplement") { |
| 559 m_Status = 5; | 559 m_Status = 5; |
| 560 } else if (word == "begincodespacerange") { | 560 } else if (word == "begincodespacerange") { |
| 561 m_Status = 7; | 561 m_Status = 7; |
| 562 m_CodeSeq = 0; | 562 m_CodeSeq = 0; |
| 563 } else if (word == "usecmap") { | 563 } else if (word == "usecmap") { |
| 564 } else if (m_Status == 1 || m_Status == 2) { | 564 } else if (m_Status == 1 || m_Status == 2) { |
| 565 m_CodePoints[m_CodeSeq] = CMap_GetCode(word); | 565 m_CodePoints[m_CodeSeq] = CMap_GetCode(word); |
| 566 m_CodeSeq++; | 566 m_CodeSeq++; |
| 567 FX_DWORD StartCode, EndCode; | 567 FX_DWORD StartCode, EndCode; |
| 568 FX_WORD StartCID; | 568 uint16_t StartCID; |
| 569 if (m_Status == 1) { | 569 if (m_Status == 1) { |
| 570 if (m_CodeSeq < 2) { | 570 if (m_CodeSeq < 2) { |
| 571 return; | 571 return; |
| 572 } | 572 } |
| 573 EndCode = StartCode = m_CodePoints[0]; | 573 EndCode = StartCode = m_CodePoints[0]; |
| 574 StartCID = (FX_WORD)m_CodePoints[1]; | 574 StartCID = (uint16_t)m_CodePoints[1]; |
| 575 } else { | 575 } else { |
| 576 if (m_CodeSeq < 3) { | 576 if (m_CodeSeq < 3) { |
| 577 return; | 577 return; |
| 578 } | 578 } |
| 579 StartCode = m_CodePoints[0]; | 579 StartCode = m_CodePoints[0]; |
| 580 EndCode = m_CodePoints[1]; | 580 EndCode = m_CodePoints[1]; |
| 581 StartCID = (FX_WORD)m_CodePoints[2]; | 581 StartCID = (uint16_t)m_CodePoints[2]; |
| 582 } | 582 } |
| 583 if (EndCode < 0x10000) { | 583 if (EndCode < 0x10000) { |
| 584 for (FX_DWORD code = StartCode; code <= EndCode; code++) { | 584 for (FX_DWORD code = StartCode; code <= EndCode; code++) { |
| 585 m_pCMap->m_pMapping[code] = (FX_WORD)(StartCID + code - StartCode); | 585 m_pCMap->m_pMapping[code] = (uint16_t)(StartCID + code - StartCode); |
| 586 } | 586 } |
| 587 } else { | 587 } else { |
| 588 FX_DWORD buf[2]; | 588 FX_DWORD buf[2]; |
| 589 buf[0] = StartCode; | 589 buf[0] = StartCode; |
| 590 buf[1] = ((EndCode - StartCode) << 16) + StartCID; | 590 buf[1] = ((EndCode - StartCode) << 16) + StartCID; |
| 591 m_AddMaps.AppendBlock(buf, sizeof buf); | 591 m_AddMaps.AppendBlock(buf, sizeof buf); |
| 592 } | 592 } |
| 593 m_CodeSeq = 0; | 593 m_CodeSeq = 0; |
| 594 } else if (m_Status == 3) { | 594 } else if (m_Status == 3) { |
| 595 CMap_GetString(word); | 595 CMap_GetString(word); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 } | 748 } |
| 749 } | 749 } |
| 750 FPDFAPI_FindEmbeddedCMap(pName, m_Charset, m_Coding, m_pEmbedMap); | 750 FPDFAPI_FindEmbeddedCMap(pName, m_Charset, m_Coding, m_pEmbedMap); |
| 751 if (m_pEmbedMap) { | 751 if (m_pEmbedMap) { |
| 752 m_bLoaded = TRUE; | 752 m_bLoaded = TRUE; |
| 753 return TRUE; | 753 return TRUE; |
| 754 } | 754 } |
| 755 return FALSE; | 755 return FALSE; |
| 756 } | 756 } |
| 757 FX_BOOL CPDF_CMap::LoadEmbedded(const uint8_t* pData, FX_DWORD size) { | 757 FX_BOOL CPDF_CMap::LoadEmbedded(const uint8_t* pData, FX_DWORD size) { |
| 758 m_pMapping = FX_Alloc(FX_WORD, 65536); | 758 m_pMapping = FX_Alloc(uint16_t, 65536); |
| 759 CPDF_CMapParser parser; | 759 CPDF_CMapParser parser; |
| 760 parser.Initialize(this); | 760 parser.Initialize(this); |
| 761 CPDF_SimpleParser syntax(pData, size); | 761 CPDF_SimpleParser syntax(pData, size); |
| 762 while (1) { | 762 while (1) { |
| 763 CFX_ByteStringC word = syntax.GetWord(); | 763 CFX_ByteStringC word = syntax.GetWord(); |
| 764 if (word.IsEmpty()) { | 764 if (word.IsEmpty()) { |
| 765 break; | 765 break; |
| 766 } | 766 } |
| 767 parser.ParseWord(word); | 767 parser.ParseWord(word); |
| 768 } | 768 } |
| 769 if (m_CodingScheme == MixedFourBytes && parser.m_AddMaps.GetSize()) { | 769 if (m_CodingScheme == MixedFourBytes && parser.m_AddMaps.GetSize()) { |
| 770 m_pAddMapping = FX_Alloc(uint8_t, parser.m_AddMaps.GetSize() + 4); | 770 m_pAddMapping = FX_Alloc(uint8_t, parser.m_AddMaps.GetSize() + 4); |
| 771 *(FX_DWORD*)m_pAddMapping = parser.m_AddMaps.GetSize() / 8; | 771 *(FX_DWORD*)m_pAddMapping = parser.m_AddMaps.GetSize() / 8; |
| 772 FXSYS_memcpy(m_pAddMapping + 4, parser.m_AddMaps.GetBuffer(), | 772 FXSYS_memcpy(m_pAddMapping + 4, parser.m_AddMaps.GetBuffer(), |
| 773 parser.m_AddMaps.GetSize()); | 773 parser.m_AddMaps.GetSize()); |
| 774 FXSYS_qsort(m_pAddMapping + 4, parser.m_AddMaps.GetSize() / 8, 8, | 774 FXSYS_qsort(m_pAddMapping + 4, parser.m_AddMaps.GetSize() / 8, 8, |
| 775 CompareDWORD); | 775 CompareDWORD); |
| 776 } | 776 } |
| 777 return TRUE; | 777 return TRUE; |
| 778 } | 778 } |
| 779 | 779 |
| 780 FX_WORD CPDF_CMap::CIDFromCharCode(FX_DWORD charcode) const { | 780 uint16_t CPDF_CMap::CIDFromCharCode(FX_DWORD charcode) const { |
| 781 if (m_Coding == CIDCODING_CID) { | 781 if (m_Coding == CIDCODING_CID) { |
| 782 return (FX_WORD)charcode; | 782 return (uint16_t)charcode; |
| 783 } | 783 } |
| 784 if (m_pEmbedMap) { | 784 if (m_pEmbedMap) { |
| 785 return FPDFAPI_CIDFromCharCode(m_pEmbedMap, charcode); | 785 return FPDFAPI_CIDFromCharCode(m_pEmbedMap, charcode); |
| 786 } | 786 } |
| 787 if (!m_pMapping) { | 787 if (!m_pMapping) { |
| 788 return (FX_WORD)charcode; | 788 return (uint16_t)charcode; |
| 789 } | 789 } |
| 790 if (charcode >> 16) { | 790 if (charcode >> 16) { |
| 791 if (m_pAddMapping) { | 791 if (m_pAddMapping) { |
| 792 void* found = FXSYS_bsearch(&charcode, m_pAddMapping + 4, | 792 void* found = FXSYS_bsearch(&charcode, m_pAddMapping + 4, |
| 793 *(FX_DWORD*)m_pAddMapping, 8, CompareCID); | 793 *(FX_DWORD*)m_pAddMapping, 8, CompareCID); |
| 794 if (!found) { | 794 if (!found) { |
| 795 if (m_pUseMap) { | 795 if (m_pUseMap) { |
| 796 return m_pUseMap->CIDFromCharCode(charcode); | 796 return m_pUseMap->CIDFromCharCode(charcode); |
| 797 } | 797 } |
| 798 return 0; | 798 return 0; |
| 799 } | 799 } |
| 800 return (FX_WORD)(((FX_DWORD*)found)[1] % 65536 + charcode - | 800 return (uint16_t)(((FX_DWORD*)found)[1] % 65536 + charcode - |
| 801 *(FX_DWORD*)found); | 801 *(FX_DWORD*)found); |
| 802 } | 802 } |
| 803 if (m_pUseMap) | 803 if (m_pUseMap) |
| 804 return m_pUseMap->CIDFromCharCode(charcode); | 804 return m_pUseMap->CIDFromCharCode(charcode); |
| 805 return 0; | 805 return 0; |
| 806 } | 806 } |
| 807 FX_DWORD CID = m_pMapping[charcode]; | 807 FX_DWORD CID = m_pMapping[charcode]; |
| 808 if (!CID && m_pUseMap) | 808 if (!CID && m_pUseMap) |
| 809 return m_pUseMap->CIDFromCharCode(charcode); | 809 return m_pUseMap->CIDFromCharCode(charcode); |
| 810 return (FX_WORD)CID; | 810 return (uint16_t)CID; |
| 811 } | 811 } |
| 812 | 812 |
| 813 FX_DWORD CPDF_CMap::GetNextChar(const FX_CHAR* pString, | 813 FX_DWORD CPDF_CMap::GetNextChar(const FX_CHAR* pString, |
| 814 int nStrLen, | 814 int nStrLen, |
| 815 int& offset) const { | 815 int& offset) const { |
| 816 switch (m_CodingScheme) { | 816 switch (m_CodingScheme) { |
| 817 case OneByte: | 817 case OneByte: |
| 818 return ((uint8_t*)pString)[offset++]; | 818 return ((uint8_t*)pString)[offset++]; |
| 819 case TwoBytes: | 819 case TwoBytes: |
| 820 offset += 2; | 820 offset += 2; |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 949 CPDF_CID2UnicodeMap::CPDF_CID2UnicodeMap() { | 949 CPDF_CID2UnicodeMap::CPDF_CID2UnicodeMap() { |
| 950 m_EmbeddedCount = 0; | 950 m_EmbeddedCount = 0; |
| 951 } | 951 } |
| 952 CPDF_CID2UnicodeMap::~CPDF_CID2UnicodeMap() {} | 952 CPDF_CID2UnicodeMap::~CPDF_CID2UnicodeMap() {} |
| 953 FX_BOOL CPDF_CID2UnicodeMap::Initialize() { | 953 FX_BOOL CPDF_CID2UnicodeMap::Initialize() { |
| 954 return TRUE; | 954 return TRUE; |
| 955 } | 955 } |
| 956 FX_BOOL CPDF_CID2UnicodeMap::IsLoaded() { | 956 FX_BOOL CPDF_CID2UnicodeMap::IsLoaded() { |
| 957 return m_EmbeddedCount != 0; | 957 return m_EmbeddedCount != 0; |
| 958 } | 958 } |
| 959 FX_WCHAR CPDF_CID2UnicodeMap::UnicodeFromCID(FX_WORD CID) { | 959 FX_WCHAR CPDF_CID2UnicodeMap::UnicodeFromCID(uint16_t CID) { |
| 960 if (m_Charset == CIDSET_UNICODE) { | 960 if (m_Charset == CIDSET_UNICODE) { |
| 961 return CID; | 961 return CID; |
| 962 } | 962 } |
| 963 if (CID < m_EmbeddedCount) { | 963 if (CID < m_EmbeddedCount) { |
| 964 return m_pEmbeddedMap[CID]; | 964 return m_pEmbeddedMap[CID]; |
| 965 } | 965 } |
| 966 return 0; | 966 return 0; |
| 967 } | 967 } |
| 968 | 968 |
| 969 void CPDF_CID2UnicodeMap::Load(CPDF_CMapManager* pMgr, | 969 void CPDF_CID2UnicodeMap::Load(CPDF_CMapManager* pMgr, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 997 } | 997 } |
| 998 | 998 |
| 999 const CPDF_CIDFont* CPDF_CIDFont::AsCIDFont() const { | 999 const CPDF_CIDFont* CPDF_CIDFont::AsCIDFont() const { |
| 1000 return this; | 1000 return this; |
| 1001 } | 1001 } |
| 1002 | 1002 |
| 1003 CPDF_CIDFont* CPDF_CIDFont::AsCIDFont() { | 1003 CPDF_CIDFont* CPDF_CIDFont::AsCIDFont() { |
| 1004 return this; | 1004 return this; |
| 1005 } | 1005 } |
| 1006 | 1006 |
| 1007 FX_WORD CPDF_CIDFont::CIDFromCharCode(FX_DWORD charcode) const { | 1007 uint16_t CPDF_CIDFont::CIDFromCharCode(FX_DWORD charcode) const { |
| 1008 if (!m_pCMap) { | 1008 if (!m_pCMap) { |
| 1009 return (FX_WORD)charcode; | 1009 return (uint16_t)charcode; |
| 1010 } | 1010 } |
| 1011 return m_pCMap->CIDFromCharCode(charcode); | 1011 return m_pCMap->CIDFromCharCode(charcode); |
| 1012 } | 1012 } |
| 1013 | 1013 |
| 1014 FX_BOOL CPDF_CIDFont::IsVertWriting() const { | 1014 FX_BOOL CPDF_CIDFont::IsVertWriting() const { |
| 1015 return m_pCMap ? m_pCMap->IsVertWriting() : FALSE; | 1015 return m_pCMap ? m_pCMap->IsVertWriting() : FALSE; |
| 1016 } | 1016 } |
| 1017 | 1017 |
| 1018 CFX_WideString CPDF_CIDFont::UnicodeFromCharCode(FX_DWORD charcode) const { | 1018 CFX_WideString CPDF_CIDFont::UnicodeFromCharCode(FX_DWORD charcode) const { |
| 1019 CFX_WideString str = CPDF_Font::UnicodeFromCharCode(charcode); | 1019 CFX_WideString str = CPDF_Font::UnicodeFromCharCode(charcode); |
| 1020 if (!str.IsEmpty()) | 1020 if (!str.IsEmpty()) |
| 1021 return str; | 1021 return str; |
| 1022 FX_WCHAR ret = GetUnicodeFromCharCode(charcode); | 1022 FX_WCHAR ret = GetUnicodeFromCharCode(charcode); |
| 1023 if (ret == 0) | 1023 if (ret == 0) |
| 1024 return CFX_WideString(); | 1024 return CFX_WideString(); |
| 1025 return ret; | 1025 return ret; |
| 1026 } | 1026 } |
| 1027 | 1027 |
| 1028 FX_WCHAR CPDF_CIDFont::GetUnicodeFromCharCode(FX_DWORD charcode) const { | 1028 FX_WCHAR CPDF_CIDFont::GetUnicodeFromCharCode(FX_DWORD charcode) const { |
| 1029 switch (m_pCMap->m_Coding) { | 1029 switch (m_pCMap->m_Coding) { |
| 1030 case CIDCODING_UCS2: | 1030 case CIDCODING_UCS2: |
| 1031 case CIDCODING_UTF16: | 1031 case CIDCODING_UTF16: |
| 1032 return (FX_WCHAR)charcode; | 1032 return (FX_WCHAR)charcode; |
| 1033 case CIDCODING_CID: | 1033 case CIDCODING_CID: |
| 1034 if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) { | 1034 if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) { |
| 1035 return 0; | 1035 return 0; |
| 1036 } | 1036 } |
| 1037 return m_pCID2UnicodeMap->UnicodeFromCID((FX_WORD)charcode); | 1037 return m_pCID2UnicodeMap->UnicodeFromCID((uint16_t)charcode); |
| 1038 } | 1038 } |
| 1039 if (!m_pCMap->IsLoaded() || !m_pCID2UnicodeMap || | 1039 if (!m_pCMap->IsLoaded() || !m_pCID2UnicodeMap || |
| 1040 !m_pCID2UnicodeMap->IsLoaded()) { | 1040 !m_pCID2UnicodeMap->IsLoaded()) { |
| 1041 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ | 1041 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ |
| 1042 FX_WCHAR unicode; | 1042 FX_WCHAR unicode; |
| 1043 int charsize = 1; | 1043 int charsize = 1; |
| 1044 if (charcode > 255) { | 1044 if (charcode > 255) { |
| 1045 charcode = (charcode % 256) * 256 + (charcode / 256); | 1045 charcode = (charcode % 256) * 256 + (charcode / 256); |
| 1046 charsize = 2; | 1046 charsize = 2; |
| 1047 } | 1047 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1071 return 0; | 1071 return 0; |
| 1072 case CIDCODING_UCS2: | 1072 case CIDCODING_UCS2: |
| 1073 case CIDCODING_UTF16: | 1073 case CIDCODING_UTF16: |
| 1074 return unicode; | 1074 return unicode; |
| 1075 case CIDCODING_CID: { | 1075 case CIDCODING_CID: { |
| 1076 if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) { | 1076 if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) { |
| 1077 return 0; | 1077 return 0; |
| 1078 } | 1078 } |
| 1079 FX_DWORD CID = 0; | 1079 FX_DWORD CID = 0; |
| 1080 while (CID < 65536) { | 1080 while (CID < 65536) { |
| 1081 FX_WCHAR this_unicode = m_pCID2UnicodeMap->UnicodeFromCID((FX_WORD)CID); | 1081 FX_WCHAR this_unicode = |
| 1082 m_pCID2UnicodeMap->UnicodeFromCID((uint16_t)CID); |
| 1082 if (this_unicode == unicode) { | 1083 if (this_unicode == unicode) { |
| 1083 return CID; | 1084 return CID; |
| 1084 } | 1085 } |
| 1085 CID++; | 1086 CID++; |
| 1086 } | 1087 } |
| 1087 break; | 1088 break; |
| 1088 } | 1089 } |
| 1089 } | 1090 } |
| 1090 | 1091 |
| 1091 if (unicode < 0x80) { | 1092 if (unicode < 0x80) { |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1280 FXFT_Get_Glyph_Width(face), | 1281 FXFT_Get_Glyph_Width(face), |
| 1281 face), | 1282 face), |
| 1282 TT2PDF(FXFT_Get_Glyph_HoriBearingY(face) - | 1283 TT2PDF(FXFT_Get_Glyph_HoriBearingY(face) - |
| 1283 FXFT_Get_Glyph_Height(face), | 1284 FXFT_Get_Glyph_Height(face), |
| 1284 face)); | 1285 face)); |
| 1285 rect.top += rect.top / 64; | 1286 rect.top += rect.top / 64; |
| 1286 } | 1287 } |
| 1287 } | 1288 } |
| 1288 } | 1289 } |
| 1289 if (!m_pFontFile && m_Charset == CIDSET_JAPAN1) { | 1290 if (!m_pFontFile && m_Charset == CIDSET_JAPAN1) { |
| 1290 FX_WORD CID = CIDFromCharCode(charcode); | 1291 uint16_t CID = CIDFromCharCode(charcode); |
| 1291 const uint8_t* pTransform = GetCIDTransform(CID); | 1292 const uint8_t* pTransform = GetCIDTransform(CID); |
| 1292 if (pTransform && !bVert) { | 1293 if (pTransform && !bVert) { |
| 1293 CFX_Matrix matrix(CIDTransformToFloat(pTransform[0]), | 1294 CFX_Matrix matrix(CIDTransformToFloat(pTransform[0]), |
| 1294 CIDTransformToFloat(pTransform[1]), | 1295 CIDTransformToFloat(pTransform[1]), |
| 1295 CIDTransformToFloat(pTransform[2]), | 1296 CIDTransformToFloat(pTransform[2]), |
| 1296 CIDTransformToFloat(pTransform[3]), | 1297 CIDTransformToFloat(pTransform[3]), |
| 1297 CIDTransformToFloat(pTransform[4]) * 1000, | 1298 CIDTransformToFloat(pTransform[4]) * 1000, |
| 1298 CIDTransformToFloat(pTransform[5]) * 1000); | 1299 CIDTransformToFloat(pTransform[5]) * 1000); |
| 1299 CFX_FloatRect rect_f(rect); | 1300 CFX_FloatRect rect_f(rect); |
| 1300 rect_f.Transform(&matrix); | 1301 rect_f.Transform(&matrix); |
| 1301 rect = rect_f.GetOutterRect(); | 1302 rect = rect_f.GetOutterRect(); |
| 1302 } | 1303 } |
| 1303 } | 1304 } |
| 1304 if (charcode < 256) | 1305 if (charcode < 256) |
| 1305 m_CharBBox[charcode] = rect.ToSmallRect(); | 1306 m_CharBBox[charcode] = rect.ToSmallRect(); |
| 1306 | 1307 |
| 1307 return rect; | 1308 return rect; |
| 1308 } | 1309 } |
| 1309 int CPDF_CIDFont::GetCharWidthF(FX_DWORD charcode, int level) { | 1310 int CPDF_CIDFont::GetCharWidthF(FX_DWORD charcode, int level) { |
| 1310 if (m_pAnsiWidths && charcode < 0x80) { | 1311 if (m_pAnsiWidths && charcode < 0x80) { |
| 1311 return m_pAnsiWidths[charcode]; | 1312 return m_pAnsiWidths[charcode]; |
| 1312 } | 1313 } |
| 1313 FX_WORD cid = CIDFromCharCode(charcode); | 1314 uint16_t cid = CIDFromCharCode(charcode); |
| 1314 int size = m_WidthList.GetSize(); | 1315 int size = m_WidthList.GetSize(); |
| 1315 FX_DWORD* list = m_WidthList.GetData(); | 1316 FX_DWORD* list = m_WidthList.GetData(); |
| 1316 for (int i = 0; i < size; i += 3) { | 1317 for (int i = 0; i < size; i += 3) { |
| 1317 if (cid >= list[i] && cid <= list[i + 1]) { | 1318 if (cid >= list[i] && cid <= list[i + 1]) { |
| 1318 return (int)list[i + 2]; | 1319 return (int)list[i + 2]; |
| 1319 } | 1320 } |
| 1320 } | 1321 } |
| 1321 return m_DefaultWidth; | 1322 return m_DefaultWidth; |
| 1322 } | 1323 } |
| 1323 short CPDF_CIDFont::GetVertWidth(FX_WORD CID) const { | 1324 short CPDF_CIDFont::GetVertWidth(uint16_t CID) const { |
| 1324 FX_DWORD vertsize = m_VertMetrics.GetSize() / 5; | 1325 FX_DWORD vertsize = m_VertMetrics.GetSize() / 5; |
| 1325 if (vertsize == 0) { | 1326 if (vertsize == 0) { |
| 1326 return m_DefaultW1; | 1327 return m_DefaultW1; |
| 1327 } | 1328 } |
| 1328 const FX_DWORD* pTable = m_VertMetrics.GetData(); | 1329 const FX_DWORD* pTable = m_VertMetrics.GetData(); |
| 1329 for (FX_DWORD i = 0; i < vertsize; i++) | 1330 for (FX_DWORD i = 0; i < vertsize; i++) |
| 1330 if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) { | 1331 if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) { |
| 1331 return (short)(int)pTable[i * 5 + 2]; | 1332 return (short)(int)pTable[i * 5 + 2]; |
| 1332 } | 1333 } |
| 1333 return m_DefaultW1; | 1334 return m_DefaultW1; |
| 1334 } | 1335 } |
| 1335 void CPDF_CIDFont::GetVertOrigin(FX_WORD CID, short& vx, short& vy) const { | 1336 void CPDF_CIDFont::GetVertOrigin(uint16_t CID, short& vx, short& vy) const { |
| 1336 FX_DWORD vertsize = m_VertMetrics.GetSize() / 5; | 1337 FX_DWORD vertsize = m_VertMetrics.GetSize() / 5; |
| 1337 if (vertsize) { | 1338 if (vertsize) { |
| 1338 const FX_DWORD* pTable = m_VertMetrics.GetData(); | 1339 const FX_DWORD* pTable = m_VertMetrics.GetData(); |
| 1339 for (FX_DWORD i = 0; i < vertsize; i++) | 1340 for (FX_DWORD i = 0; i < vertsize; i++) |
| 1340 if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) { | 1341 if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) { |
| 1341 vx = (short)(int)pTable[i * 5 + 3]; | 1342 vx = (short)(int)pTable[i * 5 + 3]; |
| 1342 vy = (short)(int)pTable[i * 5 + 4]; | 1343 vy = (short)(int)pTable[i * 5 + 4]; |
| 1343 return; | 1344 return; |
| 1344 } | 1345 } |
| 1345 } | 1346 } |
| 1346 FX_DWORD dwWidth = m_DefaultWidth; | 1347 FX_DWORD dwWidth = m_DefaultWidth; |
| 1347 int size = m_WidthList.GetSize(); | 1348 int size = m_WidthList.GetSize(); |
| 1348 const FX_DWORD* list = m_WidthList.GetData(); | 1349 const FX_DWORD* list = m_WidthList.GetData(); |
| 1349 for (int i = 0; i < size; i += 3) { | 1350 for (int i = 0; i < size; i += 3) { |
| 1350 if (CID >= list[i] && CID <= list[i + 1]) { | 1351 if (CID >= list[i] && CID <= list[i + 1]) { |
| 1351 dwWidth = (FX_WORD)list[i + 2]; | 1352 dwWidth = (uint16_t)list[i + 2]; |
| 1352 break; | 1353 break; |
| 1353 } | 1354 } |
| 1354 } | 1355 } |
| 1355 vx = (short)dwWidth / 2; | 1356 vx = (short)dwWidth / 2; |
| 1356 vy = (short)m_DefaultVY; | 1357 vy = (short)m_DefaultVY; |
| 1357 } | 1358 } |
| 1358 int CPDF_CIDFont::GetGlyphIndex(FX_DWORD unicode, FX_BOOL* pVertGlyph) { | 1359 int CPDF_CIDFont::GetGlyphIndex(FX_DWORD unicode, FX_BOOL* pVertGlyph) { |
| 1359 if (pVertGlyph) { | 1360 if (pVertGlyph) { |
| 1360 *pVertGlyph = FALSE; | 1361 *pVertGlyph = FALSE; |
| 1361 } | 1362 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1403 if (pVertGlyph) { | 1404 if (pVertGlyph) { |
| 1404 *pVertGlyph = FALSE; | 1405 *pVertGlyph = FALSE; |
| 1405 } | 1406 } |
| 1406 return index; | 1407 return index; |
| 1407 } | 1408 } |
| 1408 int CPDF_CIDFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) { | 1409 int CPDF_CIDFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) { |
| 1409 if (pVertGlyph) { | 1410 if (pVertGlyph) { |
| 1410 *pVertGlyph = FALSE; | 1411 *pVertGlyph = FALSE; |
| 1411 } | 1412 } |
| 1412 if (!m_pFontFile && !m_pCIDToGIDMap) { | 1413 if (!m_pFontFile && !m_pCIDToGIDMap) { |
| 1413 FX_WORD cid = CIDFromCharCode(charcode); | 1414 uint16_t cid = CIDFromCharCode(charcode); |
| 1414 FX_WCHAR unicode = 0; | 1415 FX_WCHAR unicode = 0; |
| 1415 if (m_bCIDIsGID) { | 1416 if (m_bCIDIsGID) { |
| 1416 #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ | 1417 #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ |
| 1417 return cid; | 1418 return cid; |
| 1418 #else | 1419 #else |
| 1419 if (m_Flags & PDFFONT_SYMBOLIC) { | 1420 if (m_Flags & PDFFONT_SYMBOLIC) { |
| 1420 return cid; | 1421 return cid; |
| 1421 } | 1422 } |
| 1422 CFX_WideString uni_str = UnicodeFromCharCode(charcode); | 1423 CFX_WideString uni_str = UnicodeFromCharCode(charcode); |
| 1423 if (uni_str.IsEmpty()) { | 1424 if (uni_str.IsEmpty()) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1451 iBaseEncoding = PDFFONT_ENCODING_STANDARD; | 1452 iBaseEncoding = PDFFONT_ENCODING_STANDARD; |
| 1452 if (bMSUnicode) { | 1453 if (bMSUnicode) { |
| 1453 iBaseEncoding = PDFFONT_ENCODING_WINANSI; | 1454 iBaseEncoding = PDFFONT_ENCODING_WINANSI; |
| 1454 } else if (bMacRoman) { | 1455 } else if (bMacRoman) { |
| 1455 iBaseEncoding = PDFFONT_ENCODING_MACROMAN; | 1456 iBaseEncoding = PDFFONT_ENCODING_MACROMAN; |
| 1456 } | 1457 } |
| 1457 const FX_CHAR* name = GetAdobeCharName(iBaseEncoding, NULL, charcode); | 1458 const FX_CHAR* name = GetAdobeCharName(iBaseEncoding, NULL, charcode); |
| 1458 if (!name) { | 1459 if (!name) { |
| 1459 return charcode == 0 ? -1 : (int)charcode; | 1460 return charcode == 0 ? -1 : (int)charcode; |
| 1460 } | 1461 } |
| 1461 FX_WORD unicode = PDF_UnicodeFromAdobeName(name); | 1462 uint16_t unicode = PDF_UnicodeFromAdobeName(name); |
| 1462 if (unicode) { | 1463 if (unicode) { |
| 1463 if (bMSUnicode) { | 1464 if (bMSUnicode) { |
| 1464 index = FXFT_Get_Char_Index(face, unicode); | 1465 index = FXFT_Get_Char_Index(face, unicode); |
| 1465 } else if (bMacRoman) { | 1466 } else if (bMacRoman) { |
| 1466 FX_DWORD maccode = | 1467 FX_DWORD maccode = |
| 1467 FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, unicode); | 1468 FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, unicode); |
| 1468 index = !maccode ? FXFT_Get_Name_Index(face, (char*)name) | 1469 index = !maccode ? FXFT_Get_Name_Index(face, (char*)name) |
| 1469 : FXFT_Get_Char_Index(face, maccode); | 1470 : FXFT_Get_Char_Index(face, maccode); |
| 1470 } else { | 1471 } else { |
| 1471 return FXFT_Get_Char_Index(face, unicode); | 1472 return FXFT_Get_Char_Index(face, unicode); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1513 int index = GetGlyphIndex(unicode, pVertGlyph); | 1514 int index = GetGlyphIndex(unicode, pVertGlyph); |
| 1514 if (index == 0) | 1515 if (index == 0) |
| 1515 return -1; | 1516 return -1; |
| 1516 return index; | 1517 return index; |
| 1517 } | 1518 } |
| 1518 return unicode; | 1519 return unicode; |
| 1519 } | 1520 } |
| 1520 if (!m_Font.GetFace()) | 1521 if (!m_Font.GetFace()) |
| 1521 return -1; | 1522 return -1; |
| 1522 | 1523 |
| 1523 FX_WORD cid = CIDFromCharCode(charcode); | 1524 uint16_t cid = CIDFromCharCode(charcode); |
| 1524 if (m_bType1) { | 1525 if (m_bType1) { |
| 1525 if (!m_pCIDToGIDMap) { | 1526 if (!m_pCIDToGIDMap) { |
| 1526 return cid; | 1527 return cid; |
| 1527 } | 1528 } |
| 1528 } else { | 1529 } else { |
| 1529 if (!m_pCIDToGIDMap) { | 1530 if (!m_pCIDToGIDMap) { |
| 1530 if (m_pFontFile && !m_pCMap->m_pMapping) | 1531 if (m_pFontFile && !m_pCMap->m_pMapping) |
| 1531 return cid; | 1532 return cid; |
| 1532 if (m_pCMap->m_Coding == CIDCODING_UNKNOWN || | 1533 if (m_pCMap->m_Coding == CIDCODING_UNKNOWN || |
| 1533 !FXFT_Get_Face_Charmap(m_Font.GetFace())) { | 1534 !FXFT_Get_Face_Charmap(m_Font.GetFace())) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1651 ->m_CMapManager.GetPredefinedCMap("GBK-EUC-H", FALSE); | 1652 ->m_CMapManager.GetPredefinedCMap("GBK-EUC-H", FALSE); |
| 1652 m_pCID2UnicodeMap = CPDF_ModuleMgr::Get() | 1653 m_pCID2UnicodeMap = CPDF_ModuleMgr::Get() |
| 1653 ->GetPageModule() | 1654 ->GetPageModule() |
| 1654 ->GetFontGlobals() | 1655 ->GetFontGlobals() |
| 1655 ->m_CMapManager.GetCID2UnicodeMap(m_Charset, FALSE); | 1656 ->m_CMapManager.GetCID2UnicodeMap(m_Charset, FALSE); |
| 1656 if (!IsEmbedded()) { | 1657 if (!IsEmbedded()) { |
| 1657 LoadSubstFont(); | 1658 LoadSubstFont(); |
| 1658 } | 1659 } |
| 1659 CheckFontMetrics(); | 1660 CheckFontMetrics(); |
| 1660 m_DefaultWidth = 1000; | 1661 m_DefaultWidth = 1000; |
| 1661 m_pAnsiWidths = FX_Alloc(FX_WORD, 128); | 1662 m_pAnsiWidths = FX_Alloc(uint16_t, 128); |
| 1662 for (int i = 32; i < 127; i++) { | 1663 for (int i = 32; i < 127; i++) { |
| 1663 m_pAnsiWidths[i] = 500; | 1664 m_pAnsiWidths[i] = 500; |
| 1664 } | 1665 } |
| 1665 return TRUE; | 1666 return TRUE; |
| 1666 } | 1667 } |
| 1667 | 1668 |
| 1668 const uint8_t* CPDF_CIDFont::GetCIDTransform(FX_WORD CID) const { | 1669 const uint8_t* CPDF_CIDFont::GetCIDTransform(uint16_t CID) const { |
| 1669 if (m_Charset != CIDSET_JAPAN1 || m_pFontFile) | 1670 if (m_Charset != CIDSET_JAPAN1 || m_pFontFile) |
| 1670 return nullptr; | 1671 return nullptr; |
| 1671 | 1672 |
| 1672 const struct CIDTransform* found = (const struct CIDTransform*)FXSYS_bsearch( | 1673 const struct CIDTransform* found = (const struct CIDTransform*)FXSYS_bsearch( |
| 1673 &CID, g_Japan1_VertCIDs, FX_ArraySize(g_Japan1_VertCIDs), | 1674 &CID, g_Japan1_VertCIDs, FX_ArraySize(g_Japan1_VertCIDs), |
| 1674 sizeof(g_Japan1_VertCIDs[0]), CompareCIDTransform); | 1675 sizeof(g_Japan1_VertCIDs[0]), CompareCIDTransform); |
| 1675 return found ? &found->a : nullptr; | 1676 return found ? &found->a : nullptr; |
| 1676 } | 1677 } |
| OLD | NEW |