Remove SkiaState

Removes SkiaState by moving the remaining methods into
CFX_SkiaDeviceDriver.

Bug: pdfium:1963
Change-Id: Iba36aeb61ea1502f9eeb510f8cd341dc658fe485
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/104610
Commit-Queue: K. Moon <kmoon@chromium.org>
Reviewed-by: Nigi <nigi@chromium.org>
diff --git a/core/fxge/BUILD.gn b/core/fxge/BUILD.gn
index 8d41381..d05386f 100644
--- a/core/fxge/BUILD.gn
+++ b/core/fxge/BUILD.gn
@@ -129,6 +129,8 @@
     "../fxcrt",
   ]
 
+  public_deps = []
+
   if (is_component_build || use_system_freetype) {
     # ft_adobe_glyph_list is not exported from the Freetype shared library so we
     # need it defined in component builds and builds using system freetype.
@@ -144,7 +146,7 @@
 
   if (pdf_use_skia) {
     sources += [ "skia/fx_skia_device.cpp" ]
-    deps += [ "//skia" ]
+    public_deps += [ "//skia" ]
   }
 
   if (is_android) {
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
index dfd0cb9..9d0ebf9 100644
--- a/core/fxge/skia/fx_skia_device.cpp
+++ b/core/fxge/skia/fx_skia_device.cpp
@@ -27,7 +27,6 @@
 #include "core/fxcrt/data_vector.h"
 #include "core/fxcrt/fx_2d_size.h"
 #include "core/fxcrt/fx_coordinates.h"
-#include "core/fxcrt/fx_memory_wrappers.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/stl_util.h"
 #include "core/fxge/calculate_pitch.h"
@@ -75,10 +74,6 @@
 #include "third_party/skia/include/effects/SkGradientShader.h"
 #include "third_party/skia/include/pathops/SkPathOps.h"
 
-// Assumes Skia is not going to add non-data members to its fundamental types.
-FX_DATA_PARTITION_EXCEPTION(SkPoint);
-FX_DATA_PARTITION_EXCEPTION(SkRSXform);
-
 namespace {
 
 #define SHOW_SKIA_PATH 0  // set to 1 to print the path contents
@@ -785,180 +780,39 @@
   return bitmap;
 }
 
-}  // namespace
-
-// TODO(crbug.com/pdfium/1936): Inline remaining methods.
-class SkiaState {
- public:
-  // mark all cached state as uninitialized
-  explicit SkiaState(SkCanvas* pCanvas) : m_pCanvas(pCanvas) {}
-
-  bool HasRSX(pdfium::span<const TextCharPos> char_pos,
-              float* scaleXPtr,
-              bool* oneAtATimePtr) const {
-    bool useRSXform = false;
-    bool oneAtATime = false;
-    float scaleX = 1;
-    for (const TextCharPos& cp : char_pos) {
-      if (!cp.m_bGlyphAdjust)
-        continue;
-      bool upright = 0 == cp.m_AdjustMatrix[1] && 0 == cp.m_AdjustMatrix[2];
-      if (cp.m_AdjustMatrix[0] != cp.m_AdjustMatrix[3]) {
-        if (upright && 1 == cp.m_AdjustMatrix[3]) {
-          if (1 == scaleX)
-            scaleX = cp.m_AdjustMatrix[0];
-          else if (scaleX != cp.m_AdjustMatrix[0])
-            oneAtATime = true;
-        } else {
+bool HasRSX(pdfium::span<const TextCharPos> char_pos,
+            float* scaleXPtr,
+            bool* oneAtATimePtr) {
+  bool useRSXform = false;
+  bool oneAtATime = false;
+  float scaleX = 1;
+  for (const TextCharPos& cp : char_pos) {
+    if (!cp.m_bGlyphAdjust) {
+      continue;
+    }
+    bool upright = 0 == cp.m_AdjustMatrix[1] && 0 == cp.m_AdjustMatrix[2];
+    if (cp.m_AdjustMatrix[0] != cp.m_AdjustMatrix[3]) {
+      if (upright && 1 == cp.m_AdjustMatrix[3]) {
+        if (1 == scaleX) {
+          scaleX = cp.m_AdjustMatrix[0];
+        } else if (scaleX != cp.m_AdjustMatrix[0]) {
           oneAtATime = true;
         }
-      } else if (cp.m_AdjustMatrix[1] != -cp.m_AdjustMatrix[2]) {
-        oneAtATime = true;
       } else {
-        useRSXform = true;
+        oneAtATime = true;
       }
-    }
-    *oneAtATimePtr = oneAtATime;
-    *scaleXPtr = oneAtATime ? 1 : scaleX;
-    return oneAtATime ? false : useRSXform;
-  }
-
-  bool DrawText(pdfium::span<const TextCharPos> char_pos,
-                const CFX_Font* pFont,
-                const CFX_Matrix& matrix,
-                float font_size,
-                uint32_t color,
-                const CFX_TextRenderOptions& options) {
-    float scaleX = 1;
-    bool oneAtATime = false;
-    bool hasRSX = HasRSX(char_pos, &scaleX, &oneAtATime);
-    if (oneAtATime) {
-      return false;
-    }
-
-    m_charDetails.SetCount(0);
-    m_rsxform.resize(0);
-
-    const size_t original_count = m_charDetails.Count();
-    FX_SAFE_SIZE_T safe_count = original_count;
-    safe_count += char_pos.size();
-    const size_t total_count = safe_count.ValueOrDie();
-    m_charDetails.SetCount(total_count);
-    if (hasRSX)
-      m_rsxform.resize(total_count);
-
-    const SkScalar flip = font_size < 0 ? -1 : 1;
-    const SkScalar vFlip = pFont->IsVertical() ? -1 : 1;
-    for (size_t index = 0; index < char_pos.size(); ++index) {
-      const TextCharPos& cp = char_pos[index];
-      size_t cur_index = index + original_count;
-      m_charDetails.SetPositionAt(
-          cur_index, {cp.m_Origin.x * flip, cp.m_Origin.y * vFlip});
-      m_charDetails.SetGlyphAt(cur_index,
-                               static_cast<uint16_t>(cp.m_GlyphIndex));
-      m_charDetails.SetFontCharWidthAt(cur_index, cp.m_FontCharWidth);
-#if BUILDFLAG(IS_APPLE)
-      if (cp.m_ExtGID) {
-        m_charDetails.SetGlyphAt(cur_index, static_cast<uint16_t>(cp.m_ExtGID));
-      }
-#endif
-    }
-    if (hasRSX) {
-      const DataVector<SkPoint>& positions = m_charDetails.GetPositions();
-      for (size_t index = 0; index < char_pos.size(); ++index) {
-        const TextCharPos& cp = char_pos[index];
-        SkRSXform& rsxform = m_rsxform[index + original_count];
-        if (cp.m_bGlyphAdjust) {
-          rsxform.fSCos = cp.m_AdjustMatrix[0];
-          rsxform.fSSin = cp.m_AdjustMatrix[1];
-          rsxform.fTx = cp.m_AdjustMatrix[0] * positions[index].fX;
-          rsxform.fTy = -cp.m_AdjustMatrix[3] * positions[index].fY;
-        } else {
-          rsxform.fSCos = 1;
-          rsxform.fSSin = 0;
-          rsxform.fTx = positions[index].fX;
-          rsxform.fTy = positions[index].fY;
-        }
-      }
-    }
-
-    SkPaint skPaint;
-    skPaint.setAntiAlias(true);
-    skPaint.setColor(color);
-
-    SkFont font;
-    if (pFont->GetFaceRec()) {  // exclude placeholder test fonts
-      font.setTypeface(sk_ref_sp(pFont->GetDeviceCache()));
-    }
-    font.setEmbolden(pFont->IsSubstFontBold());
-    font.setHinting(SkFontHinting::kNone);
-    font.setScaleX(scaleX);
-    font.setSkewX(tanf(pFont->GetSubstFontItalicAngle() * FXSYS_PI / 180.0));
-    font.setSize(SkTAbs(font_size));
-    font.setSubpixel(true);
-    font.setEdging(GetFontEdgingType(options));
-
-    SkAutoCanvasRestore scoped_save_restore(m_pCanvas, /*doSave=*/true);
-    m_pCanvas->concat(ToFlippedSkMatrix(matrix, flip));
-
-    const DataVector<uint16_t>& glyphs = m_charDetails.GetGlyphs();
-    if (m_rsxform.size()) {
-      sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromRSXform(
-          glyphs.data(), glyphs.size() * sizeof(uint16_t), m_rsxform.data(),
-          font, SkTextEncoding::kGlyphID);
-      m_pCanvas->drawTextBlob(blob, 0, 0, skPaint);
+    } else if (cp.m_AdjustMatrix[1] != -cp.m_AdjustMatrix[2]) {
+      oneAtATime = true;
     } else {
-      const DataVector<SkPoint>& positions = m_charDetails.GetPositions();
-      for (size_t i = 0; i < m_charDetails.Count(); ++i) {
-        sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText(
-            &glyphs[i], sizeof(glyphs[i]), font, SkTextEncoding::kGlyphID);
-        m_pCanvas->drawTextBlob(blob, positions[i].fX, positions[i].fY,
-                                skPaint);
-      }
+      useRSXform = true;
     }
-    return true;
   }
+  *oneAtATimePtr = oneAtATime;
+  *scaleXPtr = oneAtATime ? 1 : scaleX;
+  return oneAtATime ? false : useRSXform;
+}
 
- private:
-  class CharDetail {
-   public:
-    CharDetail() = default;
-    ~CharDetail() = default;
-
-    const DataVector<SkPoint>& GetPositions() const { return m_positions; }
-    void SetPositionAt(size_t index, const SkPoint& position) {
-      m_positions[index] = position;
-    }
-    const DataVector<uint16_t>& GetGlyphs() const { return m_glyphs; }
-    void SetGlyphAt(size_t index, uint16_t glyph) { m_glyphs[index] = glyph; }
-    const DataVector<uint32_t>& GetFontCharWidths() const {
-      return m_fontCharWidths;
-    }
-    void SetFontCharWidthAt(size_t index, uint32_t width) {
-      m_fontCharWidths[index] = width;
-    }
-    size_t Count() const {
-      DCHECK_EQ(m_positions.size(), m_glyphs.size());
-      return m_glyphs.size();
-    }
-    void SetCount(size_t count) {
-      m_positions.resize(count);
-      m_glyphs.resize(count);
-      m_fontCharWidths.resize(count);
-    }
-
-   private:
-    DataVector<SkPoint> m_positions;  // accumulator for text positions
-    DataVector<uint16_t> m_glyphs;    // accumulator for text glyphs
-    // accumulator for glyphs' width defined in pdf
-    DataVector<uint32_t> m_fontCharWidths;
-  };
-
-  CharDetail m_charDetails;
-  // accumulator for txt rotate/scale/translate
-  DataVector<SkRSXform> m_rsxform;
-  UnownedPtr<SkCanvas> const m_pCanvas;
-};
+}  // namespace
 
 // static
 std::unique_ptr<CFX_SkiaDeviceDriver> CFX_SkiaDeviceDriver::Create(
@@ -1019,13 +873,11 @@
   skBitmap.installPixels(imageInfo, m_pBitmap->GetBuffer().data(),
                          m_pBitmap->GetPitch());
   m_pCanvas = new SkCanvas(skBitmap);
-  m_pCache = std::make_unique<SkiaState>(m_pCanvas);
 }
 
 CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(SkPictureRecorder* recorder)
     : m_pRecorder(recorder), m_bGroupKnockout(false) {
   m_pCanvas = m_pRecorder->getRecordingCanvas();
-  m_pCache = std::make_unique<SkiaState>(m_pCanvas);
   int width = m_pCanvas->imageInfo().width();
   int height = m_pCanvas->imageInfo().height();
   DCHECK_EQ(kUnknown_SkColorType, m_pCanvas->imageInfo().colorType());
@@ -1051,7 +903,6 @@
   }
 
   if (!m_pRecorder) {
-    m_pCache.reset();
     delete m_pCanvas;
   }
 }
@@ -1085,8 +936,8 @@
       return false;
   }
 
-  if (m_pCache->DrawText(pCharPos, pFont, mtObject2Device, font_size, color,
-                         options)) {
+  if (TryDrawText(pCharPos, pFont, mtObject2Device, font_size, color,
+                  options)) {
     return true;
   }
   sk_sp<SkTypeface> typeface(SkSafeRef(pFont->GetDeviceCache()));
@@ -1110,6 +961,8 @@
   m_pCanvas->concat(skMatrix);
   DataVector<SkPoint> positions(pCharPos.size());
   DataVector<uint16_t> glyphs(pCharPos.size());
+
+  // TODO(crbug.com/pdfium/1936): Reuse `HasRSX()` result.
   bool useRSXform = false;
   bool oneAtATime = false;
   for (size_t index = 0; index < pCharPos.size(); ++index) {
@@ -1199,6 +1052,101 @@
   return true;
 }
 
+bool CFX_SkiaDeviceDriver::TryDrawText(pdfium::span<const TextCharPos> char_pos,
+                                       const CFX_Font* pFont,
+                                       const CFX_Matrix& matrix,
+                                       float font_size,
+                                       uint32_t color,
+                                       const CFX_TextRenderOptions& options) {
+  float scaleX = 1;
+  bool oneAtATime = false;
+  bool hasRSX = HasRSX(char_pos, &scaleX, &oneAtATime);
+  if (oneAtATime) {
+    return false;
+  }
+
+  m_charDetails.SetCount(0);
+  m_rsxform.resize(0);
+
+  const size_t original_count = m_charDetails.Count();
+  FX_SAFE_SIZE_T safe_count = original_count;
+  safe_count += char_pos.size();
+  const size_t total_count = safe_count.ValueOrDie();
+  m_charDetails.SetCount(total_count);
+  if (hasRSX) {
+    m_rsxform.resize(total_count);
+  }
+
+  const SkScalar flip = font_size < 0 ? -1 : 1;
+  const SkScalar vFlip = pFont->IsVertical() ? -1 : 1;
+  for (size_t index = 0; index < char_pos.size(); ++index) {
+    const TextCharPos& cp = char_pos[index];
+    size_t cur_index = index + original_count;
+    m_charDetails.SetPositionAt(cur_index,
+                                {cp.m_Origin.x * flip, cp.m_Origin.y * vFlip});
+    m_charDetails.SetGlyphAt(cur_index, static_cast<uint16_t>(cp.m_GlyphIndex));
+    m_charDetails.SetFontCharWidthAt(cur_index, cp.m_FontCharWidth);
+#if BUILDFLAG(IS_APPLE)
+    if (cp.m_ExtGID) {
+      m_charDetails.SetGlyphAt(cur_index, static_cast<uint16_t>(cp.m_ExtGID));
+    }
+#endif
+  }
+  if (hasRSX) {
+    const DataVector<SkPoint>& positions = m_charDetails.GetPositions();
+    for (size_t index = 0; index < char_pos.size(); ++index) {
+      const TextCharPos& cp = char_pos[index];
+      SkRSXform& rsxform = m_rsxform[index + original_count];
+      if (cp.m_bGlyphAdjust) {
+        rsxform.fSCos = cp.m_AdjustMatrix[0];
+        rsxform.fSSin = cp.m_AdjustMatrix[1];
+        rsxform.fTx = cp.m_AdjustMatrix[0] * positions[index].fX;
+        rsxform.fTy = -cp.m_AdjustMatrix[3] * positions[index].fY;
+      } else {
+        rsxform.fSCos = 1;
+        rsxform.fSSin = 0;
+        rsxform.fTx = positions[index].fX;
+        rsxform.fTy = positions[index].fY;
+      }
+    }
+  }
+
+  SkPaint skPaint;
+  skPaint.setAntiAlias(true);
+  skPaint.setColor(color);
+
+  SkFont font;
+  if (pFont->GetFaceRec()) {  // exclude placeholder test fonts
+    font.setTypeface(sk_ref_sp(pFont->GetDeviceCache()));
+  }
+  font.setEmbolden(pFont->IsSubstFontBold());
+  font.setHinting(SkFontHinting::kNone);
+  font.setScaleX(scaleX);
+  font.setSkewX(tanf(pFont->GetSubstFontItalicAngle() * FXSYS_PI / 180.0));
+  font.setSize(SkTAbs(font_size));
+  font.setSubpixel(true);
+  font.setEdging(GetFontEdgingType(options));
+
+  SkAutoCanvasRestore scoped_save_restore(m_pCanvas, /*doSave=*/true);
+  m_pCanvas->concat(ToFlippedSkMatrix(matrix, flip));
+
+  const DataVector<uint16_t>& glyphs = m_charDetails.GetGlyphs();
+  if (m_rsxform.size()) {
+    sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromRSXform(
+        glyphs.data(), glyphs.size() * sizeof(uint16_t), m_rsxform.data(), font,
+        SkTextEncoding::kGlyphID);
+    m_pCanvas->drawTextBlob(blob, 0, 0, skPaint);
+  } else {
+    const DataVector<SkPoint>& positions = m_charDetails.GetPositions();
+    for (size_t i = 0; i < m_charDetails.Count(); ++i) {
+      sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromText(
+          &glyphs[i], sizeof(glyphs[i]), font, SkTextEncoding::kGlyphID);
+      m_pCanvas->drawTextBlob(blob, positions[i].fX, positions[i].fY, skPaint);
+    }
+  }
+  return true;
+}
+
 int CFX_SkiaDeviceDriver::GetDriverType() const {
   return 1;
 }
@@ -1857,6 +1805,9 @@
   return true;
 }
 
+CFX_SkiaDeviceDriver::CharDetail::CharDetail() = default;
+CFX_SkiaDeviceDriver::CharDetail::~CharDetail() = default;
+
 void CFX_DefaultRenderDevice::Clear(uint32_t color) {
   static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver())->Clear(color);
 }
diff --git a/core/fxge/skia/fx_skia_device.h b/core/fxge/skia/fx_skia_device.h
index 876c20e..d18f0e0 100644
--- a/core/fxge/skia/fx_skia_device.h
+++ b/core/fxge/skia/fx_skia_device.h
@@ -5,17 +5,31 @@
 #ifndef CORE_FXGE_SKIA_FX_SKIA_DEVICE_H_
 #define CORE_FXGE_SKIA_FX_SKIA_DEVICE_H_
 
+#include <stdint.h>
+
 #include <memory>
 
+#include "core/fxcrt/data_vector.h"
+#include "core/fxcrt/fx_memory_wrappers.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxge/cfx_fillrenderoptions.h"
 #include "core/fxge/cfx_path.h"
 #include "core/fxge/renderdevicedriver_iface.h"
+#include "third_party/base/check_op.h"
+#include "third_party/base/span.h"
+#include "third_party/skia/include/core/SkPoint.h"
+#include "third_party/skia/include/core/SkRSXform.h"
 
+class CFX_Font;
+class CFX_Matrix;
 class SkCanvas;
 class SkPictureRecorder;
-class SkiaState;
 class TextCharPos;
+struct CFX_TextRenderOptions;
+
+// Assumes Skia is not going to add non-data members to its fundamental types.
+FX_DATA_PARTITION_EXCEPTION(SkPoint);
+FX_DATA_PARTITION_EXCEPTION(SkRSXform);
 
 class CFX_SkiaDeviceDriver final : public RenderDeviceDriverIface {
  public:
@@ -142,11 +156,52 @@
   void Dump() const;
 
  private:
+  class CharDetail {
+   public:
+    CharDetail();
+    ~CharDetail();
+
+    const DataVector<SkPoint>& GetPositions() const { return m_positions; }
+    void SetPositionAt(size_t index, const SkPoint& position) {
+      m_positions[index] = position;
+    }
+    const DataVector<uint16_t>& GetGlyphs() const { return m_glyphs; }
+    void SetGlyphAt(size_t index, uint16_t glyph) { m_glyphs[index] = glyph; }
+    const DataVector<uint32_t>& GetFontCharWidths() const {
+      return m_fontCharWidths;
+    }
+    void SetFontCharWidthAt(size_t index, uint32_t width) {
+      m_fontCharWidths[index] = width;
+    }
+    size_t Count() const {
+      DCHECK_EQ(m_positions.size(), m_glyphs.size());
+      return m_glyphs.size();
+    }
+    void SetCount(size_t count) {
+      m_positions.resize(count);
+      m_glyphs.resize(count);
+      m_fontCharWidths.resize(count);
+    }
+
+   private:
+    DataVector<SkPoint> m_positions;  // accumulator for text positions
+    DataVector<uint16_t> m_glyphs;    // accumulator for text glyphs
+    // accumulator for glyphs' width defined in pdf
+    DataVector<uint32_t> m_fontCharWidths;
+  };
+
   CFX_SkiaDeviceDriver(RetainPtr<CFX_DIBitmap> pBitmap,
                        bool bRgbByteOrder,
                        RetainPtr<CFX_DIBitmap> pBackdropBitmap,
                        bool bGroupKnockout);
 
+  bool TryDrawText(pdfium::span<const TextCharPos> char_pos,
+                   const CFX_Font* pFont,
+                   const CFX_Matrix& matrix,
+                   float font_size,
+                   uint32_t color,
+                   const CFX_TextRenderOptions& options);
+
   bool StartDIBitsSkia(const RetainPtr<CFX_DIBBase>& pBitmap,
                        int bitmap_alpha,
                        uint32_t color,
@@ -163,10 +218,13 @@
 
   SkCanvas* m_pCanvas;
   SkPictureRecorder* const m_pRecorder;
-  std::unique_ptr<SkiaState> m_pCache;
   CFX_FillRenderOptions m_FillOptions;
   bool m_bRgbByteOrder;
   bool m_bGroupKnockout;
+
+  CharDetail m_charDetails;
+  // accumulator for txt rotate/scale/translate
+  DataVector<SkRSXform> m_rsxform;
 };
 
 #endif  // CORE_FXGE_SKIA_FX_SKIA_DEVICE_H_