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

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

Issue 2763013002: Fix incorrect bounding box position for '\n' (Closed)
Patch Set: Refactor to populate one vector. Created 3 years, 8 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
« no previous file with comments | « third_party/WebKit/LayoutTests/fast/dom/Range/getBoundingClientRect-linebreak-character.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 // coordinates are unsigneds, so changing this function to take ints causes 370 // coordinates are unsigneds, so changing this function to take ints causes
371 // various internal mismatches. But selectionRect takes ints, and passing 371 // various internal mismatches. But selectionRect takes ints, and passing
372 // UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take 372 // UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take
373 // unsigneds, but that would cause many ripple effects, so for now we'll just 373 // unsigneds, but that would cause many ripple effects, so for now we'll just
374 // clamp our unsigned parameters to INT_MAX. 374 // clamp our unsigned parameters to INT_MAX.
375 ASSERT(end == UINT_MAX || end <= INT_MAX); 375 ASSERT(end == UINT_MAX || end <= INT_MAX);
376 ASSERT(start <= INT_MAX); 376 ASSERT(start <= INT_MAX);
377 start = std::min(start, static_cast<unsigned>(INT_MAX)); 377 start = std::min(start, static_cast<unsigned>(INT_MAX));
378 end = std::min(end, static_cast<unsigned>(INT_MAX)); 378 end = std::min(end, static_cast<unsigned>(INT_MAX));
379 379
380 bool hasCheckedBoxInRange = false;
381
380 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 382 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
381 // Note: box->end() returns the index of the last character, not the index 383 // Note: box->end() returns the index of the last character, not the index
382 // past it 384 // past it
383 if (start <= box->start() && box->end() < end) { 385 if (start <= box->start() && box->end() < end) {
384 FloatRect r(box->frameRect()); 386 FloatRect r(box->frameRect());
385 if (useSelectionHeight) { 387 if (useSelectionHeight) {
386 LayoutRect selectionRect = box->localSelectionRect(start, end); 388 LayoutRect selectionRect = box->localSelectionRect(start, end);
387 if (box->isHorizontal()) { 389 if (box->isHorizontal()) {
388 r.setHeight(selectionRect.height().toFloat()); 390 r.setHeight(selectionRect.height().toFloat());
389 r.setY(selectionRect.y().toFloat()); 391 r.setY(selectionRect.y().toFloat());
390 } else { 392 } else {
391 r.setWidth(selectionRect.width().toFloat()); 393 r.setWidth(selectionRect.width().toFloat());
392 r.setX(selectionRect.x().toFloat()); 394 r.setX(selectionRect.x().toFloat());
393 } 395 }
394 } 396 }
397 if (!hasCheckedBoxInRange) {
398 hasCheckedBoxInRange = true;
399 rects.clear();
400 }
395 rects.push_back(localToAbsoluteQuad(r).enclosingBoundingBox()); 401 rects.push_back(localToAbsoluteQuad(r).enclosingBoundingBox());
396 } else { 402 } else if ((box->start() <= start && start <= box->end()) ||
403 (box->start() < end && end <= box->end())) {
404 FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight);
405 if (!rect.isZero()) {
406 if (!hasCheckedBoxInRange) {
407 hasCheckedBoxInRange = true;
408 rects.clear();
409 }
410 rects.push_back(localToAbsoluteQuad(rect).enclosingBoundingBox());
411 }
412 } else if (!hasCheckedBoxInRange) {
397 // FIXME: This code is wrong. It's converting local to absolute twice. 413 // FIXME: This code is wrong. It's converting local to absolute twice.
398 // http://webkit.org/b/65722 414 // http://webkit.org/b/65722
399 FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight); 415 FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight);
400 if (!rect.isZero()) 416 if (!rect.isZero())
401 rects.push_back(localToAbsoluteQuad(rect).enclosingBoundingBox()); 417 rects.push_back(localToAbsoluteQuad(rect).enclosingBoundingBox());
402 } 418 }
403 } 419 }
404 } 420 }
405 421
406 static IntRect ellipsisRectForBox(InlineTextBox* box, 422 static IntRect ellipsisRectForBox(InlineTextBox* box,
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 end = std::min(end, static_cast<unsigned>(INT_MAX)); 493 end = std::min(end, static_cast<unsigned>(INT_MAX));
478 494
479 const unsigned caretMinOffset = static_cast<unsigned>(this->caretMinOffset()); 495 const unsigned caretMinOffset = static_cast<unsigned>(this->caretMinOffset());
480 const unsigned caretMaxOffset = static_cast<unsigned>(this->caretMaxOffset()); 496 const unsigned caretMaxOffset = static_cast<unsigned>(this->caretMaxOffset());
481 497
482 // Narrows |start| and |end| into |caretMinOffset| and |careMaxOffset| 498 // Narrows |start| and |end| into |caretMinOffset| and |careMaxOffset|
483 // to ignore unrendered leading and trailing whitespaces. 499 // to ignore unrendered leading and trailing whitespaces.
484 start = std::min(std::max(caretMinOffset, start), caretMaxOffset); 500 start = std::min(std::max(caretMinOffset, start), caretMaxOffset);
485 end = std::min(std::max(caretMinOffset, end), caretMaxOffset); 501 end = std::min(std::max(caretMinOffset, end), caretMaxOffset);
486 502
503 bool hasCheckedBoxInRange = false;
504
487 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { 505 for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
488 // Note: box->end() returns the index of the last character, not the index 506 // Note: box->end() returns the index of the last character, not the index
489 // past it 507 // past it
490 if (start <= box->start() && box->end() < end) { 508 if (start <= box->start() && box->end() < end) {
491 LayoutRect r(box->frameRect()); 509 LayoutRect r(box->frameRect());
492 if (useSelectionHeight) { 510 if (useSelectionHeight) {
493 LayoutRect selectionRect = box->localSelectionRect(start, end); 511 LayoutRect selectionRect = box->localSelectionRect(start, end);
494 if (box->isHorizontal()) { 512 if (box->isHorizontal()) {
495 r.setHeight(selectionRect.height()); 513 r.setHeight(selectionRect.height());
496 r.setY(selectionRect.y()); 514 r.setY(selectionRect.y());
497 } else { 515 } else {
498 r.setWidth(selectionRect.width()); 516 r.setWidth(selectionRect.width());
499 r.setX(selectionRect.x()); 517 r.setX(selectionRect.x());
500 } 518 }
501 } 519 }
520 if (!hasCheckedBoxInRange) {
521 hasCheckedBoxInRange = true;
522 quads.clear();
523 }
502 quads.push_back(localToAbsoluteQuad(FloatRect(r))); 524 quads.push_back(localToAbsoluteQuad(FloatRect(r)));
503 } else { 525 } else if ((box->start() <= start && start <= box->end()) ||
526 (box->start() < end && end <= box->end())) {
527 FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight);
528 if (!rect.isZero()) {
529 if (!hasCheckedBoxInRange) {
530 hasCheckedBoxInRange = true;
531 quads.clear();
532 }
533 quads.push_back(localToAbsoluteQuad(rect));
534 }
535 } else if (!hasCheckedBoxInRange) {
536 // consider when the offset of range is area of leading or trailing
537 // whitespace
504 FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight); 538 FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight);
505 if (!rect.isZero()) 539 if (!rect.isZero())
506 quads.push_back(localToAbsoluteQuad(rect)); 540 quads.push_back(localToAbsoluteQuad(rect).enclosingBoundingBox());
507 } 541 }
508 } 542 }
509 } 543 }
510 544
511 FloatRect LayoutText::localBoundingBoxRectForAccessibility() const { 545 FloatRect LayoutText::localBoundingBoxRectForAccessibility() const {
512 FloatRect result; 546 FloatRect result;
513 Vector<FloatQuad> quads; 547 Vector<FloatQuad> quads;
514 this->quads(quads, LayoutText::ClipToEllipsis, LayoutText::LocalQuads); 548 this->quads(quads, LayoutText::ClipToEllipsis, LayoutText::LocalQuads);
515 for (const FloatQuad& quad : quads) 549 for (const FloatQuad& quad : quads)
516 result.unite(quad.boundingBox()); 550 result.unite(quad.boundingBox());
(...skipping 1536 matching lines...) Expand 10 before | Expand all | Expand 10 after
2053 LayoutRect rect = LayoutRect( 2087 LayoutRect rect = LayoutRect(
2054 IntRect(firstRunX(), firstRunY(), linesBox.width(), linesBox.height())); 2088 IntRect(firstRunX(), firstRunY(), linesBox.width(), linesBox.height()));
2055 LayoutBlock* block = containingBlock(); 2089 LayoutBlock* block = containingBlock();
2056 if (block && hasTextBoxes()) 2090 if (block && hasTextBoxes())
2057 block->adjustChildDebugRect(rect); 2091 block->adjustChildDebugRect(rect);
2058 2092
2059 return rect; 2093 return rect;
2060 } 2094 }
2061 2095
2062 } // namespace blink 2096 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/fast/dom/Range/getBoundingClientRect-linebreak-character.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698