[webkit-changes] cvs commit: WebCore/khtml/rendering bidi.cpp render_block.cpp render_flow.cpp render_line.cpp render_object.cpp render_object.h

Maciej mjs at opensource.apple.com
Mon Oct 17 20:15:34 PDT 2005


mjs         05/10/17 20:15:34

  Modified:    .        ChangeLog
               kxmlcore FastMalloc.cpp
               .        ChangeLog
               khtml/html htmltokenizer.cpp htmltokenizer.h
               khtml/rendering bidi.cpp render_block.cpp render_flow.cpp
                        render_line.cpp render_object.cpp render_object.h
  Log:
  JavaScriptCore:
  
          Reviewed by Geoff. Code changes by Darin.
  
  	- some micro-optimizations to FastMalloc to reduce math and branches.
  
          * kxmlcore/FastMalloc.cpp:
          (KXMLCore::TCMalloc_Central_FreeList::Populate):
          (KXMLCore::fastMallocRegisterThread):
          (KXMLCore::TCMalloc_ThreadCache::GetCache):
          (KXMLCore::TCMalloc_ThreadCache::GetCacheIfPresent):
  
  WebCore:
  
          Reviewed by Geoff.
  
          Speed up the tokenizer by keeping more state on the stack instead of in the object,
  	to avoid load-store traffic. About a .5% speedup.
  
          * khtml/html/htmltokenizer.cpp:
          (khtml::HTMLTokenizer::HTMLTokenizer):
          (khtml::HTMLTokenizer::reset):
          (khtml::HTMLTokenizer::begin):
          (khtml::HTMLTokenizer::setForceSynchronous):
          (khtml::HTMLTokenizer::processListing):
          (khtml::HTMLTokenizer::parseSpecial):
          (khtml::HTMLTokenizer::scriptHandler):
          (khtml::HTMLTokenizer::scriptExecution):
          (khtml::HTMLTokenizer::parseComment):
          (khtml::HTMLTokenizer::parseServer):
          (khtml::HTMLTokenizer::parseProcessingInstruction):
          (khtml::HTMLTokenizer::parseText):
          (khtml::HTMLTokenizer::parseEntity):
          (khtml::HTMLTokenizer::parseTag):
          (khtml::HTMLTokenizer::continueProcessing):
          (khtml::HTMLTokenizer::write):
          (khtml::HTMLTokenizer::allDataProcessed):
          (khtml::HTMLTokenizer::end):
          (khtml::HTMLTokenizer::finish):
          (khtml::HTMLTokenizer::notifyFinished):
          (khtml::HTMLTokenizer::isWaitingForScripts):
          * khtml/html/htmltokenizer.h:
          (khtml::HTMLTokenizer::):
          (khtml::HTMLTokenizer::State::State):
          (khtml::HTMLTokenizer::State::tagState):
          (khtml::HTMLTokenizer::State::setTagState):
          (khtml::HTMLTokenizer::State::entityState):
          (khtml::HTMLTokenizer::State::setEntityState):
          (khtml::HTMLTokenizer::State::inScript):
          (khtml::HTMLTokenizer::State::setInScript):
          (khtml::HTMLTokenizer::State::inStyle):
          (khtml::HTMLTokenizer::State::setInStyle):
          (khtml::HTMLTokenizer::State::inSelect):
          (khtml::HTMLTokenizer::State::setInSelect):
          (khtml::HTMLTokenizer::State::inXmp):
          (khtml::HTMLTokenizer::State::setInXmp):
          (khtml::HTMLTokenizer::State::inTitle):
          (khtml::HTMLTokenizer::State::setInTitle):
          (khtml::HTMLTokenizer::State::inPlainText):
          (khtml::HTMLTokenizer::State::setInPlainText):
          (khtml::HTMLTokenizer::State::inProcessingInstruction):
          (khtml::HTMLTokenizer::State::setInProcessingInstruction):
          (khtml::HTMLTokenizer::State::inComment):
          (khtml::HTMLTokenizer::State::setInComment):
          (khtml::HTMLTokenizer::State::inTextArea):
          (khtml::HTMLTokenizer::State::setInTextArea):
          (khtml::HTMLTokenizer::State::escaped):
          (khtml::HTMLTokenizer::State::setEscaped):
          (khtml::HTMLTokenizer::State::inServer):
          (khtml::HTMLTokenizer::State::setInServer):
          (khtml::HTMLTokenizer::State::skipLF):
          (khtml::HTMLTokenizer::State::setSkipLF):
          (khtml::HTMLTokenizer::State::startTag):
          (khtml::HTMLTokenizer::State::setStartTag):
          (khtml::HTMLTokenizer::State::discardLF):
          (khtml::HTMLTokenizer::State::setDiscardLF):
          (khtml::HTMLTokenizer::State::allowYield):
          (khtml::HTMLTokenizer::State::setAllowYield):
          (khtml::HTMLTokenizer::State::loadingExtScript):
          (khtml::HTMLTokenizer::State::setLoadingExtScript):
          (khtml::HTMLTokenizer::State::forceSynchronous):
          (khtml::HTMLTokenizer::State::setForceSynchronous):
          (khtml::HTMLTokenizer::State::inAnySpecial):
          (khtml::HTMLTokenizer::State::hasTagState):
          (khtml::HTMLTokenizer::State::hasEntityState):
          (khtml::HTMLTokenizer::State::):
          (khtml::HTMLTokenizer::State::setBit):
          (khtml::HTMLTokenizer::State::testBit):
          * khtml/rendering/bidi.cpp:
          (khtml::RenderBlock::checkLinesForTextOverflow):
          * khtml/rendering/render_block.cpp:
          (khtml::RenderBlock::updateFirstLetter):
          * khtml/rendering/render_flow.cpp:
          (RenderFlow::caretRect):
          * khtml/rendering/render_line.cpp:
          (khtml::EllipsisBox::paint):
          * khtml/rendering/render_object.cpp:
          (RenderObject::firstLineStyle):
          * khtml/rendering/render_object.h:
          (khtml::RenderObject::style):
  
  Revision  Changes    Path
  1.868     +12 -0     JavaScriptCore/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/ChangeLog,v
  retrieving revision 1.867
  retrieving revision 1.868
  diff -u -r1.867 -r1.868
  --- ChangeLog	16 Oct 2005 00:46:19 -0000	1.867
  +++ ChangeLog	18 Oct 2005 03:15:26 -0000	1.868
  @@ -1,3 +1,15 @@
  +2005-10-17  Maciej Stachowiak  <mjs at apple.com>
  +
  +        Reviewed by Geoff. Code changes by Darin.
  +
  +	- some micro-optimizations to FastMalloc to reduce math and branches.
  +
  +        * kxmlcore/FastMalloc.cpp:
  +        (KXMLCore::TCMalloc_Central_FreeList::Populate):
  +        (KXMLCore::fastMallocRegisterThread):
  +        (KXMLCore::TCMalloc_ThreadCache::GetCache):
  +        (KXMLCore::TCMalloc_ThreadCache::GetCacheIfPresent):
  +
   2005-10-15  Maciej Stachowiak  <mjs at apple.com>
   
   	Reverted fix for this bug, because it was part of a time range that caused a performance
  
  
  
  1.4       +9 -5      JavaScriptCore/kxmlcore/FastMalloc.cpp
  
  Index: FastMalloc.cpp
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kxmlcore/FastMalloc.cpp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- FastMalloc.cpp	3 Oct 2005 22:42:28 -0000	1.3
  +++ FastMalloc.cpp	18 Oct 2005 03:15:26 -0000	1.4
  @@ -1234,10 +1234,11 @@
     char* limit = ptr + (npages << kPageShift);
     const size_t size = ByteSizeForClass(size_class_);
     int num = 0;
  -  while (ptr + size <= limit) {
  +  char* nptr;
  +  while ((nptr = ptr + size) <= limit) {
       *tail = ptr;
       tail = reinterpret_cast<void**>(ptr);
  -    ptr += size;
  +    ptr = nptr;
       num++;
     }
     ASSERT(ptr <= limit);
  @@ -1393,17 +1394,20 @@
           // variable cache is the same as the thread-specific cache for the main thread.
           // And other threads can't get it wrong because they must have gone through 
           // this function before allocating so they've synchronized.
  +        // Also, mainThreadCache is only set when isMultiThreaded is false, 
  +        // to save a branchin some cases.
           SpinLockHolder lock(&multiThreadedLock);
           isMultiThreaded = true;
  +        mainThreadCache = 0;
       }
   }
   
  -inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetCache() {
  +ALWAYS_INLINE TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetCache() {
     void* ptr = NULL;
     if (!tsd_inited) {
       InitModule();
     } else {
  -      if (!isMultiThreaded)
  +      if (mainThreadCache)
             ptr = mainThreadCache;
         else
             ptr = pthread_getspecific(heap_key);
  @@ -1416,7 +1420,7 @@
   // because we may be in the thread destruction code and may have
   // already cleaned up the cache for this thread.
   inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetCacheIfPresent() {
  -  if (!isMultiThreaded)
  +  if (mainThreadCache)
         return mainThreadCache;
     if (!tsd_inited) return NULL;
     return reinterpret_cast<TCMalloc_ThreadCache*>
  
  
  
  1.248     +89 -0     WebCore/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/WebCore/ChangeLog,v
  retrieving revision 1.247
  retrieving revision 1.248
  diff -u -r1.247 -r1.248
  --- ChangeLog	18 Oct 2005 00:16:42 -0000	1.247
  +++ ChangeLog	18 Oct 2005 03:15:27 -0000	1.248
  @@ -1,5 +1,94 @@
   2005-10-17  Maciej Stachowiak  <mjs at apple.com>
   
  +        Reviewed by Geoff.
  +
  +        Speed up the tokenizer by keeping more state on the stack instead of in the object,
  +	to avoid load-store traffic. About a .5% speedup.
  +
  +        * khtml/html/htmltokenizer.cpp:
  +        (khtml::HTMLTokenizer::HTMLTokenizer):
  +        (khtml::HTMLTokenizer::reset):
  +        (khtml::HTMLTokenizer::begin):
  +        (khtml::HTMLTokenizer::setForceSynchronous):
  +        (khtml::HTMLTokenizer::processListing):
  +        (khtml::HTMLTokenizer::parseSpecial):
  +        (khtml::HTMLTokenizer::scriptHandler):
  +        (khtml::HTMLTokenizer::scriptExecution):
  +        (khtml::HTMLTokenizer::parseComment):
  +        (khtml::HTMLTokenizer::parseServer):
  +        (khtml::HTMLTokenizer::parseProcessingInstruction):
  +        (khtml::HTMLTokenizer::parseText):
  +        (khtml::HTMLTokenizer::parseEntity):
  +        (khtml::HTMLTokenizer::parseTag):
  +        (khtml::HTMLTokenizer::continueProcessing):
  +        (khtml::HTMLTokenizer::write):
  +        (khtml::HTMLTokenizer::allDataProcessed):
  +        (khtml::HTMLTokenizer::end):
  +        (khtml::HTMLTokenizer::finish):
  +        (khtml::HTMLTokenizer::notifyFinished):
  +        (khtml::HTMLTokenizer::isWaitingForScripts):
  +        * khtml/html/htmltokenizer.h:
  +        (khtml::HTMLTokenizer::):
  +        (khtml::HTMLTokenizer::State::State):
  +        (khtml::HTMLTokenizer::State::tagState):
  +        (khtml::HTMLTokenizer::State::setTagState):
  +        (khtml::HTMLTokenizer::State::entityState):
  +        (khtml::HTMLTokenizer::State::setEntityState):
  +        (khtml::HTMLTokenizer::State::inScript):
  +        (khtml::HTMLTokenizer::State::setInScript):
  +        (khtml::HTMLTokenizer::State::inStyle):
  +        (khtml::HTMLTokenizer::State::setInStyle):
  +        (khtml::HTMLTokenizer::State::inSelect):
  +        (khtml::HTMLTokenizer::State::setInSelect):
  +        (khtml::HTMLTokenizer::State::inXmp):
  +        (khtml::HTMLTokenizer::State::setInXmp):
  +        (khtml::HTMLTokenizer::State::inTitle):
  +        (khtml::HTMLTokenizer::State::setInTitle):
  +        (khtml::HTMLTokenizer::State::inPlainText):
  +        (khtml::HTMLTokenizer::State::setInPlainText):
  +        (khtml::HTMLTokenizer::State::inProcessingInstruction):
  +        (khtml::HTMLTokenizer::State::setInProcessingInstruction):
  +        (khtml::HTMLTokenizer::State::inComment):
  +        (khtml::HTMLTokenizer::State::setInComment):
  +        (khtml::HTMLTokenizer::State::inTextArea):
  +        (khtml::HTMLTokenizer::State::setInTextArea):
  +        (khtml::HTMLTokenizer::State::escaped):
  +        (khtml::HTMLTokenizer::State::setEscaped):
  +        (khtml::HTMLTokenizer::State::inServer):
  +        (khtml::HTMLTokenizer::State::setInServer):
  +        (khtml::HTMLTokenizer::State::skipLF):
  +        (khtml::HTMLTokenizer::State::setSkipLF):
  +        (khtml::HTMLTokenizer::State::startTag):
  +        (khtml::HTMLTokenizer::State::setStartTag):
  +        (khtml::HTMLTokenizer::State::discardLF):
  +        (khtml::HTMLTokenizer::State::setDiscardLF):
  +        (khtml::HTMLTokenizer::State::allowYield):
  +        (khtml::HTMLTokenizer::State::setAllowYield):
  +        (khtml::HTMLTokenizer::State::loadingExtScript):
  +        (khtml::HTMLTokenizer::State::setLoadingExtScript):
  +        (khtml::HTMLTokenizer::State::forceSynchronous):
  +        (khtml::HTMLTokenizer::State::setForceSynchronous):
  +        (khtml::HTMLTokenizer::State::inAnySpecial):
  +        (khtml::HTMLTokenizer::State::hasTagState):
  +        (khtml::HTMLTokenizer::State::hasEntityState):
  +        (khtml::HTMLTokenizer::State::):
  +        (khtml::HTMLTokenizer::State::setBit):
  +        (khtml::HTMLTokenizer::State::testBit):
  +        * khtml/rendering/bidi.cpp:
  +        (khtml::RenderBlock::checkLinesForTextOverflow):
  +        * khtml/rendering/render_block.cpp:
  +        (khtml::RenderBlock::updateFirstLetter):
  +        * khtml/rendering/render_flow.cpp:
  +        (RenderFlow::caretRect):
  +        * khtml/rendering/render_line.cpp:
  +        (khtml::EllipsisBox::paint):
  +        * khtml/rendering/render_object.cpp:
  +        (RenderObject::firstLineStyle):
  +        * khtml/rendering/render_object.h:
  +        (khtml::RenderObject::style):
  +
  +2005-10-17  Maciej Stachowiak  <mjs at apple.com>
  +
           - temporarily back out hyatt's recent changes since the tree was closed
   
           * khtml/rendering/render_container.cpp:
  
  
  
  1.119     +329 -315  WebCore/khtml/html/htmltokenizer.cpp
  
  Index: htmltokenizer.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/html/htmltokenizer.cpp,v
  retrieving revision 1.118
  retrieving revision 1.119
  diff -u -r1.118 -r1.119
  --- htmltokenizer.cpp	14 Oct 2005 20:57:54 -0000	1.118
  +++ htmltokenizer.cpp	18 Oct 2005 03:15:28 -0000	1.119
  @@ -172,7 +172,6 @@
       charsets = KGlobal::charsets();
       parser = new HTMLParser(_view, _doc, includesComments);
       m_executingScript = 0;
  -    loadingExtScript = false;
       onHold = false;
       timerId = 0;
       includesCommentsInDOM = includesComments;
  @@ -191,7 +190,6 @@
       charsets = KGlobal::charsets();
       parser = new HTMLParser(i, _doc, includesComments);
       m_executingScript = 0;
  -    loadingExtScript = false;
       onHold = false;
       timerId = 0;
       includesCommentsInDOM = includesComments;
  @@ -211,12 +209,12 @@
         cs->deref(this);
       }
       
  -    if ( buffer )
  +    if (buffer)
           KHTML_DELETE_QCHAR_VEC(buffer);
       buffer = dest = 0;
       size = 0;
   
  -    if ( scriptCode )
  +    if (scriptCode)
           KHTML_DELETE_QCHAR_VEC(scriptCode);
       scriptCode = 0;
       scriptCodeSize = scriptCodeMaxSize = scriptCodeResync = 0;
  @@ -226,8 +224,8 @@
           timerId = 0;
       }
       timerId = 0;
  -    allowYield = false;
  -    forceSynchronous = false;
  +    m_state.setAllowYield(false);
  +    m_state.setForceSynchronous(false);
   
       currToken.reset();
   }
  @@ -235,31 +233,15 @@
   void HTMLTokenizer::begin()
   {
       m_executingScript = 0;
  -    loadingExtScript = false;
  +    m_state.setLoadingExtScript(false);
       onHold = false;
       reset();
       size = 254;
       buffer = KHTML_ALLOC_QCHAR_VEC( 255 );
       dest = buffer;
  -    tag = NoTag;
  -    discard = NoneDiscard;
  -    plaintext = false;
  -    xmp = false;
  -    processingInstruction = false;
  -    script = false;
  -    escaped = false;
  -    style = false;
  -    skipLF = false;
  -    select = false;
  -    comment = false;
  -    server = false;
  -    textarea = false;
  -    title = false;
  -    startTag = false;
       tquote = NoQuote;
       searchCount = 0;
  -    Entity = NoEntity;
  -    loadingExtScript = false;
  +    m_state.setEntityState(NoEntity);
       scriptSrc = QString::null;
       pendingSrc.clear();
       currentPrependingSrc = 0;
  @@ -269,63 +251,66 @@
       lineno = 0;
       scriptStartLineno = 0;
       tagStartLineno = 0;
  -    forceSynchronous = false;
  +    m_state.setForceSynchronous(false);
   }
   
   void HTMLTokenizer::setForceSynchronous(bool force)
   {
  -    forceSynchronous = force;
  +    m_state.setForceSynchronous(force);
   }
   
  -void HTMLTokenizer::processListing(TokenizerString list)
  +HTMLTokenizer::State HTMLTokenizer::processListing(TokenizerString list, State state)
   {
       // This function adds the listing 'list' as
       // preformatted text-tokens to the token-collection
       while (!list.isEmpty()) {
           checkBuffer();
   
  -        if (skipLF && *list != '\n')
  -            skipLF = false;
  +        if (state.skipLF() && *list != '\n')
  +            state.setSkipLF(false);
   
  -        if (skipLF) {
  -            skipLF = false;
  +        if (state.skipLF()) {
  +            state.setSkipLF(false);
               ++list;
           } else if (*list == '\n' || *list == '\r') {
  -            if (discard == LFDiscard)
  +            if (state.discardLF())
                   // Ignore this LF
  -                discard = NoneDiscard; // We have discarded 1 LF
  +                state.setDiscardLF(false); // We have discarded 1 LF
               else
                   *dest++ = '\n';
   
               /* Check for MS-DOS CRLF sequence */
               if (*list == '\r')
  -                skipLF = true;
  +                state.setSkipLF(true);
   
               ++list;
           } else {
  -            discard = NoneDiscard;
  +            state.setDiscardLF(false);
               *dest++ = *list;
               ++list;
           }
       }
  +
  +    return state;
   }
   
  -void HTMLTokenizer::parseSpecial(TokenizerString &src)
  +HTMLTokenizer::State HTMLTokenizer::parseSpecial(TokenizerString &src, State state)
   {
  -    assert( textarea || title || !Entity );
  -    assert( !tag );
  -    assert( xmp+textarea+title+style+script == 1 );
  -    if (script)
  -        scriptStartLineno = lineno+src.lineCount();
  +    assert(state.inTextArea() || state.inTitle() || !state.hasEntityState());
  +    assert(!state.hasTagState());
  +    assert(state.inXmp() + state.inTextArea() + state.inTitle() + state.inStyle() + state.inScript() == 1 );
  +    if (state.inScript())
  +        scriptStartLineno = lineno + src.lineCount();
   
  -    if ( comment ) parseComment( src );
  +    if (state.inComment()) 
  +        state = parseComment(src, state);
   
       while ( !src.isEmpty() ) {
           checkScriptBuffer();
           unsigned char ch = src->latin1();
  -        if ( !scriptCodeResync && !brokenComments && !textarea && !xmp && !title && ch == '-' && scriptCodeSize >= 3 && !src.escaped() && scriptCode[scriptCodeSize-3] == '<' && scriptCode[scriptCodeSize-2] == '!' && scriptCode[scriptCodeSize-1] == '-' ) {
  -            comment = true;
  -            parseComment( src );
  +        if (!scriptCodeResync && !brokenComments && !state.inTextArea() && !state.inXmp() && !state.inTitle() && ch == '-' && scriptCodeSize >= 3 && !src.escaped() && scriptCode[scriptCodeSize-3] == '<' && scriptCode[scriptCodeSize-2] == '!' && scriptCode[scriptCodeSize-1] == '-') {
  +            state.setInComment(true);
  +            state = parseComment(src, state);
               continue;
           }
           if ( scriptCodeResync && !tquote && ( ch == '>' ) ) {
  @@ -333,31 +318,44 @@
               scriptCodeSize = scriptCodeResync-1;
               scriptCodeResync = 0;
               scriptCode[ scriptCodeSize ] = scriptCode[ scriptCodeSize + 1 ] = 0;
  -            if ( script )
  -                scriptHandler();
  +            if (state.inScript())
  +                state = scriptHandler(state);
               else {
  -                processListing(TokenizerString(scriptCode, scriptCodeSize));
  +                state = processListing(TokenizerString(scriptCode, scriptCodeSize), state);
                   processToken();
  -                if ( style )         { currToken.tagName = styleTag.localName(); currToken.beginTag = false; }
  -                else if ( textarea ) { currToken.tagName = textareaTag.localName(); currToken.beginTag = false; }
  -                else if ( title ) { currToken.tagName = titleTag.localName(); currToken.beginTag = false; }
  -                else if ( xmp )  { currToken.tagName = xmpTag.localName(); currToken.beginTag = false; }
  +                if (state.inStyle()) { 
  +                    currToken.tagName = styleTag.localName(); 
  +                    currToken.beginTag = false; 
  +                } else if (state.inTextArea()) { 
  +                    currToken.tagName = textareaTag.localName(); 
  +                    currToken.beginTag = false; 
  +                } else if (state.inTitle()) { 
  +                    currToken.tagName = titleTag.localName(); 
  +                    currToken.beginTag = false; 
  +                } else if (state.inXmp()) {
  +                    currToken.tagName = xmpTag.localName(); 
  +                    currToken.beginTag = false; 
  +                }
                   processToken();
  -                style = script = style = textarea = title = xmp = false;
  +                state.setInStyle(false);
  +                state.setInScript(false);
  +                state.setInTextArea(false);
  +                state.setInTitle(false);
  +                state.setInXmp(false);
                   tquote = NoQuote;
                   scriptCodeSize = scriptCodeResync = 0;
               }
  -            return;
  +            return state;
           }
           // possible end of tagname, lets check.
  -        if ( !scriptCodeResync && !escaped && !src.escaped() && ( ch == '>' || ch == '/' || ch <= ' ' ) && ch &&
  +        if ( !scriptCodeResync && !state.escaped() && !src.escaped() && ( ch == '>' || ch == '/' || ch <= ' ' ) && ch &&
                scriptCodeSize >= searchStopperLen &&
                tagMatch( searchStopper, scriptCode+scriptCodeSize-searchStopperLen, searchStopperLen )) {
               scriptCodeResync = scriptCodeSize-searchStopperLen+1;
               tquote = NoQuote;
               continue;
           }
  -        if ( scriptCodeResync && !escaped ) {
  +        if ( scriptCodeResync && !state.escaped() ) {
               if(ch == '\"')
                   tquote = (tquote == NoQuote) ? DoubleQuote : ((tquote == SingleQuote) ? SingleQuote : NoQuote);
               else if(ch == '\'')
  @@ -365,11 +363,11 @@
               else if (tquote != NoQuote && (ch == '\r' || ch == '\n'))
                   tquote = NoQuote;
           }
  -        escaped = ( !escaped && ch == '\\' );
  -        if (!scriptCodeResync && (textarea||title) && !src.escaped() && ch == '&') {
  +        state.setEscaped(!state.escaped() && ch == '\\');
  +        if (!scriptCodeResync && (state.inTextArea() || state.inTitle()) && !src.escaped() && ch == '&') {
               QChar *scriptCodeDest = scriptCode+scriptCodeSize;
               ++src;
  -            parseEntity(src,scriptCodeDest,true);
  +            state = parseEntity(src, scriptCodeDest, state, m_cBufferPos, true, false);
               scriptCodeSize = scriptCodeDest-scriptCode;
           }
           else {
  @@ -378,9 +376,11 @@
               ++src;
           }
       }
  +
  +    return state;
   }
   
  -void HTMLTokenizer::scriptHandler()
  +HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state)
   {
       // We are inside a <script>
       bool doScriptExec = false;
  @@ -412,7 +412,7 @@
           // Parse scriptCode containing <script> info
           doScriptExec = true;
       }
  -    processListing(TokenizerString(scriptCode, scriptCodeSize));
  +    state = processListing(TokenizerString(scriptCode, scriptCodeSize), state);
       QString exScript( buffer, dest-buffer );
       processToken();
       currToken.tagName = scriptTag.localName();
  @@ -434,10 +434,15 @@
   	    }
               setSrc(TokenizerString());
               scriptCodeSize = scriptCodeResync = 0;
  +
  +            // the ref() call below may call notifyFinished if the script is already in cache,
  +            // and that mucks with the state directly, so we must write it back to the object.
  +            m_state = state;
               cs->ref(this);
  +            state = m_state;
               // will be 0 if script was already loaded and ref() executed it
               if (!pendingScripts.isEmpty())
  -                loadingExtScript = true;
  +                state.setLoadingExtScript(true);
           }
           else if (view && doScriptExec && javascript ) {
               if (!m_executingScript)
  @@ -448,15 +453,15 @@
               scriptCodeSize = scriptCodeResync = 0;
               //QTime dt;
               //dt.start();
  -            scriptExecution( exScript, QString::null, scriptStartLineno );
  +            state = scriptExecution(exScript, state, QString::null, scriptStartLineno);
   	    //kdDebug( 6036 ) << "script execution time:" << dt.elapsed() << endl;
           }
       }
   
  -    script = false;
  +    state.setInScript(false);
       scriptCodeSize = scriptCodeResync = 0;
   
  -    if ( !m_executingScript && !loadingExtScript ) {
  +    if (!m_executingScript && !state.loadingExtScript()) {
   	// kdDebug( 6036 ) << "adding pending Output to parsed string" << endl;
   	src.append(pendingSrc);
   	pendingSrc.clear();
  @@ -468,30 +473,34 @@
   	// we need to do this slightly modified bit of one of the write() cases
   	// because we want to prepend to pendingSrc rather than appending
   	// if there's no previous prependingSrc
  -	if (loadingExtScript) {
  +	if (state.loadingExtScript()) {
   	    if (currentPrependingSrc) {
   		currentPrependingSrc->append(prependingSrc);
   	    } else {
   		pendingSrc.prepend(prependingSrc);
   	    }
   	} else {
  +            m_state = state;
   	    write(prependingSrc, false);
  +            state = m_state;
   	}
       }
   
       currentPrependingSrc = savedPrependingSrc;
  +
  +    return state;
   }
   
  -void HTMLTokenizer::scriptExecution( const QString& str, QString scriptURL,
  -                                     int baseLine)
  +HTMLTokenizer::State HTMLTokenizer::scriptExecution(const QString& str, State state, 
  +                                                    QString scriptURL, int baseLine)
   {
   #if APPLE_CHANGES
       if (!view || !view->part())
  -        return;
  +        return state;
   #endif
  -    bool oldscript = script;
  +    bool oldscript = state.inScript();
       m_executingScript++;
  -    script = false;
  +    state.setInScript(false);
       QString url;    
       if (scriptURL.isNull())
         url = view->part()->xmlDocImpl()->URL();
  @@ -507,9 +516,11 @@
           printf("beginning script execution at %d\n", parser->doc()->elapsedTime());
   #endif
   
  +    m_state = state;
       view->part()->executeScript(url,baseLine,0,str);
  +    state = m_state;
   
  -    allowYield = true;
  +    state.setAllowYield(true);
   
   #ifdef INSTRUMENT_LAYOUT_SCHEDULING
       if (!parser->doc()->ownerElement())
  @@ -517,9 +528,9 @@
   #endif
       
       m_executingScript--;
  -    script = oldscript;
  +    state.setInScript(oldscript);
   
  -    if ( !m_executingScript && !loadingExtScript ) {
  +    if (!m_executingScript && !state.loadingExtScript()) {
   	// kdDebug( 6036 ) << "adding pending Output to parsed string" << endl;
   	src.append(pendingSrc);
   	pendingSrc.clear();
  @@ -531,24 +542,28 @@
   	// we need to do this slightly modified bit of one of the write() cases
   	// because we want to prepend to pendingSrc rather than appending
   	// if there's no previous prependingSrc
  -	if (loadingExtScript) {
  +	if (state.loadingExtScript()) {
   	    if (currentPrependingSrc) {
   		currentPrependingSrc->append(prependingSrc);
   	    } else {
   		pendingSrc.prepend(prependingSrc);
   	    }
   	} else {
  +            m_state = state;
   	    write(prependingSrc, false);
  +            state = m_state;
   	}
       }
   
       currentPrependingSrc = savedPrependingSrc;
  +
  +    return state;
   }
   
  -void HTMLTokenizer::parseComment(TokenizerString &src)
  +HTMLTokenizer::State HTMLTokenizer::parseComment(TokenizerString &src, State state)
   {
       // FIXME: Why does this code even run for comments inside <script> and <style>? This seems bogus.
  -    bool strict = !parser->doc()->inCompatMode() && !script && !style;
  +    bool strict = !parser->doc()->inCompatMode() && !state.inScript() && !state.inStyle();
       int delimiterCount = 0;
       bool canClose = false;
       checkScriptBuffer(src.length());
  @@ -572,7 +587,7 @@
           }
   
           if ((!strict || canClose) && src->unicode() == '>') {
  -            bool handleBrokenComments = brokenComments && !(script || style);
  +            bool handleBrokenComments = brokenComments && !(state.inScript() || state.inStyle());
               int endCharsCount = 1; // start off with one for the '>' character
               if (!strict) {
                   // In quirks mode just check for -->
  @@ -588,14 +603,14 @@
               }
               if (canClose || handleBrokenComments || endCharsCount > 1) {
                   ++src;
  -                if (!( script || xmp || textarea || style)) {
  +                if (!(state.inScript() || state.inXmp() || state.inTextArea() || state.inStyle())) {
                       if (includesCommentsInDOM) {
                           checkScriptBuffer();
                           scriptCode[ scriptCodeSize ] = 0;
                           scriptCode[ scriptCodeSize + 1 ] = 0;
                           currToken.tagName = commentAtom;
                           currToken.beginTag = true;
  -                        processListing(TokenizerString(scriptCode, scriptCodeSize - endCharsCount));
  +                        state = processListing(TokenizerString(scriptCode, scriptCodeSize - endCharsCount), state);
                           processToken();
                           currToken.tagName = commentAtom;
                           currToken.beginTag = false;
  @@ -603,31 +618,34 @@
                       }
                       scriptCodeSize = 0;
                   }
  -                comment = false;
  -                return; // Finished parsing comment
  +                state.setInComment(false);
  +                return state; // Finished parsing comment
               }
           }
           ++src;
       }
  +
  +    return state;
   }
   
  -void HTMLTokenizer::parseServer(TokenizerString &src)
  +HTMLTokenizer::State HTMLTokenizer::parseServer(TokenizerString& src, State state)
   {
       checkScriptBuffer(src.length());
  -    while ( !src.isEmpty() ) {
  -        scriptCode[ scriptCodeSize++ ] = *src;
  +    while (!src.isEmpty()) {
  +        scriptCode[scriptCodeSize++] = *src;
           if (src->unicode() == '>' &&
               scriptCodeSize > 1 && scriptCode[scriptCodeSize-2] == '%') {
               ++src;
  -            server = false;
  +            state.setInServer(false);
               scriptCodeSize = 0;
  -            return; // Finished parsing server include
  +            return state; // Finished parsing server include
           }
           ++src;
       }
  +    return state;
   }
   
  -void HTMLTokenizer::parseProcessingInstruction(TokenizerString &src)
  +HTMLTokenizer::State HTMLTokenizer::parseProcessingInstruction(TokenizerString &src, State state)
   {
       char oldchar = 0;
       while ( !src.isEmpty() )
  @@ -645,19 +663,21 @@
           else if ( chbegin == '>' && ( !tquote || oldchar == '?' ) )
           {
               // We got a '?>' sequence
  -            processingInstruction = false;
  +            state.setInProcessingInstruction(false);
               ++src;
  -            discard = LFDiscard;
  -            return; // Finished parsing comment!
  +            state.setDiscardLF(true);
  +            return state; // Finished parsing comment!
           }
           ++src;
           oldchar = chbegin;
       }
  +    
  +    return state;
   }
   
  -void HTMLTokenizer::parseText(TokenizerString &src)
  +HTMLTokenizer::State HTMLTokenizer::parseText(TokenizerString &src, State state)
   {
  -    while ( !src.isEmpty() )
  +    while (!src.isEmpty())
       {
           // do we need to enlarge the buffer?
           checkBuffer();
  @@ -665,20 +685,17 @@
           // ascii is okay because we only do ascii comparisons
           unsigned char chbegin = src->latin1();
   
  -        if (skipLF && ( chbegin != '\n' ))
  -        {
  -            skipLF = false;
  -        }
  +        if (state.skipLF() && (chbegin != '\n' ))
  +            state.setSkipLF(false);
   
  -        if (skipLF)
  +        if (state.skipLF())
           {
  -            skipLF = false;
  +            state.setSkipLF(false);
               ++src;
  -        }
  -        else if (( chbegin == '\n' ) || ( chbegin == '\r' ))
  +        } else if ((chbegin == '\n') || (chbegin == '\r'))
           {
               if (chbegin == '\r')
  -                skipLF = true;
  +                state.setSkipLF(true);
   
               *dest++ = '\n';
               ++src;
  @@ -690,34 +707,36 @@
               ++src;
           }
       }
  +
  +    return state;
   }
   
   
  -void HTMLTokenizer::parseEntity(TokenizerString &src, QChar *&dest, bool start)
  +HTMLTokenizer::State HTMLTokenizer::parseEntity(TokenizerString &src, QChar *&dest, State state, unsigned &cBufferPos, bool start, bool parsingTag)
   {
  -    if( start )
  +    if (start)
       {
           cBufferPos = 0;
  -        Entity = SearchEntity;
  +        state.setEntityState(SearchEntity);
           EntityUnicodeValue = 0;
       }
   
  -    while( !src.isEmpty() )
  +    while(!src.isEmpty())
       {
           ushort cc = src->unicode();
  -        switch(Entity) {
  +        switch(state.entityState()) {
           case NoEntity:
  -            assert(Entity != NoEntity);
  -            return;
  +            assert(state.entityState() != NoEntity);
  +            return state;
           
           case SearchEntity:
               if(cc == '#') {
                   cBuffer[cBufferPos++] = cc;
                   ++src;
  -                Entity = NumericSearch;
  +                state.setEntityState(NumericSearch);
               }
               else
  -                Entity = EntityName;
  +                state.setEntityState(EntityName);
   
               break;
   
  @@ -725,12 +744,12 @@
               if(cc == 'x' || cc == 'X') {
                   cBuffer[cBufferPos++] = cc;
                   ++src;
  -                Entity = Hexadecimal;
  +                state.setEntityState(Hexadecimal);
               }
               else if(cc >= '0' && cc <= '9')
  -                Entity = Decimal;
  +                state.setEntityState(Decimal);
               else
  -                Entity = SearchSemicolon;
  +                state.setEntityState(SearchSemicolon);
   
               break;
   
  @@ -742,14 +761,15 @@
                   cc = csrc.cell();
   
                   if(csrc.row() || !((cc >= '0' && cc <= '9') || (cc >= 'a' && cc <= 'f'))) {
  -                    Entity = SearchSemicolon;
  +                    state.setEntityState(SearchSemicolon);
                       break;
                   }
                   EntityUnicodeValue = EntityUnicodeValue*16 + (cc - ( cc < 'a' ? '0' : 'a' - 10));
                   cBuffer[cBufferPos++] = cc;
                   ++src;
               }
  -            if(cBufferPos == 10)  Entity = SearchSemicolon;
  +            if (cBufferPos == 10)  
  +                state.setEntityState(SearchSemicolon);
               break;
           }
           case Decimal:
  @@ -759,7 +779,7 @@
                   cc = src->cell();
   
                   if(src->row() || !(cc >= '0' && cc <= '9')) {
  -                    Entity = SearchSemicolon;
  +                    state.setEntityState(SearchSemicolon);
                       break;
                   }
   
  @@ -767,7 +787,8 @@
                   cBuffer[cBufferPos++] = cc;
                   ++src;
               }
  -            if(cBufferPos == 9)  Entity = SearchSemicolon;
  +            if (cBufferPos == 9)  
  +                state.setEntityState(SearchSemicolon);
               break;
           }
           case EntityName:
  @@ -779,22 +800,23 @@
   
                   if(csrc.row() || !((cc >= 'a' && cc <= 'z') ||
                                      (cc >= '0' && cc <= '9') || (cc >= 'A' && cc <= 'Z'))) {
  -                    Entity = SearchSemicolon;
  +                    state.setEntityState(SearchSemicolon);
                       break;
                   }
   
                   cBuffer[cBufferPos++] = cc;
                   ++src;
               }
  -            if(cBufferPos == 9) Entity = SearchSemicolon;
  -            if(Entity == SearchSemicolon) {
  +            if (cBufferPos == 9) 
  +                state.setEntityState(SearchSemicolon);
  +            if (state.entityState() == SearchSemicolon) {
                   if(cBufferPos > 1) {
                       const entity *e = findEntity(cBuffer, cBufferPos);
                       if(e)
                           EntityUnicodeValue = e->code;
   
                       // be IE compatible
  -                    if(tag && EntityUnicodeValue > 255 && *src != ';')
  +                    if(parsingTag && EntityUnicodeValue > 255 && *src != ';')
                           EntityUnicodeValue = 0;
                   }
               }
  @@ -838,17 +860,21 @@
                   dest += cBufferPos;
               }
   
  -            Entity = NoEntity;
  -            return;
  +            state.setEntityState(NoEntity);
  +            return state;
           }
       }
  +
  +    return state;
   }
   
  -void HTMLTokenizer::parseTag(TokenizerString &src)
  +HTMLTokenizer::State HTMLTokenizer::parseTag(TokenizerString &src, State state)
   {
  -    assert(!Entity );
  +    assert(!state.hasEntityState());
   
  -    while ( !src.isEmpty() )
  +    unsigned cBufferPos = m_cBufferPos;
  +
  +    while (!src.isEmpty())
       {
           checkBuffer();
   #if defined(TOKEN_DEBUG) && TOKEN_DEBUG > 1
  @@ -858,10 +884,11 @@
           qDebug("src is now: *%s*, tquote: %d",
                  QConstString((QChar*)src.operator->(), l).qstring().latin1(), tquote);
   #endif
  -        switch(tag) {
  +        switch(state.tagState()) {
           case NoTag:
           {
  -            return;
  +            m_cBufferPos = cBufferPos;
  +            return state;
           }
           case TagName:
           {
  @@ -881,22 +908,23 @@
                           // Found '<!--' sequence
                           ++src;
                           dest = buffer; // ignore the previous part of this tag
  -                        comment = true;
  -                        tag = NoTag;
  +                        state.setInComment(true);
  +                        state.setTagState(NoTag);
   
                           // Fix bug 34302 at kde.bugs.org.  Go ahead and treat
                           // <!--> as a valid comment, since both mozilla and IE on windows
                           // can handle this case.  Only do this in quirks mode. -dwh
                           if (!src.isEmpty() && *src == '>' && parser->doc()->inCompatMode()) {
  -                          comment = false;
  +                          state.setInComment(false);
                             ++src;
                             if (!src.isEmpty())
                                 cBuffer[cBufferPos++] = src->cell();
                           }
   		        else
  -                          parseComment(src);
  +                          state = parseComment(src, state);
   
  -                        return; // Finished parsing tag!
  +                        m_cBufferPos = cBufferPos;
  +                        return state; // Finished parsing tag!
                       }
                       // cuts of high part, is okay
                       cBuffer[cBufferPos++] = src->cell();
  @@ -952,7 +980,7 @@
                       currToken.beginTag = beginTag;
                   }
                   dest = buffer;
  -                tag = SearchAttribute;
  +                state.setTagState(SearchAttribute);
                   cBufferPos = 0;
               }
               break;
  @@ -969,9 +997,9 @@
                   // In this mode just ignore any quotes we encounter and treat them like spaces.
                   if (curchar > ' ' && curchar != '\'' && curchar != '"') {
                       if (curchar == '<' || curchar == '>')
  -                        tag = SearchEnd;
  +                        state.setTagState(SearchEnd);
                       else
  -                        tag = AttributeName;
  +                        state.setTagState(AttributeName);
   
                       cBufferPos = 0;
                       break;
  @@ -996,7 +1024,7 @@
                       attrName = AtomicString(cBuffer);
                       dest = buffer;
                       *dest++ = 0;
  -                    tag = SearchEqual;
  +                    state.setTagState(SearchEqual);
                       // This is a deliberate quirk to match Mozilla and Opera.  We have to do this
                       // since sites that use the "standards-compliant" path sometimes send
                       // <script src="foo.js"/>.  Both Moz and Opera will honor this, despite it
  @@ -1019,7 +1047,7 @@
                   attrName = AtomicString(cBuffer);
                   dest = buffer;
                   *dest++ = 0;
  -                tag = SearchEqual;
  +                state.setTagState(SearchEqual);
               }
               break;
           }
  @@ -1038,13 +1066,13 @@
   #ifdef TOKEN_DEBUG
                           kdDebug(6036) << "found equal" << endl;
   #endif
  -                        tag = SearchValue;
  +                        state.setTagState(SearchValue);
                           ++src;
                       }
                       else {
                           currToken.addAttribute(parser->docPtr()->document(), attrName, emptyAtom);
                           dest = buffer;
  -                        tag = SearchAttribute;
  +                        state.setTagState(SearchAttribute);
                       }
                       break;
                   }
  @@ -1061,10 +1089,10 @@
                   if(curchar > ' ') {
                       if(( curchar == '\'' || curchar == '\"' )) {
                           tquote = curchar == '\"' ? DoubleQuote : SingleQuote;
  -                        tag = QuotedValue;
  +                        state.setTagState(QuotedValue);
                           ++src;
                       } else
  -                        tag = Value;
  +                        state.setTagState(Value);
   
                       break;
                   }
  @@ -1095,7 +1123,7 @@
                       AtomicString v(buffer+1, dest-buffer-1);
                       attrName = v; // Just make the name/value match. (FIXME: Is this some WinIE quirk?)
                       currToken.addAttribute(parser->docPtr()->document(), attrName, v);
  -                    tag = SearchAttribute;
  +                    state.setTagState(SearchAttribute);
                       dest = buffer;
                       tquote = NoQuote;
                       break;
  @@ -1106,7 +1134,7 @@
                       if ( curchar == '&' )
                       {
                           ++src;
  -                        parseEntity(src, dest, true);
  +                        state = parseEntity(src, dest, state, cBufferPos, true, true);
                           break;
                       }
                       else if ( (tquote == SingleQuote && curchar == '\'') ||
  @@ -1121,7 +1149,7 @@
                           currToken.addAttribute(parser->docPtr()->document(), attrName, v);
   
                           dest = buffer;
  -                        tag = SearchAttribute;
  +                        state.setTagState(SearchAttribute);
                           tquote = NoQuote;
                           ++src;
                           break;
  @@ -1148,7 +1176,7 @@
                       if ( curchar == '&' )
                       {
                           ++src;
  -                        parseEntity(src, dest, true);
  +                        state = parseEntity(src, dest, state, cBufferPos, true, true);
                           break;
                       }
                       // no quotes. Every space means end of value
  @@ -1158,7 +1186,7 @@
                           AtomicString v(buffer+1, dest-buffer-1);
                           currToken.addAttribute(parser->docPtr()->document(), attrName, v);
                           dest = buffer;
  -                        tag = SearchAttribute;
  +                        state.setTagState(SearchAttribute);
                           break;
                       }
                   }
  @@ -1187,14 +1215,16 @@
               if (src.isEmpty()) break;
   
               searchCount = 0; // Stop looking for '<!--' sequence
  -            tag = NoTag;
  +            state.setTagState(NoTag);
               tquote = NoQuote;
   
               if (*src != '<')
                   ++src;
   
  -            if (currToken.tagName == nullAtom) //stop if tag is unknown
  -                return;
  +            if (currToken.tagName == nullAtom) { //stop if tag is unknown
  +                m_cBufferPos = cBufferPos;
  +                return state;
  +            }
   
               AtomicString tagName = currToken.tagName;
   #if defined(TOKEN_DEBUG) && TOKEN_DEBUG > 0
  @@ -1281,54 +1311,87 @@
               processToken();
   
               if (tagName == preTag) {
  -                discard = LFDiscard; // Discard the first LF after we open a pre.
  +                state.setDiscardLF(true); // Discard the first LF after we open a pre.
               } else if (tagName == scriptTag) {
                   if (beginTag) {
                       searchStopper = scriptEnd;
                       searchStopperLen = 8;
  -                    script = true;
  -                    parseSpecial(src);
  +                    state.setInScript(true);
  +                    state = parseSpecial(src, state);
                   } else if (isSelfClosingScript) { // Handle <script src="foo"/>
  -                    script = true;
  -                    scriptHandler();
  +                    state.setInScript(true);
  +                    state = scriptHandler(state);
                   }
               } else if (tagName == styleTag) {
                   if (beginTag) {
                       searchStopper = styleEnd;
                       searchStopperLen = 7;
  -                    style = true;
  -                    parseSpecial(src);
  +                    state.setInStyle(true);
  +                    state = parseSpecial(src, state);
                   }
               } else if (tagName == textareaTag) {
                   if(beginTag) {
                       searchStopper = textareaEnd;
                       searchStopperLen = 10;
  -                    textarea = true;
  -                    parseSpecial(src);
  +                    state.setInTextArea(true);
  +                    state = parseSpecial(src, state);
                   }
               } else if (tagName == titleTag) {
                    if (beginTag) {
                       searchStopper = titleEnd;
                       searchStopperLen = 7;
  -                    title = true;
  -                    parseSpecial(src);
  +                    state.setInTitle(true);
  +                    state = parseSpecial(src, state);
                   }
               } else if (tagName == xmpTag) {
                   if (beginTag) {
                       searchStopper = xmpEnd;
                       searchStopperLen = 5;
  -                    xmp = true;
  -                    parseSpecial(src);
  +                    state.setInXmp(true);
  +                    state = parseSpecial(src, state);
                   }
               } else if (tagName == selectTag)
  -                select = beginTag;
  +                state.setInSelect(beginTag);
               else if (tagName == plaintextTag)
  -                plaintext = beginTag;
  -            return; // Finished parsing tag!
  +                state.setInPlainText(beginTag);
  +            m_cBufferPos = cBufferPos;
  +            return state; // Finished parsing tag!
           }
           } // end switch
       }
  -    return;
  +    m_cBufferPos = cBufferPos;
  +    return state;
  +}
  +
  +inline bool HTMLTokenizer::continueProcessing(int& processedCount, const QTime& startTime, const KWQUIEventTime& eventTime, State &state)
  +{
  +    // We don't want to be checking elapsed time with every character, so we only check after we've
  +    // processed a certain number of characters.
  +    bool allowedYield = state.allowYield();
  +    state.setAllowYield(false);
  +    if (!state.loadingExtScript() && !state.forceSynchronous() && !m_executingScript && (processedCount > TOKENIZER_CHUNK_SIZE || allowedYield)) {
  +        processedCount = 0;
  +        if (startTime.elapsed() > TOKENIZER_TIME_DELAY) {
  +            /* FIXME: We'd like to yield aggressively to give stylesheets the opportunity to
  +               load, but this hurts overall performance on slower machines.  For now turn this
  +               off.
  +            || (!parser->doc()->haveStylesheetsLoaded() && 
  +                (parser->doc()->documentElement()->id() != ID_HTML || parser->doc()->body()))) {*/
  +            // Schedule the timer to keep processing as soon as possible.
  +            if (!timerId)
  +                timerId = startTimer(0);
  +#ifdef INSTRUMENT_LAYOUT_SCHEDULING
  +            if (eventTime.uiEventPending())
  +                printf("Deferring processing of data because of UI event.\n");
  +            else if (startTime.elapsed() > TOKENIZER_TIME_DELAY)
  +                printf("Deferring processing of data because 200ms elapsed away from event loop.\n");
  +#endif
  +            return false;
  +        }
  +    }
  +    
  +    processedCount++;
  +    return true;
   }
   
   void HTMLTokenizer::write(const TokenizerString &str, bool appendData)
  @@ -1353,7 +1416,7 @@
           return;
       }
   
  -    if ( onHold ) {
  +    if (onHold) {
           src.append(str);
           return;
       }
  @@ -1375,17 +1438,17 @@
           printf("Beginning write at time %d\n", parser->doc()->elapsedTime());
   #endif
       
  -//     if (Entity)
  -//         parseEntity(src, dest);
  -
       int processedCount = 0;
       QTime startTime;
       startTime.start();
       KWQUIEventTime eventTime;
   
       KHTMLPart* part = parser->doc()->part();
  +
  +    State state = m_state;
  +
       while (!src.isEmpty() && (!part || !part->isScheduledLocationChangePending())) {
  -        if (!continueProcessing(processedCount, startTime, eventTime))
  +        if (!continueProcessing(processedCount, startTime, eventTime, state))
               break;
   
           // do we need to enlarge the buffer?
  @@ -1393,116 +1456,98 @@
   
           ushort cc = src->unicode();
   
  -        if (skipLF && (cc != '\n'))
  -            skipLF = false;
  +        bool wasSkipLF = state.skipLF();
  +        if (wasSkipLF)
  +            state.setSkipLF(false);
   
  -        if (skipLF) {
  -            skipLF = false;
  +        if (wasSkipLF && (cc == '\n'))
               ++src;
  -        }
  -        else if ( Entity )
  -            parseEntity( src, dest );
  -        else if ( plaintext )
  -            parseText( src );
  -        else if (script)
  -            parseSpecial(src);
  -        else if (style)
  -            parseSpecial(src);
  -        else if (xmp)
  -            parseSpecial(src);
  -        else if (textarea)
  -            parseSpecial(src);
  -        else if (title)
  -            parseSpecial(src);
  -        else if (comment)
  -            parseComment(src);
  -        else if (server)
  -            parseServer(src);
  -        else if (processingInstruction)
  -            parseProcessingInstruction(src);
  -        else if (tag)
  -            parseTag(src);
  -        else if ( startTag )
  -        {
  -            startTag = false;
  -
  -            switch(cc) {
  -            case '/':
  -                break;
  -            case '!':
  -            {
  -                // <!-- comment -->
  -                searchCount = 1; // Look for '<!--' sequence to start comment
  -
  -                break;
  -            }
  -            case '?':
  -            {
  -                // xml processing instruction
  -                processingInstruction = true;
  -                tquote = NoQuote;
  -                parseProcessingInstruction(src);
  -                continue;
  -
  -                break;
  -            }
  -            case '%':
  -                if (!brokenServer) {
  -                    // <% server stuff, handle as comment %>
  -                    server = true;
  +        else if (state.needsSpecialWriteHandling()) {
  +            // it's important to keep needsSpecialWriteHandling with the flags this block tests
  +            if (state.hasEntityState())
  +                state = parseEntity(src, dest, state, m_cBufferPos, false, state.hasTagState());
  +            else if (state.inPlainText())
  +                state = parseText(src, state);
  +            else if (state.inAnySpecial())
  +                state = parseSpecial(src, state);
  +            else if (state.inComment())
  +                state = parseComment(src, state);
  +            else if (state.inServer())
  +                state = parseServer(src, state);
  +            else if (state.inProcessingInstruction())
  +                state = parseProcessingInstruction(src, state);
  +            else if (state.hasTagState())
  +                state = parseTag(src, state);
  +            else if (state.startTag()) {
  +                state.setStartTag(false);
  +                
  +                switch(cc) {
  +                case '/':
  +                    break;
  +                case '!': {
  +                    // <!-- comment -->
  +                    searchCount = 1; // Look for '<!--' sequence to start comment
  +                    
  +                    break;
  +                }
  +                case '?': {
  +                    // xml processing instruction
  +                    state.setInProcessingInstruction(true);
                       tquote = NoQuote;
  -                    parseServer(src);
  +                    state = parseProcessingInstruction(src, state);
                       continue;
  +
  +                    break;
                   }
  -                // else fall through
  -            default:
  -            {
  -                if( ((cc >= 'a') && (cc <= 'z')) || ((cc >= 'A') && (cc <= 'Z')))
  -                {
  -                    // Start of a Start-Tag
  -                }
  -                else
  -                {
  -                    // Invalid tag
  -                    // Add as is
  -                    *dest = '<';
  -                    dest++;
  -                    continue;
  +                case '%':
  +                    if (!brokenServer) {
  +                        // <% server stuff, handle as comment %>
  +                        state.setInServer(true);
  +                        tquote = NoQuote;
  +                        state = parseServer(src, state);
  +                        continue;
  +                    }
  +                    // else fall through
  +                default: {
  +                    if( ((cc >= 'a') && (cc <= 'z')) || ((cc >= 'A') && (cc <= 'Z'))) {
  +                        // Start of a Start-Tag
  +                    } else {
  +                        // Invalid tag
  +                        // Add as is
  +                        *dest = '<';
  +                        dest++;
  +                        continue;
  +                    }
                   }
  -            }
  -            }; // end case
  +                }; // end case
   
  -            processToken();
  +                processToken();
   
  -            cBufferPos = 0;
  -            tag = TagName;
  -            parseTag(src);
  -        }
  -        else if ( cc == '&' && !src.escaped())
  -        {
  +                m_cBufferPos = 0;
  +                state.setTagState(TagName);
  +                state = parseTag(src, state);
  +            }
  +        } else if (cc == '&' && !src.escaped()) {
               ++src;
  -            parseEntity(src, dest, true);
  -        }
  -        else if ( cc == '<' && !src.escaped())
  -        {
  +            state = parseEntity(src, dest, state, m_cBufferPos, true, state.hasTagState());
  +        } else if (cc == '<' && !src.escaped()) {
               tagStartLineno = lineno+src.lineCount();
               ++src;
  -            startTag = true;
  -        }
  -        else if (cc == '\n' || cc == '\r') {
  -            if (discard == LFDiscard)
  +            state.setStartTag(true);
  +        } else if (cc == '\n' || cc == '\r') {
  +            if (state.discardLF())
                   // Ignore this LF
  -                discard = NoneDiscard; // We have discarded 1 LF
  +                state.setDiscardLF(false); // We have discarded 1 LF
               else
                   // Process this LF
                   *dest++ = '\n';
               
               /* Check for MS-DOS CRLF sequence */
               if (cc == '\r')
  -                skipLF = true;
  +                state.setSkipLF(true);
               ++src;
           } else {
  -            discard = NoneDiscard;
  +            state.setDiscardLF(false);
   #if QT_VERSION < 300
               unsigned char row = src->row();
               if ( row > 0x05 && row < 0x10 || row > 0xfd )
  @@ -1522,7 +1567,9 @@
       
       inWrite = wasInWrite;
   
  -    if (noMoreData && !inWrite && !loadingExtScript && !m_executingScript && !timerId)
  +    m_state = state;
  +
  +    if (noMoreData && !inWrite && !state.loadingExtScript() && !m_executingScript && !timerId)
           end(); // this actually causes us to be deleted
   }
   
  @@ -1539,37 +1586,6 @@
       return timerId != 0;
   }
   
  -bool HTMLTokenizer::continueProcessing(int& processedCount, const QTime& startTime, const KWQUIEventTime& eventTime)
  -{
  -    // We don't want to be checking elapsed time with every character, so we only check after we've
  -    // processed a certain number of characters.
  -    bool allowedYield = allowYield;
  -    allowYield = false;
  -    if (!loadingExtScript && !forceSynchronous && !m_executingScript && (processedCount > TOKENIZER_CHUNK_SIZE || allowedYield)) {
  -        processedCount = 0;
  -        if (startTime.elapsed() > TOKENIZER_TIME_DELAY) {
  -            /* FIXME: We'd like to yield aggressively to give stylesheets the opportunity to
  -               load, but this hurts overall performance on slower machines.  For now turn this
  -               off.
  -            || (!parser->doc()->haveStylesheetsLoaded() && 
  -                (parser->doc()->documentElement()->id() != ID_HTML || parser->doc()->body()))) {*/
  -            // Schedule the timer to keep processing as soon as possible.
  -            if (!timerId)
  -                timerId = startTimer(0);
  -#ifdef INSTRUMENT_LAYOUT_SCHEDULING
  -            if (eventTime.uiEventPending())
  -                printf("Deferring processing of data because of UI event.\n");
  -            else if (startTime.elapsed() > TOKENIZER_TIME_DELAY)
  -                printf("Deferring processing of data because 200ms elapsed away from event loop.\n");
  -#endif
  -            return false;
  -        }
  -    }
  -    
  -    processedCount++;
  -    return true;
  -}
  -
   void HTMLTokenizer::timerEvent(QTimerEvent* e)
   {
       if (e->timerId() == timerId) {
  @@ -1602,7 +1618,7 @@
   
   void HTMLTokenizer::allDataProcessed()
   {
  -    if (noMoreData && !inWrite && !loadingExtScript && !m_executingScript && !onHold && !timerId) {
  +    if (noMoreData && !inWrite && !m_state.loadingExtScript() && !m_executingScript && !onHold && !timerId) {
           QGuardedPtr<KHTMLView> savedView = view;
           end();
           if (savedView) {
  @@ -1630,7 +1646,7 @@
       }
   
       // parseTag is using the buffer for different matters
  -    if ( !tag )
  +    if (!m_state.hasTagState())
           processToken();
   
       if(buffer)
  @@ -1649,40 +1665,38 @@
   void HTMLTokenizer::finish()
   {
       // do this as long as we don't find matching comment ends
  -    while((comment || server) && scriptCode && scriptCodeSize)
  -    {
  +    while((m_state.inComment() || m_state.inServer()) && scriptCode && scriptCodeSize) {
           // we've found an unmatched comment start
  -        if (comment)
  +        if (m_state.inComment())
               brokenComments = true;
           else
               brokenServer = true;
           checkScriptBuffer();
  -        scriptCode[ scriptCodeSize ] = 0;
  -        scriptCode[ scriptCodeSize + 1 ] = 0;
  +        scriptCode[scriptCodeSize] = 0;
  +        scriptCode[scriptCodeSize + 1] = 0;
           int pos;
           QString food;
  -        if (script || style) {
  +        if (m_state.inScript() || m_state.inStyle())
               food.setUnicode(scriptCode, scriptCodeSize);
  -        }
  -        else if (server) {
  +        else if (m_state.inServer()) {
               food = "<";
               food += QString(scriptCode, scriptCodeSize);
  -        }
  -        else {
  +        } else {
               pos = QConstString(scriptCode, scriptCodeSize).string().find('>');
               food.setUnicode(scriptCode+pos+1, scriptCodeSize-pos-1); // deep copy
           }
           KHTML_DELETE_QCHAR_VEC(scriptCode);
           scriptCode = 0;
           scriptCodeSize = scriptCodeMaxSize = scriptCodeResync = 0;
  -        comment = server = false;
  -        if ( !food.isEmpty() )
  +        m_state.setInComment(false);
  +        m_state.setInServer(false);
  +        if (!food.isEmpty())
               write(food, true);
       }
       // this indicates we will not receive any more data... but if we are waiting on
       // an external script to load, we can't finish parsing until that is done
       noMoreData = true;
  -    if (!inWrite && !loadingExtScript && !m_executingScript && !onHold && !timerId)
  +    if (!inWrite && !m_state.loadingExtScript() && !m_executingScript && !onHold && !timerId)
           end(); // this actually causes us to be deleted
   }
   
  @@ -1804,23 +1818,23 @@
               printf("external script beginning execution at %d\n", parser->doc()->elapsedTime());
   #endif
   
  -	scriptExecution( scriptSource.qstring(), cachedScriptUrl );
  +	m_state = scriptExecution(scriptSource.qstring(), m_state, cachedScriptUrl);
   
           // The state of pendingScripts.isEmpty() can change inside the scriptExecution()
           // call above, so test afterwards.
           finished = pendingScripts.isEmpty();
           if (finished) {
  -            loadingExtScript = false;
  +            m_state.setLoadingExtScript(false);
   #ifdef INSTRUMENT_LAYOUT_SCHEDULING
               if (!parser->doc()->ownerElement())
                   printf("external script finished execution at %d\n", parser->doc()->elapsedTime());
   #endif
           }
   
  -        // 'script' is true when we are called synchronously from
  +        // 'inScript' is true when we are called synchronously from
           // parseScript(). In that case parseScript() will take care
           // of 'scriptOutput'.
  -        if ( !script ) {
  +        if (!m_state.inScript()) {
               TokenizerString rest = pendingSrc;
               pendingSrc.clear();
               write(rest, false);
  @@ -1832,7 +1846,7 @@
   
   bool HTMLTokenizer::isWaitingForScripts() const
   {
  -    return loadingExtScript;
  +    return m_state.loadingExtScript();
   }
   
   void HTMLTokenizer::setSrc(const TokenizerString &source)
  
  
  
  1.42      +120 -84   WebCore/khtml/html/htmltokenizer.h
  
  Index: htmltokenizer.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/html/htmltokenizer.h,v
  retrieving revision 1.41
  retrieving revision 1.42
  diff -u -r1.41 -r1.42
  --- htmltokenizer.h	13 Oct 2005 19:11:23 -0000	1.41
  +++ htmltokenizer.h	18 Oct 2005 03:15:29 -0000	1.42
  @@ -128,24 +128,25 @@
       virtual bool processingData() const;
   
   protected:
  +    class State;
  +
  +    // Where we are in parsing a tag
       void begin();
       void end();
   
       void reset();
       void processToken();
  -    void processListing(TokenizerString list);
   
  -    void parseComment(TokenizerString &str);
  -    void parseServer(TokenizerString &str);
  -    void parseText(TokenizerString &str);
  -    void parseListing(TokenizerString &str);
  -    void parseSpecial(TokenizerString &str);
  -    void parseTag(TokenizerString &str);
  -    void parseEntity(TokenizerString &str, QChar *&dest, bool start = false);
  -    void parseProcessingInstruction(TokenizerString &str);
  -    void scriptHandler();
  -    void scriptExecution(const QString& script, QString scriptURL = QString(),
  -                         int baseLine = 0);
  +    State processListing(TokenizerString, State);
  +    State parseComment(TokenizerString&, State);
  +    State parseServer(TokenizerString&, State);
  +    State parseText(TokenizerString&, State);
  +    State parseSpecial(TokenizerString&, State);
  +    State parseTag(TokenizerString&, State);
  +    State parseEntity(TokenizerString &, QChar*& dest, State, unsigned& _cBufferPos, bool start, bool parsingTag);
  +    State parseProcessingInstruction(TokenizerString&, State);
  +    State scriptHandler(State);
  +    State scriptExecution(const QString& script, State state, QString scriptURL = QString(), int baseLine = 0);
       void setSrc(const TokenizerString &source);
   
       // check if we have enough space in the buffer.
  @@ -164,7 +165,7 @@
       void enlargeBuffer(int len);
       void enlargeScriptBuffer(int len);
   
  -    bool continueProcessing(int& processedCount, const QTime& startTime, const KWQUIEventTime& eventTime);
  +    bool continueProcessing(int& processedCount, const QTime& startTime, const KWQUIEventTime& eventTime, State &state);
       void timerEvent(QTimerEvent*);
       void allDataProcessed();
   
  @@ -192,77 +193,117 @@
           DoubleQuote
       } tquote;
   
  -    // Discard line breaks immediately after <pre> tags
  -    enum
  -    {
  -        NoneDiscard = 0,
  -        LFDiscard
  -    } discard;
  -
  -    // Discard the LF part of CRLF sequence
  -    bool skipLF;
  -
  -    // Flag to say that we have the '<' but not the character following it.
  -    bool startTag;
  -
  -    // Flag to say, we are just parsing a tag, meaning, we are in the middle
  -    // of <tag...
  -    enum {
  -        NoTag = 0,
  -        TagName,
  -        SearchAttribute,
  -        AttributeName,
  -        SearchEqual,
  -        SearchValue,
  -        QuotedValue,
  -        Value,
  -        SearchEnd
  -    } tag;
  -
       // Are we in a &... character entity description?
  -    enum {
  +    enum EntityState {
           NoEntity = 0,
  -        SearchEntity,
  -        NumericSearch,
  -        Hexadecimal,
  -        Decimal,
  -        EntityName,
  -        SearchSemicolon
  -    } Entity;
  +        SearchEntity = 1,
  +        NumericSearch = 2,
  +        Hexadecimal = 3,
  +        Decimal = 4,
  +        EntityName = 5,
  +        SearchSemicolon = 6
  +    };
       unsigned EntityUnicodeValue;
   
  -    // are we in a <script> ... </script block
  -    bool script;
  -
  -    // Are we in a <style> ... </style> block
  -    bool style;
  -
  -    // Are we in a <select> ... </select> block
  -    bool select;
  -
  -    // Are we in a <xmp> ... </xmp> block
  -    bool xmp;
  -
  -    // Are we in a <title> ... </title> block
  -    bool title;
  -
  -    // Are we in plain textmode ?
  -    bool plaintext;
  -
  -    // XML processing instructions. Ignored at the moment
  -    bool processingInstruction;
  -
  -    // Area we in a <!-- comment --> block
  -    bool comment;
  -
  -    // Are we in a <textarea> ... </textarea> block
  -    bool textarea;
  +    enum TagState {
  +        NoTag = 0,
  +        TagName = 1,
  +        SearchAttribute = 2,
  +        AttributeName = 3,
  +        SearchEqual = 4,
  +        SearchValue = 5,
  +        QuotedValue = 6,
  +        Value = 7,
  +        SearchEnd = 8
  +    };
  +
  +    class State {
  +    public:
  +        State() : m_bits(0) {}
  +
  +        TagState tagState() const { return static_cast<TagState>(m_bits & TagMask); }
  +        void setTagState(TagState t) { m_bits = (m_bits & ~TagMask) | t; }
  +        EntityState entityState() const { return static_cast<EntityState>((m_bits & EntityMask) >> EntityShift); }
  +        void setEntityState(EntityState e) { m_bits = (m_bits & ~EntityMask) | (e << EntityShift); }
  +
  +        bool inScript() const { return testBit(InScript); }
  +        void setInScript(bool v) { setBit(InScript, v); }
  +        bool inStyle() const { return testBit(InStyle); }
  +        void setInStyle(bool v) { setBit(InStyle, v); }
  +        bool inSelect() const { return testBit(InSelect); }
  +        void setInSelect(bool v) { setBit(InSelect, v); }
  +        bool inXmp() const { return testBit(InXmp); }
  +        void setInXmp(bool v) { setBit(InXmp, v); }
  +        bool inTitle() const { return testBit(InTitle); }
  +        void setInTitle(bool v) { setBit(InTitle, v); }
  +        bool inPlainText() const { return testBit(InPlainText); }
  +        void setInPlainText(bool v) { setBit(InPlainText, v); }
  +        bool inProcessingInstruction() const { return testBit(InProcessingInstruction); }
  +        void setInProcessingInstruction(bool v) { return setBit(InProcessingInstruction, v); }
  +        bool inComment() const { return testBit(InComment); }
  +        void setInComment(bool v) { setBit(InComment, v); }
  +        bool inTextArea() const { return testBit(InTextArea); }
  +        void setInTextArea(bool v) { setBit(InTextArea, v); }
  +        bool escaped() const { return testBit(Escaped); }
  +        void setEscaped(bool v) { setBit(Escaped, v); }
  +        bool inServer() const { return testBit(InServer); }
  +        void setInServer(bool v) { setBit(InServer, v); }
  +        bool skipLF() const { return testBit(SkipLF); }
  +        void setSkipLF(bool v) { setBit(SkipLF, v); }
  +        bool startTag() const { return testBit(StartTag); }
  +        void setStartTag(bool v) { setBit(StartTag, v); }
  +        bool discardLF() const { return testBit(DiscardLF); }
  +        void setDiscardLF(bool v) { setBit(DiscardLF, v); }
  +        bool allowYield() const { return testBit(AllowYield); }
  +        void setAllowYield(bool v) { setBit(AllowYield, v); }
  +        bool loadingExtScript() const { return testBit(LoadingExtScript); }
  +        void setLoadingExtScript(bool v) { setBit(LoadingExtScript, v); }
  +        bool forceSynchronous() const { return testBit(ForceSynchronous); }
  +        void setForceSynchronous(bool v) { setBit(ForceSynchronous, v); }
  +
  +        bool inAnySpecial() const { return m_bits & (InScript | InStyle | InXmp | InTextArea | InTitle); }
  +        bool hasTagState() const { return m_bits & TagMask; }
  +        bool hasEntityState() const { return m_bits & EntityMask; }
  +
  +        bool needsSpecialWriteHandling() const { return m_bits & (InScript | InStyle | InXmp | InTextArea | InTitle | TagMask | EntityMask | InPlainText | InComment | InServer | InProcessingInstruction | StartTag); }
  +
  +    private:
  +        static const int EntityShift = 4;
  +        enum StateBits {
  +            TagMask = (1 << 4) - 1,
  +            EntityMask = (1 << 7) - (1 << 4),
  +            InScript = 1 << 7,
  +            InStyle = 1 << 8,
  +            InSelect = 1 << 9,
  +            InXmp = 1 << 10,
  +            InTitle = 1 << 11,
  +            InPlainText = 1 << 12,
  +            InProcessingInstruction = 1 << 13,
  +            InComment = 1 << 14,
  +            InTextArea = 1 << 15,
  +            Escaped = 1 << 16,
  +            InServer = 1 << 17,
  +            SkipLF = 1 << 18,
  +            StartTag = 1 << 19,
  +            DiscardLF = 1 << 20, // FIXME: should clarify difference between skip and discard
  +            AllowYield = 1 << 21,
  +            LoadingExtScript = 1 << 22,
  +            ForceSynchronous = 1 << 23,
  +        };
  +    
  +        void setBit(StateBits bit, bool value) 
  +        { 
  +            if (value) 
  +                m_bits |= bit; 
  +            else 
  +                m_bits &= ~bit;
  +        }
  +        bool testBit(StateBits bit) const { return m_bits & bit; }
   
  -    // was the previous character escaped ?
  -    bool escaped;
  +        unsigned m_bits;
  +    };
   
  -    // are we in a server includes statement?
  -    bool server;
  +    State m_state;
   
       bool brokenServer;
   
  @@ -288,9 +329,6 @@
       const char* searchStopper;
       // the stopper len
       int searchStopperLen;
  -    // true if we are waiting for an external script (<SCRIPT SRC=...) to load, i.e.
  -    // we don't do any parsing while this is true
  -    bool loadingExtScript;
       // if no more data is coming, just parse what we have (including ext scripts that
       // may be still downloading) and finish
       bool noMoreData;
  @@ -323,8 +361,6 @@
   
       // The timer for continued processing.
       int timerId;
  -    bool allowYield;
  -    bool forceSynchronous;  // disables yielding
   
       bool includesCommentsInDOM;
   
  @@ -333,7 +369,7 @@
   // we'll just make it large enough to handle all imaginable cases.
   #define CBUFLEN 1024
       char cBuffer[CBUFLEN+2];
  -    unsigned int cBufferPos;
  +    unsigned int m_cBufferPos;
   
       TokenizerString src;
   
  
  
  
  1.150     +1 -1      WebCore/khtml/rendering/bidi.cpp
  
  Index: bidi.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/bidi.cpp,v
  retrieving revision 1.149
  retrieving revision 1.150
  diff -u -r1.149 -r1.150
  --- bidi.cpp	13 Oct 2005 22:07:51 -0000	1.149
  +++ bidi.cpp	18 Oct 2005 03:15:30 -0000	1.150
  @@ -2523,7 +2523,7 @@
       // Determine the width of the ellipsis using the current font.
       QChar ellipsis = 0x2026; // FIXME: CSS3 says this is configurable, also need to use 0x002E (FULL STOP) if 0x2026 not renderable
       static AtomicString ellipsisStr(ellipsis);
  -    const Font& firstLineFont = style(true)->htmlFont();
  +    const Font& firstLineFont = firstLineStyle()->htmlFont();
       const Font& font = style()->htmlFont();
       int firstLineEllipsisWidth = firstLineFont.width(&ellipsis, 1, 0, 0);
       int ellipsisWidth = (font == firstLineFont) ? firstLineEllipsisWidth : font.width(&ellipsis, 1, 0, 0);
  
  
  
  1.210     +2 -2      WebCore/khtml/rendering/render_block.cpp
  
  Index: render_block.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_block.cpp,v
  retrieving revision 1.209
  retrieving revision 1.210
  diff -u -r1.209 -r1.210
  --- render_block.cpp	6 Oct 2005 22:45:46 -0000	1.209
  +++ render_block.cpp	18 Oct 2005 03:15:30 -0000	1.210
  @@ -3316,7 +3316,7 @@
       // to update it.
       if (currChild->style()->styleType() == RenderStyle::FIRST_LETTER) {
           RenderStyle* pseudo = firstLetterBlock->getPseudoStyle(RenderStyle::FIRST_LETTER,
  -                                                                    firstLetterContainer->style(true));
  +                                                               firstLetterContainer->firstLineStyle());
           currChild->setStyle(pseudo);
           for (RenderObject* genChild = currChild->firstChild(); genChild; genChild = genChild->nextSibling()) {
               if (genChild->isText()) 
  @@ -3333,7 +3333,7 @@
           
           // Create our pseudo style now that we have our firstLetterContainer determined.
           RenderStyle* pseudoStyle = firstLetterBlock->getPseudoStyle(RenderStyle::FIRST_LETTER,
  -                                                                    firstLetterContainer->style(true));
  +                                                                    firstLetterContainer->firstLineStyle());
           
           // Force inline display (except for floating first-letters)
           pseudoStyle->setDisplay( pseudoStyle->isFloating() ? BLOCK : INLINE);
  
  
  
  1.171     +1 -1      WebCore/khtml/rendering/render_flow.cpp
  
  Index: render_flow.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_flow.cpp,v
  retrieving revision 1.170
  retrieving revision 1.171
  diff -u -r1.170 -r1.171
  --- render_flow.cpp	18 Oct 2005 00:16:45 -0000	1.170
  +++ render_flow.cpp	18 Oct 2005 03:15:30 -0000	1.171
  @@ -600,7 +600,7 @@
       // constructed properly and this kludge is not called any more. So only
       // the caret size of an empty :first-line'd block is wrong, but I think we
       // can live with that.
  -    RenderStyle *currentStyle = style(true);
  +    RenderStyle *currentStyle = firstLineStyle();
       //height = currentStyle->fontMetrics().height();
       height = lineHeight(true);
       width = 1;
  
  
  
  1.55      +1 -1      WebCore/khtml/rendering/render_line.cpp
  
  Index: render_line.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_line.cpp,v
  retrieving revision 1.54
  retrieving revision 1.55
  diff -u -r1.54 -r1.55
  --- render_line.cpp	6 Oct 2005 00:53:57 -0000	1.54
  +++ render_line.cpp	18 Oct 2005 03:15:31 -0000	1.55
  @@ -1067,7 +1067,7 @@
   void EllipsisBox::paint(RenderObject::PaintInfo& i, int _tx, int _ty)
   {
       QPainter* p = i.p;
  -    RenderStyle* _style = m_firstLine ? m_object->style(true) : m_object->style();
  +    RenderStyle* _style = m_firstLine ? m_object->firstLineStyle() : m_object->style();
       if (_style->font() != p->font())
           p->setFont(_style->font());
   
  
  
  
  1.220     +15 -17    WebCore/khtml/rendering/render_object.cpp
  
  Index: render_object.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_object.cpp,v
  retrieving revision 1.219
  retrieving revision 1.220
  diff -u -r1.219 -r1.220
  --- render_object.cpp	6 Oct 2005 00:53:58 -0000	1.219
  +++ render_object.cpp	18 Oct 2005 03:15:31 -0000	1.220
  @@ -2295,23 +2295,21 @@
   {
   }
   
  -RenderStyle* RenderObject::style(bool firstLine) const {
  -    RenderStyle *s = m_style;
  -    if (firstLine) {
  -        const RenderObject* obj = isText() ? parent() : this;
  -        if (obj->isBlockFlow()) {
  -            RenderBlock* firstLineBlock = obj->firstLineBlock();
  -            if (firstLineBlock)
  -                s = firstLineBlock->getPseudoStyle(RenderStyle::FIRST_LINE, style());
  -        }
  -        else if (!obj->isAnonymous() && obj->isInlineFlow()) {
  -            RenderStyle* parentStyle = obj->parent()->style(true);
  -            if (parentStyle != obj->parent()->style()) {
  -                // A first-line style is in effect. We need to cache a first-line style
  -                // for ourselves.
  -                style()->setHasPseudoStyle(RenderStyle::FIRST_LINE_INHERITED);
  -                s = obj->getPseudoStyle(RenderStyle::FIRST_LINE_INHERITED, parentStyle);
  -            }
  +RenderStyle* RenderObject::firstLineStyle() const 
  +{
  +    RenderStyle *s = m_style; 
  +    const RenderObject* obj = isText() ? parent() : this;
  +    if (obj->isBlockFlow()) {
  +        RenderBlock* firstLineBlock = obj->firstLineBlock();
  +        if (firstLineBlock)
  +            s = firstLineBlock->getPseudoStyle(RenderStyle::FIRST_LINE, style());
  +    } else if (!obj->isAnonymous() && obj->isInlineFlow()) {
  +        RenderStyle* parentStyle = obj->parent()->firstLineStyle();
  +        if (parentStyle != obj->parent()->style()) {
  +            // A first-line style is in effect. We need to cache a first-line style
  +            // for ourselves.
  +            style()->setHasPseudoStyle(RenderStyle::FIRST_LINE_INHERITED);
  +            s = obj->getPseudoStyle(RenderStyle::FIRST_LINE_INHERITED, parentStyle);
           }
       }
       return s;
  
  
  
  1.161     +3 -1      WebCore/khtml/rendering/render_object.h
  
  Index: render_object.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_object.h,v
  retrieving revision 1.160
  retrieving revision 1.161
  diff -u -r1.160 -r1.161
  --- render_object.h	6 Oct 2005 00:53:58 -0000	1.160
  +++ render_object.h	18 Oct 2005 03:15:31 -0000	1.161
  @@ -676,7 +676,9 @@
       virtual int maxWidth() const { return 0; }
   
       RenderStyle* style() const { return m_style; }
  -    RenderStyle* style( bool firstLine ) const;
  +    RenderStyle* firstLineStyle() const;
  +    RenderStyle* style(bool firstLine) const { return firstLine ? firstLineStyle() : style(); }
  +
   
       void getTextDecorationColors(int decorations, QColor& underline, QColor& overline,
                                    QColor& linethrough, bool quirksMode=false);
  
  
  



More information about the webkit-changes mailing list