Changeset 157346 in webkit


Ignore:
Timestamp:
Oct 12, 2013 1:33:29 PM (11 years ago)
Author:
Antti Koivisto
Message:

Move line dirtying code to RenderTextLineBoxes
https://bugs.webkit.org/show_bug.cgi?id=122699

Reviewed by Andreas Kling.

  • rendering/RenderTextLineBoxes.cpp:

(WebCore::RenderTextLineBoxes::removeAllFromParent):

Also moved the removal loop.

(WebCore::RenderTextLineBoxes::dirtyAll):
(WebCore::RenderTextLineBoxes::dirtyRange):

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r157345 r157346  
     12013-10-12  Antti Koivisto  <antti@apple.com>
     2
     3        Move line dirtying code to RenderTextLineBoxes
     4        https://bugs.webkit.org/show_bug.cgi?id=122699
     5
     6        Reviewed by Andreas Kling.
     7
     8        * rendering/RenderTextLineBoxes.cpp:
     9        (WebCore::RenderTextLineBoxes::removeAllFromParent):
     10       
     11            Also moved the removal loop.
     12
     13        (WebCore::RenderTextLineBoxes::dirtyAll):
     14        (WebCore::RenderTextLineBoxes::dirtyRange):
     15
    1162013-10-12  Antti Koivisto  <antti@apple.com>
    217
  • trunk/Source/WebCore/rendering/RenderText.cpp

    r157345 r157346  
    240240void RenderText::removeAndDestroyTextBoxes()
    241241{
    242     if (!documentBeingDestroyed()) {
    243         if (firstTextBox()) {
    244             for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
    245                 box->remove();
    246         } else if (parent())
    247             parent()->dirtyLinesFromChangedChild(this);
    248     }
     242    if (!documentBeingDestroyed())
     243        m_lineBoxes.removeAllFromParent(*this);
    249244    m_lineBoxes.deleteAll(*this);
    250245}
     
    11251120        return;
    11261121
    1127     unsigned oldLen = textLength();
    1128     unsigned newLen = text.length();
    1129     int delta = newLen - oldLen;
     1122    int delta = text.length() - textLength();
    11301123    unsigned end = len ? offset + len - 1 : offset;
    11311124
    1132     RootInlineBox* firstRootBox = 0;
    1133     RootInlineBox* lastRootBox = 0;
    1134 
    1135     bool dirtiedLines = false;
    1136 
    1137     // Dirty all text boxes that include characters in between offset and offset+len.
    1138     for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) {
    1139         // FIXME: This shouldn't rely on the end of a dirty line box. See https://bugs.webkit.org/show_bug.cgi?id=97264
    1140         // Text run is entirely before the affected range.
    1141         if (curr->end() < offset)
    1142             continue;
    1143 
    1144         // Text run is entirely after the affected range.
    1145         if (curr->start() > end) {
    1146             curr->offsetRun(delta);
    1147             RootInlineBox& rootBox = curr->root();
    1148             if (!firstRootBox) {
    1149                 firstRootBox = &rootBox;
    1150                 if (!dirtiedLines) {
    1151                     // The affected area was in between two runs. Go ahead and mark the root box of
    1152                     // the run after the affected area as dirty.
    1153                     firstRootBox->markDirty();
    1154                     dirtiedLines = true;
    1155                 }
    1156             }
    1157             lastRootBox = &rootBox;
    1158         } else if (curr->end() >= offset && curr->end() <= end) {
    1159             // Text run overlaps with the left end of the affected range.
    1160             curr->dirtyLineBoxes();
    1161             dirtiedLines = true;
    1162         } else if (curr->start() <= offset && curr->end() >= end) {
    1163             // Text run subsumes the affected range.
    1164             curr->dirtyLineBoxes();
    1165             dirtiedLines = true;
    1166         } else if (curr->start() <= end && curr->end() >= end) {
    1167             // Text run overlaps with right end of the affected range.
    1168             curr->dirtyLineBoxes();
    1169             dirtiedLines = true;
    1170         }
    1171     }
    1172 
    1173     // Now we have to walk all of the clean lines and adjust their cached line break information
    1174     // to reflect our updated offsets.
    1175     if (lastRootBox)
    1176         lastRootBox = lastRootBox->nextRootBox();
    1177     if (firstRootBox) {
    1178         RootInlineBox* prev = firstRootBox->prevRootBox();
    1179         if (prev)
    1180             firstRootBox = prev;
    1181     } else if (lastTextBox()) {
    1182         ASSERT(!lastRootBox);
    1183         firstRootBox = &lastTextBox()->root();
    1184         firstRootBox->markDirty();
    1185         dirtiedLines = true;
    1186     }
    1187     for (RootInlineBox* curr = firstRootBox; curr && curr != lastRootBox; curr = curr->nextRootBox()) {
    1188         if (curr->lineBreakObj() == this && curr->lineBreakPos() > end)
    1189             curr->setLineBreakPos(curr->lineBreakPos() + delta);
    1190     }
    1191 
    1192     // If the text node is empty, dirty the line where new text will be inserted.
    1193     if (!firstTextBox() && parent()) {
    1194         parent()->dirtyLinesFromChangedChild(this);
    1195         dirtiedLines = true;
    1196     }
    1197 
    1198     m_linesDirty = dirtiedLines;
    1199     setText(text, force || dirtiedLines);
     1125    m_linesDirty = m_lineBoxes.dirtyRange(*this, offset, end, delta);
     1126
     1127    setText(text, force || m_linesDirty);
    12001128}
    12011129
     
    13391267    if (fullLayout)
    13401268        m_lineBoxes.deleteAll(*this);
    1341     else if (!m_linesDirty) {
    1342         for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
    1343             box->dirtyLineBoxes();
    1344     }
     1269    else if (!m_linesDirty)
     1270        m_lineBoxes.dirtyAll();
    13451271    m_linesDirty = false;
    13461272}
  • trunk/Source/WebCore/rendering/RenderTextLineBoxes.cpp

    r157345 r157346  
    2929#include "InlineTextBox.h"
    3030#include "RenderStyle.h"
     31#include "RootInlineBox.h"
    3132
    3233namespace WebCore {
     
    104105}
    105106
     107void RenderTextLineBoxes::removeAllFromParent(RenderText& renderer)
     108{
     109    if (!m_first) {
     110        if (renderer.parent())
     111            renderer.parent()->dirtyLinesFromChangedChild(&renderer);
     112        return;
     113    }
     114    for (auto box = m_first; box; box = box->nextTextBox())
     115        box->remove();
     116}
     117
    106118void RenderTextLineBoxes::deleteAll(RenderText& renderer)
    107119{
     
    213225}
    214226
     227void RenderTextLineBoxes::dirtyAll()
     228{
     229    for (auto box = m_first; box; box = box->nextTextBox())
     230        box->dirtyLineBoxes();
     231}
     232
     233bool RenderTextLineBoxes::dirtyRange(RenderText& renderer, unsigned start, unsigned end, int lengthDelta)
     234{
     235    RootInlineBox* firstRootBox = nullptr;
     236    RootInlineBox* lastRootBox = nullptr;
     237
     238    // Dirty all text boxes that include characters in between offset and offset+len.
     239    bool dirtiedLines = false;
     240    for (auto current = m_first; current; current = current->nextTextBox()) {
     241        // FIXME: This shouldn't rely on the end of a dirty line box. See https://bugs.webkit.org/show_bug.cgi?id=97264
     242        // Text run is entirely before the affected range.
     243        if (current->end() < start)
     244            continue;
     245        // Text run is entirely after the affected range.
     246        if (current->start() > end) {
     247            current->offsetRun(lengthDelta);
     248            auto& rootBox = current->root();
     249            if (!firstRootBox) {
     250                firstRootBox = &rootBox;
     251                if (!dirtiedLines) {
     252                    // The affected area was in between two runs. Go ahead and mark the root box of
     253                    // the run after the affected area as dirty.
     254                    firstRootBox->markDirty();
     255                    dirtiedLines = true;
     256                }
     257            }
     258            lastRootBox = &rootBox;
     259            continue;
     260        }
     261        if (current->end() >= start && current->end() <= end) {
     262            // Text run overlaps with the left end of the affected range.
     263            current->dirtyLineBoxes();
     264            dirtiedLines = true;
     265            continue;
     266        }
     267        if (current->start() <= start && current->end() >= end) {
     268            // Text run subsumes the affected range.
     269            current->dirtyLineBoxes();
     270            dirtiedLines = true;
     271            continue;
     272        }
     273        if (current->start() <= end && current->end() >= end) {
     274            // Text run overlaps with right end of the affected range.
     275            current->dirtyLineBoxes();
     276            dirtiedLines = true;
     277            continue;
     278        }
     279    }
     280
     281    // Now we have to walk all of the clean lines and adjust their cached line break information
     282    // to reflect our updated offsets.
     283    if (lastRootBox)
     284        lastRootBox = lastRootBox->nextRootBox();
     285    if (firstRootBox) {
     286        auto previousRootBox = firstRootBox->prevRootBox();
     287        if (previousRootBox)
     288            firstRootBox = previousRootBox;
     289    } else if (m_last) {
     290        ASSERT(!lastRootBox);
     291        firstRootBox = &m_last->root();
     292        firstRootBox->markDirty();
     293        dirtiedLines = true;
     294    }
     295    for (auto current = firstRootBox; current && current != lastRootBox; current = current->nextRootBox()) {
     296        if (current->lineBreakObj() == &renderer && current->lineBreakPos() > end)
     297            current->setLineBreakPos(current->lineBreakPos() + lengthDelta);
     298    }
     299   
     300    // If the text node is empty, dirty the line where new text will be inserted.
     301    if (!m_first && renderer.parent()) {
     302        renderer.parent()->dirtyLinesFromChangedChild(&renderer);
     303        dirtiedLines = true;
     304    }
     305    return dirtiedLines;
     306}
     307
    215308#if !ASSERT_DISABLED
    216309RenderTextLineBoxes::~RenderTextLineBoxes()
  • trunk/Source/WebCore/rendering/RenderTextLineBoxes.h

    r157345 r157346  
    4848    void remove(InlineTextBox&);
    4949
     50    void removeAllFromParent(RenderText&);
    5051    void deleteAll(RenderText&);
    5152
     
    5859    IntRect boundingBox(const RenderText&) const;
    5960    LayoutRect visualOverflowBoundingBox(const RenderText&) const;
     61
     62    void dirtyAll();
     63    bool dirtyRange(RenderText&, unsigned start, unsigned end, int lengthDelta);
    6064
    6165#if !ASSERT_DISABLED
Note: See TracChangeset for help on using the changeset viewer.