| Index: Source/core/rendering/InlineFlowBox.cpp
|
| diff --git a/Source/core/rendering/InlineFlowBox.cpp b/Source/core/rendering/InlineFlowBox.cpp
|
| index dd149d90349e50d6a5783df598cd66d948f18f6b..4466a57d0983d135e1a7aeafaea2a2ac58912499 100644
|
| --- a/Source/core/rendering/InlineFlowBox.cpp
|
| +++ b/Source/core/rendering/InlineFlowBox.cpp
|
| @@ -1095,59 +1095,52 @@ void InlineFlowBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
|
| if (!paintInfo.rect.intersects(pixelSnappedIntRect(overflowRect)))
|
| return;
|
|
|
| - if (paintInfo.phase != PaintPhaseChildOutlines) {
|
| - if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) {
|
| - // Add ourselves to the paint info struct's list of inlines that need to paint their
|
| - // outlines.
|
| - if (renderer().style()->visibility() == VISIBLE && renderer().hasOutline() && !isRootInlineBox()) {
|
| - RenderInline& inlineFlow = toRenderInline(renderer());
|
| -
|
| - RenderBlock* cb = 0;
|
| - bool containingBlockPaintsContinuationOutline = inlineFlow.continuation() || inlineFlow.isInlineElementContinuation();
|
| - if (containingBlockPaintsContinuationOutline) {
|
| - // FIXME: See https://bugs.webkit.org/show_bug.cgi?id=54690. We currently don't reconnect inline continuations
|
| - // after a child removal. As a result, those merged inlines do not get seperated and hence not get enclosed by
|
| - // anonymous blocks. In this case, it is better to bail out and paint it ourself.
|
| - RenderBlock* enclosingAnonymousBlock = renderer().containingBlock();
|
| - if (!enclosingAnonymousBlock->isAnonymousBlock())
|
| - containingBlockPaintsContinuationOutline = false;
|
| - else {
|
| - cb = enclosingAnonymousBlock->containingBlock();
|
| - for (RenderBoxModelObject* box = boxModelObject(); box != cb; box = box->parent()->enclosingBoxModelObject()) {
|
| - if (box->hasSelfPaintingLayer()) {
|
| - containingBlockPaintsContinuationOutline = false;
|
| - break;
|
| - }
|
| + if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) {
|
| + // Add ourselves to the paint info struct's list of inlines that need to paint their
|
| + // outlines.
|
| + if (renderer().style()->visibility() == VISIBLE && renderer().hasOutline() && !isRootInlineBox()) {
|
| + RenderInline& inlineFlow = toRenderInline(renderer());
|
| +
|
| + RenderBlock* cb = 0;
|
| + bool containingBlockPaintsContinuationOutline = inlineFlow.continuation() || inlineFlow.isInlineElementContinuation();
|
| + if (containingBlockPaintsContinuationOutline) {
|
| + // FIXME: See https://bugs.webkit.org/show_bug.cgi?id=54690. We currently don't reconnect inline continuations
|
| + // after a child removal. As a result, those merged inlines do not get seperated and hence not get enclosed by
|
| + // anonymous blocks. In this case, it is better to bail out and paint it ourself.
|
| + RenderBlock* enclosingAnonymousBlock = renderer().containingBlock();
|
| + if (!enclosingAnonymousBlock->isAnonymousBlock()) {
|
| + containingBlockPaintsContinuationOutline = false;
|
| + } else {
|
| + cb = enclosingAnonymousBlock->containingBlock();
|
| + for (RenderBoxModelObject* box = boxModelObject(); box != cb; box = box->parent()->enclosingBoxModelObject()) {
|
| + if (box->hasSelfPaintingLayer()) {
|
| + containingBlockPaintsContinuationOutline = false;
|
| + break;
|
| }
|
| }
|
| }
|
| + }
|
|
|
| - if (containingBlockPaintsContinuationOutline) {
|
| - // Add ourselves to the containing block of the entire continuation so that it can
|
| - // paint us atomically.
|
| - cb->addContinuationWithOutline(toRenderInline(renderer().node()->renderer()));
|
| - } else if (!inlineFlow.isInlineElementContinuation()) {
|
| - paintInfo.outlineObjects()->add(&inlineFlow);
|
| - }
|
| + if (containingBlockPaintsContinuationOutline) {
|
| + // Add ourselves to the containing block of the entire continuation so that it can
|
| + // paint us atomically.
|
| + cb->addContinuationWithOutline(toRenderInline(renderer().node()->renderer()));
|
| + } else if (!inlineFlow.isInlineElementContinuation()) {
|
| + paintInfo.outlineObjects()->add(&inlineFlow);
|
| }
|
| - } else if (paintInfo.phase == PaintPhaseMask) {
|
| - paintMask(paintInfo, paintOffset);
|
| - return;
|
| - } else {
|
| - // Paint our background, border and box-shadow.
|
| - paintBoxDecorations(paintInfo, paintOffset);
|
| }
|
| - }
|
| -
|
| - if (paintInfo.phase == PaintPhaseMask)
|
| + } else if (paintInfo.phase == PaintPhaseMask) {
|
| + paintMask(paintInfo, paintOffset);
|
| return;
|
| -
|
| - PaintPhase paintPhase = paintInfo.phase == PaintPhaseChildOutlines ? PaintPhaseOutline : paintInfo.phase;
|
| + } else if (paintInfo.phase == PaintPhaseForeground) {
|
| + // Paint our background, border and box-shadow.
|
| + paintBoxDecorations(paintInfo, paintOffset);
|
| + }
|
|
|
| // Paint our children.
|
| - if (paintPhase != PaintPhaseSelfOutline) {
|
| + if (paintInfo.phase != PaintPhaseSelfOutline) {
|
| PaintInfo childInfo(paintInfo);
|
| - childInfo.phase = paintPhase;
|
| + childInfo.phase = paintInfo.phase == PaintPhaseChildOutlines ? PaintPhaseOutline : paintInfo.phase;
|
|
|
| if (childInfo.paintingRoot && childInfo.paintingRoot->isDescendantOf(&renderer()))
|
| childInfo.paintingRoot = 0;
|
| @@ -1281,72 +1274,78 @@ static LayoutRect clipRectForNinePieceImageStrip(InlineFlowBox* box, const NineP
|
|
|
| void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
|
| {
|
| - if (!paintInfo.shouldPaintWithinRoot(&renderer()) || renderer().style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseForeground)
|
| + ASSERT(paintInfo.phase == PaintPhaseForeground);
|
| + if (!paintInfo.shouldPaintWithinRoot(&renderer()) || renderer().style()->visibility() != VISIBLE)
|
| + return;
|
| +
|
| + // You can use p::first-line to specify a background. If so, the root line boxes for
|
| + // a line may actually have to paint a background.
|
| + RenderStyle* styleToUse = renderer().style(isFirstLineStyle());
|
| + bool shouldPaintBoxDecorations;
|
| + if (parent())
|
| + shouldPaintBoxDecorations = renderer().hasBoxDecorations();
|
| + else
|
| + shouldPaintBoxDecorations = isFirstLineStyle() && styleToUse != renderer().style();
|
| +
|
| + if (!shouldPaintBoxDecorations)
|
| return;
|
|
|
| // Pixel snap background/border painting.
|
| LayoutRect frameRect = roundedFrameRect();
|
| -
|
| constrainToLineTopAndBottomIfNeeded(frameRect);
|
|
|
| // Move x/y to our coordinates.
|
| LayoutRect localRect(frameRect);
|
| flipForWritingMode(localRect);
|
| - LayoutPoint adjustedPaintoffset = paintOffset + localRect.location();
|
| + LayoutPoint adjustedPaintOffset = paintOffset + localRect.location();
|
|
|
| - GraphicsContext* context = paintInfo.context;
|
| + LayoutRect paintRect = LayoutRect(adjustedPaintOffset, frameRect.size());
|
|
|
| - // You can use p::first-line to specify a background. If so, the root line boxes for
|
| - // a line may actually have to paint a background.
|
| - RenderStyle* styleToUse = renderer().style(isFirstLineStyle());
|
| - if ((!parent() && isFirstLineStyle() && styleToUse != renderer().style()) || (parent() && renderer().hasBoxDecorations())) {
|
| - LayoutRect paintRect = LayoutRect(adjustedPaintoffset, frameRect.size());
|
| - // Shadow comes first and is behind the background and border.
|
| - if (!boxModelObject()->boxShadowShouldBeAppliedToBackground(BackgroundBleedNone, this))
|
| - paintBoxShadow(paintInfo, styleToUse, Normal, paintRect);
|
| -
|
| - Color c = renderer().resolveColor(styleToUse, CSSPropertyBackgroundColor);
|
| - paintFillLayers(paintInfo, c, styleToUse->backgroundLayers(), paintRect);
|
| - paintBoxShadow(paintInfo, styleToUse, Inset, paintRect);
|
| -
|
| - // :first-line cannot be used to put borders on a line. Always paint borders with our
|
| - // non-first-line style.
|
| - if (parent() && renderer().style()->hasBorder()) {
|
| - const NinePieceImage& borderImage = renderer().style()->borderImage();
|
| - StyleImage* borderImageSource = borderImage.image();
|
| - bool hasBorderImage = borderImageSource && borderImageSource->canRender(renderer(), styleToUse->effectiveZoom());
|
| - if (hasBorderImage && !borderImageSource->isLoaded())
|
| - return; // Don't paint anything while we wait for the image to load.
|
| -
|
| - // The simple case is where we either have no border image or we are the only box for this object. In those
|
| - // cases only a single call to draw is required.
|
| - if (!hasBorderImage || (!prevLineBox() && !nextLineBox()))
|
| - boxModelObject()->paintBorder(paintInfo, paintRect, renderer().style(isFirstLineStyle()), BackgroundBleedNone, includeLogicalLeftEdge(), includeLogicalRightEdge());
|
| - else {
|
| - // We have a border image that spans multiple lines.
|
| - // We need to adjust tx and ty by the width of all previous lines.
|
| - // Think of border image painting on inlines as though you had one long line, a single continuous
|
| - // strip. Even though that strip has been broken up across multiple lines, you still paint it
|
| - // as though you had one single line. This means each line has to pick up the image where
|
| - // the previous line left off.
|
| - // FIXME: What the heck do we do with RTL here? The math we're using is obviously not right,
|
| - // but it isn't even clear how this should work at all.
|
| - LayoutUnit logicalOffsetOnLine = 0;
|
| - for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
|
| - logicalOffsetOnLine += curr->logicalWidth();
|
| - LayoutUnit totalLogicalWidth = logicalOffsetOnLine;
|
| - for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox())
|
| - totalLogicalWidth += curr->logicalWidth();
|
| - LayoutUnit stripX = adjustedPaintoffset.x() - (isHorizontal() ? logicalOffsetOnLine : LayoutUnit());
|
| - LayoutUnit stripY = adjustedPaintoffset.y() - (isHorizontal() ? LayoutUnit() : logicalOffsetOnLine);
|
| - LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : frameRect.width();
|
| - LayoutUnit stripHeight = isHorizontal() ? frameRect.height() : totalLogicalWidth;
|
| -
|
| - LayoutRect clipRect = clipRectForNinePieceImageStrip(this, borderImage, paintRect);
|
| - GraphicsContextStateSaver stateSaver(*context);
|
| - context->clip(clipRect);
|
| - boxModelObject()->paintBorder(paintInfo, LayoutRect(stripX, stripY, stripWidth, stripHeight), renderer().style(isFirstLineStyle()));
|
| - }
|
| + // Shadow comes first and is behind the background and border.
|
| + if (!boxModelObject()->boxShadowShouldBeAppliedToBackground(BackgroundBleedNone, this))
|
| + paintBoxShadow(paintInfo, styleToUse, Normal, paintRect);
|
| +
|
| + Color backgroundColor = renderer().resolveColor(styleToUse, CSSPropertyBackgroundColor);
|
| + paintFillLayers(paintInfo, backgroundColor, styleToUse->backgroundLayers(), paintRect);
|
| + paintBoxShadow(paintInfo, styleToUse, Inset, paintRect);
|
| +
|
| + // :first-line cannot be used to put borders on a line. Always paint borders with our
|
| + // non-first-line style.
|
| + if (parent() && renderer().style()->hasBorder()) {
|
| + const NinePieceImage& borderImage = renderer().style()->borderImage();
|
| + StyleImage* borderImageSource = borderImage.image();
|
| + bool hasBorderImage = borderImageSource && borderImageSource->canRender(renderer(), styleToUse->effectiveZoom());
|
| + if (hasBorderImage && !borderImageSource->isLoaded())
|
| + return; // Don't paint anything while we wait for the image to load.
|
| +
|
| + // The simple case is where we either have no border image or we are the only box for this object.
|
| + // In those cases only a single call to draw is required.
|
| + if (!hasBorderImage || (!prevLineBox() && !nextLineBox())) {
|
| + boxModelObject()->paintBorder(paintInfo, paintRect, renderer().style(isFirstLineStyle()), BackgroundBleedNone, includeLogicalLeftEdge(), includeLogicalRightEdge());
|
| + } else {
|
| + // We have a border image that spans multiple lines.
|
| + // We need to adjust tx and ty by the width of all previous lines.
|
| + // Think of border image painting on inlines as though you had one long line, a single continuous
|
| + // strip. Even though that strip has been broken up across multiple lines, you still paint it
|
| + // as though you had one single line. This means each line has to pick up the image where
|
| + // the previous line left off.
|
| + // FIXME: What the heck do we do with RTL here? The math we're using is obviously not right,
|
| + // but it isn't even clear how this should work at all.
|
| + LayoutUnit logicalOffsetOnLine = 0;
|
| + for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
|
| + logicalOffsetOnLine += curr->logicalWidth();
|
| + LayoutUnit totalLogicalWidth = logicalOffsetOnLine;
|
| + for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox())
|
| + totalLogicalWidth += curr->logicalWidth();
|
| + LayoutUnit stripX = adjustedPaintOffset.x() - (isHorizontal() ? logicalOffsetOnLine : LayoutUnit());
|
| + LayoutUnit stripY = adjustedPaintOffset.y() - (isHorizontal() ? LayoutUnit() : logicalOffsetOnLine);
|
| + LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : frameRect.width();
|
| + LayoutUnit stripHeight = isHorizontal() ? frameRect.height() : totalLogicalWidth;
|
| +
|
| + LayoutRect clipRect = clipRectForNinePieceImageStrip(this, borderImage, paintRect);
|
| + GraphicsContextStateSaver stateSaver(*paintInfo.context);
|
| + paintInfo.context->clip(clipRect);
|
| + boxModelObject()->paintBorder(paintInfo, LayoutRect(stripX, stripY, stripWidth, stripHeight), renderer().style(isFirstLineStyle()));
|
| }
|
| }
|
| }
|
|
|