68f16d47c949eccb2f14676851db0be73ffe9b9a
[WebKit-https.git] / Source / WebCore / rendering / RenderText.cpp
1 /*
2  * (C) 1999 Lars Knoll (knoll@kde.org)
3  * (C) 2000 Dirk Mueller (mueller@kde.org)
4  * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
5  * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
6  * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  *
23  */
24
25 #include "config.h"
26 #include "RenderText.h"
27
28 #include "AXObjectCache.h"
29 #include "EllipsisBox.h"
30 #include "FloatQuad.h"
31 #include "FontTranscoder.h"
32 #include "FrameView.h"
33 #include "Hyphenation.h"
34 #include "InlineTextBox.h"
35 #include "Range.h"
36 #include "RenderArena.h"
37 #include "RenderBlock.h"
38 #include "RenderCombineText.h"
39 #include "RenderLayer.h"
40 #include "RenderView.h"
41 #include "Settings.h"
42 #include "Text.h"
43 #include "TextBreakIterator.h"
44 #include "TextResourceDecoder.h"
45 #include "VisiblePosition.h"
46 #include "break_lines.h"
47 #include <wtf/text/StringBuffer.h>
48 #include <wtf/unicode/CharacterNames.h>
49
50 using namespace std;
51 using namespace WTF;
52 using namespace Unicode;
53
54 namespace WebCore {
55
56 struct SameSizeAsRenderText : public RenderObject {
57     uint32_t bitfields : 16;
58     float widths[4];
59     String text;
60     void* pointers[2];
61 };
62
63 COMPILE_ASSERT(sizeof(RenderText) == sizeof(SameSizeAsRenderText), RenderText_should_stay_small);
64
65 class SecureTextTimer;
66 typedef HashMap<RenderText*, SecureTextTimer*> SecureTextTimerMap;
67 static SecureTextTimerMap* gSecureTextTimers = 0;
68
69 class SecureTextTimer : public TimerBase {
70 public:
71     SecureTextTimer(RenderText* renderText)
72         : m_renderText(renderText)
73         , m_lastTypedCharacterOffset(-1)
74     {
75     }
76
77     void restartWithNewText(unsigned lastTypedCharacterOffset)
78     {
79         m_lastTypedCharacterOffset = lastTypedCharacterOffset;
80         if (Settings* settings = m_renderText->document()->settings())
81             startOneShot(settings->passwordEchoDurationInSeconds());
82     }
83     void invalidate() { m_lastTypedCharacterOffset = -1; }
84     unsigned lastTypedCharacterOffset() { return m_lastTypedCharacterOffset; }
85
86 private:
87     virtual void fired()
88     {
89         ASSERT(gSecureTextTimers->contains(m_renderText));
90         m_renderText->setText(m_renderText->text(), true /* forcing setting text as it may be masked later */);
91     }
92
93     RenderText* m_renderText;
94     int m_lastTypedCharacterOffset;
95 };
96
97 static void makeCapitalized(String* string, UChar previous)
98 {
99     if (string->isNull())
100         return;
101
102     unsigned length = string->length();
103     const StringImpl& stringImpl = *string->impl();
104
105     if (length >= numeric_limits<unsigned>::max())
106         CRASH();
107
108     StringBuffer<UChar> stringWithPrevious(length + 1);
109     stringWithPrevious[0] = previous == noBreakSpace ? ' ' : previous;
110     for (unsigned i = 1; i < length + 1; i++) {
111         // Replace &nbsp with a real space since ICU no longer treats &nbsp as a word separator.
112         if (stringImpl[i - 1] == noBreakSpace)
113             stringWithPrevious[i] = ' ';
114         else
115             stringWithPrevious[i] = stringImpl[i - 1];
116     }
117
118     TextBreakIterator* boundary = wordBreakIterator(stringWithPrevious.characters(), length + 1);
119     if (!boundary)
120         return;
121
122     StringBuilder result;
123     result.reserveCapacity(length);
124
125     int32_t endOfWord;
126     int32_t startOfWord = textBreakFirst(boundary);
127     for (endOfWord = textBreakNext(boundary); endOfWord != TextBreakDone; startOfWord = endOfWord, endOfWord = textBreakNext(boundary)) {
128         if (startOfWord) // Ignore first char of previous string
129             result.append(stringImpl[startOfWord - 1] == noBreakSpace ? noBreakSpace : toTitleCase(stringWithPrevious[startOfWord]));
130         for (int i = startOfWord + 1; i < endOfWord; i++)
131             result.append(stringImpl[i - 1]);
132     }
133
134     *string = result.toString();
135 }
136
137 RenderText::RenderText(Node* node, PassRefPtr<StringImpl> str)
138     : RenderObject(!node || node->isDocumentNode() ? 0 : node)
139     , m_hasTab(false)
140     , m_linesDirty(false)
141     , m_containsReversedText(false)
142     , m_knownToHaveNoOverflowAndNoFallbackFonts(false)
143     , m_needsTranscoding(false)
144     , m_minWidth(-1)
145     , m_maxWidth(-1)
146     , m_beginMinWidth(0)
147     , m_endMinWidth(0)
148     , m_text(str)
149     , m_firstTextBox(0)
150     , m_lastTextBox(0)
151 {
152     ASSERT(m_text);
153     // FIXME: Some clients of RenderText (and subclasses) pass Document as node to create anonymous renderer.
154     // They should be switched to passing null and using setDocumentForAnonymous.
155     if (node && node->isDocumentNode())
156         setDocumentForAnonymous(toDocument(node));
157
158     m_isAllASCII = m_text.containsOnlyASCII();
159     m_canUseSimpleFontCodePath = computeCanUseSimpleFontCodePath();
160     setIsText();
161
162     view()->frameView()->incrementVisuallyNonEmptyCharacterCount(m_text.length());
163 }
164
165 #ifndef NDEBUG
166
167 RenderText::~RenderText()
168 {
169     ASSERT(!m_firstTextBox);
170     ASSERT(!m_lastTextBox);
171 }
172
173 #endif
174
175 const char* RenderText::renderName() const
176 {
177     return "RenderText";
178 }
179
180 bool RenderText::isTextFragment() const
181 {
182     return false;
183 }
184
185 bool RenderText::isWordBreak() const
186 {
187     return false;
188 }
189
190 void RenderText::updateNeedsTranscoding()
191 {
192     const TextEncoding* encoding = document()->decoder() ? &document()->decoder()->encoding() : 0;
193     m_needsTranscoding = fontTranscoder().needsTranscoding(style()->font().fontDescription(), encoding);
194 }
195
196 void RenderText::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
197 {
198     // There is no need to ever schedule repaints from a style change of a text run, since
199     // we already did this for the parent of the text run.
200     // We do have to schedule layouts, though, since a style change can force us to
201     // need to relayout.
202     if (diff == StyleDifferenceLayout) {
203         setNeedsLayoutAndPrefWidthsRecalc();
204         m_knownToHaveNoOverflowAndNoFallbackFonts = false;
205     }
206
207     RenderStyle* newStyle = style();
208     bool needsResetText = false;
209     if (!oldStyle) {
210         updateNeedsTranscoding();
211         needsResetText = m_needsTranscoding;
212     } else if (oldStyle->font().needsTranscoding() != newStyle->font().needsTranscoding() || (newStyle->font().needsTranscoding() && oldStyle->font().firstFamily() != newStyle->font().firstFamily())) {
213         updateNeedsTranscoding();
214         needsResetText = true;
215     }
216
217     ETextTransform oldTransform = oldStyle ? oldStyle->textTransform() : TTNONE;
218     ETextSecurity oldSecurity = oldStyle ? oldStyle->textSecurity() : TSNONE;
219     if (needsResetText || oldTransform != newStyle->textTransform() || oldSecurity != newStyle->textSecurity()) 
220         transformText();
221 }
222
223 void RenderText::removeAndDestroyTextBoxes()
224 {
225     if (!documentBeingDestroyed()) {
226         if (firstTextBox()) {
227             if (isBR()) {
228                 RootInlineBox* next = firstTextBox()->root()->nextRootBox();
229                 if (next)
230                     next->markDirty();
231             }
232             for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
233                 box->remove();
234         } else if (parent())
235             parent()->dirtyLinesFromChangedChild(this);
236     }
237     deleteTextBoxes();
238 }
239
240 void RenderText::willBeDestroyed()
241 {
242     if (SecureTextTimer* secureTextTimer = gSecureTextTimers ? gSecureTextTimers->take(this) : 0)
243         delete secureTextTimer;
244
245     removeAndDestroyTextBoxes();
246     RenderObject::willBeDestroyed();
247 }
248
249 void RenderText::extractTextBox(InlineTextBox* box)
250 {
251     checkConsistency();
252
253     m_lastTextBox = box->prevTextBox();
254     if (box == m_firstTextBox)
255         m_firstTextBox = 0;
256     if (box->prevTextBox())
257         box->prevTextBox()->setNextTextBox(0);
258     box->setPreviousTextBox(0);
259     for (InlineTextBox* curr = box; curr; curr = curr->nextTextBox())
260         curr->setExtracted();
261
262     checkConsistency();
263 }
264
265 void RenderText::attachTextBox(InlineTextBox* box)
266 {
267     checkConsistency();
268
269     if (m_lastTextBox) {
270         m_lastTextBox->setNextTextBox(box);
271         box->setPreviousTextBox(m_lastTextBox);
272     } else
273         m_firstTextBox = box;
274     InlineTextBox* last = box;
275     for (InlineTextBox* curr = box; curr; curr = curr->nextTextBox()) {
276         curr->setExtracted(false);
277         last = curr;
278     }
279     m_lastTextBox = last;
280
281     checkConsistency();
282 }
283
284 void RenderText::removeTextBox(InlineTextBox* box)
285 {
286     checkConsistency();
287
288     if (box == m_firstTextBox)
289         m_firstTextBox = box->nextTextBox();
290     if (box == m_lastTextBox)
291         m_lastTextBox = box->prevTextBox();
292     if (box->nextTextBox())
293         box->nextTextBox()->setPreviousTextBox(box->prevTextBox());
294     if (box->prevTextBox())
295         box->prevTextBox()->setNextTextBox(box->nextTextBox());
296
297     checkConsistency();
298 }
299
300 void RenderText::deleteTextBoxes()
301 {
302     if (firstTextBox()) {
303         RenderArena* arena = renderArena();
304         InlineTextBox* next;
305         for (InlineTextBox* curr = firstTextBox(); curr; curr = next) {
306             next = curr->nextTextBox();
307             curr->destroy(arena);
308         }
309         m_firstTextBox = m_lastTextBox = 0;
310     }
311 }
312
313 PassRefPtr<StringImpl> RenderText::originalText() const
314 {
315     Node* e = node();
316     return (e && e->isTextNode()) ? toText(e)->dataImpl() : 0;
317 }
318
319 void RenderText::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
320 {
321     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
322         rects.append(enclosingIntRect(FloatRect(accumulatedOffset + box->topLeft(), box->size())));
323 }
324
325 static FloatRect localQuadForTextBox(InlineTextBox* box, unsigned start, unsigned end, bool useSelectionHeight)
326 {
327     unsigned realEnd = min(box->end() + 1, end);
328     LayoutRect r = box->localSelectionRect(start, realEnd);
329     if (r.height()) {
330         if (!useSelectionHeight) {
331             // Change the height and y position (or width and x for vertical text)
332             // because selectionRect uses selection-specific values.
333             if (box->isHorizontal()) {
334                 r.setHeight(box->logicalHeight());
335                 r.setY(box->y());
336             } else {
337                 r.setWidth(box->logicalWidth());
338                 r.setX(box->x());
339             }
340         }
341         return FloatRect(r);
342     }
343     return FloatRect();
344 }
345
346 void RenderText::absoluteRectsForRange(Vector<IntRect>& rects, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed)
347 {
348     // Work around signed/unsigned issues. This function takes unsigneds, and is often passed UINT_MAX
349     // to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this 
350     // function to take ints causes various internal mismatches. But selectionRect takes ints, and 
351     // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take unsigneds, but 
352     // that would cause many ripple effects, so for now we'll just clamp our unsigned parameters to INT_MAX.
353     ASSERT(end == UINT_MAX || end <= INT_MAX);
354     ASSERT(start <= INT_MAX);
355     start = min(start, static_cast<unsigned>(INT_MAX));
356     end = min(end, static_cast<unsigned>(INT_MAX));
357     
358     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
359         // Note: box->end() returns the index of the last character, not the index past it
360         if (start <= box->start() && box->end() < end) {
361             FloatRect r = box->calculateBoundaries();
362             if (useSelectionHeight) {
363                 LayoutRect selectionRect = box->localSelectionRect(start, end);
364                 if (box->isHorizontal()) {
365                     r.setHeight(selectionRect.height());
366                     r.setY(selectionRect.y());
367                 } else {
368                     r.setWidth(selectionRect.width());
369                     r.setX(selectionRect.x());
370                 }
371             }
372             rects.append(localToAbsoluteQuad(r, 0, wasFixed).enclosingBoundingBox());
373         } else {
374             // FIXME: This code is wrong. It's converting local to absolute twice. http://webkit.org/b/65722
375             FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight);
376             if (!rect.isZero())
377                 rects.append(localToAbsoluteQuad(rect, 0, wasFixed).enclosingBoundingBox());
378         }
379     }
380 }
381
382 static IntRect ellipsisRectForBox(InlineTextBox* box, unsigned startPos, unsigned endPos)
383 {
384     if (!box)
385         return IntRect();
386     
387     unsigned short truncation = box->truncation();
388     if (truncation == cNoTruncation)
389         return IntRect();
390     
391     IntRect rect;
392     if (EllipsisBox* ellipsis = box->root()->ellipsisBox()) {
393         int ellipsisStartPosition = max<int>(startPos - box->start(), 0);
394         int ellipsisEndPosition = min<int>(endPos - box->start(), box->len());
395         
396         // The ellipsis should be considered to be selected if the end of
397         // the selection is past the beginning of the truncation and the
398         // beginning of the selection is before or at the beginning of the truncation.
399         if (ellipsisEndPosition >= truncation && ellipsisStartPosition <= truncation)
400             return ellipsis->selectionRect();
401     }
402     
403     return IntRect();
404 }
405     
406 void RenderText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed, ClippingOption option) const
407 {
408     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
409         FloatRect boundaries = box->calculateBoundaries();
410
411         // Shorten the width of this text box if it ends in an ellipsis.
412         // FIXME: ellipsisRectForBox should switch to return FloatRect soon with the subpixellayout branch.
413         IntRect ellipsisRect = (option == ClipToEllipsis) ? ellipsisRectForBox(box, 0, textLength()) : IntRect();
414         if (!ellipsisRect.isEmpty()) {
415             if (style()->isHorizontalWritingMode())
416                 boundaries.setWidth(ellipsisRect.maxX() - boundaries.x());
417             else
418                 boundaries.setHeight(ellipsisRect.maxY() - boundaries.y());
419         }
420         quads.append(localToAbsoluteQuad(boundaries, 0, wasFixed));
421     }
422 }
423     
424 void RenderText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
425 {
426     absoluteQuads(quads, wasFixed, NoClipping);
427 }
428
429 void RenderText::absoluteQuadsForRange(Vector<FloatQuad>& quads, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed)
430 {
431     // Work around signed/unsigned issues. This function takes unsigneds, and is often passed UINT_MAX
432     // to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this 
433     // function to take ints causes various internal mismatches. But selectionRect takes ints, and 
434     // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take unsigneds, but 
435     // that would cause many ripple effects, so for now we'll just clamp our unsigned parameters to INT_MAX.
436     ASSERT(end == UINT_MAX || end <= INT_MAX);
437     ASSERT(start <= INT_MAX);
438     start = min(start, static_cast<unsigned>(INT_MAX));
439     end = min(end, static_cast<unsigned>(INT_MAX));
440     
441     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
442         // Note: box->end() returns the index of the last character, not the index past it
443         if (start <= box->start() && box->end() < end) {
444             FloatRect r = box->calculateBoundaries();
445             if (useSelectionHeight) {
446                 LayoutRect selectionRect = box->localSelectionRect(start, end);
447                 if (box->isHorizontal()) {
448                     r.setHeight(selectionRect.height());
449                     r.setY(selectionRect.y());
450                 } else {
451                     r.setWidth(selectionRect.width());
452                     r.setX(selectionRect.x());
453                 }
454             }
455             quads.append(localToAbsoluteQuad(r, 0, wasFixed));
456         } else {
457             FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight);
458             if (!rect.isZero())
459                 quads.append(localToAbsoluteQuad(rect, 0, wasFixed));
460         }
461     }
462 }
463
464 InlineTextBox* RenderText::findNextInlineTextBox(int offset, int& pos) const
465 {
466     // The text runs point to parts of the RenderText's m_text
467     // (they don't include '\n')
468     // Find the text run that includes the character at offset
469     // and return pos, which is the position of the char in the run.
470
471     if (!m_firstTextBox)
472         return 0;
473
474     InlineTextBox* s = m_firstTextBox;
475     int off = s->len();
476     while (offset > off && s->nextTextBox()) {
477         s = s->nextTextBox();
478         off = s->start() + s->len();
479     }
480     // we are now in the correct text run
481     pos = (offset > off ? s->len() : s->len() - (off - offset) );
482     return s;
483 }
484
485 enum ShouldAffinityBeDownstream { AlwaysDownstream, AlwaysUpstream, UpstreamIfPositionIsNotAtStart };
486
487 static bool lineDirectionPointFitsInBox(int pointLineDirection, InlineTextBox* box, ShouldAffinityBeDownstream& shouldAffinityBeDownstream)
488 {
489     shouldAffinityBeDownstream = AlwaysDownstream;
490
491     // the x coordinate is equal to the left edge of this box
492     // the affinity must be downstream so the position doesn't jump back to the previous line
493     // except when box is the first box in the line
494     if (pointLineDirection <= box->logicalLeft()) {
495         shouldAffinityBeDownstream = !box->prevLeafChild() ? UpstreamIfPositionIsNotAtStart : AlwaysDownstream;
496         return true;
497     }
498
499     // and the x coordinate is to the left of the right edge of this box
500     // check to see if position goes in this box
501     if (pointLineDirection < box->logicalRight()) {
502         shouldAffinityBeDownstream = UpstreamIfPositionIsNotAtStart;
503         return true;
504     }
505
506     // box is first on line
507     // and the x coordinate is to the left of the first text box left edge
508     if (!box->prevLeafChildIgnoringLineBreak() && pointLineDirection < box->logicalLeft())
509         return true;
510
511     if (!box->nextLeafChildIgnoringLineBreak()) {
512         // box is last on line
513         // and the x coordinate is to the right of the last text box right edge
514         // generate VisiblePosition, use UPSTREAM affinity if possible
515         shouldAffinityBeDownstream = UpstreamIfPositionIsNotAtStart;
516         return true;
517     }
518
519     return false;
520 }
521
522 static VisiblePosition createVisiblePositionForBox(const InlineBox* box, int offset, ShouldAffinityBeDownstream shouldAffinityBeDownstream)
523 {
524     EAffinity affinity = VP_DEFAULT_AFFINITY;
525     switch (shouldAffinityBeDownstream) {
526     case AlwaysDownstream:
527         affinity = DOWNSTREAM;
528         break;
529     case AlwaysUpstream:
530         affinity = VP_UPSTREAM_IF_POSSIBLE;
531         break;
532     case UpstreamIfPositionIsNotAtStart:
533         affinity = offset > box->caretMinOffset() ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM;
534         break;
535     }
536     return box->renderer()->createVisiblePosition(offset, affinity);
537 }
538
539 static VisiblePosition createVisiblePositionAfterAdjustingOffsetForBiDi(const InlineTextBox* box, int offset, ShouldAffinityBeDownstream shouldAffinityBeDownstream)
540 {
541     ASSERT(box);
542     ASSERT(box->renderer());
543     ASSERT(offset >= 0);
544
545     if (offset && static_cast<unsigned>(offset) < box->len())
546         return createVisiblePositionForBox(box, box->start() + offset, shouldAffinityBeDownstream);
547
548     bool positionIsAtStartOfBox = !offset;
549     if (positionIsAtStartOfBox == box->isLeftToRightDirection()) {
550         // offset is on the left edge
551
552         const InlineBox* prevBox = box->prevLeafChildIgnoringLineBreak();
553         if ((prevBox && prevBox->bidiLevel() == box->bidiLevel())
554             || box->renderer()->containingBlock()->style()->direction() == box->direction()) // FIXME: left on 12CBA
555             return createVisiblePositionForBox(box, box->caretLeftmostOffset(), shouldAffinityBeDownstream);
556
557         if (prevBox && prevBox->bidiLevel() > box->bidiLevel()) {
558             // e.g. left of B in aDC12BAb
559             const InlineBox* leftmostBox;
560             do {
561                 leftmostBox = prevBox;
562                 prevBox = leftmostBox->prevLeafChildIgnoringLineBreak();
563             } while (prevBox && prevBox->bidiLevel() > box->bidiLevel());
564             return createVisiblePositionForBox(leftmostBox, leftmostBox->caretRightmostOffset(), shouldAffinityBeDownstream);
565         }
566
567         if (!prevBox || prevBox->bidiLevel() < box->bidiLevel()) {
568             // e.g. left of D in aDC12BAb
569             const InlineBox* rightmostBox;
570             const InlineBox* nextBox = box;
571             do {
572                 rightmostBox = nextBox;
573                 nextBox = rightmostBox->nextLeafChildIgnoringLineBreak();
574             } while (nextBox && nextBox->bidiLevel() >= box->bidiLevel());
575             return createVisiblePositionForBox(rightmostBox,
576                 box->isLeftToRightDirection() ? rightmostBox->caretMaxOffset() : rightmostBox->caretMinOffset(), shouldAffinityBeDownstream);
577         }
578
579         return createVisiblePositionForBox(box, box->caretRightmostOffset(), shouldAffinityBeDownstream);
580     }
581
582     const InlineBox* nextBox = box->nextLeafChildIgnoringLineBreak();
583     if ((nextBox && nextBox->bidiLevel() == box->bidiLevel())
584         || box->renderer()->containingBlock()->style()->direction() == box->direction())
585         return createVisiblePositionForBox(box, box->caretRightmostOffset(), shouldAffinityBeDownstream);
586
587     // offset is on the right edge
588     if (nextBox && nextBox->bidiLevel() > box->bidiLevel()) {
589         // e.g. right of C in aDC12BAb
590         const InlineBox* rightmostBox;
591         do {
592             rightmostBox = nextBox;
593             nextBox = rightmostBox->nextLeafChildIgnoringLineBreak();
594         } while (nextBox && nextBox->bidiLevel() > box->bidiLevel());
595         return createVisiblePositionForBox(rightmostBox, rightmostBox->caretLeftmostOffset(), shouldAffinityBeDownstream);
596     }
597
598     if (!nextBox || nextBox->bidiLevel() < box->bidiLevel()) {
599         // e.g. right of A in aDC12BAb
600         const InlineBox* leftmostBox;
601         const InlineBox* prevBox = box;
602         do {
603             leftmostBox = prevBox;
604             prevBox = leftmostBox->prevLeafChildIgnoringLineBreak();
605         } while (prevBox && prevBox->bidiLevel() >= box->bidiLevel());
606         return createVisiblePositionForBox(leftmostBox,
607             box->isLeftToRightDirection() ? leftmostBox->caretMinOffset() : leftmostBox->caretMaxOffset(), shouldAffinityBeDownstream);
608     }
609
610     return createVisiblePositionForBox(box, box->caretLeftmostOffset(), shouldAffinityBeDownstream);
611 }
612
613 VisiblePosition RenderText::positionForPoint(const LayoutPoint& point)
614 {
615     if (!firstTextBox() || textLength() == 0)
616         return createVisiblePosition(0, DOWNSTREAM);
617
618     LayoutUnit pointLineDirection = firstTextBox()->isHorizontal() ? point.x() : point.y();
619     LayoutUnit pointBlockDirection = firstTextBox()->isHorizontal() ? point.y() : point.x();
620     bool blocksAreFlipped = style()->isFlippedBlocksWritingMode();
621
622     InlineTextBox* lastBox = 0;
623     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
624         if (box->isLineBreak() && !box->prevLeafChild() && box->nextLeafChild() && !box->nextLeafChild()->isLineBreak())
625             box = box->nextTextBox();
626
627         RootInlineBox* rootBox = box->root();
628         LayoutUnit top = min(rootBox->selectionTop(), rootBox->lineTop());
629         if (pointBlockDirection > top || (!blocksAreFlipped && pointBlockDirection == top)) {
630             LayoutUnit bottom = rootBox->selectionBottom();
631             if (rootBox->nextRootBox())
632                 bottom = min(bottom, rootBox->nextRootBox()->lineTop());
633
634             if (pointBlockDirection < bottom || (blocksAreFlipped && pointBlockDirection == bottom)) {
635                 ShouldAffinityBeDownstream shouldAffinityBeDownstream;
636                 if (lineDirectionPointFitsInBox(pointLineDirection, box, shouldAffinityBeDownstream))
637                     return createVisiblePositionAfterAdjustingOffsetForBiDi(box, box->offsetForPosition(pointLineDirection), shouldAffinityBeDownstream);
638             }
639         }
640         lastBox = box;
641     }
642
643     if (lastBox) {
644         ShouldAffinityBeDownstream shouldAffinityBeDownstream;
645         lineDirectionPointFitsInBox(pointLineDirection, lastBox, shouldAffinityBeDownstream);
646         return createVisiblePositionAfterAdjustingOffsetForBiDi(lastBox, lastBox->offsetForPosition(pointLineDirection) + lastBox->start(), shouldAffinityBeDownstream);
647     }
648     return createVisiblePosition(0, DOWNSTREAM);
649 }
650
651 LayoutRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, LayoutUnit* extraWidthToEndOfLine)
652 {
653     if (!inlineBox)
654         return LayoutRect();
655
656     ASSERT(inlineBox->isInlineTextBox());
657     if (!inlineBox->isInlineTextBox())
658         return LayoutRect();
659
660     InlineTextBox* box = toInlineTextBox(inlineBox);
661
662     int height = box->root()->selectionHeight();
663     int top = box->root()->selectionTop();
664
665     // Go ahead and round left to snap it to the nearest pixel.
666     float left = box->positionForOffset(caretOffset);
667
668     // Distribute the caret's width to either side of the offset.
669     int caretWidthLeftOfOffset = caretWidth / 2;
670     left -= caretWidthLeftOfOffset;
671     int caretWidthRightOfOffset = caretWidth - caretWidthLeftOfOffset;
672
673     left = roundf(left);
674
675     float rootLeft = box->root()->logicalLeft();
676     float rootRight = box->root()->logicalRight();
677
678     // FIXME: should we use the width of the root inline box or the
679     // width of the containing block for this?
680     if (extraWidthToEndOfLine)
681         *extraWidthToEndOfLine = (box->root()->logicalWidth() + rootLeft) - (left + 1);
682
683     RenderBlock* cb = containingBlock();
684     RenderStyle* cbStyle = cb->style();
685
686     float leftEdge;
687     float rightEdge;
688     leftEdge = min<float>(0, rootLeft);
689     rightEdge = max<float>(cb->logicalWidth(), rootRight);
690
691     bool rightAligned = false;
692     switch (cbStyle->textAlign()) {
693     case RIGHT:
694     case WEBKIT_RIGHT:
695         rightAligned = true;
696         break;
697     case LEFT:
698     case WEBKIT_LEFT:
699     case CENTER:
700     case WEBKIT_CENTER:
701         break;
702     case JUSTIFY:
703     case TASTART:
704         rightAligned = !cbStyle->isLeftToRightDirection();
705         break;
706     case TAEND:
707         rightAligned = cbStyle->isLeftToRightDirection();
708         break;
709     }
710
711     if (rightAligned) {
712         left = max(left, leftEdge);
713         left = min(left, rootRight - caretWidth);
714     } else {
715         left = min(left, rightEdge - caretWidthRightOfOffset);
716         left = max(left, rootLeft);
717     }
718
719     return style()->isHorizontalWritingMode() ? IntRect(left, top, caretWidth, height) : IntRect(top, left, height, caretWidth);
720 }
721
722 ALWAYS_INLINE float RenderText::widthFromCache(const Font& f, int start, int len, float xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
723 {
724     if (style()->hasTextCombine() && isCombineText()) {
725         const RenderCombineText* combineText = toRenderCombineText(this);
726         if (combineText->isCombined())
727             return combineText->combinedTextWidth(f);
728     }
729
730     if (f.isFixedPitch() && !f.isSmallCaps() && m_isAllASCII && (!glyphOverflow || !glyphOverflow->computeBounds)) {
731         float monospaceCharacterWidth = f.spaceWidth();
732         float w = 0;
733         bool isSpace;
734         ASSERT(m_text);
735         StringImpl& text = *m_text.impl();
736         for (int i = start; i < start + len; i++) {
737             char c = text[i];
738             if (c <= ' ') {
739                 if (c == ' ' || c == '\n') {
740                     w += monospaceCharacterWidth;
741                     isSpace = true;
742                 } else if (c == '\t') {
743                     if (style()->collapseWhiteSpace()) {
744                         w += monospaceCharacterWidth;
745                         isSpace = true;
746                     } else {
747                         w += f.tabWidth(style()->tabSize(), xPos + w);
748                         isSpace = false;
749                     }
750                 } else
751                     isSpace = false;
752             } else {
753                 w += monospaceCharacterWidth;
754                 isSpace = false;
755             }
756             if (isSpace && i > start)
757                 w += f.wordSpacing();
758         }
759         return w;
760     }
761
762     TextRun run = RenderBlock::constructTextRun(const_cast<RenderText*>(this), f, this, start, len, style());
763     run.setCharactersLength(textLength() - start);
764     ASSERT(run.charactersLength() >= run.length());
765
766     run.setCharacterScanForCodePath(!canUseSimpleFontCodePath());
767     run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize());
768     run.setXPos(xPos);
769     return f.width(run, fallbackFonts, glyphOverflow);
770 }
771
772 void RenderText::trimmedPrefWidths(float leadWidth,
773                                    float& beginMinW, bool& beginWS,
774                                    float& endMinW, bool& endWS,
775                                    bool& hasBreakableChar, bool& hasBreak,
776                                    float& beginMaxW, float& endMaxW,
777                                    float& minW, float& maxW, bool& stripFrontSpaces)
778 {
779     bool collapseWhiteSpace = style()->collapseWhiteSpace();
780     if (!collapseWhiteSpace)
781         stripFrontSpaces = false;
782
783     if (m_hasTab || preferredLogicalWidthsDirty())
784         computePreferredLogicalWidths(leadWidth);
785
786     beginWS = !stripFrontSpaces && m_hasBeginWS;
787     endWS = m_hasEndWS;
788
789     int len = textLength();
790
791     if (!len || (stripFrontSpaces && text()->containsOnlyWhitespace())) {
792         beginMinW = 0;
793         endMinW = 0;
794         beginMaxW = 0;
795         endMaxW = 0;
796         minW = 0;
797         maxW = 0;
798         hasBreak = false;
799         return;
800     }
801
802     minW = m_minWidth;
803     maxW = m_maxWidth;
804
805     beginMinW = m_beginMinWidth;
806     endMinW = m_endMinWidth;
807
808     hasBreakableChar = m_hasBreakableChar;
809     hasBreak = m_hasBreak;
810
811     ASSERT(m_text);
812     StringImpl& text = *m_text.impl();
813     if (text[0] == ' ' || (text[0] == '\n' && !style()->preserveNewline()) || text[0] == '\t') {
814         const Font& font = style()->font(); // FIXME: This ignores first-line.
815         if (stripFrontSpaces) {
816             const UChar space = ' ';
817             float spaceWidth = font.width(RenderBlock::constructTextRun(this, font, &space, 1, style()));
818             maxW -= spaceWidth;
819         } else
820             maxW += font.wordSpacing();
821     }
822
823     stripFrontSpaces = collapseWhiteSpace && m_hasEndWS;
824
825     if (!style()->autoWrap() || minW > maxW)
826         minW = maxW;
827
828     // Compute our max widths by scanning the string for newlines.
829     if (hasBreak) {
830         const Font& f = style()->font(); // FIXME: This ignores first-line.
831         bool firstLine = true;
832         beginMaxW = maxW;
833         endMaxW = maxW;
834         for (int i = 0; i < len; i++) {
835             int linelen = 0;
836             while (i + linelen < len && text[i + linelen] != '\n')
837                 linelen++;
838
839             if (linelen) {
840                 endMaxW = widthFromCache(f, i, linelen, leadWidth + endMaxW, 0, 0);
841                 if (firstLine) {
842                     firstLine = false;
843                     leadWidth = 0;
844                     beginMaxW = endMaxW;
845                 }
846                 i += linelen;
847             } else if (firstLine) {
848                 beginMaxW = 0;
849                 firstLine = false;
850                 leadWidth = 0;
851             }
852
853             if (i == len - 1)
854                 // A <pre> run that ends with a newline, as in, e.g.,
855                 // <pre>Some text\n\n<span>More text</pre>
856                 endMaxW = 0;
857         }
858     }
859 }
860
861 static inline bool isSpaceAccordingToStyle(UChar c, RenderStyle* style)
862 {
863     return c == ' ' || (c == noBreakSpace && style->nbspMode() == SPACE);
864 }
865
866 float RenderText::minLogicalWidth() const
867 {
868     if (preferredLogicalWidthsDirty())
869         const_cast<RenderText*>(this)->computePreferredLogicalWidths(0);
870         
871     return m_minWidth;
872 }
873
874 float RenderText::maxLogicalWidth() const
875 {
876     if (preferredLogicalWidthsDirty())
877         const_cast<RenderText*>(this)->computePreferredLogicalWidths(0);
878         
879     return m_maxWidth;
880 }
881
882 void RenderText::computePreferredLogicalWidths(float leadWidth)
883 {
884     HashSet<const SimpleFontData*> fallbackFonts;
885     GlyphOverflow glyphOverflow;
886     computePreferredLogicalWidths(leadWidth, fallbackFonts, glyphOverflow);
887     if (fallbackFonts.isEmpty() && !glyphOverflow.left && !glyphOverflow.right && !glyphOverflow.top && !glyphOverflow.bottom)
888         m_knownToHaveNoOverflowAndNoFallbackFonts = true;
889 }
890
891 static inline float hyphenWidth(RenderText* renderer, const Font& font)
892 {
893     RenderStyle* style = renderer->style();
894     return font.width(RenderBlock::constructTextRun(renderer, font, style->hyphenString().string(), style));
895 }
896
897 static float maxWordFragmentWidth(RenderText* renderer, RenderStyle* style, const Font& font, const UChar* word, int wordLength, int minimumPrefixLength, int minimumSuffixLength, int& suffixStart, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow& glyphOverflow)
898 {
899     suffixStart = 0;
900     if (wordLength <= minimumSuffixLength)
901         return 0;
902
903     Vector<int, 8> hyphenLocations;
904     int hyphenLocation = wordLength - minimumSuffixLength;
905     while ((hyphenLocation = lastHyphenLocation(word, wordLength, hyphenLocation, style->locale())) >= minimumPrefixLength)
906         hyphenLocations.append(hyphenLocation);
907
908     if (hyphenLocations.isEmpty())
909         return 0;
910
911     hyphenLocations.reverse();
912
913     float minimumFragmentWidthToConsider = font.pixelSize() * 5 / 4 + hyphenWidth(renderer, font);
914     float maxFragmentWidth = 0;
915     for (size_t k = 0; k < hyphenLocations.size(); ++k) {
916         int fragmentLength = hyphenLocations[k] - suffixStart;
917         StringBuilder fragmentWithHyphen;
918         fragmentWithHyphen.append(word + suffixStart, fragmentLength);
919         fragmentWithHyphen.append(style->hyphenString());
920
921         TextRun run = RenderBlock::constructTextRun(renderer, font, fragmentWithHyphen.characters(), fragmentWithHyphen.length(), style);
922         run.setCharactersLength(fragmentWithHyphen.length());
923         run.setCharacterScanForCodePath(!renderer->canUseSimpleFontCodePath());
924         float fragmentWidth = font.width(run, &fallbackFonts, &glyphOverflow);
925
926         // Narrow prefixes are ignored. See tryHyphenating in RenderBlockLineLayout.cpp.
927         if (fragmentWidth <= minimumFragmentWidthToConsider)
928             continue;
929
930         suffixStart += fragmentLength;
931         maxFragmentWidth = max(maxFragmentWidth, fragmentWidth);
932     }
933
934     return maxFragmentWidth;
935 }
936
937 void RenderText::computePreferredLogicalWidths(float leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow& glyphOverflow)
938 {
939     ASSERT(m_hasTab || preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflowAndNoFallbackFonts);
940
941     m_minWidth = 0;
942     m_beginMinWidth = 0;
943     m_endMinWidth = 0;
944     m_maxWidth = 0;
945
946     if (isBR())
947         return;
948
949     float currMinWidth = 0;
950     float currMaxWidth = 0;
951     m_hasBreakableChar = false;
952     m_hasBreak = false;
953     m_hasTab = false;
954     m_hasBeginWS = false;
955     m_hasEndWS = false;
956
957     RenderStyle* styleToUse = style();
958     const Font& f = styleToUse->font(); // FIXME: This ignores first-line.
959     float wordSpacing = styleToUse->wordSpacing();
960     int len = textLength();
961     LazyLineBreakIterator breakIterator(m_text, styleToUse->locale());
962     bool needsWordSpacing = false;
963     bool ignoringSpaces = false;
964     bool isSpace = false;
965     bool firstWord = true;
966     bool firstLine = true;
967     int nextBreakable = -1;
968     int lastWordBoundary = 0;
969
970     // Non-zero only when kerning is enabled, in which case we measure words with their trailing
971     // space, then subtract its width.
972     float wordTrailingSpaceWidth = f.typesettingFeatures() & Kerning ? f.width(RenderBlock::constructTextRun(this, f, &space, 1, styleToUse), &fallbackFonts) + wordSpacing : 0;
973
974     // If automatic hyphenation is allowed, we keep track of the width of the widest word (or word
975     // fragment) encountered so far, and only try hyphenating words that are wider.
976     float maxWordWidth = numeric_limits<float>::max();
977     int minimumPrefixLength = 0;
978     int minimumSuffixLength = 0;
979     if (styleToUse->hyphens() == HyphensAuto && canHyphenate(styleToUse->locale())) {
980         maxWordWidth = 0;
981
982         // Map 'hyphenate-limit-{before,after}: auto;' to 2.
983         minimumPrefixLength = styleToUse->hyphenationLimitBefore();
984         if (minimumPrefixLength < 0)
985             minimumPrefixLength = 2;
986
987         minimumSuffixLength = styleToUse->hyphenationLimitAfter();
988         if (minimumSuffixLength < 0)
989             minimumSuffixLength = 2;
990     }
991
992     int firstGlyphLeftOverflow = -1;
993
994     bool breakNBSP = styleToUse->autoWrap() && styleToUse->nbspMode() == SPACE;
995     bool breakAll = (styleToUse->wordBreak() == BreakAllWordBreak || styleToUse->wordBreak() == BreakWordBreak) && styleToUse->autoWrap();
996
997     for (int i = 0; i < len; i++) {
998         UChar c = characterAt(i);
999
1000         bool previousCharacterIsSpace = isSpace;
1001
1002         bool isNewline = false;
1003         if (c == '\n') {
1004             if (styleToUse->preserveNewline()) {
1005                 m_hasBreak = true;
1006                 isNewline = true;
1007                 isSpace = false;
1008             } else
1009                 isSpace = true;
1010         } else if (c == '\t') {
1011             if (!styleToUse->collapseWhiteSpace()) {
1012                 m_hasTab = true;
1013                 isSpace = false;
1014             } else
1015                 isSpace = true;
1016         } else
1017             isSpace = c == ' ';
1018
1019         if ((isSpace || isNewline) && !i)
1020             m_hasBeginWS = true;
1021         if ((isSpace || isNewline) && i == len - 1)
1022             m_hasEndWS = true;
1023
1024         if (!ignoringSpaces && styleToUse->collapseWhiteSpace() && previousCharacterIsSpace && isSpace)
1025             ignoringSpaces = true;
1026
1027         if (ignoringSpaces && !isSpace)
1028             ignoringSpaces = false;
1029
1030         // Ignore spaces and soft hyphens
1031         if (ignoringSpaces) {
1032             ASSERT(lastWordBoundary == i);
1033             lastWordBoundary++;
1034             continue;
1035         } else if (c == softHyphen && styleToUse->hyphens() != HyphensNone) {
1036             currMaxWidth += widthFromCache(f, lastWordBoundary, i - lastWordBoundary, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow);
1037             if (firstGlyphLeftOverflow < 0)
1038                 firstGlyphLeftOverflow = glyphOverflow.left;
1039             lastWordBoundary = i + 1;
1040             continue;
1041         }
1042
1043         bool hasBreak = breakAll || isBreakable(breakIterator, i, nextBreakable, breakNBSP);
1044         bool betweenWords = true;
1045         int j = i;
1046         while (c != '\n' && !isSpaceAccordingToStyle(c, styleToUse) && c != '\t' && (c != softHyphen || styleToUse->hyphens() == HyphensNone)) {
1047             j++;
1048             if (j == len)
1049                 break;
1050             c = characterAt(j);
1051             if (isBreakable(breakIterator, j, nextBreakable, breakNBSP) && characterAt(j - 1) != softHyphen)
1052                 break;
1053             if (breakAll) {
1054                 betweenWords = false;
1055                 break;
1056             }
1057         }
1058
1059         int wordLen = j - i;
1060         if (wordLen) {
1061             bool isSpace = (j < len) && isSpaceAccordingToStyle(c, styleToUse);
1062             float w;
1063             if (wordTrailingSpaceWidth && isSpace)
1064                 w = widthFromCache(f, i, wordLen + 1, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow) - wordTrailingSpaceWidth;
1065             else {
1066                 w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow);
1067                 if (c == softHyphen && styleToUse->hyphens() != HyphensNone)
1068                     currMinWidth += hyphenWidth(this, f);
1069             }
1070
1071             if (w > maxWordWidth) {
1072                 int suffixStart;
1073                 float maxFragmentWidth = maxWordFragmentWidth(this, styleToUse, f, characters() + i, wordLen, minimumPrefixLength, minimumSuffixLength, suffixStart, fallbackFonts, glyphOverflow);
1074
1075                 if (suffixStart) {
1076                     float suffixWidth;
1077                     if (wordTrailingSpaceWidth && isSpace)
1078                         suffixWidth = widthFromCache(f, i + suffixStart, wordLen - suffixStart + 1, leadWidth + currMaxWidth, 0, 0) - wordTrailingSpaceWidth;
1079                     else
1080                         suffixWidth = widthFromCache(f, i + suffixStart, wordLen - suffixStart, leadWidth + currMaxWidth, 0, 0);
1081
1082                     maxFragmentWidth = max(maxFragmentWidth, suffixWidth);
1083
1084                     currMinWidth += maxFragmentWidth - w;
1085                     maxWordWidth = max(maxWordWidth, maxFragmentWidth);
1086                 } else
1087                     maxWordWidth = w;
1088             }
1089
1090             if (firstGlyphLeftOverflow < 0)
1091                 firstGlyphLeftOverflow = glyphOverflow.left;
1092             currMinWidth += w;
1093             if (betweenWords) {
1094                 if (lastWordBoundary == i)
1095                     currMaxWidth += w;
1096                 else
1097                     currMaxWidth += widthFromCache(f, lastWordBoundary, j - lastWordBoundary, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow);
1098                 lastWordBoundary = j;
1099             }
1100
1101             bool isCollapsibleWhiteSpace = (j < len) && styleToUse->isCollapsibleWhiteSpace(c);
1102             if (j < len && styleToUse->autoWrap())
1103                 m_hasBreakableChar = true;
1104
1105             // Add in wordSpacing to our currMaxWidth, but not if this is the last word on a line or the
1106             // last word in the run.
1107             if (wordSpacing && (isSpace || isCollapsibleWhiteSpace) && !containsOnlyWhitespace(j, len-j))
1108                 currMaxWidth += wordSpacing;
1109
1110             if (firstWord) {
1111                 firstWord = false;
1112                 // If the first character in the run is breakable, then we consider ourselves to have a beginning
1113                 // minimum width of 0, since a break could occur right before our run starts, preventing us from ever
1114                 // being appended to a previous text run when considering the total minimum width of the containing block.
1115                 if (hasBreak)
1116                     m_hasBreakableChar = true;
1117                 m_beginMinWidth = hasBreak ? 0 : currMinWidth;
1118             }
1119             m_endMinWidth = currMinWidth;
1120
1121             if (currMinWidth > m_minWidth)
1122                 m_minWidth = currMinWidth;
1123             currMinWidth = 0;
1124
1125             i += wordLen - 1;
1126         } else {
1127             // Nowrap can never be broken, so don't bother setting the
1128             // breakable character boolean. Pre can only be broken if we encounter a newline.
1129             if (style()->autoWrap() || isNewline)
1130                 m_hasBreakableChar = true;
1131
1132             if (currMinWidth > m_minWidth)
1133                 m_minWidth = currMinWidth;
1134             currMinWidth = 0;
1135
1136             if (isNewline) { // Only set if preserveNewline was true and we saw a newline.
1137                 if (firstLine) {
1138                     firstLine = false;
1139                     leadWidth = 0;
1140                     if (!styleToUse->autoWrap())
1141                         m_beginMinWidth = currMaxWidth;
1142                 }
1143
1144                 if (currMaxWidth > m_maxWidth)
1145                     m_maxWidth = currMaxWidth;
1146                 currMaxWidth = 0;
1147             } else {
1148                 TextRun run = RenderBlock::constructTextRun(this, f, this, i, 1, styleToUse);
1149                 run.setCharactersLength(len - i);
1150                 ASSERT(run.charactersLength() >= run.length());
1151                 run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize());
1152                 run.setXPos(leadWidth + currMaxWidth);
1153
1154                 currMaxWidth += f.width(run, &fallbackFonts);
1155                 glyphOverflow.right = 0;
1156                 needsWordSpacing = isSpace && !previousCharacterIsSpace && i == len - 1;
1157             }
1158             ASSERT(lastWordBoundary == i);
1159             lastWordBoundary++;
1160         }
1161     }
1162
1163     if (firstGlyphLeftOverflow > 0)
1164         glyphOverflow.left = firstGlyphLeftOverflow;
1165
1166     if ((needsWordSpacing && len > 1) || (ignoringSpaces && !firstWord))
1167         currMaxWidth += wordSpacing;
1168
1169     m_minWidth = max(currMinWidth, m_minWidth);
1170     m_maxWidth = max(currMaxWidth, m_maxWidth);
1171
1172     if (!styleToUse->autoWrap())
1173         m_minWidth = m_maxWidth;
1174
1175     if (styleToUse->whiteSpace() == PRE) {
1176         if (firstLine)
1177             m_beginMinWidth = m_maxWidth;
1178         m_endMinWidth = currMaxWidth;
1179     }
1180
1181     setPreferredLogicalWidthsDirty(false);
1182 }
1183
1184 bool RenderText::isAllCollapsibleWhitespace() const
1185 {
1186     unsigned length = textLength();
1187     if (is8Bit()) {
1188         for (unsigned i = 0; i < length; ++i) {
1189             if (!style()->isCollapsibleWhiteSpace(characters8()[i]))
1190                 return false;
1191         }
1192         return true;
1193     }
1194     for (unsigned i = 0; i < length; ++i) {
1195         if (!style()->isCollapsibleWhiteSpace(characters16()[i]))
1196             return false;
1197     }
1198     return true;
1199 }
1200     
1201 bool RenderText::containsOnlyWhitespace(unsigned from, unsigned len) const
1202 {
1203     ASSERT(m_text);
1204     StringImpl& text = *m_text.impl();
1205     unsigned currPos;
1206     for (currPos = from;
1207          currPos < from + len && (text[currPos] == '\n' || text[currPos] == ' ' || text[currPos] == '\t');
1208          currPos++) { }
1209     return currPos >= (from + len);
1210 }
1211
1212 FloatPoint RenderText::firstRunOrigin() const
1213 {
1214     return IntPoint(firstRunX(), firstRunY());
1215 }
1216
1217 float RenderText::firstRunX() const
1218 {
1219     return m_firstTextBox ? m_firstTextBox->x() : 0;
1220 }
1221
1222 float RenderText::firstRunY() const
1223 {
1224     return m_firstTextBox ? m_firstTextBox->y() : 0;
1225 }
1226     
1227 void RenderText::setSelectionState(SelectionState state)
1228 {
1229     RenderObject::setSelectionState(state);
1230
1231     if (canUpdateSelectionOnRootLineBoxes()) {
1232         if (state == SelectionStart || state == SelectionEnd || state == SelectionBoth) {
1233             int startPos, endPos;
1234             selectionStartEnd(startPos, endPos);
1235             if (selectionState() == SelectionStart) {
1236                 endPos = textLength();
1237
1238                 // to handle selection from end of text to end of line
1239                 if (startPos && startPos == endPos)
1240                     startPos = endPos - 1;
1241             } else if (selectionState() == SelectionEnd)
1242                 startPos = 0;
1243
1244             for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
1245                 if (box->isSelected(startPos, endPos)) {
1246                     RootInlineBox* root = box->root();
1247                     if (root)
1248                         root->setHasSelectedChildren(true);
1249                 }
1250             }
1251         } else {
1252             for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
1253                 RootInlineBox* root = box->root();
1254                 if (root)
1255                     root->setHasSelectedChildren(state == SelectionInside);
1256             }
1257         }
1258     }
1259
1260     // The containing block can be null in case of an orphaned tree.
1261     RenderBlock* containingBlock = this->containingBlock();
1262     if (containingBlock && !containingBlock->isRenderView())
1263         containingBlock->setSelectionState(state);
1264 }
1265
1266 void RenderText::setTextWithOffset(PassRefPtr<StringImpl> text, unsigned offset, unsigned len, bool force)
1267 {
1268     if (!force && equal(m_text.impl(), text.get()))
1269         return;
1270
1271     unsigned oldLen = textLength();
1272     unsigned newLen = text->length();
1273     int delta = newLen - oldLen;
1274     unsigned end = len ? offset + len - 1 : offset;
1275
1276     RootInlineBox* firstRootBox = 0;
1277     RootInlineBox* lastRootBox = 0;
1278
1279     bool dirtiedLines = false;
1280
1281     // Dirty all text boxes that include characters in between offset and offset+len.
1282     for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) {
1283         // FIXME: This shouldn't rely on the end of a dirty line box. See https://bugs.webkit.org/show_bug.cgi?id=97264
1284         // Text run is entirely before the affected range.
1285         if (curr->end() < offset)
1286             continue;
1287
1288         // Text run is entirely after the affected range.
1289         if (curr->start() > end) {
1290             curr->offsetRun(delta);
1291             RootInlineBox* root = curr->root();
1292             if (!firstRootBox) {
1293                 firstRootBox = root;
1294                 if (!dirtiedLines) {
1295                     // The affected area was in between two runs. Go ahead and mark the root box of
1296                     // the run after the affected area as dirty.
1297                     firstRootBox->markDirty();
1298                     dirtiedLines = true;
1299                 }
1300             }
1301             lastRootBox = root;
1302         } else if (curr->end() >= offset && curr->end() <= end) {
1303             // Text run overlaps with the left end of the affected range.
1304             curr->dirtyLineBoxes();
1305             dirtiedLines = true;
1306         } else if (curr->start() <= offset && curr->end() >= end) {
1307             // Text run subsumes the affected range.
1308             curr->dirtyLineBoxes();
1309             dirtiedLines = true;
1310         } else if (curr->start() <= end && curr->end() >= end) {
1311             // Text run overlaps with right end of the affected range.
1312             curr->dirtyLineBoxes();
1313             dirtiedLines = true;
1314         }
1315     }
1316
1317     // Now we have to walk all of the clean lines and adjust their cached line break information
1318     // to reflect our updated offsets.
1319     if (lastRootBox)
1320         lastRootBox = lastRootBox->nextRootBox();
1321     if (firstRootBox) {
1322         RootInlineBox* prev = firstRootBox->prevRootBox();
1323         if (prev)
1324             firstRootBox = prev;
1325     } else if (lastTextBox()) {
1326         ASSERT(!lastRootBox);
1327         firstRootBox = lastTextBox()->root();
1328         firstRootBox->markDirty();
1329         dirtiedLines = true;
1330     }
1331     for (RootInlineBox* curr = firstRootBox; curr && curr != lastRootBox; curr = curr->nextRootBox()) {
1332         if (curr->lineBreakObj() == this && curr->lineBreakPos() > end)
1333             curr->setLineBreakPos(curr->lineBreakPos() + delta);
1334     }
1335
1336     // If the text node is empty, dirty the line where new text will be inserted.
1337     if (!firstTextBox() && parent()) {
1338         parent()->dirtyLinesFromChangedChild(this);
1339         dirtiedLines = true;
1340     }
1341
1342     m_linesDirty = dirtiedLines;
1343     setText(text, force || dirtiedLines);
1344 }
1345
1346 void RenderText::transformText()
1347 {
1348     if (RefPtr<StringImpl> textToTransform = originalText())
1349         setText(textToTransform.release(), true);
1350 }
1351
1352 static inline bool isInlineFlowOrEmptyText(const RenderObject* o)
1353 {
1354     if (o->isRenderInline())
1355         return true;
1356     if (!o->isText())
1357         return false;
1358     StringImpl* text = toRenderText(o)->text();
1359     if (!text)
1360         return true;
1361     return !text->length();
1362 }
1363
1364 UChar RenderText::previousCharacter() const
1365 {
1366     // find previous text renderer if one exists
1367     const RenderObject* previousText = this;
1368     while ((previousText = previousText->previousInPreOrder()))
1369         if (!isInlineFlowOrEmptyText(previousText))
1370             break;
1371     UChar prev = ' ';
1372     if (previousText && previousText->isText())
1373         if (StringImpl* previousString = toRenderText(previousText)->text())
1374             prev = (*previousString)[previousString->length() - 1];
1375     return prev;
1376 }
1377
1378 void applyTextTransform(const RenderStyle* style, String& text, UChar previousCharacter)
1379 {
1380     if (!style)
1381         return;
1382
1383     switch (style->textTransform()) {
1384     case TTNONE:
1385         break;
1386     case CAPITALIZE:
1387         makeCapitalized(&text, previousCharacter);
1388         break;
1389     case UPPERCASE:
1390         text.makeUpper();
1391         break;
1392     case LOWERCASE:
1393         text.makeLower();
1394         break;
1395     }
1396 }
1397
1398 void RenderText::setTextInternal(PassRefPtr<StringImpl> text)
1399 {
1400     ASSERT(text);
1401     m_text = text;
1402     if (m_needsTranscoding) {
1403         const TextEncoding* encoding = document()->decoder() ? &document()->decoder()->encoding() : 0;
1404         fontTranscoder().convert(m_text, style()->font().fontDescription(), encoding);
1405     }
1406     ASSERT(m_text);
1407
1408     if (style()) {
1409         applyTextTransform(style(), m_text, previousCharacter());
1410
1411         // We use the same characters here as for list markers.
1412         // See the listMarkerText function in RenderListMarker.cpp.
1413         switch (style()->textSecurity()) {
1414         case TSNONE:
1415             break;
1416         case TSCIRCLE:
1417             secureText(whiteBullet);
1418             break;
1419         case TSDISC:
1420             secureText(bullet);
1421             break;
1422         case TSSQUARE:
1423             secureText(blackSquare);
1424         }
1425     }
1426
1427     ASSERT(m_text);
1428     ASSERT(!isBR() || (textLength() == 1 && m_text[0] == '\n'));
1429
1430     m_isAllASCII = m_text.containsOnlyASCII();
1431     m_canUseSimpleFontCodePath = computeCanUseSimpleFontCodePath();
1432 }
1433
1434 void RenderText::secureText(UChar mask)
1435 {
1436     if (!m_text.length())
1437         return;
1438
1439     int lastTypedCharacterOffsetToReveal = -1;
1440     String revealedText;
1441     SecureTextTimer* secureTextTimer = gSecureTextTimers ? gSecureTextTimers->get(this) : 0;
1442     if (secureTextTimer && secureTextTimer->isActive()) {
1443         lastTypedCharacterOffsetToReveal = secureTextTimer->lastTypedCharacterOffset();
1444         if (lastTypedCharacterOffsetToReveal >= 0)
1445             revealedText.append(m_text[lastTypedCharacterOffsetToReveal]);
1446     }
1447
1448     m_text.fill(mask);
1449     if (lastTypedCharacterOffsetToReveal >= 0) {
1450         m_text.replace(lastTypedCharacterOffsetToReveal, 1, revealedText);
1451         // m_text may be updated later before timer fires. We invalidate the lastTypedCharacterOffset to avoid inconsistency.
1452         secureTextTimer->invalidate();
1453     }
1454 }
1455
1456 void RenderText::setText(PassRefPtr<StringImpl> text, bool force)
1457 {
1458     ASSERT(text);
1459
1460     if (!force && equal(m_text.impl(), text.get()))
1461         return;
1462
1463     setTextInternal(text);
1464     setNeedsLayoutAndPrefWidthsRecalc();
1465     m_knownToHaveNoOverflowAndNoFallbackFonts = false;
1466     
1467     if (AXObjectCache* cache = document()->existingAXObjectCache())
1468         cache->textChanged(this);
1469 }
1470
1471 String RenderText::textWithoutTranscoding() const
1472 {
1473     // If m_text isn't transcoded or is secure, we can just return the modified text.
1474     if (!m_needsTranscoding || style()->textSecurity() != TSNONE)
1475         return text();
1476
1477     // Otherwise, we should use original text. If text-transform is
1478     // specified, we should transform the text on the fly.
1479     String text = originalText();
1480     applyTextTransform(style(), text, previousCharacter());
1481     return text;
1482 }
1483
1484 void RenderText::dirtyLineBoxes(bool fullLayout)
1485 {
1486     if (fullLayout)
1487         deleteTextBoxes();
1488     else if (!m_linesDirty) {
1489         for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
1490             box->dirtyLineBoxes();
1491     }
1492     m_linesDirty = false;
1493 }
1494
1495 InlineTextBox* RenderText::createTextBox()
1496 {
1497     return new (renderArena()) InlineTextBox(this);
1498 }
1499
1500 InlineTextBox* RenderText::createInlineTextBox()
1501 {
1502     InlineTextBox* textBox = createTextBox();
1503     if (!m_firstTextBox)
1504         m_firstTextBox = m_lastTextBox = textBox;
1505     else {
1506         m_lastTextBox->setNextTextBox(textBox);
1507         textBox->setPreviousTextBox(m_lastTextBox);
1508         m_lastTextBox = textBox;
1509     }
1510     textBox->setIsText(true);
1511     return textBox;
1512 }
1513
1514 void RenderText::positionLineBox(InlineBox* box)
1515 {
1516     InlineTextBox* s = toInlineTextBox(box);
1517
1518     // FIXME: should not be needed!!!
1519     if (!s->len()) {
1520         // We want the box to be destroyed.
1521         s->remove();
1522         if (m_firstTextBox == s)
1523             m_firstTextBox = s->nextTextBox();
1524         else
1525             s->prevTextBox()->setNextTextBox(s->nextTextBox());
1526         if (m_lastTextBox == s)
1527             m_lastTextBox = s->prevTextBox();
1528         else
1529             s->nextTextBox()->setPreviousTextBox(s->prevTextBox());
1530         s->destroy(renderArena());
1531         return;
1532     }
1533
1534     m_containsReversedText |= !s->isLeftToRightDirection();
1535 }
1536
1537 float RenderText::width(unsigned from, unsigned len, float xPos, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
1538 {
1539     if (from >= textLength())
1540         return 0;
1541
1542     if (from + len > textLength())
1543         len = textLength() - from;
1544
1545     return width(from, len, style(firstLine)->font(), xPos, fallbackFonts, glyphOverflow);
1546 }
1547
1548 float RenderText::width(unsigned from, unsigned len, const Font& f, float xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
1549 {
1550     ASSERT(from + len <= textLength());
1551     if (!textLength())
1552         return 0;
1553
1554     float w;
1555     if (&f == &style()->font()) {
1556         if (!style()->preserveNewline() && !from && len == textLength() && (!glyphOverflow || !glyphOverflow->computeBounds)) {
1557             if (fallbackFonts) {
1558                 ASSERT(glyphOverflow);
1559                 if (preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflowAndNoFallbackFonts) {
1560                     const_cast<RenderText*>(this)->computePreferredLogicalWidths(0, *fallbackFonts, *glyphOverflow);
1561                     if (fallbackFonts->isEmpty() && !glyphOverflow->left && !glyphOverflow->right && !glyphOverflow->top && !glyphOverflow->bottom)
1562                         m_knownToHaveNoOverflowAndNoFallbackFonts = true;
1563                 }
1564                 w = m_maxWidth;
1565             } else
1566                 w = maxLogicalWidth();
1567         } else
1568             w = widthFromCache(f, from, len, xPos, fallbackFonts, glyphOverflow);
1569     } else {
1570         TextRun run = RenderBlock::constructTextRun(const_cast<RenderText*>(this), f, this, from, len, style());
1571         run.setCharactersLength(textLength() - from);
1572         ASSERT(run.charactersLength() >= run.length());
1573
1574         run.setCharacterScanForCodePath(!canUseSimpleFontCodePath());
1575         run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize());
1576         run.setXPos(xPos);
1577         w = f.width(run, fallbackFonts, glyphOverflow);
1578     }
1579
1580     return w;
1581 }
1582
1583 IntRect RenderText::linesBoundingBox() const
1584 {
1585     IntRect result;
1586     
1587     ASSERT(!firstTextBox() == !lastTextBox());  // Either both are null or both exist.
1588     if (firstTextBox() && lastTextBox()) {
1589         // Return the width of the minimal left side and the maximal right side.
1590         float logicalLeftSide = 0;
1591         float logicalRightSide = 0;
1592         for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) {
1593             if (curr == firstTextBox() || curr->logicalLeft() < logicalLeftSide)
1594                 logicalLeftSide = curr->logicalLeft();
1595             if (curr == firstTextBox() || curr->logicalRight() > logicalRightSide)
1596                 logicalRightSide = curr->logicalRight();
1597         }
1598         
1599         bool isHorizontal = style()->isHorizontalWritingMode();
1600         
1601         float x = isHorizontal ? logicalLeftSide : firstTextBox()->x();
1602         float y = isHorizontal ? firstTextBox()->y() : logicalLeftSide;
1603         float width = isHorizontal ? logicalRightSide - logicalLeftSide : lastTextBox()->logicalBottom() - x;
1604         float height = isHorizontal ? lastTextBox()->logicalBottom() - y : logicalRightSide - logicalLeftSide;
1605         result = enclosingIntRect(FloatRect(x, y, width, height));
1606     }
1607
1608     return result;
1609 }
1610
1611 LayoutRect RenderText::linesVisualOverflowBoundingBox() const
1612 {
1613     if (!firstTextBox())
1614         return LayoutRect();
1615
1616     // Return the width of the minimal left side and the maximal right side.
1617     LayoutUnit logicalLeftSide = LayoutUnit::max();
1618     LayoutUnit logicalRightSide = LayoutUnit::min();
1619     for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) {
1620         logicalLeftSide = min(logicalLeftSide, curr->logicalLeftVisualOverflow());
1621         logicalRightSide = max(logicalRightSide, curr->logicalRightVisualOverflow());
1622     }
1623     
1624     LayoutUnit logicalTop = firstTextBox()->logicalTopVisualOverflow();
1625     LayoutUnit logicalWidth = logicalRightSide - logicalLeftSide;
1626     LayoutUnit logicalHeight = lastTextBox()->logicalBottomVisualOverflow() - logicalTop;
1627     
1628     LayoutRect rect(logicalLeftSide, logicalTop, logicalWidth, logicalHeight);
1629     if (!style()->isHorizontalWritingMode())
1630         rect = rect.transposedRect();
1631     return rect;
1632 }
1633
1634 LayoutRect RenderText::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
1635 {
1636     RenderObject* rendererToRepaint = containingBlock();
1637
1638     // Do not cross self-painting layer boundaries.
1639     RenderObject* enclosingLayerRenderer = enclosingLayer()->renderer();
1640     if (enclosingLayerRenderer != rendererToRepaint && !rendererToRepaint->isDescendantOf(enclosingLayerRenderer))
1641         rendererToRepaint = enclosingLayerRenderer;
1642
1643     // The renderer we chose to repaint may be an ancestor of repaintContainer, but we need to do a repaintContainer-relative repaint.
1644     if (repaintContainer && repaintContainer != rendererToRepaint && !rendererToRepaint->isDescendantOf(repaintContainer))
1645         return repaintContainer->clippedOverflowRectForRepaint(repaintContainer);
1646
1647     return rendererToRepaint->clippedOverflowRectForRepaint(repaintContainer);
1648 }
1649
1650 LayoutRect RenderText::selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent)
1651 {
1652     ASSERT(!needsLayout());
1653
1654     if (selectionState() == SelectionNone)
1655         return LayoutRect();
1656     RenderBlock* cb = containingBlock();
1657     if (!cb)
1658         return LayoutRect();
1659
1660     // Now calculate startPos and endPos for painting selection.
1661     // We include a selection while endPos > 0
1662     int startPos, endPos;
1663     if (selectionState() == SelectionInside) {
1664         // We are fully selected.
1665         startPos = 0;
1666         endPos = textLength();
1667     } else {
1668         selectionStartEnd(startPos, endPos);
1669         if (selectionState() == SelectionStart)
1670             endPos = textLength();
1671         else if (selectionState() == SelectionEnd)
1672             startPos = 0;
1673     }
1674
1675     if (startPos == endPos)
1676         return IntRect();
1677
1678     LayoutRect rect;
1679     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
1680         rect.unite(box->localSelectionRect(startPos, endPos));
1681         rect.unite(ellipsisRectForBox(box, startPos, endPos));
1682     }
1683
1684     if (clipToVisibleContent)
1685         computeRectForRepaint(repaintContainer, rect);
1686     else {
1687         if (cb->hasColumns())
1688             cb->adjustRectForColumns(rect);
1689
1690         rect = localToContainerQuad(FloatRect(rect), repaintContainer).enclosingBoundingBox();
1691     }
1692
1693     return rect;
1694 }
1695
1696 int RenderText::caretMinOffset() const
1697 {
1698     InlineTextBox* box = firstTextBox();
1699     if (!box)
1700         return 0;
1701     int minOffset = box->start();
1702     for (box = box->nextTextBox(); box; box = box->nextTextBox())
1703         minOffset = min<int>(minOffset, box->start());
1704     return minOffset;
1705 }
1706
1707 int RenderText::caretMaxOffset() const
1708 {
1709     InlineTextBox* box = lastTextBox();
1710     if (!lastTextBox())
1711         return textLength();
1712
1713     int maxOffset = box->start() + box->len();
1714     for (box = box->prevTextBox(); box; box = box->prevTextBox())
1715         maxOffset = max<int>(maxOffset, box->start() + box->len());
1716     return maxOffset;
1717 }
1718
1719 unsigned RenderText::renderedTextLength() const
1720 {
1721     int l = 0;
1722     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
1723         l += box->len();
1724     return l;
1725 }
1726
1727 int RenderText::previousOffset(int current) const
1728 {
1729     if (isAllASCII() || m_text.is8Bit())
1730         return current - 1;
1731
1732     StringImpl* textImpl = m_text.impl();
1733     TextBreakIterator* iterator = cursorMovementIterator(textImpl->characters16(), textImpl->length());
1734     if (!iterator)
1735         return current - 1;
1736
1737     long result = textBreakPreceding(iterator, current);
1738     if (result == TextBreakDone)
1739         result = current - 1;
1740
1741
1742     return result;
1743 }
1744
1745 #if PLATFORM(MAC)
1746
1747 #define HANGUL_CHOSEONG_START (0x1100)
1748 #define HANGUL_CHOSEONG_END (0x115F)
1749 #define HANGUL_JUNGSEONG_START (0x1160)
1750 #define HANGUL_JUNGSEONG_END (0x11A2)
1751 #define HANGUL_JONGSEONG_START (0x11A8)
1752 #define HANGUL_JONGSEONG_END (0x11F9)
1753 #define HANGUL_SYLLABLE_START (0xAC00)
1754 #define HANGUL_SYLLABLE_END (0xD7AF)
1755 #define HANGUL_JONGSEONG_COUNT (28)
1756
1757 enum HangulState {
1758     HangulStateL,
1759     HangulStateV,
1760     HangulStateT,
1761     HangulStateLV,
1762     HangulStateLVT,
1763     HangulStateBreak
1764 };
1765
1766 inline bool isHangulLVT(UChar32 character)
1767 {
1768     return (character - HANGUL_SYLLABLE_START) % HANGUL_JONGSEONG_COUNT;
1769 }
1770
1771 inline bool isMark(UChar32 c)
1772 {
1773     int8_t charType = u_charType(c);
1774     return charType == U_NON_SPACING_MARK || charType == U_ENCLOSING_MARK || charType == U_COMBINING_SPACING_MARK;
1775 }
1776
1777 inline bool isRegionalIndicator(UChar32 c)
1778 {
1779     // National flag emoji each consists of a pair of regional indicator symbols.
1780     return 0x1F1E6 <= c && c <= 0x1F1FF;
1781 }
1782
1783 #endif
1784
1785 int RenderText::previousOffsetForBackwardDeletion(int current) const
1786 {
1787 #if PLATFORM(MAC)
1788     ASSERT(m_text);
1789     StringImpl& text = *m_text.impl();
1790     UChar32 character;
1791     bool sawRegionalIndicator = false;
1792     while (current > 0) {
1793         if (U16_IS_TRAIL(text[--current]))
1794             --current;
1795         if (current < 0)
1796             break;
1797
1798         UChar32 character = text.characterStartingAt(current);
1799
1800         if (sawRegionalIndicator) {
1801             // We don't check if the pair of regional indicator symbols before current position can actually be combined
1802             // into a flag, and just delete it. This may not agree with how the pair is rendered in edge cases,
1803             // but is good enough in practice.
1804             if (isRegionalIndicator(character))
1805                 break;
1806             // Don't delete a preceding character that isn't a regional indicator symbol.
1807             U16_FWD_1_UNSAFE(text, current);
1808         }
1809
1810         // We don't combine characters in Armenian ... Limbu range for backward deletion.
1811         if ((character >= 0x0530) && (character < 0x1950))
1812             break;
1813
1814         if (isRegionalIndicator(character)) {
1815             sawRegionalIndicator = true;
1816             continue;
1817         }
1818
1819         if (!isMark(character) && (character != 0xFF9E) && (character != 0xFF9F))
1820             break;
1821     }
1822
1823     if (current <= 0)
1824         return current;
1825
1826     // Hangul
1827     character = text.characterStartingAt(current);
1828     if (((character >= HANGUL_CHOSEONG_START) && (character <= HANGUL_JONGSEONG_END)) || ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END))) {
1829         HangulState state;
1830         HangulState initialState;
1831
1832         if (character < HANGUL_JUNGSEONG_START)
1833             state = HangulStateL;
1834         else if (character < HANGUL_JONGSEONG_START)
1835             state = HangulStateV;
1836         else if (character < HANGUL_SYLLABLE_START)
1837             state = HangulStateT;
1838         else
1839             state = isHangulLVT(character) ? HangulStateLVT : HangulStateLV;
1840
1841         initialState = state;
1842
1843         while (current > 0 && ((character = text.characterStartingAt(current - 1)) >= HANGUL_CHOSEONG_START) && (character <= HANGUL_SYLLABLE_END) && ((character <= HANGUL_JONGSEONG_END) || (character >= HANGUL_SYLLABLE_START))) {
1844             switch (state) {
1845             case HangulStateV:
1846                 if (character <= HANGUL_CHOSEONG_END)
1847                     state = HangulStateL;
1848                 else if ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END) && !isHangulLVT(character))
1849                     state = HangulStateLV;
1850                 else if (character > HANGUL_JUNGSEONG_END)
1851                     state = HangulStateBreak;
1852                 break;
1853             case HangulStateT:
1854                 if ((character >= HANGUL_JUNGSEONG_START) && (character <= HANGUL_JUNGSEONG_END))
1855                     state = HangulStateV;
1856                 else if ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END))
1857                     state = (isHangulLVT(character) ? HangulStateLVT : HangulStateLV);
1858                 else if (character < HANGUL_JUNGSEONG_START)
1859                     state = HangulStateBreak;
1860                 break;
1861             default:
1862                 state = (character < HANGUL_JUNGSEONG_START) ? HangulStateL : HangulStateBreak;
1863                 break;
1864             }
1865             if (state == HangulStateBreak)
1866                 break;
1867
1868             --current;
1869         }
1870     }
1871
1872     return current;
1873 #else
1874     // Platforms other than Mac delete by one code point.
1875     if (U16_IS_TRAIL(m_text[--current]))
1876         --current;
1877     if (current < 0)
1878         current = 0;
1879     return current;
1880 #endif
1881 }
1882
1883 int RenderText::nextOffset(int current) const
1884 {
1885     if (isAllASCII() || m_text.is8Bit())
1886         return current + 1;
1887
1888     StringImpl* textImpl = m_text.impl();
1889     TextBreakIterator* iterator = cursorMovementIterator(textImpl->characters16(), textImpl->length());
1890     if (!iterator)
1891         return current + 1;
1892
1893     long result = textBreakFollowing(iterator, current);
1894     if (result == TextBreakDone)
1895         result = current + 1;
1896
1897     return result;
1898 }
1899
1900 bool RenderText::computeCanUseSimpleFontCodePath() const
1901 {
1902     if (isAllASCII() || m_text.is8Bit())
1903         return true;
1904     return Font::characterRangeCodePath(characters(), length()) == Font::Simple;
1905 }
1906
1907 #ifndef NDEBUG
1908
1909 void RenderText::checkConsistency() const
1910 {
1911 #ifdef CHECK_CONSISTENCY
1912     const InlineTextBox* prev = 0;
1913     for (const InlineTextBox* child = m_firstTextBox; child != 0; child = child->nextTextBox()) {
1914         ASSERT(child->renderer() == this);
1915         ASSERT(child->prevTextBox() == prev);
1916         prev = child;
1917     }
1918     ASSERT(prev == m_lastTextBox);
1919 #endif
1920 }
1921
1922 #endif
1923
1924 void RenderText::momentarilyRevealLastTypedCharacter(unsigned lastTypedCharacterOffset)
1925 {
1926     if (!gSecureTextTimers)
1927         gSecureTextTimers = new SecureTextTimerMap;
1928
1929     SecureTextTimer* secureTextTimer = gSecureTextTimers->get(this);
1930     if (!secureTextTimer) {
1931         secureTextTimer = new SecureTextTimer(this);
1932         gSecureTextTimers->add(this, secureTextTimer);
1933     }
1934     secureTextTimer->restartWithNewText(lastTypedCharacterOffset);
1935 }
1936
1937 } // namespace WebCore