File: box_painter.cc

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (114 lines) | stat: -rw-r--r-- 4,724 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/core/paint/box_painter.h"

#include <optional>

#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/paint/object_painter.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/paint/scrollable_area_painter.h"
#include "ui/gfx/geometry/rect_conversions.h"

namespace blink {

void BoxPainter::RecordRegionCaptureData(
    const PaintInfo& paint_info,
    const PhysicalRect& paint_rect,
    const DisplayItemClient& background_client) {
  const Element* element = DynamicTo<Element>(layout_box_.GetNode());
  if (element) {
    const RegionCaptureCropId* crop_id = element->GetRegionCaptureCropId();
    if (crop_id) {
      paint_info.context.GetPaintController().RecordRegionCaptureData(
          background_client, *crop_id, ToPixelSnappedRect(paint_rect));
    }
  }
}

void BoxPainter::RecordScrollHitTestData(
    const PaintInfo& paint_info,
    const DisplayItemClient& background_client,
    const FragmentData* fragment) {
  if (!fragment) {
    return;
  }

  // Scroll hit test data are only needed for compositing. This flag is used for
  // printing and drag images which do not need hit testing.
  if (paint_info.ShouldOmitCompositingInfo())
    return;

  // If an object is not visible, it does not scroll.
  const ComputedStyle& style = layout_box_.StyleRef();
  if (style.Visibility() != EVisibility::kVisible) {
    return;
  }

  if (!layout_box_.GetScrollableArea())
    return;

  // If there is an associated scroll node, emit scroll hit test data.
  const auto* properties = fragment->PaintProperties();
  auto hit_test_opaqueness = ObjectPainter(layout_box_).GetHitTestOpaqueness();
  if (properties && properties->Scroll()) {
    DCHECK(properties->ScrollTranslation());
    // We record scroll hit test data in the local border box properties
    // instead of the contents properties so that the scroll hit test is not
    // clipped or scrolled.
    auto& paint_controller = paint_info.context.GetPaintController();
#if DCHECK_IS_ON()
    // TODO(crbug.com/1256990): This should be
    // DCHECK_EQ(fragment->LocalBorderBoxProperties(),
    //           paint_controller.CurrentPaintChunkProperties());
    // but we have problems about the effect node with CompositingReason::
    // kTransform3DSceneLeaf on non-stacking-context elements.
    auto border_box_properties = fragment->LocalBorderBoxProperties();
    auto current_properties = paint_controller.CurrentPaintChunkProperties();
    DCHECK_EQ(&border_box_properties.Transform(),
              &current_properties.Transform())
        << border_box_properties.Transform().ToTreeString().Utf8()
        << current_properties.Transform().ToTreeString().Utf8();
    DCHECK_EQ(&border_box_properties.Clip(), &current_properties.Clip())
        << border_box_properties.Clip().ToTreeString().Utf8()
        << current_properties.Clip().ToTreeString().Utf8();
#endif
    gfx::Rect cull_rect = fragment->GetContentsCullRect().Rect();
    if (cull_rect.Contains(properties->Scroll()->ContentsRect())) {
      cull_rect = CullRect::Infinite().Rect();
    } else {
      // Don't pass the cull rect if it doesn't cover the container rect
      // because cc can't distinguish the case from paint checkerboarding.
      gfx::Rect cull_rect_in_container_space = gfx::ToEnclosingRect(
          gfx::RectF(cull_rect) +
          properties->ScrollTranslation()->Get2dTranslation());
      if (!cull_rect_in_container_space.Contains(
              properties->Scroll()->ContainerRect())) {
        cull_rect = CullRect::Infinite().Rect();
      }
    }
    paint_controller.RecordScrollHitTestData(
        background_client, DisplayItem::kScrollHitTest,
        properties->ScrollTranslation(), VisualRect(fragment->PaintOffset()),
        hit_test_opaqueness, cull_rect);
  }

  if (hit_test_opaqueness != cc::HitTestOpaqueness::kTransparent) {
    ScrollableAreaPainter(*layout_box_.GetScrollableArea())
        .RecordResizerScrollHitTestData(paint_info.context,
                                        fragment->PaintOffset());
  }
}

gfx::Rect BoxPainter::VisualRect(const PhysicalOffset& paint_offset) {
  DCHECK(!layout_box_.VisualRectRespectsVisibility() ||
         layout_box_.StyleRef().Visibility() == EVisibility::kVisible);
  PhysicalRect rect = layout_box_.SelfVisualOverflowRect();
  rect.Move(paint_offset);
  return ToEnclosingRect(rect);
}

}  // namespace blink