From a0bf1cc46e2566ccf09e76ff5330b3150ebba6fa Mon Sep 17 00:00:00 2001 From: "kipp%netscape.com" Date: Fri, 26 Mar 1999 00:41:36 +0000 Subject: [PATCH] Work around some first-letter bugs git-svn-id: svn://10.0.0.236/trunk@25157 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/generic/nsLineLayout.cpp | 3 +++ mozilla/layout/generic/nsLineLayout.h | 5 +++++ mozilla/layout/generic/nsTextFrame.cpp | 21 ++++++++++++++----- mozilla/layout/html/base/src/nsLineLayout.cpp | 3 +++ mozilla/layout/html/base/src/nsLineLayout.h | 5 +++++ mozilla/layout/html/base/src/nsTextFrame.cpp | 21 ++++++++++++++----- 6 files changed, 48 insertions(+), 10 deletions(-) diff --git a/mozilla/layout/generic/nsLineLayout.cpp b/mozilla/layout/generic/nsLineLayout.cpp index 5dc695929a2..c71cea5f7e3 100644 --- a/mozilla/layout/generic/nsLineLayout.cpp +++ b/mozilla/layout/generic/nsLineLayout.cpp @@ -800,6 +800,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, // the state out. We need to know how to treat the current frame // when breaking. PRBool notSafeToBreak = CanPlaceFloaterNow() || InWord(); + PRBool firstLetterOK = mFirstLetterStyleOK; // Apply left margins (as appropriate) to the frame computing the // new starting x,y coordinates for the frame. @@ -938,6 +939,8 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, parent->DeleteChildsNextInFlow(mPresContext, aFrame); } } + if (firstLetterOK && !mFirstLetterStyleOK) { + } // See if we can place the frame. If we can't fit it, then we // return now. diff --git a/mozilla/layout/generic/nsLineLayout.h b/mozilla/layout/generic/nsLineLayout.h index 7ae69ce1935..211e6668101 100644 --- a/mozilla/layout/generic/nsLineLayout.h +++ b/mozilla/layout/generic/nsLineLayout.h @@ -177,6 +177,10 @@ public: mFirstLetterStyleOK = aSetting; } + void SetFirstLetterFrame(nsIFrame* aFrame) { + mFirstLetterFrame = aFrame; + } + //---------------------------------------- // Text run usage methods. These methods are using during reflow to // track the current text run and to advance through text runs. @@ -221,6 +225,7 @@ protected: // This state varies during the reflow of a line but is line // "global" state not span "local" state. nsIFrame* mBRFrame; + nsIFrame* mFirstLetterFrame; PRInt32 mLineNumber; PRInt32 mColumn; PRBool mEndsInWhiteSpace; diff --git a/mozilla/layout/generic/nsTextFrame.cpp b/mozilla/layout/generic/nsTextFrame.cpp index 7f3996ed5ea..64e6833a5d5 100644 --- a/mozilla/layout/generic/nsTextFrame.cpp +++ b/mozilla/layout/generic/nsTextFrame.cpp @@ -331,6 +331,10 @@ protected: #define TEXT_TRIMMED_WS 0x10 +// This bit is set on the first frame in a continuation indicating +// that it was choppsed short because of :first-letter style. +#define TEXT_FIRST_LETTER 0x20 + //---------------------------------------------------------------------- static PRBool gBlinkTextOff; @@ -512,7 +516,7 @@ TextFrame::Paint(nsIPresContext& aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { - if (eFramePaintLayer_Content != aWhichLayer) { + if (NS_FRAME_PAINT_LAYER_FOREGROUND != aWhichLayer) { return NS_OK; } if ((0 != (mFlags & TEXT_BLINK_ON)) && gBlinkTextOff) { @@ -2207,14 +2211,17 @@ TextFrame::Reflow(nsIPresContext& aPresContext, // Loop over words and whitespace in content and measure. Set inWord // to true if we are part of a previous piece of text's word. This // is only valid for one pass through the measuring loop. - PRBool inWord = lineLayout.InWord(); + PRBool inWord = lineLayout.InWord() || + ((nsnull != mPrevInFlow) && + (((TextFrame*)mPrevInFlow)->mFlags & TEXT_FIRST_LETTER)); if (inWord) { mFlags |= TEXT_IN_WORD; } + mFlags &= ~TEXT_FIRST_LETTER; + PRInt32 column = lineLayout.GetColumn(); PRInt32 prevColumn = column; mColumn = column; - PRBool breakable = lineLayout.LineIsBreakable(); for (;;) { // Get next word/whitespace from the text @@ -2395,7 +2402,9 @@ TextFrame::Reflow(nsIPresContext& aPresContext, lineLayout.SetEndsInWhiteSpace(endsInWhitespace); } if (justDidFirstLetter) { + lineLayout.SetFirstLetterFrame(this); lineLayout.SetFirstLetterStyleOK(PR_FALSE); + mFlags |= TEXT_FIRST_LETTER; } // Setup metrics for caller; store final max-element-size information @@ -2811,9 +2820,11 @@ TextFrame::List(FILE* out, PRInt32 aIndent) const // Output the first/last content offset and prev/next in flow info PRBool isComplete = (mContentOffset + mContentLength) == contentLength; - fprintf(out, "[%d,%d,%c] ", + fprintf(out, "[%d,%d,%c][%x] ", mContentOffset, mContentOffset+mContentLength-1, - isComplete ? 'T':'F'); + isComplete ? 'T':'F', + mFlags); + if (nsnull != mPrevInFlow) { fprintf(out, "prev-in-flow=%p ", mPrevInFlow); } diff --git a/mozilla/layout/html/base/src/nsLineLayout.cpp b/mozilla/layout/html/base/src/nsLineLayout.cpp index 5dc695929a2..c71cea5f7e3 100644 --- a/mozilla/layout/html/base/src/nsLineLayout.cpp +++ b/mozilla/layout/html/base/src/nsLineLayout.cpp @@ -800,6 +800,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, // the state out. We need to know how to treat the current frame // when breaking. PRBool notSafeToBreak = CanPlaceFloaterNow() || InWord(); + PRBool firstLetterOK = mFirstLetterStyleOK; // Apply left margins (as appropriate) to the frame computing the // new starting x,y coordinates for the frame. @@ -938,6 +939,8 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, parent->DeleteChildsNextInFlow(mPresContext, aFrame); } } + if (firstLetterOK && !mFirstLetterStyleOK) { + } // See if we can place the frame. If we can't fit it, then we // return now. diff --git a/mozilla/layout/html/base/src/nsLineLayout.h b/mozilla/layout/html/base/src/nsLineLayout.h index 7ae69ce1935..211e6668101 100644 --- a/mozilla/layout/html/base/src/nsLineLayout.h +++ b/mozilla/layout/html/base/src/nsLineLayout.h @@ -177,6 +177,10 @@ public: mFirstLetterStyleOK = aSetting; } + void SetFirstLetterFrame(nsIFrame* aFrame) { + mFirstLetterFrame = aFrame; + } + //---------------------------------------- // Text run usage methods. These methods are using during reflow to // track the current text run and to advance through text runs. @@ -221,6 +225,7 @@ protected: // This state varies during the reflow of a line but is line // "global" state not span "local" state. nsIFrame* mBRFrame; + nsIFrame* mFirstLetterFrame; PRInt32 mLineNumber; PRInt32 mColumn; PRBool mEndsInWhiteSpace; diff --git a/mozilla/layout/html/base/src/nsTextFrame.cpp b/mozilla/layout/html/base/src/nsTextFrame.cpp index 7f3996ed5ea..64e6833a5d5 100644 --- a/mozilla/layout/html/base/src/nsTextFrame.cpp +++ b/mozilla/layout/html/base/src/nsTextFrame.cpp @@ -331,6 +331,10 @@ protected: #define TEXT_TRIMMED_WS 0x10 +// This bit is set on the first frame in a continuation indicating +// that it was choppsed short because of :first-letter style. +#define TEXT_FIRST_LETTER 0x20 + //---------------------------------------------------------------------- static PRBool gBlinkTextOff; @@ -512,7 +516,7 @@ TextFrame::Paint(nsIPresContext& aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { - if (eFramePaintLayer_Content != aWhichLayer) { + if (NS_FRAME_PAINT_LAYER_FOREGROUND != aWhichLayer) { return NS_OK; } if ((0 != (mFlags & TEXT_BLINK_ON)) && gBlinkTextOff) { @@ -2207,14 +2211,17 @@ TextFrame::Reflow(nsIPresContext& aPresContext, // Loop over words and whitespace in content and measure. Set inWord // to true if we are part of a previous piece of text's word. This // is only valid for one pass through the measuring loop. - PRBool inWord = lineLayout.InWord(); + PRBool inWord = lineLayout.InWord() || + ((nsnull != mPrevInFlow) && + (((TextFrame*)mPrevInFlow)->mFlags & TEXT_FIRST_LETTER)); if (inWord) { mFlags |= TEXT_IN_WORD; } + mFlags &= ~TEXT_FIRST_LETTER; + PRInt32 column = lineLayout.GetColumn(); PRInt32 prevColumn = column; mColumn = column; - PRBool breakable = lineLayout.LineIsBreakable(); for (;;) { // Get next word/whitespace from the text @@ -2395,7 +2402,9 @@ TextFrame::Reflow(nsIPresContext& aPresContext, lineLayout.SetEndsInWhiteSpace(endsInWhitespace); } if (justDidFirstLetter) { + lineLayout.SetFirstLetterFrame(this); lineLayout.SetFirstLetterStyleOK(PR_FALSE); + mFlags |= TEXT_FIRST_LETTER; } // Setup metrics for caller; store final max-element-size information @@ -2811,9 +2820,11 @@ TextFrame::List(FILE* out, PRInt32 aIndent) const // Output the first/last content offset and prev/next in flow info PRBool isComplete = (mContentOffset + mContentLength) == contentLength; - fprintf(out, "[%d,%d,%c] ", + fprintf(out, "[%d,%d,%c][%x] ", mContentOffset, mContentOffset+mContentLength-1, - isComplete ? 'T':'F'); + isComplete ? 'T':'F', + mFlags); + if (nsnull != mPrevInFlow) { fprintf(out, "prev-in-flow=%p ", mPrevInFlow); }