summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/paint/background_image_geometry.h
blob: 52c2f4593bcf22e4c494f93bb59f6536c1852f4c (plain)
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
// 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.

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BACKGROUND_IMAGE_GEOMETRY_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BACKGROUND_IMAGE_GEOMETRY_H_

#include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
#include "third_party/blink/renderer/core/paint/paint_phase.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"

namespace blink {

class FillLayer;
class LayoutBox;
class LayoutBoxModelObject;
class LayoutObject;
class LayoutTableCell;
class LayoutView;
class Document;
class ComputedStyle;
class ImageResourceObserver;
class LayoutNGTableCell;

class BackgroundImageGeometry {
  STACK_ALLOCATED();

 public:
  // Constructor for LayoutView where the coordinate space is different.
  BackgroundImageGeometry(
      const LayoutView&,
      const PhysicalOffset& element_positioning_area_offset);

  // Constructor for table cells where background_object may be the row or
  // column the background image is attached to.
  BackgroundImageGeometry(const LayoutTableCell&,
                          const LayoutObject* background_object);

  // Generic constructor for all other elements.
  BackgroundImageGeometry(const LayoutBoxModelObject&);

  // Constructor for TablesNG table parts.
  BackgroundImageGeometry(const LayoutNGTableCell& cell,
                          PhysicalOffset cell_offset,
                          const LayoutBox& table_part,
                          PhysicalSize table_part_size);

  void Calculate(const LayoutBoxModelObject* container,
                 PaintPhase,
                 const FillLayer&,
                 const PhysicalRect& paint_rect);

  // Destination rects define the area into which the image will paint.
  // For cases where no explicit background size is requested, the destination
  // also defines the subset of the image to be drawn. Both border-snapped
  // and unsnapped rectangles are available. The snapped rectangle matches the
  // inner border of the box when such information is available. This may
  // may differ from the PixelSnappedIntRect of the unsnapped rectangle
  // because both border widths and border locations are snapped. The
  // unsnapped rectangle is the size and location intended by the content
  // author, and is needed to correctly subset images when no background-size
  // size is given.
  const PhysicalRect& UnsnappedDestRect() const { return unsnapped_dest_rect_; }
  const PhysicalRect& SnappedDestRect() const { return snapped_dest_rect_; }

  // Compute the phase relative to the (snapped) destination offset.
  PhysicalOffset ComputeDestPhase() const;

  // Tile size is the area into which to draw one copy of the image. It
  // need not be the same as the intrinsic size of the image; if not,
  // the image will be resized (via an image filter) when painted into
  // that tile region. This may happen because of CSS background-size and
  // background-repeat requirements.
  const PhysicalSize& TileSize() const { return tile_size_; }

  // Phase() represents the point in the image that will appear at (0,0) in the
  // destination space. The point is defined in TileSize() coordinates, that is,
  // in the scaled image.
  const PhysicalOffset& Phase() const { return phase_; }

  // SpaceSize() represents extra width and height that may be added to
  // the image if used as a pattern with background-repeat: space.
  const PhysicalSize& SpaceSize() const { return repeat_spacing_; }

  // Has background-attachment: fixed. Implies that we can't always cheaply
  // compute the destination rects.
  bool HasNonLocalGeometry() const { return has_non_local_geometry_; }

  // Whether the background needs to be positioned relative to a container
  // element. Only used for tables.
  bool CellUsingContainerBackground() const {
    return cell_using_container_background_;
  }

  const ImageResourceObserver& ImageClient() const;
  const Document& ImageDocument() const;
  const ComputedStyle& ImageStyle(const ComputedStyle& fragment_style) const;
  InterpolationQuality ImageInterpolationQuality() const;

 private:
  static bool ShouldUseFixedAttachment(const FillLayer&);

  void SetSpaceSize(const PhysicalSize& repeat_spacing) {
    repeat_spacing_ = repeat_spacing;
  }
  void SetPhaseX(LayoutUnit x) { phase_.left = x; }
  void SetPhaseY(LayoutUnit y) { phase_.top = y; }

  void SetNoRepeatX(const FillLayer&,
                    LayoutUnit x_offset,
                    LayoutUnit snapped_x_offset);
  void SetNoRepeatY(const FillLayer&,
                    LayoutUnit y_offset,
                    LayoutUnit snapped_y_offset);
  void SetRepeatX(const FillLayer&,
                  LayoutUnit available_width,
                  LayoutUnit extra_offset);
  void SetRepeatY(const FillLayer&,
                  LayoutUnit available_height,
                  LayoutUnit extra_offset);
  void SetSpaceX(LayoutUnit space, LayoutUnit extra_offset);
  void SetSpaceY(LayoutUnit space, LayoutUnit extra_offset);

  void UseFixedAttachment(const PhysicalOffset& attachment_point);
  void SetHasNonLocalGeometry() { has_non_local_geometry_ = true; }
  PhysicalOffset GetPositioningOffsetForCell(const LayoutTableCell&,
                                             const LayoutBox&);
  PhysicalSize GetBackgroundObjectDimensions(const LayoutTableCell&,
                                             const LayoutBox&);

  // Compute adjustments for the destination rects. Adjustments
  // both optimize painting when the background is obscured by a
  // border, and snap the dest rect to the border. They also
  // account for the background-clip property.
  void ComputeDestRectAdjustments(const FillLayer&,
                                  const PhysicalRect&,
                                  bool,
                                  LayoutRectOutsets&,
                                  LayoutRectOutsets&) const;

  // Positioning area adjustments modify the size of the
  // positioning area to snap values and apply the
  // background-origin property.
  void ComputePositioningAreaAdjustments(const FillLayer&,
                                         const PhysicalRect&,
                                         bool,
                                         LayoutRectOutsets&,
                                         LayoutRectOutsets&) const;

  void ComputePositioningArea(const LayoutBoxModelObject*,
                              PaintPhase,
                              const FillLayer&,
                              const PhysicalRect&,
                              PhysicalRect&,
                              PhysicalRect&,
                              PhysicalOffset&,
                              PhysicalOffset&);
  void CalculateFillTileSize(const FillLayer&,
                             const PhysicalSize&,
                             const PhysicalSize&);

  // The offset of the background image within the background positioning area.
  PhysicalOffset OffsetInBackground(const FillLayer&) const;

  // |box_| is the source for the Document. In most cases it also provides the
  // background properties (see |positioning_box_| for exceptions.) It's also
  // the image client unless painting the view background.
  const LayoutBoxModelObject* const box_;

  // The positioning box is the source of geometric information for positioning
  // and sizing the background. It also provides the background properties if
  // painting the view background or a table-cell using its container's
  // (row's/column's) background.
  const LayoutBoxModelObject* const positioning_box_;

  // When painting table cells or the view, the positioning area
  // differs from the requested paint rect.
  PhysicalSize positioning_size_override_;

  // The background image offset from within the background positioning area for
  // non-fixed background attachment. Used for table cells and the view.
  PhysicalOffset element_positioning_area_offset_;

  PhysicalRect unsnapped_dest_rect_;
  PhysicalRect snapped_dest_rect_;
  PhysicalOffset phase_;
  PhysicalSize tile_size_;
  PhysicalSize repeat_spacing_;
  bool has_non_local_geometry_ = false;
  bool painting_view_ = false;
  bool painting_table_cell_ = false;
  bool cell_using_container_background_ = false;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BACKGROUND_IMAGE_GEOMETRY_H_