| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 42 #include "platform/fonts/Character.h" | 42 #include "platform/fonts/Character.h" | 
| 43 #include "platform/fonts/FontCache.h" | 43 #include "platform/fonts/FontCache.h" | 
| 44 #include "platform/geometry/FloatQuad.h" | 44 #include "platform/geometry/FloatQuad.h" | 
| 45 #include "platform/text/BidiResolver.h" | 45 #include "platform/text/BidiResolver.h" | 
| 46 #include "platform/text/TextBreakIterator.h" | 46 #include "platform/text/TextBreakIterator.h" | 
| 47 #include "platform/text/TextRunIterator.h" | 47 #include "platform/text/TextRunIterator.h" | 
| 48 #include "wtf/text/StringBuffer.h" | 48 #include "wtf/text/StringBuffer.h" | 
| 49 #include "wtf/text/StringBuilder.h" | 49 #include "wtf/text/StringBuilder.h" | 
| 50 #include "wtf/unicode/CharacterNames.h" | 50 #include "wtf/unicode/CharacterNames.h" | 
| 51 | 51 | 
| 52 using namespace std; |  | 
| 53 using namespace WTF; | 52 using namespace WTF; | 
| 54 using namespace Unicode; | 53 using namespace Unicode; | 
| 55 | 54 | 
| 56 namespace WebCore { | 55 namespace WebCore { | 
| 57 | 56 | 
| 58 struct SameSizeAsRenderText : public RenderObject { | 57 struct SameSizeAsRenderText : public RenderObject { | 
| 59     uint32_t bitfields : 16; | 58     uint32_t bitfields : 16; | 
| 60     float widths[4]; | 59     float widths[4]; | 
| 61     String text; | 60     String text; | 
| 62     void* pointers[2]; | 61     void* pointers[2]; | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 97 }; | 96 }; | 
| 98 | 97 | 
| 99 static void makeCapitalized(String* string, UChar previous) | 98 static void makeCapitalized(String* string, UChar previous) | 
| 100 { | 99 { | 
| 101     if (string->isNull()) | 100     if (string->isNull()) | 
| 102         return; | 101         return; | 
| 103 | 102 | 
| 104     unsigned length = string->length(); | 103     unsigned length = string->length(); | 
| 105     const StringImpl& input = *string->impl(); | 104     const StringImpl& input = *string->impl(); | 
| 106 | 105 | 
| 107     if (length >= numeric_limits<unsigned>::max()) | 106     if (length >= std::numeric_limits<unsigned>::max()) | 
| 108         CRASH(); | 107         CRASH(); | 
| 109 | 108 | 
| 110     StringBuffer<UChar> stringWithPrevious(length + 1); | 109     StringBuffer<UChar> stringWithPrevious(length + 1); | 
| 111     stringWithPrevious[0] = previous == noBreakSpace ? ' ' : previous; | 110     stringWithPrevious[0] = previous == noBreakSpace ? ' ' : previous; | 
| 112     for (unsigned i = 1; i < length + 1; i++) { | 111     for (unsigned i = 1; i < length + 1; i++) { | 
| 113         // Replace   with a real space since ICU no longer treats   as a
       word separator. | 112         // Replace   with a real space since ICU no longer treats   as a
       word separator. | 
| 114         if (input[i - 1] == noBreakSpace) | 113         if (input[i - 1] == noBreakSpace) | 
| 115             stringWithPrevious[i] = ' '; | 114             stringWithPrevious[i] = ' '; | 
| 116         else | 115         else | 
| 117             stringWithPrevious[i] = input[i - 1]; | 116             stringWithPrevious[i] = input[i - 1]; | 
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 324 } | 323 } | 
| 325 | 324 | 
| 326 void RenderText::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumu
      latedOffset) const | 325 void RenderText::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumu
      latedOffset) const | 
| 327 { | 326 { | 
| 328     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) | 327     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) | 
| 329         rects.append(enclosingIntRect(FloatRect(accumulatedOffset + box->topLeft
      (), box->size()))); | 328         rects.append(enclosingIntRect(FloatRect(accumulatedOffset + box->topLeft
      (), box->size()))); | 
| 330 } | 329 } | 
| 331 | 330 | 
| 332 static FloatRect localQuadForTextBox(InlineTextBox* box, unsigned start, unsigne
      d end, bool useSelectionHeight) | 331 static FloatRect localQuadForTextBox(InlineTextBox* box, unsigned start, unsigne
      d end, bool useSelectionHeight) | 
| 333 { | 332 { | 
| 334     unsigned realEnd = min(box->end() + 1, end); | 333     unsigned realEnd = std::min(box->end() + 1, end); | 
| 335     LayoutRect r = box->localSelectionRect(start, realEnd); | 334     LayoutRect r = box->localSelectionRect(start, realEnd); | 
| 336     if (r.height()) { | 335     if (r.height()) { | 
| 337         if (!useSelectionHeight) { | 336         if (!useSelectionHeight) { | 
| 338             // Change the height and y position (or width and x for vertical tex
      t) | 337             // Change the height and y position (or width and x for vertical tex
      t) | 
| 339             // because selectionRect uses selection-specific values. | 338             // because selectionRect uses selection-specific values. | 
| 340             if (box->isHorizontal()) { | 339             if (box->isHorizontal()) { | 
| 341                 r.setHeight(box->height()); | 340                 r.setHeight(box->height()); | 
| 342                 r.setY(box->y()); | 341                 r.setY(box->y()); | 
| 343             } else { | 342             } else { | 
| 344                 r.setWidth(box->width()); | 343                 r.setWidth(box->width()); | 
| 345                 r.setX(box->x()); | 344                 r.setX(box->x()); | 
| 346             } | 345             } | 
| 347         } | 346         } | 
| 348         return FloatRect(r); | 347         return FloatRect(r); | 
| 349     } | 348     } | 
| 350     return FloatRect(); | 349     return FloatRect(); | 
| 351 } | 350 } | 
| 352 | 351 | 
| 353 void RenderText::absoluteRectsForRange(Vector<IntRect>& rects, unsigned start, u
      nsigned end, bool useSelectionHeight, bool* wasFixed) | 352 void RenderText::absoluteRectsForRange(Vector<IntRect>& rects, unsigned start, u
      nsigned end, bool useSelectionHeight, bool* wasFixed) | 
| 354 { | 353 { | 
| 355     // Work around signed/unsigned issues. This function takes unsigneds, and is
       often passed UINT_MAX | 354     // Work around signed/unsigned issues. This function takes unsigneds, and is
       often passed UINT_MAX | 
| 356     // to mean "all the way to the end". InlineTextBox coordinates are unsigneds
      , so changing this | 355     // to mean "all the way to the end". InlineTextBox coordinates are unsigneds
      , so changing this | 
| 357     // function to take ints causes various internal mismatches. But selectionRe
      ct takes ints, and | 356     // function to take ints causes various internal mismatches. But selectionRe
      ct takes ints, and | 
| 358     // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect 
      to take unsigneds, but | 357     // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect 
      to take unsigneds, but | 
| 359     // that would cause many ripple effects, so for now we'll just clamp our uns
      igned parameters to INT_MAX. | 358     // that would cause many ripple effects, so for now we'll just clamp our uns
      igned parameters to INT_MAX. | 
| 360     ASSERT(end == UINT_MAX || end <= INT_MAX); | 359     ASSERT(end == UINT_MAX || end <= INT_MAX); | 
| 361     ASSERT(start <= INT_MAX); | 360     ASSERT(start <= INT_MAX); | 
| 362     start = min(start, static_cast<unsigned>(INT_MAX)); | 361     start = std::min(start, static_cast<unsigned>(INT_MAX)); | 
| 363     end = min(end, static_cast<unsigned>(INT_MAX)); | 362     end = std::min(end, static_cast<unsigned>(INT_MAX)); | 
| 364 | 363 | 
| 365     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { | 364     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { | 
| 366         // Note: box->end() returns the index of the last character, not the ind
      ex past it | 365         // Note: box->end() returns the index of the last character, not the ind
      ex past it | 
| 367         if (start <= box->start() && box->end() < end) { | 366         if (start <= box->start() && box->end() < end) { | 
| 368             FloatRect r = box->calculateBoundaries(); | 367             FloatRect r = box->calculateBoundaries(); | 
| 369             if (useSelectionHeight) { | 368             if (useSelectionHeight) { | 
| 370                 LayoutRect selectionRect = box->localSelectionRect(start, end); | 369                 LayoutRect selectionRect = box->localSelectionRect(start, end); | 
| 371                 if (box->isHorizontal()) { | 370                 if (box->isHorizontal()) { | 
| 372                     r.setHeight(selectionRect.height().toFloat()); | 371                     r.setHeight(selectionRect.height().toFloat()); | 
| 373                     r.setY(selectionRect.y().toFloat()); | 372                     r.setY(selectionRect.y().toFloat()); | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 390 { | 389 { | 
| 391     if (!box) | 390     if (!box) | 
| 392         return IntRect(); | 391         return IntRect(); | 
| 393 | 392 | 
| 394     unsigned short truncation = box->truncation(); | 393     unsigned short truncation = box->truncation(); | 
| 395     if (truncation == cNoTruncation) | 394     if (truncation == cNoTruncation) | 
| 396         return IntRect(); | 395         return IntRect(); | 
| 397 | 396 | 
| 398     IntRect rect; | 397     IntRect rect; | 
| 399     if (EllipsisBox* ellipsis = box->root().ellipsisBox()) { | 398     if (EllipsisBox* ellipsis = box->root().ellipsisBox()) { | 
| 400         int ellipsisStartPosition = max<int>(startPos - box->start(), 0); | 399         int ellipsisStartPosition = std::max<int>(startPos - box->start(), 0); | 
| 401         int ellipsisEndPosition = min<int>(endPos - box->start(), box->len()); | 400         int ellipsisEndPosition = std::min<int>(endPos - box->start(), box->len(
      )); | 
| 402 | 401 | 
| 403         // The ellipsis should be considered to be selected if the end of | 402         // The ellipsis should be considered to be selected if the end of | 
| 404         // the selection is past the beginning of the truncation and the | 403         // the selection is past the beginning of the truncation and the | 
| 405         // beginning of the selection is before or at the beginning of the trunc
      ation. | 404         // beginning of the selection is before or at the beginning of the trunc
      ation. | 
| 406         if (ellipsisEndPosition >= truncation && ellipsisStartPosition <= trunca
      tion) | 405         if (ellipsisEndPosition >= truncation && ellipsisStartPosition <= trunca
      tion) | 
| 407             return ellipsis->selectionRect(); | 406             return ellipsis->selectionRect(); | 
| 408     } | 407     } | 
| 409 | 408 | 
| 410     return IntRect(); | 409     return IntRect(); | 
| 411 } | 410 } | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 435 | 434 | 
| 436 void RenderText::absoluteQuadsForRange(Vector<FloatQuad>& quads, unsigned start,
       unsigned end, bool useSelectionHeight, bool* wasFixed) | 435 void RenderText::absoluteQuadsForRange(Vector<FloatQuad>& quads, unsigned start,
       unsigned end, bool useSelectionHeight, bool* wasFixed) | 
| 437 { | 436 { | 
| 438     // Work around signed/unsigned issues. This function takes unsigneds, and is
       often passed UINT_MAX | 437     // Work around signed/unsigned issues. This function takes unsigneds, and is
       often passed UINT_MAX | 
| 439     // to mean "all the way to the end". InlineTextBox coordinates are unsigneds
      , so changing this | 438     // to mean "all the way to the end". InlineTextBox coordinates are unsigneds
      , so changing this | 
| 440     // function to take ints causes various internal mismatches. But selectionRe
      ct takes ints, and | 439     // function to take ints causes various internal mismatches. But selectionRe
      ct takes ints, and | 
| 441     // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect 
      to take unsigneds, but | 440     // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect 
      to take unsigneds, but | 
| 442     // that would cause many ripple effects, so for now we'll just clamp our uns
      igned parameters to INT_MAX. | 441     // that would cause many ripple effects, so for now we'll just clamp our uns
      igned parameters to INT_MAX. | 
| 443     ASSERT(end == UINT_MAX || end <= INT_MAX); | 442     ASSERT(end == UINT_MAX || end <= INT_MAX); | 
| 444     ASSERT(start <= INT_MAX); | 443     ASSERT(start <= INT_MAX); | 
| 445     start = min(start, static_cast<unsigned>(INT_MAX)); | 444     start = std::min(start, static_cast<unsigned>(INT_MAX)); | 
| 446     end = min(end, static_cast<unsigned>(INT_MAX)); | 445     end = std::min(end, static_cast<unsigned>(INT_MAX)); | 
| 447 | 446 | 
| 448     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { | 447     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { | 
| 449         // Note: box->end() returns the index of the last character, not the ind
      ex past it | 448         // Note: box->end() returns the index of the last character, not the ind
      ex past it | 
| 450         if (start <= box->start() && box->end() < end) { | 449         if (start <= box->start() && box->end() < end) { | 
| 451             FloatRect r = box->calculateBoundaries(); | 450             FloatRect r = box->calculateBoundaries(); | 
| 452             if (useSelectionHeight) { | 451             if (useSelectionHeight) { | 
| 453                 LayoutRect selectionRect = box->localSelectionRect(start, end); | 452                 LayoutRect selectionRect = box->localSelectionRect(start, end); | 
| 454                 if (box->isHorizontal()) { | 453                 if (box->isHorizontal()) { | 
| 455                     r.setHeight(selectionRect.height().toFloat()); | 454                     r.setHeight(selectionRect.height().toFloat()); | 
| 456                     r.setY(selectionRect.y().toFloat()); | 455                     r.setY(selectionRect.y().toFloat()); | 
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 604     LayoutUnit pointLineDirection = firstTextBox()->isHorizontal() ? point.x() :
       point.y(); | 603     LayoutUnit pointLineDirection = firstTextBox()->isHorizontal() ? point.x() :
       point.y(); | 
| 605     LayoutUnit pointBlockDirection = firstTextBox()->isHorizontal() ? point.y() 
      : point.x(); | 604     LayoutUnit pointBlockDirection = firstTextBox()->isHorizontal() ? point.y() 
      : point.x(); | 
| 606     bool blocksAreFlipped = style()->isFlippedBlocksWritingMode(); | 605     bool blocksAreFlipped = style()->isFlippedBlocksWritingMode(); | 
| 607 | 606 | 
| 608     InlineTextBox* lastBox = 0; | 607     InlineTextBox* lastBox = 0; | 
| 609     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { | 608     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { | 
| 610         if (box->isLineBreak() && !box->prevLeafChild() && box->nextLeafChild() 
      && !box->nextLeafChild()->isLineBreak()) | 609         if (box->isLineBreak() && !box->prevLeafChild() && box->nextLeafChild() 
      && !box->nextLeafChild()->isLineBreak()) | 
| 611             box = box->nextTextBox(); | 610             box = box->nextTextBox(); | 
| 612 | 611 | 
| 613         RootInlineBox& rootBox = box->root(); | 612         RootInlineBox& rootBox = box->root(); | 
| 614         LayoutUnit top = min(rootBox.selectionTop(), rootBox.lineTop()); | 613         LayoutUnit top = std::min(rootBox.selectionTop(), rootBox.lineTop()); | 
| 615         if (pointBlockDirection > top || (!blocksAreFlipped && pointBlockDirecti
      on == top)) { | 614         if (pointBlockDirection > top || (!blocksAreFlipped && pointBlockDirecti
      on == top)) { | 
| 616             LayoutUnit bottom = rootBox.selectionBottom(); | 615             LayoutUnit bottom = rootBox.selectionBottom(); | 
| 617             if (rootBox.nextRootBox()) | 616             if (rootBox.nextRootBox()) | 
| 618                 bottom = min(bottom, rootBox.nextRootBox()->lineTop()); | 617                 bottom = std::min(bottom, rootBox.nextRootBox()->lineTop()); | 
| 619 | 618 | 
| 620             if (pointBlockDirection < bottom || (blocksAreFlipped && pointBlockD
      irection == bottom)) { | 619             if (pointBlockDirection < bottom || (blocksAreFlipped && pointBlockD
      irection == bottom)) { | 
| 621                 ShouldAffinityBeDownstream shouldAffinityBeDownstream; | 620                 ShouldAffinityBeDownstream shouldAffinityBeDownstream; | 
| 622                 if (lineDirectionPointFitsInBox(pointLineDirection, box, shouldA
      ffinityBeDownstream)) | 621                 if (lineDirectionPointFitsInBox(pointLineDirection, box, shouldA
      ffinityBeDownstream)) | 
| 623                     return createPositionWithAffinityForBoxAfterAdjustingOffsetF
      orBiDi(box, box->offsetForPosition(pointLineDirection.toFloat()), shouldAffinity
      BeDownstream); | 622                     return createPositionWithAffinityForBoxAfterAdjustingOffsetF
      orBiDi(box, box->offsetForPosition(pointLineDirection.toFloat()), shouldAffinity
      BeDownstream); | 
| 624             } | 623             } | 
| 625         } | 624         } | 
| 626         lastBox = box; | 625         lastBox = box; | 
| 627     } | 626     } | 
| 628 | 627 | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 664     // FIXME: should we use the width of the root inline box or the | 663     // FIXME: should we use the width of the root inline box or the | 
| 665     // width of the containing block for this? | 664     // width of the containing block for this? | 
| 666     if (extraWidthToEndOfLine) | 665     if (extraWidthToEndOfLine) | 
| 667         *extraWidthToEndOfLine = (box->root().logicalWidth() + rootLeft) - (left
       + 1); | 666         *extraWidthToEndOfLine = (box->root().logicalWidth() + rootLeft) - (left
       + 1); | 
| 668 | 667 | 
| 669     RenderBlock* cb = containingBlock(); | 668     RenderBlock* cb = containingBlock(); | 
| 670     RenderStyle* cbStyle = cb->style(); | 669     RenderStyle* cbStyle = cb->style(); | 
| 671 | 670 | 
| 672     float leftEdge; | 671     float leftEdge; | 
| 673     float rightEdge; | 672     float rightEdge; | 
| 674     leftEdge = min<float>(0, rootLeft); | 673     leftEdge = std::min<float>(0, rootLeft); | 
| 675     rightEdge = max<float>(cb->logicalWidth().toFloat(), rootRight); | 674     rightEdge = std::max<float>(cb->logicalWidth().toFloat(), rootRight); | 
| 676 | 675 | 
| 677     bool rightAligned = false; | 676     bool rightAligned = false; | 
| 678     switch (cbStyle->textAlign()) { | 677     switch (cbStyle->textAlign()) { | 
| 679     case RIGHT: | 678     case RIGHT: | 
| 680     case WEBKIT_RIGHT: | 679     case WEBKIT_RIGHT: | 
| 681         rightAligned = true; | 680         rightAligned = true; | 
| 682         break; | 681         break; | 
| 683     case LEFT: | 682     case LEFT: | 
| 684     case WEBKIT_LEFT: | 683     case WEBKIT_LEFT: | 
| 685     case CENTER: | 684     case CENTER: | 
| 686     case WEBKIT_CENTER: | 685     case WEBKIT_CENTER: | 
| 687         break; | 686         break; | 
| 688     case JUSTIFY: | 687     case JUSTIFY: | 
| 689     case TASTART: | 688     case TASTART: | 
| 690         rightAligned = !cbStyle->isLeftToRightDirection(); | 689         rightAligned = !cbStyle->isLeftToRightDirection(); | 
| 691         break; | 690         break; | 
| 692     case TAEND: | 691     case TAEND: | 
| 693         rightAligned = cbStyle->isLeftToRightDirection(); | 692         rightAligned = cbStyle->isLeftToRightDirection(); | 
| 694         break; | 693         break; | 
| 695     } | 694     } | 
| 696 | 695 | 
| 697     if (rightAligned) { | 696     if (rightAligned) { | 
| 698         left = max(left, leftEdge); | 697         left = std::max(left, leftEdge); | 
| 699         left = min(left, rootRight - caretWidth); | 698         left = std::min(left, rootRight - caretWidth); | 
| 700     } else { | 699     } else { | 
| 701         left = min(left, rightEdge - caretWidthRightOfOffset); | 700         left = std::min(left, rightEdge - caretWidthRightOfOffset); | 
| 702         left = max(left, rootLeft); | 701         left = std::max(left, rootLeft); | 
| 703     } | 702     } | 
| 704 | 703 | 
| 705     return style()->isHorizontalWritingMode() ? IntRect(left, top, caretWidth, h
      eight) : IntRect(top, left, height, caretWidth); | 704     return style()->isHorizontalWritingMode() ? IntRect(left, top, caretWidth, h
      eight) : IntRect(top, left, height, caretWidth); | 
| 706 } | 705 } | 
| 707 | 706 | 
| 708 ALWAYS_INLINE float RenderText::widthFromCache(const Font& f, int start, int len
      , float xPos, TextDirection textDirection, HashSet<const SimpleFontData*>* fallb
      ackFonts, GlyphOverflow* glyphOverflow) const | 707 ALWAYS_INLINE float RenderText::widthFromCache(const Font& f, int start, int len
      , float xPos, TextDirection textDirection, HashSet<const SimpleFontData*>* fallb
      ackFonts, GlyphOverflow* glyphOverflow) const | 
| 709 { | 708 { | 
| 710     if (style()->hasTextCombine() && isCombineText()) { | 709     if (style()->hasTextCombine() && isCombineText()) { | 
| 711         const RenderCombineText* combineText = toRenderCombineText(this); | 710         const RenderCombineText* combineText = toRenderCombineText(this); | 
| 712         if (combineText->isCombined()) | 711         if (combineText->isCombined()) | 
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1008             if (isBreakable(breakIterator, j, nextBreakable) && characterAt(j - 
      1) != softHyphen) | 1007             if (isBreakable(breakIterator, j, nextBreakable) && characterAt(j - 
      1) != softHyphen) | 
| 1009                 break; | 1008                 break; | 
| 1010             if (breakAll) { | 1009             if (breakAll) { | 
| 1011                 betweenWords = false; | 1010                 betweenWords = false; | 
| 1012                 break; | 1011                 break; | 
| 1013             } | 1012             } | 
| 1014         } | 1013         } | 
| 1015 | 1014 | 
| 1016         // Terminate word boundary at bidi run boundary. | 1015         // Terminate word boundary at bidi run boundary. | 
| 1017         if (run) | 1016         if (run) | 
| 1018             j = min(j, run->stop() + 1); | 1017             j = std::min(j, run->stop() + 1); | 
| 1019         int wordLen = j - i; | 1018         int wordLen = j - i; | 
| 1020         if (wordLen) { | 1019         if (wordLen) { | 
| 1021             bool isSpace = (j < len) && c == ' '; | 1020             bool isSpace = (j < len) && c == ' '; | 
| 1022 | 1021 | 
| 1023             // Non-zero only when kerning is enabled, in which case we measure w
      ords with their trailing | 1022             // Non-zero only when kerning is enabled, in which case we measure w
      ords with their trailing | 
| 1024             // space, then subtract its width. | 1023             // space, then subtract its width. | 
| 1025             float wordTrailingSpaceWidth = 0; | 1024             float wordTrailingSpaceWidth = 0; | 
| 1026             if (isSpace && (f.fontDescription().typesettingFeatures() & Kerning)
      ) { | 1025             if (isSpace && (f.fontDescription().typesettingFeatures() & Kerning)
      ) { | 
| 1027                 ASSERT(textDirection >=0 && textDirection <= 1); | 1026                 ASSERT(textDirection >=0 && textDirection <= 1); | 
| 1028                 if (!cachedWordTrailingSpaceWidth[textDirection]) | 1027                 if (!cachedWordTrailingSpaceWidth[textDirection]) | 
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1113     } | 1112     } | 
| 1114     if (run) | 1113     if (run) | 
| 1115         bidiResolver.runs().deleteRuns(); | 1114         bidiResolver.runs().deleteRuns(); | 
| 1116 | 1115 | 
| 1117     if (firstGlyphLeftOverflow > 0) | 1116     if (firstGlyphLeftOverflow > 0) | 
| 1118         glyphOverflow.left = firstGlyphLeftOverflow; | 1117         glyphOverflow.left = firstGlyphLeftOverflow; | 
| 1119 | 1118 | 
| 1120     if ((needsWordSpacing && len > 1) || (ignoringSpaces && !firstWord)) | 1119     if ((needsWordSpacing && len > 1) || (ignoringSpaces && !firstWord)) | 
| 1121         currMaxWidth += wordSpacing; | 1120         currMaxWidth += wordSpacing; | 
| 1122 | 1121 | 
| 1123     m_minWidth = max(currMinWidth, m_minWidth); | 1122     m_minWidth = std::max(currMinWidth, m_minWidth); | 
| 1124     m_maxWidth = max(currMaxWidth, m_maxWidth); | 1123     m_maxWidth = std::max(currMaxWidth, m_maxWidth); | 
| 1125 | 1124 | 
| 1126     if (!styleToUse->autoWrap()) | 1125     if (!styleToUse->autoWrap()) | 
| 1127         m_minWidth = m_maxWidth; | 1126         m_minWidth = m_maxWidth; | 
| 1128 | 1127 | 
| 1129     if (styleToUse->whiteSpace() == PRE) { | 1128     if (styleToUse->whiteSpace() == PRE) { | 
| 1130         if (firstLine) | 1129         if (firstLine) | 
| 1131             m_firstLineMinWidth = m_maxWidth; | 1130             m_firstLineMinWidth = m_maxWidth; | 
| 1132         m_lastLineLineMinWidth = currMaxWidth; | 1131         m_lastLineLineMinWidth = currMaxWidth; | 
| 1133     } | 1132     } | 
| 1134 | 1133 | 
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1549 LayoutRect RenderText::linesVisualOverflowBoundingBox() const | 1548 LayoutRect RenderText::linesVisualOverflowBoundingBox() const | 
| 1550 { | 1549 { | 
| 1551     if (!firstTextBox()) | 1550     if (!firstTextBox()) | 
| 1552         return LayoutRect(); | 1551         return LayoutRect(); | 
| 1553 | 1552 | 
| 1554     // Return the width of the minimal left side and the maximal right side. | 1553     // Return the width of the minimal left side and the maximal right side. | 
| 1555     LayoutUnit logicalLeftSide = LayoutUnit::max(); | 1554     LayoutUnit logicalLeftSide = LayoutUnit::max(); | 
| 1556     LayoutUnit logicalRightSide = LayoutUnit::min(); | 1555     LayoutUnit logicalRightSide = LayoutUnit::min(); | 
| 1557     for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox())
       { | 1556     for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox())
       { | 
| 1558         LayoutRect logicalVisualOverflow = curr->logicalOverflowRect(); | 1557         LayoutRect logicalVisualOverflow = curr->logicalOverflowRect(); | 
| 1559         logicalLeftSide = min(logicalLeftSide, logicalVisualOverflow.x()); | 1558         logicalLeftSide = std::min(logicalLeftSide, logicalVisualOverflow.x()); | 
| 1560         logicalRightSide = max(logicalRightSide, logicalVisualOverflow.maxX()); | 1559         logicalRightSide = std::max(logicalRightSide, logicalVisualOverflow.maxX
      ()); | 
| 1561     } | 1560     } | 
| 1562 | 1561 | 
| 1563     LayoutUnit logicalTop = firstTextBox()->logicalTopVisualOverflow(); | 1562     LayoutUnit logicalTop = firstTextBox()->logicalTopVisualOverflow(); | 
| 1564     LayoutUnit logicalWidth = logicalRightSide - logicalLeftSide; | 1563     LayoutUnit logicalWidth = logicalRightSide - logicalLeftSide; | 
| 1565     LayoutUnit logicalHeight = lastTextBox()->logicalBottomVisualOverflow() - lo
      gicalTop; | 1564     LayoutUnit logicalHeight = lastTextBox()->logicalBottomVisualOverflow() - lo
      gicalTop; | 
| 1566 | 1565 | 
| 1567     LayoutRect rect(logicalLeftSide, logicalTop, logicalWidth, logicalHeight); | 1566     LayoutRect rect(logicalLeftSide, logicalTop, logicalWidth, logicalHeight); | 
| 1568     if (!style()->isHorizontalWritingMode()) | 1567     if (!style()->isHorizontalWritingMode()) | 
| 1569         rect = rect.transposedRect(); | 1568         rect = rect.transposedRect(); | 
| 1570     return rect; | 1569     return rect; | 
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1632     return rect; | 1631     return rect; | 
| 1633 } | 1632 } | 
| 1634 | 1633 | 
| 1635 int RenderText::caretMinOffset() const | 1634 int RenderText::caretMinOffset() const | 
| 1636 { | 1635 { | 
| 1637     InlineTextBox* box = firstTextBox(); | 1636     InlineTextBox* box = firstTextBox(); | 
| 1638     if (!box) | 1637     if (!box) | 
| 1639         return 0; | 1638         return 0; | 
| 1640     int minOffset = box->start(); | 1639     int minOffset = box->start(); | 
| 1641     for (box = box->nextTextBox(); box; box = box->nextTextBox()) | 1640     for (box = box->nextTextBox(); box; box = box->nextTextBox()) | 
| 1642         minOffset = min<int>(minOffset, box->start()); | 1641         minOffset = std::min<int>(minOffset, box->start()); | 
| 1643     return minOffset; | 1642     return minOffset; | 
| 1644 } | 1643 } | 
| 1645 | 1644 | 
| 1646 int RenderText::caretMaxOffset() const | 1645 int RenderText::caretMaxOffset() const | 
| 1647 { | 1646 { | 
| 1648     InlineTextBox* box = lastTextBox(); | 1647     InlineTextBox* box = lastTextBox(); | 
| 1649     if (!lastTextBox()) | 1648     if (!lastTextBox()) | 
| 1650         return textLength(); | 1649         return textLength(); | 
| 1651 | 1650 | 
| 1652     int maxOffset = box->start() + box->len(); | 1651     int maxOffset = box->start() + box->len(); | 
| 1653     for (box = box->prevTextBox(); box; box = box->prevTextBox()) | 1652     for (box = box->prevTextBox(); box; box = box->prevTextBox()) | 
| 1654         maxOffset = max<int>(maxOffset, box->start() + box->len()); | 1653         maxOffset = std::max<int>(maxOffset, box->start() + box->len()); | 
| 1655     return maxOffset; | 1654     return maxOffset; | 
| 1656 } | 1655 } | 
| 1657 | 1656 | 
| 1658 unsigned RenderText::renderedTextLength() const | 1657 unsigned RenderText::renderedTextLength() const | 
| 1659 { | 1658 { | 
| 1660     int l = 0; | 1659     int l = 0; | 
| 1661     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) | 1660     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) | 
| 1662         l += box->len(); | 1661         l += box->len(); | 
| 1663     return l; | 1662     return l; | 
| 1664 } | 1663 } | 
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1869     } | 1868     } | 
| 1870     secureTextTimer->restartWithNewText(lastTypedCharacterOffset); | 1869     secureTextTimer->restartWithNewText(lastTypedCharacterOffset); | 
| 1871 } | 1870 } | 
| 1872 | 1871 | 
| 1873 PassRefPtr<AbstractInlineTextBox> RenderText::firstAbstractInlineTextBox() | 1872 PassRefPtr<AbstractInlineTextBox> RenderText::firstAbstractInlineTextBox() | 
| 1874 { | 1873 { | 
| 1875     return AbstractInlineTextBox::getOrCreate(this, m_firstTextBox); | 1874     return AbstractInlineTextBox::getOrCreate(this, m_firstTextBox); | 
| 1876 } | 1875 } | 
| 1877 | 1876 | 
| 1878 } // namespace WebCore | 1877 } // namespace WebCore | 
| OLD | NEW | 
|---|