Bug 1251995 part 3 - Use struct to pass params for gfxTextRun::Draw. r=jfkthame

MozReview-Commit-ID: HAqtS3VXPHH

--HG--
extra : rebase_source : de01c02d3baf3e8c648d6301bd6ff283d76ae212
This commit is contained in:
Xidorn Quan 2016-02-29 19:06:05 +08:00
Родитель 8e3206382b
Коммит 11bea4b5a2
7 изменённых файлов: 86 добавлений и 81 удалений

Просмотреть файл

@ -373,8 +373,9 @@ nsFontMetrics::DrawString(const char *aString, uint32_t aLength,
pt.x += textRun->GetAdvanceWidth(range, &provider);
}
}
textRun->Draw(aContext->ThebesContext(), pt, DrawMode::GLYPH_FILL,
range, &provider, nullptr, nullptr);
gfxTextRun::DrawParams params(aContext->ThebesContext());
params.provider = &provider;
textRun->Draw(range, pt, params);
}
void
@ -400,8 +401,9 @@ nsFontMetrics::DrawString(const char16_t* aString, uint32_t aLength,
pt.x += textRun->GetAdvanceWidth(range, &provider);
}
}
textRun->Draw(aContext->ThebesContext(), pt, DrawMode::GLYPH_FILL,
range, &provider, nullptr, nullptr);
gfxTextRun::DrawParams params(aContext->ThebesContext());
params.provider = &provider;
textRun->Draw(range, pt, params);
}
static nsBoundingMetrics

Просмотреть файл

@ -1944,6 +1944,7 @@ gfxFont::DrawEmphasisMarks(gfxTextRun* aShapedText, gfxPoint* aPt,
{
gfxFloat& inlineCoord = aParams.isVertical ? aPt->y : aPt->x;
gfxTextRun::Range markRange(aParams.mark);
gfxTextRun::DrawParams params(aParams.context);
gfxFloat clusterStart = -std::numeric_limits<gfxFloat>::infinity();
bool shouldDrawEmphasisMark = false;
@ -1965,8 +1966,7 @@ gfxFont::DrawEmphasisMarks(gfxTextRun* aShapedText, gfxPoint* aPt,
// Move the coord backward to get the needed start point.
gfxFloat delta = (clusterAdvance + aParams.advance) / 2;
inlineCoord -= delta;
aParams.mark->Draw(aParams.context, *aPt, DrawMode::GLYPH_FILL,
markRange, nullptr, nullptr, nullptr);
aParams.mark->Draw(markRange, *aPt, params);
inlineCoord += delta;
shouldDrawEmphasisMark = false;
}

Просмотреть файл

@ -564,23 +564,20 @@ struct BufferAlphaColor {
};
void
gfxTextRun::Draw(gfxContext *aContext, gfxPoint aPt, DrawMode aDrawMode,
Range aRange,
PropertyProvider *aProvider, gfxFloat *aAdvanceWidth,
gfxTextContextPaint *aContextPaint,
gfxTextRunDrawCallbacks *aCallbacks)
gfxTextRun::Draw(Range aRange, gfxPoint aPt, const DrawParams& aParams)
{
NS_ASSERTION(aRange.end <= GetLength(), "Substring out of range");
NS_ASSERTION(aDrawMode == DrawMode::GLYPH_PATH ||
!(int(aDrawMode) & int(DrawMode::GLYPH_PATH)),
NS_ASSERTION(aParams.drawMode == DrawMode::GLYPH_PATH ||
!(int(aParams.drawMode) & int(DrawMode::GLYPH_PATH)),
"GLYPH_PATH cannot be used with GLYPH_FILL, GLYPH_STROKE or GLYPH_STROKE_UNDERNEATH");
NS_ASSERTION(aDrawMode == DrawMode::GLYPH_PATH || !aCallbacks,
NS_ASSERTION(aParams.drawMode == DrawMode::GLYPH_PATH || !aParams.callbacks,
"callback must not be specified unless using GLYPH_PATH");
bool skipDrawing = mSkipDrawing;
if (aDrawMode == DrawMode::GLYPH_FILL) {
if (aParams.drawMode == DrawMode::GLYPH_FILL) {
Color currentColor;
if (aContext->GetDeviceColor(currentColor) && currentColor.a == 0) {
if (aParams.context->GetDeviceColor(currentColor) &&
currentColor.a == 0) {
skipDrawing = true;
}
}
@ -590,12 +587,11 @@ gfxTextRun::Draw(gfxContext *aContext, gfxPoint aPt, DrawMode aDrawMode,
if (skipDrawing) {
// We don't need to draw anything;
// but if the caller wants advance width, we need to compute it here
if (aAdvanceWidth) {
gfxTextRun::Metrics metrics = MeasureText(aRange,
gfxFont::LOOSE_INK_EXTENTS,
aContext->GetDrawTarget(),
aProvider);
*aAdvanceWidth = metrics.mAdvanceWidth * direction;
if (aParams.advanceWidth) {
gfxTextRun::Metrics metrics = MeasureText(
aRange, gfxFont::LOOSE_INK_EXTENTS,
aParams.context->GetDrawTarget(), aParams.provider);
*aParams.advanceWidth = metrics.mAdvanceWidth * direction;
}
// return without drawing
@ -604,19 +600,18 @@ gfxTextRun::Draw(gfxContext *aContext, gfxPoint aPt, DrawMode aDrawMode,
// synthetic bolding draws glyphs twice ==> colors with opacity won't draw
// correctly unless first drawn without alpha
BufferAlphaColor syntheticBoldBuffer(aContext);
BufferAlphaColor syntheticBoldBuffer(aParams.context);
Color currentColor;
bool needToRestore = false;
if (aDrawMode == DrawMode::GLYPH_FILL &&
HasNonOpaqueNonTransparentColor(aContext, currentColor) &&
if (aParams.drawMode == DrawMode::GLYPH_FILL &&
HasNonOpaqueNonTransparentColor(aParams.context, currentColor) &&
HasSyntheticBoldOrColor(this, aRange)) {
needToRestore = true;
// measure text, use the bounding box
gfxTextRun::Metrics metrics = MeasureText(aRange,
gfxFont::LOOSE_INK_EXTENTS,
aContext->GetDrawTarget(),
aProvider);
gfxTextRun::Metrics metrics = MeasureText(
aRange, gfxFont::LOOSE_INK_EXTENTS,
aParams.context->GetDrawTarget(), aParams.provider);
metrics.mBoundingBox.MoveBy(aPt);
syntheticBoldBuffer.PushSolidColor(metrics.mBoundingBox, currentColor,
GetAppUnitsPerDevUnit());
@ -625,17 +620,19 @@ gfxTextRun::Draw(gfxContext *aContext, gfxPoint aPt, DrawMode aDrawMode,
// Set up parameters that will be constant across all glyph runs we need
// to draw, regardless of the font used.
TextRunDrawParams params;
params.context = aContext;
params.context = aParams.context;
params.devPerApp = 1.0 / double(GetAppUnitsPerDevUnit());
params.isVerticalRun = IsVertical();
params.isRTL = IsRightToLeft();
params.direction = direction;
params.drawMode = aDrawMode;
params.callbacks = aCallbacks;
params.runContextPaint = aContextPaint;
params.paintSVGGlyphs = !aCallbacks || aCallbacks->mShouldPaintSVGGlyphs;
params.dt = aContext->GetDrawTarget();
params.fontSmoothingBGColor = aContext->GetFontSmoothingBackgroundColor();
params.drawMode = aParams.drawMode;
params.callbacks = aParams.callbacks;
params.runContextPaint = aParams.contextPaint;
params.paintSVGGlyphs = !aParams.callbacks ||
aParams.callbacks->mShouldPaintSVGGlyphs;
params.dt = aParams.context->GetDrawTarget();
params.fontSmoothingBGColor =
aParams.context->GetFontSmoothingBackgroundColor();
GlyphRunIterator iter(this, aRange);
gfxFloat advance = 0.0;
@ -647,23 +644,24 @@ gfxTextRun::Draw(gfxContext *aContext, gfxPoint aPt, DrawMode aDrawMode,
Range ligatureRange(start, end);
ShrinkToLigatureBoundaries(&ligatureRange);
bool drawPartial = aDrawMode == DrawMode::GLYPH_FILL ||
(aDrawMode == DrawMode::GLYPH_PATH && aCallbacks);
bool drawPartial = aParams.drawMode == DrawMode::GLYPH_FILL ||
(aParams.drawMode == DrawMode::GLYPH_PATH &&
aParams.callbacks);
gfxPoint origPt = aPt;
if (drawPartial) {
DrawPartialLigature(font, Range(start, ligatureRange.start),
&aPt, aProvider, params,
&aPt, aParams.provider, params,
iter.GetGlyphRun()->mOrientation);
}
DrawGlyphs(font, ligatureRange, &aPt,
aProvider, ligatureRange, params,
aParams.provider, ligatureRange, params,
iter.GetGlyphRun()->mOrientation);
if (drawPartial) {
DrawPartialLigature(font, Range(ligatureRange.end, end),
&aPt, aProvider, params,
&aPt, aParams.provider, params,
iter.GetGlyphRun()->mOrientation);
}
@ -679,8 +677,8 @@ gfxTextRun::Draw(gfxContext *aContext, gfxPoint aPt, DrawMode aDrawMode,
syntheticBoldBuffer.PopAlpha();
}
if (aAdvanceWidth) {
*aAdvanceWidth = advance;
if (aParams.advanceWidth) {
*aParams.advanceWidth = advance;
}
}

Просмотреть файл

@ -232,32 +232,39 @@ public:
uint32_t mCurrentChar;
};
struct DrawParams
{
gfxContext* context;
DrawMode drawMode = DrawMode::GLYPH_FILL;
PropertyProvider* provider = nullptr;
// If non-null, the advance width of the substring is set.
gfxFloat* advanceWidth = nullptr;
gfxTextContextPaint* contextPaint = nullptr;
gfxTextRunDrawCallbacks* callbacks = nullptr;
explicit DrawParams(gfxContext* aContext) : context(aContext) {}
};
/**
* Draws a substring. Uses only GetSpacing from aBreakProvider.
* The provided point is the baseline origin on the left of the string
* for LTR, on the right of the string for RTL.
* @param aAdvanceWidth if non-null, the advance width of the substring
* is returned here.
*
* Drawing should respect advance widths in the sense that for LTR runs,
* Draw(ctx, pt, Range(start, middle), dirty, &provider, &advance) followed by
* Draw(ctx, gfxPoint(pt.x + advance, pt.y), Range(middle, end),
* dirty, &provider, nullptr) should have the same effect as
* Draw(ctx, pt, Range(start, end), dirty, &provider, nullptr).
* Draw(Range(start, middle), pt, ...) followed by
* Draw(Range(middle, end), gfxPoint(pt.x + advance, pt.y), ...)
* should have the same effect as
* Draw(Range(start, end), pt, ...)
*
* For RTL runs the rule is:
* Draw(ctx, pt, Range(middle, end), dirty, &provider, &advance) followed by
* Draw(ctx, gfxPoint(pt.x + advance, pt.y), Range(start, middle),
* dirty, &provider, nullptr) should have the same effect as
* Draw(ctx, pt, Range(start, end), dirty, &provider, nullptr).
* Draw(Range(middle, end), pt, ...) followed by
* Draw(Range(start, middle), gfxPoint(pt.x + advance, pt.y), ...)
* should have the same effect as
* Draw(Range(start, end), pt, ...)
*
* Glyphs should be drawn in logical content order, which can be significant
* if they overlap (perhaps due to negative spacing).
*/
void Draw(gfxContext *aContext, gfxPoint aPt,
DrawMode aDrawMode, Range aRange,
PropertyProvider *aProvider,
gfxFloat *aAdvanceWidth, gfxTextContextPaint *aContextPaint,
gfxTextRunDrawCallbacks *aCallbacks = nullptr);
void Draw(Range aRange, gfxPoint aPt, const DrawParams& aParams);
/**
* Draws the emphasis marks for this text run. Uses only GetSpacing

Просмотреть файл

@ -252,8 +252,8 @@ nsDisplayTextOverflowMarker::PaintTextToContext(nsRenderingContext* aCtx,
NS_ASSERTION(!textRun->IsRightToLeft(),
"Ellipsis textruns should always be LTR!");
gfxPoint gfxPt(pt.x, pt.y);
textRun->Draw(aCtx->ThebesContext(), gfxPt, DrawMode::GLYPH_FILL,
gfxTextRun::Range(textRun), nullptr, nullptr, nullptr);
textRun->Draw(gfxTextRun::Range(textRun), gfxPt,
gfxTextRun::DrawParams(aCtx->ThebesContext()));
}
} else {
RefPtr<nsFontMetrics> fm;

Просмотреть файл

@ -6586,17 +6586,20 @@ DrawTextRun(gfxTextRun* aTextRun,
gfxTextContextPaint* aContextPaint,
nsTextFrame::DrawPathCallbacks* aCallbacks)
{
DrawMode drawMode = aCallbacks ? DrawMode::GLYPH_PATH :
DrawMode::GLYPH_FILL;
gfxTextRun::DrawParams params(aCtx);
params.drawMode = aCallbacks ? DrawMode::GLYPH_PATH
: DrawMode::GLYPH_FILL;
params.provider = aProvider;
params.advanceWidth = aAdvanceWidth;
params.contextPaint = aContextPaint;
params.callbacks = aCallbacks;
if (aCallbacks) {
aCallbacks->NotifyBeforeText(aTextColor);
aTextRun->Draw(aCtx, aTextBaselinePt, drawMode, aRange,
aProvider, aAdvanceWidth, aContextPaint, aCallbacks);
aTextRun->Draw(aRange, aTextBaselinePt, params);
aCallbacks->NotifyAfterText();
} else {
aCtx->SetColor(Color::FromABGR(aTextColor));
aTextRun->Draw(aCtx, aTextBaselinePt, drawMode, aRange,
aProvider, aAdvanceWidth, aContextPaint);
aTextRun->Draw(aRange, aTextBaselinePt, params);
}
}

Просмотреть файл

@ -2146,9 +2146,8 @@ nsMathMLChar::PaintForeground(nsPresContext* aPresContext,
// draw a single glyph (base size or size variant)
// XXXfredw verify if mGlyphs[0] is non-null to workaround bug 973322.
if (mGlyphs[0]) {
mGlyphs[0]->Draw(thebesContext, gfxPoint(0.0, mUnscaledAscent),
DrawMode::GLYPH_FILL, Range(mGlyphs[0]),
nullptr, nullptr, nullptr);
mGlyphs[0]->Draw(Range(mGlyphs[0]), gfxPoint(0.0, mUnscaledAscent),
gfxTextRun::DrawParams(thebesContext));
}
break;
case DRAW_PARTS: {
@ -2275,6 +2274,8 @@ nsMathMLChar::PaintVertically(nsPresContext* aPresContext,
mBoundingMetrics.rightBearing - mBoundingMetrics.leftBearing;
unionRect.Inflate(oneDevPixel, oneDevPixel);
gfxTextRun::DrawParams params(aThebesContext);
/////////////////////////////////////
// draw top, middle, bottom
for (i = 0; i <= 2; ++i) {
@ -2303,9 +2304,7 @@ nsMathMLChar::PaintVertically(nsPresContext* aPresContext,
}
if (!clipRect.IsEmpty()) {
AutoPushClipRect clip(aThebesContext, oneDevPixel, clipRect);
mGlyphs[i]->Draw(aThebesContext, gfxPoint(dx, dy),
DrawMode::GLYPH_FILL, Range(mGlyphs[i]),
nullptr, nullptr, nullptr);
mGlyphs[i]->Draw(Range(mGlyphs[i]), gfxPoint(dx, dy), params);
}
}
}
@ -2371,9 +2370,7 @@ nsMathMLChar::PaintVertically(nsPresContext* aPresContext,
clipRect.height = std::min(bm.ascent + bm.descent, fillEnd - dy);
AutoPushClipRect clip(aThebesContext, oneDevPixel, clipRect);
dy += bm.ascent;
mGlyphs[3]->Draw(aThebesContext, gfxPoint(dx, dy),
DrawMode::GLYPH_FILL, Range(mGlyphs[3]),
nullptr, nullptr, nullptr);
mGlyphs[3]->Draw(Range(mGlyphs[3]), gfxPoint(dx, dy), params);
dy += bm.descent;
}
}
@ -2449,6 +2446,8 @@ nsMathMLChar::PaintHorizontally(nsPresContext* aPresContext,
nsRect unionRect = aRect;
unionRect.Inflate(oneDevPixel, oneDevPixel);
gfxTextRun::DrawParams params(aThebesContext);
///////////////////////////
// draw left, middle, right
for (i = 0; i <= 2; ++i) {
@ -2475,9 +2474,7 @@ nsMathMLChar::PaintHorizontally(nsPresContext* aPresContext,
}
if (!clipRect.IsEmpty()) {
AutoPushClipRect clip(aThebesContext, oneDevPixel, clipRect);
mGlyphs[i]->Draw(aThebesContext, gfxPoint(dx, dy),
DrawMode::GLYPH_FILL, Range(mGlyphs[i]),
nullptr, nullptr, nullptr);
mGlyphs[i]->Draw(Range(mGlyphs[i]), gfxPoint(dx, dy), params);
}
}
}
@ -2541,9 +2538,7 @@ nsMathMLChar::PaintHorizontally(nsPresContext* aPresContext,
clipRect.width = std::min(bm.rightBearing - bm.leftBearing, fillEnd - dx);
AutoPushClipRect clip(aThebesContext, oneDevPixel, clipRect);
dx -= bm.leftBearing;
mGlyphs[3]->Draw(aThebesContext, gfxPoint(dx, dy),
DrawMode::GLYPH_FILL, Range(mGlyphs[3]),
nullptr, nullptr, nullptr);
mGlyphs[3]->Draw(Range(mGlyphs[3]), gfxPoint(dx, dy), params);
dx += bm.rightBearing;
}
}