7#include "core/fxge/cfx_folderfontinfo.h"
13#include "build/build_config.h"
14#include "core/fxcrt/fx_codepage.h"
15#include "core/fxcrt/fx_extension.h"
16#include "core/fxcrt/fx_folder.h"
17#include "core/fxcrt/fx_memory_wrappers.h"
18#include "core/fxcrt/fx_safe_types.h"
19#include "core/fxcrt/fx_system.h"
20#include "core/fxge/cfx_fontmapper.h"
21#include "core/fxge/fx_font.h"
22#include "third_party/base/containers/contains.h"
28 const char* m_pSubstName;
30 {
"Courier",
"Courier New"},
31 {
"Courier-Bold",
"Courier New Bold"},
32 {
"Courier-BoldOblique",
"Courier New Bold Italic"},
33 {
"Courier-Oblique",
"Courier New Italic"},
34 {
"Helvetica",
"Arial"},
35 {
"Helvetica-Bold",
"Arial Bold"},
36 {
"Helvetica-BoldOblique",
"Arial Bold Italic"},
37 {
"Helvetica-Oblique",
"Arial Italic"},
38 {
"Times-Roman",
"Times New Roman"},
39 {
"Times-Bold",
"Times New Roman Bold"},
40 {
"Times-BoldItalic",
"Times New Roman Bold Italic"},
41 {
"Times-Italic",
"Times New Roman Italic"},
46 inline void operator()(FILE* h)
const {
52bool FindFamilyNameMatch(ByteStringView family_name,
53 const ByteString& installed_font_name) {
54 absl::optional<size_t> result = installed_font_name.Find(family_name, 0);
55 if (!result.has_value())
58 size_t next_index = result.value() + family_name.GetLength();
63 if (installed_font_name.IsValidIndex(next_index) &&
64 FXSYS_IsLowerASCII(installed_font_name[next_index])) {
71ByteString ReadStringFromFile(FILE* pFile, uint32_t size) {
75 pdfium::span<
char> buffer = result.GetBuffer(size);
76 if (!fread(buffer.data(), size, 1, pFile))
79 result.ReleaseBuffer(size);
83ByteString LoadTableFromTT(FILE* pFile,
84 const uint8_t* pTables,
88 for (uint32_t i = 0; i < nTables; i++) {
89 const uint8_t* p = pTables + i * 16;
90 if (FXSYS_UINT32_GET_MSBFIRST(p) == tag) {
91 uint32_t offset = FXSYS_UINT32_GET_MSBFIRST(p + 8);
92 uint32_t size = FXSYS_UINT32_GET_MSBFIRST(p + 12);
93 if (offset >
std::numeric_limits<uint32_t>::max() - size ||
94 static_cast<
FX_FILESIZE>(offset + size) > fileSize ||
95 fseek(pFile, offset, SEEK_SET) < 0) {
98 return ReadStringFromFile(pFile, size);
124int32_t GetSimilarValue(
int weight,
129 size_t familyNameLength,
130 size_t bsNameLength) {
131 int32_t iSimilarValue = 0;
132 if (bMatchName && (familyNameLength == bsNameLength))
144 return iSimilarValue;
154 m_PathList.push_back(path);
159 for (
const auto& path : m_PathList)
165 std::unique_ptr<FX_Folder> handle = FX_Folder::OpenFolder(path);
171 while (handle->GetNextFile(&filename, &bFolder)) {
173 if (filename
== "." || filename
== "..")
176 ByteString ext = filename.Last(4);
178 if (ext
!= ".ttf" && ext
!= ".ttc" && ext
!= ".otf")
182 ByteString fullpath = path;
189 fullpath
+= filename;
195 std::unique_ptr<FILE, FxFileCloser> pFile(fopen(path.c_str(),
"rb"));
199 fseek(pFile.get(), 0, SEEK_END);
203 fseek(pFile.get(), 0, SEEK_SET);
205 size_t readCnt = fread(buffer, 12, 1, pFile.get());
209 if (FXSYS_UINT32_GET_MSBFIRST(buffer) !=
kTableTTCF) {
214 uint32_t nFaces = FXSYS_UINT32_GET_MSBFIRST(buffer + 8);
215 FX_SAFE_SIZE_T safe_face_bytes = nFaces;
216 safe_face_bytes *= 4;
217 if (!safe_face_bytes.IsValid())
220 const size_t face_bytes = safe_face_bytes.ValueOrDie();
222 FX_Alloc(uint8_t, face_bytes));
223 readCnt = fread(offsets.get(), 1, face_bytes, pFile.get());
224 if (readCnt != face_bytes)
227 auto offsets_span = pdfium::make_span(offsets.get(), face_bytes);
228 for (uint32_t i = 0; i < nFaces; i++) {
230 FXSYS_UINT32_GET_MSBFIRST(&offsets_span[i * 4]
));
239 if (fseek(pFile, offset, SEEK_SET) < 0 || !fread(buffer, 12, 1, pFile))
242 uint32_t nTables = FXSYS_UINT16_GET_MSBFIRST(buffer + 4);
243 ByteString tables = ReadStringFromFile(pFile, nTables * 16);
247 static constexpr uint32_t kNameTag =
250 LoadTableFromTT(pFile, tables
.raw_str(), nTables, kNameTag, filesize);
254 ByteString facename = GetNameFromTT(names.raw_span(), 1);
258 ByteString style = GetNameFromTT(names.raw_span(), 2);
259 if (style
!= "Regular")
260 facename
+= " " + style;
262 if (pdfium::Contains(m_FontList, facename))
266 std::make_unique<
FontFaceInfo>(path, facename, tables, offset, filesize);
267 static constexpr uint32_t kOs2Tag =
270 LoadTableFromTT(pFile, tables
.raw_str(), nTables, kOs2Tag, filesize);
271 if (os2.GetLength() >= 86) {
273 uint32_t codepages = FXSYS_UINT32_GET_MSBFIRST(p);
274 if (codepages & (1U << 17)) {
275 m_pMapper->AddInstalledFont(facename, FX_Charset::kShiftJIS);
278 if (codepages & (1U << 18)) {
279 m_pMapper->AddInstalledFont(facename, FX_Charset::kChineseSimplified);
282 if (codepages & (1U << 20)) {
283 m_pMapper->AddInstalledFont(facename, FX_Charset::kChineseTraditional);
286 if ((codepages & (1U << 19)) || (codepages & (1U << 21))) {
287 m_pMapper->AddInstalledFont(facename, FX_Charset::kHangul);
290 if (codepages & (1U << 31)) {
291 m_pMapper->AddInstalledFont(facename, FX_Charset::kSymbol);
295 m_pMapper->AddInstalledFont(facename, FX_Charset::kANSI);
298 if (style.Contains(
"Bold"))
300 if (style.Contains(
"Italic") || style.Contains(
"Oblique"))
302 if (facename.Contains(
"Serif"))
305 m_FontList[facename] = std::move(pInfo);
309 for (size_t iBaseFont = 0; iBaseFont <
std::size(Base14Substs); iBaseFont++) {
310 if (face == Base14Substs[iBaseFont].m_pName)
311 return GetFont(Base14Substs[iBaseFont].m_pSubstName
);
320 const ByteString& family,
324 ByteStringView bsFamily = family.AsStringView();
325 uint32_t charset_flag = GetCharset(charset);
326 int32_t iBestSimilar = 0;
327 for (
const auto& it : m_FontList) {
328 const ByteString& bsName = it.first;
329 FontFaceInfo* pFont = it.second.get();
330 if (!(pFont->m_Charsets & charset_flag) && charset != FX_Charset::kDefault)
333 if (bMatchName && !FindFamilyNameMatch(bsFamily, bsName))
336 int32_t iSimilarValue =
337 GetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles,
338 bMatchName, bsFamily.GetLength(), bsName.GetLength());
339 if (iSimilarValue > iBestSimilar) {
340 iBestSimilar = iSimilarValue;
350 auto* courier_new =
GetFont("Courier New");
362 const ByteString& face) {
367 auto it = m_FontList.find(face);
368 return it != m_FontList.end() ? it->second.get() :
nullptr;
373 pdfium::span<uint8_t> buffer) {
378 uint32_t datasize = 0;
385 size_t nTables = pFont->m_FontTables.GetLength() / 16;
386 for (size_t i = 0; i < nTables; i++) {
387 const uint8_t* p = pFont->m_FontTables.raw_str() + i * 16;
388 if (FXSYS_UINT32_GET_MSBFIRST(p) == table) {
389 offset = FXSYS_UINT32_GET_MSBFIRST(p + 8);
390 datasize = FXSYS_UINT32_GET_MSBFIRST(p + 12);
395 if (!datasize || buffer.size() < datasize)
398 std::unique_ptr<FILE, FxFileCloser> pFile(
399 fopen(pFont->m_FilePath.c_str(),
"rb"));
403 if (fseek(pFile.get(), offset, SEEK_SET) < 0 ||
404 fread(buffer.data(), datasize, 1, pFile.get()) != 1) {
425 ByteString fontTables,
#define CHARSET_FLAG_SHIFTJIS
#define CHARSET_FLAG_ANSI
#define CHARSET_FLAG_BIG5
#define CHARSET_FLAG_SYMBOL
#define CHARSET_FLAG_KOREAN
const uint32_t m_FontOffset
FontFaceInfo(ByteString filePath, ByteString faceName, ByteString fontTables, uint32_t fontOffset, uint32_t fileSize)
const uint32_t m_FileSize
~CFX_FolderFontInfo() override
void ScanFile(const ByteString &path)
bool GetFontCharset(void *hFont, FX_Charset *charset) override
size_t GetFontData(void *hFont, uint32_t table, pdfium::span< uint8_t > buffer) override
void * GetSubstFont(const ByteString &face)
void DeleteFont(void *hFont) override
void * FindFont(int weight, bool bItalic, FX_Charset charset, int pitch_family, const ByteString &family, bool bMatchName)
void ReportFace(const ByteString &path, FILE *pFile, FX_FILESIZE filesize, uint32_t offset)
bool GetFaceName(void *hFont, ByteString *name) override
void ScanPath(const ByteString &path)
void * MapFont(int weight, bool bItalic, FX_Charset charset, int pitch_family, const ByteString &face) override
void AddPath(const ByteString &path)
void * GetFont(const ByteString &face) override
bool EnumFontList(CFX_FontMapper *pMapper) override
static constexpr uint32_t MakeTag(char c1, char c2, char c3, char c4)
ByteString & operator+=(const ByteString &str)
const uint8_t * raw_str() const
bool operator==(const char *ptr) const
ByteString & operator+=(const char *str)
bool operator!=(const char *ptr) const
bool FontFamilyIsFixedPitch(uint32_t family)
bool FontStyleIsSerif(uint32_t style)
bool FontStyleIsFixedPitch(uint32_t style)
bool FontFamilyIsScript(int32_t family)
bool FontFamilyIsRoman(uint32_t family)
bool FontStyleIsItalic(uint32_t style)
#define FXFONT_FORCE_BOLD
bool FontStyleIsScript(uint32_t style)
bool FontStyleIsForceBold(uint32_t style)
ByteString operator+(const char *str1, const ByteString &str2)
constexpr uint32_t kTableTTCF