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 "config.h" 6#include "core/paint/LineBoxListPainter.h" 7 8#include "core/paint/InlinePainter.h" 9#include "core/rendering/InlineFlowBox.h" 10#include "core/rendering/PaintInfo.h" 11#include "core/rendering/RenderBoxModelObject.h" 12#include "core/rendering/RenderLineBoxList.h" 13#include "core/rendering/RootInlineBox.h" 14 15namespace blink { 16 17void LineBoxListPainter::paint(RenderBoxModelObject* renderer, PaintInfo& paintInfo, const LayoutPoint& paintOffset) const 18{ 19 // Only paint during the foreground/selection phases. 20 if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseOutline 21 && paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines && paintInfo.phase != PaintPhaseTextClip 22 && paintInfo.phase != PaintPhaseMask) 23 return; 24 25 ASSERT(renderer->isRenderBlock() || (renderer->isRenderInline() && renderer->hasLayer())); // The only way an inline could paint like this is if it has a layer. 26 27 // If we have no lines then we have no work to do. 28 if (!m_renderLineBoxList.firstLineBox()) 29 return; 30 31 if (!m_renderLineBoxList.anyLineIntersectsRect(renderer, paintInfo.rect, paintOffset)) 32 return; 33 34 PaintInfo info(paintInfo); 35 ListHashSet<RenderInline*> outlineObjects; 36 info.setOutlineObjects(&outlineObjects); 37 38 // See if our root lines intersect with the dirty rect. If so, then we paint 39 // them. Note that boxes can easily overlap, so we can't make any assumptions 40 // based off positions of our first line box or our last line box. 41 for (InlineFlowBox* curr = m_renderLineBoxList.firstLineBox(); curr; curr = curr->nextLineBox()) { 42 if (m_renderLineBoxList.lineIntersectsDirtyRect(renderer, curr, info, paintOffset)) { 43 RootInlineBox& root = curr->root(); 44 curr->paint(info, paintOffset, root.lineTop(), root.lineBottom()); 45 } 46 } 47 48 if (info.phase == PaintPhaseOutline || info.phase == PaintPhaseSelfOutline || info.phase == PaintPhaseChildOutlines) { 49 ListHashSet<RenderInline*>::iterator end = info.outlineObjects()->end(); 50 for (ListHashSet<RenderInline*>::iterator it = info.outlineObjects()->begin(); it != end; ++it) { 51 RenderInline* flow = *it; 52 InlinePainter(*flow).paintOutline(info, paintOffset); 53 } 54 info.outlineObjects()->clear(); 55 } 56} 57 58} // namespace blink 59