| 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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 // We have to compute the expansion for annotations over the previous li
ne to see how much we should move. | 276 // We have to compute the expansion for annotations over the previous li
ne to see how much we should move. |
| 277 LayoutUnit lowestAllowedPosition = std::max(prevRootBox()->lineBottom(),
lineTop()) - result; | 277 LayoutUnit lowestAllowedPosition = std::max(prevRootBox()->lineBottom(),
lineTop()) - result; |
| 278 result = prevRootBox()->computeOverAnnotationAdjustment(lowestAllowedPos
ition); | 278 result = prevRootBox()->computeOverAnnotationAdjustment(lowestAllowedPos
ition); |
| 279 } | 279 } |
| 280 | 280 |
| 281 return result; | 281 return result; |
| 282 } | 282 } |
| 283 | 283 |
| 284 GapRects RootInlineBox::lineSelectionGap(const LayoutBlock* rootBlock, const Lay
outPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, Layo
utUnit selTop, LayoutUnit selHeight, const PaintInfo* paintInfo) const | 284 GapRects RootInlineBox::lineSelectionGap(const LayoutBlock* rootBlock, const Lay
outPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, Layo
utUnit selTop, LayoutUnit selHeight, const PaintInfo* paintInfo) const |
| 285 { | 285 { |
| 286 LayoutObject::SelectionState lineState = selectionState(); | 286 SelectionState lineState = selectionState(); |
| 287 | 287 |
| 288 bool leftGap, rightGap; | 288 bool leftGap, rightGap; |
| 289 block().getSelectionGapInfo(lineState, leftGap, rightGap); | 289 block().getSelectionGapInfo(lineState, leftGap, rightGap); |
| 290 | 290 |
| 291 GapRects result; | 291 GapRects result; |
| 292 | 292 |
| 293 InlineBox* firstBox = firstSelectedBox(); | 293 InlineBox* firstBox = firstSelectedBox(); |
| 294 InlineBox* lastBox = lastSelectedBox(); | 294 InlineBox* lastBox = lastSelectedBox(); |
| 295 if (leftGap) { | 295 if (leftGap) { |
| 296 result.uniteLeft(block().logicalLeftSelectionGap(rootBlock, rootBlockPhy
sicalPosition, offsetFromRootBlock, | 296 result.uniteLeft(block().logicalLeftSelectionGap(rootBlock, rootBlockPhy
sicalPosition, offsetFromRootBlock, |
| 297 &firstBox->parent()->layoutObject(), firstBox->logicalLeft(), selTop
, selHeight, paintInfo)); | 297 &firstBox->parent()->layoutObject(), firstBox->logicalLeft(), selTop
, selHeight, paintInfo)); |
| 298 } | 298 } |
| 299 if (rightGap) { | 299 if (rightGap) { |
| 300 result.uniteRight(block().logicalRightSelectionGap(rootBlock, rootBlockP
hysicalPosition, offsetFromRootBlock, | 300 result.uniteRight(block().logicalRightSelectionGap(rootBlock, rootBlockP
hysicalPosition, offsetFromRootBlock, |
| 301 &lastBox->parent()->layoutObject(), lastBox->logicalRight(), selTop,
selHeight, paintInfo)); | 301 &lastBox->parent()->layoutObject(), lastBox->logicalRight(), selTop,
selHeight, paintInfo)); |
| 302 } | 302 } |
| 303 | 303 |
| 304 // When dealing with bidi text, a non-contiguous selection region is possibl
e. | 304 // When dealing with bidi text, a non-contiguous selection region is possibl
e. |
| 305 // e.g. The logical text aaaAAAbbb (capitals denote RTL text and non-capital
s LTR) is layed out | 305 // e.g. The logical text aaaAAAbbb (capitals denote RTL text and non-capital
s LTR) is layed out |
| 306 // visually as 3 text runs |aaa|bbb|AAA| if we select 4 characters from the
start of the text the | 306 // visually as 3 text runs |aaa|bbb|AAA| if we select 4 characters from the
start of the text the |
| 307 // selection will look like (underline denotes selection): | 307 // selection will look like (underline denotes selection): |
| 308 // |aaa|bbb|AAA| | 308 // |aaa|bbb|AAA| |
| 309 // ___ _ | 309 // ___ _ |
| 310 // We can see that the |bbb| run is not part of the selection while the runs
around it are. | 310 // We can see that the |bbb| run is not part of the selection while the runs
around it are. |
| 311 if (firstBox && firstBox != lastBox) { | 311 if (firstBox && firstBox != lastBox) { |
| 312 // Now fill in any gaps on the line that occurred between two selected e
lements. | 312 // Now fill in any gaps on the line that occurred between two selected e
lements. |
| 313 LayoutUnit lastLogicalLeft = firstBox->logicalRight(); | 313 LayoutUnit lastLogicalLeft = firstBox->logicalRight(); |
| 314 bool isPreviousBoxSelected = firstBox->selectionState() != LayoutObject:
:SelectionNone; | 314 bool isPreviousBoxSelected = firstBox->selectionState() != SelectionNone
; |
| 315 for (InlineBox* box = firstBox->nextLeafChild(); box; box = box->nextLea
fChild()) { | 315 for (InlineBox* box = firstBox->nextLeafChild(); box; box = box->nextLea
fChild()) { |
| 316 if (box->selectionState() != LayoutObject::SelectionNone) { | 316 if (box->selectionState() != SelectionNone) { |
| 317 LayoutRect logicalRect(lastLogicalLeft, selTop, box->logicalLeft
() - lastLogicalLeft, selHeight); | 317 LayoutRect logicalRect(lastLogicalLeft, selTop, box->logicalLeft
() - lastLogicalLeft, selHeight); |
| 318 logicalRect.move(layoutObject().isHorizontalWritingMode() ? offs
etFromRootBlock : LayoutSize(offsetFromRootBlock.height(), offsetFromRootBlock.w
idth())); | 318 logicalRect.move(layoutObject().isHorizontalWritingMode() ? offs
etFromRootBlock : LayoutSize(offsetFromRootBlock.height(), offsetFromRootBlock.w
idth())); |
| 319 LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBl
ockPhysicalPosition, logicalRect); | 319 LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBl
ockPhysicalPosition, logicalRect); |
| 320 if (isPreviousBoxSelected && gapRect.width() > 0 && gapRect.heig
ht() > 0) { | 320 if (isPreviousBoxSelected && gapRect.width() > 0 && gapRect.heig
ht() > 0) { |
| 321 if (paintInfo && box->parent()->layoutObject().style()->visi
bility() == VISIBLE) | 321 if (paintInfo && box->parent()->layoutObject().style()->visi
bility() == VISIBLE) |
| 322 paintInfo->context->fillRect(gapRect, box->parent()->lay
outObject().selectionBackgroundColor()); | 322 paintInfo->context->fillRect(gapRect, box->parent()->lay
outObject().selectionBackgroundColor()); |
| 323 // VisibleSelection may be non-contiguous, see comment above
. | 323 // VisibleSelection may be non-contiguous, see comment above
. |
| 324 result.uniteCenter(gapRect); | 324 result.uniteCenter(gapRect); |
| 325 } | 325 } |
| 326 lastLogicalLeft = box->logicalRight(); | 326 lastLogicalLeft = box->logicalRight(); |
| 327 } | 327 } |
| 328 if (box == lastBox) | 328 if (box == lastBox) |
| 329 break; | 329 break; |
| 330 isPreviousBoxSelected = box->selectionState() != LayoutObject::Selec
tionNone; | 330 isPreviousBoxSelected = box->selectionState() != SelectionNone; |
| 331 } | 331 } |
| 332 } | 332 } |
| 333 | 333 |
| 334 return result; | 334 return result; |
| 335 } | 335 } |
| 336 | 336 |
| 337 LayoutObject::SelectionState RootInlineBox::selectionState() const | 337 SelectionState RootInlineBox::selectionState() const |
| 338 { | 338 { |
| 339 // Walk over all of the selected boxes. | 339 // Walk over all of the selected boxes. |
| 340 LayoutObject::SelectionState state = LayoutObject::SelectionNone; | 340 SelectionState state = SelectionNone; |
| 341 for (InlineBox* box = firstLeafChild(); box; box = box->nextLeafChild()) { | 341 for (InlineBox* box = firstLeafChild(); box; box = box->nextLeafChild()) { |
| 342 LayoutObject::SelectionState boxState = box->selectionState(); | 342 SelectionState boxState = box->selectionState(); |
| 343 if ((boxState == LayoutObject::SelectionStart && state == LayoutObject::
SelectionEnd) | 343 if ((boxState == SelectionStart && state == SelectionEnd) |
| 344 || (boxState == LayoutObject::SelectionEnd && state == LayoutObject:
:SelectionStart)) { | 344 || (boxState == SelectionEnd && state == SelectionStart)) { |
| 345 state = LayoutObject::SelectionBoth; | 345 state = SelectionBoth; |
| 346 } else if (state == LayoutObject::SelectionNone || ((boxState == LayoutO
bject::SelectionStart || boxState == LayoutObject::SelectionEnd) && (state == La
youtObject::SelectionNone || state == LayoutObject::SelectionInside))) { | 346 } else if (state == SelectionNone || ((boxState == SelectionStart || box
State == SelectionEnd) && (state == SelectionNone || state == SelectionInside)))
{ |
| 347 state = boxState; | 347 state = boxState; |
| 348 } else if (boxState == LayoutObject::SelectionNone && state == LayoutObj
ect::SelectionStart) { | 348 } else if (boxState == SelectionNone && state == SelectionStart) { |
| 349 // We are past the end of the selection. | 349 // We are past the end of the selection. |
| 350 state = LayoutObject::SelectionBoth; | 350 state = SelectionBoth; |
| 351 } | 351 } |
| 352 if (state == LayoutObject::SelectionBoth) | 352 if (state == SelectionBoth) |
| 353 break; | 353 break; |
| 354 } | 354 } |
| 355 | 355 |
| 356 return state; | 356 return state; |
| 357 } | 357 } |
| 358 | 358 |
| 359 InlineBox* RootInlineBox::firstSelectedBox() const | 359 InlineBox* RootInlineBox::firstSelectedBox() const |
| 360 { | 360 { |
| 361 for (InlineBox* box = firstLeafChild(); box; box = box->nextLeafChild()) { | 361 for (InlineBox* box = firstLeafChild(); box; box = box->nextLeafChild()) { |
| 362 if (box->selectionState() != LayoutObject::SelectionNone) | 362 if (box->selectionState() != SelectionNone) |
| 363 return box; | 363 return box; |
| 364 } | 364 } |
| 365 | 365 |
| 366 return nullptr; | 366 return nullptr; |
| 367 } | 367 } |
| 368 | 368 |
| 369 InlineBox* RootInlineBox::lastSelectedBox() const | 369 InlineBox* RootInlineBox::lastSelectedBox() const |
| 370 { | 370 { |
| 371 for (InlineBox* box = lastLeafChild(); box; box = box->prevLeafChild()) { | 371 for (InlineBox* box = lastLeafChild(); box; box = box->prevLeafChild()) { |
| 372 if (box->selectionState() != LayoutObject::SelectionNone) | 372 if (box->selectionState() != SelectionNone) |
| 373 return box; | 373 return box; |
| 374 } | 374 } |
| 375 | 375 |
| 376 return nullptr; | 376 return nullptr; |
| 377 } | 377 } |
| 378 | 378 |
| 379 LayoutUnit RootInlineBox::selectionTop() const | 379 LayoutUnit RootInlineBox::selectionTop() const |
| 380 { | 380 { |
| 381 LayoutUnit selectionTop = m_lineTop; | 381 LayoutUnit selectionTop = m_lineTop; |
| 382 | 382 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 399 return selectionTop; | 399 return selectionTop; |
| 400 } | 400 } |
| 401 | 401 |
| 402 return prevBottom; | 402 return prevBottom; |
| 403 } | 403 } |
| 404 | 404 |
| 405 LayoutUnit RootInlineBox::selectionTopAdjustedForPrecedingBlock() const | 405 LayoutUnit RootInlineBox::selectionTopAdjustedForPrecedingBlock() const |
| 406 { | 406 { |
| 407 LayoutUnit top = selectionTop(); | 407 LayoutUnit top = selectionTop(); |
| 408 | 408 |
| 409 LayoutObject::SelectionState blockSelectionState = root().block().selectionS
tate(); | 409 SelectionState blockSelectionState = root().block().selectionState(); |
| 410 if (blockSelectionState != LayoutObject::SelectionInside && blockSelectionSt
ate != LayoutObject::SelectionEnd) | 410 if (blockSelectionState != SelectionInside && blockSelectionState != Selecti
onEnd) |
| 411 return top; | 411 return top; |
| 412 | 412 |
| 413 LayoutSize offsetToBlockBefore; | 413 LayoutSize offsetToBlockBefore; |
| 414 if (LayoutBlock* block = root().block().blockBeforeWithinSelectionRoot(offse
tToBlockBefore)) { | 414 if (LayoutBlock* block = root().block().blockBeforeWithinSelectionRoot(offse
tToBlockBefore)) { |
| 415 if (block->isLayoutBlockFlow()) { | 415 if (block->isLayoutBlockFlow()) { |
| 416 if (RootInlineBox* lastLine = toLayoutBlockFlow(block)->lastRootBox(
)) { | 416 if (RootInlineBox* lastLine = toLayoutBlockFlow(block)->lastRootBox(
)) { |
| 417 LayoutObject::SelectionState lastLineSelectionState = lastLine->
selectionState(); | 417 SelectionState lastLineSelectionState = lastLine->selectionState
(); |
| 418 if (lastLineSelectionState != LayoutObject::SelectionInside && l
astLineSelectionState != LayoutObject::SelectionStart) | 418 if (lastLineSelectionState != SelectionInside && lastLineSelecti
onState != SelectionStart) |
| 419 return top; | 419 return top; |
| 420 | 420 |
| 421 LayoutUnit lastLineSelectionBottom = lastLine->selectionBottom()
+ offsetToBlockBefore.height(); | 421 LayoutUnit lastLineSelectionBottom = lastLine->selectionBottom()
+ offsetToBlockBefore.height(); |
| 422 top = std::max(top, lastLineSelectionBottom); | 422 top = std::max(top, lastLineSelectionBottom); |
| 423 } | 423 } |
| 424 } | 424 } |
| 425 } | 425 } |
| 426 | 426 |
| 427 return top; | 427 return top; |
| 428 } | 428 } |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 849 endBox = nullptr; | 849 endBox = nullptr; |
| 850 return nullptr; | 850 return nullptr; |
| 851 } | 851 } |
| 852 | 852 |
| 853 const char* RootInlineBox::boxName() const | 853 const char* RootInlineBox::boxName() const |
| 854 { | 854 { |
| 855 return "RootInlineBox"; | 855 return "RootInlineBox"; |
| 856 } | 856 } |
| 857 | 857 |
| 858 } // namespace blink | 858 } // namespace blink |
| OLD | NEW |