Skip to content

Commit

Permalink
Add font substituted metrics for OS other than Linux
Browse files Browse the repository at this point in the history
Created a struct FPDF_SYSFONTINFO_WITHMETRICS to be able to call and
override methods from the default system font infos, for OS's other
than Linux. This was necessary because the function pointers in the
struct contain pointers to the struct. FPDF_GetDefaultSystemFontInfo
returns a pointer to a FPDF_SYSFONTINFO, but in reality it is a
FPDF_SYSFONTINFO_DEFAULT. So the overriden methods need to receive
as input the pointer given by FPDF_GetDefaultSystemFontInfo.

BUG=448584

Review-Url: https://codereview.chromium.org/2479313005
Cr-Commit-Position: refs/heads/master@{#431103}
  • Loading branch information
npm1 authored and Commit bot committed Nov 10, 2016
1 parent d5e3696 commit 394c066
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 14 deletions.
6 changes: 0 additions & 6 deletions pdf/out_of_process_instance.cc
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,7 @@ OutOfProcessInstance::OutOfProcessInstance(PP_Instance instance)
preview_document_load_state_(LOAD_STATE_COMPLETE),
uma_(this),
told_browser_about_unsupported_feature_(false),
#if defined(OS_LINUX)
font_substitution_reported_(false),
#endif
print_preview_page_count_(0),
last_progress_sent_(0),
recently_sent_find_update_(false),
Expand Down Expand Up @@ -1300,10 +1298,8 @@ void OutOfProcessInstance::DocumentLoadComplete(int page_count) {
UserMetricsRecordAction("PDF.LoadSuccess");
uma_.HistogramEnumeration("PDF.DocumentFeature", LOADED_DOCUMENT,
FEATURES_COUNT);
#if defined(OS_LINUX)
if (!font_substitution_reported_)
uma_.HistogramEnumeration("PDF.IsFontSubstituted", 0, 2);
#endif

// Note: If we are in print preview mode the scroll location is retained
// across document loads so we don't want to scroll again and override it.
Expand Down Expand Up @@ -1411,12 +1407,10 @@ void OutOfProcessInstance::DocumentLoadFailed() {
}

void OutOfProcessInstance::FontSubstituted() {
#if defined(OS_LINUX)
if (font_substitution_reported_)
return;
font_substitution_reported_ = true;
uma_.HistogramEnumeration("PDF.IsFontSubstituted", 1, 2);
#endif
}

void OutOfProcessInstance::PreviewDocumentLoadFailed() {
Expand Down
2 changes: 0 additions & 2 deletions pdf/out_of_process_instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,11 +331,9 @@ class OutOfProcessInstance : public pp::Instance,
// the stats if a feature shows up many times per document.
std::set<std::string> unsupported_features_reported_;

#if defined(OS_LINUX)
// Keeps track of whether font substitution has been reported, so we avoid
// spamming the stats if a document requested multiple substitutes.
bool font_substitution_reported_;
#endif

// Number of pages in print preview mode, 0 if not in print preview mode.
int print_preview_page_count_;
Expand Down
140 changes: 134 additions & 6 deletions pdf/pdfium/pdfium_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ std::vector<uint32_t> GetPageNumbersFromPrintPageNumberRange(

PP_Instance g_last_instance_id;

// TODO(npm): Move font stuff to another file to reduce the size of this one
PP_BrowserFont_Trusted_Weight WeightToBrowserFontTrustedWeight(int weight) {
static_assert(PP_BROWSERFONT_TRUSTED_WEIGHT_100 == 0,
"PP_BrowserFont_Trusted_Weight min");
Expand All @@ -147,7 +148,7 @@ PP_BrowserFont_Trusted_Weight WeightToBrowserFontTrustedWeight(int weight) {
// This list is for CPWL_FontMap::GetDefaultFontByCharset().
// We pretend to have these font natively and let the browser (or underlying
// fontconfig) to pick the proper font on the system.
void EnumFonts(struct _FPDF_SYSFONTINFO* sysfontinfo, void* mapper) {
void EnumFonts(FPDF_SYSFONTINFO* sysfontinfo, void* mapper) {
FPDF_AddInstalledFont(mapper, "Arial", FXFONT_DEFAULT_CHARSET);

const FPDF_CharsetFontMap* font_map = FPDF_GetDefaultTTFMap();
Expand All @@ -156,8 +157,13 @@ void EnumFonts(struct _FPDF_SYSFONTINFO* sysfontinfo, void* mapper) {
}
}

void* MapFont(struct _FPDF_SYSFONTINFO*, int weight, int italic,
int charset, int pitch_family, const char* face, int* exact) {
void* MapFont(FPDF_SYSFONTINFO*,
int weight,
int italic,
int charset,
int pitch_family,
const char* face,
int* exact) {
// Do not attempt to map fonts if pepper is not initialized (for privet local
// printing).
// TODO(noamsml): Real font substitution (http://crbug.com/391978)
Expand Down Expand Up @@ -274,8 +280,10 @@ void* MapFont(struct _FPDF_SYSFONTINFO*, int weight, int italic,
return reinterpret_cast<void*>(res_id);
}

unsigned long GetFontData(struct _FPDF_SYSFONTINFO*, void* font_id,
unsigned int table, unsigned char* buffer,
unsigned long GetFontData(FPDF_SYSFONTINFO*,
void* font_id,
unsigned int table,
unsigned char* buffer,
unsigned long buf_size) {
if (!pp::PDF::IsAvailable()) {
NOTREACHED();
Expand All @@ -289,7 +297,7 @@ unsigned long GetFontData(struct _FPDF_SYSFONTINFO*, void* font_id,
return size;
}

void DeleteFont(struct _FPDF_SYSFONTINFO*, void* font_id) {
void DeleteFont(FPDF_SYSFONTINFO*, void* font_id) {
long res_id = reinterpret_cast<long>(font_id);
pp::Module::Get()->core()->ReleaseResource(res_id);
}
Expand All @@ -305,6 +313,109 @@ FPDF_SYSFONTINFO g_font_info = {
0,
DeleteFont
};
#else
struct FPDF_SYSFONTINFO_WITHMETRICS : public FPDF_SYSFONTINFO {
explicit FPDF_SYSFONTINFO_WITHMETRICS(FPDF_SYSFONTINFO* sysfontinfo) {
version = sysfontinfo->version;
default_sysfontinfo = sysfontinfo;
}

~FPDF_SYSFONTINFO_WITHMETRICS() { delete default_sysfontinfo; }

FPDF_SYSFONTINFO* default_sysfontinfo;
};

FPDF_SYSFONTINFO_WITHMETRICS* g_font_info = nullptr;

void* MapFontWithMetrics(FPDF_SYSFONTINFO* sysfontinfo,
int weight,
int italic,
int charset,
int pitch_family,
const char* face,
int* exact) {
auto* fontinfo_with_metrics =
static_cast<FPDF_SYSFONTINFO_WITHMETRICS*>(sysfontinfo);
if (!fontinfo_with_metrics->default_sysfontinfo->MapFont)
return nullptr;
void* mapped_font = fontinfo_with_metrics->default_sysfontinfo->MapFont(
fontinfo_with_metrics->default_sysfontinfo, weight, italic, charset,
pitch_family, face, exact);
if (mapped_font && g_engine_for_fontmapper)
g_engine_for_fontmapper->FontSubstituted();
return mapped_font;
}

void DeleteFont(FPDF_SYSFONTINFO* sysfontinfo, void* font_id) {
auto* fontinfo_with_metrics =
static_cast<FPDF_SYSFONTINFO_WITHMETRICS*>(sysfontinfo);
if (!fontinfo_with_metrics->default_sysfontinfo->DeleteFont)
return;
fontinfo_with_metrics->default_sysfontinfo->DeleteFont(
fontinfo_with_metrics->default_sysfontinfo, font_id);
}

void EnumFonts(FPDF_SYSFONTINFO* sysfontinfo, void* mapper) {
auto* fontinfo_with_metrics =
static_cast<FPDF_SYSFONTINFO_WITHMETRICS*>(sysfontinfo);
if (!fontinfo_with_metrics->default_sysfontinfo->EnumFonts)
return;
fontinfo_with_metrics->default_sysfontinfo->EnumFonts(
fontinfo_with_metrics->default_sysfontinfo, mapper);
}

unsigned long GetFaceName(FPDF_SYSFONTINFO* sysfontinfo,
void* hFont,
char* buffer,
unsigned long buffer_size) {
auto* fontinfo_with_metrics =
static_cast<FPDF_SYSFONTINFO_WITHMETRICS*>(sysfontinfo);
if (!fontinfo_with_metrics->default_sysfontinfo->GetFaceName)
return 0;
return fontinfo_with_metrics->default_sysfontinfo->GetFaceName(
fontinfo_with_metrics->default_sysfontinfo, hFont, buffer, buffer_size);
}

void* GetFont(FPDF_SYSFONTINFO* sysfontinfo, const char* face) {
auto* fontinfo_with_metrics =
static_cast<FPDF_SYSFONTINFO_WITHMETRICS*>(sysfontinfo);
if (!fontinfo_with_metrics->default_sysfontinfo->GetFont)
return nullptr;
return fontinfo_with_metrics->default_sysfontinfo->GetFont(
fontinfo_with_metrics->default_sysfontinfo, face);
}

int GetFontCharset(FPDF_SYSFONTINFO* sysfontinfo, void* hFont) {
auto* fontinfo_with_metrics =
static_cast<FPDF_SYSFONTINFO_WITHMETRICS*>(sysfontinfo);
if (!fontinfo_with_metrics->default_sysfontinfo->GetFontCharset)
return 0;
return fontinfo_with_metrics->default_sysfontinfo->GetFontCharset(
fontinfo_with_metrics->default_sysfontinfo, hFont);
}

unsigned long GetFontData(FPDF_SYSFONTINFO* sysfontinfo,
void* hFont,
unsigned int table,
unsigned char* buffer,
unsigned long buf_size) {
auto* fontinfo_with_metrics =
static_cast<FPDF_SYSFONTINFO_WITHMETRICS*>(sysfontinfo);
if (!fontinfo_with_metrics->default_sysfontinfo->GetFontData)
return 0;
return fontinfo_with_metrics->default_sysfontinfo->GetFontData(
fontinfo_with_metrics->default_sysfontinfo, hFont, table, buffer,
buf_size);
}

void Release(FPDF_SYSFONTINFO* sysfontinfo) {
auto* fontinfo_with_metrics =
static_cast<FPDF_SYSFONTINFO_WITHMETRICS*>(sysfontinfo);
if (!fontinfo_with_metrics->default_sysfontinfo->Release)
return;
fontinfo_with_metrics->default_sysfontinfo->Release(
fontinfo_with_metrics->default_sysfontinfo);
}
#endif // defined(OS_LINUX)

PDFiumEngine* g_engine_for_unsupported = nullptr;
Expand Down Expand Up @@ -519,6 +630,19 @@ bool InitializeSDK() {
#if defined(OS_LINUX)
// Font loading doesn't work in the renderer sandbox in Linux.
FPDF_SetSystemFontInfo(&g_font_info);
#else
g_font_info =
new FPDF_SYSFONTINFO_WITHMETRICS(FPDF_GetDefaultSystemFontInfo());
g_font_info->Release = Release;
g_font_info->EnumFonts = EnumFonts;
// Set new MapFont that calculates metrics
g_font_info->MapFont = MapFontWithMetrics;
g_font_info->GetFont = GetFont;
g_font_info->GetFaceName = GetFaceName;
g_font_info->GetFontCharset = GetFontCharset;
g_font_info->GetFontData = GetFontData;
g_font_info->DeleteFont = DeleteFont;
FPDF_SetSystemFontInfo(g_font_info);
#endif

FSDK_SetUnSpObjProcessHandler(&g_unsupported_info);
Expand All @@ -527,6 +651,10 @@ bool InitializeSDK() {
}

void ShutdownSDK() {
#if !defined(OS_LINUX)
FPDF_FreeDefaultSystemFontInfo(g_font_info->default_sysfontinfo);
delete g_font_info;
#endif
FPDF_DestroyLibrary();
TearDownV8();
}
Expand Down

0 comments on commit 394c066

Please sign in to comment.