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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutText.cpp

Issue 2405633002: Reformat comments in core/layout (Closed)
Patch Set: Created 4 years, 2 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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 unsigned length = string->length(); 108 unsigned length = string->length();
109 const StringImpl& input = *string->impl(); 109 const StringImpl& input = *string->impl();
110 110
111 if (length >= std::numeric_limits<unsigned>::max()) 111 if (length >= std::numeric_limits<unsigned>::max())
112 CRASH(); 112 CRASH();
113 113
114 StringBuffer<UChar> stringWithPrevious(length + 1); 114 StringBuffer<UChar> stringWithPrevious(length + 1);
115 stringWithPrevious[0] = 115 stringWithPrevious[0] =
116 previous == noBreakSpaceCharacter ? spaceCharacter : previous; 116 previous == noBreakSpaceCharacter ? spaceCharacter : previous;
117 for (unsigned i = 1; i < length + 1; i++) { 117 for (unsigned i = 1; i < length + 1; i++) {
118 // Replace &nbsp with a real space since ICU no longer treats &nbsp as a wor d separator. 118 // Replace &nbsp with a real space since ICU no longer treats &nbsp as a
119 // word separator.
119 if (input[i - 1] == noBreakSpaceCharacter) 120 if (input[i - 1] == noBreakSpaceCharacter)
120 stringWithPrevious[i] = spaceCharacter; 121 stringWithPrevious[i] = spaceCharacter;
121 else 122 else
122 stringWithPrevious[i] = input[i - 1]; 123 stringWithPrevious[i] = input[i - 1];
123 } 124 }
124 125
125 TextBreakIterator* boundary = 126 TextBreakIterator* boundary =
126 wordBreakIterator(stringWithPrevious.characters(), length + 1); 127 wordBreakIterator(stringWithPrevious.characters(), length + 1);
127 if (!boundary) 128 if (!boundary)
128 return; 129 return;
(...skipping 23 matching lines...) Expand all
152 m_containsReversedText(false), 153 m_containsReversedText(false),
153 m_knownToHaveNoOverflowAndNoFallbackFonts(false), 154 m_knownToHaveNoOverflowAndNoFallbackFonts(false),
154 m_minWidth(-1), 155 m_minWidth(-1),
155 m_maxWidth(-1), 156 m_maxWidth(-1),
156 m_firstLineMinWidth(0), 157 m_firstLineMinWidth(0),
157 m_lastLineLineMinWidth(0), 158 m_lastLineLineMinWidth(0),
158 m_text(std::move(str)), 159 m_text(std::move(str)),
159 m_firstTextBox(nullptr), 160 m_firstTextBox(nullptr),
160 m_lastTextBox(nullptr) { 161 m_lastTextBox(nullptr) {
161 ASSERT(m_text); 162 ASSERT(m_text);
162 // FIXME: Some clients of LayoutText (and subclasses) pass Document as node to create anonymous layoutObject. 163 // FIXME: Some clients of LayoutText (and subclasses) pass Document as node to
164 // create anonymous layoutObject.
163 // They should be switched to passing null and using setDocumentForAnonymous. 165 // They should be switched to passing null and using setDocumentForAnonymous.
164 if (node && node->isDocumentNode()) 166 if (node && node->isDocumentNode())
165 setDocumentForAnonymous(toDocument(node)); 167 setDocumentForAnonymous(toDocument(node));
166 168
167 m_canUseSimpleFontCodePath = computeCanUseSimpleFontCodePath(); 169 m_canUseSimpleFontCodePath = computeCanUseSimpleFontCodePath();
168 setIsText(); 170 setIsText();
169 171
170 view()->frameView()->incrementVisuallyNonEmptyCharacterCount(m_text.length()); 172 view()->frameView()->incrementVisuallyNonEmptyCharacterCount(m_text.length());
171 } 173 }
172 174
173 #if ENABLE(ASSERT) 175 #if ENABLE(ASSERT)
174 176
175 LayoutText::~LayoutText() { 177 LayoutText::~LayoutText() {
176 ASSERT(!m_firstTextBox); 178 ASSERT(!m_firstTextBox);
177 ASSERT(!m_lastTextBox); 179 ASSERT(!m_lastTextBox);
178 } 180 }
179 181
180 #endif 182 #endif
181 183
182 bool LayoutText::isTextFragment() const { 184 bool LayoutText::isTextFragment() const {
183 return false; 185 return false;
184 } 186 }
185 187
186 bool LayoutText::isWordBreak() const { 188 bool LayoutText::isWordBreak() const {
187 return false; 189 return false;
188 } 190 }
189 191
190 void LayoutText::styleDidChange(StyleDifference diff, 192 void LayoutText::styleDidChange(StyleDifference diff,
191 const ComputedStyle* oldStyle) { 193 const ComputedStyle* oldStyle) {
192 // There is no need to ever schedule paint invalidations from a style change o f a text run, since 194 // There is no need to ever schedule paint invalidations from a style change
193 // we already did this for the parent of the text run. 195 // of a text run, since we already did this for the parent of the text run.
194 // We do have to schedule layouts, though, since a style change can force us t o 196 // We do have to schedule layouts, though, since a style change can force us
195 // need to relayout. 197 // to need to relayout.
196 if (diff.needsFullLayout()) { 198 if (diff.needsFullLayout()) {
197 setNeedsLayoutAndPrefWidthsRecalc(LayoutInvalidationReason::StyleChange); 199 setNeedsLayoutAndPrefWidthsRecalc(LayoutInvalidationReason::StyleChange);
198 m_knownToHaveNoOverflowAndNoFallbackFonts = false; 200 m_knownToHaveNoOverflowAndNoFallbackFonts = false;
199 } 201 }
200 202
201 const ComputedStyle& newStyle = styleRef(); 203 const ComputedStyle& newStyle = styleRef();
202 ETextTransform oldTransform = oldStyle ? oldStyle->textTransform() : TTNONE; 204 ETextTransform oldTransform = oldStyle ? oldStyle->textTransform() : TTNONE;
203 ETextSecurity oldSecurity = oldStyle ? oldStyle->textSecurity() : TSNONE; 205 ETextSecurity oldSecurity = oldStyle ? oldStyle->textSecurity() : TSNONE;
204 if (oldTransform != newStyle.textTransform() || 206 if (oldTransform != newStyle.textTransform() ||
205 oldSecurity != newStyle.textSecurity()) 207 oldSecurity != newStyle.textSecurity())
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 300
299 PassRefPtr<StringImpl> LayoutText::originalText() const { 301 PassRefPtr<StringImpl> LayoutText::originalText() const {
300 Node* e = node(); 302 Node* e = node();
301 return (e && e->isTextNode()) ? toText(e)->dataImpl() : 0; 303 return (e && e->isTextNode()) ? toText(e)->dataImpl() : 0;
302 } 304 }
303 305
304 String LayoutText::plainText() const { 306 String LayoutText::plainText() const {
305 if (node()) 307 if (node())
306 return blink::plainText(EphemeralRange::rangeOfContents(*node())); 308 return blink::plainText(EphemeralRange::rangeOfContents(*node()));
307 309
308 // FIXME: this is just a stopgap until TextIterator is adapted to support gene rated text. 310 // FIXME: this is just a stopgap until TextIterator is adapted to support
311 // generated text.
309 StringBuilder plainTextBuilder; 312 StringBuilder plainTextBuilder;
310 for (InlineTextBox* textBox = firstTextBox(); textBox; 313 for (InlineTextBox* textBox = firstTextBox(); textBox;
311 textBox = textBox->nextTextBox()) { 314 textBox = textBox->nextTextBox()) {
312 String text = m_text.substring(textBox->start(), textBox->len()) 315 String text = m_text.substring(textBox->start(), textBox->len())
313 .simplifyWhiteSpace(WTF::DoNotStripWhiteSpace); 316 .simplifyWhiteSpace(WTF::DoNotStripWhiteSpace);
314 plainTextBuilder.append(text); 317 plainTextBuilder.append(text);
315 if (textBox->nextTextBox() && 318 if (textBox->nextTextBox() &&
316 textBox->nextTextBox()->start() > textBox->end() && text.length() && 319 textBox->nextTextBox()->start() > textBox->end() && text.length() &&
317 !text.right(1).containsOnlyWhitespace()) 320 !text.right(1).containsOnlyWhitespace())
318 plainTextBuilder.append(spaceCharacter); 321 plainTextBuilder.append(spaceCharacter);
(...skipping 28 matching lines...) Expand all
347 } 350 }
348 return FloatRect(r); 351 return FloatRect(r);
349 } 352 }
350 return FloatRect(); 353 return FloatRect();
351 } 354 }
352 355
353 void LayoutText::absoluteRectsForRange(Vector<IntRect>& rects, 356 void LayoutText::absoluteRectsForRange(Vector<IntRect>& rects,
354 unsigned start, 357 unsigned start,
355 unsigned end, 358 unsigned end,
356 bool useSelectionHeight) { 359 bool useSelectionHeight) {
357 // Work around signed/unsigned issues. This function takes unsigneds, and is o ften passed UINT_MAX 360 // Work around signed/unsigned issues. This function takes unsigneds, and is
358 // to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this 361 // often passed UINT_MAX to mean "all the way to the end". InlineTextBox
359 // function to take ints causes various internal mismatches. But selectionRect takes ints, and 362 // coordinates are unsigneds, so changing this function to take ints causes
360 // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take unsigneds, but 363 // various internal mismatches. But selectionRect takes ints, and passing
361 // that would cause many ripple effects, so for now we'll just clamp our unsig ned parameters to INT_MAX. 364 // UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take
365 // unsigneds, but that would cause many ripple effects, so for now we'll just
366 // clamp our unsigned parameters to INT_MAX.
362 ASSERT(end == UINT_MAX || end <= INT_MAX); 367 ASSERT(end == UINT_MAX || end <= INT_MAX);
363 ASSERT(start <= INT_MAX); 368 ASSERT(start <= INT_MAX);
364 start = std::min(start, static_cast<unsigned>(INT_MAX)); 369 start = std::min(start, static_cast<unsigned>(INT_MAX));
365 end = std::min(end, static_cast<unsigned>(INT_MAX)); 370 end = std::min(end, static_cast<unsigned>(INT_MAX));
366 371
367 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 372 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
368 // Note: box->end() returns the index of the last character, not the index p ast it 373 // Note: box->end() returns the index of the last character, not the index
374 // past it
369 if (start <= box->start() && box->end() < end) { 375 if (start <= box->start() && box->end() < end) {
370 FloatRect r(box->calculateBoundaries()); 376 FloatRect r(box->calculateBoundaries());
371 if (useSelectionHeight) { 377 if (useSelectionHeight) {
372 LayoutRect selectionRect = box->localSelectionRect(start, end); 378 LayoutRect selectionRect = box->localSelectionRect(start, end);
373 if (box->isHorizontal()) { 379 if (box->isHorizontal()) {
374 r.setHeight(selectionRect.height().toFloat()); 380 r.setHeight(selectionRect.height().toFloat());
375 r.setY(selectionRect.y().toFloat()); 381 r.setY(selectionRect.y().toFloat());
376 } else { 382 } else {
377 r.setWidth(selectionRect.width().toFloat()); 383 r.setWidth(selectionRect.width().toFloat());
378 r.setX(selectionRect.x().toFloat()); 384 r.setX(selectionRect.x().toFloat());
379 } 385 }
380 } 386 }
381 rects.append(localToAbsoluteQuad(r).enclosingBoundingBox()); 387 rects.append(localToAbsoluteQuad(r).enclosingBoundingBox());
382 } else { 388 } else {
383 // FIXME: This code is wrong. It's converting local to absolute twice. htt p://webkit.org/b/65722 389 // FIXME: This code is wrong. It's converting local to absolute twice.
390 // http://webkit.org/b/65722
384 FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight); 391 FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight);
385 if (!rect.isZero()) 392 if (!rect.isZero())
386 rects.append(localToAbsoluteQuad(rect).enclosingBoundingBox()); 393 rects.append(localToAbsoluteQuad(rect).enclosingBoundingBox());
387 } 394 }
388 } 395 }
389 } 396 }
390 397
391 static IntRect ellipsisRectForBox(InlineTextBox* box, 398 static IntRect ellipsisRectForBox(InlineTextBox* box,
392 unsigned startPos, 399 unsigned startPos,
393 unsigned endPos) { 400 unsigned endPos) {
394 if (!box) 401 if (!box)
395 return IntRect(); 402 return IntRect();
396 403
397 unsigned short truncation = box->truncation(); 404 unsigned short truncation = box->truncation();
398 if (truncation == cNoTruncation) 405 if (truncation == cNoTruncation)
399 return IntRect(); 406 return IntRect();
400 407
401 IntRect rect; 408 IntRect rect;
402 if (EllipsisBox* ellipsis = box->root().ellipsisBox()) { 409 if (EllipsisBox* ellipsis = box->root().ellipsisBox()) {
403 int ellipsisStartPosition = std::max<int>(startPos - box->start(), 0); 410 int ellipsisStartPosition = std::max<int>(startPos - box->start(), 0);
404 int ellipsisEndPosition = std::min<int>(endPos - box->start(), box->len()); 411 int ellipsisEndPosition = std::min<int>(endPos - box->start(), box->len());
405 412
406 // The ellipsis should be considered to be selected if the end of 413 // The ellipsis should be considered to be selected if the end of the
407 // the selection is past the beginning of the truncation and the 414 // selection is past the beginning of the truncation and the beginning of
408 // beginning of the selection is before or at the beginning of the truncatio n. 415 // the selection is before or at the beginning of the truncation.
409 if (ellipsisEndPosition >= truncation && 416 if (ellipsisEndPosition >= truncation &&
410 ellipsisStartPosition <= truncation) 417 ellipsisStartPosition <= truncation)
411 return ellipsis->selectionRect(); 418 return ellipsis->selectionRect();
412 } 419 }
413 420
414 return IntRect(); 421 return IntRect();
415 } 422 }
416 423
417 void LayoutText::quads(Vector<FloatQuad>& quads, 424 void LayoutText::quads(Vector<FloatQuad>& quads,
418 ClippingOption option, 425 ClippingOption option,
419 LocalOrAbsoluteOption localOrAbsolute) const { 426 LocalOrAbsoluteOption localOrAbsolute) const {
420 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 427 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
421 FloatRect boundaries(box->calculateBoundaries()); 428 FloatRect boundaries(box->calculateBoundaries());
422 429
423 // Shorten the width of this text box if it ends in an ellipsis. 430 // Shorten the width of this text box if it ends in an ellipsis.
424 // FIXME: ellipsisRectForBox should switch to return FloatRect soon with the subpixellayout branch. 431 // FIXME: ellipsisRectForBox should switch to return FloatRect soon with the
432 // subpixellayout branch.
425 IntRect ellipsisRect = (option == ClipToEllipsis) 433 IntRect ellipsisRect = (option == ClipToEllipsis)
426 ? ellipsisRectForBox(box, 0, textLength()) 434 ? ellipsisRectForBox(box, 0, textLength())
427 : IntRect(); 435 : IntRect();
428 if (!ellipsisRect.isEmpty()) { 436 if (!ellipsisRect.isEmpty()) {
429 if (style()->isHorizontalWritingMode()) 437 if (style()->isHorizontalWritingMode())
430 boundaries.setWidth(ellipsisRect.maxX() - boundaries.x()); 438 boundaries.setWidth(ellipsisRect.maxX() - boundaries.x());
431 else 439 else
432 boundaries.setHeight(ellipsisRect.maxY() - boundaries.y()); 440 boundaries.setHeight(ellipsisRect.maxY() - boundaries.y());
433 } 441 }
434 if (localOrAbsolute == AbsoluteQuads) 442 if (localOrAbsolute == AbsoluteQuads)
435 quads.append(localToAbsoluteQuad(boundaries)); 443 quads.append(localToAbsoluteQuad(boundaries));
436 else 444 else
437 quads.append(boundaries); 445 quads.append(boundaries);
438 } 446 }
439 } 447 }
440 448
441 void LayoutText::absoluteQuads(Vector<FloatQuad>& quads) const { 449 void LayoutText::absoluteQuads(Vector<FloatQuad>& quads) const {
442 this->quads(quads, NoClipping, AbsoluteQuads); 450 this->quads(quads, NoClipping, AbsoluteQuads);
443 } 451 }
444 452
445 void LayoutText::absoluteQuadsForRange(Vector<FloatQuad>& quads, 453 void LayoutText::absoluteQuadsForRange(Vector<FloatQuad>& quads,
446 unsigned start, 454 unsigned start,
447 unsigned end, 455 unsigned end,
448 bool useSelectionHeight) { 456 bool useSelectionHeight) {
449 // Work around signed/unsigned issues. This function takes unsigneds, and is o ften passed UINT_MAX 457 // Work around signed/unsigned issues. This function takes unsigneds, and is
450 // to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this 458 // often passed UINT_MAX to mean "all the way to the end". InlineTextBox
451 // function to take ints causes various internal mismatches. But selectionRect takes ints, and 459 // coordinates are unsigneds, so changing this function to take ints causes
452 // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take unsigneds, but 460 // various internal mismatches. But selectionRect takes ints, and passing
453 // that would cause many ripple effects, so for now we'll just clamp our unsig ned parameters to INT_MAX. 461 // UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take
462 // unsigneds, but that would cause many ripple effects, so for now we'll just
463 // clamp our unsigned parameters to INT_MAX.
454 ASSERT(end == UINT_MAX || end <= INT_MAX); 464 ASSERT(end == UINT_MAX || end <= INT_MAX);
455 ASSERT(start <= INT_MAX); 465 ASSERT(start <= INT_MAX);
456 start = std::min(start, static_cast<unsigned>(INT_MAX)); 466 start = std::min(start, static_cast<unsigned>(INT_MAX));
457 end = std::min(end, static_cast<unsigned>(INT_MAX)); 467 end = std::min(end, static_cast<unsigned>(INT_MAX));
458 468
459 const unsigned caretMinOffset = static_cast<unsigned>(this->caretMinOffset()); 469 const unsigned caretMinOffset = static_cast<unsigned>(this->caretMinOffset());
460 const unsigned caretMaxOffset = static_cast<unsigned>(this->caretMaxOffset()); 470 const unsigned caretMaxOffset = static_cast<unsigned>(this->caretMaxOffset());
461 471
462 // Narrows |start| and |end| into |caretMinOffset| and |careMaxOffset| 472 // Narrows |start| and |end| into |caretMinOffset| and |careMaxOffset|
463 // to ignore unrendered leading and trailing whitespaces. 473 // to ignore unrendered leading and trailing whitespaces.
464 start = std::min(std::max(caretMinOffset, start), caretMaxOffset); 474 start = std::min(std::max(caretMinOffset, start), caretMaxOffset);
465 end = std::min(std::max(caretMinOffset, end), caretMaxOffset); 475 end = std::min(std::max(caretMinOffset, end), caretMaxOffset);
466 476
467 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 477 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
468 // Note: box->end() returns the index of the last character, not the index p ast it 478 // Note: box->end() returns the index of the last character, not the index
479 // past it
469 if (start <= box->start() && box->end() < end) { 480 if (start <= box->start() && box->end() < end) {
470 LayoutRect r(box->calculateBoundaries()); 481 LayoutRect r(box->calculateBoundaries());
471 if (useSelectionHeight) { 482 if (useSelectionHeight) {
472 LayoutRect selectionRect = box->localSelectionRect(start, end); 483 LayoutRect selectionRect = box->localSelectionRect(start, end);
473 if (box->isHorizontal()) { 484 if (box->isHorizontal()) {
474 r.setHeight(selectionRect.height()); 485 r.setHeight(selectionRect.height());
475 r.setY(selectionRect.y()); 486 r.setY(selectionRect.y());
476 } else { 487 } else {
477 r.setWidth(selectionRect.width()); 488 r.setWidth(selectionRect.width());
478 r.setX(selectionRect.x()); 489 r.setX(selectionRect.x());
(...skipping 22 matching lines...) Expand all
501 AlwaysUpstream, 512 AlwaysUpstream,
502 UpstreamIfPositionIsNotAtStart 513 UpstreamIfPositionIsNotAtStart
503 }; 514 };
504 515
505 static bool lineDirectionPointFitsInBox( 516 static bool lineDirectionPointFitsInBox(
506 int pointLineDirection, 517 int pointLineDirection,
507 InlineTextBox* box, 518 InlineTextBox* box,
508 ShouldAffinityBeDownstream& shouldAffinityBeDownstream) { 519 ShouldAffinityBeDownstream& shouldAffinityBeDownstream) {
509 shouldAffinityBeDownstream = AlwaysDownstream; 520 shouldAffinityBeDownstream = AlwaysDownstream;
510 521
511 // the x coordinate is equal to the left edge of this box 522 // the x coordinate is equal to the left edge of this box the affinity must be
512 // the affinity must be downstream so the position doesn't jump back to the pr evious line 523 // downstream so the position doesn't jump back to the previous line except
513 // except when box is the first box in the line 524 // when box is the first box in the line
514 if (pointLineDirection <= box->logicalLeft()) { 525 if (pointLineDirection <= box->logicalLeft()) {
515 shouldAffinityBeDownstream = !box->prevLeafChild() 526 shouldAffinityBeDownstream = !box->prevLeafChild()
516 ? UpstreamIfPositionIsNotAtStart 527 ? UpstreamIfPositionIsNotAtStart
517 : AlwaysDownstream; 528 : AlwaysDownstream;
518 return true; 529 return true;
519 } 530 }
520 531
521 // and the x coordinate is to the left of the right edge of this box 532 // and the x coordinate is to the left of the right edge of this box
522 // check to see if position goes in this box 533 // check to see if position goes in this box
523 if (pointLineDirection < box->logicalRight()) { 534 if (pointLineDirection < box->logicalRight()) {
524 shouldAffinityBeDownstream = UpstreamIfPositionIsNotAtStart; 535 shouldAffinityBeDownstream = UpstreamIfPositionIsNotAtStart;
525 return true; 536 return true;
526 } 537 }
527 538
528 // box is first on line 539 // box is first on line
529 // and the x coordinate is to the left of the first text box left edge 540 // and the x coordinate is to the left of the first text box left edge
530 if (!box->prevLeafChildIgnoringLineBreak() && 541 if (!box->prevLeafChildIgnoringLineBreak() &&
531 pointLineDirection < box->logicalLeft()) 542 pointLineDirection < box->logicalLeft())
532 return true; 543 return true;
533 544
534 if (!box->nextLeafChildIgnoringLineBreak()) { 545 if (!box->nextLeafChildIgnoringLineBreak()) {
535 // box is last on line 546 // box is last on line and the x coordinate is to the right of the last text
536 // and the x coordinate is to the right of the last text box right edge 547 // box right edge generate VisiblePosition, use TextAffinity::Upstream
537 // generate VisiblePosition, use TextAffinity::Upstream affinity if possible 548 // affinity if possible
538 shouldAffinityBeDownstream = UpstreamIfPositionIsNotAtStart; 549 shouldAffinityBeDownstream = UpstreamIfPositionIsNotAtStart;
539 return true; 550 return true;
540 } 551 }
541 552
542 return false; 553 return false;
543 } 554 }
544 555
545 static PositionWithAffinity createPositionWithAffinityForBox( 556 static PositionWithAffinity createPositionWithAffinityForBox(
546 const InlineBox* box, 557 const InlineBox* box,
547 int offset, 558 int offset,
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 break; 775 break;
765 case JUSTIFY: 776 case JUSTIFY:
766 case TASTART: 777 case TASTART:
767 rightAligned = !cbStyle.isLeftToRightDirection(); 778 rightAligned = !cbStyle.isLeftToRightDirection();
768 break; 779 break;
769 case TAEND: 780 case TAEND:
770 rightAligned = cbStyle.isLeftToRightDirection(); 781 rightAligned = cbStyle.isLeftToRightDirection();
771 break; 782 break;
772 } 783 }
773 784
774 // for unicode-bidi: plaintext, use inlineBoxBidiLevel() to test the correct d irection for the cursor. 785 // for unicode-bidi: plaintext, use inlineBoxBidiLevel() to test the correct
786 // direction for the cursor.
775 if (rightAligned && style()->unicodeBidi() == Plaintext) { 787 if (rightAligned && style()->unicodeBidi() == Plaintext) {
776 if (inlineBox->bidiLevel() % 2 != 1) 788 if (inlineBox->bidiLevel() % 2 != 1)
777 rightAligned = false; 789 rightAligned = false;
778 } 790 }
779 791
780 if (rightAligned) { 792 if (rightAligned) {
781 left = std::max(left, leftEdge); 793 left = std::max(left, leftEdge);
782 left = std::min(left, rootRight - caretWidth()); 794 left = std::min(left, rootRight - caretWidth());
783 } else { 795 } else {
784 left = std::min(left, rightEdge - caretWidthRightOfOffset); 796 left = std::min(left, rightEdge - caretWidthRightOfOffset);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 bool& hasBreakableChar, 843 bool& hasBreakableChar,
832 bool& hasBreak, 844 bool& hasBreak,
833 LayoutUnit& firstLineMaxWidth, 845 LayoutUnit& firstLineMaxWidth,
834 LayoutUnit& lastLineMaxWidth, 846 LayoutUnit& lastLineMaxWidth,
835 LayoutUnit& minWidth, 847 LayoutUnit& minWidth,
836 LayoutUnit& maxWidth, 848 LayoutUnit& maxWidth,
837 bool& stripFrontSpaces, 849 bool& stripFrontSpaces,
838 TextDirection direction) { 850 TextDirection direction) {
839 float floatMinWidth = 0.0f, floatMaxWidth = 0.0f; 851 float floatMinWidth = 0.0f, floatMaxWidth = 0.0f;
840 852
841 // Convert leadWidth to a float here, to avoid multiple implict conversions be low. 853 // Convert leadWidth to a float here, to avoid multiple implict conversions
854 // below.
842 float leadWidth = leadWidthLayoutUnit.toFloat(); 855 float leadWidth = leadWidthLayoutUnit.toFloat();
843 856
844 bool collapseWhiteSpace = style()->collapseWhiteSpace(); 857 bool collapseWhiteSpace = style()->collapseWhiteSpace();
845 if (!collapseWhiteSpace) 858 if (!collapseWhiteSpace)
846 stripFrontSpaces = false; 859 stripFrontSpaces = false;
847 860
848 if (m_hasTab || preferredLogicalWidthsDirty()) 861 if (m_hasTab || preferredLogicalWidthsDirty())
849 computePreferredLogicalWidths(leadWidth); 862 computePreferredLogicalWidths(leadWidth);
850 863
851 hasBreakableStart = !stripFrontSpaces && m_hasBreakableStart; 864 hasBreakableStart = !stripFrontSpaces && m_hasBreakableStart;
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
1148 } 1161 }
1149 } 1162 }
1150 1163
1151 // Terminate word boundary at bidi run boundary. 1164 // Terminate word boundary at bidi run boundary.
1152 if (run) 1165 if (run)
1153 j = std::min(j, run->stop() + 1); 1166 j = std::min(j, run->stop() + 1);
1154 int wordLen = j - i; 1167 int wordLen = j - i;
1155 if (wordLen) { 1168 if (wordLen) {
1156 bool isSpace = (j < len) && c == spaceCharacter; 1169 bool isSpace = (j < len) && c == spaceCharacter;
1157 1170
1158 // Non-zero only when kerning is enabled, in which case we measure words w ith their trailing 1171 // Non-zero only when kerning is enabled, in which case we measure words
1159 // space, then subtract its width. 1172 // with their trailing space, then subtract its width.
1160 float wordTrailingSpaceWidth = 0; 1173 float wordTrailingSpaceWidth = 0;
1161 if (isSpace && 1174 if (isSpace &&
1162 (f.getFontDescription().getTypesettingFeatures() & Kerning)) { 1175 (f.getFontDescription().getTypesettingFeatures() & Kerning)) {
1163 ASSERT(textDirection >= 0 && textDirection <= 1); 1176 ASSERT(textDirection >= 0 && textDirection <= 1);
1164 if (!cachedWordTrailingSpaceWidth[textDirection]) 1177 if (!cachedWordTrailingSpaceWidth[textDirection])
1165 cachedWordTrailingSpaceWidth[textDirection] = 1178 cachedWordTrailingSpaceWidth[textDirection] =
1166 f.width(constructTextRun(f, &spaceCharacter, 1, styleToUse, 1179 f.width(constructTextRun(f, &spaceCharacter, 1, styleToUse,
1167 textDirection)) + 1180 textDirection)) +
1168 wordSpacing; 1181 wordSpacing;
1169 wordTrailingSpaceWidth = cachedWordTrailingSpaceWidth[textDirection]; 1182 wordTrailingSpaceWidth = cachedWordTrailingSpaceWidth[textDirection];
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1216 f, lastWordBoundary, j - lastWordBoundary, leadWidth, 1229 f, lastWordBoundary, j - lastWordBoundary, leadWidth,
1217 currMaxWidth, textDirection, &fallbackFonts, &glyphBounds); 1230 currMaxWidth, textDirection, &fallbackFonts, &glyphBounds);
1218 lastWordBoundary = j; 1231 lastWordBoundary = j;
1219 } 1232 }
1220 1233
1221 bool isCollapsibleWhiteSpace = 1234 bool isCollapsibleWhiteSpace =
1222 (j < len) && styleToUse.isCollapsibleWhiteSpace(c); 1235 (j < len) && styleToUse.isCollapsibleWhiteSpace(c);
1223 if (j < len && styleToUse.autoWrap()) 1236 if (j < len && styleToUse.autoWrap())
1224 m_hasBreakableChar = true; 1237 m_hasBreakableChar = true;
1225 1238
1226 // Add in wordSpacing to our currMaxWidth, but not if this is the last wor d on a line or the 1239 // Add in wordSpacing to our currMaxWidth, but not if this is the last
1240 // word on a line or the
1227 // last word in the run. 1241 // last word in the run.
1228 if (wordSpacing && (isSpace || isCollapsibleWhiteSpace) && 1242 if (wordSpacing && (isSpace || isCollapsibleWhiteSpace) &&
1229 !containsOnlyWhitespace(j, len - j)) 1243 !containsOnlyWhitespace(j, len - j))
1230 currMaxWidth += wordSpacing; 1244 currMaxWidth += wordSpacing;
1231 1245
1232 if (firstWord) { 1246 if (firstWord) {
1233 firstWord = false; 1247 firstWord = false;
1234 // If the first character in the run is breakable, then we consider ours elves to have a beginning 1248 // If the first character in the run is breakable, then we consider
1235 // minimum width of 0, since a break could occur right before our run st arts, preventing us from ever 1249 // ourselves to have a beginning minimum width of 0, since a break could
1236 // being appended to a previous text run when considering the total mini mum width of the containing block. 1250 // occur right before our run starts, preventing us from ever being
1251 // appended to a previous text run when considering the total minimum
1252 // width of the containing block.
1237 if (hasBreak) 1253 if (hasBreak)
1238 m_hasBreakableChar = true; 1254 m_hasBreakableChar = true;
1239 m_firstLineMinWidth = hasBreak ? 0 : currMinWidth; 1255 m_firstLineMinWidth = hasBreak ? 0 : currMinWidth;
1240 } 1256 }
1241 m_lastLineLineMinWidth = currMinWidth; 1257 m_lastLineLineMinWidth = currMinWidth;
1242 1258
1243 if (currMinWidth > m_minWidth) 1259 if (currMinWidth > m_minWidth)
1244 m_minWidth = currMinWidth; 1260 m_minWidth = currMinWidth;
1245 currMinWidth = 0; 1261 currMinWidth = 0;
1246 1262
1247 i += wordLen - 1; 1263 i += wordLen - 1;
1248 } else { 1264 } else {
1249 // Nowrap can never be broken, so don't bother setting the 1265 // Nowrap can never be broken, so don't bother setting the breakable
1250 // breakable character boolean. Pre can only be broken if we encounter a n ewline. 1266 // character boolean. Pre can only be broken if we encounter a newline.
1251 if (style()->autoWrap() || isNewline) 1267 if (style()->autoWrap() || isNewline)
1252 m_hasBreakableChar = true; 1268 m_hasBreakableChar = true;
1253 1269
1254 if (currMinWidth > m_minWidth) 1270 if (currMinWidth > m_minWidth)
1255 m_minWidth = currMinWidth; 1271 m_minWidth = currMinWidth;
1256 currMinWidth = 0; 1272 currMinWidth = 0;
1257 1273
1258 if (isNewline) { // Only set if preserveNewline was true and we saw a new line. 1274 // Only set if preserveNewline was true and we saw a newline.
1275 if (isNewline) {
1259 if (firstLine) { 1276 if (firstLine) {
1260 firstLine = false; 1277 firstLine = false;
1261 leadWidth = 0; 1278 leadWidth = 0;
1262 if (!styleToUse.autoWrap()) 1279 if (!styleToUse.autoWrap())
1263 m_firstLineMinWidth = currMaxWidth; 1280 m_firstLineMinWidth = currMaxWidth;
1264 } 1281 }
1265 1282
1266 if (currMaxWidth > m_maxWidth) 1283 if (currMaxWidth > m_maxWidth)
1267 m_maxWidth = currMaxWidth; 1284 m_maxWidth = currMaxWidth;
1268 currMaxWidth = 0; 1285 currMaxWidth = 0;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 if (!style()->isCollapsibleWhiteSpace(characters16()[i])) 1341 if (!style()->isCollapsibleWhiteSpace(characters16()[i]))
1325 return false; 1342 return false;
1326 } 1343 }
1327 return true; 1344 return true;
1328 } 1345 }
1329 1346
1330 bool LayoutText::isRenderedCharacter(int offsetInNode) const { 1347 bool LayoutText::isRenderedCharacter(int offsetInNode) const {
1331 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 1348 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
1332 if (offsetInNode < static_cast<int>(box->start()) && 1349 if (offsetInNode < static_cast<int>(box->start()) &&
1333 !containsReversedText()) { 1350 !containsReversedText()) {
1334 // The offset we're looking for is before this node 1351 // The offset we're looking for is before this node this means the offset
1335 // this means the offset must be in content that is 1352 // must be in content that is not laid out. Return false.
1336 // not laid out. Return false.
1337 return false; 1353 return false;
1338 } 1354 }
1339 if (offsetInNode >= static_cast<int>(box->start()) && 1355 if (offsetInNode >= static_cast<int>(box->start()) &&
1340 offsetInNode < static_cast<int>(box->start() + box->len())) 1356 offsetInNode < static_cast<int>(box->start() + box->len()))
1341 return true; 1357 return true;
1342 } 1358 }
1343 1359
1344 return false; 1360 return false;
1345 } 1361 }
1346 1362
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1415 unsigned oldLen = textLength(); 1431 unsigned oldLen = textLength();
1416 unsigned newLen = text->length(); 1432 unsigned newLen = text->length();
1417 int delta = newLen - oldLen; 1433 int delta = newLen - oldLen;
1418 unsigned end = len ? offset + len - 1 : offset; 1434 unsigned end = len ? offset + len - 1 : offset;
1419 1435
1420 RootInlineBox* firstRootBox = nullptr; 1436 RootInlineBox* firstRootBox = nullptr;
1421 RootInlineBox* lastRootBox = nullptr; 1437 RootInlineBox* lastRootBox = nullptr;
1422 1438
1423 bool dirtiedLines = false; 1439 bool dirtiedLines = false;
1424 1440
1425 // Dirty all text boxes that include characters in between offset and offset+l en. 1441 // Dirty all text boxes that include characters in between offset and
1442 // offset+len.
1426 for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) { 1443 for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) {
1427 // FIXME: This shouldn't rely on the end of a dirty line box. See https://bu gs.webkit.org/show_bug.cgi?id=97264 1444 // FIXME: This shouldn't rely on the end of a dirty line box. See
1445 // https://bugs.webkit.org/show_bug.cgi?id=97264
1428 // Text run is entirely before the affected range. 1446 // Text run is entirely before the affected range.
1429 if (curr->end() < offset) 1447 if (curr->end() < offset)
1430 continue; 1448 continue;
1431 1449
1432 // Text run is entirely after the affected range. 1450 // Text run is entirely after the affected range.
1433 if (curr->start() > end) { 1451 if (curr->start() > end) {
1434 curr->offsetRun(delta); 1452 curr->offsetRun(delta);
1435 RootInlineBox* root = &curr->root(); 1453 RootInlineBox* root = &curr->root();
1436 if (!firstRootBox) { 1454 if (!firstRootBox) {
1437 firstRootBox = root; 1455 firstRootBox = root;
1438 // The affected area was in between two runs. Go ahead and mark the root box of 1456 // The affected area was in between two runs. Go ahead and mark the root
1439 // the run after the affected area as dirty. 1457 // box of the run after the affected area as dirty.
1440 firstRootBox->markDirty(); 1458 firstRootBox->markDirty();
1441 dirtiedLines = true; 1459 dirtiedLines = true;
1442 } 1460 }
1443 lastRootBox = root; 1461 lastRootBox = root;
1444 } else if (curr->end() >= offset && curr->end() <= end) { 1462 } else if (curr->end() >= offset && curr->end() <= end) {
1445 // Text run overlaps with the left end of the affected range. 1463 // Text run overlaps with the left end of the affected range.
1446 curr->dirtyLineBoxes(); 1464 curr->dirtyLineBoxes();
1447 dirtiedLines = true; 1465 dirtiedLines = true;
1448 } else if (curr->start() <= offset && curr->end() >= end) { 1466 } else if (curr->start() <= offset && curr->end() >= end) {
1449 // Text run subsumes the affected range. 1467 // Text run subsumes the affected range.
1450 curr->dirtyLineBoxes(); 1468 curr->dirtyLineBoxes();
1451 dirtiedLines = true; 1469 dirtiedLines = true;
1452 } else if (curr->start() <= end && curr->end() >= end) { 1470 } else if (curr->start() <= end && curr->end() >= end) {
1453 // Text run overlaps with right end of the affected range. 1471 // Text run overlaps with right end of the affected range.
1454 curr->dirtyLineBoxes(); 1472 curr->dirtyLineBoxes();
1455 dirtiedLines = true; 1473 dirtiedLines = true;
1456 } 1474 }
1457 } 1475 }
1458 1476
1459 // Now we have to walk all of the clean lines and adjust their cached line bre ak information 1477 // Now we have to walk all of the clean lines and adjust their cached line
1460 // to reflect our updated offsets. 1478 // break information to reflect our updated offsets.
1461 if (lastRootBox) 1479 if (lastRootBox)
1462 lastRootBox = lastRootBox->nextRootBox(); 1480 lastRootBox = lastRootBox->nextRootBox();
1463 if (firstRootBox) { 1481 if (firstRootBox) {
1464 RootInlineBox* prev = firstRootBox->prevRootBox(); 1482 RootInlineBox* prev = firstRootBox->prevRootBox();
1465 if (prev) 1483 if (prev)
1466 firstRootBox = prev; 1484 firstRootBox = prev;
1467 } else if (lastTextBox()) { 1485 } else if (lastTextBox()) {
1468 ASSERT(!lastRootBox); 1486 ASSERT(!lastRootBox);
1469 firstRootBox = &lastTextBox()->root(); 1487 firstRootBox = &lastTextBox()->root();
1470 firstRootBox->markDirty(); 1488 firstRootBox->markDirty();
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 lastTypedCharacterOffsetToReveal = 1601 lastTypedCharacterOffsetToReveal =
1584 secureTextTimer->lastTypedCharacterOffset(); 1602 secureTextTimer->lastTypedCharacterOffset();
1585 if (lastTypedCharacterOffsetToReveal >= 0) 1603 if (lastTypedCharacterOffsetToReveal >= 0)
1586 revealedText = m_text[lastTypedCharacterOffsetToReveal]; 1604 revealedText = m_text[lastTypedCharacterOffsetToReveal];
1587 } 1605 }
1588 1606
1589 m_text.fill(mask); 1607 m_text.fill(mask);
1590 if (lastTypedCharacterOffsetToReveal >= 0) { 1608 if (lastTypedCharacterOffsetToReveal >= 0) {
1591 m_text.replace(lastTypedCharacterOffsetToReveal, 1, 1609 m_text.replace(lastTypedCharacterOffsetToReveal, 1,
1592 String(&revealedText, 1)); 1610 String(&revealedText, 1));
1593 // m_text may be updated later before timer fires. We invalidate the lastTyp edCharacterOffset to avoid inconsistency. 1611 // m_text may be updated later before timer fires. We invalidate the
1612 // lastTypedCharacterOffset to avoid inconsistency.
1594 secureTextTimer->invalidate(); 1613 secureTextTimer->invalidate();
1595 } 1614 }
1596 } 1615 }
1597 1616
1598 void LayoutText::setText(PassRefPtr<StringImpl> text, bool force) { 1617 void LayoutText::setText(PassRefPtr<StringImpl> text, bool force) {
1599 ASSERT(text); 1618 ASSERT(text);
1600 1619
1601 if (!force && equal(m_text.impl(), text.get())) 1620 if (!force && equal(m_text.impl(), text.get()))
1602 return; 1621 return;
1603 1622
1604 setTextInternal(std::move(text)); 1623 setTextInternal(std::move(text));
1605 // If preferredLogicalWidthsDirty() of an orphan child is true, LayoutObjectCh ildList:: 1624 // If preferredLogicalWidthsDirty() of an orphan child is true,
1606 // insertChildNode() fails to set true to owner. To avoid that, we call 1625 // LayoutObjectChildList::insertChildNode() fails to set true to owner.
1607 // setNeedsLayoutAndPrefWidthsRecalc() only if this LayoutText has parent. 1626 // To avoid that, we call setNeedsLayoutAndPrefWidthsRecalc() only if this
1627 // LayoutText has parent.
1608 if (parent()) 1628 if (parent())
1609 setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( 1629 setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
1610 LayoutInvalidationReason::TextChanged); 1630 LayoutInvalidationReason::TextChanged);
1611 m_knownToHaveNoOverflowAndNoFallbackFonts = false; 1631 m_knownToHaveNoOverflowAndNoFallbackFonts = false;
1612 1632
1613 if (AXObjectCache* cache = document().existingAXObjectCache()) 1633 if (AXObjectCache* cache = document().existingAXObjectCache())
1614 cache->textChanged(this); 1634 cache->textChanged(this);
1615 } 1635 }
1616 1636
1617 void LayoutText::dirtyOrDeleteLineBoxesIfNeeded(bool fullLayout) { 1637 void LayoutText::dirtyOrDeleteLineBoxesIfNeeded(bool fullLayout) {
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
1921 LayoutRect rect = LayoutRect( 1941 LayoutRect rect = LayoutRect(
1922 IntRect(firstRunX(), firstRunY(), linesBox.width(), linesBox.height())); 1942 IntRect(firstRunX(), firstRunY(), linesBox.width(), linesBox.height()));
1923 LayoutBlock* block = containingBlock(); 1943 LayoutBlock* block = containingBlock();
1924 if (block && hasTextBoxes()) 1944 if (block && hasTextBoxes())
1925 block->adjustChildDebugRect(rect); 1945 block->adjustChildDebugRect(rect);
1926 1946
1927 return rect; 1947 return rect;
1928 } 1948 }
1929 1949
1930 } // namespace blink 1950 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutText.h ('k') | third_party/WebKit/Source/core/layout/LayoutTextCombine.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698