17242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved. 27242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// Use of this source code is governed by a BSD-style license that can be 37242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// found in the LICENSE file. 47242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 57242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "config.h" 67242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/paint/InlineFlowBoxPainter.h" 77242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 87242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/paint/BoxPainter.h" 97242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/rendering/InlineFlowBox.h" 107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/rendering/PaintInfo.h" 117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/rendering/RenderBlock.h" 127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/rendering/RenderInline.h" 137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/rendering/RenderLayer.h" 147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/rendering/RenderView.h" 157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "platform/graphics/GraphicsContextStateSaver.h" 167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccinamespace blink { 187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid InlineFlowBoxPainter::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, const LayoutUnit lineTop, const LayoutUnit lineBottom) 207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutRect overflowRect(m_inlineFlowBox.visualOverflowRect(lineTop, lineBottom)); 227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_inlineFlowBox.flipForWritingMode(overflowRect); 237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci overflowRect.moveBy(paintOffset); 247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!paintInfo.rect.intersects(pixelSnappedIntRect(overflowRect))) 267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return; 277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) { 297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Add ourselves to the paint info struct's list of inlines that need to paint their 307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // outlines. 317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (m_inlineFlowBox.renderer().style()->visibility() == VISIBLE && m_inlineFlowBox.renderer().style()->hasOutline() && !m_inlineFlowBox.isRootInlineBox()) { 327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci RenderInline& inlineFlow = toRenderInline(m_inlineFlowBox.renderer()); 337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci RenderBlock* cb = 0; 357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci bool containingBlockPaintsContinuationOutline = inlineFlow.continuation() || inlineFlow.isInlineElementContinuation(); 367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (containingBlockPaintsContinuationOutline) { 377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // FIXME: See https://bugs.webkit.org/show_bug.cgi?id=54690. We currently don't reconnect inline continuations 387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // after a child removal. As a result, those merged inlines do not get seperated and hence not get enclosed by 397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // anonymous blocks. In this case, it is better to bail out and paint it ourself. 407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci RenderBlock* enclosingAnonymousBlock = m_inlineFlowBox.renderer().containingBlock(); 417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!enclosingAnonymousBlock->isAnonymousBlock()) { 427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci containingBlockPaintsContinuationOutline = false; 437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else { 447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci cb = enclosingAnonymousBlock->containingBlock(); 457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci for (RenderBoxModelObject* box = m_inlineFlowBox.boxModelObject(); box != cb; box = box->parent()->enclosingBoxModelObject()) { 467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (box->hasSelfPaintingLayer()) { 477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci containingBlockPaintsContinuationOutline = false; 487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci break; 497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (containingBlockPaintsContinuationOutline) { 557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Add ourselves to the containing block of the entire continuation so that it can 567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // paint us atomically. 577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci cb->addContinuationWithOutline(toRenderInline(m_inlineFlowBox.renderer().node()->renderer())); 587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else if (!inlineFlow.isInlineElementContinuation()) { 597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintInfo.outlineObjects()->add(&inlineFlow); 607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else if (paintInfo.phase == PaintPhaseMask) { 637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintMask(paintInfo, paintOffset); 647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return; 657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else if (paintInfo.phase == PaintPhaseForeground) { 667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Paint our background, border and box-shadow. 677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintBoxDecorationBackground(paintInfo, paintOffset); 687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Paint our children. 717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (paintInfo.phase != PaintPhaseSelfOutline) { 727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci PaintInfo childInfo(paintInfo); 737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci childInfo.phase = paintInfo.phase == PaintPhaseChildOutlines ? PaintPhaseOutline : paintInfo.phase; 747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (childInfo.paintingRoot && childInfo.paintingRoot->isDescendantOf(&m_inlineFlowBox.renderer())) 767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci childInfo.paintingRoot = 0; 777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci else 787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci childInfo.updatePaintingRootForChildren(&m_inlineFlowBox.renderer()); 797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci for (InlineBox* curr = m_inlineFlowBox.firstChild(); curr; curr = curr->nextOnLine()) { 817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (curr->renderer().isText() || !curr->boxModelObject()->hasSelfPaintingLayer()) 827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci curr->paint(childInfo, paintOffset, lineTop, lineBottom); 837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid InlineFlowBoxPainter::paintFillLayers(const PaintInfo& paintInfo, const Color& c, const FillLayer& fillLayer, const LayoutRect& rect, CompositeOperator op) 887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // FIXME: This should be a for loop or similar. It's a little non-trivial to do so, however, since the layers need to be 907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // painted in reverse order. 917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (fillLayer.next()) 927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintFillLayers(paintInfo, c, *fillLayer.next(), rect, op); 937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintFillLayer(paintInfo, c, fillLayer, rect, op); 947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid InlineFlowBoxPainter::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const FillLayer& fillLayer, const LayoutRect& rect, CompositeOperator op) 977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci StyleImage* img = fillLayer.image(); 997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci bool hasFillImage = img && img->canRender(m_inlineFlowBox.renderer(), m_inlineFlowBox.renderer().style()->effectiveZoom()); 1007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if ((!hasFillImage && !m_inlineFlowBox.renderer().style()->hasBorderRadius()) || (!m_inlineFlowBox.prevLineBox() && !m_inlineFlowBox.nextLineBox()) || !m_inlineFlowBox.parent()) { 1017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci BoxPainter::paintFillLayerExtended(*m_inlineFlowBox.boxModelObject(), paintInfo, c, fillLayer, rect, BackgroundBleedNone, &m_inlineFlowBox, rect.size(), op); 1027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else if (m_inlineFlowBox.renderer().style()->boxDecorationBreak() == DCLONE) { 1037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci GraphicsContextStateSaver stateSaver(*paintInfo.context); 1047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintInfo.context->clip(LayoutRect(rect.x(), rect.y(), m_inlineFlowBox.width(), m_inlineFlowBox.height())); 1057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci BoxPainter::paintFillLayerExtended(*m_inlineFlowBox.boxModelObject(), paintInfo, c, fillLayer, rect, BackgroundBleedNone, &m_inlineFlowBox, rect.size(), op); 1067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else { 1077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // We have a fill image that spans multiple lines. 1087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // We need to adjust tx and ty by the width of all previous lines. 1097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Think of background painting on inlines as though you had one long line, a single continuous 1107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // strip. Even though that strip has been broken up across multiple lines, you still paint it 1117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // as though you had one single line. This means each line has to pick up the background where 1127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // the previous line left off. 1137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit logicalOffsetOnLine = 0; 1147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit totalLogicalWidth; 1157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (m_inlineFlowBox.renderer().style()->direction() == LTR) { 1167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci for (InlineFlowBox* curr = m_inlineFlowBox.prevLineBox(); curr; curr = curr->prevLineBox()) 1177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci logicalOffsetOnLine += curr->logicalWidth(); 1187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci totalLogicalWidth = logicalOffsetOnLine; 1197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci for (InlineFlowBox* curr = &m_inlineFlowBox; curr; curr = curr->nextLineBox()) 1207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci totalLogicalWidth += curr->logicalWidth(); 1217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else { 1227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci for (InlineFlowBox* curr = m_inlineFlowBox.nextLineBox(); curr; curr = curr->nextLineBox()) 1237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci logicalOffsetOnLine += curr->logicalWidth(); 1247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci totalLogicalWidth = logicalOffsetOnLine; 1257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci for (InlineFlowBox* curr = &m_inlineFlowBox; curr; curr = curr->prevLineBox()) 1267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci totalLogicalWidth += curr->logicalWidth(); 1277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit stripX = rect.x() - (m_inlineFlowBox.isHorizontal() ? logicalOffsetOnLine : LayoutUnit()); 1297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit stripY = rect.y() - (m_inlineFlowBox.isHorizontal() ? LayoutUnit() : logicalOffsetOnLine); 1307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit stripWidth = m_inlineFlowBox.isHorizontal() ? totalLogicalWidth : static_cast<LayoutUnit>(m_inlineFlowBox.width()); 1317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit stripHeight = m_inlineFlowBox.isHorizontal() ? static_cast<LayoutUnit>(m_inlineFlowBox.height()) : totalLogicalWidth; 1327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci GraphicsContextStateSaver stateSaver(*paintInfo.context); 1347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintInfo.context->clip(LayoutRect(rect.x(), rect.y(), m_inlineFlowBox.width(), m_inlineFlowBox.height())); 1357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci BoxPainter::paintFillLayerExtended(*m_inlineFlowBox.boxModelObject(), paintInfo, c, fillLayer, LayoutRect(stripX, stripY, stripWidth, stripHeight), BackgroundBleedNone, &m_inlineFlowBox, rect.size(), op); 1367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid InlineFlowBoxPainter::paintBoxShadow(const PaintInfo& info, RenderStyle* s, ShadowStyle shadowStyle, const LayoutRect& paintRect) 1407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if ((!m_inlineFlowBox.prevLineBox() && !m_inlineFlowBox.nextLineBox()) || !m_inlineFlowBox.parent()) { 1427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci BoxPainter::paintBoxShadow(info, paintRect, s, shadowStyle); 1437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else { 1447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // FIXME: We can do better here in the multi-line case. We want to push a clip so that the shadow doesn't 1457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // protrude incorrectly at the edges, and we want to possibly include shadows cast from the previous/following lines 1467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci BoxPainter::paintBoxShadow(info, paintRect, s, shadowStyle, m_inlineFlowBox.includeLogicalLeftEdge(), m_inlineFlowBox.includeLogicalRightEdge()); 1477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccistatic LayoutRect clipRectForNinePieceImageStrip(InlineFlowBox* box, const NinePieceImage& image, const LayoutRect& paintRect) 1527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutRect clipRect(paintRect); 1547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci RenderStyle* style = box->renderer().style(); 1557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutBoxExtent outsets = style->imageOutsets(image); 1567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (box->isHorizontal()) { 1577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci clipRect.setY(paintRect.y() - outsets.top()); 1587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci clipRect.setHeight(paintRect.height() + outsets.top() + outsets.bottom()); 1597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (box->includeLogicalLeftEdge()) { 1607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci clipRect.setX(paintRect.x() - outsets.left()); 1617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci clipRect.setWidth(paintRect.width() + outsets.left()); 1627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (box->includeLogicalRightEdge()) 1647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci clipRect.setWidth(clipRect.width() + outsets.right()); 1657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else { 1667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci clipRect.setX(paintRect.x() - outsets.left()); 1677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci clipRect.setWidth(paintRect.width() + outsets.left() + outsets.right()); 1687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (box->includeLogicalLeftEdge()) { 1697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci clipRect.setY(paintRect.y() - outsets.top()); 1707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci clipRect.setHeight(paintRect.height() + outsets.top()); 1717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (box->includeLogicalRightEdge()) 1737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci clipRect.setHeight(clipRect.height() + outsets.bottom()); 1747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return clipRect; 1767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid InlineFlowBoxPainter::paintBoxDecorationBackground(PaintInfo& paintInfo, const LayoutPoint& paintOffset) 1797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(paintInfo.phase == PaintPhaseForeground); 1817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!paintInfo.shouldPaintWithinRoot(&m_inlineFlowBox.renderer()) || m_inlineFlowBox.renderer().style()->visibility() != VISIBLE) 1827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return; 1837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // You can use p::first-line to specify a background. If so, the root line boxes for 1857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // a line may actually have to paint a background. 1867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci RenderStyle* styleToUse = m_inlineFlowBox.renderer().style(m_inlineFlowBox.isFirstLineStyle()); 1877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci bool shouldPaintBoxDecorationBackground; 1887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (m_inlineFlowBox.parent()) 1897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci shouldPaintBoxDecorationBackground = m_inlineFlowBox.renderer().hasBoxDecorationBackground(); 1907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci else 1917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci shouldPaintBoxDecorationBackground = m_inlineFlowBox.isFirstLineStyle() && styleToUse != m_inlineFlowBox.renderer().style(); 1927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!shouldPaintBoxDecorationBackground) 1947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return; 1957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutRect frameRect = roundedFrameRectClampedToLineTopAndBottomIfNeeded(); 1977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Move x/y to our coordinates. 1997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutRect localRect(frameRect); 2007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_inlineFlowBox.flipForWritingMode(localRect); 2017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutPoint adjustedPaintOffset = paintOffset + localRect.location(); 2027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutRect paintRect = LayoutRect(adjustedPaintOffset, frameRect.size()); 2047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Shadow comes first and is behind the background and border. 2067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!m_inlineFlowBox.boxModelObject()->boxShadowShouldBeAppliedToBackground(BackgroundBleedNone, &m_inlineFlowBox)) 2077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintBoxShadow(paintInfo, styleToUse, Normal, paintRect); 2087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci Color backgroundColor = m_inlineFlowBox.renderer().resolveColor(styleToUse, CSSPropertyBackgroundColor); 2107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintFillLayers(paintInfo, backgroundColor, styleToUse->backgroundLayers(), paintRect); 2117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintBoxShadow(paintInfo, styleToUse, Inset, paintRect); 2127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // :first-line cannot be used to put borders on a line. Always paint borders with our 2147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // non-first-line style. 2157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (m_inlineFlowBox.parent() && m_inlineFlowBox.renderer().style()->hasBorder()) { 2167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci const NinePieceImage& borderImage = m_inlineFlowBox.renderer().style()->borderImage(); 2177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci StyleImage* borderImageSource = borderImage.image(); 2187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci bool hasBorderImage = borderImageSource && borderImageSource->canRender(m_inlineFlowBox.renderer(), styleToUse->effectiveZoom()); 2197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (hasBorderImage && !borderImageSource->isLoaded()) 2207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return; // Don't paint anything while we wait for the image to load. 2217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // The simple case is where we either have no border image or we are the only box for this object. 2237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // In those cases only a single call to draw is required. 2247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!hasBorderImage || (!m_inlineFlowBox.prevLineBox() && !m_inlineFlowBox.nextLineBox())) { 2257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci BoxPainter::paintBorder(*m_inlineFlowBox.boxModelObject(), paintInfo, paintRect, m_inlineFlowBox.renderer().style(m_inlineFlowBox.isFirstLineStyle()), BackgroundBleedNone, m_inlineFlowBox.includeLogicalLeftEdge(), m_inlineFlowBox.includeLogicalRightEdge()); 2267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else { 2277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // We have a border image that spans multiple lines. 2287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // We need to adjust tx and ty by the width of all previous lines. 2297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Think of border image painting on inlines as though you had one long line, a single continuous 2307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // strip. Even though that strip has been broken up across multiple lines, you still paint it 2317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // as though you had one single line. This means each line has to pick up the image where 2327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // the previous line left off. 2337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // FIXME: What the heck do we do with RTL here? The math we're using is obviously not right, 2347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // but it isn't even clear how this should work at all. 2357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit logicalOffsetOnLine = 0; 2367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci for (InlineFlowBox* curr = m_inlineFlowBox.prevLineBox(); curr; curr = curr->prevLineBox()) 2377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci logicalOffsetOnLine += curr->logicalWidth(); 2387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit totalLogicalWidth = logicalOffsetOnLine; 2397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci for (InlineFlowBox* curr = &m_inlineFlowBox; curr; curr = curr->nextLineBox()) 2407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci totalLogicalWidth += curr->logicalWidth(); 2417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit stripX = adjustedPaintOffset.x() - (m_inlineFlowBox.isHorizontal() ? logicalOffsetOnLine : LayoutUnit()); 2427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit stripY = adjustedPaintOffset.y() - (m_inlineFlowBox.isHorizontal() ? LayoutUnit() : logicalOffsetOnLine); 2437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit stripWidth = m_inlineFlowBox.isHorizontal() ? totalLogicalWidth : frameRect.width(); 2447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit stripHeight = m_inlineFlowBox.isHorizontal() ? frameRect.height() : totalLogicalWidth; 2457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutRect clipRect = clipRectForNinePieceImageStrip(&m_inlineFlowBox, borderImage, paintRect); 2477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci GraphicsContextStateSaver stateSaver(*paintInfo.context); 2487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintInfo.context->clip(clipRect); 2497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci BoxPainter::paintBorder(*m_inlineFlowBox.boxModelObject(), paintInfo, LayoutRect(stripX, stripY, stripWidth, stripHeight), m_inlineFlowBox.renderer().style(m_inlineFlowBox.isFirstLineStyle())); 2507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 2517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 2527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 2537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid InlineFlowBoxPainter::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffset) 2557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 2567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!paintInfo.shouldPaintWithinRoot(&m_inlineFlowBox.renderer()) || m_inlineFlowBox.renderer().style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask) 2577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return; 2587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutRect frameRect = roundedFrameRectClampedToLineTopAndBottomIfNeeded(); 2607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Move x/y to our coordinates. 2627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutRect localRect(frameRect); 2637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_inlineFlowBox.flipForWritingMode(localRect); 2647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutPoint adjustedPaintOffset = paintOffset + localRect.location(); 2657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci const NinePieceImage& maskNinePieceImage = m_inlineFlowBox.renderer().style()->maskBoxImage(); 2677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci StyleImage* maskBoxImage = m_inlineFlowBox.renderer().style()->maskBoxImage().image(); 2687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Figure out if we need to push a transparency layer to render our mask. 2707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci bool pushTransparencyLayer = false; 2717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci bool compositedMask = m_inlineFlowBox.renderer().hasLayer() && m_inlineFlowBox.boxModelObject()->layer()->hasCompositedMask(); 2727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci bool flattenCompositingLayers = m_inlineFlowBox.renderer().view()->frameView() && m_inlineFlowBox.renderer().view()->frameView()->paintBehavior() & PaintBehaviorFlattenCompositingLayers; 2737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci CompositeOperator compositeOp = CompositeSourceOver; 2747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!compositedMask || flattenCompositingLayers) { 2757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if ((maskBoxImage && m_inlineFlowBox.renderer().style()->maskLayers().hasImage()) || m_inlineFlowBox.renderer().style()->maskLayers().next()) 2767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci pushTransparencyLayer = true; 2777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci compositeOp = CompositeDestinationIn; 2797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (pushTransparencyLayer) { 2807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintInfo.context->setCompositeOperation(CompositeDestinationIn); 2817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintInfo.context->beginTransparencyLayer(1.0f); 2827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci compositeOp = CompositeSourceOver; 2837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 2847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 2857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutRect paintRect = LayoutRect(adjustedPaintOffset, frameRect.size()); 2877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintFillLayers(paintInfo, Color::transparent, m_inlineFlowBox.renderer().style()->maskLayers(), paintRect, compositeOp); 2887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(m_inlineFlowBox.renderer(), m_inlineFlowBox.renderer().style()->effectiveZoom()); 2907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!hasBoxImage || !maskBoxImage->isLoaded()) { 2917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (pushTransparencyLayer) 2927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintInfo.context->endLayer(); 2937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return; // Don't paint anything while we wait for the image to load. 2947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 2957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // The simple case is where we are the only box for this object. In those 2977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // cases only a single call to draw is required. 2987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!m_inlineFlowBox.prevLineBox() && !m_inlineFlowBox.nextLineBox()) { 2997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci BoxPainter::paintNinePieceImage(*m_inlineFlowBox.boxModelObject(), paintInfo.context, LayoutRect(adjustedPaintOffset, frameRect.size()), m_inlineFlowBox.renderer().style(), maskNinePieceImage, compositeOp); 3007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else { 3017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // We have a mask image that spans multiple lines. 3027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // We need to adjust _tx and _ty by the width of all previous lines. 3037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit logicalOffsetOnLine = 0; 3047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci for (InlineFlowBox* curr = m_inlineFlowBox.prevLineBox(); curr; curr = curr->prevLineBox()) 3057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci logicalOffsetOnLine += curr->logicalWidth(); 3067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit totalLogicalWidth = logicalOffsetOnLine; 3077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci for (InlineFlowBox* curr = &m_inlineFlowBox; curr; curr = curr->nextLineBox()) 3087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci totalLogicalWidth += curr->logicalWidth(); 3097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit stripX = adjustedPaintOffset.x() - (m_inlineFlowBox.isHorizontal() ? logicalOffsetOnLine : LayoutUnit()); 3107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit stripY = adjustedPaintOffset.y() - (m_inlineFlowBox.isHorizontal() ? LayoutUnit() : logicalOffsetOnLine); 3117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit stripWidth = m_inlineFlowBox.isHorizontal() ? totalLogicalWidth : frameRect.width(); 3127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit stripHeight = m_inlineFlowBox.isHorizontal() ? frameRect.height() : totalLogicalWidth; 3137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 3147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutRect clipRect = clipRectForNinePieceImageStrip(&m_inlineFlowBox, maskNinePieceImage, paintRect); 3157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci GraphicsContextStateSaver stateSaver(*paintInfo.context); 3167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintInfo.context->clip(clipRect); 3177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci BoxPainter::paintNinePieceImage(*m_inlineFlowBox.boxModelObject(), paintInfo.context, LayoutRect(stripX, stripY, stripWidth, stripHeight), m_inlineFlowBox.renderer().style(), maskNinePieceImage, compositeOp); 3187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 3197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 3207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (pushTransparencyLayer) 3217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintInfo.context->endLayer(); 3227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 3237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 3247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciLayoutRect InlineFlowBoxPainter::roundedFrameRectClampedToLineTopAndBottomIfNeeded() const 3257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 3267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Pixel snap rect painting. 3277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutRect rect = m_inlineFlowBox.roundedFrameRect(); 3287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 3297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci bool noQuirksMode = m_inlineFlowBox.renderer().document().inNoQuirksMode(); 3307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!noQuirksMode && !m_inlineFlowBox.hasTextChildren() && !(m_inlineFlowBox.descendantsHaveSameLineHeightAndBaseline() && m_inlineFlowBox.hasTextDescendants())) { 3317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci const RootInlineBox& rootBox = m_inlineFlowBox.root(); 3327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit logicalTop = m_inlineFlowBox.isHorizontal() ? rect.y() : rect.x(); 3337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit logicalHeight = m_inlineFlowBox.isHorizontal() ? rect.height() : rect.width(); 3347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci LayoutUnit bottom = std::min(rootBox.lineBottom(), logicalTop + logicalHeight); 3357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci logicalTop = std::max(rootBox.lineTop(), logicalTop); 3367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci logicalHeight = bottom - logicalTop; 3377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (m_inlineFlowBox.isHorizontal()) { 3387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci rect.setY(logicalTop); 3397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci rect.setHeight(logicalHeight); 3407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else { 3417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci rect.setX(logicalTop); 3427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci rect.setWidth(logicalHeight); 3437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 3447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 3457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return rect; 3467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 3477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 3487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} // namespace blink 349