--- /dev/null
+layer at (0,0) size 800x600
+ RenderView at (0,0) size 800x600
+layer at (0,0) size 800x286
+ RenderBlock {HTML} at (0,0) size 800x286
+ RenderBody {BODY} at (8,16) size 784x262
+ RenderBlock {P} at (0,0) size 784x36
+ RenderText {#text} at (0,0) size 104x18
+ text run at (0,0) width 104: "This is a test for "
+ RenderInline {I} at (0,0) size 744x36
+ RenderInline {A} at (0,0) size 348x18 [color=#0000EE]
+ RenderText {#text} at (104,0) size 348x18
+ text run at (104,0) width 348: "http://bugzilla.opendarwin.org/show_bug.cgi?id=9669"
+ RenderText {#text} at (452,0) size 744x36
+ text run at (452,0) width 4: " "
+ text run at (456,0) width 288: "Incomplete repaint when changing an inline's"
+ text run at (0,18) width 43: "border"
+ RenderText {#text} at (43,18) size 4x18
+ text run at (43,18) width 4: "."
+ RenderBlock {HR} at (0,52) size 784x2 [border: (1px inset #000000)]
+ RenderBlock {DIV} at (0,62) size 200x200
+ RenderText {#text} at (0,0) size 192x54
+ text run at (0,0) width 129: "Cras faucibus. Nunc"
+ text run at (0,18) width 192: "adipiscing, enim in scelerisque"
+ text run at (0,36) width 64: "convallis, "
+ text run at (64,36) width 42: "augue "
+ RenderInline {SPAN} at (0,0) size 35x48 [border: (30px solid #0000FF) none]
+ RenderText {#text} at (106,36) size 35x18
+ text run at (106,36) width 35: "purus"
+ RenderText {#text} at (141,36) size 195x90
+ text run at (141,36) width 54: " eleifend"
+ text run at (0,54) width 151: "lacus, at sagittis eros leo"
+ text run at (0,72) width 135: "pulvinar velit. Integer"
+ text run at (0,90) width 190: "sollicitudin nisi ut urna blandit"
+ text run at (0,108) width 60: "convallis."
BidiState bidi;
bool useRepaintRect = false;
- IntRect repaintRect(0,0,0,0);
+ int repaintTop = 0;
+ int repaintBottom = 0;
m_overflowHeight = 0;
if (hasTextOverflow)
deleteEllipsisLineBoxes();
- int oldLineBottom = lastRootBox() ? lastRootBox()->bottomOverflow() : m_height;
- int startLineBottom = 0;
-
if (firstChild()) {
// layout replaced elements
bool endOfInline = false;
cleanLineBidiContext->ref();
if (startLine) {
useRepaintRect = true;
- startLineBottom = startLine->bottomOverflow();
- repaintRect.setY(min(m_height, startLine->topOverflow()));
+ repaintTop = m_height;
+ repaintBottom = m_height;
RenderArena* arena = renderArena();
RootInlineBox* box = startLine;
while (box) {
+ repaintTop = min(repaintTop, box->topOverflow());
+ repaintBottom = max(repaintBottom, box->bottomOverflow());
RootInlineBox* next = box->nextRootBox();
box->deleteLine(arena);
box = next;
bool endLineMatched = false;
while (!end.atEnd()) {
start = end;
- if (endLine && (endLineMatched = matchedEndLine(start, bidi.status, bidi.context.get(), cleanLineStart, cleanLineBidiStatus, cleanLineBidiContext, endLine, endLineYPos)))
+ if (endLine && (endLineMatched = matchedEndLine(start, bidi.status, bidi.context.get(), cleanLineStart, cleanLineBidiStatus, cleanLineBidiContext, endLine, endLineYPos, repaintBottom, repaintTop)))
break;
betweenMidpoints = false;
bidi.adjustEmbedding = false;
}
- if (lineBox)
+ if (lineBox) {
lineBox->setLineBreakInfo(end.obj, end.pos, &bidi.status, bidi.context.get());
+ if (useRepaintRect) {
+ repaintTop = min(repaintTop, lineBox->topOverflow());
+ repaintBottom = max(repaintBottom, lineBox->bottomOverflow());
+ }
+ }
m_firstLine = false;
newLine();
if (endLine) {
if (endLineMatched) {
- // Note our current y-position for correct repainting when no lines move. If no lines move, we still have to
- // repaint up to the maximum of the bottom overflow of the old start line or the bottom overflow of the new last line.
- int currYPos = max(startLineBottom, m_height);
- if (lastRootBox())
- currYPos = max(currYPos, lastRootBox()->bottomOverflow());
-
// Attach all the remaining lines, and then adjust their y-positions as needed.
for (RootInlineBox* line = endLine; line; line = line->nextRootBox())
line->attachLine();
// Now apply the offset to each line if needed.
int delta = m_height - endLineYPos;
if (delta) {
- for (RootInlineBox* line = endLine; line; line = line->nextRootBox())
+ for (RootInlineBox* line = endLine; line; line = line->nextRootBox()) {
+ repaintTop = min(repaintTop, line->topOverflow() + (delta < 0 ? delta : 0));
+ repaintBottom = max(repaintBottom, line->bottomOverflow() + (delta > 0 ? delta : 0));
line->adjustPosition(0, delta);
+ }
}
m_height = lastRootBox()->blockHeight();
- m_overflowHeight = max(m_height, m_overflowHeight);
- int bottomOfLine = lastRootBox()->bottomOverflow();
- if (bottomOfLine > m_height && bottomOfLine > m_overflowHeight)
- m_overflowHeight = bottomOfLine;
- if (delta)
- repaintRect.setHeight(max(m_overflowHeight-delta, m_overflowHeight) - repaintRect.y());
- else
- repaintRect.setHeight(currYPos - repaintRect.y());
- }
- else {
+ } else {
// Delete all the remaining lines.
- m_overflowHeight = max(m_height, m_overflowHeight);
InlineRunBox* line = endLine;
RenderArena* arena = renderArena();
while (line) {
+ repaintTop = min(repaintTop, line->topOverflow());
+ repaintBottom = max(repaintBottom, line->bottomOverflow());
InlineRunBox* next = line->nextLineBox();
- if (!next)
- repaintRect.setHeight(max(m_overflowHeight, line->bottomOverflow()) - repaintRect.y());
line->deleteLine(arena);
line = next;
}
// See if any lines spill out of the block. If so, we need to update our overflow width.
checkLinesForOverflow();
+ IntRect repaintRect(0, 0, 0, 0);
if (useRepaintRect) {
repaintRect.setX(m_overflowLeft);
- repaintRect.setWidth(max((int)m_width, m_overflowWidth) - m_overflowLeft);
- if (repaintRect.height() == 0)
- repaintRect.setHeight(max(oldLineBottom, m_overflowHeight) - repaintRect.y());
+ repaintRect.setWidth(m_overflowWidth - m_overflowLeft);
+ repaintRect.setY(repaintTop);
+ repaintRect.setHeight(repaintBottom - repaintTop);
if (hasOverflowClip())
// Don't allow this rect to spill out of our overflow box.
repaintRect.intersect(IntRect(0, 0, m_width, m_height));
previousLineBrokeCleanly = !last || last->endsWithBreak();
if (last) {
m_height = last->blockHeight();
- int bottomOfLine = last->bottomOverflow();
- if (bottomOfLine > m_height && bottomOfLine > m_overflowHeight)
- m_overflowHeight = bottomOfLine;
startObj = last->lineBreakObj();
pos = last->lineBreakPos();
bidi.status = last->lineBreakBidiStatus();
cleanLineStart = BidiIterator(this, prev->lineBreakObj(), prev->lineBreakPos());
cleanLineBidiStatus = prev->lineBreakBidiStatus();
cleanLineBidiContext = prev->lineBreakBidiContext();
- yPos = last->prevRootBox()->blockHeight();
+ yPos = prev->blockHeight();
for (RootInlineBox* line = last; line; line = line->nextRootBox())
line->extractLine(); // Disconnect all line boxes from their render objects while preserving
}
bool RenderBlock::matchedEndLine(const BidiIterator& start, const BidiStatus& status, BidiContext* context,
- const BidiIterator& endLineStart, const BidiStatus& endLineStatus,
- BidiContext* endLineContext, RootInlineBox*& endLine, int& endYPos)
+ const BidiIterator& endLineStart, const BidiStatus& endLineStatus, BidiContext* endLineContext,
+ RootInlineBox*& endLine, int& endYPos, int& repaintBottom, int& repaintTop)
{
if (start == endLineStart)
return status == endLineStatus && *context == *endLineContext;
RootInlineBox* boxToDelete = endLine;
RenderArena* arena = renderArena();
while (boxToDelete && boxToDelete != result) {
+ repaintTop = min(repaintTop, boxToDelete->topOverflow());
+ repaintBottom = max(repaintBottom, boxToDelete->bottomOverflow());
RootInlineBox* next = boxToDelete->nextRootBox();
boxToDelete->deleteLine(arena);
boxToDelete = next;
void RenderBlock::checkLinesForOverflow()
{
- // FIXME: Inline blocks can have overflow. Need to understand when those objects are present on a line
- // and factor that in somehow.
m_overflowWidth = m_width;
for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
m_overflowLeft = min(curr->leftOverflow(), m_overflowLeft);