[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 08:25:49 UTC 2009
The following commit has been merged in the debian/unstable branch:
commit 30cd23394a21faa1d66a8093d5386f66073533be
Author: darin <darin at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Sun Feb 8 22:40:10 2004 +0000
WebCore:
Reviewed by Dave.
- fixed things seen in the profile, for a total speedup of 4% on cvs-base
- fixed some layout regressions from my last speedup due to text measurement inconsistencies
* WebCorePrefix.h: Add a workaround for a bug in our system headers that prevents the <ctype.h>
macros from working right in C++ code that uses the <cctype> header.
* khtml/css/cssstyleselector.cpp:
(khtml::checkPseudoState): Use prepend instead of operator + here. Will probably be obviated if
someone fixes the checkPseudoState problem.
(khtml::colorForCSSValue): Get rid of all the code that uses QPalette; it wasn't doing any good
in Safari. Instead, hardcode the UI colors.
* kwq/KWQChar.mm:
(QChar::isDigitNonASCII): Non-inline part. The ASCII case is handled with an inline now.
(QChar::isLetterNonASCII): Ditto.
(QChar::isNumberNonASCII): Ditto.
(QChar::isLetterOrNumberNonASCII): Ditto.
(QChar::lowerNonASCII): Ditto.
(QChar::upperNonASCII): Ditto.
(QChar::digitValueNonASCII): Ditto.
* kwq/KWQColorGroup.mm: Put all roles base inside #if, since we don't need them, and copying
the color group and palette was making things slow.
* kwq/KWQComboBox.h: Remove KWQComboBoxAdapter, not needed any more.
* kwq/KWQComboBox.mm:
(QComboBox::QComboBox): Remove KWQComboBoxAdapter, not needed any more.
(QComboBox::~QComboBox): Ditto.
(QComboBox::sizeHint): Turn off rounding; we use that in web text, but not in widgets.
(-[KWQPopUpButton action:]): Moved the action method here.
* kwq/KWQLineEdit.mm: (QLineEdit::sizeForCharacterWidth): Turn off rounding. We use it in web
page text, but not in widgets.
* kwq/KWQListBox.mm:
(QListBox::sizeForNumberOfLines): Ditto.
(-[KWQTableView drawRow:clipRect:]): Ditto.
* kwq/KWQKURL.mm:
(KURL::KURL): Added code to put the "file:" in front of a path without making a QString.
(hasSlashDotOrDotDot): Added. Faster than two calls to strstr.
(matchLetter): Added. Faster than tolower calls on each letter.
(KURL::parse): Changed to use matchLetter and hasSlashDotOrDotDot.
* kwq/KWQPalette.h: Remove all roles except base, and all groups except active, since we don't
need them, and copying the color group and palette was making things slow.
* kwq/KWQPalette.mm: Ditto.
* kwq/KWQRegExp.mm: (QRegExp::match): Fixed logic so we don't create and destroy a QCString
in the fast case. Also avoid UTF-8/UTF-16 offset mapping.
* kwq/KWQString.h:
(QChar::isDigit): Add inline section for ASCII.
(QChar::isLetter): Ditto.
(QChar::isNumber): Ditto.
(QChar::isLetterOrNumber): Ditto.
(QChar::digitValue): Ditto.
(QChar::lower): Ditto.
(QChar::upper): Ditto.
(QString::utf8): Add a new version that returns the length; used by QRegExp.
(QString::operator+=): Call a new append function.
* kwq/KWQString.mm:
(ucstrcmp): Made this function inline.
(equal): Added, replacing various strcmp functions.
(equalCaseInsensitive): Ditto.
(ok_in_base): Changed to use <ctype.h> isdigit and isalpha instead of QChar functions.
(QString::detachInternal): Moved up so it will be inlined.
(QString::~QString): Streamlined a little.
(QString::utf8): Changed to return the length.
(QString::find): Use unicode() instead of cell() in various places. Also refined a faster
version of the one that takes a char *.
(QString::contains): Changed all of the overloads to have structure that's more similar,
and made them slightly faster too.
(QString::isAllLatin1): Added.
(QString::copyLatin1): Added. Lets you get the string as a char * buffer without changing
the string itself into that format.
(QString::toLong): Changed to use <ctype.h> isdigit instead of QChar function.
(QString::toULong): Ditto.
(QString::setUnicode): Call the new detachAndDiscardCharacters; not implemented yet.
(QString::setLatin1): Call the new detachAndDiscardCharacters; not implemented yet.
(QString::sprintf): Call the new detachAndDiscardCharacters; not implemented yet.
(QString::insert): Remove one memmove call for the case that appends at the end.
(QString::detach): Change code to use the internal data if we can; saves at destructor time.
(QString::detachAndDiscardCharacters): Added. Placeholder for now that just calls detach().
(QString::setLength): Optimize the setLength(0) case.
(QString::fill): Call the new detachAndDiscardCharacters; not implemented yet.
(QString::append): Renamed from operator+=, which now simply calls append().
(QString::reserve): Added. Useful when building up a string, like in QTextCodec.
* WebCore-tests.exp: Added new function names for QChar.
* WebCore-combined.exp: Updated.
* kwq/KWQTextCodec.mm:
(KWQTextDecoder::convertLatin1): Added. Since this is the most common encoding, and very
easy to decode (built into QString, in fact), best to do it as a special case, not with TEC.
(KWQTextDecoder::convertUTF16): Added a reserve() call for better performance and made the
stack buffer larger.
(KWQTextDecoder::convertUsingTEC): Added a reserve() call for better performance and made the
stack buffer larger.
(KWQTextDecoder::convert): Added a switch statement and convertLatin1 case.
* kwq/KWQView.h: Removed the KWQView class.
* kwq/KWQView.mm: Removed.
* WebCore.pbproj/project.pbxproj: Removed KWQView.mm.
* kwq/KWQWidget.h: Changed name of QWidgetPrivate to KWQWidgetPrivate.
* kwq/KWQWidget.mm:
(QWidget::QWidget): Got rid of code that makes a KWQView when no view is passed in. We were
creating and destroying extra views because of this.
(QWidget::setFrameGeometry): Only call getOuterView() once, not three times. Also, don't do
any work at all if the frame is already correct.
* khtml/khtmlview.cpp: (KHTMLView::init): Removed a call that will hit an assertion due to the
way a new KHTMLView does not yet have an NSView.
* kwq/WebCoreTextRenderer.h: Broke applyRounding into applyRunRounding and applyWordRounding.
* kwq/WebCoreTextRendererFactory.m: (WebCoreInitializeEmptyTextStyle): Initialize both rounding
flags on.
WebKit:
Reviewed by Dave.
- fixed things seen in the profile, for a total speedup of 4% on cvs-base
- fixed some layout regressions from my last speedup due to text measurement inconsistencies by adding
a flag to control whether word rounding is done or not
- fixed text measurement to be used with AppKit to match AppKit again, as it did at some point in the past
* WebCoreSupport.subproj/WebTextRenderer.h: Remove some unused fields, and added a field to say whether we
treat this font as fixed pitch.
* WebCoreSupport.subproj/WebTextRenderer.m:
(getUncachedWidth): Remove space width hack from this level. There was already a width hack up at the higher
level for space itself, so there's not a significant speed benefit, and the higher level can make a more
intelligent choice based on the current rounding setting since it's not cached.
(-[WebTextRenderer _computeWidthForSpace]): Don't store so many widths; just the adjusted width we will
actually use.
(widthForNextCharacter): Use two different rules for when to adjust space widths, based on whether this is
a fixed pitch font or not. Also, don't do any adjusting of space widths if applyWordRounding is false.
* Misc.subproj/WebKitNSStringExtras.m:
(-[NSString _web_drawAtPoint:font:textColor:]): Turn off rounding, so we get the kind of spacing AppKit would normally give.
(-[NSString _web_widthWithFont:]): Ditto.
* Misc.subproj/WebStringTruncator.m: (stringWidth): Ditto.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6052 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/fast/overflow/005-expected.txt b/LayoutTests/fast/overflow/005-expected.txt
new file mode 100644
index 0000000..c7bc8d7
--- /dev/null
+++ b/LayoutTests/fast/overflow/005-expected.txt
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600
+ RenderCanvas at (0,0) size 800x600
+layer at (0,0) size 800x66
+ RenderBlock {HTML} at (0,0) size 800x66
+ RenderBody {BODY} at (8,8) size 784x45
+layer at (8,8) size 300x45 clip at (8,8) size 300x30
+ RenderBlock {PRE} at (0,0) size 300x45
+ RenderText {TEXT} at (0,0) size 312x30
+ text run at (0,0) width 312: "This is a test to see if this messes up"
+ text run at (0,15) width 240: "the way I think it's going to."
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 5d4f722..0c6db94 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,124 @@
+2004-02-08 Darin Adler <darin at apple.com>
+
+ Reviewed by Dave.
+
+ - fixed things seen in the profile, for a total speedup of 4% on cvs-base
+ - fixed some layout regressions from my last speedup due to text measurement inconsistencies
+
+ * WebCorePrefix.h: Add a workaround for a bug in our system headers that prevents the <ctype.h>
+ macros from working right in C++ code that uses the <cctype> header.
+
+ * khtml/css/cssstyleselector.cpp:
+ (khtml::checkPseudoState): Use prepend instead of operator + here. Will probably be obviated if
+ someone fixes the checkPseudoState problem.
+ (khtml::colorForCSSValue): Get rid of all the code that uses QPalette; it wasn't doing any good
+ in Safari. Instead, hardcode the UI colors.
+
+ * kwq/KWQChar.mm:
+ (QChar::isDigitNonASCII): Non-inline part. The ASCII case is handled with an inline now.
+ (QChar::isLetterNonASCII): Ditto.
+ (QChar::isNumberNonASCII): Ditto.
+ (QChar::isLetterOrNumberNonASCII): Ditto.
+ (QChar::lowerNonASCII): Ditto.
+ (QChar::upperNonASCII): Ditto.
+ (QChar::digitValueNonASCII): Ditto.
+
+ * kwq/KWQColorGroup.mm: Put all roles base inside #if, since we don't need them, and copying
+ the color group and palette was making things slow.
+
+ * kwq/KWQComboBox.h: Remove KWQComboBoxAdapter, not needed any more.
+ * kwq/KWQComboBox.mm:
+ (QComboBox::QComboBox): Remove KWQComboBoxAdapter, not needed any more.
+ (QComboBox::~QComboBox): Ditto.
+ (QComboBox::sizeHint): Turn off rounding; we use that in web text, but not in widgets.
+ (-[KWQPopUpButton action:]): Moved the action method here.
+
+ * kwq/KWQLineEdit.mm: (QLineEdit::sizeForCharacterWidth): Turn off rounding. We use it in web
+ page text, but not in widgets.
+ * kwq/KWQListBox.mm:
+ (QListBox::sizeForNumberOfLines): Ditto.
+ (-[KWQTableView drawRow:clipRect:]): Ditto.
+
+ * kwq/KWQKURL.mm:
+ (KURL::KURL): Added code to put the "file:" in front of a path without making a QString.
+ (hasSlashDotOrDotDot): Added. Faster than two calls to strstr.
+ (matchLetter): Added. Faster than tolower calls on each letter.
+ (KURL::parse): Changed to use matchLetter and hasSlashDotOrDotDot.
+
+ * kwq/KWQPalette.h: Remove all roles except base, and all groups except active, since we don't
+ need them, and copying the color group and palette was making things slow.
+ * kwq/KWQPalette.mm: Ditto.
+
+ * kwq/KWQRegExp.mm: (QRegExp::match): Fixed logic so we don't create and destroy a QCString
+ in the fast case. Also avoid UTF-8/UTF-16 offset mapping.
+
+ * kwq/KWQString.h:
+ (QChar::isDigit): Add inline section for ASCII.
+ (QChar::isLetter): Ditto.
+ (QChar::isNumber): Ditto.
+ (QChar::isLetterOrNumber): Ditto.
+ (QChar::digitValue): Ditto.
+ (QChar::lower): Ditto.
+ (QChar::upper): Ditto.
+ (QString::utf8): Add a new version that returns the length; used by QRegExp.
+ (QString::operator+=): Call a new append function.
+ * kwq/KWQString.mm:
+ (ucstrcmp): Made this function inline.
+ (equal): Added, replacing various strcmp functions.
+ (equalCaseInsensitive): Ditto.
+ (ok_in_base): Changed to use <ctype.h> isdigit and isalpha instead of QChar functions.
+ (QString::detachInternal): Moved up so it will be inlined.
+ (QString::~QString): Streamlined a little.
+ (QString::utf8): Changed to return the length.
+ (QString::find): Use unicode() instead of cell() in various places. Also refined a faster
+ version of the one that takes a char *.
+ (QString::contains): Changed all of the overloads to have structure that's more similar,
+ and made them slightly faster too.
+ (QString::isAllLatin1): Added.
+ (QString::copyLatin1): Added. Lets you get the string as a char * buffer without changing
+ the string itself into that format.
+ (QString::toLong): Changed to use <ctype.h> isdigit instead of QChar function.
+ (QString::toULong): Ditto.
+ (QString::setUnicode): Call the new detachAndDiscardCharacters; not implemented yet.
+ (QString::setLatin1): Call the new detachAndDiscardCharacters; not implemented yet.
+ (QString::sprintf): Call the new detachAndDiscardCharacters; not implemented yet.
+ (QString::insert): Remove one memmove call for the case that appends at the end.
+ (QString::detach): Change code to use the internal data if we can; saves at destructor time.
+ (QString::detachAndDiscardCharacters): Added. Placeholder for now that just calls detach().
+ (QString::setLength): Optimize the setLength(0) case.
+ (QString::fill): Call the new detachAndDiscardCharacters; not implemented yet.
+ (QString::append): Renamed from operator+=, which now simply calls append().
+ (QString::reserve): Added. Useful when building up a string, like in QTextCodec.
+
+ * WebCore-tests.exp: Added new function names for QChar.
+ * WebCore-combined.exp: Updated.
+
+ * kwq/KWQTextCodec.mm:
+ (KWQTextDecoder::convertLatin1): Added. Since this is the most common encoding, and very
+ easy to decode (built into QString, in fact), best to do it as a special case, not with TEC.
+ (KWQTextDecoder::convertUTF16): Added a reserve() call for better performance and made the
+ stack buffer larger.
+ (KWQTextDecoder::convertUsingTEC): Added a reserve() call for better performance and made the
+ stack buffer larger.
+ (KWQTextDecoder::convert): Added a switch statement and convertLatin1 case.
+
+ * kwq/KWQView.h: Removed the KWQView class.
+ * kwq/KWQView.mm: Removed.
+ * WebCore.pbproj/project.pbxproj: Removed KWQView.mm.
+
+ * kwq/KWQWidget.h: Changed name of QWidgetPrivate to KWQWidgetPrivate.
+ * kwq/KWQWidget.mm:
+ (QWidget::QWidget): Got rid of code that makes a KWQView when no view is passed in. We were
+ creating and destroying extra views because of this.
+ (QWidget::setFrameGeometry): Only call getOuterView() once, not three times. Also, don't do
+ any work at all if the frame is already correct.
+ * khtml/khtmlview.cpp: (KHTMLView::init): Removed a call that will hit an assertion due to the
+ way a new KHTMLView does not yet have an NSView.
+
+ * kwq/WebCoreTextRenderer.h: Broke applyRounding into applyRunRounding and applyWordRounding.
+ * kwq/WebCoreTextRendererFactory.m: (WebCoreInitializeEmptyTextStyle): Initialize both rounding
+ flags on.
+
2004-02-07 Darin Adler <darin at apple.com>
Reviewed by Dave.
diff --git a/WebCore/WebCore-combined.exp b/WebCore/WebCore-combined.exp
index 1eab8a1..940439d 100644
--- a/WebCore/WebCore-combined.exp
+++ b/WebCore/WebCore-combined.exp
@@ -146,6 +146,10 @@ __ZN4KURLC1ERKS_
__ZN4KURLC1ERKS_RK7QStringPK10QTextCodec
__ZN4KURLC1Ev
__ZN4KURLD1Ev
+__ZN5QChar13lowerNonASCIIEt
+__ZN5QChar13upperNonASCIIEt
+__ZN5QChar15isDigitNonASCIIEt
+__ZN5QChar24isLetterOrNumberNonASCIIEt
__ZN5QDateC1Eiii
__ZN5QFile4openEi
__ZN5QFile5closeEv
@@ -169,7 +173,9 @@ __ZN7QRegExpC1EPKc
__ZN7QRegExpC1ERK7QStringbb
__ZN7QRegExpD1Ev
__ZN7QString4fillE5QChari
+__ZN7QString6appendE5QChar
__ZN7QString6appendERKS_
+__ZN7QString6appendEc
__ZN7QString6insertEj5QChar
__ZN7QString6insertEjRKS_
__ZN7QString6insertEjc
diff --git a/WebCore/WebCore-tests.exp b/WebCore/WebCore-tests.exp
index 07d0efe..92b3b2f 100644
--- a/WebCore/WebCore-tests.exp
+++ b/WebCore/WebCore-tests.exp
@@ -112,6 +112,10 @@ __ZN4KURLC1ERKS_
__ZN4KURLC1ERKS_RK7QStringPK10QTextCodec
__ZN4KURLC1Ev
__ZN4KURLD1Ev
+__ZN5QChar13lowerNonASCIIEt
+__ZN5QChar13upperNonASCIIEt
+__ZN5QChar15isDigitNonASCIIEt
+__ZN5QChar24isLetterOrNumberNonASCIIEt
__ZN5QDateC1Eiii
__ZN5QFile4openEi
__ZN5QFile5closeEv
@@ -135,7 +139,9 @@ __ZN7QRegExpC1EPKc
__ZN7QRegExpC1ERK7QStringbb
__ZN7QRegExpD1Ev
__ZN7QString4fillE5QChari
+__ZN7QString6appendE5QChar
__ZN7QString6appendERKS_
+__ZN7QString6appendEc
__ZN7QString6insertEj5QChar
__ZN7QString6insertEjRKS_
__ZN7QString6insertEjc
diff --git a/WebCore/WebCore.pbproj/project.pbxproj b/WebCore/WebCore.pbproj/project.pbxproj
index 83f472f..c609a6d 100644
--- a/WebCore/WebCore.pbproj/project.pbxproj
+++ b/WebCore/WebCore.pbproj/project.pbxproj
@@ -637,7 +637,6 @@
F58785CE02DE375901EA4122,
F58785CF02DE375901EA4122,
F58785D102DE375901EA4122,
- F58785D302DE375901EA4122,
F58785D402DE375901EA4122,
F58785D602DE375901EA4122,
F58785DA02DE375901EA4122,
@@ -2772,7 +2771,6 @@
F587851B02DE375901EA4122,
F587851C02DE375901EA4122,
F587854002DE375901EA4122,
- F587854102DE375901EA4122,
F587854302DE375901EA4122,
F587854402DE375901EA4122,
BC7B2AF80450824100A8000F,
@@ -7118,14 +7116,6 @@
refType = 4;
sourceTree = "<group>";
};
- F587854102DE375901EA4122 = {
- fileEncoding = 30;
- isa = PBXFileReference;
- lastKnownFileType = sourcecode.cpp.objcpp;
- path = KWQView.mm;
- refType = 4;
- sourceTree = "<group>";
- };
F587854202DE375901EA4122 = {
fileEncoding = 30;
isa = PBXFileReference;
@@ -7886,12 +7876,6 @@
settings = {
};
};
- F58785D302DE375901EA4122 = {
- fileRef = F587854102DE375901EA4122;
- isa = PBXBuildFile;
- settings = {
- };
- };
F58785D402DE375901EA4122 = {
fileRef = F587854202DE375901EA4122;
isa = PBXBuildFile;
diff --git a/WebCore/WebCorePrefix.h b/WebCore/WebCorePrefix.h
index 8d4208c..f8e190a 100644
--- a/WebCore/WebCorePrefix.h
+++ b/WebCore/WebCorePrefix.h
@@ -30,6 +30,22 @@
#include <ostream>
#endif
+// Work around bug 3553309 by re-including <ctype.h>.
+#include <cctype>
+#define isalnum(c) __istype((c), (_CTYPE_A|_CTYPE_D))
+#define isalpha(c) __istype((c), _CTYPE_A)
+#define iscntrl(c) __istype((c), _CTYPE_C)
+#define isdigit(c) __isctype((c), _CTYPE_D) /* ANSI -- locale independent */
+#define isgraph(c) __istype((c), _CTYPE_G)
+#define islower(c) __istype((c), _CTYPE_L)
+#define isprint(c) __istype((c), _CTYPE_R)
+#define ispunct(c) __istype((c), _CTYPE_P)
+#define isspace(c) __istype((c), _CTYPE_S)
+#define isupper(c) __istype((c), _CTYPE_U)
+#define isxdigit(c) __isctype((c), _CTYPE_X) /* ANSI -- locale independent */
+#define tolower(c) __tolower(c)
+#define toupper(c) __toupper(c)
+
#endif
#include <sys/types.h>
diff --git a/WebCore/khtml/css/cssstyleselector.cpp b/WebCore/khtml/css/cssstyleselector.cpp
index 2f2f3eb..59331ac 100644
--- a/WebCore/khtml/css/cssstyleselector.cpp
+++ b/WebCore/khtml/css/cssstyleselector.cpp
@@ -2,7 +2,7 @@
* This file is part of the CSS implementation for KDE.
*
* Copyright (C) 1999 Lars Knoll (knoll at kde.org)
- * Copyright (C) 2003 Apple Computer, Inc.
+ * Copyright (C) 2004 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -756,11 +756,11 @@ static void checkPseudoState( DOM::ElementImpl *e, bool checkVisited = true )
QString u = cu.string();
if ( !u.contains("://") ) {
if ( u[0] == '/' )
- u = encodedurl->host + u;
+ u.prepend(encodedurl->host);
else if ( u[0] == '#' )
- u = encodedurl->file + u;
+ u.prepend(encodedurl->file);
else
- u = encodedurl->path + u;
+ u.prepend(encodedurl->path);
cleanpath( u );
}
//completeURL( attr.string() );
@@ -1321,10 +1321,42 @@ static const colorMap cmap[] = {
{ CSS_VAL_YELLOW, 0xFFFFFF00 },
{ CSS_VAL_INVERT, invertedColor },
{ CSS_VAL_TRANSPARENT, transparentColor },
- { CSS_VAL_GREY, 0xff808080 },
+ { CSS_VAL_GREY, 0xFF808080 },
+#if APPLE_CHANGES
+ { CSS_VAL_ACTIVEBORDER, 0xFFE0E0E0 },
+ { CSS_VAL_ACTIVECAPTION, 0xFF000000 },
+ { CSS_VAL_APPWORKSPACE, 0xFF000000 },
+ { CSS_VAL_BUTTONFACE, 0xFFC0C0C0 },
+ { CSS_VAL_BUTTONHIGHLIGHT, 0xFFE0E0E0 },
+ { CSS_VAL_BUTTONSHADOW, 0xFFFFFFFF },
+ { CSS_VAL_BUTTONTEXT, 0xFF000000 },
+ { CSS_VAL_CAPTIONTEXT, 0xFF000000 },
+ { CSS_VAL_GRAYTEXT, 0xFF000000 },
+ { CSS_VAL_HIGHLIGHT, 0xFFFFFFFF },
+ { CSS_VAL_HIGHLIGHTTEXT, 0xFFFFFFFF },
+ { CSS_VAL_INACTIVEBORDER, 0xFFFFFFFF },
+ { CSS_VAL_INACTIVECAPTION, 0xFFFFFFFF },
+ { CSS_VAL_INACTIVECAPTIONTEXT, 0xFF000000 },
+ { CSS_VAL_INFOBACKGROUND, 0xFF000000 },
+ { CSS_VAL_INFOTEXT, 0xFF000000 },
+ { CSS_VAL_MENU, 0xFFFFFFFF },
+ { CSS_VAL_MENUTEXT, 0xFFFFFFFF },
+ { CSS_VAL_SCROLLBAR, 0xFFFFFFFF },
+ { CSS_VAL_TEXT, 0xFF000000 },
+ { CSS_VAL_THREEDDARKSHADOW, 0xFF404040 },
+ { CSS_VAL_THREEDFACE, 0xFFC0C0C0 },
+ { CSS_VAL_THREEDHIGHLIGHT, 0xFFE0E0E0 },
+ { CSS_VAL_THREEDLIGHTSHADOW, 0xFFC0C0C0 },
+ { CSS_VAL_THREEDSHADOW, 0xFFFFFFFF },
+ { CSS_VAL_WINDOW, 0xFFFFFFFF },
+ { CSS_VAL_WINDOWFRAME, 0xFFFFFFFF },
+ { CSS_VAL_WINDOWTEXT, 0xFF000000 },
+#endif
{ 0, 0 }
};
+#if !APPLE_CHANGES
+
struct uiColors {
int css_value;
const char * configGroup;
@@ -1400,6 +1432,8 @@ static const uiColors uimap[] = {
{ 0, 0, 0, QPalette::NColorGroups, QColorGroup::NColorRoles }
};
+#endif // !APPLE_CHANGES
+
static QColor colorForCSSValue( int css_value )
{
// try the regular ones first
@@ -1409,10 +1443,12 @@ static QColor colorForCSSValue( int css_value )
if ( col->css_value )
return col->color;
+#if APPLE_CHANGES
+ return QColor();
+#else
const uiColors *uicol = uimap;
while ( uicol->css_value && uicol->css_value != css_value )
++uicol;
-#if !APPLE_CHANGES
if ( !uicol->css_value ) {
if ( css_value == CSS_VAL_INFOBACKGROUND )
return QToolTip::palette().inactive().background();
@@ -1426,20 +1462,18 @@ static QColor colorForCSSValue( int css_value )
}
return khtml::invalidColor;
}
-#endif
const QPalette &pal = qApp->palette();
QColor c = pal.color( uicol->group, uicol->role );
-#if !APPLE_CHANGES
if ( uicol->configEntry ) {
KConfig *globalConfig = KGlobal::config();
globalConfig->setGroup( uicol->configGroup );
c = globalConfig->readColorEntry( uicol->configEntry, &c );
}
-#endif
return c;
-};
+#endif
+}
void CSSStyleSelector::applyDeclarations(bool applyFirst, bool isImportant,
int startIndex, int endIndex)
diff --git a/WebCore/khtml/khtmlview.cpp b/WebCore/khtml/khtmlview.cpp
index 97d0450..041b5ab 100644
--- a/WebCore/khtml/khtmlview.cpp
+++ b/WebCore/khtml/khtmlview.cpp
@@ -323,7 +323,9 @@ void KHTMLView::init()
setAcceptDrops(true);
+#if !APPLE_CHANGES
resizeContents(visibleWidth(), visibleHeight());
+#endif
}
void KHTMLView::clear()
diff --git a/WebCore/kwq/KWQChar.mm b/WebCore/kwq/KWQChar.mm
index 5defaa0..63cd6da 100644
--- a/WebCore/kwq/KWQChar.mm
+++ b/WebCore/kwq/KWQChar.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,24 +29,24 @@
#import <Foundation/Foundation.h>
-bool QChar::isDigit() const
+bool QChar::isDigitNonASCII(UniChar c)
{
static CFCharacterSetRef set = CFCharacterSetGetPredefined(kCFCharacterSetDecimalDigit);
return CFCharacterSetIsCharacterMember(set, c);
}
-bool QChar::isLetter() const
+bool QChar::isLetterNonASCII(UniChar c)
{
static CFCharacterSetRef set = CFCharacterSetGetPredefined(kCFCharacterSetLetter);
return CFCharacterSetIsCharacterMember(set, c);
}
-bool QChar::isNumber() const
+bool QChar::isNumberNonASCII(UniChar c)
{
- return isLetterOrNumber() && !isLetter();
+ return isLetterOrNumberNonASCII(c) && !isLetterNonASCII(c);
}
-bool QChar::isLetterOrNumber() const
+bool QChar::isLetterOrNumberNonASCII(UniChar c)
{
static CFCharacterSetRef set = CFCharacterSetGetPredefined(kCFCharacterSetAlphaNumeric);
return CFCharacterSetIsCharacterMember(set, c);
@@ -58,14 +58,14 @@ bool QChar::isPunct() const
return CFCharacterSetIsCharacterMember(set, c);
}
-QChar QChar::lower() const
+UniChar QChar::lowerNonASCII(UniChar c)
{
- return (UniChar)WebCoreUnicodeLowerFunction(c);
+ return WebCoreUnicodeLowerFunction(c);
}
-QChar QChar::upper() const
+UniChar QChar::upperNonASCII(UniChar c)
{
- return (UniChar)WebCoreUnicodeUpperFunction(c);
+ return WebCoreUnicodeUpperFunction(c);
}
bool QChar::mirrored() const
@@ -78,10 +78,8 @@ QChar QChar::mirroredChar() const
return QChar((UniChar)WebCoreUnicodeMirroredCharFunction(c));
}
-int QChar::digitValue() const
+int QChar::digitValueNonASCII(UniChar)
{
- if (c < '0' || c > '9')
- return -1;
- else
- return c - '0';
+ // FIXME: This isn't right. Need Unicode-savvy version of this that matches isDigitNonASCII.
+ return -1;
}
diff --git a/WebCore/kwq/KWQColorGroup.mm b/WebCore/kwq/KWQColorGroup.mm
index 692b244..0d50bff 100644
--- a/WebCore/kwq/KWQColorGroup.mm
+++ b/WebCore/kwq/KWQColorGroup.mm
@@ -27,19 +27,23 @@
QColorGroup::QColorGroup()
{
+#if KWQ_USE_PALETTES
brushes[Foreground] = QColor(255,255,255);
brushes[Shadow] = QColor(255,255,255);
brushes[Light] = QColor(224,224,224);
brushes[Midlight] = QColor(192,192,192);
brushes[Mid] = QColor(128,128,128);
brushes[Dark] = QColor(64,64,64);
+#endif
brushes[Base] = QColor(255,255,255);
+#if KWQ_USE_PALETTES
brushes[ButtonText] = QColor(0,0,0);
brushes[Button] = QColor(192,192,192);
brushes[Background] = QColor(255,255,255);
brushes[Text] = QColor(0,0,0);
brushes[Highlight] = QColor(64,64,64);
brushes[HighlightedText] = QColor(0,0,0);
+#endif
}
const QBrush &QColorGroup::brush(ColorRole cr) const
@@ -57,6 +61,8 @@ void QColorGroup::setColor(QColorGroup::ColorRole cr, const QColor &color)
brushes[cr].setColor(color);
}
+#if KWQ_USE_PALETTES
+
const QColor &QColorGroup::foreground() const
{
return brushes[Foreground].color();
@@ -82,11 +88,15 @@ const QColor &QColorGroup::dark() const
return brushes[Dark].color();
}
+#endif
+
const QColor &QColorGroup::base() const
{
return brushes[Base].color();
}
+#if KWQ_USE_PALETTES
+
const QColor &QColorGroup::buttonText() const
{
return brushes[ButtonText].color();
@@ -117,6 +127,8 @@ const QColor &QColorGroup::highlightedText() const
return brushes[HighlightedText].color();
}
+#endif
+
bool QColorGroup::operator==(const QColorGroup &other) const
{
for (int i = 0; i < NColorRoles; i++) {
diff --git a/WebCore/kwq/KWQComboBox.h b/WebCore/kwq/KWQComboBox.h
index 1e6efb6..bf3a3a9 100644
--- a/WebCore/kwq/KWQComboBox.h
+++ b/WebCore/kwq/KWQComboBox.h
@@ -68,8 +68,6 @@ public:
private:
const int *dimensions() const;
- KWQComboBoxAdapter *_adapter;
-
mutable int _width;
mutable bool _widthGood;
diff --git a/WebCore/kwq/KWQComboBox.mm b/WebCore/kwq/KWQComboBox.mm
index 74c1d7d..ab0bbf2 100644
--- a/WebCore/kwq/KWQComboBox.mm
+++ b/WebCore/kwq/KWQComboBox.mm
@@ -49,14 +49,6 @@ enum {
minimumTextWidth
};
- at interface KWQComboBoxAdapter : NSObject
-{
- QComboBox *box;
-}
-- (id)initWithQComboBox:(QComboBox *)b;
-- (void)action:(id)sender;
- at end
-
@interface KWQPopUpButtonCell : NSPopUpButtonCell <KWQWidgetHolder>
{
QComboBox *box;
@@ -74,15 +66,13 @@ enum {
@end
QComboBox::QComboBox()
- : _adapter(0)
- , _widthGood(false)
+ : _widthGood(false)
, _currentItem(0)
, _menuPopulated(true)
, _activated(this, SIGNAL(activated(int)))
{
KWQ_BLOCK_EXCEPTIONS;
- _adapter = [[KWQComboBoxAdapter alloc] initWithQComboBox:this];
KWQPopUpButton *button = [[KWQPopUpButton alloc] init];
setView(button);
[button release];
@@ -91,7 +81,7 @@ QComboBox::QComboBox()
[button setCell:cell];
[cell release];
- [button setTarget:_adapter];
+ [button setTarget:button];
[button setAction:@selector(action:)];
[[button cell] setControlSize:NSSmallControlSize];
@@ -106,7 +96,6 @@ QComboBox::~QComboBox()
KWQPopUpButton *button = (KWQPopUpButton *)getView();
[button setTarget:nil];
- [_adapter release];
KWQ_UNBLOCK_EXCEPTIONS;
}
@@ -147,6 +136,8 @@ QSize QComboBox::sizeHint() const
rendererWithFont:[button font] usingPrinterFont:![NSGraphicsContext currentContextDrawingToScreen]];
WebCoreTextStyle style;
WebCoreInitializeEmptyTextStyle(&style);
+ style.applyRunRounding = NO;
+ style.applyWordRounding = NO;
do {
const QString &s = *i;
++i;
@@ -329,21 +320,6 @@ void QComboBox::populateMenu()
}
}
- at implementation KWQComboBoxAdapter
-
-- (id)initWithQComboBox:(QComboBox *)b
-{
- box = b;
- return [super init];
-}
-
-- (void)action:(id)sender
-{
- box->itemSelected();
-}
-
- at end
-
@implementation KWQPopUpButtonCell
- (id)initWithQComboBox:(QComboBox *)b
@@ -407,6 +383,11 @@ void QComboBox::populateMenu()
@implementation KWQPopUpButton
+- (void)action:(id)sender
+{
+ static_cast<QComboBox *>([self widget])->itemSelected();
+}
+
- (QWidget *)widget
{
return [(KWQPopUpButtonCell *)[self cell] widget];
diff --git a/WebCore/kwq/KWQKURL.mm b/WebCore/kwq/KWQKURL.mm
index 2aad083..85a2387 100644
--- a/WebCore/kwq/KWQKURL.mm
+++ b/WebCore/kwq/KWQKURL.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -225,8 +225,25 @@ KURL::KURL() : m_isValid(false)
KURL::KURL(const char *url)
{
if (url != NULL && url[0] == '/') {
- QString qurl = QString("file:") + url;
- parse(qurl.ascii(), &qurl);
+ char staticBuffer[2048];
+ char *buffer;
+ size_t urlLength = strlen(url) + 1;
+ size_t bufferLength = urlLength + 5; // 5 for "file:"
+ if (bufferLength > sizeof(staticBuffer)) {
+ buffer = (char *)malloc(bufferLength);
+ } else {
+ buffer = staticBuffer;
+ }
+ buffer[0] = 'f';
+ buffer[1] = 'i';
+ buffer[2] = 'l';
+ buffer[3] = 'e';
+ buffer[4] = ':';
+ memcpy(&buffer[5], url, urlLength);
+ parse(buffer, NULL);
+ if (buffer != staticBuffer) {
+ free(buffer);
+ }
} else {
parse(url, NULL);
}
@@ -235,8 +252,24 @@ KURL::KURL(const char *url)
KURL::KURL(const QString &url)
{
if (!url.isEmpty() && url[0] == '/') {
- QString fileUrl = QString("file:") + url;
- parse(fileUrl.ascii(), &fileUrl);
+ char staticBuffer[2048];
+ char *buffer;
+ size_t bufferLength = url.length() + 6; // 5 for "file:", 1 for terminator
+ if (bufferLength > sizeof(staticBuffer)) {
+ buffer = (char *)malloc(bufferLength);
+ } else {
+ buffer = staticBuffer;
+ }
+ buffer[0] = 'f';
+ buffer[1] = 'i';
+ buffer[2] = 'l';
+ buffer[3] = 'e';
+ buffer[4] = ':';
+ url.copyLatin1(&buffer[5]);
+ parse(buffer, NULL);
+ if (buffer != staticBuffer) {
+ free(buffer);
+ }
} else {
parse(url.ascii(), &url);
}
@@ -245,17 +278,31 @@ KURL::KURL(const QString &url)
KURL::KURL(NSURL *url)
{
if (url) {
- CFIndex bufferLength = CFURLGetBytes((CFURLRef)url, NULL, 0);
- char *bytes = new char [bufferLength + 1];
- CFURLGetBytes((CFURLRef)url, (UInt8 *)bytes, bufferLength);
- bytes[bufferLength] = '\0';
+ CFIndex bytesLength = CFURLGetBytes((CFURLRef)url, NULL, 0);
+ size_t bufferLength = bytesLength + 6; // 5 for "file:", 1 for NUL terminator
+ char staticBuffer[2048];
+ char *buffer;
+ if (bufferLength > sizeof(staticBuffer)) {
+ buffer = (char *)malloc(bufferLength);
+ } else {
+ buffer = staticBuffer;
+ }
+ char *bytes = &buffer[5];
+ CFURLGetBytes((CFURLRef)url, (UInt8 *)bytes, bytesLength);
+ bytes[bytesLength] = '\0';
if (bytes[0] == '/') {
- QString fileUrl = QString("file:") + bytes;
- parse(fileUrl.ascii(), &fileUrl);
+ buffer[0] = 'f';
+ buffer[1] = 'i';
+ buffer[2] = 'l';
+ buffer[3] = 'e';
+ buffer[4] = ':';
+ parse(buffer, NULL);
} else {
parse(bytes, NULL);
}
- delete [] bytes;
+ if (buffer != staticBuffer) {
+ free(buffer);
+ }
}
else {
parse("", NULL);
@@ -391,15 +438,15 @@ KURL::KURL(const KURL &base, const QString &relative, const QTextCodec *codec)
{
// must be relative-path reference
- char static_buffer[2048];
+ char staticBuffer[2048];
char *buffer;
size_t bufferLength = base.pathEndPos + strlen(str) + 1;
- if (bufferLength > sizeof(static_buffer)) {
+ if (bufferLength > sizeof(staticBuffer)) {
buffer = (char *)malloc(bufferLength);
} else {
- buffer = static_buffer;
+ buffer = staticBuffer;
}
char *bufferPos = buffer;
@@ -467,7 +514,7 @@ KURL::KURL(const KURL &base, const QString &relative, const QTextCodec *codec)
ASSERT(strlen(buffer) + 1 <= bufferLength);
- if (buffer != static_buffer) {
+ if (buffer != staticBuffer) {
free(buffer);
}
@@ -930,6 +977,25 @@ static int copyPathRemovingDots(char *dst, const char *src, int srcStart, int sr
return dst - bufferPathStart;
}
+static inline bool hasSlashDotOrDotDot(const char *str)
+{
+ const char *p = str;
+ if (!*p)
+ return false;
+ char pc = *p;
+ while (char c = *++p) {
+ if (c == '.' && (pc == '/' || pc == '.'))
+ return true;
+ pc = c;
+ }
+ return false;
+}
+
+static inline bool matchLetter(char c, char lowercaseLetter)
+{
+ return (c | 0x20) == lowercaseLetter;
+}
+
void KURL::parse(const char *url, const QString *originalString)
{
m_isValid = true;
@@ -1103,11 +1169,11 @@ void KURL::parse(const char *url, const QString *originalString)
// assemble it all, remembering the real ranges
- char static_buffer[4096];
+ char staticBuffer[4096];
char *buffer;
uint bufferLength = fragmentEnd * 3 + 1;
- if (bufferLength <= sizeof(static_buffer)) {
- buffer = static_buffer;
+ if (bufferLength <= sizeof(staticBuffer)) {
+ buffer = staticBuffer;
} else {
buffer = (char *)malloc(bufferLength);
}
@@ -1123,28 +1189,28 @@ void KURL::parse(const char *url, const QString *originalString)
schemeEndPos = p - buffer;
// Check if we're http or https.
- bool isHTTPorHTTPS = tolower(url[0]) == 'h'
- && tolower(url[1]) == 't'
- && tolower(url[2]) == 't'
- && tolower(url[3]) == 'p'
+ bool isHTTPorHTTPS = matchLetter(url[0], 'h')
+ && matchLetter(url[1], 't')
+ && matchLetter(url[2], 't')
+ && matchLetter(url[3], 'p')
&& (url[4] == ':'
- || (tolower(url[4]) == 's' && url[5] == ':'));
+ || (matchLetter(url[4], 's') && url[5] == ':'));
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 isFile = tolower(url[0]) == 'f'
- && tolower(url[1]) == 'i'
- && tolower(url[2]) == 'l'
- && tolower(url[3]) == 'e'
+ && matchLetter(url[userStart], 'l')
+ && matchLetter(url[userStart+1], 'o')
+ && matchLetter(url[userStart+2], 'c')
+ && matchLetter(url[userStart+3], 'a')
+ && matchLetter(url[userStart+4], 'l')
+ && matchLetter(url[userStart+5], 'h')
+ && matchLetter(url[userStart+6], 'o')
+ && matchLetter(url[userStart+7], 's')
+ && matchLetter(url[userStart+8], 't');
+
+ bool isFile = matchLetter(url[0], 'f')
+ && matchLetter(url[1], 'i')
+ && matchLetter(url[2], 'l')
+ && matchLetter(url[3], 'e')
&& url[4] == ':';
// File URLs need a host part unless it is just file:// or file://localhost
@@ -1228,7 +1294,7 @@ void KURL::parse(const char *url, const QString *originalString)
// add path, escaping bad characters
- if (hierarchical && (strstr(url, "/.") || strstr(url, ".."))) {
+ if (hierarchical && hasSlashDotOrDotDot(url)) {
char static_path_buffer[4096];
char *path_buffer;
uint pathBufferLength = pathEnd - pathStart + 1;
@@ -1271,7 +1337,7 @@ void KURL::parse(const char *url, const QString *originalString)
ASSERT(p - buffer <= (int)bufferLength);
- if (buffer != static_buffer) {
+ if (buffer != staticBuffer) {
free(buffer);
}
}
@@ -1307,11 +1373,11 @@ QString KURL::encode_string(const QString& notEncodedString)
{
QCString asUTF8 = notEncodedString.utf8();
- char static_buffer[4096];
+ char staticBuffer[4096];
char *buffer;
uint bufferLength = asUTF8.length() * 3 + 1;
- if (bufferLength <= sizeof(static_buffer)) {
- buffer = static_buffer;
+ if (bufferLength <= sizeof(staticBuffer)) {
+ buffer = staticBuffer;
} else {
buffer = (char *)malloc(bufferLength);
}
@@ -1335,7 +1401,7 @@ QString KURL::encode_string(const QString& notEncodedString)
ASSERT(p - buffer <= (int)bufferLength);
- if (buffer != static_buffer) {
+ if (buffer != staticBuffer) {
free(buffer);
}
diff --git a/WebCore/kwq/KWQLineEdit.mm b/WebCore/kwq/KWQLineEdit.mm
index 579ccc5..0bf42aa 100644
--- a/WebCore/kwq/KWQLineEdit.mm
+++ b/WebCore/kwq/KWQLineEdit.mm
@@ -190,6 +190,8 @@ QSize QLineEdit::sizeForCharacterWidth(int numCharacters) const
WebCoreTextStyle style;
WebCoreInitializeEmptyTextStyle(&style);
+ style.applyRunRounding = NO;
+ style.applyWordRounding = NO;
const UniChar zero = '0';
WebCoreTextRun run;
diff --git a/WebCore/kwq/KWQListBox.mm b/WebCore/kwq/KWQListBox.mm
index 6a270fe..5c9ccde 100644
--- a/WebCore/kwq/KWQListBox.mm
+++ b/WebCore/kwq/KWQListBox.mm
@@ -256,6 +256,8 @@ QSize QListBox::sizeForNumberOfLines(int lines) const
WebCoreTextStyle style;
WebCoreInitializeEmptyTextStyle(&style);
style.rtl = [tableView baseWritingDirection] == NSWritingDirectionRightToLeft;
+ style.applyRunRounding = NO;
+ style.applyWordRounding = NO;
do {
const QString &s = (*i).string;
id <WebCoreTextRenderer> renderer = (*i).isGroupLabel ? groupLabelTextRenderer() : itemTextRenderer();
@@ -503,6 +505,8 @@ void QListBox::setWritingDirection(QPainter::TextDirection d)
WebCoreTextStyle style;
WebCoreInitializeEmptyTextStyle(&style);
style.rtl = RTL;
+ style.applyRunRounding = NO;
+ style.applyWordRounding = NO;
style.textColor = color;
WebCoreTextRun run;
diff --git a/WebCore/kwq/KWQPalette.h b/WebCore/kwq/KWQPalette.h
index d394e35..c9d9737 100644
--- a/WebCore/kwq/KWQPalette.h
+++ b/WebCore/kwq/KWQPalette.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,25 +29,33 @@
#include "KWQColor.h"
#include "KWQBrush.h"
+// We don't colorize widgets, so we don't need palettes.
+// And copying the palettes was taking a measurable amount of time.
+#define KWQ_USE_PALETTES 0
+
class QColorGroupPrivate;
class QPalettePrivate;
class QColorGroup {
public:
enum ColorRole {
- Foreground,
- Shadow,
- Light,
- Midlight,
- Mid,
- Dark,
- Base,
- ButtonText,
- Button,
- Background,
+#if KWQ_USE_PALETTES
+ Foreground,
+ Shadow,
+ Light,
+ Midlight,
+ Mid,
+ Dark,
+#endif
+ Base,
+#if KWQ_USE_PALETTES
+ ButtonText,
+ Button,
+ Background,
Text,
Highlight,
HighlightedText,
+#endif
NColorRoles
};
@@ -58,18 +66,22 @@ public:
const QColor &color(ColorRole) const;
void setColor(ColorRole, const QColor &);
+#if KWQ_USE_PALETTES
const QColor &foreground() const;
const QColor &shadow() const;
const QColor &light() const;
const QColor &midlight() const;
const QColor &dark() const;
+#endif
const QColor &base() const;
+#if KWQ_USE_PALETTES
const QColor &buttonText() const;
const QColor &button() const;
const QColor &text() const;
const QColor &background() const;
const QColor &highlight() const;
const QColor &highlightedText() const;
+#endif
bool operator==(const QColorGroup &) const;
@@ -82,8 +94,10 @@ class QPalette {
public:
enum ColorGroup {
Active,
+#if KWQ_USE_PALETTES
Inactive,
Disabled,
+#endif
NColorGroups
};
@@ -91,16 +105,20 @@ public:
void setColor(ColorGroup, QColorGroup::ColorRole, const QColor &);
const QColorGroup &active() const { return m_active; }
+#if KWQ_USE_PALETTES
const QColorGroup &inactive() const { return m_inactive; }
const QColorGroup &disabled() const { return m_disabled; }
const QColorGroup &normal() const { return m_active; }
+#endif
bool operator==(const QPalette &) const;
private:
QColorGroup m_active;
+#if KWQ_USE_PALETTES
QColorGroup m_inactive;
QColorGroup m_disabled;
+#endif
};
#endif
diff --git a/WebCore/kwq/KWQPalette.mm b/WebCore/kwq/KWQPalette.mm
index 8a2febf..e48db80 100644
--- a/WebCore/kwq/KWQPalette.mm
+++ b/WebCore/kwq/KWQPalette.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,17 +25,24 @@
#import "KWQPalette.h"
+#import "KWQAssertions.h"
+
const QColor& QPalette::color(ColorGroup cg, QColorGroup::ColorRole role) const
{
switch (cg) {
- default: // keep GCC from complaining about NColorGroups
+ case NColorGroups:
+ break;
case Active:
return m_active.color(role);
+#if KWQ_USE_PALETTES
case Inactive:
return m_inactive.color(role);
case Disabled:
return m_disabled.color(role);
+#endif
}
+ ASSERT(false);
+ return m_active.color(QColorGroup::Base);
}
void QPalette::setColor(ColorGroup cg, QColorGroup::ColorRole role, const QColor &color)
@@ -44,18 +51,25 @@ void QPalette::setColor(ColorGroup cg, QColorGroup::ColorRole role, const QColor
case Active:
m_active.setColor(role, color);
break;
+#if KWQ_USE_PALETTES
case Inactive:
m_inactive.setColor(role, color);
break;
case Disabled:
m_disabled.setColor(role, color);
break;
- default: // keep GCC from complaining about NColorGroups
+#endif
+ case NColorGroups:
+ ASSERT(false);
break;
}
}
bool QPalette::operator==(QPalette const &other) const
{
- return m_active == other.m_active && m_inactive == other.m_inactive && m_disabled == other.m_disabled;
+ return m_active == other.m_active
+#if KWQ_USE_PALETTES
+ && m_inactive == other.m_inactive && m_disabled == other.m_disabled
+#endif
+ ;
}
diff --git a/WebCore/kwq/KWQRegExp.mm b/WebCore/kwq/KWQRegExp.mm
index 26aa384..9da9548 100644
--- a/WebCore/kwq/KWQRegExp.mm
+++ b/WebCore/kwq/KWQRegExp.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -159,23 +159,25 @@ QString QRegExp::pattern() const
}
int QRegExp::match(const QString &str, int startFrom, int *matchLength) const
-{
- QCString asUTF8;
- const char *cstring;
-
+{
+ // First 2 offsets are start and end offsets; 3rd entry is used internally by pcre
+ int offsets[3];
+ int result;
+
if (str.isAllASCII()) {
- cstring = str.ascii();
+ result = pcre_exec(d->regex, NULL, str.ascii(), str.length(), startFrom,
+ startFrom == 0 ? 0 : PCRE_NOTBOL, offsets, 3);
} else {
- asUTF8 = str.utf8();
- cstring = asUTF8;
- }
-
- // first 2 offsets are start and end offsets; 3rd entry is used internally by pcre
- int offsets[3];
- convertUTF16OffsetsToUTF8Offsets(cstring, &startFrom, 1);
- int result = pcre_exec(d->regex, NULL, cstring, strlen(cstring), startFrom,
+ int length;
+ QCString asUTF8 = str.utf8(length);
+ convertUTF16OffsetsToUTF8Offsets(asUTF8, &startFrom, 1);
+ result = pcre_exec(d->regex, NULL, asUTF8, length, startFrom,
startFrom == 0 ? 0 : PCRE_NOTBOL, offsets, 3);
-
+ if (result >= 0) {
+ convertUTF8OffsetsToUTF16Offsets(asUTF8, offsets, 2);
+ }
+ }
+
if (result < 0) {
if (result != PCRE_ERROR_NOMATCH) {
ERROR("KWQRegExp: pcre_exec() failed with result %d", result);
@@ -185,9 +187,8 @@ int QRegExp::match(const QString &str, int startFrom, int *matchLength) const
return -1;
}
+ // 1 means 1 match; 0 means more than one match. First match is recorded in offsets.
ASSERT(result < 2);
- // 1 means 1 match; 0 means more than one match, first one is recorded in offsets
- convertUTF8OffsetsToUTF16Offsets(cstring, offsets, 2);
d->lastMatchPos = offsets[0];
d->lastMatchLength = offsets[1] - offsets[0];
if (matchLength != NULL) {
diff --git a/WebCore/kwq/KWQString.h b/WebCore/kwq/KWQString.h
index af42e9d..a1c087a 100644
--- a/WebCore/kwq/KWQString.h
+++ b/WebCore/kwq/KWQString.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -65,15 +65,7 @@ public:
uchar row() const;
char latin1() const;
bool isNull() const;
- bool isSpace() const
- {
- // Use isspace() for basic latin1. This will include newlines, which
- // aren't included in unicode DirWS.
- if (c <= 0x7F) {
- return isspace(c);
- }
- return direction() == DirWS;
- }
+ bool isSpace() const;
bool isDigit() const;
bool isLetter() const;
bool isNumber() const;
@@ -82,10 +74,7 @@ public:
int digitValue() const;
QChar lower() const;
QChar upper() const;
- Direction direction() const
- {
- return (Direction)WebCoreUnicodeDirectionFunction(c);
- }
+ Direction direction() const;
bool mirrored() const;
QChar mirroredChar() const;
@@ -122,6 +111,13 @@ private:
friend class QString;
friend class QConstString;
+ static bool isDigitNonASCII(UniChar c);
+ static bool isLetterNonASCII(UniChar c);
+ static bool isNumberNonASCII(UniChar c);
+ static bool isLetterOrNumberNonASCII(UniChar c);
+ static int digitValueNonASCII(UniChar c);
+ static UniChar lowerNonASCII(UniChar c);
+ static UniChar upperNonASCII(UniChar c);
};
inline QChar::QChar() : c(0)
@@ -167,6 +163,53 @@ inline bool QChar::isNull() const
return c == 0;
}
+inline bool QChar::isSpace() const
+{
+ // Use isspace() for basic latin1. This will include newlines, which
+ // aren't included in unicode DirWS.
+ return c <= 0x7F ? isspace(c) : direction() == DirWS;
+}
+
+inline bool QChar::isDigit() const
+{
+ return c <= 0x7F ? isdigit(c) : isDigitNonASCII(c);
+}
+
+inline bool QChar::isLetter() const
+{
+ return c <= 0x7F ? isalpha(c) : isLetterNonASCII(c);
+}
+
+inline bool QChar::isNumber() const
+{
+ return c <= 0x7F ? isdigit(c) : isNumberNonASCII(c);
+}
+
+inline bool QChar::isLetterOrNumber() const
+{
+ return c <= 0x7F ? isalnum(c) : isLetterOrNumberNonASCII(c);
+}
+
+inline int QChar::digitValue() const
+{
+ return c <= '9' ? c - '0' : digitValueNonASCII(c);
+}
+
+inline QChar QChar::lower() const
+{
+ return c <= 0x7F ? tolower(c) : lowerNonASCII(c);
+}
+
+inline QChar QChar::upper() const
+{
+ return c <= 0x7F ? toupper(c) : upperNonASCII(c);
+}
+
+inline QChar::Direction QChar::direction() const
+{
+ return static_cast<Direction>(WebCoreUnicodeDirectionFunction(c));
+}
+
inline uchar QChar::row() const
{
return c >> 8;
@@ -366,7 +409,10 @@ public:
const char *latin1() const;
const char *ascii() const;
bool isAllASCII() const;
- QCString utf8() const;
+ bool isAllLatin1() const;
+ void copyLatin1(char *latin1) const;
+ QCString utf8() const { int length; return utf8(length); }
+ QCString utf8(int &length) const;
QCString local8Bit() const;
bool isNull() const;
@@ -452,47 +498,49 @@ public:
QString &sprintf(const char *, ...) __attribute__ ((format (printf, 2, 3)));
- QString &prepend(const QString &);
QString &append(const QString &);
+ QString &append(QChar);
+ QString &append(char);
QString &insert(uint, const QString &);
QString &insert(uint, QChar);
QString &insert(uint, char);
QString &insert(uint index, const char *insertChars, uint insertLength);
+ QString &prepend(const QString &);
QString &remove(uint, uint);
QString &replace(uint index, uint len, const QString &s);
QString &replace(const QRegExp &, const QString &);
QString &replace(QChar, QChar);
- void truncate(uint);
+ QString &append(const QChar *, uint length);
+ QString &append(const char *, uint length);
+ QString &insert(uint position, const QChar *, uint length);
+ QString &prepend(const QChar *, uint length);
+
void fill(QChar, int len=-1);
+ void truncate(uint);
- void compose();
- QString visual();
+ void reserve(uint);
- CFStringRef getCFString() const;
- NSString *getNSString() const;
+ uint hash() const;
bool operator!() const;
const QChar operator[](int) const;
- QString &operator+=(const QString &);
- QString &operator+=(QChar);
- QString &operator+=(char);
+ QString &operator+=(const QString &s) { return append(s); }
+ QString &operator+=(QChar c) { return append(c); }
+ QString &operator+=(char c) { return append(c); }
+
+ CFStringRef getCFString() const;
+ NSString *getNSString() const;
void setBufferFromCFString(CFStringRef);
- QString &append(const char *, uint length);
- QString &append(const QChar *, uint length);
- QString &prepend(const QChar *, uint length);
- QString &insert(uint position, const QChar *, uint length);
-
- uint hash() const;
-
private:
// Used by QConstString.
QString(KWQStringData *constData, bool /*dummy*/);
void detach();
+ void detachAndDiscardCharacters();
void detachIfInternal();
void detachInternal();
void deref();
diff --git a/WebCore/kwq/KWQString.mm b/WebCore/kwq/KWQString.mm
index 80105bf..a79efec 100644
--- a/WebCore/kwq/KWQString.mm
+++ b/WebCore/kwq/KWQString.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -46,12 +46,13 @@ int malloc_good_size(int size);
#define ALLOC_CHAR_GOOD_SIZE(X) (malloc_good_size(X))
#ifdef QSTRING_DEBUG_ALLOCATIONS
+
#import <pthread.h>
#import <mach/mach_types.h>
-static CFMutableDictionaryRef _allocatedBuffers = 0;
+static CFMutableDictionaryRef allocatedBuffers = 0;
#define ALLOCATION_HISTOGRAM_SIZE 128
-static uint _allocationHistogram[ALLOCATION_HISTOGRAM_SIZE];
+static uint allocationHistogram[ALLOCATION_HISTOGRAM_SIZE];
static uint stackInstances = 0;
static uint heapInstances = 0;
@@ -60,7 +61,8 @@ static uint stringDataHeapInstances = 0;
static uint stringDataDetachments = 0;
static uint handleInstances = 0;
-static bool _isOnStack(void *ptr){
+static bool isOnStack(void *ptr)
+{
void *address;
size_t size;
pthread_t thisThread = pthread_self();
@@ -73,10 +75,9 @@ static bool _isOnStack(void *ptr){
return false;
}
-
static void countInstance(void *ptr)
{
- if (_isOnStack(ptr))
+ if (isOnStack(ptr))
stackInstances++;
else
heapInstances++;
@@ -84,35 +85,37 @@ static void countInstance(void *ptr)
static CFMutableDictionaryRef allocatedBuffers()
{
- if (_allocatedBuffers == 0){
+ if (allocatedBuffers == 0){
for (int i = 0; i < ALLOCATION_HISTOGRAM_SIZE; i++)
- _allocationHistogram[i] = 0;
- _allocatedBuffers = CFDictionaryCreateMutable (kCFAllocatorDefault, 1024*8, NULL, NULL);
+ allocationHistogram[i] = 0;
+ allocatedBuffers = CFDictionaryCreateMutable (kCFAllocatorDefault, 1024*8, NULL, NULL);
}
- return _allocatedBuffers;
+ return allocatedBuffers;
}
-static char *ALLOC_CHAR(int n){
+static char *ALLOC_CHAR(int n)
+{
char *ptr = (char *)malloc(n);
CFDictionarySetValue (allocatedBuffers(), ptr, (void *)n);
if (n >= ALLOCATION_HISTOGRAM_SIZE)
- _allocationHistogram[ALLOCATION_HISTOGRAM_SIZE-1]++;
+ allocationHistogram[ALLOCATION_HISTOGRAM_SIZE-1]++;
else
- _allocationHistogram[n]++;
+ allocationHistogram[n]++;
return ptr;
}
-static char *REALLOC_CHAR(void *p, int n){
+static char *REALLOC_CHAR(void *p, int n)
+{
char *ptr = (char *)realloc(p, n);
CFDictionaryRemoveValue (allocatedBuffers(), p);
CFDictionarySetValue (allocatedBuffers(), ptr, (const void *)(n));
if (n >= ALLOCATION_HISTOGRAM_SIZE)
- _allocationHistogram[ALLOCATION_HISTOGRAM_SIZE-1]++;
+ allocationHistogram[ALLOCATION_HISTOGRAM_SIZE-1]++;
else
- _allocationHistogram[n]++;
+ allocationHistogram[n]++;
return ptr;
}
@@ -122,28 +125,30 @@ static void DELETE_CHAR(void *p)
free (p);
}
-static QChar *ALLOC_QCHAR(int n){
+static QChar *ALLOC_QCHAR(int n)
+{
size_t size = (sizeof(QChar)*( n ));
QChar *ptr = (QChar *)malloc(size);
CFDictionarySetValue (allocatedBuffers(), ptr, (const void *)size);
if (size >= ALLOCATION_HISTOGRAM_SIZE)
- _allocationHistogram[ALLOCATION_HISTOGRAM_SIZE-1]++;
+ allocationHistogram[ALLOCATION_HISTOGRAM_SIZE-1]++;
else
- _allocationHistogram[size]++;
+ allocationHistogram[size]++;
return ptr;
}
-static QChar *REALLOC_QCHAR(void *p, int n){
+static QChar *REALLOC_QCHAR(void *p, int n)
+{
size_t size = (sizeof(QChar)*( n ));
QChar *ptr = (QChar *)realloc(p, size);
CFDictionaryRemoveValue (allocatedBuffers(), p);
CFDictionarySetValue (allocatedBuffers(), ptr, (const void *)size);
if (size >= ALLOCATION_HISTOGRAM_SIZE)
- _allocationHistogram[ALLOCATION_HISTOGRAM_SIZE-1]++;
+ allocationHistogram[ALLOCATION_HISTOGRAM_SIZE-1]++;
else
- _allocationHistogram[size]++;
+ allocationHistogram[size]++;
return ptr;
}
@@ -183,9 +188,9 @@ void _printQStringAllocationStatistics()
printf ("\nString size histogram:\n");
for (i = 0; i < ALLOCATION_HISTOGRAM_SIZE; i++){
- if (_allocationHistogram[i])
- printf ("[%d] = %d\n", i, _allocationHistogram[i]);
- totalAllocations += _allocationHistogram[i];
+ if (allocationHistogram[i])
+ printf ("[%d] = %d\n", i, allocationHistogram[i]);
+ totalAllocations += allocationHistogram[i];
}
printf ("Total allocations %d\n", totalAllocations);
@@ -200,6 +205,7 @@ void _printQStringAllocationStatistics()
free(keys);
free(values);
}
+
#else
#define ALLOC_CHAR( N ) (char*) malloc(N)
@@ -209,13 +215,14 @@ void _printQStringAllocationStatistics()
#define ALLOC_QCHAR( N ) (QChar*) malloc(sizeof(QChar)*( N ))
#define REALLOC_QCHAR( P, N ) (QChar *) realloc(P,sizeof(QChar)*( N ))
#define DELETE_QCHAR( P ) free( P )
+
#endif // QSTRING_DEBUG_ALLOCATIONS
#import <mach/vm_map.h>
#import <mach/mach_init.h>
-static void *allocateHandle();
-static void freeHandle(void *free);
+static KWQStringData **allocateHandle();
+static void freeHandle(KWQStringData **);
#define IS_ASCII_QCHAR(c) ((c).unicode() > 0 && (c).unicode() <= 0xff)
@@ -230,7 +237,7 @@ KWQStringData **QString::shared_null_handle = 0;
// Utility functions
// -------------------------------------------------------------------------
-static int ucstrcmp( const QString &as, const QString &bs )
+static inline int ucstrcmp( const QString &as, const QString &bs )
{
const QChar *a = as.unicode();
const QChar *b = bs.unicode();
@@ -240,7 +247,7 @@ static int ucstrcmp( const QString &as, const QString &bs )
return 1;
if ( b == 0 )
return -1;
- int l = QMIN(as.length(), bs.length());
+ int l = kMin(as.length(), bs.length());
while ( l-- && *a == *b )
a++,b++;
if ( l == -1 )
@@ -249,38 +256,75 @@ static int ucstrcmp( const QString &as, const QString &bs )
}
-static int ucstrncmp( const QChar *a, const QChar *b, int l )
+static bool equal(const QChar *a, const char *b, int l)
{
- while ( l-- && *a == *b )
- a++,b++;
- if ( l == -1 )
- return 0;
- return a->unicode() - b->unicode();
+ ASSERT(l >= 0);
+ while (l--) {
+ if (*a != *b)
+ return false;
+ a++; b++;
+ }
+ return true;
}
+// Not a "true" case insensitive compare; only insensitive for plain ASCII.
-static int ucstrnicmp( const QChar *a, const QChar *b, int l )
+static bool equalCaseInsensitive(const char *a, const char *b, int l)
{
- while ( l-- && a->lower() == b->lower() )
- a++,b++;
- if ( l == -1 )
- return 0;
- QChar al = a->lower();
- QChar bl = b->lower();
- return al.unicode() - bl.unicode();
+ ASSERT(l >= 0);
+ while (l--) {
+ if (tolower(*a) != tolower(*b))
+ return false;
+ a++; b++;
+ }
+ return true;
}
+static bool equalCaseInsensitive(const QChar *a, const char *b, int l)
+{
+ ASSERT(l >= 0);
+ while (l--) {
+ if (tolower(a->unicode()) != tolower(*b))
+ return false;
+ a++; b++;
+ }
+ return true;
+}
-static bool ok_in_base( QChar c, int base )
+static bool equalCaseInsensitive(const QChar *a, const QChar *b, int l)
{
- if ( base <= 10 )
- return c.isDigit() && c.digitValue() < base;
- else
- return c.isDigit() || (c >= 'a' && c < char('a' + base - 10))
- || (c >= 'A' && c < char('A' + base - 10));
+ ASSERT(l >= 0);
+ while (l--) {
+ if (tolower(a->unicode()) != tolower(b->unicode()))
+ return false;
+ a++; b++;
+ }
+ return true;
}
+static inline bool equalCaseInsensitive(char c1, char c2)
+{
+ return tolower(c1) == tolower(c2);
+}
+static inline bool equalCaseInsensitive(QChar c1, char c2)
+{
+ return tolower(c1.unicode()) == tolower(static_cast<unsigned char>(c2));
+}
+
+static bool ok_in_base(QChar c, int base)
+{
+ int uc = c.unicode();
+ if (isdigit(uc))
+ return uc - '0' < base;
+ if (isalpha(uc)) {
+ if (base > 36)
+ base = 36;
+ return (uc >= 'a' && uc < 'a' + base - 10)
+ || (uc >= 'A' && uc < 'A' + base - 10);
+ }
+ return false;
+}
// -------------------------------------------------------------------------
// KWQStringData
@@ -436,7 +480,7 @@ KWQStringData *QString::makeSharedNull()
KWQStringData **QString::makeSharedNullHandle()
{
if (!shared_null_handle) {
- shared_null_handle = (KWQStringData **)allocateHandle();
+ shared_null_handle = allocateHandle();
*shared_null_handle = makeSharedNull();
}
return shared_null_handle;
@@ -599,29 +643,6 @@ QChar *KWQStringData::makeUnicode()
// -------------------------------------------------------------------------
-static inline bool compareIgnoringCaseForASCIIOnly(char c1, char c2)
-{
- if (c2 >= 'a' && c2 <= 'z') {
- return c1 == c2 || c1 == c2 - caseDelta;
- }
- if (c2 >= 'A' && c2 <= 'Z') {
- return c1 == c2 || c1 == c2 + caseDelta;
- }
- return c1 == c2;
-}
-
-static inline bool compareIgnoringCaseForASCIIOnly(QChar c1, char c2)
-{
- if (c2 >= 'a' && c2 <= 'z') {
- return c1 == c2 || c1.unicode() == c2 - caseDelta;
- }
- if (c2 >= 'A' && c2 <= 'Z') {
- return c1 == c2 || c1.unicode() == c2 + caseDelta;
- }
- return c1 == c2;
-}
-
-
QString QString::number(int n)
{
QString qs;
@@ -718,6 +739,30 @@ NSString *QString::getNSString() const
return nil;
}
+inline void QString::detachInternal()
+{
+ 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;
+ }
+ }
+ newData->_isHeapAllocated = 1;
+ newData->refCount = oldData->refCount - 1;
+ *dataHandle = newData;
+
+ oldData->refCount = 1;
+}
+
inline void QString::detachIfInternal()
{
KWQStringData *oldData = *dataHandle;
@@ -737,7 +782,7 @@ QString::~QString()
// Only free the handle if no other string has a reference to the
// data. The handle will be freed by the string that has the
// last reference to data.
- bool needToFreeHandle = oldHandle != shared_null_handle && oldData->refCount == 1;
+ bool needToFreeHandle = oldData->refCount == 1 && oldData != shared_null;
// Copy our internal data if necessary, other strings still need it.
detachIfInternal();
@@ -770,7 +815,7 @@ QString::QString()
QString::QString(KWQStringData *constData, bool /*dummy*/)
{
internalData.deref();
- dataHandle = (KWQStringData **)allocateHandle();
+ dataHandle = allocateHandle();
*dataHandle = constData;
// The QConstString constructor allocated the KWQStringData.
@@ -783,7 +828,7 @@ QString::QString(QChar qc)
#ifdef QSTRING_DEBUG_ALLOCATIONS
countInstance (&dataHandle);
#endif
- dataHandle = (KWQStringData **)allocateHandle();
+ dataHandle = allocateHandle();
// Copy the QChar.
if (IS_ASCII_QCHAR(qc)) {
@@ -802,7 +847,7 @@ QString::QString(const QByteArray &qba)
#ifdef QSTRING_DEBUG_ALLOCATIONS
countInstance (&dataHandle);
#endif
- dataHandle = (KWQStringData **)allocateHandle();
+ dataHandle = allocateHandle();
// Copy data
*dataHandle = &internalData;
@@ -819,7 +864,7 @@ QString::QString(const QChar *unicode, uint length)
dataHandle = makeSharedNullHandle();
dataHandle[0]->ref();
} else {
- dataHandle = (KWQStringData **)allocateHandle();
+ dataHandle = allocateHandle();
// Copy the QChar *
*dataHandle = &internalData;
@@ -835,7 +880,7 @@ QString::QString(const char *chs)
if (chs) {
internalData.initialize(chs,strlen(chs));
- dataHandle = (KWQStringData **)allocateHandle();
+ dataHandle = allocateHandle();
*dataHandle = &internalData;
} else {
internalData.deref();
@@ -849,7 +894,7 @@ QString::QString(const char *chs, int len)
#ifdef QSTRING_DEBUG_ALLOCATIONS
countInstance (&dataHandle);
#endif
- dataHandle = (KWQStringData **)allocateHandle();
+ dataHandle = allocateHandle();
*dataHandle = &internalData;
internalData.initialize(chs,len);
}
@@ -917,10 +962,10 @@ QChar QString::at(uint i) const
return thisData->_unicode[i];
}
-int QString::compare( const QString& s ) const
+int QString::compare(const QString& s) const
{
if (dataHandle[0]->_isAsciiValid && s.dataHandle[0]->_isAsciiValid)
- return strcmp (ascii(), s.ascii());
+ return strcmp(ascii(), s.ascii());
return ucstrcmp(*this,s);
}
@@ -972,24 +1017,24 @@ bool QString::startsWith( const QString& s ) const
bool QString::startsWith(const char *prefix) const
{
- int prefixLength = strlen(prefix);
- if (dataHandle[0]->_isAsciiValid) {
- return strncmp(prefix, ascii(), prefixLength) == 0;
- } else if (dataHandle[0]->_isUnicodeValid) {
- int l = dataHandle[0]->_length;
- if (prefixLength > l) {
+ KWQStringData *data = *dataHandle;
+
+ uint prefixLength = strlen(prefix);
+ if (data->_isAsciiValid) {
+ return strncmp(prefix, data->_ascii, prefixLength) == 0;
+ } else {
+ ASSERT(data->_isUnicodeValid);
+ if (prefixLength > data->_length) {
return false;
}
- const QChar *uni = unicode();
- for (int i = 0; i < prefixLength; ++i) {
+ const QChar *uni = data->_unicode;
+ for (uint i = 0; i < prefixLength; ++i) {
if (uni[i] != prefix[i]) {
return false;
}
}
- } else {
- FATAL("invalid character cache");
+ return true;
}
- return true;
}
bool QString::startsWith(const char *prefix, bool caseSensitive) const
@@ -997,24 +1042,25 @@ bool QString::startsWith(const char *prefix, bool caseSensitive) const
if (caseSensitive) {
return startsWith(prefix);
}
- int prefixLength = strlen(prefix);
- if (dataHandle[0]->_isAsciiValid) {
- return strncasecmp(prefix, ascii(), prefixLength) == 0;
- } else if (dataHandle[0]->_isUnicodeValid) {
- int l = dataHandle[0]->_length;
- if (prefixLength > l) {
+
+ KWQStringData *data = *dataHandle;
+
+ uint prefixLength = strlen(prefix);
+ if (data->_isAsciiValid) {
+ return strncasecmp(prefix, data->_ascii, prefixLength) == 0;
+ } else {
+ ASSERT(data->_isUnicodeValid);
+ if (prefixLength > data->_length) {
return false;
}
- const QChar *uni = unicode();
- for (int i = 0; i < prefixLength; ++i) {
- if (!compareIgnoringCaseForASCIIOnly(uni[i], prefix[i])) {
+ const QChar *uni = data->_unicode;
+ for (uint i = 0; i < prefixLength; ++i) {
+ if (!equalCaseInsensitive(uni[i], prefix[i])) {
return false;
}
}
- } else {
- FATAL("invalid character cache");
+ return true;
}
- return true;
}
bool QString::endsWith( const QString& s ) const
@@ -1031,7 +1077,7 @@ bool QString::endsWith( const QString& s ) const
return TRUE;
}
-QCString QString::utf8() const
+QCString QString::utf8(int &length) const
{
uint len = dataHandle[0]->_length;
if (len == 0) {
@@ -1040,6 +1086,7 @@ QCString QString::utf8() const
CFStringRef s = getCFString();
CFIndex utf8Size;
CFStringGetBytes(s, CFRangeMake(0, len), kCFStringEncodingUTF8, '?', false, 0, 0, &utf8Size);
+ length = utf8Size;
QCString qcs(utf8Size + 1);
CFStringGetCString(s, qcs.data(), utf8Size + 1, kCFStringEncodingUTF8);
return qcs;
@@ -1094,8 +1141,8 @@ int QString::find(const QString &str, int index, bool caseSensitive) const
// FIXME, use the first character algorithm
/*
We use some weird hashing for efficiency's sake. Instead of
- comparing strings, we compare the hash value of str with that of
- a part of this QString. Only if that matches, we call ucstrncmp
+ comparing strings, we compare the sum of str with that of
+ a part of this QString. Only if that matches, we call memcmp
or ucstrnicmp.
The hash value of a string is the sum of the cells of its
@@ -1118,139 +1165,97 @@ int QString::find(const QString &str, int index, bool caseSensitive) const
int i;
if ( caseSensitive ) {
for ( i = 0; i < lstr; i++ ) {
- hthis += uthis[i].cell();
- hstr += ustr[i].cell();
+ hthis += uthis[i].unicode();
+ hstr += ustr[i].unicode();
}
i = 0;
while ( TRUE ) {
- if ( hthis == hstr && ucstrncmp(uthis + i, ustr, lstr) == 0 )
+ if ( hthis == hstr && memcmp(uthis + i, ustr, lstr * sizeof(QChar)) == 0 )
return index + i;
if ( i == delta )
return -1;
- hthis += uthis[i + lstr].cell();
- hthis -= uthis[i].cell();
+ hthis += uthis[i + lstr].unicode();
+ hthis -= uthis[i].unicode();
i++;
}
} else {
for ( i = 0; i < lstr; i++ ) {
- hthis += uthis[i].lower().cell();
- hstr += ustr[i].lower().cell();
+ hthis += tolower(uthis[i].unicode());
+ hstr += tolower(ustr[i].unicode());
}
i = 0;
while ( TRUE ) {
- if ( hthis == hstr && ucstrnicmp(uthis + i, ustr, lstr) == 0 )
+ if ( hthis == hstr && equalCaseInsensitive(uthis + i, ustr, lstr) )
return index + i;
if ( i == delta )
return -1;
- hthis += uthis[i + lstr].lower().cell();
- hthis -= uthis[i].lower().cell();
+ hthis += tolower(uthis[i + lstr].unicode());
+ hthis -= tolower(uthis[i].unicode());
i++;
}
}
-
- // Should never get here.
- return -1;
}
-
// This function should be as fast as possible, every little bit helps.
// Our usage patterns are typically small strings. In time trials
// this simplistic algorithm is much faster than Boyer-Moore or hash
// based algorithms.
int QString::find(const char *chs, int index, bool caseSensitive) const
{
- if (dataHandle[0]->_isAsciiValid){
- char *ptr = dataHandle[0]->ascii();
-
- if (chs) {
- int len = dataHandle[0]->_length;
-
- ptr += index;
-
- if (len && (index >= 0) && (index < len)) {
- int remaining = len - index;
- int compareToLength = strlen(chs);
-
- char firstC = *chs;
-
- if (caseSensitive) {
- while (remaining >= compareToLength) {
- if (*ptr++ == firstC) {
- const char *_chs = chs + 1;
- char *compareTo = ptr;
- char c2;
- while ((c2 = *_chs++))
- if (*compareTo++ != c2)
- break;
- if (c2 == 0)
- return len - remaining;
- }
- remaining--;
- }
- } else {
- while (remaining >= compareToLength) {
- if (compareIgnoringCaseForASCIIOnly(*ptr++, firstC)) {
- const char *_chs = chs + 1;
- char *compareTo = ptr;
- char c2;
- while ((c2 = *_chs++))
- if (!compareIgnoringCaseForASCIIOnly(*compareTo++, c2))
- break;
- if (c2 == 0)
- return len - remaining;
- _chs = chs + 1;
- }
- remaining--;
- }
+ if (!chs || index < 0)
+ return -1;
+
+ KWQStringData *data = *dataHandle;
+
+ int chsLength = strlen(chs);
+ int n = data->_length - index;
+ if (n < 0)
+ return -1;
+ n -= chsLength - 1;
+ if (n <= 0)
+ return -1;
+
+ const char *chsPlusOne = chs + 1;
+ int chsLengthMinusOne = chsLength - 1;
+
+ if (data->_isAsciiValid) {
+ char *ptr = data->_ascii + index - 1;
+ if (caseSensitive) {
+ char c = *chs;
+ do {
+ if (*++ptr == c && memcmp(ptr + 1, chsPlusOne, chsLengthMinusOne) == 0) {
+ return data->_length - chsLength - n + 1;
}
- }
+ } while (--n);
+ } else {
+ int lc = tolower(*chs);
+ do {
+ if (tolower(*++ptr) == lc && equalCaseInsensitive(ptr + 1, chsPlusOne, chsLengthMinusOne)) {
+ return data->_length - chsLength - n + 1;
+ }
+ } while (--n);
}
- }
- else if (dataHandle[0]->_isUnicodeValid){
- QChar *ptr = (QChar *)dataHandle[0]->unicode();
-
- if (chs) {
- int len = dataHandle[0]->_length;
-
- ptr += index;
- if (len && (index >= 0) && (index < len)) {
- int remaining = len - index;
- int compareToLength = strlen(chs);
-
- if (caseSensitive) {
- QChar firstC = *chs;
- while (remaining >= compareToLength) {
- if (*ptr++ == firstC) {
- QChar *compareTo = ptr;
- const char *_chs = chs + 1;
- char c2;
- while ((c2 = *_chs++))
- if (*compareTo++ != c2)
- break;
- if (c2 == 0)
- return len - remaining;
- }
- remaining--;
- }
- } else {
- char firstC = *chs;
- while (remaining >= compareToLength) {
- if (compareIgnoringCaseForASCIIOnly(*ptr++, firstC)) {
- QChar *compareTo = ptr;
- const char *_chs = chs + 1;
- char c2;
- while ((c2 = *_chs++))
- if (!compareIgnoringCaseForASCIIOnly(*compareTo++, c2))
- break;
- if (c2 == 0)
- return len - remaining;
- }
- remaining--;
- }
+ } else {
+ ASSERT(data->_isUnicodeValid);
+
+ const QChar *ptr = data->_unicode + index - 1;
+ if (caseSensitive) {
+ QChar c = *chs;
+ do {
+ if (*++ptr == c && equal(ptr + 1, chsPlusOne, chsLengthMinusOne)) {
+ return data->_length - chsLength - n + 1;
}
- }
+ } while (--n);
+ } else {
+ int lc = tolower((unsigned char)*chs);
+ do {
+ if (tolower((++ptr)->unicode()) == lc && equalCaseInsensitive(ptr + 1, chsPlusOne, chsLengthMinusOne)) {
+ return data->_length - chsLength - n + 1;
+ }
+ } while (--n);
}
}
+
return -1;
}
@@ -1318,7 +1323,7 @@ int QString::findRev( const QString& str, int index, bool cs ) const
}
i = index;
while ( TRUE ) {
- if ( hthis == hstr && ucstrncmp(uthis + i, ustr, lstr) == 0 )
+ if ( hthis == hstr && memcmp(uthis + i, ustr, lstr * sizeof(QChar)) == 0 )
return i;
if ( i == 0 )
return -1;
@@ -1333,7 +1338,7 @@ int QString::findRev( const QString& str, int index, bool cs ) const
}
i = index;
while ( TRUE ) {
- if ( hthis == hstr && ucstrnicmp(uthis + i, ustr, lstr) == 0 )
+ if ( hthis == hstr && equalCaseInsensitive(uthis + i, ustr, lstr) )
return i;
if ( i == 0 )
return -1;
@@ -1352,138 +1357,201 @@ int QString::findRev( const QString& str, int index, bool cs ) const
static int containsCount = 0;
#endif
-int QString::contains( QChar c, bool cs ) const
+int QString::contains(QChar c, bool cs) const
{
int count = 0;
- if (dataHandle[0]->_isAsciiValid){
+ KWQStringData *data = *dataHandle;
+
+ if (data->_isAsciiValid) {
if (!IS_ASCII_QCHAR(c))
return 0;
-
- char tc, ac = (char)c;
- const char *cPtr = ascii();
- if ( !cPtr )
- return 0;
- int n = dataHandle[0]->_length;
- if ( cs ) { // case sensitive
- while ( n-- )
- if ( *cPtr++ == ac )
- count++;
+ const char *cPtr = data->_ascii;
+ int n = data->_length;
+ char ac = c.unicode();
+ if (cs) { // case sensitive
+ while (n--)
+ count += *cPtr++ == ac;
} else { // case insensitive
- ac = (ac >= 'A' && ac <= 'Z') ? ac + caseDelta : ac;
- while ( n-- ) {
- tc = *cPtr++;
- tc = (tc >= 'A' && tc <= 'Z') ? tc + caseDelta : tc;
- if ( tc == ac )
- count++;
+ int lc = tolower(ac);
+ while (n--) {
+ count += tolower(*cPtr++) == lc;
}
}
- }
- else if (dataHandle[0]->_isUnicodeValid){
- const QChar *uc = unicode();
- if ( !uc )
- return 0;
- int n = dataHandle[0]->_length;
- if ( cs ) { // case sensitive
+ } else {
+ ASSERT(data->_isUnicodeValid);
+ const QChar *uc = data->_unicode;
+ int n = data->_length;
+ if (cs) { // case sensitive
while ( n-- )
- if ( *uc++ == c )
- count++;
+ count += *uc++ == c;
} else { // case insensitive
- c = c.lower();
- while ( n-- ) {
- if ( uc->lower() == c )
- count++;
+ int lc = tolower(c.unicode());
+ while (n--) {
+ count += tolower(uc->unicode()) == lc;
uc++;
}
}
}
- else
- FATAL("invalid character cache");
+
return count;
}
int QString::contains(char ch) const
{
- return contains (QChar(ch),true);
+ return contains(QChar(ch), true);
}
int QString::contains(const char *str, bool caseSensitive) const
{
- if ( !str )
+ if (!str)
return 0;
- if (dataHandle[0]->_isAsciiValid){
- int count = 0;
- const char *uc = ascii();
- int n = dataHandle[0]->_length;
- int toLen = strlen(str);
-
- while ( n-- ) {
- if ( caseSensitive ) {
- if ( strncmp( uc, str, toLen ) == 0 )
- count++;
- } else {
- if ( strncasecmp(uc, str, toLen) == 0 )
- count++;
- }
- uc++;
+ int len = strlen(str);
+ char c = *str;
+
+ KWQStringData *data = *dataHandle;
+ int n = data->_length;
+
+ n -= len - 1;
+ if (n <= 0)
+ return 0;
+
+ int count = 0;
+
+ if (data->_isAsciiValid) {
+ const char *p = data->_ascii;
+ if (caseSensitive) {
+ do {
+ count += *p == c && memcmp(p + 1, str + 1, len - 1) == 0;
+ p++;
+ } while (--n);
+ } else {
+ int lc = tolower(c);
+ do {
+ count += tolower(*p) == lc && equalCaseInsensitive(p + 1, str + 1, len - 1);
+ p++;
+ } while (--n);
+ }
+ } else {
+ ASSERT(data->_isUnicodeValid);
+ const QChar *p = data->_unicode;
+ if (caseSensitive) {
+ do {
+ count += *p == c && equal(p + 1, str + 1, len - 1);
+ p++;
+ } while (--n);
+ } else {
+ int lc = tolower(c);
+ do {
+ count += tolower(p->unicode()) == lc && equalCaseInsensitive(p + 1, str + 1, len - 1);
+ p++;
+ } while (--n);
}
- return count;
}
- else if (dataHandle[0]->_isUnicodeValid)
- return contains(QString(str),caseSensitive);
- else
- FATAL("invalid character cache");
- return 0;
+ return count;
}
int QString::contains(const QString &str, bool caseSensitive) const
{
- int count = 0;
- const QChar *uc = unicode();
- if ( !str )
- return 0;
+ if (str.isEmpty())
+ return 0;
+
+ const QChar *strP = str.unicode();
int len = str.dataHandle[0]->_length;
+ QChar c = *strP;
+
+ const QChar *p = unicode();
int n = dataHandle[0]->_length;
- while ( n-- ) { // counts overlapping strings
- // ### Doesn't account for length of this - searches over "end"
- if ( caseSensitive ) {
- if ( ucstrncmp( uc, str.unicode(), len ) == 0 )
- count++;
- } else {
- if ( ucstrnicmp(uc, str.unicode(), len) == 0 )
- count++;
- }
- uc++;
+
+ n -= len - 1;
+ if (n <= 0)
+ return 0;
+
+ int count = 0;
+
+ if (caseSensitive) {
+ int byteCount = len * sizeof(QChar);
+ do {
+ count += *p == c && memcmp(p, strP, byteCount) == 0;
+ ++p;
+ } while (--n);
+ } else {
+ do {
+ count += p->lower() == c && equalCaseInsensitive(p, strP, len) == 0;
+ ++p;
+ } while (--n);
}
+
return count;
}
bool QString::isAllASCII() const
{
- if (dataHandle[0]->_isAsciiValid) {
- const char *p = ascii();
- int n = dataHandle[0]->_length;
+ KWQStringData *data = *dataHandle;
+
+ int n = data->_length;
+ if (data->_isAsciiValid) {
+ const char *p = data->_ascii;
while (n--) {
unsigned char c = *p++;
if (c > 0x7F) {
return false;
}
}
- }
- else if (dataHandle[0]->_isUnicodeValid) {
- const QChar *p = unicode();
- int n = dataHandle[0]->_length;
+ } else {
+ ASSERT(data->_isUnicodeValid);
+ const QChar *p = data->_unicode;
while (n--) {
if ((*p++).unicode() > 0x7F) {
return false;
}
}
}
+
+ return true;
+}
+
+bool QString::isAllLatin1() const
+{
+ KWQStringData *data = *dataHandle;
+
+ if (data->_isAsciiValid) {
+ return true;
+ }
+
+ ASSERT(data->_isUnicodeValid);
+ int n = data->_length;
+ const QChar *p = data->_unicode;
+ while (n--) {
+ if ((*p++).unicode() > 0xFF) {
+ return false;
+ }
+ }
+
return true;
}
+void QString::copyLatin1(char *buffer) const
+{
+ KWQStringData *data = *dataHandle;
+
+ int length = data->_length;
+
+ if (data->_isAsciiValid) {
+ memcpy(buffer, data->_ascii, length + 1);
+ return;
+ }
+
+ ASSERT(data->_isUnicodeValid);
+ const QChar *uc = data->_unicode;
+ while (length--)
+ *buffer++ = *uc++;
+ *buffer = 0;
+}
+
+
short QString::toShort(bool *ok, int base) const
{
long v = toLong( ok, base );
@@ -1541,13 +1609,14 @@ long QString::toLong(bool *ok, int base) const
while ( l && ok_in_base(*p,base) ) {
l--;
int dv;
- if ( p->isDigit() ) {
- dv = p->digitValue();
+ int c = p->unicode();
+ if ( isdigit(c) ) {
+ dv = c - '0';
} else {
- if ( *p >= 'a' && *p <= 'z' )
- dv = *p - 'a' + 10;
+ if ( c >= 'a' )
+ dv = c - 'a' + 10;
else
- dv = *p - 'A' + 10;
+ dv = c - 'A' + 10;
}
if ( val > max_mult || (val == max_mult && dv > (LONG_MAX % base)+neg) )
goto bye;
@@ -1586,13 +1655,14 @@ ulong QString::toULong(bool *ok, int base) const
while ( l && ok_in_base(*p,base) ) {
l--;
uint dv;
- if ( p->isDigit() ) {
- dv = p->digitValue();
+ int c = p->unicode();
+ if ( isdigit(c) ) {
+ dv = c - '0';
} else {
- if ( *p >= 'a' && *p <= 'z' )
- dv = *p - 'a' + 10;
+ if ( c >= 'a' )
+ dv = c - 'a' + 10;
else
- dv = *p - 'A' + 10;
+ dv = c - 'A' + 10;
}
if ( val > max_mult || (val == max_mult && dv > (ULONG_MAX % base)) )
goto bye;
@@ -1915,7 +1985,7 @@ void QString::deref()
QString &QString::setUnicode(const QChar *uni, uint len)
{
- detach();
+ detachAndDiscardCharacters();
// 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;
@@ -1930,7 +2000,7 @@ QString &QString::setUnicode(const QChar *uni, uint len)
deref();
if (needToFreeHandle)
freeHandle(dataHandle);
- dataHandle = (KWQStringData **)allocateHandle();
+ dataHandle = allocateHandle();
*dataHandle = new KWQStringData(uni, len);
dataHandle[0]->_isHeapAllocated = 1;
} else {
@@ -1951,7 +2021,7 @@ QString &QString::setLatin1(const char *str, int len)
if ( len < 0 )
len = strlen(str);
- detach();
+ detachAndDiscardCharacters();
// 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;
@@ -1960,7 +2030,7 @@ QString &QString::setLatin1(const char *str, int len)
deref();
if (needToFreeHandle)
freeHandle(dataHandle);
- dataHandle = (KWQStringData **)allocateHandle();
+ dataHandle = allocateHandle();
*dataHandle = new KWQStringData(str,len);
dataHandle[0]->_isHeapAllocated = 1;
} else {
@@ -2022,14 +2092,14 @@ QString &QString::sprintf(const char *format, ...)
}
// Arrange for storage for the resulting string.
- detach();
+ detachAndDiscardCharacters();
if (len >= dataHandle[0]->_maxAscii || dataHandle[0]->refCount != 1 || !dataHandle[0]->_isAsciiValid) {
// 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;
deref();
if (needToFreeHandle)
freeHandle(dataHandle);
- dataHandle = (KWQStringData **)allocateHandle();
+ dataHandle = allocateHandle();
*dataHandle = new KWQStringData((char *)0, len);
dataHandle[0]->_isHeapAllocated = 1;
} else {
@@ -2124,8 +2194,8 @@ QString &QString::insert(uint index, const QString &qs)
#ifdef QSTRING_DEBUG_UNICODE
forceUnicode();
#endif
- if (dataHandle[0]->_isAsciiValid && qs.dataHandle[0]->_isAsciiValid){
- insert (index, qs.ascii(), qs.length());
+ if (dataHandle[0]->_isAsciiValid && qs.isAllLatin1()) {
+ insert(index, qs.latin1(), qs.length());
}
else {
uint insertLength = qs.dataHandle[0]->_length;
@@ -2171,7 +2241,9 @@ QString &QString::insert(uint index, const QChar *insertChars, uint insertLength
setLength(originalLength + insertLength);
QChar *targetChars = const_cast<QChar *>(unicode());
- memmove(targetChars + index + insertLength, targetChars + index, (originalLength - index) * sizeof(QChar));
+ if (originalLength > index) {
+ memmove(targetChars + index + insertLength, targetChars + index, (originalLength - index) * sizeof(QChar));
+ }
memcpy(targetChars + index, insertChars, insertLength * sizeof(QChar));
return *this;
@@ -2222,7 +2294,7 @@ QString &QString::insert(uint index, char ch)
{
detach();
- if (dataHandle[0]->_isAsciiValid){
+ if (dataHandle[0]->_isAsciiValid) {
uint originalLength = dataHandle[0]->_length;
char *targetChars;
@@ -2258,58 +2330,48 @@ QString &QString::insert(uint index, char ch)
return *this;
}
-inline void QString::detachInternal()
-{
- 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;
- }
- }
- newData->_isHeapAllocated = 1;
- newData->refCount = oldData->refCount - 1;
- *dataHandle = newData;
-
- oldData->refCount = 1;
-}
-
// 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)
+ KWQStringData *oldData = *dataHandle;
+
+ if (oldData->refCount == 1 && oldData != shared_null)
return;
#ifdef QSTRING_DEBUG_ALLOCATIONS
stringDataDetachments++;
#endif
- KWQStringData *oldData = *dataHandle;
-
- // Copy data for this string so we can safely mutate it,
- // and put it in a new handle.
+
+ // Copy data for this string so we can safely mutate it.
KWQStringData *newData;
if (oldData->_isAsciiValid)
newData = new KWQStringData(oldData->ascii(), oldData->_length);
else
newData = new KWQStringData(oldData->unicode(), oldData->_length);
-
- // Copy our internal data so other strings can still safely reference it.
- detachIfInternal();
-
newData->_isHeapAllocated = 1;
- dataHandle = (KWQStringData **)allocateHandle();
- *dataHandle = newData;
-
- // Release the old data.
+
+ // There is now one less client for the old data.
oldData->deref();
+
+ // If the old data is our internal data, then we'll keep that.
+ // This decreases the chance we'll have to do a detachInternal later
+ // when this object is destroyed.
+ if (oldData == &internalData) {
+ newData->refCount = oldData->refCount;
+ oldData->refCount = 1;
+ *dataHandle = newData;
+ newData = oldData;
+ }
+
+ // Create a new handle.
+ dataHandle = allocateHandle();
+ *dataHandle = newData;
+}
+
+void QString::detachAndDiscardCharacters()
+{
+ // Missing optimization: Don't bother copying the old data if we detach.
+ detach();
}
QString &QString::remove(uint index, uint len)
@@ -2320,6 +2382,9 @@ QString &QString::remove(uint index, uint len)
} else if ( index + len >= olen ) { // index ok
setLength( index );
} else if ( len != 0 ) {
+ // Missing optimization: Could avoid copying characters we are going to remove
+ // by making a special version of detach().
+
detach();
#ifdef QSTRING_DEBUG_UNICODE
@@ -2414,15 +2479,16 @@ QChar *QString::forceUnicode()
// bytes will contain garbage.
void QString::setLength(uint newLen)
{
- detach();
-
- // If we going to change the length, we'll need our own data.
- if (dataHandle == shared_null_handle) {
- deref();
- dataHandle = (KWQStringData **)allocateHandle();
- *dataHandle = new KWQStringData();
- dataHandle[0]->_isHeapAllocated = 1;
+ if (newLen == 0) {
+ setUnicode(0, 0);
+ return;
}
+
+ // Missing optimization: Could avoid copying characters we are going to remove
+ // by making a special version of detach().
+ detach();
+
+ ASSERT(dataHandle != shared_null_handle);
#ifdef QSTRING_DEBUG_UNICODE
forceUnicode();
@@ -2431,7 +2497,6 @@ void QString::setLength(uint newLen)
if (newLen+1 > dataHandle[0]->_maxAscii) {
dataHandle[0]->increaseAsciiSize(newLen+1);
}
-
// Ensure null termination, although newly allocated
// bytes contain garbage.
dataHandle[0]->_ascii[newLen] = 0;
@@ -2456,7 +2521,7 @@ void QString::truncate(uint newLen)
void QString::fill(QChar qc, int len)
{
- detach();
+ detachAndDiscardCharacters();
#ifdef QSTRING_DEBUG_UNICODE
forceUnicode();
@@ -2491,57 +2556,7 @@ void QString::fill(QChar qc, int len)
}
}
-void QString::compose()
-{
- // FIXME: unimplemented because we don't do ligatures yet
- ERROR("not yet implemented");
-}
-
-QString QString::visual()
-{
- // FIXME: unimplemented because we don't do BIDI yet
- ERROR("not yet implemented");
- return QString(*this);
-}
-
-QString &QString::operator+=(const QString &qs)
-{
- detach();
-
- 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.dataHandle[0]->_isAsciiValid){
- char *fp = (char *)qs.ascii();
- while (i--)
- *tp++ = *fp++;
- }
- else if(qs.dataHandle[0]->_isUnicodeValid){
- QChar *fp = (QChar *)qs.unicode();
- while (i--)
- *tp++ = *fp++;
- }
- else
- FATAL("invalid character cache");
- dataHandle[0]->_length += qs.dataHandle[0]->_length;
- dataHandle[0]->_isAsciiValid = 0;
- return *this;
- }
- 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.dataHandle[0]->_length;
- dataHandle[0]->_isUnicodeValid = 0;
- return *this;
- }
- return insert(dataHandle[0]->_length, qs);
-}
-
-QString &QString::operator+=(QChar qc)
+QString &QString::append(QChar qc)
{
detach();
@@ -2562,7 +2577,7 @@ QString &QString::operator+=(QChar qc)
return insert(thisData->_length, qc);
}
-QString &QString::operator+=(char ch)
+QString &QString::append(char ch)
{
detach();
@@ -2583,6 +2598,14 @@ QString &QString::operator+=(char ch)
return insert(thisData->_length, ch);
}
+void QString::reserve(uint length)
+{
+ if (length > dataHandle[0]->_maxUnicode) {
+ detach();
+ dataHandle[0]->increaseUnicodeSize(length);
+ }
+}
+
bool operator==(const QString &s1, const QString &s2)
{
if (s1.dataHandle[0]->_isAsciiValid && s2.dataHandle[0]->_isAsciiValid) {
@@ -2825,7 +2848,7 @@ static void CHECK_PAGE_LISTS()
#endif
-static HandleNode *_initializeHandleNodeBlock(HandlePageNode *pageNode)
+static HandleNode *initializeHandleNodeBlock(HandlePageNode *pageNode)
{
uint i;
HandleNode *block, *aNode;
@@ -2852,21 +2875,21 @@ static HandleNode *_initializeHandleNodeBlock(HandlePageNode *pageNode)
return block;
}
-HandlePageNode *_allocatePageNode()
+static HandlePageNode *allocatePageNode()
{
HandlePageNode *node = (HandlePageNode *)malloc(sizeof(HandlePageNode));
node->next = node->previous = 0;
- node->nodes = _initializeHandleNodeBlock(node);
+ node->nodes = initializeHandleNodeBlock(node);
return node;
}
-void _initializeHandleNodes()
+static inline void initializeHandleNodes()
{
if (freeNodeAllocationPages == 0)
- freeNodeAllocationPages = _allocatePageNode();
+ freeNodeAllocationPages = allocatePageNode();
}
-HandleNode *_allocateNode(HandlePageNode *pageNode)
+static HandleNode *allocateNode(HandlePageNode *pageNode)
{
CHECK_PAGE_LISTS();
@@ -2908,24 +2931,22 @@ HandleNode *_allocateNode(HandlePageNode *pageNode)
return allocated;
}
-
-void *allocateHandle()
+KWQStringData **allocateHandle()
{
#if CHECK_FOR_HANDLE_LEAKS
- return malloc(sizeof(void *));
+ return static_cast<KWQStringData **>(malloc(sizeof(KWQStringData *)));
#endif
- _initializeHandleNodes();
+ initializeHandleNodes();
#ifdef QSTRING_DEBUG_ALLOCATIONS
handleInstances++;
#endif
- return _allocateNode (freeNodeAllocationPages);
+ return reinterpret_cast<KWQStringData **>(allocateNode(freeNodeAllocationPages));
}
-
-void freeHandle(void *_free)
+void freeHandle(KWQStringData **_free)
{
#if CHECK_FOR_HANDLE_LEAKS
free(_free);
diff --git a/WebCore/kwq/KWQTextCodec.mm b/WebCore/kwq/KWQTextCodec.mm
index 1b32330..8d5f11f 100644
--- a/WebCore/kwq/KWQTextCodec.mm
+++ b/WebCore/kwq/KWQTextCodec.mm
@@ -41,6 +41,7 @@ private:
QString convert(const char *chs, int len, bool flush)
{ return convert(reinterpret_cast<const unsigned char *>(chs), len, flush); }
QString convert(const unsigned char *chs, int len, bool flush);
+ QString convertLatin1(const unsigned char *chs, int len);
QString convertUTF16(const unsigned char *chs, int len);
QString convertUsingTEC(const unsigned char *chs, int len, bool flush);
@@ -236,6 +237,41 @@ KWQTextDecoder::~KWQTextDecoder()
}
}
+QString KWQTextDecoder::convertLatin1(const unsigned char *s, int length)
+{
+ ASSERT(_numBufferedBytes == 0);
+
+ int i;
+ for (i = 0; i != length; ++i) {
+ if (s[i] == 0) {
+ break;
+ }
+ }
+ if (i == length) {
+ return QString(reinterpret_cast<const char *>(s), length);
+ }
+
+ QString result;
+
+ result.reserve(length);
+
+ result.append(reinterpret_cast<const char *>(s), i);
+ int start = i + 1;
+ for (; i != length; ++i) {
+ if (s[i] == 0) {
+ if (start != i) {
+ result.append(reinterpret_cast<const char *>(&s[start]), i - start);
+ }
+ start = i + 1;
+ }
+ }
+ if (start != length) {
+ result.append(reinterpret_cast<const char *>(&s[start]), length - start);
+ }
+
+ return result;
+}
+
QString KWQTextDecoder::convertUTF16(const unsigned char *s, int length)
{
ASSERT(_numBufferedBytes == 0 || _numBufferedBytes == 1);
@@ -245,6 +281,8 @@ QString KWQTextDecoder::convertUTF16(const unsigned char *s, int length)
QString result;
+ result.reserve(length / 2);
+
if (_numBufferedBytes != 0 && len != 0) {
ASSERT(_numBufferedBytes == 1);
UniChar c;
@@ -262,7 +300,7 @@ QString KWQTextDecoder::convertUTF16(const unsigned char *s, int length)
}
while (len > 1) {
- UniChar buffer[4096];
+ UniChar buffer[16384];
int runLength = MIN(len / 2, sizeof(buffer) / sizeof(buffer[0]));
int bufferLength = 0;
if (_littleEndian) {
@@ -411,10 +449,12 @@ QString KWQTextDecoder::convertUsingTEC(const unsigned char *chs, int len, bool
QString result;
+ result.reserve(len);
+
const unsigned char *sourcePointer = chs;
int sourceLength = len;
bool bufferWasFull = false;
- UniChar buffer[4096];
+ UniChar buffer[16384];
while (sourceLength || bufferWasFull) {
int bytesRead = 0;
@@ -430,7 +470,7 @@ QString KWQTextDecoder::convertUsingTEC(const unsigned char *chs, int len, bool
break;
case kTextMalformedInputErr:
case kTextUndefinedElementErr:
- // FIXME: Put in FFFD character into the output string?
+ // FIXME: Put FFFD character into the output string in this case?
TECClearConverterContextInfo(_converter);
if (sourceLength) {
sourcePointer += 1;
@@ -480,25 +520,32 @@ QString KWQTextDecoder::convertUsingTEC(const unsigned char *chs, int len, bool
QString KWQTextDecoder::convert(const unsigned char *chs, int len, bool flush)
{
- if (_encoding == kCFStringEncodingUnicode) {
+ //#define PARTIAL_CHARACTER_HANDLING_TEST_CHUNK_SIZE 1000
+
+ switch (_encoding) {
+ case kCFStringEncodingISOLatin1:
+ case kCFStringEncodingWindowsLatin1:
+ return convertLatin1(chs, len);
+
+ case kCFStringEncodingUnicode:
return convertUTF16(chs, len);
- }
-//#define PARTIAL_CHARACTER_HANDLING_TEST_CHUNK_SIZE 1000
+ default:
#if PARTIAL_CHARACTER_HANDLING_TEST_CHUNK_SIZE
- QString result;
- int chunkSize;
- for (int i = 0; i != len; i += chunkSize) {
- chunkSize = len - i;
- if (chunkSize > PARTIAL_CHARACTER_HANDLING_TEST_CHUNK_SIZE) {
- chunkSize = PARTIAL_CHARACTER_HANDLING_TEST_CHUNK_SIZE;
+ QString result;
+ int chunkSize;
+ for (int i = 0; i != len; i += chunkSize) {
+ chunkSize = len - i;
+ if (chunkSize > PARTIAL_CHARACTER_HANDLING_TEST_CHUNK_SIZE) {
+ chunkSize = PARTIAL_CHARACTER_HANDLING_TEST_CHUNK_SIZE;
+ }
+ result += convertUsingTEC(chs + i, chunkSize, flush && (i + chunkSize == len));
}
- result += convertUsingTEC(chs + i, chunkSize, flush && (i + chunkSize == len));
- }
- return result;
+ return result;
#else
- return convertUsingTEC(chs, len, flush);
+ return convertUsingTEC(chs, len, flush);
#endif
+ }
}
QString KWQTextDecoder::toUnicode(const char *chs, int len, bool flush)
diff --git a/WebCore/kwq/KWQView.h b/WebCore/kwq/KWQView.h
index 2a21cdc..bac6d18 100644
--- a/WebCore/kwq/KWQView.h
+++ b/WebCore/kwq/KWQView.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,12 +31,3 @@ class QWidget;
@protocol KWQWidgetHolder
- (QWidget *)widget;
@end
-
- at interface KWQView : NSView <KWQWidgetHolder>
-{
- QWidget *widget;
- bool isFlipped;
-}
-- initWithWidget:(QWidget *)w;
-- (void)setIsFlipped:(bool)flag;
- at end
diff --git a/WebCore/kwq/KWQView.mm b/WebCore/kwq/KWQView.mm
deleted file mode 100644
index 15e9d78..0000000
--- a/WebCore/kwq/KWQView.mm
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#import "KWQView.h"
-
- at implementation KWQView
-
-- initWithFrame:(NSRect)frame
-{
- [super initWithFrame:frame];
- isFlipped = YES;
- return self;
-}
-
-- initWithWidget:(QWidget *)w
-{
- [super init];
- widget = w;
- return self;
-}
-
-- (void)setIsFlipped:(bool)flag
-{
- isFlipped = flag;
-}
-
-- (BOOL)isFlipped
-{
- return isFlipped;
-}
-
-- (QWidget *)widget
-{
- return widget;
-}
-
- at end
diff --git a/WebCore/kwq/KWQWidget.h b/WebCore/kwq/KWQWidget.h
index 7eff52a..0038f52 100644
--- a/WebCore/kwq/KWQWidget.h
+++ b/WebCore/kwq/KWQWidget.h
@@ -43,7 +43,7 @@
class NSView;
#endif
-class QWidgetPrivate;
+class KWQWidgetPrivate;
class QWidget : public QObject, public QPaintDevice {
public:
@@ -156,7 +156,7 @@ public:
void sendConsumedMouseUp();
private:
- QWidgetPrivate *data;
+ KWQWidgetPrivate *data;
};
#endif
diff --git a/WebCore/kwq/KWQWidget.mm b/WebCore/kwq/KWQWidget.mm
index 38955a3..7fbe2ff 100644
--- a/WebCore/kwq/KWQWidget.mm
+++ b/WebCore/kwq/KWQWidget.mm
@@ -28,7 +28,6 @@
#import "KWQExceptions.h"
#import "KWQKHTMLPart.h"
#import "KWQLogging.h"
-#import "KWQView.h"
#import "KWQWindowWidget.h"
#import "WebCoreBridge.h"
#import "WebCoreFrameView.h"
@@ -45,8 +44,7 @@ using khtml::RenderWidget;
emulate most QWidgets using NSViews.
*/
-
-class QWidgetPrivate
+class KWQWidgetPrivate
{
public:
QStyle *style;
@@ -56,28 +54,19 @@ public:
bool visible;
};
-QWidget::QWidget()
- : data(new QWidgetPrivate)
+QWidget::QWidget() : data(new KWQWidgetPrivate)
{
- data->view = nil;
-
- KWQ_BLOCK_EXCEPTIONS;
- data->view = [[KWQView alloc] initWithWidget:this];
- KWQ_UNBLOCK_EXCEPTIONS;
-
static QStyle defaultStyle;
data->style = &defaultStyle;
-
+ data->view = nil;
data->visible = true;
}
-QWidget::QWidget(NSView *view)
- : data(new QWidgetPrivate)
+QWidget::QWidget(NSView *view) : data(new KWQWidgetPrivate)
{
- data->view = [view retain];
-
static QStyle defaultStyle;
data->style = &defaultStyle;
+ data->view = [view retain];
data->visible = true;
}
@@ -432,9 +421,13 @@ void QWidget::hide()
void QWidget::setFrameGeometry(const QRect &rect)
{
KWQ_BLOCK_EXCEPTIONS;
- [getOuterView() setNeedsDisplay: YES];
- [getOuterView() setFrame:rect];
- [getOuterView() setNeedsDisplay: YES];
+ NSView *v = getOuterView();
+ NSRect f = rect;
+ if (!NSEqualRects(f, [v frame])) {
+ [v setNeedsDisplay:YES];
+ [v setFrame:f];
+ [v setNeedsDisplay:YES];
+ }
KWQ_UNBLOCK_EXCEPTIONS;
}
diff --git a/WebCore/kwq/WebCoreTextRenderer.h b/WebCore/kwq/WebCoreTextRenderer.h
index ca23132..9b187c4 100644
--- a/WebCore/kwq/WebCoreTextRenderer.h
+++ b/WebCore/kwq/WebCoreTextRenderer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,11 +37,12 @@ struct WebCoreTextStyle
int wordSpacing;
int padding;
NSString **families;
- unsigned smallCaps:1;
- unsigned rtl:1;
- unsigned visuallyOrdered:1;
- unsigned applyRounding:1;
- unsigned attemptFontSubstitution:1;
+ unsigned smallCaps : 1;
+ unsigned rtl : 1;
+ unsigned visuallyOrdered : 1;
+ unsigned applyRunRounding : 1;
+ unsigned applyWordRounding : 1;
+ unsigned attemptFontSubstitution : 1;
};
struct WebCoreTextRun
diff --git a/WebCore/kwq/WebCoreTextRendererFactory.m b/WebCore/kwq/WebCoreTextRendererFactory.m
index 8153e06..8d758c3 100644
--- a/WebCore/kwq/WebCoreTextRendererFactory.m
+++ b/WebCore/kwq/WebCoreTextRendererFactory.m
@@ -46,7 +46,8 @@ void WebCoreInitializeEmptyTextStyle(WebCoreTextStyle *style)
style->letterSpacing = 0;
style->wordSpacing = 0;
style->smallCaps = false;
- style->applyRounding = true;
+ style->applyRunRounding = true;
+ style->applyWordRounding = true;
style->attemptFontSubstitution = true;
style->families = nil;
}
diff --git a/WebCore/kwq/WebCoreTextRendererFactory.mm b/WebCore/kwq/WebCoreTextRendererFactory.mm
index 8153e06..8d758c3 100644
--- a/WebCore/kwq/WebCoreTextRendererFactory.mm
+++ b/WebCore/kwq/WebCoreTextRendererFactory.mm
@@ -46,7 +46,8 @@ void WebCoreInitializeEmptyTextStyle(WebCoreTextStyle *style)
style->letterSpacing = 0;
style->wordSpacing = 0;
style->smallCaps = false;
- style->applyRounding = true;
+ style->applyRunRounding = true;
+ style->applyWordRounding = true;
style->attemptFontSubstitution = true;
style->families = nil;
}
diff --git a/WebKit/ChangeLog b/WebKit/ChangeLog
index 3afb345..f95727a 100644
--- a/WebKit/ChangeLog
+++ b/WebKit/ChangeLog
@@ -1,3 +1,37 @@
+2004-02-08 Darin Adler <darin at apple.com>
+
+ Reviewed by Dave.
+
+ - fixed things seen in the profile, for a total speedup of 4% on cvs-base
+ - fixed some layout regressions from my last speedup due to text measurement inconsistencies by adding
+ a flag to control whether word rounding is done or not
+ - fixed text measurement to be used with AppKit to match AppKit again, as it did at some point in the past
+
+ * WebCoreSupport.subproj/WebTextRenderer.h: Remove some unused fields, and added a field to say whether we
+ treat this font as fixed pitch.
+ * WebCoreSupport.subproj/WebTextRenderer.m:
+ (getUncachedWidth): Remove space width hack from this level. There was already a width hack up at the higher
+ level for space itself, so there's not a significant speed benefit, and the higher level can make a more
+ intelligent choice based on the current rounding setting since it's not cached.
+ (-[WebTextRenderer _computeWidthForSpace]): Don't store so many widths; just the adjusted width we will
+ actually use.
+ (widthForNextCharacter): Use two different rules for when to adjust space widths, based on whether this is
+ a fixed pitch font or not. Also, don't do any adjusting of space widths if applyWordRounding is false.
+
+ * Misc.subproj/WebKitNSStringExtras.m:
+ (-[NSString _web_drawAtPoint:font:textColor:]): Turn off rounding, so we get the kind of spacing AppKit would normally give.
+ (-[NSString _web_widthWithFont:]): Ditto.
+ * Misc.subproj/WebStringTruncator.m: (stringWidth): Ditto.
+
+2004-02-08 Darin Adler <darin at apple.com>
+
+ Reviewed by NOBODY (OOPS!).
+
+ - fixed things seen in the profile, for a total speedup of 3.7% on cvs-base
+
+ * Misc.subproj/WebNSURLExtras.m: (-[NSURL _web_userVisibleString]): Check for "xn--" as we
+ walk the string instead of in a separate call to strcasestr. Faster this way.
+
2004-02-07 Darin Adler <darin at apple.com>
* WebKit.pbproj/project.pbxproj: Get rid of the DEPLOYMENT_LOCATION and DEPLOYMENT_POSTPROCESSING
diff --git a/WebKit/Misc.subproj/WebKitNSStringExtras.m b/WebKit/Misc.subproj/WebKitNSStringExtras.m
index 9d79769..7daacdf 100644
--- a/WebKit/Misc.subproj/WebKitNSStringExtras.m
+++ b/WebKit/Misc.subproj/WebKitNSStringExtras.m
@@ -40,6 +40,8 @@ static BOOL canUseFastRenderer (const UniChar *buffer, unsigned length)
WebCoreInitializeTextRun (&run, buffer, length, 0, length);
WebCoreTextStyle style;
WebCoreInitializeEmptyTextStyle(&style);
+ style.applyRunRounding = NO;
+ style.applyWordRounding = NO;
style.textColor = textColor;
[renderer drawRun:&run style:&style atPoint:point];
}
@@ -90,6 +92,8 @@ static BOOL canUseFastRenderer (const UniChar *buffer, unsigned length)
WebCoreInitializeTextRun (&run, buffer, length, 0, length);
WebCoreTextStyle style;
WebCoreInitializeEmptyTextStyle(&style);
+ style.applyRunRounding = NO;
+ style.applyWordRounding = NO;
width = [renderer floatWidthForRun:&run style:&style widths: 0];
}
else {
diff --git a/WebKit/Misc.subproj/WebNSURLExtras.m b/WebKit/Misc.subproj/WebNSURLExtras.m
index 3989d68..fd5d6c2 100644
--- a/WebKit/Misc.subproj/WebNSURLExtras.m
+++ b/WebKit/Misc.subproj/WebNSURLExtras.m
@@ -383,6 +383,8 @@ static NSString *mapHostNames(NSString *string, BOOL encode)
const unsigned char *before = [data bytes];
int length = [data length];
+ bool needsHostNameDecoding = false;
+
const unsigned char *p = before;
int bufferLength = (length * 3) + 1;
char *after = malloc(bufferLength); // large enough to %-escape every character
@@ -413,6 +415,10 @@ static NSString *mapHostNames(NSString *string, BOOL encode)
}
else {
*q++ = c;
+
+ // Check for "xn--" in an efficient, non-case-sensitive, way.
+ if (c == '-' && i >= 3 && !needsHostNameDecoding && (q[-4] | 0x20) == 'x' && (q[-3] | 0x20) == 'n' && q[-2] == '-')
+ needsHostNameDecoding = true;
}
}
*q = '\0';
@@ -445,11 +451,9 @@ static NSString *mapHostNames(NSString *string, BOOL encode)
result = [NSString stringWithUTF8String:after];
}
- // As an optimization, only do host name decoding if we have xn-- somewhere.
- bool needsHostNameDecoding = strcasestr(after, "xn--") != NULL;
-
free(after);
+ // As an optimization, only do host name decoding if we have "xn--" somewhere.
return needsHostNameDecoding ? mapHostNames(result, NO) : result;
}
diff --git a/WebKit/Misc.subproj/WebStringTruncator.m b/WebKit/Misc.subproj/WebStringTruncator.m
index 60b032c..9cc0163 100644
--- a/WebKit/Misc.subproj/WebStringTruncator.m
+++ b/WebKit/Misc.subproj/WebStringTruncator.m
@@ -7,6 +7,7 @@
// Complete rewrite with API similar to slow truncator by Al Dul
#import <WebKit/WebStringTruncator.h>
+
#import <Cocoa/Cocoa.h>
#import <WebKit/WebAssertions.h>
@@ -63,6 +64,8 @@ static float stringWidth(WebTextRenderer *renderer, const unichar *characters, u
WebCoreInitializeTextRun (&run, characters, length, 0, length);
WebCoreTextStyle style;
WebCoreInitializeEmptyTextStyle(&style);
+ style.applyRunRounding = NO;
+ style.applyWordRounding = NO;
return [renderer floatWidthForRun:&run style:&style widths:0];
}
diff --git a/WebKit/WebCoreSupport.subproj/WebTextRenderer.h b/WebKit/WebCoreSupport.subproj/WebTextRenderer.h
index fc0d348..66a58e1 100644
--- a/WebKit/WebCoreSupport.subproj/WebTextRenderer.h
+++ b/WebKit/WebCoreSupport.subproj/WebTextRenderer.h
@@ -26,14 +26,14 @@ typedef struct CharacterWidthIterator CharacterWidthIterator;
ATSStyleGroupPtr styleGroup;
@public
- ATSGlyphRef spaceGlyph;
NSFont *font;
GlyphMap *characterToGlyphMap; // Used for 16bit clean unicode characters.
UnicodeGlyphMap *unicodeCharacterToGlyphMap; // Used for surrogates.
WidthMap *glyphToWidthMap;
+
+ BOOL treatAsFixedPitch;
+ ATSGlyphRef spaceGlyph;
float spaceWidth;
- float ceiledSpaceWidth;
- float roundedSpaceWidth;
float adjustedSpaceWidth;
int numSubstituteFontWidthMaps;
diff --git a/WebKit/WebCoreSupport.subproj/WebTextRenderer.m b/WebKit/WebCoreSupport.subproj/WebTextRenderer.m
index eb924b9..2855bbe 100644
--- a/WebKit/WebCoreSupport.subproj/WebTextRenderer.m
+++ b/WebKit/WebCoreSupport.subproj/WebTextRenderer.m
@@ -1,6 +1,6 @@
/*
WebTextRenderer.m
- Copyright 2002, Apple, Inc. All rights reserved.
+ Copyright 2004, Apple, Inc. All rights reserved.
*/
#import "WebTextRenderer.h"
@@ -8,11 +8,10 @@
#import <ApplicationServices/ApplicationServices.h>
#import <Cocoa/Cocoa.h>
+#import <AppKit/NSFont_Private.h>
#import <CoreGraphics/CoreGraphicsPrivate.h>
#import <QD/ATSUnicodePriv.h>
-#import <AppKit/NSFont_Private.h>
-
#import <WebCore/WebCoreUnicode.h>
#import <WebKit/WebGlyphBuffer.h>
@@ -27,7 +26,7 @@
// Macros
#define SPACE 0x0020
-#define ROUND_TO_INT(x) (unsigned)((x)+.5)
+#define ROUND_TO_INT(x) (int)((x)+.5)
// Lose precision beyond 1000ths place. This is to work around an apparent
// bug in CoreGraphics where there seem to be small errors to some metrics.
@@ -209,17 +208,6 @@ static WebGlyphWidth getUncachedWidth(WebTextRenderer *renderer, WidthMap *map,
if (errorResult == 0)
FATAL_ALWAYS ("Unable to cache glyph widths for %@ %f", [renderer->font displayName], [renderer->font pointSize]);
- // Hack to ensure that characters that match the width of the space character
- // have the same integer width as the space character. This is necessary so
- // glyphs in fixed pitch fonts all have the same integer width. We can't depend
- // on the fixed pitch property of NSFont because that isn't set for all
- // monospaced fonts, in particular Courier! This has the downside of inappropriately
- // adjusting the widths of characters in non-monospaced fonts that are coincidentally
- // the same width as a space in that font. In practice this is not an issue as the
- // adjustment is always at the sub-pixel level.
- if (width == renderer->spaceWidth)
- return renderer->ceiledSpaceWidth;
-
return width;
}
@@ -375,15 +363,15 @@ static BOOL alwaysUseATSU = NO;
#ifdef COMPARE_APPKIT_CG_METRICS
printf ("\nCG/Appkit metrics for font %s, %f, lineGap %f, adjustment %f, _canDrawOutsideLineHeight %d, _isSystemFont %d\n", [[font displayName] cString], [font pointSize], lineGap, adjustment, (int)[font _canDrawOutsideLineHeight], (int)[font _isSystemFont]);
- if ((int)ROUND_TO_INT([font ascender]) != ascent ||
- (int)ROUND_TO_INT(-[font descender]) != descent ||
- (int)ROUND_TO_INT([font defaultLineHeightForFont]) != lineSpacing){
+ if (ROUND_TO_INT([font ascender]) != ascent ||
+ ROUND_TO_INT(-[font descender]) != descent ||
+ ROUND_TO_INT([font defaultLineHeightForFont]) != lineSpacing){
printf ("\nCG/Appkit mismatched metrics for font %s, %f (%s)\n", [[font displayName] cString], [font pointSize],
([font screenFont] ? [[[font screenFont] displayName] cString] : "none"));
printf ("ascent(%s), descent(%s), lineSpacing(%s)\n",
- ((int)ROUND_TO_INT([font ascender]) != ascent) ? "different" : "same",
- ((int)ROUND_TO_INT(-[font descender]) != descent) ? "different" : "same",
- ((int)ROUND_TO_INT([font defaultLineHeightForFont]) != lineSpacing) ? "different" : "same");
+ (ROUND_TO_INT([font ascender]) != ascent) ? "different" : "same",
+ (ROUND_TO_INT(-[font descender]) != descent) ? "different" : "same",
+ (ROUND_TO_INT([font defaultLineHeightForFont]) != lineSpacing) ? "different" : "same");
printf ("CG: ascent %f, ", asc);
printf ("descent %f, ", dsc);
printf ("lineGap %f, ", lineGap);
@@ -419,40 +407,6 @@ static BOOL alwaysUseATSU = NO;
[super dealloc];
}
-- (int)widthForCharacters:(const UniChar *)characters length:(unsigned)stringLength
-{
- WebCoreTextRun run;
- WebCoreInitializeTextRun (&run, characters, stringLength, 0, stringLength);
- WebCoreTextStyle style;
- WebCoreInitializeEmptyTextStyle(&style);
- return ROUND_TO_INT([self floatWidthForRun:&run style:&style widths: 0]);
-}
-
-- (int)widthForString:(NSString *)string
-{
- UniChar localCharacterBuffer[LOCAL_BUFFER_SIZE];
- UniChar *characterBuffer = localCharacterBuffer;
- const UniChar *usedCharacterBuffer = CFStringGetCharactersPtr((CFStringRef)string);
- unsigned length;
- int width;
-
- // Get the characters from the string into a buffer.
- length = [string length];
- if (!usedCharacterBuffer) {
- if (length > LOCAL_BUFFER_SIZE)
- characterBuffer = (UniChar *)malloc(length * sizeof(UniChar));
- [string getCharacters:characterBuffer];
- usedCharacterBuffer = characterBuffer;
- }
-
- width = [self widthForCharacters:usedCharacterBuffer length:length];
-
- if (characterBuffer != localCharacterBuffer)
- free(characterBuffer);
-
- return width;
-}
-
- (int)ascent
{
// This simple return obviously can't throw an exception.
@@ -751,27 +705,20 @@ static inline BOOL fontContainsString(NSFont *font, NSString *string)
}
// Nasty hack to determine if we should round or ceil space widths.
-// If the font is monospace, or fake monospace we ceil to ensure that
+// If the font is monospace or fake monospace we ceil to ensure that
// every character and the space are the same width. Otherwise we round.
- (BOOL)_computeWidthForSpace
{
- UniChar c = ' ';
- float _spaceWidth;
-
- spaceGlyph = [self _extendCharacterToGlyphMapToInclude: c];
- if (spaceGlyph == 0){
+ spaceGlyph = [self _extendCharacterToGlyphMapToInclude:SPACE];
+ if (spaceGlyph == 0) {
return NO;
}
- _spaceWidth = widthForGlyph(self, spaceGlyph, 0);
- ceiledSpaceWidth = (float)CEIL_TO_INT(_spaceWidth);
- roundedSpaceWidth = (float)ROUND_TO_INT(_spaceWidth);
- if ([font isFixedPitch] || [font _isFakeFixedPitch]){
- adjustedSpaceWidth = ceiledSpaceWidth;
- }
- else {
- adjustedSpaceWidth = roundedSpaceWidth;
- }
- spaceWidth = _spaceWidth;
+
+ float width = widthForGlyph(self, spaceGlyph, 0);
+ spaceWidth = width;
+
+ treatAsFixedPitch = [font isFixedPitch] || [font _isFakeFixedPitch];
+ adjustedSpaceWidth = treatAsFixedPitch ? CEIL_TO_INT(width) : ROUND_TO_INT(width);
return YES;
}
@@ -1887,13 +1834,15 @@ static float widthForNextCharacter(CharacterWidthIterator *iterator, ATSGlyphRef
}
}
- // Now that we have glyph and font, get its width. We special case spaces.
- // They are always an even integer width.
- WebGlyphWidth width;
- if (*glyphUsed == renderer->spaceGlyph)
+ // Now that we have glyph and font, get its width.
+ WebGlyphWidth width = widthForGlyph(renderer, *glyphUsed, *fontUsed);
+
+ // We special case spaces in two ways when applying word rounding.
+ // First, we round spaces to an adjusted width in all fonts.
+ // Second, in fixed-pitch fonts we ensure that all characters that
+ // match the width of the space character have the same width as the space character.
+ if ((renderer->treatAsFixedPitch ? width == renderer->spaceWidth : *glyphUsed == renderer->spaceGlyph) && iterator->style->applyWordRounding)
width = renderer->adjustedSpaceWidth;
- else
- width = widthForGlyph(renderer, *glyphUsed, *fontUsed);
// Try to find a substitute font if this font didn't have a glyph for a character in the
// string. If one isn't found we end up drawing and measuring the 0 glyph, usually a box.
@@ -1920,7 +1869,7 @@ static float widthForNextCharacter(CharacterWidthIterator *iterator, ATSGlyphRef
WebCoreInitializeTextRun(&clusterRun, characterArray, characterArrayLength, 0, characterArrayLength);
WebCoreTextStyle clusterStyle = *iterator->style;
clusterStyle.padding = 0;
- clusterStyle.applyRounding = false;
+ clusterStyle.applyRunRounding = false;
clusterStyle.attemptFontSubstitution = false;
WebTextRenderer *substituteRenderer;
@@ -1948,7 +1897,7 @@ static float widthForNextCharacter(CharacterWidthIterator *iterator, ATSGlyphRef
// Force characters that are used to determine word boundaries for the rounding hack
// to be integer width, so following words will start on an integer boundary.
- if (isRoundingHackCharacter(c)) {
+ if (isRoundingHackCharacter(c) && iterator->style->applyWordRounding) {
width = CEIL_TO_INT(width);
}
@@ -1992,10 +1941,10 @@ static float widthForNextCharacter(CharacterWidthIterator *iterator, ATSGlyphRef
// floats we can remove this (and related) hacks.
//
// Check to see if the next character is a "RoundingHackCharacter", if so, adjust.
- if (currentCharacter < run->length && isRoundingHackCharacter(cp[clusterLength])) {
+ if (currentCharacter < run->length && isRoundingHackCharacter(cp[clusterLength]) && iterator->style->applyWordRounding) {
width += ceilCurrentWidth(iterator);
}
- else if (currentCharacter >= (unsigned)run->to && (len > 1 || run->length == 1) && iterator->style->applyRounding) {
+ else if (currentCharacter >= (unsigned)run->to && (len > 1 || run->length == 1) && iterator->style->applyRunRounding) {
width += ceilCurrentWidth(iterator);
}
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list