Introduce span<> in ScanlineComposerIface.

Then propagate upwards, calling .data() as needed.

Change-Id: Iaa19396bddcea843b3d917dd31d478a15e433872
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/85575
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxge/dib/cfx_bitmapcomposer.cpp b/core/fxge/dib/cfx_bitmapcomposer.cpp
index 75c9bea..23a59bd 100644
--- a/core/fxge/dib/cfx_bitmapcomposer.cpp
+++ b/core/fxge/dib/cfx_bitmapcomposer.cpp
@@ -70,11 +70,11 @@
 }
 
 void CFX_BitmapComposer::DoCompose(uint8_t* dest_scan,
-                                   const uint8_t* src_scan,
+                                   pdfium::span<const uint8_t> src_scan,
                                    int dest_width,
                                    const uint8_t* clip_scan,
-                                   const uint8_t* src_extra_alpha,
-                                   uint8_t* dst_extra_alpha) {
+                                   pdfium::span<const uint8_t> src_extra_alpha,
+                                   pdfium::span<uint8_t> dst_extra_alpha) {
   uint8_t* pAddClipScan = m_pAddClipScan.data();
   if (m_BitmapAlpha < 255) {
     if (clip_scan) {
@@ -99,9 +99,10 @@
   }
 }
 
-void CFX_BitmapComposer::ComposeScanline(int line,
-                                         const uint8_t* scanline,
-                                         const uint8_t* scan_extra_alpha) {
+void CFX_BitmapComposer::ComposeScanline(
+    int line,
+    pdfium::span<const uint8_t> scanline,
+    pdfium::span<const uint8_t> scan_extra_alpha) {
   if (m_bVertical) {
     ComposeScanlineV(line, scanline, scan_extra_alpha);
     return;
@@ -124,18 +125,19 @@
     // Help some compilers perform pointer arithmetic against safe numerics.
     dest_scan += static_cast<uint32_t>(offset.ValueOrDie());
   }
-  uint8_t* dest_alpha_scan =
-      m_pBitmap->GetWritableAlphaMaskScanline(line + m_DestTop).data();
-  if (dest_alpha_scan)
-    dest_alpha_scan += m_DestLeft;
+  pdfium::span<uint8_t> dest_alpha_scan =
+      m_pBitmap->GetWritableAlphaMaskScanline(line + m_DestTop);
+  if (!dest_alpha_scan.empty())
+    dest_alpha_scan = dest_alpha_scan.subspan(m_DestLeft);
 
   DoCompose(dest_scan, scanline, m_DestWidth, clip_scan, scan_extra_alpha,
             dest_alpha_scan);
 }
 
-void CFX_BitmapComposer::ComposeScanlineV(int line,
-                                          const uint8_t* scanline,
-                                          const uint8_t* scan_extra_alpha) {
+void CFX_BitmapComposer::ComposeScanlineV(
+    int line,
+    pdfium::span<const uint8_t> scanline,
+    pdfium::span<const uint8_t> scan_extra_alpha) {
   int Bpp = m_pBitmap->GetBPP() / 8;
   int dest_pitch = m_pBitmap->GetPitch();
   int dest_alpha_pitch = m_pBitmap->GetAlphaMaskPitch();
@@ -191,7 +193,7 @@
     }
   }
   DoCompose(m_pScanlineV.data(), scanline, m_DestHeight, clip_scan,
-            scan_extra_alpha, m_pScanlineAlphaV.data());
+            scan_extra_alpha, m_pScanlineAlphaV);
   src_scan = m_pScanlineV.data();
   dest_scan = dest_buf;
   for (int i = 0; i < m_DestHeight; ++i) {
diff --git a/core/fxge/dib/cfx_bitmapcomposer.h b/core/fxge/dib/cfx_bitmapcomposer.h
index 30f7132..f38297d 100644
--- a/core/fxge/dib/cfx_bitmapcomposer.h
+++ b/core/fxge/dib/cfx_bitmapcomposer.h
@@ -43,19 +43,19 @@
                pdfium::span<const uint32_t> src_palette) override;
 
   void ComposeScanline(int line,
-                       const uint8_t* scanline,
-                       const uint8_t* scan_extra_alpha) override;
+                       pdfium::span<const uint8_t> scanline,
+                       pdfium::span<const uint8_t> scan_extra_alpha) override;
 
  private:
   void DoCompose(uint8_t* dest_scan,
-                 const uint8_t* src_scan,
+                 pdfium::span<const uint8_t> src_scan,
                  int dest_width,
                  const uint8_t* clip_scan,
-                 const uint8_t* src_extra_alpha,
-                 uint8_t* dst_extra_alpha);
+                 pdfium::span<const uint8_t> src_extra_alpha,
+                 pdfium::span<uint8_t> dst_extra_alpha);
   void ComposeScanlineV(int line,
-                        const uint8_t* scanline,
-                        const uint8_t* scan_extra_alpha);
+                        pdfium::span<const uint8_t> scanline,
+                        pdfium::span<const uint8_t> scan_extra_alpha);
 
   RetainPtr<CFX_DIBitmap> m_pBitmap;
   UnownedPtr<const CFX_ClipRgn> m_pClipRgn;
diff --git a/core/fxge/dib/cfx_bitmapstorer.cpp b/core/fxge/dib/cfx_bitmapstorer.cpp
index 2de8ba8..c3443a2 100644
--- a/core/fxge/dib/cfx_bitmapstorer.cpp
+++ b/core/fxge/dib/cfx_bitmapstorer.cpp
@@ -10,6 +10,7 @@
 
 #include <utility>
 
+#include "core/fxcrt/span_util.h"
 #include "core/fxge/dib/cfx_dibitmap.h"
 
 CFX_BitmapStorer::CFX_BitmapStorer() = default;
@@ -24,17 +25,18 @@
   m_pBitmap = std::move(pBitmap);
 }
 
-void CFX_BitmapStorer::ComposeScanline(int line,
-                                       const uint8_t* scanline,
-                                       const uint8_t* scan_extra_alpha) {
-  uint8_t* dest_buf = m_pBitmap->GetWritableScanline(line).data();
-  if (dest_buf)
-    memcpy(dest_buf, scanline, m_pBitmap->GetPitch());
+void CFX_BitmapStorer::ComposeScanline(
+    int line,
+    pdfium::span<const uint8_t> scanline,
+    pdfium::span<const uint8_t> scan_extra_alpha) {
+  pdfium::span<uint8_t> dest_buf = m_pBitmap->GetWritableScanline(line);
+  if (!dest_buf.empty())
+    fxcrt::spancpy(dest_buf, scanline);
 
-  uint8_t* dest_alpha_buf =
-      m_pBitmap->GetWritableAlphaMaskScanline(line).data();
-  if (dest_alpha_buf)
-    memcpy(dest_alpha_buf, scan_extra_alpha, m_pBitmap->GetAlphaMaskPitch());
+  pdfium::span<uint8_t> dest_alpha_buf =
+      m_pBitmap->GetWritableAlphaMaskScanline(line);
+  if (!dest_alpha_buf.empty())
+    fxcrt::spancpy(dest_alpha_buf, scan_extra_alpha);
 }
 
 bool CFX_BitmapStorer::SetInfo(int width,
diff --git a/core/fxge/dib/cfx_bitmapstorer.h b/core/fxge/dib/cfx_bitmapstorer.h
index 3145875..7427691 100644
--- a/core/fxge/dib/cfx_bitmapstorer.h
+++ b/core/fxge/dib/cfx_bitmapstorer.h
@@ -9,6 +9,7 @@
 
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxge/dib/scanlinecomposer_iface.h"
+#include "third_party/base/span.h"
 
 class CFX_DIBitmap;
 
@@ -19,8 +20,8 @@
 
   // ScanlineComposerIface:
   void ComposeScanline(int line,
-                       const uint8_t* scanline,
-                       const uint8_t* scan_extra_alpha) override;
+                       pdfium::span<const uint8_t> scanline,
+                       pdfium::span<const uint8_t> scan_extra_alpha) override;
   bool SetInfo(int width,
                int height,
                FXDIB_Format src_format,
diff --git a/core/fxge/dib/cfx_dibitmap.cpp b/core/fxge/dib/cfx_dibitmap.cpp
index 7ce6a73..8ef8b82 100644
--- a/core/fxge/dib/cfx_dibitmap.cpp
+++ b/core/fxge/dib/cfx_dibitmap.cpp
@@ -767,18 +767,16 @@
   for (int row = 0; row < height; row++) {
     uint8_t* dest_scan =
         m_pBuffer.Get() + (dest_top + row) * m_Pitch + dest_left * dest_Bpp;
-    const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row)
-                                  .subspan(src_left * src_Bpp)
-                                  .data();
-    const uint8_t* src_scan_extra_alpha =
+    pdfium::span<const uint8_t> src_scan =
+        pSrcBitmap->GetScanline(src_top + row).subspan(src_left * src_Bpp);
+    pdfium::span<const uint8_t> src_scan_extra_alpha =
         pSrcAlphaMask
-            ? pSrcAlphaMask->GetScanline(src_top + row).subspan(src_left).data()
-            : nullptr;
-    uint8_t* dst_scan_extra_alpha =
+            ? pSrcAlphaMask->GetScanline(src_top + row).subspan(src_left)
+            : pdfium::span<const uint8_t>();
+    pdfium::span<uint8_t> dst_scan_extra_alpha =
         m_pAlphaMask ? m_pAlphaMask->GetWritableScanline(dest_top + row)
                            .subspan(dest_left)
-                           .data()
-                     : nullptr;
+                     : pdfium::span<uint8_t>();
     const uint8_t* clip_scan = nullptr;
     if (pClipMask) {
       clip_scan = pClipMask->m_pBuffer.Get() +
@@ -846,12 +844,11 @@
   for (int row = 0; row < height; row++) {
     uint8_t* dest_scan =
         m_pBuffer.Get() + (dest_top + row) * m_Pitch + dest_left * Bpp;
-    const uint8_t* src_scan = pMask->GetScanline(src_top + row).data();
-    uint8_t* dst_scan_extra_alpha =
+    pdfium::span<const uint8_t> src_scan = pMask->GetScanline(src_top + row);
+    pdfium::span<uint8_t> dst_scan_extra_alpha =
         m_pAlphaMask ? m_pAlphaMask->GetWritableScanline(dest_top + row)
                            .subspan(dest_left)
-                           .data()
-                     : nullptr;
+                     : pdfium::span<uint8_t>();
     const uint8_t* clip_scan = nullptr;
     if (pClipMask) {
       clip_scan = pClipMask->m_pBuffer.Get() +
@@ -862,8 +859,8 @@
       compositor.CompositeBitMaskLine(dest_scan, src_scan, src_left, width,
                                       clip_scan, dst_scan_extra_alpha);
     } else {
-      compositor.CompositeByteMaskLine(dest_scan, src_scan + src_left, width,
-                                       clip_scan, dst_scan_extra_alpha);
+      compositor.CompositeByteMaskLine(dest_scan, src_scan.subspan(src_left),
+                                       width, clip_scan, dst_scan_extra_alpha);
     }
   }
   return true;
diff --git a/core/fxge/dib/cfx_scanlinecompositor.cpp b/core/fxge/dib/cfx_scanlinecompositor.cpp
index c04c6dc..858176c 100644
--- a/core/fxge/dib/cfx_scanlinecompositor.cpp
+++ b/core/fxge/dib/cfx_scanlinecompositor.cpp
@@ -2773,11 +2773,11 @@
 
 void CFX_ScanlineCompositor::CompositeRgbBitmapLine(
     uint8_t* dest_scan,
-    const uint8_t* src_scan,
+    pdfium::span<const uint8_t> src_scan,
     int width,
     const uint8_t* clip_scan,
-    const uint8_t* src_extra_alpha,
-    uint8_t* dst_extra_alpha) {
+    pdfium::span<const uint8_t> src_extra_alpha,
+    pdfium::span<uint8_t> dst_extra_alpha) {
   int src_Bpp = GetCompsFromFormat(m_SrcFormat);
   int dest_Bpp = GetCompsFromFormat(m_DestFormat);
   if (m_bRgbByteOrder) {
@@ -2786,51 +2786,52 @@
       case 4:
       case 8:
       case 12:
-        CompositeRow_Argb2Argb_RgbByteOrder(dest_scan, src_scan, width,
+        CompositeRow_Argb2Argb_RgbByteOrder(dest_scan, src_scan.data(), width,
                                             m_BlendType, clip_scan);
         break;
       case 1:
         CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(
-            dest_scan, src_scan, width, m_BlendType, src_Bpp);
+            dest_scan, src_scan.data(), width, m_BlendType, src_Bpp);
         break;
       case 2:
       case 10:
-        CompositeRow_Argb2Rgb_Blend_RgbByteOrder(
-            dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan);
+        CompositeRow_Argb2Rgb_Blend_RgbByteOrder(dest_scan, src_scan.data(),
+                                                 width, m_BlendType, dest_Bpp,
+                                                 clip_scan);
         break;
       case 3:
         CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(
-            dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp);
+            dest_scan, src_scan.data(), width, m_BlendType, dest_Bpp, src_Bpp);
         break;
       case 5:
-        CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan,
-                                                          width, src_Bpp);
+        CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(
+            dest_scan, src_scan.data(), width, src_Bpp);
         break;
       case 6:
       case 14:
-        CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, width,
-                                                   dest_Bpp, clip_scan);
+        CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan.data(),
+                                                   width, dest_Bpp, clip_scan);
         break;
       case 7:
         CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(
-            dest_scan, src_scan, width, dest_Bpp, src_Bpp);
+            dest_scan, src_scan.data(), width, dest_Bpp, src_Bpp);
         break;
       case 9:
         CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(
-            dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan);
+            dest_scan, src_scan.data(), width, m_BlendType, src_Bpp, clip_scan);
         break;
       case 11:
-        CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(dest_scan, src_scan, width,
-                                                     m_BlendType, dest_Bpp,
-                                                     src_Bpp, clip_scan);
+        CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(
+            dest_scan, src_scan.data(), width, m_BlendType, dest_Bpp, src_Bpp,
+            clip_scan);
         break;
       case 13:
         CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(
-            dest_scan, src_scan, width, src_Bpp, clip_scan);
+            dest_scan, src_scan.data(), width, src_Bpp, clip_scan);
         break;
       case 15:
         CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(
-            dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan);
+            dest_scan, src_scan.data(), width, dest_Bpp, src_Bpp, clip_scan);
         break;
     }
     return;
@@ -2838,30 +2839,32 @@
   if (m_DestFormat == FXDIB_Format::k8bppMask) {
     if (GetIsAlphaFromFormat(m_SrcFormat)) {
       if (m_SrcFormat == FXDIB_Format::kArgb) {
-        CompositeRow_AlphaToMask(dest_scan, src_scan, width, clip_scan, 4);
+        CompositeRow_AlphaToMask(dest_scan, src_scan.data(), width, clip_scan,
+                                 4);
       } else {
-        CompositeRow_AlphaToMask(dest_scan, src_extra_alpha, width, clip_scan,
-                                 1);
+        CompositeRow_AlphaToMask(dest_scan, src_extra_alpha.data(), width,
+                                 clip_scan, 1);
       }
     } else {
-      CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan);
+      CompositeRow_Rgb2Mask(dest_scan, src_scan.data(), width, clip_scan);
     }
   } else if (GetBppFromFormat(m_DestFormat) == 8) {
     if (GetIsAlphaFromFormat(m_SrcFormat)) {
       if (GetIsAlphaFromFormat(m_DestFormat)) {
-        CompositeRow_Argb2Graya(dest_scan, src_scan, width, m_BlendType,
-                                clip_scan, src_extra_alpha, dst_extra_alpha);
+        CompositeRow_Argb2Graya(dest_scan, src_scan.data(), width, m_BlendType,
+                                clip_scan, src_extra_alpha.data(),
+                                dst_extra_alpha.data());
       } else {
-        CompositeRow_Argb2Gray(dest_scan, src_scan, width, m_BlendType,
-                               clip_scan, src_extra_alpha);
+        CompositeRow_Argb2Gray(dest_scan, src_scan.data(), width, m_BlendType,
+                               clip_scan, src_extra_alpha.data());
       }
     } else {
       if (GetIsAlphaFromFormat(m_DestFormat)) {
-        CompositeRow_Rgb2Graya(dest_scan, src_scan, src_Bpp, width, m_BlendType,
-                               clip_scan, dst_extra_alpha);
+        CompositeRow_Rgb2Graya(dest_scan, src_scan.data(), src_Bpp, width,
+                               m_BlendType, clip_scan, dst_extra_alpha.data());
       } else {
-        CompositeRow_Rgb2Gray(dest_scan, src_scan, src_Bpp, width, m_BlendType,
-                              clip_scan);
+        CompositeRow_Rgb2Gray(dest_scan, src_scan.data(), src_Bpp, width,
+                              m_BlendType, clip_scan);
       }
     }
   } else {
@@ -2870,51 +2873,57 @@
       case 4:
       case 8:
       case 4 + 8: {
-        CompositeRow_Argb2Argb(dest_scan, src_scan, width, m_BlendType,
-                               clip_scan, dst_extra_alpha, src_extra_alpha);
+        CompositeRow_Argb2Argb(dest_scan, src_scan.data(), width, m_BlendType,
+                               clip_scan, dst_extra_alpha.data(),
+                               src_extra_alpha.data());
       } break;
       case 1:
-        CompositeRow_Rgb2Argb_Blend_NoClip(
-            dest_scan, src_scan, width, m_BlendType, src_Bpp, dst_extra_alpha);
+        CompositeRow_Rgb2Argb_Blend_NoClip(dest_scan, src_scan.data(), width,
+                                           m_BlendType, src_Bpp,
+                                           dst_extra_alpha.data());
         break;
       case 1 + 8:
-        CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_scan, width,
+        CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_scan.data(), width,
                                          m_BlendType, src_Bpp, clip_scan,
-                                         dst_extra_alpha);
+                                         dst_extra_alpha.data());
         break;
       case 1 + 4:
-        CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_scan, width,
-                                             src_Bpp, dst_extra_alpha);
+        CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_scan.data(), width,
+                                             src_Bpp, dst_extra_alpha.data());
         break;
       case 1 + 4 + 8:
-        CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_scan, width, src_Bpp,
-                                           clip_scan, dst_extra_alpha);
+        CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_scan.data(), width,
+                                           src_Bpp, clip_scan,
+                                           dst_extra_alpha.data());
         break;
       case 2:
       case 2 + 8:
-        CompositeRow_Argb2Rgb_Blend(dest_scan, src_scan, width, m_BlendType,
-                                    dest_Bpp, clip_scan, src_extra_alpha);
+        CompositeRow_Argb2Rgb_Blend(dest_scan, src_scan.data(), width,
+                                    m_BlendType, dest_Bpp, clip_scan,
+                                    src_extra_alpha.data());
         break;
       case 2 + 4:
       case 2 + 4 + 8:
-        CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_scan, width, dest_Bpp,
-                                      clip_scan, src_extra_alpha);
+        CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_scan.data(), width,
+                                      dest_Bpp, clip_scan,
+                                      src_extra_alpha.data());
         break;
       case 1 + 2:
-        CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_scan, width,
+        CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_scan.data(), width,
                                           m_BlendType, dest_Bpp, src_Bpp);
         break;
       case 1 + 2 + 8:
-        CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_scan, width, m_BlendType,
-                                        dest_Bpp, src_Bpp, clip_scan);
+        CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_scan.data(), width,
+                                        m_BlendType, dest_Bpp, src_Bpp,
+                                        clip_scan);
         break;
       case 1 + 2 + 4:
-        CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_scan, width,
+        CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_scan.data(), width,
                                             dest_Bpp, src_Bpp);
         break;
       case 1 + 2 + 4 + 8:
-        CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_scan, width, dest_Bpp,
-                                          src_Bpp, clip_scan);
+        CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_scan.data(), width,
+                                          dest_Bpp, src_Bpp, clip_scan);
         break;
     }
   }
@@ -2922,12 +2931,12 @@
 
 void CFX_ScanlineCompositor::CompositePalBitmapLine(
     uint8_t* dest_scan,
-    const uint8_t* src_scan,
+    pdfium::span<const uint8_t> src_scan,
     int src_left,
     int width,
     const uint8_t* clip_scan,
-    const uint8_t* src_extra_alpha,
-    uint8_t* dst_extra_alpha) {
+    pdfium::span<const uint8_t> src_extra_alpha,
+    pdfium::span<uint8_t> dst_extra_alpha) {
   if (m_bRgbByteOrder) {
     if (m_SrcFormat == FXDIB_Format::k1bppRgb) {
       if (m_DestFormat == FXDIB_Format::k8bppRgb) {
@@ -2935,12 +2944,13 @@
       }
       if (m_DestFormat == FXDIB_Format::kArgb) {
         CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(
-            dest_scan, src_scan, src_left, width,
+            dest_scan, src_scan.data(), src_left, width,
             m_SrcPalette.Get32BitPalette(), clip_scan);
       } else {
         CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(
-            dest_scan, src_scan, src_left, m_SrcPalette.Get32BitPalette(),
-            width, GetCompsFromFormat(m_DestFormat), clip_scan);
+            dest_scan, src_scan.data(), src_left,
+            m_SrcPalette.Get32BitPalette(), width,
+            GetCompsFromFormat(m_DestFormat), clip_scan);
       }
     } else {
       if (m_DestFormat == FXDIB_Format::k8bppRgb) {
@@ -2948,151 +2958,161 @@
       }
       if (m_DestFormat == FXDIB_Format::kArgb) {
         CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(
-            dest_scan, src_scan, width, m_SrcPalette.Get32BitPalette().data(),
-            clip_scan);
+            dest_scan, src_scan.data(), width,
+            m_SrcPalette.Get32BitPalette().data(), clip_scan);
       } else {
         CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(
-            dest_scan, src_scan, m_SrcPalette.Get32BitPalette().data(), width,
-            GetCompsFromFormat(m_DestFormat), clip_scan);
+            dest_scan, src_scan.data(), m_SrcPalette.Get32BitPalette().data(),
+            width, GetCompsFromFormat(m_DestFormat), clip_scan);
       }
     }
     return;
   }
   if (m_DestFormat == FXDIB_Format::k8bppMask) {
-    CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan);
+    CompositeRow_Rgb2Mask(dest_scan, src_scan.data(), width, clip_scan);
     return;
   }
   if (GetBppFromFormat(m_DestFormat) == 8) {
     if (m_iTransparency & 8) {
       if (GetIsAlphaFromFormat(m_DestFormat)) {
-        CompositeRow_1bppPal2Graya(dest_scan, src_scan, src_left,
-                                   m_SrcPalette.Get8BitPalette(), width,
-                                   m_BlendType, clip_scan, dst_extra_alpha);
+        CompositeRow_1bppPal2Graya(
+            dest_scan, src_scan.data(), src_left, m_SrcPalette.Get8BitPalette(),
+            width, m_BlendType, clip_scan, dst_extra_alpha.data());
       } else {
-        CompositeRow_1bppPal2Gray(dest_scan, src_scan, src_left,
+        CompositeRow_1bppPal2Gray(dest_scan, src_scan.data(), src_left,
                                   m_SrcPalette.Get8BitPalette(), width,
                                   m_BlendType, clip_scan);
       }
     } else {
       if (GetIsAlphaFromFormat(m_DestFormat)) {
         CompositeRow_8bppPal2Graya(
-            dest_scan, src_scan, m_SrcPalette.Get8BitPalette().data(), width,
-            m_BlendType, clip_scan, dst_extra_alpha, src_extra_alpha);
+            dest_scan, src_scan.data(), m_SrcPalette.Get8BitPalette().data(),
+            width, m_BlendType, clip_scan, dst_extra_alpha.data(),
+            src_extra_alpha.data());
       } else {
-        CompositeRow_8bppPal2Gray(dest_scan, src_scan,
-                                  m_SrcPalette.Get8BitPalette().data(), width,
-                                  m_BlendType, clip_scan, src_extra_alpha);
+        CompositeRow_8bppPal2Gray(
+            dest_scan, src_scan.data(), m_SrcPalette.Get8BitPalette().data(),
+            width, m_BlendType, clip_scan, src_extra_alpha.data());
       }
     }
   } else {
     switch (m_iTransparency) {
       case 1 + 2:
-        CompositeRow_8bppRgb2Argb_NoBlend(dest_scan, src_scan, width,
+        CompositeRow_8bppRgb2Argb_NoBlend(dest_scan, src_scan.data(), width,
                                           m_SrcPalette.Get32BitPalette().data(),
-                                          clip_scan, src_extra_alpha);
+                                          clip_scan, src_extra_alpha.data());
         break;
       case 1 + 2 + 8:
-        CompositeRow_1bppRgb2Argb_NoBlend(dest_scan, src_scan, src_left, width,
-                                          m_SrcPalette.Get32BitPalette(),
+        CompositeRow_1bppRgb2Argb_NoBlend(dest_scan, src_scan.data(), src_left,
+                                          width, m_SrcPalette.Get32BitPalette(),
                                           clip_scan);
         break;
       case 0:
         CompositeRow_8bppRgb2Rgb_NoBlend(
-            dest_scan, src_scan, m_SrcPalette.Get32BitPalette().data(), width,
-            GetCompsFromFormat(m_DestFormat), clip_scan, src_extra_alpha);
+            dest_scan, src_scan.data(), m_SrcPalette.Get32BitPalette().data(),
+            width, GetCompsFromFormat(m_DestFormat), clip_scan,
+            src_extra_alpha.data());
         break;
       case 0 + 8:
-        CompositeRow_1bppRgb2Rgb_NoBlend(
-            dest_scan, src_scan, src_left, m_SrcPalette.Get32BitPalette(),
-            width, GetCompsFromFormat(m_DestFormat), clip_scan);
+        CompositeRow_1bppRgb2Rgb_NoBlend(dest_scan, src_scan.data(), src_left,
+                                         m_SrcPalette.Get32BitPalette(), width,
+                                         GetCompsFromFormat(m_DestFormat),
+                                         clip_scan);
         break;
       case 0 + 2:
         CompositeRow_8bppRgb2Rgb_NoBlend(
-            dest_scan, src_scan, m_SrcPalette.Get32BitPalette().data(), width,
-            GetCompsFromFormat(m_DestFormat), clip_scan, src_extra_alpha);
+            dest_scan, src_scan.data(), m_SrcPalette.Get32BitPalette().data(),
+            width, GetCompsFromFormat(m_DestFormat), clip_scan,
+            src_extra_alpha.data());
         break;
       case 0 + 2 + 8:
-        CompositeRow_1bppRgb2Rgba_NoBlend(dest_scan, src_scan, src_left, width,
-                                          m_SrcPalette.Get32BitPalette(),
-                                          clip_scan, dst_extra_alpha);
+        CompositeRow_1bppRgb2Rgba_NoBlend(dest_scan, src_scan.data(), src_left,
+                                          width, m_SrcPalette.Get32BitPalette(),
+                                          clip_scan, dst_extra_alpha.data());
         break;
     }
   }
 }
 
-void CFX_ScanlineCompositor::CompositeByteMaskLine(uint8_t* dest_scan,
-                                                   const uint8_t* src_scan,
-                                                   int width,
-                                                   const uint8_t* clip_scan,
-                                                   uint8_t* dst_extra_alpha) {
+void CFX_ScanlineCompositor::CompositeByteMaskLine(
+    uint8_t* dest_scan,
+    pdfium::span<const uint8_t> src_scan,
+    int width,
+    const uint8_t* clip_scan,
+    pdfium::span<uint8_t> dst_extra_alpha) {
   if (m_DestFormat == FXDIB_Format::k8bppMask) {
-    CompositeRow_ByteMask2Mask(dest_scan, src_scan, m_MaskAlpha, width,
+    CompositeRow_ByteMask2Mask(dest_scan, src_scan.data(), m_MaskAlpha, width,
                                clip_scan);
   } else if (GetBppFromFormat(m_DestFormat) == 8) {
     if (GetIsAlphaFromFormat(m_DestFormat)) {
-      CompositeRow_ByteMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
-                                  width, clip_scan, dst_extra_alpha);
+      CompositeRow_ByteMask2Graya(dest_scan, src_scan.data(), m_MaskAlpha,
+                                  m_MaskRed, width, clip_scan,
+                                  dst_extra_alpha.data());
     } else {
-      CompositeRow_ByteMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
-                                 width, clip_scan);
+      CompositeRow_ByteMask2Gray(dest_scan, src_scan.data(), m_MaskAlpha,
+                                 m_MaskRed, width, clip_scan);
     }
   } else if (m_bRgbByteOrder) {
     if (m_DestFormat == FXDIB_Format::kArgb) {
       CompositeRow_ByteMask2Argb_RgbByteOrder(
-          dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
-          width, m_BlendType, clip_scan);
+          dest_scan, src_scan.data(), m_MaskAlpha, m_MaskRed, m_MaskGreen,
+          m_MaskBlue, width, m_BlendType, clip_scan);
     } else {
       CompositeRow_ByteMask2Rgb_RgbByteOrder(
-          dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
-          width, m_BlendType, GetCompsFromFormat(m_DestFormat), clip_scan);
+          dest_scan, src_scan.data(), m_MaskAlpha, m_MaskRed, m_MaskGreen,
+          m_MaskBlue, width, m_BlendType, GetCompsFromFormat(m_DestFormat),
+          clip_scan);
     }
   } else if (m_DestFormat == FXDIB_Format::kArgb) {
-    CompositeRow_ByteMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
-                               m_MaskGreen, m_MaskBlue, width, m_BlendType,
-                               clip_scan);
+    CompositeRow_ByteMask2Argb(dest_scan, src_scan.data(), m_MaskAlpha,
+                               m_MaskRed, m_MaskGreen, m_MaskBlue, width,
+                               m_BlendType, clip_scan);
   } else if (m_DestFormat == FXDIB_Format::kRgb ||
              m_DestFormat == FXDIB_Format::kRgb32) {
-    CompositeRow_ByteMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
-                              m_MaskGreen, m_MaskBlue, width, m_BlendType,
-                              GetCompsFromFormat(m_DestFormat), clip_scan);
+    CompositeRow_ByteMask2Rgb(dest_scan, src_scan.data(), m_MaskAlpha,
+                              m_MaskRed, m_MaskGreen, m_MaskBlue, width,
+                              m_BlendType, GetCompsFromFormat(m_DestFormat),
+                              clip_scan);
   }
 }
 
-void CFX_ScanlineCompositor::CompositeBitMaskLine(uint8_t* dest_scan,
-                                                  const uint8_t* src_scan,
-                                                  int src_left,
-                                                  int width,
-                                                  const uint8_t* clip_scan,
-                                                  uint8_t* dst_extra_alpha) {
+void CFX_ScanlineCompositor::CompositeBitMaskLine(
+    uint8_t* dest_scan,
+    pdfium::span<const uint8_t> src_scan,
+    int src_left,
+    int width,
+    const uint8_t* clip_scan,
+    pdfium::span<uint8_t> dst_extra_alpha) {
   if (m_DestFormat == FXDIB_Format::k8bppMask) {
-    CompositeRow_BitMask2Mask(dest_scan, src_scan, m_MaskAlpha, src_left, width,
-                              clip_scan);
+    CompositeRow_BitMask2Mask(dest_scan, src_scan.data(), m_MaskAlpha, src_left,
+                              width, clip_scan);
   } else if (GetBppFromFormat(m_DestFormat) == 8) {
     if (GetIsAlphaFromFormat(m_DestFormat)) {
-      CompositeRow_BitMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
-                                 src_left, width, clip_scan, dst_extra_alpha);
+      CompositeRow_BitMask2Graya(dest_scan, src_scan.data(), m_MaskAlpha,
+                                 m_MaskRed, src_left, width, clip_scan,
+                                 dst_extra_alpha.data());
     } else {
-      CompositeRow_BitMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
-                                src_left, width, clip_scan);
+      CompositeRow_BitMask2Gray(dest_scan, src_scan.data(), m_MaskAlpha,
+                                m_MaskRed, src_left, width, clip_scan);
     }
   } else if (m_bRgbByteOrder) {
     if (m_DestFormat == FXDIB_Format::kArgb) {
       CompositeRow_BitMask2Argb_RgbByteOrder(
-          dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
-          src_left, width, m_BlendType, clip_scan);
+          dest_scan, src_scan.data(), m_MaskAlpha, m_MaskRed, m_MaskGreen,
+          m_MaskBlue, src_left, width, m_BlendType, clip_scan);
     } else {
       CompositeRow_BitMask2Rgb_RgbByteOrder(
-          dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
-          src_left, width, m_BlendType, GetCompsFromFormat(m_DestFormat),
-          clip_scan);
+          dest_scan, src_scan.data(), m_MaskAlpha, m_MaskRed, m_MaskGreen,
+          m_MaskBlue, src_left, width, m_BlendType,
+          GetCompsFromFormat(m_DestFormat), clip_scan);
     }
   } else if (m_DestFormat == FXDIB_Format::kArgb) {
-    CompositeRow_BitMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
-                              m_MaskGreen, m_MaskBlue, src_left, width,
-                              m_BlendType, clip_scan);
+    CompositeRow_BitMask2Argb(dest_scan, src_scan.data(), m_MaskAlpha,
+                              m_MaskRed, m_MaskGreen, m_MaskBlue, src_left,
+                              width, m_BlendType, clip_scan);
   } else if (m_DestFormat == FXDIB_Format::kRgb ||
              m_DestFormat == FXDIB_Format::kRgb32) {
-    CompositeRow_BitMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
+    CompositeRow_BitMask2Rgb(dest_scan, src_scan.data(), m_MaskAlpha, m_MaskRed,
                              m_MaskGreen, m_MaskBlue, src_left, width,
                              m_BlendType, GetCompsFromFormat(m_DestFormat),
                              clip_scan);
diff --git a/core/fxge/dib/cfx_scanlinecompositor.h b/core/fxge/dib/cfx_scanlinecompositor.h
index 2cb9604..0017f1c 100644
--- a/core/fxge/dib/cfx_scanlinecompositor.h
+++ b/core/fxge/dib/cfx_scanlinecompositor.h
@@ -28,32 +28,32 @@
             bool bRgbByteOrder);
 
   void CompositeRgbBitmapLine(uint8_t* dest_scan,
-                              const uint8_t* src_scan,
+                              pdfium::span<const uint8_t> src_scan,
                               int width,
                               const uint8_t* clip_scan,
-                              const uint8_t* src_extra_alpha,
-                              uint8_t* dst_extra_alpha);
+                              pdfium::span<const uint8_t> src_extra_alpha,
+                              pdfium::span<uint8_t> dst_extra_alpha);
 
   void CompositePalBitmapLine(uint8_t* dest_scan,
-                              const uint8_t* src_scan,
+                              pdfium::span<const uint8_t> src_scan,
                               int src_left,
                               int width,
                               const uint8_t* clip_scan,
-                              const uint8_t* src_extra_alpha,
-                              uint8_t* dst_extra_alpha);
+                              pdfium::span<const uint8_t> src_extra_alpha,
+                              pdfium::span<uint8_t> dst_extra_alpha);
 
   void CompositeByteMaskLine(uint8_t* dest_scan,
-                             const uint8_t* src_scan,
+                             pdfium::span<const uint8_t> src_scan,
                              int width,
                              const uint8_t* clip_scan,
-                             uint8_t* dst_extra_alpha);
+                             pdfium::span<uint8_t> dst_extra_alpha);
 
   void CompositeBitMaskLine(uint8_t* dest_scan,
-                            const uint8_t* src_scan,
+                            pdfium::span<const uint8_t> src_scan,
                             int src_left,
                             int width,
                             const uint8_t* clip_scan,
-                            uint8_t* dst_extra_alpha);
+                            pdfium::span<uint8_t> dst_extra_alpha);
 
  private:
   class Palette {
diff --git a/core/fxge/dib/cstretchengine.cpp b/core/fxge/dib/cstretchengine.cpp
index db4830c..3c073bd 100644
--- a/core/fxge/dib/cstretchengine.cpp
+++ b/core/fxge/dib/cstretchengine.cpp
@@ -588,7 +588,7 @@
         break;
       }
     }
-    m_pDestBitmap->ComposeScanline(row - m_DestClip.top, m_DestScanline.data(),
-                                   m_DestMaskScanline.data());
+    m_pDestBitmap->ComposeScanline(row - m_DestClip.top, m_DestScanline,
+                                   m_DestMaskScanline);
   }
 }
diff --git a/core/fxge/dib/scanlinecomposer_iface.h b/core/fxge/dib/scanlinecomposer_iface.h
index 6275fe5..8325c58 100644
--- a/core/fxge/dib/scanlinecomposer_iface.h
+++ b/core/fxge/dib/scanlinecomposer_iface.h
@@ -14,9 +14,10 @@
  public:
   virtual ~ScanlineComposerIface() = default;
 
-  virtual void ComposeScanline(int line,
-                               const uint8_t* scanline,
-                               const uint8_t* scan_extra_alpha) = 0;
+  virtual void ComposeScanline(
+      int line,
+      pdfium::span<const uint8_t> scanline,
+      pdfium::span<const uint8_t> scan_extra_alpha) = 0;
 
   virtual bool SetInfo(int width,
                        int height,