Introduce CFX_GEModule::PlatformIface pure virtual class.
This replaces a void* pointer in the CFX_GEModule, and allows platform
destruction order to be controlled by the member order, rather than an
explicit call in the destructor.
Each of the platforms implements its own platform-specific subclass.
In the future, it seems likely that CFX_FontCache/CFX_FontMgr members
will not get to outlive the PlatformIface, and this makes that change
easier to accomplish.
Change-Id: If278f79b66fa8a7d6b2f9be089c31b37c308ae26
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/54810
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/font/cpdf_type1font.cpp b/core/fpdfapi/font/cpdf_type1font.cpp
index b78922d..0cb8d19 100644
--- a/core/fpdfapi/font/cpdf_type1font.cpp
+++ b/core/fpdfapi/font/cpdf_type1font.cpp
@@ -126,7 +126,7 @@
#if defined(OS_MACOSX)
bool bCoreText = true;
CQuartz2D& quartz2d =
- static_cast<CApplePlatform*>(CFX_GEModule::Get()->GetPlatformData())
+ static_cast<CApplePlatform*>(CFX_GEModule::Get()->GetPlatform())
->m_quartz2d;
if (!m_Font.GetPlatformFont()) {
if (m_Font.GetPsName() == "DFHeiStd-W5")
diff --git a/core/fxge/android/fx_android_imp.cpp b/core/fxge/android/fx_android_imp.cpp
index db2f3ef..147011c 100644
--- a/core/fxge/android/fx_android_imp.cpp
+++ b/core/fxge/android/fx_android_imp.cpp
@@ -14,21 +14,31 @@
#include "core/fxge/cfx_fontmgr.h"
#include "third_party/base/ptr_util.h"
-void CFX_GEModule::InitPlatform() {
- CFPF_SkiaDeviceModule* pDeviceModule = CFPF_GetSkiaDeviceModule();
- if (!pDeviceModule)
- return;
+class CAndroidPlatform : public CFX_GEModule::PlatformIface {
+ public:
+ CAndroidPlatform() = default;
+ ~CAndroidPlatform() override {
+ if (m_pDeviceModule)
+ m_pDeviceModule->Destroy();
+ }
- CFPF_SkiaFontMgr* pFontMgr = pDeviceModule->GetFontMgr();
- if (pFontMgr) {
+ void Init() override {
+ m_pDeviceModule = CFPF_GetSkiaDeviceModule();
+ CFPF_SkiaFontMgr* pFontMgr = m_pDeviceModule->GetFontMgr();
+ if (!pFontMgr)
+ return;
+
auto pFontInfo = pdfium::MakeUnique<CFX_AndroidFontInfo>();
pFontInfo->Init(pFontMgr);
- m_pFontMgr->SetSystemFontInfo(std::move(pFontInfo));
+ CFX_GEModule::Get()->GetFontMgr()->SetSystemFontInfo(std::move(pFontInfo));
}
- m_pPlatformData = pDeviceModule;
-}
-void CFX_GEModule::DestroyPlatform() {
- if (m_pPlatformData)
- static_cast<CFPF_SkiaDeviceModule*>(m_pPlatformData)->Destroy();
+ private:
+ CFPF_SkiaDeviceModule* m_pDeviceModule = nullptr;
+};
+
+// static
+std::unique_ptr<CFX_GEModule::PlatformIface>
+CFX_GEModule::PlatformIface::Create() {
+ return pdfium::MakeUnique<CAndroidPlatform>();
}
diff --git a/core/fxge/apple/apple_int.h b/core/fxge/apple/apple_int.h
index e91b1e1..cbf3464 100644
--- a/core/fxge/apple/apple_int.h
+++ b/core/fxge/apple/apple_int.h
@@ -11,6 +11,7 @@
#include <Carbon/Carbon.h>
+#include "core/fxge/cfx_gemodule.h"
#include "core/fxge/cfx_graphstatedata.h"
#include "core/fxge/cfx_pathdata.h"
#include "core/fxge/fx_dib.h"
@@ -35,10 +36,13 @@
void restoreGraphicsState(void* graphics);
};
-class CApplePlatform {
+class CApplePlatform : public CFX_GEModule::PlatformIface {
public:
- CApplePlatform() {}
- ~CApplePlatform() {}
+ CApplePlatform();
+ ~CApplePlatform() override;
+
+ // CFX_GEModule::PlatformIface:
+ void Init() override;
CQuartz2D m_quartz2d;
};
diff --git a/core/fxge/apple/fx_apple_platform.cpp b/core/fxge/apple/fx_apple_platform.cpp
index ad2bdaf..c8c55a8 100644
--- a/core/fxge/apple/fx_apple_platform.cpp
+++ b/core/fxge/apple/fx_apple_platform.cpp
@@ -50,7 +50,7 @@
new_matrix.Concat(*pObject2Device);
CQuartz2D& quartz2d =
- static_cast<CApplePlatform*>(CFX_GEModule::Get()->GetPlatformData())
+ static_cast<CApplePlatform*>(CFX_GEModule::Get()->GetPlatform())
->m_quartz2d;
if (!pFont->GetPlatformFont()) {
if (pFont->GetPsName() == "DFHeiStd-W5")
@@ -89,14 +89,14 @@
void CFX_AggDeviceDriver::InitPlatform() {
CQuartz2D& quartz2d =
- static_cast<CApplePlatform*>(CFX_GEModule::Get()->GetPlatformData())
+ static_cast<CApplePlatform*>(CFX_GEModule::Get()->GetPlatform())
->m_quartz2d;
m_pPlatformGraphics = quartz2d.createGraphics(m_pBitmap);
}
void CFX_AggDeviceDriver::DestroyPlatform() {
CQuartz2D& quartz2d =
- static_cast<CApplePlatform*>(CFX_GEModule::Get()->GetPlatformData())
+ static_cast<CApplePlatform*>(CFX_GEModule::Get()->GetPlatform())
->m_quartz2d;
if (m_pPlatformGraphics) {
quartz2d.destroyGraphics(m_pPlatformGraphics);
@@ -181,7 +181,7 @@
void CFX_Font::ReleasePlatformResource() {
if (m_pPlatformFont) {
CQuartz2D& quartz2d =
- static_cast<CApplePlatform*>(CFX_GEModule::Get()->GetPlatformData())
+ static_cast<CApplePlatform*>(CFX_GEModule::Get()->GetPlatform())
->m_quartz2d;
quartz2d.DestroyFont(m_pPlatformFont);
m_pPlatformFont = nullptr;
diff --git a/core/fxge/apple/fx_mac_imp.cpp b/core/fxge/apple/fx_mac_imp.cpp
index bf8e4f6..64e50cc 100644
--- a/core/fxge/apple/fx_mac_imp.cpp
+++ b/core/fxge/apple/fx_mac_imp.cpp
@@ -142,13 +142,18 @@
return std::move(pInfo);
}
-void CFX_GEModule::InitPlatform() {
- m_pPlatformData = new CApplePlatform;
- m_pFontMgr->SetSystemFontInfo(
- SystemFontInfoIface::CreateDefault(m_pUserFontPaths));
+CApplePlatform::CApplePlatform() = default;
+
+CApplePlatform::~CApplePlatform() = default;
+
+void CApplePlatform::Init() {
+ CFX_GEModule* pModule = CFX_GEModule::Get();
+ pModule->GetFontMgr()->SetSystemFontInfo(
+ SystemFontInfoIface::CreateDefault(pModule->GetUserFontPaths()));
}
-void CFX_GEModule::DestroyPlatform() {
- delete reinterpret_cast<CApplePlatform*>(m_pPlatformData);
- m_pPlatformData = nullptr;
+// static
+std::unique_ptr<CFX_GEModule::PlatformIface>
+CFX_GEModule::PlatformIface::Create() {
+ return pdfium::MakeUnique<CApplePlatform>();
}
diff --git a/core/fxge/cfx_gemodule.cpp b/core/fxge/cfx_gemodule.cpp
index cbc66c3..b9b232d 100644
--- a/core/fxge/cfx_gemodule.cpp
+++ b/core/fxge/cfx_gemodule.cpp
@@ -19,12 +19,9 @@
CFX_GEModule::CFX_GEModule()
: m_pFontMgr(pdfium::MakeUnique<CFX_FontMgr>()),
- m_pPlatformData(nullptr),
- m_pUserFontPaths(nullptr) {}
+ m_pPlatform(PlatformIface::Create()) {}
-CFX_GEModule::~CFX_GEModule() {
- DestroyPlatform();
-}
+CFX_GEModule::~CFX_GEModule() = default;
// static
CFX_GEModule* CFX_GEModule::Get() {
@@ -43,7 +40,7 @@
void CFX_GEModule::Init(const char** userFontPaths) {
ASSERT(g_pGEModule);
m_pUserFontPaths = userFontPaths;
- InitPlatform();
+ m_pPlatform->Init();
}
CFX_FontCache* CFX_GEModule::GetFontCache() {
diff --git a/core/fxge/cfx_gemodule.h b/core/fxge/cfx_gemodule.h
index f48d065..afcbff4 100644
--- a/core/fxge/cfx_gemodule.h
+++ b/core/fxge/cfx_gemodule.h
@@ -14,26 +14,31 @@
class CFX_GEModule {
public:
+ class PlatformIface {
+ public:
+ static std::unique_ptr<PlatformIface> Create();
+ virtual ~PlatformIface() {}
+
+ virtual void Init() = 0;
+ };
+
static CFX_GEModule* Get();
static void Destroy();
void Init(const char** pUserFontPaths);
CFX_FontCache* GetFontCache();
- CFX_FontMgr* GetFontMgr() { return m_pFontMgr.get(); }
-
- void* GetPlatformData() { return m_pPlatformData; }
+ CFX_FontMgr* GetFontMgr() const { return m_pFontMgr.get(); }
+ PlatformIface* GetPlatform() const { return m_pPlatform.get(); }
+ const char** GetUserFontPaths() const { return m_pUserFontPaths; }
private:
CFX_GEModule();
~CFX_GEModule();
- void InitPlatform();
- void DestroyPlatform();
-
std::unique_ptr<CFX_FontCache> m_pFontCache;
std::unique_ptr<CFX_FontMgr> m_pFontMgr;
- void* m_pPlatformData;
- const char** m_pUserFontPaths;
+ std::unique_ptr<PlatformIface> m_pPlatform;
+ const char** m_pUserFontPaths = nullptr;
};
#endif // CORE_FXGE_CFX_GEMODULE_H_
diff --git a/core/fxge/fx_ge_linux.cpp b/core/fxge/fx_ge_linux.cpp
index d3af1b7..ddde4a6 100644
--- a/core/fxge/fx_ge_linux.cpp
+++ b/core/fxge/fx_ge_linux.cpp
@@ -159,10 +159,21 @@
return std::move(pInfo);
}
-void CFX_GEModule::InitPlatform() {
- m_pFontMgr->SetSystemFontInfo(
- SystemFontInfoIface::CreateDefault(m_pUserFontPaths));
-}
+class CLinuxPlatform : public CFX_GEModule::PlatformIface {
+ public:
+ CLinuxPlatform() = default;
+ ~CLinuxPlatform() override = default;
-void CFX_GEModule::DestroyPlatform() {}
+ void Init() override {
+ CFX_GEModule* pModule = CFX_GEModule::Get();
+ pModule->GetFontMgr()->SetSystemFontInfo(
+ SystemFontInfoIface::CreateDefault(pModule->GetUserFontPaths()));
+ }
+};
+
+// static
+std::unique_ptr<CFX_GEModule::PlatformIface>
+CFX_GEModule::PlatformIface::Create() {
+ return pdfium::MakeUnique<CLinuxPlatform>();
+}
#endif // _FX_PLATFORM_ == _FX_PLATFORM_LINUX_
diff --git a/core/fxge/win32/fx_win32_device.cpp b/core/fxge/win32/fx_win32_device.cpp
index 3361e7c..c4e4576 100644
--- a/core/fxge/win32/fx_win32_device.cpp
+++ b/core/fxge/win32/fx_win32_device.cpp
@@ -683,28 +683,32 @@
return std::unique_ptr<SystemFontInfoIface>(pInfoFallback);
}
-void CFX_GEModule::InitPlatform() {
- CWin32Platform* pPlatformData = new CWin32Platform;
+CWin32Platform::CWin32Platform() = default;
+
+CWin32Platform::~CWin32Platform() = default;
+
+void CWin32Platform::Init() {
OSVERSIONINFO ver;
ver.dwOSVersionInfoSize = sizeof(ver);
GetVersionEx(&ver);
- pPlatformData->m_bHalfTone = ver.dwMajorVersion >= 5;
+ m_bHalfTone = ver.dwMajorVersion >= 5;
if (pdfium::base::win::IsUser32AndGdi32Available())
- pPlatformData->m_GdiplusExt.Load();
- m_pPlatformData = pPlatformData;
- m_pFontMgr->SetSystemFontInfo(SystemFontInfoIface::CreateDefault(nullptr));
+ m_GdiplusExt.Load();
+ CFX_GEModule::Get()->GetFontMgr()->SetSystemFontInfo(
+ SystemFontInfoIface::CreateDefault(nullptr));
}
-void CFX_GEModule::DestroyPlatform() {
- delete (CWin32Platform*)m_pPlatformData;
- m_pPlatformData = nullptr;
+// static
+std::unique_ptr<CFX_GEModule::PlatformIface>
+CFX_GEModule::PlatformIface::Create() {
+ return pdfium::MakeUnique<CWin32Platform>();
}
CGdiDeviceDriver::CGdiDeviceDriver(HDC hDC, int device_class) {
m_hDC = hDC;
m_DeviceClass = device_class;
- CWin32Platform* pPlatform =
- (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
+ auto* pPlatform =
+ static_cast<CWin32Platform*>(CFX_GEModule::Get()->GetPlatform());
SetStretchBltMode(hDC, pPlatform->m_bHalfTone ? HALFTONE : COLORONCOLOR);
DWORD obj_type = GetObjectType(m_hDC);
m_bMetafileDCType = obj_type == OBJ_ENHMETADC || obj_type == OBJ_ENHMETAFILE;
@@ -954,8 +958,8 @@
if (blend_type != BlendMode::kNormal)
return false;
- CWin32Platform* pPlatform =
- (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
+ auto* pPlatform =
+ static_cast<CWin32Platform*>(CFX_GEModule::Get()->GetPlatform());
if (!(pGraphState || stroke_color == 0) &&
!pPlatform->m_GdiplusExt.IsAvailable()) {
CFX_FloatRect bbox_f = pPathData->GetBoundingBox();
@@ -1128,8 +1132,8 @@
CGdiDisplayDriver::CGdiDisplayDriver(HDC hDC)
: CGdiDeviceDriver(hDC, FXDC_DISPLAY) {
- CWin32Platform* pPlatform =
- (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
+ auto* pPlatform =
+ static_cast<CWin32Platform*>(CFX_GEModule::Get()->GetPlatform());
if (pPlatform->m_GdiplusExt.IsAvailable()) {
m_RenderCaps |= FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE;
}
@@ -1300,8 +1304,8 @@
image_rect.top + clip_rect.top, BlendMode::kNormal);
}
if (pSource->HasAlpha()) {
- CWin32Platform* pPlatform =
- (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
+ auto* pPlatform =
+ static_cast<CWin32Platform*>(CFX_GEModule::Get()->GetPlatform());
if (pPlatform->m_GdiplusExt.IsAvailable() && !pSource->IsCmykImage()) {
CFX_DIBExtractor temp(pSource);
RetainPtr<CFX_DIBitmap> pBitmap = temp.GetBitmap();
diff --git a/core/fxge/win32/fx_win32_dib.cpp b/core/fxge/win32/fx_win32_dib.cpp
index 1a7cd45..6c9d394 100644
--- a/core/fxge/win32/fx_win32_dib.cpp
+++ b/core/fxge/win32/fx_win32_dib.cpp
@@ -120,8 +120,8 @@
}
RetainPtr<CFX_DIBitmap> CFX_WindowsDIB::LoadFromFile(const wchar_t* filename) {
- CWin32Platform* pPlatform =
- (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
+ auto* pPlatform =
+ static_cast<CWin32Platform*>(CFX_GEModule::Get()->GetPlatform());
if (pPlatform->m_GdiplusExt.IsAvailable()) {
WINDIB_Open_Args_ args;
args.flags = WINDIB_OPEN_PATHNAME;
@@ -156,8 +156,8 @@
}
RetainPtr<CFX_DIBitmap> CFX_WindowsDIB::LoadDIBitmap(WINDIB_Open_Args_ args) {
- CWin32Platform* pPlatform =
- (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
+ auto* pPlatform =
+ static_cast<CWin32Platform*>(CFX_GEModule::Get()->GetPlatform());
if (pPlatform->m_GdiplusExt.IsAvailable()) {
return pPlatform->m_GdiplusExt.LoadDIBitmap(args);
}
diff --git a/core/fxge/win32/fx_win32_gdipext.cpp b/core/fxge/win32/fx_win32_gdipext.cpp
index ea3db4d..0b6667b 100644
--- a/core/fxge/win32/fx_win32_gdipext.cpp
+++ b/core/fxge/win32/fx_win32_gdipext.cpp
@@ -302,7 +302,7 @@
const CGdiplusExt& GetGdiplusExt() {
auto* pData =
- reinterpret_cast<CWin32Platform*>(CFX_GEModule::Get()->GetPlatformData());
+ static_cast<CWin32Platform*>(CFX_GEModule::Get()->GetPlatform());
return pData->m_GdiplusExt;
}
diff --git a/core/fxge/win32/win32_int.h b/core/fxge/win32/win32_int.h
index 3d4ef2d..d0a4588 100644
--- a/core/fxge/win32/win32_int.h
+++ b/core/fxge/win32/win32_int.h
@@ -13,6 +13,7 @@
#include <vector>
#include "core/fxcrt/retain_ptr.h"
+#include "core/fxge/cfx_gemodule.h"
#include "core/fxge/cfx_pathdata.h"
#include "core/fxge/cfx_windowsrenderdevice.h"
#include "core/fxge/renderdevicedriver_iface.h"
@@ -59,9 +60,15 @@
HMODULE m_GdiModule = nullptr;
};
-class CWin32Platform {
+class CWin32Platform : public CFX_GEModule::PlatformIface {
public:
- bool m_bHalfTone;
+ CWin32Platform();
+ ~CWin32Platform() override;
+
+ // CFX_GEModule::PlatformIface:
+ void Init() override;
+
+ bool m_bHalfTone = false;
CGdiplusExt m_GdiplusExt;
};