1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "third_party/blink/renderer/core/paint/html_canvas_painter.h"
6 
7 #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
8 #include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
9 #include "third_party/blink/renderer/core/layout/layout_html_canvas.h"
10 #include "third_party/blink/renderer/core/paint/paint_info.h"
11 #include "third_party/blink/renderer/platform/geometry/layout_point.h"
12 #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
13 #include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h"
14 #include "third_party/blink/renderer/platform/graphics/scoped_interpolation_quality.h"
15 
16 namespace blink {
17 
18 namespace {
19 
InterpolationQualityForCanvas(const ComputedStyle & style)20 InterpolationQuality InterpolationQualityForCanvas(const ComputedStyle& style) {
21   if (style.ImageRendering() == EImageRendering::kWebkitOptimizeContrast)
22     return kInterpolationLow;
23 
24   if (style.ImageRendering() == EImageRendering::kPixelated)
25     return kInterpolationNone;
26 
27   return CanvasDefaultInterpolationQuality;
28 }
29 
30 }  // namespace
31 
PaintReplaced(const PaintInfo & paint_info,const PhysicalOffset & paint_offset)32 void HTMLCanvasPainter::PaintReplaced(const PaintInfo& paint_info,
33                                       const PhysicalOffset& paint_offset) {
34   GraphicsContext& context = paint_info.context;
35 
36   PhysicalRect paint_rect = layout_html_canvas_.ReplacedContentRect();
37   paint_rect.Move(paint_offset);
38 
39   auto* canvas = To<HTMLCanvasElement>(layout_html_canvas_.GetNode());
40   if (canvas->IsOffscreenCanvasRegistered())
41     canvas->UpdateOffscreenCanvasFilterQuality(canvas->FilterQuality());
42 
43   if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
44     if (auto* layer = canvas->ContentsCcLayer()) {
45       IntRect pixel_snapped_rect = PixelSnappedIntRect(paint_rect);
46       layer->SetBounds(gfx::Size(pixel_snapped_rect.Size()));
47       layer->SetIsDrawable(true);
48       layer->SetHitTestable(true);
49       RecordForeignLayer(context, layout_html_canvas_,
50                          DisplayItem::kForeignLayerCanvas, layer,
51                          FloatPoint(pixel_snapped_rect.Location()));
52       return;
53     }
54   }
55 
56   if (DrawingRecorder::UseCachedDrawingIfPossible(context, layout_html_canvas_,
57                                                   paint_info.phase))
58     return;
59 
60   DrawingRecorder recorder(context, layout_html_canvas_, paint_info.phase);
61   ScopedInterpolationQuality interpolation_quality_scope(
62       context, InterpolationQualityForCanvas(layout_html_canvas_.StyleRef()));
63   canvas->Paint(
64       context, paint_rect,
65       paint_info.GetGlobalPaintFlags() == kGlobalPaintFlattenCompositingLayers);
66 }
67 
68 }  // namespace blink
69