layout/generic/nsTextFrame.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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 nsTextFrame_h__
     7 #define nsTextFrame_h__
     9 #include "mozilla/Attributes.h"
    10 #include "nsFrame.h"
    11 #include "nsSplittableFrame.h"
    12 #include "nsLineBox.h"
    13 #include "gfxFont.h"
    14 #include "gfxSkipChars.h"
    15 #include "nsDisplayList.h"
    17 class nsTextPaintStyle;
    18 class PropertyProvider;
    20 typedef nsFrame nsTextFrameBase;
    22 class nsDisplayTextGeometry;
    23 class nsDisplayText;
    25 class nsTextFrameTextRunCache {
    26 public:
    27   static void Init();
    28   static void Shutdown();
    29 };
    31 class nsTextFrame : public nsTextFrameBase {
    32 public:
    33   NS_DECL_QUERYFRAME_TARGET(nsTextFrame)
    34   NS_DECL_FRAMEARENA_HELPERS
    36   friend class nsContinuingTextFrame;
    37   friend class nsDisplayTextGeometry;
    38   friend class nsDisplayText;
    40   nsTextFrame(nsStyleContext* aContext)
    41     : nsTextFrameBase(aContext)
    42   {
    43     NS_ASSERTION(mContentOffset == 0, "Bogus content offset");
    44   }
    46   // nsQueryFrame
    47   NS_DECL_QUERYFRAME
    49   // nsIFrame
    50   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
    51                                 const nsRect&           aDirtyRect,
    52                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
    54   virtual void Init(nsIContent*      aContent,
    55                     nsIFrame*        aParent,
    56                     nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
    58   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
    60   virtual nsresult GetCursor(const nsPoint& aPoint,
    61                              nsIFrame::Cursor& aCursor) MOZ_OVERRIDE;
    63   virtual nsresult CharacterDataChanged(CharacterDataChangeInfo* aInfo) MOZ_OVERRIDE;
    65   virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
    67   virtual nsIFrame* GetNextContinuation() const MOZ_OVERRIDE {
    68     return mNextContinuation;
    69   }
    70   virtual void SetNextContinuation(nsIFrame* aNextContinuation) MOZ_OVERRIDE {
    71     NS_ASSERTION (!aNextContinuation || GetType() == aNextContinuation->GetType(),
    72                   "setting a next continuation with incorrect type!");
    73     NS_ASSERTION (!nsSplittableFrame::IsInNextContinuationChain(aNextContinuation, this),
    74                   "creating a loop in continuation chain!");
    75     mNextContinuation = aNextContinuation;
    76     if (aNextContinuation)
    77       aNextContinuation->RemoveStateBits(NS_FRAME_IS_FLUID_CONTINUATION);
    78   }
    79   virtual nsIFrame* GetNextInFlowVirtual() const MOZ_OVERRIDE { return GetNextInFlow(); }
    80   nsIFrame* GetNextInFlow() const {
    81     return mNextContinuation && (mNextContinuation->GetStateBits() & NS_FRAME_IS_FLUID_CONTINUATION) ? 
    82       mNextContinuation : nullptr;
    83   }
    84   virtual void SetNextInFlow(nsIFrame* aNextInFlow) MOZ_OVERRIDE {
    85     NS_ASSERTION (!aNextInFlow || GetType() == aNextInFlow->GetType(),
    86                   "setting a next in flow with incorrect type!");
    87     NS_ASSERTION (!nsSplittableFrame::IsInNextContinuationChain(aNextInFlow, this),
    88                   "creating a loop in continuation chain!");
    89     mNextContinuation = aNextInFlow;
    90     if (aNextInFlow)
    91       aNextInFlow->AddStateBits(NS_FRAME_IS_FLUID_CONTINUATION);
    92   }
    93   virtual nsIFrame* LastInFlow() const MOZ_OVERRIDE;
    94   virtual nsIFrame* LastContinuation() const MOZ_OVERRIDE;
    96   virtual nsSplittableType GetSplittableType() const MOZ_OVERRIDE {
    97     return NS_FRAME_SPLITTABLE;
    98   }
   100   /**
   101     * Get the "type" of the frame
   102    *
   103    * @see nsGkAtoms::textFrame
   104    */
   105   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
   107   virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   108   {
   109     // Set the frame state bit for text frames to mark them as replaced.
   110     // XXX kipp: temporary
   111     return nsFrame::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced |
   112                                              nsIFrame::eLineParticipant));
   113   }
   115   virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
   116   virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
   118 #ifdef DEBUG_FRAME_DUMP
   119   void List(FILE* out = stderr, const char* aPrefix = "", uint32_t aFlags = 0) const MOZ_OVERRIDE;
   120   virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
   121   void ToCString(nsCString& aBuf, int32_t* aTotalContentLength) const;
   122 #endif
   124 #ifdef DEBUG
   125   virtual nsFrameState GetDebugStateBits() const MOZ_OVERRIDE;
   126 #endif
   128   virtual ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint) MOZ_OVERRIDE;
   129   ContentOffsets GetCharacterOffsetAtFramePoint(const nsPoint &aPoint);
   131   /**
   132    * This is called only on the primary text frame. It indicates that
   133    * the selection state of the given character range has changed.
   134    * Text in the range is unconditionally invalidated
   135    * (Selection::Repaint depends on this).
   136    * @param aSelected true if the selection has been added to the range,
   137    * false otherwise
   138    * @param aType the type of selection added or removed
   139    */
   140   void SetSelectedRange(uint32_t aStart, uint32_t aEnd, bool aSelected,
   141                         SelectionType aType);
   143   virtual FrameSearchResult PeekOffsetNoAmount(bool aForward, int32_t* aOffset) MOZ_OVERRIDE;
   144   virtual FrameSearchResult PeekOffsetCharacter(bool aForward, int32_t* aOffset,
   145                                      bool aRespectClusters = true) MOZ_OVERRIDE;
   146   virtual FrameSearchResult PeekOffsetWord(bool aForward, bool aWordSelectEatSpace, bool aIsKeyboardSelect,
   147                                 int32_t* aOffset, PeekWordState* aState) MOZ_OVERRIDE;
   149   virtual nsresult CheckVisibility(nsPresContext* aContext, int32_t aStartIndex, int32_t aEndIndex, bool aRecurse, bool *aFinished, bool *_retval) MOZ_OVERRIDE;
   151   // Flags for aSetLengthFlags
   152   enum { ALLOW_FRAME_CREATION_AND_DESTRUCTION = 0x01 };
   154   // Update offsets to account for new length. This may clear mTextRun.
   155   void SetLength(int32_t aLength, nsLineLayout* aLineLayout,
   156                  uint32_t aSetLengthFlags = 0);
   158   virtual nsresult GetOffsets(int32_t &start, int32_t &end)const MOZ_OVERRIDE;
   160   virtual void AdjustOffsetsForBidi(int32_t start, int32_t end) MOZ_OVERRIDE;
   162   virtual nsresult GetPointFromOffset(int32_t  inOffset,
   163                                       nsPoint* outPoint) MOZ_OVERRIDE;
   165   virtual nsresult GetChildFrameContainingOffset(int32_t inContentOffset,
   166                                                  bool    inHint,
   167                                                  int32_t* outFrameContentOffset,
   168                                                  nsIFrame** outChildFrame) MOZ_OVERRIDE;
   170   virtual bool IsVisibleInSelection(nsISelection* aSelection) MOZ_OVERRIDE;
   172   virtual bool IsEmpty() MOZ_OVERRIDE;
   173   virtual bool IsSelfEmpty() MOZ_OVERRIDE { return IsEmpty(); }
   174   virtual nscoord GetBaseline() const MOZ_OVERRIDE;
   176   virtual bool HasSignificantTerminalNewline() const MOZ_OVERRIDE;
   178   /**
   179    * Returns true if this text frame is logically adjacent to the end of the
   180    * line.
   181    */
   182   bool IsAtEndOfLine() const;
   184   /**
   185    * Call this only after reflow the frame. Returns true if non-collapsed
   186    * characters are present.
   187    */
   188   bool HasNoncollapsedCharacters() const {
   189     return (GetStateBits() & TEXT_HAS_NONCOLLAPSED_CHARACTERS) != 0;
   190   }
   192 #ifdef ACCESSIBILITY
   193   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
   194 #endif
   196   float GetFontSizeInflation() const;
   197   bool IsCurrentFontInflation(float aInflation) const;
   198   bool HasFontSizeInflation() const {
   199     return (GetStateBits() & TEXT_HAS_FONT_INFLATION) != 0;
   200   }
   201   void SetFontSizeInflation(float aInflation);
   203   virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE;
   204   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   205   virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   206   virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
   207                                  InlineMinWidthData *aData) MOZ_OVERRIDE;
   208   virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext,
   209                                   InlinePrefWidthData *aData) MOZ_OVERRIDE;
   210   virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
   211                              nsSize aCBSize, nscoord aAvailableWidth,
   212                              nsSize aMargin, nsSize aBorder, nsSize aPadding,
   213                              uint32_t aFlags) MOZ_OVERRIDE;
   214   virtual nsRect ComputeTightBounds(gfxContext* aContext) const MOZ_OVERRIDE;
   215   virtual nsresult GetPrefWidthTightBounds(nsRenderingContext* aContext,
   216                                            nscoord* aX,
   217                                            nscoord* aXMost) MOZ_OVERRIDE;
   218   virtual nsresult Reflow(nsPresContext* aPresContext,
   219                           nsHTMLReflowMetrics& aMetrics,
   220                           const nsHTMLReflowState& aReflowState,
   221                           nsReflowStatus& aStatus) MOZ_OVERRIDE;
   222   virtual bool CanContinueTextRun() const MOZ_OVERRIDE;
   223   // Method that is called for a text frame that is logically
   224   // adjacent to the end of the line (i.e. followed only by empty text frames,
   225   // placeholders or inlines containing such).
   226   struct TrimOutput {
   227     // true if we trimmed some space or changed metrics in some other way.
   228     // In this case, we should call RecomputeOverflow on this frame.
   229     bool mChanged;
   230     // true if the last character is not justifiable so should be subtracted
   231     // from the count of justifiable characters in the frame, since the last
   232     // character in a line is not justifiable.
   233     bool mLastCharIsJustifiable;
   234     // an amount to *subtract* from the frame's width (zero if !mChanged)
   235     nscoord      mDeltaWidth;
   236   };
   237   TrimOutput TrimTrailingWhiteSpace(nsRenderingContext* aRC);
   238   virtual nsresult GetRenderedText(nsAString* aString = nullptr,
   239                                    gfxSkipChars* aSkipChars = nullptr,
   240                                    gfxSkipCharsIterator* aSkipIter = nullptr,
   241                                    uint32_t aSkippedStartOffset = 0,
   242                                    uint32_t aSkippedMaxLength = UINT32_MAX) MOZ_OVERRIDE;
   244   nsOverflowAreas
   245     RecomputeOverflow(const nsHTMLReflowState& aBlockReflowState);
   247   enum TextRunType {
   248     // Anything in reflow (but not intrinsic width calculation) or
   249     // painting should use the inflated text run (i.e., with font size
   250     // inflation applied).
   251     eInflated,
   252     // Intrinsic width calculation should use the non-inflated text run.
   253     // When there is font size inflation, it will be different.
   254     eNotInflated
   255   };
   257   void AddInlineMinWidthForFlow(nsRenderingContext *aRenderingContext,
   258                                 nsIFrame::InlineMinWidthData *aData,
   259                                 TextRunType aTextRunType);
   260   void AddInlinePrefWidthForFlow(nsRenderingContext *aRenderingContext,
   261                                  InlinePrefWidthData *aData,
   262                                  TextRunType aTextRunType);
   264   /**
   265    * Calculate the horizontal bounds of the grapheme clusters that fit entirely
   266    * inside the given left/right edges (which are positive lengths from the
   267    * respective frame edge).  If an input value is zero it is ignored and the
   268    * result for that edge is zero.  All out parameter values are undefined when
   269    * the method returns false.
   270    * @return true if at least one whole grapheme cluster fit between the edges
   271    */
   272   bool MeasureCharClippedText(nscoord aLeftEdge, nscoord aRightEdge,
   273                               nscoord* aSnappedLeftEdge,
   274                               nscoord* aSnappedRightEdge);
   275   /**
   276    * Same as above; this method also the returns the corresponding text run
   277    * offset and number of characters that fit.  All out parameter values are
   278    * undefined when the method returns false.
   279    * @return true if at least one whole grapheme cluster fit between the edges
   280    */
   281   bool MeasureCharClippedText(PropertyProvider& aProvider,
   282                               nscoord aLeftEdge, nscoord aRightEdge,
   283                               uint32_t* aStartOffset, uint32_t* aMaxLength,
   284                               nscoord* aSnappedLeftEdge,
   285                               nscoord* aSnappedRightEdge);
   287   /**
   288    * Object with various callbacks for PaintText() to invoke for different parts
   289    * of the frame's text rendering, when we're generating paths rather than
   290    * painting.
   291    *
   292    * Callbacks are invoked in the following order:
   293    *
   294    *   (NotifyBeforeSelectionBackground NotifySelectionBackgroundPathEmitted)?
   295    *   (NotifyBeforeDecorationLine NotifyDecorationLinePathEmitted)*
   296    *   NotifyBeforeText
   297    *   (NotifyGlyphPathEmitted |
   298    *    (NotifyBeforeSVGGlyphPainted NotifyAfterSVGGlyphPainted))*
   299    *   NotifyAfterText
   300    *   (NotifyBeforeDecorationLine NotifyDecorationLinePathEmitted)*
   301    *   (NotifyBeforeSelectionDecorationLine NotifySelectionDecorationLinePathEmitted)*
   302    *
   303    * The color of each part of the frame's text rendering is passed as an argument
   304    * to the NotifyBefore* callback for that part.  The nscolor can take on one of
   305    * the three selection special colors defined in LookAndFeel.h --
   306    * NS_TRANSPARENT, NS_SAME_AS_FOREGROUND_COLOR and
   307    * NS_40PERCENT_FOREGROUND_COLOR.
   308    */
   309   struct DrawPathCallbacks : gfxTextRunDrawCallbacks
   310   {
   311     /**
   312      * @param aShouldPaintSVGGlyphs Whether SVG glyphs should be painted.
   313      */
   314     DrawPathCallbacks(bool aShouldPaintSVGGlyphs = false)
   315       : gfxTextRunDrawCallbacks(aShouldPaintSVGGlyphs)
   316     {
   317     }
   319     /**
   320      * Called just before any paths have been emitted to the gfxContext
   321      * for the glyphs of the frame's text.
   322      */
   323     virtual void NotifyBeforeText(nscolor aColor) { }
   325     /**
   326      * Called just after all the paths have been emitted to the gfxContext
   327      * for the glyphs of the frame's text.
   328      */
   329     virtual void NotifyAfterText() { }
   331     /**
   332      * Called just before a path corresponding to the selection background
   333      * has been emitted to the gfxContext.
   334      */
   335     virtual void NotifyBeforeSelectionBackground(nscolor aColor) { }
   337     /**
   338      * Called just after a path corresponding to the selection background
   339      * has been emitted to the gfxContext.
   340      */
   341     virtual void NotifySelectionBackgroundPathEmitted() { }
   343     /**
   344      * Called just before a path corresponding to a text decoration line
   345      * has been emitted to the gfxContext.
   346      */
   347     virtual void NotifyBeforeDecorationLine(nscolor aColor) { }
   349     /**
   350      * Called just after a path corresponding to a text decoration line
   351      * has been emitted to the gfxContext.
   352      */
   353     virtual void NotifyDecorationLinePathEmitted() { }
   355     /**
   356      * Called just before a path corresponding to a selection decoration line
   357      * has been emitted to the gfxContext.
   358      */
   359     virtual void NotifyBeforeSelectionDecorationLine(nscolor aColor) { }
   361     /**
   362      * Called just after a path corresponding to a selection decoration line
   363      * has been emitted to the gfxContext.
   364      */
   365     virtual void NotifySelectionDecorationLinePathEmitted() { }
   366   };
   368   // Primary frame paint method called from nsDisplayText.  Can also be used
   369   // to generate paths rather than paint the frame's text by passing a callback
   370   // object.  The private DrawText() is what applies the text to a graphics
   371   // context.
   372   void PaintText(nsRenderingContext* aRenderingContext, nsPoint aPt,
   373                  const nsRect& aDirtyRect, const nsCharClipDisplayItem& aItem,
   374                  gfxTextContextPaint* aContextPaint = nullptr,
   375                  DrawPathCallbacks* aCallbacks = nullptr);
   376   // helper: paint text frame when we're impacted by at least one selection.
   377   // Return false if the text was not painted and we should continue with
   378   // the fast path.
   379   bool PaintTextWithSelection(gfxContext* aCtx,
   380                               const gfxPoint& aFramePt,
   381                               const gfxPoint& aTextBaselinePt,
   382                               const gfxRect& aDirtyRect,
   383                               PropertyProvider& aProvider,
   384                               uint32_t aContentOffset,
   385                               uint32_t aContentLength,
   386                               nsTextPaintStyle& aTextPaintStyle,
   387                               const nsCharClipDisplayItem::ClipEdges& aClipEdges,
   388                               gfxTextContextPaint* aContextPaint,
   389                               DrawPathCallbacks* aCallbacks);
   390   // helper: paint text with foreground and background colors determined
   391   // by selection(s). Also computes a mask of all selection types applying to
   392   // our text, returned in aAllTypes.
   393   // Return false if the text was not painted and we should continue with
   394   // the fast path.
   395   bool PaintTextWithSelectionColors(gfxContext* aCtx,
   396                                     const gfxPoint& aFramePt,
   397                                     const gfxPoint& aTextBaselinePt,
   398                                     const gfxRect& aDirtyRect,
   399                                     PropertyProvider& aProvider,
   400                                     uint32_t aContentOffset,
   401                                     uint32_t aContentLength,
   402                                     nsTextPaintStyle& aTextPaintStyle,
   403                                     SelectionDetails* aDetails,
   404                                     SelectionType* aAllTypes,
   405                              const nsCharClipDisplayItem::ClipEdges& aClipEdges,
   406                                     DrawPathCallbacks* aCallbacks);
   407   // helper: paint text decorations for text selected by aSelectionType
   408   void PaintTextSelectionDecorations(gfxContext* aCtx,
   409                                      const gfxPoint& aFramePt,
   410                                      const gfxPoint& aTextBaselinePt,
   411                                      const gfxRect& aDirtyRect,
   412                                      PropertyProvider& aProvider,
   413                                      uint32_t aContentOffset,
   414                                      uint32_t aContentLength,
   415                                      nsTextPaintStyle& aTextPaintStyle,
   416                                      SelectionDetails* aDetails,
   417                                      SelectionType aSelectionType,
   418                                      DrawPathCallbacks* aCallbacks);
   420   virtual nscolor GetCaretColorAt(int32_t aOffset) MOZ_OVERRIDE;
   422   int16_t GetSelectionStatus(int16_t* aSelectionFlags);
   424   int32_t GetContentOffset() const { return mContentOffset; }
   425   int32_t GetContentLength() const
   426   {
   427     NS_ASSERTION(GetContentEnd() - mContentOffset >= 0, "negative length");
   428     return GetContentEnd() - mContentOffset;
   429   }
   430   int32_t GetContentEnd() const;
   431   // This returns the length the frame thinks it *should* have after it was
   432   // last reflowed (0 if it hasn't been reflowed yet). This should be used only
   433   // when setting up the text offsets for a new continuation frame.
   434   int32_t GetContentLengthHint() const { return mContentLengthHint; }
   436   // Compute the length of the content mapped by this frame
   437   // and all its in-flow siblings. Basically this means starting at mContentOffset
   438   // and going to the end of the text node or the next bidi continuation
   439   // boundary.
   440   int32_t GetInFlowContentLength();
   442   /**
   443    * Acquires the text run for this content, if necessary.
   444    * @param aWhichTextRun indicates whether to get an inflated or non-inflated
   445    * text run
   446    * @param aReferenceContext the rendering context to use as a reference for
   447    * creating the textrun, if available (if not, we'll create one which will
   448    * just be slower)
   449    * @param aLineContainer the block ancestor for this frame, or nullptr if
   450    * unknown
   451    * @param aFlowEndInTextRun if non-null, this returns the textrun offset of
   452    * end of the text associated with this frame and its in-flow siblings
   453    * @return a gfxSkipCharsIterator set up to map DOM offsets for this frame
   454    * to offsets into the textrun; its initial offset is set to this frame's
   455    * content offset
   456    */
   457   gfxSkipCharsIterator EnsureTextRun(TextRunType aWhichTextRun,
   458                                      gfxContext* aReferenceContext = nullptr,
   459                                      nsIFrame* aLineContainer = nullptr,
   460                                      const nsLineList::iterator* aLine = nullptr,
   461                                      uint32_t* aFlowEndInTextRun = nullptr);
   463   gfxTextRun* GetTextRun(TextRunType aWhichTextRun) {
   464     if (aWhichTextRun == eInflated || !HasFontSizeInflation())
   465       return mTextRun;
   466     return GetUninflatedTextRun();
   467   }
   468   gfxTextRun* GetUninflatedTextRun();
   469   void SetTextRun(gfxTextRun* aTextRun, TextRunType aWhichTextRun,
   470                   float aInflation);
   471   bool IsInTextRunUserData() const {
   472     return GetStateBits() &
   473       (TEXT_IN_TEXTRUN_USER_DATA | TEXT_IN_UNINFLATED_TEXTRUN_USER_DATA);
   474   }
   475   /**
   476    * Notify the frame that it should drop its pointer to a text run.
   477    * Returns whether the text run was removed (i.e., whether it was
   478    * associated with this frame, either as its inflated or non-inflated
   479    * text run.
   480    */
   481   bool RemoveTextRun(gfxTextRun* aTextRun);
   482   /**
   483    * Clears out |mTextRun| (or the uninflated text run, when aInflated
   484    * is nsTextFrame::eNotInflated and there is inflation) from all frames that hold a
   485    * reference to it, starting at |aStartContinuation|, or if it's
   486    * nullptr, starting at |this|.  Deletes the text run if all references
   487    * were cleared and it's not cached.
   488    */
   489   void ClearTextRun(nsTextFrame* aStartContinuation,
   490                     TextRunType aWhichTextRun);
   492   void ClearTextRuns() {
   493     ClearTextRun(nullptr, nsTextFrame::eInflated);
   494     if (HasFontSizeInflation()) {
   495       ClearTextRun(nullptr, nsTextFrame::eNotInflated);
   496     }
   497   }
   499   /**
   500    * Wipe out references to textrun(s) without deleting the textruns.
   501    */
   502   void DisconnectTextRuns();
   504   // Get the DOM content range mapped by this frame after excluding
   505   // whitespace subject to start-of-line and end-of-line trimming.
   506   // The textrun must have been created before calling this.
   507   struct TrimmedOffsets {
   508     int32_t mStart;
   509     int32_t mLength;
   510     int32_t GetEnd() const { return mStart + mLength; }
   511   };
   512   TrimmedOffsets GetTrimmedOffsets(const nsTextFragment* aFrag,
   513                                    bool aTrimAfter, bool aPostReflow = true);
   515   // Similar to Reflow(), but for use from nsLineLayout
   516   void ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
   517                   nsRenderingContext* aRenderingContext,
   518                   nsHTMLReflowMetrics& aMetrics, nsReflowStatus& aStatus);
   520   bool IsFloatingFirstLetterChild() const;
   522 protected:
   523   virtual ~nsTextFrame();
   525   nsIFrame*   mNextContinuation;
   526   // The key invariant here is that mContentOffset never decreases along
   527   // a next-continuation chain. And of course mContentOffset is always <= the
   528   // the text node's content length, and the mContentOffset for the first frame
   529   // is always 0. Furthermore the text mapped by a frame is determined by
   530   // GetContentOffset() and GetContentLength()/GetContentEnd(), which get
   531   // the length from the difference between this frame's offset and the next
   532   // frame's offset, or the text length if there is no next frame. This means
   533   // the frames always map the text node without overlapping or leaving any gaps.
   534   int32_t     mContentOffset;
   535   // This does *not* indicate the length of text currently mapped by the frame;
   536   // instead it's a hint saying that this frame *wants* to map this much text
   537   // so if we create a new continuation, this is where that continuation should
   538   // start.
   539   int32_t     mContentLengthHint;
   540   nscoord     mAscent;
   541   gfxTextRun* mTextRun;
   543   /**
   544    * Return true if the frame is part of a Selection.
   545    * Helper method to implement the public IsSelected() API.
   546    */
   547   virtual bool IsFrameSelected() const MOZ_OVERRIDE;
   549   // The caller of this method must call DestroySelectionDetails() on the
   550   // return value, if that return value is not null.  Calling
   551   // DestroySelectionDetails() on a null value is still OK, just not necessary.
   552   SelectionDetails* GetSelectionDetails();
   554   void UnionAdditionalOverflow(nsPresContext* aPresContext,
   555                                const nsHTMLReflowState& aBlockReflowState,
   556                                PropertyProvider& aProvider,
   557                                nsRect* aVisualOverflowRect,
   558                                bool aIncludeTextDecorations);
   560   void PaintOneShadow(uint32_t aOffset,
   561                       uint32_t aLength,
   562                       nsCSSShadowItem* aShadowDetails,
   563                       PropertyProvider* aProvider,
   564                       const nsRect& aDirtyRect,
   565                       const gfxPoint& aFramePt,
   566                       const gfxPoint& aTextBaselinePt,
   567                       gfxContext* aCtx,
   568                       const nscolor& aForegroundColor,
   569                       const nsCharClipDisplayItem::ClipEdges& aClipEdges,
   570                       nscoord aLeftSideOffset,
   571                       gfxRect& aBoundingBox);
   573   struct LineDecoration {
   574     nsIFrame* mFrame;
   576     // This is represents the offset from our baseline to mFrame's baseline;
   577     // positive offsets are *above* the baseline and negative offsets below
   578     nscoord mBaselineOffset;
   580     nscolor mColor;
   581     uint8_t mStyle;
   583     LineDecoration(nsIFrame *const aFrame,
   584                    const nscoord aOff,
   585                    const nscolor aColor,
   586                    const uint8_t aStyle)
   587       : mFrame(aFrame),
   588         mBaselineOffset(aOff),
   589         mColor(aColor),
   590         mStyle(aStyle)
   591     {}
   593     LineDecoration(const LineDecoration& aOther)
   594       : mFrame(aOther.mFrame),
   595         mBaselineOffset(aOther.mBaselineOffset),
   596         mColor(aOther.mColor),
   597         mStyle(aOther.mStyle)
   598     {}
   600     bool operator==(const LineDecoration& aOther) const {
   601       return mFrame == aOther.mFrame &&
   602              mStyle == aOther.mStyle &&
   603              mColor == aOther.mColor &&
   604              mBaselineOffset == aOther.mBaselineOffset;
   605     }
   607     bool operator!=(const LineDecoration& aOther) const {
   608       return !(*this == aOther);
   609     }
   610   };
   611   struct TextDecorations {
   612     nsAutoTArray<LineDecoration, 1> mOverlines, mUnderlines, mStrikes;
   614     TextDecorations() { }
   616     bool HasDecorationLines() const {
   617       return HasUnderline() || HasOverline() || HasStrikeout();
   618     }
   619     bool HasUnderline() const {
   620       return !mUnderlines.IsEmpty();
   621     }
   622     bool HasOverline() const {
   623       return !mOverlines.IsEmpty();
   624     }
   625     bool HasStrikeout() const {
   626       return !mStrikes.IsEmpty();
   627     }
   628     bool operator==(const TextDecorations& aOther) const {
   629       return mOverlines == aOther.mOverlines &&
   630              mUnderlines == aOther.mUnderlines &&
   631              mStrikes == aOther.mStrikes;
   632     }
   634     bool operator!=(const TextDecorations& aOther) const {
   635       return !(*this == aOther);
   636     }
   638   };
   639   enum TextDecorationColorResolution {
   640     eResolvedColors,
   641     eUnresolvedColors
   642   };
   643   void GetTextDecorations(nsPresContext* aPresContext,
   644                           TextDecorationColorResolution aColorResolution,
   645                           TextDecorations& aDecorations);
   647   void DrawTextRun(gfxContext* const aCtx,
   648                    const gfxPoint& aTextBaselinePt,
   649                    uint32_t aOffset,
   650                    uint32_t aLength,
   651                    PropertyProvider& aProvider,
   652                    nscolor aTextColor,
   653                    gfxFloat& aAdvanceWidth,
   654                    bool aDrawSoftHyphen,
   655                    gfxTextContextPaint* aContextPaint,
   656                    DrawPathCallbacks* aCallbacks);
   658   void DrawTextRunAndDecorations(gfxContext* const aCtx,
   659                                  const gfxRect& aDirtyRect,
   660                                  const gfxPoint& aFramePt,
   661                                  const gfxPoint& aTextBaselinePt,
   662                                  uint32_t aOffset,
   663                                  uint32_t aLength,
   664                                  PropertyProvider& aProvider,
   665                                  const nsTextPaintStyle& aTextStyle,
   666                                  nscolor aTextColor,
   667                              const nsCharClipDisplayItem::ClipEdges& aClipEdges,
   668                                  gfxFloat& aAdvanceWidth,
   669                                  bool aDrawSoftHyphen,
   670                                  const TextDecorations& aDecorations,
   671                                  const nscolor* const aDecorationOverrideColor,
   672                                  gfxTextContextPaint* aContextPaint,
   673                                  DrawPathCallbacks* aCallbacks);
   675   void DrawText(gfxContext* const aCtx,
   676                 const gfxRect& aDirtyRect,
   677                 const gfxPoint& aFramePt,
   678                 const gfxPoint& aTextBaselinePt,
   679                 uint32_t aOffset,
   680                 uint32_t aLength,
   681                 PropertyProvider& aProvider,
   682                 const nsTextPaintStyle& aTextStyle,
   683                 nscolor aTextColor,
   684                 const nsCharClipDisplayItem::ClipEdges& aClipEdges,
   685                 gfxFloat& aAdvanceWidth,
   686                 bool aDrawSoftHyphen,
   687                 const nscolor* const aDecorationOverrideColor = nullptr,
   688                 gfxTextContextPaint* aContextPaint = nullptr,
   689                 DrawPathCallbacks* aCallbacks = nullptr);
   691   // Set non empty rect to aRect, it should be overflow rect or frame rect.
   692   // If the result rect is larger than the given rect, this returns true.
   693   bool CombineSelectionUnderlineRect(nsPresContext* aPresContext,
   694                                        nsRect& aRect);
   696   ContentOffsets GetCharacterOffsetAtFramePointInternal(nsPoint aPoint,
   697                    bool aForInsertionPoint);
   699   void ClearFrameOffsetCache();
   701   virtual bool HasAnyNoncollapsedCharacters() MOZ_OVERRIDE;
   703   void ClearMetrics(nsHTMLReflowMetrics& aMetrics);
   704 };
   706 #endif

mercurial