Push some page object logic back into appropriate files.
Avoids having the font/ layer do too much work itself.
- Rename LoadBitmap() to indicate it only covers a special case.
- Use incomplete type for CPDF_Image in header file.
Change-Id: I2d7c7547fd659b6da72a449997dd141eb8118426
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/57690
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/font/cpdf_type3char.cpp b/core/fpdfapi/font/cpdf_type3char.cpp
index 1e3ff65..96c9b30 100644
--- a/core/fpdfapi/font/cpdf_type3char.cpp
+++ b/core/fpdfapi/font/cpdf_type3char.cpp
@@ -36,33 +36,19 @@
pRect->Scale(kTextUnitInGlyphUnit);
}
-bool CPDF_Type3Char::LoadBitmap() {
+bool CPDF_Type3Char::LoadBitmapFromSoleImageOfForm() {
if (m_pBitmap || !m_pForm)
return true;
- if (m_pForm->GetPageObjectCount() != 1 || m_bColored)
+ if (m_bColored)
return false;
- auto& pPageObj = *m_pForm->begin();
- if (!pPageObj->IsImage())
+ const CPDF_ImageObject* pImageObject = m_pForm->GetSoleImageOfForm();
+ if (!pImageObject)
return false;
- m_ImageMatrix = pPageObj->AsImage()->matrix();
- {
- // |pSource| actually gets assigned a CPDF_DIBBase, which has pointers
- // into objects owned by |m_pForm|. Make sure it is out of scope before
- // clearing the form.
- RetainPtr<CFX_DIBBase> pSource =
- pPageObj->AsImage()->GetImage()->LoadDIBBase();
-
- // Clone() is non-virtual, and can't be overloaded by CPDF_DIBBase to
- // return a clone of the subclass as one would typically expect from a
- // such a method. Instead, it only clones the CFX_DIBBase, none of whose
- // members point to objects owned by the form. As a result, |m_pBitmap|
- // may outlive |m_pForm|.
- if (pSource)
- m_pBitmap = pSource->Clone(nullptr);
- }
+ m_ImageMatrix = pImageObject->matrix();
+ m_pBitmap = pImageObject->GetIndependentBitmap();
m_pForm.reset();
return true;
}
diff --git a/core/fpdfapi/font/cpdf_type3char.h b/core/fpdfapi/font/cpdf_type3char.h
index 784332d..bcf94da 100644
--- a/core/fpdfapi/font/cpdf_type3char.h
+++ b/core/fpdfapi/font/cpdf_type3char.h
@@ -24,7 +24,7 @@
static float TextUnitToGlyphUnit(float fTextUnit);
static void TextUnitRectToGlyphUnitRect(CFX_FloatRect* pRect);
- bool LoadBitmap();
+ bool LoadBitmapFromSoleImageOfForm();
void InitializeFromStreamData(bool bColored, const float* pData);
void Transform(CPDF_Form* pForm, const CFX_Matrix& matrix);
diff --git a/core/fpdfapi/page/cpdf_form.cpp b/core/fpdfapi/page/cpdf_form.cpp
index 31b4133..a30087a 100644
--- a/core/fpdfapi/page/cpdf_form.cpp
+++ b/core/fpdfapi/page/cpdf_form.cpp
@@ -7,6 +7,7 @@
#include "core/fpdfapi/page/cpdf_form.h"
#include "core/fpdfapi/page/cpdf_contentparser.h"
+#include "core/fpdfapi/page/cpdf_imageobject.h"
#include "core/fpdfapi/page/cpdf_pageobject.h"
#include "core/fpdfapi/page/cpdf_pageobjectholder.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
@@ -69,3 +70,7 @@
const CPDF_Stream* CPDF_Form::GetStream() const {
return m_pFormStream.Get();
}
+
+const CPDF_ImageObject* CPDF_Form::GetSoleImageOfForm() const {
+ return GetPageObjectCount() == 1 ? (*begin())->AsImage() : nullptr;
+}
diff --git a/core/fpdfapi/page/cpdf_form.h b/core/fpdfapi/page/cpdf_form.h
index 1fe0ae2..9719476 100644
--- a/core/fpdfapi/page/cpdf_form.h
+++ b/core/fpdfapi/page/cpdf_form.h
@@ -16,6 +16,7 @@
class CPDF_AllStates;
class CPDF_Dictionary;
class CPDF_Document;
+class CPDF_ImageObject;
class CPDF_Stream;
class CPDF_Type3Char;
@@ -42,9 +43,11 @@
const CPDF_Stream* GetStream() const;
+ // Fast path helper for avoiding a full rendering of form.
+ const CPDF_ImageObject* GetSoleImageOfForm() const;
+
private:
std::unique_ptr<std::set<const uint8_t*>> m_ParsedSet;
-
RetainPtr<CPDF_Stream> const m_pFormStream;
};
diff --git a/core/fpdfapi/page/cpdf_imageobject.cpp b/core/fpdfapi/page/cpdf_imageobject.cpp
index ed12465..e1c8520 100644
--- a/core/fpdfapi/page/cpdf_imageobject.cpp
+++ b/core/fpdfapi/page/cpdf_imageobject.cpp
@@ -12,6 +12,8 @@
#include "core/fpdfapi/page/cpdf_image.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fxge/dib/cfx_dibbase.h"
+#include "core/fxge/dib/cfx_dibitmap.h"
CPDF_ImageObject::CPDF_ImageObject(int32_t content_stream)
: CPDF_PageObject(content_stream) {}
@@ -54,6 +56,21 @@
m_pImage = pImage;
}
+RetainPtr<CPDF_Image> CPDF_ImageObject::GetImage() const {
+ return m_pImage;
+}
+
+RetainPtr<CFX_DIBitmap> CPDF_ImageObject::GetIndependentBitmap() const {
+ RetainPtr<CFX_DIBBase> pSource = GetImage()->LoadDIBBase();
+
+ // Clone() is non-virtual, and can't be overloaded by CPDF_DIBBase to
+ // return a clone of the subclass as one would typically expect from a
+ // such a method. Instead, it only clones the CFX_DIBBase, none of whose
+ // members point to objects owned by |this| or the form containing |this|.
+ // As a result, the clone may outlive them.
+ return pSource ? pSource->Clone(nullptr) : nullptr;
+}
+
void CPDF_ImageObject::MaybePurgeCache() {
if (!m_pImage)
return;
diff --git a/core/fpdfapi/page/cpdf_imageobject.h b/core/fpdfapi/page/cpdf_imageobject.h
index b28e733..f221a98 100644
--- a/core/fpdfapi/page/cpdf_imageobject.h
+++ b/core/fpdfapi/page/cpdf_imageobject.h
@@ -7,9 +7,12 @@
#ifndef CORE_FPDFAPI_PAGE_CPDF_IMAGEOBJECT_H_
#define CORE_FPDFAPI_PAGE_CPDF_IMAGEOBJECT_H_
-#include "core/fpdfapi/page/cpdf_image.h"
#include "core/fpdfapi/page/cpdf_pageobject.h"
#include "core/fxcrt/fx_coordinates.h"
+#include "core/fxcrt/retain_ptr.h"
+
+class CFX_DIBitmap;
+class CPDF_Image;
class CPDF_ImageObject final : public CPDF_PageObject {
public:
@@ -25,8 +28,10 @@
const CPDF_ImageObject* AsImage() const override;
void CalcBoundingBox();
- RetainPtr<CPDF_Image> GetImage() const { return m_pImage; }
void SetImage(const RetainPtr<CPDF_Image>& pImage);
+ RetainPtr<CPDF_Image> GetImage() const;
+ RetainPtr<CFX_DIBitmap> GetIndependentBitmap() const;
+
void set_matrix(const CFX_Matrix& matrix) { m_Matrix = matrix; }
const CFX_Matrix& matrix() const { return m_Matrix; }
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index 95ad758..55b959d 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -1825,7 +1825,7 @@
matrix.e += iChar > 0 ? textobj->GetCharPositions()[iChar - 1] : 0;
matrix.Concat(text_matrix);
matrix.Concat(mtObj2Device);
- if (!pType3Char->LoadBitmap()) {
+ if (!pType3Char->LoadBitmapFromSoleImageOfForm()) {
if (!glyphs.empty()) {
for (size_t i = 0; i < iChar; ++i) {
const TextGlyphPos& glyph = glyphs[i];