Include more font details in CFX_Font.
CPDF_Font knows more high level details about fonts in PDFs that
CFX_Font does not. Meanwhile, RenderDeviceDriverIface::DrawDeviceText()
takes a CFX_Font*. For DrawDeviceText() implementations to make better
output decisions based on the font type, add more getters/setters to
CFX_Font to plumb through the following data:
- Font type
- Font object's object and generation number as an opaque tag
Bug: chromium:1232526
Change-Id: I65fdd3b240139dfa725a9c5a61afbf7b58e74771
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/84871
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/font/cpdf_cidfont.cpp b/core/fpdfapi/font/cpdf_cidfont.cpp
index e4f5955..fbcfc2d 100644
--- a/core/fpdfapi/font/cpdf_cidfont.cpp
+++ b/core/fpdfapi/font/cpdf_cidfont.cpp
@@ -492,6 +492,11 @@
m_DefaultW1 = pDefaultArray->GetIntegerAt(1);
}
}
+
+ // TODO(thestig): Better identify font types and identify more font types.
+ if (m_FontType == CIDFontType::kTrueType && IsEmbedded())
+ m_Font.SetFontType(CFX_Font::FontType::kCIDTrueType);
+
return true;
}
diff --git a/core/fpdfapi/font/cpdf_font.cpp b/core/fpdfapi/font/cpdf_font.cpp
index c22a560..46112e4 100644
--- a/core/fpdfapi/font/cpdf_font.cpp
+++ b/core/fpdfapi/font/cpdf_font.cpp
@@ -45,6 +45,11 @@
{0xB7, 0xC2, 0xCB, 0xCE},
{0xD0, 0xC2, 0xCB, 0xCE}};
+uint64_t MakeObjectTag(uint32_t id, uint32_t gen) {
+ uint64_t tag = id;
+ return (tag << 32) | gen;
+}
+
} // namespace
CPDF_Font::CPDF_Font(CPDF_Document* pDocument, CPDF_Dictionary* pFontDict)
@@ -213,7 +218,8 @@
if (!m_pFontFile)
return;
- if (!m_Font.LoadEmbedded(m_pFontFile->GetSpan(), IsVertWriting())) {
+ uint64_t tag = MakeObjectTag(pFontFile->GetObjNum(), pFontFile->GetGenNum());
+ if (!m_Font.LoadEmbedded(m_pFontFile->GetSpan(), IsVertWriting(), tag)) {
pData->MaybePurgeFontFileStreamAcc(m_pFontFile->GetStream()->AsStream());
m_pFontFile = nullptr;
}
diff --git a/core/fxge/cfx_font.cpp b/core/fxge/cfx_font.cpp
index 4f0e029..8eafb54 100644
--- a/core/fxge/cfx_font.cpp
+++ b/core/fxge/cfx_font.cpp
@@ -297,6 +297,7 @@
bool CFX_Font::LoadFile(RetainPtr<IFX_SeekableReadStream> pFile,
int nFaceIndex) {
m_bEmbedded = false;
+ m_ObjectTag = 0;
auto pStreamRec = std::make_unique<FXFT_StreamRec>();
pStreamRec->base = nullptr;
@@ -324,6 +325,7 @@
#if !defined(OS_WIN)
void CFX_Font::SetFace(RetainPtr<CFX_Face> face) {
ClearGlyphCache();
+ m_ObjectTag = 0;
m_Face = face;
}
@@ -351,6 +353,7 @@
bool bVertical) {
m_bEmbedded = false;
m_bVertical = bVertical;
+ m_ObjectTag = 0;
m_pSubstFont = std::make_unique<CFX_SubstFont>();
m_Face = CFX_GEModule::Get()->GetFontMgr()->FindSubstFont(
face_name, bTrueType, flags, weight, italic_angle, code_page,
@@ -380,9 +383,10 @@
}
bool CFX_Font::LoadEmbedded(pdfium::span<const uint8_t> src_span,
- bool bForceAsVertical) {
- if (bForceAsVertical)
- m_bVertical = true;
+ bool force_vertical,
+ uint64_t object_tag) {
+ m_bVertical = force_vertical;
+ m_ObjectTag = object_tag;
m_FontDataAllocation = std::vector<uint8_t, FxAllocAllocator<uint8_t>>(
src_span.begin(), src_span.end());
m_Face = CFX_GEModule::Get()->GetFontMgr()->NewFixedFace(
diff --git a/core/fxge/cfx_font.h b/core/fxge/cfx_font.h
index b3f2b16..3627a43 100644
--- a/core/fxge/cfx_font.h
+++ b/core/fxge/cfx_font.h
@@ -40,6 +40,11 @@
const char* fontname; // Name of default font to use with that charset.
};
+ enum class FontType {
+ kUnknown,
+ kCIDTrueType,
+ };
+
// Pointer to the default character set to TT Font name map. The map is an
// array of CharsetFontMap structs, with its end indicated by a {-1, nullptr}
// entry.
@@ -72,7 +77,8 @@
bool bVertical);
bool LoadEmbedded(pdfium::span<const uint8_t> src_span,
- bool bForceAsVertical);
+ bool force_vertical,
+ uint64_t object_tag);
RetainPtr<CFX_Face> GetFace() const { return m_Face; }
FXFT_FaceRec* GetFaceRec() const {
return m_Face ? m_Face->GetRec() : nullptr;
@@ -115,6 +121,9 @@
bool IsEmbedded() const { return m_bEmbedded; }
uint8_t* GetSubData() const { return m_pGsubData.get(); }
void SetSubData(uint8_t* data) { m_pGsubData.reset(data); }
+ FontType GetFontType() const { return m_FontType; }
+ void SetFontType(FontType type) { m_FontType = type; }
+ uint64_t GetObjectTag() const { return m_ObjectTag; }
pdfium::span<uint8_t> GetFontSpan() const { return m_FontData; }
void AdjustMMParams(int glyph_index, int dest_width, int weight) const;
std::unique_ptr<CFX_Path> LoadGlyphPathImpl(uint32_t glyph_index,
@@ -150,6 +159,8 @@
std::unique_ptr<uint8_t, FxFreeDeleter> m_pGsubData;
std::vector<uint8_t, FxAllocAllocator<uint8_t>> m_FontDataAllocation;
pdfium::span<uint8_t> m_FontData;
+ FontType m_FontType = FontType::kUnknown;
+ uint64_t m_ObjectTag = 0;
bool m_bEmbedded = false;
bool m_bVertical = false;
#if defined(OS_APPLE)
diff --git a/fpdfsdk/fpdf_edittext.cpp b/fpdfsdk/fpdf_edittext.cpp
index c7fb03c..3fcd0b3 100644
--- a/fpdfsdk/fpdf_edittext.cpp
+++ b/fpdfsdk/fpdf_edittext.cpp
@@ -520,7 +520,7 @@
// TODO(npm): Maybe use FT_Get_X11_Font_Format to check format? Otherwise, we
// are allowing giving any font that can be loaded on freetype and setting it
// as any font type.
- if (!pFont->LoadEmbedded(span, false))
+ if (!pFont->LoadEmbedded(span, /*force_vertical=*/false, /*object_tag=*/0))
return nullptr;
// Caller takes ownership.