LCOV - code coverage report
Current view: top level - layout/generic - nsTextFrame.h (source / functions) Hit Total Coverage
Test: output.info Lines: 65 119 54.6 %
Date: 2017-07-14 16:53:18 Functions: 31 48 64.6 %
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 nsTextFrame_h__
       7             : #define nsTextFrame_h__
       8             : 
       9             : #include "mozilla/Attributes.h"
      10             : #include "mozilla/EventForwards.h"
      11             : #include "mozilla/gfx/2D.h"
      12             : #include "mozilla/UniquePtr.h"
      13             : #include "nsFrame.h"
      14             : #include "nsFrameSelection.h"
      15             : #include "nsSplittableFrame.h"
      16             : #include "nsLineBox.h"
      17             : #include "gfxSkipChars.h"
      18             : #include "gfxTextRun.h"
      19             : #include "nsDisplayList.h"
      20             : #include "JustificationUtils.h"
      21             : #include "RubyUtils.h"
      22             : 
      23             : // Undo the windows.h damage
      24             : #if defined(XP_WIN) && defined(DrawText)
      25             : #undef DrawText
      26             : #endif
      27             : 
      28             : class nsTextPaintStyle;
      29             : class PropertyProvider;
      30             : struct SelectionDetails;
      31             : class nsTextFragment;
      32             : 
      33             : class nsDisplayTextGeometry;
      34             : class nsDisplayText;
      35             : 
      36             : namespace mozilla {
      37             : class SVGContextPaint;
      38             : };
      39             : 
      40             : class nsTextFrame : public nsFrame
      41             : {
      42             :   typedef mozilla::LayoutDeviceRect LayoutDeviceRect;
      43             :   typedef mozilla::RawSelectionType RawSelectionType;
      44             :   typedef mozilla::SelectionType SelectionType;
      45             :   typedef mozilla::TextRangeStyle TextRangeStyle;
      46             :   typedef mozilla::gfx::DrawTarget DrawTarget;
      47             :   typedef mozilla::gfx::Point Point;
      48             :   typedef mozilla::gfx::Rect Rect;
      49             :   typedef mozilla::gfx::Size Size;
      50             :   typedef gfxTextRun::Range Range;
      51             : 
      52             : public:
      53          18 :   explicit nsTextFrame(nsStyleContext* aContext, ClassID aID = kClassID)
      54          18 :     : nsFrame(aContext, aID)
      55             :     , mNextContinuation(nullptr)
      56             :     , mContentOffset(0)
      57             :     , mContentLengthHint(0)
      58          18 :     , mAscent(0)
      59          18 :   {}
      60             : 
      61          52 :   NS_DECL_FRAMEARENA_HELPERS(nsTextFrame)
      62             : 
      63             :   friend class nsContinuingTextFrame;
      64             :   friend class nsDisplayTextGeometry;
      65             :   friend class nsDisplayText;
      66             : 
      67             :   // nsQueryFrame
      68             :   NS_DECL_QUERYFRAME
      69             : 
      70             :   // nsIFrame
      71             :   void BuildDisplayList(nsDisplayListBuilder* aBuilder,
      72             :                         const nsRect& aDirtyRect,
      73             :                         const nsDisplayListSet& aLists) override;
      74             : 
      75             :   void Init(nsIContent* aContent,
      76             :             nsContainerFrame* aParent,
      77             :             nsIFrame* aPrevInFlow) override;
      78             : 
      79             :   void DestroyFrom(nsIFrame* aDestructRoot) override;
      80             : 
      81             :   nsresult GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor) override;
      82             : 
      83             :   nsresult CharacterDataChanged(CharacterDataChangeInfo* aInfo) final;
      84             : 
      85         150 :   nsTextFrame* GetPrevContinuation() const override { return nullptr; }
      86         608 :   nsTextFrame* GetNextContinuation() const final { return mNextContinuation; }
      87           0 :   void SetNextContinuation(nsIFrame* aNextContinuation) final
      88             :   {
      89           0 :     NS_ASSERTION(!aNextContinuation || Type() == aNextContinuation->Type(),
      90             :                  "setting a next continuation with incorrect type!");
      91           0 :     NS_ASSERTION(
      92             :       !nsSplittableFrame::IsInNextContinuationChain(aNextContinuation, this),
      93             :       "creating a loop in continuation chain!");
      94           0 :     mNextContinuation = static_cast<nsTextFrame*>(aNextContinuation);
      95           0 :     if (aNextContinuation)
      96           0 :       aNextContinuation->RemoveStateBits(NS_FRAME_IS_FLUID_CONTINUATION);
      97             :     // Setting a non-fluid continuation might affect our flow length (they're
      98             :     // quite rare so we assume it always does) so we delete our cached value:
      99           0 :     GetContent()->DeleteProperty(nsGkAtoms::flowlength);
     100           0 :   }
     101          48 :   nsIFrame* GetNextInFlowVirtual() const override { return GetNextInFlow(); }
     102         120 :   nsTextFrame* GetNextInFlow() const
     103             :   {
     104         120 :     return mNextContinuation &&
     105           0 :                (mNextContinuation->GetStateBits() &
     106             :                 NS_FRAME_IS_FLUID_CONTINUATION)
     107         120 :              ? mNextContinuation
     108         120 :              : nullptr;
     109             :   }
     110           0 :   void SetNextInFlow(nsIFrame* aNextInFlow) final
     111             :   {
     112           0 :     NS_ASSERTION(!aNextInFlow || Type() == aNextInFlow->Type(),
     113             :                  "setting a next in flow with incorrect type!");
     114           0 :     NS_ASSERTION(
     115             :       !nsSplittableFrame::IsInNextContinuationChain(aNextInFlow, this),
     116             :       "creating a loop in continuation chain!");
     117           0 :     mNextContinuation = static_cast<nsTextFrame*>(aNextInFlow);
     118           0 :     if (mNextContinuation &&
     119           0 :         !mNextContinuation->HasAnyStateBits(NS_FRAME_IS_FLUID_CONTINUATION)) {
     120             :       // Changing from non-fluid to fluid continuation might affect our flow
     121             :       // length, so we delete our cached value:
     122           0 :       GetContent()->DeleteProperty(nsGkAtoms::flowlength);
     123             :     }
     124           0 :     if (aNextInFlow) {
     125           0 :       aNextInFlow->AddStateBits(NS_FRAME_IS_FLUID_CONTINUATION);
     126             :     }
     127           0 :   }
     128             :   nsTextFrame* LastInFlow() const final;
     129             :   nsTextFrame* LastContinuation() const final;
     130             : 
     131           0 :   nsSplittableType GetSplittableType() const final
     132             :   {
     133           0 :     return NS_FRAME_SPLITTABLE;
     134             :   }
     135             : 
     136         183 :   bool IsFrameOfType(uint32_t aFlags) const final
     137             :   {
     138             :     // Set the frame state bit for text frames to mark them as replaced.
     139             :     // XXX kipp: temporary
     140         183 :     return nsFrame::IsFrameOfType(
     141         183 :       aFlags & ~(nsIFrame::eReplaced | nsIFrame::eLineParticipant));
     142             :   }
     143             : 
     144          85 :   bool ShouldSuppressLineBreak() const
     145             :   {
     146             :     // If the parent frame of the text frame is ruby content box, it must
     147             :     // suppress line break inside. This check is necessary, because when
     148             :     // a whitespace is only contained by pseudo ruby frames, its style
     149             :     // context won't have SuppressLineBreak bit set.
     150          85 :     if (mozilla::RubyUtils::IsRubyContentBox(GetParent()->Type())) {
     151           0 :       return true;
     152             :     }
     153          85 :     return StyleContext()->ShouldSuppressLineBreak();
     154             :   }
     155             : 
     156             :   void InvalidateFrame(uint32_t aDisplayItemKey = 0) override;
     157             :   void InvalidateFrameWithRect(const nsRect& aRect,
     158             :                                uint32_t aDisplayItemKey = 0) override;
     159             : 
     160             : #ifdef DEBUG_FRAME_DUMP
     161             :   void List(FILE* out = stderr,
     162             :             const char* aPrefix = "",
     163             :             uint32_t aFlags = 0) const override;
     164             :   nsresult GetFrameName(nsAString& aResult) const override;
     165             :   void ToCString(nsCString& aBuf, int32_t* aTotalContentLength) const;
     166             : #endif
     167             : 
     168             : #ifdef DEBUG
     169             :   nsFrameState GetDebugStateBits() const override;
     170             : #endif
     171             : 
     172             :   ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint) override;
     173             :   ContentOffsets GetCharacterOffsetAtFramePoint(const nsPoint& aPoint);
     174             : 
     175             :   /**
     176             :    * This is called only on the primary text frame. It indicates that
     177             :    * the selection state of the given character range has changed.
     178             :    * Text in the range is unconditionally invalidated
     179             :    * (Selection::Repaint depends on this).
     180             :    * @param aSelected true if the selection has been added to the range,
     181             :    * false otherwise
     182             :    * @param aType the type of selection added or removed
     183             :    */
     184             :   void SetSelectedRange(uint32_t aStart,
     185             :                         uint32_t aEnd,
     186             :                         bool aSelected,
     187             :                         SelectionType aSelectionType);
     188             : 
     189             :   FrameSearchResult PeekOffsetNoAmount(bool aForward,
     190             :                                        int32_t* aOffset) override;
     191             :   FrameSearchResult
     192             :   PeekOffsetCharacter(bool aForward,
     193             :                       int32_t* aOffset,
     194             :                       PeekOffsetCharacterOptions aOptions =
     195             :                         PeekOffsetCharacterOptions()) override;
     196             :   FrameSearchResult PeekOffsetWord(bool aForward,
     197             :                                    bool aWordSelectEatSpace,
     198             :                                    bool aIsKeyboardSelect,
     199             :                                    int32_t* aOffset,
     200             :                                    PeekWordState* aState) override;
     201             : 
     202             :   nsresult CheckVisibility(nsPresContext* aContext,
     203             :                            int32_t aStartIndex,
     204             :                            int32_t aEndIndex,
     205             :                            bool aRecurse,
     206             :                            bool* aFinished,
     207             :                            bool* _retval) override;
     208             : 
     209             :   // Flags for aSetLengthFlags
     210             :   enum
     211             :   {
     212             :     ALLOW_FRAME_CREATION_AND_DESTRUCTION = 0x01
     213             :   };
     214             : 
     215             :   // Update offsets to account for new length. This may clear mTextRun.
     216             :   void SetLength(int32_t aLength,
     217             :                  nsLineLayout* aLineLayout,
     218             :                  uint32_t aSetLengthFlags = 0);
     219             : 
     220             :   nsresult GetOffsets(int32_t& start, int32_t& end) const override;
     221             : 
     222             :   void AdjustOffsetsForBidi(int32_t start, int32_t end) override;
     223             : 
     224             :   nsresult GetPointFromOffset(int32_t inOffset, nsPoint* outPoint) override;
     225             :   nsresult GetCharacterRectsInRange(int32_t aInOffset,
     226             :                                     int32_t aLength,
     227             :                                     nsTArray<nsRect>& aRects) override;
     228             : 
     229             :   nsresult GetChildFrameContainingOffset(int32_t inContentOffset,
     230             :                                          bool inHint,
     231             :                                          int32_t* outFrameContentOffset,
     232             :                                          nsIFrame** outChildFrame) override;
     233             : 
     234             :   bool IsVisibleInSelection(nsISelection* aSelection) override;
     235             : 
     236             :   bool IsEmpty() override;
     237           0 :   bool IsSelfEmpty() override { return IsEmpty(); }
     238             :   nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const final;
     239             : 
     240             :   bool HasSignificantTerminalNewline() const override;
     241             : 
     242             :   /**
     243             :    * Returns true if this text frame is logically adjacent to the end of the
     244             :    * line.
     245             :    */
     246             :   bool IsAtEndOfLine() const;
     247             : 
     248             :   /**
     249             :    * Call this only after reflow the frame. Returns true if non-collapsed
     250             :    * characters are present.
     251             :    */
     252          48 :   bool HasNoncollapsedCharacters() const
     253             :   {
     254          48 :     return (GetStateBits() & TEXT_HAS_NONCOLLAPSED_CHARACTERS) != 0;
     255             :   }
     256             : 
     257             : #ifdef ACCESSIBILITY
     258             :   mozilla::a11y::AccType AccessibleType() override;
     259             : #endif
     260             : 
     261             :   float GetFontSizeInflation() const;
     262             :   bool IsCurrentFontInflation(float aInflation) const;
     263         321 :   bool HasFontSizeInflation() const
     264             :   {
     265         321 :     return (GetStateBits() & TEXT_HAS_FONT_INFLATION) != 0;
     266             :   }
     267             :   void SetFontSizeInflation(float aInflation);
     268             : 
     269             :   void MarkIntrinsicISizesDirty() override;
     270             :   nscoord GetMinISize(gfxContext* aRenderingContext) override;
     271             :   nscoord GetPrefISize(gfxContext* aRenderingContext) override;
     272             :   void AddInlineMinISize(gfxContext* aRenderingContext,
     273             :                          InlineMinISizeData* aData) override;
     274             :   void AddInlinePrefISize(gfxContext* aRenderingContext,
     275             :                           InlinePrefISizeData* aData) override;
     276             :   mozilla::LogicalSize ComputeSize(gfxContext* aRenderingContext,
     277             :                                    mozilla::WritingMode aWritingMode,
     278             :                                    const mozilla::LogicalSize& aCBSize,
     279             :                                    nscoord aAvailableISize,
     280             :                                    const mozilla::LogicalSize& aMargin,
     281             :                                    const mozilla::LogicalSize& aBorder,
     282             :                                    const mozilla::LogicalSize& aPadding,
     283             :                                    ComputeSizeFlags aFlags) override;
     284             :   nsRect ComputeTightBounds(DrawTarget* aDrawTarget) const override;
     285             :   nsresult GetPrefWidthTightBounds(gfxContext* aContext,
     286             :                                    nscoord* aX,
     287             :                                    nscoord* aXMost) override;
     288             :   void Reflow(nsPresContext* aPresContext,
     289             :               ReflowOutput& aMetrics,
     290             :               const ReflowInput& aReflowInput,
     291             :               nsReflowStatus& aStatus) override;
     292             :   bool CanContinueTextRun() const override;
     293             :   // Method that is called for a text frame that is logically
     294             :   // adjacent to the end of the line (i.e. followed only by empty text frames,
     295             :   // placeholders or inlines containing such).
     296             :   struct TrimOutput
     297             :   {
     298             :     // true if we trimmed some space or changed metrics in some other way.
     299             :     // In this case, we should call RecomputeOverflow on this frame.
     300             :     bool mChanged;
     301             :     // an amount to *subtract* from the frame's width (zero if !mChanged)
     302             :     nscoord mDeltaWidth;
     303             :   };
     304             :   TrimOutput TrimTrailingWhiteSpace(DrawTarget* aDrawTarget);
     305             :   RenderedText GetRenderedText(
     306             :     uint32_t aStartOffset = 0,
     307             :     uint32_t aEndOffset = UINT32_MAX,
     308             :     TextOffsetType aOffsetType = TextOffsetType::OFFSETS_IN_CONTENT_TEXT,
     309             :     TrailingWhitespace aTrimTrailingWhitespace =
     310             :       TrailingWhitespace::TRIM_TRAILING_WHITESPACE) override;
     311             : 
     312             :   nsOverflowAreas RecomputeOverflow(nsIFrame* aBlockFrame);
     313             : 
     314             :   enum TextRunType
     315             :   {
     316             :     // Anything in reflow (but not intrinsic width calculation) or
     317             :     // painting should use the inflated text run (i.e., with font size
     318             :     // inflation applied).
     319             :     eInflated,
     320             :     // Intrinsic width calculation should use the non-inflated text run.
     321             :     // When there is font size inflation, it will be different.
     322             :     eNotInflated
     323             :   };
     324             : 
     325             :   void AddInlineMinISizeForFlow(gfxContext* aRenderingContext,
     326             :                                 nsIFrame::InlineMinISizeData* aData,
     327             :                                 TextRunType aTextRunType);
     328             :   void AddInlinePrefISizeForFlow(gfxContext* aRenderingContext,
     329             :                                  InlinePrefISizeData* aData,
     330             :                                  TextRunType aTextRunType);
     331             : 
     332             :   /**
     333             :    * Calculate the horizontal bounds of the grapheme clusters that fit entirely
     334             :    * inside the given left[top]/right[bottom] edges (which are positive lengths
     335             :    * from the respective frame edge).  If an input value is zero it is ignored
     336             :    * and the result for that edge is zero.  All out parameter values are
     337             :    * undefined when the method returns false.
     338             :    * @return true if at least one whole grapheme cluster fit between the edges
     339             :    */
     340             :   bool MeasureCharClippedText(nscoord aVisIStartEdge,
     341             :                               nscoord aVisIEndEdge,
     342             :                               nscoord* aSnappedStartEdge,
     343             :                               nscoord* aSnappedEndEdge);
     344             :   /**
     345             :    * Same as above; this method also the returns the corresponding text run
     346             :    * offset and number of characters that fit.  All out parameter values are
     347             :    * undefined when the method returns false.
     348             :    * @return true if at least one whole grapheme cluster fit between the edges
     349             :    */
     350             :   bool MeasureCharClippedText(PropertyProvider& aProvider,
     351             :                               nscoord aVisIStartEdge,
     352             :                               nscoord aVisIEndEdge,
     353             :                               uint32_t* aStartOffset,
     354             :                               uint32_t* aMaxLength,
     355             :                               nscoord* aSnappedStartEdge,
     356             :                               nscoord* aSnappedEndEdge);
     357             : 
     358             :   /**
     359             :    * Object with various callbacks for PaintText() to invoke for different parts
     360             :    * of the frame's text rendering, when we're generating paths rather than
     361             :    * painting.
     362             :    *
     363             :    * Callbacks are invoked in the following order:
     364             :    *
     365             :    *   NotifySelectionBackgroundNeedsFill?
     366             :    *   PaintDecorationLine*
     367             :    *   NotifyBeforeText
     368             :    *   NotifyGlyphPathEmitted*
     369             :    *   NotifyAfterText
     370             :    *   PaintDecorationLine*
     371             :    *   PaintSelectionDecorationLine*
     372             :    *
     373             :    * The color of each part of the frame's text rendering is passed as an argument
     374             :    * to the NotifyBefore* callback for that part.  The nscolor can take on one of
     375             :    * the three selection special colors defined in LookAndFeel.h --
     376             :    * NS_TRANSPARENT, NS_SAME_AS_FOREGROUND_COLOR and
     377             :    * NS_40PERCENT_FOREGROUND_COLOR.
     378             :    */
     379             :   struct DrawPathCallbacks : gfxTextRunDrawCallbacks
     380             :   {
     381             :     /**
     382             :      * @param aShouldPaintSVGGlyphs Whether SVG glyphs should be painted.
     383             :      */
     384           0 :     explicit DrawPathCallbacks(bool aShouldPaintSVGGlyphs = false)
     385           0 :       : gfxTextRunDrawCallbacks(aShouldPaintSVGGlyphs)
     386           0 :     {}
     387             : 
     388             :     /**
     389             :      * Called to have the selection highlight drawn before the text is drawn
     390             :      * over the top.
     391             :      */
     392           0 :     virtual void NotifySelectionBackgroundNeedsFill(const Rect& aBackgroundRect,
     393             :                                                     nscolor aColor,
     394             :                                                     DrawTarget& aDrawTarget)
     395           0 :     {}
     396             : 
     397             :     /**
     398             :      * Called before (for under/over-line) or after (for line-through) the text
     399             :      * is drawn to have a text decoration line drawn.
     400             :      */
     401           0 :     virtual void PaintDecorationLine(Rect aPath, nscolor aColor) {}
     402             : 
     403             :     /**
     404             :      * Called after selected text is drawn to have a decoration line drawn over
     405             :      * the text. (All types of text decoration are drawn after the text when
     406             :      * text is selected.)
     407             :      */
     408           0 :     virtual void PaintSelectionDecorationLine(Rect aPath, nscolor aColor) {}
     409             : 
     410             :     /**
     411             :      * Called just before any paths have been emitted to the gfxContext
     412             :      * for the glyphs of the frame's text.
     413             :      */
     414           0 :     virtual void NotifyBeforeText(nscolor aColor) {}
     415             : 
     416             :     /**
     417             :      * Called just after all the paths have been emitted to the gfxContext
     418             :      * for the glyphs of the frame's text.
     419             :      */
     420           0 :     virtual void NotifyAfterText() {}
     421             : 
     422             :     /**
     423             :      * Called just before a path corresponding to a selection decoration line
     424             :      * has been emitted to the gfxContext.
     425             :      */
     426           0 :     virtual void NotifyBeforeSelectionDecorationLine(nscolor aColor) {}
     427             : 
     428             :     /**
     429             :      * Called just after a path corresponding to a selection decoration line
     430             :      * has been emitted to the gfxContext.
     431             :      */
     432           0 :     virtual void NotifySelectionDecorationLinePathEmitted() {}
     433             :   };
     434             : 
     435             :   struct PaintTextParams
     436             :   {
     437             :     gfxContext* context;
     438             :     gfxPoint framePt;
     439             :     LayoutDeviceRect dirtyRect;
     440             :     mozilla::SVGContextPaint* contextPaint = nullptr;
     441             :     DrawPathCallbacks* callbacks = nullptr;
     442             :     enum
     443             :     {
     444             :       PaintText,        // Normal text painting.
     445             :       PaintTextBGColor, // Only paint background color of the selected text
     446             :                         // range in this state.
     447             :       GenerateTextMask  // To generate a mask from a text frame. Should
     448             :                         // only paint text itself with opaque color.
     449             :                         // Text shadow, text selection color and text
     450             :                         // decoration are all discarded in this state.
     451             :     };
     452             :     uint8_t state = PaintText;
     453          17 :     explicit PaintTextParams(gfxContext* aContext)
     454          17 :       : context(aContext)
     455             :     {
     456          17 :     }
     457             : 
     458          16 :     bool IsPaintText() const { return state == PaintText; }
     459          34 :     bool IsGenerateTextMask() const { return state == GenerateTextMask; }
     460          18 :     bool IsPaintBGColor() const { return state == PaintTextBGColor; }
     461             :   };
     462             : 
     463             :   struct PaintTextSelectionParams : PaintTextParams
     464             :   {
     465             :     gfxPoint textBaselinePt;
     466             :     PropertyProvider* provider = nullptr;
     467             :     Range contentRange;
     468             :     nsTextPaintStyle* textPaintStyle = nullptr;
     469           1 :     explicit PaintTextSelectionParams(const PaintTextParams& aParams)
     470           1 :       : PaintTextParams(aParams)
     471           1 :     {}
     472             :   };
     473             : 
     474             :   struct DrawTextRunParams
     475             :   {
     476             :     gfxContext* context;
     477             :     PropertyProvider* provider = nullptr;
     478             :     gfxFloat* advanceWidth = nullptr;
     479             :     mozilla::SVGContextPaint* contextPaint = nullptr;
     480             :     DrawPathCallbacks* callbacks = nullptr;
     481             :     nscolor textColor = NS_RGBA(0, 0, 0, 0);
     482             :     nscolor textStrokeColor = NS_RGBA(0, 0, 0, 0);
     483             :     float textStrokeWidth = 0.0f;
     484             :     bool drawSoftHyphen = false;
     485          17 :     explicit DrawTextRunParams(gfxContext* aContext)
     486          17 :       : context(aContext)
     487          17 :     {}
     488             :   };
     489             : 
     490             :   struct DrawTextParams : DrawTextRunParams
     491             :   {
     492             :     gfxPoint framePt;
     493             :     LayoutDeviceRect dirtyRect;
     494             :     const nsTextPaintStyle* textStyle = nullptr;
     495             :     const nsCharClipDisplayItem::ClipEdges* clipEdges = nullptr;
     496             :     const nscolor* decorationOverrideColor = nullptr;
     497          17 :     explicit DrawTextParams(gfxContext* aContext)
     498          17 :       : DrawTextRunParams(aContext)
     499          17 :     {}
     500             :   };
     501             : 
     502             :   // Primary frame paint method called from nsDisplayText.  Can also be used
     503             :   // to generate paths rather than paint the frame's text by passing a callback
     504             :   // object.  The private DrawText() is what applies the text to a graphics
     505             :   // context.
     506             :   void PaintText(const PaintTextParams& aParams,
     507             :                  const nsCharClipDisplayItem& aItem,
     508             :                  float aOpacity = 1.0f);
     509             :   // helper: paint text frame when we're impacted by at least one selection.
     510             :   // Return false if the text was not painted and we should continue with
     511             :   // the fast path.
     512             :   bool PaintTextWithSelection(
     513             :     const PaintTextSelectionParams& aParams,
     514             :     const nsCharClipDisplayItem::ClipEdges& aClipEdges);
     515             :   // helper: paint text with foreground and background colors determined
     516             :   // by selection(s). Also computes a mask of all selection types applying to
     517             :   // our text, returned in aAllTypes.
     518             :   // Return false if the text was not painted and we should continue with
     519             :   // the fast path.
     520             :   bool PaintTextWithSelectionColors(
     521             :     const PaintTextSelectionParams& aParams,
     522             :     const mozilla::UniquePtr<SelectionDetails>& aDetails,
     523             :     RawSelectionType* aAllRawSelectionTypes,
     524             :     const nsCharClipDisplayItem::ClipEdges& aClipEdges);
     525             :   // helper: paint text decorations for text selected by aSelectionType
     526             :   void PaintTextSelectionDecorations(const PaintTextSelectionParams& aParams,
     527             :                                      const mozilla::UniquePtr<SelectionDetails>& aDetails,
     528             :                                      SelectionType aSelectionType);
     529             : 
     530             :   void DrawEmphasisMarks(gfxContext* aContext,
     531             :                          mozilla::WritingMode aWM,
     532             :                          const gfxPoint& aTextBaselinePt,
     533             :                          const gfxPoint& aFramePt,
     534             :                          Range aRange,
     535             :                          const nscolor* aDecorationOverrideColor,
     536             :                          PropertyProvider* aProvider);
     537             : 
     538             :   nscolor GetCaretColorAt(int32_t aOffset) override;
     539             : 
     540             :   int16_t GetSelectionStatus(int16_t* aSelectionFlags);
     541             : 
     542         242 :   int32_t GetContentOffset() const { return mContentOffset; }
     543         174 :   int32_t GetContentLength() const
     544             :   {
     545         174 :     NS_ASSERTION(GetContentEnd() - mContentOffset >= 0, "negative length");
     546         174 :     return GetContentEnd() - mContentOffset;
     547             :   }
     548             :   int32_t GetContentEnd() const;
     549             :   // This returns the length the frame thinks it *should* have after it was
     550             :   // last reflowed (0 if it hasn't been reflowed yet). This should be used only
     551             :   // when setting up the text offsets for a new continuation frame.
     552           0 :   int32_t GetContentLengthHint() const { return mContentLengthHint; }
     553             : 
     554             :   // Compute the length of the content mapped by this frame
     555             :   // and all its in-flow siblings. Basically this means starting at mContentOffset
     556             :   // and going to the end of the text node or the next bidi continuation
     557             :   // boundary.
     558             :   int32_t GetInFlowContentLength();
     559             : 
     560             :   /**
     561             :    * Acquires the text run for this content, if necessary.
     562             :    * @param aWhichTextRun indicates whether to get an inflated or non-inflated
     563             :    * text run
     564             :    * @param aRefDrawTarget the DrawTarget to use as a reference for creating the
     565             :    * textrun, if available (if not, we'll create one which will just be slower)
     566             :    * @param aLineContainer the block ancestor for this frame, or nullptr if
     567             :    * unknown
     568             :    * @param aFlowEndInTextRun if non-null, this returns the textrun offset of
     569             :    * end of the text associated with this frame and its in-flow siblings
     570             :    * @return a gfxSkipCharsIterator set up to map DOM offsets for this frame
     571             :    * to offsets into the textrun; its initial offset is set to this frame's
     572             :    * content offset
     573             :    */
     574             :   gfxSkipCharsIterator EnsureTextRun(
     575             :     TextRunType aWhichTextRun,
     576             :     DrawTarget* aRefDrawTarget = nullptr,
     577             :     nsIFrame* aLineContainer = nullptr,
     578             :     const nsLineList::iterator* aLine = nullptr,
     579             :     uint32_t* aFlowEndInTextRun = nullptr);
     580             : 
     581         329 :   gfxTextRun* GetTextRun(TextRunType aWhichTextRun)
     582             :   {
     583         329 :     if (aWhichTextRun == eInflated || !HasFontSizeInflation())
     584         329 :       return mTextRun;
     585           0 :     return GetUninflatedTextRun();
     586             :   }
     587             :   gfxTextRun* GetUninflatedTextRun();
     588             :   void SetTextRun(gfxTextRun* aTextRun,
     589             :                   TextRunType aWhichTextRun,
     590             :                   float aInflation);
     591           0 :   bool IsInTextRunUserData() const
     592             :   {
     593           0 :     return GetStateBits() &
     594           0 :            (TEXT_IN_TEXTRUN_USER_DATA | TEXT_IN_UNINFLATED_TEXTRUN_USER_DATA);
     595             :   }
     596             :   /**
     597             :    * Notify the frame that it should drop its pointer to a text run.
     598             :    * Returns whether the text run was removed (i.e., whether it was
     599             :    * associated with this frame, either as its inflated or non-inflated
     600             :    * text run.
     601             :    */
     602             :   bool RemoveTextRun(gfxTextRun* aTextRun);
     603             :   /**
     604             :    * Clears out |mTextRun| (or the uninflated text run, when aInflated
     605             :    * is nsTextFrame::eNotInflated and there is inflation) from all frames that hold a
     606             :    * reference to it, starting at |aStartContinuation|, or if it's
     607             :    * nullptr, starting at |this|.  Deletes the text run if all references
     608             :    * were cleared and it's not cached.
     609             :    */
     610             :   void ClearTextRun(nsTextFrame* aStartContinuation, TextRunType aWhichTextRun);
     611             : 
     612          17 :   void ClearTextRuns()
     613             :   {
     614          17 :     ClearTextRun(nullptr, nsTextFrame::eInflated);
     615          17 :     if (HasFontSizeInflation()) {
     616           0 :       ClearTextRun(nullptr, nsTextFrame::eNotInflated);
     617             :     }
     618          17 :   }
     619             : 
     620             :   /**
     621             :    * Wipe out references to textrun(s) without deleting the textruns.
     622             :    */
     623             :   void DisconnectTextRuns();
     624             : 
     625             :   // Get the DOM content range mapped by this frame after excluding
     626             :   // whitespace subject to start-of-line and end-of-line trimming.
     627             :   // The textrun must have been created before calling this.
     628             :   struct TrimmedOffsets
     629             :   {
     630             :     int32_t mStart;
     631             :     int32_t mLength;
     632          61 :     int32_t GetEnd() const { return mStart + mLength; }
     633             :   };
     634             :   TrimmedOffsets GetTrimmedOffsets(const nsTextFragment* aFrag,
     635             :                                    bool aTrimAfter,
     636             :                                    bool aPostReflow = true) const;
     637             : 
     638             :   // Similar to Reflow(), but for use from nsLineLayout
     639             :   void ReflowText(nsLineLayout& aLineLayout,
     640             :                   nscoord aAvailableWidth,
     641             :                   DrawTarget* aDrawTarget,
     642             :                   ReflowOutput& aMetrics,
     643             :                   nsReflowStatus& aStatus);
     644             : 
     645             :   bool IsFloatingFirstLetterChild() const;
     646             : 
     647             :   bool IsInitialLetterChild() const;
     648             : 
     649             :   bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override;
     650             : 
     651             :   void AssignJustificationGaps(const mozilla::JustificationAssignment& aAssign);
     652             :   mozilla::JustificationAssignment GetJustificationAssignment() const;
     653             : 
     654             :   uint32_t CountGraphemeClusters() const;
     655             : 
     656             : protected:
     657             :   virtual ~nsTextFrame();
     658             : 
     659             :   RefPtr<gfxTextRun> mTextRun;
     660             :   nsTextFrame* mNextContinuation;
     661             :   // The key invariant here is that mContentOffset never decreases along
     662             :   // a next-continuation chain. And of course mContentOffset is always <= the
     663             :   // the text node's content length, and the mContentOffset for the first frame
     664             :   // is always 0. Furthermore the text mapped by a frame is determined by
     665             :   // GetContentOffset() and GetContentLength()/GetContentEnd(), which get
     666             :   // the length from the difference between this frame's offset and the next
     667             :   // frame's offset, or the text length if there is no next frame. This means
     668             :   // the frames always map the text node without overlapping or leaving any gaps.
     669             :   int32_t mContentOffset;
     670             :   // This does *not* indicate the length of text currently mapped by the frame;
     671             :   // instead it's a hint saying that this frame *wants* to map this much text
     672             :   // so if we create a new continuation, this is where that continuation should
     673             :   // start.
     674             :   int32_t mContentLengthHint;
     675             :   nscoord mAscent;
     676             : 
     677             :   /**
     678             :    * Return true if the frame is part of a Selection.
     679             :    * Helper method to implement the public IsSelected() API.
     680             :    */
     681             :   bool IsFrameSelected() const override;
     682             : 
     683             :   mozilla::UniquePtr<SelectionDetails> GetSelectionDetails();
     684             : 
     685             :   void UnionAdditionalOverflow(nsPresContext* aPresContext,
     686             :                                nsIFrame* aBlock,
     687             :                                PropertyProvider& aProvider,
     688             :                                nsRect* aVisualOverflowRect,
     689             :                                bool aIncludeTextDecorations);
     690             : 
     691             :   // Update information of emphasis marks, and return the visial
     692             :   // overflow rect of the emphasis marks.
     693             :   nsRect UpdateTextEmphasis(mozilla::WritingMode aWM,
     694             :                             PropertyProvider& aProvider);
     695             : 
     696             :   struct PaintShadowParams
     697             :   {
     698             :     gfxTextRun::Range range;
     699             :     LayoutDeviceRect dirtyRect;
     700             :     gfxPoint framePt;
     701             :     gfxPoint textBaselinePt;
     702             :     gfxContext* context;
     703             :     nscolor foregroundColor = NS_RGBA(0, 0, 0, 0);
     704             :     const nsCharClipDisplayItem::ClipEdges* clipEdges = nullptr;
     705             :     PropertyProvider* provider = nullptr;
     706             :     nscoord leftSideOffset = 0;
     707          17 :     explicit PaintShadowParams(const PaintTextParams& aParams)
     708          17 :       : dirtyRect(aParams.dirtyRect)
     709             :       , framePt(aParams.framePt)
     710          17 :       , context(aParams.context)
     711             :     {
     712          17 :     }
     713             :   };
     714             : 
     715             :   void PaintOneShadow(const PaintShadowParams& aParams,
     716             :                       nsCSSShadowItem* aShadowDetails,
     717             :                       gfxRect& aBoundingBox,
     718             :                       uint32_t aBlurFlags);
     719             : 
     720             :   void PaintShadows(nsCSSShadowArray* aShadow,
     721             :                     const PaintShadowParams& aParams);
     722             : 
     723             :   struct LineDecoration
     724             :   {
     725             :     nsIFrame* mFrame;
     726             : 
     727             :     // This is represents the offset from our baseline to mFrame's baseline;
     728             :     // positive offsets are *above* the baseline and negative offsets below
     729             :     nscoord mBaselineOffset;
     730             : 
     731             :     nscolor mColor;
     732             :     uint8_t mStyle;
     733             : 
     734           0 :     LineDecoration(nsIFrame* const aFrame,
     735             :                    const nscoord aOff,
     736             :                    const nscolor aColor,
     737             :                    const uint8_t aStyle)
     738           0 :       : mFrame(aFrame)
     739             :       , mBaselineOffset(aOff)
     740             :       , mColor(aColor)
     741           0 :       , mStyle(aStyle)
     742             :     {
     743           0 :     }
     744             : 
     745           0 :     LineDecoration(const LineDecoration& aOther)
     746           0 :       : mFrame(aOther.mFrame)
     747           0 :       , mBaselineOffset(aOther.mBaselineOffset)
     748           0 :       , mColor(aOther.mColor)
     749           0 :       , mStyle(aOther.mStyle)
     750             :     {
     751           0 :     }
     752             : 
     753           0 :     bool operator==(const LineDecoration& aOther) const
     754             :     {
     755           0 :       return mFrame == aOther.mFrame && mStyle == aOther.mStyle &&
     756           0 :              mColor == aOther.mColor &&
     757           0 :              mBaselineOffset == aOther.mBaselineOffset;
     758             :     }
     759             : 
     760             :     bool operator!=(const LineDecoration& aOther) const
     761             :     {
     762             :       return !(*this == aOther);
     763             :     }
     764             :   };
     765         163 :   struct TextDecorations
     766             :   {
     767             :     AutoTArray<LineDecoration, 1> mOverlines, mUnderlines, mStrikes;
     768             : 
     769         167 :     TextDecorations() {}
     770             : 
     771          92 :     bool HasDecorationLines() const
     772             :     {
     773          92 :       return HasUnderline() || HasOverline() || HasStrikeout();
     774             :     }
     775          92 :     bool HasUnderline() const { return !mUnderlines.IsEmpty(); }
     776          92 :     bool HasOverline() const { return !mOverlines.IsEmpty(); }
     777          92 :     bool HasStrikeout() const { return !mStrikes.IsEmpty(); }
     778          61 :     bool operator==(const TextDecorations& aOther) const
     779             :     {
     780         122 :       return mOverlines == aOther.mOverlines &&
     781         122 :              mUnderlines == aOther.mUnderlines && mStrikes == aOther.mStrikes;
     782             :     }
     783          61 :     bool operator!=(const TextDecorations& aOther) const
     784             :     {
     785          61 :       return !(*this == aOther);
     786             :     }
     787             :   };
     788             :   enum TextDecorationColorResolution
     789             :   {
     790             :     eResolvedColors,
     791             :     eUnresolvedColors
     792             :   };
     793             :   void GetTextDecorations(nsPresContext* aPresContext,
     794             :                           TextDecorationColorResolution aColorResolution,
     795             :                           TextDecorations& aDecorations);
     796             : 
     797             :   void DrawTextRun(Range aRange,
     798             :                    const gfxPoint& aTextBaselinePt,
     799             :                    const DrawTextRunParams& aParams);
     800             : 
     801             :   void DrawTextRunAndDecorations(Range aRange,
     802             :                                  const gfxPoint& aTextBaselinePt,
     803             :                                  const DrawTextParams& aParams,
     804             :                                  const TextDecorations& aDecorations);
     805             : 
     806             :   void DrawText(Range aRange,
     807             :                 const gfxPoint& aTextBaselinePt,
     808             :                 const DrawTextParams& aParams);
     809             : 
     810             :   // Set non empty rect to aRect, it should be overflow rect or frame rect.
     811             :   // If the result rect is larger than the given rect, this returns true.
     812             :   bool CombineSelectionUnderlineRect(nsPresContext* aPresContext,
     813             :                                      nsRect& aRect);
     814             : 
     815             :   /**
     816             :    * Utility methods to paint selection.
     817             :    */
     818             :   void DrawSelectionDecorations(gfxContext* aContext,
     819             :                                 const LayoutDeviceRect& aDirtyRect,
     820             :                                 mozilla::SelectionType aSelectionType,
     821             :                                 nsTextPaintStyle& aTextPaintStyle,
     822             :                                 const TextRangeStyle& aRangeStyle,
     823             :                                 const Point& aPt,
     824             :                                 gfxFloat aICoordInFrame,
     825             :                                 gfxFloat aWidth,
     826             :                                 gfxFloat aAscent,
     827             :                                 const gfxFont::Metrics& aFontMetrics,
     828             :                                 DrawPathCallbacks* aCallbacks,
     829             :                                 bool aVertical,
     830             :                                 gfxFloat aDecorationOffsetDir,
     831             :                                 uint8_t aDecoration);
     832             : 
     833             :   struct PaintDecorationLineParams;
     834             :   void PaintDecorationLine(const PaintDecorationLineParams& aParams);
     835             :   /**
     836             :    * ComputeDescentLimitForSelectionUnderline() computes the most far position
     837             :    * where we can put selection underline.
     838             :    *
     839             :    * @return The maximum underline offset from the baseline (positive value
     840             :    *         means that the underline can put below the baseline).
     841             :    */
     842             :   gfxFloat ComputeDescentLimitForSelectionUnderline(
     843             :     nsPresContext* aPresContext,
     844             :     const gfxFont::Metrics& aFontMetrics);
     845             :   /**
     846             :    * This function encapsulates all knowledge of how selections affect
     847             :    * foreground and background colors.
     848             :    * @param aForeground the foreground color to use
     849             :    * @param aBackground the background color to use, or RGBA(0,0,0,0) if no
     850             :    *                    background should be painted
     851             :    * @return            true if the selection affects colors, false otherwise
     852             :    */
     853             :   static bool GetSelectionTextColors(SelectionType aSelectionType,
     854             :                                      nsTextPaintStyle& aTextPaintStyle,
     855             :                                      const TextRangeStyle& aRangeStyle,
     856             :                                      nscolor* aForeground,
     857             :                                      nscolor* aBackground);
     858             :   /**
     859             :    * ComputeSelectionUnderlineHeight() computes selection underline height of
     860             :    * the specified selection type from the font metrics.
     861             :    */
     862             :   static gfxFloat ComputeSelectionUnderlineHeight(
     863             :     nsPresContext* aPresContext,
     864             :     const gfxFont::Metrics& aFontMetrics,
     865             :     SelectionType aSelectionType);
     866             : 
     867             :   ContentOffsets GetCharacterOffsetAtFramePointInternal(
     868             :     nsPoint aPoint,
     869             :     bool aForInsertionPoint);
     870             : 
     871             :   void ClearFrameOffsetCache();
     872             : 
     873             :   bool HasAnyNoncollapsedCharacters() override;
     874             : 
     875             :   void ClearMetrics(ReflowOutput& aMetrics);
     876             : 
     877             :   /**
     878             :    * UpdateIteratorFromOffset() updates the iterator from a given offset.
     879             :    * Also, aInOffset may be updated to cluster start if aInOffset isn't
     880             :    * the offset of cluster start.
     881             :    */
     882             :   void UpdateIteratorFromOffset(const PropertyProvider& aProperties,
     883             :                                 int32_t& aInOffset,
     884             :                                 gfxSkipCharsIterator& aIter);
     885             : 
     886             :   nsPoint GetPointFromIterator(const gfxSkipCharsIterator& aIter,
     887             :                                PropertyProvider& aProperties);
     888             : };
     889             : 
     890             : #endif

Generated by: LCOV version 1.13