| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2003, 2006, 2008 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 29 matching lines...) Expand all Loading... |
| 40 struct SameSizeAsRootInlineBox : public InlineFlowBox { | 40 struct SameSizeAsRootInlineBox : public InlineFlowBox { |
| 41 unsigned variables[5]; | 41 unsigned variables[5]; |
| 42 void* pointers[4]; | 42 void* pointers[4]; |
| 43 }; | 43 }; |
| 44 | 44 |
| 45 COMPILE_ASSERT(sizeof(RootInlineBox) == sizeof(SameSizeAsRootInlineBox), RootInl
ineBox_should_stay_small); | 45 COMPILE_ASSERT(sizeof(RootInlineBox) == sizeof(SameSizeAsRootInlineBox), RootInl
ineBox_should_stay_small); |
| 46 | 46 |
| 47 typedef WTF::HashMap<const RootInlineBox*, EllipsisBox*> EllipsisBoxMap; | 47 typedef WTF::HashMap<const RootInlineBox*, EllipsisBox*> EllipsisBoxMap; |
| 48 static EllipsisBoxMap* gEllipsisBoxMap = 0; | 48 static EllipsisBoxMap* gEllipsisBoxMap = 0; |
| 49 | 49 |
| 50 RootInlineBox::RootInlineBox(RenderBlockFlow* block) | 50 RootInlineBox::RootInlineBox(RenderBlockFlow& block) |
| 51 : InlineFlowBox(block) | 51 : InlineFlowBox(block) |
| 52 , m_lineBreakPos(0) | 52 , m_lineBreakPos(0) |
| 53 , m_lineBreakObj(0) | 53 , m_lineBreakObj(0) |
| 54 , m_lineTop(0) | 54 , m_lineTop(0) |
| 55 , m_lineBottom(0) | 55 , m_lineBottom(0) |
| 56 , m_lineTopWithLeading(0) | 56 , m_lineTopWithLeading(0) |
| 57 , m_lineBottomWithLeading(0) | 57 , m_lineBottomWithLeading(0) |
| 58 { | 58 { |
| 59 setIsHorizontal(block->isHorizontalWritingMode()); | 59 setIsHorizontal(block.isHorizontalWritingMode()); |
| 60 } | 60 } |
| 61 | 61 |
| 62 | 62 |
| 63 void RootInlineBox::destroy() | 63 void RootInlineBox::destroy() |
| 64 { | 64 { |
| 65 detachEllipsisBox(); | 65 detachEllipsisBox(); |
| 66 InlineFlowBox::destroy(); | 66 InlineFlowBox::destroy(); |
| 67 } | 67 } |
| 68 | 68 |
| 69 void RootInlineBox::detachEllipsisBox() | 69 void RootInlineBox::detachEllipsisBox() |
| 70 { | 70 { |
| 71 if (hasEllipsisBox()) { | 71 if (hasEllipsisBox()) { |
| 72 EllipsisBox* box = gEllipsisBoxMap->take(this); | 72 EllipsisBox* box = gEllipsisBoxMap->take(this); |
| 73 box->setParent(0); | 73 box->setParent(0); |
| 74 box->destroy(); | 74 box->destroy(); |
| 75 setHasEllipsisBox(false); | 75 setHasEllipsisBox(false); |
| 76 } | 76 } |
| 77 } | 77 } |
| 78 | 78 |
| 79 RenderLineBoxList* RootInlineBox::rendererLineBoxes() const | 79 RenderLineBoxList* RootInlineBox::rendererLineBoxes() const |
| 80 { | 80 { |
| 81 return block()->lineBoxes(); | 81 return block().lineBoxes(); |
| 82 } | 82 } |
| 83 | 83 |
| 84 void RootInlineBox::clearTruncation() | 84 void RootInlineBox::clearTruncation() |
| 85 { | 85 { |
| 86 if (hasEllipsisBox()) { | 86 if (hasEllipsisBox()) { |
| 87 detachEllipsisBox(); | 87 detachEllipsisBox(); |
| 88 InlineFlowBox::clearTruncation(); | 88 InlineFlowBox::clearTruncation(); |
| 89 } | 89 } |
| 90 } | 90 } |
| 91 | 91 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 float result = InlineFlowBox::placeEllipsisBox(ltr, blockLeftEdge, blockRigh
tEdge, ellipsisWidth, truncatedWidth, foundBox); | 157 float result = InlineFlowBox::placeEllipsisBox(ltr, blockLeftEdge, blockRigh
tEdge, ellipsisWidth, truncatedWidth, foundBox); |
| 158 if (result == -1) { | 158 if (result == -1) { |
| 159 result = ltr ? blockRightEdge - ellipsisWidth : blockLeftEdge; | 159 result = ltr ? blockRightEdge - ellipsisWidth : blockLeftEdge; |
| 160 truncatedWidth = blockRightEdge - blockLeftEdge; | 160 truncatedWidth = blockRightEdge - blockLeftEdge; |
| 161 } | 161 } |
| 162 return result; | 162 return result; |
| 163 } | 163 } |
| 164 | 164 |
| 165 void RootInlineBox::paintEllipsisBox(PaintInfo& paintInfo, const LayoutPoint& pa
intOffset, LayoutUnit lineTop, LayoutUnit lineBottom) const | 165 void RootInlineBox::paintEllipsisBox(PaintInfo& paintInfo, const LayoutPoint& pa
intOffset, LayoutUnit lineTop, LayoutUnit lineBottom) const |
| 166 { | 166 { |
| 167 if (hasEllipsisBox() && paintInfo.shouldPaintWithinRoot(renderer()) && rende
rer()->style()->visibility() == VISIBLE | 167 if (hasEllipsisBox() && paintInfo.shouldPaintWithinRoot(&renderer()) && rend
erer().style()->visibility() == VISIBLE |
| 168 && paintInfo.phase == PaintPhaseForeground) | 168 && paintInfo.phase == PaintPhaseForeground) |
| 169 ellipsisBox()->paint(paintInfo, paintOffset, lineTop, lineBottom); | 169 ellipsisBox()->paint(paintInfo, paintOffset, lineTop, lineBottom); |
| 170 } | 170 } |
| 171 | 171 |
| 172 void RootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
LayoutUnit lineTop, LayoutUnit lineBottom) | 172 void RootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
LayoutUnit lineTop, LayoutUnit lineBottom) |
| 173 { | 173 { |
| 174 InlineFlowBox::paint(paintInfo, paintOffset, lineTop, lineBottom); | 174 InlineFlowBox::paint(paintInfo, paintOffset, lineTop, lineBottom); |
| 175 paintEllipsisBox(paintInfo, paintOffset, lineTop, lineBottom); | 175 paintEllipsisBox(paintInfo, paintOffset, lineTop, lineBottom); |
| 176 } | 176 } |
| 177 | 177 |
| 178 bool RootInlineBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated
Offset, LayoutUnit lineTop, LayoutUnit lineBottom) | 178 bool RootInlineBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated
Offset, LayoutUnit lineTop, LayoutUnit lineBottom) |
| 179 { | 179 { |
| 180 if (hasEllipsisBox() && visibleToHitTestRequest(request)) { | 180 if (hasEllipsisBox() && visibleToHitTestRequest(request)) { |
| 181 if (ellipsisBox()->nodeAtPoint(request, result, locationInContainer, acc
umulatedOffset, lineTop, lineBottom)) { | 181 if (ellipsisBox()->nodeAtPoint(request, result, locationInContainer, acc
umulatedOffset, lineTop, lineBottom)) { |
| 182 renderer()->updateHitTestResult(result, locationInContainer.point()
- toLayoutSize(accumulatedOffset)); | 182 renderer().updateHitTestResult(result, locationInContainer.point() -
toLayoutSize(accumulatedOffset)); |
| 183 return true; | 183 return true; |
| 184 } | 184 } |
| 185 } | 185 } |
| 186 return InlineFlowBox::nodeAtPoint(request, result, locationInContainer, accu
mulatedOffset, lineTop, lineBottom); | 186 return InlineFlowBox::nodeAtPoint(request, result, locationInContainer, accu
mulatedOffset, lineTop, lineBottom); |
| 187 } | 187 } |
| 188 | 188 |
| 189 void RootInlineBox::adjustPosition(float dx, float dy) | 189 void RootInlineBox::adjustPosition(float dx, float dy) |
| 190 { | 190 { |
| 191 InlineFlowBox::adjustPosition(dx, dy); | 191 InlineFlowBox::adjustPosition(dx, dy); |
| 192 LayoutUnit blockDirectionDelta = isHorizontal() ? dy : dx; // The block dire
ction delta is a LayoutUnit. | 192 LayoutUnit blockDirectionDelta = isHorizontal() ? dy : dx; // The block dire
ction delta is a LayoutUnit. |
| 193 m_lineTop += blockDirectionDelta; | 193 m_lineTop += blockDirectionDelta; |
| 194 m_lineBottom += blockDirectionDelta; | 194 m_lineBottom += blockDirectionDelta; |
| 195 m_lineTopWithLeading += blockDirectionDelta; | 195 m_lineTopWithLeading += blockDirectionDelta; |
| 196 m_lineBottomWithLeading += blockDirectionDelta; | 196 m_lineBottomWithLeading += blockDirectionDelta; |
| 197 if (hasEllipsisBox()) | 197 if (hasEllipsisBox()) |
| 198 ellipsisBox()->adjustPosition(dx, dy); | 198 ellipsisBox()->adjustPosition(dx, dy); |
| 199 } | 199 } |
| 200 | 200 |
| 201 void RootInlineBox::childRemoved(InlineBox* box) | 201 void RootInlineBox::childRemoved(InlineBox* box) |
| 202 { | 202 { |
| 203 if (box->renderer() == m_lineBreakObj) | 203 if (&box->renderer() == m_lineBreakObj) |
| 204 setLineBreakInfo(0, 0, BidiStatus()); | 204 setLineBreakInfo(0, 0, BidiStatus()); |
| 205 | 205 |
| 206 for (RootInlineBox* prev = prevRootBox(); prev && prev->lineBreakObj() == bo
x->renderer(); prev = prev->prevRootBox()) { | 206 for (RootInlineBox* prev = prevRootBox(); prev && prev->lineBreakObj() == &b
ox->renderer(); prev = prev->prevRootBox()) { |
| 207 prev->setLineBreakInfo(0, 0, BidiStatus()); | 207 prev->setLineBreakInfo(0, 0, BidiStatus()); |
| 208 prev->markDirty(); | 208 prev->markDirty(); |
| 209 } | 209 } |
| 210 } | 210 } |
| 211 | 211 |
| 212 LayoutUnit RootInlineBox::alignBoxesInBlockDirection(LayoutUnit heightOfBlock, G
lyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& vertical
PositionCache) | 212 LayoutUnit RootInlineBox::alignBoxesInBlockDirection(LayoutUnit heightOfBlock, G
lyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& vertical
PositionCache) |
| 213 { | 213 { |
| 214 // SVG will handle vertical alignment on its own. | 214 // SVG will handle vertical alignment on its own. |
| 215 if (isSVGRootInlineBox()) | 215 if (isSVGRootInlineBox()) |
| 216 return 0; | 216 return 0; |
| 217 | 217 |
| 218 LayoutUnit maxPositionTop = 0; | 218 LayoutUnit maxPositionTop = 0; |
| 219 LayoutUnit maxPositionBottom = 0; | 219 LayoutUnit maxPositionBottom = 0; |
| 220 int maxAscent = 0; | 220 int maxAscent = 0; |
| 221 int maxDescent = 0; | 221 int maxDescent = 0; |
| 222 bool setMaxAscent = false; | 222 bool setMaxAscent = false; |
| 223 bool setMaxDescent = false; | 223 bool setMaxDescent = false; |
| 224 | 224 |
| 225 // Figure out if we're in no-quirks mode. | 225 // Figure out if we're in no-quirks mode. |
| 226 bool noQuirksMode = renderer()->document().inNoQuirksMode(); | 226 bool noQuirksMode = renderer().document().inNoQuirksMode(); |
| 227 | 227 |
| 228 m_baselineType = requiresIdeographicBaseline(textBoxDataMap) ? IdeographicBa
seline : AlphabeticBaseline; | 228 m_baselineType = requiresIdeographicBaseline(textBoxDataMap) ? IdeographicBa
seline : AlphabeticBaseline; |
| 229 | 229 |
| 230 computeLogicalBoxHeights(this, maxPositionTop, maxPositionBottom, maxAscent,
maxDescent, setMaxAscent, setMaxDescent, noQuirksMode, | 230 computeLogicalBoxHeights(this, maxPositionTop, maxPositionBottom, maxAscent,
maxDescent, setMaxAscent, setMaxDescent, noQuirksMode, |
| 231 textBoxDataMap, baselineType(), verticalPositionCac
he); | 231 textBoxDataMap, baselineType(), verticalPositionCac
he); |
| 232 | 232 |
| 233 if (maxAscent + maxDescent < max(maxPositionTop, maxPositionBottom)) | 233 if (maxAscent + maxDescent < max(maxPositionTop, maxPositionBottom)) |
| 234 adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPosi
tionBottom); | 234 adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPosi
tionBottom); |
| 235 | 235 |
| 236 LayoutUnit maxHeight = maxAscent + maxDescent; | 236 LayoutUnit maxHeight = maxAscent + maxDescent; |
| 237 LayoutUnit lineTop = heightOfBlock; | 237 LayoutUnit lineTop = heightOfBlock; |
| 238 LayoutUnit lineBottom = heightOfBlock; | 238 LayoutUnit lineBottom = heightOfBlock; |
| 239 LayoutUnit lineTopIncludingMargins = heightOfBlock; | 239 LayoutUnit lineTopIncludingMargins = heightOfBlock; |
| 240 LayoutUnit lineBottomIncludingMargins = heightOfBlock; | 240 LayoutUnit lineBottomIncludingMargins = heightOfBlock; |
| 241 bool setLineTop = false; | 241 bool setLineTop = false; |
| 242 bool hasAnnotationsBefore = false; | 242 bool hasAnnotationsBefore = false; |
| 243 bool hasAnnotationsAfter = false; | 243 bool hasAnnotationsAfter = false; |
| 244 placeBoxesInBlockDirection(heightOfBlock, maxHeight, maxAscent, noQuirksMode
, lineTop, lineBottom, setLineTop, | 244 placeBoxesInBlockDirection(heightOfBlock, maxHeight, maxAscent, noQuirksMode
, lineTop, lineBottom, setLineTop, |
| 245 lineTopIncludingMargins, lineBottomIncludingMargi
ns, hasAnnotationsBefore, hasAnnotationsAfter, baselineType()); | 245 lineTopIncludingMargins, lineBottomIncludingMargi
ns, hasAnnotationsBefore, hasAnnotationsAfter, baselineType()); |
| 246 m_hasAnnotationsBefore = hasAnnotationsBefore; | 246 m_hasAnnotationsBefore = hasAnnotationsBefore; |
| 247 m_hasAnnotationsAfter = hasAnnotationsAfter; | 247 m_hasAnnotationsAfter = hasAnnotationsAfter; |
| 248 | 248 |
| 249 maxHeight = max<LayoutUnit>(0, maxHeight); // FIXME: Is this really necessar
y? | 249 maxHeight = max<LayoutUnit>(0, maxHeight); // FIXME: Is this really necessar
y? |
| 250 | 250 |
| 251 setLineTopBottomPositions(lineTop, lineBottom, heightOfBlock, heightOfBlock
+ maxHeight); | 251 setLineTopBottomPositions(lineTop, lineBottom, heightOfBlock, heightOfBlock
+ maxHeight); |
| 252 setPaginatedLineWidth(block()->availableLogicalWidthForContent()); | 252 setPaginatedLineWidth(block().availableLogicalWidthForContent()); |
| 253 | 253 |
| 254 LayoutUnit annotationsAdjustment = beforeAnnotationsAdjustment(); | 254 LayoutUnit annotationsAdjustment = beforeAnnotationsAdjustment(); |
| 255 if (annotationsAdjustment) { | 255 if (annotationsAdjustment) { |
| 256 // FIXME: Need to handle pagination here. We might have to move to the n
ext page/column as a result of the | 256 // FIXME: Need to handle pagination here. We might have to move to the n
ext page/column as a result of the |
| 257 // ruby expansion. | 257 // ruby expansion. |
| 258 adjustBlockDirectionPosition(annotationsAdjustment); | 258 adjustBlockDirectionPosition(annotationsAdjustment); |
| 259 heightOfBlock += annotationsAdjustment; | 259 heightOfBlock += annotationsAdjustment; |
| 260 } | 260 } |
| 261 | 261 |
| 262 return heightOfBlock + maxHeight; | 262 return heightOfBlock + maxHeight; |
| 263 } | 263 } |
| 264 | 264 |
| 265 float RootInlineBox::maxLogicalTop() const | 265 float RootInlineBox::maxLogicalTop() const |
| 266 { | 266 { |
| 267 float maxLogicalTop = 0; | 267 float maxLogicalTop = 0; |
| 268 computeMaxLogicalTop(maxLogicalTop); | 268 computeMaxLogicalTop(maxLogicalTop); |
| 269 return maxLogicalTop; | 269 return maxLogicalTop; |
| 270 } | 270 } |
| 271 | 271 |
| 272 LayoutUnit RootInlineBox::beforeAnnotationsAdjustment() const | 272 LayoutUnit RootInlineBox::beforeAnnotationsAdjustment() const |
| 273 { | 273 { |
| 274 LayoutUnit result = 0; | 274 LayoutUnit result = 0; |
| 275 | 275 |
| 276 if (!renderer()->style()->isFlippedLinesWritingMode()) { | 276 if (!renderer().style()->isFlippedLinesWritingMode()) { |
| 277 // Annotations under the previous line may push us down. | 277 // Annotations under the previous line may push us down. |
| 278 if (prevRootBox() && prevRootBox()->hasAnnotationsAfter()) | 278 if (prevRootBox() && prevRootBox()->hasAnnotationsAfter()) |
| 279 result = prevRootBox()->computeUnderAnnotationAdjustment(lineTop()); | 279 result = prevRootBox()->computeUnderAnnotationAdjustment(lineTop()); |
| 280 | 280 |
| 281 if (!hasAnnotationsBefore()) | 281 if (!hasAnnotationsBefore()) |
| 282 return result; | 282 return result; |
| 283 | 283 |
| 284 // Annotations over this line may push us further down. | 284 // Annotations over this line may push us further down. |
| 285 LayoutUnit highestAllowedPosition = prevRootBox() ? min(prevRootBox()->l
ineBottom(), lineTop()) + result : static_cast<LayoutUnit>(block()->borderBefore
()); | 285 LayoutUnit highestAllowedPosition = prevRootBox() ? min(prevRootBox()->l
ineBottom(), lineTop()) + result : static_cast<LayoutUnit>(block().borderBefore(
)); |
| 286 result = computeOverAnnotationAdjustment(highestAllowedPosition); | 286 result = computeOverAnnotationAdjustment(highestAllowedPosition); |
| 287 } else { | 287 } else { |
| 288 // Annotations under this line may push us up. | 288 // Annotations under this line may push us up. |
| 289 if (hasAnnotationsBefore()) | 289 if (hasAnnotationsBefore()) |
| 290 result = computeUnderAnnotationAdjustment(prevRootBox() ? prevRootBo
x()->lineBottom() : static_cast<LayoutUnit>(block()->borderBefore())); | 290 result = computeUnderAnnotationAdjustment(prevRootBox() ? prevRootBo
x()->lineBottom() : static_cast<LayoutUnit>(block().borderBefore())); |
| 291 | 291 |
| 292 if (!prevRootBox() || !prevRootBox()->hasAnnotationsAfter()) | 292 if (!prevRootBox() || !prevRootBox()->hasAnnotationsAfter()) |
| 293 return result; | 293 return result; |
| 294 | 294 |
| 295 // We have to compute the expansion for annotations over the previous li
ne to see how much we should move. | 295 // We have to compute the expansion for annotations over the previous li
ne to see how much we should move. |
| 296 LayoutUnit lowestAllowedPosition = max(prevRootBox()->lineBottom(), line
Top()) - result; | 296 LayoutUnit lowestAllowedPosition = max(prevRootBox()->lineBottom(), line
Top()) - result; |
| 297 result = prevRootBox()->computeOverAnnotationAdjustment(lowestAllowedPos
ition); | 297 result = prevRootBox()->computeOverAnnotationAdjustment(lowestAllowedPos
ition); |
| 298 } | 298 } |
| 299 | 299 |
| 300 return result; | 300 return result; |
| 301 } | 301 } |
| 302 | 302 |
| 303 GapRects RootInlineBox::lineSelectionGap(RenderBlock* rootBlock, const LayoutPoi
nt& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, | 303 GapRects RootInlineBox::lineSelectionGap(RenderBlock* rootBlock, const LayoutPoi
nt& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, |
| 304 LayoutUnit selTop, LayoutUnit selHeight
, const PaintInfo* paintInfo) | 304 LayoutUnit selTop, LayoutUnit selHeight
, const PaintInfo* paintInfo) |
| 305 { | 305 { |
| 306 RenderObject::SelectionState lineState = selectionState(); | 306 RenderObject::SelectionState lineState = selectionState(); |
| 307 | 307 |
| 308 bool leftGap, rightGap; | 308 bool leftGap, rightGap; |
| 309 block()->getSelectionGapInfo(lineState, leftGap, rightGap); | 309 block().getSelectionGapInfo(lineState, leftGap, rightGap); |
| 310 | 310 |
| 311 GapRects result; | 311 GapRects result; |
| 312 | 312 |
| 313 InlineBox* firstBox = firstSelectedBox(); | 313 InlineBox* firstBox = firstSelectedBox(); |
| 314 InlineBox* lastBox = lastSelectedBox(); | 314 InlineBox* lastBox = lastSelectedBox(); |
| 315 if (leftGap) | 315 if (leftGap) { |
| 316 result.uniteLeft(block()->logicalLeftSelectionGap(rootBlock, rootBlockPh
ysicalPosition, offsetFromRootBlock, | 316 result.uniteLeft(block().logicalLeftSelectionGap(rootBlock, rootBlockPhy
sicalPosition, offsetFromRootBlock, |
| 317 firstBox->parent()->re
nderer(), firstBox->logicalLeft(), selTop, selHeight, paintInfo)); | 317 &firstBox->parent()->renderer(), firstBox->logicalLeft(), selTop, se
lHeight, paintInfo)); |
| 318 if (rightGap) | 318 } |
| 319 result.uniteRight(block()->logicalRightSelectionGap(rootBlock, rootBlock
PhysicalPosition, offsetFromRootBlock, | 319 if (rightGap) { |
| 320 lastBox->parent()->r
enderer(), lastBox->logicalRight(), selTop, selHeight, paintInfo)); | 320 result.uniteRight(block().logicalRightSelectionGap(rootBlock, rootBlockP
hysicalPosition, offsetFromRootBlock, |
| 321 &lastBox->parent()->renderer(), lastBox->logicalRight(), selTop, sel
Height, paintInfo)); |
| 322 } |
| 321 | 323 |
| 322 // When dealing with bidi text, a non-contiguous selection region is possibl
e. | 324 // When dealing with bidi text, a non-contiguous selection region is possibl
e. |
| 323 // e.g. The logical text aaaAAAbbb (capitals denote RTL text and non-capital
s LTR) is layed out | 325 // e.g. The logical text aaaAAAbbb (capitals denote RTL text and non-capital
s LTR) is layed out |
| 324 // visually as 3 text runs |aaa|bbb|AAA| if we select 4 characters from the
start of the text the | 326 // visually as 3 text runs |aaa|bbb|AAA| if we select 4 characters from the
start of the text the |
| 325 // selection will look like (underline denotes selection): | 327 // selection will look like (underline denotes selection): |
| 326 // |aaa|bbb|AAA| | 328 // |aaa|bbb|AAA| |
| 327 // ___ _ | 329 // ___ _ |
| 328 // We can see that the |bbb| run is not part of the selection while the runs
around it are. | 330 // We can see that the |bbb| run is not part of the selection while the runs
around it are. |
| 329 if (firstBox && firstBox != lastBox) { | 331 if (firstBox && firstBox != lastBox) { |
| 330 // Now fill in any gaps on the line that occurred between two selected e
lements. | 332 // Now fill in any gaps on the line that occurred between two selected e
lements. |
| 331 LayoutUnit lastLogicalLeft = firstBox->logicalRight(); | 333 LayoutUnit lastLogicalLeft = firstBox->logicalRight(); |
| 332 bool isPreviousBoxSelected = firstBox->selectionState() != RenderObject:
:SelectionNone; | 334 bool isPreviousBoxSelected = firstBox->selectionState() != RenderObject:
:SelectionNone; |
| 333 for (InlineBox* box = firstBox->nextLeafChild(); box; box = box->nextLea
fChild()) { | 335 for (InlineBox* box = firstBox->nextLeafChild(); box; box = box->nextLea
fChild()) { |
| 334 if (box->selectionState() != RenderObject::SelectionNone) { | 336 if (box->selectionState() != RenderObject::SelectionNone) { |
| 335 LayoutRect logicalRect(lastLogicalLeft, selTop, box->logicalLeft
() - lastLogicalLeft, selHeight); | 337 LayoutRect logicalRect(lastLogicalLeft, selTop, box->logicalLeft
() - lastLogicalLeft, selHeight); |
| 336 logicalRect.move(renderer()->isHorizontalWritingMode() ? offsetF
romRootBlock : LayoutSize(offsetFromRootBlock.height(), offsetFromRootBlock.widt
h())); | 338 logicalRect.move(renderer().isHorizontalWritingMode() ? offsetFr
omRootBlock : LayoutSize(offsetFromRootBlock.height(), offsetFromRootBlock.width
())); |
| 337 LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBl
ockPhysicalPosition, logicalRect); | 339 LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBl
ockPhysicalPosition, logicalRect); |
| 338 if (isPreviousBoxSelected && gapRect.width() > 0 && gapRect.heig
ht() > 0) { | 340 if (isPreviousBoxSelected && gapRect.width() > 0 && gapRect.heig
ht() > 0) { |
| 339 if (paintInfo && box->parent()->renderer()->style()->visibil
ity() == VISIBLE) | 341 if (paintInfo && box->parent()->renderer().style()->visibili
ty() == VISIBLE) |
| 340 paintInfo->context->fillRect(gapRect, box->parent()->ren
derer()->selectionBackgroundColor()); | 342 paintInfo->context->fillRect(gapRect, box->parent()->ren
derer().selectionBackgroundColor()); |
| 341 // VisibleSelection may be non-contiguous, see comment above
. | 343 // VisibleSelection may be non-contiguous, see comment above
. |
| 342 result.uniteCenter(gapRect); | 344 result.uniteCenter(gapRect); |
| 343 } | 345 } |
| 344 lastLogicalLeft = box->logicalRight(); | 346 lastLogicalLeft = box->logicalRight(); |
| 345 } | 347 } |
| 346 if (box == lastBox) | 348 if (box == lastBox) |
| 347 break; | 349 break; |
| 348 isPreviousBoxSelected = box->selectionState() != RenderObject::Selec
tionNone; | 350 isPreviousBoxSelected = box->selectionState() != RenderObject::Selec
tionNone; |
| 349 } | 351 } |
| 350 } | 352 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 } | 396 } |
| 395 | 397 |
| 396 return 0; | 398 return 0; |
| 397 } | 399 } |
| 398 | 400 |
| 399 LayoutUnit RootInlineBox::selectionTop() const | 401 LayoutUnit RootInlineBox::selectionTop() const |
| 400 { | 402 { |
| 401 LayoutUnit selectionTop = m_lineTop; | 403 LayoutUnit selectionTop = m_lineTop; |
| 402 | 404 |
| 403 if (m_hasAnnotationsBefore) | 405 if (m_hasAnnotationsBefore) |
| 404 selectionTop -= !renderer()->style()->isFlippedLinesWritingMode() ? comp
uteOverAnnotationAdjustment(m_lineTop) : computeUnderAnnotationAdjustment(m_line
Top); | 406 selectionTop -= !renderer().style()->isFlippedLinesWritingMode() ? compu
teOverAnnotationAdjustment(m_lineTop) : computeUnderAnnotationAdjustment(m_lineT
op); |
| 405 | 407 |
| 406 if (renderer()->style()->isFlippedLinesWritingMode() || !prevRootBox()) | 408 if (renderer().style()->isFlippedLinesWritingMode() || !prevRootBox()) |
| 407 return selectionTop; | 409 return selectionTop; |
| 408 | 410 |
| 409 LayoutUnit prevBottom = prevRootBox()->selectionBottom(); | 411 LayoutUnit prevBottom = prevRootBox()->selectionBottom(); |
| 410 if (prevBottom < selectionTop && block()->containsFloats()) { | 412 if (prevBottom < selectionTop && block().containsFloats()) { |
| 411 // This line has actually been moved further down, probably from a large
line-height, but possibly because the | 413 // This line has actually been moved further down, probably from a large
line-height, but possibly because the |
| 412 // line was forced to clear floats. If so, let's check the offsets, and
only be willing to use the previous | 414 // line was forced to clear floats. If so, let's check the offsets, and
only be willing to use the previous |
| 413 // line's bottom if the offsets are greater on both sides. | 415 // line's bottom if the offsets are greater on both sides. |
| 414 LayoutUnit prevLeft = block()->logicalLeftOffsetForLine(prevBottom, fals
e); | 416 LayoutUnit prevLeft = block().logicalLeftOffsetForLine(prevBottom, false
); |
| 415 LayoutUnit prevRight = block()->logicalRightOffsetForLine(prevBottom, fa
lse); | 417 LayoutUnit prevRight = block().logicalRightOffsetForLine(prevBottom, fal
se); |
| 416 LayoutUnit newLeft = block()->logicalLeftOffsetForLine(selectionTop, fal
se); | 418 LayoutUnit newLeft = block().logicalLeftOffsetForLine(selectionTop, fals
e); |
| 417 LayoutUnit newRight = block()->logicalRightOffsetForLine(selectionTop, f
alse); | 419 LayoutUnit newRight = block().logicalRightOffsetForLine(selectionTop, fa
lse); |
| 418 if (prevLeft > newLeft || prevRight < newRight) | 420 if (prevLeft > newLeft || prevRight < newRight) |
| 419 return selectionTop; | 421 return selectionTop; |
| 420 } | 422 } |
| 421 | 423 |
| 422 return prevBottom; | 424 return prevBottom; |
| 423 } | 425 } |
| 424 | 426 |
| 425 LayoutUnit RootInlineBox::selectionTopAdjustedForPrecedingBlock() const | 427 LayoutUnit RootInlineBox::selectionTopAdjustedForPrecedingBlock() const |
| 426 { | 428 { |
| 427 LayoutUnit top = selectionTop(); | 429 LayoutUnit top = selectionTop(); |
| 428 | 430 |
| 429 RenderObject::SelectionState blockSelectionState = root()->block()->selectio
nState(); | 431 RenderObject::SelectionState blockSelectionState = root()->block().selection
State(); |
| 430 if (blockSelectionState != RenderObject::SelectionInside && blockSelectionSt
ate != RenderObject::SelectionEnd) | 432 if (blockSelectionState != RenderObject::SelectionInside && blockSelectionSt
ate != RenderObject::SelectionEnd) |
| 431 return top; | 433 return top; |
| 432 | 434 |
| 433 LayoutSize offsetToBlockBefore; | 435 LayoutSize offsetToBlockBefore; |
| 434 if (RenderBlock* block = root()->block()->blockBeforeWithinSelectionRoot(off
setToBlockBefore)) { | 436 if (RenderBlock* block = root()->block().blockBeforeWithinSelectionRoot(offs
etToBlockBefore)) { |
| 435 if (RootInlineBox* lastLine = block->lastRootBox()) { | 437 if (RootInlineBox* lastLine = block->lastRootBox()) { |
| 436 RenderObject::SelectionState lastLineSelectionState = lastLine->sele
ctionState(); | 438 RenderObject::SelectionState lastLineSelectionState = lastLine->sele
ctionState(); |
| 437 if (lastLineSelectionState != RenderObject::SelectionInside && lastL
ineSelectionState != RenderObject::SelectionStart) | 439 if (lastLineSelectionState != RenderObject::SelectionInside && lastL
ineSelectionState != RenderObject::SelectionStart) |
| 438 return top; | 440 return top; |
| 439 | 441 |
| 440 LayoutUnit lastLineSelectionBottom = lastLine->selectionBottom() + o
ffsetToBlockBefore.height(); | 442 LayoutUnit lastLineSelectionBottom = lastLine->selectionBottom() + o
ffsetToBlockBefore.height(); |
| 441 top = max(top, lastLineSelectionBottom); | 443 top = max(top, lastLineSelectionBottom); |
| 442 } | 444 } |
| 443 } | 445 } |
| 444 | 446 |
| 445 return top; | 447 return top; |
| 446 } | 448 } |
| 447 | 449 |
| 448 LayoutUnit RootInlineBox::selectionBottom() const | 450 LayoutUnit RootInlineBox::selectionBottom() const |
| 449 { | 451 { |
| 450 LayoutUnit selectionBottom = m_lineBottom; | 452 LayoutUnit selectionBottom = m_lineBottom; |
| 451 | 453 |
| 452 if (m_hasAnnotationsAfter) | 454 if (m_hasAnnotationsAfter) |
| 453 selectionBottom += !renderer()->style()->isFlippedLinesWritingMode() ? c
omputeUnderAnnotationAdjustment(m_lineBottom) : computeOverAnnotationAdjustment(
m_lineBottom); | 455 selectionBottom += !renderer().style()->isFlippedLinesWritingMode() ? co
mputeUnderAnnotationAdjustment(m_lineBottom) : computeOverAnnotationAdjustment(m
_lineBottom); |
| 454 | 456 |
| 455 if (!renderer()->style()->isFlippedLinesWritingMode() || !nextRootBox()) | 457 if (!renderer().style()->isFlippedLinesWritingMode() || !nextRootBox()) |
| 456 return selectionBottom; | 458 return selectionBottom; |
| 457 | 459 |
| 458 LayoutUnit nextTop = nextRootBox()->selectionTop(); | 460 LayoutUnit nextTop = nextRootBox()->selectionTop(); |
| 459 if (nextTop > selectionBottom && block()->containsFloats()) { | 461 if (nextTop > selectionBottom && block().containsFloats()) { |
| 460 // The next line has actually been moved further over, probably from a l
arge line-height, but possibly because the | 462 // The next line has actually been moved further over, probably from a l
arge line-height, but possibly because the |
| 461 // line was forced to clear floats. If so, let's check the offsets, and
only be willing to use the next | 463 // line was forced to clear floats. If so, let's check the offsets, and
only be willing to use the next |
| 462 // line's top if the offsets are greater on both sides. | 464 // line's top if the offsets are greater on both sides. |
| 463 LayoutUnit nextLeft = block()->logicalLeftOffsetForLine(nextTop, false); | 465 LayoutUnit nextLeft = block().logicalLeftOffsetForLine(nextTop, false); |
| 464 LayoutUnit nextRight = block()->logicalRightOffsetForLine(nextTop, false
); | 466 LayoutUnit nextRight = block().logicalRightOffsetForLine(nextTop, false)
; |
| 465 LayoutUnit newLeft = block()->logicalLeftOffsetForLine(selectionBottom,
false); | 467 LayoutUnit newLeft = block().logicalLeftOffsetForLine(selectionBottom, f
alse); |
| 466 LayoutUnit newRight = block()->logicalRightOffsetForLine(selectionBottom
, false); | 468 LayoutUnit newRight = block().logicalRightOffsetForLine(selectionBottom,
false); |
| 467 if (nextLeft > newLeft || nextRight < newRight) | 469 if (nextLeft > newLeft || nextRight < newRight) |
| 468 return selectionBottom; | 470 return selectionBottom; |
| 469 } | 471 } |
| 470 | 472 |
| 471 return nextTop; | 473 return nextTop; |
| 472 } | 474 } |
| 473 | 475 |
| 474 int RootInlineBox::blockDirectionPointInLine() const | 476 int RootInlineBox::blockDirectionPointInLine() const |
| 475 { | 477 { |
| 476 return !block()->style()->isFlippedBlocksWritingMode() ? max(lineTop(), sele
ctionTop()) : min(lineBottom(), selectionBottom()); | 478 return !block().style()->isFlippedBlocksWritingMode() ? max(lineTop(), selec
tionTop()) : min(lineBottom(), selectionBottom()); |
| 477 } | 479 } |
| 478 | 480 |
| 479 RenderBlockFlow* RootInlineBox::block() const | 481 RenderBlockFlow& RootInlineBox::block() const |
| 480 { | 482 { |
| 481 return toRenderBlockFlow(renderer()); | 483 return toRenderBlockFlow(renderer()); |
| 482 } | 484 } |
| 483 | 485 |
| 484 static bool isEditableLeaf(InlineBox* leaf) | 486 static bool isEditableLeaf(InlineBox* leaf) |
| 485 { | 487 { |
| 486 return leaf && leaf->renderer() && leaf->renderer()->node() && leaf->rendere
r()->node()->rendererIsEditable(); | 488 return leaf && leaf->renderer().node() && leaf->renderer().node()->rendererI
sEditable(); |
| 487 } | 489 } |
| 488 | 490 |
| 489 InlineBox* RootInlineBox::closestLeafChildForPoint(const IntPoint& pointInConten
ts, bool onlyEditableLeaves) | 491 InlineBox* RootInlineBox::closestLeafChildForPoint(const IntPoint& pointInConten
ts, bool onlyEditableLeaves) |
| 490 { | 492 { |
| 491 return closestLeafChildForLogicalLeftPosition(block()->isHorizontalWritingMo
de() ? pointInContents.x() : pointInContents.y(), onlyEditableLeaves); | 493 return closestLeafChildForLogicalLeftPosition(block().isHorizontalWritingMod
e() ? pointInContents.x() : pointInContents.y(), onlyEditableLeaves); |
| 492 } | 494 } |
| 493 | 495 |
| 494 InlineBox* RootInlineBox::closestLeafChildForLogicalLeftPosition(int leftPositio
n, bool onlyEditableLeaves) | 496 InlineBox* RootInlineBox::closestLeafChildForLogicalLeftPosition(int leftPositio
n, bool onlyEditableLeaves) |
| 495 { | 497 { |
| 496 InlineBox* firstLeaf = firstLeafChild(); | 498 InlineBox* firstLeaf = firstLeafChild(); |
| 497 InlineBox* lastLeaf = lastLeafChild(); | 499 InlineBox* lastLeaf = lastLeafChild(); |
| 498 | 500 |
| 499 if (firstLeaf != lastLeaf) { | 501 if (firstLeaf != lastLeaf) { |
| 500 if (firstLeaf->isLineBreak()) | 502 if (firstLeaf->isLineBreak()) |
| 501 firstLeaf = firstLeaf->nextLeafChildIgnoringLineBreak(); | 503 firstLeaf = firstLeaf->nextLeafChildIgnoringLineBreak(); |
| 502 else if (lastLeaf->isLineBreak()) | 504 else if (lastLeaf->isLineBreak()) |
| 503 lastLeaf = lastLeaf->prevLeafChildIgnoringLineBreak(); | 505 lastLeaf = lastLeaf->prevLeafChildIgnoringLineBreak(); |
| 504 } | 506 } |
| 505 | 507 |
| 506 if (firstLeaf == lastLeaf && (!onlyEditableLeaves || isEditableLeaf(firstLea
f))) | 508 if (firstLeaf == lastLeaf && (!onlyEditableLeaves || isEditableLeaf(firstLea
f))) |
| 507 return firstLeaf; | 509 return firstLeaf; |
| 508 | 510 |
| 509 // Avoid returning a list marker when possible. | 511 // Avoid returning a list marker when possible. |
| 510 if (leftPosition <= firstLeaf->logicalLeft() && !firstLeaf->renderer()->isLi
stMarker() && (!onlyEditableLeaves || isEditableLeaf(firstLeaf))) | 512 if (leftPosition <= firstLeaf->logicalLeft() && !firstLeaf->renderer().isLis
tMarker() && (!onlyEditableLeaves || isEditableLeaf(firstLeaf))) |
| 511 // The leftPosition coordinate is less or equal to left edge of the firs
tLeaf. | 513 // The leftPosition coordinate is less or equal to left edge of the firs
tLeaf. |
| 512 // Return it. | 514 // Return it. |
| 513 return firstLeaf; | 515 return firstLeaf; |
| 514 | 516 |
| 515 if (leftPosition >= lastLeaf->logicalRight() && !lastLeaf->renderer()->isLis
tMarker() && (!onlyEditableLeaves || isEditableLeaf(lastLeaf))) | 517 if (leftPosition >= lastLeaf->logicalRight() && !lastLeaf->renderer().isList
Marker() && (!onlyEditableLeaves || isEditableLeaf(lastLeaf))) |
| 516 // The leftPosition coordinate is greater or equal to right edge of the
lastLeaf. | 518 // The leftPosition coordinate is greater or equal to right edge of the
lastLeaf. |
| 517 // Return it. | 519 // Return it. |
| 518 return lastLeaf; | 520 return lastLeaf; |
| 519 | 521 |
| 520 InlineBox* closestLeaf = 0; | 522 InlineBox* closestLeaf = 0; |
| 521 for (InlineBox* leaf = firstLeaf; leaf; leaf = leaf->nextLeafChildIgnoringLi
neBreak()) { | 523 for (InlineBox* leaf = firstLeaf; leaf; leaf = leaf->nextLeafChildIgnoringLi
neBreak()) { |
| 522 if (!leaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEdita
bleLeaf(leaf))) { | 524 if (!leaf->renderer().isListMarker() && (!onlyEditableLeaves || isEditab
leLeaf(leaf))) { |
| 523 closestLeaf = leaf; | 525 closestLeaf = leaf; |
| 524 if (leftPosition < leaf->logicalRight()) | 526 if (leftPosition < leaf->logicalRight()) |
| 525 // The x coordinate is less than the right edge of the box. | 527 // The x coordinate is less than the right edge of the box. |
| 526 // Return it. | 528 // Return it. |
| 527 return leaf; | 529 return leaf; |
| 528 } | 530 } |
| 529 } | 531 } |
| 530 | 532 |
| 531 return closestLeaf ? closestLeaf : lastLeaf; | 533 return closestLeaf ? closestLeaf : lastLeaf; |
| 532 } | 534 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 555 | 557 |
| 556 EllipsisBox* RootInlineBox::ellipsisBox() const | 558 EllipsisBox* RootInlineBox::ellipsisBox() const |
| 557 { | 559 { |
| 558 if (!hasEllipsisBox()) | 560 if (!hasEllipsisBox()) |
| 559 return 0; | 561 return 0; |
| 560 return gEllipsisBoxMap->get(this); | 562 return gEllipsisBoxMap->get(this); |
| 561 } | 563 } |
| 562 | 564 |
| 563 void RootInlineBox::removeLineBoxFromRenderObject() | 565 void RootInlineBox::removeLineBoxFromRenderObject() |
| 564 { | 566 { |
| 565 block()->lineBoxes()->removeLineBox(this); | 567 block().lineBoxes()->removeLineBox(this); |
| 566 } | 568 } |
| 567 | 569 |
| 568 void RootInlineBox::extractLineBoxFromRenderObject() | 570 void RootInlineBox::extractLineBoxFromRenderObject() |
| 569 { | 571 { |
| 570 block()->lineBoxes()->extractLineBox(this); | 572 block().lineBoxes()->extractLineBox(this); |
| 571 } | 573 } |
| 572 | 574 |
| 573 void RootInlineBox::attachLineBoxToRenderObject() | 575 void RootInlineBox::attachLineBoxToRenderObject() |
| 574 { | 576 { |
| 575 block()->lineBoxes()->attachLineBox(this); | 577 block().lineBoxes()->attachLineBox(this); |
| 576 } | 578 } |
| 577 | 579 |
| 578 LayoutRect RootInlineBox::paddedLayoutOverflowRect(LayoutUnit endPadding) const | 580 LayoutRect RootInlineBox::paddedLayoutOverflowRect(LayoutUnit endPadding) const |
| 579 { | 581 { |
| 580 LayoutRect lineLayoutOverflow = layoutOverflowRect(lineTop(), lineBottom()); | 582 LayoutRect lineLayoutOverflow = layoutOverflowRect(lineTop(), lineBottom()); |
| 581 if (!endPadding) | 583 if (!endPadding) |
| 582 return lineLayoutOverflow; | 584 return lineLayoutOverflow; |
| 583 | 585 |
| 584 if (isHorizontal()) { | 586 if (isHorizontal()) { |
| 585 if (isLeftToRightDirection()) | 587 if (isLeftToRightDirection()) |
| (...skipping 22 matching lines...) Expand all Loading... |
| 608 } | 610 } |
| 609 } | 611 } |
| 610 | 612 |
| 611 void RootInlineBox::ascentAndDescentForBox(InlineBox* box, GlyphOverflowAndFallb
ackFontsMap& textBoxDataMap, int& ascent, int& descent, | 613 void RootInlineBox::ascentAndDescentForBox(InlineBox* box, GlyphOverflowAndFallb
ackFontsMap& textBoxDataMap, int& ascent, int& descent, |
| 612 bool& affectsAscent, bool& affectsDes
cent) const | 614 bool& affectsAscent, bool& affectsDes
cent) const |
| 613 { | 615 { |
| 614 bool ascentDescentSet = false; | 616 bool ascentDescentSet = false; |
| 615 | 617 |
| 616 // Replaced boxes will return 0 for the line-height if line-box-contain says
they are | 618 // Replaced boxes will return 0 for the line-height if line-box-contain says
they are |
| 617 // not to be included. | 619 // not to be included. |
| 618 if (box->renderer()->isReplaced()) { | 620 if (box->renderer().isReplaced()) { |
| 619 if (renderer()->style(isFirstLineStyle())->lineBoxContain() & LineBoxCon
tainReplaced) { | 621 if (renderer().style(isFirstLineStyle())->lineBoxContain() & LineBoxCont
ainReplaced) { |
| 620 ascent = box->baselinePosition(baselineType()); | 622 ascent = box->baselinePosition(baselineType()); |
| 621 descent = box->lineHeight() - ascent; | 623 descent = box->lineHeight() - ascent; |
| 622 | 624 |
| 623 // Replaced elements always affect both the ascent and descent. | 625 // Replaced elements always affect both the ascent and descent. |
| 624 affectsAscent = true; | 626 affectsAscent = true; |
| 625 affectsDescent = true; | 627 affectsDescent = true; |
| 626 } | 628 } |
| 627 return; | 629 return; |
| 628 } | 630 } |
| 629 | 631 |
| 630 Vector<const SimpleFontData*>* usedFonts = 0; | 632 Vector<const SimpleFontData*>* usedFonts = 0; |
| 631 GlyphOverflow* glyphOverflow = 0; | 633 GlyphOverflow* glyphOverflow = 0; |
| 632 if (box->isText()) { | 634 if (box->isText()) { |
| 633 GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.find(toIn
lineTextBox(box)); | 635 GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.find(toIn
lineTextBox(box)); |
| 634 usedFonts = it == textBoxDataMap.end() ? 0 : &it->value.first; | 636 usedFonts = it == textBoxDataMap.end() ? 0 : &it->value.first; |
| 635 glyphOverflow = it == textBoxDataMap.end() ? 0 : &it->value.second; | 637 glyphOverflow = it == textBoxDataMap.end() ? 0 : &it->value.second; |
| 636 } | 638 } |
| 637 | 639 |
| 638 bool includeLeading = includeLeadingForBox(box); | 640 bool includeLeading = includeLeadingForBox(box); |
| 639 bool includeFont = includeFontForBox(box); | 641 bool includeFont = includeFontForBox(box); |
| 640 | 642 |
| 641 bool setUsedFont = false; | 643 bool setUsedFont = false; |
| 642 bool setUsedFontWithLeading = false; | 644 bool setUsedFontWithLeading = false; |
| 643 | 645 |
| 644 if (usedFonts && !usedFonts->isEmpty() && (includeFont || (box->renderer()->
style(isFirstLineStyle())->lineHeight().isNegative() && includeLeading))) { | 646 if (usedFonts && !usedFonts->isEmpty() && (includeFont || (box->renderer().s
tyle(isFirstLineStyle())->lineHeight().isNegative() && includeLeading))) { |
| 645 usedFonts->append(box->renderer()->style(isFirstLineStyle())->font().pri
maryFont()); | 647 usedFonts->append(box->renderer().style(isFirstLineStyle())->font().prim
aryFont()); |
| 646 for (size_t i = 0; i < usedFonts->size(); ++i) { | 648 for (size_t i = 0; i < usedFonts->size(); ++i) { |
| 647 const FontMetrics& fontMetrics = usedFonts->at(i)->fontMetrics(); | 649 const FontMetrics& fontMetrics = usedFonts->at(i)->fontMetrics(); |
| 648 int usedFontAscent = fontMetrics.ascent(baselineType()); | 650 int usedFontAscent = fontMetrics.ascent(baselineType()); |
| 649 int usedFontDescent = fontMetrics.descent(baselineType()); | 651 int usedFontDescent = fontMetrics.descent(baselineType()); |
| 650 int halfLeading = (fontMetrics.lineSpacing() - fontMetrics.height())
/ 2; | 652 int halfLeading = (fontMetrics.lineSpacing() - fontMetrics.height())
/ 2; |
| 651 int usedFontAscentAndLeading = usedFontAscent + halfLeading; | 653 int usedFontAscentAndLeading = usedFontAscent + halfLeading; |
| 652 int usedFontDescentAndLeading = fontMetrics.lineSpacing() - usedFont
AscentAndLeading; | 654 int usedFontDescentAndLeading = fontMetrics.lineSpacing() - usedFont
AscentAndLeading; |
| 653 if (includeFont) { | 655 if (includeFont) { |
| 654 setAscentAndDescent(ascent, descent, usedFontAscent, usedFontDes
cent, ascentDescentSet); | 656 setAscentAndDescent(ascent, descent, usedFontAscent, usedFontDes
cent, ascentDescentSet); |
| 655 setUsedFont = true; | 657 setUsedFont = true; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 673 | 675 |
| 674 // Examine the font box for inline flows and text boxes to see if any pa
rt of it is above the baseline. | 676 // Examine the font box for inline flows and text boxes to see if any pa
rt of it is above the baseline. |
| 675 // If the top of our font box relative to the root box baseline is above
the root box baseline, then | 677 // If the top of our font box relative to the root box baseline is above
the root box baseline, then |
| 676 // we are contributing to the maxAscent value. Descent is similar. If an
y part of our font box is below | 678 // we are contributing to the maxAscent value. Descent is similar. If an
y part of our font box is below |
| 677 // the root box's baseline, then we contribute to the maxDescent value. | 679 // the root box's baseline, then we contribute to the maxDescent value. |
| 678 affectsAscent = ascentWithLeading - box->logicalTop() > 0; | 680 affectsAscent = ascentWithLeading - box->logicalTop() > 0; |
| 679 affectsDescent = descentWithLeading + box->logicalTop() > 0; | 681 affectsDescent = descentWithLeading + box->logicalTop() > 0; |
| 680 } | 682 } |
| 681 | 683 |
| 682 if (includeFontForBox(box) && !setUsedFont) { | 684 if (includeFontForBox(box) && !setUsedFont) { |
| 683 int fontAscent = box->renderer()->style(isFirstLineStyle())->fontMetrics
().ascent(baselineType()); | 685 int fontAscent = box->renderer().style(isFirstLineStyle())->fontMetrics(
).ascent(baselineType()); |
| 684 int fontDescent = box->renderer()->style(isFirstLineStyle())->fontMetric
s().descent(baselineType()); | 686 int fontDescent = box->renderer().style(isFirstLineStyle())->fontMetrics
().descent(baselineType()); |
| 685 setAscentAndDescent(ascent, descent, fontAscent, fontDescent, ascentDesc
entSet); | 687 setAscentAndDescent(ascent, descent, fontAscent, fontDescent, ascentDesc
entSet); |
| 686 affectsAscent = fontAscent - box->logicalTop() > 0; | 688 affectsAscent = fontAscent - box->logicalTop() > 0; |
| 687 affectsDescent = fontDescent + box->logicalTop() > 0; | 689 affectsDescent = fontDescent + box->logicalTop() > 0; |
| 688 } | 690 } |
| 689 | 691 |
| 690 if (includeGlyphsForBox(box) && glyphOverflow && glyphOverflow->computeBound
s) { | 692 if (includeGlyphsForBox(box) && glyphOverflow && glyphOverflow->computeBound
s) { |
| 691 setAscentAndDescent(ascent, descent, glyphOverflow->top, glyphOverflow->
bottom, ascentDescentSet); | 693 setAscentAndDescent(ascent, descent, glyphOverflow->top, glyphOverflow->
bottom, ascentDescentSet); |
| 692 affectsAscent = glyphOverflow->top - box->logicalTop() > 0; | 694 affectsAscent = glyphOverflow->top - box->logicalTop() > 0; |
| 693 affectsDescent = glyphOverflow->bottom + box->logicalTop() > 0; | 695 affectsDescent = glyphOverflow->bottom + box->logicalTop() > 0; |
| 694 glyphOverflow->top = min(glyphOverflow->top, max(0, glyphOverflow->top -
box->renderer()->style(isFirstLineStyle())->fontMetrics().ascent(baselineType()
))); | 696 glyphOverflow->top = min(glyphOverflow->top, max(0, glyphOverflow->top -
box->renderer().style(isFirstLineStyle())->fontMetrics().ascent(baselineType())
)); |
| 695 glyphOverflow->bottom = min(glyphOverflow->bottom, max(0, glyphOverflow-
>bottom - box->renderer()->style(isFirstLineStyle())->fontMetrics().descent(base
lineType()))); | 697 glyphOverflow->bottom = min(glyphOverflow->bottom, max(0, glyphOverflow-
>bottom - box->renderer().style(isFirstLineStyle())->fontMetrics().descent(basel
ineType()))); |
| 696 } | 698 } |
| 697 | 699 |
| 698 if (includeMarginForBox(box)) { | 700 if (includeMarginForBox(box)) { |
| 699 LayoutUnit ascentWithMargin = box->renderer()->style(isFirstLineStyle())
->fontMetrics().ascent(baselineType()); | 701 LayoutUnit ascentWithMargin = box->renderer().style(isFirstLineStyle())-
>fontMetrics().ascent(baselineType()); |
| 700 LayoutUnit descentWithMargin = box->renderer()->style(isFirstLineStyle()
)->fontMetrics().descent(baselineType()); | 702 LayoutUnit descentWithMargin = box->renderer().style(isFirstLineStyle())
->fontMetrics().descent(baselineType()); |
| 701 if (box->parent() && !box->renderer()->isText()) { | 703 if (box->parent() && !box->renderer().isText()) { |
| 702 ascentWithMargin += box->boxModelObject()->borderBefore() + box->box
ModelObject()->paddingBefore() + box->boxModelObject()->marginBefore(); | 704 ascentWithMargin += box->boxModelObject()->borderBefore() + box->box
ModelObject()->paddingBefore() + box->boxModelObject()->marginBefore(); |
| 703 descentWithMargin += box->boxModelObject()->borderAfter() + box->box
ModelObject()->paddingAfter() + box->boxModelObject()->marginAfter(); | 705 descentWithMargin += box->boxModelObject()->borderAfter() + box->box
ModelObject()->paddingAfter() + box->boxModelObject()->marginAfter(); |
| 704 } | 706 } |
| 705 setAscentAndDescent(ascent, descent, ascentWithMargin, descentWithMargin
, ascentDescentSet); | 707 setAscentAndDescent(ascent, descent, ascentWithMargin, descentWithMargin
, ascentDescentSet); |
| 706 | 708 |
| 707 // Treat like a replaced element, since we're using the margin box. | 709 // Treat like a replaced element, since we're using the margin box. |
| 708 affectsAscent = true; | 710 affectsAscent = true; |
| 709 affectsDescent = true; | 711 affectsDescent = true; |
| 710 } | 712 } |
| 711 } | 713 } |
| 712 | 714 |
| 713 LayoutUnit RootInlineBox::verticalPositionForBox(InlineBox* box, VerticalPositio
nCache& verticalPositionCache) | 715 LayoutUnit RootInlineBox::verticalPositionForBox(InlineBox* box, VerticalPositio
nCache& verticalPositionCache) |
| 714 { | 716 { |
| 715 if (box->renderer()->isText()) | 717 if (box->renderer().isText()) |
| 716 return box->parent()->logicalTop(); | 718 return box->parent()->logicalTop(); |
| 717 | 719 |
| 718 RenderBoxModelObject* renderer = box->boxModelObject(); | 720 RenderBoxModelObject* renderer = box->boxModelObject(); |
| 719 ASSERT(renderer->isInline()); | 721 ASSERT(renderer->isInline()); |
| 720 if (!renderer->isInline()) | 722 if (!renderer->isInline()) |
| 721 return 0; | 723 return 0; |
| 722 | 724 |
| 723 // This method determines the vertical position for inline elements. | 725 // This method determines the vertical position for inline elements. |
| 724 bool firstLine = isFirstLineStyle(); | 726 bool firstLine = isFirstLineStyle(); |
| 725 if (firstLine && !renderer->document().styleEngine()->usesFirstLineRules()) | 727 if (firstLine && !renderer->document().styleEngine()->usesFirstLineRules()) |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 | 779 |
| 778 // Store the cached value. | 780 // Store the cached value. |
| 779 if (isRenderInline && !firstLine) | 781 if (isRenderInline && !firstLine) |
| 780 verticalPositionCache.set(renderer, baselineType(), verticalPosition); | 782 verticalPositionCache.set(renderer, baselineType(), verticalPosition); |
| 781 | 783 |
| 782 return verticalPosition; | 784 return verticalPosition; |
| 783 } | 785 } |
| 784 | 786 |
| 785 bool RootInlineBox::includeLeadingForBox(InlineBox* box) const | 787 bool RootInlineBox::includeLeadingForBox(InlineBox* box) const |
| 786 { | 788 { |
| 787 if (box->renderer()->isReplaced() || (box->renderer()->isText() && !box->isT
ext())) | 789 if (box->renderer().isReplaced() || (box->renderer().isText() && !box->isTex
t())) |
| 788 return false; | 790 return false; |
| 789 | 791 |
| 790 LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain(); | 792 LineBoxContain lineBoxContain = renderer().style()->lineBoxContain(); |
| 791 return (lineBoxContain & LineBoxContainInline) || (box == this && (lineBoxCo
ntain & LineBoxContainBlock)); | 793 return (lineBoxContain & LineBoxContainInline) || (box == this && (lineBoxCo
ntain & LineBoxContainBlock)); |
| 792 } | 794 } |
| 793 | 795 |
| 794 bool RootInlineBox::includeFontForBox(InlineBox* box) const | 796 bool RootInlineBox::includeFontForBox(InlineBox* box) const |
| 795 { | 797 { |
| 796 if (box->renderer()->isReplaced() || (box->renderer()->isText() && !box->isT
ext())) | 798 if (box->renderer().isReplaced() || (box->renderer().isText() && !box->isTex
t())) |
| 797 return false; | 799 return false; |
| 798 | 800 |
| 799 if (!box->isText() && box->isInlineFlowBox() && !toInlineFlowBox(box)->hasTe
xtChildren()) | 801 if (!box->isText() && box->isInlineFlowBox() && !toInlineFlowBox(box)->hasTe
xtChildren()) |
| 800 return false; | 802 return false; |
| 801 | 803 |
| 802 // For now map "glyphs" to "font" in vertical text mode until the bounds ret
urned by glyphs aren't garbage. | 804 // For now map "glyphs" to "font" in vertical text mode until the bounds ret
urned by glyphs aren't garbage. |
| 803 LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain(); | 805 LineBoxContain lineBoxContain = renderer().style()->lineBoxContain(); |
| 804 return (lineBoxContain & LineBoxContainFont) || (!isHorizontal() && (lineBox
Contain & LineBoxContainGlyphs)); | 806 return (lineBoxContain & LineBoxContainFont) || (!isHorizontal() && (lineBox
Contain & LineBoxContainGlyphs)); |
| 805 } | 807 } |
| 806 | 808 |
| 807 bool RootInlineBox::includeGlyphsForBox(InlineBox* box) const | 809 bool RootInlineBox::includeGlyphsForBox(InlineBox* box) const |
| 808 { | 810 { |
| 809 if (box->renderer()->isReplaced() || (box->renderer()->isText() && !box->isT
ext())) | 811 if (box->renderer().isReplaced() || (box->renderer().isText() && !box->isTex
t())) |
| 810 return false; | 812 return false; |
| 811 | 813 |
| 812 if (!box->isText() && box->isInlineFlowBox() && !toInlineFlowBox(box)->hasTe
xtChildren()) | 814 if (!box->isText() && box->isInlineFlowBox() && !toInlineFlowBox(box)->hasTe
xtChildren()) |
| 813 return false; | 815 return false; |
| 814 | 816 |
| 815 // FIXME: We can't fit to glyphs yet for vertical text, since the bounds ret
urned are garbage. | 817 // FIXME: We can't fit to glyphs yet for vertical text, since the bounds ret
urned are garbage. |
| 816 LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain(); | 818 LineBoxContain lineBoxContain = renderer().style()->lineBoxContain(); |
| 817 return isHorizontal() && (lineBoxContain & LineBoxContainGlyphs); | 819 return isHorizontal() && (lineBoxContain & LineBoxContainGlyphs); |
| 818 } | 820 } |
| 819 | 821 |
| 820 bool RootInlineBox::includeMarginForBox(InlineBox* box) const | 822 bool RootInlineBox::includeMarginForBox(InlineBox* box) const |
| 821 { | 823 { |
| 822 if (box->renderer()->isReplaced() || (box->renderer()->isText() && !box->isT
ext())) | 824 if (box->renderer().isReplaced() || (box->renderer().isText() && !box->isTex
t())) |
| 823 return false; | 825 return false; |
| 824 | 826 |
| 825 LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain(); | 827 LineBoxContain lineBoxContain = renderer().style()->lineBoxContain(); |
| 826 return lineBoxContain & LineBoxContainInlineBox; | 828 return lineBoxContain & LineBoxContainInlineBox; |
| 827 } | 829 } |
| 828 | 830 |
| 829 | 831 |
| 830 bool RootInlineBox::fitsToGlyphs() const | 832 bool RootInlineBox::fitsToGlyphs() const |
| 831 { | 833 { |
| 832 // FIXME: We can't fit to glyphs yet for vertical text, since the bounds ret
urned are garbage. | 834 // FIXME: We can't fit to glyphs yet for vertical text, since the bounds ret
urned are garbage. |
| 833 LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain(); | 835 LineBoxContain lineBoxContain = renderer().style()->lineBoxContain(); |
| 834 return isHorizontal() && (lineBoxContain & LineBoxContainGlyphs); | 836 return isHorizontal() && (lineBoxContain & LineBoxContainGlyphs); |
| 835 } | 837 } |
| 836 | 838 |
| 837 bool RootInlineBox::includesRootLineBoxFontOrLeading() const | 839 bool RootInlineBox::includesRootLineBoxFontOrLeading() const |
| 838 { | 840 { |
| 839 LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain(); | 841 LineBoxContain lineBoxContain = renderer().style()->lineBoxContain(); |
| 840 return (lineBoxContain & LineBoxContainBlock) || (lineBoxContain & LineBoxCo
ntainInline) || (lineBoxContain & LineBoxContainFont); | 842 return (lineBoxContain & LineBoxContainBlock) || (lineBoxContain & LineBoxCo
ntainInline) || (lineBoxContain & LineBoxContainFont); |
| 841 } | 843 } |
| 842 | 844 |
| 843 Node* RootInlineBox::getLogicalStartBoxWithNode(InlineBox*& startBox) const | 845 Node* RootInlineBox::getLogicalStartBoxWithNode(InlineBox*& startBox) const |
| 844 { | 846 { |
| 845 Vector<InlineBox*> leafBoxesInLogicalOrder; | 847 Vector<InlineBox*> leafBoxesInLogicalOrder; |
| 846 collectLeafBoxesInLogicalOrder(leafBoxesInLogicalOrder); | 848 collectLeafBoxesInLogicalOrder(leafBoxesInLogicalOrder); |
| 847 for (size_t i = 0; i < leafBoxesInLogicalOrder.size(); ++i) { | 849 for (size_t i = 0; i < leafBoxesInLogicalOrder.size(); ++i) { |
| 848 if (leafBoxesInLogicalOrder[i]->renderer()->node()) { | 850 if (leafBoxesInLogicalOrder[i]->renderer().node()) { |
| 849 startBox = leafBoxesInLogicalOrder[i]; | 851 startBox = leafBoxesInLogicalOrder[i]; |
| 850 return startBox->renderer()->node(); | 852 return startBox->renderer().node(); |
| 851 } | 853 } |
| 852 } | 854 } |
| 853 startBox = 0; | 855 startBox = 0; |
| 854 return 0; | 856 return 0; |
| 855 } | 857 } |
| 856 | 858 |
| 857 Node* RootInlineBox::getLogicalEndBoxWithNode(InlineBox*& endBox) const | 859 Node* RootInlineBox::getLogicalEndBoxWithNode(InlineBox*& endBox) const |
| 858 { | 860 { |
| 859 Vector<InlineBox*> leafBoxesInLogicalOrder; | 861 Vector<InlineBox*> leafBoxesInLogicalOrder; |
| 860 collectLeafBoxesInLogicalOrder(leafBoxesInLogicalOrder); | 862 collectLeafBoxesInLogicalOrder(leafBoxesInLogicalOrder); |
| 861 for (size_t i = leafBoxesInLogicalOrder.size(); i > 0; --i) { | 863 for (size_t i = leafBoxesInLogicalOrder.size(); i > 0; --i) { |
| 862 if (leafBoxesInLogicalOrder[i - 1]->renderer()->node()) { | 864 if (leafBoxesInLogicalOrder[i - 1]->renderer().node()) { |
| 863 endBox = leafBoxesInLogicalOrder[i - 1]; | 865 endBox = leafBoxesInLogicalOrder[i - 1]; |
| 864 return endBox->renderer()->node(); | 866 return endBox->renderer().node(); |
| 865 } | 867 } |
| 866 } | 868 } |
| 867 endBox = 0; | 869 endBox = 0; |
| 868 return 0; | 870 return 0; |
| 869 } | 871 } |
| 870 | 872 |
| 871 #ifndef NDEBUG | 873 #ifndef NDEBUG |
| 872 const char* RootInlineBox::boxName() const | 874 const char* RootInlineBox::boxName() const |
| 873 { | 875 { |
| 874 return "RootInlineBox"; | 876 return "RootInlineBox"; |
| 875 } | 877 } |
| 876 #endif | 878 #endif |
| 877 | 879 |
| 878 } // namespace WebCore | 880 } // namespace WebCore |
| OLD | NEW |