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