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 <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 | 734 |
735 std::vector<uint8_t> buffer(size); | 735 std::vector<uint8_t> buffer(size); |
736 uint8_t* buffer_ptr = buffer.data(); | 736 uint8_t* buffer_ptr = buffer.data(); |
737 uint32_t bytes_read = | 737 uint32_t bytes_read = |
738 m_pFontInfo->GetFontData(hFont, kTableNAME, buffer_ptr, size); | 738 m_pFontInfo->GetFontData(hFont, kTableNAME, buffer_ptr, size); |
739 return bytes_read == size ? GetNameFromTT(buffer_ptr, bytes_read, 6) | 739 return bytes_read == size ? GetNameFromTT(buffer_ptr, bytes_read, 6) |
740 : CFX_ByteString(); | 740 : CFX_ByteString(); |
741 } | 741 } |
742 | 742 |
743 void CFX_FontMapper::AddInstalledFont(const CFX_ByteString& name, int charset) { | 743 void CFX_FontMapper::AddInstalledFont(const CFX_ByteString& name, int charset) { |
744 if (!m_pFontInfo) { | 744 if (!m_pFontInfo) |
745 return; | 745 return; |
746 } | 746 |
747 if (m_CharsetArray.Find((uint32_t)charset) == -1) { | 747 m_FaceArray.push_back({name, static_cast<uint32_t>(charset)}); |
748 m_CharsetArray.Add((uint32_t)charset); | 748 if (name == m_LastFamily) |
749 m_FaceArray.push_back(name); | |
750 } | |
751 if (name == m_LastFamily) { | |
752 return; | 749 return; |
753 } | 750 |
754 const uint8_t* ptr = name.raw_str(); | 751 const uint8_t* ptr = name.raw_str(); |
755 FX_BOOL bLocalized = FALSE; | 752 FX_BOOL bLocalized = FALSE; |
756 for (int i = 0; i < name.GetLength(); i++) | 753 for (int i = 0; i < name.GetLength(); i++) { |
757 if (ptr[i] > 0x80) { | 754 if (ptr[i] > 0x80) { |
758 bLocalized = TRUE; | 755 bLocalized = TRUE; |
759 break; | 756 break; |
760 } | 757 } |
| 758 } |
| 759 |
761 if (bLocalized) { | 760 if (bLocalized) { |
762 void* hFont = m_pFontInfo->GetFont(name); | 761 void* hFont = m_pFontInfo->GetFont(name); |
763 if (!hFont) { | 762 if (!hFont) { |
764 int iExact; | 763 int iExact; |
765 hFont = | 764 hFont = |
766 m_pFontInfo->MapFont(0, 0, FXFONT_DEFAULT_CHARSET, 0, name, iExact); | 765 m_pFontInfo->MapFont(0, 0, FXFONT_DEFAULT_CHARSET, 0, name, iExact); |
767 if (!hFont) { | 766 if (!hFont) |
768 return; | 767 return; |
769 } | |
770 } | 768 } |
| 769 |
771 CFX_ByteString new_name = GetPSNameFromTT(hFont); | 770 CFX_ByteString new_name = GetPSNameFromTT(hFont); |
772 if (!new_name.IsEmpty()) { | 771 if (!new_name.IsEmpty()) { |
773 new_name.Insert(0, ' '); | 772 new_name.Insert(0, ' '); |
774 m_InstalledTTFonts.push_back(new_name); | 773 m_InstalledTTFonts.push_back(new_name); |
775 } | 774 } |
776 m_pFontInfo->DeleteFont(hFont); | 775 m_pFontInfo->DeleteFont(hFont); |
777 } | 776 } |
778 m_InstalledTTFonts.push_back(name); | 777 m_InstalledTTFonts.push_back(name); |
779 m_LastFamily = name; | 778 m_LastFamily = name; |
780 } | 779 } |
| 780 |
781 void CFX_FontMapper::LoadInstalledFonts() { | 781 void CFX_FontMapper::LoadInstalledFonts() { |
782 if (!m_pFontInfo) { | 782 if (!m_pFontInfo) { |
783 return; | 783 return; |
784 } | 784 } |
785 if (m_bListLoaded) { | 785 if (m_bListLoaded) { |
786 return; | 786 return; |
787 } | 787 } |
788 if (m_bListLoaded) { | 788 if (m_bListLoaded) { |
789 return; | 789 return; |
790 } | 790 } |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1148 #endif | 1148 #endif |
1149 pSubstFont->m_SubstFlags |= FXFONT_SUBST_NONSYMBOL; | 1149 pSubstFont->m_SubstFlags |= FXFONT_SUBST_NONSYMBOL; |
1150 return FindSubstFont(family, bTrueType, flags & ~FXFONT_SYMBOLIC, | 1150 return FindSubstFont(family, bTrueType, flags & ~FXFONT_SYMBOLIC, |
1151 weight, italic_angle, 0, pSubstFont); | 1151 weight, italic_angle, 0, pSubstFont); |
1152 } | 1152 } |
1153 if (Charset == FXFONT_ANSI_CHARSET) { | 1153 if (Charset == FXFONT_ANSI_CHARSET) { |
1154 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; | 1154 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; |
1155 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, | 1155 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, |
1156 PitchFamily); | 1156 PitchFamily); |
1157 } | 1157 } |
1158 int index = m_CharsetArray.Find(Charset); | 1158 |
1159 if (index < 0) { | 1159 auto it = std::find_if( |
| 1160 m_FaceArray.begin(), m_FaceArray.end(), |
| 1161 [Charset](const FaceData& face) { return face.charset == Charset; }); |
| 1162 if (it == m_FaceArray.end()) { |
1160 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, | 1163 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, |
1161 PitchFamily); | 1164 PitchFamily); |
1162 } | 1165 } |
1163 hFont = m_pFontInfo->GetFont(m_FaceArray[index]); | 1166 hFont = m_pFontInfo->GetFont(it->name); |
1164 } | 1167 } |
1165 } | 1168 } |
1166 pSubstFont->m_ExtHandle = m_pFontInfo->RetainFont(hFont); | 1169 pSubstFont->m_ExtHandle = m_pFontInfo->RetainFont(hFont); |
1167 if (!hFont) | 1170 if (!hFont) |
1168 return nullptr; | 1171 return nullptr; |
1169 | 1172 |
1170 m_pFontInfo->GetFaceName(hFont, SubstName); | 1173 m_pFontInfo->GetFaceName(hFont, SubstName); |
1171 if (Charset == FXFONT_DEFAULT_CHARSET) { | 1174 if (Charset == FXFONT_DEFAULT_CHARSET) { |
1172 m_pFontInfo->GetFontCharset(hFont, Charset); | 1175 m_pFontInfo->GetFontCharset(hFont, Charset); |
1173 } | 1176 } |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 } | 1367 } |
1365 } | 1368 } |
1366 void CFX_FolderFontInfo::AddPath(const CFX_ByteStringC& path) { | 1369 void CFX_FolderFontInfo::AddPath(const CFX_ByteStringC& path) { |
1367 m_PathList.push_back(path); | 1370 m_PathList.push_back(path); |
1368 } | 1371 } |
1369 void CFX_FolderFontInfo::Release() { | 1372 void CFX_FolderFontInfo::Release() { |
1370 delete this; | 1373 delete this; |
1371 } | 1374 } |
1372 FX_BOOL CFX_FolderFontInfo::EnumFontList(CFX_FontMapper* pMapper) { | 1375 FX_BOOL CFX_FolderFontInfo::EnumFontList(CFX_FontMapper* pMapper) { |
1373 m_pMapper = pMapper; | 1376 m_pMapper = pMapper; |
1374 for (const auto& path : m_PathList) { | 1377 for (const auto& path : m_PathList) |
1375 ScanPath(path); | 1378 ScanPath(path); |
1376 } | |
1377 return TRUE; | 1379 return TRUE; |
1378 } | 1380 } |
1379 void CFX_FolderFontInfo::ScanPath(const CFX_ByteString& path) { | 1381 void CFX_FolderFontInfo::ScanPath(const CFX_ByteString& path) { |
1380 void* handle = FX_OpenFolder(path); | 1382 void* handle = FX_OpenFolder(path); |
1381 if (!handle) { | 1383 if (!handle) |
1382 return; | 1384 return; |
1383 } | 1385 |
1384 CFX_ByteString filename; | 1386 CFX_ByteString filename; |
1385 FX_BOOL bFolder; | 1387 FX_BOOL bFolder; |
1386 while (FX_GetNextFile(handle, filename, bFolder)) { | 1388 while (FX_GetNextFile(handle, filename, bFolder)) { |
1387 if (bFolder) { | 1389 if (bFolder) { |
1388 if (filename == "." || filename == "..") { | 1390 if (filename == "." || filename == "..") |
1389 continue; | 1391 continue; |
1390 } | |
1391 } else { | 1392 } else { |
1392 CFX_ByteString ext = filename.Right(4); | 1393 CFX_ByteString ext = filename.Right(4); |
1393 ext.MakeUpper(); | 1394 ext.MakeUpper(); |
1394 if (ext != ".TTF" && ext != ".OTF" && ext != ".TTC") { | 1395 if (ext != ".TTF" && ext != ".OTF" && ext != ".TTC") |
1395 continue; | 1396 continue; |
1396 } | |
1397 } | 1397 } |
| 1398 |
1398 CFX_ByteString fullpath = path; | 1399 CFX_ByteString fullpath = path; |
1399 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ | 1400 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ |
1400 fullpath += "\\"; | 1401 fullpath += "\\"; |
1401 #else | 1402 #else |
1402 fullpath += "/"; | 1403 fullpath += "/"; |
1403 #endif | 1404 #endif |
| 1405 |
1404 fullpath += filename; | 1406 fullpath += filename; |
1405 if (bFolder) { | 1407 bFolder ? ScanPath(fullpath) : ScanFile(fullpath); |
1406 ScanPath(fullpath); | |
1407 } else { | |
1408 ScanFile(fullpath); | |
1409 } | |
1410 } | 1408 } |
1411 FX_CloseFolder(handle); | 1409 FX_CloseFolder(handle); |
1412 } | 1410 } |
| 1411 |
1413 void CFX_FolderFontInfo::ScanFile(const CFX_ByteString& path) { | 1412 void CFX_FolderFontInfo::ScanFile(const CFX_ByteString& path) { |
1414 FXSYS_FILE* pFile = FXSYS_fopen(path, "rb"); | 1413 FXSYS_FILE* pFile = FXSYS_fopen(path, "rb"); |
1415 if (!pFile) { | 1414 if (!pFile) |
1416 return; | 1415 return; |
1417 } | 1416 |
1418 FXSYS_fseek(pFile, 0, FXSYS_SEEK_END); | 1417 FXSYS_fseek(pFile, 0, FXSYS_SEEK_END); |
| 1418 |
1419 uint32_t filesize = FXSYS_ftell(pFile); | 1419 uint32_t filesize = FXSYS_ftell(pFile); |
1420 uint8_t buffer[16]; | 1420 uint8_t buffer[16]; |
1421 FXSYS_fseek(pFile, 0, FXSYS_SEEK_SET); | 1421 FXSYS_fseek(pFile, 0, FXSYS_SEEK_SET); |
| 1422 |
1422 size_t readCnt = FXSYS_fread(buffer, 12, 1, pFile); | 1423 size_t readCnt = FXSYS_fread(buffer, 12, 1, pFile); |
1423 if (readCnt != 1) { | 1424 if (readCnt != 1) { |
1424 FXSYS_fclose(pFile); | 1425 FXSYS_fclose(pFile); |
1425 return; | 1426 return; |
1426 } | 1427 } |
1427 | 1428 |
1428 if (GET_TT_LONG(buffer) == kTableTTCF) { | 1429 if (GET_TT_LONG(buffer) == kTableTTCF) { |
1429 uint32_t nFaces = GET_TT_LONG(buffer + 8); | 1430 uint32_t nFaces = GET_TT_LONG(buffer + 8); |
1430 if (nFaces > std::numeric_limits<uint32_t>::max() / 4) { | 1431 if (nFaces > std::numeric_limits<uint32_t>::max() / 4) { |
1431 FXSYS_fclose(pFile); | 1432 FXSYS_fclose(pFile); |
(...skipping 16 matching lines...) Expand all Loading... |
1448 ReportFace(path, pFile, filesize, 0); | 1449 ReportFace(path, pFile, filesize, 0); |
1449 } | 1450 } |
1450 FXSYS_fclose(pFile); | 1451 FXSYS_fclose(pFile); |
1451 } | 1452 } |
1452 void CFX_FolderFontInfo::ReportFace(const CFX_ByteString& path, | 1453 void CFX_FolderFontInfo::ReportFace(const CFX_ByteString& path, |
1453 FXSYS_FILE* pFile, | 1454 FXSYS_FILE* pFile, |
1454 uint32_t filesize, | 1455 uint32_t filesize, |
1455 uint32_t offset) { | 1456 uint32_t offset) { |
1456 FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); | 1457 FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); |
1457 char buffer[16]; | 1458 char buffer[16]; |
1458 if (!FXSYS_fread(buffer, 12, 1, pFile)) { | 1459 if (!FXSYS_fread(buffer, 12, 1, pFile)) |
1459 return; | 1460 return; |
1460 } | 1461 |
1461 uint32_t nTables = GET_TT_SHORT(buffer + 4); | 1462 uint32_t nTables = GET_TT_SHORT(buffer + 4); |
1462 CFX_ByteString tables = FPDF_ReadStringFromFile(pFile, nTables * 16); | 1463 CFX_ByteString tables = FPDF_ReadStringFromFile(pFile, nTables * 16); |
1463 if (tables.IsEmpty()) { | 1464 if (tables.IsEmpty()) |
1464 return; | 1465 return; |
1465 } | 1466 |
1466 CFX_ByteString names = | 1467 CFX_ByteString names = |
1467 FPDF_LoadTableFromTT(pFile, tables.raw_str(), nTables, 0x6e616d65); | 1468 FPDF_LoadTableFromTT(pFile, tables.raw_str(), nTables, 0x6e616d65); |
1468 if (names.IsEmpty()) { | 1469 if (names.IsEmpty()) |
1469 return; | 1470 return; |
1470 } | 1471 |
1471 CFX_ByteString facename = | 1472 CFX_ByteString facename = |
1472 GetNameFromTT(names.raw_str(), names.GetLength(), 1); | 1473 GetNameFromTT(names.raw_str(), names.GetLength(), 1); |
1473 if (facename.IsEmpty()) { | 1474 if (facename.IsEmpty()) |
1474 return; | 1475 return; |
1475 } | 1476 |
1476 CFX_ByteString style = GetNameFromTT(names.raw_str(), names.GetLength(), 2); | 1477 CFX_ByteString style = GetNameFromTT(names.raw_str(), names.GetLength(), 2); |
1477 if (style != "Regular") { | 1478 if (style != "Regular") |
1478 facename += " " + style; | 1479 facename += " " + style; |
1479 } | 1480 |
1480 if (pdfium::ContainsKey(m_FontList, facename)) | 1481 if (pdfium::ContainsKey(m_FontList, facename)) |
1481 return; | 1482 return; |
1482 | 1483 |
1483 CFX_FontFaceInfo* pInfo = | 1484 CFX_FontFaceInfo* pInfo = |
1484 new CFX_FontFaceInfo(path, facename, tables, offset, filesize); | 1485 new CFX_FontFaceInfo(path, facename, tables, offset, filesize); |
1485 CFX_ByteString os2 = | 1486 CFX_ByteString os2 = |
1486 FPDF_LoadTableFromTT(pFile, tables.raw_str(), nTables, 0x4f532f32); | 1487 FPDF_LoadTableFromTT(pFile, tables.raw_str(), nTables, 0x4f532f32); |
1487 if (os2.GetLength() >= 86) { | 1488 if (os2.GetLength() >= 86) { |
1488 const uint8_t* p = os2.raw_str() + 78; | 1489 const uint8_t* p = os2.raw_str() + 78; |
1489 uint32_t codepages = GET_TT_LONG(p); | 1490 uint32_t codepages = GET_TT_LONG(p); |
(...skipping 14 matching lines...) Expand all Loading... |
1504 pInfo->m_Charsets |= CHARSET_FLAG_KOREAN; | 1505 pInfo->m_Charsets |= CHARSET_FLAG_KOREAN; |
1505 } | 1506 } |
1506 if (codepages & (1 << 31)) { | 1507 if (codepages & (1 << 31)) { |
1507 m_pMapper->AddInstalledFont(facename, FXFONT_SYMBOL_CHARSET); | 1508 m_pMapper->AddInstalledFont(facename, FXFONT_SYMBOL_CHARSET); |
1508 pInfo->m_Charsets |= CHARSET_FLAG_SYMBOL; | 1509 pInfo->m_Charsets |= CHARSET_FLAG_SYMBOL; |
1509 } | 1510 } |
1510 } | 1511 } |
1511 m_pMapper->AddInstalledFont(facename, FXFONT_ANSI_CHARSET); | 1512 m_pMapper->AddInstalledFont(facename, FXFONT_ANSI_CHARSET); |
1512 pInfo->m_Charsets |= CHARSET_FLAG_ANSI; | 1513 pInfo->m_Charsets |= CHARSET_FLAG_ANSI; |
1513 pInfo->m_Styles = 0; | 1514 pInfo->m_Styles = 0; |
1514 if (style.Find("Bold") > -1) { | 1515 if (style.Find("Bold") > -1) |
1515 pInfo->m_Styles |= FXFONT_BOLD; | 1516 pInfo->m_Styles |= FXFONT_BOLD; |
1516 } | 1517 if (style.Find("Italic") > -1 || style.Find("Oblique") > -1) |
1517 if (style.Find("Italic") > -1 || style.Find("Oblique") > -1) { | |
1518 pInfo->m_Styles |= FXFONT_ITALIC; | 1518 pInfo->m_Styles |= FXFONT_ITALIC; |
1519 } | 1519 if (facename.Find("Serif") > -1) |
1520 if (facename.Find("Serif") > -1) { | |
1521 pInfo->m_Styles |= FXFONT_SERIF; | 1520 pInfo->m_Styles |= FXFONT_SERIF; |
1522 } | 1521 |
1523 m_FontList[facename] = pInfo; | 1522 m_FontList[facename] = pInfo; |
1524 } | 1523 } |
1525 | 1524 |
1526 void* CFX_FolderFontInfo::GetSubstFont(const CFX_ByteString& face) { | 1525 void* CFX_FolderFontInfo::GetSubstFont(const CFX_ByteString& face) { |
1527 for (size_t iBaseFont = 0; iBaseFont < FX_ArraySize(Base14Substs); | 1526 for (size_t iBaseFont = 0; iBaseFont < FX_ArraySize(Base14Substs); |
1528 iBaseFont++) { | 1527 iBaseFont++) { |
1529 if (face == Base14Substs[iBaseFont].m_pName) { | 1528 if (face == Base14Substs[iBaseFont].m_pName) |
1530 return GetFont(Base14Substs[iBaseFont].m_pSubstName); | 1529 return GetFont(Base14Substs[iBaseFont].m_pSubstName); |
1531 } | |
1532 } | 1530 } |
1533 return nullptr; | 1531 return nullptr; |
1534 } | 1532 } |
1535 | 1533 |
1536 void* CFX_FolderFontInfo::FindFont(int weight, | 1534 void* CFX_FolderFontInfo::FindFont(int weight, |
1537 FX_BOOL bItalic, | 1535 FX_BOOL bItalic, |
1538 int charset, | 1536 int charset, |
1539 int pitch_family, | 1537 int pitch_family, |
1540 const FX_CHAR* family, | 1538 const FX_CHAR* family, |
1541 FX_BOOL bMatchName) { | 1539 FX_BOOL bMatchName) { |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1644 int PDF_GetStandardFontName(CFX_ByteString* name) { | 1642 int PDF_GetStandardFontName(CFX_ByteString* name) { |
1645 AltFontName* found = static_cast<AltFontName*>( | 1643 AltFontName* found = static_cast<AltFontName*>( |
1646 FXSYS_bsearch(name->c_str(), g_AltFontNames, FX_ArraySize(g_AltFontNames), | 1644 FXSYS_bsearch(name->c_str(), g_AltFontNames, FX_ArraySize(g_AltFontNames), |
1647 sizeof(AltFontName), CompareString)); | 1645 sizeof(AltFontName), CompareString)); |
1648 if (!found) | 1646 if (!found) |
1649 return -1; | 1647 return -1; |
1650 | 1648 |
1651 *name = g_Base14FontNames[found->m_Index]; | 1649 *name = g_Base14FontNames[found->m_Index]; |
1652 return found->m_Index; | 1650 return found->m_Index; |
1653 } | 1651 } |
OLD | NEW |