0

Improve fallback handling for CamelCase fonts

From early Canary trials we observe unfulfilled requests
for fonts named in CamelCase without spaces which do not
resolve using the Skia mechanisms. e.g. `TrebuchetMS`
can resolve as `Trebuchet MS`. We attempt to find these
fonts by applying a regex to the face name that inserts
a space between lowercase and uppercase characters.

Additionally, we observe that, like ArialBlack, some
requests for ArialNarrow specify a bad weight. Handling
for ArialNarrow and common variants is added.

This CL only affects PDFium running in Chrome if the
WinPdfUseFontProxy feature is enabled.

Tests: pdf_unittests.exe --gtest_filter=PDFiumFontWinTest.*
Bug: 344643689
Change-Id: Icca13fae5ff17d6abe303e983da8795da6a33c24
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5660721
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Alex Gough <ajgo@chromium.org>
Reviewed-by: Rick Byers <rbyers@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1321146}
This commit is contained in:
Alex Gough
2024-06-28 19:52:13 +00:00
committed by Chromium LUCI CQ
parent 3af5dd4a06
commit 745114d657
4 changed files with 38 additions and 7 deletions

@ -200,6 +200,7 @@ if (enable_pdf) {
"pdfium/pdfium_font_win.cc",
"pdfium/pdfium_font_win.h",
]
deps += [ "//third_party/re2" ]
}
if (is_chromeos) {

@ -2,6 +2,7 @@ include_rules = [
"+components/services/font/public/cpp",
"+skia/ext/font_utils.h",
"+third_party/pdfium/public",
"+third_party/re2/src/re2/re2.h",
"+ui/accessibility",
"+ui/gfx/codec",
]

@ -26,6 +26,7 @@
#include "skia/ext/font_utils.h"
#include "third_party/blink/public/platform/web_font_description.h"
#include "third_party/pdfium/public/fpdf_sysfontinfo.h"
#include "third_party/re2/src/re2/re2.h"
#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/core/SkFontStyle.h"
#include "third_party/skia/include/core/SkStream.h"
@ -295,13 +296,25 @@ class SkiaFontMapper {
const SkFontStyle& style) {
// Some fonts are specified with weights that Skia can't provide.
// pdf.js/tests/issue5801.pdf specifies ArialBlack but a weight of 390.
if (face == "ArialBlack" || face == "Arial Black") {
SkFontStyle force_black = SkFontStyle(SkFontStyle::Weight::kBlack_Weight,
style.width(), style.slant());
return manager_->matchFamilyStyle("Arial", force_black);
// Commonly seen patterns: `ArialBlack` `Arial Black` & `Arial-Black`.
if (base::StartsWith(face, "Arial")) {
if (base::EndsWith(face, "Black")) {
SkFontStyle black = SkFontStyle(SkFontStyle::Weight::kBlack_Weight,
style.width(), style.slant());
return manager_->matchFamilyStyle("Arial", black);
}
if (base::EndsWith(face, "Narrow")) {
SkFontStyle narrow = SkFontStyle(SkFontStyle::Weight::kThin_Weight,
style.width(), style.slant());
return manager_->matchFamilyStyle("Arial", narrow);
}
}
if (face == "ComicSansMS") {
return manager_->matchFamilyStyle("Comic Sans MS", style);
// Some fonts are specified without spaces in their name e.g. `ComicSansMS`.
std::string with_spaces(face);
// s/{lower case letter}{uppercase letter}/l u/g.
if (re2::RE2::GlobalReplace(&with_spaces, "(\\p{Ll})(\\p{Lu})", "\\1 \\2") >
0) {
return manager_->matchFamilyStyle(with_spaces.c_str(), style);
}
return nullptr;
}

@ -143,7 +143,7 @@ TEST_F(PDFiumFontWinTest, FallbackFontsHangeul) {
DeleteFont(id);
}
TEST_F(PDFiumFontWinTest, FinalFixups) {
TEST_F(PDFiumFontWinTest, FinalFixupsArialBlack) {
// ArialBlack with a low weight needs to be forced to weight kBlack.
FontId id = MapFont(390, false, FXFONT_DEFAULT_CHARSET, FXFONT_FF_ROMAN,
"ArialBlack");
@ -151,4 +151,20 @@ TEST_F(PDFiumFontWinTest, FinalFixups) {
DeleteFont(id);
}
TEST_F(PDFiumFontWinTest, FinalFixupsComicSansMS) {
// ComicSansMS -> Comic Sans MS.
FontId id = MapFont(FXFONT_FW_NORMAL, false, FXFONT_DEFAULT_CHARSET,
FXFONT_FF_ROMAN, "ComicSansMS");
EXPECT_TRUE(id);
DeleteFont(id);
}
TEST_F(PDFiumFontWinTest, FinalFixupsTrebuchetMS) {
// TrebuchetMS -> Trebuchet MS.
FontId id = MapFont(FXFONT_FW_NORMAL, false, FXFONT_DEFAULT_CHARSET,
FXFONT_FF_ROMAN, "TrebuchetMS");
EXPECT_TRUE(id);
DeleteFont(id);
}
} // namespace chrome_pdf