LCOV - code coverage report
Current view: top level - layout/svg - SVGTextFrame.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 40 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 16 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       5             : 
       6             : #ifndef MOZILLA_SVGTEXTFRAME_H
       7             : #define MOZILLA_SVGTEXTFRAME_H
       8             : 
       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 "gfxTextRun.h"
      15             : #include "nsAutoPtr.h"
      16             : #include "nsIContent.h" // for GetContent
      17             : #include "nsStubMutationObserver.h"
      18             : #include "nsSVGContainerFrame.h"
      19             : 
      20             : class gfxContext;
      21             : class nsDisplaySVGText;
      22             : class SVGTextFrame;
      23             : class nsTextFrame;
      24             : 
      25             : namespace mozilla {
      26             : 
      27             : class CharIterator;
      28             : class nsISVGPoint;
      29             : class TextFrameIterator;
      30             : class TextNodeCorrespondenceRecorder;
      31             : struct TextRenderedRun;
      32             : class TextRenderedRunIterator;
      33             : 
      34             : namespace dom {
      35             : class SVGIRect;
      36             : class SVGPathElement;
      37             : } // namespace dom
      38             : 
      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             :   }
      57             : 
      58           0 :   CharPosition(gfxPoint aPosition, double aAngle)
      59           0 :     : mPosition(aPosition),
      60             :       mAngle(aAngle),
      61             :       mHidden(false),
      62             :       mUnaddressable(false),
      63             :       mClusterOrLigatureGroupMiddle(false),
      64             :       mRunBoundary(false),
      65           0 :       mStartOfChunk(false)
      66             :   {
      67           0 :   }
      68             : 
      69           0 :   static CharPosition Unspecified(bool aUnaddressable)
      70             :   {
      71           0 :     CharPosition cp(UnspecifiedPoint(), UnspecifiedAngle());
      72           0 :     cp.mUnaddressable = aUnaddressable;
      73           0 :     return cp;
      74             :   }
      75             : 
      76           0 :   bool IsAngleSpecified() const
      77             :   {
      78           0 :     return mAngle != UnspecifiedAngle();
      79             :   }
      80             : 
      81           0 :   bool IsXSpecified() const
      82             :   {
      83           0 :     return mPosition.x != UnspecifiedCoord();
      84             :   }
      85             : 
      86           0 :   bool IsYSpecified() const
      87             :   {
      88           0 :     return mPosition.y != UnspecifiedCoord();
      89             :   }
      90             : 
      91             :   gfxPoint mPosition;
      92             :   double mAngle;
      93             : 
      94             :   // not displayed due to falling off the end of a <textPath>
      95             :   bool mHidden;
      96             : 
      97             :   // skipped in positioning attributes due to being collapsed-away white space
      98             :   bool mUnaddressable;
      99             : 
     100             :   // a preceding character is what positioning attributes address
     101             :   bool mClusterOrLigatureGroupMiddle;
     102             : 
     103             :   // rendering is split here since an explicit position or rotation was given
     104             :   bool mRunBoundary;
     105             : 
     106             :   // an anchored chunk begins here
     107             :   bool mStartOfChunk;
     108             : 
     109             : private:
     110           0 :   static gfxFloat UnspecifiedCoord()
     111             :   {
     112           0 :     return std::numeric_limits<gfxFloat>::infinity();
     113             :   }
     114             : 
     115           0 :   static double UnspecifiedAngle()
     116             :   {
     117           0 :     return std::numeric_limits<double>::infinity();
     118             :   }
     119             : 
     120           0 :   static gfxPoint UnspecifiedPoint()
     121             :   {
     122           0 :     return gfxPoint(UnspecifiedCoord(), UnspecifiedCoord());
     123             :   }
     124             : };
     125             : 
     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 Runnable {
     131             : public:
     132             :   NS_DECL_NSIRUNNABLE
     133             :   explicit GlyphMetricsUpdater(SVGTextFrame* aFrame)
     134             :     : Runnable("GlyphMetricsUpdater")
     135             :     , mFrame(aFrame)
     136             :   {
     137             :   }
     138             :   static void Run(SVGTextFrame* aFrame);
     139             :   void Revoke() { mFrame = nullptr; }
     140             : private:
     141             :   SVGTextFrame* mFrame;
     142             : };
     143             : 
     144             : } // namespace mozilla
     145             : 
     146             : /**
     147             :  * Frame class for SVG <text> elements.
     148             :  *
     149             :  * An SVGTextFrame manages SVG text layout, painting and interaction for
     150             :  * all descendent text content elements.  The frame tree will look like this:
     151             :  *
     152             :  *   SVGTextFrame                     -- for <text>
     153             :  *     <anonymous block frame>
     154             :  *       ns{Block,Inline,Text}Frames  -- for text nodes, <tspan>s, <a>s, etc.
     155             :  *
     156             :  * SVG text layout is done by:
     157             :  *
     158             :  *   1. Reflowing the anonymous block frame.
     159             :  *   2. Inspecting the (app unit) positions of the glyph for each character in
     160             :  *      the nsTextFrames underneath the anonymous block frame.
     161             :  *   3. Determining the (user unit) positions for each character in the <text>
     162             :  *      using the x/y/dx/dy/rotate attributes on all the text content elements,
     163             :  *      and using the step 2 results to fill in any gaps.
     164             :  *   4. Applying any other SVG specific text layout (anchoring and text paths)
     165             :  *      to the positions computed in step 3.
     166             :  *
     167             :  * Rendering of the text is done by splitting up each nsTextFrame into ranges
     168             :  * that can be contiguously painted.  (For example <text x="10 20">abcd</text>
     169             :  * would have two contiguous ranges: one for the "a" and one for the "bcd".)
     170             :  * Each range is called a "text rendered run", represented by a TextRenderedRun
     171             :  * object.  The TextRenderedRunIterator class performs that splitting and
     172             :  * returns a TextRenderedRun for each bit of text to be painted separately.
     173             :  *
     174             :  * Each rendered run is painted by calling nsTextFrame::PaintText.  If the text
     175             :  * formatting is simple enough (solid fill, no stroking, etc.), PaintText will
     176             :  * itself do the painting.  Otherwise, a DrawPathCallback is passed to
     177             :  * PaintText so that we can fill the text geometry with SVG paint servers.
     178             :  */
     179             : class SVGTextFrame final : public nsSVGDisplayContainerFrame
     180             : {
     181             :   friend nsIFrame*
     182             :   NS_NewSVGTextFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
     183             : 
     184             :   friend class mozilla::CharIterator;
     185             :   friend class mozilla::GlyphMetricsUpdater;
     186             :   friend class mozilla::TextFrameIterator;
     187             :   friend class mozilla::TextNodeCorrespondenceRecorder;
     188             :   friend struct mozilla::TextRenderedRun;
     189             :   friend class mozilla::TextRenderedRunIterator;
     190             :   friend class MutationObserver;
     191             :   friend class nsDisplaySVGText;
     192             : 
     193             :   typedef gfxTextRun::Range Range;
     194             :   typedef mozilla::gfx::DrawTarget DrawTarget;
     195             :   typedef mozilla::gfx::Path Path;
     196             :   typedef mozilla::gfx::Point Point;
     197             : 
     198             : protected:
     199           0 :   explicit SVGTextFrame(nsStyleContext* aContext)
     200           0 :     : nsSVGDisplayContainerFrame(aContext, kClassID)
     201             :     , mTrailingUndisplayedCharacters(0)
     202             :     , mFontSizeScaleFactor(1.0f)
     203             :     , mLastContextScale(1.0f)
     204           0 :     , mLengthAdjustScaleFactor(1.0f)
     205             :   {
     206           0 :     AddStateBits(NS_STATE_SVG_POSITIONING_DIRTY);
     207           0 :   }
     208             : 
     209           0 :   ~SVGTextFrame() {}
     210             : 
     211             : public:
     212             :   NS_DECL_QUERYFRAME
     213           0 :   NS_DECL_FRAMEARENA_HELPERS(SVGTextFrame)
     214             : 
     215             :   // nsIFrame:
     216             :   virtual void Init(nsIContent*       aContent,
     217             :                     nsContainerFrame* aParent,
     218             :                     nsIFrame*         aPrevInFlow) override;
     219             : 
     220             :   virtual nsresult AttributeChanged(int32_t aNamespaceID,
     221             :                                     nsIAtom* aAttribute,
     222             :                                     int32_t aModType) override;
     223             : 
     224           0 :   virtual nsContainerFrame* GetContentInsertionFrame() override
     225             :   {
     226           0 :     return PrincipalChildList().FirstChild()->GetContentInsertionFrame();
     227             :   }
     228             : 
     229             :   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
     230             :                                 const nsRect&           aDirtyRect,
     231             :                                 const nsDisplayListSet& aLists) override;
     232             : 
     233             : #ifdef DEBUG_FRAME_DUMP
     234           0 :   virtual nsresult GetFrameName(nsAString& aResult) const override
     235             :   {
     236           0 :     return MakeFrameName(NS_LITERAL_STRING("SVGText"), aResult);
     237             :   }
     238             : #endif
     239             : 
     240             :   virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override;
     241             : 
     242             :   /**
     243             :    * Finds the nsTextFrame for the closest rendered run to the specified point.
     244             :    */
     245             :   virtual void FindCloserFrameForSelection(nsPoint aPoint,
     246             :                                           FrameWithDistance* aCurrentBestFrame) override;
     247             : 
     248             : 
     249             : 
     250             :   // nsSVGDisplayableFrame interface:
     251             :   virtual void NotifySVGChanged(uint32_t aFlags) override;
     252             :   virtual void PaintSVG(gfxContext& aContext,
     253             :                         const gfxMatrix& aTransform,
     254             :                         imgDrawingParams& aImgParams,
     255             :                         const nsIntRect* aDirtyRect = nullptr) override;
     256             :   virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) override;
     257             :   virtual void ReflowSVG() override;
     258             :   virtual SVGBBox GetBBoxContribution(const Matrix& aToBBoxUserspace,
     259             :                                       uint32_t aFlags) override;
     260             : 
     261             :   // nsSVGContainerFrame methods:
     262             :   virtual gfxMatrix GetCanvasTM() override;
     263             : 
     264             :   // SVG DOM text methods:
     265             :   uint32_t GetNumberOfChars(nsIContent* aContent);
     266             :   float GetComputedTextLength(nsIContent* aContent);
     267             :   nsresult SelectSubString(nsIContent* aContent, uint32_t charnum, uint32_t nchars);
     268             :   nsresult GetSubStringLength(nsIContent* aContent, uint32_t charnum,
     269             :                               uint32_t nchars, float* aResult);
     270             :   int32_t GetCharNumAtPosition(nsIContent* aContent, mozilla::nsISVGPoint* point);
     271             : 
     272             :   nsresult GetStartPositionOfChar(nsIContent* aContent, uint32_t aCharNum,
     273             :                                   mozilla::nsISVGPoint** aResult);
     274             :   nsresult GetEndPositionOfChar(nsIContent* aContent, uint32_t aCharNum,
     275             :                                 mozilla::nsISVGPoint** aResult);
     276             :   nsresult GetExtentOfChar(nsIContent* aContent, uint32_t aCharNum,
     277             :                            mozilla::dom::SVGIRect** aResult);
     278             :   nsresult GetRotationOfChar(nsIContent* aContent, uint32_t aCharNum,
     279             :                              float* aResult);
     280             : 
     281             :   // SVGTextFrame methods:
     282             : 
     283             :   /**
     284             :    * Handles a base or animated attribute value change to a descendant
     285             :    * text content element.
     286             :    */
     287             :   void HandleAttributeChangeInDescendant(mozilla::dom::Element* aElement,
     288             :                                          int32_t aNameSpaceID,
     289             :                                          nsIAtom* aAttribute);
     290             : 
     291             :   /**
     292             :    * Schedules mPositions to be recomputed and the covered region to be
     293             :    * updated.
     294             :    */
     295             :   void NotifyGlyphMetricsChange();
     296             : 
     297             :   /**
     298             :    * Calls ScheduleReflowSVGNonDisplayText if this is a non-display frame,
     299             :    * and nsSVGUtils::ScheduleReflowSVG otherwise.
     300             :    */
     301             :   void ScheduleReflowSVG();
     302             : 
     303             :   /**
     304             :    * Reflows the anonymous block frame of this non-display SVGTextFrame.
     305             :    *
     306             :    * When we are under nsSVGDisplayContainerFrame::ReflowSVG, we need to
     307             :    * reflow any SVGTextFrame frames in the subtree in case they are
     308             :    * being observed (by being for example in a <mask>) and the change
     309             :    * that caused the reflow would not already have caused a reflow.
     310             :    *
     311             :    * Note that displayed SVGTextFrames are reflowed as needed, when PaintSVG
     312             :    * is called or some SVG DOM method is called on the element.
     313             :    */
     314             :   void ReflowSVGNonDisplayText();
     315             : 
     316             :   /**
     317             :    * This is a function that behaves similarly to nsSVGUtils::ScheduleReflowSVG,
     318             :    * but which will skip over any ancestor non-display container frames on the
     319             :    * way to the nsSVGOuterSVGFrame.  It exists for the situation where a
     320             :    * non-display <text> element has changed and needs to ensure ReflowSVG will
     321             :    * be called on its closest display container frame, so that
     322             :    * nsSVGDisplayContainerFrame::ReflowSVG will call ReflowSVGNonDisplayText on
     323             :    * it.
     324             :    *
     325             :    * We have to do this in two cases: in response to a style change on a
     326             :    * non-display <text>, where aReason will be eStyleChange (the common case),
     327             :    * and also in response to glyphs changes on non-display <text> (i.e.,
     328             :    * animated SVG-in-OpenType glyphs), in which case aReason will be eResize,
     329             :    * since layout doesn't need to be recomputed.
     330             :    */
     331             :   void ScheduleReflowSVGNonDisplayText(nsIPresShell::IntrinsicDirty aReason);
     332             : 
     333             :   /**
     334             :    * Updates the mFontSizeScaleFactor value by looking at the range of
     335             :    * font-sizes used within the <text>.
     336             :    *
     337             :    * @return Whether mFontSizeScaleFactor changed.
     338             :    */
     339             :   bool UpdateFontSizeScaleFactor();
     340             : 
     341             :   double GetFontSizeScaleFactor() const;
     342             : 
     343             :   /**
     344             :    * Takes a point from the <text> element's user space and
     345             :    * converts it to the appropriate frame user space of aChildFrame,
     346             :    * according to which rendered run the point hits.
     347             :    */
     348             :   Point TransformFramePointToTextChild(const Point& aPoint,
     349             :                                        nsIFrame* aChildFrame);
     350             : 
     351             :   /**
     352             :    * Takes an app unit rectangle in the coordinate space of a given descendant
     353             :    * frame of this frame, and returns a rectangle in the <text> element's user
     354             :    * space that covers all parts of rendered runs that intersect with the
     355             :    * rectangle.
     356             :    */
     357             :   gfxRect TransformFrameRectFromTextChild(const nsRect& aRect,
     358             :                                           nsIFrame* aChildFrame);
     359             : 
     360             :   // Return our ::-moz-svg-text anonymous box.
     361             :   void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
     362             : 
     363             : private:
     364             :   /**
     365             :    * Mutation observer used to watch for text positioning attribute changes
     366             :    * on descendent text content elements (like <tspan>s).
     367             :    */
     368             :   class MutationObserver final : public nsStubMutationObserver {
     369             :   public:
     370           0 :     explicit MutationObserver(SVGTextFrame* aFrame)
     371           0 :       : mFrame(aFrame)
     372             :     {
     373           0 :       MOZ_ASSERT(mFrame, "MutationObserver needs a non-null frame");
     374           0 :       mFrame->GetContent()->AddMutationObserver(this);
     375           0 :     }
     376             : 
     377             :     // nsISupports
     378             :     NS_DECL_ISUPPORTS
     379             : 
     380             :     // nsIMutationObserver
     381             :     NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
     382             :     NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
     383             :     NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
     384             :     NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
     385             :     NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
     386             : 
     387             :   private:
     388           0 :     ~MutationObserver()
     389           0 :     {
     390           0 :       mFrame->GetContent()->RemoveMutationObserver(this);
     391           0 :     }
     392             : 
     393             :     SVGTextFrame* const mFrame;
     394             :   };
     395             : 
     396             :   /**
     397             :    * Reflows the anonymous block child if it is dirty or has dirty
     398             :    * children, or if the SVGTextFrame itself is dirty.
     399             :    */
     400             :   void MaybeReflowAnonymousBlockChild();
     401             : 
     402             :   /**
     403             :    * Performs the actual work of reflowing the anonymous block child.
     404             :    */
     405             :   void DoReflow();
     406             : 
     407             :   /**
     408             :    * Recomputes mPositions by calling DoGlyphPositioning if this information
     409             :    * is out of date.
     410             :    */
     411             :   void UpdateGlyphPositioning();
     412             : 
     413             :   /**
     414             :    * Populates mPositions with positioning information for each character
     415             :    * within the <text>.
     416             :    */
     417             :   void DoGlyphPositioning();
     418             : 
     419             :   /**
     420             :    * Converts the specified index into mPositions to an addressable
     421             :    * character index (as can be used with the SVG DOM text methods)
     422             :    * relative to the specified text child content element.
     423             :    *
     424             :    * @param aIndex The global character index.
     425             :    * @param aContent The descendant text child content element that
     426             :    *   the returned addressable index will be relative to; null
     427             :    *   means the same as the <text> element.
     428             :    * @return The addressable index, or -1 if the index cannot be
     429             :    *   represented as an addressable index relative to aContent.
     430             :    */
     431             :   int32_t
     432             :   ConvertTextElementCharIndexToAddressableIndex(int32_t aIndex,
     433             :                                                 nsIContent* aContent);
     434             : 
     435             :   /**
     436             :    * Recursive helper for ResolvePositions below.
     437             :    *
     438             :    * @param aContent The current node.
     439             :    * @param aIndex (in/out) The current character index.
     440             :    * @param aInTextPath Whether we are currently under a <textPath> element.
     441             :    * @param aForceStartOfChunk (in/out) Whether the next character we find
     442             :    *   should start a new anchored chunk.
     443             :    * @param aDeltas (in/out) Receives the resolved dx/dy values for each
     444             :    *   character.
     445             :    * @return false if we discover that mPositions did not have enough
     446             :    *   elements; true otherwise.
     447             :    */
     448             :   bool ResolvePositionsForNode(nsIContent* aContent, uint32_t& aIndex,
     449             :                                bool aInTextPath, bool& aForceStartOfChunk,
     450             :                                nsTArray<gfxPoint>& aDeltas);
     451             : 
     452             :   /**
     453             :    * Initializes mPositions with character position information based on
     454             :    * x/y/rotate attributes, leaving unspecified values in the array if a position
     455             :    * was not given for that character.  Also fills aDeltas with values based on
     456             :    * dx/dy attributes.
     457             :    *
     458             :    * @param aDeltas (in/out) Receives the resolved dx/dy values for each
     459             :    *   character.
     460             :    * @param aRunPerGlyph Whether mPositions should record that a new run begins
     461             :    *   at each glyph.
     462             :    * @return false if we did not record any positions (due to having no
     463             :    *   displayed characters) or if we discover that mPositions did not have
     464             :    *   enough elements; true otherwise.
     465             :    */
     466             :   bool ResolvePositions(nsTArray<gfxPoint>& aDeltas, bool aRunPerGlyph);
     467             : 
     468             :   /**
     469             :    * Determines the position, in app units, of each character in the <text> as
     470             :    * laid out by reflow, and appends them to aPositions.  Any characters that
     471             :    * are undisplayed or trimmed away just get the last position.
     472             :    */
     473             :   void DetermineCharPositions(nsTArray<nsPoint>& aPositions);
     474             : 
     475             :   /**
     476             :    * Sets mStartOfChunk to true for each character in mPositions that starts a
     477             :    * line of text.
     478             :    */
     479             :   void AdjustChunksForLineBreaks();
     480             : 
     481             :   /**
     482             :    * Adjusts recorded character positions in mPositions to account for glyph
     483             :    * boundaries.  Four things are done:
     484             :    *
     485             :    *   1. mClusterOrLigatureGroupMiddle is set to true for all such characters.
     486             :    *
     487             :    *   2. Any run and anchored chunk boundaries that begin in the middle of a
     488             :    *      cluster/ligature group get moved to the start of the next
     489             :    *      cluster/ligature group.
     490             :    *
     491             :    *   3. The position of any character in the middle of a cluster/ligature
     492             :    *      group is updated to take into account partial ligatures and any
     493             :    *      rotation the glyph as a whole has.  (The values that come out of
     494             :    *      DetermineCharPositions which then get written into mPositions in
     495             :    *      ResolvePositions store the same position value for each part of the
     496             :    *      ligature.)
     497             :    *
     498             :    *   4. The rotation of any character in the middle of a cluster/ligature
     499             :    *      group is set to the rotation of the first character.
     500             :    */
     501             :   void AdjustPositionsForClusters();
     502             : 
     503             :   /**
     504             :    * Updates the character positions stored in mPositions to account for
     505             :    * text anchoring.
     506             :    */
     507             :   void DoAnchoring();
     508             : 
     509             :   /**
     510             :    * Updates character positions in mPositions for those characters inside a
     511             :    * <textPath>.
     512             :    */
     513             :   void DoTextPathLayout();
     514             : 
     515             :   /**
     516             :    * Returns whether we need to render the text using
     517             :    * nsTextFrame::DrawPathCallbacks rather than directly painting
     518             :    * the text frames.
     519             :    *
     520             :    * @param aShouldPaintSVGGlyphs (out) Whether SVG glyphs in the text
     521             :    *   should be painted.
     522             :    */
     523             :   bool ShouldRenderAsPath(nsTextFrame* aFrame, bool& aShouldPaintSVGGlyphs);
     524             : 
     525             :   // Methods to get information for a <textPath> frame.
     526             :   mozilla::dom::SVGPathElement*
     527             :   GetTextPathPathElement(nsIFrame* aTextPathFrame);
     528             :   already_AddRefed<Path> GetTextPath(nsIFrame* aTextPathFrame);
     529             :   gfxFloat GetOffsetScale(nsIFrame* aTextPathFrame);
     530             :   gfxFloat GetStartOffset(nsIFrame* aTextPathFrame);
     531             : 
     532             :   /**
     533             :    * The MutationObserver we have registered for the <text> element subtree.
     534             :    */
     535             :   RefPtr<MutationObserver> mMutationObserver;
     536             : 
     537             :   /**
     538             :    * Cached canvasTM value.
     539             :    */
     540             :   nsAutoPtr<gfxMatrix> mCanvasTM;
     541             : 
     542             :   /**
     543             :    * The number of characters in the DOM after the final nsTextFrame.  For
     544             :    * example, with
     545             :    *
     546             :    *   <text>abcd<tspan display="none">ef</tspan></text>
     547             :    *
     548             :    * mTrailingUndisplayedCharacters would be 2.
     549             :    */
     550             :   uint32_t mTrailingUndisplayedCharacters;
     551             : 
     552             :   /**
     553             :    * Computed position information for each DOM character within the <text>.
     554             :    */
     555             :   nsTArray<mozilla::CharPosition> mPositions;
     556             : 
     557             :   /**
     558             :    * mFontSizeScaleFactor is used to cause the nsTextFrames to create text
     559             :    * runs with a font size different from the actual font-size property value.
     560             :    * This is used so that, for example with:
     561             :    *
     562             :    *   <svg>
     563             :    *     <g transform="scale(2)">
     564             :    *       <text font-size="10">abc</text>
     565             :    *     </g>
     566             :    *   </svg>
     567             :    *
     568             :    * a font size of 20 would be used.  It's preferable to use a font size that
     569             :    * is identical or close to the size that the text will appear on the screen,
     570             :    * because at very small or large font sizes, text metrics will be computed
     571             :    * differently due to the limited precision that text runs have.
     572             :    *
     573             :    * mFontSizeScaleFactor is the amount the actual font-size property value
     574             :    * should be multiplied by to cause the text run font size to (a) be within a
     575             :    * "reasonable" range, and (b) be close to the actual size to be painted on
     576             :    * screen.  (The "reasonable" range as determined by some #defines in
     577             :    * SVGTextFrame.cpp is 8..200.)
     578             :    */
     579             :   float mFontSizeScaleFactor;
     580             : 
     581             :   /**
     582             :    * The scale of the context that we last used to compute mFontSizeScaleFactor.
     583             :    * We record this so that we can tell when our scale transform has changed
     584             :    * enough to warrant reflowing the text.
     585             :    */
     586             :   float mLastContextScale;
     587             : 
     588             :   /**
     589             :    * The amount that we need to scale each rendered run to account for
     590             :    * lengthAdjust="spacingAndGlyphs".
     591             :    */
     592             :   float mLengthAdjustScaleFactor;
     593             : };
     594             : 
     595             : #endif

Generated by: LCOV version 1.13