Break remaining dependency from fxge to fxcodec.
Pass a struct of function pointers down to CFX_PSRenderer, so it can
access encoding functions without directly calling them.
Change-Id: I7fd1ddc75496f47d3a3ff32bb13a486b0db0da29
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/55154
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcodec/BUILD.gn b/core/fxcodec/BUILD.gn
index 8f4d7b8..3543360 100644
--- a/core/fxcodec/BUILD.gn
+++ b/core/fxcodec/BUILD.gn
@@ -78,7 +78,6 @@
"../fxge",
"//third_party:jpeg",
]
- allow_circular_includes_from = []
if (pdf_enable_xfa) {
sources += [
@@ -125,10 +124,6 @@
}
}
- if (is_win) {
- allow_circular_includes_from += [ "../fxge" ]
- }
-
visibility = [ "../../*" ]
}
diff --git a/core/fxge/cfx_windowsrenderdevice.h b/core/fxge/cfx_windowsrenderdevice.h
index ef4dc39..d2ca8a0 100644
--- a/core/fxge/cfx_windowsrenderdevice.h
+++ b/core/fxge/cfx_windowsrenderdevice.h
@@ -21,6 +21,7 @@
};
class RenderDeviceDriverIface;
+struct EncoderIface;
#if defined(PDFIUM_PRINT_TEXT_WITH_GDI)
typedef void (*PDFiumEnsureTypefaceCharactersAccessible)(const LOGFONT* font,
@@ -35,11 +36,13 @@
class CFX_WindowsRenderDevice final : public CFX_RenderDevice {
public:
- explicit CFX_WindowsRenderDevice(HDC hDC);
+ CFX_WindowsRenderDevice(HDC hDC, const EncoderIface* pEncoderIface);
~CFX_WindowsRenderDevice() override;
private:
- static RenderDeviceDriverIface* CreateDriver(HDC hDC);
+ static RenderDeviceDriverIface* CreateDriver(
+ HDC hDC,
+ const EncoderIface* pEncoderIface);
};
#endif // CORE_FXGE_CFX_WINDOWSRENDERDEVICE_H_
diff --git a/core/fxge/win32/cfx_psrenderer.cpp b/core/fxge/win32/cfx_psrenderer.cpp
index 15efa25..3ae1df6 100644
--- a/core/fxge/win32/cfx_psrenderer.cpp
+++ b/core/fxge/win32/cfx_psrenderer.cpp
@@ -11,10 +11,6 @@
#include <sstream>
#include <utility>
-#include "core/fxcodec/codec/ccodec_basicmodule.h"
-#include "core/fxcodec/codec/ccodec_faxmodule.h"
-#include "core/fxcodec/codec/ccodec_flatemodule.h"
-#include "core/fxcodec/codec/ccodec_jpegmodule.h"
#include "core/fxcrt/maybe_owned.h"
#include "core/fxge/cfx_fontcache.h"
#include "core/fxge/cfx_gemodule.h"
@@ -27,64 +23,6 @@
#include "core/fxge/win32/cpsoutput.h"
#include "third_party/base/ptr_util.h"
-namespace {
-
-bool FaxCompressData(std::unique_ptr<uint8_t, FxFreeDeleter> src_buf,
- int width,
- int height,
- std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
- uint32_t* dest_size) {
- if (width * height <= 128) {
- *dest_buf = std::move(src_buf);
- *dest_size = (width + 7) / 8 * height;
- return false;
- }
-
- CCodec_FaxModule::FaxEncode(src_buf.get(), width, height, (width + 7) / 8,
- dest_buf, dest_size);
- return true;
-}
-
-void PSCompressData(int PSLevel,
- uint8_t* src_buf,
- uint32_t src_size,
- uint8_t** output_buf,
- uint32_t* output_size,
- const char** filter) {
- *output_buf = src_buf;
- *output_size = src_size;
- *filter = "";
- if (src_size < 1024)
- return;
-
- uint8_t* dest_buf = nullptr;
- uint32_t dest_size = src_size;
- if (PSLevel >= 3) {
- std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf_unique;
- if (CCodec_FlateModule::Encode(src_buf, src_size, &dest_buf_unique,
- &dest_size)) {
- dest_buf = dest_buf_unique.release();
- *filter = "/FlateDecode filter ";
- }
- } else {
- std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf_unique;
- if (CCodec_BasicModule::RunLengthEncode({src_buf, src_size},
- &dest_buf_unique, &dest_size)) {
- dest_buf = dest_buf_unique.release();
- *filter = "/RunLengthDecode filter ";
- }
- }
- if (dest_size < src_size) {
- *output_buf = dest_buf;
- *output_size = dest_size;
- } else {
- *filter = nullptr;
- FX_Free(dest_buf);
- }
-}
-
-} // namespace
-
struct PSGlyph {
UnownedPtr<CFX_Font> m_pFont;
uint32_t m_GlyphIndex;
@@ -98,7 +36,8 @@
PSGlyph m_Glyphs[256];
};
-CFX_PSRenderer::CFX_PSRenderer() = default;
+CFX_PSRenderer::CFX_PSRenderer(const EncoderIface* pEncoderIface)
+ : m_pEncoderIface(pEncoderIface) {}
CFX_PSRenderer::~CFX_PSRenderer() = default;
@@ -454,7 +393,8 @@
size_t output_size = 0;
const char* filter = nullptr;
if ((m_PSLevel == 2 || options.bLossy) &&
- CCodec_JpegModule::JpegEncode(pConverted, &output_buf, &output_size)) {
+ m_pEncoderIface->pJpegEncodeFunc(pConverted, &output_buf,
+ &output_size)) {
filter = "/DCTDecode filter ";
}
if (!filter) {
@@ -477,8 +417,8 @@
}
uint8_t* compressed_buf;
uint32_t compressed_size;
- PSCompressData(m_PSLevel, output_buf, output_size, &compressed_buf,
- &compressed_size, &filter);
+ PSCompressData(output_buf, output_size, &compressed_buf, &compressed_size,
+ &filter);
if (output_buf != compressed_buf)
FX_Free(output_buf);
@@ -680,11 +620,65 @@
return true;
}
+bool CFX_PSRenderer::FaxCompressData(
+ std::unique_ptr<uint8_t, FxFreeDeleter> src_buf,
+ int width,
+ int height,
+ std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
+ uint32_t* dest_size) const {
+ if (width * height <= 128) {
+ *dest_buf = std::move(src_buf);
+ *dest_size = (width + 7) / 8 * height;
+ return false;
+ }
+
+ m_pEncoderIface->pFaxEncodeFunc(src_buf.get(), width, height, (width + 7) / 8,
+ dest_buf, dest_size);
+ return true;
+}
+
+void CFX_PSRenderer::PSCompressData(uint8_t* src_buf,
+ uint32_t src_size,
+ uint8_t** output_buf,
+ uint32_t* output_size,
+ const char** filter) const {
+ *output_buf = src_buf;
+ *output_size = src_size;
+ *filter = "";
+ if (src_size < 1024)
+ return;
+
+ uint8_t* dest_buf = nullptr;
+ uint32_t dest_size = src_size;
+ if (m_PSLevel >= 3) {
+ std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf_unique;
+ if (m_pEncoderIface->pFlateEncodeFunc(src_buf, src_size, &dest_buf_unique,
+ &dest_size)) {
+ dest_buf = dest_buf_unique.release();
+ *filter = "/FlateDecode filter ";
+ }
+ } else {
+ std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf_unique;
+ if (m_pEncoderIface->pRunLengthEncodeFunc({src_buf, src_size},
+ &dest_buf_unique, &dest_size)) {
+ dest_buf = dest_buf_unique.release();
+ *filter = "/RunLengthDecode filter ";
+ }
+ }
+ if (dest_size < src_size) {
+ *output_buf = dest_buf;
+ *output_size = dest_size;
+ } else {
+ *filter = nullptr;
+ FX_Free(dest_buf);
+ }
+}
+
void CFX_PSRenderer::WritePSBinary(const uint8_t* data, int len) {
std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
uint32_t dest_size;
- if (CCodec_BasicModule::A85Encode({data, static_cast<size_t>(len)}, &dest_buf,
- &dest_size)) {
+ if (m_pEncoderIface->pA85EncodeFunc({data, static_cast<size_t>(len)},
+ &dest_buf, &dest_size)) {
m_pStream->WriteBlock(dest_buf.get(), dest_size);
} else {
m_pStream->WriteBlock(data, len);
diff --git a/core/fxge/win32/cfx_psrenderer.h b/core/fxge/win32/cfx_psrenderer.h
index a9b9f10..55dad2f 100644
--- a/core/fxge/win32/cfx_psrenderer.h
+++ b/core/fxge/win32/cfx_psrenderer.h
@@ -24,9 +24,32 @@
class TextCharPos;
struct FXDIB_ResampleOptions;
+struct EncoderIface {
+ bool (*pA85EncodeFunc)(pdfium::span<const uint8_t> src_buf,
+ std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
+ uint32_t* dest_size);
+ void (*pFaxEncodeFunc)(const uint8_t* src_buf,
+ int width,
+ int height,
+ int pitch,
+ std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
+ uint32_t* dest_size);
+ bool (*pFlateEncodeFunc)(const uint8_t* src_buf,
+ uint32_t src_size,
+ std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
+ uint32_t* dest_size);
+ bool (*pJpegEncodeFunc)(const RetainPtr<CFX_DIBBase>& pSource,
+ uint8_t** dest_buf,
+ size_t* dest_size);
+ bool (*pRunLengthEncodeFunc)(
+ pdfium::span<const uint8_t> src_buf,
+ std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
+ uint32_t* dest_size);
+};
+
class CFX_PSRenderer {
public:
- CFX_PSRenderer();
+ explicit CFX_PSRenderer(const EncoderIface* pEncoderIface);
~CFX_PSRenderer();
void Init(const RetainPtr<IFX_RetainableWriteStream>& stream,
@@ -83,6 +106,16 @@
const TextCharPos& charpos,
int* ps_fontnum,
int* ps_glyphindex);
+ bool FaxCompressData(std::unique_ptr<uint8_t, FxFreeDeleter> src_buf,
+ int width,
+ int height,
+ std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
+ uint32_t* dest_size) const;
+ void PSCompressData(uint8_t* src_buf,
+ uint32_t src_size,
+ uint8_t** output_buf,
+ uint32_t* output_size,
+ const char** filter) const;
void WritePSBinary(const uint8_t* data, int len);
void WriteToStream(std::ostringstream* stringStream);
@@ -94,6 +127,7 @@
uint32_t m_LastColor = 0;
FX_RECT m_ClipBox;
CFX_GraphStateData m_CurGraphState;
+ const EncoderIface* const m_pEncoderIface;
RetainPtr<IFX_RetainableWriteStream> m_pStream;
std::vector<std::unique_ptr<CPSFont>> m_PSFontList;
std::vector<FX_RECT> m_ClipBoxStack;
diff --git a/core/fxge/win32/fx_win32_device.cpp b/core/fxge/win32/fx_win32_device.cpp
index 2b53b61..9744857 100644
--- a/core/fxge/win32/fx_win32_device.cpp
+++ b/core/fxge/win32/fx_win32_device.cpp
@@ -1337,15 +1337,18 @@
return false;
}
-CFX_WindowsRenderDevice::CFX_WindowsRenderDevice(HDC hDC) {
- SetDeviceDriver(pdfium::WrapUnique(CreateDriver(hDC)));
+CFX_WindowsRenderDevice::CFX_WindowsRenderDevice(
+ HDC hDC,
+ const EncoderIface* pEncoderIface) {
+ SetDeviceDriver(pdfium::WrapUnique(CreateDriver(hDC, pEncoderIface)));
}
CFX_WindowsRenderDevice::~CFX_WindowsRenderDevice() = default;
// static
RenderDeviceDriverIface* CFX_WindowsRenderDevice::CreateDriver(
- HDC hDC) {
+ HDC hDC,
+ const EncoderIface* pEncoderIface) {
int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY);
int obj_type = ::GetObjectType(hDC);
bool use_printer = device_type == DT_RASPRINTER ||
@@ -1361,5 +1364,5 @@
if (g_pdfium_print_mode == WindowsPrintMode::kModeTextOnly)
return new CTextOnlyPrinterDriver(hDC);
- return new CPSPrinterDriver(hDC, g_pdfium_print_mode, false);
+ return new CPSPrinterDriver(hDC, g_pdfium_print_mode, false, pEncoderIface);
}
diff --git a/core/fxge/win32/fx_win32_print.cpp b/core/fxge/win32/fx_win32_print.cpp
index b6dd416..8ebcec1 100644
--- a/core/fxge/win32/fx_win32_print.cpp
+++ b/core/fxge/win32/fx_win32_print.cpp
@@ -332,8 +332,9 @@
CPSPrinterDriver::CPSPrinterDriver(HDC hDC,
WindowsPrintMode mode,
- bool bCmykOutput)
- : m_hDC(hDC), m_bCmykOutput(bCmykOutput) {
+ bool bCmykOutput,
+ const EncoderIface* pEncoderIface)
+ : m_hDC(hDC), m_bCmykOutput(bCmykOutput), m_PSRenderer(pEncoderIface) {
// |mode| should be PostScript.
ASSERT(mode == WindowsPrintMode::kModePostScript2 ||
mode == WindowsPrintMode::kModePostScript3 ||
diff --git a/core/fxge/win32/win32_int.h b/core/fxge/win32/win32_int.h
index 444c1dd..a021677 100644
--- a/core/fxge/win32/win32_int.h
+++ b/core/fxge/win32/win32_int.h
@@ -213,7 +213,10 @@
class CPSPrinterDriver final : public RenderDeviceDriverIface {
public:
- CPSPrinterDriver(HDC hDC, WindowsPrintMode mode, bool bCmykOutput);
+ CPSPrinterDriver(HDC hDC,
+ WindowsPrintMode mode,
+ bool bCmykOutput,
+ const EncoderIface* pEncoderIface);
~CPSPrinterDriver() override;
private:
diff --git a/fpdfsdk/BUILD.gn b/fpdfsdk/BUILD.gn
index 0194ee5..786cc8f 100644
--- a/fpdfsdk/BUILD.gn
+++ b/fpdfsdk/BUILD.gn
@@ -83,6 +83,7 @@
"../core/fpdfapi/render",
"../core/fpdfdoc",
"../core/fpdftext",
+ "../core/fxcodec",
"../core/fxcrt",
"../core/fxge",
"../fxjs",
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index 3186779..82fdcd3 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -51,7 +51,12 @@
#endif // PDF_ENABLE_XFA
#if defined(OS_WIN)
+#include "core/fxcodec/codec/ccodec_basicmodule.h"
+#include "core/fxcodec/codec/ccodec_faxmodule.h"
+#include "core/fxcodec/codec/ccodec_flatemodule.h"
+#include "core/fxcodec/codec/ccodec_jpegmodule.h"
#include "core/fxge/cfx_windowsrenderdevice.h"
+#include "core/fxge/win32/cfx_psrenderer.h"
#include "public/fpdf_edit.h"
// These checks are here because core/ and public/ cannot depend on each other.
@@ -75,6 +80,13 @@
bool g_bLibraryInitialized = false;
+#if defined(OS_WIN)
+constexpr EncoderIface kEncoderIface = {
+ CCodec_BasicModule::A85Encode, CCodec_FaxModule::FaxEncode,
+ CCodec_FlateModule::Encode, CCodec_JpegModule::JpegEncode,
+ CCodec_BasicModule::RunLengthEncode};
+#endif // defined(OS_WIN)
+
void RenderPageImpl(CPDF_PageRenderContext* pContext,
CPDF_Page* pPage,
const CFX_Matrix& matrix,
@@ -545,7 +557,8 @@
pContext->m_pOptions->GetOptions().bBreakForMasks = true;
}
} else {
- pContext->m_pDevice = pdfium::MakeUnique<CFX_WindowsRenderDevice>(dc);
+ pContext->m_pDevice =
+ pdfium::MakeUnique<CFX_WindowsRenderDevice>(dc, &kEncoderIface);
}
RenderPageWithContext(pContext, page, start_x, start_y, size_x, size_y,
@@ -572,7 +585,8 @@
// pause after each image mask.
pPage->SetRenderContext(pdfium::MakeUnique<CPDF_PageRenderContext>());
pContext = pPage->GetRenderContext();
- pContext->m_pDevice = pdfium::MakeUnique<CFX_WindowsRenderDevice>(dc);
+ pContext->m_pDevice =
+ pdfium::MakeUnique<CFX_WindowsRenderDevice>(dc, &kEncoderIface);
pContext->m_pOptions = pdfium::MakeUnique<CPDF_RenderOptions>();
pContext->m_pOptions->GetOptions().bBreakForMasks = true;
@@ -589,7 +603,7 @@
pContext->m_pRenderer->Continue(nullptr);
}
} else if (bNewBitmap) {
- CFX_WindowsRenderDevice WinDC(dc);
+ CFX_WindowsRenderDevice WinDC(dc, &kEncoderIface);
bool bitsStretched = false;
if (WinDC.GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) {
auto pDst = pdfium::MakeRetain<CFX_DIBitmap>();