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

darin darin at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 07:15:00 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 107c53d26ae9b922586276b648a2cb998d9c7795
Author: darin <darin at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Sun Dec 15 09:15:07 2002 +0000

    JavaScriptCore:
    
            Reviewed by Maciej.
    
            * JavaScriptCore.pbproj/project.pbxproj: Make dtoa.h visible as an SPI so I can
    	use it inside QString.
    
    WebFoundation:
    
            Reviewed by Maciej.
    
            * English.lproj/StringsNotToBeLocalized.txt: Updated for recent changes.
    
    WebCore:
    
            Reviewed by Maciej and Dave.
    
    	- optimizations that improve speed; total is 13.8% on cached cvs-base on my machine
    
            * khtml/css/css_valueimpl.h: Add isKonqBody() and genericFamilyType() to find out if
    	a font is a standard one. This is much faster than doing string comparisons all the time.
            * khtml/css/css_valueimpl.cpp: (FontFamilyValueImpl::FontFamilyValueImpl):
    	Check the font names against the standard ones on time when the FontFamilyValueImpl
    	object is constructed rather than every time the stuff is matched.
            * khtml/css/cssparser.h: Add pseudoType() and extractPseudoType() to CSSSelector so we
    	don't have to do string compares all the time.
            * khtml/css/cssparser.cpp:
            (StyleBaseImpl::parseValue): Use QConstString in a way that's effective (with an
    	object that has a long enough lifetime), or don't use it at all.
            (StyleBaseImpl::parseContent): Ditto.
            (StyleBaseImpl::preprocess): Preprocess into a buffer, usually on the stack, rather than
    	using QString += QChar over and over again.
            (CSSSelector::extractPseudoType): Convert the value string into a type, and get rid of it.
    	Saves memory because the string goes away. And doing it once is much faster than string
    	comparing each time.
            * khtml/css/cssstyleselector.cpp:
    	(cleanPath): Restructure to save one find() in the common case.
    	(checkPseudoState): Restructure to avoid some DOMString creation/destruction in the case
    	where the tag is not an <A>. Also use QConstString correctly.
    	(CSSStyleSelector::checkOneSelector): Use the new pseudoType() instead of string compares.
    	(CSSStyleSelector::applyRule): Use isKonqBody() and genericFamilyType() instead of string
    	comparisons.
    
            * khtml/dom/dom_string.h: Make the destructor non-virtual. This was a big win, and a mistake
    	the way it was before. Also make the DOMString constructor with no parameters inline.
            * khtml/dom/dom_string.cpp:
            (DOMString::string): Don't use QConstString here, since it does no good.
            (DOM::operator==): Rewrite to do things faster and avoid calling strlen.
    
            * khtml/html/html_objectimpl.h: Don't use QConstString in places where it does harm and no good.
            * khtml/html/html_objectimpl.cpp: (HTMLEmbedElementImpl::parseAttribute): Use QConstString properly.
    
            * khtml/html/htmltokenizer.cpp:
            (tagMatch): Added.
            (HTMLTokenizer::parseSpecial): Change tokenizing so it doesn't construct temporary strings (with
    	QConstString) just to compare small substrings.
    
            * khtml/khtml_part.cpp: (KHTMLPart::write): Don't use a decoder object when source is all ASCII.
    
            * kwq/KWQColor.mm:
            (hex2int): Don't bother with uppercase hex since we always lowercase anyway.
            (QColor::setNamedColor): Use a new gperf-based table instead of an NSDictionary to look up colors.
            * kwq/KWQColorData.c: Added this autogenerated file.
            * kwq/KWQColorData.gperf: Added. Source file with list of colors and color values.
            * kwq/Makefile.am: Build KWQColorData.c from KWQColorData.gperf.
            * WebCore.pbproj/project.pbxproj: Added KWQColorData.gperf.
    
            * khtml/misc/helper.cpp: (khtml::setNamedColor): Don't call setNamedColor again with the lowercased
    	color name, since our QColor::setNamedColor already has to lowercase the name (because it has to check
    	all names before checking any hex values).
    
            * khtml/rendering/font.h: Don't initialize the QFontMetrics since in every case we end up changing
    	the font later anyway. Also remove unused field.
            * khtml/rendering/font.cpp: (Font::update): Use the new QFontMetrics::setFont for speed.
    
            * khtml/rendering/render_object.cpp: (RenderObject::enclosingLayer): Change it so it doesn't get
    	the layer twice. This function showed up on the sample so we know it's hot.
    
            * khtml/xml/dom_stringimpl.cpp: (DOMStringImpl::containsOnlyWhitespace): Did a faster implementation
    	that doesn't call QChar::direction() except for non-ASCII characters.
    
            * kwq/KWQFontMetrics.h: Add empty constructor for use in font.cpp. Add accessor and setter for the
    	font too. Made baselineOffset() inline since it's trivial.
            * kwq/KWQFontMetrics.mm:
    	(QFontMetricsPrivate::QFontMetricsPrivate): Don't make the renderer until we use it.
    	(QFontMetricsPrivate::getRenderer): Make it here.
    	(QFontMetricsPrivate::font): Added.
    	(QFontMetricsPrivate::setFont): Added. Dumps the renderer if the font is different.
            (QFontMetrics::QFontMetrics): Added empty constructor.
            (QFontMetrics::setFont): Added.
    
            * kwq/KWQKURL.mm: (KURL::parse): Avoid function call overhead calling strncasecmp and strncmp.
    	Also made the check for localhost case insensitive.
    
            * kwq/KWQString.h: Remove _isUnicodeInternal and _isAsciiInternal, since they are trivially
    	computed, and it saves time to not have that extra field to manipulate. Removed private
    	data() function since it's the same as *dataHandle and not really more clear. Made ascii()
    	and unicode() simpler and inline. Also made latin1() and getCFString() inline. Renamed
    	QStringData to KWQStringData.
            * kwq/KWQString.mm:
            (QStringData::QStringData): Remove initializers for the xxxInternal.
            (QStringData::initialize): Removed some unnecessary if statements, and made a slight improvement
    	in the case of a 0-length string that comes with a pointer for Unicode (can't do it in the
            char * case because it's a feature that's used).
            (QString::makeSharedNull): No need to set _isUnicodeInternal.
            (QStringData::~QStringData): Use the new functions instead of the old bits.
            (QStringData::increaseAsciiSize): Grow faster when we get to larger sizes where the "good size"
    	call doesn't have as much of an effect. Simplified by removing unneeded code.
            (QStringData::increaseUnicodeSize): Ditto.
            (QStringData::makeAscii): Update for removal of _isAsciiInternal.
            (QStringData::makeUnicode): Update for removal of _isUnicodeInternal.
            (QString::detachIfInternal): Add this new inline to speed things up for the common case where
    	there's no detaching needed.
            (QString::at): Simplify, there were excess if branches here.
            (QString::toDouble): Use kjs_strtod and don't copy the string using QCString for additional speed.
            (QString::lower): Don't detach if the string is already all lowercase. Added a FIXME about the
    	code that assumes all "ASCII" bytes are truly ASCII. This code blurs the distinction between Latin-1
    	and ASCII in a way that will not work right for Latin-1 characters in an 8-byte character QString.
            (QString::detachInternal): Update for removal of _isUnicodeInternal.
            (QString::detach): Removed a special case for shared_null that was dead code since shared_null has
    	the _isUnicodeValid flag set.
            (operator==): Rewrote the comparison with char * to avoid the costly call to strlen.
    
            * Makefile.am: Updated the rules here so the force clean timestamp works right.
            * force-clean-timestamp: Touched this since the header dependencies don't seem right
    	for the DOMString constructor change, at least.
    	* WebCore-tests.exp: Exported a symbol now needed by tests since QString does more inlining.
    	* WebCore-combined.exp: Re-generated.
    
    WebBrowser:
    
            Reviewed by Maciej.
    
            * English.lproj/StringsNotToBeLocalized.txt: Updated for recent changes.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@3058 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 86af252..df48d57 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,10 @@
+2002-12-14  Darin Adler  <darin at apple.com>
+
+        Reviewed by Maciej.
+
+        * JavaScriptCore.pbproj/project.pbxproj: Make dtoa.h visible as an SPI so I can
+	use it inside QString.
+
 2002-12-14  Maciej Stachowiak  <mjs at apple.com>
 
         Reviewed by Ken.
diff --git a/JavaScriptCore/ChangeLog-2003-10-25 b/JavaScriptCore/ChangeLog-2003-10-25
index 86af252..df48d57 100644
--- a/JavaScriptCore/ChangeLog-2003-10-25
+++ b/JavaScriptCore/ChangeLog-2003-10-25
@@ -1,3 +1,10 @@
+2002-12-14  Darin Adler  <darin at apple.com>
+
+        Reviewed by Maciej.
+
+        * JavaScriptCore.pbproj/project.pbxproj: Make dtoa.h visible as an SPI so I can
+	use it inside QString.
+
 2002-12-14  Maciej Stachowiak  <mjs at apple.com>
 
         Reviewed by Ken.
diff --git a/JavaScriptCore/JavaScriptCore.pbproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.pbproj/project.pbxproj
index 0f20f49..930a43a 100644
--- a/JavaScriptCore/JavaScriptCore.pbproj/project.pbxproj
+++ b/JavaScriptCore/JavaScriptCore.pbproj/project.pbxproj
@@ -473,6 +473,9 @@
 			fileRef = 651F6413039D5B5F0078395C;
 			isa = PBXBuildFile;
 			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
 			};
 		};
 		65417200039E01BA0058BFEB = {
diff --git a/WebCore/ChangeLog-2003-10-25 b/WebCore/ChangeLog-2003-10-25
index a47d130..e3085be 100644
--- a/WebCore/ChangeLog-2003-10-25
+++ b/WebCore/ChangeLog-2003-10-25
@@ -1,3 +1,119 @@
+2002-12-14  Darin Adler  <darin at apple.com>
+
+        Reviewed by Maciej and Dave.
+
+	- optimizations that improve speed; total is 13.8% on cached cvs-base on my machine
+
+        * khtml/css/css_valueimpl.h: Add isKonqBody() and genericFamilyType() to find out if
+	a font is a standard one. This is much faster than doing string comparisons all the time.
+        * khtml/css/css_valueimpl.cpp: (FontFamilyValueImpl::FontFamilyValueImpl):
+	Check the font names against the standard ones on time when the FontFamilyValueImpl
+	object is constructed rather than every time the stuff is matched.
+        * khtml/css/cssparser.h: Add pseudoType() and extractPseudoType() to CSSSelector so we
+	don't have to do string compares all the time.
+        * khtml/css/cssparser.cpp:
+        (StyleBaseImpl::parseValue): Use QConstString in a way that's effective (with an
+	object that has a long enough lifetime), or don't use it at all.
+        (StyleBaseImpl::parseContent): Ditto.
+        (StyleBaseImpl::preprocess): Preprocess into a buffer, usually on the stack, rather than
+	using QString += QChar over and over again.
+        (CSSSelector::extractPseudoType): Convert the value string into a type, and get rid of it.
+	Saves memory because the string goes away. And doing it once is much faster than string
+	comparing each time.
+        * khtml/css/cssstyleselector.cpp:
+	(cleanPath): Restructure to save one find() in the common case.
+	(checkPseudoState): Restructure to avoid some DOMString creation/destruction in the case
+	where the tag is not an <A>. Also use QConstString correctly.
+	(CSSStyleSelector::checkOneSelector): Use the new pseudoType() instead of string compares.
+	(CSSStyleSelector::applyRule): Use isKonqBody() and genericFamilyType() instead of string
+	comparisons.
+
+        * khtml/dom/dom_string.h: Make the destructor non-virtual. This was a big win, and a mistake
+	the way it was before. Also make the DOMString constructor with no parameters inline.
+        * khtml/dom/dom_string.cpp:
+        (DOMString::string): Don't use QConstString here, since it does no good.
+        (DOM::operator==): Rewrite to do things faster and avoid calling strlen.
+
+        * khtml/html/html_objectimpl.h: Don't use QConstString in places where it does harm and no good.
+        * khtml/html/html_objectimpl.cpp: (HTMLEmbedElementImpl::parseAttribute): Use QConstString properly.
+
+        * khtml/html/htmltokenizer.cpp:
+        (tagMatch): Added.
+        (HTMLTokenizer::parseSpecial): Change tokenizing so it doesn't construct temporary strings (with
+	QConstString) just to compare small substrings.
+
+        * khtml/khtml_part.cpp: (KHTMLPart::write): Don't use a decoder object when source is all ASCII.
+
+        * kwq/KWQColor.mm:
+        (hex2int): Don't bother with uppercase hex since we always lowercase anyway.
+        (QColor::setNamedColor): Use a new gperf-based table instead of an NSDictionary to look up colors.
+        * kwq/KWQColorData.c: Added this autogenerated file.
+        * kwq/KWQColorData.gperf: Added. Source file with list of colors and color values.
+        * kwq/Makefile.am: Build KWQColorData.c from KWQColorData.gperf.
+        * WebCore.pbproj/project.pbxproj: Added KWQColorData.gperf.
+
+        * khtml/misc/helper.cpp: (khtml::setNamedColor): Don't call setNamedColor again with the lowercased
+	color name, since our QColor::setNamedColor already has to lowercase the name (because it has to check
+	all names before checking any hex values).
+
+        * khtml/rendering/font.h: Don't initialize the QFontMetrics since in every case we end up changing
+	the font later anyway. Also remove unused field.
+        * khtml/rendering/font.cpp: (Font::update): Use the new QFontMetrics::setFont for speed.
+
+        * khtml/rendering/render_object.cpp: (RenderObject::enclosingLayer): Change it so it doesn't get
+	the layer twice. This function showed up on the sample so we know it's hot.
+
+        * khtml/xml/dom_stringimpl.cpp: (DOMStringImpl::containsOnlyWhitespace): Did a faster implementation
+	that doesn't call QChar::direction() except for non-ASCII characters.
+
+        * kwq/KWQFontMetrics.h: Add empty constructor for use in font.cpp. Add accessor and setter for the
+	font too. Made baselineOffset() inline since it's trivial.
+        * kwq/KWQFontMetrics.mm:
+	(QFontMetricsPrivate::QFontMetricsPrivate): Don't make the renderer until we use it.
+	(QFontMetricsPrivate::getRenderer): Make it here.
+	(QFontMetricsPrivate::font): Added.
+	(QFontMetricsPrivate::setFont): Added. Dumps the renderer if the font is different.
+        (QFontMetrics::QFontMetrics): Added empty constructor.
+        (QFontMetrics::setFont): Added.
+
+        * kwq/KWQKURL.mm: (KURL::parse): Avoid function call overhead calling strncasecmp and strncmp.
+	Also made the check for localhost case insensitive.
+
+        * kwq/KWQString.h: Remove _isUnicodeInternal and _isAsciiInternal, since they are trivially
+	computed, and it saves time to not have that extra field to manipulate. Removed private
+	data() function since it's the same as *dataHandle and not really more clear. Made ascii()
+	and unicode() simpler and inline. Also made latin1() and getCFString() inline. Renamed
+	QStringData to KWQStringData.
+        * kwq/KWQString.mm:
+        (QStringData::QStringData): Remove initializers for the xxxInternal.
+        (QStringData::initialize): Removed some unnecessary if statements, and made a slight improvement
+	in the case of a 0-length string that comes with a pointer for Unicode (can't do it in the
+        char * case because it's a feature that's used).
+        (QString::makeSharedNull): No need to set _isUnicodeInternal.
+        (QStringData::~QStringData): Use the new functions instead of the old bits.
+        (QStringData::increaseAsciiSize): Grow faster when we get to larger sizes where the "good size"
+	call doesn't have as much of an effect. Simplified by removing unneeded code.
+        (QStringData::increaseUnicodeSize): Ditto.
+        (QStringData::makeAscii): Update for removal of _isAsciiInternal.
+        (QStringData::makeUnicode): Update for removal of _isUnicodeInternal.
+        (QString::detachIfInternal): Add this new inline to speed things up for the common case where
+	there's no detaching needed.
+        (QString::at): Simplify, there were excess if branches here.
+        (QString::toDouble): Use kjs_strtod and don't copy the string using QCString for additional speed.
+        (QString::lower): Don't detach if the string is already all lowercase. Added a FIXME about the
+	code that assumes all "ASCII" bytes are truly ASCII. This code blurs the distinction between Latin-1
+	and ASCII in a way that will not work right for Latin-1 characters in an 8-byte character QString.
+        (QString::detachInternal): Update for removal of _isUnicodeInternal.
+        (QString::detach): Removed a special case for shared_null that was dead code since shared_null has
+	the _isUnicodeValid flag set.
+        (operator==): Rewrote the comparison with char * to avoid the costly call to strlen.
+
+        * Makefile.am: Updated the rules here so the force clean timestamp works right.
+        * force-clean-timestamp: Touched this since the header dependencies don't seem right
+	for the DOMString constructor change, at least.
+	* WebCore-tests.exp: Exported a symbol now needed by tests since QString does more inlining.
+	* WebCore-combined.exp: Re-generated.
+
 2002-12-14  Maciej Stachowiak  <mjs at apple.com>
 
         Reviewed by Darin.
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index a47d130..e3085be 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,119 @@
+2002-12-14  Darin Adler  <darin at apple.com>
+
+        Reviewed by Maciej and Dave.
+
+	- optimizations that improve speed; total is 13.8% on cached cvs-base on my machine
+
+        * khtml/css/css_valueimpl.h: Add isKonqBody() and genericFamilyType() to find out if
+	a font is a standard one. This is much faster than doing string comparisons all the time.
+        * khtml/css/css_valueimpl.cpp: (FontFamilyValueImpl::FontFamilyValueImpl):
+	Check the font names against the standard ones on time when the FontFamilyValueImpl
+	object is constructed rather than every time the stuff is matched.
+        * khtml/css/cssparser.h: Add pseudoType() and extractPseudoType() to CSSSelector so we
+	don't have to do string compares all the time.
+        * khtml/css/cssparser.cpp:
+        (StyleBaseImpl::parseValue): Use QConstString in a way that's effective (with an
+	object that has a long enough lifetime), or don't use it at all.
+        (StyleBaseImpl::parseContent): Ditto.
+        (StyleBaseImpl::preprocess): Preprocess into a buffer, usually on the stack, rather than
+	using QString += QChar over and over again.
+        (CSSSelector::extractPseudoType): Convert the value string into a type, and get rid of it.
+	Saves memory because the string goes away. And doing it once is much faster than string
+	comparing each time.
+        * khtml/css/cssstyleselector.cpp:
+	(cleanPath): Restructure to save one find() in the common case.
+	(checkPseudoState): Restructure to avoid some DOMString creation/destruction in the case
+	where the tag is not an <A>. Also use QConstString correctly.
+	(CSSStyleSelector::checkOneSelector): Use the new pseudoType() instead of string compares.
+	(CSSStyleSelector::applyRule): Use isKonqBody() and genericFamilyType() instead of string
+	comparisons.
+
+        * khtml/dom/dom_string.h: Make the destructor non-virtual. This was a big win, and a mistake
+	the way it was before. Also make the DOMString constructor with no parameters inline.
+        * khtml/dom/dom_string.cpp:
+        (DOMString::string): Don't use QConstString here, since it does no good.
+        (DOM::operator==): Rewrite to do things faster and avoid calling strlen.
+
+        * khtml/html/html_objectimpl.h: Don't use QConstString in places where it does harm and no good.
+        * khtml/html/html_objectimpl.cpp: (HTMLEmbedElementImpl::parseAttribute): Use QConstString properly.
+
+        * khtml/html/htmltokenizer.cpp:
+        (tagMatch): Added.
+        (HTMLTokenizer::parseSpecial): Change tokenizing so it doesn't construct temporary strings (with
+	QConstString) just to compare small substrings.
+
+        * khtml/khtml_part.cpp: (KHTMLPart::write): Don't use a decoder object when source is all ASCII.
+
+        * kwq/KWQColor.mm:
+        (hex2int): Don't bother with uppercase hex since we always lowercase anyway.
+        (QColor::setNamedColor): Use a new gperf-based table instead of an NSDictionary to look up colors.
+        * kwq/KWQColorData.c: Added this autogenerated file.
+        * kwq/KWQColorData.gperf: Added. Source file with list of colors and color values.
+        * kwq/Makefile.am: Build KWQColorData.c from KWQColorData.gperf.
+        * WebCore.pbproj/project.pbxproj: Added KWQColorData.gperf.
+
+        * khtml/misc/helper.cpp: (khtml::setNamedColor): Don't call setNamedColor again with the lowercased
+	color name, since our QColor::setNamedColor already has to lowercase the name (because it has to check
+	all names before checking any hex values).
+
+        * khtml/rendering/font.h: Don't initialize the QFontMetrics since in every case we end up changing
+	the font later anyway. Also remove unused field.
+        * khtml/rendering/font.cpp: (Font::update): Use the new QFontMetrics::setFont for speed.
+
+        * khtml/rendering/render_object.cpp: (RenderObject::enclosingLayer): Change it so it doesn't get
+	the layer twice. This function showed up on the sample so we know it's hot.
+
+        * khtml/xml/dom_stringimpl.cpp: (DOMStringImpl::containsOnlyWhitespace): Did a faster implementation
+	that doesn't call QChar::direction() except for non-ASCII characters.
+
+        * kwq/KWQFontMetrics.h: Add empty constructor for use in font.cpp. Add accessor and setter for the
+	font too. Made baselineOffset() inline since it's trivial.
+        * kwq/KWQFontMetrics.mm:
+	(QFontMetricsPrivate::QFontMetricsPrivate): Don't make the renderer until we use it.
+	(QFontMetricsPrivate::getRenderer): Make it here.
+	(QFontMetricsPrivate::font): Added.
+	(QFontMetricsPrivate::setFont): Added. Dumps the renderer if the font is different.
+        (QFontMetrics::QFontMetrics): Added empty constructor.
+        (QFontMetrics::setFont): Added.
+
+        * kwq/KWQKURL.mm: (KURL::parse): Avoid function call overhead calling strncasecmp and strncmp.
+	Also made the check for localhost case insensitive.
+
+        * kwq/KWQString.h: Remove _isUnicodeInternal and _isAsciiInternal, since they are trivially
+	computed, and it saves time to not have that extra field to manipulate. Removed private
+	data() function since it's the same as *dataHandle and not really more clear. Made ascii()
+	and unicode() simpler and inline. Also made latin1() and getCFString() inline. Renamed
+	QStringData to KWQStringData.
+        * kwq/KWQString.mm:
+        (QStringData::QStringData): Remove initializers for the xxxInternal.
+        (QStringData::initialize): Removed some unnecessary if statements, and made a slight improvement
+	in the case of a 0-length string that comes with a pointer for Unicode (can't do it in the
+        char * case because it's a feature that's used).
+        (QString::makeSharedNull): No need to set _isUnicodeInternal.
+        (QStringData::~QStringData): Use the new functions instead of the old bits.
+        (QStringData::increaseAsciiSize): Grow faster when we get to larger sizes where the "good size"
+	call doesn't have as much of an effect. Simplified by removing unneeded code.
+        (QStringData::increaseUnicodeSize): Ditto.
+        (QStringData::makeAscii): Update for removal of _isAsciiInternal.
+        (QStringData::makeUnicode): Update for removal of _isUnicodeInternal.
+        (QString::detachIfInternal): Add this new inline to speed things up for the common case where
+	there's no detaching needed.
+        (QString::at): Simplify, there were excess if branches here.
+        (QString::toDouble): Use kjs_strtod and don't copy the string using QCString for additional speed.
+        (QString::lower): Don't detach if the string is already all lowercase. Added a FIXME about the
+	code that assumes all "ASCII" bytes are truly ASCII. This code blurs the distinction between Latin-1
+	and ASCII in a way that will not work right for Latin-1 characters in an 8-byte character QString.
+        (QString::detachInternal): Update for removal of _isUnicodeInternal.
+        (QString::detach): Removed a special case for shared_null that was dead code since shared_null has
+	the _isUnicodeValid flag set.
+        (operator==): Rewrote the comparison with char * to avoid the costly call to strlen.
+
+        * Makefile.am: Updated the rules here so the force clean timestamp works right.
+        * force-clean-timestamp: Touched this since the header dependencies don't seem right
+	for the DOMString constructor change, at least.
+	* WebCore-tests.exp: Exported a symbol now needed by tests since QString does more inlining.
+	* WebCore-combined.exp: Re-generated.
+
 2002-12-14  Maciej Stachowiak  <mjs at apple.com>
 
         Reviewed by Darin.
diff --git a/WebCore/Makefile.am b/WebCore/Makefile.am
index 7614bb7..580ac2b 100644
--- a/WebCore/Makefile.am
+++ b/WebCore/Makefile.am
@@ -8,10 +8,10 @@ clean-am:
 	rm -rf $(SYMROOTS)/WebCore.framework
 	rm -rf $(SYMROOTS)/Safari.app/Frameworks/WebCore.framework
 
-WebCore-combined.exp: WebCore.exp WebCore-tests.exp
+WebCore-combined.exp: WebCore.exp WebCore-tests.exp previous-clean-timestamp
 	cat $^ > $@
 
-config.h: ../config.h
+config.h: ../config.h previous-clean-timestamp
 	grep -v NO_LICENSE ../config.h > new-config.h
 	if cmp -s config.h new-config.h; then \
 		rm -f new-config.h; \
diff --git a/WebCore/WebCore-combined.exp b/WebCore/WebCore-combined.exp
index 789c2a7..c05f352 100644
--- a/WebCore/WebCore-combined.exp
+++ b/WebCore/WebCore-combined.exp
@@ -62,9 +62,10 @@ __ZN12KWQArrayImplC1ERKS_
 __ZN12KWQArrayImplC1Emm
 __ZN12KWQArrayImplD1Ev
 __ZN12KWQArrayImplaSERKS_
+__ZN13KWQStringData9makeAsciiEv
 __ZN13KWQVectorImpl5clearEb
-__ZN13KWQVectorImpl6removeEjb
 __ZN13KWQVectorImpl6insertEjPvb
+__ZN13KWQVectorImpl6removeEjb
 __ZN13KWQVectorImpl6resizeEjb
 __ZN13KWQVectorImplC1EPFvPvE
 __ZN13KWQVectorImplC1ERKS_
@@ -252,6 +253,7 @@ __ZNK5QTime4msecEv
 __ZNK6QPoint15manhattanLengthEv
 __ZNK7QRegExp5matchERK7QStringiPib
 __ZNK7QRegExp7patternEv
+__ZNK7QString10startsWithERKS_
 __ZNK7QString15stripWhiteSpaceEv
 __ZNK7QString18simplifyWhiteSpaceEv
 __ZNK7QString3argERKS_i
@@ -274,6 +276,7 @@ __ZNK7QString6isNullEv
 __ZNK7QString6latin1Ev
 __ZNK7QString6toLongEPbi
 __ZNK7QString6toUIntEPbi
+__ZNK7QString7compareERKS_
 __ZNK7QString7findRevEPKci
 __ZNK7QString7findRevEci
 __ZNK7QString8containsEPKcb
@@ -307,5 +310,3 @@ __ZplPKcRK7QString
 __ZplRK5QSizeS1_
 __ZplRK6QPointS1_
 __ZplcRK7QString
-__ZNK7QString7compareERKS_
-__ZNK7QString10startsWithERKS_
diff --git a/WebCore/WebCore-tests.exp b/WebCore/WebCore-tests.exp
index 1a364a6..c47e18c 100644
--- a/WebCore/WebCore-tests.exp
+++ b/WebCore/WebCore-tests.exp
@@ -40,9 +40,10 @@ __ZN12KWQArrayImplC1ERKS_
 __ZN12KWQArrayImplC1Emm
 __ZN12KWQArrayImplD1Ev
 __ZN12KWQArrayImplaSERKS_
+__ZN13KWQStringData9makeAsciiEv
 __ZN13KWQVectorImpl5clearEb
-__ZN13KWQVectorImpl6removeEjb
 __ZN13KWQVectorImpl6insertEjPvb
+__ZN13KWQVectorImpl6removeEjb
 __ZN13KWQVectorImpl6resizeEjb
 __ZN13KWQVectorImplC1EPFvPvE
 __ZN13KWQVectorImplC1ERKS_
@@ -230,6 +231,7 @@ __ZNK5QTime4msecEv
 __ZNK6QPoint15manhattanLengthEv
 __ZNK7QRegExp5matchERK7QStringiPib
 __ZNK7QRegExp7patternEv
+__ZNK7QString10startsWithERKS_
 __ZNK7QString15stripWhiteSpaceEv
 __ZNK7QString18simplifyWhiteSpaceEv
 __ZNK7QString3argERKS_i
@@ -252,6 +254,7 @@ __ZNK7QString6isNullEv
 __ZNK7QString6latin1Ev
 __ZNK7QString6toLongEPbi
 __ZNK7QString6toUIntEPbi
+__ZNK7QString7compareERKS_
 __ZNK7QString7findRevEPKci
 __ZNK7QString7findRevEci
 __ZNK7QString8containsEPKcb
@@ -285,5 +288,3 @@ __ZplPKcRK7QString
 __ZplRK5QSizeS1_
 __ZplRK6QPointS1_
 __ZplcRK7QString
-__ZNK7QString7compareERKS_
-__ZNK7QString10startsWithERKS_
diff --git a/WebCore/WebCore.pbproj/project.pbxproj b/WebCore/WebCore.pbproj/project.pbxproj
index 984ab9f..97c92e6 100644
--- a/WebCore/WebCore.pbproj/project.pbxproj
+++ b/WebCore/WebCore.pbproj/project.pbxproj
@@ -1050,6 +1050,12 @@
 			settings = {
 			};
 		};
+		93ECDB7E03ABE65B008635CE = {
+			fileEncoding = 4;
+			isa = PBXFileReference;
+			path = KWQColorData.gperf;
+			refType = 4;
+		};
 //930
 //931
 //932
@@ -7555,6 +7561,7 @@
 				F58784CF02DE375901EA4122,
 				F587868102DE3B8601EA4122,
 				F58784D002DE375901EA4122,
+				93ECDB7E03ABE65B008635CE,
 				F587868202DE3B8601EA4122,
 				F58784D202DE375901EA4122,
 				F587868302DE3B8601EA4122,
diff --git a/WebCore/force-clean-timestamp b/WebCore/force-clean-timestamp
index e1d4ab1..d96e045 100644
--- a/WebCore/force-clean-timestamp
+++ b/WebCore/force-clean-timestamp
@@ -1 +1 @@
-loader.h added member to CacheObject 10/07
+DOMString constructor 12/13
diff --git a/WebCore/khtml/css/css_valueimpl.cpp b/WebCore/khtml/css/css_valueimpl.cpp
index 753c565..428a47f 100644
--- a/WebCore/khtml/css/css_valueimpl.cpp
+++ b/WebCore/khtml/css/css_valueimpl.cpp
@@ -34,6 +34,7 @@
 
 #include "misc/loader.h"
 
+#include "rendering/font.h"
 #include "rendering/render_style.h"
 
 #include <kdebug.h>
@@ -44,6 +45,8 @@
 // Hack for debugging purposes
 extern DOM::DOMString getPropertyName(unsigned short id);
 
+using khtml::FontDef;
+
 using namespace DOM;
 
 CSSStyleDeclarationImpl::CSSStyleDeclarationImpl(CSSRuleImpl *parent)
@@ -757,4 +760,44 @@ FontFamilyValueImpl::FontFamilyValueImpl( const QString &string)
 	}
     }
 #endif // !APPLE_CHANGES
+
+    _genericFamilyType = FontDef::eNone;
+    _isKonqBody = false;
+
+    if (parsedFontName.isEmpty()) {
+        return;
+    }
+    
+    // Check font names here instead of every time through the CSSStyleSelector.
+    switch (parsedFontName[0]) {
+        case 'c':
+            if (parsedFontName == "cursive") {
+                _genericFamilyType = FontDef::eCursive;
+            }
+            break;
+        case 'f':
+            if (parsedFontName == "fantasy") {
+                _genericFamilyType = FontDef::eFantasy;
+            }
+            break;
+        case 'k':
+            if (parsedFontName == "konq_default") {
+                _genericFamilyType = FontDef::eStandard;
+            } else if (parsedFontName == "konq_body") {
+                _isKonqBody = true;
+            }
+            break;
+        case 'm':
+            if (parsedFontName == "monospace") {
+                _genericFamilyType = FontDef::eMonospace;
+            }
+            break;
+        case 's':
+            if (parsedFontName == "serif") {
+                _genericFamilyType = FontDef::eSerif;
+            } else if (parsedFontName == "sans-serif") {
+                _genericFamilyType = FontDef::eSansSerif;
+            }
+            break;
+    }
 }
diff --git a/WebCore/khtml/css/css_valueimpl.h b/WebCore/khtml/css/css_valueimpl.h
index acf78f5..2b02891 100644
--- a/WebCore/khtml/css/css_valueimpl.h
+++ b/WebCore/khtml/css/css_valueimpl.h
@@ -291,8 +291,13 @@ class FontFamilyValueImpl : public CSSPrimitiveValueImpl
 public:
     FontFamilyValueImpl( const QString &string);
     const QString &fontName() const { return parsedFontName; }
+    int genericFamilyType() const { return _genericFamilyType; }
+    bool isKonqBody() const { return _isKonqBody; }
 protected:
     QString parsedFontName;
+private:
+    int _genericFamilyType;
+    bool _isKonqBody;
 };
 
 // ------------------------------------------------------------------------------
diff --git a/WebCore/khtml/css/cssparser.cpp b/WebCore/khtml/css/cssparser.cpp
index 7c1b04e..3ca6f2d 100644
--- a/WebCore/khtml/css/cssparser.cpp
+++ b/WebCore/khtml/css/cssparser.cpp
@@ -1166,8 +1166,7 @@ bool StyleBaseImpl::parseValue( const QChar *curP, const QChar *endP, int propId
 {
   if (curP==endP) {return 0; /* e.g.: width="" */}
 
-  QString value(curP, endP - curP);
-  value = value.lower().stripWhiteSpace();
+  QString value = QConstString(curP, endP - curP).string().lower().stripWhiteSpace();
 #ifdef CSS_DEBUG
   kdDebug( 6080 ) << "id [" << getPropertyName(propId).string() << "] parseValue [" << value << "]" << endl;
 #endif
@@ -1233,7 +1232,7 @@ bool StyleBaseImpl::parseValue( const QChar *curP, const QChar *endP, int propId
 	      parsedValue = new CSSPrimitiveValueImpl( cssval->id );
 	  else {
 	      // only shape in CSS2 is rect( top right bottom left )
-	      QString str = QConstString( const_cast<QChar*>( curP ), endP - curP ).string();
+	      QString str(curP, endP - curP);
 	      // the CSS specs are not really clear if there should be commas in here or not. We accept both spaces and commas.
 	      QChar *uc = (QChar *)str.unicode();
 	      int len = str.length();
@@ -2376,7 +2375,8 @@ CSSValueImpl* StyleBaseImpl::parseContent(const QChar *curP, const QChar *endP)
                 break;
             nextP++;
         }
-        QString str = QConstString(curP, nextP-curP).string();
+        QConstString cstr(curP, nextP-curP);
+        QString str = cstr.string();
         CSSValueImpl* parsedValue=0;
         if (str.startsWith("url("))
         {
@@ -2866,7 +2866,13 @@ StyleBaseImpl::parseRule(const QChar *&curP, const QChar *endP)
 const QString StyleBaseImpl::preprocess(const QString &str, bool justOneRule)
 {
   // ### use DOMString here to avoid coversions
-  QString processed;
+
+  char fixedSizeBuffer[8192];
+  uint size = str.length() * 2 * sizeof(QChar);
+  char *buffer = fixedSizeBuffer;
+  if (size > sizeof(fixedSizeBuffer))
+    buffer = new char [size];
+  QChar *p = (QChar *)buffer;
 
   bool sq = false;	// Within single quote
   bool dq = false;	// Within double quote
@@ -2893,33 +2899,33 @@ const QString StyleBaseImpl::preprocess(const QString &str, bool justOneRule)
 //              QConstString(ch, kMin(last-ch, 10)).string().latin1(), sq, dq, bracket, comment, firstChar, space, curlyBracket, skipgarbage);
     if( !comment && !sq && *ch == '"' ) {
       dq = !dq;
-      processed += *ch;
+      *p++ = *ch;
       space = skipgarbage = false;
     } else if ( !comment && !dq && *ch == '\'') {
       skipgarbage = sq;
       sq = !sq;
-      processed += *ch;
+      *p++ = *ch;
       space = false;
     } else if ( !comment && !dq && !sq && *ch == '(') {
       bracket = true;
-      processed += *ch;
+      *p++ = *ch;
       space = true;  // Explictly true
       skipgarbage = false;
     } else if ( !comment && !dq && !sq && *ch == ')') {
       bracket = false;
-      processed += *ch;
-      processed += QChar(' '); // Adding a space after this token
+      *p++ = *ch;
+      *p++ = QChar(' '); // Adding a space after this token
       space = true;
       skipgarbage = false;
     } else if ( !comment && !dq && !sq && *ch == '{') {
       ++curlyBracket;
-      processed += *ch;
+      *p++ = *ch;
       space = true;  // Explictly true
       skipgarbage = true;
     } else if ( !comment && !dq && !sq && *ch == '}') {
       --curlyBracket;
-      processed += *ch;
-      processed += QChar(' '); // Adding a space after this token
+      *p++ = *ch;
+      *p++ = QChar(' '); // Adding a space after this token
       space = true;
       skipgarbage = true;
     } else if ( !comment && skipgarbage && !dq && !sq && (*ch == '-') && ((ch+2) < last)  /* SGML Comment */
@@ -2942,11 +2948,11 @@ const QString StyleBaseImpl::preprocess(const QString &str, bool justOneRule)
 	if ( *ch == '*' ) {
 	  comment = true;
 	} else {
-	  processed += '/';
+	  *p++ = '/';
 	  if (curlyBracket > 0) {
-	    processed += ch->lower();
+	    *p++ = ch->lower();
 	  } else {
-	    processed += *ch;
+	    *p++ = *ch;
 	  }
 	  space = ch->isSpace();
 	}
@@ -2954,8 +2960,8 @@ const QString StyleBaseImpl::preprocess(const QString &str, bool justOneRule)
       } else if ( *ch == '/' ) {
 	firstChar = true; // Slash added only if next is not '*'
       } else if ( *ch == ',' || *ch == ';') {
-	processed += *ch;
-	processed += QChar(' '); // Adding a space after these tokens
+	*p++ = *ch;
+	*p++ = QChar(' '); // Adding a space after these tokens
 	space = true;
              skipgarbage = true;
       } else {
@@ -2970,6 +2976,11 @@ const QString StyleBaseImpl::preprocess(const QString &str, bool justOneRule)
   end:
     ++ch;
   }
+  
+  {
+    QString processed((QChar *)buffer, p - (QChar *)buffer);
+    if (buffer != fixedSizeBuffer)
+        delete [] buffer;
 
 #ifdef CSS_DEBUG
   kdDebug(6080) << "---After ---" << endl;
@@ -2980,24 +2991,25 @@ const QString StyleBaseImpl::preprocess(const QString &str, bool justOneRule)
   kdDebug(6080) << "------------" << endl;
 #endif
 
-  return processed;
+    return processed;
+  }
 
  addChar:
   if ( !sq && !dq && !bracket ) {
     if (!(space && ch->isSpace())) { // Don't add more than one space
       if (ch->isSpace()) {
-	processed += QChar(' '); // Normalize whitespace
+	*p++ = QChar(' '); // Normalize whitespace
       } else {
 	if (curlyBracket > 0 || justOneRule) {
-	  processed += ch->lower();
+	  *p++ = ch->lower();
 	} else {
-	  processed += *ch;
+	  *p++ = *ch;
 	}
       }
     }
     space = ch->isSpace();
   } else {
-    processed += *ch; // We're within quotes or brackets, leave untouched
+    *p++ = *ch; // We're within quotes or brackets, leave untouched
   }
   goto end;
 }
@@ -3058,6 +3070,54 @@ unsigned int CSSSelector::specificity()
     return s & 0xffffff;
 }
 
+void CSSSelector::extractPseudoType() const
+{
+    _pseudoType = PseudoOther;
+    if (!value.isEmpty()) {
+        switch (value[0]) {
+            case 'a':
+                if (value == "active")
+                    _pseudoType = PseudoActive;
+                else if (value == "after")
+                    _pseudoType = PseudoAfter;
+                break;
+            case 'b':
+                if (value == "before")
+                    _pseudoType = PseudoBefore;
+                break;
+            case 'e':
+                if (value == "empty")
+                    _pseudoType = PseudoEmpty;
+                break;
+            case 'f':
+                if (value == "first-child")
+                    _pseudoType = PseudoFirstChild;
+                else if (value == "first-letter")
+                    _pseudoType = PseudoFirstLetter;
+                else if (value == "first-line")
+                    _pseudoType = PseudoFirstLine;
+                else if (value == "focus")
+                    _pseudoType = PseudoFocus;
+                break;
+            case 'h':
+                if (value == "hover")
+                    _pseudoType = PseudoHover;
+                break;
+            case 'l':
+                if (value == "link")
+                    _pseudoType = PseudoLink;
+                break;
+            case 'v':
+                if (value == "visited")
+                    _pseudoType = PseudoVisited;
+                break;
+        }
+    }
+    
+    value = QString::null;
+}
+
+
 bool CSSSelector::operator == ( const CSSSelector &other )
 {
     const CSSSelector *sel1 = this;
diff --git a/WebCore/khtml/css/cssparser.h b/WebCore/khtml/css/cssparser.h
index caea5ff..dfd7ada 100644
--- a/WebCore/khtml/css/cssparser.h
+++ b/WebCore/khtml/css/cssparser.h
@@ -50,19 +50,18 @@ namespace DOM {
 class CSSSelector
 {
 public:
-    CSSSelector(void)
+    CSSSelector()
 	: tagHistory(0), attr(0), tag(0), relation( Descendant ),
-    match( None ), nonCSSHint( false ), pseudoId( 0 ) {}
+    match( None ), nonCSSHint( false ), pseudoId( 0 ), _pseudoType(PseudoNotParsed) {}
 
-    ~CSSSelector(void) {
-	if (tagHistory)
-	    delete tagHistory;
+    ~CSSSelector() {
+	delete tagHistory;
     }
 
     /**
      * Print debug output for this selector
      */
-    void print(void);
+    void print();
 
     /**
      * Re-create selector text from selector's data
@@ -97,8 +96,32 @@ public:
 	Sibling,
 	SubSelector
     };
+    
+    enum PseudoType
+    {
+        PseudoNotParsed = 0,
+        PseudoOther,
+	PseudoEmpty,
+        PseudoFirstChild,
+        PseudoFirstLine,
+        PseudoFirstLetter,
+        PseudoLink,
+        PseudoVisited,
+        PseudoHover,
+        PseudoFocus,
+        PseudoActive,
+        PseudoBefore,
+        PseudoAfter
+    };
 
-    DOM::DOMString value;
+    inline PseudoType pseudoType() const
+    {
+        if (_pseudoType == PseudoNotParsed)
+            extractPseudoType();
+        return _pseudoType;
+    }
+
+    mutable DOM::DOMString value;
     CSSSelector *tagHistory;
     int          attr;
     int          tag;
@@ -107,8 +130,11 @@ public:
     Match 	 match         : 4;
     bool	nonCSSHint : 1;
     unsigned int pseudoId : 3;
-
-
+    
+    mutable PseudoType _pseudoType;
+    
+private:
+    void extractPseudoType() const;
 };
 
     // a style class which has a parent (almost all have)
@@ -133,7 +159,7 @@ public:
 	virtual bool isCharetRule() { return false; }
 	virtual bool isImportRule() { return false; }
 	virtual bool isMediaRule() { return false; }
-    virtual bool isQuirksRule() { return false; }
+	virtual bool isQuirksRule() { return false; }
 	virtual bool isFontFaceRule() { return false; }
 	virtual bool isPageRule() { return false; }
 	virtual bool isUnknownRule() { return false; }
@@ -167,7 +193,7 @@ public:
 	void setParsedValue(int propId, const CSSValueImpl *parsedValue);
 	void setParsedValue(int propId, const CSSValueImpl *parsedValue,
 			    bool important, bool nonCSSHint, QPtrList<CSSProperty> *propList);
-    bool isHexadecimal( const QChar &c );
+	bool isHexadecimal( const QChar &c );
 	QPtrList<QChar> splitShorthandProperties(const QChar *curP, const QChar *endP);
 	bool parseBackgroundPosition(const QChar *curP, const QChar *&nextP, const QChar *endP);
 
diff --git a/WebCore/khtml/css/cssstyleselector.cpp b/WebCore/khtml/css/cssstyleselector.cpp
index a2c8d26..a7f4f24 100644
--- a/WebCore/khtml/css/cssstyleselector.cpp
+++ b/WebCore/khtml/css/cssstyleselector.cpp
@@ -628,8 +628,13 @@ static void cleanpath(QString &path)
     pos = 0;
 
     // Don't remove "//" from an anchor identifier. -rjw
-    int refPos = path.find("#", 0);
+    // Set refPos to -2 to mean "I haven't looked for the anchor yet".
+    // We don't want to waste a function call on the search for the the anchor
+    // in the vast majority of cases where there is no "//" in the path.
+    int refPos = -2;
     while ( (pos = path.find( "//", pos )) != -1) {
+        if (refPos == -2)
+            refPos = path.find("#", 0);
         if (refPos > 0 && pos >= refPos)
             break;
             
@@ -645,12 +650,17 @@ static void cleanpath(QString &path)
 
 static void checkPseudoState( DOM::ElementImpl *e )
 {
-    DOMString attr;
-    if( e->id() != ID_A || (attr = e->getAttribute(ATTR_HREF)).isNull() ) {
+    if( e->id() != ID_A ) {
+	pseudoState = PseudoNone;
+        return;
+    }
+    DOMString attr = e->getAttribute(ATTR_HREF);
+    if( attr.isNull() ) {
 	pseudoState = PseudoNone;
 	return;
     }
-    QString u = attr.string();
+    QConstString cu(attr.unicode(), attr.length());
+    QString u = cu.string();
     if ( !u.contains("://") ) {
 	if ( u[0] == '/' )
 	    u = encodedurl->host + u;
@@ -760,57 +770,72 @@ bool CSSStyleSelector::checkOneSelector(DOM::CSSSelector *sel, DOM::ElementImpl
     {
         // Pseudo elements. We need to check first child here. No dynamic pseudo
         // elements for the moment
-	const QString& value = sel->value.string();
 //	kdDebug() << "CSSOrderedRule::pseudo " << value << endl;
-	if (value == "empty") {
-        if (!e->firstChild())
-            return true;
-	}
-	else if(value == "first-child") {
-	    // first-child matches the first child that is an element!
-	    DOM::NodeImpl *n = e->parentNode()->firstChild();
-	    while( n && !n->isElementNode() )
-		n = n->nextSibling();
-	    if( n == e )
-		return true;
-	} else if ( value == "first-line" && subject ) {
-	    dynamicPseudo=RenderStyle::FIRST_LINE;
-	    return true;
-	} else if ( value == "first-letter" && subject ) {
-	    dynamicPseudo=RenderStyle::FIRST_LETTER;
-	    return true;
-	} else if( value == "link") {
-	    if ( pseudoState == PseudoUnknown )
-		checkPseudoState( e );
-	    if ( pseudoState == PseudoLink ) {
-		return true;
-	    }
-	} else if ( value == "visited" ) {
-	    if ( pseudoState == PseudoUnknown )
-		checkPseudoState( e );
-	    if ( pseudoState == PseudoVisited )
-		return true;
-	} else if ( value == "hover" ) {
-	    selectorDynamicState |= StyleSelector::Hover;
-	    // dynamic pseudos have to be sorted out in checkSelector, so we if it could in some state apply
-	    // to the element.
-	    return true;
-	} else if ( value == "focus" ) {
-	    selectorDynamicState |= StyleSelector::Focus;
-	    return true;
-	} else if ( value == "active" ) {
-	    if ( pseudoState == PseudoUnknown )
-		checkPseudoState( e );
-	    if ( pseudoState != PseudoNone ) {
-		selectorDynamicState |= StyleSelector::Active;
-		return true;
-	    }
-	} else if ( value == "before" ) {
-            dynamicPseudo = RenderStyle::BEFORE;
-            return true;
-        } else if ( value == "after" ) {
-            dynamicPseudo = RenderStyle::AFTER;
-            return true;
+	switch (sel->pseudoType()) {
+            case CSSSelector::PseudoEmpty:
+                if (!e->firstChild())
+                    return true;
+                break;
+            case CSSSelector::PseudoFirstChild: {
+                // first-child matches the first child that is an element!
+                DOM::NodeImpl *n = e->parentNode()->firstChild();
+                while ( n && !n->isElementNode() )
+                    n = n->nextSibling();
+                if ( n == e )
+                    return true;
+                break;
+            }
+            case CSSSelector::PseudoFirstLine:
+                if ( subject ) {
+                    dynamicPseudo=RenderStyle::FIRST_LINE;
+                    return true;
+                }
+                break;
+            case CSSSelector::PseudoFirstLetter:
+                if ( subject ) {
+                    dynamicPseudo=RenderStyle::FIRST_LETTER;
+                    return true;
+                }
+                break;
+            case CSSSelector::PseudoLink:
+                if ( pseudoState == PseudoUnknown )
+                    checkPseudoState( e );
+                if ( pseudoState == PseudoLink )
+                    return true;
+                break;
+            case CSSSelector::PseudoVisited:
+                if ( pseudoState == PseudoUnknown )
+                    checkPseudoState( e );
+                if ( pseudoState == PseudoVisited )
+                    return true;
+                break;
+            case CSSSelector::PseudoHover:
+                selectorDynamicState |= StyleSelector::Hover;
+                // dynamic pseudos have to be sorted out in checkSelector, so we if it could in some state apply
+                // to the element.
+                return true;
+            case CSSSelector::PseudoFocus:
+                selectorDynamicState |= StyleSelector::Focus;
+                return true;
+            case CSSSelector::PseudoActive:
+                if ( pseudoState == PseudoUnknown )
+                    checkPseudoState( e );
+                if ( pseudoState != PseudoNone ) {
+                    selectorDynamicState |= StyleSelector::Active;
+                    return true;
+                }
+                break;
+            case CSSSelector::PseudoBefore:
+                dynamicPseudo = RenderStyle::BEFORE;
+                return true;
+            case CSSSelector::PseudoAfter:
+                dynamicPseudo = RenderStyle::AFTER;
+                return true;
+            case CSSSelector::PseudoNotParsed:
+                assert(false);
+                break;
+            case CSSSelector::PseudoOther:
+                break;
         }
 	return false;
     }
@@ -2333,21 +2358,17 @@ void CSSStyleSelector::applyRule( DOM::CSSProperty *prop )
 
         } else {
             int type = primitiveValue->primitiveType();
-#ifndef APPLE_CHANGES
             if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) {
+#if !APPLE_CHANGES
                 size = primitiveValue->computeLengthFloat(parentStyle, paintDeviceMetrics);
-                if (!khtml::printpainter && element && element->getDocument()->view())
-                    size *= element->getDocument()->view()->part()->zoomFactor() / 100.0;
-            } 
 #else
-            // OS X will always provide device independent font size, so we don't want to adjust
-            // the device indepent sizes.
-            if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) {
+                // OS X will always provide device independent font size, so we don't want to adjust
+                // the device independent sizes.
                 size = primitiveValue->computePointFloat(parentStyle, paintDeviceMetrics);
+#endif
                 if (!khtml::printpainter && element && element->getDocument()->view())
                     size *= element->getDocument()->view()->part()->zoomFactor() / 100.0;
-            }
-#endif
+            } 
             else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
                 size = (primitiveValue->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE)
                         * parentStyle->font().pixelSize()) / 100;
@@ -2540,75 +2561,80 @@ void CSSStyleSelector::applyRule( DOM::CSSProperty *prop )
             CSSValueImpl *item = list->item(i);
             if(!item->isPrimitiveValue()) continue;
             CSSPrimitiveValueImpl *val = static_cast<CSSPrimitiveValueImpl *>(item);
-            if(!val->primitiveType() == CSSPrimitiveValue::CSS_STRING) return;
-            QString face = static_cast<FontFamilyValueImpl *>(val)->fontName();
-            if ( !face.isEmpty() ) {
-                if(face == "serif") {
-                    face = settings->serifFontName();
-                    fontDef.setGenericFamily(FontDef::eSerif);
-                }
-                else if(face == "sans-serif") {
-                    face = settings->sansSerifFontName();
-                    fontDef.setGenericFamily(FontDef::eSansSerif);
-                }
-                else if( face == "cursive") {
-                    face = settings->cursiveFontName();
-                    fontDef.setGenericFamily(FontDef::eCursive);
-                }
-                else if( face == "fantasy") {
-                    face = settings->fantasyFontName();
-                    fontDef.setGenericFamily(FontDef::eFantasy);
-                }
-                else if( face == "monospace") {
-                    face = settings->fixedFontName();
-                    fontDef.setGenericFamily(FontDef::eMonospace);
-                }
-                else if( face == "konq_default") {
-                    // Treat this as though it's a generic family, since we will want
-                    // to reset to default sizes when we encounter this (and inherit
-                    // from an enclosing different family like monospace.
-                    face = settings->stdFontName();
-                    fontDef.setGenericFamily(FontDef::eStandard);
-                }
-                else if (face == "konq_body") {
-                    // Obtain the <body> element's font information,
-                    // and use its family list.
-                    DOM::DocumentImpl* doc = element->getDocument();
-                    if (doc && doc->isHTMLDocument()) {
-                        DOM::HTMLDocumentImpl* htmldoc = 
-                          static_cast<DOM::HTMLDocumentImpl*>(doc);
-                        DOM::HTMLElementImpl* body = htmldoc->body();
-                        if (body && body->renderer()) {
-                            FontDef& bodyFontDef = 
-                              (FontDef&)(body->renderer()->style()->htmlFont().fontDef);
-                            fontDef.family = bodyFontDef.firstFamily();
-                            fontDef.genericFamily = bodyFontDef.genericFamily;
-                            if (style->setFontDef( fontDef )) {
-                                fontDirty = true;
-                            }
-                            break;
+            if(val->primitiveType() != CSSPrimitiveValue::CSS_STRING) return;
+            QString face;
+            FontFamilyValueImpl *familyVal = static_cast<FontFamilyValueImpl *>(val);
+            if (familyVal->isKonqBody()) {
+                // Obtain the <body> element's font information,
+                // and use its family list.
+                DOM::DocumentImpl* doc = element->getDocument();
+                if (doc && doc->isHTMLDocument()) {
+                    DOM::HTMLDocumentImpl* htmldoc = static_cast<DOM::HTMLDocumentImpl*>(doc);
+                    DOM::HTMLElementImpl* body = htmldoc->body();
+                    if (body && body->renderer()) {
+                        FontDef& bodyFontDef = const_cast<FontDef &>(body->renderer()->style()->htmlFont().fontDef);
+                        fontDef.family = bodyFontDef.firstFamily();
+                        fontDef.genericFamily = bodyFontDef.genericFamily;
+                        if (style->setFontDef( fontDef )) {
+                            fontDirty = true;
                         }
+                        break;
                     }
-                    
-                    face = settings->stdFontName();
                 }
+                
+                face = settings->stdFontName();
+            } else {
+            	FontDef::GenericFamilyType type = static_cast<FontDef::GenericFamilyType>(familyVal->genericFamilyType());
+                switch (type) {
+                    case FontDef::eNone:
+                        face = familyVal->fontName();
+                        break;
+                    case FontDef::eSerif:
+                        face = settings->serifFontName();
+                        fontDef.setGenericFamily(FontDef::eSerif);
+                        break;
+                    case FontDef::eSansSerif:
+                        face = settings->serifFontName();
+                        fontDef.setGenericFamily(FontDef::eSansSerif);
+                        break;
+                    case FontDef::eCursive:
+                        face = settings->cursiveFontName();
+                        fontDef.setGenericFamily(FontDef::eCursive);
+                        break;
+                    case FontDef::eFantasy:
+                        face = settings->fantasyFontName();
+                        fontDef.setGenericFamily(FontDef::eFantasy);
+                        break;
+                    case FontDef::eMonospace:
+                        face = settings->fixedFontName();
+                        fontDef.setGenericFamily(FontDef::eMonospace);
+                        break;
+                    case FontDef::eStandard:
+                        // Actually "konq_default".
+                        // Treat this as though it's a generic family, since we will want
+                        // to reset to default sizes when we encounter this (and inherit
+                        // from an enclosing different family like monospace).
+                        face = settings->stdFontName();
+                        fontDef.setGenericFamily(FontDef::eStandard);
+                        break;
+                }
+            }
     
-                if ( !face.isEmpty() ) {
-                    if (!currFamily) {
-                        // Filling in the first family.
-                        firstFamily.setFamily(face);
-                        currFamily = &firstFamily;
-                    }
-                    else {
-                        KWQFontFamily *newFamily = new KWQFontFamily;
-                        newFamily->setFamily(face);
-                        currFamily->appendFamily(newFamily);
-                        currFamily = newFamily;
-                    }
-                    
-                    if (style->setFontDef( fontDef )) {
-                        fontDirty = true;
-                    }
+            if ( !face.isEmpty() ) {
+                if (!currFamily) {
+                    // Filling in the first family.
+                    firstFamily.setFamily(face);
+                    currFamily = &firstFamily;
+                }
+                else {
+                    KWQFontFamily *newFamily = new KWQFontFamily;
+                    newFamily->setFamily(face);
+                    currFamily->appendFamily(newFamily);
+                    currFamily = newFamily;
+                }
+                
+                if (style->setFontDef( fontDef )) {
+                    fontDirty = true;
                 }
             }
         }
diff --git a/WebCore/khtml/dom/dom_string.cpp b/WebCore/khtml/dom/dom_string.cpp
index 6c542fb..a1d37ad 100644
--- a/WebCore/khtml/dom/dom_string.cpp
+++ b/WebCore/khtml/dom/dom_string.cpp
@@ -26,11 +26,6 @@
 using namespace DOM;
 
 
-DOMString::DOMString()
-{
-    impl = 0;
-}
-
 DOMString::DOMString(const QChar *str, uint len)
 {
     impl = new DOMStringImpl( str, len );
@@ -207,7 +202,7 @@ QString DOMString::string() const
 {
     if(!impl) return QString::null;
 
-    return QConstString(impl->s, impl->l).string();
+    return QString(impl->s, impl->l);
 }
 
 int DOMString::toInt() const
@@ -287,19 +282,19 @@ bool DOM::operator==( const DOMString &a, const QString &b )
 
 bool DOM::operator==( const DOMString &a, const char *b )
 {
-    if ( !b ) return a.isNull();
-    unsigned int blen = strlen(b);
-    if ( a.isNull() ) return (blen == 0);
-    if(a.length() != blen) return false;
-
-    const QChar* aptr = a.impl->s;
-    while( blen-- ) {
-        if((*aptr++).latin1() != *b++)
-            return false;
+    DOMStringImpl *aimpl = a.impl;
+    
+    if (!b)
+        return !aimpl;
+    
+    if (aimpl) {
+        int alen = aimpl->l;
+        const QChar *aptr = aimpl->s;
+        while (alen--) {
+            unsigned char c = *b++;
+            if (!c || (*aptr++).unicode() != c)
+                return false;
+        }
     }
-
-    return true;
+    return *b == 0;
 }
-
-
-
diff --git a/WebCore/khtml/dom/dom_string.h b/WebCore/khtml/dom/dom_string.h
index b96b1a6..2e896d5 100644
--- a/WebCore/khtml/dom/dom_string.h
+++ b/WebCore/khtml/dom/dom_string.h
@@ -45,13 +45,13 @@ public:
     /**
      * default constructor. Gives an empty DOMString
      */
-    DOMString();
+    DOMString() : impl(0) { }
 
     DOMString(const QChar *str, uint len);
     DOMString(const QString &);
     DOMString(const char *str);
     DOMString(DOMStringImpl *i);
-    virtual ~DOMString();
+    ~DOMString();
 
     // assign and copy
     DOMString(const DOMString &str);
diff --git a/WebCore/khtml/html/html_objectimpl.cpp b/WebCore/khtml/html/html_objectimpl.cpp
index d37faca..adf66bf 100644
--- a/WebCore/khtml/html/html_objectimpl.cpp
+++ b/WebCore/khtml/html/html_objectimpl.cpp
@@ -181,7 +181,8 @@ NodeImpl::Id HTMLEmbedElementImpl::id() const
 void HTMLEmbedElementImpl::parseAttribute(AttributeImpl *attr)
 {
   DOM::DOMStringImpl *stringImpl = attr->val();
-  QString val = QConstString( stringImpl->s, stringImpl->l ).string();
+  QConstString cval(stringImpl->s, stringImpl->l);
+  QString val = cval.string();
 
   int pos;
   switch ( attr->id() )
diff --git a/WebCore/khtml/html/html_objectimpl.h b/WebCore/khtml/html/html_objectimpl.h
index ae542bf..e54d28a 100644
--- a/WebCore/khtml/html/html_objectimpl.h
+++ b/WebCore/khtml/html/html_objectimpl.h
@@ -118,8 +118,8 @@ public:
 
     virtual void parseAttribute(AttributeImpl *token);
 
-    QString name() const { if(!m_name) return QString::null; return QConstString(m_name->s, m_name->l).string(); }
-    QString value() const { if(!m_value) return QString::null; return QConstString(m_value->s, m_value->l).string(); }
+    QString name() const { if(!m_name) return QString::null; return QString(m_name->s, m_name->l); }
+    QString value() const { if(!m_value) return QString::null; return QString(m_value->s, m_value->l); }
 
  protected:
     DOMStringImpl *m_name;
diff --git a/WebCore/khtml/html/htmltokenizer.cpp b/WebCore/khtml/html/htmltokenizer.cpp
index a7be86b..fbc1540 100644
--- a/WebCore/khtml/html/htmltokenizer.cpp
+++ b/WebCore/khtml/html/htmltokenizer.cpp
@@ -200,6 +200,18 @@ inline void fixUpChar(QChar& c) {
 
 #endif // APPLE_CHANGES
 
+inline bool tagMatch(const char *s1, const QChar *s2, uint length)
+{
+    for (uint i = 0; i != length; ++i) {
+        char c1 = s1[i];
+        char uc1 = toupper(c1);
+        QChar c2 = s2[i];
+        if (c1 != c2 && uc1 != c2)
+            return false;
+    }
+    return true;
+}
+
 // ----------------------------------------------------------------------------
 
 HTMLTokenizer::HTMLTokenizer(DOM::DocumentPtr *_doc, KHTMLView *_view)
@@ -384,7 +396,7 @@ void HTMLTokenizer::parseSpecial(DOMStringIt &src)
     while ( src.length() ) {
         checkScriptBuffer();
         unsigned char ch = src->latin1();
-        if ( !scriptCodeResync && !brokenComments && !textarea && !xmp && !title && ch == '-' && scriptCodeSize >= 3 && !src.escaped() && QConstString( scriptCode+scriptCodeSize-3, 3 ).string() == "<!-" ) {
+        if ( !scriptCodeResync && !brokenComments && !textarea && !xmp && !title && ch == '-' && scriptCodeSize >= 3 && !src.escaped() && scriptCode[scriptCodeSize-3] == '<' && scriptCode[scriptCodeSize-2] == '!' && scriptCode[scriptCodeSize-1] == '-' ) {
             comment = true;
             parseComment( src );
             continue;
@@ -413,7 +425,7 @@ void HTMLTokenizer::parseSpecial(DOMStringIt &src)
         // possible end of tagname, lets check.
         if ( !scriptCodeResync && !escaped && !src.escaped() && ( ch == '>' || ch == '/' || ch <= ' ' ) && ch &&
              scriptCodeSize >= searchStopperLen &&
-             !QConstString( scriptCode+scriptCodeSize-searchStopperLen, searchStopperLen ).string().find( searchStopper, 0, false )) {
+             tagMatch( searchStopper, scriptCode+scriptCodeSize-searchStopperLen, searchStopperLen )) {
             scriptCodeResync = scriptCodeSize-searchStopperLen+1;
             tquote = NoQuote;
             continue;
diff --git a/WebCore/khtml/khtml_part.cpp b/WebCore/khtml/khtml_part.cpp
index 4eb2eb3..a3dba62 100644
--- a/WebCore/khtml/khtml_part.cpp
+++ b/WebCore/khtml/khtml_part.cpp
@@ -1356,7 +1356,7 @@ void KHTMLPart::begin( const KURL &url, int xOffset, int yOffset )
 #endif
 
   // ### not sure if XHTML documents served as text/xml should use DocumentImpl or HTMLDocumentImpl
-#ifndef APPLE_CHANGES
+#if !APPLE_CHANGES
   // We can't deal with XML yet, so just give it an HTML document for now. -dwh
   if (args.serviceType == "text/xml")
     d->m_doc = DOMImplementationImpl::instance()->createDocument( d->m_view );
@@ -1407,22 +1407,44 @@ void KHTMLPart::begin( const KURL &url, int xOffset, int yOffset )
 
 void KHTMLPart::write( const char *str, int len )
 {
-    if ( !d->m_decoder ) {
-        d->m_decoder = new khtml::Decoder();
-        if(d->m_encoding != QString::null)
-            d->m_decoder->setEncoding(d->m_encoding.latin1(), d->m_haveEncoding);
-        else
-            d->m_decoder->setEncoding(settings()->encoding().latin1(), d->m_haveEncoding);
+  bool allASCII = !d->m_decoder;
+  const char *p = str;
+  if ( len == -1 ) {
+    len = 0;
+    unsigned char c;
+    while ( (c = *p++) ) {
+      ++len;
+      if (c > 0x7F)
+        allASCII = false;
+    }
+  } else {
+    int l = len;
+    while ( allASCII && l-- ) {
+      unsigned char c = *p++;
+      if (c > 0x7F)
+        allASCII = false;
     }
+  }
+
   if ( len == 0 )
     return;
 
-  if ( len == -1 )
-    len = strlen( str );
-
-  QString decoded = d->m_decoder->decode( str, len );
-
-  if(decoded.isEmpty()) return;
+  QString decoded;
+  if (allASCII)
+    decoded = QString(str, len);
+  else {
+    if ( !d->m_decoder ) {
+      d->m_decoder = new khtml::Decoder;
+      if (!d->m_encoding.isNull())
+        d->m_decoder->setEncoding(d->m_encoding.latin1(), d->m_haveEncoding);
+      else
+        d->m_decoder->setEncoding(settings()->encoding().latin1(), d->m_haveEncoding);
+      // ### this is still quite hacky, but should work a lot better than the old solution
+      if(d->m_decoder->visuallyOrdered()) d->m_doc->setVisuallyOrdered();
+    }
+    decoded = d->m_decoder->decode( str, len );
+    if(decoded.isEmpty()) return;
+  }
 
   if(d->m_bFirstData) {
       // determine the parse mode
@@ -1430,8 +1452,6 @@ void KHTMLPart::write( const char *str, int len )
       d->m_bFirstData = false;
 
   //kdDebug(6050) << "KHTMLPart::write haveEnc = " << d->m_haveEncoding << endl;
-      // ### this is still quite hacky, but should work a lot better than the old solution
-      if(d->m_decoder->visuallyOrdered()) d->m_doc->setVisuallyOrdered();
       d->m_doc->recalcStyle( NodeImpl::Force );
   }
 
diff --git a/WebCore/khtml/misc/helper.cpp b/WebCore/khtml/misc/helper.cpp
index 97541e1..e4a7ac4 100644
--- a/WebCore/khtml/misc/helper.cpp
+++ b/WebCore/khtml/misc/helper.cpp
@@ -273,7 +273,11 @@ void khtml::setNamedColor(QColor &color, const QString &_name)
             color = tc;
         else {
             color.setNamedColor(name);
+#if !APPLE_CHANGES
+            // The KWQ version of QColor::setNamedColor already has to lowercase the string.
+            // So this is wasted work, and it even shows up in profiles.
             if ( !color.isValid() )  color.setNamedColor( name.lower() );
+#endif
             if(!color.isValid()) {
                 bool hasalpha = false;
                 for(unsigned int i = 0; i < name.length(); i++)
diff --git a/WebCore/khtml/rendering/font.cpp b/WebCore/khtml/rendering/font.cpp
index 5cdbd3a..434c126 100644
--- a/WebCore/khtml/rendering/font.cpp
+++ b/WebCore/khtml/rendering/font.cpp
@@ -23,6 +23,7 @@
  */
 
 #include "font.h"
+
 #include "khtml_factory.h"
 #include "khtml_settings.h"
 
@@ -37,7 +38,7 @@
 
 using namespace khtml;
 
-#ifdef APPLE_CHANGES
+#if APPLE_CHANGES
 void Font::drawLineForText( QPainter *p, int x, int y, QChar *str, int slen, int pos, int len,
                      int toAdd, int yOffset, QPainter::TextDirection d) const
 {
@@ -189,15 +190,16 @@ void Font::update( QPaintDeviceMetrics* devMetrics ) const
 	f.setFamily(KHTMLFactory::defaultHTMLSettings()->stdFontName());
     else
 	f.setFirstFamily(fontDef.family);
+    f.setItalic(fontDef.italic);
+    f.setWeight(fontDef.weight);
+    f.setPixelSize(fontDef.size);
+
+    fm.setFont(f);
 #else
     f.setFamily( fontDef.family.isEmpty() ? KHTMLFactory::defaultHTMLSettings()->stdFontName() : fontDef.family );
-#endif
     f.setItalic( fontDef.italic );
     f.setWeight( fontDef.weight );
 
-#if APPLE_CHANGES
-    f.setPixelSize(fontDef.size);
-#else
     QFontDatabase db;
 
     int size = fontDef.size;
@@ -239,11 +241,9 @@ void Font::update( QPaintDeviceMetrics* devMetrics ) const
 
 
     f.setPixelSize( size );
-#endif
 
     fm = QFontMetrics( f );
 
-#if !APPLE_CHANGES
     fontDef.hasNbsp = fm.inFont( 0xa0 );
 #endif
 }
diff --git a/WebCore/khtml/rendering/font.h b/WebCore/khtml/rendering/font.h
index 005f01a..643b279 100644
--- a/WebCore/khtml/rendering/font.h
+++ b/WebCore/khtml/rendering/font.h
@@ -74,10 +74,15 @@ class Font
     friend class CSSStyleSelector;
 
 public:
+#if APPLE_CHANGES
+    Font() : letterSpacing(0), wordSpacing(0) {}
+    Font(const FontDef &fd) : fontDef(fd), letterSpacing(0), wordSpacing(0) {}
+#else
     Font() : fontDef(), f(), fm( f ), scFont( 0 ), letterSpacing( 0 ), wordSpacing( 0 ) {}
     Font( const FontDef &fd )
         :  fontDef( fd ), f(), fm( f ), scFont( 0 ), letterSpacing( 0 ), wordSpacing( 0 )
         {}
+#endif
 
     bool operator == ( const Font &other ) const {
         return (fontDef == other.fontDef &&
@@ -104,12 +109,13 @@ private:
     FontDef fontDef;
     mutable QFont f;
     mutable QFontMetrics fm;
+#if !APPLE_CHANGES
     QFont *scFont;
+#endif
     short letterSpacing;
     short wordSpacing;
 };
 
 };
 
-
 #endif
diff --git a/WebCore/khtml/rendering/render_object.cpp b/WebCore/khtml/rendering/render_object.cpp
index 11a62a0..ee9dcd6 100644
--- a/WebCore/khtml/rendering/render_object.cpp
+++ b/WebCore/khtml/rendering/render_object.cpp
@@ -202,7 +202,9 @@ RenderLayer* RenderObject::enclosingLayer()
 {
     RenderObject* curr = this;
     while (curr) {
-        if (curr->layer()) return curr->layer();
+        RenderLayer *layer = curr->layer();
+        if (layer)
+            return layer;
         curr = curr->parent();
     }
     return 0;
diff --git a/WebCore/khtml/xml/dom_stringimpl.cpp b/WebCore/khtml/xml/dom_stringimpl.cpp
index 881228d..1d3023e 100644
--- a/WebCore/khtml/xml/dom_stringimpl.cpp
+++ b/WebCore/khtml/xml/dom_stringimpl.cpp
@@ -130,17 +130,20 @@ DOMStringImpl *DOMStringImpl::split(uint pos)
 
 bool DOMStringImpl::containsOnlyWhitespace() const
 {
-  if (!s)
-    return true;
+    if (!s)
+        return true;
     
-  unsigned int i;
-  QChar tab('\t');
-  QChar ret('\r');
-  QChar lf('\n');
-  for (i = 0; i < l; i++)
-    if (s[i].direction() != QChar::DirWS && s[i] != tab && s[i] != ret && s[i] != lf)
-	    return false;
-  return true;
+    for (uint i = 0; i < l; i++) {
+        QChar c = s[i];
+        if (c.unicode() <= 0x7F) {
+            if (!isspace(c.unicode()))
+                return false;
+        } else {
+            if (c.direction() != QChar::DirWS)
+                return false;
+        }
+    }
+    return true;
 }
     
 DOMStringImpl *DOMStringImpl::substring(uint pos, uint len)
diff --git a/WebCore/kwq/KWQColor.mm b/WebCore/kwq/KWQColor.mm
index ad08522..8aa7db9 100644
--- a/WebCore/kwq/KWQColor.mm
+++ b/WebCore/kwq/KWQColor.mm
@@ -29,6 +29,8 @@
 #import "KWQString.h"
 #import "KWQAssertions.h"
 
+#import "KWQColorData.c"
+
 const QColor Qt::black    (0x00, 0x00, 0x00);
 const QColor Qt::white    (0xFF, 0xFF, 0xFF);
 const QColor Qt::darkGray (0x80, 0x80, 0x80);
@@ -41,168 +43,6 @@ const QColor Qt::cyan     (0x00, 0xFF, 0xFF);
 const QColor Qt::magenta  (0xFF, 0x00, 0xFF);
 const QColor Qt::yellow   (0xFF, 0xFF, 0x00);
 
-static NSDictionary *getNamedColors()
-{
-    static NSDictionary *namedColors;
-    
-    if (namedColors)
-        return namedColors;
-    
-    namedColors = [[NSDictionary alloc] initWithObjectsAndKeys:
-        @"#f0f8ff", @"aliceblue",
-        @"#faebd7", @"antiquewhite",
-        @"#00ffff", @"aqua",
-        @"#7fffd4", @"aquamarine",
-        @"#f0ffff", @"azure",
-        @"#f5f5dc", @"beige",
-        @"#ffe4c4", @"bisque",
-        @"#000000", @"black",
-        @"#ffebcd", @"blanchedalmond",
-        @"#0000ff", @"blue",
-        @"#8a2be2", @"blueviolet",
-        @"#a52a2a", @"brown",
-        @"#deb887", @"burlywood",
-        @"#5f9ea0", @"cadetblue",
-        @"#7fff00", @"chartreuse",
-        @"#d2691e", @"chocolate",
-        @"#ff7f50", @"coral",
-        @"#6495ed", @"cornflowerblue",
-        @"#fff8dc", @"cornsilk",
-        @"#dc143c", @"crimson",
-        @"#00ffff", @"cyan",
-        @"#00008b", @"darkblue",
-        @"#008b8b", @"darkcyan",
-        @"#b8860b", @"darkgoldenrod",
-        @"#a9a9a9", @"darkgray",
-        @"#a9a9a9", @"darkgrey",
-        @"#006400", @"darkgreen",
-        @"#bdb76b", @"darkkhaki",
-        @"#8b008b", @"darkmagenta",
-        @"#556b2f", @"darkolivegreen",
-        @"#ff8c00", @"darkorange",
-        @"#9932cc", @"darkorchid",
-        @"#8b0000", @"darkred",
-        @"#e9967a", @"darksalmon",
-        @"#8fbc8f", @"darkseagreen",
-        @"#483d8b", @"darkslateblue",
-        @"#2f4f4f", @"darkslategray",
-        @"#2f4f4f", @"darkslategrey",
-        @"#00ced1", @"darkturquoise",
-        @"#9400d3", @"darkviolet",
-        @"#ff1493", @"deeppink",
-        @"#00bfff", @"deepskyblue",
-        @"#696969", @"dimgray",
-        @"#696969", @"dimgrey",
-        @"#1e90ff", @"dodgerblue",
-        @"#b22222", @"firebrick",
-        @"#fffaf0", @"floralwhite",
-        @"#228b22", @"forestgreen",
-        @"#ff00ff", @"fuchsia",
-        @"#dcdcdc", @"gainsboro",
-        @"#f8f8ff", @"ghostwhite",
-        @"#ffd700", @"gold",
-        @"#daa520", @"goldenrod",
-        @"#808080", @"gray",
-        @"#808080", @"grey",
-        @"#008000", @"green",
-        @"#adff2f", @"greenyellow",
-        @"#f0fff0", @"honeydew",
-        @"#ff69b4", @"hotpink",
-        @"#cd5c5c", @"indianred",
-        @"#4b0082", @"indigo",
-        @"#fffff0", @"ivory",
-        @"#f0e68c", @"khaki",
-        @"#e6e6fa", @"lavender",
-        @"#fff0f5", @"lavenderblush",
-        @"#7cfc00", @"lawngreen",
-        @"#fffacd", @"lemonchiffon",
-        @"#add8e6", @"lightblue",
-        @"#f08080", @"lightcoral",
-        @"#e0ffff", @"lightcyan",
-        @"#fafad2", @"lightgoldenrodyellow",
-        @"#d3d3d3", @"lightgray",
-        @"#d3d3d3", @"lightgrey",
-        @"#90ee90", @"lightgreen",
-        @"#ffb6c1", @"lightpink",
-        @"#ffa07a", @"lightsalmon",
-        @"#20b2aa", @"lightseagreen",
-        @"#87cefa", @"lightskyblue",
-        @"#8470ff", @"lightslateblue",
-        @"#778899", @"lightslategray",
-        @"#778899", @"lightslategrey",
-        @"#b0c4de", @"lightsteelblue",
-        @"#ffffe0", @"lightyellow",
-        @"#00ff00", @"lime",
-        @"#32cd32", @"limegreen",
-        @"#faf0e6", @"linen",
-        @"#ff00ff", @"magenta",
-        @"#800000", @"maroon",
-        @"#66cdaa", @"mediumaquamarine",
-        @"#0000cd", @"mediumblue",
-        @"#ba55d3", @"mediumorchid",
-        @"#9370d8", @"mediumpurple",
-        @"#3cb371", @"mediumseagreen",
-        @"#7b68ee", @"mediumslateblue",
-        @"#00fa9a", @"mediumspringgreen",
-        @"#48d1cc", @"mediumturquoise",
-        @"#c71585", @"mediumvioletred",
-        @"#191970", @"midnightblue",
-        @"#f5fffa", @"mintcream",
-        @"#ffe4e1", @"mistyrose",
-        @"#ffe4b5", @"moccasin",
-        @"#ffdead", @"navajowhite",
-        @"#000080", @"navy",
-        @"#fdf5e6", @"oldlace",
-        @"#808000", @"olive",
-        @"#6b8e23", @"olivedrab",
-        @"#ffa500", @"orange",
-        @"#ff4500", @"orangered",
-        @"#da70d6", @"orchid",
-        @"#eee8aa", @"palegoldenrod",
-        @"#98fb98", @"palegreen",
-        @"#afeeee", @"paleturquoise",
-        @"#d87093", @"palevioletred",
-        @"#ffefd5", @"papayawhip",
-        @"#ffdab9", @"peachpuff",
-        @"#cd853f", @"peru",
-        @"#ffc0cb", @"pink",
-        @"#dda0dd", @"plum",
-        @"#b0e0e6", @"powderblue",
-        @"#800080", @"purple",
-        @"#ff0000", @"red",
-        @"#bc8f8f", @"rosybrown",
-        @"#4169e1", @"royalblue",
-        @"#8b4513", @"saddlebrown",
-        @"#fa8072", @"salmon",
-        @"#f4a460", @"sandybrown",
-        @"#2e8b57", @"seagreen",
-        @"#fff5ee", @"seashell",
-        @"#a0522d", @"sienna",
-        @"#c0c0c0", @"silver",
-        @"#87ceeb", @"skyblue",
-        @"#6a5acd", @"slateblue",
-        @"#708090", @"slategray",
-        @"#708090", @"slategrey",
-        @"#fffafa", @"snow",
-        @"#00ff7f", @"springgreen",
-        @"#4682b4", @"steelblue",
-        @"#d2b48c", @"tan",
-        @"#008080", @"teal",
-        @"#d8bfd8", @"thistle",
-        @"#ff6347", @"tomato",
-        @"#40e0d0", @"turquoise",
-        @"#ee82ee", @"violet",
-        @"#d02090", @"violetred",
-        @"#f5deb3", @"wheat",
-        @"#ffffff", @"white",
-        @"#f5f5f5", @"whitesmoke",
-        @"#ffff00", @"yellow",
-        @"#9acd32", @"yellowgreen",
-    nil];
-    
-    return namedColors;
-}
-
 QRgb qRgb(int r, int g, int b)
 {
     return r << 16 | g << 8 | b;
@@ -237,8 +77,6 @@ static int hex2int(QChar hexchar)
     
     if (hexchar.isDigit())
 	v = hexchar.digitValue();
-    else if (hexchar >= 'A' && hexchar <= 'F')
-	v = hexchar.cell() - 'A' + 10;
     else if (hexchar >= 'a' && hexchar <= 'f')
 	v = hexchar.cell() - 'a' + 10;
     else
@@ -326,16 +164,18 @@ void QColor::setNamedColor(const QString &name)
     } 
     
     int r, g, b;
-    NSString *hexString = [getNamedColors() objectForKey:[name.getNSString() lowercaseString]];
-    if (hexString && decodeColorFromHexColorString(QString::fromNSString(hexString), &r, &g, &b)) {
-        setRgb(r, g, b);
+    QString lowerName = name.lower();
+    const Color *foundColor = findColor(name.latin1(), name.length());
+    if (foundColor) {
+        int RGBValue = foundColor->RGBValue;
+        setRgb((RGBValue >> 16) & 0xFF, (RGBValue >> 8) & 0xFF, RGBValue & 0xFF);
         return;
     }
 
-    if (decodeColorFromHexColorString(name, &r, &g, &b)) {
+    if (decodeColorFromHexColorString(lowerName, &r, &g, &b)) {
         setRgb(r, g, b);
         return;
-    } 
+    }
 
     ERROR("couldn't create color using name %s", name.ascii());
     color = KWQInvalidColor;
diff --git a/WebCore/kwq/KWQColorData.c b/WebCore/kwq/KWQColorData.c
new file mode 100644
index 0000000..93e33fb
--- /dev/null
+++ b/WebCore/kwq/KWQColorData.c
@@ -0,0 +1,448 @@
+/* ANSI-C code produced by gperf version 2.7.2 */
+/* Command-line: gperf -CDEot -L ANSI-C -k '*' -N findColor KWQColorData.gperf  */
+struct Color { const char *name; int RGBValue; };
+/* maximum key range = 1178, duplicates = 1 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static unsigned int
+hash (register const char *str, register unsigned int len)
+{
+  static const unsigned short asso_values[] =
+    {
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181,   10,  249,   55,
+         0,    0,    0,    5,   10,    0,    0,   15,    0,  110,
+         0,    0,  250,    5,    0,   10,   15,  150,  148,  240,
+      1181,  140,    5, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+      1181, 1181, 1181, 1181, 1181, 1181
+    };
+  register int hval = len;
+
+  switch (hval)
+    {
+      default:
+      case 20:
+        hval += asso_values[(unsigned char)str[19]];
+      case 19:
+        hval += asso_values[(unsigned char)str[18]];
+      case 18:
+        hval += asso_values[(unsigned char)str[17]];
+      case 17:
+        hval += asso_values[(unsigned char)str[16]];
+      case 16:
+        hval += asso_values[(unsigned char)str[15]];
+      case 15:
+        hval += asso_values[(unsigned char)str[14]];
+      case 14:
+        hval += asso_values[(unsigned char)str[13]];
+      case 13:
+        hval += asso_values[(unsigned char)str[12]];
+      case 12:
+        hval += asso_values[(unsigned char)str[11]];
+      case 11:
+        hval += asso_values[(unsigned char)str[10]];
+      case 10:
+        hval += asso_values[(unsigned char)str[9]];
+      case 9:
+        hval += asso_values[(unsigned char)str[8]];
+      case 8:
+        hval += asso_values[(unsigned char)str[7]];
+      case 7:
+        hval += asso_values[(unsigned char)str[6]];
+      case 6:
+        hval += asso_values[(unsigned char)str[5]];
+      case 5:
+        hval += asso_values[(unsigned char)str[4]];
+      case 4:
+        hval += asso_values[(unsigned char)str[3]];
+      case 3:
+        hval += asso_values[(unsigned char)str[2]];
+      case 2:
+        hval += asso_values[(unsigned char)str[1]];
+      case 1:
+        hval += asso_values[(unsigned char)str[0]];
+        break;
+    }
+  return hval;
+}
+
+#ifdef __GNUC__
+__inline
+#endif
+const struct Color *
+findColor (register const char *str, register unsigned int len)
+{
+  enum
+    {
+      TOTAL_KEYWORDS = 149,
+      MIN_WORD_LENGTH = 3,
+      MAX_WORD_LENGTH = 20,
+      MIN_HASH_VALUE = 3,
+      MAX_HASH_VALUE = 1180
+    };
+
+  static const struct Color wordlist[] =
+    {
+      {"red", 0xff0000},
+      {"linen", 0xfaf0e6},
+      {"gold", 0xffd700},
+      {"green", 0x008000},
+      {"indigo", 0x4b0082},
+      {"goldenrod", 0xdaa520},
+      {"indianred", 0xcd5c5c},
+      {"orange", 0xffa500},
+      {"orangered", 0xff4500},
+      {"sienna", 0xa0522d},
+      {"tan", 0xd2b48c},
+      {"teal", 0x008080},
+      {"darkred", 0x8b0000},
+      {"seagreen", 0x2e8b57},
+      {"darkgreen", 0x006400},
+      {"forestgreen", 0x228b22},
+      {"darkgoldenrod", 0xb8860b},
+      {"lightgreen", 0x90ee90},
+      {"seashell", 0xfff5ee},
+      {"darkorange", 0xff8c00},
+      {"khaki", 0xf0e68c},
+      {"thistle", 0xd8bfd8},
+      {"darkseagreen", 0x8fbc8f},
+      {"lightseagreen", 0x20b2aa},
+      {"coral", 0xff7f50},
+      {"orchid", 0xda70d6},
+      {"oldlace", 0xfdf5e6},
+      {"darkkhaki", 0xbdb76b},
+      {"cornsilk", 0xfff8dc},
+      {"darkorchid", 0x9932cc},
+      {"lightcoral", 0xf08080},
+      {"lime", 0x00ff00},
+      {"limegreen", 0x32cd32},
+      {"maroon", 0x800000},
+      {"salmon", 0xfa8072},
+      {"grey", 0x808080},
+      {"olive", 0x808000},
+      {"chocolate", 0xd2691e},
+      {"tomato", 0xff6347},
+      {"magenta", 0xff00ff},
+      {"gray", 0x808080},
+      {"silver", 0xc0c0c0},
+      {"darksalmon", 0xe9967a},
+      {"lavender", 0xe6e6fa},
+      {"violet", 0xee82ee},
+      {"azure", 0xf0ffff},
+      {"lightsalmon", 0xffa07a},
+      {"violetred", 0xd02090},
+      {"darkgrey", 0xa9a9a9},
+      {"aqua", 0x00ffff},
+      {"crimson", 0xdc143c},
+      {"lightgrey", 0xd3d3d3},
+      {"darkmagenta", 0x8b008b},
+      {"lemonchiffon", 0xfffacd},
+      {"darkgray", 0xa9a9a9},
+      {"slategrey", 0x708090},
+      {"darkolivegreen", 0x556b2f},
+      {"lightgray", 0xd3d3d3},
+      {"darkviolet", 0x9400d3},
+      {"slategray", 0x708090},
+      {"cyan", 0x00ffff},
+      {"darkslategrey", 0x2f4f4f},
+      {"lightslategrey", 0x778899},
+      {"darkslategray", 0x2f4f4f},
+      {"lightslategray", 0x778899},
+      {"darkcyan", 0x008b8b},
+      {"fuchsia", 0xff00ff},
+      {"lightcyan", 0xe0ffff},
+      {"moccasin", 0xffe4b5},
+      {"snow", 0xfffafa},
+      {"beige", 0xf5f5dc},
+      {"chartreuse", 0x7fff00},
+      {"dimgrey", 0x696969},
+      {"lawngreen", 0x7cfc00},
+      {"pink", 0xffc0cb},
+      {"white", 0xffffff},
+      {"dimgray", 0x696969},
+      {"palegreen", 0x98fb98},
+      {"palegoldenrod", 0xeee8aa},
+      {"wheat", 0xf5deb3},
+      {"springgreen", 0x00ff7f},
+      {"gainsboro", 0xdcdcdc},
+      {"floralwhite", 0xfffaf0},
+      {"ivory", 0xfffff0},
+      {"mistyrose", 0xffe4e1},
+      {"hotpink", 0xff69b4},
+      {"navy", 0x000080},
+      {"lightpink", 0xffb6c1},
+      {"aquamarine", 0x7fffd4},
+      {"mintcream", 0xf5fffa},
+      {"ghostwhite", 0xf8f8ff},
+      {"firebrick", 0xb22222},
+      {"black", 0x000000},
+      {"turquoise", 0x40e0d0},
+      {"darkturquoise", 0x00ced1},
+      {"yellow", 0xffff00},
+      {"greenyellow", 0xadff2f},
+      {"yellowgreen", 0x9acd32},
+      {"honeydew", 0xf0fff0},
+      {"blue", 0x0000ff},
+      {"peru", 0xcd853f},
+      {"mediumseagreen", 0x3cb371},
+      {"whitesmoke", 0xf5f5f5},
+      {"dodgerblue", 0x1e90ff},
+      {"olivedrab", 0x6b8e23},
+      {"bisque", 0xffe4c4},
+      {"lightyellow", 0xffffe0},
+      {"darkblue", 0x00008b},
+      {"steelblue", 0x4682b4},
+      {"lightgoldenrodyellow", 0xfafad2},
+      {"palevioletred", 0xd87093},
+      {"lightblue", 0xadd8e6},
+      {"slateblue", 0x6a5acd},
+      {"navajowhite", 0xffdead},
+      {"mediumorchid", 0xba55d3},
+      {"antiquewhite", 0xfaebd7},
+      {"blanchedalmond", 0xffebcd},
+      {"lightsteelblue", 0xb0c4de},
+      {"darkslateblue", 0x483d8b},
+      {"aliceblue", 0xf0f8ff},
+      {"lightslateblue", 0x8470ff},
+      {"cadetblue", 0x5f9ea0},
+      {"brown", 0xa52a2a},
+      {"plum", 0xdda0dd},
+      {"saddlebrown", 0x8b4513},
+      {"deeppink", 0xff1493},
+      {"mediumvioletred", 0xc71585},
+      {"midnightblue", 0x191970},
+      {"royalblue", 0x4169e1},
+      {"skyblue", 0x87ceeb},
+      {"blueviolet", 0x8a2be2},
+      {"lavenderblush", 0xfff0f5},
+      {"paleturquoise", 0xafeeee},
+      {"lightskyblue", 0x87cefa},
+      {"rosybrown", 0xbc8f8f},
+      {"purple", 0x800080},
+      {"mediumspringgreen", 0x00fa9a},
+      {"sandybrown", 0xf4a460},
+      {"mediumaquamarine", 0x66cdaa},
+      {"cornflowerblue", 0x6495ed},
+      {"mediumturquoise", 0x48d1cc},
+      {"peachpuff", 0xffdab9},
+      {"mediumblue", 0x0000cd},
+      {"burlywood", 0xdeb887},
+      {"mediumslateblue", 0x7b68ee},
+      {"deepskyblue", 0x00bfff},
+      {"powderblue", 0xb0e0e6},
+      {"mediumpurple", 0x9370d8},
+      {"papayawhip", 0xffefd5}
+    };
+
+  static const short lookup[] =
+    {
+        -1,   -1,   -1,    0,   -1,    1,   -1,   -1,
+        -1,    2,    3,    4,   -1,   -1,    5,   -1,
+        -1,   -1,   -1,    6,   -1,    7,   -1,   -1,
+         8,   -1,    9,   -1,   10,   11,   -1,   -1,
+        12,   13,   -1,   -1,   -1,   -1,   -1,   14,
+        -1,   15,   -1,   16,   -1,   17,   -1,   -1,
+        18,   -1,   19,   -1,   -1,   -1,   -1,   20,
+        -1,   21,   -1,   -1,   -1,   -1,   22,   -1,
+        -1,   -1,   -1,   -1,   23,   -1,   24,   25,
+        26,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   27,   -1,   -1,   -1,
+        28,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   29,   -1,   -1,   -1,
+        -1,   30,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   31,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   32,   -1,   33,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        34,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   35,   -1,   -1,
+        -1,   36,   37,   -1,   38,   39,   -1,   40,
+        -1,   -1,   -1,   -1,   41,   42,   43,   -1,
+        -1,   44,   45,   46,   47,   -1,   -1,   -1,
+        -1,   -1,   48,   49,   -1,   -1,   50,   -1,
+        51,   -1,   52,   53,   54,   55,   -1,   -1,
+        56,   -1,   57,   -1,   -1,   -1,   58,   59,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   60,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   61,   -1,   -1,   -1,   -1,   -1,
+        62,   -1,   -1,   -1,   63,   -1,   -1,   -1,
+        -1,   -1,   64,   -1,   -1,   -1,   65,   -1,
+        -1,   -1,   66,   -1,   67,   -1,   -1,   -1,
+        68,   -1,   -1,   -1,   -1,   -1,   69,   -1,
+        -1,   -1,   -1,   70,   71,   -1,   72,   -1,
+        73,   -1,   -1,   -1,   -1,   74,   75,   -1,
+        76,   -1,   77,   -1,   -1,   -1,   78,   -1,
+        79,   80,   -1,   81,   -1,   -1,   82,   -1,
+        -1,   -1,   -1,   -1,   -1,   83,   84,   -1,
+        -1,   85,   -1,   -1,   -1,   -1,   86,   -1,
+        87,   88,   -1,   -1,   -1,   89,   -1,   -1,
+        -1,   -1,   -1,   90,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        91,   -1,   -1,   -1,   -1,   -1,   92,   -1,
+        -1,   -1,   -1,   93,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        94,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   95,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, -549,   -1,   98,  -53,
+        -2,   -1,   -1,   99,  100,   -1,   -1,   -1,
+        -1,  101,  102,   -1,   -1,   -1,  103,   -1,
+       104,   -1,   -1,   -1,  105,  106,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       107,  108,   -1,  109,  110,   -1,  111,   -1,
+        -1,   -1,   -1,  112,  113,   -1,   -1,  114,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,  115,  116,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  117,   -1,   -1,   -1,
+       118,  119,   -1,   -1,   -1,   -1,  120,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       121,   -1,   -1,   -1,   -1,   -1,  122,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  123,   -1,   -1,   -1,   -1,   -1,
+       124,   -1,   -1,  125,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  126,   -1,   -1,  127,
+        -1,   -1,   -1,   -1,   -1,   -1,  128,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  129,  130,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  131,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  132,   -1,   -1,  133,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       134,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       135,  136,   -1,  137,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,  138,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  139,   -1,   -1,   -1,
+        -1,   -1,   -1,  140,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  141,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  142,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  143,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  144,   -1,   -1,   -1,   -1,
+        -1,  145,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  146,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       147,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  148
+    };
+
+  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+    {
+      register int key = hash (str, len);
+
+      if (key <= MAX_HASH_VALUE && key >= 0)
+        {
+          register int index = lookup[key];
+
+          if (index >= 0)
+            {
+              register const char *s = wordlist[index].name;
+
+              if (*str == *s && !strcmp (str + 1, s + 1))
+                return &wordlist[index];
+            }
+          else if (index < -TOTAL_KEYWORDS)
+            {
+              register int offset = - 1 - TOTAL_KEYWORDS - index;
+              register const struct Color *wordptr = &wordlist[TOTAL_KEYWORDS + lookup[offset]];
+              register const struct Color *wordendptr = wordptr + -lookup[offset + 1];
+
+              while (wordptr < wordendptr)
+                {
+                  register const char *s = wordptr->name;
+
+                  if (*str == *s && !strcmp (str + 1, s + 1))
+                    return wordptr;
+                  wordptr++;
+                }
+            }
+        }
+    }
+  return 0;
+}
diff --git a/WebCore/kwq/KWQColorData.gperf b/WebCore/kwq/KWQColorData.gperf
new file mode 100644
index 0000000..3edc29c
--- /dev/null
+++ b/WebCore/kwq/KWQColorData.gperf
@@ -0,0 +1,151 @@
+struct Color { const char *name; int RGBValue; };
+%%
+aliceblue, 0xf0f8ff
+antiquewhite, 0xfaebd7
+aqua, 0x00ffff
+aquamarine, 0x7fffd4
+azure, 0xf0ffff
+beige, 0xf5f5dc
+bisque, 0xffe4c4
+black, 0x000000
+blanchedalmond, 0xffebcd
+blue, 0x0000ff
+blueviolet, 0x8a2be2
+brown, 0xa52a2a
+burlywood, 0xdeb887
+cadetblue, 0x5f9ea0
+chartreuse, 0x7fff00
+chocolate, 0xd2691e
+coral, 0xff7f50
+cornflowerblue, 0x6495ed
+cornsilk, 0xfff8dc
+crimson, 0xdc143c
+cyan, 0x00ffff
+darkblue, 0x00008b
+darkcyan, 0x008b8b
+darkgoldenrod, 0xb8860b
+darkgray, 0xa9a9a9
+darkgrey, 0xa9a9a9
+darkgreen, 0x006400
+darkkhaki, 0xbdb76b
+darkmagenta, 0x8b008b
+darkolivegreen, 0x556b2f
+darkorange, 0xff8c00
+darkorchid, 0x9932cc
+darkred, 0x8b0000
+darksalmon, 0xe9967a
+darkseagreen, 0x8fbc8f
+darkslateblue, 0x483d8b
+darkslategray, 0x2f4f4f
+darkslategrey, 0x2f4f4f
+darkturquoise, 0x00ced1
+darkviolet, 0x9400d3
+deeppink, 0xff1493
+deepskyblue, 0x00bfff
+dimgray, 0x696969
+dimgrey, 0x696969
+dodgerblue, 0x1e90ff
+firebrick, 0xb22222
+floralwhite, 0xfffaf0
+forestgreen, 0x228b22
+fuchsia, 0xff00ff
+gainsboro, 0xdcdcdc
+ghostwhite, 0xf8f8ff
+gold, 0xffd700
+goldenrod, 0xdaa520
+gray, 0x808080
+grey, 0x808080
+green, 0x008000
+greenyellow, 0xadff2f
+honeydew, 0xf0fff0
+hotpink, 0xff69b4
+indianred, 0xcd5c5c
+indigo, 0x4b0082
+ivory, 0xfffff0
+khaki, 0xf0e68c
+lavender, 0xe6e6fa
+lavenderblush, 0xfff0f5
+lawngreen, 0x7cfc00
+lemonchiffon, 0xfffacd
+lightblue, 0xadd8e6
+lightcoral, 0xf08080
+lightcyan, 0xe0ffff
+lightgoldenrodyellow, 0xfafad2
+lightgray, 0xd3d3d3
+lightgrey, 0xd3d3d3
+lightgreen, 0x90ee90
+lightpink, 0xffb6c1
+lightsalmon, 0xffa07a
+lightseagreen, 0x20b2aa
+lightskyblue, 0x87cefa
+lightslateblue, 0x8470ff
+lightslategray, 0x778899
+lightslategrey, 0x778899
+lightsteelblue, 0xb0c4de
+lightyellow, 0xffffe0
+lime, 0x00ff00
+limegreen, 0x32cd32
+linen, 0xfaf0e6
+magenta, 0xff00ff
+maroon, 0x800000
+mediumaquamarine, 0x66cdaa
+mediumblue, 0x0000cd
+mediumorchid, 0xba55d3
+mediumpurple, 0x9370d8
+mediumseagreen, 0x3cb371
+mediumslateblue, 0x7b68ee
+mediumspringgreen, 0x00fa9a
+mediumturquoise, 0x48d1cc
+mediumvioletred, 0xc71585
+midnightblue, 0x191970
+mintcream, 0xf5fffa
+mistyrose, 0xffe4e1
+moccasin, 0xffe4b5
+navajowhite, 0xffdead
+navy, 0x000080
+oldlace, 0xfdf5e6
+olive, 0x808000
+olivedrab, 0x6b8e23
+orange, 0xffa500
+orangered, 0xff4500
+orchid, 0xda70d6
+palegoldenrod, 0xeee8aa
+palegreen, 0x98fb98
+paleturquoise, 0xafeeee
+palevioletred, 0xd87093
+papayawhip, 0xffefd5
+peachpuff, 0xffdab9
+peru, 0xcd853f
+pink, 0xffc0cb
+plum, 0xdda0dd
+powderblue, 0xb0e0e6
+purple, 0x800080
+red, 0xff0000
+rosybrown, 0xbc8f8f
+royalblue, 0x4169e1
+saddlebrown, 0x8b4513
+salmon, 0xfa8072
+sandybrown, 0xf4a460
+seagreen, 0x2e8b57
+seashell, 0xfff5ee
+sienna, 0xa0522d
+silver, 0xc0c0c0
+skyblue, 0x87ceeb
+slateblue, 0x6a5acd
+slategray, 0x708090
+slategrey, 0x708090
+snow, 0xfffafa
+springgreen, 0x00ff7f
+steelblue, 0x4682b4
+tan, 0xd2b48c
+teal, 0x008080
+thistle, 0xd8bfd8
+tomato, 0xff6347
+turquoise, 0x40e0d0
+violet, 0xee82ee
+violetred, 0xd02090
+wheat, 0xf5deb3
+white, 0xffffff
+whitesmoke, 0xf5f5f5
+yellow, 0xffff00
+yellowgreen, 0x9acd32
diff --git a/WebCore/kwq/KWQFontMetrics.h b/WebCore/kwq/KWQFontMetrics.h
index 3f173ac..1f4cf25 100644
--- a/WebCore/kwq/KWQFontMetrics.h
+++ b/WebCore/kwq/KWQFontMetrics.h
@@ -36,12 +36,16 @@ class QFontMetricsPrivate;
 
 class QFontMetrics {
 public:
+    QFontMetrics();
     QFontMetrics(const QFont &);
     ~QFontMetrics();
 
     QFontMetrics(const QFontMetrics &);
     QFontMetrics &operator=(const QFontMetrics &);
 
+    const QFont &font() const;
+    void setFont(const QFont &);
+    
     int ascent() const;
     int descent() const;
     int height() const;
@@ -63,7 +67,7 @@ public:
 
     int rightBearing(QChar) const;
     int leftBearing(QChar) const;
-    int baselineOffset() const;
+    int baselineOffset() const { return ascent(); }
     
 private:
     KWQRefPtr<QFontMetricsPrivate> data;
diff --git a/WebCore/kwq/KWQFontMetrics.mm b/WebCore/kwq/KWQFontMetrics.mm
index cabb00c..6f38dd9 100644
--- a/WebCore/kwq/KWQFontMetrics.mm
+++ b/WebCore/kwq/KWQFontMetrics.mm
@@ -34,40 +34,54 @@
 
 struct QFontMetricsPrivate
 {
-    friend class QFontMetrics;
-    
     QFontMetricsPrivate(const QFont &font)
+        : refCount(0), _font(font), _renderer(nil)
     {
-        refCount = 0;
-
-        renderer = [[[WebCoreTextRendererFactory sharedFactory] rendererWithFont: font.getNSFont()] retain];
-        _font = font;
     }
     ~QFontMetricsPrivate()
     {
-        [renderer release];
+        [_renderer release];
     }
     id <WebCoreTextRenderer> getRenderer()
     {
-        return renderer;
+        if (!_renderer) {
+            _renderer = [[[WebCoreTextRendererFactory sharedFactory] rendererWithFont:_font.getNSFont()] retain];
+        }
+        return _renderer;
+    }
+    
+    const QFont &font() const { return _font; }
+    void setFont(const QFont &font)
+    {
+        if (_font == font) {
+            return;
+        }
+        _font == font;
+        [_renderer release];
+        _renderer = nil;
     }
     
     int refCount;
     
 private:
-    id <WebCoreTextRenderer> renderer;
     QFont _font;
+    id <WebCoreTextRenderer> _renderer;
+    
     QFontMetricsPrivate(const QFontMetricsPrivate&);
     QFontMetricsPrivate& operator=(const QFontMetricsPrivate&);
 };
 
-QFontMetrics::QFontMetrics(const QFont &withFont)
-: data(new QFontMetricsPrivate(withFont))
+QFontMetrics::QFontMetrics()
 {
 }
 
-QFontMetrics::QFontMetrics(const QFontMetrics &withFont)
-: data(withFont.data)
+QFontMetrics::QFontMetrics(const QFont &font)
+    : data(new QFontMetricsPrivate(font))
+{
+}
+
+QFontMetrics::QFontMetrics(const QFontMetrics &other)
+    : data(other.data)
 {
 }
 
@@ -75,15 +89,19 @@ QFontMetrics::~QFontMetrics()
 {
 }
 
-QFontMetrics &QFontMetrics::operator=(const QFontMetrics &withFont)
+QFontMetrics &QFontMetrics::operator=(const QFontMetrics &other)
 {
-    data = withFont.data;
+    data = other.data;
     return *this;
 }
 
-int QFontMetrics::baselineOffset() const
+void QFontMetrics::setFont(const QFont &font)
 {
-    return ascent();
+    if (data.isNull()) {
+        data = KWQRefPtr<QFontMetricsPrivate>(new QFontMetricsPrivate(font));
+    } else {
+        data->setFont(font);
+    }
 }
 
 int QFontMetrics::ascent() const
@@ -117,7 +135,7 @@ int QFontMetrics::width(QChar qc) const
 {
     UniChar c = qc.unicode();
 
-    CREATE_FAMILY_ARRAY(data->_font, families);
+    CREATE_FAMILY_ARRAY(data->font(), families);
     
     return ROUND_TO_INT([data->getRenderer() floatWidthForCharacters:&c stringLength:1 fromCharacterPosition:0 numberOfCharacters:1 withPadding: 0 applyRounding:YES attemptFontSubstitution: YES widths:0 letterSpacing:0 wordSpacing:0 fontFamilies: families]);
 }
@@ -131,35 +149,35 @@ int QFontMetrics::width(char c) const
 {
     UniChar ch = (uchar) c;
 
-    CREATE_FAMILY_ARRAY(data->_font, families);
+    CREATE_FAMILY_ARRAY(data->font(), families);
 
     return ROUND_TO_INT([data->getRenderer() floatWidthForCharacters:&ch stringLength:1 fromCharacterPosition:0 numberOfCharacters:1 withPadding: 0 applyRounding:YES attemptFontSubstitution: YES widths:0  letterSpacing:0 wordSpacing:0 fontFamilies: families]);
 }
 
 int QFontMetrics::width(const QString &qstring, int len) const
 {
-    CREATE_FAMILY_ARRAY(data->_font, families);
+    CREATE_FAMILY_ARRAY(data->font(), families);
 
     return ROUND_TO_INT([data->getRenderer() floatWidthForCharacters:(const UniChar *)qstring.unicode() stringLength:len fromCharacterPosition:0 numberOfCharacters:len withPadding: 0 applyRounding:YES attemptFontSubstitution: YES widths: 0 letterSpacing:0 wordSpacing:0 fontFamilies: families]);
 }
 
 int QFontMetrics::width(const QChar *uchars, int len) const
 {
-    CREATE_FAMILY_ARRAY(data->_font, families);
+    CREATE_FAMILY_ARRAY(data->font(), families);
 
     return ROUND_TO_INT([data->getRenderer() floatWidthForCharacters:(const UniChar *)uchars stringLength:len fromCharacterPosition:0 numberOfCharacters:len withPadding: 0 applyRounding:YES attemptFontSubstitution: YES widths: 0 letterSpacing:0 wordSpacing:0 fontFamilies: families]);
 }
 
 float QFontMetrics::floatWidth(const QChar *uchars, int slen, int pos, int len, int letterSpacing, int wordSpacing) const
 {
-    CREATE_FAMILY_ARRAY(data->_font, families);
+    CREATE_FAMILY_ARRAY(data->font(), families);
 
     return [data->getRenderer() floatWidthForCharacters:(const UniChar *)uchars stringLength:slen fromCharacterPosition:pos numberOfCharacters:len withPadding: 0 applyRounding: YES attemptFontSubstitution: YES widths: 0 letterSpacing:letterSpacing wordSpacing:wordSpacing fontFamilies: families];
 }
 
 float QFontMetrics::floatCharacterWidths(const QChar *uchars, int slen, int pos, int len, int toAdd, float *buffer, int letterSpacing, int wordSpacing) const
 {
-    CREATE_FAMILY_ARRAY(data->_font, families);
+    CREATE_FAMILY_ARRAY(data->font(), families);
     
     return [data->getRenderer() floatWidthForCharacters:(const UniChar *)uchars stringLength:slen fromCharacterPosition:pos numberOfCharacters:len withPadding: toAdd applyRounding: YES attemptFontSubstitution: YES widths: (float *)buffer letterSpacing:letterSpacing wordSpacing: wordSpacing fontFamilies: families];
 }
diff --git a/WebCore/kwq/KWQKURL.mm b/WebCore/kwq/KWQKURL.mm
index f32856c..4de7e6a 100644
--- a/WebCore/kwq/KWQKURL.mm
+++ b/WebCore/kwq/KWQKURL.mm
@@ -966,13 +966,33 @@ void KURL::parse(const char *url, const QString *originalString)
     schemeEndPos = p - buffer;
 
     // Check if we're http or https.
-    bool isHTTPorHTTPS = strncasecmp ("http", url, schemeEnd) == 0 ||
-        strncasecmp ("https", url, schemeEnd) == 0;
+    bool isHTTPorHTTPS = tolower(url[0]) == 'h'
+        && tolower(url[1]) == 't'
+        && tolower(url[2]) == 't'
+        && tolower(url[3]) == 'p'
+        && (url[4] == ':'
+            || (tolower(url[4]) == 's' && url[5] == ':'));
     
-    bool isFILENeedsHostPart = strncasecmp("file", url, schemeEnd) == 0 && pathStart != pathEnd
-        && !(pathStart + 2 == pathEnd && strncmp("//", url + pathStart, 2) == 0);
+    bool isFILENeedsHostPart = pathStart != pathEnd
+        && tolower(url[0]) == 'f'
+        && tolower(url[1]) == 'i'
+        && tolower(url[2]) == 'l'
+        && tolower(url[3]) == 'e'
+        && url[4] == ':'
+        && !(pathStart + 2 == pathEnd
+             && url[pathStart] == '/'
+             && url[pathStart+1] == '/');
     
-    bool hostIsLocalHost = portEnd - userStart == 9 && strncmp(url + userStart, "localhost", 9) == 0;
+    bool hostIsLocalHost = portEnd - userStart == 9
+        && tolower(url[userStart]) == 'l'
+        && tolower(url[userStart+1]) == 'o'
+        && tolower(url[userStart+2]) == 'c'
+        && tolower(url[userStart+3]) == 'a'
+        && tolower(url[userStart+4]) == 'l'
+        && tolower(url[userStart+5]) == 'h'
+        && tolower(url[userStart+6]) == 'o'
+        && tolower(url[userStart+7]) == 's'
+        && tolower(url[userStart+8]) == 't';
     
     bool haveNonHostAuthorityPart = userStart != userEnd || passwordStart != passwordEnd || portStart != portEnd;
     
diff --git a/WebCore/kwq/KWQListImpl.h b/WebCore/kwq/KWQListImpl.h
index 08d61ba..6700730 100644
--- a/WebCore/kwq/KWQListImpl.h
+++ b/WebCore/kwq/KWQListImpl.h
@@ -87,7 +87,7 @@ public:
     mutable KWQListIteratorImpl *iterators;
 
     friend class KWQListIteratorImpl;
-}; 
+};
 
 
 class KWQListIteratorImpl {
diff --git a/WebCore/kwq/KWQString.h b/WebCore/kwq/KWQString.h
index 2383945..0530670 100644
--- a/WebCore/kwq/KWQString.h
+++ b/WebCore/kwq/KWQString.h
@@ -45,12 +45,6 @@ class QChar {
 public:
 
     enum Direction {
-        // NOTE: alphabetical order
-        //DirAL, DirAN, DirB, DirBN, DirCS, DirEN, DirES, DirET, DirL, DirLRE,
-        //DirLRO, DirNSM, DirON, DirPDF, DirR, DirRLE, DirRLO, DirS, DirWS
-        //
-        // Until we understand the implications better, I say we go with the qt
-        // ordering here
         DirL, DirR, DirEN, DirES, DirET, DirAN, DirCS, DirB, DirS, DirWS, DirON,
         DirLRE, DirLRO, DirAL, DirRLE, DirRLO, DirPDF, DirNSM, DirBN
     };
@@ -272,24 +266,24 @@ inline bool operator<(char ch, QChar qc)
 #define QS_INTERNAL_BUFFER_CHARS QS_INTERNAL_BUFFER_SIZE-1
 #define QS_INTERNAL_BUFFER_UCHARS QS_INTERNAL_BUFFER_SIZE/2
 
-struct QStringData {
+struct KWQStringData {
     // Uses shared null data.
-    QStringData();
+    KWQStringData();
     void initialize();
     
     // No copy.
-    QStringData(QChar *u, uint l, uint m);
+    KWQStringData(QChar *u, uint l, uint m);
     void initialize(QChar *u, uint l, uint m);
     
     // Copy bytes;
-    QStringData(const QChar *u, uint l);
+    KWQStringData(const QChar *u, uint l);
     void initialize(const QChar *u, uint l);
 
     // Copy bytes;
-    QStringData(const char *u, uint l);
+    KWQStringData(const char *u, uint l);
     void initialize(const char *u, uint l);
 
-    ~QStringData();
+    ~KWQStringData();
 
 #ifdef QSTRING_DEBUG_ALLOCATIONS
     void* operator new(size_t s);
@@ -306,19 +300,20 @@ struct QStringData {
     QChar *unicode();
     QChar *makeUnicode();    
     void increaseUnicodeSize(uint size);
-        
+    
+    bool isUnicodeInternal() const { return (char *)_unicode == _internalBuffer; }
+    bool isAsciiInternal() const { return _ascii == _internalBuffer; }
+    
     uint refCount;
     uint _length;
     mutable QChar *_unicode;
     mutable char *_ascii;
-    uint _maxUnicode:29;
-    uint _isUnicodeInternal:1;
+    uint _maxUnicode:30;
     uint _isUnicodeValid:1;
-    uint _isHeapAllocated:1;	// Fragile, but the only way we can be sure the instance was
-                                // created with 'new'.
-    uint _maxAscii:30;
-    uint _isAsciiInternal:1;
+    uint _isHeapAllocated:1;	// Fragile, but the only way we can be sure the instance was created with 'new'.
+    uint _maxAscii:31;
     uint _isAsciiValid:1;
+    
     char _internalBuffer[QS_INTERNAL_BUFFER_SIZE]; // Pad out to a (((size + 1) & ~15) + 14) size
 };
 
@@ -474,31 +469,30 @@ public:
     
 private:
     // Used by QConstString.
-    QString(QStringData *constData, bool /*dummy*/);
+    QString(KWQStringData *constData, bool /*dummy*/);
     void detach();
+    void detachIfInternal();
     void detachInternal();
     void deref();
     QChar *forceUnicode();
     void setLength(uint);
 
-    QStringData *data() const;
-    
     QCString convertToQCString(CFStringEncoding) const;
 
-    QStringData **dataHandle;
-    QStringData internalData;
+    KWQStringData **dataHandle;
+    KWQStringData internalData;
     
-    static QStringData* shared_null;
-    static QStringData* makeSharedNull();
-    static QStringData**shared_null_handle;
-    static QStringData**makeSharedNullHandle();
+    static KWQStringData *shared_null;
+    static KWQStringData *makeSharedNull();
+    static KWQStringData **shared_null_handle;
+    static KWQStringData **makeSharedNullHandle();
 
     friend bool operator==(const QString &, const QString &);
     friend bool operator==(const QString &, const char *);
 
     friend class QConstString;
     friend class QGDict;
-    friend struct QStringData;
+    friend struct KWQStringData;
 };
 
 QString operator+(const QString &, const QString &);
@@ -509,16 +503,39 @@ QString operator+(const char *, const QString &);
 QString operator+(QChar, const QString &);
 QString operator+(char, const QString &);
 
-inline QStringData *QString::data() const { return *dataHandle; }
+inline char *KWQStringData::ascii()
+{
+    return _isAsciiValid ? _ascii : makeAscii();
+}
+
+inline QChar *KWQStringData::unicode()
+{
+    return _isUnicodeValid ? _unicode : makeUnicode();
+}
 
 inline uint QString::length() const
 {
-    return data()->_length;
+    return dataHandle[0]->_length;
 }
 
 inline bool QString::isEmpty() const
 {
-    return length() == 0;
+    return dataHandle[0]->_length == 0;
+}
+
+inline const char *QString::latin1() const
+{
+    return dataHandle[0]->ascii();
+}
+
+inline const QChar *QString::unicode() const
+{
+    return dataHandle[0]->unicode();
+}
+
+inline CFStringRef QString::getCFString() const
+{
+    return (CFStringRef)getNSString();
 }
 
 inline QString QString::fromLatin1(const char *chs)
diff --git a/WebCore/kwq/KWQString.mm b/WebCore/kwq/KWQString.mm
index 8474249..c4bda11 100644
--- a/WebCore/kwq/KWQString.mm
+++ b/WebCore/kwq/KWQString.mm
@@ -24,10 +24,14 @@
  */
 
 #import <Foundation/Foundation.h>
+
+#import <stdio.h>
+
+#import <JavaScriptCore/dtoa.h>
+
 #import "KWQLogging.h"
 #import "KWQString.h"
 #import "KWQRegExp.h"
-#import <stdio.h>
 
 #define CHECK_FOR_HANDLE_LEAKS 0
 
@@ -187,10 +191,10 @@ void _printQStringAllocationStatistics()
     printf ("\nQString instance counts:\n");
     printf ("QString stack allocated instances %d\n", stackInstances);
     printf ("QString heap allocated instances %d\n", heapInstances);
-    printf ("QStringData instances %d\n", stringDataInstances);
-    printf ("QStringData heap allocated instances %d\n", stringDataHeapInstances);
-    printf ("QStringData detachments (copies) %d\n", stringDataDetachments);
-    printf ("QStringData handles %d\n", handleInstances);
+    printf ("KWQStringData instances %d\n", stringDataInstances);
+    printf ("KWQStringData heap allocated instances %d\n", stringDataHeapInstances);
+    printf ("KWQStringData detachments (copies) %d\n", stringDataDetachments);
+    printf ("KWQStringData handles %d\n", handleInstances);
     
     free(keys);
     free(values);
@@ -198,11 +202,11 @@ void _printQStringAllocationStatistics()
 #else
 
 #define ALLOC_CHAR( N ) (char*) malloc(N)
-#define REALLOC_CHAR( P, N ) realloc(P,N)
+#define REALLOC_CHAR( P, N ) (char *) realloc(P,N)
 #define DELETE_CHAR( P ) free(P)
 
 #define ALLOC_QCHAR( N ) (QChar*) malloc(sizeof(QChar)*( N ))
-#define REALLOC_QCHAR( P, N ) realloc(P,sizeof(QChar)*( N ))
+#define REALLOC_QCHAR( P, N ) (QChar *) realloc(P,sizeof(QChar)*( N ))
 #define DELETE_QCHAR( P ) free( P )
 #endif // QSTRING_DEBUG_ALLOCATIONS
 
@@ -216,8 +220,8 @@ static void freeHandle(void *free);
 
 static const int caseDelta = ('a' - 'A');
 
-QStringData *QString::shared_null = 0;
-QStringData **QString::shared_null_handle = 0;
+KWQStringData *QString::shared_null = 0;
+KWQStringData **QString::shared_null_handle = 0;
 
 // -------------------------------------------------------------------------
 // Utility functions
@@ -276,42 +280,40 @@ static bool ok_in_base( QChar c, int base )
 
 
 // -------------------------------------------------------------------------
-// QStringData
+// KWQStringData
 // -------------------------------------------------------------------------
 
 // FIXME, make constructor explicity take a 'copy' flag.
 // This can be used to hand off ownership of allocated data when detaching and
 // deleting QStrings.
 
-QStringData::QStringData() :
-	refCount(1), _length(0), _unicode(0), _ascii(0), _maxUnicode(QS_INTERNAL_BUFFER_UCHARS), _isUnicodeInternal(0), _isUnicodeValid(0), _isHeapAllocated(0), _maxAscii(QS_INTERNAL_BUFFER_CHARS), _isAsciiInternal(1), _isAsciiValid(1) 
+KWQStringData::KWQStringData() :
+	refCount(1), _length(0), _unicode(0), _ascii(0), _maxUnicode(QS_INTERNAL_BUFFER_UCHARS), _isUnicodeValid(0), _isHeapAllocated(0), _maxAscii(QS_INTERNAL_BUFFER_CHARS), _isAsciiValid(1) 
 { 
 #ifdef QSTRING_DEBUG_ALLOCATIONS
     stringDataInstances++;
 #endif
-    _ascii = &_internalBuffer[0];
+    _ascii = _internalBuffer;
     _internalBuffer[0] = 0;
 }
 
-void QStringData::initialize()
+void KWQStringData::initialize()
 {
     refCount = 1;
     _length = 0;
     _unicode = 0;
-    _ascii = &_internalBuffer[0];
+    _ascii = _internalBuffer;
     _maxUnicode = QS_INTERNAL_BUFFER_UCHARS;
-    _isUnicodeInternal = 0;
     _isUnicodeValid = 0;
     _maxAscii = QS_INTERNAL_BUFFER_CHARS;
-    _isAsciiInternal = 1;
     _isAsciiValid = 1;
     _internalBuffer[0] = 0;
     _isHeapAllocated = 0;
 }
 
 // Don't copy data.
-QStringData::QStringData(QChar *u, uint l, uint m) :
-	refCount(1), _length(l), _unicode(u), _ascii(0), _maxUnicode(m), _isUnicodeInternal(0), _isUnicodeValid(1), _isHeapAllocated(0), _maxAscii(QS_INTERNAL_BUFFER_CHARS), _isAsciiInternal(0), _isAsciiValid(0)
+KWQStringData::KWQStringData(QChar *u, uint l, uint m) :
+	refCount(1), _length(l), _unicode(u), _ascii(0), _maxUnicode(m), _isUnicodeValid(1), _isHeapAllocated(0), _maxAscii(QS_INTERNAL_BUFFER_CHARS), _isAsciiValid(0)
 {
     ASSERT(m >= l);
 #ifdef QSTRING_DEBUG_ALLOCATIONS
@@ -320,7 +322,7 @@ QStringData::QStringData(QChar *u, uint l, uint m) :
 }
 
 // Don't copy data.
-void QStringData::initialize(QChar *u, uint l, uint m)
+void KWQStringData::initialize(QChar *u, uint l, uint m)
 {
     ASSERT(m >= l);
     refCount = 1;
@@ -328,16 +330,14 @@ void QStringData::initialize(QChar *u, uint l, uint m)
     _unicode = u;
     _ascii = 0;
     _maxUnicode = m;
-    _isUnicodeInternal = 0;
     _isUnicodeValid = 1;
     _maxAscii = 0;
-    _isAsciiInternal = 0;
     _isAsciiValid = 0;
     _isHeapAllocated = 0;
 }
 
 // Copy data
-QStringData::QStringData(const QChar *u, uint l)
+KWQStringData::KWQStringData(const QChar *u, uint l)
 {
 #ifdef QSTRING_DEBUG_ALLOCATIONS
     stringDataInstances++;
@@ -346,48 +346,43 @@ QStringData::QStringData(const QChar *u, uint l)
 }
 
 #ifdef QSTRING_DEBUG_ALLOCATIONS
-void* QStringData::operator new(size_t s)
+void* KWQStringData::operator new(size_t s)
 {
     stringDataHeapInstances++;
     return malloc(s);
 }
-void QStringData::operator delete(void*p)
+void KWQStringData::operator delete(void*p)
 {
     return free(p);
 }
 #endif
 
 // Copy data
-void QStringData::initialize(const QChar *u, uint l)
+void KWQStringData::initialize(const QChar *u, uint l)
 {
     refCount = 1;
     _length = l;
     _ascii = 0;
-    _isUnicodeInternal = 0;
     _isUnicodeValid = 1;
     _maxAscii = 0;
-    _isAsciiInternal = 0;
     _isAsciiValid = 0;
     _isHeapAllocated = 0;
 
-    if (l > QS_INTERNAL_BUFFER_UCHARS){
+    if (l > QS_INTERNAL_BUFFER_UCHARS) {
         _maxUnicode = ALLOC_QCHAR_GOOD_SIZE(l);
         _unicode = ALLOC_QCHAR(_maxUnicode);
-        if (u)
-            memcpy(_unicode, u, l*sizeof(QChar));
-    }
-    else {
-        _unicode = (QChar *)&_internalBuffer[0];
+        memcpy(_unicode, u, l*sizeof(QChar));
+    } else {
         _maxUnicode = QS_INTERNAL_BUFFER_UCHARS;
-        _isUnicodeInternal = 1;
-        if (u)
+        _unicode = (QChar *)_internalBuffer;
+        if (l)
             memcpy(_internalBuffer, u, l*sizeof(QChar));
     }
 }
 
 
 // Copy data
-QStringData::QStringData(const char *a, uint l)
+KWQStringData::KWQStringData(const char *a, uint l)
 {
 #ifdef QSTRING_DEBUG_ALLOCATIONS
     stringDataInstances++;
@@ -397,177 +392,114 @@ QStringData::QStringData(const char *a, uint l)
 
 
 // Copy data
-void QStringData::initialize(const char *a, uint l)
+void KWQStringData::initialize(const char *a, uint l)
 {
     refCount = 1;
     _length = l;
     _unicode = 0;
-    _isUnicodeInternal = 0;
     _isUnicodeValid = 0;
     _maxUnicode = 0;
-    _isAsciiInternal = 0;
     _isAsciiValid = 1;
     _isHeapAllocated = 0;
 
-    if (l > QS_INTERNAL_BUFFER_CHARS){
+    if (l > QS_INTERNAL_BUFFER_CHARS) {
         _maxAscii = ALLOC_CHAR_GOOD_SIZE(l+1);
         _ascii = ALLOC_CHAR(_maxAscii);
         if (a)
-            memcpy(_ascii, a, l*sizeof(char));
+            memcpy(_ascii, a, l);
         _ascii[l] = 0;
-    }
-    else {
-        _ascii = &_internalBuffer[0];
+    } else {
         _maxAscii = QS_INTERNAL_BUFFER_CHARS;
-        _isAsciiInternal = 1;
+        _ascii = _internalBuffer;
         if (a)
-            memcpy(_internalBuffer, a, l*sizeof(char));
+            memcpy(_internalBuffer, a, l);
         _internalBuffer[l] = 0;
     }
 }
 
-QStringData *QString::makeSharedNull()
+KWQStringData *QString::makeSharedNull()
 {
     if (!shared_null) {
-        shared_null = new QStringData;
+        shared_null = new KWQStringData;
         shared_null->ref();
         shared_null->_maxAscii = 0;
         shared_null->_maxUnicode = 0;
         shared_null->_unicode = (QChar *)&shared_null->_internalBuffer[0]; 
         shared_null->_isUnicodeValid = 1;   
-        shared_null->_isUnicodeInternal = 1;   
     }
     return shared_null;
 }
 
-QStringData **QString::makeSharedNullHandle()
+KWQStringData **QString::makeSharedNullHandle()
 {
     if (!shared_null_handle) {
-        shared_null_handle = (QStringData **)allocateHandle();
+        shared_null_handle = (KWQStringData **)allocateHandle();
         *shared_null_handle = makeSharedNull();
     }
     return shared_null_handle;
 }
 
-QStringData::~QStringData()
+KWQStringData::~KWQStringData()
 {
     ASSERT(refCount == 0);
-        
-    // Ack!  The destcructor will be called when the QString is deleted.
-    if ( _unicode && !_isUnicodeInternal)
-        DELETE_QCHAR (_unicode);
-    if ( _ascii && !_isAsciiInternal)
-        DELETE_CHAR (_ascii); 
+    if (_unicode && !isUnicodeInternal())
+        DELETE_QCHAR(_unicode);
+    if (_ascii && !isAsciiInternal())
+        DELETE_CHAR(_ascii);
 }
 
-
-inline char *QStringData::ascii()
-{
-    if (_isAsciiValid){
-        if (_isAsciiInternal)
-            return &_internalBuffer[0];
-        else
-            return _ascii;
-    }
-    else
-        return makeAscii();
-}
-
-
-void QStringData::increaseAsciiSize(uint size)
+void KWQStringData::increaseAsciiSize(uint size)
 {
     ASSERT(this != QString::shared_null);
         
-    uint newSize = (uint)ALLOC_CHAR_GOOD_SIZE(size);
-    char *prev = 0;
+    uint newSize = (uint)ALLOC_CHAR_GOOD_SIZE((size * 3 + 1) / 2);
     
-    if (!_isAsciiValid && _isUnicodeValid)
+    if (!_isAsciiValid)
         makeAscii();
-        
-    if (_ascii && !_isAsciiInternal)
-        prev = _ascii;
-        
-    if (_isAsciiValid){
-        if (_isAsciiInternal){
-            if (_length){
-                char *newAscii = ALLOC_CHAR(newSize);
-                memcpy (newAscii, _ascii, _length);
-                _ascii = newAscii;
-            }
-            else
-                _ascii = ALLOC_CHAR(newSize);
-        }
-        else {
-            _ascii = (char *)REALLOC_CHAR (_ascii, newSize);
-            prev = 0;
-        }
+    ASSERT(_isAsciiValid);
+    
+    if (isAsciiInternal()) {
+        char *newAscii = ALLOC_CHAR(newSize);
+        if (_length)
+            memcpy(newAscii, _ascii, _length);
+        _ascii = newAscii;
+    } else {
+        _ascii = REALLOC_CHAR(_ascii, newSize);
     }
-    else
-        FATAL("invalid character cache");
     
-    if (prev)
-        DELETE_CHAR(prev);
-        
     _maxAscii = newSize;
     _isAsciiValid = 1;
-    _isAsciiInternal = 0;
     _isUnicodeValid = 0;
 }
 
 
-inline QChar *QStringData::unicode()
-{
-    if (_isUnicodeValid){
-        if (_isUnicodeInternal)
-            return (QChar *)_internalBuffer;
-        else
-            return _unicode;
-    }
-    else
-        return makeUnicode();
-}
-
-
-void QStringData::increaseUnicodeSize(uint size)
+void KWQStringData::increaseUnicodeSize(uint size)
 {
     ASSERT(size > _length);
     ASSERT(this != QString::shared_null);
         
-    uint newSize = (uint)ALLOC_QCHAR_GOOD_SIZE(size);
-    QChar *prev = 0;
+    uint newSize = (uint)ALLOC_QCHAR_GOOD_SIZE((size * 3 + 1) / 2);
     
-    if (!_isUnicodeValid && _isAsciiValid)
+    if (!_isUnicodeValid)
         makeUnicode();
+    ASSERT(_isUnicodeValid);
 
-    if (_unicode && !_isUnicodeInternal)
-        prev = _unicode;
-        
-    if (_isUnicodeValid){
-        if (_isUnicodeInternal){
-            QChar *newUni = ALLOC_QCHAR(newSize);
-            if (_length)
-                memcpy (newUni, _unicode, _length*sizeof(QChar));
-            _unicode = newUni;
-        }
-        else {
-            _unicode = (QChar *)REALLOC_QCHAR (_unicode, newSize);
-            prev = 0;
-        }
+    if (isUnicodeInternal()) {
+        QChar *newUni = ALLOC_QCHAR(newSize);
+        if (_length)
+            memcpy(newUni, _unicode, _length*sizeof(QChar));
+        _unicode = newUni;
+    } else {
+        _unicode = REALLOC_QCHAR(_unicode, newSize);
     }
-    else
-        FATAL("invalid character cache");
     
-    if (prev)
-        DELETE_QCHAR(prev);
-        
     _maxUnicode = newSize;
     _isUnicodeValid = 1;
-    _isUnicodeInternal = 0;
     _isAsciiValid = 0;
 }
 
 
-char *QStringData::makeAscii()
+char *KWQStringData::makeAscii()
 {
     ASSERT(this != QString::shared_null);
         
@@ -575,11 +507,11 @@ char *QStringData::makeAscii()
         QChar copyBuf[QS_INTERNAL_BUFFER_CHARS];
         QChar *str;
         
-        if (_ascii && !_isAsciiInternal)
+        if (_ascii && !isAsciiInternal())
             DELETE_QCHAR(_ascii);
             
         if (_length < QS_INTERNAL_BUFFER_CHARS){
-            if (_isUnicodeInternal){
+            if (isUnicodeInternal()) {
                 uint i = _length;
                 QChar *tp = &copyBuf[0], *fp = _unicode;
                 while (i--)
@@ -589,16 +521,14 @@ char *QStringData::makeAscii()
             }
             else
                 str = _unicode;
-            _ascii = (char *)&_internalBuffer[0];
+            _ascii = _internalBuffer;
             _maxAscii = QS_INTERNAL_BUFFER_CHARS;
-            _isAsciiInternal = 1;
         }
         else {
             uint newSize = ALLOC_CHAR_GOOD_SIZE(_length+1);
             _ascii = ALLOC_CHAR(newSize);
             _maxAscii = newSize;
             str = _unicode;
-            _isAsciiInternal = 0;
         }
 
         uint i = _length;
@@ -616,7 +546,7 @@ char *QStringData::makeAscii()
 }
 
 
-QChar *QStringData::makeUnicode()
+QChar *KWQStringData::makeUnicode()
 {
     ASSERT(this != QString::shared_null);
         
@@ -624,11 +554,11 @@ QChar *QStringData::makeUnicode()
         char copyBuf[QS_INTERNAL_BUFFER_CHARS];
         char *str;
         
-        if (_unicode && !_isUnicodeInternal)
+        if (_unicode && !isUnicodeInternal())
             DELETE_QCHAR(_unicode);
             
         if (_length <= QS_INTERNAL_BUFFER_UCHARS){
-            if (_isAsciiInternal){
+            if (isAsciiInternal()) {
                 uint i = _length;
                 char *tp = &copyBuf[0], *fp = _ascii;
                 while (i--)
@@ -638,16 +568,14 @@ QChar *QStringData::makeUnicode()
             }
             else
                 str = _ascii;
-            _unicode = (QChar *)&_internalBuffer[0];
+            _unicode = (QChar *)_internalBuffer;
             _maxUnicode = QS_INTERNAL_BUFFER_UCHARS;
-            _isUnicodeInternal = 1;
         }
         else {
             uint newSize = ALLOC_QCHAR_GOOD_SIZE(_length);
             _unicode = ALLOC_QCHAR(newSize);
             _maxUnicode = newSize;
             str = _ascii;
-            _isUnicodeInternal = 0;
         }
         uint i = _length;
         QChar *cp = _unicode;
@@ -818,11 +746,6 @@ QString QString::fromNSString(NSString *nss)
     return qs;
 }
 
-CFStringRef QString::getCFString() const
-{
-    return (CFStringRef)getNSString();
-}
-
 NSString *QString::getNSString() const
 {
     if (dataHandle[0]->_isUnicodeValid) {
@@ -839,10 +762,18 @@ NSString *QString::getNSString() const
 
 const QString QString::null;
 
+inline void QString::detachIfInternal()
+{
+    KWQStringData *oldData = *dataHandle;
+    if (oldData->refCount > 1 && oldData == &internalData) {
+        detachInternal();
+    }
+}
+
 QString::~QString()
 {
-    QStringData **oldHandle = dataHandle;
-    QStringData *oldData = *oldHandle;
+    KWQStringData **oldHandle = dataHandle;
+    KWQStringData *oldData = *oldHandle;
     
     ASSERT(oldHandle);
     ASSERT(oldData->refCount != 0);
@@ -853,10 +784,10 @@ QString::~QString()
     bool needToFreeHandle = oldHandle != shared_null_handle && oldData->refCount == 1;
 
     // Copy our internal data if necessary, other strings still need it.
-    detachInternal();
+    detachIfInternal();
     
-    // Remove our reference.  This should always be the last reference
-    // if *dataHandle points to our internal QStringData.
+    // Remove our reference. This should always be the last reference
+    // if *dataHandle points to our internal KWQStringData.
     oldData->deref();
 
     ASSERT(oldData != &internalData || oldData->refCount == 0);
@@ -880,13 +811,13 @@ QString::QString()
 
 
 // Careful, just used by QConstString
-QString::QString(QStringData *constData, bool /*dummy*/) 
+QString::QString(KWQStringData *constData, bool /*dummy*/) 
 {
     internalData.deref();
-    dataHandle = (QStringData **)allocateHandle();
+    dataHandle = (KWQStringData **)allocateHandle();
     *dataHandle = constData;
     
-    // The QConstString constructor allocated the QStringData.
+    // The QConstString constructor allocated the KWQStringData.
     constData->_isHeapAllocated = 1;
 }
 
@@ -896,7 +827,7 @@ QString::QString(QChar qc)
 #ifdef QSTRING_DEBUG_ALLOCATIONS
     countInstance (&dataHandle);
 #endif
-    dataHandle = (QStringData **)allocateHandle();
+    dataHandle = (KWQStringData **)allocateHandle();
 
     // Copy the QChar.
     if (IS_ASCII_QCHAR(qc)) {
@@ -915,7 +846,7 @@ QString::QString(const QByteArray &qba)
 #ifdef QSTRING_DEBUG_ALLOCATIONS
     countInstance (&dataHandle);
 #endif
-    dataHandle = (QStringData **)allocateHandle();
+    dataHandle = (KWQStringData **)allocateHandle();
 
     // Copy data
     *dataHandle = &internalData;
@@ -932,7 +863,7 @@ QString::QString(const QChar *unicode, uint length)
         dataHandle = makeSharedNullHandle();
 	dataHandle[0]->ref();
     } else {
-        dataHandle = (QStringData **)allocateHandle();
+        dataHandle = (KWQStringData **)allocateHandle();
 
         // Copy the QChar *
         *dataHandle = &internalData;
@@ -948,7 +879,7 @@ QString::QString(const char *chs)
 
     if (chs) {
         internalData.initialize(chs,strlen(chs));
-	dataHandle = (QStringData **)allocateHandle();
+	dataHandle = (KWQStringData **)allocateHandle();
 	*dataHandle = &internalData;
     } else {
 	internalData.deref();
@@ -962,7 +893,7 @@ QString::QString(const char *chs, int len)
 #ifdef QSTRING_DEBUG_ALLOCATIONS
     countInstance (&dataHandle);
 #endif
-    dataHandle = (QStringData **)allocateHandle();
+    dataHandle = (KWQStringData **)allocateHandle();
     *dataHandle = &internalData;
     internalData.initialize(chs,len);
 }
@@ -984,7 +915,7 @@ QString &QString::operator=(const QString &qs)
     // Free our handle if it isn't the shared null handle, and if no-one else is using it.
     bool needToFreeHandle = dataHandle != shared_null_handle && dataHandle[0]->refCount == 1;
     
-    qs.data()->ref();
+    qs.dataHandle[0]->ref();
     deref();
     
     if (needToFreeHandle)
@@ -1017,32 +948,17 @@ QString &QString::operator=(char ch)
 
 QChar QString::at(uint i) const
 {
-    QStringData *thisData = *dataHandle;
+    KWQStringData *thisData = *dataHandle;
     
     if (i >= thisData->_length)
         return QChar::null;
         
-    if (thisData->_isAsciiValid){
-        if (thisData->_isAsciiInternal)
-            return QChar(thisData->_internalBuffer[i]);
-        else
-            return QChar(thisData->_ascii[i]);
+    if (thisData->_isAsciiValid) {
+        return thisData->_ascii[i];
     }
-    else if (thisData->_isUnicodeValid){
-        if (thisData->_isUnicodeInternal)
-            return ((QChar *)thisData->_internalBuffer)[i];
-        else
-            return thisData->_unicode[i];
-    }
-    else
-        FATAL("invalid character cache");
-        
-    return QChar::null;
-}
-
-const QChar *QString::unicode() const
-{
-    return dataHandle[0]->unicode();
+    
+    ASSERT(thisData->_isUnicodeValid);
+    return thisData->_unicode[i];
 }
 
 int QString::compare( const QString& s ) const
@@ -1057,7 +973,7 @@ bool QString::startsWith( const QString& s ) const
     if (dataHandle[0]->_isAsciiValid){
         const char *asc = ascii();
         
-        for ( int i =0; i < (int) s.data()->_length; i++ ) {
+        for ( int i =0; i < (int) s.dataHandle[0]->_length; i++ ) {
             if ( i >= (int) dataHandle[0]->_length || asc[i] != s[i] )
                 return FALSE;
         }
@@ -1065,7 +981,7 @@ bool QString::startsWith( const QString& s ) const
     else if (dataHandle[0]->_isUnicodeValid){
         const QChar *uni = unicode();
         
-        for ( int i =0; i < (int) s.data()->_length; i++ ) {
+        for ( int i =0; i < (int) s.dataHandle[0]->_length; i++ ) {
             if ( i >= (int) dataHandle[0]->_length || uni[i] != s[i] )
                 return FALSE;
         }
@@ -1080,21 +996,16 @@ bool QString::endsWith( const QString& s ) const
 {
     const QChar *uni = unicode();
 
-    if (dataHandle[0]->_length < s.data()->_length)
+    if (dataHandle[0]->_length < s.dataHandle[0]->_length)
         return FALSE;
         
-    for ( int i = dataHandle[0]->_length - s.data()->_length, j = 0; i < (int) s.data()->_length; i++, j++ ) {
+    for ( int i = dataHandle[0]->_length - s.dataHandle[0]->_length, j = 0; i < (int) s.dataHandle[0]->_length; i++, j++ ) {
 	if ( uni[i] != s[j] )
 	    return FALSE;
     }
     return TRUE;
 }
 
-const char *QString::latin1() const
-{
-    return dataHandle[0]->ascii();
-}
-
 QCString QString::utf8() const
 {
     uint len = dataHandle[0]->_length;
@@ -1169,7 +1080,7 @@ int QString::find(const QString &str, int index, bool caseSensitive) const
     */
     if ( index < 0 )
 	index += dataHandle[0]->_length;
-    int lstr = str.data()->_length;
+    int lstr = str.dataHandle[0]->_length;
     int lthis = dataHandle[0]->_length - index;
     if ( (uint)lthis > dataHandle[0]->_length )
 	return -1;
@@ -1388,7 +1299,7 @@ int QString::findRev( const QString& str, int index, bool cs ) const
     if ( index < 0 )
 	index += lthis;
 
-    int lstr = str.data()->_length;
+    int lstr = str.dataHandle[0]->_length;
     int delta = lthis - lstr;
     if ( index < 0 || index > lthis || delta < 0 )
 	return -1;
@@ -1533,7 +1444,7 @@ int QString::contains(const QString &str, bool caseSensitive) const
     const QChar *uc = unicode();
     if ( !str )
 	return 0;
-    int len = str.data()->_length;
+    int len = str.dataHandle[0]->_length;
     int n = dataHandle[0]->_length;
     while ( n-- ) {				// counts overlapping strings
 	// ### Doesn't account for length of this - searches over "end"
@@ -1677,17 +1588,19 @@ bye:
 
 double QString::toDouble(bool *ok) const
 {
+    if (isEmpty()) {
+        if (ok)
+            *ok = false;
+        return 0;
+    }
+    const char *s = latin1();
     char *end;
-
-    QCString a = latin1();
-
-    double val = strtod( a.data() ? a.data() : "", &end );
-    if ( ok )
-	*ok = ( a && *a && ( end == 0 || *end == '\0' ) );
+    double val = kjs_strtod(s, &end);
+    if (ok)
+	*ok = end == NULL || *end == '\0';
     return val;
 }
 
-
 bool QString::findArg(int& pos, int& len) const
 {
     char lowest=0;
@@ -1716,21 +1629,21 @@ QString QString::arg(const QString &a, int fieldwidth) const
 		  latin1(), a.latin1() );
 	// Make sure the text at least appears SOMEWHERE
 	r += ' ';
-	pos = r.data()->_length;
+	pos = r.dataHandle[0]->_length;
 	len = 0;
     }
 
     r.replace( pos, len, a );
     if ( fieldwidth < 0 ) {
 	QString s;
-	while ( (uint)-fieldwidth > a.data()->_length ) {
+	while ( (uint)-fieldwidth > a.dataHandle[0]->_length ) {
 	    s += ' ';
 	    fieldwidth++;
 	}
-	r.insert( pos + a.data()->_length, s );
+	r.insert( pos + a.dataHandle[0]->_length, s );
     } else if ( fieldwidth ) {
 	QString s;
-	while ( (uint)fieldwidth > a.data()->_length ) {
+	while ( (uint)fieldwidth > a.dataHandle[0]->_length ) {
 	    s += ' ';
 	    fieldwidth--;
 	}
@@ -1845,33 +1758,58 @@ QString QString::copy() const
 QString QString::lower() const
 {
     QString s(*this);
-    int l = dataHandle[0]->_length;
-    if ( l ) {
-	s.detach();
-        if (s.data()->_isAsciiValid){
-            char *p= (char *)s.ascii();
-            if ( p ) {
-                while ( l-- ) {
-                    *p = (*p >= 'A' && *p <= 'Z') ? (*p + caseDelta) : *p;
-                    p++;
+    KWQStringData *d = *s.dataHandle;
+    int l = d->_length;
+    if (l) {
+        bool detached = false;
+        if (d->_isAsciiValid) {
+            char *p = d->_ascii;
+            while (l--) {
+                char c = *p;
+                // FIXME: Doesn't work for 0x80-0xFF.
+                if (c >= 'A' && c <= 'Z') {
+                    if (!detached) {
+                        s.detach();
+                        d = *s.dataHandle;
+                        p = d->_ascii + d->_length - l - 1;
+                        detached = true;
+                    }
+                    *p = c + ('a' - 'A');
                 }
+                p++;
             }
         }
-        else if (s.data()->_isUnicodeValid){
-            QChar *p= (QChar *)s.unicode();
-            if ( p ) {
-                while ( l-- ) {
-                    if (IS_ASCII_QCHAR(*p)){
-                        *p = (*p >= (QChar)'A' && *p <= (QChar)'Z') ? (QChar)(*p + caseDelta) : *p;
+        else {
+            ASSERT(d->_isUnicodeValid);
+            QChar *p = d->_unicode;
+            while (l--) {
+                QChar c = *p;
+                // FIXME: Doesn't work for 0x80-0xFF.
+                if (IS_ASCII_QCHAR(c)) {
+                    if (c >= 'A' && c <= 'Z') {
+                        if (!detached) {
+                            s.detach();
+                            d = *s.dataHandle;
+                            p = d->_unicode + d->_length - l - 1;
+                            detached = true;
+                        }
+                        *p = c + ('a' - 'A');
+                    }
+                } else {
+                    QChar clower = c.lower();
+                    if (clower != c) {
+                        if (!detached) {
+                            s.detach();
+                            d = *s.dataHandle;
+                            p = d->_unicode + d->_length - l - 1;
+                            detached = true;
+                        }
+                        *p = clower;
                     }
-                    else
-                        *p = p->lower();
-                    p++;
                 }
+                p++;
             }
         }
-        else
-            FATAL("invalid character cache");
     }
     return s;
 }
@@ -1899,7 +1837,7 @@ QString QString::stripWhiteSpace() const
     if (dataHandle[0]->_isAsciiValid){
         result.setLength( l );
         if ( l )
-            memcpy( (char *)result.data()->ascii(), &ascii()[start], l );
+            memcpy( (char *)result.dataHandle[0]->ascii(), &ascii()[start], l );
     }
     else if (dataHandle[0]->_isUnicodeValid){
         result.setLength( l );
@@ -1989,8 +1927,8 @@ QString &QString::setUnicode(const QChar *uni, uint len)
         deref();
         if (needToFreeHandle)
             freeHandle(dataHandle);
-        dataHandle = (QStringData **)allocateHandle();
-	*dataHandle = new QStringData(uni, len);
+        dataHandle = (KWQStringData **)allocateHandle();
+	*dataHandle = new KWQStringData(uni, len);
         dataHandle[0]->_isHeapAllocated = 1;
     } else {
 	if ( uni )
@@ -2025,8 +1963,8 @@ QString &QString::setLatin1(const char *str, int len)
         deref();
         if (needToFreeHandle)
             freeHandle(dataHandle);
-        dataHandle = (QStringData **)allocateHandle();
-        *dataHandle = new QStringData(str,len);
+        dataHandle = (KWQStringData **)allocateHandle();
+        *dataHandle = new KWQStringData(str,len);
         dataHandle[0]->_isHeapAllocated = 1;
     } else {
         strcpy( (char *)ascii(), str );
@@ -2094,8 +2032,8 @@ QString &QString::sprintf(const char *format, ...)
         deref();
         if (needToFreeHandle)
             freeHandle(dataHandle);
-        dataHandle = (QStringData **)allocateHandle();
-        *dataHandle = new QStringData((char *)0, len);
+        dataHandle = (KWQStringData **)allocateHandle();
+        *dataHandle = new KWQStringData((char *)0, len);
         dataHandle[0]->_isHeapAllocated = 1;
     } else {
         dataHandle[0]->_length = len;
@@ -2174,17 +2112,17 @@ QString &QString::insert(uint index, const char *insertChars, uint insertLength)
 
 QString &QString::insert(uint index, const QString &qs)
 {
-    if (qs.data()->_length == 0)
+    if (qs.dataHandle[0]->_length == 0)
         return *this;
         
 #ifdef QSTRING_DEBUG_UNICODE
     forceUnicode();
 #endif
-    if (dataHandle[0]->_isAsciiValid && qs.data()->_isAsciiValid){
+    if (dataHandle[0]->_isAsciiValid && qs.dataHandle[0]->_isAsciiValid){
         insert (index, qs.ascii(), qs.length());
     }
     else {
-        uint insertLength = qs.data()->_length;
+        uint insertLength = qs.dataHandle[0]->_length;
         uint originalLength = dataHandle[0]->_length;
         QChar *targetChars;
         
@@ -2196,7 +2134,7 @@ QString &QString::insert(uint index, const QString &qs)
         memmove (targetChars+(index+insertLength), targetChars+index, (originalLength-index)*sizeof(QChar));
 
         // Insert characters.
-        if (qs.data()->_isAsciiValid){
+        if (qs.dataHandle[0]->_isAsciiValid){
             uint i = insertLength;
             QChar *target = targetChars+index;
             char *a = (char *)qs.ascii();
@@ -2314,36 +2252,31 @@ QString &QString::insert(uint index, char ch)
     return *this;
 }
 
-
-void QString::detachInternal()
+inline void QString::detachInternal()
 {
-    QStringData *oldData = *dataHandle;
-    
-    if (oldData->refCount > 1 && oldData == &internalData) {
-        QStringData *newData = NULL;
-        if (oldData->_isAsciiValid)
-            newData = new QStringData (oldData->ascii(), oldData->_length);
-        else if (oldData->_isUnicodeValid){
-            // No need to copy the allocated unicode bytes.
-            if (!oldData->_isUnicodeInternal){
-                newData = new QStringData (oldData->unicode(), oldData->_length, oldData->_maxUnicode);
-                oldData->_unicode = 0;
-                oldData->_isUnicodeValid = 0;
-            }
-            else
-                newData = new QStringData (oldData->unicode(), oldData->_length);
+    KWQStringData *oldData = *dataHandle;
+    KWQStringData *newData;
+    if (oldData->_isAsciiValid)
+        newData = new KWQStringData(oldData->ascii(), oldData->_length);
+    else {
+        ASSERT(oldData->_isUnicodeValid);
+        // No need to copy the allocated unicode bytes.
+        if (oldData->isUnicodeInternal())
+            newData = new KWQStringData(oldData->unicode(), oldData->_length);
+        else {
+            newData = new KWQStringData(oldData->unicode(), oldData->_length, oldData->_maxUnicode);
+            oldData->_unicode = 0;
+            oldData->_isUnicodeValid = 0;
         }
-        else
-            FATAL("invalid character cache");
-        newData->_isHeapAllocated = 1;
-        newData->refCount = oldData->refCount - 1;
-        *dataHandle = newData;
-        
-        oldData->refCount = 1;
     }
+    newData->_isHeapAllocated = 1;
+    newData->refCount = oldData->refCount - 1;
+    *dataHandle = newData;
+    
+    oldData->refCount = 1;
 }
 
-// Copy QStringData if necessary.  Must be called before the string data is mutated.
+// Copy KWQStringData if necessary. Must be called before the string data is mutated.
 void QString::detach()
 {
     if (dataHandle != shared_null_handle && dataHandle[0]->refCount == 1)
@@ -2352,26 +2285,21 @@ void QString::detach()
 #ifdef QSTRING_DEBUG_ALLOCATIONS
     stringDataDetachments++;
 #endif
-    QStringData *oldData = *dataHandle;
+    KWQStringData *oldData = *dataHandle;
     
     // Copy data for this string so we can safely mutate it,
     // and put it in a new handle.
-    QStringData *newData = NULL;
+    KWQStringData *newData;
     if (oldData->_isAsciiValid)
-        newData = new QStringData (oldData->ascii(), oldData->_length);
-    else if (oldData->_isUnicodeValid)
-        newData = new QStringData (oldData->unicode(), oldData->_length);
-    else if (oldData == shared_null) {
-        newData = new QStringData;
-    }
+        newData = new KWQStringData(oldData->ascii(), oldData->_length);
     else
-        FATAL("invalid character cache");
+        newData = new KWQStringData(oldData->unicode(), oldData->_length);
 
     // Copy our internal data so other strings can still safely reference it.
-    detachInternal();
+    detachIfInternal();
     
     newData->_isHeapAllocated = 1;
-    dataHandle = (QStringData **)allocateHandle();
+    dataHandle = (KWQStringData **)allocateHandle();
     *dataHandle = newData;
     
     // Release the old data.
@@ -2419,7 +2347,7 @@ QString &QString::replace(const QRegExp &qre, const QString &str)
     if ( isEmpty() )
 	return *this;
     int index = 0;
-    int slen  = str.data()->_length;
+    int slen  = str.dataHandle[0]->_length;
     int len;
     while ( index < (int)dataHandle[0]->_length ) {
 	index = qre.match( *this, index, &len, FALSE );
@@ -2454,8 +2382,8 @@ void QString::setLength(uint newLen)
     // If we going to change the length, we'll need our own data.
     if (dataHandle == shared_null_handle) {
         deref();
-        dataHandle = (QStringData **)allocateHandle();
-        *dataHandle = new QStringData();
+        dataHandle = (KWQStringData **)allocateHandle();
+        *dataHandle = new KWQStringData();
         dataHandle[0]->_isHeapAllocated = 1;
     }
     
@@ -2511,14 +2439,13 @@ void QString::fill(QChar qc, int len)
             shared_null->ref();
         }
     } else {
-        if (dataHandle[0]->_isAsciiValid && IS_ASCII_QCHAR(qc)){
+        if (dataHandle[0]->_isAsciiValid && IS_ASCII_QCHAR(qc)) {
             setLength(len);
             char *nd = (char *)ascii();
             while (len--) 
                 *nd++ = (char)qc;
             dataHandle[0]->_isUnicodeValid = 0;
-        }
-        else {
+        } else {
             setLength(len);
             QChar *nd = forceUnicode();
             while (len--) 
@@ -2544,33 +2471,33 @@ QString &QString::operator+=(const QString &qs)
 {
     detach();
 
-    if (dataHandle[0]->_isUnicodeValid && dataHandle[0]->_length + qs.data()->_length < dataHandle[0]->_maxUnicode){
-        uint i = qs.data()->_length;
+    if (dataHandle[0]->_isUnicodeValid && dataHandle[0]->_length + qs.dataHandle[0]->_length < dataHandle[0]->_maxUnicode){
+        uint i = qs.dataHandle[0]->_length;
         QChar *tp = &dataHandle[0]->_unicode[dataHandle[0]->_length];
-        if (qs.data()->_isAsciiValid){
+        if (qs.dataHandle[0]->_isAsciiValid){
             char *fp = (char *)qs.ascii();
             while (i--)
                 *tp++ = *fp++;
         }
-        else if(qs.data()->_isUnicodeValid){
+        else if(qs.dataHandle[0]->_isUnicodeValid){
             QChar *fp = (QChar *)qs.unicode();
             while (i--)
                 *tp++ = *fp++;
         }
         else 
             FATAL("invalid character cache");
-        dataHandle[0]->_length += qs.data()->_length;
+        dataHandle[0]->_length += qs.dataHandle[0]->_length;
         dataHandle[0]->_isAsciiValid = 0;
         return *this;
     }
-    else if (dataHandle[0]->_isAsciiValid && qs.data()->_isAsciiValid && dataHandle[0]->_length + qs.data()->_length < dataHandle[0]->_maxAscii){
-        uint i = qs.data()->_length;
+    else if (dataHandle[0]->_isAsciiValid && qs.dataHandle[0]->_isAsciiValid && dataHandle[0]->_length + qs.dataHandle[0]->_length < dataHandle[0]->_maxAscii){
+        uint i = qs.dataHandle[0]->_length;
         char *tp = &dataHandle[0]->_ascii[dataHandle[0]->_length];
         char *fp = (char *)qs.ascii();
         while (i--)
             *tp++ = *fp++;
         *tp = 0;
-        dataHandle[0]->_length += qs.data()->_length;
+        dataHandle[0]->_length += qs.dataHandle[0]->_length;
         dataHandle[0]->_isUnicodeValid = 0;
         return *this;
     }
@@ -2581,17 +2508,17 @@ QString &QString::operator+=(QChar qc)
 {
     detach();
     
-    QStringData *thisData = *dataHandle;
+    KWQStringData *thisData = *dataHandle;
     if (thisData->_isUnicodeValid && thisData->_length + 1 < thisData->_maxUnicode){
-        thisData->_unicode[data()->_length] = qc;
+        thisData->_unicode[thisData->_length] = qc;
         thisData->_length++;
         thisData->_isAsciiValid = 0;
         return *this;
     }
     else if (thisData->_isAsciiValid && IS_ASCII_QCHAR(qc) && thisData->_length + 2 < thisData->_maxAscii){
-        thisData->_ascii[data()->_length] = (char)qc;
+        thisData->_ascii[thisData->_length] = (char)qc;
         thisData->_length++;
-        thisData->_ascii[data()->_length] = 0;
+        thisData->_ascii[thisData->_length] = 0;
         thisData->_isUnicodeValid = 0;
         return *this;
     }
@@ -2602,7 +2529,7 @@ QString &QString::operator+=(char ch)
 {
     detach();
     
-    QStringData *thisData = *dataHandle;
+    KWQStringData *thisData = *dataHandle;
     if (thisData->_isUnicodeValid && thisData->_length + 1 < thisData->_maxUnicode){
         thisData->_unicode[thisData->_length] = (QChar)ch;
         thisData->_length++;
@@ -2621,32 +2548,35 @@ QString &QString::operator+=(char ch)
 
 bool operator==(const QString &s1, const QString &s2)
 {
-    if (s1.data()->_isAsciiValid && s2.data()->_isAsciiValid) {
+    if (s1.dataHandle[0]->_isAsciiValid && s2.dataHandle[0]->_isAsciiValid) {
         return strcmp(s1.ascii(), s2.ascii()) == 0;
     }
-    return s1.data()->_length == s2.data()->_length
-        && memcmp(s1.unicode(), s2.unicode(), s1.data()->_length * sizeof(QChar)) == 0;
+    return s1.dataHandle[0]->_length == s2.dataHandle[0]->_length
+        && memcmp(s1.unicode(), s2.unicode(), s1.dataHandle[0]->_length * sizeof(QChar)) == 0;
 }
 
 bool operator==(const QString &s1, const char *chs)
 {
     if (!chs)
         return s1.isNull();
-    uint length = strlen(chs);
-    if (s1.data()->_length != length)
-        return false;
-    if (s1.data()->_isAsciiValid) {
+    KWQStringData *d = s1.dataHandle[0];
+    uint len = d->_length;
+    if (d->_isAsciiValid) {
         const char *s = s1.ascii();
-        for (uint i = 0; i != length; ++i)
-            if (s[i] != chs[i])
+        for (uint i = 0; i != len; ++i) {
+            char c = chs[i];
+            if (!c || s[i] != c)
                 return false;
+        }
     } else {
         const QChar *s = s1.unicode();
-        for (uint i = 0; i != length; ++i)
-            if (s[i] != chs[i])
+        for (uint i = 0; i != len; ++i) {
+            char c = chs[i];
+            if (!c || s[i] != c)
                 return false;
+        }
     }
-    return true;
+    return chs[len] == '\0';
 }
 
 uint QString::hash() const
@@ -2657,7 +2587,7 @@ uint QString::hash() const
         uint prefixLength = len < 8 ? len : 8;
         uint suffixPosition = len < 16 ? 8 : len - 8;
     
-        if (data()->_isAsciiValid) {
+        if (dataHandle[0]->_isAsciiValid) {
             const char *s = ascii();
             for (uint i = 0; i < prefixLength; i++)
                 h = 127 * h + (unsigned char)s[i];
@@ -2712,30 +2642,28 @@ QString operator+(char ch, const QString &qs)
 }
 
 QConstString::QConstString(const QChar* unicode, uint length) :
-    QString(new QStringData((QChar *)unicode, length, length), true)
+    QString(new KWQStringData((QChar *)unicode, length, length), true)
 {
 }
 
 QConstString::~QConstString()
 {
-    if (dataHandle[0]->refCount > 1) {
-        QChar *tp, *fp = (QChar *)unicode();
-        if (dataHandle[0]->_length <= QS_INTERNAL_BUFFER_UCHARS){
-            dataHandle[0]->_maxUnicode = QS_INTERNAL_BUFFER_UCHARS;
-            tp = (QChar *)&dataHandle[0]->_internalBuffer[0];
-            dataHandle[0]->_isUnicodeInternal = 1;
-        }
-        else {
-            dataHandle[0]->_maxUnicode = ALLOC_QCHAR_GOOD_SIZE(dataHandle[0]->_length);
-            tp = ALLOC_QCHAR( dataHandle[0]->_maxUnicode );
-            dataHandle[0]->_isUnicodeInternal = 0;
+    KWQStringData *data = *dataHandle;
+    if (data->refCount > 1) {
+        QChar *tp;
+        if (data->_length <= QS_INTERNAL_BUFFER_UCHARS) {
+            data->_maxUnicode = QS_INTERNAL_BUFFER_UCHARS;
+            tp = (QChar *)&data->_internalBuffer[0];
+        } else {
+            data->_maxUnicode = ALLOC_QCHAR_GOOD_SIZE(data->_length);
+            tp = ALLOC_QCHAR(data->_maxUnicode);
         }
-        memcpy( tp, fp, dataHandle[0]->_length*sizeof(QChar) );
-        dataHandle[0]->_unicode = tp;
-	dataHandle[0]->_isUnicodeValid = 1;
-        dataHandle[0]->_isAsciiValid = 0;
+        memcpy(tp, data->_unicode, data->_length * sizeof(QChar));
+        data->_unicode = tp;
+	data->_isUnicodeValid = 1;
+        data->_isAsciiValid = 0;
     } else {
-	dataHandle[0]->_unicode = 0;
+	data->_unicode = 0;
     }
 }
 
diff --git a/WebCore/kwq/Makefile.am b/WebCore/kwq/Makefile.am
index 9382809..d86be78 100644
--- a/WebCore/kwq/Makefile.am
+++ b/WebCore/kwq/Makefile.am
@@ -1,5 +1,8 @@
 KWQCharsetData.c: make-charset-table.pl character-sets.txt mac-encodings.txt
 	perl $^ > $@
 
-BUILT_SOURCES = KWQCharsetData.c
+KWQColorData.c: KWQColorData.gperf Makefile.am
+	gperf -CDEot -L 'ANSI-C' -k '*' -N findColor $< > $@ 
+
+BUILT_SOURCES = KWQCharsetData.c KWQColorData.c
 CLEANFILES = $(BUILT_SOURCES)

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list