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.
6 #include "core/paint/FrameSetPainter.h"
8 #include "core/html/HTMLFrameSetElement.h"
9 #include "core/layout/LayoutFrameSet.h"
10 #include "core/paint/LayoutObjectDrawingRecorder.h"
11 #include "core/paint/PaintInfo.h"
15 static Color
borderStartEdgeColor()
17 return Color(170, 170, 170);
20 static Color
borderEndEdgeColor()
25 static Color
borderFillColor()
27 return Color(208, 208, 208);
30 void FrameSetPainter::paintColumnBorder(const PaintInfo
& paintInfo
, const IntRect
& borderRect
)
32 if (!paintInfo
.rect
.intersects(borderRect
))
35 // FIXME: We should do something clever when borders from distinct framesets meet at a join.
38 GraphicsContext
* context
= paintInfo
.context
;
39 context
->fillRect(borderRect
, m_layoutFrameSet
.frameSet()->hasBorderColor() ? m_layoutFrameSet
.resolveColor(CSSPropertyBorderLeftColor
) : borderFillColor());
41 // Now stroke the edges but only if we have enough room to paint both edges with a little
42 // bit of the fill color showing through.
43 if (borderRect
.width() >= 3) {
44 context
->fillRect(IntRect(borderRect
.location(), IntSize(1, borderRect
.height())), borderStartEdgeColor());
45 context
->fillRect(IntRect(IntPoint(borderRect
.maxX() - 1, borderRect
.y()), IntSize(1, borderRect
.height())), borderEndEdgeColor());
49 void FrameSetPainter::paintRowBorder(const PaintInfo
& paintInfo
, const IntRect
& borderRect
)
51 // FIXME: We should do something clever when borders from distinct framesets meet at a join.
54 GraphicsContext
* context
= paintInfo
.context
;
55 context
->fillRect(borderRect
, m_layoutFrameSet
.frameSet()->hasBorderColor() ? m_layoutFrameSet
.resolveColor(CSSPropertyBorderLeftColor
) : borderFillColor());
57 // Now stroke the edges but only if we have enough room to paint both edges with a little
58 // bit of the fill color showing through.
59 if (borderRect
.height() >= 3) {
60 context
->fillRect(IntRect(borderRect
.location(), IntSize(borderRect
.width(), 1)), borderStartEdgeColor());
61 context
->fillRect(IntRect(IntPoint(borderRect
.x(), borderRect
.maxY() - 1), IntSize(borderRect
.width(), 1)), borderEndEdgeColor());
65 static bool shouldPaintBorderAfter(const LayoutFrameSet::GridAxis
& axis
, size_t index
)
67 // Should not paint a border after the last frame along the axis.
68 return index
+ 1 < axis
.m_sizes
.size() && axis
.m_allowBorder
[index
+ 1];
71 void FrameSetPainter::paintBorders(const PaintInfo
& paintInfo
, const LayoutPoint
& adjustedPaintOffset
)
73 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(*paintInfo
.context
, m_layoutFrameSet
, paintInfo
.phase
, adjustedPaintOffset
))
76 LayoutRect
adjustedFrameRect(adjustedPaintOffset
, m_layoutFrameSet
.size());
77 LayoutObjectDrawingRecorder
recorder(*paintInfo
.context
, m_layoutFrameSet
, paintInfo
.phase
, adjustedFrameRect
, adjustedPaintOffset
);
79 LayoutUnit borderThickness
= m_layoutFrameSet
.frameSet()->border();
83 LayoutObject
* child
= m_layoutFrameSet
.firstChild();
84 size_t rows
= m_layoutFrameSet
.rows().m_sizes
.size();
85 size_t cols
= m_layoutFrameSet
.columns().m_sizes
.size();
87 for (size_t r
= 0; r
< rows
; r
++) {
89 for (size_t c
= 0; c
< cols
; c
++) {
90 xPos
+= m_layoutFrameSet
.columns().m_sizes
[c
];
91 if (shouldPaintBorderAfter(m_layoutFrameSet
.columns(), c
)) {
92 paintColumnBorder(paintInfo
, pixelSnappedIntRect(
93 LayoutRect(adjustedPaintOffset
.x() + xPos
, adjustedPaintOffset
.y() + yPos
, borderThickness
, m_layoutFrameSet
.size().height() - yPos
)));
94 xPos
+= borderThickness
;
96 child
= child
->nextSibling();
100 yPos
+= m_layoutFrameSet
.rows().m_sizes
[r
];
101 if (shouldPaintBorderAfter(m_layoutFrameSet
.rows(), r
)) {
102 paintRowBorder(paintInfo
, pixelSnappedIntRect(
103 LayoutRect(adjustedPaintOffset
.x(), adjustedPaintOffset
.y() + yPos
, m_layoutFrameSet
.size().width(), borderThickness
)));
104 yPos
+= borderThickness
;
109 void FrameSetPainter::paintChildren(const PaintInfo
& paintInfo
, const LayoutPoint
& adjustedPaintOffset
)
111 // Paint only those children that fit in the grid.
112 // Remaining frames are "hidden".
113 // See also LayoutFrameSet::positionFrames.
114 LayoutObject
* child
= m_layoutFrameSet
.firstChild();
115 size_t rows
= m_layoutFrameSet
.rows().m_sizes
.size();
116 size_t cols
= m_layoutFrameSet
.columns().m_sizes
.size();
117 for (size_t r
= 0; r
< rows
; r
++) {
118 for (size_t c
= 0; c
< cols
; c
++) {
119 // Self-painting layers are painted during the DeprecatedPaintLayer paint recursion, not LayoutObject.
120 if (!child
->isBoxModelObject() || !toLayoutBoxModelObject(child
)->hasSelfPaintingLayer())
121 child
->paint(paintInfo
, adjustedPaintOffset
);
122 child
= child
->nextSibling();
129 void FrameSetPainter::paint(const PaintInfo
& paintInfo
, const LayoutPoint
& paintOffset
)
131 if (paintInfo
.phase
!= PaintPhaseForeground
)
134 LayoutObject
* child
= m_layoutFrameSet
.firstChild();
138 LayoutPoint adjustedPaintOffset
= paintOffset
+ m_layoutFrameSet
.location();
139 paintChildren(paintInfo
, adjustedPaintOffset
);
140 paintBorders(paintInfo
, adjustedPaintOffset
);