Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -245,43 +245,51 @@ void CFX_FolderFontInfo::ReportFace(const ByteString& path,

auto pInfo =
std::make_unique<FontFaceInfo>(path, facename, tables, offset, filesize);
pInfo->m_Styles = 0;
if (style.Contains("Bold"))
pInfo->m_Styles |= FXFONT_FORCE_BOLD;
if (style.Contains("Italic") || style.Contains("Oblique"))
pInfo->m_Styles |= FXFONT_ITALIC;
if (facename.Contains("Serif"))
pInfo->m_Styles |= FXFONT_SERIF;

// 必须先把该字体注册进 m_FontList,再通知 mapper:在字体枚举期间,
// CFX_FontMapper::AddInstalledFont() 会调用 GetFont(facename) 打开该字体
// 以读取其 PostScript 名。若像原先那样在调用之后再注册,枚举期间
// GetFont() 必然失败,已安装字体的 PostScript 名永远不会被索引,导致
// 后续按 PostScript 名的请求(如 PDF /BaseFont 中的 "FZXBSJW--GB1-0")
// 无法解析到已安装的字族。
FontFaceInfo* pFace = pInfo.get();
m_FontList[facename] = std::move(pInfo);

ByteString os2 =
LoadTableFromTT(pFile, tables.raw_str(), nTables, 0x4f532f32, filesize);
if (os2.GetLength() >= 86) {
const uint8_t* p = os2.raw_str() + 78;
uint32_t codepages = GET_TT_LONG(p);
if (codepages & (1U << 17)) {
m_pMapper->AddInstalledFont(facename, FX_CHARSET_ShiftJIS);
pInfo->m_Charsets |= CHARSET_FLAG_SHIFTJIS;
pFace->m_Charsets |= CHARSET_FLAG_SHIFTJIS;
}
if (codepages & (1U << 18)) {
m_pMapper->AddInstalledFont(facename, FX_CHARSET_ChineseSimplified);
pInfo->m_Charsets |= CHARSET_FLAG_GB;
pFace->m_Charsets |= CHARSET_FLAG_GB;
}
if (codepages & (1U << 20)) {
m_pMapper->AddInstalledFont(facename, FX_CHARSET_ChineseTraditional);
pInfo->m_Charsets |= CHARSET_FLAG_BIG5;
pFace->m_Charsets |= CHARSET_FLAG_BIG5;
}
if ((codepages & (1U << 19)) || (codepages & (1U << 21))) {
m_pMapper->AddInstalledFont(facename, FX_CHARSET_Hangul);
pInfo->m_Charsets |= CHARSET_FLAG_KOREAN;
pFace->m_Charsets |= CHARSET_FLAG_KOREAN;
}
if (codepages & (1U << 31)) {
m_pMapper->AddInstalledFont(facename, FX_CHARSET_Symbol);
pInfo->m_Charsets |= CHARSET_FLAG_SYMBOL;
pFace->m_Charsets |= CHARSET_FLAG_SYMBOL;
}
}
m_pMapper->AddInstalledFont(facename, FX_CHARSET_ANSI);
pInfo->m_Charsets |= CHARSET_FLAG_ANSI;
pInfo->m_Styles = 0;
if (style.Contains("Bold"))
pInfo->m_Styles |= FXFONT_FORCE_BOLD;
if (style.Contains("Italic") || style.Contains("Oblique"))
pInfo->m_Styles |= FXFONT_ITALIC;
if (facename.Contains("Serif"))
pInfo->m_Styles |= FXFONT_SERIF;

m_FontList[facename] = std::move(pInfo);
pFace->m_Charsets |= CHARSET_FLAG_ANSI;
}

void* CFX_FolderFontInfo::GetSubstFont(const ByteString& face) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,18 +323,26 @@ void CFX_FontMapper::AddInstalledFont(const ByteString& name, int charset) {
return static_cast<uint8_t>(c) > 0x80;
});

if (bLocalized) {
void* hFont = m_pFontInfo->GetFont(name.c_str());
if (!hFont) {
// 字体既可能通过族名(family name)引用,也可能通过 PostScript 名引用;
// 而 PDF 的 /BaseFont 条目通常携带的是 PostScript 名(例如族名
// "FZXiaoBiaoSong-B05S" 对应的 "FZXBSJW--GB1-0")。此处为每台已安装
// 字体中 PostScript 名与族名不同的字体建立 PostScript 名索引,使
// MatchInstalledFonts() 能把 PostScript 名请求解析到已安装的字体族上。
// 原先仅对本地化(含非 ASCII 字符)的族名做该索引,导致 ASCII 族名字体
// 的 PostScript 名请求永远无法匹配已安装字体,总会被无关的替代字体替换。
void* hFont = m_pFontInfo->GetFont(name.c_str());
if (!hFont && bLocalized) {
hFont = m_pFontInfo->MapFont(0, 0, FX_CHARSET_Default, 0, name.c_str());
Comment on lines +334 to 335

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium · PostScript font name is not indexed

When an external provider cannot resolve an ASCII family through GetFont() but can open it through MapFont(), AddInstalledFont() calls MapFont() only when bLocalized is true, so it never reads the font’s differing PostScript name and requests using that name fail to resolve to the installed family.

Try MapFont() when GetFont() returns null for an ASCII family as well.

Prompt for AI agents
In `3rdparty/deepin-pdfium/src/3rdparty/pdfium/pdfium/core/fxge/cfx_fontmapper.cpp` at lines 334-335:

**PostScript font name is not indexed**

When an external provider cannot resolve an ASCII family through `GetFont()` but can open it through `MapFont()`, `AddInstalledFont()` calls `MapFont()` only when `bLocalized` is true, so it never reads the font’s differing PostScript name and requests using that name fail to resolve to the installed family.

Try `MapFont()` when `GetFont()` returns null for an ASCII family as well.

if (!hFont)
return;
}

ByteString new_name = GetPSNameFromTT(hFont);
if (!new_name.IsEmpty())
m_LocalizedTTFonts.push_back(std::make_pair(new_name, name));
m_pFontInfo->DeleteFont(hFont);
}
if (hFont) {
ByteString ps_name = GetPSNameFromTT(hFont);
if (!ps_name.IsEmpty() &&
TT_NormalizeName(ps_name.c_str()) != TT_NormalizeName(name.c_str())) {
m_LocalizedTTFonts.push_back(std::make_pair(ps_name, name));
}
m_pFontInfo->DeleteFont(hFont);
} else if (bLocalized) {
return;
}
m_InstalledTTFonts.push_back(name);
m_LastFamily = name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ void* CFX_LinuxFontInfo::MapFont(int weight,
break;
}
case FX_CHARSET_ChineseSimplified: {
// 优先按请求的族名精确匹配,而不是直接落入硬编码回退列表:PDF 常以
// 某个已安装 CJK 字体的族名引用它(例如 "FZXiaoBiaoSong-B05S"),
// 该名字往往不在下方任何旧回退列表中;若不先做精确匹配,下方列表
// 会无条件替换为列表中第一个找到的字体,完全忽略请求的族名。
auto exact_it = m_FontList.find(family);
if (exact_it != m_FontList.end())
Comment on lines +121 to +122

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium · Installed Japanese font is ignored

When a PDF requests ShiftJIS text in an installed Japanese family that is absent from the hardcoded Japanese fallback lists, MapFont() searches g_LinuxJpFontList without checking m_FontList for the requested family, so it selects a generic fallback instead of the installed font.

Check m_FontList for the requested family before searching the Japanese fallback lists.

Prompt for AI agents
In `3rdparty/deepin-pdfium/src/3rdparty/pdfium/pdfium/core/fxge/fx_ge_linux.cpp` at lines 121-122:

**Installed Japanese font is ignored**

When a PDF requests ShiftJIS text in an installed Japanese family that is absent from the hardcoded Japanese fallback lists, `MapFont()` searches `g_LinuxJpFontList` without checking `m_FontList` for the requested family, so it selects a generic fallback instead of the installed font.

Check `m_FontList` for the requested family before searching the Japanese fallback lists.

return exact_it->second.get();
Comment on lines +122 to +123

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High · CJK text loses glyphs

When a requested CJK family is installed but its face lacks the requested charset, MapFont() returns exact_it without checking charset support, bypassing the CJK fallback list and rendering the text with a face that lacks the required glyphs.

Return the exact match only when it supports the requested charset; otherwise continue to the CJK fallback list.

Also at 3rdparty/deepin-pdfium/src/3rdparty/pdfium/pdfium/core/fxge/fx_ge_linux.cpp:133-135, 3rdparty/deepin-pdfium/src/3rdparty/pdfium/pdfium/core/fxge/fx_ge_linux.cpp:145-147.

Prompt for AI agents
In `3rdparty/deepin-pdfium/src/3rdparty/pdfium/pdfium/core/fxge/fx_ge_linux.cpp` at lines 122-123:

**CJK text loses glyphs**

When a requested CJK family is installed but its face lacks the requested charset, `MapFont()` returns `exact_it` without checking charset support, bypassing the CJK fallback list and rendering the text with a face that lacks the required glyphs.

Return the exact match only when it supports the requested charset; otherwise continue to the CJK fallback list.

Also at `3rdparty/deepin-pdfium/src/3rdparty/pdfium/pdfium/core/fxge/fx_ge_linux.cpp:133-135`, `3rdparty/deepin-pdfium/src/3rdparty/pdfium/pdfium/core/fxge/fx_ge_linux.cpp:145-147`.

Comment on lines +121 to +123

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium · Requested font style is ignored

When the family has an exact regular face and the request calls for a different weight or italic style, the exact-family branch returns the regular face without considering weight or bItalic, even when the requested styled face is installed.

Apply the requested weight and italic style when selecting an exact-family match.

Also at 3rdparty/deepin-pdfium/src/3rdparty/pdfium/pdfium/core/fxge/fx_ge_linux.cpp:133-135, 3rdparty/deepin-pdfium/src/3rdparty/pdfium/pdfium/core/fxge/fx_ge_linux.cpp:145-147.

Prompt for AI agents
In `3rdparty/deepin-pdfium/src/3rdparty/pdfium/pdfium/core/fxge/fx_ge_linux.cpp` at lines 121-123:

**Requested font style is ignored**

When the family has an exact regular face and the request calls for a different weight or italic style, the exact-family branch returns the regular face without considering `weight` or `bItalic`, even when the requested styled face is installed.

Apply the requested weight and italic style when selecting an exact-family match.

Also at `3rdparty/deepin-pdfium/src/3rdparty/pdfium/pdfium/core/fxge/fx_ge_linux.cpp:133-135`, `3rdparty/deepin-pdfium/src/3rdparty/pdfium/pdfium/core/fxge/fx_ge_linux.cpp:145-147`.

for (const char* name : g_LinuxGbFontList) {
auto it = m_FontList.find(name);
if (it != m_FontList.end())
Expand All @@ -122,6 +129,10 @@ void* CFX_LinuxFontInfo::MapFont(int weight,
break;
}
case FX_CHARSET_ChineseTraditional: {
// 参见上方 FX_CHARSET_ChineseSimplified 分支的注释。
auto exact_it = m_FontList.find(family);
if (exact_it != m_FontList.end())
return exact_it->second.get();
for (const char* name : g_LinuxB5FontList) {
auto it = m_FontList.find(name);
if (it != m_FontList.end())
Expand All @@ -130,6 +141,10 @@ void* CFX_LinuxFontInfo::MapFont(int weight,
break;
}
case FX_CHARSET_Hangul: {
// 参见上方 FX_CHARSET_ChineseSimplified 分支的注释。
auto exact_it = m_FontList.find(family);
if (exact_it != m_FontList.end())
return exact_it->second.get();
for (const char* name : g_LinuxHGFontList) {
auto it = m_FontList.find(name);
if (it != m_FontList.end())
Expand Down
Loading