| OLD | NEW |
| 1 /* | 1 /* |
| 2 * (C) 1999 Lars Knoll (knoll@kde.org) | 2 * (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 2000 Dirk Mueller (mueller@kde.org) | 3 * (C) 2000 Dirk Mueller (mueller@kde.org) |
| 4 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. | 4 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. |
| 5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) | 5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) |
| 6 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) | 6 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 } | 222 } |
| 223 | 223 |
| 224 void LayoutText::RemoveAndDestroyTextBoxes() { | 224 void LayoutText::RemoveAndDestroyTextBoxes() { |
| 225 if (!DocumentBeingDestroyed()) { | 225 if (!DocumentBeingDestroyed()) { |
| 226 if (FirstTextBox()) { | 226 if (FirstTextBox()) { |
| 227 if (IsBR()) { | 227 if (IsBR()) { |
| 228 RootInlineBox* next = FirstTextBox()->Root().NextRootBox(); | 228 RootInlineBox* next = FirstTextBox()->Root().NextRootBox(); |
| 229 if (next) | 229 if (next) |
| 230 next->MarkDirty(); | 230 next->MarkDirty(); |
| 231 } | 231 } |
| 232 for (InlineTextBox* box = FirstTextBox(); box; box = box->NextTextBox()) | 232 for (InlineTextBox* box : InlineTextBoxesOf(*this)) |
| 233 box->Remove(); | 233 box->Remove(); |
| 234 } else if (Parent()) { | 234 } else if (Parent()) { |
| 235 Parent()->DirtyLinesFromChangedChild(this); | 235 Parent()->DirtyLinesFromChangedChild(this); |
| 236 } | 236 } |
| 237 } | 237 } |
| 238 DeleteTextBoxes(); | 238 DeleteTextBoxes(); |
| 239 } | 239 } |
| 240 | 240 |
| 241 void LayoutText::WillBeDestroyed() { | 241 void LayoutText::WillBeDestroyed() { |
| 242 if (SecureTextTimer* secure_text_timer = | 242 if (SecureTextTimer* secure_text_timer = |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 return (e && e->IsTextNode()) ? ToText(e)->DataImpl() : 0; | 300 return (e && e->IsTextNode()) ? ToText(e)->DataImpl() : 0; |
| 301 } | 301 } |
| 302 | 302 |
| 303 String LayoutText::PlainText() const { | 303 String LayoutText::PlainText() const { |
| 304 if (GetNode()) | 304 if (GetNode()) |
| 305 return blink::PlainText(EphemeralRange::RangeOfContents(*GetNode())); | 305 return blink::PlainText(EphemeralRange::RangeOfContents(*GetNode())); |
| 306 | 306 |
| 307 // FIXME: this is just a stopgap until TextIterator is adapted to support | 307 // FIXME: this is just a stopgap until TextIterator is adapted to support |
| 308 // generated text. | 308 // generated text. |
| 309 StringBuilder plain_text_builder; | 309 StringBuilder plain_text_builder; |
| 310 for (InlineTextBox* text_box = FirstTextBox(); text_box; | 310 for (InlineTextBox* text_box : InlineTextBoxesOf(*this)) { |
| 311 text_box = text_box->NextTextBox()) { | |
| 312 String text = text_.Substring(text_box->Start(), text_box->Len()) | 311 String text = text_.Substring(text_box->Start(), text_box->Len()) |
| 313 .SimplifyWhiteSpace(WTF::kDoNotStripWhiteSpace); | 312 .SimplifyWhiteSpace(WTF::kDoNotStripWhiteSpace); |
| 314 plain_text_builder.Append(text); | 313 plain_text_builder.Append(text); |
| 315 if (text_box->NextTextBox() && | 314 if (text_box->NextTextBox() && |
| 316 text_box->NextTextBox()->Start() > text_box->end() && text.length() && | 315 text_box->NextTextBox()->Start() > text_box->end() && text.length() && |
| 317 !text.Right(1).ContainsOnlyWhitespace()) | 316 !text.Right(1).ContainsOnlyWhitespace()) |
| 318 plain_text_builder.Append(kSpaceCharacter); | 317 plain_text_builder.Append(kSpaceCharacter); |
| 319 } | 318 } |
| 320 return plain_text_builder.ToString(); | 319 return plain_text_builder.ToString(); |
| 321 } | 320 } |
| 322 | 321 |
| 323 void LayoutText::AbsoluteRects(Vector<IntRect>& rects, | 322 void LayoutText::AbsoluteRects(Vector<IntRect>& rects, |
| 324 const LayoutPoint& accumulated_offset) const { | 323 const LayoutPoint& accumulated_offset) const { |
| 325 for (InlineTextBox* box = FirstTextBox(); box; box = box->NextTextBox()) { | 324 for (InlineTextBox* box : InlineTextBoxesOf(*this)) { |
| 326 rects.push_back(EnclosingIntRect(LayoutRect( | 325 rects.push_back(EnclosingIntRect(LayoutRect( |
| 327 LayoutPoint(accumulated_offset) + box->Location(), box->Size()))); | 326 LayoutPoint(accumulated_offset) + box->Location(), box->Size()))); |
| 328 } | 327 } |
| 329 } | 328 } |
| 330 | 329 |
| 331 static FloatRect LocalQuadForTextBox(InlineTextBox* box, | 330 static FloatRect LocalQuadForTextBox(InlineTextBox* box, |
| 332 unsigned start, | 331 unsigned start, |
| 333 unsigned end) { | 332 unsigned end) { |
| 334 unsigned real_end = std::min(box->end() + 1, end); | 333 unsigned real_end = std::min(box->end() + 1, end); |
| 335 LayoutRect r = box->LocalSelectionRect(start, real_end); | 334 LayoutRect r = box->LocalSelectionRect(start, real_end); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 return ellipsis->SelectionRect(); | 371 return ellipsis->SelectionRect(); |
| 373 } | 372 } |
| 374 | 373 |
| 375 return IntRect(); | 374 return IntRect(); |
| 376 } | 375 } |
| 377 | 376 |
| 378 void LayoutText::Quads(Vector<FloatQuad>& quads, | 377 void LayoutText::Quads(Vector<FloatQuad>& quads, |
| 379 ClippingOption option, | 378 ClippingOption option, |
| 380 LocalOrAbsoluteOption local_or_absolute, | 379 LocalOrAbsoluteOption local_or_absolute, |
| 381 MapCoordinatesFlags mode) const { | 380 MapCoordinatesFlags mode) const { |
| 382 for (InlineTextBox* box = FirstTextBox(); box; box = box->NextTextBox()) { | 381 for (InlineTextBox* box : InlineTextBoxesOf(*this)) { |
| 383 FloatRect boundaries(box->FrameRect()); | 382 FloatRect boundaries(box->FrameRect()); |
| 384 | 383 |
| 385 // Shorten the width of this text box if it ends in an ellipsis. | 384 // Shorten the width of this text box if it ends in an ellipsis. |
| 386 // FIXME: ellipsisRectForBox should switch to return FloatRect soon with the | 385 // FIXME: ellipsisRectForBox should switch to return FloatRect soon with the |
| 387 // subpixellayout branch. | 386 // subpixellayout branch. |
| 388 IntRect ellipsis_rect = (option == kClipToEllipsis) | 387 IntRect ellipsis_rect = (option == kClipToEllipsis) |
| 389 ? EllipsisRectForBox(box, 0, TextLength()) | 388 ? EllipsisRectForBox(box, 0, TextLength()) |
| 390 : IntRect(); | 389 : IntRect(); |
| 391 if (!ellipsis_rect.IsEmpty()) { | 390 if (!ellipsis_rect.IsEmpty()) { |
| 392 if (Style()->IsHorizontalWritingMode()) | 391 if (Style()->IsHorizontalWritingMode()) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 static_cast<unsigned>(this->CaretMaxOffset()); | 426 static_cast<unsigned>(this->CaretMaxOffset()); |
| 428 | 427 |
| 429 // Narrows |start| and |end| into |caretMinOffset| and |careMaxOffset| | 428 // Narrows |start| and |end| into |caretMinOffset| and |careMaxOffset| |
| 430 // to ignore unrendered leading and trailing whitespaces. | 429 // to ignore unrendered leading and trailing whitespaces. |
| 431 start = std::min(std::max(caret_min_offset, start), caret_max_offset); | 430 start = std::min(std::max(caret_min_offset, start), caret_max_offset); |
| 432 end = std::min(std::max(caret_min_offset, end), caret_max_offset); | 431 end = std::min(std::max(caret_min_offset, end), caret_max_offset); |
| 433 | 432 |
| 434 // This function is always called in sequence that this check should work. | 433 // This function is always called in sequence that this check should work. |
| 435 bool has_checked_box_in_range = !quads.IsEmpty(); | 434 bool has_checked_box_in_range = !quads.IsEmpty(); |
| 436 | 435 |
| 437 for (InlineTextBox* box = FirstTextBox(); box; box = box->NextTextBox()) { | 436 for (InlineTextBox* box : InlineTextBoxesOf(*this)) { |
| 438 // Note: box->end() returns the index of the last character, not the index | 437 // Note: box->end() returns the index of the last character, not the index |
| 439 // past it | 438 // past it |
| 440 if (start <= box->Start() && box->end() < end) { | 439 if (start <= box->Start() && box->end() < end) { |
| 441 LayoutRect r(box->FrameRect()); | 440 LayoutRect r(box->FrameRect()); |
| 442 if (!has_checked_box_in_range) { | 441 if (!has_checked_box_in_range) { |
| 443 has_checked_box_in_range = true; | 442 has_checked_box_in_range = true; |
| 444 quads.clear(); | 443 quads.clear(); |
| 445 } | 444 } |
| 446 quads.push_back(LocalToAbsoluteQuad(FloatRect(r))); | 445 quads.push_back(LocalToAbsoluteQuad(FloatRect(r))); |
| 447 } else if ((box->Start() <= start && start <= box->end()) || | 446 } else if ((box->Start() <= start && start <= box->end()) || |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 if (!FirstTextBox() || TextLength() == 0) | 640 if (!FirstTextBox() || TextLength() == 0) |
| 642 return CreatePositionWithAffinity(0); | 641 return CreatePositionWithAffinity(0); |
| 643 | 642 |
| 644 LayoutUnit point_line_direction = | 643 LayoutUnit point_line_direction = |
| 645 FirstTextBox()->IsHorizontal() ? point.X() : point.Y(); | 644 FirstTextBox()->IsHorizontal() ? point.X() : point.Y(); |
| 646 LayoutUnit point_block_direction = | 645 LayoutUnit point_block_direction = |
| 647 FirstTextBox()->IsHorizontal() ? point.Y() : point.X(); | 646 FirstTextBox()->IsHorizontal() ? point.Y() : point.X(); |
| 648 bool blocks_are_flipped = Style()->IsFlippedBlocksWritingMode(); | 647 bool blocks_are_flipped = Style()->IsFlippedBlocksWritingMode(); |
| 649 | 648 |
| 650 InlineTextBox* last_box = nullptr; | 649 InlineTextBox* last_box = nullptr; |
| 651 for (InlineTextBox* box = FirstTextBox(); box; box = box->NextTextBox()) { | 650 for (InlineTextBox* box : InlineTextBoxesOf(*this)) { |
| 652 if (box->IsLineBreak() && !box->PrevLeafChild() && box->NextLeafChild() && | 651 if (box->IsLineBreak() && !box->PrevLeafChild() && box->NextLeafChild() && |
| 653 !box->NextLeafChild()->IsLineBreak()) | 652 !box->NextLeafChild()->IsLineBreak()) |
| 654 box = box->NextTextBox(); | 653 box = box->NextTextBox(); |
| 655 | 654 |
| 656 RootInlineBox& root_box = box->Root(); | 655 RootInlineBox& root_box = box->Root(); |
| 657 LayoutUnit top = std::min(root_box.SelectionTop(), root_box.LineTop()); | 656 LayoutUnit top = std::min(root_box.SelectionTop(), root_box.LineTop()); |
| 658 if (point_block_direction > top || | 657 if (point_block_direction > top || |
| 659 (!blocks_are_flipped && point_block_direction == top)) { | 658 (!blocks_are_flipped && point_block_direction == top)) { |
| 660 LayoutUnit bottom = root_box.SelectionBottom(); | 659 LayoutUnit bottom = root_box.SelectionBottom(); |
| 661 if (root_box.NextRootBox()) | 660 if (root_box.NextRootBox()) |
| (...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1391 return true; | 1390 return true; |
| 1392 } | 1391 } |
| 1393 for (unsigned i = 0; i < length; ++i) { | 1392 for (unsigned i = 0; i < length; ++i) { |
| 1394 if (!Style()->IsCollapsibleWhiteSpace(Characters16()[i])) | 1393 if (!Style()->IsCollapsibleWhiteSpace(Characters16()[i])) |
| 1395 return false; | 1394 return false; |
| 1396 } | 1395 } |
| 1397 return true; | 1396 return true; |
| 1398 } | 1397 } |
| 1399 | 1398 |
| 1400 bool LayoutText::IsRenderedCharacter(int offset_in_node) const { | 1399 bool LayoutText::IsRenderedCharacter(int offset_in_node) const { |
| 1401 for (InlineTextBox* box = FirstTextBox(); box; box = box->NextTextBox()) { | 1400 for (InlineTextBox* box : InlineTextBoxesOf(*this)) { |
| 1402 if (offset_in_node < static_cast<int>(box->Start()) && | 1401 if (offset_in_node < static_cast<int>(box->Start()) && |
| 1403 !ContainsReversedText()) { | 1402 !ContainsReversedText()) { |
| 1404 // The offset we're looking for is before this node this means the offset | 1403 // The offset we're looking for is before this node this means the offset |
| 1405 // must be in content that is not laid out. Return false. | 1404 // must be in content that is not laid out. Return false. |
| 1406 return false; | 1405 return false; |
| 1407 } | 1406 } |
| 1408 if (offset_in_node >= static_cast<int>(box->Start()) && | 1407 if (offset_in_node >= static_cast<int>(box->Start()) && |
| 1409 offset_in_node < static_cast<int>(box->Start() + box->Len())) | 1408 offset_in_node < static_cast<int>(box->Start() + box->Len())) |
| 1410 return true; | 1409 return true; |
| 1411 } | 1410 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1449 if (GetSelectionState() == SelectionState::kStart) { | 1448 if (GetSelectionState() == SelectionState::kStart) { |
| 1450 end_pos = TextLength(); | 1449 end_pos = TextLength(); |
| 1451 | 1450 |
| 1452 // to handle selection from end of text to end of line | 1451 // to handle selection from end of text to end of line |
| 1453 if (start_pos && start_pos == end_pos) | 1452 if (start_pos && start_pos == end_pos) |
| 1454 start_pos = end_pos - 1; | 1453 start_pos = end_pos - 1; |
| 1455 } else if (GetSelectionState() == SelectionState::kEnd) { | 1454 } else if (GetSelectionState() == SelectionState::kEnd) { |
| 1456 start_pos = 0; | 1455 start_pos = 0; |
| 1457 } | 1456 } |
| 1458 | 1457 |
| 1459 for (InlineTextBox* box = FirstTextBox(); box; box = box->NextTextBox()) { | 1458 for (InlineTextBox* box : InlineTextBoxesOf(*this)) { |
| 1460 if (box->IsSelected(start_pos, end_pos)) { | 1459 if (box->IsSelected(start_pos, end_pos)) { |
| 1461 box->Root().SetHasSelectedChildren(true); | 1460 box->Root().SetHasSelectedChildren(true); |
| 1462 } | 1461 } |
| 1463 } | 1462 } |
| 1464 } else { | 1463 } else { |
| 1465 for (InlineTextBox* box = FirstTextBox(); box; box = box->NextTextBox()) { | 1464 for (InlineTextBox* box : InlineTextBoxesOf(*this)) { |
| 1466 box->Root().SetHasSelectedChildren(state == SelectionState::kInside); | 1465 box->Root().SetHasSelectedChildren(state == SelectionState::kInside); |
| 1467 } | 1466 } |
| 1468 } | 1467 } |
| 1469 } | 1468 } |
| 1470 | 1469 |
| 1471 // The containing block can be null in case of an orphaned tree. | 1470 // The containing block can be null in case of an orphaned tree. |
| 1472 LayoutBlock* containing_block = this->ContainingBlock(); | 1471 LayoutBlock* containing_block = this->ContainingBlock(); |
| 1473 if (containing_block && !containing_block->IsLayoutView()) | 1472 if (containing_block && !containing_block->IsLayoutView()) |
| 1474 containing_block->SetSelectionState(state); | 1473 containing_block->SetSelectionState(state); |
| 1475 } | 1474 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1486 int delta = new_len - old_len; | 1485 int delta = new_len - old_len; |
| 1487 unsigned end = len ? offset + len - 1 : offset; | 1486 unsigned end = len ? offset + len - 1 : offset; |
| 1488 | 1487 |
| 1489 RootInlineBox* first_root_box = nullptr; | 1488 RootInlineBox* first_root_box = nullptr; |
| 1490 RootInlineBox* last_root_box = nullptr; | 1489 RootInlineBox* last_root_box = nullptr; |
| 1491 | 1490 |
| 1492 bool dirtied_lines = false; | 1491 bool dirtied_lines = false; |
| 1493 | 1492 |
| 1494 // Dirty all text boxes that include characters in between offset and | 1493 // Dirty all text boxes that include characters in between offset and |
| 1495 // offset+len. | 1494 // offset+len. |
| 1496 for (InlineTextBox* curr = FirstTextBox(); curr; curr = curr->NextTextBox()) { | 1495 for (InlineTextBox* curr : InlineTextBoxesOf(*this)) { |
| 1497 // FIXME: This shouldn't rely on the end of a dirty line box. See | 1496 // FIXME: This shouldn't rely on the end of a dirty line box. See |
| 1498 // https://bugs.webkit.org/show_bug.cgi?id=97264 | 1497 // https://bugs.webkit.org/show_bug.cgi?id=97264 |
| 1499 // Text run is entirely before the affected range. | 1498 // Text run is entirely before the affected range. |
| 1500 if (curr->end() < offset) | 1499 if (curr->end() < offset) |
| 1501 continue; | 1500 continue; |
| 1502 | 1501 |
| 1503 // Text run is entirely after the affected range. | 1502 // Text run is entirely after the affected range. |
| 1504 if (curr->Start() > end) { | 1503 if (curr->Start() > end) { |
| 1505 curr->OffsetRun(delta); | 1504 curr->OffsetRun(delta); |
| 1506 RootInlineBox* root = &curr->Root(); | 1505 RootInlineBox* root = &curr->Root(); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1692 | 1691 |
| 1693 void LayoutText::DirtyOrDeleteLineBoxesIfNeeded(bool full_layout) { | 1692 void LayoutText::DirtyOrDeleteLineBoxesIfNeeded(bool full_layout) { |
| 1694 if (full_layout) | 1693 if (full_layout) |
| 1695 DeleteTextBoxes(); | 1694 DeleteTextBoxes(); |
| 1696 else if (!lines_dirty_) | 1695 else if (!lines_dirty_) |
| 1697 DirtyLineBoxes(); | 1696 DirtyLineBoxes(); |
| 1698 lines_dirty_ = false; | 1697 lines_dirty_ = false; |
| 1699 } | 1698 } |
| 1700 | 1699 |
| 1701 void LayoutText::DirtyLineBoxes() { | 1700 void LayoutText::DirtyLineBoxes() { |
| 1702 for (InlineTextBox* box = FirstTextBox(); box; box = box->NextTextBox()) | 1701 for (InlineTextBox* box : InlineTextBoxesOf(*this)) |
| 1703 box->DirtyLineBoxes(); | 1702 box->DirtyLineBoxes(); |
| 1704 lines_dirty_ = false; | 1703 lines_dirty_ = false; |
| 1705 } | 1704 } |
| 1706 | 1705 |
| 1707 InlineTextBox* LayoutText::CreateTextBox(int start, unsigned short length) { | 1706 InlineTextBox* LayoutText::CreateTextBox(int start, unsigned short length) { |
| 1708 return new InlineTextBox(LineLayoutItem(this), start, length); | 1707 return new InlineTextBox(LineLayoutItem(this), start, length); |
| 1709 } | 1708 } |
| 1710 | 1709 |
| 1711 InlineTextBox* LayoutText::CreateInlineTextBox(int start, | 1710 InlineTextBox* LayoutText::CreateInlineTextBox(int start, |
| 1712 unsigned short length) { | 1711 unsigned short length) { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1813 | 1812 |
| 1814 LayoutRect LayoutText::LinesBoundingBox() const { | 1813 LayoutRect LayoutText::LinesBoundingBox() const { |
| 1815 LayoutRect result; | 1814 LayoutRect result; |
| 1816 | 1815 |
| 1817 DCHECK_EQ(!FirstTextBox(), | 1816 DCHECK_EQ(!FirstTextBox(), |
| 1818 !LastTextBox()); // Either both are null or both exist. | 1817 !LastTextBox()); // Either both are null or both exist. |
| 1819 if (FirstTextBox() && LastTextBox()) { | 1818 if (FirstTextBox() && LastTextBox()) { |
| 1820 // Return the width of the minimal left side and the maximal right side. | 1819 // Return the width of the minimal left side and the maximal right side. |
| 1821 float logical_left_side = 0; | 1820 float logical_left_side = 0; |
| 1822 float logical_right_side = 0; | 1821 float logical_right_side = 0; |
| 1823 for (InlineTextBox* curr = FirstTextBox(); curr; | 1822 for (InlineTextBox* curr : InlineTextBoxesOf(*this)) { |
| 1824 curr = curr->NextTextBox()) { | |
| 1825 if (curr == FirstTextBox() || curr->LogicalLeft() < logical_left_side) | 1823 if (curr == FirstTextBox() || curr->LogicalLeft() < logical_left_side) |
| 1826 logical_left_side = curr->LogicalLeft().ToFloat(); | 1824 logical_left_side = curr->LogicalLeft().ToFloat(); |
| 1827 if (curr == FirstTextBox() || curr->LogicalRight() > logical_right_side) | 1825 if (curr == FirstTextBox() || curr->LogicalRight() > logical_right_side) |
| 1828 logical_right_side = curr->LogicalRight().ToFloat(); | 1826 logical_right_side = curr->LogicalRight().ToFloat(); |
| 1829 } | 1827 } |
| 1830 | 1828 |
| 1831 bool is_horizontal = Style()->IsHorizontalWritingMode(); | 1829 bool is_horizontal = Style()->IsHorizontalWritingMode(); |
| 1832 | 1830 |
| 1833 float x = is_horizontal ? logical_left_side : FirstTextBox()->X().ToFloat(); | 1831 float x = is_horizontal ? logical_left_side : FirstTextBox()->X().ToFloat(); |
| 1834 float y = is_horizontal ? FirstTextBox()->Y().ToFloat() : logical_left_side; | 1832 float y = is_horizontal ? FirstTextBox()->Y().ToFloat() : logical_left_side; |
| 1835 float width = is_horizontal ? logical_right_side - logical_left_side | 1833 float width = is_horizontal ? logical_right_side - logical_left_side |
| 1836 : LastTextBox()->LogicalBottom() - x; | 1834 : LastTextBox()->LogicalBottom() - x; |
| 1837 float height = is_horizontal ? LastTextBox()->LogicalBottom() - y | 1835 float height = is_horizontal ? LastTextBox()->LogicalBottom() - y |
| 1838 : logical_right_side - logical_left_side; | 1836 : logical_right_side - logical_left_side; |
| 1839 result = EnclosingLayoutRect(FloatRect(x, y, width, height)); | 1837 result = EnclosingLayoutRect(FloatRect(x, y, width, height)); |
| 1840 } | 1838 } |
| 1841 | 1839 |
| 1842 return result; | 1840 return result; |
| 1843 } | 1841 } |
| 1844 | 1842 |
| 1845 LayoutRect LayoutText::VisualOverflowRect() const { | 1843 LayoutRect LayoutText::VisualOverflowRect() const { |
| 1846 if (!FirstTextBox()) | 1844 if (!FirstTextBox()) |
| 1847 return LayoutRect(); | 1845 return LayoutRect(); |
| 1848 | 1846 |
| 1849 // Return the width of the minimal left side and the maximal right side. | 1847 // Return the width of the minimal left side and the maximal right side. |
| 1850 LayoutUnit logical_left_side = LayoutUnit::Max(); | 1848 LayoutUnit logical_left_side = LayoutUnit::Max(); |
| 1851 LayoutUnit logical_right_side = LayoutUnit::Min(); | 1849 LayoutUnit logical_right_side = LayoutUnit::Min(); |
| 1852 for (InlineTextBox* curr = FirstTextBox(); curr; curr = curr->NextTextBox()) { | 1850 for (InlineTextBox* curr : InlineTextBoxesOf(*this)) { |
| 1853 LayoutRect logical_visual_overflow = curr->LogicalOverflowRect(); | 1851 LayoutRect logical_visual_overflow = curr->LogicalOverflowRect(); |
| 1854 logical_left_side = | 1852 logical_left_side = |
| 1855 std::min(logical_left_side, logical_visual_overflow.X()); | 1853 std::min(logical_left_side, logical_visual_overflow.X()); |
| 1856 logical_right_side = | 1854 logical_right_side = |
| 1857 std::max(logical_right_side, logical_visual_overflow.MaxX()); | 1855 std::max(logical_right_side, logical_visual_overflow.MaxX()); |
| 1858 } | 1856 } |
| 1859 | 1857 |
| 1860 LayoutUnit logical_top = FirstTextBox()->LogicalTopVisualOverflow(); | 1858 LayoutUnit logical_top = FirstTextBox()->LogicalTopVisualOverflow(); |
| 1861 LayoutUnit logical_width = logical_right_side - logical_left_side; | 1859 LayoutUnit logical_width = logical_right_side - logical_left_side; |
| 1862 LayoutUnit logical_height = | 1860 LayoutUnit logical_height = |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1916 end_pos = TextLength(); | 1914 end_pos = TextLength(); |
| 1917 else if (GetSelectionState() == SelectionState::kEnd) | 1915 else if (GetSelectionState() == SelectionState::kEnd) |
| 1918 start_pos = 0; | 1916 start_pos = 0; |
| 1919 } | 1917 } |
| 1920 | 1918 |
| 1921 LayoutRect rect; | 1919 LayoutRect rect; |
| 1922 | 1920 |
| 1923 if (start_pos == end_pos) | 1921 if (start_pos == end_pos) |
| 1924 return rect; | 1922 return rect; |
| 1925 | 1923 |
| 1926 for (InlineTextBox* box = FirstTextBox(); box; box = box->NextTextBox()) { | 1924 for (InlineTextBox* box : InlineTextBoxesOf(*this)) { |
| 1927 rect.Unite(box->LocalSelectionRect(start_pos, end_pos)); | 1925 rect.Unite(box->LocalSelectionRect(start_pos, end_pos)); |
| 1928 rect.Unite(LayoutRect(EllipsisRectForBox(box, start_pos, end_pos))); | 1926 rect.Unite(LayoutRect(EllipsisRectForBox(box, start_pos, end_pos))); |
| 1929 } | 1927 } |
| 1930 | 1928 |
| 1931 return rect; | 1929 return rect; |
| 1932 } | 1930 } |
| 1933 | 1931 |
| 1934 int LayoutText::CaretMinOffset() const { | 1932 int LayoutText::CaretMinOffset() const { |
| 1935 InlineTextBox* box = FirstTextBox(); | 1933 InlineTextBox* box = FirstTextBox(); |
| 1936 if (!box) | 1934 if (!box) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1947 return TextLength(); | 1945 return TextLength(); |
| 1948 | 1946 |
| 1949 int max_offset = box->Start() + box->Len(); | 1947 int max_offset = box->Start() + box->Len(); |
| 1950 for (box = box->PrevTextBox(); box; box = box->PrevTextBox()) | 1948 for (box = box->PrevTextBox(); box; box = box->PrevTextBox()) |
| 1951 max_offset = std::max<int>(max_offset, box->Start() + box->Len()); | 1949 max_offset = std::max<int>(max_offset, box->Start() + box->Len()); |
| 1952 return max_offset; | 1950 return max_offset; |
| 1953 } | 1951 } |
| 1954 | 1952 |
| 1955 unsigned LayoutText::ResolvedTextLength() const { | 1953 unsigned LayoutText::ResolvedTextLength() const { |
| 1956 int len = 0; | 1954 int len = 0; |
| 1957 for (InlineTextBox* box = FirstTextBox(); box; box = box->NextTextBox()) | 1955 for (InlineTextBox* box : InlineTextBoxesOf(*this)) |
| 1958 len += box->Len(); | 1956 len += box->Len(); |
| 1959 return len; | 1957 return len; |
| 1960 } | 1958 } |
| 1961 | 1959 |
| 1962 void LayoutText::MomentarilyRevealLastTypedCharacter( | 1960 void LayoutText::MomentarilyRevealLastTypedCharacter( |
| 1963 unsigned last_typed_character_offset) { | 1961 unsigned last_typed_character_offset) { |
| 1964 if (!g_secure_text_timers) | 1962 if (!g_secure_text_timers) |
| 1965 g_secure_text_timers = new SecureTextTimerMap; | 1963 g_secure_text_timers = new SecureTextTimerMap; |
| 1966 | 1964 |
| 1967 SecureTextTimer* secure_text_timer = g_secure_text_timers->at(this); | 1965 SecureTextTimer* secure_text_timer = g_secure_text_timers->at(this); |
| 1968 if (!secure_text_timer) { | 1966 if (!secure_text_timer) { |
| 1969 secure_text_timer = new SecureTextTimer(this); | 1967 secure_text_timer = new SecureTextTimer(this); |
| 1970 g_secure_text_timers->insert(this, secure_text_timer); | 1968 g_secure_text_timers->insert(this, secure_text_timer); |
| 1971 } | 1969 } |
| 1972 secure_text_timer->RestartWithNewText(last_typed_character_offset); | 1970 secure_text_timer->RestartWithNewText(last_typed_character_offset); |
| 1973 } | 1971 } |
| 1974 | 1972 |
| 1975 PassRefPtr<AbstractInlineTextBox> LayoutText::FirstAbstractInlineTextBox() { | 1973 PassRefPtr<AbstractInlineTextBox> LayoutText::FirstAbstractInlineTextBox() { |
| 1976 return AbstractInlineTextBox::GetOrCreate(LineLayoutText(this), | 1974 return AbstractInlineTextBox::GetOrCreate(LineLayoutText(this), |
| 1977 first_text_box_); | 1975 first_text_box_); |
| 1978 } | 1976 } |
| 1979 | 1977 |
| 1980 void LayoutText::InvalidateDisplayItemClients( | 1978 void LayoutText::InvalidateDisplayItemClients( |
| 1981 PaintInvalidationReason invalidation_reason) const { | 1979 PaintInvalidationReason invalidation_reason) const { |
| 1982 ObjectPaintInvalidator paint_invalidator(*this); | 1980 ObjectPaintInvalidator paint_invalidator(*this); |
| 1983 paint_invalidator.InvalidateDisplayItemClient(*this, invalidation_reason); | 1981 paint_invalidator.InvalidateDisplayItemClient(*this, invalidation_reason); |
| 1984 | 1982 |
| 1985 for (InlineTextBox* box = FirstTextBox(); box; box = box->NextTextBox()) { | 1983 for (InlineTextBox* box : InlineTextBoxesOf(*this)) { |
| 1986 paint_invalidator.InvalidateDisplayItemClient(*box, invalidation_reason); | 1984 paint_invalidator.InvalidateDisplayItemClient(*box, invalidation_reason); |
| 1987 if (box->Truncation() != kCNoTruncation) { | 1985 if (box->Truncation() != kCNoTruncation) { |
| 1988 if (EllipsisBox* ellipsis_box = box->Root().GetEllipsisBox()) | 1986 if (EllipsisBox* ellipsis_box = box->Root().GetEllipsisBox()) |
| 1989 paint_invalidator.InvalidateDisplayItemClient(*ellipsis_box, | 1987 paint_invalidator.InvalidateDisplayItemClient(*ellipsis_box, |
| 1990 invalidation_reason); | 1988 invalidation_reason); |
| 1991 } | 1989 } |
| 1992 } | 1990 } |
| 1993 } | 1991 } |
| 1994 | 1992 |
| 1995 // TODO(lunalu): Would be better to dump the bounding box x and y rather than | 1993 // TODO(lunalu): Would be better to dump the bounding box x and y rather than |
| 1996 // the first run's x and y, but that would involve updating many test results. | 1994 // the first run's x and y, but that would involve updating many test results. |
| 1997 LayoutRect LayoutText::DebugRect() const { | 1995 LayoutRect LayoutText::DebugRect() const { |
| 1998 IntRect lines_box = EnclosingIntRect(LinesBoundingBox()); | 1996 IntRect lines_box = EnclosingIntRect(LinesBoundingBox()); |
| 1999 LayoutRect rect = LayoutRect( | 1997 LayoutRect rect = LayoutRect( |
| 2000 IntRect(FirstRunX(), FirstRunY(), lines_box.Width(), lines_box.Height())); | 1998 IntRect(FirstRunX(), FirstRunY(), lines_box.Width(), lines_box.Height())); |
| 2001 LayoutBlock* block = ContainingBlock(); | 1999 LayoutBlock* block = ContainingBlock(); |
| 2002 if (block && HasTextBoxes()) | 2000 if (block && HasTextBoxes()) |
| 2003 block->AdjustChildDebugRect(rect); | 2001 block->AdjustChildDebugRect(rect); |
| 2004 | 2002 |
| 2005 return rect; | 2003 return rect; |
| 2006 } | 2004 } |
| 2007 | 2005 |
| 2006 // ----- |
| 2007 InlineTextBoxRange::Iterator::Iterator(InlineTextBox* current) |
| 2008 : current_(current) {} |
| 2009 |
| 2010 InlineTextBoxRange::Iterator& InlineTextBoxRange::Iterator::operator++() { |
| 2011 current_ = current_->NextTextBox(); |
| 2012 return *this; |
| 2013 } |
| 2014 |
| 2015 InlineTextBox* InlineTextBoxRange::Iterator::operator*() const { |
| 2016 DCHECK(current_); |
| 2017 return current_; |
| 2018 } |
| 2019 |
| 2020 InlineTextBoxRange::InlineTextBoxRange(const LayoutText& layout_text) |
| 2021 : layout_text_(&layout_text) {} |
| 2022 |
| 2023 InlineTextBoxRange InlineTextBoxesOf(const LayoutText& layout_text) { |
| 2024 return InlineTextBoxRange(layout_text); |
| 2025 } |
| 2026 |
| 2008 } // namespace blink | 2027 } // namespace blink |
| OLD | NEW |