Bug 1282248 - Declare a bunch of gfxTextRun measurement/drawing methods and related helpers as const. r=m_kato
authorJonathan Kew <jkew@mozilla.com>
Mon, 27 Jun 2016 17:41:55 +0100
changeset 381528 ab8e9e4b893d13748c71c463296840dc356805b9
parent 381527 c9ee3b0069e4841323c512d563ea84df73e5c313
child 381529 6e994818e8f60192ca953c7b48adbc368b64f5f4
push id21504
push userbmo:npang@mozilla.com
push dateMon, 27 Jun 2016 18:10:09 +0000
reviewersm_kato
bugs1282248
milestone50.0a1
Bug 1282248 - Declare a bunch of gfxTextRun measurement/drawing methods and related helpers as const. r=m_kato
gfx/thebes/gfxDWriteFonts.cpp
gfx/thebes/gfxDWriteFonts.h
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxFont.h
gfx/thebes/gfxGDIFont.cpp
gfx/thebes/gfxGDIFont.h
gfx/thebes/gfxMacFont.cpp
gfx/thebes/gfxMacFont.h
gfx/thebes/gfxTextRun.cpp
gfx/thebes/gfxTextRun.h
layout/generic/nsTextRunTransformations.cpp
--- a/gfx/thebes/gfxDWriteFonts.cpp
+++ b/gfx/thebes/gfxDWriteFonts.cpp
@@ -554,17 +554,17 @@ gfxDWriteFont::GetCairoScaledFont()
                  cairo_scaled_font_status(mScaledFont) 
                    == CAIRO_STATUS_SUCCESS,
                  "Failed to make scaled font");
 
     return mScaledFont;
 }
 
 gfxFont::RunMetrics
-gfxDWriteFont::Measure(gfxTextRun* aTextRun,
+gfxDWriteFont::Measure(const gfxTextRun* aTextRun,
                        uint32_t aStart, uint32_t aEnd,
                        BoundingBoxType aBoundingBoxType,
                        DrawTarget* aRefDrawTarget,
                        Spacing* aSpacing,
                        uint16_t aOrientation)
 {
     gfxFont::RunMetrics metrics =
         gfxFont::Measure(aTextRun, aStart, aEnd, aBoundingBoxType,
--- a/gfx/thebes/gfxDWriteFonts.h
+++ b/gfx/thebes/gfxDWriteFonts.h
@@ -43,17 +43,17 @@ public:
 
     virtual gfxFloat GetAdjustedSize() const override {
         return mAdjustedSize;
     }
 
     IDWriteFontFace *GetFontFace();
 
     /* override Measure to add padding for antialiasing */
-    virtual RunMetrics Measure(gfxTextRun *aTextRun,
+    virtual RunMetrics Measure(const gfxTextRun *aTextRun,
                                uint32_t aStart, uint32_t aEnd,
                                BoundingBoxType aBoundingBoxType,
                                DrawTarget *aDrawTargetForTightBoundingBox,
                                Spacing *aSpacing,
                                uint16_t aOrientation) override;
 
     virtual bool ProvidesGlyphWidths() const override;
 
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -1807,17 +1807,17 @@ gfxFont::DrawOneGlyph(uint32_t aGlyphID,
     }
 
     *aEmittedGlyphs = true;
 }
 
 // Draw a run of CharacterGlyph records from the given offset in aShapedText.
 // Returns true if glyph paths were actually emitted.
 bool
-gfxFont::DrawGlyphs(gfxShapedText            *aShapedText,
+gfxFont::DrawGlyphs(const gfxShapedText      *aShapedText,
                     uint32_t                  aOffset, // offset in the textrun
                     uint32_t                  aCount, // length of run to draw
                     gfxPoint                 *aPt,
                     const TextRunDrawParams&  aRunParams,
                     const FontDrawParams&     aFontParams)
 {
     bool emittedGlyphs = false;
     GlyphBufferAzure buffer(aRunParams, aFontParams);
@@ -1919,17 +1919,17 @@ gfxFont::DrawGlyphs(gfxShapedText       
         }
     }
 
     return emittedGlyphs;
 }
 
 // This method is mostly parallel to DrawGlyphs.
 void
-gfxFont::DrawEmphasisMarks(gfxTextRun* aShapedText, gfxPoint* aPt,
+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);
 
     gfxFloat clusterStart = -std::numeric_limits<gfxFloat>::infinity();
@@ -1958,17 +1958,17 @@ gfxFont::DrawEmphasisMarks(gfxTextRun* a
         }
         if (aParams.spacing) {
             inlineCoord += aParams.direction * aParams.spacing[i].mAfter;
         }
     }
 }
 
 void
-gfxFont::Draw(gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd,
+gfxFont::Draw(const gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd,
               gfxPoint *aPt, const TextRunDrawParams& aRunParams,
               uint16_t aOrientation)
 {
     NS_ASSERTION(aRunParams.drawMode == DrawMode::GLYPH_PATH ||
                  !(int(aRunParams.drawMode) & int(DrawMode::GLYPH_PATH)),
                  "GLYPH_PATH cannot be used with GLYPH_FILL, GLYPH_STROKE or GLYPH_STROKE_UNDERNEATH");
 
     if (aStart >= aEnd) {
@@ -2206,41 +2206,42 @@ UnionRange(gfxFloat aX, gfxFloat* aDestM
     *aDestMin = std::min(*aDestMin, aX);
     *aDestMax = std::max(*aDestMax, aX);
 }
 
 // We get precise glyph extents if the textrun creator requested them, or
 // if the font is a user font --- in which case the author may be relying
 // on overflowing glyphs.
 static bool
-NeedsGlyphExtents(gfxFont *aFont, gfxTextRun *aTextRun)
+NeedsGlyphExtents(gfxFont *aFont, const gfxTextRun *aTextRun)
 {
     return (aTextRun->GetFlags() & gfxTextRunFactory::TEXT_NEED_BOUNDING_BOX) ||
         aFont->GetFontEntry()->IsUserFont();
 }
 
 bool
-gfxFont::IsSpaceGlyphInvisible(DrawTarget* aRefDrawTarget, gfxTextRun* aTextRun)
+gfxFont::IsSpaceGlyphInvisible(DrawTarget* aRefDrawTarget,
+                               const gfxTextRun* aTextRun)
 {
     if (!mFontEntry->mSpaceGlyphIsInvisibleInitialized &&
         GetAdjustedSize() >= 1.0) {
         gfxGlyphExtents *extents =
             GetOrCreateGlyphExtents(aTextRun->GetAppUnitsPerDevUnit());
         gfxRect glyphExtents;
         mFontEntry->mSpaceGlyphIsInvisible =
             extents->GetTightGlyphExtentsAppUnits(this, aRefDrawTarget,
                 GetSpaceGlyph(), &glyphExtents) &&
             glyphExtents.IsEmpty();
         mFontEntry->mSpaceGlyphIsInvisibleInitialized = true;
     }
     return mFontEntry->mSpaceGlyphIsInvisible;
 }
 
 gfxFont::RunMetrics
-gfxFont::Measure(gfxTextRun *aTextRun,
+gfxFont::Measure(const gfxTextRun *aTextRun,
                  uint32_t aStart, uint32_t aEnd,
                  BoundingBoxType aBoundingBoxType,
                  DrawTarget* aRefDrawTarget,
                  Spacing *aSpacing,
                  uint16_t aOrientation)
 {
     // If aBoundingBoxType is TIGHT_HINTED_OUTLINE_EXTENTS
     // and the underlying cairo font may be antialiased,
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -895,16 +895,17 @@ public:
         }
 
     private:
         uint32_t mValue;
     };
 
     // Accessor for the array of CompressedGlyph records, which will be in
     // a different place in gfxShapedWord vs gfxTextRun
+    virtual const CompressedGlyph *GetCharacterGlyphs() const = 0;
     virtual CompressedGlyph *GetCharacterGlyphs() = 0;
 
     /**
      * When the glyphs for a character don't fit into a CompressedGlyph record
      * in SimpleGlyph format, we use an array of DetailedGlyphs instead.
      */
     struct DetailedGlyph {
         /** The glyphID, or the Unicode character
@@ -934,17 +935,17 @@ public:
     bool IsLigatureGroupStart(uint32_t aPos) {
         NS_ASSERTION(aPos < GetLength(), "aPos out of range");
         return GetCharacterGlyphs()[aPos].IsLigatureGroupStart();
     }
 
     // NOTE that this must not be called for a character offset that does
     // not have any DetailedGlyph records; callers must have verified that
     // GetCharacterGlyphs()[aCharIndex].GetGlyphCount() is greater than zero.
-    DetailedGlyph *GetDetailedGlyphs(uint32_t aCharIndex) {
+    DetailedGlyph *GetDetailedGlyphs(uint32_t aCharIndex) const {
         NS_ASSERTION(GetCharacterGlyphs() && HasDetailedGlyphs() &&
                      !GetCharacterGlyphs()[aCharIndex].IsSimpleGlyph() &&
                      GetCharacterGlyphs()[aCharIndex].GetGlyphCount() > 0,
                      "invalid use of GetDetailedGlyphs; check the caller!");
         return mDetailedGlyphs->Get(aCharIndex);
     }
 
     void AdjustAdvancesForSyntheticBold(float aSynBoldOffset,
@@ -1234,16 +1235,19 @@ public:
     }
 
     // Override operator delete to properly free the object that was
     // allocated via malloc.
     void operator delete(void* p) {
         free(p);
     }
 
+    virtual const CompressedGlyph *GetCharacterGlyphs() const override {
+        return &mCharGlyphsStorage[0];
+    }
     virtual CompressedGlyph *GetCharacterGlyphs() override {
         return &mCharGlyphsStorage[0];
     }
 
     const uint8_t* Text8Bit() const {
         NS_ASSERTION(TextIs8Bit(), "invalid use of Text8Bit()");
         return reinterpret_cast<const uint8_t*>(mCharGlyphsStorage + GetLength());
     }
@@ -1611,27 +1615,27 @@ public:
      *   indicates that the current source from context should be used for fill
      * .context  the Thebes graphics context to which we're drawing
      * .dt  Moz2D DrawTarget to which we're drawing
      *
      * Callers guarantee:
      * -- aStart and aEnd are aligned to cluster and ligature boundaries
      * -- all glyphs use this font
      */
-    void Draw(gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd,
+    void Draw(const gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd,
               gfxPoint *aPt, const TextRunDrawParams& aRunParams,
               uint16_t aOrientation);
 
     /**
      * Draw the emphasis marks for the given text run. Its prerequisite
      * and output are similiar to the method Draw().
      * @param aPt the baseline origin of the emphasis marks.
      * @param aParams some drawing parameters, see EmphasisMarkDrawParams.
      */
-    void DrawEmphasisMarks(gfxTextRun* aShapedText, gfxPoint* aPt,
+    void DrawEmphasisMarks(const gfxTextRun* aShapedText, gfxPoint* aPt,
                            uint32_t aOffset, uint32_t aCount,
                            const EmphasisMarkDrawParams& aParams);
 
     /**
      * Measure a run of characters. See gfxTextRun::Metrics.
      * @param aTight if false, then return the union of the glyph extents
      * with the font-box for the characters (the rectangle with x=0,width=
      * the advance width for the character run,y=-(font ascent), and height=
@@ -1646,17 +1650,17 @@ public:
      * Callers guarantee:
      * -- aStart and aEnd are aligned to cluster and ligature boundaries
      * -- all glyphs use this font
      * 
      * The default implementation just uses font metrics and aTextRun's
      * advances, and assumes no characters fall outside the font box. In
      * general this is insufficient, because that assumption is not always true.
      */
-    virtual RunMetrics Measure(gfxTextRun *aTextRun,
+    virtual RunMetrics Measure(const gfxTextRun *aTextRun,
                                uint32_t aStart, uint32_t aEnd,
                                BoundingBoxType aBoundingBoxType,
                                DrawTarget* aDrawTargetForTightBoundingBox,
                                Spacing *aSpacing, uint16_t aOrientation);
     /**
      * Line breaks have been changed at the beginning and/or end of a substring
      * of the text. Reshaping may be required; glyph updating is permitted.
      * @return true if anything was changed, false otherwise
@@ -1878,17 +1882,17 @@ protected:
                       double             aAdvance,
                       gfxPoint          *aPt,
                       GlyphBufferAzure&  aBuffer,
                       bool              *aEmittedGlyphs) const;
 
     // Output a run of glyphs at *aPt, which is updated to follow the last glyph
     // in the run. This method also takes account of any letter-spacing provided
     // in aRunParams.
-    bool DrawGlyphs(gfxShapedText            *aShapedText,
+    bool DrawGlyphs(const gfxShapedText      *aShapedText,
                     uint32_t                  aOffset, // offset in the textrun
                     uint32_t                  aCount, // length of run to draw
                     gfxPoint                 *aPt,
                     const TextRunDrawParams&  aRunParams,
                     const FontDrawParams&     aFontParams);
 
     // set the font size and offset used for
     // synthetic subscript/superscript glyphs
@@ -1912,17 +1916,17 @@ protected:
 
     // The return value is interpreted as a horizontal advance in 16.16 fixed
     // point format.
     virtual int32_t GetGlyphWidth(DrawTarget& aDrawTarget, uint16_t aGID) {
         return -1;
     }
 
     bool IsSpaceGlyphInvisible(DrawTarget* aRefDrawTarget,
-                               gfxTextRun* aTextRun);
+                               const gfxTextRun* aTextRun);
 
     void AddGlyphChangeObserver(GlyphChangeObserver *aObserver);
     void RemoveGlyphChangeObserver(GlyphChangeObserver *aObserver);
 
     // whether font contains substitution lookups containing spaces
     bool HasSubstitutionRulesWithSpaceLookups(Script aRunScript);
 
     // do spaces participate in shaping rules? if so, can't used word cache
--- a/gfx/thebes/gfxGDIFont.cpp
+++ b/gfx/thebes/gfxGDIFont.cpp
@@ -136,17 +136,17 @@ gfxGDIFont::SetupCairoFont(DrawTarget* a
         // the cairo_t, precluding any further drawing.
         return false;
     }
     cairo_set_scaled_font(gfxFont::RefCairo(aDrawTarget), mScaledFont);
     return true;
 }
 
 gfxFont::RunMetrics
-gfxGDIFont::Measure(gfxTextRun *aTextRun,
+gfxGDIFont::Measure(const gfxTextRun *aTextRun,
                     uint32_t aStart, uint32_t aEnd,
                     BoundingBoxType aBoundingBoxType,
                     DrawTarget *aRefDrawTarget,
                     Spacing *aSpacing,
                     uint16_t aOrientation)
 {
     gfxFont::RunMetrics metrics =
         gfxFont::Measure(aTextRun, aStart, aEnd, aBoundingBoxType,
--- a/gfx/thebes/gfxGDIFont.h
+++ b/gfx/thebes/gfxGDIFont.h
@@ -40,17 +40,17 @@ public:
     cairo_scaled_font_t *CairoScaledFont() { return mScaledFont; }
 
     /* overrides for the pure virtual methods in gfxFont */
     virtual uint32_t GetSpaceGlyph() override;
 
     virtual bool SetupCairoFont(DrawTarget* aDrawTarget) override;
 
     /* override Measure to add padding for antialiasing */
-    virtual RunMetrics Measure(gfxTextRun *aTextRun,
+    virtual RunMetrics Measure(const gfxTextRun *aTextRun,
                                uint32_t aStart, uint32_t aEnd,
                                BoundingBoxType aBoundingBoxType,
                                DrawTarget *aDrawTargetForTightBoundingBox,
                                Spacing *aSpacing,
                                uint16_t aOrientation) override;
 
     /* required for MathML to suppress effects of ClearType "padding" */
     virtual gfxFont*
--- a/gfx/thebes/gfxMacFont.cpp
+++ b/gfx/thebes/gfxMacFont.cpp
@@ -160,17 +160,17 @@ gfxMacFont::SetupCairoFont(DrawTarget* a
         // the cairo_t, precluding any further drawing.
         return false;
     }
     cairo_set_scaled_font(gfxFont::RefCairo(aDrawTarget), mScaledFont);
     return true;
 }
 
 gfxFont::RunMetrics
-gfxMacFont::Measure(gfxTextRun *aTextRun,
+gfxMacFont::Measure(const gfxTextRun *aTextRun,
                     uint32_t aStart, uint32_t aEnd,
                     BoundingBoxType aBoundingBoxType,
                     DrawTarget *aRefDrawTarget,
                     Spacing *aSpacing,
                     uint16_t aOrientation)
 {
     gfxFont::RunMetrics metrics =
         gfxFont::Measure(aTextRun, aStart, aEnd,
--- a/gfx/thebes/gfxMacFont.h
+++ b/gfx/thebes/gfxMacFont.h
@@ -26,17 +26,17 @@ public:
     /* overrides for the pure virtual methods in gfxFont */
     virtual uint32_t GetSpaceGlyph() override {
         return mSpaceGlyph;
     }
 
     virtual bool SetupCairoFont(DrawTarget* aDrawTarget) override;
 
     /* override Measure to add padding for antialiasing */
-    virtual RunMetrics Measure(gfxTextRun *aTextRun,
+    virtual RunMetrics Measure(const gfxTextRun *aTextRun,
                                uint32_t aStart, uint32_t aEnd,
                                BoundingBoxType aBoundingBoxType,
                                DrawTarget *aDrawTargetForTightBoundingBox,
                                Spacing *aSpacing,
                                uint16_t aOrientation) override;
 
     // We need to provide hinted (non-linear) glyph widths if using a font
     // with embedded color bitmaps (Apple Color Emoji), as Core Text renders
--- a/gfx/thebes/gfxTextRun.cpp
+++ b/gfx/thebes/gfxTextRun.cpp
@@ -226,24 +226,25 @@ gfxTextRun::SetPotentialLineBreaks(Range
             canBreak = CompressedGlyph::FLAG_BREAK_TYPE_NONE;
         }
         changed |= charGlyphs[i].SetCanBreakBefore(canBreak);
     }
     return changed != 0;
 }
 
 gfxTextRun::LigatureData
-gfxTextRun::ComputeLigatureData(Range aPartRange, PropertyProvider *aProvider)
+gfxTextRun::ComputeLigatureData(Range aPartRange,
+                                PropertyProvider *aProvider) const
 {
     NS_ASSERTION(aPartRange.start < aPartRange.end,
                  "Computing ligature data for empty range");
     NS_ASSERTION(aPartRange.end <= GetLength(), "Character length overflow");
   
     LigatureData result;
-    CompressedGlyph *charGlyphs = mCharacterGlyphs;
+    const CompressedGlyph *charGlyphs = mCharacterGlyphs;
 
     uint32_t i;
     for (i = aPartRange.start; !charGlyphs[i].IsLigatureGroupStart(); --i) {
         NS_ASSERTION(i > 0, "Ligature at the start of the run??");
     }
     result.mRange.start = i;
     for (i = aPartRange.start + 1;
          i < GetLength() && !charGlyphs[i].IsLigatureGroupStart(); ++i) {
@@ -308,36 +309,36 @@ gfxTextRun::ComputeLigatureData(Range aP
         }
     }
 
     return result;
 }
 
 gfxFloat
 gfxTextRun::ComputePartialLigatureWidth(Range aPartRange,
-                                        PropertyProvider *aProvider)
+                                        PropertyProvider *aProvider) const
 {
     if (aPartRange.start >= aPartRange.end)
         return 0;
     LigatureData data = ComputeLigatureData(aPartRange, aProvider);
     return data.mPartWidth;
 }
 
 int32_t
-gfxTextRun::GetAdvanceForGlyphs(Range aRange)
+gfxTextRun::GetAdvanceForGlyphs(Range aRange) const
 {
     int32_t advance = 0;
     for (auto i = aRange.start; i < aRange.end; ++i) {
         advance += GetAdvanceForGlyph(i);
     }
     return advance;
 }
 
 static void
-GetAdjustedSpacing(gfxTextRun *aTextRun, gfxTextRun::Range aRange,
+GetAdjustedSpacing(const gfxTextRun *aTextRun, gfxTextRun::Range aRange,
                    gfxTextRun::PropertyProvider *aProvider,
                    gfxTextRun::PropertyProvider::Spacing *aSpacing)
 {
     if (aRange.start >= aRange.end)
         return;
 
     aProvider->GetSpacing(aRange, aSpacing);
 
@@ -358,55 +359,56 @@ GetAdjustedSpacing(gfxTextRun *aTextRun,
         }
     }
 #endif
 }
 
 bool
 gfxTextRun::GetAdjustedSpacingArray(Range aRange, PropertyProvider *aProvider,
                                     Range aSpacingRange,
-                                    nsTArray<PropertyProvider::Spacing> *aSpacing)
+                                    nsTArray<PropertyProvider::Spacing>*
+                                        aSpacing) const
 {
     if (!aProvider || !(mFlags & gfxTextRunFactory::TEXT_ENABLE_SPACING))
         return false;
     if (!aSpacing->AppendElements(aRange.Length()))
         return false;
     auto spacingOffset = aSpacingRange.start - aRange.start;
     memset(aSpacing->Elements(), 0, sizeof(gfxFont::Spacing) * spacingOffset);
     GetAdjustedSpacing(this, aSpacingRange, aProvider,
                        aSpacing->Elements() + spacingOffset);
     memset(aSpacing->Elements() + aSpacingRange.end - aRange.start, 0,
            sizeof(gfxFont::Spacing) * (aRange.end - aSpacingRange.end));
     return true;
 }
 
 void
-gfxTextRun::ShrinkToLigatureBoundaries(Range* aRange)
+gfxTextRun::ShrinkToLigatureBoundaries(Range* aRange) const
 {
     if (aRange->start >= aRange->end)
         return;
   
-    CompressedGlyph *charGlyphs = mCharacterGlyphs;
+    const CompressedGlyph *charGlyphs = mCharacterGlyphs;
 
     while (aRange->start < aRange->end &&
            !charGlyphs[aRange->start].IsLigatureGroupStart()) {
         ++aRange->start;
     }
     if (aRange->end < GetLength()) {
         while (aRange->end > aRange->start &&
                !charGlyphs[aRange->end].IsLigatureGroupStart()) {
             --aRange->end;
         }
     }
 }
 
 void
 gfxTextRun::DrawGlyphs(gfxFont *aFont, Range aRange, gfxPoint *aPt,
                        PropertyProvider *aProvider, Range aSpacingRange,
-                       TextRunDrawParams& aParams, uint16_t aOrientation)
+                       TextRunDrawParams& aParams, uint16_t aOrientation) const
 {
     AutoTArray<PropertyProvider::Spacing,200> spacingBuffer;
     bool haveSpacing = GetAdjustedSpacingArray(aRange, aProvider,
                                                aSpacingRange, &spacingBuffer);
     aParams.spacing = haveSpacing ? spacingBuffer.Elements() : nullptr;
     aFont->Draw(this, aRange.start, aRange.end, aPt, aParams, aOrientation);
 }
 
@@ -432,17 +434,18 @@ ClipPartialLigature(const gfxTextRun* aT
             *aEnd = std::min(*aEnd, endEdge);
         }
     }    
 }
 
 void
 gfxTextRun::DrawPartialLigature(gfxFont *aFont, Range aRange,
                                 gfxPoint *aPt, PropertyProvider *aProvider,
-                                TextRunDrawParams& aParams, uint16_t aOrientation)
+                                TextRunDrawParams& aParams,
+                                uint16_t aOrientation) const
 {
     if (aRange.start >= aRange.end) {
         return;
     }
 
     // Draw partial ligature. We hack this by clipping the ligature.
     LigatureData data = ComputeLigatureData(aRange, aProvider);
     gfxRect clipExtents = aParams.context->GetClipExtents();
@@ -490,17 +493,17 @@ gfxTextRun::DrawPartialLigature(gfxFont 
     }
 }
 
 // Returns true if a glyph run is using a font with synthetic bolding enabled,
 // or a color font (COLR/SVG/sbix/CBDT), false otherwise. This is used to
 // check whether the text run needs to be explicitly composited in order to
 // support opacity.
 static bool
-HasSyntheticBoldOrColor(gfxTextRun *aRun, gfxTextRun::Range aRange)
+HasSyntheticBoldOrColor(const gfxTextRun *aRun, gfxTextRun::Range aRange)
 {
     gfxTextRun::GlyphRunIterator iter(aRun, aRange);
     while (iter.NextRun()) {
         gfxFont *font = iter.GetGlyphRun()->mFont;
         if (font) {
             if (font->IsSyntheticBold()) {
                 return true;
             }
@@ -560,17 +563,17 @@ struct BufferAlphaColor {
         mContext->PopGroupAndBlend();
         mContext->Restore();
     }
 
     gfxContext *mContext;
 };
 
 void
-gfxTextRun::Draw(Range aRange, gfxPoint aPt, const DrawParams& aParams)
+gfxTextRun::Draw(Range aRange, gfxPoint aPt, const DrawParams& aParams) const
 {
     NS_ASSERTION(aRange.end <= GetLength(), "Substring out of range");
     NS_ASSERTION(aParams.drawMode == DrawMode::GLYPH_PATH ||
                  !(aParams.drawMode & DrawMode::GLYPH_PATH),
                  "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");
 
@@ -684,17 +687,17 @@ gfxTextRun::Draw(Range aRange, gfxPoint 
         *aParams.advanceWidth = advance;
     }
 }
 
 // This method is mostly parallel to Draw().
 void
 gfxTextRun::DrawEmphasisMarks(gfxContext *aContext, gfxTextRun* aMark,
                               gfxFloat aMarkAdvance, gfxPoint aPt,
-                              Range aRange, PropertyProvider* aProvider)
+                              Range aRange, PropertyProvider* aProvider) const
 {
     MOZ_ASSERT(aRange.end <= GetLength());
 
     EmphasisMarkDrawParams params;
     params.context = aContext;
     params.mark = aMark;
     params.advance = aMarkAdvance;
     params.direction = GetDirection();
@@ -728,32 +731,33 @@ gfxTextRun::DrawEmphasisMarks(gfxContext
 
 void
 gfxTextRun::AccumulateMetricsForRun(gfxFont *aFont, Range aRange,
                                     gfxFont::BoundingBoxType aBoundingBoxType,
                                     DrawTarget* aRefDrawTarget,
                                     PropertyProvider *aProvider,
                                     Range aSpacingRange,
                                     uint16_t aOrientation,
-                                    Metrics *aMetrics)
+                                    Metrics *aMetrics) const
 {
     AutoTArray<PropertyProvider::Spacing,200> spacingBuffer;
     bool haveSpacing = GetAdjustedSpacingArray(aRange, aProvider,
                                                aSpacingRange, &spacingBuffer);
     Metrics metrics = aFont->Measure(this, aRange.start, aRange.end,
                                      aBoundingBoxType, aRefDrawTarget,
                                      haveSpacing ? spacingBuffer.Elements() : nullptr,
                                      aOrientation);
     aMetrics->CombineWith(metrics, IsRightToLeft());
 }
 
 void
 gfxTextRun::AccumulatePartialLigatureMetrics(gfxFont *aFont, Range aRange,
     gfxFont::BoundingBoxType aBoundingBoxType, DrawTarget* aRefDrawTarget,
-    PropertyProvider *aProvider, uint16_t aOrientation, Metrics *aMetrics)
+    PropertyProvider *aProvider, uint16_t aOrientation,
+    Metrics *aMetrics) const
 {
     if (aRange.start >= aRange.end)
         return;
 
     // Measure partial ligature. We hack this by clipping the metrics in the
     // same way we clip the drawing.
     LigatureData data = ComputeLigatureData(aRange, aProvider);
 
@@ -781,17 +785,17 @@ gfxTextRun::AccumulatePartialLigatureMet
 
     aMetrics->CombineWith(metrics, IsRightToLeft());
 }
 
 gfxTextRun::Metrics
 gfxTextRun::MeasureText(Range aRange,
                         gfxFont::BoundingBoxType aBoundingBoxType,
                         DrawTarget* aRefDrawTarget,
-                        PropertyProvider *aProvider)
+                        PropertyProvider *aProvider) const
 {
     NS_ASSERTION(aRange.end <= GetLength(), "Substring out of range");
 
     Metrics accumulatedMetrics;
     GlyphRunIterator iter(this, aRange);
     while (iter.NextRun()) {
         gfxFont *font = iter.GetGlyphRun()->mFont;
         uint32_t start = iter.GetStringStart();
@@ -1001,17 +1005,17 @@ gfxTextRun::BreakAndMeasureText(uint32_t
         }
     }
 
     return charsFit;
 }
 
 gfxFloat
 gfxTextRun::GetAdvanceWidth(Range aRange, PropertyProvider *aProvider,
-                            PropertyProvider::Spacing* aSpacing)
+                            PropertyProvider::Spacing* aSpacing) const
 {
     NS_ASSERTION(aRange.end <= GetLength(), "Substring out of range");
 
     Range ligatureRange = aRange;
     ShrinkToLigatureBoundaries(&ligatureRange);
 
     gfxFloat result =
         ComputePartialLigatureWidth(Range(aRange.start, ligatureRange.start),
@@ -1054,17 +1058,17 @@ gfxTextRun::SetLineBreaks(Range aRange,
     // account. There is no change in advance width.
     if (aAdvanceWidthDelta) {
         *aAdvanceWidthDelta = 0;
     }
     return false;
 }
 
 uint32_t
-gfxTextRun::FindFirstGlyphRunContaining(uint32_t aOffset)
+gfxTextRun::FindFirstGlyphRunContaining(uint32_t aOffset) const
 {
     NS_ASSERTION(aOffset <= GetLength(), "Bad offset looking for glyphrun");
     NS_ASSERTION(GetLength() == 0 || mGlyphRuns.Length() > 0,
                  "non-empty text but no glyph runs present!");
     if (aOffset == GetLength())
         return mGlyphRuns.Length();
     uint32_t start = 0;
     uint32_t end = mGlyphRuns.Length();
@@ -1199,17 +1203,17 @@ gfxTextRun::SanitizeGlyphRuns()
             (i == lastRunIndex && run.mCharacterOffset == GetLength())) {
             mGlyphRuns.RemoveElementAt(i);
             --lastRunIndex;
         }
     }
 }
 
 uint32_t
-gfxTextRun::CountMissingGlyphs()
+gfxTextRun::CountMissingGlyphs() const
 {
     uint32_t i;
     uint32_t count = 0;
     for (i = 0; i < GetLength(); ++i) {
         if (mCharacterGlyphs[i].IsMissing()) {
             ++count;
         }
     }
@@ -1281,17 +1285,17 @@ gfxTextRun::CopyGlyphDataFrom(gfxTextRun
             }
         }
         dstGlyphs[i] = g;
     }
 
     // Copy glyph runs
     GlyphRunIterator iter(aSource, aRange);
 #ifdef DEBUG
-    GlyphRun *prevRun = nullptr;
+    const GlyphRun *prevRun = nullptr;
 #endif
     while (iter.NextRun()) {
         gfxFont *font = iter.GetGlyphRun()->mFont;
         NS_ASSERTION(!prevRun || prevRun->mFont != iter.GetGlyphRun()->mFont ||
                      prevRun->mMatchType != iter.GetGlyphRun()->mMatchType ||
                      prevRun->mOrientation != iter.GetGlyphRun()->mOrientation,
                      "Glyphruns not coalesced?");
 #ifdef DEBUG
--- a/gfx/thebes/gfxTextRun.h
+++ b/gfx/thebes/gfxTextRun.h
@@ -143,17 +143,17 @@ public:
     {
         uint32_t start;
         uint32_t end;
         uint32_t Length() const { return end - start; }
 
         Range() : start(0), end(0) {}
         Range(uint32_t aStart, uint32_t aEnd)
             : start(aStart), end(aEnd) {}
-        explicit Range(gfxTextRun* aTextRun)
+        explicit Range(const gfxTextRun* aTextRun)
             : start(0), end(aTextRun->GetLength()) {}
     };
 
     // All coordinates are in layout/app units
 
     /**
      * Set the potential linebreaks for a substring of the textrun. These are
      * the "allow break before" points. Initially, there are no potential
@@ -262,55 +262,56 @@ public:
      *   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(Range aRange, gfxPoint aPt, const DrawParams& aParams);
+    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, gfxTextRun* aMark,
                            gfxFloat aMarkAdvance, gfxPoint aPt,
-                           Range aRange, PropertyProvider* aProvider);
+                           Range aRange, PropertyProvider* aProvider) const;
 
     /**
      * Computes the ReflowMetrics for a substring.
      * Uses GetSpacing from aBreakProvider.
      * @param aBoundingBoxType which kind of bounding box (loose/tight)
      */
     Metrics MeasureText(Range aRange,
                         gfxFont::BoundingBoxType aBoundingBoxType,
                         DrawTarget* aDrawTargetForTightBoundingBox,
-                        PropertyProvider* aProvider);
+                        PropertyProvider* aProvider) const;
 
     Metrics MeasureText(gfxFont::BoundingBoxType aBoundingBoxType,
                         DrawTarget* aDrawTargetForTightBoundingBox,
-                        PropertyProvider* aProvider = nullptr) {
+                        PropertyProvider* aProvider = nullptr) const {
         return MeasureText(Range(this), aBoundingBoxType,
                            aDrawTargetForTightBoundingBox, aProvider);
     }
 
     /**
      * Computes just the advance width for a substring.
      * Uses GetSpacing from aBreakProvider.
      * If aSpacing is not null, the spacing attached before and after
      * the substring would be returned in it. NOTE: the spacing is
      * included in the advance width.
      */
     gfxFloat GetAdvanceWidth(Range aRange, PropertyProvider *aProvider,
-                             PropertyProvider::Spacing* aSpacing = nullptr);
+                             PropertyProvider::Spacing*
+                                 aSpacing = nullptr) const;
 
-    gfxFloat GetAdvanceWidth() {
+    gfxFloat GetAdvanceWidth() const {
         return GetAdvanceWidth(Range(this), nullptr);
     }
 
     /**
      * Clear all stored line breaks for the given range (both before and after),
      * and then set the line-break state before aRange.start to aBreakBefore and
      * after the last cluster to aBreakAfter.
      * 
@@ -447,29 +448,29 @@ public:
         RefPtr<gfxFont> mFont;   // never null
         uint32_t          mCharacterOffset; // into original UTF16 string
         uint8_t           mMatchType;
         uint16_t          mOrientation; // gfxTextRunFactory::TEXT_ORIENT_* value
     };
 
     class GlyphRunIterator {
     public:
-        GlyphRunIterator(gfxTextRun *aTextRun, Range aRange)
+        GlyphRunIterator(const gfxTextRun *aTextRun, Range aRange)
           : mTextRun(aTextRun)
           , mStartOffset(aRange.start)
           , mEndOffset(aRange.end) {
             mNextIndex = mTextRun->FindFirstGlyphRunContaining(aRange.start);
         }
         bool NextRun();
-        GlyphRun *GetGlyphRun() { return mGlyphRun; }
-        uint32_t GetStringStart() { return mStringStart; }
-        uint32_t GetStringEnd() { return mStringEnd; }
+        const GlyphRun *GetGlyphRun() const { return mGlyphRun; }
+        uint32_t GetStringStart() const { return mStringStart; }
+        uint32_t GetStringEnd() const { return mStringEnd; }
     private:
-        gfxTextRun *mTextRun;
-        GlyphRun   *mGlyphRun;
+        const gfxTextRun *mTextRun;
+        const GlyphRun   *mGlyphRun;
         uint32_t    mStringStart;
         uint32_t    mStringEnd;
         uint32_t    mNextIndex;
         uint32_t    mStartOffset;
         uint32_t    mEndOffset;
     };
 
     class GlyphRunOffsetComparator {
@@ -507,16 +508,20 @@ public:
      */
     nsresult AddGlyphRun(gfxFont *aFont, uint8_t aMatchType,
                          uint32_t aStartCharIndex, bool aForceNewRun,
                          uint16_t aOrientation);
     void ResetGlyphRuns() { mGlyphRuns.Clear(); }
     void SortGlyphRuns();
     void SanitizeGlyphRuns();
 
+    const CompressedGlyph* GetCharacterGlyphs() const final {
+        MOZ_ASSERT(mCharacterGlyphs, "failed to initialize mCharacterGlyphs");
+        return mCharacterGlyphs;
+    }
     CompressedGlyph* GetCharacterGlyphs() final {
         MOZ_ASSERT(mCharacterGlyphs, "failed to initialize mCharacterGlyphs");
         return mCharacterGlyphs;
     }
 
     // clean out results from shaping in progress, used for fallback scenarios
     void ClearGlyphsAndCharacters();
 
@@ -558,24 +563,24 @@ public:
     /**
      * Prefetch all the glyph extents needed to ensure that Measure calls
      * on this textrun not requesting tight boundingBoxes will succeed. Note
      * that some glyph extents might not be fetched due to OOM or other
      * errors.
      */
     void FetchGlyphExtents(DrawTarget* aRefDrawTarget);
 
-    uint32_t CountMissingGlyphs();
+    uint32_t CountMissingGlyphs() const;
     const GlyphRun *GetGlyphRuns(uint32_t *aNumGlyphRuns) {
         *aNumGlyphRuns = mGlyphRuns.Length();
         return mGlyphRuns.Elements();
     }
     // Returns the index of the GlyphRun containing the given offset.
     // Returns mGlyphRuns.Length() when aOffset is mCharacterCount.
-    uint32_t FindFirstGlyphRunContaining(uint32_t aOffset);
+    uint32_t FindFirstGlyphRunContaining(uint32_t aOffset) const;
 
     // Copy glyph data from a ShapedWord into this textrun.
     void CopyGlyphDataFrom(gfxShapedWord *aSource, uint32_t aStart);
 
     // Copy glyph data for a range of characters from aSource to this
     // textrun.
     void CopyGlyphDataFrom(gfxTextRun *aSource, Range aRange, uint32_t aDest);
 
@@ -633,17 +638,17 @@ public:
         eShapingState_ForceFallbackFeature    // redo with fallback forced on
     };
 
     ShapingState GetShapingState() const { return mShapingState; }
     void SetShapingState(ShapingState aShapingState) {
         mShapingState = aShapingState;
     }
 
-    int32_t GetAdvanceForGlyph(uint32_t aIndex)
+    int32_t GetAdvanceForGlyph(uint32_t aIndex) const
     {
         const CompressedGlyph& glyphData = mCharacterGlyphs[aIndex];
         if (glyphData.IsSimpleGlyph()) {
             return glyphData.GetSimpleAdvance();
         }
         uint32_t glyphCount = glyphData.GetGlyphCount();
         if (!glyphCount) {
             return 0;
@@ -680,70 +685,73 @@ protected:
     // Pointer to the array of CompressedGlyph records; must be initialized
     // when the object is constructed.
     CompressedGlyph *mCharacterGlyphs;
 
 private:
     // **** general helpers **** 
 
     // Get the total advance for a range of glyphs.
-    int32_t GetAdvanceForGlyphs(Range aRange);
+    int32_t GetAdvanceForGlyphs(Range aRange) const;
 
     // Spacing for characters outside the range aSpacingStart/aSpacingEnd
     // is assumed to be zero; such characters are not passed to aProvider.
     // This is useful to protect aProvider from being passed character indices
     // it is not currently able to handle.
     bool GetAdjustedSpacingArray(Range aRange, PropertyProvider *aProvider,
                                  Range aSpacingRange,
-                                 nsTArray<PropertyProvider::Spacing> *aSpacing);
+                                 nsTArray<PropertyProvider::Spacing>*
+                                     aSpacing) const;
 
     CompressedGlyph& EnsureComplexGlyph(uint32_t aIndex)
     {
         gfxShapedText::EnsureComplexGlyph(aIndex, mCharacterGlyphs[aIndex]);
         return mCharacterGlyphs[aIndex];
     }
 
     //  **** ligature helpers ****
     // (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(Range aPartRange,
-                                     PropertyProvider *aProvider);
+                                     PropertyProvider *aProvider) const;
     gfxFloat ComputePartialLigatureWidth(Range aPartRange,
-                                         PropertyProvider *aProvider);
+                                         PropertyProvider *aProvider) const;
     void DrawPartialLigature(gfxFont *aFont, Range aRange,
                              gfxPoint *aPt, PropertyProvider *aProvider,
-                             TextRunDrawParams& aParams, uint16_t aOrientation);
+                             TextRunDrawParams& aParams,
+                             uint16_t aOrientation) const;
     // Advance aRange.start to the start of the nearest ligature, back
     // up aRange.end to the nearest ligature end; may result in
     // aRange->start == aRange->end.
-    void ShrinkToLigatureBoundaries(Range* aRange);
+    void ShrinkToLigatureBoundaries(Range* aRange) const;
     // result in appunits
-    gfxFloat GetPartialLigatureWidth(Range aRange, PropertyProvider *aProvider);
+    gfxFloat GetPartialLigatureWidth(Range aRange,
+                                     PropertyProvider *aProvider) const;
     void AccumulatePartialLigatureMetrics(gfxFont *aFont, Range aRange,
                                           gfxFont::BoundingBoxType aBoundingBoxType,
                                           DrawTarget* aRefDrawTarget,
                                           PropertyProvider *aProvider,
                                           uint16_t aOrientation,
-                                          Metrics *aMetrics);
+                                          Metrics *aMetrics) const;
 
     // **** measurement helper ****
     void AccumulateMetricsForRun(gfxFont *aFont, Range aRange,
                                  gfxFont::BoundingBoxType aBoundingBoxType,
                                  DrawTarget* aRefDrawTarget,
                                  PropertyProvider *aProvider,
                                  Range aSpacingRange,
                                  uint16_t aOrientation,
-                                 Metrics *aMetrics);
+                                 Metrics *aMetrics) const;
 
     // **** drawing helper ****
     void DrawGlyphs(gfxFont *aFont, Range aRange, gfxPoint *aPt,
                     PropertyProvider *aProvider, Range aSpacingRange,
-                    TextRunDrawParams& aParams, uint16_t aOrientation);
+                    TextRunDrawParams& aParams, uint16_t aOrientation) const;
 
     // XXX this should be changed to a GlyphRun plus a maybe-null GlyphRun*,
     // for smaller size especially in the super-common one-glyphrun case
     AutoTArray<GlyphRun,1>        mGlyphRuns;
 
     void             *mUserData;
     gfxFontGroup     *mFontGroup; // addrefed on creation, but our reference
                                   // may be released by ReleaseFontGroup()
--- a/layout/generic/nsTextRunTransformations.cpp
+++ b/layout/generic/nsTextRunTransformations.cpp
@@ -130,17 +130,17 @@ MergeCharactersInTextRun(gfxTextRun* aDe
                          const bool* aCharsToMerge, const bool* aDeletedChars)
 {
   aDest->ResetGlyphRuns();
 
   gfxTextRun::GlyphRunIterator iter(aSrc, gfxTextRun::Range(aSrc));
   uint32_t offset = 0;
   AutoTArray<gfxTextRun::DetailedGlyph,2> glyphs;
   while (iter.NextRun()) {
-    gfxTextRun::GlyphRun* run = iter.GetGlyphRun();
+    const gfxTextRun::GlyphRun* run = iter.GetGlyphRun();
     nsresult rv = aDest->AddGlyphRun(run->mFont, run->mMatchType,
                                      offset, false, run->mOrientation);
     if (NS_FAILED(rv))
       return;
 
     bool anyMissing = false;
     uint32_t mergeRunStart = iter.GetStringStart();
     const gfxTextRun::CompressedGlyph *srcGlyphs = aSrc->GetCharacterGlyphs();