bug 621918 - part 1 - eliminate aDirtyRect parameter from gfxTextRun::Draw etc. r=roc a=roc
authorJonathan Kew <jfkthame@gmail.com>
Tue, 11 Jan 2011 11:17:00 +0000
changeset 60285 8e1487c6e663aa104986c40058c2ded96f686a67
parent 60284 fd860ead307768d027e819831f42710211741778
child 60286 119ef8681a16fd7eb79d515cebaa4800faab4bf3
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, roc
bugs621918
milestone2.0b10pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 621918 - part 1 - eliminate aDirtyRect parameter from gfxTextRun::Draw etc. r=roc a=roc
content/canvas/src/nsCanvasRenderingContext2D.cpp
gfx/src/thebes/nsThebesFontMetrics.cpp
gfx/tests/gfxFontSelectionTest.cpp
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxFont.h
layout/generic/nsTextFrameThebes.cpp
layout/svg/base/src/nsSVGGlyphFrame.cpp
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -2571,17 +2571,16 @@ struct NS_STACK_CLASS nsCanvasBidiProces
                                  nsnull);
         else
             // mOp == TEXT_DRAW_OPERATION_FILL
             mTextRun->Draw(mThebes,
                            point,
                            0,
                            mTextRun->GetLength(),
                            nsnull,
-                           nsnull,
                            nsnull);
     }
 
     // current text run
     gfxTextRunCache::AutoTextRun mTextRun;
 
     // pointer to the context, may not be the canvas's context
     // if an intermediate surface is being used
@@ -2919,17 +2918,16 @@ nsCanvasRenderingContext2D::MozDrawText(
     // Fill color is text color
     ApplyStyle(STYLE_FILL);
 
     textRun->Draw(mThebes,
                   pt,
                   /* offset = */ 0,
                   textToDraw.Length(),
                   nsnull,
-                  nsnull,
                   nsnull);
 
     return Redraw();
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::MozMeasureText(const nsAString& textToMeasure, float *retVal)
 {
@@ -3056,17 +3054,17 @@ nsCanvasRenderingContext2D::MozTextAlong
 
         rot.Invert();
         rot.Scale(aupdp,aupdp);
         gfxPoint pt = rot.Transform(cp[i].pos);
 
         if(stroke) {
             textRun->DrawToPath(mThebes, pt, i, 1, nsnull, nsnull);
         } else {
-            textRun->Draw(mThebes, pt, i, 1, nsnull, nsnull, nsnull);
+            textRun->Draw(mThebes, pt, i, 1, nsnull, nsnull);
         }
         mThebes->SetMatrix(matrix);
     }
 
     if (stroke)
         mThebes->Stroke();
 
     delete [] cp;
--- a/gfx/src/thebes/nsThebesFontMetrics.cpp
+++ b/gfx/src/thebes/nsThebesFontMetrics.cpp
@@ -394,17 +394,17 @@ nsThebesFontMetrics::DrawString(const ch
     AutoTextRun textRun(this, aContext, aString, aLength);
     if (!textRun.get())
         return NS_ERROR_FAILURE;
     gfxPoint pt(aX, aY);
     if (mTextRunRTL) {
         pt.x += textRun->GetAdvanceWidth(0, aLength, &provider);
     }
     textRun->Draw(aContext->ThebesContext(), pt, 0, aLength,
-                  nsnull, &provider, nsnull);
+                  &provider, nsnull);
     return NS_OK;
 }
 
 nsresult
 nsThebesFontMetrics::DrawString(const PRUnichar* aString, PRUint32 aLength,
                                 nscoord aX, nscoord aY,
                                 PRInt32 aFontID,
                                 const nscoord* aSpacing,
@@ -418,17 +418,17 @@ nsThebesFontMetrics::DrawString(const PR
     AutoTextRun textRun(this, aContext, aString, aLength);
     if (!textRun.get())
         return NS_ERROR_FAILURE;
     gfxPoint pt(aX, aY);
     if (mTextRunRTL) {
         pt.x += textRun->GetAdvanceWidth(0, aLength, &provider);
     }
     textRun->Draw(aContext->ThebesContext(), pt, 0, aLength,
-                  nsnull, &provider, nsnull);
+                  &provider, nsnull);
     return NS_OK;
 }
 
 #ifdef MOZ_MATHML
 
 static void
 GetTextRunBoundingMetrics(gfxTextRun *aTextRun, PRUint32 aStart, PRUint32 aLength,
                           nsThebesRenderingContext *aContext,
--- a/gfx/tests/gfxFontSelectionTest.cpp
+++ b/gfx/tests/gfxFontSelectionTest.cpp
@@ -307,17 +307,17 @@ RunTest (TestEntry *test, gfxContext *ct
         textRun = gfxTextRunWordCache::MakeTextRun(reinterpret_cast<const PRUint8*>(test->string), length, fontGroup, &params, flags);
     } else {
         NS_ConvertUTF8toUTF16 str(nsDependentCString(test->string));
         length = str.Length();
         textRun = gfxTextRunWordCache::MakeTextRun(str.get(), length, fontGroup, &params, flags);
     }
 
     gfxFontTestStore::NewStore();
-    textRun->Draw(ctx, gfxPoint(0,0), 0, length, nsnull, nsnull, nsnull);
+    textRun->Draw(ctx, gfxPoint(0,0), 0, length, nsnull, nsnull);
     gfxFontTestStore *s = gfxFontTestStore::CurrentStore();
 
     gTextRunCache->RemoveTextRun(textRun);
 
     if (!test->Check(s)) {
         DumpStore(s);
         printf ("  expected:\n");
         DumpTestExpect(test);
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -3242,43 +3242,45 @@ ClipPartialLigature(gfxTextRun *aTextRun
             *aLeft = PR_MAX(*aLeft, endEdge);
         } else {
             *aRight = PR_MIN(*aRight, endEdge);
         }
     }    
 }
 
 void
-gfxTextRun::DrawPartialLigature(gfxFont *aFont, gfxContext *aCtx, PRUint32 aStart,
-                                PRUint32 aEnd,
-                                const gfxRect *aDirtyRect, gfxPoint *aPt,
+gfxTextRun::DrawPartialLigature(gfxFont *aFont, gfxContext *aCtx,
+                                PRUint32 aStart, PRUint32 aEnd,
+                                gfxPoint *aPt,
                                 PropertyProvider *aProvider)
 {
     if (aStart >= aEnd)
         return;
-    if (!aDirtyRect) {
-        NS_ERROR("Cannot draw partial ligatures without a dirty rect");
-        return;
-    }
+
+    // Need to preserve the path, otherwise this can break canvas text-on-path;
+    // in general it seems like a good thing, as naive callers probably won't
+    // expect gfxTextRun::Draw to implicitly destroy the current path.
+    gfxContextPathAutoSaveRestore savePath(aCtx);
 
     // Draw partial ligature. We hack this by clipping the ligature.
     LigatureData data = ComputeLigatureData(aStart, aEnd, aProvider);
-    gfxFloat left = aDirtyRect->X();
-    gfxFloat right = aDirtyRect->XMost();
+    gfxRect clipExtents = aCtx->GetClipExtents();
+    gfxFloat left = clipExtents.X()*mAppUnitsPerDevUnit;
+    gfxFloat right = clipExtents.XMost()*mAppUnitsPerDevUnit;
     ClipPartialLigature(this, &left, &right, aPt->x, &data);
 
     aCtx->Save();
     aCtx->NewPath();
     // use division here to ensure that when the rect is aligned on multiples
     // of mAppUnitsPerDevUnit, we clip to true device unit boundaries.
     // Also, make sure we snap the rectangle to device pixels.
     aCtx->Rectangle(gfxRect(left/mAppUnitsPerDevUnit,
-                            aDirtyRect->Y()/mAppUnitsPerDevUnit,
+                            clipExtents.Y(),
                             (right - left)/mAppUnitsPerDevUnit,
-                            aDirtyRect->Height()/mAppUnitsPerDevUnit), PR_TRUE);
+                            clipExtents.Height()), PR_TRUE);
     aCtx->Clip();
     gfxFloat direction = GetDirection();
     gfxPoint pt(aPt->x - direction*data.mPartAdvance, aPt->y);
     DrawGlyphs(aFont, aCtx, PR_FALSE, &pt, data.mLigatureStart,
                data.mLigatureEnd, aProvider, aStart, aEnd);
     aCtx->Restore();
 
     aPt->x += direction*data.mPartWidth;
@@ -3395,17 +3397,17 @@ gfxTextRun::AdjustAdvancesForSyntheticBo
                 }
             }
         }
     }
 }
 
 void
 gfxTextRun::Draw(gfxContext *aContext, gfxPoint aPt,
-                 PRUint32 aStart, PRUint32 aLength, const gfxRect *aDirtyRect,
+                 PRUint32 aStart, PRUint32 aLength,
                  PropertyProvider *aProvider, gfxFloat *aAdvanceWidth)
 {
     NS_ASSERTION(aStart + aLength <= mCharacterCount, "Substring out of range");
 
     gfxFloat direction = GetDirection();
     gfxPoint pt = aPt;
 
     // synthetic bolding draws glyphs twice ==> colors with opacity won't draw correctly unless first drawn without alpha
@@ -3426,20 +3428,20 @@ gfxTextRun::Draw(gfxContext *aContext, g
     while (iter.NextRun()) {
         gfxFont *font = iter.GetGlyphRun()->mFont;
         PRUint32 start = iter.GetStringStart();
         PRUint32 end = iter.GetStringEnd();
         PRUint32 ligatureRunStart = start;
         PRUint32 ligatureRunEnd = end;
         ShrinkToLigatureBoundaries(&ligatureRunStart, &ligatureRunEnd);
         
-        DrawPartialLigature(font, aContext, start, ligatureRunStart, aDirtyRect, &pt, aProvider);
+        DrawPartialLigature(font, aContext, start, ligatureRunStart, &pt, aProvider);
         DrawGlyphs(font, aContext, PR_FALSE, &pt, ligatureRunStart,
                    ligatureRunEnd, aProvider, ligatureRunStart, ligatureRunEnd);
-        DrawPartialLigature(font, aContext, ligatureRunEnd, end, aDirtyRect, &pt, aProvider);
+        DrawPartialLigature(font, aContext, ligatureRunEnd, end, &pt, aProvider);
     }
 
     // composite result when synthetic bolding used
     if (needToRestore) {
         syntheticBoldBuffer.PopAlpha();
     }
 
     if (aAdvanceWidth) {
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -1462,20 +1462,16 @@ public:
         virtual void GetSpacing(PRUint32 aStart, PRUint32 aLength,
                                 Spacing *aSpacing) = 0;
     };
 
     /**
      * 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 aDirtyRect if non-null, drawing outside of the rectangle can be
-     * (but does not need to be) dropped. Note that if this is null, we cannot
-     * draw partial ligatures and we will assert if partial ligatures
-     * are detected.
      * @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, offset1, length1, dirty, &provider, &advance) followed by
      * Draw(ctx, gfxPoint(pt.x + advance, pt.y), offset1 + length1, length2,
      *      dirty, &provider, nsnull) should have the same effect as
      * Draw(ctx, pt, offset1, length1+length2, dirty, &provider, nsnull).
@@ -1485,17 +1481,16 @@ public:
      *      dirty, &provider, nsnull) should have the same effect as
      * Draw(ctx, pt, offset1, length1+length2, dirty, &provider, nsnull).
      * 
      * 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,
               PRUint32 aStart, PRUint32 aLength,
-              const gfxRect *aDirtyRect,
               PropertyProvider *aProvider,
               gfxFloat *aAdvanceWidth);
 
     /**
      * Renders a substring to a path. 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
@@ -2025,18 +2020,18 @@ private:
     // (Platforms do the actual ligaturization, but we need to do a bunch of stuff
     // to handle requests that begin or end inside a ligature)
 
     // if aProvider is null then mBeforeSpacing and mAfterSpacing are set to zero
     LigatureData ComputeLigatureData(PRUint32 aPartStart, PRUint32 aPartEnd,
                                      PropertyProvider *aProvider);
     gfxFloat ComputePartialLigatureWidth(PRUint32 aPartStart, PRUint32 aPartEnd,
                                          PropertyProvider *aProvider);
-    void DrawPartialLigature(gfxFont *aFont, gfxContext *aCtx, PRUint32 aStart,
-                             PRUint32 aEnd, const gfxRect *aDirtyRect, gfxPoint *aPt,
+    void DrawPartialLigature(gfxFont *aFont, gfxContext *aCtx,
+                             PRUint32 aStart, PRUint32 aEnd, gfxPoint *aPt,
                              PropertyProvider *aProvider);
     // Advance aStart to the start of the nearest ligature; back up aEnd
     // to the nearest ligature end; may result in *aStart == *aEnd
     void ShrinkToLigatureBoundaries(PRUint32 *aStart, PRUint32 *aEnd);
     // result in appunits
     gfxFloat GetPartialLigatureWidth(PRUint32 aStart, PRUint32 aEnd, PropertyProvider *aProvider);
     void AccumulatePartialLigatureMetrics(gfxFont *aFont,
                                           PRUint32 aStart, PRUint32 aEnd,
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -5078,29 +5078,29 @@ nsTextFrame::PaintText(nsIRenderingConte
 void
 nsTextFrame::DrawText(gfxContext* aCtx, const gfxPoint& aTextBaselinePt,
                       PRUint32 aOffset, PRUint32 aLength,
                       const gfxRect* aDirtyRect, PropertyProvider* aProvider,
                       gfxFloat& aAdvanceWidth, PRBool aDrawSoftHyphen)
 {
   // Paint the text and soft-hyphen (if any) onto the given graphics context
   mTextRun->Draw(aCtx, aTextBaselinePt, aOffset, aLength,
-                 aDirtyRect, aProvider, &aAdvanceWidth);
+                 aProvider, &aAdvanceWidth);
 
   if (aDrawSoftHyphen) {
     // Don't use ctx as the context, because we need a reference context here,
     // ctx may be transformed.
     gfxTextRunCache::AutoTextRun hyphenTextRun(GetHyphenTextRun(mTextRun, nsnull, this));
     if (hyphenTextRun.get()) {
       // For right-to-left text runs, the soft-hyphen is positioned at the left
       // of the text, minus its own width
       gfxFloat hyphenBaselineX = aTextBaselinePt.x + mTextRun->GetDirection() * aAdvanceWidth -
         (mTextRun->IsRightToLeft() ? hyphenTextRun->GetAdvanceWidth(0, hyphenTextRun->GetLength(), nsnull) : 0);
       hyphenTextRun->Draw(aCtx, gfxPoint(hyphenBaselineX, aTextBaselinePt.y),
-                          0, hyphenTextRun->GetLength(), aDirtyRect, nsnull, nsnull);
+                          0, hyphenTextRun->GetLength(), nsnull, nsnull);
     }
   }
 }
 
 PRInt16
 nsTextFrame::GetSelectionStatus(PRInt16* aSelectionFlags)
 {
   // get the selection controller
--- a/layout/svg/base/src/nsSVGGlyphFrame.cpp
+++ b/layout/svg/base/src/nsSVGGlyphFrame.cpp
@@ -598,24 +598,24 @@ nsSVGGlyphFrame::AddBoundingBoxesToPath(
 }
 
 void
 nsSVGGlyphFrame::FillCharacters(CharacterIterator *aIter,
                                 gfxContext *aContext)
 {
   if (aIter->SetupForDirectTextRunDrawing(aContext)) {
     mTextRun->Draw(aContext, gfxPoint(0, 0), 0,
-                   mTextRun->GetLength(), nsnull, nsnull, nsnull);
+                   mTextRun->GetLength(), nsnull, nsnull);
     return;
   }
 
   PRInt32 i;
   while ((i = aIter->NextChar()) >= 0) {
     aIter->SetupForDrawing(aContext);
-    mTextRun->Draw(aContext, gfxPoint(0, 0), i, 1, nsnull, nsnull, nsnull);
+    mTextRun->Draw(aContext, gfxPoint(0, 0), i, 1, nsnull, nsnull);
   }
 }
 
 gfxRect
 nsSVGGlyphFrame::GetBBoxContribution(const gfxMatrix &aToBBoxUserspace)
 {
   mOverrideCanvasTM = NS_NewSVGMatrix(aToBBoxUserspace);