diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index cb010c0a1a80..84fed85de70c 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -124,6 +124,7 @@ #include "DisplayItemClip.h" #include "mozilla/layers/WebRenderLayerManager.h" #include "prenv.h" +#include "TextDrawTarget.h" #ifdef MOZ_XUL #include "nsXULPopupManager.h" @@ -6067,6 +6068,29 @@ nsLayoutUtils::PaintTextShadow(const nsIFrame* aFrame, nsPresContext* presCtx = aFrame->PresContext(); nsContextBoxBlur contextBoxBlur; + + nscolor shadowColor; + if (shadowDetails->mHasColor) + shadowColor = shadowDetails->mColor; + else + shadowColor = aForegroundColor; + + // Webrender just needs the shadow details + if (auto* textDrawer = aContext->GetTextDrawer()) { + wr::TextShadow wrShadow; + + wrShadow.offset = { + presCtx->AppUnitsToFloatDevPixels(shadowDetails->mXOffset), + presCtx->AppUnitsToFloatDevPixels(shadowDetails->mYOffset) + }; + + wrShadow.blur_radius = presCtx->AppUnitsToFloatDevPixels(shadowDetails->mRadius); + wrShadow.color = wr::ToColorF(ToDeviceColor(shadowColor)); + + textDrawer->AppendShadow(wrShadow); + return; + } + gfxContext* shadowContext = contextBoxBlur.Init(shadowRect, 0, blurRadius, presCtx->AppUnitsPerDevPixel(), aDestCtx, aDirtyRect, nullptr, @@ -6074,11 +6098,7 @@ nsLayoutUtils::PaintTextShadow(const nsIFrame* aFrame, if (!shadowContext) continue; - nscolor shadowColor; - if (shadowDetails->mHasColor) - shadowColor = shadowDetails->mColor; - else - shadowColor = aForegroundColor; + aDestCtx->Save(); aDestCtx->NewPath(); diff --git a/layout/generic/TextOverflow.cpp b/layout/generic/TextOverflow.cpp index 739fc509ed77..53c63b015289 100644 --- a/layout/generic/TextOverflow.cpp +++ b/layout/generic/TextOverflow.cpp @@ -24,6 +24,7 @@ #include "mozilla/ArrayUtils.h" #include "mozilla/Likely.h" #include "nsISelection.h" +#include "TextDrawTarget.h" namespace mozilla { namespace css { @@ -208,6 +209,13 @@ public: } void PaintTextToContext(gfxContext* aCtx, nsPoint aOffsetFromRect); + + virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder, + mozilla::wr::IpcResourceUpdateQueue& aResources, + const StackingContextHelper& aSc, + layers::WebRenderLayerManager* aManager, + nsDisplayListBuilder* aDisplayListBuilder) override; + NS_DISPLAY_DECL_NAME("TextOverflow", TYPE_TEXT_OVERFLOW) private: nsRect mRect; // in reference frame coordinates @@ -278,6 +286,43 @@ nsDisplayTextOverflowMarker::PaintTextToContext(gfxContext* aCtx, } } +bool +nsDisplayTextOverflowMarker::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder, + mozilla::wr::IpcResourceUpdateQueue& aResources, + const StackingContextHelper& aSc, + layers::WebRenderLayerManager* aManager, + nsDisplayListBuilder* aDisplayListBuilder) +{ + if (!aManager->IsLayersFreeTransaction() || + !gfxPrefs::LayersAllowTextLayers() || + !CanUseAdvancedLayer(aDisplayListBuilder->GetWidgetLayerManager())) { + return false; + } + + bool snap; + nsRect bounds = GetBounds(aDisplayListBuilder, &snap); + if (bounds.IsEmpty()) { + return true; + } + + // Run the rendering algorithm to capture the glyphs and shadows + RefPtr textDrawer = new TextDrawTarget(); + RefPtr captureCtx = gfxContext::CreateOrNull(textDrawer); + // TextOverflowMarker only draws glyphs + textDrawer->StartDrawing(TextDrawTarget::Phase::eGlyphs); + Paint(aDisplayListBuilder, captureCtx); + + if (!textDrawer->CanSerializeFonts()) { + return false; + } + + textDrawer->CreateWebRenderCommands(aBuilder, aSc, aManager, this, bounds); + + + return true; +} + + TextOverflow::TextOverflow(nsDisplayListBuilder* aBuilder, nsIFrame* aBlockFrame) : mContentArea(aBlockFrame->GetWritingMode(),