kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 1 | // Copyright 2016 The PDFium Authors |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | |
| 7 | #include "core/fxge/cfx_folderfontinfo.h" |
| 8 | |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 9 | #include <iterator> |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 10 | #include <limits> |
| 11 | #include <utility> |
| 12 | |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 13 | #include "build/build_config.h" |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 14 | #include "core/fxcrt/fx_codepage.h" |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 15 | #include "core/fxcrt/fx_extension.h" |
| 16 | #include "core/fxcrt/fx_folder.h" |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 17 | #include "core/fxcrt/fx_memory_wrappers.h" |
| 18 | #include "core/fxcrt/fx_safe_types.h" |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 19 | #include "core/fxcrt/fx_system.h" |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 20 | #include "core/fxge/cfx_fontmapper.h" |
| 21 | #include "core/fxge/fx_font.h" |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 22 | #include "third_party/base/containers/contains.h" |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 23 | |
| 24 | namespace { |
| 25 | |
| 26 | const struct { |
| 27 | const char* m_pName; |
| 28 | const char* m_pSubstName; |
| 29 | } Base14Substs[] = { |
| 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"}, |
| 42 | }; |
| 43 | |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 44 | // Used with std::unique_ptr to automatically call fclose(). |
| 45 | struct FxFileCloser { |
| 46 | inline void operator()(FILE* h) const { |
| 47 | if (h) |
| 48 | fclose(h); |
| 49 | } |
| 50 | }; |
| 51 | |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 52 | bool 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()) |
| 56 | return false; |
| 57 | |
| 58 | size_t next_index = result.value() + family_name.GetLength(); |
| 59 | // Rule out the case that |family_name| is a substring of |
| 60 | // |installed_font_name| but their family names are actually different words. |
| 61 | // For example: "Univers" and "Universal" are not a match because they have |
| 62 | // different family names, but "Univers" and "Univers Bold" are a match. |
| 63 | if (installed_font_name.IsValidIndex(next_index) && |
| 64 | FXSYS_IsLowerASCII(installed_font_name[next_index])) { |
| 65 | return false; |
| 66 | } |
| 67 | |
| 68 | return true; |
| 69 | } |
| 70 | |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 71 | ByteString ReadStringFromFile(FILE* pFile, uint32_t size) { |
| 72 | ByteString result; |
| 73 | { |
| 74 | // Span's lifetime must end before ReleaseBuffer() below. |
| 75 | pdfium::span<char> buffer = result.GetBuffer(size); |
| 76 | if (!fread(buffer.data(), size, 1, pFile)) |
| 77 | return ByteString(); |
| 78 | } |
| 79 | result.ReleaseBuffer(size); |
| 80 | return result; |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 81 | } |
| 82 | |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 83 | ByteString LoadTableFromTT(FILE* pFile, |
| 84 | const uint8_t* pTables, |
| 85 | uint32_t nTables, |
| 86 | uint32_t tag, |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 87 | FX_FILESIZE fileSize) { |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 88 | for (uint32_t i = 0; i < nTables; i++) { |
| 89 | const uint8_t* p = pTables + i * 16; |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 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); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 93 | if (offset > std::numeric_limits<uint32_t>::max() - size || |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 94 | static_cast<FX_FILESIZE>(offset + size) > fileSize || |
| 95 | fseek(pFile, offset, SEEK_SET) < 0) { |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 96 | return ByteString(); |
| 97 | } |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 98 | return ReadStringFromFile(pFile, size); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 99 | } |
| 100 | } |
| 101 | return ByteString(); |
| 102 | } |
| 103 | |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 104 | uint32_t GetCharset(FX_Charset charset) { |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 105 | switch (charset) { |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 106 | case FX_Charset::kShiftJIS: |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 107 | return CHARSET_FLAG_SHIFTJIS; |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 108 | case FX_Charset::kChineseSimplified: |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 109 | return CHARSET_FLAG_GB; |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 110 | case FX_Charset::kChineseTraditional: |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 111 | return CHARSET_FLAG_BIG5; |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 112 | case FX_Charset::kHangul: |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 113 | return CHARSET_FLAG_KOREAN; |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 114 | case FX_Charset::kSymbol: |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 115 | return CHARSET_FLAG_SYMBOL; |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 116 | case FX_Charset::kANSI: |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 117 | return CHARSET_FLAG_ANSI; |
| 118 | default: |
| 119 | break; |
| 120 | } |
| 121 | return 0; |
| 122 | } |
| 123 | |
| 124 | int32_t GetSimilarValue(int weight, |
| 125 | bool bItalic, |
| 126 | int pitch_family, |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 127 | uint32_t style, |
| 128 | bool bMatchName, |
| 129 | size_t familyNameLength, |
| 130 | size_t bsNameLength) { |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 131 | int32_t iSimilarValue = 0; |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 132 | if (bMatchName && (familyNameLength == bsNameLength)) |
| 133 | iSimilarValue += 4; |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 134 | if (FontStyleIsForceBold(style) == (weight > 400)) |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 135 | iSimilarValue += 16; |
| 136 | if (FontStyleIsItalic(style) == bItalic) |
| 137 | iSimilarValue += 16; |
| 138 | if (FontStyleIsSerif(style) == FontFamilyIsRoman(pitch_family)) |
| 139 | iSimilarValue += 16; |
| 140 | if (FontStyleIsScript(style) == FontFamilyIsScript(pitch_family)) |
| 141 | iSimilarValue += 8; |
| 142 | if (FontStyleIsFixedPitch(style) == FontFamilyIsFixedPitch(pitch_family)) |
| 143 | iSimilarValue += 8; |
| 144 | return iSimilarValue; |
| 145 | } |
| 146 | |
| 147 | } // namespace |
| 148 | |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 149 | CFX_FolderFontInfo::CFX_FolderFontInfo() = default; |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 150 | |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 151 | CFX_FolderFontInfo::~CFX_FolderFontInfo() = default; |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 152 | |
| 153 | void CFX_FolderFontInfo::AddPath(const ByteString& path) { |
| 154 | m_PathList.push_back(path); |
| 155 | } |
| 156 | |
| 157 | bool CFX_FolderFontInfo::EnumFontList(CFX_FontMapper* pMapper) { |
| 158 | m_pMapper = pMapper; |
| 159 | for (const auto& path : m_PathList) |
| 160 | ScanPath(path); |
| 161 | return true; |
| 162 | } |
| 163 | |
| 164 | void CFX_FolderFontInfo::ScanPath(const ByteString& path) { |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 165 | std::unique_ptr<FX_Folder> handle = FX_Folder::OpenFolder(path); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 166 | if (!handle) |
| 167 | return; |
| 168 | |
| 169 | ByteString filename; |
| 170 | bool bFolder; |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 171 | while (handle->GetNextFile(&filename, &bFolder)) { |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 172 | if (bFolder) { |
| 173 | if (filename == "." || filename == "..") |
| 174 | continue; |
| 175 | } else { |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 176 | ByteString ext = filename.Last(4); |
| 177 | ext.MakeLower(); |
| 178 | if (ext != ".ttf" && ext != ".ttc" && ext != ".otf") |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 179 | continue; |
| 180 | } |
| 181 | |
| 182 | ByteString fullpath = path; |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 183 | #if BUILDFLAG(IS_WIN) |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 184 | fullpath += "\\"; |
| 185 | #else |
| 186 | fullpath += "/"; |
| 187 | #endif |
| 188 | |
| 189 | fullpath += filename; |
| 190 | bFolder ? ScanPath(fullpath) : ScanFile(fullpath); |
| 191 | } |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 192 | } |
| 193 | |
| 194 | void CFX_FolderFontInfo::ScanFile(const ByteString& path) { |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 195 | std::unique_ptr<FILE, FxFileCloser> pFile(fopen(path.c_str(), "rb")); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 196 | if (!pFile) |
| 197 | return; |
| 198 | |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 199 | fseek(pFile.get(), 0, SEEK_END); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 200 | |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 201 | FX_FILESIZE filesize = ftell(pFile.get()); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 202 | uint8_t buffer[16]; |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 203 | fseek(pFile.get(), 0, SEEK_SET); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 204 | |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 205 | size_t readCnt = fread(buffer, 12, 1, pFile.get()); |
| 206 | if (readCnt != 1) |
| 207 | return; |
| 208 | |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 209 | if (FXSYS_UINT32_GET_MSBFIRST(buffer) != kTableTTCF) { |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 210 | ReportFace(path, pFile.get(), filesize, 0); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 211 | return; |
| 212 | } |
| 213 | |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 214 | uint32_t nFaces = FXSYS_UINT32_GET_MSBFIRST(buffer + 8); |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 215 | FX_SAFE_SIZE_T safe_face_bytes = nFaces; |
| 216 | safe_face_bytes *= 4; |
| 217 | if (!safe_face_bytes.IsValid()) |
| 218 | return; |
| 219 | |
| 220 | const size_t face_bytes = safe_face_bytes.ValueOrDie(); |
| 221 | std::unique_ptr<uint8_t, FxFreeDeleter> offsets( |
| 222 | FX_Alloc(uint8_t, face_bytes)); |
| 223 | readCnt = fread(offsets.get(), 1, face_bytes, pFile.get()); |
| 224 | if (readCnt != face_bytes) |
| 225 | return; |
| 226 | |
| 227 | auto offsets_span = pdfium::make_span(offsets.get(), face_bytes); |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 228 | for (uint32_t i = 0; i < nFaces; i++) { |
| 229 | ReportFace(path, pFile.get(), filesize, |
| 230 | FXSYS_UINT32_GET_MSBFIRST(&offsets_span[i * 4])); |
| 231 | } |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 232 | } |
| 233 | |
| 234 | void CFX_FolderFontInfo::ReportFace(const ByteString& path, |
| 235 | FILE* pFile, |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 236 | FX_FILESIZE filesize, |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 237 | uint32_t offset) { |
| 238 | char buffer[16]; |
| 239 | if (fseek(pFile, offset, SEEK_SET) < 0 || !fread(buffer, 12, 1, pFile)) |
| 240 | return; |
| 241 | |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 242 | uint32_t nTables = FXSYS_UINT16_GET_MSBFIRST(buffer + 4); |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 243 | ByteString tables = ReadStringFromFile(pFile, nTables * 16); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 244 | if (tables.IsEmpty()) |
| 245 | return; |
| 246 | |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 247 | static constexpr uint32_t kNameTag = |
| 248 | CFX_FontMapper::MakeTag('n', 'a', 'm', 'e'); |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 249 | ByteString names = |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 250 | LoadTableFromTT(pFile, tables.raw_str(), nTables, kNameTag, filesize); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 251 | if (names.IsEmpty()) |
| 252 | return; |
| 253 | |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 254 | ByteString facename = GetNameFromTT(names.raw_span(), 1); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 255 | if (facename.IsEmpty()) |
| 256 | return; |
| 257 | |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 258 | ByteString style = GetNameFromTT(names.raw_span(), 2); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 259 | if (style != "Regular") |
| 260 | facename += " " + style; |
| 261 | |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 262 | if (pdfium::Contains(m_FontList, facename)) |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 263 | return; |
| 264 | |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 265 | auto pInfo = |
| 266 | std::make_unique<FontFaceInfo>(path, facename, tables, offset, filesize); |
| 267 | static constexpr uint32_t kOs2Tag = |
| 268 | CFX_FontMapper::MakeTag('O', 'S', '/', '2'); |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 269 | ByteString os2 = |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 270 | LoadTableFromTT(pFile, tables.raw_str(), nTables, kOs2Tag, filesize); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 271 | if (os2.GetLength() >= 86) { |
| 272 | const uint8_t* p = os2.raw_str() + 78; |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 273 | uint32_t codepages = FXSYS_UINT32_GET_MSBFIRST(p); |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 274 | if (codepages & (1U << 17)) { |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 275 | m_pMapper->AddInstalledFont(facename, FX_Charset::kShiftJIS); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 276 | pInfo->m_Charsets |= CHARSET_FLAG_SHIFTJIS; |
| 277 | } |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 278 | if (codepages & (1U << 18)) { |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 279 | m_pMapper->AddInstalledFont(facename, FX_Charset::kChineseSimplified); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 280 | pInfo->m_Charsets |= CHARSET_FLAG_GB; |
| 281 | } |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 282 | if (codepages & (1U << 20)) { |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 283 | m_pMapper->AddInstalledFont(facename, FX_Charset::kChineseTraditional); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 284 | pInfo->m_Charsets |= CHARSET_FLAG_BIG5; |
| 285 | } |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 286 | if ((codepages & (1U << 19)) || (codepages & (1U << 21))) { |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 287 | m_pMapper->AddInstalledFont(facename, FX_Charset::kHangul); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 288 | pInfo->m_Charsets |= CHARSET_FLAG_KOREAN; |
| 289 | } |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 290 | if (codepages & (1U << 31)) { |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 291 | m_pMapper->AddInstalledFont(facename, FX_Charset::kSymbol); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 292 | pInfo->m_Charsets |= CHARSET_FLAG_SYMBOL; |
| 293 | } |
| 294 | } |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 295 | m_pMapper->AddInstalledFont(facename, FX_Charset::kANSI); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 296 | pInfo->m_Charsets |= CHARSET_FLAG_ANSI; |
| 297 | pInfo->m_Styles = 0; |
| 298 | if (style.Contains("Bold")) |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 299 | pInfo->m_Styles |= FXFONT_FORCE_BOLD; |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 300 | if (style.Contains("Italic") || style.Contains("Oblique")) |
| 301 | pInfo->m_Styles |= FXFONT_ITALIC; |
| 302 | if (facename.Contains("Serif")) |
| 303 | pInfo->m_Styles |= FXFONT_SERIF; |
| 304 | |
| 305 | m_FontList[facename] = std::move(pInfo); |
| 306 | } |
| 307 | |
| 308 | void* CFX_FolderFontInfo::GetSubstFont(const ByteString& face) { |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 309 | for (size_t iBaseFont = 0; iBaseFont < std::size(Base14Substs); iBaseFont++) { |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 310 | if (face == Base14Substs[iBaseFont].m_pName) |
| 311 | return GetFont(Base14Substs[iBaseFont].m_pSubstName); |
| 312 | } |
| 313 | return nullptr; |
| 314 | } |
| 315 | |
| 316 | void* CFX_FolderFontInfo::FindFont(int weight, |
| 317 | bool bItalic, |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 318 | FX_Charset charset, |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 319 | int pitch_family, |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 320 | const ByteString& family, |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 321 | bool bMatchName) { |
| 322 | FontFaceInfo* pFind = nullptr; |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 323 | |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 324 | ByteStringView bsFamily = family.AsStringView(); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 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(); |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 330 | if (!(pFont->m_Charsets & charset_flag) && charset != FX_Charset::kDefault) |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 331 | continue; |
| 332 | |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 333 | if (bMatchName && !FindFamilyNameMatch(bsFamily, bsName)) |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 334 | continue; |
| 335 | |
| 336 | int32_t iSimilarValue = |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 337 | GetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles, |
| 338 | bMatchName, bsFamily.GetLength(), bsName.GetLength()); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 339 | if (iSimilarValue > iBestSimilar) { |
| 340 | iBestSimilar = iSimilarValue; |
| 341 | pFind = pFont; |
| 342 | } |
| 343 | } |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 344 | |
| 345 | if (pFind) { |
| 346 | return pFind; |
| 347 | } |
| 348 | |
| 349 | if (charset == FX_Charset::kANSI && FontFamilyIsFixedPitch(pitch_family)) { |
| 350 | auto* courier_new = GetFont("Courier New"); |
| 351 | if (courier_new) |
| 352 | return courier_new; |
| 353 | } |
| 354 | |
| 355 | return nullptr; |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 356 | } |
| 357 | |
| 358 | void* CFX_FolderFontInfo::MapFont(int weight, |
| 359 | bool bItalic, |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 360 | FX_Charset charset, |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 361 | int pitch_family, |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 362 | const ByteString& face) { |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 363 | return nullptr; |
| 364 | } |
| 365 | |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 366 | void* CFX_FolderFontInfo::GetFont(const ByteString& face) { |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 367 | auto it = m_FontList.find(face); |
| 368 | return it != m_FontList.end() ? it->second.get() : nullptr; |
| 369 | } |
| 370 | |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 371 | size_t CFX_FolderFontInfo::GetFontData(void* hFont, |
| 372 | uint32_t table, |
| 373 | pdfium::span<uint8_t> buffer) { |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 374 | if (!hFont) |
| 375 | return 0; |
| 376 | |
| 377 | const FontFaceInfo* pFont = static_cast<FontFaceInfo*>(hFont); |
| 378 | uint32_t datasize = 0; |
| 379 | uint32_t offset = 0; |
| 380 | if (table == 0) { |
| 381 | datasize = pFont->m_FontOffset ? 0 : pFont->m_FileSize; |
| 382 | } else if (table == kTableTTCF) { |
| 383 | datasize = pFont->m_FontOffset ? pFont->m_FileSize : 0; |
| 384 | } else { |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 385 | size_t nTables = pFont->m_FontTables.GetLength() / 16; |
| 386 | for (size_t i = 0; i < nTables; i++) { |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 387 | const uint8_t* p = pFont->m_FontTables.raw_str() + i * 16; |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 388 | if (FXSYS_UINT32_GET_MSBFIRST(p) == table) { |
| 389 | offset = FXSYS_UINT32_GET_MSBFIRST(p + 8); |
| 390 | datasize = FXSYS_UINT32_GET_MSBFIRST(p + 12); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 391 | } |
| 392 | } |
| 393 | } |
| 394 | |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 395 | if (!datasize || buffer.size() < datasize) |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 396 | return datasize; |
| 397 | |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 398 | std::unique_ptr<FILE, FxFileCloser> pFile( |
| 399 | fopen(pFont->m_FilePath.c_str(), "rb")); |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 400 | if (!pFile) |
| 401 | return 0; |
| 402 | |
Haibo Huang | 49cc930 | 2020-04-27 16:14:24 -0700 | [diff] [blame] | 403 | if (fseek(pFile.get(), offset, SEEK_SET) < 0 || |
| 404 | fread(buffer.data(), datasize, 1, pFile.get()) != 1) { |
| 405 | return 0; |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 406 | } |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 407 | return datasize; |
| 408 | } |
| 409 | |
| 410 | void CFX_FolderFontInfo::DeleteFont(void* hFont) {} |
| 411 | |
| 412 | bool CFX_FolderFontInfo::GetFaceName(void* hFont, ByteString* name) { |
| 413 | if (!hFont) |
| 414 | return false; |
| 415 | *name = static_cast<FontFaceInfo*>(hFont)->m_FaceName; |
| 416 | return true; |
| 417 | } |
| 418 | |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 419 | bool CFX_FolderFontInfo::GetFontCharset(void* hFont, FX_Charset* charset) { |
Philip P. Moltmann | d904c1e | 2018-03-19 09:26:45 -0700 | [diff] [blame] | 420 | return false; |
| 421 | } |
| 422 | |
| 423 | CFX_FolderFontInfo::FontFaceInfo::FontFaceInfo(ByteString filePath, |
| 424 | ByteString faceName, |
| 425 | ByteString fontTables, |
| 426 | uint32_t fontOffset, |
| 427 | uint32_t fileSize) |
| 428 | : m_FilePath(filePath), |
| 429 | m_FaceName(faceName), |
| 430 | m_FontTables(fontTables), |
| 431 | m_FontOffset(fontOffset), |
kumarashishg | 826308d | 2023-06-23 13:21:22 +0000 | [diff] [blame] | 432 | m_FileSize(fileSize) {} |