From 7c3766dbb43d9f1af2779f2354eb4c90a583e9cd Mon Sep 17 00:00:00 2001 From: CJKu Date: Tue, 12 Apr 2016 21:58:22 +0800 Subject: [PATCH] Bug 759568 - Part 3. Render text-selection beneath background image; r=jfkthame MozReview-Commit-ID: 3VUGqyJOX8Q --- layout/generic/nsTextFrame.cpp | 49 +++++++++++++++++++++++++++++++--- layout/generic/nsTextFrame.h | 2 +- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 2f208354294c..c92b9ba1f254 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -98,6 +98,16 @@ using namespace mozilla; using namespace mozilla::dom; using namespace mozilla::gfx; +void +nsTextFrame::DrawPathCallbacks::NotifySelectionBackgroundNeedsFill( + const Rect& aBackgroundRect, + nscolor aColor, + DrawTarget& aDrawTarget) +{ + ColorPattern color(ToDeviceColor(aColor)); + aDrawTarget.FillRect(aBackgroundRect, color); +} + struct TabWidth { TabWidth(uint32_t aOffset, uint32_t aWidth) : mOffset(aOffset), mWidth(float(aWidth)) @@ -5922,7 +5932,6 @@ nsTextFrame::PaintOneShadow(const PaintShadowParams& aParams, } aParams.context->Save(); - aParams.context->NewPath(); aParams.context->SetColor(Color::FromABGR(shadowColor)); // Draw the text onto our alpha-only surface to capture the alpha values. @@ -6077,7 +6086,7 @@ nsTextFrame::PaintTextWithSelectionColors( // or from the ::-moz-selection pseudo-class if specified there nsCSSShadowArray* shadow = textStyle->GetTextShadow(); GetSelectionTextShadow(this, type, *aParams.textPaintStyle, &shadow); - if (shadow) { + if (shadow && !aParams.callbacks) { nscoord startEdge = iOffset; if (mTextRun->IsInlineReversed()) { startEdge -= hyphenWidth + @@ -6481,6 +6490,39 @@ nsTextFrame::PaintShadows(nsCSSShadowArray* aShadow, } } +static bool +ShouldDrawSelection(const nsIFrame* aFrame, + const nsTextFrame::PaintTextParams& aParams) +{ + // Normal text-with-selection rendering sequence is: + // * Paint background > Paint text-selection-color > Paint text + // When we have an parent frame with background-clip-text style, rendering + // sequence changes to: + // * Paint text-selection-color > Paint background > Paint text + // + // If there is a parent frame has background-clip:text style, + // text-selection-color should be drawn with the background of that parent + // frame, so we should not draw it again while painting text frames. + // + // "aParams.callbacks != nullptr": it means we are currently painting + // background. We should paint text-selection-color. + // "aParams.callbacks == nullptr": it means we are currently painting text + // frame itself. We should not paint text-selection-color. + if (!aFrame || aParams.callbacks) { + return true; + } + + const nsStyleBackground* bg = aFrame->StyleContext()->StyleBackground(); + const nsStyleImageLayers& layers = bg->mImage; + NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, layers) { + if (layers.mLayers[i].mClip == NS_STYLE_IMAGELAYER_CLIP_TEXT) { + return false; + } + } + + return ShouldDrawSelection(aFrame->GetParent(), aParams); +} + void nsTextFrame::PaintText(const PaintTextParams& aParams, const nsCharClipDisplayItem& aItem, @@ -6544,7 +6586,8 @@ nsTextFrame::PaintText(const PaintTextParams& aParams, textPaintStyle.SetResolveColors(!aParams.callbacks); // Fork off to the (slower) paint-with-selection path if necessary. - if (aItem.mIsFrameSelected.value()) { + if (aItem.mIsFrameSelected.value() && + ShouldDrawSelection(this->GetParent(), aParams)) { MOZ_ASSERT(aOpacity == 1.0f, "We don't support opacity with selections!"); gfxSkipCharsIterator tmp(provider.GetStart()); Range contentRange( diff --git a/layout/generic/nsTextFrame.h b/layout/generic/nsTextFrame.h index 8546295c4490..7036efbcc738 100644 --- a/layout/generic/nsTextFrame.h +++ b/layout/generic/nsTextFrame.h @@ -349,7 +349,7 @@ public: */ virtual void NotifySelectionBackgroundNeedsFill(const Rect& aBackgroundRect, nscolor aColor, - DrawTarget& aDrawTarget) { } + DrawTarget& aDrawTarget); /** * Called before (for under/over-line) or after (for line-through) the text