mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Fixed pullup logic for ReflowLine to not de-reference deleted nextLine's
This commit is contained in:
parent
09145642f6
commit
f6c2579b4e
@ -1196,95 +1196,96 @@ InlineFrameData::ReflowLine(nsCSSBlockReflowState& aState,
|
|||||||
// XXX factor this better while still keeping it fast
|
// XXX factor this better while still keeping it fast
|
||||||
while (nsnull != ild->mNext) {
|
while (nsnull != ild->mNext) {
|
||||||
InlineLineData* nextLine = ild->mNext;
|
InlineLineData* nextLine = ild->mNext;
|
||||||
PRInt32 i, n = nextLine->mChildCount;
|
if (0 == nextLine->mChildCount) {
|
||||||
for (i = 0; i < n; i++) {
|
// The next line is empty. This can happen when a child that was
|
||||||
nsIFrame* nextKid;
|
// continued across lines is reflowed and fits completey and has
|
||||||
prevChild->GetNextSibling(nextKid);
|
// it's continuation destroyed
|
||||||
NS_ASSERTION(nextKid == nextLine->mFirstChild, "bad lines");
|
NS_ASSERTION(nsnull == nextLine->mFirstChild, "bad pullup code");
|
||||||
|
ild->mNext = nextLine->mNext;
|
||||||
// Get first child from the next line and try reflowing and placing it
|
delete nextLine;
|
||||||
child = nextLine->mFirstChild;
|
continue;
|
||||||
rs = inlineLayout.ReflowAndPlaceFrame(child);
|
|
||||||
if (IS_REFLOW_ERROR(rs)) {
|
|
||||||
return nsresult(rs);
|
|
||||||
}
|
|
||||||
switch (rs & NS_INLINE_REFLOW_REFLOW_MASK) {
|
|
||||||
case NS_INLINE_REFLOW_COMPLETE:
|
|
||||||
// Pullup succeeded
|
|
||||||
if (0 == ild->mChildCount) {
|
|
||||||
ild->mFirstChild = child;
|
|
||||||
}
|
|
||||||
ild->mChildCount++;
|
|
||||||
if (--nextLine->mChildCount == 0) {
|
|
||||||
ild->mNext = nextLine->mNext;
|
|
||||||
delete nextLine;
|
|
||||||
nextLine = nsnull;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
child->GetNextSibling(nextLine->mFirstChild);
|
|
||||||
}
|
|
||||||
prevChild = child;
|
|
||||||
aState.mChildPrevInFlow = nsnull;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NS_INLINE_REFLOW_BREAK_AFTER:
|
|
||||||
// Pullup succeeded and we are done
|
|
||||||
if (0 == ild->mChildCount) {
|
|
||||||
ild->mFirstChild = child;
|
|
||||||
}
|
|
||||||
ild->mChildCount++;
|
|
||||||
if (--nextLine->mChildCount == 0) {
|
|
||||||
ild->mNext = nextLine->mNext;
|
|
||||||
delete nextLine;
|
|
||||||
nextLine = nsnull;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
child->GetNextSibling(nextLine->mFirstChild);
|
|
||||||
}
|
|
||||||
aState.mChildPrevInFlow = nsnull;
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
case NS_INLINE_REFLOW_BREAK_BEFORE:
|
|
||||||
// The child can't fit on this line so never mind
|
|
||||||
aState.mChildPrevInFlow = nsnull;
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
case NS_INLINE_REFLOW_NOT_COMPLETE:
|
|
||||||
// Some of the child fit on the line.
|
|
||||||
if (0 == ild->mChildCount) {
|
|
||||||
ild->mFirstChild = child;
|
|
||||||
}
|
|
||||||
ild->mChildCount++;
|
|
||||||
if (--nextLine->mChildCount == 0) {
|
|
||||||
ild->mNext = nextLine->mNext;
|
|
||||||
delete nextLine;
|
|
||||||
nextLine = nsnull;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
child->GetNextSibling(nextLine->mFirstChild);
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX as this section is coded, the above will delete an empty
|
|
||||||
// nextLine and then the MaybeCreateNextInFlow code will turn
|
|
||||||
// around and recreate it
|
|
||||||
|
|
||||||
// Create continuation frame (if necessary); add it to the end
|
|
||||||
// of this InlineLineData
|
|
||||||
MaybeCreateNextInFlow(aState, inlineLayout, ild, child);
|
|
||||||
child->GetNextSibling(child);
|
|
||||||
|
|
||||||
// Put continuation frame onto the next InlineLineData
|
|
||||||
rv = SplitLine(aState, inlineLayout, ild, child);
|
|
||||||
if (IS_REFLOW_ERROR(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove empty lines from the list
|
nsIFrame* child = nextLine->mFirstChild;
|
||||||
ild->mNext = nextLine->mNext;
|
rs = inlineLayout.ReflowAndPlaceFrame(child);
|
||||||
delete nextLine;/* XXX freeList in nsCSSBlockReflowState? */
|
if (IS_REFLOW_ERROR(rs)) {
|
||||||
|
return nsresult(rs);
|
||||||
|
}
|
||||||
|
switch (rs & NS_INLINE_REFLOW_REFLOW_MASK) {
|
||||||
|
case NS_INLINE_REFLOW_COMPLETE:
|
||||||
|
// Pullup succeeded
|
||||||
|
if (0 == ild->mChildCount) {
|
||||||
|
ild->mFirstChild = child;
|
||||||
|
}
|
||||||
|
ild->mChildCount++;
|
||||||
|
|
||||||
|
// Take child from nextLine
|
||||||
|
if (--nextLine->mChildCount == 0) {
|
||||||
|
ild->mNext = nextLine->mNext;
|
||||||
|
delete nextLine;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
child->GetNextSibling(nextLine->mFirstChild);
|
||||||
|
}
|
||||||
|
prevChild = child;
|
||||||
|
aState.mChildPrevInFlow = nsnull;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NS_INLINE_REFLOW_BREAK_AFTER:
|
||||||
|
// Pullup succeeded and we are done
|
||||||
|
if (0 == ild->mChildCount) {
|
||||||
|
ild->mFirstChild = child;
|
||||||
|
}
|
||||||
|
ild->mChildCount++;
|
||||||
|
|
||||||
|
// Take child from nextLine
|
||||||
|
if (--nextLine->mChildCount == 0) {
|
||||||
|
ild->mNext = nextLine->mNext;
|
||||||
|
delete nextLine;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
child->GetNextSibling(nextLine->mFirstChild);
|
||||||
|
}
|
||||||
|
aState.mChildPrevInFlow = nsnull;
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
case NS_INLINE_REFLOW_BREAK_BEFORE:
|
||||||
|
// The child can't fit on this line so never mind
|
||||||
|
aState.mChildPrevInFlow = nsnull;
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
case NS_INLINE_REFLOW_NOT_COMPLETE:
|
||||||
|
// Some of the child fit on the line.
|
||||||
|
if (0 == ild->mChildCount) {
|
||||||
|
ild->mFirstChild = child;
|
||||||
|
}
|
||||||
|
ild->mChildCount++;
|
||||||
|
|
||||||
|
// Take child from nextLine
|
||||||
|
if (--nextLine->mChildCount == 0) {
|
||||||
|
ild->mNext = nextLine->mNext;
|
||||||
|
delete nextLine;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
child->GetNextSibling(nextLine->mFirstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX as this section is coded, the above will delete an empty
|
||||||
|
// nextLine and then the MaybeCreateNextInFlow code will turn
|
||||||
|
// around and recreate it
|
||||||
|
|
||||||
|
// Create continuation frame (if necessary); add it to the end
|
||||||
|
// of this InlineLineData
|
||||||
|
MaybeCreateNextInFlow(aState, inlineLayout, ild, child);
|
||||||
|
child->GetNextSibling(child);
|
||||||
|
|
||||||
|
// Put continuation frame onto the next InlineLineData
|
||||||
|
rv = SplitLine(aState, inlineLayout, ild, child);
|
||||||
|
if (IS_REFLOW_ERROR(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pullup children from the blocks next-in-flow
|
// Pullup children from the blocks next-in-flow
|
||||||
|
Loading…
Reference in New Issue
Block a user