bug 45152 (Typed text does not render in TextAreas with a horizontal scrollbar)

fixed by adding a flag in nsLineBox for the content of a line to mark it "forceInvalidate",
logic in nsLineLayout to set the line dirty for initial reflow of text frames,
and logic in block to check the new flag.
r=kin
This commit is contained in:
buster%netscape.com 2000-08-24 04:26:43 +00:00
Родитель 2016929679
Коммит a017796f68
12 изменённых файлов: 198 добавлений и 10 удалений

Просмотреть файл

@ -2674,6 +2674,17 @@ nsBlockFrame::FindLineFor(nsIFrame* aFrame,
return line;
}
// SEC: added GetCurrentLine() for bug 45152
// we need a way for line layout to know what line is being reflowed,
// but we don't want to expose the innards of nsBlockReflowState.
nsresult
nsBlockFrame::GetCurrentLine(nsBlockReflowState *aState, nsLineBox ** aOutCurrentLine)
{
if (!aState || !aOutCurrentLine) return NS_ERROR_FAILURE;
*aOutCurrentLine = aState->mCurrentLine;
return NS_OK;
}
void
nsBlockFrame::RecoverStateFrom(nsBlockReflowState& aState,
nsLineBox* aLine,
@ -3257,7 +3268,9 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState,
// We don't really know what changed in the line, so use the union
// of the old and new combined areas
if (aDamageDirtyArea) {
// SEC: added "aLine->IsForceInvalidate()" for bug 45152
if (aDamageDirtyArea || aLine->IsForceInvalidate()) {
aLine->SetForceInvalidate(PR_FALSE); // doing the invalidate now, force flag to off
nsRect combinedArea;
aLine->GetCombinedArea(&combinedArea);

Просмотреть файл

@ -161,6 +161,8 @@ public:
nsLineBox* FindLineFor(nsIFrame* aFrame, nsLineBox** aPrevLineResult,
PRBool* aIsFloaterResult);
static nsresult GetCurrentLine(nsBlockReflowState *aState, nsLineBox **aOutCurrentLine);
// return our ascent (i.e., ascent of our first line)
// to support 'vertical-align: baseline' in table-cells
nscoord GetAscent() const;

Просмотреть файл

@ -2674,6 +2674,17 @@ nsBlockFrame::FindLineFor(nsIFrame* aFrame,
return line;
}
// SEC: added GetCurrentLine() for bug 45152
// we need a way for line layout to know what line is being reflowed,
// but we don't want to expose the innards of nsBlockReflowState.
nsresult
nsBlockFrame::GetCurrentLine(nsBlockReflowState *aState, nsLineBox ** aOutCurrentLine)
{
if (!aState || !aOutCurrentLine) return NS_ERROR_FAILURE;
*aOutCurrentLine = aState->mCurrentLine;
return NS_OK;
}
void
nsBlockFrame::RecoverStateFrom(nsBlockReflowState& aState,
nsLineBox* aLine,
@ -3257,7 +3268,9 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState,
// We don't really know what changed in the line, so use the union
// of the old and new combined areas
if (aDamageDirtyArea) {
// SEC: added "aLine->IsForceInvalidate()" for bug 45152
if (aDamageDirtyArea || aLine->IsForceInvalidate()) {
aLine->SetForceInvalidate(PR_FALSE); // doing the invalidate now, force flag to off
nsRect combinedArea;
aLine->GetCombinedArea(&combinedArea);

Просмотреть файл

@ -2674,6 +2674,17 @@ nsBlockFrame::FindLineFor(nsIFrame* aFrame,
return line;
}
// SEC: added GetCurrentLine() for bug 45152
// we need a way for line layout to know what line is being reflowed,
// but we don't want to expose the innards of nsBlockReflowState.
nsresult
nsBlockFrame::GetCurrentLine(nsBlockReflowState *aState, nsLineBox ** aOutCurrentLine)
{
if (!aState || !aOutCurrentLine) return NS_ERROR_FAILURE;
*aOutCurrentLine = aState->mCurrentLine;
return NS_OK;
}
void
nsBlockFrame::RecoverStateFrom(nsBlockReflowState& aState,
nsLineBox* aLine,
@ -3257,7 +3268,9 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState,
// We don't really know what changed in the line, so use the union
// of the old and new combined areas
if (aDamageDirtyArea) {
// SEC: added "aLine->IsForceInvalidate()" for bug 45152
if (aDamageDirtyArea || aLine->IsForceInvalidate()) {
aLine->SetForceInvalidate(PR_FALSE); // doing the invalidate now, force flag to off
nsRect combinedArea;
aLine->GetCombinedArea(&combinedArea);

Просмотреть файл

@ -136,7 +136,7 @@ protected:
//----------------------------------------------------------------------
#define LINE_MAX_BREAK_TYPE ((1 << 4) - 1)
#define LINE_MAX_CHILD_COUNT ((1 << 24) - 1)
#define LINE_MAX_CHILD_COUNT ((1 << 21) - 1)
#if NS_STYLE_CLEAR_LAST_VALUE > 15
need to rearrange the mBits bitfield;
@ -222,6 +222,15 @@ public:
PRBool IsLineWrapped() const {
return mFlags.mLineWrapped;
}
// mLineWrapped bit
void SetForceInvalidate(PRBool aOn) {
NS_ASSERTION((PR_FALSE==aOn || PR_TRUE==aOn), "somebody is playing fast and loose with bools and bits!");
mFlags.mForceInvalidate = aOn;
}
PRBool IsForceInvalidate() const {
return mFlags.mForceInvalidate;
}
// mChildCount value
PRInt32 GetChildCount() const {
@ -328,10 +337,11 @@ public:
PRUint32 mTrimmed : 1;
PRUint32 mHasPercentageChild : 1;
PRUint32 mLineWrapped: 1;
PRUint32 mForceInvalidate: 1;
PRUint32 mBreakType : 4;
PRUint32 mChildCount : 22;
PRUint32 mChildCount : 21;
};
struct ExtraData {

Просмотреть файл

@ -25,6 +25,7 @@
*/
#include "nsCOMPtr.h"
#include "nsLineLayout.h"
#include "nsBlockFrame.h"
#include "nsStyleConsts.h"
#include "nsHTMLContainerFrame.h"
#include "nsHTMLIIDs.h"
@ -934,6 +935,48 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
aFrame->Reflow(mPresContext, metrics, reflowState, aReflowStatus);
// SEC: added this next block for bug 45152
// text frames don't know how to invalidate themselves on initial reflow. Do it for them here.
// This only shows up in textareas, so do a quick check to see if we're inside one
if (eReflowReason_Initial == reflowState.reason)
{
nsCOMPtr<nsIAtom> frameType;
aFrame->GetFrameType(getter_AddRefs(frameType));
if (frameType && nsLayoutAtoms::textFrame == frameType.get())
{ // aFrame is a text frame, see if it's inside a text control
// although this is a bit slow, the frame tree shouldn't be too deep, it's only called
// for the text frame's initial reflow (once in the text frame's lifetime)
// and we don't make any expensive calls.
// Doing it this way shields us from knowing anything about the frame structure inside a text control.
nsIFrame *parentFrame;
aFrame->GetParent(&parentFrame);
PRBool inTextControl = PR_FALSE;
while (parentFrame)
{
nsCOMPtr<nsIAtom> frameType;
parentFrame->GetFrameType(getter_AddRefs(frameType));
if (frameType)
{
if (nsLayoutAtoms::textInputFrame == frameType.get())
{
inTextControl = PR_TRUE; // found it
break;
}
}
parentFrame->GetParent(&parentFrame); // advance the loop up the frame tree
}
if (inTextControl)
{
nsLineBox *currentLine=nsnull;
nsresult rv = nsBlockFrame::GetCurrentLine(mBlockRS, &currentLine);
if (NS_SUCCEEDED(rv) && currentLine) {
currentLine->SetForceInvalidate(PR_TRUE);
}
}
}
}
// end fix for bug 45152
pfd->mJustificationNumSpaces = mTextJustificationNumSpaces;
pfd->mJustificationNumLetters = mTextJustificationNumLetters;

Просмотреть файл

@ -2674,6 +2674,17 @@ nsBlockFrame::FindLineFor(nsIFrame* aFrame,
return line;
}
// SEC: added GetCurrentLine() for bug 45152
// we need a way for line layout to know what line is being reflowed,
// but we don't want to expose the innards of nsBlockReflowState.
nsresult
nsBlockFrame::GetCurrentLine(nsBlockReflowState *aState, nsLineBox ** aOutCurrentLine)
{
if (!aState || !aOutCurrentLine) return NS_ERROR_FAILURE;
*aOutCurrentLine = aState->mCurrentLine;
return NS_OK;
}
void
nsBlockFrame::RecoverStateFrom(nsBlockReflowState& aState,
nsLineBox* aLine,
@ -3257,7 +3268,9 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState,
// We don't really know what changed in the line, so use the union
// of the old and new combined areas
if (aDamageDirtyArea) {
// SEC: added "aLine->IsForceInvalidate()" for bug 45152
if (aDamageDirtyArea || aLine->IsForceInvalidate()) {
aLine->SetForceInvalidate(PR_FALSE); // doing the invalidate now, force flag to off
nsRect combinedArea;
aLine->GetCombinedArea(&combinedArea);

Просмотреть файл

@ -161,6 +161,8 @@ public:
nsLineBox* FindLineFor(nsIFrame* aFrame, nsLineBox** aPrevLineResult,
PRBool* aIsFloaterResult);
static nsresult GetCurrentLine(nsBlockReflowState *aState, nsLineBox **aOutCurrentLine);
// return our ascent (i.e., ascent of our first line)
// to support 'vertical-align: baseline' in table-cells
nscoord GetAscent() const;

Просмотреть файл

@ -2674,6 +2674,17 @@ nsBlockFrame::FindLineFor(nsIFrame* aFrame,
return line;
}
// SEC: added GetCurrentLine() for bug 45152
// we need a way for line layout to know what line is being reflowed,
// but we don't want to expose the innards of nsBlockReflowState.
nsresult
nsBlockFrame::GetCurrentLine(nsBlockReflowState *aState, nsLineBox ** aOutCurrentLine)
{
if (!aState || !aOutCurrentLine) return NS_ERROR_FAILURE;
*aOutCurrentLine = aState->mCurrentLine;
return NS_OK;
}
void
nsBlockFrame::RecoverStateFrom(nsBlockReflowState& aState,
nsLineBox* aLine,
@ -3257,7 +3268,9 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState,
// We don't really know what changed in the line, so use the union
// of the old and new combined areas
if (aDamageDirtyArea) {
// SEC: added "aLine->IsForceInvalidate()" for bug 45152
if (aDamageDirtyArea || aLine->IsForceInvalidate()) {
aLine->SetForceInvalidate(PR_FALSE); // doing the invalidate now, force flag to off
nsRect combinedArea;
aLine->GetCombinedArea(&combinedArea);

Просмотреть файл

@ -2674,6 +2674,17 @@ nsBlockFrame::FindLineFor(nsIFrame* aFrame,
return line;
}
// SEC: added GetCurrentLine() for bug 45152
// we need a way for line layout to know what line is being reflowed,
// but we don't want to expose the innards of nsBlockReflowState.
nsresult
nsBlockFrame::GetCurrentLine(nsBlockReflowState *aState, nsLineBox ** aOutCurrentLine)
{
if (!aState || !aOutCurrentLine) return NS_ERROR_FAILURE;
*aOutCurrentLine = aState->mCurrentLine;
return NS_OK;
}
void
nsBlockFrame::RecoverStateFrom(nsBlockReflowState& aState,
nsLineBox* aLine,
@ -3257,7 +3268,9 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState,
// We don't really know what changed in the line, so use the union
// of the old and new combined areas
if (aDamageDirtyArea) {
// SEC: added "aLine->IsForceInvalidate()" for bug 45152
if (aDamageDirtyArea || aLine->IsForceInvalidate()) {
aLine->SetForceInvalidate(PR_FALSE); // doing the invalidate now, force flag to off
nsRect combinedArea;
aLine->GetCombinedArea(&combinedArea);

Просмотреть файл

@ -136,7 +136,7 @@ protected:
//----------------------------------------------------------------------
#define LINE_MAX_BREAK_TYPE ((1 << 4) - 1)
#define LINE_MAX_CHILD_COUNT ((1 << 24) - 1)
#define LINE_MAX_CHILD_COUNT ((1 << 21) - 1)
#if NS_STYLE_CLEAR_LAST_VALUE > 15
need to rearrange the mBits bitfield;
@ -222,6 +222,15 @@ public:
PRBool IsLineWrapped() const {
return mFlags.mLineWrapped;
}
// mLineWrapped bit
void SetForceInvalidate(PRBool aOn) {
NS_ASSERTION((PR_FALSE==aOn || PR_TRUE==aOn), "somebody is playing fast and loose with bools and bits!");
mFlags.mForceInvalidate = aOn;
}
PRBool IsForceInvalidate() const {
return mFlags.mForceInvalidate;
}
// mChildCount value
PRInt32 GetChildCount() const {
@ -328,10 +337,11 @@ public:
PRUint32 mTrimmed : 1;
PRUint32 mHasPercentageChild : 1;
PRUint32 mLineWrapped: 1;
PRUint32 mForceInvalidate: 1;
PRUint32 mBreakType : 4;
PRUint32 mChildCount : 22;
PRUint32 mChildCount : 21;
};
struct ExtraData {

Просмотреть файл

@ -25,6 +25,7 @@
*/
#include "nsCOMPtr.h"
#include "nsLineLayout.h"
#include "nsBlockFrame.h"
#include "nsStyleConsts.h"
#include "nsHTMLContainerFrame.h"
#include "nsHTMLIIDs.h"
@ -934,6 +935,48 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
aFrame->Reflow(mPresContext, metrics, reflowState, aReflowStatus);
// SEC: added this next block for bug 45152
// text frames don't know how to invalidate themselves on initial reflow. Do it for them here.
// This only shows up in textareas, so do a quick check to see if we're inside one
if (eReflowReason_Initial == reflowState.reason)
{
nsCOMPtr<nsIAtom> frameType;
aFrame->GetFrameType(getter_AddRefs(frameType));
if (frameType && nsLayoutAtoms::textFrame == frameType.get())
{ // aFrame is a text frame, see if it's inside a text control
// although this is a bit slow, the frame tree shouldn't be too deep, it's only called
// for the text frame's initial reflow (once in the text frame's lifetime)
// and we don't make any expensive calls.
// Doing it this way shields us from knowing anything about the frame structure inside a text control.
nsIFrame *parentFrame;
aFrame->GetParent(&parentFrame);
PRBool inTextControl = PR_FALSE;
while (parentFrame)
{
nsCOMPtr<nsIAtom> frameType;
parentFrame->GetFrameType(getter_AddRefs(frameType));
if (frameType)
{
if (nsLayoutAtoms::textInputFrame == frameType.get())
{
inTextControl = PR_TRUE; // found it
break;
}
}
parentFrame->GetParent(&parentFrame); // advance the loop up the frame tree
}
if (inTextControl)
{
nsLineBox *currentLine=nsnull;
nsresult rv = nsBlockFrame::GetCurrentLine(mBlockRS, &currentLine);
if (NS_SUCCEEDED(rv) && currentLine) {
currentLine->SetForceInvalidate(PR_TRUE);
}
}
}
}
// end fix for bug 45152
pfd->mJustificationNumSpaces = mTextJustificationNumSpaces;
pfd->mJustificationNumLetters = mTextJustificationNumLetters;