layout/svg/SVGTextFrame.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef MOZILLA_SVGTEXTFRAME_H
     7 #define MOZILLA_SVGTEXTFRAME_H
     9 #include "mozilla/Attributes.h"
    10 #include "mozilla/RefPtr.h"
    11 #include "mozilla/gfx/2D.h"
    12 #include "gfxMatrix.h"
    13 #include "gfxRect.h"
    14 #include "gfxSVGGlyphs.h"
    15 #include "nsIContent.h"
    16 #include "nsStubMutationObserver.h"
    17 #include "nsSVGPaintServerFrame.h"
    19 class nsDisplaySVGText;
    20 class nsRenderingContext;
    21 class SVGTextFrame;
    22 class nsTextFrame;
    24 typedef nsSVGDisplayContainerFrame SVGTextFrameBase;
    26 namespace mozilla {
    28 class CharIterator;
    29 class nsISVGPoint;
    30 class TextFrameIterator;
    31 class TextNodeCorrespondenceRecorder;
    32 struct TextRenderedRun;
    33 class TextRenderedRunIterator;
    35 namespace dom {
    36 class SVGIRect;
    37 }
    39 /**
    40  * Information about the positioning for a single character in an SVG <text>
    41  * element.
    42  *
    43  * During SVG text layout, we use infinity values to represent positions and
    44  * rotations that are not explicitly specified with x/y/rotate attributes.
    45  */
    46 struct CharPosition
    47 {
    48   CharPosition()
    49     : mAngle(0),
    50       mHidden(false),
    51       mUnaddressable(false),
    52       mClusterOrLigatureGroupMiddle(false),
    53       mRunBoundary(false),
    54       mStartOfChunk(false)
    55   {
    56   }
    58   CharPosition(gfxPoint aPosition, double aAngle)
    59     : mPosition(aPosition),
    60       mAngle(aAngle),
    61       mHidden(false),
    62       mUnaddressable(false),
    63       mClusterOrLigatureGroupMiddle(false),
    64       mRunBoundary(false),
    65       mStartOfChunk(false)
    66   {
    67   }
    69   static CharPosition Unspecified(bool aUnaddressable)
    70   {
    71     CharPosition cp(UnspecifiedPoint(), UnspecifiedAngle());
    72     cp.mUnaddressable = aUnaddressable;
    73     return cp;
    74   }
    76   bool IsAngleSpecified() const
    77   {
    78     return mAngle != UnspecifiedAngle();
    79   }
    81   bool IsXSpecified() const
    82   {
    83     return mPosition.x != UnspecifiedCoord();
    84   }
    86   bool IsYSpecified() const
    87   {
    88     return mPosition.y != UnspecifiedCoord();
    89   }
    91   gfxPoint mPosition;
    92   double mAngle;
    94   // not displayed due to falling off the end of a <textPath>
    95   bool mHidden;
    97   // skipped in positioning attributes due to being collapsed-away white space
    98   bool mUnaddressable;
   100   // a preceding character is what positioning attributes address
   101   bool mClusterOrLigatureGroupMiddle;
   103   // rendering is split here since an explicit position or rotation was given
   104   bool mRunBoundary;
   106   // an anchored chunk begins here
   107   bool mStartOfChunk;
   109 private:
   110   static gfxFloat UnspecifiedCoord()
   111   {
   112     return std::numeric_limits<gfxFloat>::infinity();
   113   }
   115   static double UnspecifiedAngle()
   116   {
   117     return std::numeric_limits<double>::infinity();
   118   }
   120   static gfxPoint UnspecifiedPoint()
   121   {
   122     return gfxPoint(UnspecifiedCoord(), UnspecifiedCoord());
   123   }
   124 };
   126 /**
   127  * A runnable to mark glyph positions as needing to be recomputed
   128  * and to invalid the bounds of the SVGTextFrame frame.
   129  */
   130 class GlyphMetricsUpdater : public nsRunnable {
   131 public:
   132   NS_DECL_NSIRUNNABLE
   133   GlyphMetricsUpdater(SVGTextFrame* aFrame) : mFrame(aFrame) { }
   134   static void Run(SVGTextFrame* aFrame);
   135   void Revoke() { mFrame = nullptr; }
   136 private:
   137   SVGTextFrame* mFrame;
   138 };
   140 // Slightly horrible callback for deferring application of opacity
   141 struct SVGTextContextPaint : public gfxTextContextPaint {
   142   already_AddRefed<gfxPattern> GetFillPattern(float aOpacity,
   143                                               const gfxMatrix& aCTM) MOZ_OVERRIDE;
   144   already_AddRefed<gfxPattern> GetStrokePattern(float aOpacity,
   145                                                 const gfxMatrix& aCTM) MOZ_OVERRIDE;
   147   void SetFillOpacity(float aOpacity) { mFillOpacity = aOpacity; }
   148   float GetFillOpacity() MOZ_OVERRIDE { return mFillOpacity; }
   150   void SetStrokeOpacity(float aOpacity) { mStrokeOpacity = aOpacity; }
   151   float GetStrokeOpacity() MOZ_OVERRIDE { return mStrokeOpacity; }
   153   struct Paint {
   154     Paint() : mPaintType(eStyleSVGPaintType_None) {}
   156     void SetPaintServer(nsIFrame *aFrame, const gfxMatrix& aContextMatrix,
   157                         nsSVGPaintServerFrame *aPaintServerFrame) {
   158       mPaintType = eStyleSVGPaintType_Server;
   159       mPaintDefinition.mPaintServerFrame = aPaintServerFrame;
   160       mFrame = aFrame;
   161       mContextMatrix = aContextMatrix;
   162     }
   164     void SetColor(const nscolor &aColor) {
   165       mPaintType = eStyleSVGPaintType_Color;
   166       mPaintDefinition.mColor = aColor;
   167     }
   169     void SetContextPaint(gfxTextContextPaint *aContextPaint,
   170                          nsStyleSVGPaintType aPaintType) {
   171       NS_ASSERTION(aPaintType == eStyleSVGPaintType_ContextFill ||
   172                    aPaintType == eStyleSVGPaintType_ContextStroke,
   173                    "Invalid context paint type");
   174       mPaintType = aPaintType;
   175       mPaintDefinition.mContextPaint = aContextPaint;
   176     }
   178     union {
   179       nsSVGPaintServerFrame *mPaintServerFrame;
   180       gfxTextContextPaint *mContextPaint;
   181       nscolor mColor;
   182     } mPaintDefinition;
   184     nsIFrame *mFrame;
   185     // CTM defining the user space for the pattern we will use.
   186     gfxMatrix mContextMatrix;
   187     nsStyleSVGPaintType mPaintType;
   189     // Device-space-to-pattern-space
   190     gfxMatrix mPatternMatrix;
   191     nsRefPtrHashtable<nsFloatHashKey, gfxPattern> mPatternCache;
   193     already_AddRefed<gfxPattern> GetPattern(float aOpacity,
   194                                             nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
   195                                             const gfxMatrix& aCTM);
   196   };
   198   Paint mFillPaint;
   199   Paint mStrokePaint;
   201   float mFillOpacity;
   202   float mStrokeOpacity;
   203 };
   205 } // namespace mozilla
   207 /**
   208  * Frame class for SVG <text> elements, used when the
   209  * layout.svg.css-text.enabled is true.
   210  *
   211  * An SVGTextFrame manages SVG text layout, painting and interaction for
   212  * all descendent text content elements.  The frame tree will look like this:
   213  *
   214  *   SVGTextFrame                     -- for <text>
   215  *     <anonymous block frame>
   216  *       ns{Block,Inline,Text}Frames  -- for text nodes, <tspan>s, <a>s, etc.
   217  *
   218  * SVG text layout is done by:
   219  *
   220  *   1. Reflowing the anonymous block frame.
   221  *   2. Inspecting the (app unit) positions of the glyph for each character in
   222  *      the nsTextFrames underneath the anonymous block frame.
   223  *   3. Determining the (user unit) positions for each character in the <text>
   224  *      using the x/y/dx/dy/rotate attributes on all the text content elements,
   225  *      and using the step 2 results to fill in any gaps.
   226  *   4. Applying any other SVG specific text layout (anchoring and text paths)
   227  *      to the positions computed in step 3.
   228  *
   229  * Rendering of the text is done by splitting up each nsTextFrame into ranges
   230  * that can be contiguously painted.  (For example <text x="10 20">abcd</text>
   231  * would have two contiguous ranges: one for the "a" and one for the "bcd".)
   232  * Each range is called a "text rendered run", represented by a TextRenderedRun
   233  * object.  The TextRenderedRunIterator class performs that splitting and
   234  * returns a TextRenderedRun for each bit of text to be painted separately.
   235  *
   236  * Each rendered run is painted by calling nsTextFrame::PaintText.  If the text
   237  * formatting is simple enough (solid fill, no stroking, etc.), PaintText will
   238  * itself do the painting.  Otherwise, a DrawPathCallback is passed to
   239  * PaintText so that we can fill the text geometry with SVG paint servers.
   240  */
   241 class SVGTextFrame : public SVGTextFrameBase
   242 {
   243   friend nsIFrame*
   244   NS_NewSVGTextFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
   246   friend class mozilla::CharIterator;
   247   friend class mozilla::GlyphMetricsUpdater;
   248   friend class mozilla::TextFrameIterator;
   249   friend class mozilla::TextNodeCorrespondenceRecorder;
   250   friend struct mozilla::TextRenderedRun;
   251   friend class mozilla::TextRenderedRunIterator;
   252   friend class MutationObserver;
   253   friend class nsDisplaySVGText;
   255   typedef mozilla::gfx::Path Path;
   256   typedef mozilla::SVGTextContextPaint SVGTextContextPaint;
   258 protected:
   259   SVGTextFrame(nsStyleContext* aContext)
   260     : SVGTextFrameBase(aContext),
   261       mFontSizeScaleFactor(1.0f),
   262       mLastContextScale(1.0f),
   263       mLengthAdjustScaleFactor(1.0f)
   264   {
   265     AddStateBits(NS_STATE_SVG_POSITIONING_DIRTY);
   266   }
   268 public:
   269   NS_DECL_QUERYFRAME_TARGET(SVGTextFrame)
   270   NS_DECL_QUERYFRAME
   271   NS_DECL_FRAMEARENA_HELPERS
   273   // nsIFrame:
   274   virtual void Init(nsIContent* aContent,
   275                     nsIFrame*   aParent,
   276                     nsIFrame*   aPrevInFlow) MOZ_OVERRIDE;
   278   virtual nsresult AttributeChanged(int32_t aNamespaceID,
   279                                     nsIAtom* aAttribute,
   280                                     int32_t aModType) MOZ_OVERRIDE;
   282   virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE
   283   {
   284     return GetFirstPrincipalChild()->GetContentInsertionFrame();
   285   }
   287   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
   288                                 const nsRect&           aDirtyRect,
   289                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
   291   /**
   292    * Get the "type" of the frame
   293    *
   294    * @see nsGkAtoms::svgTextFrame
   295    */
   296   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
   298 #ifdef DEBUG_FRAME_DUMP
   299   virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
   300   {
   301     return MakeFrameName(NS_LITERAL_STRING("SVGText"), aResult);
   302   }
   303 #endif
   305   virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
   307   /**
   308    * Finds the nsTextFrame for the closest rendered run to the specified point.
   309    */
   310   virtual void FindCloserFrameForSelection(nsPoint aPoint,
   311                                           FrameWithDistance* aCurrentBestFrame) MOZ_OVERRIDE;
   315   // nsISVGChildFrame interface:
   316   virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE;
   317   virtual nsresult PaintSVG(nsRenderingContext* aContext,
   318                             const nsIntRect* aDirtyRect,
   319                             nsIFrame* aTransformRoot = nullptr) MOZ_OVERRIDE;
   320   virtual nsIFrame* GetFrameForPoint(const nsPoint& aPoint) MOZ_OVERRIDE;
   321   virtual void ReflowSVG() MOZ_OVERRIDE;
   322   virtual nsRect GetCoveredRegion() MOZ_OVERRIDE;
   323   virtual SVGBBox GetBBoxContribution(const Matrix& aToBBoxUserspace,
   324                                       uint32_t aFlags) MOZ_OVERRIDE;
   326   // nsSVGContainerFrame methods:
   327   virtual gfxMatrix GetCanvasTM(uint32_t aFor,
   328                                 nsIFrame* aTransformRoot = nullptr) MOZ_OVERRIDE;
   330   // SVG DOM text methods:
   331   uint32_t GetNumberOfChars(nsIContent* aContent);
   332   float GetComputedTextLength(nsIContent* aContent);
   333   nsresult SelectSubString(nsIContent* aContent, uint32_t charnum, uint32_t nchars);
   334   nsresult GetSubStringLength(nsIContent* aContent, uint32_t charnum,
   335                               uint32_t nchars, float* aResult);
   336   int32_t GetCharNumAtPosition(nsIContent* aContent, mozilla::nsISVGPoint* point);
   338   nsresult GetStartPositionOfChar(nsIContent* aContent, uint32_t aCharNum,
   339                                   mozilla::nsISVGPoint** aResult);
   340   nsresult GetEndPositionOfChar(nsIContent* aContent, uint32_t aCharNum,
   341                                 mozilla::nsISVGPoint** aResult);
   342   nsresult GetExtentOfChar(nsIContent* aContent, uint32_t aCharNum,
   343                            mozilla::dom::SVGIRect** aResult);
   344   nsresult GetRotationOfChar(nsIContent* aContent, uint32_t aCharNum,
   345                              float* aResult);
   347   // SVGTextFrame methods:
   349   /**
   350    * Schedules mPositions to be recomputed and the covered region to be
   351    * updated.
   352    */
   353   void NotifyGlyphMetricsChange();
   355   /**
   356    * Calls ScheduleReflowSVGNonDisplayText if this is a non-display frame,
   357    * and nsSVGUtils::ScheduleReflowSVG otherwise.
   358    */
   359   void ScheduleReflowSVG();
   361   /**
   362    * Reflows the anonymous block frame of this non-display SVGTextFrame.
   363    *
   364    * When we are under nsSVGDisplayContainerFrame::ReflowSVG, we need to
   365    * reflow any SVGTextFrame frames in the subtree in case they are
   366    * being observed (by being for example in a <mask>) and the change
   367    * that caused the reflow would not already have caused a reflow.
   368    *
   369    * Note that displayed SVGTextFrames are reflowed as needed, when PaintSVG
   370    * is called or some SVG DOM method is called on the element.
   371    */
   372   void ReflowSVGNonDisplayText();
   374   /**
   375    * This is a function that behaves similarly to nsSVGUtils::ScheduleReflowSVG,
   376    * but which will skip over any ancestor non-display container frames on the
   377    * way to the nsSVGOuterSVGFrame.  It exists for the situation where a
   378    * non-display <text> element has changed and needs to ensure ReflowSVG will
   379    * be called on its closest display container frame, so that
   380    * nsSVGDisplayContainerFrame::ReflowSVG will call ReflowSVGNonDisplayText on
   381    * it.
   382    *
   383    * The only case where we have to do this is in response to a style change on
   384    * a non-display <text>; the only caller of ScheduleReflowSVGNonDisplayText
   385    * currently is SVGTextFrame::DidSetStyleContext.
   386    */
   387   void ScheduleReflowSVGNonDisplayText();
   389   /**
   390    * Updates the mFontSizeScaleFactor value by looking at the range of
   391    * font-sizes used within the <text>.
   392    *
   393    * @return Whether mFontSizeScaleFactor changed.
   394    */
   395   bool UpdateFontSizeScaleFactor();
   397   double GetFontSizeScaleFactor() const;
   399   /**
   400    * Takes a point from the <text> element's user space and
   401    * converts it to the appropriate frame user space of aChildFrame,
   402    * according to which rendered run the point hits.
   403    */
   404   gfxPoint TransformFramePointToTextChild(const gfxPoint& aPoint,
   405                                           nsIFrame* aChildFrame);
   407   /**
   408    * Takes a rectangle, aRect, in the <text> element's user space, and
   409    * returns a rectangle in aChildFrame's frame user space that
   410    * covers intersections of aRect with each rendered run for text frames
   411    * within aChildFrame.
   412    */
   413   gfxRect TransformFrameRectToTextChild(const gfxRect& aRect,
   414                                         nsIFrame* aChildFrame);
   416   /**
   417    * Takes an app unit rectangle in the coordinate space of a given descendant
   418    * frame of this frame, and returns a rectangle in the <text> element's user
   419    * space that covers all parts of rendered runs that intersect with the
   420    * rectangle.
   421    */
   422   gfxRect TransformFrameRectFromTextChild(const nsRect& aRect,
   423                                           nsIFrame* aChildFrame);
   425 private:
   426   /**
   427    * Mutation observer used to watch for text positioning attribute changes
   428    * on descendent text content elements (like <tspan>s).
   429    */
   430   class MutationObserver : public nsStubMutationObserver {
   431   public:
   432     MutationObserver()
   433       : mFrame(nullptr)
   434     {
   435     }
   437     void StartObserving(SVGTextFrame* aFrame)
   438     {
   439       NS_ASSERTION(!mFrame, "should not be observing yet!");
   440       mFrame = aFrame;
   441       aFrame->GetContent()->AddMutationObserver(this);
   442     }
   444     virtual ~MutationObserver()
   445     {
   446       if (mFrame) {
   447         mFrame->GetContent()->RemoveMutationObserver(this);
   448       }
   449     }
   451     // nsISupports
   452     NS_DECL_ISUPPORTS
   454     // nsIMutationObserver
   455     NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   456     NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   457     NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
   458     NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
   459     NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
   461   private:
   462     SVGTextFrame* mFrame;
   463   };
   465   /**
   466    * Reflows the anonymous block child if it is dirty or has dirty
   467    * children, or if the SVGTextFrame itself is dirty.
   468    */
   469   void MaybeReflowAnonymousBlockChild();
   471   /**
   472    * Performs the actual work of reflowing the anonymous block child.
   473    */
   474   void DoReflow();
   476   /**
   477    * Recomputes mPositions by calling DoGlyphPositioning if this information
   478    * is out of date.
   479    */
   480   void UpdateGlyphPositioning();
   482   /**
   483    * Populates mPositions with positioning information for each character
   484    * within the <text>.
   485    */
   486   void DoGlyphPositioning();
   488   /**
   489    * Converts the specified index into mPositions to an addressable
   490    * character index (as can be used with the SVG DOM text methods)
   491    * relative to the specified text child content element.
   492    *
   493    * @param aIndex The global character index.
   494    * @param aContent The descendant text child content element that
   495    *   the returned addressable index will be relative to; null
   496    *   means the same as the <text> element.
   497    * @return The addressable index, or -1 if the index cannot be
   498    *   represented as an addressable index relative to aContent.
   499    */
   500   int32_t
   501   ConvertTextElementCharIndexToAddressableIndex(int32_t aIndex,
   502                                                 nsIContent* aContent);
   504   /**
   505    * Recursive helper for ResolvePositions below.
   506    *
   507    * @param aContent The current node.
   508    * @param aIndex The current character index.
   509    * @param aInTextPath Whether we are currently under a <textPath> element.
   510    * @param aForceStartOfChunk Whether the next character we find should start a
   511    *   new anchored chunk.
   512    * @return The character index we got up to.
   513    */
   514   uint32_t ResolvePositions(nsIContent* aContent, uint32_t aIndex,
   515                             bool aInTextPath, bool& aForceStartOfChunk,
   516                             nsTArray<gfxPoint>& aDeltas);
   518   /**
   519    * Initializes mPositions with character position information based on
   520    * x/y/rotate attributes, leaving unspecified values in the array if a position
   521    * was not given for that character.  Also fills aDeltas with values based on
   522    * dx/dy attributes.
   523    *
   524    * @param aRunPerGlyph Whether mPositions should record that a new run begins
   525    *   at each glyph.
   526    * @return True if we recorded any positions.
   527    */
   528   bool ResolvePositions(nsTArray<gfxPoint>& aDeltas, bool aRunPerGlyph);
   530   /**
   531    * Determines the position, in app units, of each character in the <text> as
   532    * laid out by reflow, and appends them to aPositions.  Any characters that
   533    * are undisplayed or trimmed away just get the last position.
   534    */
   535   void DetermineCharPositions(nsTArray<nsPoint>& aPositions);
   537   /**
   538    * Sets mStartOfChunk to true for each character in mPositions that starts a
   539    * line of text.
   540    */
   541   void AdjustChunksForLineBreaks();
   543   /**
   544    * Adjusts recorded character positions in mPositions to account for glyph
   545    * boundaries.  Four things are done:
   546    *
   547    *   1. mClusterOrLigatureGroupMiddle is set to true for all such characters.
   548    *
   549    *   2. Any run and anchored chunk boundaries that begin in the middle of a
   550    *      cluster/ligature group get moved to the start of the next
   551    *      cluster/ligature group.
   552    *
   553    *   3. The position of any character in the middle of a cluster/ligature
   554    *      group is updated to take into account partial ligatures and any
   555    *      rotation the glyph as a whole has.  (The values that come out of
   556    *      DetermineCharPositions which then get written into mPositions in
   557    *      ResolvePositions store the same position value for each part of the
   558    *      ligature.)
   559    *
   560    *   4. The rotation of any character in the middle of a cluster/ligature
   561    *      group is set to the rotation of the first character.
   562    */
   563   void AdjustPositionsForClusters();
   565   /**
   566    * Updates the character positions stored in mPositions to account for
   567    * text anchoring.
   568    */
   569   void DoAnchoring();
   571   /**
   572    * Updates character positions in mPositions for those characters inside a
   573    * <textPath>.
   574    */
   575   void DoTextPathLayout();
   577   /**
   578    * Returns whether we need to render the text using
   579    * nsTextFrame::DrawPathCallbacks rather than directly painting
   580    * the text frames.
   581    *
   582    * @param aShouldPaintSVGGlyphs (out) Whether SVG glyphs in the text
   583    *   should be painted.
   584    */
   585   bool ShouldRenderAsPath(nsRenderingContext* aContext, nsTextFrame* aFrame,
   586                           bool& aShouldPaintSVGGlyphs);
   588   // Methods to get information for a <textPath> frame.
   589   nsIFrame* GetTextPathPathFrame(nsIFrame* aTextPathFrame);
   590   mozilla::TemporaryRef<Path> GetTextPath(nsIFrame* aTextPathFrame);
   591   gfxFloat GetOffsetScale(nsIFrame* aTextPathFrame);
   592   gfxFloat GetStartOffset(nsIFrame* aTextPathFrame);
   594   DrawMode SetupCairoState(gfxContext* aContext,
   595                            nsIFrame* aFrame,
   596                            gfxTextContextPaint* aOuterContextPaint,
   597                            gfxTextContextPaint** aThisContextPaint);
   599   /**
   600    * Sets up the stroke style for |aFrame| in |aContext| and stores stroke
   601    * pattern information in |aThisContextPaint|.
   602    */
   603   bool SetupCairoStroke(gfxContext* aContext,
   604                         nsIFrame* aFrame,
   605                         gfxTextContextPaint* aOuterContextPaint,
   606                         SVGTextContextPaint* aThisContextPaint);
   608   /**
   609    * Sets up the fill style for |aFrame| in |aContext| and stores fill pattern
   610    * information in |aThisContextPaint|.
   611    */
   612   bool SetupCairoFill(gfxContext* aContext,
   613                       nsIFrame* aFrame,
   614                       gfxTextContextPaint* aOuterContextPaint,
   615                       SVGTextContextPaint* aThisContextPaint);
   617   /**
   618    * Stores in |aTargetPaint| information on how to reconstruct the current
   619    * fill or stroke pattern. Will also set the paint opacity to transparent if
   620    * the paint is set to "none".
   621    * @param aOuterContextPaint pattern information from the outer text context
   622    * @param aTargetPaint where to store the current pattern information
   623    * @param aFillOrStroke member pointer to the paint we are setting up
   624    * @param aProperty the frame property descriptor of the fill or stroke paint
   625    *   server frame
   626    */
   627   void SetupInheritablePaint(gfxContext* aContext,
   628                              nsIFrame* aFrame,
   629                              float& aOpacity,
   630                              gfxTextContextPaint* aOuterContextPaint,
   631                              SVGTextContextPaint::Paint& aTargetPaint,
   632                              nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
   633                              const FramePropertyDescriptor* aProperty);
   635   /**
   636    * The MutationObserver we have registered for the <text> element subtree.
   637    */
   638   MutationObserver mMutationObserver;
   640   /**
   641    * Cached canvasTM value.
   642    */
   643   nsAutoPtr<gfxMatrix> mCanvasTM;
   645   /**
   646    * The number of characters in the DOM after the final nsTextFrame.  For
   647    * example, with
   648    *
   649    *   <text>abcd<tspan display="none">ef</tspan></text>
   650    *
   651    * mTrailingUndisplayedCharacters would be 2.
   652    */
   653   uint32_t mTrailingUndisplayedCharacters;
   655   /**
   656    * Computed position information for each DOM character within the <text>.
   657    */
   658   nsTArray<mozilla::CharPosition> mPositions;
   660   /**
   661    * mFontSizeScaleFactor is used to cause the nsTextFrames to create text
   662    * runs with a font size different from the actual font-size property value.
   663    * This is used so that, for example with:
   664    *
   665    *   <svg>
   666    *     <g transform="scale(2)">
   667    *       <text font-size="10">abc</text>
   668    *     </g>
   669    *   </svg>
   670    *
   671    * a font size of 20 would be used.  It's preferable to use a font size that
   672    * is identical or close to the size that the text will appear on the screen,
   673    * because at very small or large font sizes, text metrics will be computed
   674    * differently due to the limited precision that text runs have.
   675    *
   676    * mFontSizeScaleFactor is the amount the actual font-size property value
   677    * should be multiplied by to cause the text run font size to (a) be within a
   678    * "reasonable" range, and (b) be close to the actual size to be painted on
   679    * screen.  (The "reasonable" range as determined by some #defines in
   680    * SVGTextFrame.cpp is 8..200.)
   681    */
   682   float mFontSizeScaleFactor;
   684   /**
   685    * The scale of the context that we last used to compute mFontSizeScaleFactor.
   686    * We record this so that we can tell when our scale transform has changed
   687    * enough to warrant reflowing the text.
   688    */
   689   float mLastContextScale;
   691   /**
   692    * The amount that we need to scale each rendered run to account for
   693    * lengthAdjust="spacingAndGlyphs".
   694    */
   695   float mLengthAdjustScaleFactor;
   696 };
   698 #endif

mercurial