File: fieldset_painter.cc

package info (click to toggle)
chromium 90.0.4430.212-1~deb10u1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 3,450,632 kB
  • sloc: cpp: 19,832,434; javascript: 2,948,838; ansic: 2,312,399; python: 1,464,622; xml: 584,121; java: 514,189; asm: 470,557; objc: 83,463; perl: 77,861; sh: 77,030; cs: 70,789; fortran: 24,137; tcl: 18,916; php: 18,872; makefile: 16,848; ruby: 16,721; pascal: 13,150; sql: 10,199; yacc: 7,507; lex: 1,313; lisp: 840; awk: 329; jsp: 39; sed: 19
file content (126 lines) | stat: -rw-r--r-- 5,517 bytes parent folder | download | duplicates (6)
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
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright 2014 The Chromium Authors. All rights reserved.
// 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/fieldset_painter.h"

#include "third_party/blink/renderer/core/layout/layout_fieldset.h"
#include "third_party/blink/renderer/core/paint/background_image_geometry.h"
#include "third_party/blink/renderer/core/paint/box_decoration_data.h"
#include "third_party/blink/renderer/core/paint/box_model_object_painter.h"
#include "third_party/blink/renderer/core/paint/box_painter.h"
#include "third_party/blink/renderer/core/paint/fieldset_paint_info.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"

namespace blink {

namespace {

FieldsetPaintInfo CreateFieldsetPaintInfo(const LayoutBox& fieldset,
                                          const LayoutBox& legend) {
  LayoutRectOutsets fieldset_borders(
      fieldset.BorderTop(), fieldset.BorderRight(),
      LayoutUnit(),  // bottom border will always be left alone.
      fieldset.BorderLeft());
  // Using legend.FrameRect() is incorrect in vertical-rl mode, but we probably
  // won't fix this here which is for legacy layout.
  return FieldsetPaintInfo(fieldset.StyleRef(),
                           PhysicalSizeToBeNoop(fieldset.Size()),
                           fieldset_borders, PhysicalRect(legend.FrameRect()));
}

}  // anonymous namespace

void FieldsetPainter::PaintBoxDecorationBackground(
    const PaintInfo& paint_info,
    const PhysicalOffset& paint_offset) {
  if (layout_fieldset_.StyleRef().Visibility() != EVisibility::kVisible)
    return;

  PhysicalRect paint_rect(paint_offset, layout_fieldset_.Size());
  LayoutBox* legend = layout_fieldset_.FindInFlowLegend();
  if (!legend || paint_info.DescendantPaintingBlocked()) {
    return BoxPainter(layout_fieldset_)
        .PaintBoxDecorationBackground(paint_info, paint_offset);
  }

  BoxDecorationData box_decoration_data(paint_info, layout_fieldset_);
  // TODO(crbug.com/786475): Fieldset should not scroll.
  DCHECK(!box_decoration_data.IsPaintingScrollingBackground());
  if (box_decoration_data.ShouldPaint() &&
      !DrawingRecorder::UseCachedDrawingIfPossible(
          paint_info.context, layout_fieldset_, paint_info.phase)) {
    FieldsetPaintInfo fieldset_paint_info =
        CreateFieldsetPaintInfo(layout_fieldset_, *legend);
    paint_rect.Contract(fieldset_paint_info.border_outsets);

    BoxDrawingRecorder recorder(paint_info.context, layout_fieldset_,
                                paint_info.phase, paint_offset);

    if (box_decoration_data.ShouldPaintShadow()) {
      BoxPainterBase::PaintNormalBoxShadow(paint_info, paint_rect,
                                           layout_fieldset_.StyleRef());
    }
    if (box_decoration_data.ShouldPaintBackground()) {
      BackgroundImageGeometry geometry(layout_fieldset_);
      BoxModelObjectPainter(layout_fieldset_)
          .PaintFillLayers(paint_info, box_decoration_data.BackgroundColor(),
                           layout_fieldset_.StyleRef().BackgroundLayers(),
                           paint_rect, geometry);
    }
    if (box_decoration_data.ShouldPaintShadow()) {
      BoxPainterBase::PaintInsetBoxShadowWithBorderRect(
          paint_info, paint_rect, layout_fieldset_.StyleRef());
    }

    if (box_decoration_data.ShouldPaintBorder()) {
      // Create a clipping region around the legend and paint the border as
      // normal
      GraphicsContext& graphics_context = paint_info.context;
      GraphicsContextStateSaver state_saver(graphics_context);

      PhysicalRect legend_cutout_rect = fieldset_paint_info.legend_cutout_rect;
      legend_cutout_rect.Move(paint_offset);
      graphics_context.ClipOut(PixelSnappedIntRect(legend_cutout_rect));

      Node* node = nullptr;
      const LayoutObject* layout_object = &layout_fieldset_;
      for (; layout_object && !node; layout_object = layout_object->Parent())
        node = layout_object->GeneratingNode();
      BoxPainterBase::PaintBorder(
          layout_fieldset_, layout_fieldset_.GetDocument(), node, paint_info,
          paint_rect, layout_fieldset_.StyleRef());
    }
  }

  BoxPainter(layout_fieldset_)
      .RecordHitTestData(paint_info, paint_rect, layout_fieldset_);
}

void FieldsetPainter::PaintMask(const PaintInfo& paint_info,
                                const PhysicalOffset& paint_offset) {
  if (layout_fieldset_.StyleRef().Visibility() != EVisibility::kVisible ||
      paint_info.phase != PaintPhase::kMask)
    return;

  PhysicalRect paint_rect(paint_offset, layout_fieldset_.Size());
  LayoutBox* legend = layout_fieldset_.FindInFlowLegend();
  if (!legend || paint_info.DescendantPaintingBlocked())
    return BoxPainter(layout_fieldset_).PaintMask(paint_info, paint_offset);

  if (DrawingRecorder::UseCachedDrawingIfPossible(
          paint_info.context, layout_fieldset_, paint_info.phase))
    return;

  FieldsetPaintInfo fieldset_paint_info =
      CreateFieldsetPaintInfo(layout_fieldset_, *legend);
  paint_rect.Contract(fieldset_paint_info.border_outsets);

  BoxDrawingRecorder recorder(paint_info.context, layout_fieldset_,
                              paint_info.phase, paint_offset);
  BoxPainter(layout_fieldset_).PaintMaskImages(paint_info, paint_rect);
}

}  // namespace blink