--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -496,16 +496,17 @@ bool
Factory::DoesBackendSupportDataDrawtarget(BackendType aType)
{
switch (aType) {
case BackendType::DIRECT2D:
case BackendType::DIRECT2D1_1:
case BackendType::RECORDING:
case BackendType::NONE:
case BackendType::BACKEND_LAST:
+ case BackendType::WEBRENDER_TEXT:
return false;
case BackendType::CAIRO:
case BackendType::SKIA:
return true;
}
return false;
}
--- a/gfx/2d/Types.h
+++ b/gfx/2d/Types.h
@@ -136,16 +136,17 @@ enum class DrawTargetType : int8_t {
enum class BackendType : int8_t {
NONE = 0,
DIRECT2D, // Used for version independent D2D objects.
CAIRO,
SKIA,
RECORDING,
DIRECT2D1_1,
+ WEBRENDER_TEXT,
// Add new entries above this line.
BACKEND_LAST
};
enum class FontType : int8_t {
DWRITE,
GDI,
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -18,16 +18,17 @@
#include "gfxPattern.h"
#include "gfxPlatform.h"
#include "gfxPrefs.h"
#include "GeckoProfiler.h"
#include "gfx2DGlue.h"
#include "mozilla/gfx/PathHelpers.h"
#include "mozilla/gfx/DrawTargetTiled.h"
#include <algorithm>
+#include "TextDrawTarget.h"
#if XP_WIN
#include "gfxWindowsPlatform.h"
#include "mozilla/gfx/DeviceManagerDx.h"
#endif
using namespace mozilla;
using namespace mozilla::gfx;
@@ -119,16 +120,25 @@ gfxContext::~gfxContext()
{
for (int i = mStateStack.Length() - 1; i >= 0; i--) {
for (unsigned int c = 0; c < mStateStack[i].pushedClips.Length(); c++) {
mStateStack[i].drawTarget->PopClip();
}
}
}
+mozilla::layout::TextDrawTarget*
+gfxContext::GetTextDrawer()
+{
+ if (mDT->GetBackendType() == BackendType::WEBRENDER_TEXT) {
+ return static_cast<mozilla::layout::TextDrawTarget*>(&*mDT);
+ }
+ return nullptr;
+}
+
void
gfxContext::Save()
{
CurrentState().transform = mTransform;
mStateStack.AppendElement(AzureState(CurrentState()));
CurrentState().pushedClips.Clear();
#ifdef DEBUG
CurrentState().mContentChanged = false;
--- a/gfx/thebes/gfxContext.h
+++ b/gfx/thebes/gfxContext.h
@@ -19,16 +19,19 @@
typedef struct _cairo cairo_t;
class GlyphBufferAzure;
namespace mozilla {
namespace gfx {
struct RectCornerRadii;
} // namespace gfx
+namespace layout {
+class TextDrawTarget;
+} // namespace layout
} // namespace mozilla
class ClipExporter;
/**
* This is the main class for doing actual drawing. It is initialized using
* a surface and can be drawn on. It manages various state information like
* a current transformation matrix (CTM), a current path, current color,
@@ -75,16 +78,21 @@ public:
* is responsible for handling this scenario as appropriate.
*/
static already_AddRefed<gfxContext>
CreatePreservingTransformOrNull(mozilla::gfx::DrawTarget* aTarget);
mozilla::gfx::DrawTarget *GetDrawTarget() { return mDT; }
/**
+ * Returns the DrawTarget if it's actually a TextDrawTarget.
+ */
+ mozilla::layout::TextDrawTarget* GetTextDrawer();
+
+ /**
** State
**/
// XXX document exactly what bits are saved
void Save();
void Restore();
/**
** Paths & Drawing
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -2001,17 +2001,16 @@ gfxFont::DrawGlyphs(const gfxShapedText
void
gfxFont::DrawEmphasisMarks(const gfxTextRun* aShapedText, gfxPoint* aPt,
uint32_t aOffset, uint32_t aCount,
const EmphasisMarkDrawParams& aParams)
{
gfxFloat& inlineCoord = aParams.isVertical ? aPt->y : aPt->x;
gfxTextRun::Range markRange(aParams.mark);
gfxTextRun::DrawParams params(aParams.context);
- params.textDrawer = aParams.textDrawer;
gfxFloat clusterStart = -std::numeric_limits<gfxFloat>::infinity();
bool shouldDrawEmphasisMark = false;
for (uint32_t i = 0, idx = aOffset; i < aCount; ++i, ++idx) {
if (aParams.spacing) {
inlineCoord += aParams.direction * aParams.spacing[i].mBefore;
}
if (aShapedText->IsClusterStart(idx) ||
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -70,19 +70,16 @@ class gfxMathTable;
struct gfxTextRunDrawCallbacks;
namespace mozilla {
class SVGContextPaint;
namespace gfx {
class GlyphRenderingOptions;
} // namespace gfx
-namespace layout {
-class TextDrawTarget;
-} // namespace layout
} // namespace mozilla
struct gfxFontStyle {
gfxFontStyle();
gfxFontStyle(uint8_t aStyle, uint16_t aWeight, int16_t aStretch,
gfxFloat aSize, nsIAtom *aLanguage, bool aExplicitLanguage,
float aSizeAdjust, bool aSystemFont,
bool aPrinterFont,
@@ -2308,17 +2305,16 @@ struct MOZ_STACK_CLASS FontDrawParams {
mozilla::gfx::DrawOptions drawOptions;
bool isVerticalFont;
bool haveSVGGlyphs;
bool haveColorGlyphs;
};
struct MOZ_STACK_CLASS EmphasisMarkDrawParams {
gfxContext* context;
- mozilla::layout::TextDrawTarget* textDrawer = nullptr;
gfxFont::Spacing* spacing;
gfxTextRun* mark;
gfxFloat advance;
gfxFloat direction;
bool isVertical;
};
#endif
--- a/gfx/thebes/gfxPlatform.h
+++ b/gfx/thebes/gfxPlatform.h
@@ -111,16 +111,18 @@ GetBackendName(mozilla::gfx::BackendType
case mozilla::gfx::BackendType::CAIRO:
return "cairo";
case mozilla::gfx::BackendType::SKIA:
return "skia";
case mozilla::gfx::BackendType::RECORDING:
return "recording";
case mozilla::gfx::BackendType::DIRECT2D1_1:
return "direct2d 1.1";
+ case mozilla::gfx::BackendType::WEBRENDER_TEXT:
+ return "webrender text";
case mozilla::gfx::BackendType::NONE:
return "none";
case mozilla::gfx::BackendType::BACKEND_LAST:
return "invalid";
}
MOZ_CRASH("Incomplete switch");
}
--- a/gfx/thebes/gfxTextRun.cpp
+++ b/gfx/thebes/gfxTextRun.cpp
@@ -602,17 +602,17 @@ gfxTextRun::Draw(Range aRange, gfxPoint
"GLYPH_PATH cannot be used with GLYPH_FILL, GLYPH_STROKE or GLYPH_STROKE_UNDERNEATH");
NS_ASSERTION(aParams.drawMode == DrawMode::GLYPH_PATH || !aParams.callbacks,
"callback must not be specified unless using GLYPH_PATH");
bool skipDrawing = mSkipDrawing;
if (aParams.drawMode & DrawMode::GLYPH_FILL) {
Color currentColor;
if (aParams.context->GetDeviceColor(currentColor) &&
- currentColor.a == 0 && !aParams.textDrawer) {
+ currentColor.a == 0 && !aParams.context->GetTextDrawer()) {
skipDrawing = true;
}
}
gfxFloat direction = GetDirection();
if (skipDrawing) {
// We don't need to draw anything;
@@ -720,26 +720,24 @@ gfxTextRun::Draw(Range aRange, gfxPoint
if (aParams.advanceWidth) {
*aParams.advanceWidth = advance;
}
}
// This method is mostly parallel to Draw().
void
gfxTextRun::DrawEmphasisMarks(gfxContext *aContext,
- mozilla::layout::TextDrawTarget* aTextDrawer,
gfxTextRun* aMark,
gfxFloat aMarkAdvance, gfxPoint aPt,
Range aRange, PropertyProvider* aProvider) const
{
MOZ_ASSERT(aRange.end <= GetLength());
EmphasisMarkDrawParams params;
params.context = aContext;
- params.textDrawer = aTextDrawer;
params.mark = aMark;
params.advance = aMarkAdvance;
params.direction = GetDirection();
params.isVertical = IsVertical();
gfxFloat& inlineCoord = params.isVertical ? aPt.y : aPt.x;
gfxFloat direction = params.direction;
--- a/gfx/thebes/gfxTextRun.h
+++ b/gfx/thebes/gfxTextRun.h
@@ -37,19 +37,16 @@ class gfxUserFontEntry;
class gfxUserFontSet;
class nsIAtom;
class nsLanguageAtomService;
class gfxMissingFontRecorder;
namespace mozilla {
class SVGContextPaint;
enum class StyleHyphens : uint8_t;
-namespace layout {
-class TextDrawTarget;
-};
};
/**
* Callback for Draw() to use when drawing text with mode
* DrawMode::GLYPH_PATH.
*/
struct gfxTextRunDrawCallbacks {
@@ -242,17 +239,16 @@ public:
// Return the appUnitsPerDevUnit value to be used when measuring.
// Only called if the hyphen width is requested.
virtual uint32_t GetAppUnitsPerDevUnit() const = 0;
};
struct MOZ_STACK_CLASS DrawParams
{
gfxContext* context;
- mozilla::layout::TextDrawTarget* textDrawer = nullptr;
DrawMode drawMode = DrawMode::GLYPH_FILL;
nscolor textStrokeColor = 0;
gfxPattern* textStrokePattern = nullptr;
const mozilla::gfx::StrokeOptions *strokeOpts = nullptr;
const mozilla::gfx::DrawOptions *drawOpts = nullptr;
PropertyProvider* provider = nullptr;
// If non-null, the advance width of the substring is set.
gfxFloat* advanceWidth = nullptr;
@@ -284,17 +280,16 @@ public:
void Draw(Range aRange, gfxPoint aPt, const DrawParams& aParams) const;
/**
* Draws the emphasis marks for this text run. Uses only GetSpacing
* from aProvider. The provided point is the baseline origin of the
* line of emphasis marks.
*/
void DrawEmphasisMarks(gfxContext* aContext,
- mozilla::layout::TextDrawTarget* aTextDrawer,
gfxTextRun* aMark,
gfxFloat aMarkAdvance, gfxPoint aPt,
Range aRange, PropertyProvider* aProvider) const;
/**
* Computes the ReflowMetrics for a substring.
* Uses GetSpacing from aBreakProvider.
* @param aBoundingBoxType which kind of bounding box (loose/tight)
--- a/layout/generic/TextDrawTarget.h
+++ b/layout/generic/TextDrawTarget.h
@@ -2,16 +2,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef TextDrawTarget_h
#define TextDrawTarget_h
#include "mozilla/gfx/2D.h"
+#include "mozilla/webrender/WebRenderApi.h"
namespace mozilla {
namespace layout {
using namespace gfx;
// This is used by all Advanced Layers users, so we use plain gfx types
struct TextRunFragment {
@@ -311,21 +312,21 @@ private:
nsTArray<SelectedTextRunFragment> mParts;
// A dummy to handle parts of the DrawTarget impl we don't care for
RefPtr<DrawTarget> mCurrentTarget;
// The rest of this is dummy implementations of DrawTarget's API
public:
DrawTargetType GetType() const override {
- return mCurrentTarget->GetType();
+ return DrawTargetType::SOFTWARE_RASTER;
}
BackendType GetBackendType() const override {
- return mCurrentTarget->GetBackendType();
+ return BackendType::WEBRENDER_TEXT;
}
bool IsRecording() const override { return true; }
bool IsCaptureDT() const override { return false; }
already_AddRefed<SourceSurface> Snapshot() override {
return mCurrentTarget->Snapshot();
}
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -4997,17 +4997,17 @@ public:
}
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override;
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion) const override;
- void RenderToContext(gfxContext* aCtx, TextDrawTarget* aTextDrawer, nsDisplayListBuilder* aBuilder, bool aIsRecording = false);
+ void RenderToContext(gfxContext* aCtx, nsDisplayListBuilder* aBuilder, bool aIsRecording = false);
bool CanApplyOpacity() const override
{
nsTextFrame* f = static_cast<nsTextFrame*>(mFrame);
if (f->IsSelected()) {
return false;
}
@@ -5138,17 +5138,17 @@ nsDisplayText::GetLayerState(nsDisplayLi
// If we haven't yet, compute the layout/style of the text by running
// the painting algorithm with a TextDrawTarget (doesn't actually paint).
if (!mTextDrawer) {
mTextDrawer = new TextDrawTarget();
RefPtr<gfxContext> captureCtx = gfxContext::CreateOrNull(mTextDrawer);
// TODO: Paint() checks mDisableSubpixelAA, we should too.
- RenderToContext(captureCtx, mTextDrawer, aBuilder, true);
+ RenderToContext(captureCtx, aBuilder, true);
}
if (!mTextDrawer->CanSerializeFonts()) {
return mozilla::LAYER_NONE;
}
// If we're using the webrender backend, then we're good to go!
if (aManager->GetBackendType() == layers::LayersBackend::LAYERS_WR) {
@@ -5166,17 +5166,17 @@ nsDisplayText::GetLayerState(nsDisplayLi
void
nsDisplayText::Paint(nsDisplayListBuilder* aBuilder,
gfxContext* aCtx) {
AUTO_PROFILER_LABEL("nsDisplayText::Paint", GRAPHICS);
DrawTargetAutoDisableSubpixelAntialiasing disable(aCtx->GetDrawTarget(),
mDisableSubpixelAA);
- RenderToContext(aCtx, nullptr, aBuilder);
+ RenderToContext(aCtx, aBuilder);
}
bool
nsDisplayText::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
@@ -5302,17 +5302,17 @@ nsDisplayText::BuildLayer(nsDisplayListB
layer->SetBounds(IntRect(destBounds.x, destBounds.y, destBounds.width, destBounds.height));
layer->SetBaseTransform(gfx::Matrix4x4::Translation(aContainerParameters.mOffset.x,
aContainerParameters.mOffset.y, 0));
return layer.forget();
}
void
-nsDisplayText::RenderToContext(gfxContext* aCtx, TextDrawTarget* aTextDrawer, nsDisplayListBuilder* aBuilder, bool aIsRecording)
+nsDisplayText::RenderToContext(gfxContext* aCtx, nsDisplayListBuilder* aBuilder, bool aIsRecording)
{
nsTextFrame* f = static_cast<nsTextFrame*>(mFrame);
// Add 1 pixel of dirty area around mVisibleRect to allow us to paint
// antialiased pixels beyond the measured text extents.
// This is temporary until we do this in the actual calculation of text extents.
auto A2D = mFrame->PresContext()->AppUnitsPerDevPixel();
LayoutDeviceRect extraVisible =
@@ -5350,17 +5350,16 @@ nsDisplayText::RenderToContext(gfxContex
gfxMatrix mat = aCtx->CurrentMatrix()
.PreTranslate(pt).PreScale(scaleFactor, 1.0).PreTranslate(-pt);
aCtx->SetMatrix (mat);
}
}
nsTextFrame::PaintTextParams params(aCtx);
params.framePt = gfxPoint(framePt.x, framePt.y);
params.dirtyRect = extraVisible;
- params.textDrawer = aTextDrawer;
if (aBuilder->IsForGenerateGlyphMask()) {
MOZ_ASSERT(!aBuilder->IsForPaintingSelectionBG());
params.state = nsTextFrame::PaintTextParams::GenerateTextMask;
} else if (aBuilder->IsForPaintingSelectionBG()) {
params.state = nsTextFrame::PaintTextParams::PaintTextBGColor;
} else {
params.state = nsTextFrame::PaintTextParams::PaintText;
@@ -6041,17 +6040,16 @@ nsTextFrame::ComputeSelectionUnderlineHe
enum class DecorationType
{
Normal, Selection
};
struct nsTextFrame::PaintDecorationLineParams
: nsCSSRendering::DecorationRectParams
{
gfxContext* context = nullptr;
- TextDrawTarget* textDrawer = nullptr;
LayoutDeviceRect dirtyRect;
Point pt;
const nscolor* overrideColor = nullptr;
nscolor color = NS_RGBA(0, 0, 0, 0);
gfxFloat icoordInFrame = 0.0f;
DecorationType decorationType = DecorationType::Normal;
DrawPathCallbacks* callbacks = nullptr;
};
@@ -6060,17 +6058,16 @@ void
nsTextFrame::PaintDecorationLine(const PaintDecorationLineParams& aParams)
{
nsCSSRendering::PaintDecorationLineParams params;
static_cast<nsCSSRendering::DecorationRectParams&>(params) = aParams;
params.dirtyRect = aParams.dirtyRect.ToUnknownRect();
params.pt = aParams.pt;
params.color = aParams.overrideColor ? *aParams.overrideColor : aParams.color;
params.icoordInFrame = Float(aParams.icoordInFrame);
- params.textDrawer = aParams.textDrawer;
if (aParams.callbacks) {
Rect path = nsCSSRendering::DecorationLineToPath(params);
if (aParams.decorationType == DecorationType::Normal) {
aParams.callbacks->PaintDecorationLine(path, params.color);
} else {
aParams.callbacks->PaintSelectionDecorationLine(path, params.color);
}
} else {
@@ -6080,54 +6077,54 @@ nsTextFrame::PaintDecorationLine(const P
}
/**
* This, plus kSelectionTypesWithDecorations, encapsulates all knowledge
* about drawing text decoration for selections.
*/
void
nsTextFrame::DrawSelectionDecorations(gfxContext* aContext,
- TextDrawTarget* aTextDrawer,
const LayoutDeviceRect& aDirtyRect,
SelectionType aSelectionType,
nsTextPaintStyle& aTextPaintStyle,
const TextRangeStyle &aRangeStyle,
const Point& aPt,
gfxFloat aICoordInFrame,
gfxFloat aWidth,
gfxFloat aAscent,
const gfxFont::Metrics& aFontMetrics,
DrawPathCallbacks* aCallbacks,
bool aVertical,
gfxFloat aDecorationOffsetDir,
uint8_t aDecoration)
{
PaintDecorationLineParams params;
params.context = aContext;
- params.textDrawer = aTextDrawer;
params.dirtyRect = aDirtyRect;
params.pt = aPt;
params.lineSize.width = aWidth;
params.ascent = aAscent;
params.offset = aDecoration == NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE ?
aFontMetrics.underlineOffset : aFontMetrics.maxAscent;
params.decoration = aDecoration;
params.decorationType = DecorationType::Selection;
params.callbacks = aCallbacks;
params.vertical = aVertical;
params.descentLimit =
ComputeDescentLimitForSelectionUnderline(aTextPaintStyle.PresContext(),
aFontMetrics);
float relativeSize;
+ auto* textDrawer = aContext->GetTextDrawer();
+
// Since this happens after text, all we *should* be allowed to do is strikeThrough.
// If this isn't true, we're at least bug-compatible with gecko!
- if (aTextDrawer) {
- aTextDrawer->StartDrawing(TextDrawTarget::Phase::eLineThrough);
+ if (textDrawer) {
+ textDrawer->StartDrawing(TextDrawTarget::Phase::eLineThrough);
}
switch (aSelectionType) {
case SelectionType::eIMERawClause:
case SelectionType::eIMESelectedRawClause:
case SelectionType::eIMEConvertedClause:
case SelectionType::eIMESelectedClause:
case SelectionType::eSpellCheck: {
@@ -6477,41 +6474,41 @@ nsTextFrame::PaintOneShadow(const PaintS
shadowRect, 0, blurRadius, A2D, aParams.context,
LayoutDevicePixel::ToAppUnits(aParams.dirtyRect, A2D), nullptr, aBlurFlags);
if (!shadowContext)
return;
nscolor shadowColor = aShadowDetails->mHasColor ? aShadowDetails->mColor
: aParams.foregroundColor;
- if (aParams.textDrawer) {
+ auto* textDrawer = aParams.context->GetTextDrawer();
+ if (textDrawer) {
wr::TextShadow wrShadow;
wrShadow.offset = {
PresContext()->AppUnitsToFloatDevPixels(aShadowDetails->mXOffset),
PresContext()->AppUnitsToFloatDevPixels(aShadowDetails->mYOffset)
};
wrShadow.blur_radius = PresContext()->AppUnitsToFloatDevPixels(aShadowDetails->mRadius);
wrShadow.color = wr::ToColorF(ToDeviceColor(shadowColor));
- aParams.textDrawer->AppendShadow(wrShadow);
+ textDrawer->AppendShadow(wrShadow);
return;
}
aParams.context->Save();
aParams.context->SetColor(Color::FromABGR(shadowColor));
// Draw the text onto our alpha-only surface to capture the alpha values.
// Remember that the box blur context has a device offset on it, so we don't need to
// translate any coordinates to fit on the surface.
gfxFloat advanceWidth;
nsTextPaintStyle textPaintStyle(this);
DrawTextParams params(shadowContext);
- params.textDrawer = nullptr; // Don't record anything that happens here
params.advanceWidth = &advanceWidth;
params.dirtyRect = aParams.dirtyRect;
params.framePt = aParams.framePt + shadowOffset;
params.provider = aParams.provider;
params.textStyle = &textPaintStyle;
params.textColor =
aParams.context == shadowContext ? shadowColor : NS_RGB(0, 0, 0);
params.clipEdges = aParams.clipEdges;
@@ -6587,27 +6584,30 @@ nsTextFrame::PaintTextWithSelectionColor
bool vertical = mTextRun->IsVertical();
const gfxFloat startIOffset = vertical ?
aParams.textBaselinePt.y - aParams.framePt.y :
aParams.textBaselinePt.x - aParams.framePt.x;
gfxFloat iOffset, hyphenWidth;
Range range; // in transformed string
TextRangeStyle rangeStyle;
// Draw background colors
+
+ auto* textDrawer = aParams.context->GetTextDrawer();
+
if (anyBackgrounds && !aParams.IsGenerateTextMask()) {
int32_t appUnitsPerDevPixel =
aParams.textPaintStyle->PresContext()->AppUnitsPerDevPixel();
SelectionIterator iterator(prevailingSelections, contentRange,
*aParams.provider, mTextRun, startIOffset);
SelectionType selectionType;
size_t selectionIndex = 0;
while (iterator.GetNextSegment(&iOffset, &range, &hyphenWidth,
&selectionType, &rangeStyle)) {
- if (aParams.textDrawer) {
- aParams.textDrawer->SetSelectionIndex(selectionIndex);
+ if (textDrawer) {
+ textDrawer->SetSelectionIndex(selectionIndex);
}
nscolor foreground, background;
GetSelectionTextColors(selectionType, *aParams.textPaintStyle,
rangeStyle, &foreground, &background);
// Draw background color
gfxFloat advance = hyphenWidth +
mTextRun->GetAdvanceWidth(range, aParams.provider);
@@ -6620,19 +6620,18 @@ nsTextFrame::PaintTextWithSelectionColor
} else {
bgRect = nsRect(aParams.framePt.x + offs, aParams.framePt.y,
advance, GetSize().height);
}
LayoutDeviceRect selectionRect =
LayoutDeviceRect::FromAppUnits(bgRect, appUnitsPerDevPixel);
- if (aParams.textDrawer) {
- aParams.textDrawer->SetSelectionRect(selectionRect,
- ToDeviceColor(background));
+ if (textDrawer) {
+ textDrawer->SetSelectionRect(selectionRect, ToDeviceColor(background));
} else {
PaintSelectionBackground(
*aParams.context->GetDrawTarget(), background, aParams.dirtyRect,
selectionRect, aParams.callbacks);
}
}
iterator.UpdateWithAdvance(advance);
++selectionIndex;
@@ -6640,17 +6639,16 @@ nsTextFrame::PaintTextWithSelectionColor
}
if (aParams.IsPaintBGColor()) {
return true;
}
gfxFloat advance;
DrawTextParams params(aParams.context);
- params.textDrawer = aParams.textDrawer;
params.dirtyRect = aParams.dirtyRect;
params.framePt = aParams.framePt;
params.provider = aParams.provider;
params.textStyle = aParams.textPaintStyle;
params.clipEdges = &aClipEdges;
params.advanceWidth = &advance;
params.callbacks = aParams.callbacks;
@@ -6662,18 +6660,18 @@ nsTextFrame::PaintTextWithSelectionColor
const nsStyleText* textStyle = StyleText();
SelectionIterator iterator(prevailingSelections, contentRange,
*aParams.provider, mTextRun, startIOffset);
SelectionType selectionType;
size_t selectionIndex = 0;
while (iterator.GetNextSegment(&iOffset, &range, &hyphenWidth,
&selectionType, &rangeStyle)) {
- if (aParams.textDrawer) {
- aParams.textDrawer->SetSelectionIndex(selectionIndex);
+ if (textDrawer) {
+ textDrawer->SetSelectionIndex(selectionIndex);
}
nscolor foreground, background;
if (aParams.IsGenerateTextMask()) {
foreground = NS_RGBA(0, 0, 0, 255);
} else {
GetSelectionTextColors(selectionType, *aParams.textPaintStyle,
rangeStyle, &foreground, &background);
@@ -6780,36 +6778,39 @@ nsTextFrame::PaintTextSelectionDecoratio
if (verticalRun) {
pt.x = (aParams.textBaselinePt.x - mAscent) / app;
} else {
pt.y = (aParams.textBaselinePt.y - mAscent) / app;
}
gfxFloat decorationOffsetDir = mTextRun->IsSidewaysLeft() ? -1.0 : 1.0;
SelectionType nextSelectionType;
TextRangeStyle selectedStyle;
+
size_t selectionIndex = 0;
+ auto* textDrawer = aParams.context->GetTextDrawer();
+
while (iterator.GetNextSegment(&iOffset, &range, &hyphenWidth,
&nextSelectionType, &selectedStyle)) {
- if (aParams.textDrawer) {
- aParams.textDrawer->SetSelectionIndex(selectionIndex);
+ if (textDrawer) {
+ textDrawer->SetSelectionIndex(selectionIndex);
}
gfxFloat advance = hyphenWidth +
mTextRun->GetAdvanceWidth(range, aParams.provider);
if (nextSelectionType == aSelectionType) {
if (verticalRun) {
pt.y = (aParams.framePt.y + iOffset -
(mTextRun->IsInlineReversed() ? advance : 0)) / app;
} else {
pt.x = (aParams.framePt.x + iOffset -
(mTextRun->IsInlineReversed() ? advance : 0)) / app;
}
gfxFloat width = Abs(advance) / app;
gfxFloat xInFrame = pt.x - (aParams.framePt.x / app);
DrawSelectionDecorations(
- aParams.context, aParams.textDrawer, aParams.dirtyRect, aSelectionType,
+ aParams.context, aParams.dirtyRect, aSelectionType,
*aParams.textPaintStyle, selectedStyle, pt, xInFrame,
width, mAscent / app, decorationMetrics, aParams.callbacks,
verticalRun, decorationOffsetDir, kDecoration);
}
iterator.UpdateWithAdvance(advance);
++selectionIndex;
}
}
@@ -6849,17 +6850,16 @@ nsTextFrame::PaintTextWithSelection(
}
}
return true;
}
void
nsTextFrame::DrawEmphasisMarks(gfxContext* aContext,
- TextDrawTarget* aTextDrawer,
WritingMode aWM,
const gfxPoint& aTextBaselinePt,
const gfxPoint& aFramePt, Range aRange,
const nscolor* aDecorationOverrideColor,
PropertyProvider* aProvider)
{
const EmphasisMarkInfo* info = GetProperty(EmphasisMarkProperty());
if (!info) {
@@ -6887,22 +6887,21 @@ nsTextFrame::DrawEmphasisMarks(gfxContex
} else {
if (aWM.IsVerticalRL()) {
pt.x -= info->baselineOffset;
} else {
pt.x += info->baselineOffset;
}
}
if (!isTextCombined) {
- mTextRun->DrawEmphasisMarks(aContext, aTextDrawer, info->textRun.get(),
+ mTextRun->DrawEmphasisMarks(aContext, info->textRun.get(),
info->advance, pt, aRange, aProvider);
} else {
pt.y += (GetSize().height - info->advance) / 2;
gfxTextRun::DrawParams params(aContext);
- params.textDrawer = aTextDrawer;
info->textRun->Draw(Range(info->textRun.get()), pt,
params);
}
}
nscolor
nsTextFrame::GetCaretColorAt(int32_t aOffset)
{
@@ -7265,17 +7264,16 @@ nsTextFrame::PaintText(const PaintTextPa
shadowParams.provider = &provider;
shadowParams.foregroundColor = foregroundColor;
shadowParams.clipEdges = &clipEdges;
PaintShadows(textStyle->mTextShadow, shadowParams);
}
gfxFloat advanceWidth;
DrawTextParams params(aParams.context);
- params.textDrawer = aParams.textDrawer;
params.dirtyRect = aParams.dirtyRect;
params.framePt = aParams.framePt;
params.provider = &provider;
params.advanceWidth = &advanceWidth;
params.textStyle = &textPaintStyle;
params.textColor = foregroundColor;
params.textStrokeColor = textStrokeColor;
params.textStrokeWidth = textPaintStyle.GetWebkitTextStrokeWidth();
@@ -7291,34 +7289,34 @@ nsTextFrame::PaintText(const PaintTextPa
static void
DrawTextRun(const gfxTextRun* aTextRun,
const gfxPoint& aTextBaselinePt,
gfxTextRun::Range aRange,
const nsTextFrame::DrawTextRunParams& aParams)
{
gfxTextRun::DrawParams params(aParams.context);
- params.textDrawer = aParams.textDrawer;
params.provider = aParams.provider;
params.advanceWidth = aParams.advanceWidth;
params.contextPaint = aParams.contextPaint;
params.callbacks = aParams.callbacks;
if (aParams.callbacks) {
aParams.callbacks->NotifyBeforeText(aParams.textColor);
params.drawMode = DrawMode::GLYPH_PATH;
aTextRun->Draw(aRange, aTextBaselinePt, params);
aParams.callbacks->NotifyAfterText();
} else {
- if (NS_GET_A(aParams.textColor) != 0 || aParams.textDrawer) {
+ auto* textDrawer = aParams.context->GetTextDrawer();
+ if (NS_GET_A(aParams.textColor) != 0 || textDrawer) {
aParams.context->SetColor(Color::FromABGR(aParams.textColor));
} else {
params.drawMode = DrawMode::GLYPH_STROKE;
}
- if ((NS_GET_A(aParams.textStrokeColor) != 0 || aParams.textDrawer) &&
+ if ((NS_GET_A(aParams.textStrokeColor) != 0 || textDrawer) &&
aParams.textStrokeWidth != 0.0f) {
StrokeOptions strokeOpts;
params.drawMode |= DrawMode::GLYPH_STROKE;
params.textStrokeColor = aParams.textStrokeColor;
strokeOpts.mLineWidth = aParams.textStrokeWidth;
params.strokeOpts = &strokeOpts;
aTextRun->Draw(aRange, aTextBaselinePt, params);
} else {
@@ -7328,18 +7326,19 @@ DrawTextRun(const gfxTextRun* aTextRun,
}
void
nsTextFrame::DrawTextRun(Range aRange, const gfxPoint& aTextBaselinePt,
const DrawTextRunParams& aParams)
{
MOZ_ASSERT(aParams.advanceWidth, "Must provide advanceWidth");
- if (aParams.textDrawer) {
- aParams.textDrawer->StartDrawing(TextDrawTarget::Phase::eGlyphs);
+ auto* textDrawer = aParams.context->GetTextDrawer();
+ if (textDrawer) {
+ textDrawer->StartDrawing(TextDrawTarget::Phase::eGlyphs);
}
::DrawTextRun(mTextRun, aTextBaselinePt, aRange, aParams);
if (aParams.drawSoftHyphen) {
// Don't use ctx as the context, because we need a reference context here,
// ctx may be transformed.
RefPtr<gfxTextRun> hyphenTextRun =
@@ -7416,17 +7415,16 @@ nsTextFrame::DrawTextRunAndDecorations(R
// so we will multiply the values from metrics by this factor.
gfxFloat decorationOffsetDir = mTextRun->IsSidewaysLeft() ? -1.0 : 1.0;
PaintDecorationLineParams params;
params.context = aParams.context;
params.dirtyRect = aParams.dirtyRect;
params.overrideColor = aParams.decorationOverrideColor;
params.callbacks = aParams.callbacks;
- params.textDrawer = aParams.textDrawer;
// pt is the physical point where the decoration is to be drawn,
// relative to the frame; one of its coordinates will be updated below.
params.pt = Point(x / app, y / app);
Float& bCoord = verticalDec ? params.pt.x : params.pt.y;
params.lineSize = Size(measure / app, 0);
params.ascent = ascent;
params.vertical = verticalDec;
@@ -7463,30 +7461,32 @@ nsTextFrame::DrawTextRunAndDecorations(R
bCoord = (frameBStart - dec.mBaselineOffset) / app;
params.color = dec.mColor;
params.offset = decorationOffsetDir * metrics.*lineOffset;
params.style = dec.mStyle;
PaintDecorationLine(params);
};
+ auto* textDrawer = aParams.context->GetTextDrawer();
+
// Underlines
- if (aParams.textDrawer && aDecorations.mUnderlines.Length() > 0) {
- aParams.textDrawer->StartDrawing(TextDrawTarget::Phase::eUnderline);
+ if (textDrawer && aDecorations.mUnderlines.Length() > 0) {
+ textDrawer->StartDrawing(TextDrawTarget::Phase::eUnderline);
}
//
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
for (const LineDecoration& dec : Reversed(aDecorations.mUnderlines)) {
paintDecorationLine(dec, &Metrics::underlineSize,
&Metrics::underlineOffset);
}
// Overlines
- if (aParams.textDrawer && aDecorations.mOverlines.Length() > 0) {
- aParams.textDrawer->StartDrawing(TextDrawTarget::Phase::eOverline);
+ if (textDrawer && aDecorations.mOverlines.Length() > 0) {
+ textDrawer->StartDrawing(TextDrawTarget::Phase::eOverline);
}
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
for (const LineDecoration& dec : Reversed(aDecorations.mOverlines)) {
paintDecorationLine(dec, &Metrics::underlineSize, &Metrics::maxAscent);
}
{
gfxContextMatrixAutoSaveRestore unscaledRestorer;
@@ -7496,26 +7496,26 @@ nsTextFrame::DrawTextRunAndDecorations(R
}
// CSS 2.1 mandates that text be painted after over/underlines,
// and *then* line-throughs
DrawTextRun(aRange, aTextBaselinePt, aParams);
}
// Emphasis marks
- if (aParams.textDrawer) {
- aParams.textDrawer->StartDrawing(TextDrawTarget::Phase::eEmphasisMarks);
- }
- DrawEmphasisMarks(aParams.context, aParams.textDrawer, wm,
+ if (textDrawer) {
+ textDrawer->StartDrawing(TextDrawTarget::Phase::eEmphasisMarks);
+ }
+ DrawEmphasisMarks(aParams.context, wm,
aTextBaselinePt, aParams.framePt, aRange,
aParams.decorationOverrideColor, aParams.provider);
// Line-throughs
- if (aParams.textDrawer && aDecorations.mStrikes.Length() > 0) {
- aParams.textDrawer->StartDrawing(TextDrawTarget::Phase::eLineThrough);
+ if (textDrawer && aDecorations.mStrikes.Length() > 0) {
+ textDrawer->StartDrawing(TextDrawTarget::Phase::eLineThrough);
}
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
for (const LineDecoration& dec : Reversed(aDecorations.mStrikes)) {
paintDecorationLine(dec, &Metrics::strikeoutSize,
&Metrics::strikeoutOffset);
}
}
--- a/layout/generic/nsTextFrame.h
+++ b/layout/generic/nsTextFrame.h
@@ -438,34 +438,33 @@ public:
* has been emitted to the gfxContext.
*/
virtual void NotifySelectionDecorationLinePathEmitted() {}
};
struct PaintTextParams
{
gfxContext* context;
- TextDrawTarget* textDrawer;
gfxPoint framePt;
LayoutDeviceRect dirtyRect;
mozilla::SVGContextPaint* contextPaint = nullptr;
DrawPathCallbacks* callbacks = nullptr;
enum
{
PaintText, // Normal text painting.
PaintTextBGColor, // Only paint background color of the selected text
// range in this state.
GenerateTextMask // To generate a mask from a text frame. Should
// only paint text itself with opaque color.
// Text shadow, text selection color and text
// decoration are all discarded in this state.
};
uint8_t state = PaintText;
explicit PaintTextParams(gfxContext* aContext)
- : context(aContext), textDrawer(nullptr)
+ : context(aContext)
{
}
bool IsPaintText() const { return state == PaintText; }
bool IsGenerateTextMask() const { return state == GenerateTextMask; }
bool IsPaintBGColor() const { return state == PaintTextBGColor; }
};
@@ -478,27 +477,26 @@ public:
explicit PaintTextSelectionParams(const PaintTextParams& aParams)
: PaintTextParams(aParams)
{}
};
struct DrawTextRunParams
{
gfxContext* context;
- TextDrawTarget* textDrawer;
PropertyProvider* provider = nullptr;
gfxFloat* advanceWidth = nullptr;
mozilla::SVGContextPaint* contextPaint = nullptr;
DrawPathCallbacks* callbacks = nullptr;
nscolor textColor = NS_RGBA(0, 0, 0, 0);
nscolor textStrokeColor = NS_RGBA(0, 0, 0, 0);
float textStrokeWidth = 0.0f;
bool drawSoftHyphen = false;
explicit DrawTextRunParams(gfxContext* aContext)
- : context(aContext), textDrawer(nullptr)
+ : context(aContext)
{}
};
struct DrawTextParams : DrawTextRunParams
{
gfxPoint framePt;
LayoutDeviceRect dirtyRect;
const nsTextPaintStyle* textStyle = nullptr;
@@ -533,17 +531,16 @@ public:
SelectionTypeMask* aAllSelectionTypeMask,
const nsCharClipDisplayItem::ClipEdges& aClipEdges);
// helper: paint text decorations for text selected by aSelectionType
void PaintTextSelectionDecorations(const PaintTextSelectionParams& aParams,
const mozilla::UniquePtr<SelectionDetails>& aDetails,
SelectionType aSelectionType);
void DrawEmphasisMarks(gfxContext* aContext,
- TextDrawTarget* aTextDrawer,
mozilla::WritingMode aWM,
const gfxPoint& aTextBaselinePt,
const gfxPoint& aFramePt,
Range aRange,
const nscolor* aDecorationOverrideColor,
PropertyProvider* aProvider);
nscolor GetCaretColorAt(int32_t aOffset) override;
@@ -706,26 +703,24 @@ protected:
struct PaintShadowParams
{
gfxTextRun::Range range;
LayoutDeviceRect dirtyRect;
gfxPoint framePt;
gfxPoint textBaselinePt;
gfxContext* context;
- TextDrawTarget* textDrawer;
nscolor foregroundColor = NS_RGBA(0, 0, 0, 0);
const nsCharClipDisplayItem::ClipEdges* clipEdges = nullptr;
PropertyProvider* provider = nullptr;
nscoord leftSideOffset = 0;
explicit PaintShadowParams(const PaintTextParams& aParams)
: dirtyRect(aParams.dirtyRect)
, framePt(aParams.framePt)
, context(aParams.context)
- , textDrawer(aParams.textDrawer)
{
}
};
void PaintOneShadow(const PaintShadowParams& aParams,
nsCSSShadowItem* aShadowDetails,
gfxRect& aBoundingBox,
uint32_t aBlurFlags);
@@ -824,17 +819,16 @@ protected:
// If the result rect is larger than the given rect, this returns true.
bool CombineSelectionUnderlineRect(nsPresContext* aPresContext,
nsRect& aRect);
/**
* Utility methods to paint selection.
*/
void DrawSelectionDecorations(gfxContext* aContext,
- TextDrawTarget* aTextDrawer,
const LayoutDeviceRect& aDirtyRect,
mozilla::SelectionType aSelectionType,
nsTextPaintStyle& aTextPaintStyle,
const TextRangeStyle& aRangeStyle,
const Point& aPt,
gfxFloat aICoordInFrame,
gfxFloat aWidth,
gfxFloat aAscent,
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -3824,16 +3824,21 @@ nsCSSRendering::PaintDecorationLine(nsIF
ColorPattern colorPat(color);
StrokeOptions strokeOptions(lineThickness);
DrawOptions drawOptions;
Float dash[2];
AutoPopClips autoPopClips(&aDrawTarget);
+ mozilla::layout::TextDrawTarget* textDrawer = nullptr;
+ if (aDrawTarget.GetBackendType() == BackendType::WEBRENDER_TEXT) {
+ textDrawer = static_cast<mozilla::layout::TextDrawTarget*>(&aDrawTarget);
+ }
+
switch (aParams.style) {
case NS_STYLE_TEXT_DECORATION_STYLE_SOLID:
case NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE:
break;
case NS_STYLE_TEXT_DECORATION_STYLE_DASHED: {
autoPopClips.PushClipRect(rect);
Float dashWidth = lineThickness * DOT_LENGTH * DASH_LENGTH;
dash[0] = dashWidth;
@@ -3894,18 +3899,18 @@ nsCSSRendering::PaintDecorationLine(nsIF
}
switch (aParams.style) {
case NS_STYLE_TEXT_DECORATION_STYLE_SOLID:
case NS_STYLE_TEXT_DECORATION_STYLE_DOTTED:
case NS_STYLE_TEXT_DECORATION_STYLE_DASHED: {
Point p1 = rect.TopLeft();
Point p2 = aParams.vertical ? rect.BottomLeft() : rect.TopRight();
- if (aParams.textDrawer) {
- aParams.textDrawer->AppendDecoration(
+ if (textDrawer) {
+ textDrawer->AppendDecoration(
p1, p2, lineThickness, aParams.vertical, color, aParams.style);
} else {
aDrawTarget.StrokeLine(p1, p2, colorPat, strokeOptions, drawOptions);
}
return;
}
case NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE: {
/**
@@ -3929,21 +3934,21 @@ nsCSSRendering::PaintDecorationLine(nsIF
rect.width -= lineThickness;
} else {
rect.height -= lineThickness;
}
Point p1b = aParams.vertical ? rect.TopRight() : rect.BottomLeft();
Point p2b = rect.BottomRight();
- if (aParams.textDrawer) {
- aParams.textDrawer->AppendDecoration(
+ if (textDrawer) {
+ textDrawer->AppendDecoration(
p1a, p2a, lineThickness, aParams.vertical, color,
NS_STYLE_TEXT_DECORATION_STYLE_SOLID);
- aParams.textDrawer->AppendDecoration(
+ textDrawer->AppendDecoration(
p1b, p2b, lineThickness, aParams.vertical, color,
NS_STYLE_TEXT_DECORATION_STYLE_SOLID);
} else {
aDrawTarget.StrokeLine(p1a, p2a, colorPat, strokeOptions, drawOptions);
aDrawTarget.StrokeLine(p1b, p2b, colorPat, strokeOptions, drawOptions);
}
return;
}
@@ -4003,21 +4008,21 @@ nsCSSRendering::PaintDecorationLine(nsIF
int32_t skipCycles = floor((dirtyRectICoord - rectICoord) / cycleLength);
if (skipCycles > 0) {
rectICoord += skipCycles * cycleLength;
rectISize -= skipCycles * cycleLength;
}
rectICoord += lineThickness / 2.0;
- if (aParams.textDrawer) {
+ if (textDrawer) {
Point p1 = rect.TopLeft();
Point p2 = aParams.vertical ? rect.BottomLeft() : rect.TopRight();
- aParams.textDrawer->AppendDecoration(
+ textDrawer->AppendDecoration(
p1, p2, adv, aParams.vertical, color,
NS_STYLE_TEXT_DECORATION_STYLE_WAVY);
return;
}
Point pt(rect.TopLeft());
Float& ptICoord = aParams.vertical ? pt.y : pt.x;
Float& ptBCoord = aParams.vertical ? pt.x : pt.y;
--- a/layout/painting/nsCSSRendering.h
+++ b/layout/painting/nsCSSRendering.h
@@ -14,17 +14,16 @@
#include "mozilla/gfx/PathHelpers.h"
#include "mozilla/gfx/Rect.h"
#include "mozilla/TypedEnumBits.h"
#include "nsLayoutUtils.h"
#include "nsStyleStruct.h"
#include "nsIFrame.h"
#include "nsImageRenderer.h"
#include "nsCSSRenderingBorders.h"
-#include "TextDrawTarget.h"
class gfxContext;
class nsStyleContext;
class nsPresContext;
namespace mozilla {
namespace gfx {
@@ -595,17 +594,16 @@ struct nsCSSRendering {
Rect dirtyRect;
// The top/left edge of the text.
Point pt;
// The color of the decoration line.
nscolor color = NS_RGBA(0, 0, 0, 0);
// The distance between the left edge of the given frame and the
// position of the text as positioned without offset of the shadow.
Float icoordInFrame = 0.0f;
- mozilla::layout::TextDrawTarget* textDrawer = nullptr;
};
/**
* Function for painting the decoration lines for the text.
*
* input:
* @param aFrame the frame which needs the decoration line
* @param aGfxContext