[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

rjw rjw at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 07:16:46 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 9409ba5b45a31fc0c73c14a2c572e86f7017078a
Author: rjw <rjw at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Dec 20 20:41:42 2002 +0000

    WebCore:
            Fixed 3133261.  This fix really has two parts.  This first part
            fixes the stupid stack allocated buffer that caused the crash.
            The second part makes any RenderText with a large string perform
            much faster.  The page mentioned in the bug used to load and draw
            in about 15 minutes.  Now it loads in about 10 seconds and draws in about
            2 seconds.  The performance optimization caches a widths array
            for the string in the RenderText, and only updates that array if
            the font or text for the RenderText change.
    
            Reviewed by john.
    
            * khtml/rendering/render_text.cpp:
            (RenderText::RenderText):
            (RenderText::setStyle):
            (RenderText::~RenderText):
            (RenderText::computeWidths):
            (RenderText::widthFromBuffer):
            (RenderText::trimmedMinMaxWidth):
            (RenderText::calcMinMaxWidth):
            (RenderText::setText):
            (RenderText::width):
            * khtml/rendering/render_text.h:
    
    WebKit:
            Fixed 3133261.  This fix really has two parts.  This first part
            is here in WebTextRenderer.  The second part adds some width
            caching to RenderText.  I was using a stack allocated array,
            this would blow out the stack for large strings.
    
            Reviewed by john.
    
            * WebCoreSupport.subproj/WebTextRenderer.m:
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@3152 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2003-10-25 b/WebCore/ChangeLog-2003-10-25
index bf3b6a7..4a04207 100644
--- a/WebCore/ChangeLog-2003-10-25
+++ b/WebCore/ChangeLog-2003-10-25
@@ -1,3 +1,28 @@
+2002-12-20  Richard Williamson   <rjw at apple.com>
+
+        Fixed 3133261.  This fix really has two parts.  This first part
+        fixes the stupid stack allocated buffer that caused the crash.
+        The second part makes any RenderText with a large string perform
+        much faster.  The page mentioned in the bug used to load and draw
+        in about 15 minutes.  Now it loads in about 10 seconds and draws in about
+        2 seconds.  The performance optimization caches a widths array
+        for the string in the RenderText, and only updates that array if
+        the font or text for the RenderText change.  
+        
+        Reviewed by john.
+
+        * khtml/rendering/render_text.cpp:
+        (RenderText::RenderText):
+        (RenderText::setStyle):
+        (RenderText::~RenderText):
+        (RenderText::computeWidths):
+        (RenderText::widthFromBuffer):
+        (RenderText::trimmedMinMaxWidth):
+        (RenderText::calcMinMaxWidth):
+        (RenderText::setText):
+        (RenderText::width):
+        * khtml/rendering/render_text.h:
+
 2002-12-20  Trey Matteson  <trey at apple.com>
 
 	We now build with symbols the B&I.  Deployment builds are without symbols,
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index bf3b6a7..4a04207 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,28 @@
+2002-12-20  Richard Williamson   <rjw at apple.com>
+
+        Fixed 3133261.  This fix really has two parts.  This first part
+        fixes the stupid stack allocated buffer that caused the crash.
+        The second part makes any RenderText with a large string perform
+        much faster.  The page mentioned in the bug used to load and draw
+        in about 15 minutes.  Now it loads in about 10 seconds and draws in about
+        2 seconds.  The performance optimization caches a widths array
+        for the string in the RenderText, and only updates that array if
+        the font or text for the RenderText change.  
+        
+        Reviewed by john.
+
+        * khtml/rendering/render_text.cpp:
+        (RenderText::RenderText):
+        (RenderText::setStyle):
+        (RenderText::~RenderText):
+        (RenderText::computeWidths):
+        (RenderText::widthFromBuffer):
+        (RenderText::trimmedMinMaxWidth):
+        (RenderText::calcMinMaxWidth):
+        (RenderText::setText):
+        (RenderText::width):
+        * khtml/rendering/render_text.h:
+
 2002-12-20  Trey Matteson  <trey at apple.com>
 
 	We now build with symbols the B&I.  Deployment builds are without symbols,
diff --git a/WebCore/khtml/rendering/render_text.cpp b/WebCore/khtml/rendering/render_text.cpp
index 500ad22..883d538 100644
--- a/WebCore/khtml/rendering/render_text.cpp
+++ b/WebCore/khtml/rendering/render_text.cpp
@@ -326,6 +326,9 @@ RenderText::RenderText(DOM::NodeImpl* node, DOMStringImpl *_str)
 
     m_minWidth = -1;
     m_maxWidth = -1;
+#if APPLE_CHANGES
+    m_widths = 0;
+#endif
     str = _str;
     if(str) str->ref();
     KHTMLAssert(!str || !str->l || str->s);
@@ -351,12 +354,21 @@ void RenderText::setStyle(RenderStyle *_style)
 
         if (changedText && element() && element()->string())
             setText(element()->string(), changedText);
+#if APPLE_CHANGES
+        // set also call computeWidths(), so no need to recache if that has already been done.
+        else
+            computeWidths();
+#endif
     }
 }
 
 RenderText::~RenderText()
 {
     if(str) str->deref();
+#if APPLE_CHANGES
+    if (m_widths)
+        free (m_widths);
+#endif
 }
 
 void RenderText::detach(RenderArena* renderArena)
@@ -760,6 +772,50 @@ void RenderText::paint(QPainter *p, int x, int y, int w, int h,
     paintObject(p, x, y, w, h, tx, ty, paintPhase);
 }
 
+#ifdef APPLE_CHANGES
+
+// We cache the widths array for the characters in the string only
+// if the string is very large.  This is a short term performance
+// optimization.  It has the downside of increasing the size
+// of each render text by float * str->l.  The performance
+// gained is huge though, so this is justifiable.  The long term
+// fix is to rework the word break/line break/bidi mechanisms
+// to reduce the measurement performed, and to correctly account
+// for unicode break points and surrogate pairs.
+#define MIN_STRING_LENGTH_FOR_WIDTH_CACHE 1024
+
+void RenderText::computeWidths()
+{
+    const Font *f = htmlFont( false );
+    
+    if (f){
+        if (m_widths){
+            free (m_widths);
+            m_widths = 0;
+        }
+
+        if (str->l > MIN_STRING_LENGTH_FOR_WIDTH_CACHE){
+            m_widths = (float *)malloc(str->l * sizeof(float));
+            f->floatCharacterWidths( str->s, str->l, 0, str->l, 0, m_widths);
+        }
+    }
+}
+
+inline int RenderText::widthFromBuffer(const Font *f, int start, int len) const
+{
+    float width = 0;
+    int i;
+    
+    if (m_widths == 0)
+        return f->width(str->s, str->l, start, len);
+        
+    for (i = start; i < start+len; i++){
+        width += m_widths[i];
+    }
+    return (int)width;
+}
+#endif
+
 void RenderText::trimmedMinMaxWidth(short& beginMinW, bool& beginWS, 
                                     short& endMinW, bool& endWS,
                                     bool& hasBreakableChar, bool& hasBreak,
@@ -781,7 +837,6 @@ void RenderText::trimmedMinMaxWidth(short& beginMinW, bool& beginWS,
     endMinW = m_endMinWidth;
     
     hasBreakableChar = m_hasBreakableChar;
-    hasBreak = m_hasBreak;
     
     if (len == 0)
         return;
@@ -799,35 +854,9 @@ void RenderText::trimmedMinMaxWidth(short& beginMinW, bool& beginWS,
         minW = maxW;
     else if (minW > maxW)
         minW = maxW;
-
-    // Compute our max widths by scanning the string for newlines.
-    if (hasBreak) {
-        const Font *f = htmlFont( false );
-        bool firstLine = true;
-        beginMaxW = endMaxW = maxW;
-        for(int i = 0; i < len; i++)
-        {
-            int linelen = 0;
-            while( i+linelen < len && str->s[i+linelen] != '\n')
-                linelen++;
-                
-            if (linelen)
-            {
-                endMaxW = f->width(str->s, str->l, i, linelen);
-                if (firstLine) {
-                    firstLine = false;
-                    beginMaxW = endMaxW;
-                }
-                i += linelen;
-                if (i == len-1)
-                    endMaxW = 0;
-            }
-            else if (firstLine) {
-                beginMaxW = 0;
-                firstLine = false;
-            }
-        }
-    }
+        
+    beginMaxW = m_beginMaxWidth;
+    endMaxW = m_endMaxWidth;
 }
 
 void RenderText::calcMinMaxWidth()
@@ -836,7 +865,7 @@ void RenderText::calcMinMaxWidth()
 
     // ### calc Min and Max width...
     m_minWidth = m_beginMinWidth = m_endMinWidth = 0;
-    m_maxWidth = 0;
+    m_maxWidth = m_beginMaxWidth = m_endMaxWidth = 0;
 
     if (isBR())
         return;
@@ -889,7 +918,11 @@ void RenderText::calcMinMaxWidth()
             
         if (wordlen)
         {
+#if !APPLE_CHANGES
             int w = f->width(str->s, str->l, i, wordlen);
+#else
+            int w = widthFromBuffer(f, i, wordlen);
+#endif
             currMinWidth += w;
             currMaxWidth += w;
             if (firstWord) {
@@ -930,6 +963,39 @@ void RenderText::calcMinMaxWidth()
     if (style()->whiteSpace() == NOWRAP)
         m_minWidth = m_maxWidth;
 
+    // Compute our max widths by scanning the string for newlines.
+    m_beginMaxWidth = m_endMaxWidth = m_maxWidth;
+    if (m_hasBreak) {
+        const Font *f = htmlFont( false );
+        bool firstLine = true;
+        for(int i = 0; i < len; i++)
+        {
+            int linelen = 0;
+            while( i+linelen < len && str->s[i+linelen] != '\n')
+                linelen++;
+                
+            if (linelen)
+            {
+#if !APPLE_CHANGES
+                m_endMaxWidth = f->width(str->s, str->l, i, linelen);
+#else
+                m_endMaxWidth = widthFromBuffer(f, i, linelen);
+#endif
+                if (firstLine) {
+                    firstLine = false;
+                    m_beginMaxWidth = m_endMaxWidth;
+                }
+                i += linelen;
+                if (i == len-1)
+                    m_endMaxWidth = 0;
+            }
+            else if (firstLine) {
+                m_beginMaxWidth = 0;
+                firstLine = false;
+            }
+        }
+    }
+
     setMinMaxKnown();
     //kdDebug( 6040 ) << "Text::calcMinMaxWidth(): min = " << m_minWidth << " max = " << m_maxWidth << endl;
 }
@@ -991,6 +1057,9 @@ void RenderText::setText(DOMStringImpl *text, bool force)
         str->ref();
     }
 
+#if APPLE_CHANGES
+    computeWidths();
+#endif
     // ### what should happen if we change the text of a
     // RenderBR object ?
     KHTMLAssert(!isBR() || (str->l == 1 && (*str->s) == '\n'));
@@ -1082,6 +1151,10 @@ unsigned int RenderText::width(unsigned int from, unsigned int len, const Font *
     int w;
     if ( f == &style()->htmlFont() && from == 0 && len == str->l )
  	 w = m_maxWidth;
+#if APPLE_CHANGES
+    else if (f == &style()->htmlFont())
+        w = widthFromBuffer (f, from, len);
+#endif
     else
 	w = f->width(str->s, str->l, from, len );
 
diff --git a/WebCore/khtml/rendering/render_text.h b/WebCore/khtml/rendering/render_text.h
index f5182f7..6c1fd18 100644
--- a/WebCore/khtml/rendering/render_text.h
+++ b/WebCore/khtml/rendering/render_text.h
@@ -217,6 +217,8 @@ public:
 #if APPLE_CHANGES
     TextSlave * findTextSlave( int offset, int &pos );
     TextSlaveArray textSlaves() { return m_lines; }
+    int widthFromBuffer(const Font *, int start, int len) const;
+    void computeWidths();
 #endif
 
 protected:
@@ -236,6 +238,8 @@ protected: // members
     short m_maxWidth;
     short m_beginMinWidth;
     short m_endMinWidth;
+    short m_beginMaxWidth;
+    short m_endMaxWidth;
     
     SelectionState m_selectionState : 3 ;
     bool m_hasBreakableChar : 1; // Whether or not we can be broken into multiple lines.
@@ -244,6 +248,9 @@ protected: // members
     bool m_hasEndWS : 1; // Whether or not we end with WS (only true if we aren't pre)
     
     // 19 bits left
+#if APPLE_CHANGES
+    float *m_widths;
+#endif
 };
 
 
diff --git a/WebKit/ChangeLog b/WebKit/ChangeLog
index 6e03e6a..5ddefce 100644
--- a/WebKit/ChangeLog
+++ b/WebKit/ChangeLog
@@ -1,3 +1,14 @@
+2002-12-20  Richard Williamson   <rjw at apple.com>
+
+        Fixed 3133261.  This fix really has two parts.  This first part
+        is here in WebTextRenderer.  The second part adds some width
+        caching to RenderText.  I was using a stack allocated array,
+        this would blow out the stack for large strings.
+
+        Reviewed by john.
+
+        * WebCoreSupport.subproj/WebTextRenderer.m:
+
 2002-12-20  Trey Matteson  <trey at apple.com>
 
 	We now build with symbols the B&I.  Deployment builds are without symbols,
diff --git a/WebKit/WebCoreSupport.subproj/WebTextRenderer.m b/WebKit/WebCoreSupport.subproj/WebTextRenderer.m
index 3e735a3..6ada6e8 100644
--- a/WebKit/WebCoreSupport.subproj/WebTextRenderer.m
+++ b/WebKit/WebCoreSupport.subproj/WebTextRenderer.m
@@ -889,7 +889,8 @@ static const char *joiningNames[] = {
 
 #define SHAPE_STRINGS
 #ifdef SHAPE_STRINGS
-    UniChar munged[stringLength];
+     UniChar *munged = 0;
+     UniChar _localMunged[LOCAL_BUFFER_SIZE];
     {
         UniChar *shaped;
         int lengthOut;
@@ -898,6 +899,10 @@ static const char *joiningNames[] = {
                                len,
                                0, &lengthOut);
         if (shaped){
+             if (stringLength < LOCAL_BUFFER_SIZE)
+                 munged = &_localMunged[0];
+             else
+                 munged = (UniChar *)malloc(stringLength * sizeof(UniChar));
             //printf ("%d input, %d output\n", len, lengthOut);
             //for (i = 0; i < (int)len; i++){
             //    printf ("0x%04x shaped to 0x%04x\n", characters[i], shaped[i]);
@@ -1126,6 +1131,11 @@ static const char *joiningNames[] = {
 
     if (_numGlyphs)
         *_numGlyphs = numGlyphs;
+
+#ifdef SHAPE_STRINGS
+     if (munged != &_localMunged[0])
+         free (munged);
+#endif
     
     return totalWidth;
 }

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list