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; };