Backed out changeset aeff4052ef00 (bug 789096)

This commit is contained in:
Carsten "Tomcat" Book
2014-03-11 09:22:52 +01:00
parent aaf2226136
commit db3b507cf9
13 changed files with 763 additions and 843 deletions

View File

@@ -1229,9 +1229,7 @@ nsBidiPresUtils::ResolveParagraphWithinBlock(nsBlockFrame* aBlockFrame,
void void
nsBidiPresUtils::ReorderFrames(nsIFrame* aFirstFrameOnLine, nsBidiPresUtils::ReorderFrames(nsIFrame* aFirstFrameOnLine,
int32_t aNumFramesOnLine, int32_t aNumFramesOnLine)
WritingMode aLineWM,
nscoord& aLineWidth)
{ {
// If this line consists of a line frame, reorder the line frame's children. // If this line consists of a line frame, reorder the line frame's children.
if (aFirstFrameOnLine->GetType() == nsGkAtoms::lineFrame) { if (aFirstFrameOnLine->GetType() == nsGkAtoms::lineFrame) {
@@ -1244,7 +1242,7 @@ nsBidiPresUtils::ReorderFrames(nsIFrame* aFirstFrameOnLine,
} }
BidiLineData bld(aFirstFrameOnLine, aNumFramesOnLine); BidiLineData bld(aFirstFrameOnLine, aNumFramesOnLine);
RepositionInlineFrames(&bld, aFirstFrameOnLine, aLineWM, aLineWidth); RepositionInlineFrames(&bld, aFirstFrameOnLine);
} }
nsIFrame* nsIFrame*
@@ -1284,20 +1282,22 @@ nsBidiPresUtils::GetFrameBaseLevel(nsIFrame* aFrame)
} }
void void
nsBidiPresUtils::IsFirstOrLast(nsIFrame* aFrame, nsBidiPresUtils::IsLeftOrRightMost(nsIFrame* aFrame,
nsContinuationStates* aContinuationStates, nsContinuationStates* aContinuationStates,
bool& aIsFirst /* out */, bool& aIsLeftMost /* out */,
bool& aIsLast /* out */) bool& aIsRightMost /* out */)
{ {
const nsStyleVisibility* vis = aFrame->StyleVisibility();
bool isLTR = (NS_STYLE_DIRECTION_LTR == vis->mDirection);
/* /*
* Since we lay out frames in the line's direction, visiting a frame with * Since we lay out frames from left to right (in both LTR and RTL), visiting a
* 'mFirstVisualFrame == nullptr', means it's the first appearance of one * frame with 'mFirstVisualFrame == nullptr', means it's the first appearance of
* of its continuation chain frames on the line. * one of its continuation chain frames on the line.
* To determine if it's the last visual frame of its continuation chain on * To determine if it's the last visual frame of its continuation chain on the line
* the line or not, we count the number of frames of the chain on the line, * or not, we count the number of frames of the chain on the line, and then reduce
* and then reduce it when we lay out a frame of the chain. If this value * it when we lay out a frame of the chain. If this value becomes 1 it means
* becomes 1 it means that it's the last visual frame of its continuation * that it's the last visual frame of its continuation chain on this line.
* chain on this line.
*/ */
nsFrameContinuationState* frameState = aContinuationStates->GetEntry(aFrame); nsFrameContinuationState* frameState = aContinuationStates->GetEntry(aFrame);
@@ -1334,18 +1334,20 @@ nsBidiPresUtils::IsFirstOrLast(nsIFrame* aFrame,
} }
frameState->mHasContOnNextLines = (frame != nullptr); frameState->mHasContOnNextLines = (frame != nullptr);
aIsFirst = !frameState->mHasContOnPrevLines; aIsLeftMost = isLTR ? !frameState->mHasContOnPrevLines
: !frameState->mHasContOnNextLines;
firstFrameState = frameState; firstFrameState = frameState;
} else { } else {
// aFrame is not the first visual frame of its continuation chain // aFrame is not the first visual frame of its continuation chain
aIsFirst = false; aIsLeftMost = false;
firstFrameState = aContinuationStates->GetEntry(frameState->mFirstVisualFrame); firstFrameState = aContinuationStates->GetEntry(frameState->mFirstVisualFrame);
} }
aIsLast = (firstFrameState->mFrameCount == 1 && aIsRightMost = (firstFrameState->mFrameCount == 1) &&
!firstFrameState->mHasContOnNextLines); (isLTR ? !firstFrameState->mHasContOnNextLines
: !firstFrameState->mHasContOnPrevLines);
if ((aIsFirst || aIsLast) && if ((aIsLeftMost || aIsRightMost) &&
(aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT)) { (aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT)) {
// For ib splits, don't treat anything except the last part as // For ib splits, don't treat anything except the last part as
// endmost or anything except the first part as startmost. // endmost or anything except the first part as startmost.
@@ -1353,11 +1355,19 @@ nsBidiPresUtils::IsFirstOrLast(nsIFrame* aFrame,
nsIFrame* firstContinuation = aFrame->FirstContinuation(); nsIFrame* firstContinuation = aFrame->FirstContinuation();
if (firstContinuation->FrameIsNonLastInIBSplit()) { if (firstContinuation->FrameIsNonLastInIBSplit()) {
// We are not endmost // We are not endmost
aIsLast = false; if (isLTR) {
aIsRightMost = false;
} else {
aIsLeftMost = false;
}
} }
if (firstContinuation->FrameIsNonFirstInIBSplit()) { if (firstContinuation->FrameIsNonFirstInIBSplit()) {
// We are not startmost // We are not startmost
aIsFirst = false; if (isLTR) {
aIsLeftMost = false;
} else {
aIsRightMost = false;
}
} }
} }
@@ -1367,38 +1377,28 @@ nsBidiPresUtils::IsFirstOrLast(nsIFrame* aFrame,
void void
nsBidiPresUtils::RepositionFrame(nsIFrame* aFrame, nsBidiPresUtils::RepositionFrame(nsIFrame* aFrame,
bool aIsEvenLevel, bool aIsOddLevel,
nscoord& aStart, nscoord& aLeft,
nsContinuationStates* aContinuationStates, nsContinuationStates* aContinuationStates)
WritingMode aLineWM,
nscoord& aLineWidth)
{ {
if (!aFrame) if (!aFrame)
return; return;
bool isFirst, isLast; bool isLeftMost, isRightMost;
IsFirstOrLast(aFrame, IsLeftOrRightMost(aFrame,
aContinuationStates, aContinuationStates,
isFirst /* out */, isLeftMost /* out */,
isLast /* out */); isRightMost /* out */);
WritingMode frameWM = aFrame->GetWritingMode();
nsInlineFrame* testFrame = do_QueryFrame(aFrame); nsInlineFrame* testFrame = do_QueryFrame(aFrame);
//XXX temporary until GetSkipSides is logicalized
bool isLeftMost = false, isRightMost = false;
if (testFrame) { if (testFrame) {
aFrame->AddStateBits(NS_INLINE_FRAME_BIDI_VISUAL_STATE_IS_SET); aFrame->AddStateBits(NS_INLINE_FRAME_BIDI_VISUAL_STATE_IS_SET);
isLeftMost = ((isFirst && frameWM.IsBidiLTR()) ||
(isLast && !frameWM.IsBidiLTR()));
if (isLeftMost) if (isLeftMost)
aFrame->AddStateBits(NS_INLINE_FRAME_BIDI_VISUAL_IS_LEFT_MOST); aFrame->AddStateBits(NS_INLINE_FRAME_BIDI_VISUAL_IS_LEFT_MOST);
else else
aFrame->RemoveStateBits(NS_INLINE_FRAME_BIDI_VISUAL_IS_LEFT_MOST); aFrame->RemoveStateBits(NS_INLINE_FRAME_BIDI_VISUAL_IS_LEFT_MOST);
isRightMost = ((isLast && frameWM.IsBidiLTR()) ||
(isFirst && !frameWM.IsBidiLTR()));
if (isRightMost) if (isRightMost)
aFrame->AddStateBits(NS_INLINE_FRAME_BIDI_VISUAL_IS_RIGHT_MOST); aFrame->AddStateBits(NS_INLINE_FRAME_BIDI_VISUAL_IS_RIGHT_MOST);
else else
@@ -1407,30 +1407,26 @@ nsBidiPresUtils::RepositionFrame(nsIFrame* aFrame,
// This method is called from nsBlockFrame::PlaceLine via the call to // This method is called from nsBlockFrame::PlaceLine via the call to
// bidiUtils->ReorderFrames, so this is guaranteed to be after the inlines // bidiUtils->ReorderFrames, so this is guaranteed to be after the inlines
// have been reflowed, which is required for GetUsedMargin/Border/Padding // have been reflowed, which is required for GetUsedMargin/Border/Padding
LogicalMargin margin(frameWM, aFrame->GetUsedMargin()); nsMargin margin = aFrame->GetUsedMargin();
if (isFirst) { if (isLeftMost)
aStart += margin.IStart(frameWM); aLeft += margin.left;
}
nscoord start = aStart; nscoord start = aLeft;
nscoord frameWidth = aFrame->GetSize().width;
if (!IsBidiLeaf(aFrame)) if (!IsBidiLeaf(aFrame))
{ {
nscoord iCoord = 0; nscoord x = 0;
LogicalMargin borderPadding(frameWM, aFrame->GetUsedBorderAndPadding()); nsMargin borderPadding = aFrame->GetUsedBorderAndPadding();
if (isFirst) { if (isLeftMost) {
iCoord += borderPadding.IStart(frameWM); x += borderPadding.left;
} }
// If the resolved direction of the container is different from the // If aIsOddLevel is true, so we need to traverse the child list
// direction of the frame, we need to traverse the child list in reverse // in reverse order, to make it O(n) we store the list locally and
// order, to make it O(n) we store the list locally and iterate the list // iterate the list reversely
// in reverse
bool reverseOrder = aIsEvenLevel != frameWM.IsBidiLTR();
nsTArray<nsIFrame*> childList; nsTArray<nsIFrame*> childList;
nsIFrame *frame = aFrame->GetFirstPrincipalChild(); nsIFrame *frame = aFrame->GetFirstPrincipalChild();
if (frame && reverseOrder) { if (frame && aIsOddLevel) {
childList.AppendElement((nsIFrame*)nullptr); childList.AppendElement((nsIFrame*)nullptr);
while (frame) { while (frame) {
childList.AppendElement(frame); childList.AppendElement(frame);
@@ -1443,33 +1439,27 @@ nsBidiPresUtils::RepositionFrame(nsIFrame* aFrame,
int32_t index = 0; int32_t index = 0;
while (frame) { while (frame) {
RepositionFrame(frame, RepositionFrame(frame,
aIsEvenLevel, aIsOddLevel,
iCoord, x,
aContinuationStates, aContinuationStates);
frameWM,
frameWidth);
index++; index++;
frame = reverseOrder ? frame = aIsOddLevel ?
childList[childList.Length() - index - 1] : childList[childList.Length() - index - 1] :
frame->GetNextSibling(); frame->GetNextSibling();
} }
if (isLast) { if (isRightMost) {
iCoord += borderPadding.IEnd(frameWM); x += borderPadding.right;
} }
aStart += iCoord; aLeft += x;
} else { } else {
aStart += frameWidth; aLeft += aFrame->GetSize().width;
} }
nsRect rect = aFrame->GetRect();
aFrame->SetRect(nsRect(start, rect.y, aLeft - start, rect.height));
LogicalRect logicalRect(aLineWM, aFrame->GetRect(), aLineWidth); if (isRightMost)
logicalRect.IStart(aLineWM) = start; aLeft += margin.right;
logicalRect.ISize(aLineWM) = aStart - start;
aFrame->SetRect(aLineWM, logicalRect, aLineWidth);
if (isLast) {
aStart += margin.IEnd(frameWM);
}
} }
void void
@@ -1494,23 +1484,21 @@ nsBidiPresUtils::InitContinuationStates(nsIFrame* aFrame,
void void
nsBidiPresUtils::RepositionInlineFrames(BidiLineData *aBld, nsBidiPresUtils::RepositionInlineFrames(BidiLineData *aBld,
nsIFrame* aFirstChild, nsIFrame* aFirstChild)
WritingMode aLineWM,
nscoord& aLineWidth)
{ {
nscoord startSpace = 0; const nsStyleVisibility* vis = aFirstChild->StyleVisibility();
bool isLTR = (NS_STYLE_DIRECTION_LTR == vis->mDirection);
nscoord leftSpace = 0;
// This method is called from nsBlockFrame::PlaceLine via the call to // This method is called from nsBlockFrame::PlaceLine via the call to
// bidiUtils->ReorderFrames, so this is guaranteed to be after the inlines // bidiUtils->ReorderFrames, so this is guaranteed to be after the inlines
// have been reflowed, which is required for GetUsedMargin/Border/Padding // have been reflowed, which is required for GetUsedMargin/Border/Padding
WritingMode frameWM = aFirstChild->GetWritingMode(); nsMargin margin = aFirstChild->GetUsedMargin();
LogicalMargin margin(frameWM, aFirstChild->GetUsedMargin());
if (!aFirstChild->GetPrevContinuation() && if (!aFirstChild->GetPrevContinuation() &&
!aFirstChild->FrameIsNonFirstInIBSplit()) !aFirstChild->FrameIsNonFirstInIBSplit())
startSpace = margin.IStart(frameWM); leftSpace = isLTR ? margin.left : margin.right;
nscoord start = LogicalRect(aLineWM, aFirstChild->GetRect(), nscoord left = aFirstChild->GetPosition().x - leftSpace;
aLineWidth).IStart(aLineWM) - startSpace;
nsIFrame* frame; nsIFrame* frame;
int32_t count = aBld->mVisualFrames.Length(); int32_t count = aBld->mVisualFrames.Length();
int32_t index; int32_t index;
@@ -1523,25 +1511,13 @@ nsBidiPresUtils::RepositionInlineFrames(BidiLineData *aBld,
} }
// Reposition frames in visual order // Reposition frames in visual order
int32_t step, limit; for (index = 0; index < count; index++) {
if (aLineWM.IsBidiLTR()) {
index = 0;
step = 1;
limit = count;
} else {
index = count - 1;
step = -1;
limit = -1;
}
for (; index != limit; index += step) {
frame = aBld->VisualFrameAt(index); frame = aBld->VisualFrameAt(index);
RepositionFrame(frame, RepositionFrame(frame,
!(aBld->mLevels[aBld->mIndexMap[index]] & 1), (aBld->mLevels[aBld->mIndexMap[index]] & 1),
start, left,
&continuationStates, &continuationStates);
aLineWM, } // for
aLineWidth);
}
} }
bool bool

View File

@@ -27,7 +27,6 @@ class nsRenderingContext;
class nsBlockInFlowLineIterator; class nsBlockInFlowLineIterator;
class nsStyleContext; class nsStyleContext;
template<class T> class nsTHashtable; template<class T> class nsTHashtable;
namespace mozilla { class WritingMode; }
/** /**
* A structure representing some continuation state for each frame on the line, * A structure representing some continuation state for each frame on the line,
@@ -160,9 +159,7 @@ public:
* @lina 05/02/2000 * @lina 05/02/2000
*/ */
static void ReorderFrames(nsIFrame* aFirstFrameOnLine, static void ReorderFrames(nsIFrame* aFirstFrameOnLine,
int32_t aNumFramesOnLine, int32_t aNumFramesOnLine);
mozilla::WritingMode aLineWM,
nscoord& aLineWidth);
/** /**
* Format Unicode text, taking into account bidi capabilities * Format Unicode text, taking into account bidi capabilities
@@ -382,25 +379,22 @@ private:
BidiParagraphData* aBpd); BidiParagraphData* aBpd);
/* /*
* Position aFrame and its descendants to their visual places. Also if aFrame * Position aFrame and it's descendants to their visual places. Also if aFrame
* is not leaf, resize it to embrace its children. * is not leaf, resize it to embrace it's children.
* *
* @param aFrame The frame which itself and its children are * @param aFrame The frame which itself and its children are going
* going to be repositioned * to be repositioned
* @param aIsEvenLevel TRUE means the embedding level of this frame * @param aIsOddLevel TRUE means the embedding level of this frame is odd
* is even (LTR) * @param[in,out] aLeft IN value is the starting position of aFrame(without
* @param[in,out] aStart IN value is the starting position of aFrame * considering its left margin)
* (without considering its inline-start margin) * OUT value will be the ending position of aFrame(after
* OUT value will be the ending position of aFrame * adding its right margin)
* (after adding its inline-end margin)
* @param aContinuationStates A map from nsIFrame* to nsFrameContinuationState * @param aContinuationStates A map from nsIFrame* to nsFrameContinuationState
*/ */
static void RepositionFrame(nsIFrame* aFrame, static void RepositionFrame(nsIFrame* aFrame,
bool aIsEvenLevel, bool aIsOddLevel,
nscoord& aStart, nscoord& aLeft,
nsContinuationStates* aContinuationStates, nsContinuationStates* aContinuationStates);
mozilla::WritingMode aLineWM,
nscoord& aLineWidth);
/* /*
* Initialize the continuation state(nsFrameContinuationState) to * Initialize the continuation state(nsFrameContinuationState) to
@@ -428,10 +422,10 @@ private:
* @param[out] aIsLeftMost TRUE means aFrame is leftmost frame or continuation * @param[out] aIsLeftMost TRUE means aFrame is leftmost frame or continuation
* @param[out] aIsRightMost TRUE means aFrame is rightmost frame or continuation * @param[out] aIsRightMost TRUE means aFrame is rightmost frame or continuation
*/ */
static void IsFirstOrLast(nsIFrame* aFrame, static void IsLeftOrRightMost(nsIFrame* aFrame,
nsContinuationStates* aContinuationStates, nsContinuationStates* aContinuationStates,
bool& aIsFirst /* out */, bool& aIsLeftMost /* out */,
bool& aIsLast /* out */); bool& aIsRightMost /* out */);
/** /**
* Adjust frame positions following their visual order * Adjust frame positions following their visual order
@@ -441,9 +435,7 @@ private:
* @lina 04/11/2000 * @lina 04/11/2000
*/ */
static void RepositionInlineFrames(BidiLineData* aBld, static void RepositionInlineFrames(BidiLineData* aBld,
nsIFrame* aFirstChild, nsIFrame* aFirstChild);
mozilla::WritingMode aLineWM,
nscoord& aLineWidth);
/** /**
* Helper method for Resolve() * Helper method for Resolve()

View File

@@ -833,12 +833,6 @@ public:
*this : LogicalMargin(aToMode, GetPhysicalMargin(aFromMode)); *this : LogicalMargin(aToMode, GetPhysicalMargin(aFromMode));
} }
bool IsEmpty() const
{
return (mMargin.left == 0 && mMargin.top == 0 &&
mMargin.right == 0 && mMargin.bottom == 0);
}
private: private:
friend class LogicalRect; friend class LogicalRect;
@@ -1129,17 +1123,6 @@ public:
return aWritingMode.IsVertical() ? mRect.XMost() : mRect.YMost(); return aWritingMode.IsVertical() ? mRect.XMost() : mRect.YMost();
} }
bool IsEmpty() const
{
return (mRect.x == 0 && mRect.y == 0 &&
mRect.width == 0 && mRect.height == 0);
}
bool IsZeroSize() const
{
return (mRect.width == 0 && mRect.height == 0);
}
/* XXX are these correct? /* XXX are these correct?
nscoord ILeft(WritingMode aWritingMode) const nscoord ILeft(WritingMode aWritingMode) const
{ {

View File

@@ -1450,7 +1450,7 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
*aBottomEdgeOfChildren = bottomEdgeOfChildren; *aBottomEdgeOfChildren = bottomEdgeOfChildren;
#ifdef DEBUG_blocks #ifdef DEBUG_blocks
if (CRAZY_SIZE(aMetrics.Width()) || CRAZY_SIZE(aMetrics.Height())) { if (CRAZY_WIDTH(aMetrics.Width()) || CRAZY_HEIGHT(aMetrics.Height())) {
ListTag(stdout); ListTag(stdout);
printf(": WARNING: desired:%d,%d\n", aMetrics.Width(), aMetrics.Height()); printf(": WARNING: desired:%d,%d\n", aMetrics.Width(), aMetrics.Height());
} }
@@ -3448,32 +3448,35 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
this, aFloatAvailableSpace.mHasFloats); this, aFloatAvailableSpace.mHasFloats);
#endif #endif
WritingMode wm = GetWritingMode(aLine->mFirstChild); nscoord x = aFloatAvailableSpace.mRect.x;
nscoord lineWidth = aFloatAvailableSpace.mRect.width + nscoord availWidth = aFloatAvailableSpace.mRect.width;
aState.BorderPadding().LeftRight(); nscoord availHeight;
LogicalRect lineRect(wm, aFloatAvailableSpace.mRect, lineWidth);
nscoord iStart = lineRect.IStart(wm);
nscoord availISize = lineRect.ISize(wm);
nscoord availBSize;
if (aState.GetFlag(BRS_UNCONSTRAINEDHEIGHT)) { if (aState.GetFlag(BRS_UNCONSTRAINEDHEIGHT)) {
availBSize = NS_UNCONSTRAINEDSIZE; availHeight = NS_UNCONSTRAINEDSIZE;
} }
else { else {
/* XXX get the height right! */ /* XXX get the height right! */
availBSize = lineRect.BSize(wm); availHeight = aFloatAvailableSpace.mRect.height;
} }
// Make sure to enable resize optimization before we call BeginLineReflow // Make sure to enable resize optimization before we call BeginLineReflow
// because it might get disabled there // because it might get disabled there
aLine->EnableResizeReflowOptimization(); aLine->EnableResizeReflowOptimization();
aLineLayout.BeginLineReflow(iStart, aState.mY, // For unicode-bidi: plaintext, we need to get the direction of the line from
availISize, availBSize, // the resolved paragraph level of the first frame on the line, not the block
// frame, because the block frame could be split by hard line breaks into
// multiple paragraphs with different base direction
uint8_t direction =
(StyleTextReset()->mUnicodeBidi & NS_STYLE_UNICODE_BIDI_PLAINTEXT) ?
nsBidiPresUtils::GetFrameBaseLevel(aLine->mFirstChild) & 1 :
StyleVisibility()->mDirection;
aLineLayout.BeginLineReflow(x, aState.mY,
availWidth, availHeight,
aFloatAvailableSpace.mHasFloats, aFloatAvailableSpace.mHasFloats,
false, /*XXX isTopOfPage*/ false, /*XXX isTopOfPage*/
wm, lineWidth); direction);
aState.SetFlag(BRS_LINE_LAYOUT_EMPTY, false); aState.SetFlag(BRS_LINE_LAYOUT_EMPTY, false);
@@ -4049,7 +4052,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
bool addedBullet = false; bool addedBullet = false;
if (HasOutsideBullet() && if (HasOutsideBullet() &&
((aLine == mLines.front() && ((aLine == mLines.front() &&
(!aLineLayout.IsZeroBSize() || (aLine == mLines.back()))) || (!aLineLayout.IsZeroHeight() || (aLine == mLines.back()))) ||
(mLines.front() != mLines.back() && (mLines.front() != mLines.back() &&
0 == mLines.front()->mBounds.height && 0 == mLines.front()->mBounds.height &&
aLine == mLines.begin().next()))) { aLine == mLines.begin().next()))) {
@@ -4061,7 +4064,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
aLineLayout.AddBulletFrame(bullet, metrics); aLineLayout.AddBulletFrame(bullet, metrics);
addedBullet = true; addedBullet = true;
} }
aLineLayout.BlockDirAlignLine(); aLineLayout.VerticalAlignLine();
// We want to compare to the available space that we would have had in // We want to compare to the available space that we would have had in
// the line's height *before* we placed any floats in the line itself. // the line's height *before* we placed any floats in the line itself.
@@ -4089,9 +4092,9 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
#ifdef DEBUG #ifdef DEBUG
{ {
static nscoord lastHeight = 0; static nscoord lastHeight = 0;
if (CRAZY_SIZE(aLine->mBounds.y)) { if (CRAZY_HEIGHT(aLine->mBounds.y)) {
lastHeight = aLine->mBounds.y; lastHeight = aLine->mBounds.y;
if (abs(aLine->mBounds.y - lastHeight) > CRAZY_COORD/10) { if (abs(aLine->mBounds.y - lastHeight) > CRAZY_H/10) {
nsFrame::ListTag(stdout); nsFrame::ListTag(stdout);
printf(": line=%p y=%d line.bounds.height=%d\n", printf(": line=%p y=%d line.bounds.height=%d\n",
static_cast<void*>(aLine.get()), static_cast<void*>(aLine.get()),
@@ -4122,9 +4125,20 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
NS_STYLE_TEXT_ALIGN_JUSTIFY == styleText->mTextAlign) && NS_STYLE_TEXT_ALIGN_JUSTIFY == styleText->mTextAlign) &&
(aLineLayout.GetLineEndsInBR() || (aLineLayout.GetLineEndsInBR() ||
IsLastLine(aState, aLine))); IsLastLine(aState, aLine)));
aLineLayout.HorizontalAlignFrames(aLine->mBounds, isLastLine);
aLineLayout.InlineDirAlignFrames(aLine->mBounds, isLastLine, // XXX: not only bidi: right alignment can be broken after
aLine->GetChildCount()); // RelativePositionFrames!!!
// XXXldb Is something here considering relatively positioned frames at
// other than their original positions?
#ifdef IBMBIDI
// XXXldb Why don't we do this earlier?
if (aState.mPresContext->BidiEnabled()) {
if (!aState.mPresContext->IsVisualMode() ||
StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) {
nsBidiPresUtils::ReorderFrames(aLine->mFirstChild, aLine->GetChildCount());
} // not visual mode
} // bidi enabled
#endif // IBMBIDI
// From here on, pfd->mBounds rectangles are incorrect because bidi // From here on, pfd->mBounds rectangles are incorrect because bidi
// might have moved frames around! // might have moved frames around!

View File

@@ -262,7 +262,7 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
#ifdef DEBUG #ifdef DEBUG
if (!NS_INLINE_IS_BREAK_BEFORE(aFrameReflowStatus)) { if (!NS_INLINE_IS_BREAK_BEFORE(aFrameReflowStatus)) {
if (CRAZY_SIZE(mMetrics.Width()) || CRAZY_SIZE(mMetrics.Height())) { if (CRAZY_WIDTH(mMetrics.Width()) || CRAZY_HEIGHT(mMetrics.Height())) {
printf("nsBlockReflowContext: "); printf("nsBlockReflowContext: ");
nsFrame::ListTag(stdout, mFrame); nsFrame::ListTag(stdout, mFrame);
printf(" metrics=%d,%d!\n", mMetrics.Width(), mMetrics.Height()); printf(" metrics=%d,%d!\n", mMetrics.Width(), mMetrics.Height());

View File

@@ -34,8 +34,11 @@ class FramePropertyTable;
// dependency on nsDeviceContext.h. It doesn't matter if it's a // dependency on nsDeviceContext.h. It doesn't matter if it's a
// little off. // little off.
#ifdef DEBUG #ifdef DEBUG
#define CRAZY_COORD (1000000*60) #define CRAZY_W (1000000*60)
#define CRAZY_SIZE(_x) (((_x) < -CRAZY_COORD) || ((_x) > CRAZY_COORD)) #define CRAZY_H CRAZY_W
#define CRAZY_WIDTH(_x) (((_x) < -CRAZY_W) || ((_x) > CRAZY_W))
#define CRAZY_HEIGHT(_y) (((_y) < -CRAZY_H) || ((_y) > CRAZY_H))
#endif #endif
/** /**

View File

@@ -188,10 +188,21 @@ nsFirstLetterFrame::Reflow(nsPresContext* aPresContext,
nsHTMLReflowState rs(aPresContext, aReflowState, kid, availSize); nsHTMLReflowState rs(aPresContext, aReflowState, kid, availSize);
nsLineLayout ll(aPresContext, nullptr, &aReflowState, nullptr); nsLineLayout ll(aPresContext, nullptr, &aReflowState, nullptr);
// For unicode-bidi: plaintext, we need to get the direction of the line
// from the resolved paragraph level of the child, not the block frame,
// because the block frame could be split by hard line breaks into
// multiple paragraphs with different base direction
uint8_t direction;
nsIFrame* containerFrame = ll.LineContainerFrame();
if (containerFrame->StyleTextReset()->mUnicodeBidi &
NS_STYLE_UNICODE_BIDI_PLAINTEXT) {
FramePropertyTable *propTable = aPresContext->PropertyTable();
direction = NS_PTR_TO_INT32(propTable->Get(kid, BaseLevelProperty())) & 1;
} else {
direction = containerFrame->StyleVisibility()->mDirection;
}
ll.BeginLineReflow(bp.left, bp.top, availSize.width, NS_UNCONSTRAINEDSIZE, ll.BeginLineReflow(bp.left, bp.top, availSize.width, NS_UNCONSTRAINEDSIZE,
false, true, false, true, direction);
ll.LineContainerFrame()->GetWritingMode(kid),
aReflowState.AvailableWidth());
rs.mLineLayout = &ll; rs.mLineLayout = &ll;
ll.SetInFirstLetter(true); ll.SetInFirstLetter(true);
ll.SetFirstLetterStyleOK(true); ll.SetFirstLetterStyleOK(true);

View File

@@ -975,20 +975,6 @@ nsIFrame::GetPaddingRect() const
return GetPaddingRectRelativeToSelf() + GetPosition(); return GetPaddingRectRelativeToSelf() + GetPosition();
} }
WritingMode
nsIFrame::GetWritingMode(nsIFrame* aSubFrame) const
{
WritingMode writingMode = GetWritingMode();
if (!writingMode.IsVertical() &&
(StyleTextReset()->mUnicodeBidi & NS_STYLE_UNICODE_BIDI_PLAINTEXT)) {
nsBidiLevel frameLevel = nsBidiPresUtils::GetFrameBaseLevel(aSubFrame);
writingMode.SetDirectionFromBidiLevel(frameLevel);
}
return writingMode;
}
nsRect nsRect
nsIFrame::GetMarginRectRelativeToSelf() const nsIFrame::GetMarginRectRelativeToSelf() const
{ {

View File

@@ -672,15 +672,6 @@ public:
return mozilla::WritingMode(StyleVisibility()); return mozilla::WritingMode(StyleVisibility());
} }
/**
* Get the writing mode of this frame, but if it is styled with
* unicode-bidi: plaintext, reset the direction to the resolved paragraph
* level of the given subframe (typically the first frame on the line),
* not this frame's writing mode, because the container frame could be split
* by hard line breaks into multiple paragraphs with different base direction.
*/
mozilla::WritingMode GetWritingMode(nsIFrame* aSubFrame) const;
/** /**
* Bounding rect of the frame. The values are in app units, and the origin is * Bounding rect of the frame. The values are in app units, and the origin is
* relative to the upper-left of the geometric parent. The size includes the * relative to the upper-left of the geometric parent. The size includes the

View File

@@ -487,21 +487,23 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
nsLineLayout* lineLayout = aReflowState.mLineLayout; nsLineLayout* lineLayout = aReflowState.mLineLayout;
bool inFirstLine = aReflowState.mLineLayout->GetInFirstLine(); bool inFirstLine = aReflowState.mLineLayout->GetInFirstLine();
RestyleManager* restyleManager = aPresContext->RestyleManager(); RestyleManager* restyleManager = aPresContext->RestyleManager();
WritingMode wm = aReflowState.GetWritingMode(); bool ltr = (NS_STYLE_DIRECTION_LTR == aReflowState.mStyleVisibility->mDirection);
nscoord startEdge = 0; nscoord leftEdge = 0;
// Don't offset by our start borderpadding if we have a prev continuation or // Don't offset by our start borderpadding if we have a prev continuation or
// if we're in a part of an {ib} split other than the first one. // if we're in a part of an {ib} split other than the first one.
if (!GetPrevContinuation() && !FrameIsNonFirstInIBSplit()) { if (!GetPrevContinuation() && !FrameIsNonFirstInIBSplit()) {
startEdge = aReflowState.ComputedLogicalBorderPadding().IStart(wm); leftEdge = ltr ? aReflowState.ComputedPhysicalBorderPadding().left
: aReflowState.ComputedPhysicalBorderPadding().right;
} }
nscoord availableISize = aReflowState.AvailableISize(); nscoord availableWidth = aReflowState.AvailableWidth();
NS_ASSERTION(availableISize != NS_UNCONSTRAINEDSIZE, NS_ASSERTION(availableWidth != NS_UNCONSTRAINEDSIZE,
"should no longer use available widths"); "should no longer use available widths");
// Subtract off inline axis border+padding from availableISize // Subtract off left and right border+padding from availableWidth
availableISize -= startEdge; availableWidth -= leftEdge;
availableISize -= aReflowState.ComputedLogicalBorderPadding().IEnd(wm); availableWidth -= ltr ? aReflowState.ComputedPhysicalBorderPadding().right
lineLayout->BeginSpan(this, &aReflowState, startEdge, : aReflowState.ComputedPhysicalBorderPadding().left;
startEdge + availableISize, &mBaseline); lineLayout->BeginSpan(this, &aReflowState, leftEdge,
leftEdge + availableWidth, &mBaseline);
// First reflow our principal children. // First reflow our principal children.
nsIFrame* frame = mFrames.FirstChild(); nsIFrame* frame = mFrames.FirstChild();
@@ -644,7 +646,7 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
// line-height calculations. However, continuations of an inline // line-height calculations. However, continuations of an inline
// that are empty we force to empty so that things like collapsed // that are empty we force to empty so that things like collapsed
// whitespace in an inline element don't affect the line-height. // whitespace in an inline element don't affect the line-height.
aMetrics.ISize() = lineLayout->EndSpan(this); aMetrics.Width() = lineLayout->EndSpan(this);
// Compute final width. // Compute final width.
@@ -652,7 +654,8 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
// continuation or if we're in a part of an {ib} split other than the first // continuation or if we're in a part of an {ib} split other than the first
// one. // one.
if (!GetPrevContinuation() && !FrameIsNonFirstInIBSplit()) { if (!GetPrevContinuation() && !FrameIsNonFirstInIBSplit()) {
aMetrics.ISize() += aReflowState.ComputedLogicalBorderPadding().IStart(wm); aMetrics.Width() += ltr ? aReflowState.ComputedPhysicalBorderPadding().left
: aReflowState.ComputedPhysicalBorderPadding().right;
} }
/* /*
@@ -665,7 +668,8 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
if (NS_FRAME_IS_COMPLETE(aStatus) && if (NS_FRAME_IS_COMPLETE(aStatus) &&
!LastInFlow()->GetNextContinuation() && !LastInFlow()->GetNextContinuation() &&
!FrameIsNonLastInIBSplit()) { !FrameIsNonLastInIBSplit()) {
aMetrics.Width() += aReflowState.ComputedLogicalBorderPadding().IEnd(wm); aMetrics.Width() += ltr ? aReflowState.ComputedPhysicalBorderPadding().right
: aReflowState.ComputedPhysicalBorderPadding().left;
} }
nsRefPtr<nsFontMetrics> fm; nsRefPtr<nsFontMetrics> fm;

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,6 @@
#include "nsBlockReflowState.h" #include "nsBlockReflowState.h"
#include "plarena.h" #include "plarena.h"
#include "gfxTypes.h" #include "gfxTypes.h"
#include "WritingModes.h"
class nsFloatManager; class nsFloatManager;
struct nsStyleText; struct nsStyleText;
@@ -34,10 +33,10 @@ public:
const nsLineList::iterator* aLine); const nsLineList::iterator* aLine);
~nsLineLayout(); ~nsLineLayout();
void Init(nsBlockReflowState* aState, nscoord aMinLineBSize, void Init(nsBlockReflowState* aState, nscoord aMinLineHeight,
int32_t aLineNumber) { int32_t aLineNumber) {
mBlockRS = aState; mBlockRS = aState;
mMinLineBSize = aMinLineBSize; mMinLineHeight = aMinLineHeight;
mLineNumber = aLineNumber; mLineNumber = aLineNumber;
} }
@@ -45,12 +44,11 @@ public:
return mLineNumber; return mLineNumber;
} }
void BeginLineReflow(nscoord aICoord, nscoord aBCoord, void BeginLineReflow(nscoord aX, nscoord aY,
nscoord aISize, nscoord aBSize, nscoord aWidth, nscoord aHeight,
bool aImpactedByFloats, bool aImpactedByFloats,
bool aIsTopOfPage, bool aIsTopOfPage,
mozilla::WritingMode aWritingMode, uint8_t aDirection);
nscoord aContainerWidth);
void EndLineReflow(); void EndLineReflow();
@@ -75,7 +73,7 @@ public:
void SplitLineTo(int32_t aNewCount); void SplitLineTo(int32_t aNewCount);
bool IsZeroBSize(); bool IsZeroHeight();
// Reflows the frame and returns the reflow status. aPushedFrame is true // Reflows the frame and returns the reflow status. aPushedFrame is true
// if the frame is pushed to the next line because it doesn't fit // if the frame is pushed to the next line because it doesn't fit
@@ -90,12 +88,11 @@ public:
PushFrame(aFrame); PushFrame(aFrame);
} }
void BlockDirAlignLine(); void VerticalAlignLine();
bool TrimTrailingWhiteSpace(); bool TrimTrailingWhiteSpace();
void InlineDirAlignFrames(nsRect& aLineBounds, bool aIsLastLine, void HorizontalAlignFrames(nsRect& aLineBounds, bool aIsLastLine);
int32_t aFrameCount);
/** /**
* Handle all the relative positioning in the line, compute the * Handle all the relative positioning in the line, compute the
@@ -306,10 +303,10 @@ public:
* the right edge for RTL blocks and from the left edge for LTR blocks. * the right edge for RTL blocks and from the left edge for LTR blocks.
* In other words, the current frame's distance from the line container's * In other words, the current frame's distance from the line container's
* start content edge is: * start content edge is:
* <code>GetCurrentFrameInlineDistanceFromBlock() - lineContainer->GetUsedBorderAndPadding().left</code> * <code>GetCurrentFrameXDistanceFromBlock() - lineContainer->GetUsedBorderAndPadding().left</code>
* Note the use of <code>.left</code> for both LTR and RTL line containers. * Note the use of <code>.left</code> for both LTR and RTL line containers.
*/ */
nscoord GetCurrentFrameInlineDistanceFromBlock(); nscoord GetCurrentFrameXDistanceFromBlock();
protected: protected:
// This state is constant for a given block frame doing line layout // This state is constant for a given block frame doing line layout
@@ -329,22 +326,14 @@ protected:
// Per-frame data recorded by the line-layout reflow logic. This // Per-frame data recorded by the line-layout reflow logic. This
// state is the state needed to post-process the line after reflow // state is the state needed to post-process the line after reflow
// has completed (block-direction alignment, inline-direction alignment, // has completed (vertical alignment, horizontal alignment,
// justification and relative positioning). // justification and relative positioning).
struct PerSpanData; struct PerSpanData;
struct PerFrameData; struct PerFrameData;
friend struct PerSpanData; friend struct PerSpanData;
friend struct PerFrameData; friend struct PerFrameData;
struct PerFrameData struct PerFrameData {
{
PerFrameData(mozilla::WritingMode aWritingMode)
: mBounds(aWritingMode)
, mMargin(aWritingMode)
, mBorderPadding(aWritingMode)
, mOffsets(aWritingMode)
{}
// link to next/prev frame in same span // link to next/prev frame in same span
PerFrameData* mNext; PerFrameData* mNext;
PerFrameData* mPrev; PerFrameData* mPrev;
@@ -357,23 +346,20 @@ protected:
// From metrics // From metrics
nscoord mAscent; nscoord mAscent;
// note that mBounds is a logical rect in the *line*'s writing mode. nsRect mBounds;
// When setting frame coordinates, we have to convert to the frame's
// writing mode
mozilla::LogicalRect mBounds;
nsOverflowAreas mOverflowAreas; nsOverflowAreas mOverflowAreas;
// From reflow-state // From reflow-state
mozilla::LogicalMargin mMargin; nsMargin mMargin;
mozilla::LogicalMargin mBorderPadding; nsMargin mBorderPadding;
mozilla::LogicalMargin mOffsets; nsMargin mOffsets;
// state for text justification // state for text justification
int32_t mJustificationNumSpaces; int32_t mJustificationNumSpaces;
int32_t mJustificationNumLetters; int32_t mJustificationNumLetters;
// Other state we use // Other state we use
uint8_t mBlockDirAlign; uint8_t mVerticalAlign;
// PerFrameData flags // PerFrameData flags
#define PFD_RELATIVEPOS 0x00000001 #define PFD_RELATIVEPOS 0x00000001
@@ -428,18 +414,19 @@ protected:
const nsHTMLReflowState* mReflowState; const nsHTMLReflowState* mReflowState;
bool mNoWrap; bool mNoWrap;
mozilla::WritingMode mWritingMode; uint8_t mDirection;
bool mChangedFrameDirection;
bool mZeroEffectiveSpanBox; bool mZeroEffectiveSpanBox;
bool mContainsFloat; bool mContainsFloat;
bool mHasNonemptyContent; bool mHasNonemptyContent;
nscoord mIStart; nscoord mLeftEdge;
nscoord mICoord; nscoord mX;
nscoord mIEnd; nscoord mRightEdge;
nscoord mBStartLeading, mBEndLeading; nscoord mTopLeading, mBottomLeading;
nscoord mLogicalBSize; nscoord mLogicalHeight;
nscoord mMinBCoord, mMaxBCoord; nscoord mMinY, mMaxY;
nscoord* mBaseline; nscoord* mBaseline;
void AppendFrame(PerFrameData* pfd) { void AppendFrame(PerFrameData* pfd) {
@@ -461,7 +448,7 @@ protected:
int32_t mLastOptionalBreakContentOffset; int32_t mLastOptionalBreakContentOffset;
int32_t mForceBreakContentOffset; int32_t mForceBreakContentOffset;
nscoord mMinLineBSize; nscoord mMinLineHeight;
// The amount of text indent that we applied to this line, needed for // The amount of text indent that we applied to this line, needed for
// max-element-size calculation. // max-element-size calculation.
@@ -475,21 +462,19 @@ protected:
int32_t mTotalPlacedFrames; int32_t mTotalPlacedFrames;
nscoord mBStartEdge; nscoord mTopEdge;
nscoord mMaxStartBoxBSize; nscoord mMaxTopBoxHeight;
nscoord mMaxEndBoxBSize; nscoord mMaxBottomBoxHeight;
nscoord mInflationMinFontSize; nscoord mInflationMinFontSize;
// Final computed line-bSize value after BlockDirAlignFrames for // Final computed line-height value after VerticalAlignFrames for
// the block has been called. // the block has been called.
nscoord mFinalLineBSize; nscoord mFinalLineHeight;
// Amount of trimmable whitespace width for the trailing text frame, if any // Amount of trimmable whitespace width for the trailing text frame, if any
nscoord mTrimmableWidth; nscoord mTrimmableWidth;
nscoord mContainerWidth;
bool mFirstLetterStyleOK : 1; bool mFirstLetterStyleOK : 1;
bool mIsTopOfPage : 1; bool mIsTopOfPage : 1;
bool mImpactedByFloats : 1; bool mImpactedByFloats : 1;
@@ -514,7 +499,7 @@ protected:
/** /**
* Allocate a PerFrameData from the mArena pool. The allocation is infallible. * Allocate a PerFrameData from the mArena pool. The allocation is infallible.
*/ */
PerFrameData* NewPerFrameData(nsIFrame* aFrame); PerFrameData* NewPerFrameData();
/** /**
* Allocate a PerSpanData from the mArena pool. The allocation is infallible. * Allocate a PerSpanData from the mArena pool. The allocation is infallible.
@@ -533,6 +518,7 @@ protected:
nsHTMLReflowState& aReflowState); nsHTMLReflowState& aReflowState);
bool CanPlaceFrame(PerFrameData* pfd, bool CanPlaceFrame(PerFrameData* pfd,
uint8_t aFrameDirection,
bool aNotSafeToBreak, bool aNotSafeToBreak,
bool aFrameCanContinueTextRun, bool aFrameCanContinueTextRun,
bool aCanRollBackBeforeFrame, bool aCanRollBackBeforeFrame,
@@ -543,15 +529,15 @@ protected:
void PlaceFrame(PerFrameData* pfd, void PlaceFrame(PerFrameData* pfd,
nsHTMLReflowMetrics& aMetrics); nsHTMLReflowMetrics& aMetrics);
void BlockDirAlignFrames(PerSpanData* psd); void VerticalAlignFrames(PerSpanData* psd);
void PlaceStartEndFrames(PerSpanData* psd, void PlaceTopBottomFrames(PerSpanData* psd,
nscoord aDistanceFromStart, nscoord aDistanceFromTop,
nscoord aLineBSize); nscoord aLineHeight);
void RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas); void RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas);
bool TrimTrailingWhiteSpaceIn(PerSpanData* psd, nscoord* aDeltaISize); bool TrimTrailingWhiteSpaceIn(PerSpanData* psd, nscoord* aDeltaWidth);
void ComputeJustificationWeights(PerSpanData* psd, int32_t* numSpaces, int32_t* numLetters); void ComputeJustificationWeights(PerSpanData* psd, int32_t* numSpaces, int32_t* numLetters);

View File

@@ -7841,7 +7841,7 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
iter.SetOriginalOffset(offset); iter.SetOriginalOffset(offset);
nscoord xOffsetForTabs = (mTextRun->GetFlags() & nsTextFrameUtils::TEXT_HAS_TAB) ? nscoord xOffsetForTabs = (mTextRun->GetFlags() & nsTextFrameUtils::TEXT_HAS_TAB) ?
(aLineLayout.GetCurrentFrameInlineDistanceFromBlock() - (aLineLayout.GetCurrentFrameXDistanceFromBlock() -
lineContainer->GetUsedBorderAndPadding().left) lineContainer->GetUsedBorderAndPadding().left)
: -1; : -1;
PropertyProvider provider(mTextRun, textStyle, frag, this, iter, length, PropertyProvider provider(mTextRun, textStyle, frag, this, iter, length,