OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
reserved. |
3 * | 3 * |
4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { | 67 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { |
68 if (curr->isInlineFlowBox()) | 68 if (curr->isInlineFlowBox()) |
69 totWidth += toInlineFlowBox(curr)->getFlowSpacingLogicalWidth(); | 69 totWidth += toInlineFlowBox(curr)->getFlowSpacingLogicalWidth(); |
70 } | 70 } |
71 return totWidth; | 71 return totWidth; |
72 } | 72 } |
73 | 73 |
74 IntRect InlineFlowBox::roundedFrameRect() const | 74 IntRect InlineFlowBox::roundedFrameRect() const |
75 { | 75 { |
76 // Begin by snapping the x and y coordinates to the nearest pixel. | 76 // Begin by snapping the x and y coordinates to the nearest pixel. |
77 int snappedX = lroundf(x()); | 77 int snappedX = LAYOUT_UNIT_ROUND(x()); |
78 int snappedY = lroundf(y()); | 78 int snappedY = LAYOUT_UNIT_ROUND(y()); |
79 | 79 |
80 int snappedMaxX = lroundf(x() + width()); | 80 int snappedMaxX = LAYOUT_UNIT_ROUND(x() + width()); |
81 int snappedMaxY = lroundf(y() + height()); | 81 int snappedMaxY = LAYOUT_UNIT_ROUND(y() + height()); |
82 | 82 |
83 return IntRect(snappedX, snappedY, snappedMaxX - snappedX, snappedMaxY - sna
ppedY); | 83 return IntRect(snappedX, snappedY, snappedMaxX - snappedX, snappedMaxY - sna
ppedY); |
84 } | 84 } |
85 | 85 |
86 static void setHasTextDescendantsOnAncestors(InlineFlowBox* box) | 86 static void setHasTextDescendantsOnAncestors(InlineFlowBox* box) |
87 { | 87 { |
88 while (box && !box->hasTextDescendants()) { | 88 while (box && !box->hasTextDescendants()) { |
89 box->setHasTextDescendants(); | 89 box->setHasTextDescendants(); |
90 box = box->parent(); | 90 box = box->parent(); |
91 } | 91 } |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 attachLineBoxToRenderObject(); | 247 attachLineBoxToRenderObject(); |
248 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) | 248 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) |
249 child->attachLine(); | 249 child->attachLine(); |
250 } | 250 } |
251 | 251 |
252 void InlineFlowBox::attachLineBoxToRenderObject() | 252 void InlineFlowBox::attachLineBoxToRenderObject() |
253 { | 253 { |
254 rendererLineBoxes()->attachLineBox(this); | 254 rendererLineBoxes()->attachLineBox(this); |
255 } | 255 } |
256 | 256 |
257 void InlineFlowBox::adjustPosition(float dx, float dy) | 257 void InlineFlowBox::adjustPosition(FloatWillBeLayoutUnit dx, FloatWillBeLayoutUn
it dy) |
258 { | 258 { |
259 InlineBox::adjustPosition(dx, dy); | 259 InlineBox::adjustPosition(dx, dy); |
260 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) | 260 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) |
261 child->adjustPosition(dx, dy); | 261 child->adjustPosition(dx, dy); |
262 if (m_overflow) | 262 if (m_overflow) |
263 m_overflow->move(dx, dy); // FIXME: Rounding error here since overflow w
as pixel snapped, but nobody other than list markers passes non-integral values
here. | 263 m_overflow->move(dx, dy); // FIXME: Rounding error here since overflow w
as pixel snapped, but nobody other than list markers passes non-integral values
here. |
264 } | 264 } |
265 | 265 |
266 RenderLineBoxList* InlineFlowBox::rendererLineBoxes() const | 266 RenderLineBoxList* InlineFlowBox::rendererLineBoxes() const |
267 { | 267 { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 | 352 |
353 // Recur into our children. | 353 // Recur into our children. |
354 for (InlineBox* currChild = firstChild(); currChild; currChild = currChild->
nextOnLine()) { | 354 for (InlineBox* currChild = firstChild(); currChild; currChild = currChild->
nextOnLine()) { |
355 if (currChild->isInlineFlowBox()) { | 355 if (currChild->isInlineFlowBox()) { |
356 InlineFlowBox* currFlow = toInlineFlowBox(currChild); | 356 InlineFlowBox* currFlow = toInlineFlowBox(currChild); |
357 currFlow->determineSpacingForFlowBoxes(lastLine, isLogicallyLastRunW
rapped, logicallyLastRunRenderer); | 357 currFlow->determineSpacingForFlowBoxes(lastLine, isLogicallyLastRunW
rapped, logicallyLastRunRenderer); |
358 } | 358 } |
359 } | 359 } |
360 } | 360 } |
361 | 361 |
362 float InlineFlowBox::placeBoxesInInlineDirection(float logicalLeft, bool& needsW
ordSpacing) | 362 FloatWillBeLayoutUnit InlineFlowBox::placeBoxesInInlineDirection(FloatWillBeLayo
utUnit logicalLeft, bool& needsWordSpacing) |
363 { | 363 { |
364 // Set our x position. | 364 // Set our x position. |
365 beginPlacingBoxRangesInInlineDirection(logicalLeft); | 365 beginPlacingBoxRangesInInlineDirection(logicalLeft); |
366 | 366 |
367 float startLogicalLeft = logicalLeft; | 367 FloatWillBeLayoutUnit startLogicalLeft = logicalLeft; |
368 logicalLeft += borderLogicalLeft() + paddingLogicalLeft(); | 368 logicalLeft += borderLogicalLeft() + paddingLogicalLeft(); |
369 | 369 |
370 float minLogicalLeft = startLogicalLeft; | 370 FloatWillBeLayoutUnit minLogicalLeft = startLogicalLeft; |
371 float maxLogicalRight = logicalLeft; | 371 FloatWillBeLayoutUnit maxLogicalRight = logicalLeft; |
372 | 372 |
373 placeBoxRangeInInlineDirection(firstChild(), 0, logicalLeft, minLogicalLeft,
maxLogicalRight, needsWordSpacing); | 373 placeBoxRangeInInlineDirection(firstChild(), 0, logicalLeft, minLogicalLeft,
maxLogicalRight, needsWordSpacing); |
374 | 374 |
375 logicalLeft += borderLogicalRight() + paddingLogicalRight(); | 375 logicalLeft += borderLogicalRight() + paddingLogicalRight(); |
376 endPlacingBoxRangesInInlineDirection(startLogicalLeft, logicalLeft, minLogic
alLeft, maxLogicalRight); | 376 endPlacingBoxRangesInInlineDirection(startLogicalLeft, logicalLeft, minLogic
alLeft, maxLogicalRight); |
377 return logicalLeft; | 377 return logicalLeft; |
378 } | 378 } |
379 | 379 |
380 float InlineFlowBox::placeBoxRangeInInlineDirection(InlineBox* firstChild, Inlin
eBox* lastChild, | 380 FloatWillBeLayoutUnit InlineFlowBox::placeBoxRangeInInlineDirection(InlineBox* f
irstChild, InlineBox* lastChild, |
381 float& logicalLeft, float& minLogicalLeft, float& maxLogicalRight, bool& nee
dsWordSpacing) | 381 FloatWillBeLayoutUnit& logicalLeft, FloatWillBeLayoutUnit& minLogicalLeft, F
loatWillBeLayoutUnit& maxLogicalRight, bool& needsWordSpacing) |
382 { | 382 { |
383 for (InlineBox* curr = firstChild; curr && curr != lastChild; curr = curr->n
extOnLine()) { | 383 for (InlineBox* curr = firstChild; curr && curr != lastChild; curr = curr->n
extOnLine()) { |
384 if (curr->renderer().isText()) { | 384 if (curr->renderer().isText()) { |
385 InlineTextBox* text = toInlineTextBox(curr); | 385 InlineTextBox* text = toInlineTextBox(curr); |
386 RenderText& rt = text->renderer(); | 386 RenderText& rt = text->renderer(); |
387 float space = 0; | 387 FloatWillBeLayoutUnit space = 0; |
388 if (rt.textLength()) { | 388 if (rt.textLength()) { |
389 if (needsWordSpacing && isSpaceOrNewline(rt.characterAt(text->st
art()))) | 389 if (needsWordSpacing && isSpaceOrNewline(rt.characterAt(text->st
art()))) |
390 space = rt.style(isFirstLineStyle())->font().fontDescription
().wordSpacing(); | 390 space = rt.style(isFirstLineStyle())->font().fontDescription
().wordSpacing(); |
391 needsWordSpacing = !isSpaceOrNewline(rt.characterAt(text->end())
); | 391 needsWordSpacing = !isSpaceOrNewline(rt.characterAt(text->end())
); |
392 } | 392 } |
393 if (isLeftToRightDirection()) { | 393 if (isLeftToRightDirection()) { |
394 logicalLeft += space; | 394 logicalLeft += space; |
395 text->setLogicalLeft(logicalLeft); | 395 text->setLogicalLeft(logicalLeft); |
396 } else { | 396 } else { |
397 text->setLogicalLeft(logicalLeft); | 397 text->setLogicalLeft(logicalLeft); |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 if (maxPositionBottom < boxHeight) | 580 if (maxPositionBottom < boxHeight) |
581 maxPositionBottom = boxHeight; | 581 maxPositionBottom = boxHeight; |
582 } else if (!inlineFlowBox || strictMode || inlineFlowBox->hasTextChildre
n() || (inlineFlowBox->descendantsHaveSameLineHeightAndBaseline() && inlineFlowB
ox->hasTextDescendants()) | 582 } else if (!inlineFlowBox || strictMode || inlineFlowBox->hasTextChildre
n() || (inlineFlowBox->descendantsHaveSameLineHeightAndBaseline() && inlineFlowB
ox->hasTextDescendants()) |
583 || inlineFlowBox->boxModelObject()->hasInlineDirectionBorders
OrPadding()) { | 583 || inlineFlowBox->boxModelObject()->hasInlineDirectionBorders
OrPadding()) { |
584 // Note that these values can be negative. Even though we only affe
ct the maxAscent and maxDescent values | 584 // Note that these values can be negative. Even though we only affe
ct the maxAscent and maxDescent values |
585 // if our box (excluding line-height) was above (for ascent) or belo
w (for descent) the root baseline, once you factor in line-height | 585 // if our box (excluding line-height) was above (for ascent) or belo
w (for descent) the root baseline, once you factor in line-height |
586 // the final box can end up being fully above or fully below the roo
t box's baseline! This is ok, but what it | 586 // the final box can end up being fully above or fully below the roo
t box's baseline! This is ok, but what it |
587 // means is that ascent and descent (including leading), can end up
being negative. The setMaxAscent and | 587 // means is that ascent and descent (including leading), can end up
being negative. The setMaxAscent and |
588 // setMaxDescent booleans are used to ensure that we're willing to i
nitially set maxAscent/Descent to negative | 588 // setMaxDescent booleans are used to ensure that we're willing to i
nitially set maxAscent/Descent to negative |
589 // values. | 589 // values. |
590 ascent -= curr->logicalTop(); | 590 ascent -= WILL_BE_LAYOUT_UNIT_TO_INT(curr->logicalTop()); |
591 descent += curr->logicalTop(); | 591 descent += WILL_BE_LAYOUT_UNIT_TO_INT(curr->logicalTop()); |
592 if (affectsAscent && (maxAscent < ascent || !setMaxAscent)) { | 592 if (affectsAscent && (maxAscent < ascent || !setMaxAscent)) { |
593 maxAscent = ascent; | 593 maxAscent = ascent; |
594 setMaxAscent = true; | 594 setMaxAscent = true; |
595 } | 595 } |
596 | 596 |
597 if (affectsDescent && (maxDescent < descent || !setMaxDescent)) { | 597 if (affectsDescent && (maxDescent < descent || !setMaxDescent)) { |
598 maxDescent = descent; | 598 maxDescent = descent; |
599 setMaxDescent = true; | 599 setMaxDescent = true; |
600 } | 600 } |
601 } | 601 } |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
736 selectionBottom = std::max<LayoutUnit>(selectionBottom, pixelSnapped
LogicalBottom()); | 736 selectionBottom = std::max<LayoutUnit>(selectionBottom, pixelSnapped
LogicalBottom()); |
737 lineBottom = std::max<LayoutUnit>(lineBottom, pixelSnappedLogicalBot
tom()); | 737 lineBottom = std::max<LayoutUnit>(lineBottom, pixelSnappedLogicalBot
tom()); |
738 lineBottomIncludingMargins = std::max(lineBottom, lineBottomIncludin
gMargins); | 738 lineBottomIncludingMargins = std::max(lineBottom, lineBottomIncludin
gMargins); |
739 } | 739 } |
740 | 740 |
741 if (renderer().style()->isFlippedLinesWritingMode()) | 741 if (renderer().style()->isFlippedLinesWritingMode()) |
742 flipLinesInBlockDirection(lineTopIncludingMargins, lineBottomIncludi
ngMargins); | 742 flipLinesInBlockDirection(lineTopIncludingMargins, lineBottomIncludi
ngMargins); |
743 } | 743 } |
744 } | 744 } |
745 | 745 |
746 void InlineFlowBox::computeMaxLogicalTop(float& maxLogicalTop) const | 746 void InlineFlowBox::computeMaxLogicalTop(FloatWillBeLayoutUnit& maxLogicalTop) c
onst |
747 { | 747 { |
748 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { | 748 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { |
749 if (curr->renderer().isOutOfFlowPositioned()) | 749 if (curr->renderer().isOutOfFlowPositioned()) |
750 continue; // Positioned placeholders don't affect calculations. | 750 continue; // Positioned placeholders don't affect calculations. |
751 | 751 |
752 if (descendantsHaveSameLineHeightAndBaseline()) | 752 if (descendantsHaveSameLineHeightAndBaseline()) |
753 continue; | 753 continue; |
754 | 754 |
755 maxLogicalTop = std::max<float>(maxLogicalTop, curr->y()); | 755 maxLogicalTop = std::max<FloatWillBeLayoutUnit>(maxLogicalTop, curr->y()
); |
756 float localMaxLogicalTop = 0; | 756 FloatWillBeLayoutUnit localMaxLogicalTop = 0; |
757 if (curr->isInlineFlowBox()) | 757 if (curr->isInlineFlowBox()) |
758 toInlineFlowBox(curr)->computeMaxLogicalTop(localMaxLogicalTop); | 758 toInlineFlowBox(curr)->computeMaxLogicalTop(localMaxLogicalTop); |
759 maxLogicalTop = std::max<float>(maxLogicalTop, localMaxLogicalTop); | 759 maxLogicalTop = std::max<FloatWillBeLayoutUnit>(maxLogicalTop, localMaxL
ogicalTop); |
760 } | 760 } |
761 } | 761 } |
762 | 762 |
763 void InlineFlowBox::flipLinesInBlockDirection(LayoutUnit lineTop, LayoutUnit lin
eBottom) | 763 void InlineFlowBox::flipLinesInBlockDirection(LayoutUnit lineTop, LayoutUnit lin
eBottom) |
764 { | 764 { |
765 // Flip the box on the line such that the top is now relative to the lineBot
tom instead of the lineTop. | 765 // Flip the box on the line such that the top is now relative to the lineBot
tom instead of the lineTop. |
766 setLogicalTop(lineBottom - (logicalTop() - lineTop) - logicalHeight()); | 766 setLogicalTop(lineBottom - (logicalTop() - lineTop) - logicalHeight()); |
767 | 767 |
768 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { | 768 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { |
769 if (curr->renderer().isOutOfFlowPositioned()) | 769 if (curr->renderer().isOutOfFlowPositioned()) |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 | 1134 |
1135 bool InlineFlowBox::canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsis
Width) const | 1135 bool InlineFlowBox::canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsis
Width) const |
1136 { | 1136 { |
1137 for (InlineBox *box = firstChild(); box; box = box->nextOnLine()) { | 1137 for (InlineBox *box = firstChild(); box; box = box->nextOnLine()) { |
1138 if (!box->canAccommodateEllipsis(ltr, blockEdge, ellipsisWidth)) | 1138 if (!box->canAccommodateEllipsis(ltr, blockEdge, ellipsisWidth)) |
1139 return false; | 1139 return false; |
1140 } | 1140 } |
1141 return true; | 1141 return true; |
1142 } | 1142 } |
1143 | 1143 |
1144 float InlineFlowBox::placeEllipsisBox(bool ltr, float blockLeftEdge, float block
RightEdge, float ellipsisWidth, float &truncatedWidth, bool& foundBox) | 1144 FloatWillBeLayoutUnit InlineFlowBox::placeEllipsisBox(bool ltr, FloatWillBeLayou
tUnit blockLeftEdge, FloatWillBeLayoutUnit blockRightEdge, FloatWillBeLayoutUnit
ellipsisWidth, FloatWillBeLayoutUnit &truncatedWidth, bool& foundBox) |
1145 { | 1145 { |
1146 float result = -1; | 1146 FloatWillBeLayoutUnit result = -1; |
1147 // We iterate over all children, the foundBox variable tells us when we've f
ound the | 1147 // We iterate over all children, the foundBox variable tells us when we've f
ound the |
1148 // box containing the ellipsis. All boxes after that one in the flow are hi
dden. | 1148 // box containing the ellipsis. All boxes after that one in the flow are hi
dden. |
1149 // If our flow is ltr then iterate over the boxes from left to right, otherw
ise iterate | 1149 // If our flow is ltr then iterate over the boxes from left to right, otherw
ise iterate |
1150 // from right to left. Varying the order allows us to correctly hide the box
es following the ellipsis. | 1150 // from right to left. Varying the order allows us to correctly hide the box
es following the ellipsis. |
1151 InlineBox* box = ltr ? firstChild() : lastChild(); | 1151 InlineBox* box = ltr ? firstChild() : lastChild(); |
1152 | 1152 |
1153 // NOTE: these will cross after foundBox = true. | 1153 // NOTE: these will cross after foundBox = true. |
1154 int visibleLeftEdge = blockLeftEdge; | 1154 int visibleLeftEdge = blockLeftEdge; |
1155 int visibleRightEdge = blockRightEdge; | 1155 int visibleRightEdge = blockRightEdge; |
1156 | 1156 |
1157 while (box) { | 1157 while (box) { |
1158 int currResult = box->placeEllipsisBox(ltr, visibleLeftEdge, visibleRigh
tEdge, ellipsisWidth, truncatedWidth, foundBox); | 1158 int currResult = box->placeEllipsisBox(ltr, visibleLeftEdge, visibleRigh
tEdge, ellipsisWidth, truncatedWidth, foundBox); |
1159 if (currResult != -1 && result == -1) | 1159 if (currResult != -1 && result == -1) |
1160 result = currResult; | 1160 result = currResult; |
1161 | 1161 |
1162 if (ltr) { | 1162 if (ltr) { |
1163 visibleLeftEdge += box->logicalWidth(); | 1163 visibleLeftEdge += WILL_BE_LAYOUT_UNIT_TO_INT(box->logicalWidth()); |
1164 box = box->nextOnLine(); | 1164 box = box->nextOnLine(); |
1165 } | 1165 } |
1166 else { | 1166 else { |
1167 visibleRightEdge -= box->logicalWidth(); | 1167 visibleRightEdge -= WILL_BE_LAYOUT_UNIT_TO_INT(box->logicalWidth()); |
1168 box = box->prevOnLine(); | 1168 box = box->prevOnLine(); |
1169 } | 1169 } |
1170 } | 1170 } |
1171 return result; | 1171 return result; |
1172 } | 1172 } |
1173 | 1173 |
1174 void InlineFlowBox::clearTruncation() | 1174 void InlineFlowBox::clearTruncation() |
1175 { | 1175 { |
1176 for (InlineBox *box = firstChild(); box; box = box->nextOnLine()) | 1176 for (InlineBox *box = firstChild(); box; box = box->nextOnLine()) |
1177 box->clearTruncation(); | 1177 box->clearTruncation(); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 ASSERT(child->prevOnLine() == prev); | 1352 ASSERT(child->prevOnLine() == prev); |
1353 prev = child; | 1353 prev = child; |
1354 } | 1354 } |
1355 ASSERT(prev == m_lastChild); | 1355 ASSERT(prev == m_lastChild); |
1356 #endif | 1356 #endif |
1357 } | 1357 } |
1358 | 1358 |
1359 #endif | 1359 #endif |
1360 | 1360 |
1361 } // namespace blink | 1361 } // namespace blink |
OLD | NEW |