Fix overlapping glyphs rendering for aliased text

Bug: pdfium:1919

Change-Id: I241ccb6ab67ec7b5eb36afb0f090439848cc21d9
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/99531
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxge/cfx_renderdevice.cpp b/core/fxge/cfx_renderdevice.cpp
index 8b3deec..d96021c 100644
--- a/core/fxge/cfx_renderdevice.cpp
+++ b/core/fxge/cfx_renderdevice.cpp
@@ -1148,9 +1148,9 @@
         continue;
 
       const RetainPtr<CFX_DIBitmap>& pGlyph = glyph.m_pGlyph->GetBitmap();
-      bitmap->TransferBitmap(point.value().x, point.value().y,
-                             pGlyph->GetWidth(), pGlyph->GetHeight(), pGlyph, 0,
-                             0);
+      bitmap->CompositeOneBPPMask(point.value().x, point.value().y,
+                                  pGlyph->GetWidth(), pGlyph->GetHeight(),
+                                  pGlyph, 0, 0);
     }
     return SetBitMask(bitmap, bmp_rect.left, bmp_rect.top, fill_color);
   }
diff --git a/core/fxge/dib/cfx_dibitmap.cpp b/core/fxge/dib/cfx_dibitmap.cpp
index edd2d01..9dc9d5d 100644
--- a/core/fxge/dib/cfx_dibitmap.cpp
+++ b/core/fxge/dib/cfx_dibitmap.cpp
@@ -823,6 +823,36 @@
   return true;
 }
 
+void CFX_DIBitmap::CompositeOneBPPMask(int dest_left,
+                                       int dest_top,
+                                       int width,
+                                       int height,
+                                       const RetainPtr<CFX_DIBBase>& pSrcBitmap,
+                                       int src_left,
+                                       int src_top) {
+  if (GetBPP() != 1) {
+    return;
+  }
+
+  if (!GetOverlapRect(dest_left, dest_top, width, height,
+                      pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(), src_left,
+                      src_top, nullptr)) {
+    return;
+  }
+
+  for (int row = 0; row < height; ++row) {
+    uint8_t* dest_scan = m_pBuffer.Get() + (dest_top + row) * m_Pitch;
+    const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row).data();
+    for (int col = 0; col < width; ++col) {
+      int src_idx = src_left + col;
+      int dest_idx = dest_left + col;
+      if (src_scan[src_idx / 8] & (1 << (7 - src_idx % 8))) {
+        dest_scan[dest_idx / 8] |= 1 << (7 - dest_idx % 8);
+      }
+    }
+  }
+}
+
 bool CFX_DIBitmap::CompositeRect(int left,
                                  int top,
                                  int width,
diff --git a/core/fxge/dib/cfx_dibitmap.h b/core/fxge/dib/cfx_dibitmap.h
index 3354684..29ebbd9 100644
--- a/core/fxge/dib/cfx_dibitmap.h
+++ b/core/fxge/dib/cfx_dibitmap.h
@@ -86,6 +86,14 @@
                      const CFX_ClipRgn* pClipRgn,
                      bool bRgbByteOrder);
 
+  void CompositeOneBPPMask(int dest_left,
+                           int dest_top,
+                           int width,
+                           int height,
+                           const RetainPtr<CFX_DIBBase>& pSrcBitmap,
+                           int src_left,
+                           int src_top);
+
   bool CompositeRect(int dest_left,
                      int dest_top,
                      int width,
diff --git a/fpdfsdk/fpdf_view_embeddertest.cpp b/fpdfsdk/fpdf_view_embeddertest.cpp
index 788cecb..c8bd7f0 100644
--- a/fpdfsdk/fpdf_view_embeddertest.cpp
+++ b/fpdfsdk/fpdf_view_embeddertest.cpp
@@ -2032,3 +2032,13 @@
   UnloadPage(page);
 }
 #endif  // _SKIA_SUPPORT_
+
+TEST_F(FPDFViewEmbedderTest, NoSmoothTextItalicOverlappingGlyphs) {
+  ASSERT_TRUE(OpenDocument("bug_1919.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  ASSERT_TRUE(page);
+
+  TestRenderPageBitmapWithFlags(page, FPDF_RENDER_NO_SMOOTHTEXT,
+                                "4ef1f65ab1ac76acb97a3540dcb10b4e");
+  UnloadPage(page);
+}
diff --git a/testing/resources/bug_1919.pdf b/testing/resources/bug_1919.pdf
new file mode 100644
index 0000000..8331e0d
--- /dev/null
+++ b/testing/resources/bug_1919.pdf
Binary files differ