зеркало из https://github.com/mozilla/gecko-dev.git
Make nsLineBox.mBounds a LogicalRect. Bug 789096, r=jfkthame
This commit is contained in:
Родитель
83c84303ea
Коммит
f8a68ec80e
|
@ -4466,11 +4466,11 @@ nsLayoutUtils::GetFirstLinePosition(const nsIFrame* aFrame,
|
|||
} else {
|
||||
// XXX Is this the right test? We have some bogus empty lines
|
||||
// floating around, but IsEmpty is perhaps too weak.
|
||||
if (line->GetHeight() != 0 || !line->IsEmpty()) {
|
||||
nscoord top = line->mBounds.y;
|
||||
if (line->BSize() != 0 || !line->IsEmpty()) {
|
||||
nscoord top = line->BStart();
|
||||
aResult->mTop = top;
|
||||
aResult->mBaseline = top + line->GetAscent();
|
||||
aResult->mBottom = top + line->GetHeight();
|
||||
aResult->mBottom = top + line->BSize();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -4505,8 +4505,8 @@ nsLayoutUtils::GetLastLineBaseline(const nsIFrame* aFrame, nscoord* aResult)
|
|||
} else {
|
||||
// XXX Is this the right test? We have some bogus empty lines
|
||||
// floating around, but IsEmpty is perhaps too weak.
|
||||
if (line->GetHeight() != 0 || !line->IsEmpty()) {
|
||||
*aResult = line->mBounds.y + line->GetAscent();
|
||||
if (line->BSize() != 0 || !line->IsEmpty()) {
|
||||
*aResult = line->BStart() + line->GetAscent();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -4531,7 +4531,7 @@ CalculateBlockContentBottom(nsBlockFrame* aFrame)
|
|||
nsLayoutUtils::CalculateContentBottom(child) + offset);
|
||||
}
|
||||
else {
|
||||
contentBottom = std::max(contentBottom, line->mBounds.YMost());
|
||||
contentBottom = std::max(contentBottom, line->BEnd());
|
||||
}
|
||||
}
|
||||
return contentBottom;
|
||||
|
|
|
@ -715,8 +715,8 @@ TextOverflow::CreateMarkers(const nsLineBox* aLine,
|
|||
DisplayListClipState::AutoSaveRestore clipState(mBuilder);
|
||||
|
||||
nsRect markerRect = nsRect(aInsideMarkersArea.x - mLeft.mIntrinsicWidth,
|
||||
aLine->mBounds.y,
|
||||
mLeft.mIntrinsicWidth, aLine->mBounds.height);
|
||||
aLine->BStart(),
|
||||
mLeft.mIntrinsicWidth, aLine->BSize());
|
||||
markerRect += mBuilder->ToReferenceFrame(mBlock);
|
||||
ClipMarker(mContentArea + mBuilder->ToReferenceFrame(mBlock),
|
||||
markerRect, clipState);
|
||||
|
@ -730,8 +730,8 @@ TextOverflow::CreateMarkers(const nsLineBox* aLine,
|
|||
DisplayListClipState::AutoSaveRestore clipState(mBuilder);
|
||||
|
||||
nsRect markerRect = nsRect(aInsideMarkersArea.XMost(),
|
||||
aLine->mBounds.y,
|
||||
mRight.mIntrinsicWidth, aLine->mBounds.height);
|
||||
aLine->BStart(),
|
||||
mRight.mIntrinsicWidth, aLine->BSize());
|
||||
markerRect += mBuilder->ToReferenceFrame(mBlock);
|
||||
ClipMarker(mContentArea + mBuilder->ToReferenceFrame(mBlock),
|
||||
markerRect, clipState);
|
||||
|
|
|
@ -1130,7 +1130,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
|
|||
// the second case can happen.
|
||||
if (HasOutsideBullet() && !mLines.empty() &&
|
||||
(mLines.front()->IsBlock() ||
|
||||
(0 == mLines.front()->mBounds.height &&
|
||||
(0 == mLines.front()->BSize() &&
|
||||
mLines.front() != mLines.back() &&
|
||||
mLines.begin().next()->IsBlock()))) {
|
||||
// Reflow the bullet
|
||||
|
@ -1313,7 +1313,7 @@ nsBlockFrame::CheckForCollapsedBottomMarginFromClearanceLine()
|
|||
return false;
|
||||
}
|
||||
--line;
|
||||
if (line->mBounds.height != 0 || !line->CachedIsEmpty()) {
|
||||
if (line->BSize() != 0 || !line->CachedIsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (line->HasClearance()) {
|
||||
|
@ -1536,7 +1536,7 @@ nsBlockFrame::UpdateOverflow()
|
|||
for (line_iterator line = begin_lines(), line_end = end_lines();
|
||||
line != line_end;
|
||||
++line) {
|
||||
nsRect bounds = line->mBounds;
|
||||
nsRect bounds = line->GetPhysicalBounds();
|
||||
nsOverflowAreas lineAreas(bounds, bounds);
|
||||
|
||||
int32_t n = line->GetChildCount();
|
||||
|
@ -1649,17 +1649,8 @@ IsAlignedLeft(uint8_t aAlignment,
|
|||
void
|
||||
nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
|
||||
{
|
||||
const nsStyleText* styleText = StyleText();
|
||||
const nsStyleTextReset* styleTextReset = StyleTextReset();
|
||||
// See if we can try and avoid marking all the lines as dirty
|
||||
bool tryAndSkipLines =
|
||||
// The block must be LTR (bug 806284)
|
||||
StyleVisibility()->mDirection == NS_STYLE_DIRECTION_LTR &&
|
||||
// The text must be left-aligned.
|
||||
IsAlignedLeft(styleText->mTextAlign,
|
||||
aState.mReflowState.mStyleVisibility->mDirection,
|
||||
styleTextReset->mUnicodeBidi,
|
||||
this) &&
|
||||
// The left content-edge must be a constant distance from the left
|
||||
// border-edge.
|
||||
!StylePadding()->mPadding.GetLeft().HasPercent();
|
||||
|
@ -1672,9 +1663,8 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
|
|||
if (!tryAndSkipLines) {
|
||||
IndentBy(stdout, gNoiseIndent);
|
||||
ListTag(stdout);
|
||||
printf(": marking all lines dirty: availWidth=%d textAlign=%d\n",
|
||||
aState.mReflowState.AvailableWidth(),
|
||||
styleText->mTextAlign);
|
||||
printf(": marking all lines dirty: availWidth=%d\n",
|
||||
aState.mReflowState.AvailableWidth());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1694,13 +1684,6 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
|
|||
}
|
||||
#endif
|
||||
|
||||
// The last line might not be aligned left even if the rest of the block is
|
||||
bool skipLastLine = NS_STYLE_TEXT_ALIGN_AUTO == styleText->mTextAlignLast ||
|
||||
IsAlignedLeft(styleText->mTextAlignLast,
|
||||
aState.mReflowState.mStyleVisibility->mDirection,
|
||||
styleTextReset->mUnicodeBidi,
|
||||
this);
|
||||
|
||||
for (line_iterator line = begin_lines(), line_end = end_lines();
|
||||
line != line_end;
|
||||
++line)
|
||||
|
@ -1711,10 +1694,10 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
|
|||
if (line->IsBlock() ||
|
||||
line->HasFloats() ||
|
||||
(!isLastLine && !line->HasBreakAfter()) ||
|
||||
((isLastLine || !line->IsLineWrapped()) && !skipLastLine) ||
|
||||
((isLastLine || !line->IsLineWrapped())) ||
|
||||
line->ResizeReflowOptimizationDisabled() ||
|
||||
line->IsImpactedByFloat() ||
|
||||
(line->mBounds.XMost() > newAvailWidth)) {
|
||||
(line->IEnd() > newAvailWidth)) {
|
||||
line->MarkDirty();
|
||||
}
|
||||
|
||||
|
@ -1727,16 +1710,15 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
|
|||
#ifdef DEBUG
|
||||
if (gNoisyReflow && !line->IsDirty()) {
|
||||
IndentBy(stdout, gNoiseIndent + 1);
|
||||
printf("skipped: line=%p next=%p %s %s%s%s%s breakTypeBefore/After=%d/%d xmost=%d\n",
|
||||
printf("skipped: line=%p next=%p %s %s%s%s breakTypeBefore/After=%d/%d xmost=%d\n",
|
||||
static_cast<void*>(line.get()),
|
||||
static_cast<void*>((line.next() != end_lines() ? line.next().get() : nullptr)),
|
||||
line->IsBlock() ? "block" : "inline",
|
||||
line->HasBreakAfter() ? "has-break-after " : "",
|
||||
line->HasFloats() ? "has-floats " : "",
|
||||
line->IsImpactedByFloat() ? "impacted " : "",
|
||||
skipLastLine ? "last-line-left-aligned " : "",
|
||||
line->GetBreakTypeBefore(), line->GetBreakTypeAfter(),
|
||||
line->mBounds.XMost());
|
||||
line->IEnd());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1784,8 +1766,8 @@ nsBlockFrame::PropagateFloatDamage(nsBlockReflowState& aState,
|
|||
if (floatManager->HasFloatDamage()) {
|
||||
// Need to check mBounds *and* mCombinedArea to find intersections
|
||||
// with aLine's floats
|
||||
nscoord lineYA = aLine->mBounds.y + aDeltaY;
|
||||
nscoord lineYB = lineYA + aLine->mBounds.height;
|
||||
nscoord lineYA = aLine->BStart() + aDeltaY;
|
||||
nscoord lineYB = lineYA + aLine->BSize();
|
||||
// Scrollable overflow should be sufficient for things that affect
|
||||
// layout.
|
||||
nsRect overflow = aLine->GetOverflowArea(eScrollableOverflow);
|
||||
|
@ -1809,8 +1791,8 @@ nsBlockFrame::PropagateFloatDamage(nsBlockReflowState& aState,
|
|||
} else {
|
||||
bool wasImpactedByFloat = aLine->IsImpactedByFloat();
|
||||
nsFlowAreaRect floatAvailableSpace =
|
||||
aState.GetFloatAvailableSpaceForHeight(aLine->mBounds.y + aDeltaY,
|
||||
aLine->mBounds.height,
|
||||
aState.GetFloatAvailableSpaceForHeight(aLine->BStart() + aDeltaY,
|
||||
aLine->BSize(),
|
||||
nullptr);
|
||||
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
|
@ -1865,8 +1847,8 @@ static void DumpLine(const nsBlockReflowState& aState, nsLineBox* aLine,
|
|||
printf("line=%p mY=%d dirty=%s oldBounds={%d,%d,%d,%d} oldoverflow-vis={%d,%d,%d,%d} oldoverflow-scr={%d,%d,%d,%d} deltaY=%d mPrevBottomMargin=%d childCount=%d\n",
|
||||
static_cast<void*>(aLine), aState.mY,
|
||||
aLine->IsDirty() ? "yes" : "no",
|
||||
aLine->mBounds.x, aLine->mBounds.y,
|
||||
aLine->mBounds.width, aLine->mBounds.height,
|
||||
aLine->IStart(), aLine->BStart(),
|
||||
aLine->ISize(), aLine->BSize(),
|
||||
ovis.x, ovis.y, ovis.width, ovis.height,
|
||||
oscr.x, oscr.y, oscr.width, oscr.height,
|
||||
aDeltaY, aState.mPrevBottomMargin.get(), aLine->GetChildCount());
|
||||
|
@ -1973,7 +1955,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
// top border-edge of the block frame. If sliding the
|
||||
// block by deltaY isn't going to put it in the predicted
|
||||
// position, then we'd better reflow the line.
|
||||
|| newY != line->mBounds.y + deltaY) {
|
||||
|| newY != line->BStart() + deltaY) {
|
||||
line->MarkDirty();
|
||||
}
|
||||
} else {
|
||||
|
@ -1987,7 +1969,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
// We might have to reflow a line that is after a clearing BR.
|
||||
if (inlineFloatBreakType != NS_STYLE_CLEAR_NONE) {
|
||||
aState.mY = aState.ClearFloats(aState.mY, inlineFloatBreakType);
|
||||
if (aState.mY != line->mBounds.y + deltaY) {
|
||||
if (aState.mY != line->BStart() + deltaY) {
|
||||
// SlideLine is not going to put the line where the clearance
|
||||
// put it. Reflow the line to be sure.
|
||||
line->MarkDirty();
|
||||
|
@ -2000,7 +1982,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
// If the previous margin is dirty, reflow the current line
|
||||
line->MarkDirty();
|
||||
line->ClearPreviousMarginDirty();
|
||||
} else if (line->mBounds.YMost() + deltaY > aState.mBottomEdge) {
|
||||
} else if (line->BEnd() + deltaY > aState.mBottomEdge) {
|
||||
// Lines that aren't dirty but get slid past our height constraint must
|
||||
// be reflowed.
|
||||
line->MarkDirty();
|
||||
|
@ -2027,6 +2009,27 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
PropagateFloatDamage(aState, line, deltaY);
|
||||
}
|
||||
|
||||
// If the container width has changed reset the container width. If the
|
||||
// line's writing mode is not ltr, or if the line is not left-aligned, also
|
||||
// mark the line dirty.
|
||||
if (aState.mContainerWidth != line->mContainerWidth) {
|
||||
line->mContainerWidth = aState.mContainerWidth;
|
||||
|
||||
bool isLastLine = line == mLines.back() &&
|
||||
!GetNextInFlow() &&
|
||||
NS_STYLE_TEXT_ALIGN_AUTO == StyleText()->mTextAlignLast;
|
||||
uint8_t align = isLastLine ?
|
||||
StyleText()->mTextAlign : StyleText()->mTextAlignLast;
|
||||
|
||||
if (line->mWritingMode.IsVertical() ||
|
||||
!line->mWritingMode.IsBidiLTR() ||
|
||||
!IsAlignedLeft(align,
|
||||
aState.mReflowState.mStyleVisibility->mDirection,
|
||||
StyleTextReset()->mUnicodeBidi, this)) {
|
||||
line->MarkDirty();
|
||||
}
|
||||
}
|
||||
|
||||
if (needToRecoverState && line->IsDirty()) {
|
||||
// We need to reconstruct the bottom margin only if we didn't
|
||||
// reflow the previous line and we do need to reflow (or repair
|
||||
|
@ -2060,14 +2063,14 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
lastLineMovedUp = true;
|
||||
|
||||
bool maybeReflowingForFirstTime =
|
||||
line->mBounds.x == 0 && line->mBounds.y == 0 &&
|
||||
line->mBounds.width == 0 && line->mBounds.height == 0;
|
||||
line->IStart() == 0 && line->BStart() == 0 &&
|
||||
line->ISize() == 0 && line->BSize() == 0;
|
||||
|
||||
// Compute the dirty lines "before" YMost, after factoring in
|
||||
// Compute the dirty lines "before" BEnd, after factoring in
|
||||
// the running deltaY value - the running value is implicit in
|
||||
// aState.mY.
|
||||
nscoord oldY = line->mBounds.y;
|
||||
nscoord oldYMost = line->mBounds.YMost();
|
||||
nscoord oldY = line->BStart();
|
||||
nscoord oldYMost = line->BEnd();
|
||||
|
||||
NS_ASSERTION(!willReflowAgain || !line->IsBlock(),
|
||||
"Don't reflow blocks while willReflowAgain is true, reflow of block abs-pos children depends on this");
|
||||
|
@ -2124,7 +2127,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
// it wasn't empty before, any adjacency and clearance changes are irrelevant
|
||||
// to the result of nextLine->ShouldApplyTopMargin.
|
||||
if (line.next() != end_lines()) {
|
||||
bool maybeWasEmpty = oldY == line.next()->mBounds.y;
|
||||
bool maybeWasEmpty = oldY == line.next()->BStart();
|
||||
bool isEmpty = line->CachedIsEmpty();
|
||||
if (maybeReflowingForFirstTime /*1*/ ||
|
||||
(isEmpty || maybeWasEmpty) /*2/3/4*/) {
|
||||
|
@ -2139,7 +2142,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
// MarkPreviousMarginDirty on the next line which will force it
|
||||
// to be reflowed, so this computation of deltaY will not be
|
||||
// used.
|
||||
deltaY = line->mBounds.YMost() - oldYMost;
|
||||
deltaY = line->BEnd() - oldYMost;
|
||||
|
||||
// Now do an interrupt check. We want to do this only in the case when we
|
||||
// actually reflow the line, so that if we get back in here we'll get
|
||||
|
@ -2182,7 +2185,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
// empty, because that's what PlaceLine does. (Empty blocks may
|
||||
// want to update mY, e.g. if they have clearance.)
|
||||
if (line->IsBlock() || !line->CachedIsEmpty()) {
|
||||
aState.mY = line->mBounds.YMost();
|
||||
aState.mY = line->BEnd();
|
||||
}
|
||||
|
||||
needToRecoverState = true;
|
||||
|
@ -2669,7 +2672,7 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
|
|||
NS_PRECONDITION(aDY != 0, "why slide a line nowhere?");
|
||||
|
||||
// Adjust line state
|
||||
aLine->SlideBy(aDY);
|
||||
aLine->SlideBy(aDY, aState.mContainerWidth);
|
||||
|
||||
// Adjust the frames in the line
|
||||
nsIFrame* kid = aLine->mFirstChild;
|
||||
|
@ -3185,8 +3188,9 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||
nsOverflowAreas overflowAreas;
|
||||
*aKeepReflowGoing = brc.PlaceBlock(blockHtmlRS, forceFit, aLine.get(),
|
||||
collapsedBottomMargin,
|
||||
aLine->mBounds, overflowAreas,
|
||||
frameReflowStatus);
|
||||
overflowAreas,
|
||||
frameReflowStatus,
|
||||
aState.mContainerWidth);
|
||||
if (!NS_FRAME_IS_FULLY_COMPLETE(frameReflowStatus) &&
|
||||
ShouldAvoidBreakInside(aState.mReflowState)) {
|
||||
*aKeepReflowGoing = false;
|
||||
|
@ -3205,7 +3209,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||
// Some of the child block fit
|
||||
|
||||
// Advance to new Y position
|
||||
nscoord newY = aLine->mBounds.YMost();
|
||||
nscoord newY = aLine->BEnd();
|
||||
aState.mY = newY;
|
||||
|
||||
// Continue the block frame now if it didn't completely fit in
|
||||
|
@ -3487,9 +3491,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
|||
#endif
|
||||
|
||||
WritingMode wm = GetWritingMode(aLine->mFirstChild);
|
||||
nscoord lineWidth = aFloatAvailableSpace.mRect.width +
|
||||
aState.BorderPadding().LeftRight();
|
||||
LogicalRect lineRect(wm, aFloatAvailableSpace.mRect, lineWidth);
|
||||
LogicalRect lineRect(wm, aFloatAvailableSpace.mRect, aState.mContainerWidth);
|
||||
|
||||
nscoord iStart = lineRect.IStart(wm);
|
||||
|
||||
|
@ -3511,7 +3513,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
|||
availISize, availBSize,
|
||||
aFloatAvailableSpace.mHasFloats,
|
||||
false, /*XXX isTopOfPage*/
|
||||
wm, lineWidth);
|
||||
wm, aState.mContainerWidth);
|
||||
|
||||
aState.SetFlag(BRS_LINE_LAYOUT_EMPTY, false);
|
||||
|
||||
|
@ -4089,7 +4091,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||
((aLine == mLines.front() &&
|
||||
(!aLineLayout.IsZeroBSize() || (aLine == mLines.back()))) ||
|
||||
(mLines.front() != mLines.back() &&
|
||||
0 == mLines.front()->mBounds.height &&
|
||||
0 == mLines.front()->BSize() &&
|
||||
aLine == mLines.begin().next()))) {
|
||||
nsHTMLReflowMetrics metrics(aState.mReflowState);
|
||||
nsIFrame* bullet = GetOutsideBullet();
|
||||
|
@ -4109,9 +4111,9 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||
nsRect oldFloatAvailableSpace(aFloatAvailableSpace);
|
||||
// As we redo for floats, we can't reduce the amount of height we're
|
||||
// checking.
|
||||
aAvailableSpaceHeight = std::max(aAvailableSpaceHeight, aLine->mBounds.height);
|
||||
aAvailableSpaceHeight = std::max(aAvailableSpaceHeight, aLine->BSize());
|
||||
aFloatAvailableSpace =
|
||||
aState.GetFloatAvailableSpaceForHeight(aLine->mBounds.y,
|
||||
aState.GetFloatAvailableSpaceForHeight(aLine->BStart(),
|
||||
aAvailableSpaceHeight,
|
||||
aFloatStateBeforeLine).mRect;
|
||||
NS_ASSERTION(aFloatAvailableSpace.y == oldFloatAvailableSpace.y, "yikes");
|
||||
|
@ -4127,13 +4129,13 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||
#ifdef DEBUG
|
||||
{
|
||||
static nscoord lastHeight = 0;
|
||||
if (CRAZY_SIZE(aLine->mBounds.y)) {
|
||||
lastHeight = aLine->mBounds.y;
|
||||
if (abs(aLine->mBounds.y - lastHeight) > CRAZY_COORD/10) {
|
||||
if (CRAZY_SIZE(aLine->BStart())) {
|
||||
lastHeight = aLine->BStart();
|
||||
if (abs(aLine->BStart() - lastHeight) > CRAZY_COORD/10) {
|
||||
nsFrame::ListTag(stdout);
|
||||
printf(": line=%p y=%d line.bounds.height=%d\n",
|
||||
static_cast<void*>(aLine.get()),
|
||||
aLine->mBounds.y, aLine->mBounds.height);
|
||||
aLine->BStart(), aLine->BSize());
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -4161,8 +4163,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||
(aLineLayout.GetLineEndsInBR() ||
|
||||
IsLastLine(aState, aLine)));
|
||||
|
||||
aLineLayout.InlineDirAlignFrames(aLine->mBounds, isLastLine,
|
||||
aLine->GetChildCount());
|
||||
aLineLayout.InlineDirAlignFrames(aLine, isLastLine);
|
||||
|
||||
// From here on, pfd->mBounds rectangles are incorrect because bidi
|
||||
// might have moved frames around!
|
||||
|
@ -4185,7 +4186,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||
// This line has some height. Therefore the application of the
|
||||
// previous-bottom-margin should stick.
|
||||
aState.mPrevBottomMargin.Zero();
|
||||
newY = aLine->mBounds.YMost();
|
||||
newY = aLine->BEnd();
|
||||
}
|
||||
else {
|
||||
// Don't let the previous-bottom-margin value affect the newY
|
||||
|
@ -4336,7 +4337,7 @@ nsBlockFrame::PushLines(nsBlockReflowState& aState,
|
|||
{
|
||||
line->MarkDirty();
|
||||
line->MarkPreviousMarginDirty();
|
||||
line->mBounds.SetRect(0, 0, 0, 0);
|
||||
line->SetBoundsEmpty();
|
||||
if (line->HasFloats()) {
|
||||
line->FreeFloats(aState.mFloatCacheFreeList);
|
||||
}
|
||||
|
@ -6117,8 +6118,8 @@ static void DebugOutputDrawLine(int32_t aDepth, nsLineBox* aLine, bool aDrawn) {
|
|||
printf("%s line=%p bounds=%d,%d,%d,%d ca=%d,%d,%d,%d\n",
|
||||
aDrawn ? "draw" : "skip",
|
||||
static_cast<void*>(aLine),
|
||||
aLine->mBounds.x, aLine->mBounds.y,
|
||||
aLine->mBounds.width, aLine->mBounds.height,
|
||||
aLine->IStart(), aLine->BStart(),
|
||||
aLine->ISize(), aLine->BSize(),
|
||||
lineArea.x, lineArea.y,
|
||||
lineArea.width, lineArea.height);
|
||||
}
|
||||
|
@ -6416,7 +6417,7 @@ nsBlockFrame::ChildIsDirty(nsIFrame* aChild)
|
|||
// height 0 and there is a second line, in which case it lives
|
||||
// in the second line.
|
||||
line_iterator bulletLine = begin_lines();
|
||||
if (bulletLine != end_lines() && bulletLine->mBounds.height == 0 &&
|
||||
if (bulletLine != end_lines() && bulletLine->BSize() == 0 &&
|
||||
bulletLine != mLines.back()) {
|
||||
bulletLine = bulletLine.next();
|
||||
}
|
||||
|
|
|
@ -245,7 +245,8 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
|
|||
mY = ty = mSpace.y + mTopMargin.get() + aClearance;
|
||||
|
||||
if ((mFrame->GetStateBits() & NS_BLOCK_FLOAT_MGR) == 0)
|
||||
aFrameRS.mBlockDelta = mOuterReflowState.mBlockDelta + ty - aLine->mBounds.y;
|
||||
aFrameRS.mBlockDelta =
|
||||
mOuterReflowState.mBlockDelta + ty - aLine->BStart();
|
||||
}
|
||||
|
||||
// Let frame know that we are reflowing it
|
||||
|
@ -310,13 +311,13 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
|
|||
* margins (CSS2 8.3.1). Also apply relative positioning.
|
||||
*/
|
||||
bool
|
||||
nsBlockReflowContext::PlaceBlock(const nsHTMLReflowState& aReflowState,
|
||||
bool aForceFit,
|
||||
nsLineBox* aLine,
|
||||
nsCollapsingMargin& aBottomMarginResult,
|
||||
nsRect& aInFlowBounds,
|
||||
nsOverflowAreas& aOverflowAreas,
|
||||
nsReflowStatus aReflowStatus)
|
||||
nsBlockReflowContext::PlaceBlock(const nsHTMLReflowState& aReflowState,
|
||||
bool aForceFit,
|
||||
nsLineBox* aLine,
|
||||
nsCollapsingMargin& aBottomMarginResult,
|
||||
nsOverflowAreas& aOverflowAreas,
|
||||
nsReflowStatus aReflowStatus,
|
||||
nscoord aContainerWidth)
|
||||
{
|
||||
// Compute collapsed bottom margin value.
|
||||
if (NS_FRAME_IS_COMPLETE(aReflowStatus)) {
|
||||
|
@ -386,11 +387,15 @@ nsBlockReflowContext::PlaceBlock(const nsHTMLReflowState& aReflowState,
|
|||
}
|
||||
}
|
||||
|
||||
aInFlowBounds = nsRect(position.x, position.y - backupContainingBlockAdvance,
|
||||
mMetrics.Width(), mMetrics.Height());
|
||||
|
||||
aLine->SetBounds(aReflowState.GetWritingMode(),
|
||||
nsRect(position.x,
|
||||
position.y - backupContainingBlockAdvance,
|
||||
mMetrics.Width(),
|
||||
mMetrics.Height()),
|
||||
aContainerWidth);
|
||||
|
||||
aReflowState.ApplyRelativePositioning(&position);
|
||||
|
||||
|
||||
// Now place the frame and complete the reflow process
|
||||
nsContainerFrame::FinishReflowChild(mFrame, mPresContext, mMetrics,
|
||||
&aReflowState, position.x, position.y, 0);
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "nsIFrame.h"
|
||||
#include "nsHTMLReflowMetrics.h"
|
||||
|
||||
class nsBlockFrame;
|
||||
class nsBlockReflowState;
|
||||
struct nsHTMLReflowState;
|
||||
class nsLineBox;
|
||||
|
@ -40,12 +39,12 @@ public:
|
|||
nsBlockReflowState& aState);
|
||||
|
||||
bool PlaceBlock(const nsHTMLReflowState& aReflowState,
|
||||
bool aForceFit,
|
||||
nsLineBox* aLine,
|
||||
nsCollapsingMargin& aBottomMarginResult /* out */,
|
||||
nsRect& aInFlowBounds,
|
||||
nsOverflowAreas& aOverflowAreas,
|
||||
nsReflowStatus aReflowStatus);
|
||||
bool aForceFit,
|
||||
nsLineBox* aLine,
|
||||
nsCollapsingMargin& aBottomMarginResult /* out */,
|
||||
nsOverflowAreas& aOverflowAreas,
|
||||
nsReflowStatus aReflowStatus,
|
||||
nscoord aContainerWidth);
|
||||
|
||||
nsCollapsingMargin& GetCarriedOutBottomMargin() {
|
||||
return mMetrics.mCarriedOutBottomMargin;
|
||||
|
|
|
@ -47,6 +47,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
|
|||
IS_TRUE_OVERFLOW_CONTAINER(aFrame));
|
||||
|
||||
const nsMargin& borderPadding = BorderPadding();
|
||||
mContainerWidth = aReflowState.ComputedWidth() +
|
||||
aReflowState.ComputedPhysicalBorderPadding().LeftRight();
|
||||
|
||||
if (aTopMarginRoot || 0 != aReflowState.ComputedPhysicalBorderPadding().top) {
|
||||
SetFlag(BRS_ISTOPMARGINROOT, true);
|
||||
|
|
|
@ -188,6 +188,7 @@ public:
|
|||
// mContentArea.height is not NS_UNCONSTRAINEDSIZE; otherwise
|
||||
// coordinate overflow may occur.
|
||||
nsRect mContentArea;
|
||||
nscoord mContainerWidth;
|
||||
|
||||
// Continuation out-of-flow float frames that need to move to our
|
||||
// next in flow are placed here during reflow. It's a pointer to
|
||||
|
|
|
@ -3451,40 +3451,43 @@ static FrameTarget GetSelectionClosestFrameForLine(
|
|||
// Account for end of lines (any iterator from the block is valid)
|
||||
if (aLine == aParent->end_lines())
|
||||
return DrillDownToSelectionFrame(aParent, true, aFlags);
|
||||
nsIFrame *closestFromLeft = nullptr, *closestFromRight = nullptr;
|
||||
nsRect rect = aLine->mBounds;
|
||||
nscoord closestLeft = rect.x, closestRight = rect.XMost();
|
||||
nsIFrame *closestFromIStart = nullptr, *closestFromIEnd = nullptr;
|
||||
nscoord closestIStart = aLine->IStart(), closestIEnd = aLine->IEnd();
|
||||
WritingMode wm = aLine->mWritingMode;
|
||||
LogicalPoint pt(wm, aPoint, aLine->mContainerWidth);
|
||||
for (int32_t n = aLine->GetChildCount(); n;
|
||||
--n, frame = frame->GetNextSibling()) {
|
||||
if (!SelfIsSelectable(frame, aFlags) || frame->IsEmpty())
|
||||
continue;
|
||||
nsRect frameRect = frame->GetRect();
|
||||
if (aPoint.x >= frameRect.x) {
|
||||
if (aPoint.x < frameRect.XMost()) {
|
||||
LogicalRect frameRect = LogicalRect(wm, frame->GetRect(),
|
||||
aLine->mContainerWidth);
|
||||
if (pt.I(wm) >= frameRect.IStart(wm)) {
|
||||
if (pt.I(wm) < frameRect.IEnd(wm)) {
|
||||
return GetSelectionClosestFrameForChild(frame, aPoint, aFlags);
|
||||
}
|
||||
if (frameRect.XMost() >= closestLeft) {
|
||||
closestFromLeft = frame;
|
||||
closestLeft = frameRect.XMost();
|
||||
if (frameRect.IEnd(wm) >= closestIStart) {
|
||||
closestFromIStart = frame;
|
||||
closestIStart = frameRect.IEnd(wm);
|
||||
}
|
||||
} else {
|
||||
if (frameRect.x <= closestRight) {
|
||||
closestFromRight = frame;
|
||||
closestRight = frameRect.x;
|
||||
if (frameRect.IStart(wm) <= closestIEnd) {
|
||||
closestFromIEnd = frame;
|
||||
closestIEnd = frameRect.IStart(wm);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!closestFromLeft && !closestFromRight) {
|
||||
if (!closestFromIStart && !closestFromIEnd) {
|
||||
// We should only get here if there are no selectable frames on a line
|
||||
// XXX Do we need more elaborate handling here?
|
||||
return FrameTarget::Null();
|
||||
}
|
||||
if (closestFromLeft &&
|
||||
(!closestFromRight ||
|
||||
(abs(aPoint.x - closestLeft) <= abs(aPoint.x - closestRight)))) {
|
||||
return GetSelectionClosestFrameForChild(closestFromLeft, aPoint, aFlags);
|
||||
if (closestFromIStart &&
|
||||
(!closestFromIEnd ||
|
||||
(abs(pt.I(wm) - closestIStart) <= abs(pt.I(wm) - closestIEnd)))) {
|
||||
return GetSelectionClosestFrameForChild(closestFromIStart, aPoint,
|
||||
aFlags);
|
||||
}
|
||||
return GetSelectionClosestFrameForChild(closestFromRight, aPoint, aFlags);
|
||||
return GetSelectionClosestFrameForChild(closestFromIEnd, aPoint, aFlags);
|
||||
}
|
||||
|
||||
// This method is for the special handling we do for block frames; they're
|
||||
|
@ -3513,15 +3516,18 @@ static FrameTarget GetSelectionClosestFrameForBlock(nsIFrame* aFrame,
|
|||
}
|
||||
nsBlockFrame::line_iterator curLine = firstLine;
|
||||
nsBlockFrame::line_iterator closestLine = end;
|
||||
// Convert aPoint into a LogicalPoint in the writing-mode of this block
|
||||
WritingMode wm = curLine->mWritingMode;
|
||||
LogicalPoint pt(wm, aPoint, curLine->mContainerWidth);
|
||||
while (curLine != end) {
|
||||
// Check to see if our point lies with the line's Y bounds
|
||||
nscoord y = aPoint.y - curLine->mBounds.y;
|
||||
nscoord height = curLine->mBounds.height;
|
||||
if (y >= 0 && y < height) {
|
||||
// Check to see if our point lies within the line's block-direction bounds
|
||||
nscoord BCoord = pt.B(wm) - curLine->BStart();
|
||||
nscoord BSize = curLine->BSize();
|
||||
if (BCoord >= 0 && BCoord < BSize) {
|
||||
closestLine = curLine;
|
||||
break; // We found the line; stop looking
|
||||
}
|
||||
if (y < 0)
|
||||
if (BCoord < 0)
|
||||
break;
|
||||
++curLine;
|
||||
}
|
||||
|
@ -3550,7 +3556,7 @@ static FrameTarget GetSelectionClosestFrameForBlock(nsIFrame* aFrame,
|
|||
return DrillDownToSelectionFrame(aFrame, true, aFlags);
|
||||
closestLine = prevLine;
|
||||
} else { // Figure out which line is closer
|
||||
if (aPoint.y - prevLine->mBounds.YMost() < nextLine->mBounds.y - aPoint.y)
|
||||
if (pt.B(wm) - prevLine->BEnd() < nextLine->BStart() - pt.B(wm))
|
||||
closestLine = prevLine;
|
||||
else
|
||||
closestLine = nextLine;
|
||||
|
|
|
@ -1186,7 +1186,7 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext,
|
|||
if (mStyleDisplay->IsOriginalDisplayInlineOutsideStyle()) {
|
||||
// Use the top of the inline box which the placeholder lives in
|
||||
// as the hypothetical box's top.
|
||||
aHypotheticalBox.mTop = lineBox->mBounds.y + blockYOffset;
|
||||
aHypotheticalBox.mTop = lineBox->GetPhysicalBounds().y + blockYOffset;
|
||||
} else {
|
||||
// The element would have been block-level which means it would
|
||||
// be below the line containing the placeholder frame, unless
|
||||
|
@ -1211,11 +1211,11 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext,
|
|||
// The top of the hypothetical box is the top of the line
|
||||
// containing the placeholder, since there is nothing in the
|
||||
// line before our placeholder except empty frames.
|
||||
aHypotheticalBox.mTop = lineBox->mBounds.y + blockYOffset;
|
||||
aHypotheticalBox.mTop = lineBox->GetPhysicalBounds().y + blockYOffset;
|
||||
} else {
|
||||
// The top of the hypothetical box is just below the line
|
||||
// containing the placeholder.
|
||||
aHypotheticalBox.mTop = lineBox->mBounds.YMost() + blockYOffset;
|
||||
aHypotheticalBox.mTop = lineBox->GetPhysicalBounds().YMost() + blockYOffset;
|
||||
}
|
||||
} else {
|
||||
// Just use the placeholder's y-offset wrt the containing block
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "nsBidiPresUtils.h"
|
||||
#endif
|
||||
#include "nsIFrameInlines.h"
|
||||
#include "WritingModes.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
@ -28,8 +29,13 @@ int32_t nsLineBox::GetCtorCount() { return ctorCount; }
|
|||
const uint32_t nsLineBox::kMinChildCountForHashtable;
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
nsLineBox::nsLineBox(nsIFrame* aFrame, int32_t aCount, bool aIsBlock)
|
||||
: mFirstChild(aFrame)
|
||||
, mContainerWidth(-1)
|
||||
, mBounds(WritingMode()) // mBounds will be initialized with the correct
|
||||
// writing mode when it is set
|
||||
// NOTE: memory is already zeroed since we allocate with AllocateByObjectID.
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsLineBox);
|
||||
|
@ -75,6 +81,7 @@ NS_NewLineBox(nsIPresShell* aPresShell, nsLineBox* aFromLine,
|
|||
{
|
||||
nsLineBox* newLine = new (aPresShell) nsLineBox(aFrame, aCount, false);
|
||||
newLine->NoteFramesMovedFrom(aFromLine);
|
||||
newLine->mContainerWidth = aFromLine->mContainerWidth;
|
||||
return newLine;
|
||||
}
|
||||
|
||||
|
@ -241,11 +248,12 @@ nsLineBox::List(FILE* out, const char* aPrefix, uint32_t aFlags) const
|
|||
if (IsBlock() && !GetCarriedOutBottomMargin().IsZero()) {
|
||||
str += nsPrintfCString("bm=%d ", GetCarriedOutBottomMargin().get());
|
||||
}
|
||||
nsRect bounds = GetPhysicalBounds();
|
||||
str += nsPrintfCString("{%d,%d,%d,%d} ",
|
||||
mBounds.x, mBounds.y, mBounds.width, mBounds.height);
|
||||
bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
if (mData &&
|
||||
(!mData->mOverflowAreas.VisualOverflow().IsEqualEdges(mBounds) ||
|
||||
!mData->mOverflowAreas.ScrollableOverflow().IsEqualEdges(mBounds))) {
|
||||
(!mData->mOverflowAreas.VisualOverflow().IsEqualEdges(bounds) ||
|
||||
!mData->mOverflowAreas.ScrollableOverflow().IsEqualEdges(bounds))) {
|
||||
str += nsPrintfCString("vis-overflow=%d,%d,%d,%d scr-overflow=%d,%d,%d,%d ",
|
||||
mData->mOverflowAreas.VisualOverflow().x,
|
||||
mData->mOverflowAreas.VisualOverflow().y,
|
||||
|
@ -440,7 +448,7 @@ nsLineBox::SetCarriedOutBottomMargin(nsCollapsingMargin aValue)
|
|||
if (IsBlock()) {
|
||||
if (!aValue.IsZero()) {
|
||||
if (!mBlockData) {
|
||||
mBlockData = new ExtraBlockData(mBounds);
|
||||
mBlockData = new ExtraBlockData(GetPhysicalBounds());
|
||||
}
|
||||
changed = aValue != mBlockData->mCarriedOutBottomMargin;
|
||||
mBlockData->mCarriedOutBottomMargin = aValue;
|
||||
|
@ -457,7 +465,8 @@ nsLineBox::SetCarriedOutBottomMargin(nsCollapsingMargin aValue)
|
|||
void
|
||||
nsLineBox::MaybeFreeData()
|
||||
{
|
||||
if (mData && mData->mOverflowAreas == nsOverflowAreas(mBounds, mBounds)) {
|
||||
nsRect bounds = GetPhysicalBounds();
|
||||
if (mData && mData->mOverflowAreas == nsOverflowAreas(bounds, bounds)) {
|
||||
if (IsInline()) {
|
||||
if (mInlineData->mFloats.IsEmpty()) {
|
||||
delete mInlineData;
|
||||
|
@ -499,7 +508,7 @@ nsLineBox::AppendFloats(nsFloatCacheFreeList& aFreeList)
|
|||
if (IsInline()) {
|
||||
if (aFreeList.NotEmpty()) {
|
||||
if (!mInlineData) {
|
||||
mInlineData = new ExtraInlineData(mBounds);
|
||||
mInlineData = new ExtraInlineData(GetPhysicalBounds());
|
||||
}
|
||||
mInlineData->mFloats.Append(aFreeList);
|
||||
}
|
||||
|
@ -533,14 +542,15 @@ nsLineBox::SetOverflowAreas(const nsOverflowAreas& aOverflowAreas)
|
|||
NS_ASSERTION(aOverflowAreas.Overflow(otype).height >= 0,
|
||||
"illegal height for combined area");
|
||||
}
|
||||
if (!aOverflowAreas.VisualOverflow().IsEqualInterior(mBounds) ||
|
||||
!aOverflowAreas.ScrollableOverflow().IsEqualEdges(mBounds)) {
|
||||
nsRect bounds = GetPhysicalBounds();
|
||||
if (!aOverflowAreas.VisualOverflow().IsEqualInterior(bounds) ||
|
||||
!aOverflowAreas.ScrollableOverflow().IsEqualEdges(bounds)) {
|
||||
if (!mData) {
|
||||
if (IsInline()) {
|
||||
mInlineData = new ExtraInlineData(mBounds);
|
||||
mInlineData = new ExtraInlineData(bounds);
|
||||
}
|
||||
else {
|
||||
mBlockData = new ExtraBlockData(mBounds);
|
||||
mBlockData = new ExtraBlockData(bounds);
|
||||
}
|
||||
}
|
||||
mData->mOverflowAreas = aOverflowAreas;
|
||||
|
@ -644,7 +654,7 @@ nsLineIterator::GetLine(int32_t aLineNumber,
|
|||
nsLineBox* line = mLines[aLineNumber];
|
||||
*aFirstFrameOnLine = line->mFirstChild;
|
||||
*aNumFramesOnLine = line->GetChildCount();
|
||||
aLineBounds = line->mBounds;
|
||||
aLineBounds = line->GetPhysicalBounds();
|
||||
|
||||
uint32_t flags = 0;
|
||||
if (line->IsBlock()) {
|
||||
|
@ -727,7 +737,7 @@ nsLineIterator::FindFrameAt(int32_t aLineNumber,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
if (line->mBounds.width == 0 && line->mBounds.height == 0)
|
||||
if (line->ISize() == 0 && line->BSize() == 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsIFrame* frame = line->mFirstChild;
|
||||
|
|
|
@ -447,28 +447,46 @@ public:
|
|||
// layout (except for handling of 'overflow').
|
||||
void SetOverflowAreas(const nsOverflowAreas& aOverflowAreas);
|
||||
nsRect GetOverflowArea(nsOverflowType aType) {
|
||||
return mData ? mData->mOverflowAreas.Overflow(aType) : mBounds;
|
||||
return mData ? mData->mOverflowAreas.Overflow(aType) : GetPhysicalBounds();
|
||||
}
|
||||
nsOverflowAreas GetOverflowAreas() {
|
||||
if (mData) {
|
||||
return mData->mOverflowAreas;
|
||||
}
|
||||
return nsOverflowAreas(mBounds, mBounds);
|
||||
nsRect bounds = GetPhysicalBounds();
|
||||
return nsOverflowAreas(bounds, bounds);
|
||||
}
|
||||
nsRect GetVisualOverflowArea()
|
||||
{ return GetOverflowArea(eVisualOverflow); }
|
||||
nsRect GetScrollableOverflowArea()
|
||||
{ return GetOverflowArea(eScrollableOverflow); }
|
||||
|
||||
void SlideBy(nscoord aDY) {
|
||||
mBounds.y += aDY;
|
||||
void SlideBy(nscoord aDBCoord, nscoord aContainerWidth) {
|
||||
NS_ASSERTION(aContainerWidth == mContainerWidth || mContainerWidth == -1,
|
||||
"container width doesn't match");
|
||||
mContainerWidth = aContainerWidth;
|
||||
mBounds.BStart(mWritingMode) += aDBCoord;
|
||||
if (mData) {
|
||||
NS_FOR_FRAME_OVERFLOW_TYPES(otype) {
|
||||
mData->mOverflowAreas.Overflow(otype).y += aDY;
|
||||
mData->mOverflowAreas.Overflow(otype).y += aDBCoord;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IndentBy(nscoord aDICoord, nscoord aContainerWidth) {
|
||||
NS_ASSERTION(aContainerWidth == mContainerWidth || mContainerWidth == -1,
|
||||
"container width doesn't match");
|
||||
mContainerWidth = aContainerWidth;
|
||||
mBounds.IStart(mWritingMode) += aDICoord;
|
||||
}
|
||||
|
||||
void ExpandBy(nscoord aDISize, nscoord aContainerWidth) {
|
||||
NS_ASSERTION(aContainerWidth == mContainerWidth || mContainerWidth == -1,
|
||||
"container width doesn't match");
|
||||
mContainerWidth = aContainerWidth;
|
||||
mBounds.ISize(mWritingMode) += aDISize;
|
||||
}
|
||||
|
||||
/**
|
||||
* The ascent (distance from top to baseline) of the linebox is the
|
||||
* ascent of the anonymous inline box (for which we don't actually
|
||||
|
@ -480,8 +498,29 @@ public:
|
|||
nscoord GetAscent() const { return mAscent; }
|
||||
void SetAscent(nscoord aAscent) { mAscent = aAscent; }
|
||||
|
||||
nscoord GetHeight() const {
|
||||
return mBounds.height;
|
||||
nscoord BStart() const {
|
||||
return mBounds.BStart(mWritingMode);
|
||||
}
|
||||
nscoord BSize() const {
|
||||
return mBounds.BSize(mWritingMode);
|
||||
}
|
||||
nscoord BEnd() const {
|
||||
return mBounds.BEnd(mWritingMode);
|
||||
}
|
||||
nscoord IStart() const {
|
||||
return mBounds.IStart(mWritingMode);
|
||||
}
|
||||
nscoord ISize() const {
|
||||
return mBounds.ISize(mWritingMode);
|
||||
}
|
||||
nscoord IEnd() const {
|
||||
return mBounds.IEnd(mWritingMode);
|
||||
}
|
||||
void SetBoundsEmpty() {
|
||||
mBounds.IStart(mWritingMode) = 0;
|
||||
mBounds.ISize(mWritingMode) = 0;
|
||||
mBounds.BStart(mWritingMode) = 0;
|
||||
mBounds.BSize(mWritingMode) = 0;
|
||||
}
|
||||
|
||||
static void DeleteLineList(nsPresContext* aPresContext, nsLineList& aLines,
|
||||
|
@ -539,7 +578,38 @@ public:
|
|||
|
||||
nsIFrame* mFirstChild;
|
||||
|
||||
nsRect mBounds;
|
||||
mozilla::WritingMode mWritingMode;
|
||||
nscoord mContainerWidth;
|
||||
private:
|
||||
mozilla::LogicalRect mBounds;
|
||||
public:
|
||||
const mozilla::LogicalRect& GetBounds() { return mBounds; }
|
||||
nsRect GetPhysicalBounds() const
|
||||
{
|
||||
if (mBounds.IsEmpty()) {
|
||||
return nsRect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
NS_ASSERTION(mContainerWidth != -1, "mContainerWidth not initialized");
|
||||
return mBounds.GetPhysicalRect(mWritingMode, mContainerWidth);
|
||||
}
|
||||
void SetBounds(mozilla::WritingMode aWritingMode,
|
||||
nscoord aIStart, nscoord aBStart,
|
||||
nscoord aISize, nscoord aBSize,
|
||||
nscoord aContainerWidth)
|
||||
{
|
||||
mWritingMode = aWritingMode;
|
||||
mContainerWidth = aContainerWidth;
|
||||
mBounds = mozilla::LogicalRect(aWritingMode, aIStart, aBStart,
|
||||
aISize, aBSize);
|
||||
}
|
||||
void SetBounds(mozilla::WritingMode aWritingMode,
|
||||
nsRect aRect, nscoord aContainerWidth)
|
||||
{
|
||||
mWritingMode = aWritingMode;
|
||||
mContainerWidth = aContainerWidth;
|
||||
mBounds = mozilla::LogicalRect(aWritingMode, aRect, aContainerWidth);
|
||||
}
|
||||
|
||||
// mFlags.mHasHashedFrames says which one to use
|
||||
union {
|
||||
|
|
|
@ -1481,18 +1481,18 @@ nsLineLayout::BlockDirAlignLine()
|
|||
}
|
||||
|
||||
// Fill in returned line-box and max-element-width data
|
||||
mLineBox->mBounds.x = psd->mIStart;
|
||||
mLineBox->mBounds.y = mBStartEdge;
|
||||
mLineBox->mBounds.width = psd->mICoord - psd->mIStart;
|
||||
mLineBox->mBounds.height = lineBSize;
|
||||
mLineBox->SetBounds(lineWM,
|
||||
psd->mIStart, mBStartEdge,
|
||||
psd->mICoord - psd->mIStart, lineBSize,
|
||||
mContainerWidth);
|
||||
|
||||
mFinalLineBSize = lineBSize;
|
||||
mLineBox->SetAscent(baselineBCoord - mBStartEdge);
|
||||
#ifdef NOISY_BLOCKDIR_ALIGN
|
||||
printf(
|
||||
" [line]==> bounds{x,y,w,h}={%d,%d,%d,%d} lh=%d a=%d\n",
|
||||
mLineBox->mBounds.x, mLineBox->mBounds.y,
|
||||
mLineBox->mBounds.width, mLineBox->mBounds.height,
|
||||
mLineBox->mBounds.IStart(lineWM), mLineBox->mBounds.BStart(lineWM),
|
||||
mLineBox->mBounds.ISize(lineWM), mLineBox->mBounds.BSize(lineWM),
|
||||
mFinalLineBSize, mLineBox->GetAscent());
|
||||
#endif
|
||||
|
||||
|
@ -2509,29 +2509,27 @@ nsLineLayout::ApplyFrameJustification(PerSpanData* aPSD, FrameJustificationState
|
|||
}
|
||||
|
||||
void
|
||||
nsLineLayout::InlineDirAlignFrames(nsRect& aLineBounds,
|
||||
bool aIsLastLine,
|
||||
int32_t aFrameCount)
|
||||
nsLineLayout::InlineDirAlignFrames(nsLineBox* aLine,
|
||||
bool aIsLastLine)
|
||||
{
|
||||
/**
|
||||
* NOTE: aIsLastLine ain't necessarily so: it is correctly set by caller
|
||||
* only in cases where the last line needs special handling.
|
||||
*/
|
||||
PerSpanData* psd = mRootSpan;
|
||||
WritingMode lineWM = psd->mWritingMode;
|
||||
NS_WARN_IF_FALSE(psd->mIEnd != NS_UNCONSTRAINEDSIZE,
|
||||
"have unconstrained width; this should only result from "
|
||||
"very large sizes, not attempts at intrinsic width "
|
||||
"calculation");
|
||||
nscoord availWidth = psd->mIEnd - psd->mIStart;
|
||||
nscoord remainingWidth = availWidth - aLineBounds.width;
|
||||
nscoord availISize = psd->mIEnd - psd->mIStart;
|
||||
nscoord remainingISize = availISize - aLine->ISize();
|
||||
#ifdef NOISY_INLINEDIR_ALIGN
|
||||
nsFrame::ListTag(stdout, mBlockReflowState->frame);
|
||||
printf(": availWidth=%d lineBounds.x=%d lineWidth=%d delta=%d\n",
|
||||
availWidth, aLineBounds.x, aLineBounds.width, remainingWidth);
|
||||
printf(": availISize=%d lineBounds.IStart=%d lineISize=%d delta=%d\n",
|
||||
availISize, aLine->IStart(), aLine->ISize(), remainingISize);
|
||||
#endif
|
||||
|
||||
WritingMode lineWM = psd->mWritingMode;
|
||||
|
||||
// 'text-align-last: auto' is equivalent to the value of the 'text-align'
|
||||
// property except when 'text-align' is set to 'justify', in which case it
|
||||
// is 'justify' when 'text-justify' is 'distribute' and 'start' otherwise.
|
||||
|
@ -2552,24 +2550,25 @@ nsLineLayout::InlineDirAlignFrames(nsRect& aLineBounds,
|
|||
}
|
||||
}
|
||||
|
||||
if ((remainingWidth > 0 || textAlignTrue) &&
|
||||
if ((remainingISize > 0 || textAlignTrue) &&
|
||||
!(mBlockReflowState->frame->IsSVGText())) {
|
||||
|
||||
switch (textAlign) {
|
||||
case NS_STYLE_TEXT_ALIGN_JUSTIFY:
|
||||
int32_t numSpaces;
|
||||
int32_t numLetters;
|
||||
|
||||
|
||||
ComputeJustificationWeights(psd, &numSpaces, &numLetters);
|
||||
|
||||
if (numSpaces > 0) {
|
||||
FrameJustificationState state =
|
||||
{ numSpaces, numLetters, remainingWidth, 0, 0, 0, 0, 0 };
|
||||
{ numSpaces, numLetters, remainingISize, 0, 0, 0, 0, 0 };
|
||||
|
||||
// Apply the justification, and make sure to update our linebox
|
||||
// width to account for it.
|
||||
aLineBounds.width += ApplyFrameJustification(psd, &state);
|
||||
remainingWidth = availWidth - aLineBounds.width;
|
||||
aLine->ExpandBy(ApplyFrameJustification(psd, &state),
|
||||
mContainerWidth);
|
||||
remainingISize = availISize - aLine->ISize();
|
||||
break;
|
||||
}
|
||||
// Fall through to the default case if we could not justify to fill
|
||||
|
@ -2582,25 +2581,25 @@ nsLineLayout::InlineDirAlignFrames(nsRect& aLineBounds,
|
|||
case NS_STYLE_TEXT_ALIGN_LEFT:
|
||||
case NS_STYLE_TEXT_ALIGN_MOZ_LEFT:
|
||||
if (!lineWM.IsBidiLTR()) {
|
||||
dx = remainingWidth;
|
||||
dx = remainingISize;
|
||||
}
|
||||
break;
|
||||
|
||||
case NS_STYLE_TEXT_ALIGN_RIGHT:
|
||||
case NS_STYLE_TEXT_ALIGN_MOZ_RIGHT:
|
||||
if (lineWM.IsBidiLTR()) {
|
||||
dx = remainingWidth;
|
||||
dx = remainingISize;
|
||||
}
|
||||
break;
|
||||
|
||||
case NS_STYLE_TEXT_ALIGN_END:
|
||||
dx = remainingWidth;
|
||||
dx = remainingISize;
|
||||
break;
|
||||
|
||||
|
||||
case NS_STYLE_TEXT_ALIGN_CENTER:
|
||||
case NS_STYLE_TEXT_ALIGN_MOZ_CENTER:
|
||||
dx = remainingWidth / 2;
|
||||
dx = remainingISize / 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2610,12 +2609,13 @@ nsLineLayout::InlineDirAlignFrames(nsRect& aLineBounds,
|
|||
pfd->mBounds.IStart(lineWM) += dx;
|
||||
pfd->mFrame->SetRect(lineWM, pfd->mBounds, mContainerWidth);
|
||||
}
|
||||
aLineBounds.x += dx;
|
||||
aLine->IndentBy(dx, mContainerWidth);
|
||||
}
|
||||
|
||||
if (mPresContext->BidiEnabled() &&
|
||||
(!mPresContext->IsVisualMode() || !lineWM.IsBidiLTR())) {
|
||||
nsBidiPresUtils::ReorderFrames(psd->mFirstFrame->mFrame, aFrameCount,
|
||||
nsBidiPresUtils::ReorderFrames(psd->mFirstFrame->mFrame,
|
||||
aLine->GetChildCount(),
|
||||
lineWM, mContainerWidth);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,8 +94,7 @@ public:
|
|||
|
||||
bool TrimTrailingWhiteSpace();
|
||||
|
||||
void InlineDirAlignFrames(nsRect& aLineBounds, bool aIsLastLine,
|
||||
int32_t aFrameCount);
|
||||
void InlineDirAlignFrames(nsLineBox* aLine, bool aIsLastLine);
|
||||
|
||||
/**
|
||||
* Handle all the relative positioning in the line, compute the
|
||||
|
|
Загрузка…
Ссылка в новой задаче