[tor-commits] [tor-browser] 34/73: Bug 1777209 - Use DrawSurface rather than FillRect to paint <canvas>, and don't use EXTEND_PAD when writing to PDF. r=jrmuizel, a=RyanVM

gitolite role git at cupani.torproject.org
Wed Sep 21 20:17:27 UTC 2022


This is an automated email from the git hooks/post-receive script.

richard pushed a commit to branch geckoview-102.3.0esr-12.0-1
in repository tor-browser.

commit 344e8654b59ec8b052cb6a2ab1bf28d37d81d559
Author: Jonathan Kew <jkew at mozilla.com>
AuthorDate: Tue Jul 5 07:55:56 2022 +0000

    Bug 1777209 - Use DrawSurface rather than FillRect to paint <canvas>, and don't use EXTEND_PAD when writing to PDF. r=jrmuizel, a=RyanVM
    
    Differential Revision: https://phabricator.services.mozilla.com/D150601
---
 gfx/2d/DrawTargetCairo.cpp           | 12 ++++++++-
 layout/generic/nsHTMLCanvasFrame.cpp | 50 ++++++++++++++++++++----------------
 layout/reftests/bugs/reftest.list    |  2 +-
 3 files changed, 40 insertions(+), 24 deletions(-)

diff --git a/gfx/2d/DrawTargetCairo.cpp b/gfx/2d/DrawTargetCairo.cpp
index e0e7607936de7..1877ddc2ba226 100644
--- a/gfx/2d/DrawTargetCairo.cpp
+++ b/gfx/2d/DrawTargetCairo.cpp
@@ -884,7 +884,17 @@ void DrawTargetCairo::DrawSurface(SourceSurface* aSurface, const Rect& aDest,
   cairo_pattern_set_matrix(pat, &src_mat);
   cairo_pattern_set_filter(
       pat, GfxSamplingFilterToCairoFilter(aSurfOptions.mSamplingFilter));
-  cairo_pattern_set_extend(pat, CAIRO_EXTEND_PAD);
+  // For PDF output, we avoid using EXTEND_PAD here because floating-point
+  // error accumulation may lead cairo_pdf_surface to conclude that padding
+  // is needed due to an apparent one- or two-pixel mismatch between source
+  // pattern and destination rect sizes when we're rendering a pdf.js page,
+  // and this forces undesirable fallback to the rasterization codepath
+  // instead of simply replaying the recording.
+  // (See bug 1777209.)
+  cairo_pattern_set_extend(
+      pat, cairo_surface_get_type(mSurface) == CAIRO_SURFACE_TYPE_PDF
+               ? CAIRO_EXTEND_NONE
+               : CAIRO_EXTEND_PAD);
 
   cairo_set_antialias(mContext,
                       GfxAntialiasToCairoAntialias(aOptions.mAntialiasMode));
diff --git a/layout/generic/nsHTMLCanvasFrame.cpp b/layout/generic/nsHTMLCanvasFrame.cpp
index bfb9f1f71c034..09d6358e8e0cd 100644
--- a/layout/generic/nsHTMLCanvasFrame.cpp
+++ b/layout/generic/nsHTMLCanvasFrame.cpp
@@ -298,19 +298,20 @@ class nsDisplayCanvas final : public nsPaintedDisplayItem {
     nsRect dest = nsLayoutUtils::ComputeObjectDestRect(
         area, intrinsicSize, intrinsicRatio, f->StylePosition());
 
-    gfxRect destGFXRect = presContext->AppUnitsToGfxUnits(dest);
-
-    // Transform the canvas into the right place
-    gfxPoint p = destGFXRect.TopLeft();
-    Matrix transform = Matrix::Translation(p.x, p.y);
-    transform.PreScale(destGFXRect.Width() / canvasSizeInPx.width,
-                       destGFXRect.Height() / canvasSizeInPx.height);
     gfxContextMatrixAutoSaveRestore saveMatrix(aCtx);
 
-    aCtx->SetMatrix(
-        gfxUtils::SnapTransformTranslation(aCtx->CurrentMatrix(), nullptr));
-
     if (RefPtr<layers::Image> image = canvas->GetAsImage()) {
+      gfxRect destGFXRect = presContext->AppUnitsToGfxUnits(dest);
+
+      // Transform the canvas into the right place
+      gfxPoint p = destGFXRect.TopLeft();
+      Matrix transform = Matrix::Translation(p.x, p.y);
+      transform.PreScale(destGFXRect.Width() / canvasSizeInPx.width,
+                         destGFXRect.Height() / canvasSizeInPx.height);
+
+      aCtx->SetMatrix(
+          gfxUtils::SnapTransformTranslation(aCtx->CurrentMatrix(), nullptr));
+
       RefPtr<gfx::SourceSurface> surface = image->GetAsSourceSurface();
       if (!surface || !surface->IsValid()) {
         return;
@@ -338,23 +339,28 @@ class nsDisplayCanvas final : public nsPaintedDisplayItem {
     }
     renderer->FirePreTransactionCallback();
     const auto snapshot = renderer->BorrowSnapshot();
-    if (!snapshot) return;
+    if (!snapshot) {
+      return;
+    }
     const auto& surface = snapshot->mSurf;
-
-    transform = gfxUtils::SnapTransform(
-        transform, gfxRect(0, 0, canvasSizeInPx.width, canvasSizeInPx.height),
-        nullptr);
+    DrawTarget& dt = *aCtx->GetDrawTarget();
+    gfx::Rect destRect =
+        NSRectToSnappedRect(dest, presContext->AppUnitsPerDevPixel(), dt);
 
     if (!renderer->YIsDown()) {
-      // y-flip
-      transform.PreTranslate(0.0f, canvasSizeInPx.height).PreScale(1.0f, -1.0f);
+      // Calculate y-coord that is as far below the bottom of destGFXRect as
+      // the origin was above the top, then reflect about that.
+      float y = destRect.Y() + destRect.YMost();
+      Matrix transform = Matrix::Translation(0.0f, y).PreScale(1.0f, -1.0f);
+      aCtx->Multiply(transform);
     }
-    aCtx->Multiply(transform);
 
-    aCtx->GetDrawTarget()->FillRect(
-        Rect(0, 0, canvasSizeInPx.width, canvasSizeInPx.height),
-        SurfacePattern(surface, ExtendMode::CLAMP, Matrix(),
-                       nsLayoutUtils::GetSamplingFilterForFrame(f)));
+    const auto& srcRect = surface->GetRect();
+    dt.DrawSurface(
+        surface, destRect,
+        Rect(float(srcRect.X()), float(srcRect.Y()), float(srcRect.Width()),
+             float(srcRect.Height())),
+        DrawSurfaceOptions(nsLayoutUtils::GetSamplingFilterForFrame(f)));
 
     renderer->FireDidTransactionCallback();
     renderer->ResetDirty();
diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list
index 557cefccf4f2b..03dcde776fc1b 100644
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1567,7 +1567,7 @@ random-if(winWidget) fuzzy(0-1,0-480) needs-focus == 598726-1.html 598726-1-ref.
 # the idealized rendering. As such we assume we fail the old test, and pass the
 # new test. See bug 1580534 for more details.
 fuzzy-if(Android,0-8,0-20) fails-if(!useDrawSnapshot) == 602200-3.html 602200-3-ref.html
-fuzzy-if(useDrawSnapshot,255-255,44-44) == 1580534.html 1580534-ref.html
+fuzzy-if(useDrawSnapshot,255-255,34-34) == 1580534.html 1580534-ref.html
 == 602200-4.html 602200-4-ref.html
 == 603423-1.html 603423-1-ref.html
 == 604737.html 604737-ref.html

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the tor-commits mailing list