Move CPDF_DeviceBuffer::Initialize() params to the ctor.

So CPDF_DeviceBuffer members can become const.

Along the way:
- Check the return value from CPDF_DeviceBuffer::Initialize().
- Change a CPDF_RenderContext::GetBackground() parameter to
  const-reference since it is never null.
- Add CPDF_DeviceBuffer::CalculateMatrix() and remove the copy in
  CPDF_ScaledRenderBuffer.

Change-Id: I534e5d33dbcb0c2e2ddc1259bf89ebaa723cb04c
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/55756
Auto-Submit: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/render/cpdf_devicebuffer.cpp b/core/fpdfapi/render/cpdf_devicebuffer.cpp
index 091a0c1..3426f01 100644
--- a/core/fpdfapi/render/cpdf_devicebuffer.cpp
+++ b/core/fpdfapi/render/cpdf_devicebuffer.cpp
@@ -15,39 +15,59 @@
 #include "core/fxge/dib/cfx_dibitmap.h"
 #include "core/fxge/fx_dib.h"
 
-CPDF_DeviceBuffer::CPDF_DeviceBuffer() {}
+namespace {
 
-CPDF_DeviceBuffer::~CPDF_DeviceBuffer() {}
-
-bool CPDF_DeviceBuffer::Initialize(CPDF_RenderContext* pContext,
-                                   CFX_RenderDevice* pDevice,
-                                   const FX_RECT& rect,
-                                   const CPDF_PageObject* pObj,
-                                   int max_dpi) {
-  m_pDevice = pDevice;
-  m_pContext = pContext;
-  m_Rect = rect;
-  m_pObject = pObj;
-  m_Matrix.Translate(-rect.left, -rect.top);
-#if !defined(OS_MACOSX)
-  int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE);
-  int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE);
-  if (horz_size && vert_size && max_dpi) {
-    int dpih =
-        pDevice->GetDeviceCaps(FXDC_PIXEL_WIDTH) * 254 / (horz_size * 10);
-    int dpiv =
-        pDevice->GetDeviceCaps(FXDC_PIXEL_HEIGHT) * 254 / (vert_size * 10);
-    if (dpih > max_dpi)
-      m_Matrix.Scale((float)(max_dpi) / dpih, 1.0f);
-    if (dpiv > max_dpi)
-      m_Matrix.Scale(1.0f, (float)(max_dpi) / (float)dpiv);
-  }
+#if defined(OS_MACOSX)
+constexpr bool kScaleDeviceBuffer = false;
+#else
+constexpr bool kScaleDeviceBuffer = true;
 #endif
+
+}  // namespace
+
+// static
+CFX_Matrix CPDF_DeviceBuffer::CalculateMatrix(CFX_RenderDevice* pDevice,
+                                              const FX_RECT& rect,
+                                              int max_dpi,
+                                              bool scale) {
+  CFX_Matrix matrix;
+  matrix.Translate(-rect.left, -rect.top);
+  if (scale) {
+    int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE);
+    int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE);
+    if (horz_size && vert_size && max_dpi) {
+      int dpih =
+          pDevice->GetDeviceCaps(FXDC_PIXEL_WIDTH) * 254 / (horz_size * 10);
+      int dpiv =
+          pDevice->GetDeviceCaps(FXDC_PIXEL_HEIGHT) * 254 / (vert_size * 10);
+      if (dpih > max_dpi)
+        matrix.Scale(static_cast<float>(max_dpi) / dpih, 1.0f);
+      if (dpiv > max_dpi)
+        matrix.Scale(1.0f, static_cast<float>(max_dpi) / dpiv);
+    }
+  }
+  return matrix;
+}
+
+CPDF_DeviceBuffer::CPDF_DeviceBuffer(CPDF_RenderContext* pContext,
+                                     CFX_RenderDevice* pDevice,
+                                     const FX_RECT& rect,
+                                     const CPDF_PageObject* pObj,
+                                     int max_dpi)
+    : m_pDevice(pDevice),
+      m_pContext(pContext),
+      m_pObject(pObj),
+      m_pBitmap(pdfium::MakeRetain<CFX_DIBitmap>()),
+      m_Rect(rect),
+      m_Matrix(CalculateMatrix(pDevice, rect, max_dpi, kScaleDeviceBuffer)) {}
+
+CPDF_DeviceBuffer::~CPDF_DeviceBuffer() = default;
+
+bool CPDF_DeviceBuffer::Initialize() {
   FX_RECT bitmap_rect =
-      m_Matrix.TransformRect(CFX_FloatRect(rect)).GetOuterRect();
-  m_pBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
-  m_pBitmap->Create(bitmap_rect.Width(), bitmap_rect.Height(), FXDIB_Argb);
-  return true;
+      m_Matrix.TransformRect(CFX_FloatRect(m_Rect)).GetOuterRect();
+  return m_pBitmap->Create(bitmap_rect.Width(), bitmap_rect.Height(),
+                           FXDIB_Argb);
 }
 
 void CPDF_DeviceBuffer::OutputToDevice() {
@@ -63,7 +83,7 @@
   auto pBuffer = pdfium::MakeRetain<CFX_DIBitmap>();
   m_pDevice->CreateCompatibleBitmap(pBuffer, m_pBitmap->GetWidth(),
                                     m_pBitmap->GetHeight());
-  m_pContext->GetBackground(pBuffer, m_pObject.Get(), nullptr, &m_Matrix);
+  m_pContext->GetBackground(pBuffer, m_pObject.Get(), nullptr, m_Matrix);
   pBuffer->CompositeBitmap(0, 0, pBuffer->GetWidth(), pBuffer->GetHeight(),
                            m_pBitmap, 0, 0, BlendMode::kNormal, nullptr, false);
   m_pDevice->StretchDIBits(pBuffer, m_Rect.left, m_Rect.top, m_Rect.Width(),
diff --git a/core/fpdfapi/render/cpdf_devicebuffer.h b/core/fpdfapi/render/cpdf_devicebuffer.h
index 00fd5c8..1f16dbe 100644
--- a/core/fpdfapi/render/cpdf_devicebuffer.h
+++ b/core/fpdfapi/render/cpdf_devicebuffer.h
@@ -18,25 +18,30 @@
 
 class CPDF_DeviceBuffer {
  public:
-  CPDF_DeviceBuffer();
+  static CFX_Matrix CalculateMatrix(CFX_RenderDevice* pDevice,
+                                    const FX_RECT& rect,
+                                    int max_dpi,
+                                    bool scale);
+
+  CPDF_DeviceBuffer(CPDF_RenderContext* pContext,
+                    CFX_RenderDevice* pDevice,
+                    const FX_RECT& rect,
+                    const CPDF_PageObject* pObj,
+                    int max_dpi);
   ~CPDF_DeviceBuffer();
 
-  bool Initialize(CPDF_RenderContext* pContext,
-                  CFX_RenderDevice* pDevice,
-                  const FX_RECT& rect,
-                  const CPDF_PageObject* pObj,
-                  int max_dpi);
+  bool Initialize();
   void OutputToDevice();
   RetainPtr<CFX_DIBitmap> GetBitmap() const { return m_pBitmap; }
   const CFX_Matrix& GetMatrix() const { return m_Matrix; }
 
  private:
-  UnownedPtr<CFX_RenderDevice> m_pDevice;
-  UnownedPtr<CPDF_RenderContext> m_pContext;
-  UnownedPtr<const CPDF_PageObject> m_pObject;
-  RetainPtr<CFX_DIBitmap> m_pBitmap;
-  FX_RECT m_Rect;
-  CFX_Matrix m_Matrix;
+  UnownedPtr<CFX_RenderDevice> const m_pDevice;
+  UnownedPtr<CPDF_RenderContext> const m_pContext;
+  UnownedPtr<const CPDF_PageObject> const m_pObject;
+  RetainPtr<CFX_DIBitmap> const m_pBitmap;
+  const FX_RECT m_Rect;
+  const CFX_Matrix m_Matrix;
 };
 
 #endif  // CORE_FPDFAPI_RENDER_CPDF_DEVICEBUFFER_H_
diff --git a/core/fpdfapi/render/cpdf_rendercontext.cpp b/core/fpdfapi/render/cpdf_rendercontext.cpp
index 96b98a4..aebb9cf 100644
--- a/core/fpdfapi/render/cpdf_rendercontext.cpp
+++ b/core/fpdfapi/render/cpdf_rendercontext.cpp
@@ -35,13 +35,13 @@
 void CPDF_RenderContext::GetBackground(const RetainPtr<CFX_DIBitmap>& pBuffer,
                                        const CPDF_PageObject* pObj,
                                        const CPDF_RenderOptions* pOptions,
-                                       CFX_Matrix* pFinalMatrix) {
+                                       const CFX_Matrix& mtFinal) {
   CFX_DefaultRenderDevice device;
   device.Attach(pBuffer, false, nullptr, false);
 
   device.FillRect(FX_RECT(0, 0, device.GetWidth(), device.GetHeight()),
                   0xffffffff);
-  Render(&device, pObj, pOptions, pFinalMatrix);
+  Render(&device, pObj, pOptions, &mtFinal);
 }
 
 void CPDF_RenderContext::AppendLayer(CPDF_PageObjectHolder* pObjectHolder,
diff --git a/core/fpdfapi/render/cpdf_rendercontext.h b/core/fpdfapi/render/cpdf_rendercontext.h
index 5329338..ff4911d 100644
--- a/core/fpdfapi/render/cpdf_rendercontext.h
+++ b/core/fpdfapi/render/cpdf_rendercontext.h
@@ -55,7 +55,7 @@
   void GetBackground(const RetainPtr<CFX_DIBitmap>& pBuffer,
                      const CPDF_PageObject* pObj,
                      const CPDF_RenderOptions* pOptions,
-                     CFX_Matrix* pFinalMatrix);
+                     const CFX_Matrix& mtFinal);
 
   size_t CountLayers() const { return m_Layers.size(); }
   Layer* GetLayer(uint32_t index) { return &m_Layers[index]; }
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index d1f702b..403bdd4 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -2054,9 +2054,11 @@
           pPattern, &mtMatrix, clip_rect_bbox, alpha, bAlphaMode)) {
     return;
   }
-  CPDF_DeviceBuffer buffer;
-  buffer.Initialize(m_pContext.Get(), m_pDevice, clip_rect_bbox,
-                    m_pCurObj.Get(), 150);
+  CPDF_DeviceBuffer buffer(m_pContext.Get(), m_pDevice, clip_rect_bbox,
+                           m_pCurObj.Get(), 150);
+  if (!buffer.Initialize())
+    return;
+
   CFX_Matrix FinalMatrix = mtMatrix * buffer.GetMatrix();
   RetainPtr<CFX_DIBitmap> pBitmap = buffer.GetBitmap();
   if (!pBitmap->GetBuffer())
diff --git a/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp b/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp
index a70b160..8536b3b 100644
--- a/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp
+++ b/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp
@@ -6,8 +6,8 @@
 
 #include "core/fpdfapi/render/cpdf_scaledrenderbuffer.h"
 
+#include "core/fpdfapi/render/cpdf_devicebuffer.h"
 #include "core/fpdfapi/render/cpdf_rendercontext.h"
-#include "core/fpdfapi/render/cpdf_renderoptions.h"
 #include "core/fxge/cfx_defaultrenderdevice.h"
 #include "core/fxge/dib/cfx_dibitmap.h"
 #include "third_party/base/ptr_util.h"
@@ -24,7 +24,7 @@
 
 bool CPDF_ScaledRenderBuffer::Initialize(CPDF_RenderContext* pContext,
                                          CFX_RenderDevice* pDevice,
-                                         const FX_RECT& pRect,
+                                         const FX_RECT& rect,
                                          const CPDF_PageObject* pObj,
                                          const CPDF_RenderOptions* pOptions,
                                          int max_dpi) {
@@ -33,28 +33,17 @@
     return true;
 
   m_pContext = pContext;
-  m_Rect = pRect;
+  m_Rect = rect;
   m_pObject = pObj;
-  m_Matrix.Translate(-pRect.left, -pRect.top);
-  int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE);
-  int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE);
-  if (horz_size && vert_size && max_dpi) {
-    int dpih =
-        pDevice->GetDeviceCaps(FXDC_PIXEL_WIDTH) * 254 / (horz_size * 10);
-    int dpiv =
-        pDevice->GetDeviceCaps(FXDC_PIXEL_HEIGHT) * 254 / (vert_size * 10);
-    if (dpih > max_dpi)
-      m_Matrix.Scale((float)(max_dpi) / dpih, 1.0f);
-    if (dpiv > max_dpi)
-      m_Matrix.Scale(1.0f, (float)(max_dpi) / (float)dpiv);
-  }
+  m_Matrix = CPDF_DeviceBuffer::CalculateMatrix(pDevice, rect, max_dpi,
+                                                /*scale=*/true);
   m_pBitmapDevice = pdfium::MakeUnique<CFX_DefaultRenderDevice>();
   bool bIsAlpha =
       !!(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_ALPHA_OUTPUT);
   FXDIB_Format dibFormat = bIsAlpha ? FXDIB_Argb : FXDIB_Rgb;
   while (1) {
     FX_RECT bitmap_rect =
-        m_Matrix.TransformRect(CFX_FloatRect(pRect)).GetOuterRect();
+        m_Matrix.TransformRect(CFX_FloatRect(rect)).GetOuterRect();
     int32_t width = bitmap_rect.Width();
     int32_t height = bitmap_rect.Height();
     // Set to 0 to make CalculatePitchAndSize() calculate it.
@@ -72,7 +61,7 @@
     m_Matrix.Scale(0.5f, 0.5f);
   }
   m_pContext->GetBackground(m_pBitmapDevice->GetBitmap(), m_pObject.Get(),
-                            pOptions, &m_Matrix);
+                            pOptions, m_Matrix);
   return true;
 }
 
diff --git a/core/fpdfapi/render/cpdf_scaledrenderbuffer.h b/core/fpdfapi/render/cpdf_scaledrenderbuffer.h
index e809845..0e7ac07 100644
--- a/core/fpdfapi/render/cpdf_scaledrenderbuffer.h
+++ b/core/fpdfapi/render/cpdf_scaledrenderbuffer.h
@@ -25,7 +25,7 @@
 
   bool Initialize(CPDF_RenderContext* pContext,
                   CFX_RenderDevice* pDevice,
-                  const FX_RECT& pRect,
+                  const FX_RECT& rect,
                   const CPDF_PageObject* pObj,
                   const CPDF_RenderOptions* pOptions,
                   int max_dpi);