layout/generic/nsTextFrame.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/generic/nsTextFrame.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,706 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#ifndef nsTextFrame_h__
    1.10 +#define nsTextFrame_h__
    1.11 +
    1.12 +#include "mozilla/Attributes.h"
    1.13 +#include "nsFrame.h"
    1.14 +#include "nsSplittableFrame.h"
    1.15 +#include "nsLineBox.h"
    1.16 +#include "gfxFont.h"
    1.17 +#include "gfxSkipChars.h"
    1.18 +#include "nsDisplayList.h"
    1.19 +
    1.20 +class nsTextPaintStyle;
    1.21 +class PropertyProvider;
    1.22 +
    1.23 +typedef nsFrame nsTextFrameBase;
    1.24 +
    1.25 +class nsDisplayTextGeometry;
    1.26 +class nsDisplayText;
    1.27 +
    1.28 +class nsTextFrameTextRunCache {
    1.29 +public:
    1.30 +  static void Init();
    1.31 +  static void Shutdown();
    1.32 +};
    1.33 +
    1.34 +class nsTextFrame : public nsTextFrameBase {
    1.35 +public:
    1.36 +  NS_DECL_QUERYFRAME_TARGET(nsTextFrame)
    1.37 +  NS_DECL_FRAMEARENA_HELPERS
    1.38 +
    1.39 +  friend class nsContinuingTextFrame;
    1.40 +  friend class nsDisplayTextGeometry;
    1.41 +  friend class nsDisplayText;
    1.42 +
    1.43 +  nsTextFrame(nsStyleContext* aContext)
    1.44 +    : nsTextFrameBase(aContext)
    1.45 +  {
    1.46 +    NS_ASSERTION(mContentOffset == 0, "Bogus content offset");
    1.47 +  }
    1.48 +  
    1.49 +  // nsQueryFrame
    1.50 +  NS_DECL_QUERYFRAME
    1.51 +
    1.52 +  // nsIFrame
    1.53 +  virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
    1.54 +                                const nsRect&           aDirtyRect,
    1.55 +                                const nsDisplayListSet& aLists) MOZ_OVERRIDE;
    1.56 +
    1.57 +  virtual void Init(nsIContent*      aContent,
    1.58 +                    nsIFrame*        aParent,
    1.59 +                    nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
    1.60 +
    1.61 +  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
    1.62 +  
    1.63 +  virtual nsresult GetCursor(const nsPoint& aPoint,
    1.64 +                             nsIFrame::Cursor& aCursor) MOZ_OVERRIDE;
    1.65 +  
    1.66 +  virtual nsresult CharacterDataChanged(CharacterDataChangeInfo* aInfo) MOZ_OVERRIDE;
    1.67 +                                  
    1.68 +  virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
    1.69 +  
    1.70 +  virtual nsIFrame* GetNextContinuation() const MOZ_OVERRIDE {
    1.71 +    return mNextContinuation;
    1.72 +  }
    1.73 +  virtual void SetNextContinuation(nsIFrame* aNextContinuation) MOZ_OVERRIDE {
    1.74 +    NS_ASSERTION (!aNextContinuation || GetType() == aNextContinuation->GetType(),
    1.75 +                  "setting a next continuation with incorrect type!");
    1.76 +    NS_ASSERTION (!nsSplittableFrame::IsInNextContinuationChain(aNextContinuation, this),
    1.77 +                  "creating a loop in continuation chain!");
    1.78 +    mNextContinuation = aNextContinuation;
    1.79 +    if (aNextContinuation)
    1.80 +      aNextContinuation->RemoveStateBits(NS_FRAME_IS_FLUID_CONTINUATION);
    1.81 +  }
    1.82 +  virtual nsIFrame* GetNextInFlowVirtual() const MOZ_OVERRIDE { return GetNextInFlow(); }
    1.83 +  nsIFrame* GetNextInFlow() const {
    1.84 +    return mNextContinuation && (mNextContinuation->GetStateBits() & NS_FRAME_IS_FLUID_CONTINUATION) ? 
    1.85 +      mNextContinuation : nullptr;
    1.86 +  }
    1.87 +  virtual void SetNextInFlow(nsIFrame* aNextInFlow) MOZ_OVERRIDE {
    1.88 +    NS_ASSERTION (!aNextInFlow || GetType() == aNextInFlow->GetType(),
    1.89 +                  "setting a next in flow with incorrect type!");
    1.90 +    NS_ASSERTION (!nsSplittableFrame::IsInNextContinuationChain(aNextInFlow, this),
    1.91 +                  "creating a loop in continuation chain!");
    1.92 +    mNextContinuation = aNextInFlow;
    1.93 +    if (aNextInFlow)
    1.94 +      aNextInFlow->AddStateBits(NS_FRAME_IS_FLUID_CONTINUATION);
    1.95 +  }
    1.96 +  virtual nsIFrame* LastInFlow() const MOZ_OVERRIDE;
    1.97 +  virtual nsIFrame* LastContinuation() const MOZ_OVERRIDE;
    1.98 +  
    1.99 +  virtual nsSplittableType GetSplittableType() const MOZ_OVERRIDE {
   1.100 +    return NS_FRAME_SPLITTABLE;
   1.101 +  }
   1.102 +  
   1.103 +  /**
   1.104 +    * Get the "type" of the frame
   1.105 +   *
   1.106 +   * @see nsGkAtoms::textFrame
   1.107 +   */
   1.108 +  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
   1.109 +  
   1.110 +  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   1.111 +  {
   1.112 +    // Set the frame state bit for text frames to mark them as replaced.
   1.113 +    // XXX kipp: temporary
   1.114 +    return nsFrame::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced |
   1.115 +                                             nsIFrame::eLineParticipant));
   1.116 +  }
   1.117 +
   1.118 +  virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
   1.119 +  virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
   1.120 +
   1.121 +#ifdef DEBUG_FRAME_DUMP
   1.122 +  void List(FILE* out = stderr, const char* aPrefix = "", uint32_t aFlags = 0) const MOZ_OVERRIDE;
   1.123 +  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
   1.124 +  void ToCString(nsCString& aBuf, int32_t* aTotalContentLength) const;
   1.125 +#endif
   1.126 +
   1.127 +#ifdef DEBUG
   1.128 +  virtual nsFrameState GetDebugStateBits() const MOZ_OVERRIDE;
   1.129 +#endif
   1.130 +  
   1.131 +  virtual ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint) MOZ_OVERRIDE;
   1.132 +  ContentOffsets GetCharacterOffsetAtFramePoint(const nsPoint &aPoint);
   1.133 +
   1.134 +  /**
   1.135 +   * This is called only on the primary text frame. It indicates that
   1.136 +   * the selection state of the given character range has changed.
   1.137 +   * Text in the range is unconditionally invalidated
   1.138 +   * (Selection::Repaint depends on this).
   1.139 +   * @param aSelected true if the selection has been added to the range,
   1.140 +   * false otherwise
   1.141 +   * @param aType the type of selection added or removed
   1.142 +   */
   1.143 +  void SetSelectedRange(uint32_t aStart, uint32_t aEnd, bool aSelected,
   1.144 +                        SelectionType aType);
   1.145 +
   1.146 +  virtual FrameSearchResult PeekOffsetNoAmount(bool aForward, int32_t* aOffset) MOZ_OVERRIDE;
   1.147 +  virtual FrameSearchResult PeekOffsetCharacter(bool aForward, int32_t* aOffset,
   1.148 +                                     bool aRespectClusters = true) MOZ_OVERRIDE;
   1.149 +  virtual FrameSearchResult PeekOffsetWord(bool aForward, bool aWordSelectEatSpace, bool aIsKeyboardSelect,
   1.150 +                                int32_t* aOffset, PeekWordState* aState) MOZ_OVERRIDE;
   1.151 +
   1.152 +  virtual nsresult CheckVisibility(nsPresContext* aContext, int32_t aStartIndex, int32_t aEndIndex, bool aRecurse, bool *aFinished, bool *_retval) MOZ_OVERRIDE;
   1.153 +  
   1.154 +  // Flags for aSetLengthFlags
   1.155 +  enum { ALLOW_FRAME_CREATION_AND_DESTRUCTION = 0x01 };
   1.156 +
   1.157 +  // Update offsets to account for new length. This may clear mTextRun.
   1.158 +  void SetLength(int32_t aLength, nsLineLayout* aLineLayout,
   1.159 +                 uint32_t aSetLengthFlags = 0);
   1.160 +  
   1.161 +  virtual nsresult GetOffsets(int32_t &start, int32_t &end)const MOZ_OVERRIDE;
   1.162 +  
   1.163 +  virtual void AdjustOffsetsForBidi(int32_t start, int32_t end) MOZ_OVERRIDE;
   1.164 +  
   1.165 +  virtual nsresult GetPointFromOffset(int32_t  inOffset,
   1.166 +                                      nsPoint* outPoint) MOZ_OVERRIDE;
   1.167 +  
   1.168 +  virtual nsresult GetChildFrameContainingOffset(int32_t inContentOffset,
   1.169 +                                                 bool    inHint,
   1.170 +                                                 int32_t* outFrameContentOffset,
   1.171 +                                                 nsIFrame** outChildFrame) MOZ_OVERRIDE;
   1.172 +  
   1.173 +  virtual bool IsVisibleInSelection(nsISelection* aSelection) MOZ_OVERRIDE;
   1.174 +  
   1.175 +  virtual bool IsEmpty() MOZ_OVERRIDE;
   1.176 +  virtual bool IsSelfEmpty() MOZ_OVERRIDE { return IsEmpty(); }
   1.177 +  virtual nscoord GetBaseline() const MOZ_OVERRIDE;
   1.178 +  
   1.179 +  virtual bool HasSignificantTerminalNewline() const MOZ_OVERRIDE;
   1.180 +
   1.181 +  /**
   1.182 +   * Returns true if this text frame is logically adjacent to the end of the
   1.183 +   * line.
   1.184 +   */
   1.185 +  bool IsAtEndOfLine() const;
   1.186 +  
   1.187 +  /**
   1.188 +   * Call this only after reflow the frame. Returns true if non-collapsed
   1.189 +   * characters are present.
   1.190 +   */
   1.191 +  bool HasNoncollapsedCharacters() const {
   1.192 +    return (GetStateBits() & TEXT_HAS_NONCOLLAPSED_CHARACTERS) != 0;
   1.193 +  }
   1.194 +  
   1.195 +#ifdef ACCESSIBILITY
   1.196 +  virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
   1.197 +#endif
   1.198 +
   1.199 +  float GetFontSizeInflation() const;
   1.200 +  bool IsCurrentFontInflation(float aInflation) const;
   1.201 +  bool HasFontSizeInflation() const {
   1.202 +    return (GetStateBits() & TEXT_HAS_FONT_INFLATION) != 0;
   1.203 +  }
   1.204 +  void SetFontSizeInflation(float aInflation);
   1.205 +
   1.206 +  virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE;
   1.207 +  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   1.208 +  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   1.209 +  virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
   1.210 +                                 InlineMinWidthData *aData) MOZ_OVERRIDE;
   1.211 +  virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext,
   1.212 +                                  InlinePrefWidthData *aData) MOZ_OVERRIDE;
   1.213 +  virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
   1.214 +                             nsSize aCBSize, nscoord aAvailableWidth,
   1.215 +                             nsSize aMargin, nsSize aBorder, nsSize aPadding,
   1.216 +                             uint32_t aFlags) MOZ_OVERRIDE;
   1.217 +  virtual nsRect ComputeTightBounds(gfxContext* aContext) const MOZ_OVERRIDE;
   1.218 +  virtual nsresult GetPrefWidthTightBounds(nsRenderingContext* aContext,
   1.219 +                                           nscoord* aX,
   1.220 +                                           nscoord* aXMost) MOZ_OVERRIDE;
   1.221 +  virtual nsresult Reflow(nsPresContext* aPresContext,
   1.222 +                          nsHTMLReflowMetrics& aMetrics,
   1.223 +                          const nsHTMLReflowState& aReflowState,
   1.224 +                          nsReflowStatus& aStatus) MOZ_OVERRIDE;
   1.225 +  virtual bool CanContinueTextRun() const MOZ_OVERRIDE;
   1.226 +  // Method that is called for a text frame that is logically
   1.227 +  // adjacent to the end of the line (i.e. followed only by empty text frames,
   1.228 +  // placeholders or inlines containing such).
   1.229 +  struct TrimOutput {
   1.230 +    // true if we trimmed some space or changed metrics in some other way.
   1.231 +    // In this case, we should call RecomputeOverflow on this frame.
   1.232 +    bool mChanged;
   1.233 +    // true if the last character is not justifiable so should be subtracted
   1.234 +    // from the count of justifiable characters in the frame, since the last
   1.235 +    // character in a line is not justifiable.
   1.236 +    bool mLastCharIsJustifiable;
   1.237 +    // an amount to *subtract* from the frame's width (zero if !mChanged)
   1.238 +    nscoord      mDeltaWidth;
   1.239 +  };
   1.240 +  TrimOutput TrimTrailingWhiteSpace(nsRenderingContext* aRC);
   1.241 +  virtual nsresult GetRenderedText(nsAString* aString = nullptr,
   1.242 +                                   gfxSkipChars* aSkipChars = nullptr,
   1.243 +                                   gfxSkipCharsIterator* aSkipIter = nullptr,
   1.244 +                                   uint32_t aSkippedStartOffset = 0,
   1.245 +                                   uint32_t aSkippedMaxLength = UINT32_MAX) MOZ_OVERRIDE;
   1.246 +
   1.247 +  nsOverflowAreas
   1.248 +    RecomputeOverflow(const nsHTMLReflowState& aBlockReflowState);
   1.249 +
   1.250 +  enum TextRunType {
   1.251 +    // Anything in reflow (but not intrinsic width calculation) or
   1.252 +    // painting should use the inflated text run (i.e., with font size
   1.253 +    // inflation applied).
   1.254 +    eInflated,
   1.255 +    // Intrinsic width calculation should use the non-inflated text run.
   1.256 +    // When there is font size inflation, it will be different.
   1.257 +    eNotInflated
   1.258 +  };
   1.259 +
   1.260 +  void AddInlineMinWidthForFlow(nsRenderingContext *aRenderingContext,
   1.261 +                                nsIFrame::InlineMinWidthData *aData,
   1.262 +                                TextRunType aTextRunType);
   1.263 +  void AddInlinePrefWidthForFlow(nsRenderingContext *aRenderingContext,
   1.264 +                                 InlinePrefWidthData *aData,
   1.265 +                                 TextRunType aTextRunType);
   1.266 +
   1.267 +  /**
   1.268 +   * Calculate the horizontal bounds of the grapheme clusters that fit entirely
   1.269 +   * inside the given left/right edges (which are positive lengths from the
   1.270 +   * respective frame edge).  If an input value is zero it is ignored and the
   1.271 +   * result for that edge is zero.  All out parameter values are undefined when
   1.272 +   * the method returns false.
   1.273 +   * @return true if at least one whole grapheme cluster fit between the edges
   1.274 +   */
   1.275 +  bool MeasureCharClippedText(nscoord aLeftEdge, nscoord aRightEdge,
   1.276 +                              nscoord* aSnappedLeftEdge,
   1.277 +                              nscoord* aSnappedRightEdge);
   1.278 +  /**
   1.279 +   * Same as above; this method also the returns the corresponding text run
   1.280 +   * offset and number of characters that fit.  All out parameter values are
   1.281 +   * undefined when the method returns false.
   1.282 +   * @return true if at least one whole grapheme cluster fit between the edges
   1.283 +   */
   1.284 +  bool MeasureCharClippedText(PropertyProvider& aProvider,
   1.285 +                              nscoord aLeftEdge, nscoord aRightEdge,
   1.286 +                              uint32_t* aStartOffset, uint32_t* aMaxLength,
   1.287 +                              nscoord* aSnappedLeftEdge,
   1.288 +                              nscoord* aSnappedRightEdge);
   1.289 +
   1.290 +  /**
   1.291 +   * Object with various callbacks for PaintText() to invoke for different parts
   1.292 +   * of the frame's text rendering, when we're generating paths rather than
   1.293 +   * painting.
   1.294 +   *
   1.295 +   * Callbacks are invoked in the following order:
   1.296 +   *
   1.297 +   *   (NotifyBeforeSelectionBackground NotifySelectionBackgroundPathEmitted)?
   1.298 +   *   (NotifyBeforeDecorationLine NotifyDecorationLinePathEmitted)*
   1.299 +   *   NotifyBeforeText
   1.300 +   *   (NotifyGlyphPathEmitted |
   1.301 +   *    (NotifyBeforeSVGGlyphPainted NotifyAfterSVGGlyphPainted))*
   1.302 +   *   NotifyAfterText
   1.303 +   *   (NotifyBeforeDecorationLine NotifyDecorationLinePathEmitted)*
   1.304 +   *   (NotifyBeforeSelectionDecorationLine NotifySelectionDecorationLinePathEmitted)*
   1.305 +   *
   1.306 +   * The color of each part of the frame's text rendering is passed as an argument
   1.307 +   * to the NotifyBefore* callback for that part.  The nscolor can take on one of
   1.308 +   * the three selection special colors defined in LookAndFeel.h --
   1.309 +   * NS_TRANSPARENT, NS_SAME_AS_FOREGROUND_COLOR and
   1.310 +   * NS_40PERCENT_FOREGROUND_COLOR.
   1.311 +   */
   1.312 +  struct DrawPathCallbacks : gfxTextRunDrawCallbacks
   1.313 +  {
   1.314 +    /**
   1.315 +     * @param aShouldPaintSVGGlyphs Whether SVG glyphs should be painted.
   1.316 +     */
   1.317 +    DrawPathCallbacks(bool aShouldPaintSVGGlyphs = false)
   1.318 +      : gfxTextRunDrawCallbacks(aShouldPaintSVGGlyphs)
   1.319 +    {
   1.320 +    }
   1.321 +
   1.322 +    /**
   1.323 +     * Called just before any paths have been emitted to the gfxContext
   1.324 +     * for the glyphs of the frame's text.
   1.325 +     */
   1.326 +    virtual void NotifyBeforeText(nscolor aColor) { }
   1.327 +
   1.328 +    /**
   1.329 +     * Called just after all the paths have been emitted to the gfxContext
   1.330 +     * for the glyphs of the frame's text.
   1.331 +     */
   1.332 +    virtual void NotifyAfterText() { }
   1.333 +
   1.334 +    /**
   1.335 +     * Called just before a path corresponding to the selection background
   1.336 +     * has been emitted to the gfxContext.
   1.337 +     */
   1.338 +    virtual void NotifyBeforeSelectionBackground(nscolor aColor) { }
   1.339 +
   1.340 +    /**
   1.341 +     * Called just after a path corresponding to the selection background
   1.342 +     * has been emitted to the gfxContext.
   1.343 +     */
   1.344 +    virtual void NotifySelectionBackgroundPathEmitted() { }
   1.345 +
   1.346 +    /**
   1.347 +     * Called just before a path corresponding to a text decoration line
   1.348 +     * has been emitted to the gfxContext.
   1.349 +     */
   1.350 +    virtual void NotifyBeforeDecorationLine(nscolor aColor) { }
   1.351 +
   1.352 +    /**
   1.353 +     * Called just after a path corresponding to a text decoration line
   1.354 +     * has been emitted to the gfxContext.
   1.355 +     */
   1.356 +    virtual void NotifyDecorationLinePathEmitted() { }
   1.357 +
   1.358 +    /**
   1.359 +     * Called just before a path corresponding to a selection decoration line
   1.360 +     * has been emitted to the gfxContext.
   1.361 +     */
   1.362 +    virtual void NotifyBeforeSelectionDecorationLine(nscolor aColor) { }
   1.363 +
   1.364 +    /**
   1.365 +     * Called just after a path corresponding to a selection decoration line
   1.366 +     * has been emitted to the gfxContext.
   1.367 +     */
   1.368 +    virtual void NotifySelectionDecorationLinePathEmitted() { }
   1.369 +  };
   1.370 +
   1.371 +  // Primary frame paint method called from nsDisplayText.  Can also be used
   1.372 +  // to generate paths rather than paint the frame's text by passing a callback
   1.373 +  // object.  The private DrawText() is what applies the text to a graphics
   1.374 +  // context.
   1.375 +  void PaintText(nsRenderingContext* aRenderingContext, nsPoint aPt,
   1.376 +                 const nsRect& aDirtyRect, const nsCharClipDisplayItem& aItem,
   1.377 +                 gfxTextContextPaint* aContextPaint = nullptr,
   1.378 +                 DrawPathCallbacks* aCallbacks = nullptr);
   1.379 +  // helper: paint text frame when we're impacted by at least one selection.
   1.380 +  // Return false if the text was not painted and we should continue with
   1.381 +  // the fast path.
   1.382 +  bool PaintTextWithSelection(gfxContext* aCtx,
   1.383 +                              const gfxPoint& aFramePt,
   1.384 +                              const gfxPoint& aTextBaselinePt,
   1.385 +                              const gfxRect& aDirtyRect,
   1.386 +                              PropertyProvider& aProvider,
   1.387 +                              uint32_t aContentOffset,
   1.388 +                              uint32_t aContentLength,
   1.389 +                              nsTextPaintStyle& aTextPaintStyle,
   1.390 +                              const nsCharClipDisplayItem::ClipEdges& aClipEdges,
   1.391 +                              gfxTextContextPaint* aContextPaint,
   1.392 +                              DrawPathCallbacks* aCallbacks);
   1.393 +  // helper: paint text with foreground and background colors determined
   1.394 +  // by selection(s). Also computes a mask of all selection types applying to
   1.395 +  // our text, returned in aAllTypes.
   1.396 +  // Return false if the text was not painted and we should continue with
   1.397 +  // the fast path.
   1.398 +  bool PaintTextWithSelectionColors(gfxContext* aCtx,
   1.399 +                                    const gfxPoint& aFramePt,
   1.400 +                                    const gfxPoint& aTextBaselinePt,
   1.401 +                                    const gfxRect& aDirtyRect,
   1.402 +                                    PropertyProvider& aProvider,
   1.403 +                                    uint32_t aContentOffset,
   1.404 +                                    uint32_t aContentLength,
   1.405 +                                    nsTextPaintStyle& aTextPaintStyle,
   1.406 +                                    SelectionDetails* aDetails,
   1.407 +                                    SelectionType* aAllTypes,
   1.408 +                             const nsCharClipDisplayItem::ClipEdges& aClipEdges,
   1.409 +                                    DrawPathCallbacks* aCallbacks);
   1.410 +  // helper: paint text decorations for text selected by aSelectionType
   1.411 +  void PaintTextSelectionDecorations(gfxContext* aCtx,
   1.412 +                                     const gfxPoint& aFramePt,
   1.413 +                                     const gfxPoint& aTextBaselinePt,
   1.414 +                                     const gfxRect& aDirtyRect,
   1.415 +                                     PropertyProvider& aProvider,
   1.416 +                                     uint32_t aContentOffset,
   1.417 +                                     uint32_t aContentLength,
   1.418 +                                     nsTextPaintStyle& aTextPaintStyle,
   1.419 +                                     SelectionDetails* aDetails,
   1.420 +                                     SelectionType aSelectionType,
   1.421 +                                     DrawPathCallbacks* aCallbacks);
   1.422 +
   1.423 +  virtual nscolor GetCaretColorAt(int32_t aOffset) MOZ_OVERRIDE;
   1.424 +
   1.425 +  int16_t GetSelectionStatus(int16_t* aSelectionFlags);
   1.426 +
   1.427 +  int32_t GetContentOffset() const { return mContentOffset; }
   1.428 +  int32_t GetContentLength() const
   1.429 +  {
   1.430 +    NS_ASSERTION(GetContentEnd() - mContentOffset >= 0, "negative length");
   1.431 +    return GetContentEnd() - mContentOffset;
   1.432 +  }
   1.433 +  int32_t GetContentEnd() const;
   1.434 +  // This returns the length the frame thinks it *should* have after it was
   1.435 +  // last reflowed (0 if it hasn't been reflowed yet). This should be used only
   1.436 +  // when setting up the text offsets for a new continuation frame.
   1.437 +  int32_t GetContentLengthHint() const { return mContentLengthHint; }
   1.438 +
   1.439 +  // Compute the length of the content mapped by this frame
   1.440 +  // and all its in-flow siblings. Basically this means starting at mContentOffset
   1.441 +  // and going to the end of the text node or the next bidi continuation
   1.442 +  // boundary.
   1.443 +  int32_t GetInFlowContentLength();
   1.444 +
   1.445 +  /**
   1.446 +   * Acquires the text run for this content, if necessary.
   1.447 +   * @param aWhichTextRun indicates whether to get an inflated or non-inflated
   1.448 +   * text run
   1.449 +   * @param aReferenceContext the rendering context to use as a reference for
   1.450 +   * creating the textrun, if available (if not, we'll create one which will
   1.451 +   * just be slower)
   1.452 +   * @param aLineContainer the block ancestor for this frame, or nullptr if
   1.453 +   * unknown
   1.454 +   * @param aFlowEndInTextRun if non-null, this returns the textrun offset of
   1.455 +   * end of the text associated with this frame and its in-flow siblings
   1.456 +   * @return a gfxSkipCharsIterator set up to map DOM offsets for this frame
   1.457 +   * to offsets into the textrun; its initial offset is set to this frame's
   1.458 +   * content offset
   1.459 +   */
   1.460 +  gfxSkipCharsIterator EnsureTextRun(TextRunType aWhichTextRun,
   1.461 +                                     gfxContext* aReferenceContext = nullptr,
   1.462 +                                     nsIFrame* aLineContainer = nullptr,
   1.463 +                                     const nsLineList::iterator* aLine = nullptr,
   1.464 +                                     uint32_t* aFlowEndInTextRun = nullptr);
   1.465 +
   1.466 +  gfxTextRun* GetTextRun(TextRunType aWhichTextRun) {
   1.467 +    if (aWhichTextRun == eInflated || !HasFontSizeInflation())
   1.468 +      return mTextRun;
   1.469 +    return GetUninflatedTextRun();
   1.470 +  }
   1.471 +  gfxTextRun* GetUninflatedTextRun();
   1.472 +  void SetTextRun(gfxTextRun* aTextRun, TextRunType aWhichTextRun,
   1.473 +                  float aInflation);
   1.474 +  bool IsInTextRunUserData() const {
   1.475 +    return GetStateBits() &
   1.476 +      (TEXT_IN_TEXTRUN_USER_DATA | TEXT_IN_UNINFLATED_TEXTRUN_USER_DATA);
   1.477 +  }
   1.478 +  /**
   1.479 +   * Notify the frame that it should drop its pointer to a text run.
   1.480 +   * Returns whether the text run was removed (i.e., whether it was
   1.481 +   * associated with this frame, either as its inflated or non-inflated
   1.482 +   * text run.
   1.483 +   */
   1.484 +  bool RemoveTextRun(gfxTextRun* aTextRun);
   1.485 +  /**
   1.486 +   * Clears out |mTextRun| (or the uninflated text run, when aInflated
   1.487 +   * is nsTextFrame::eNotInflated and there is inflation) from all frames that hold a
   1.488 +   * reference to it, starting at |aStartContinuation|, or if it's
   1.489 +   * nullptr, starting at |this|.  Deletes the text run if all references
   1.490 +   * were cleared and it's not cached.
   1.491 +   */
   1.492 +  void ClearTextRun(nsTextFrame* aStartContinuation,
   1.493 +                    TextRunType aWhichTextRun);
   1.494 +
   1.495 +  void ClearTextRuns() {
   1.496 +    ClearTextRun(nullptr, nsTextFrame::eInflated);
   1.497 +    if (HasFontSizeInflation()) {
   1.498 +      ClearTextRun(nullptr, nsTextFrame::eNotInflated);
   1.499 +    }
   1.500 +  }
   1.501 +
   1.502 +  /**
   1.503 +   * Wipe out references to textrun(s) without deleting the textruns.
   1.504 +   */
   1.505 +  void DisconnectTextRuns();
   1.506 +
   1.507 +  // Get the DOM content range mapped by this frame after excluding
   1.508 +  // whitespace subject to start-of-line and end-of-line trimming.
   1.509 +  // The textrun must have been created before calling this.
   1.510 +  struct TrimmedOffsets {
   1.511 +    int32_t mStart;
   1.512 +    int32_t mLength;
   1.513 +    int32_t GetEnd() const { return mStart + mLength; }
   1.514 +  };
   1.515 +  TrimmedOffsets GetTrimmedOffsets(const nsTextFragment* aFrag,
   1.516 +                                   bool aTrimAfter, bool aPostReflow = true);
   1.517 +
   1.518 +  // Similar to Reflow(), but for use from nsLineLayout
   1.519 +  void ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
   1.520 +                  nsRenderingContext* aRenderingContext,
   1.521 +                  nsHTMLReflowMetrics& aMetrics, nsReflowStatus& aStatus);
   1.522 +
   1.523 +  bool IsFloatingFirstLetterChild() const;
   1.524 +
   1.525 +protected:
   1.526 +  virtual ~nsTextFrame();
   1.527 +
   1.528 +  nsIFrame*   mNextContinuation;
   1.529 +  // The key invariant here is that mContentOffset never decreases along
   1.530 +  // a next-continuation chain. And of course mContentOffset is always <= the
   1.531 +  // the text node's content length, and the mContentOffset for the first frame
   1.532 +  // is always 0. Furthermore the text mapped by a frame is determined by
   1.533 +  // GetContentOffset() and GetContentLength()/GetContentEnd(), which get
   1.534 +  // the length from the difference between this frame's offset and the next
   1.535 +  // frame's offset, or the text length if there is no next frame. This means
   1.536 +  // the frames always map the text node without overlapping or leaving any gaps.
   1.537 +  int32_t     mContentOffset;
   1.538 +  // This does *not* indicate the length of text currently mapped by the frame;
   1.539 +  // instead it's a hint saying that this frame *wants* to map this much text
   1.540 +  // so if we create a new continuation, this is where that continuation should
   1.541 +  // start.
   1.542 +  int32_t     mContentLengthHint;
   1.543 +  nscoord     mAscent;
   1.544 +  gfxTextRun* mTextRun;
   1.545 +
   1.546 +  /**
   1.547 +   * Return true if the frame is part of a Selection.
   1.548 +   * Helper method to implement the public IsSelected() API.
   1.549 +   */
   1.550 +  virtual bool IsFrameSelected() const MOZ_OVERRIDE;
   1.551 +
   1.552 +  // The caller of this method must call DestroySelectionDetails() on the
   1.553 +  // return value, if that return value is not null.  Calling
   1.554 +  // DestroySelectionDetails() on a null value is still OK, just not necessary.
   1.555 +  SelectionDetails* GetSelectionDetails();
   1.556 +
   1.557 +  void UnionAdditionalOverflow(nsPresContext* aPresContext,
   1.558 +                               const nsHTMLReflowState& aBlockReflowState,
   1.559 +                               PropertyProvider& aProvider,
   1.560 +                               nsRect* aVisualOverflowRect,
   1.561 +                               bool aIncludeTextDecorations);
   1.562 +
   1.563 +  void PaintOneShadow(uint32_t aOffset,
   1.564 +                      uint32_t aLength,
   1.565 +                      nsCSSShadowItem* aShadowDetails,
   1.566 +                      PropertyProvider* aProvider,
   1.567 +                      const nsRect& aDirtyRect,
   1.568 +                      const gfxPoint& aFramePt,
   1.569 +                      const gfxPoint& aTextBaselinePt,
   1.570 +                      gfxContext* aCtx,
   1.571 +                      const nscolor& aForegroundColor,
   1.572 +                      const nsCharClipDisplayItem::ClipEdges& aClipEdges,
   1.573 +                      nscoord aLeftSideOffset,
   1.574 +                      gfxRect& aBoundingBox);
   1.575 +
   1.576 +  struct LineDecoration {
   1.577 +    nsIFrame* mFrame;
   1.578 +
   1.579 +    // This is represents the offset from our baseline to mFrame's baseline;
   1.580 +    // positive offsets are *above* the baseline and negative offsets below
   1.581 +    nscoord mBaselineOffset;
   1.582 +
   1.583 +    nscolor mColor;
   1.584 +    uint8_t mStyle;
   1.585 +
   1.586 +    LineDecoration(nsIFrame *const aFrame,
   1.587 +                   const nscoord aOff,
   1.588 +                   const nscolor aColor,
   1.589 +                   const uint8_t aStyle)
   1.590 +      : mFrame(aFrame),
   1.591 +        mBaselineOffset(aOff),
   1.592 +        mColor(aColor),
   1.593 +        mStyle(aStyle)
   1.594 +    {}
   1.595 +
   1.596 +    LineDecoration(const LineDecoration& aOther)
   1.597 +      : mFrame(aOther.mFrame),
   1.598 +        mBaselineOffset(aOther.mBaselineOffset),
   1.599 +        mColor(aOther.mColor),
   1.600 +        mStyle(aOther.mStyle)
   1.601 +    {}
   1.602 +
   1.603 +    bool operator==(const LineDecoration& aOther) const {
   1.604 +      return mFrame == aOther.mFrame &&
   1.605 +             mStyle == aOther.mStyle &&
   1.606 +             mColor == aOther.mColor &&
   1.607 +             mBaselineOffset == aOther.mBaselineOffset;
   1.608 +    }
   1.609 +
   1.610 +    bool operator!=(const LineDecoration& aOther) const {
   1.611 +      return !(*this == aOther);
   1.612 +    }
   1.613 +  };
   1.614 +  struct TextDecorations {
   1.615 +    nsAutoTArray<LineDecoration, 1> mOverlines, mUnderlines, mStrikes;
   1.616 +
   1.617 +    TextDecorations() { }
   1.618 +
   1.619 +    bool HasDecorationLines() const {
   1.620 +      return HasUnderline() || HasOverline() || HasStrikeout();
   1.621 +    }
   1.622 +    bool HasUnderline() const {
   1.623 +      return !mUnderlines.IsEmpty();
   1.624 +    }
   1.625 +    bool HasOverline() const {
   1.626 +      return !mOverlines.IsEmpty();
   1.627 +    }
   1.628 +    bool HasStrikeout() const {
   1.629 +      return !mStrikes.IsEmpty();
   1.630 +    }
   1.631 +    bool operator==(const TextDecorations& aOther) const {
   1.632 +      return mOverlines == aOther.mOverlines &&
   1.633 +             mUnderlines == aOther.mUnderlines &&
   1.634 +             mStrikes == aOther.mStrikes;
   1.635 +    }
   1.636 +    
   1.637 +    bool operator!=(const TextDecorations& aOther) const {
   1.638 +      return !(*this == aOther);
   1.639 +    }
   1.640 +
   1.641 +  };
   1.642 +  enum TextDecorationColorResolution {
   1.643 +    eResolvedColors,
   1.644 +    eUnresolvedColors
   1.645 +  };
   1.646 +  void GetTextDecorations(nsPresContext* aPresContext,
   1.647 +                          TextDecorationColorResolution aColorResolution,
   1.648 +                          TextDecorations& aDecorations);
   1.649 +
   1.650 +  void DrawTextRun(gfxContext* const aCtx,
   1.651 +                   const gfxPoint& aTextBaselinePt,
   1.652 +                   uint32_t aOffset,
   1.653 +                   uint32_t aLength,
   1.654 +                   PropertyProvider& aProvider,
   1.655 +                   nscolor aTextColor,
   1.656 +                   gfxFloat& aAdvanceWidth,
   1.657 +                   bool aDrawSoftHyphen,
   1.658 +                   gfxTextContextPaint* aContextPaint,
   1.659 +                   DrawPathCallbacks* aCallbacks);
   1.660 +
   1.661 +  void DrawTextRunAndDecorations(gfxContext* const aCtx,
   1.662 +                                 const gfxRect& aDirtyRect,
   1.663 +                                 const gfxPoint& aFramePt,
   1.664 +                                 const gfxPoint& aTextBaselinePt,
   1.665 +                                 uint32_t aOffset,
   1.666 +                                 uint32_t aLength,
   1.667 +                                 PropertyProvider& aProvider,
   1.668 +                                 const nsTextPaintStyle& aTextStyle,
   1.669 +                                 nscolor aTextColor,
   1.670 +                             const nsCharClipDisplayItem::ClipEdges& aClipEdges,
   1.671 +                                 gfxFloat& aAdvanceWidth,
   1.672 +                                 bool aDrawSoftHyphen,
   1.673 +                                 const TextDecorations& aDecorations,
   1.674 +                                 const nscolor* const aDecorationOverrideColor,
   1.675 +                                 gfxTextContextPaint* aContextPaint,
   1.676 +                                 DrawPathCallbacks* aCallbacks);
   1.677 +
   1.678 +  void DrawText(gfxContext* const aCtx,
   1.679 +                const gfxRect& aDirtyRect,
   1.680 +                const gfxPoint& aFramePt,
   1.681 +                const gfxPoint& aTextBaselinePt,
   1.682 +                uint32_t aOffset,
   1.683 +                uint32_t aLength,
   1.684 +                PropertyProvider& aProvider,
   1.685 +                const nsTextPaintStyle& aTextStyle,
   1.686 +                nscolor aTextColor,
   1.687 +                const nsCharClipDisplayItem::ClipEdges& aClipEdges,
   1.688 +                gfxFloat& aAdvanceWidth,
   1.689 +                bool aDrawSoftHyphen,
   1.690 +                const nscolor* const aDecorationOverrideColor = nullptr,
   1.691 +                gfxTextContextPaint* aContextPaint = nullptr,
   1.692 +                DrawPathCallbacks* aCallbacks = nullptr);
   1.693 +
   1.694 +  // Set non empty rect to aRect, it should be overflow rect or frame rect.
   1.695 +  // If the result rect is larger than the given rect, this returns true.
   1.696 +  bool CombineSelectionUnderlineRect(nsPresContext* aPresContext,
   1.697 +                                       nsRect& aRect);
   1.698 +
   1.699 +  ContentOffsets GetCharacterOffsetAtFramePointInternal(nsPoint aPoint,
   1.700 +                   bool aForInsertionPoint);
   1.701 +
   1.702 +  void ClearFrameOffsetCache();
   1.703 +
   1.704 +  virtual bool HasAnyNoncollapsedCharacters() MOZ_OVERRIDE;
   1.705 +
   1.706 +  void ClearMetrics(nsHTMLReflowMetrics& aMetrics);
   1.707 +};
   1.708 +
   1.709 +#endif

mercurial