Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: Source/core/rendering/RenderText.cpp

Issue 182413005: Return refererence from InlineBox::root() (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: re-upload because previous patch didn't upload correctly. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 206
207 if (!text().containsOnlyWhitespace()) 207 if (!text().containsOnlyWhitespace())
208 newStyle->font().willUseFontData(); 208 newStyle->font().willUseFontData();
209 } 209 }
210 210
211 void RenderText::removeAndDestroyTextBoxes() 211 void RenderText::removeAndDestroyTextBoxes()
212 { 212 {
213 if (!documentBeingDestroyed()) { 213 if (!documentBeingDestroyed()) {
214 if (firstTextBox()) { 214 if (firstTextBox()) {
215 if (isBR()) { 215 if (isBR()) {
216 RootInlineBox* next = firstTextBox()->root()->nextRootBox(); 216 RootInlineBox* next = firstTextBox()->root().nextRootBox();
217 if (next) 217 if (next)
218 next->markDirty(); 218 next->markDirty();
219 } 219 }
220 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBo x()) 220 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBo x())
221 box->remove(); 221 box->remove();
222 } else if (parent()) 222 } else if (parent())
223 parent()->dirtyLinesFromChangedChild(this); 223 parent()->dirtyLinesFromChangedChild(this);
224 } 224 }
225 deleteTextBoxes(); 225 deleteTextBoxes();
226 } 226 }
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 static IntRect ellipsisRectForBox(InlineTextBox* box, unsigned startPos, unsigne d endPos) 385 static IntRect ellipsisRectForBox(InlineTextBox* box, unsigned startPos, unsigne d endPos)
386 { 386 {
387 if (!box) 387 if (!box)
388 return IntRect(); 388 return IntRect();
389 389
390 unsigned short truncation = box->truncation(); 390 unsigned short truncation = box->truncation();
391 if (truncation == cNoTruncation) 391 if (truncation == cNoTruncation)
392 return IntRect(); 392 return IntRect();
393 393
394 IntRect rect; 394 IntRect rect;
395 if (EllipsisBox* ellipsis = box->root()->ellipsisBox()) { 395 if (EllipsisBox* ellipsis = box->root().ellipsisBox()) {
396 int ellipsisStartPosition = max<int>(startPos - box->start(), 0); 396 int ellipsisStartPosition = max<int>(startPos - box->start(), 0);
397 int ellipsisEndPosition = min<int>(endPos - box->start(), box->len()); 397 int ellipsisEndPosition = min<int>(endPos - box->start(), box->len());
398 398
399 // The ellipsis should be considered to be selected if the end of 399 // The ellipsis should be considered to be selected if the end of
400 // the selection is past the beginning of the truncation and the 400 // the selection is past the beginning of the truncation and the
401 // beginning of the selection is before or at the beginning of the trunc ation. 401 // beginning of the selection is before or at the beginning of the trunc ation.
402 if (ellipsisEndPosition >= truncation && ellipsisStartPosition <= trunca tion) 402 if (ellipsisEndPosition >= truncation && ellipsisStartPosition <= trunca tion)
403 return ellipsis->selectionRect(); 403 return ellipsis->selectionRect();
404 } 404 }
405 405
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 620
621 LayoutUnit pointLineDirection = firstTextBox()->isHorizontal() ? point.x() : point.y(); 621 LayoutUnit pointLineDirection = firstTextBox()->isHorizontal() ? point.x() : point.y();
622 LayoutUnit pointBlockDirection = firstTextBox()->isHorizontal() ? point.y() : point.x(); 622 LayoutUnit pointBlockDirection = firstTextBox()->isHorizontal() ? point.y() : point.x();
623 bool blocksAreFlipped = style()->isFlippedBlocksWritingMode(); 623 bool blocksAreFlipped = style()->isFlippedBlocksWritingMode();
624 624
625 InlineTextBox* lastBox = 0; 625 InlineTextBox* lastBox = 0;
626 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 626 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
627 if (box->isLineBreak() && !box->prevLeafChild() && box->nextLeafChild() && !box->nextLeafChild()->isLineBreak()) 627 if (box->isLineBreak() && !box->prevLeafChild() && box->nextLeafChild() && !box->nextLeafChild()->isLineBreak())
628 box = box->nextTextBox(); 628 box = box->nextTextBox();
629 629
630 RootInlineBox* rootBox = box->root(); 630 RootInlineBox& rootBox = box->root();
631 LayoutUnit top = min(rootBox->selectionTop(), rootBox->lineTop()); 631 LayoutUnit top = min(rootBox.selectionTop(), rootBox.lineTop());
632 if (pointBlockDirection > top || (!blocksAreFlipped && pointBlockDirecti on == top)) { 632 if (pointBlockDirection > top || (!blocksAreFlipped && pointBlockDirecti on == top)) {
633 LayoutUnit bottom = rootBox->selectionBottom(); 633 LayoutUnit bottom = rootBox.selectionBottom();
634 if (rootBox->nextRootBox()) 634 if (rootBox.nextRootBox())
635 bottom = min(bottom, rootBox->nextRootBox()->lineTop()); 635 bottom = min(bottom, rootBox.nextRootBox()->lineTop());
636 636
637 if (pointBlockDirection < bottom || (blocksAreFlipped && pointBlockD irection == bottom)) { 637 if (pointBlockDirection < bottom || (blocksAreFlipped && pointBlockD irection == bottom)) {
638 ShouldAffinityBeDownstream shouldAffinityBeDownstream; 638 ShouldAffinityBeDownstream shouldAffinityBeDownstream;
639 if (lineDirectionPointFitsInBox(pointLineDirection, box, shouldA ffinityBeDownstream)) 639 if (lineDirectionPointFitsInBox(pointLineDirection, box, shouldA ffinityBeDownstream))
640 return createPositionWithAffinityForBoxAfterAdjustingOffsetF orBiDi(box, box->offsetForPosition(pointLineDirection), shouldAffinityBeDownstre am); 640 return createPositionWithAffinityForBoxAfterAdjustingOffsetF orBiDi(box, box->offsetForPosition(pointLineDirection), shouldAffinityBeDownstre am);
641 } 641 }
642 } 642 }
643 lastBox = box; 643 lastBox = box;
644 } 644 }
645 645
646 if (lastBox) { 646 if (lastBox) {
647 ShouldAffinityBeDownstream shouldAffinityBeDownstream; 647 ShouldAffinityBeDownstream shouldAffinityBeDownstream;
648 lineDirectionPointFitsInBox(pointLineDirection, lastBox, shouldAffinityB eDownstream); 648 lineDirectionPointFitsInBox(pointLineDirection, lastBox, shouldAffinityB eDownstream);
649 return createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(lastB ox, lastBox->offsetForPosition(pointLineDirection) + lastBox->start(), shouldAff inityBeDownstream); 649 return createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(lastB ox, lastBox->offsetForPosition(pointLineDirection) + lastBox->start(), shouldAff inityBeDownstream);
650 } 650 }
651 return createPositionWithAffinity(0, DOWNSTREAM); 651 return createPositionWithAffinity(0, DOWNSTREAM);
652 } 652 }
653 653
654 LayoutRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, Lay outUnit* extraWidthToEndOfLine) 654 LayoutRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, Lay outUnit* extraWidthToEndOfLine)
655 { 655 {
656 if (!inlineBox) 656 if (!inlineBox)
657 return LayoutRect(); 657 return LayoutRect();
658 658
659 ASSERT(inlineBox->isInlineTextBox()); 659 ASSERT(inlineBox->isInlineTextBox());
660 if (!inlineBox->isInlineTextBox()) 660 if (!inlineBox->isInlineTextBox())
661 return LayoutRect(); 661 return LayoutRect();
662 662
663 InlineTextBox* box = toInlineTextBox(inlineBox); 663 InlineTextBox* box = toInlineTextBox(inlineBox);
664 664
665 int height = box->root()->selectionHeight(); 665 int height = box->root().selectionHeight();
666 int top = box->root()->selectionTop(); 666 int top = box->root().selectionTop();
667 667
668 // Go ahead and round left to snap it to the nearest pixel. 668 // Go ahead and round left to snap it to the nearest pixel.
669 float left = box->positionForOffset(caretOffset); 669 float left = box->positionForOffset(caretOffset);
670 670
671 // Distribute the caret's width to either side of the offset. 671 // Distribute the caret's width to either side of the offset.
672 int caretWidthLeftOfOffset = caretWidth / 2; 672 int caretWidthLeftOfOffset = caretWidth / 2;
673 left -= caretWidthLeftOfOffset; 673 left -= caretWidthLeftOfOffset;
674 int caretWidthRightOfOffset = caretWidth - caretWidthLeftOfOffset; 674 int caretWidthRightOfOffset = caretWidth - caretWidthLeftOfOffset;
675 675
676 left = roundf(left); 676 left = roundf(left);
677 677
678 float rootLeft = box->root()->logicalLeft(); 678 float rootLeft = box->root().logicalLeft();
679 float rootRight = box->root()->logicalRight(); 679 float rootRight = box->root().logicalRight();
680 680
681 // FIXME: should we use the width of the root inline box or the 681 // FIXME: should we use the width of the root inline box or the
682 // width of the containing block for this? 682 // width of the containing block for this?
683 if (extraWidthToEndOfLine) 683 if (extraWidthToEndOfLine)
684 *extraWidthToEndOfLine = (box->root()->logicalWidth() + rootLeft) - (lef t + 1); 684 *extraWidthToEndOfLine = (box->root().logicalWidth() + rootLeft) - (left + 1);
685 685
686 RenderBlock* cb = containingBlock(); 686 RenderBlock* cb = containingBlock();
687 RenderStyle* cbStyle = cb->style(); 687 RenderStyle* cbStyle = cb->style();
688 688
689 float leftEdge; 689 float leftEdge;
690 float rightEdge; 690 float rightEdge;
691 leftEdge = min<float>(0, rootLeft); 691 leftEdge = min<float>(0, rootLeft);
692 rightEdge = max<float>(cb->logicalWidth(), rootRight); 692 rightEdge = max<float>(cb->logicalWidth(), rootRight);
693 693
694 bool rightAligned = false; 694 bool rightAligned = false;
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 endPos = textLength(); 1184 endPos = textLength();
1185 1185
1186 // to handle selection from end of text to end of line 1186 // to handle selection from end of text to end of line
1187 if (startPos && startPos == endPos) 1187 if (startPos && startPos == endPos)
1188 startPos = endPos - 1; 1188 startPos = endPos - 1;
1189 } else if (selectionState() == SelectionEnd) 1189 } else if (selectionState() == SelectionEnd)
1190 startPos = 0; 1190 startPos = 0;
1191 1191
1192 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBo x()) { 1192 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBo x()) {
1193 if (box->isSelected(startPos, endPos)) { 1193 if (box->isSelected(startPos, endPos)) {
1194 RootInlineBox* root = box->root(); 1194 box->root().setHasSelectedChildren(true);
1195 if (root)
1196 root->setHasSelectedChildren(true);
1197 } 1195 }
1198 } 1196 }
1199 } else { 1197 } else {
1200 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBo x()) { 1198 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBo x()) {
1201 RootInlineBox* root = box->root(); 1199 box->root().setHasSelectedChildren(state == SelectionInside);
1202 if (root)
1203 root->setHasSelectedChildren(state == SelectionInside);
1204 } 1200 }
1205 } 1201 }
1206 } 1202 }
1207 1203
1208 // The containing block can be null in case of an orphaned tree. 1204 // The containing block can be null in case of an orphaned tree.
1209 RenderBlock* containingBlock = this->containingBlock(); 1205 RenderBlock* containingBlock = this->containingBlock();
1210 if (containingBlock && !containingBlock->isRenderView()) 1206 if (containingBlock && !containingBlock->isRenderView())
1211 containingBlock->setSelectionState(state); 1207 containingBlock->setSelectionState(state);
1212 } 1208 }
1213 1209
(...skipping 15 matching lines...) Expand all
1229 // Dirty all text boxes that include characters in between offset and offset +len. 1225 // Dirty all text boxes that include characters in between offset and offset +len.
1230 for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) { 1226 for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) {
1231 // FIXME: This shouldn't rely on the end of a dirty line box. See https: //bugs.webkit.org/show_bug.cgi?id=97264 1227 // FIXME: This shouldn't rely on the end of a dirty line box. See https: //bugs.webkit.org/show_bug.cgi?id=97264
1232 // Text run is entirely before the affected range. 1228 // Text run is entirely before the affected range.
1233 if (curr->end() < offset) 1229 if (curr->end() < offset)
1234 continue; 1230 continue;
1235 1231
1236 // Text run is entirely after the affected range. 1232 // Text run is entirely after the affected range.
1237 if (curr->start() > end) { 1233 if (curr->start() > end) {
1238 curr->offsetRun(delta); 1234 curr->offsetRun(delta);
1239 RootInlineBox* root = curr->root(); 1235 RootInlineBox* root = &curr->root();
1240 if (!firstRootBox) { 1236 if (!firstRootBox) {
1241 firstRootBox = root; 1237 firstRootBox = root;
1242 // The affected area was in between two runs. Go ahead and mark the root box of 1238 // The affected area was in between two runs. Go ahead and mark the root box of
1243 // the run after the affected area as dirty. 1239 // the run after the affected area as dirty.
1244 firstRootBox->markDirty(); 1240 firstRootBox->markDirty();
1245 dirtiedLines = true; 1241 dirtiedLines = true;
1246 } 1242 }
1247 lastRootBox = root; 1243 lastRootBox = root;
1248 } else if (curr->end() >= offset && curr->end() <= end) { 1244 } else if (curr->end() >= offset && curr->end() <= end) {
1249 // Text run overlaps with the left end of the affected range. 1245 // Text run overlaps with the left end of the affected range.
(...skipping 13 matching lines...) Expand all
1263 // Now we have to walk all of the clean lines and adjust their cached line b reak information 1259 // Now we have to walk all of the clean lines and adjust their cached line b reak information
1264 // to reflect our updated offsets. 1260 // to reflect our updated offsets.
1265 if (lastRootBox) 1261 if (lastRootBox)
1266 lastRootBox = lastRootBox->nextRootBox(); 1262 lastRootBox = lastRootBox->nextRootBox();
1267 if (firstRootBox) { 1263 if (firstRootBox) {
1268 RootInlineBox* prev = firstRootBox->prevRootBox(); 1264 RootInlineBox* prev = firstRootBox->prevRootBox();
1269 if (prev) 1265 if (prev)
1270 firstRootBox = prev; 1266 firstRootBox = prev;
1271 } else if (lastTextBox()) { 1267 } else if (lastTextBox()) {
1272 ASSERT(!lastRootBox); 1268 ASSERT(!lastRootBox);
1273 firstRootBox = lastTextBox()->root(); 1269 firstRootBox = &lastTextBox()->root();
1274 firstRootBox->markDirty(); 1270 firstRootBox->markDirty();
1275 dirtiedLines = true; 1271 dirtiedLines = true;
1276 } 1272 }
1277 for (RootInlineBox* curr = firstRootBox; curr && curr != lastRootBox; curr = curr->nextRootBox()) { 1273 for (RootInlineBox* curr = firstRootBox; curr && curr != lastRootBox; curr = curr->nextRootBox()) {
1278 if (curr->lineBreakObj() == this && curr->lineBreakPos() > end) 1274 if (curr->lineBreakObj() == this && curr->lineBreakPos() > end)
1279 curr->setLineBreakPos(clampToInteger(curr->lineBreakPos() + delta)); 1275 curr->setLineBreakPos(clampToInteger(curr->lineBreakPos() + delta));
1280 } 1276 }
1281 1277
1282 // If the text node is empty, dirty the line where new text will be inserted . 1278 // If the text node is empty, dirty the line where new text will be inserted .
1283 if (!firstTextBox() && parent()) { 1279 if (!firstTextBox() && parent()) {
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
1866 } 1862 }
1867 secureTextTimer->restartWithNewText(lastTypedCharacterOffset); 1863 secureTextTimer->restartWithNewText(lastTypedCharacterOffset);
1868 } 1864 }
1869 1865
1870 PassRefPtr<AbstractInlineTextBox> RenderText::firstAbstractInlineTextBox() 1866 PassRefPtr<AbstractInlineTextBox> RenderText::firstAbstractInlineTextBox()
1871 { 1867 {
1872 return AbstractInlineTextBox::getOrCreate(this, m_firstTextBox); 1868 return AbstractInlineTextBox::getOrCreate(this, m_firstTextBox);
1873 } 1869 }
1874 1870
1875 } // namespace WebCore 1871 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698