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 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 void LayoutText::AbsoluteRects(Vector<IntRect>& rects, | 336 void LayoutText::AbsoluteRects(Vector<IntRect>& rects, |
337 const LayoutPoint& accumulated_offset) const { | 337 const LayoutPoint& accumulated_offset) const { |
338 for (InlineTextBox* box = FirstTextBox(); box; box = box->NextTextBox()) { | 338 for (InlineTextBox* box = FirstTextBox(); box; box = box->NextTextBox()) { |
339 rects.push_back(EnclosingIntRect(LayoutRect( | 339 rects.push_back(EnclosingIntRect(LayoutRect( |
340 LayoutPoint(accumulated_offset) + box->Location(), box->Size()))); | 340 LayoutPoint(accumulated_offset) + box->Location(), box->Size()))); |
341 } | 341 } |
342 } | 342 } |
343 | 343 |
344 static FloatRect LocalQuadForTextBox(InlineTextBox* box, | 344 static FloatRect LocalQuadForTextBox(InlineTextBox* box, |
345 unsigned start, | 345 unsigned start, |
346 unsigned end, | 346 unsigned end) { |
347 bool use_selection_height) { | |
348 unsigned real_end = std::min(box->end() + 1, end); | 347 unsigned real_end = std::min(box->end() + 1, end); |
349 LayoutRect r = box->LocalSelectionRect(start, real_end); | 348 LayoutRect r = box->LocalSelectionRect(start, real_end); |
350 if (r.Height()) { | 349 if (r.Height()) { |
351 if (!use_selection_height) { | 350 // Change the height and y position (or width and x for vertical text) |
352 // Change the height and y position (or width and x for vertical text) | 351 // because selectionRect uses selection-specific values. |
353 // because selectionRect uses selection-specific values. | 352 if (box->IsHorizontal()) { |
354 if (box->IsHorizontal()) { | 353 r.SetHeight(box->Height()); |
355 r.SetHeight(box->Height()); | 354 r.SetY(box->Y()); |
356 r.SetY(box->Y()); | 355 } else { |
357 } else { | 356 r.SetWidth(box->Width()); |
358 r.SetWidth(box->Width()); | 357 r.SetX(box->X()); |
359 r.SetX(box->X()); | |
360 } | |
361 } | 358 } |
362 return FloatRect(r); | 359 return FloatRect(r); |
363 } | 360 } |
364 return FloatRect(); | 361 return FloatRect(); |
365 } | 362 } |
366 | 363 |
367 void LayoutText::AbsoluteRectsForRange(Vector<IntRect>& rects, | 364 void LayoutText::AbsoluteRectsForRange(Vector<IntRect>& rects, |
368 unsigned start, | 365 unsigned start, |
369 unsigned end, | 366 unsigned end) const { |
370 bool use_selection_height) const { | |
371 // Work around signed/unsigned issues. This function takes unsigneds, and is | 367 // Work around signed/unsigned issues. This function takes unsigneds, and is |
372 // often passed UINT_MAX to mean "all the way to the end". InlineTextBox | 368 // often passed UINT_MAX to mean "all the way to the end". InlineTextBox |
373 // coordinates are unsigneds, so changing this function to take ints causes | 369 // coordinates are unsigneds, so changing this function to take ints causes |
374 // various internal mismatches. But selectionRect takes ints, and passing | 370 // various internal mismatches. But selectionRect takes ints, and passing |
375 // UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take | 371 // UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take |
376 // unsigneds, but that would cause many ripple effects, so for now we'll just | 372 // unsigneds, but that would cause many ripple effects, so for now we'll just |
377 // clamp our unsigned parameters to INT_MAX. | 373 // clamp our unsigned parameters to INT_MAX. |
378 DCHECK(end == UINT_MAX || end <= INT_MAX); | 374 DCHECK(end == UINT_MAX || end <= INT_MAX); |
379 DCHECK_LE(start, static_cast<unsigned>(INT_MAX)); | 375 DCHECK_LE(start, static_cast<unsigned>(INT_MAX)); |
380 start = std::min(start, static_cast<unsigned>(INT_MAX)); | 376 start = std::min(start, static_cast<unsigned>(INT_MAX)); |
381 end = std::min(end, static_cast<unsigned>(INT_MAX)); | 377 end = std::min(end, static_cast<unsigned>(INT_MAX)); |
382 | 378 |
383 // This function is always called in sequence that this check should work. | 379 // This function is always called in sequence that this check should work. |
384 bool has_checked_box_in_range = !rects.IsEmpty(); | 380 bool has_checked_box_in_range = !rects.IsEmpty(); |
385 | 381 |
386 for (InlineTextBox* box = FirstTextBox(); box; box = box->NextTextBox()) { | 382 for (InlineTextBox* box = FirstTextBox(); box; box = box->NextTextBox()) { |
387 // 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 |
388 // past it | 384 // past it |
389 if (start <= box->Start() && box->end() < end) { | 385 if (start <= box->Start() && box->end() < end) { |
390 FloatRect r(box->FrameRect()); | 386 FloatRect r(box->FrameRect()); |
391 if (use_selection_height) { | |
392 LayoutRect selection_rect = box->LocalSelectionRect(start, end); | |
393 if (box->IsHorizontal()) { | |
394 r.SetHeight(selection_rect.Height().ToFloat()); | |
395 r.SetY(selection_rect.Y().ToFloat()); | |
396 } else { | |
397 r.SetWidth(selection_rect.Width().ToFloat()); | |
398 r.SetX(selection_rect.X().ToFloat()); | |
399 } | |
400 } | |
401 if (!has_checked_box_in_range) { | 387 if (!has_checked_box_in_range) { |
402 has_checked_box_in_range = true; | 388 has_checked_box_in_range = true; |
403 rects.clear(); | 389 rects.clear(); |
404 } | 390 } |
405 rects.push_back(LocalToAbsoluteQuad(r).EnclosingBoundingBox()); | 391 rects.push_back(LocalToAbsoluteQuad(r).EnclosingBoundingBox()); |
406 } else if ((box->Start() <= start && start <= box->end()) || | 392 } else if ((box->Start() <= start && start <= box->end()) || |
407 (box->Start() < end && end <= box->end())) { | 393 (box->Start() < end && end <= box->end())) { |
408 FloatRect rect = | 394 FloatRect rect = LocalQuadForTextBox(box, start, end); |
409 LocalQuadForTextBox(box, start, end, use_selection_height); | |
410 if (!rect.IsZero()) { | 395 if (!rect.IsZero()) { |
411 if (!has_checked_box_in_range) { | 396 if (!has_checked_box_in_range) { |
412 has_checked_box_in_range = true; | 397 has_checked_box_in_range = true; |
413 rects.clear(); | 398 rects.clear(); |
414 } | 399 } |
415 rects.push_back(LocalToAbsoluteQuad(rect).EnclosingBoundingBox()); | 400 rects.push_back(LocalToAbsoluteQuad(rect).EnclosingBoundingBox()); |
416 } | 401 } |
417 } else if (!has_checked_box_in_range) { | 402 } else if (!has_checked_box_in_range) { |
418 // FIXME: This code is wrong. It's converting local to absolute twice. | 403 // FIXME: This code is wrong. It's converting local to absolute twice. |
419 // http://webkit.org/b/65722 | 404 // http://webkit.org/b/65722 |
420 FloatRect rect = | 405 FloatRect rect = LocalQuadForTextBox(box, start, end); |
421 LocalQuadForTextBox(box, start, end, use_selection_height); | |
422 if (!rect.IsZero()) | 406 if (!rect.IsZero()) |
423 rects.push_back(LocalToAbsoluteQuad(rect).EnclosingBoundingBox()); | 407 rects.push_back(LocalToAbsoluteQuad(rect).EnclosingBoundingBox()); |
424 } | 408 } |
425 } | 409 } |
426 } | 410 } |
427 | 411 |
428 static IntRect EllipsisRectForBox(InlineTextBox* box, | 412 static IntRect EllipsisRectForBox(InlineTextBox* box, |
429 unsigned start_pos, | 413 unsigned start_pos, |
430 unsigned end_pos) { | 414 unsigned end_pos) { |
431 if (!box) | 415 if (!box) |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 // past it | 500 // past it |
517 if (start <= box->Start() && box->end() < end) { | 501 if (start <= box->Start() && box->end() < end) { |
518 LayoutRect r(box->FrameRect()); | 502 LayoutRect r(box->FrameRect()); |
519 if (!has_checked_box_in_range) { | 503 if (!has_checked_box_in_range) { |
520 has_checked_box_in_range = true; | 504 has_checked_box_in_range = true; |
521 quads.clear(); | 505 quads.clear(); |
522 } | 506 } |
523 quads.push_back(LocalToAbsoluteQuad(FloatRect(r))); | 507 quads.push_back(LocalToAbsoluteQuad(FloatRect(r))); |
524 } else if ((box->Start() <= start && start <= box->end()) || | 508 } else if ((box->Start() <= start && start <= box->end()) || |
525 (box->Start() < end && end <= box->end())) { | 509 (box->Start() < end && end <= box->end())) { |
526 FloatRect rect = LocalQuadForTextBox(box, start, end, false); | 510 FloatRect rect = LocalQuadForTextBox(box, start, end); |
527 if (!rect.IsZero()) { | 511 if (!rect.IsZero()) { |
528 if (!has_checked_box_in_range) { | 512 if (!has_checked_box_in_range) { |
529 has_checked_box_in_range = true; | 513 has_checked_box_in_range = true; |
530 quads.clear(); | 514 quads.clear(); |
531 } | 515 } |
532 quads.push_back(LocalToAbsoluteQuad(rect)); | 516 quads.push_back(LocalToAbsoluteQuad(rect)); |
533 } | 517 } |
534 } else if (!has_checked_box_in_range) { | 518 } else if (!has_checked_box_in_range) { |
535 // consider when the offset of range is area of leading or trailing | 519 // consider when the offset of range is area of leading or trailing |
536 // whitespace | 520 // whitespace |
537 FloatRect rect = LocalQuadForTextBox(box, start, end, false); | 521 FloatRect rect = LocalQuadForTextBox(box, start, end); |
538 if (!rect.IsZero()) | 522 if (!rect.IsZero()) |
539 quads.push_back(LocalToAbsoluteQuad(rect).EnclosingBoundingBox()); | 523 quads.push_back(LocalToAbsoluteQuad(rect).EnclosingBoundingBox()); |
540 } | 524 } |
541 } | 525 } |
542 } | 526 } |
543 | 527 |
544 FloatRect LayoutText::LocalBoundingBoxRectForAccessibility() const { | 528 FloatRect LayoutText::LocalBoundingBoxRectForAccessibility() const { |
545 FloatRect result; | 529 FloatRect result; |
546 Vector<FloatQuad> quads; | 530 Vector<FloatQuad> quads; |
547 this->Quads(quads, LayoutText::kClipToEllipsis, LayoutText::kLocalQuads); | 531 this->Quads(quads, LayoutText::kClipToEllipsis, LayoutText::kLocalQuads); |
(...skipping 1576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2124 LayoutRect rect = LayoutRect( | 2108 LayoutRect rect = LayoutRect( |
2125 IntRect(FirstRunX(), FirstRunY(), lines_box.Width(), lines_box.Height())); | 2109 IntRect(FirstRunX(), FirstRunY(), lines_box.Width(), lines_box.Height())); |
2126 LayoutBlock* block = ContainingBlock(); | 2110 LayoutBlock* block = ContainingBlock(); |
2127 if (block && HasTextBoxes()) | 2111 if (block && HasTextBoxes()) |
2128 block->AdjustChildDebugRect(rect); | 2112 block->AdjustChildDebugRect(rect); |
2129 | 2113 |
2130 return rect; | 2114 return rect; |
2131 } | 2115 } |
2132 | 2116 |
2133 } // namespace blink | 2117 } // namespace blink |
OLD | NEW |