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.

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

mercurial