Commit 0033926d authored by rjw's avatar rjw

Fixed another problem in QString::find().

        Added dangerous but fast string allocation optimization to render_text.cpp.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@746 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 30b34ec4
2002-03-14 Richard Williamson <rjw@apple.com>
Fixed another problem in QString::find().
Added dangerous but fast string allocation optimization to render_text.cpp.
* src/kdelibs/khtml/rendering/render_text.cpp: (RenderText::calcMinMaxWidth):
* src/kwq/KWQFontMetrics.mm: (QFontMetrics::_width):
* src/kwq/KWQString.mm: (QString::find):
* src/kwq/KWQTextStorage.mm: (-[KWQTextStorage _buildFragmentForString:]),
(-[KWQTextStorage setString:]):
* src/kwq/qt/qfontmetrics.h:
2002-03-14 Richard Williamson <rjw@apple.com>
Fixed optimized find() implementation. I had the sense of caseSensitive inverted.
......
2002-03-14 Richard Williamson <rjw@apple.com>
Fixed another problem in QString::find().
Added dangerous but fast string allocation optimization to render_text.cpp.
* src/kdelibs/khtml/rendering/render_text.cpp: (RenderText::calcMinMaxWidth):
* src/kwq/KWQFontMetrics.mm: (QFontMetrics::_width):
* src/kwq/KWQString.mm: (QString::find):
* src/kwq/KWQTextStorage.mm: (-[KWQTextStorage _buildFragmentForString:]),
(-[KWQTextStorage setString:]):
* src/kwq/qt/qfontmetrics.h:
2002-03-14 Richard Williamson <rjw@apple.com>
Fixed optimized find() implementation. I had the sense of caseSensitive inverted.
......
2002-03-14 Richard Williamson <rjw@apple.com>
Fixed another problem in QString::find().
Added dangerous but fast string allocation optimization to render_text.cpp.
* src/kdelibs/khtml/rendering/render_text.cpp: (RenderText::calcMinMaxWidth):
* src/kwq/KWQFontMetrics.mm: (QFontMetrics::_width):
* src/kwq/KWQString.mm: (QString::find):
* src/kwq/KWQTextStorage.mm: (-[KWQTextStorage _buildFragmentForString:]),
(-[KWQTextStorage setString:]):
* src/kwq/qt/qfontmetrics.h:
2002-03-14 Richard Williamson <rjw@apple.com>
Fixed optimized find() implementation. I had the sense of caseSensitive inverted.
......
......@@ -659,6 +659,13 @@ void RenderText::print( QPainter *p, int x, int y, int w, int h,
printObject(p, x, y, w, h, tx, ty);
}
#ifdef APPLE_CHANGES
#define OPTIMIZE_STRING_USAGE
#ifdef OPTIMIZE_STRING_USAGE
static CFMutableStringRef reuseableString = 0;
#endif
#endif
void RenderText::calcMinMaxWidth()
{
//kdDebug( 6040 ) << "Text::calcMinMaxWidth(): known=" << minMaxKnown() << endl;
......@@ -686,7 +693,15 @@ void RenderText::calcMinMaxWidth()
} while( i+wordlen < len && !(isBreakable( str->s, i+wordlen, str->l )) );
if (wordlen)
{
#if (defined(APPLE_CHANGES) && defined(OPTIMIZE_STRING_USAGE))
if (reuseableString == 0)
reuseableString = CFStringCreateMutableWithExternalCharactersNoCopy (kCFAllocatorDefault, (UniChar *)(str->s+i), wordlen, wordlen, kCFAllocatorDefault);
else
CFStringSetExternalCharactersNoCopy (reuseableString, (UniChar *)(str->s+i), wordlen, wordlen);
int w = _fm._width(reuseableString);
#else
int w = _fm.width(QConstString(str->s+i, wordlen).string());
#endif
currMinWidth += w;
currMaxWidth += w;
}
......@@ -705,7 +720,15 @@ void RenderText::calcMinMaxWidth()
{
if(currMinWidth > m_minWidth) m_minWidth = currMinWidth;
currMinWidth = 0;
#if (defined(APPLE_CHANGES) && defined(OPTIMIZE_STRING_USAGE))
if (reuseableString == 0)
reuseableString = CFStringCreateMutableWithExternalCharactersNoCopy (kCFAllocatorDefault, (UniChar *)(str->s+i+wordlen), wordlen, wordlen, kCFAllocatorDefault);
else
CFStringSetExternalCharactersNoCopy (reuseableString, (UniChar *)(str->s+i+wordlen), 1, 1);
currMaxWidth += _fm._width(reuseableString);
#else
currMaxWidth += _fm.width( *(str->s+i+wordlen) );
#endif
}
/* else if( c == '-')
{
......
......@@ -66,6 +66,10 @@ public:
int width(QChar) const;
int width(char) const;
int width(const QString &, int len=-1) const;
#if (defined(__APPLE__))
int _width (CFStringRef string) const;
#endif
int descent() const;
QRect boundingRect(const QString &, int len=-1) const;
QRect boundingRect(QChar) const;
......
......@@ -427,6 +427,12 @@ int QFontMetrics::width(const QString &qstring, int len) const
return stringWidth;
}
int QFontMetrics::_width(CFStringRef string) const
{
int stringWidth = ROUND_TO_INT([data->info rectForString: (NSString *)string].size.width);
return stringWidth;
}
QRect QFontMetrics::boundingRect(const QString &qstring, int len) const
{
......
......@@ -534,6 +534,8 @@ static int findExpensiveCount = 0;
static int findCheapCount = 0;
#endif
static int caseDelta = ('a' - 'A');
int QString::find(const char *chs, int index, bool caseSensitive) const
{
int pos = -1;
......@@ -574,42 +576,41 @@ int QString::find(const char *chs, int index, bool caseSensitive) const
fprintf (stdout, "findCount = %d, expensive = %d, cheap = %d\n", findCount, findExpensiveCount, findCheapCount);
#endif
if (len && (index >= 0) && (index < len)) {
UniChar firstC, c1, c2, otherCase_c2;
UniChar firstC, c1, c2;
const char *_chs;
int remaining = len - index, found = -1;
int compareToLength = strlen(chs);
internalBuffer = &internalBuffer[index];
_chs = chs;
firstC = (UniChar)(*_chs);
_chs = chs + 1;
firstC = (UniChar)(*chs);
while (remaining >= compareToLength){
if (*internalBuffer++ == firstC){
const UniChar *compareTo = internalBuffer;
int caseDelta = ('a' - 'A');
found = len - remaining;
_chs++;
while (*compareTo && *_chs){
while ( (c2 = (UniChar)(*_chs++)) ){
c1 = (UniChar)(*compareTo++);
c2 = (UniChar)(*_chs);
if (!caseSensitive){
if (c2 >= 'a' && c2 <= 'z')
otherCase_c2 = c2 - caseDelta;
else if (c2 >= 'A' && c2 <= 'Z')
otherCase_c2 = c2 + caseDelta;
else
otherCase_c2 = c2;
if (c1 != c2 && c1 != otherCase_c2)
break;
if (c2 >= 'a' && c2 <= 'z'){
if (c1 == c2 || c1 == c2 - caseDelta)
continue;
}
else if (c2 >= 'A' && c2 <= 'Z'){
if (c1 == c2 || c1 == c2 + caseDelta)
continue;
}
else if (c1 == c2)
continue;
}
else if (c1 != c2)
break;
_chs++;
else if (c1 == c2)
continue;
break;
}
if (!*_chs)
if (c2 == 0)
return found;
_chs = chs;
_chs = chs + 1;
}
remaining--;
}
......
......@@ -56,6 +56,7 @@
fragmentCache = [[NSMutableDictionary alloc] init];
[self setString: measureString];
glyphRange = [_layoutManager glyphRangeForCharacterRange:range actualCharacterRange:nil];
boundingRect = [_layoutManager boundingRectForGlyphRange: glyphRange inTextContainer: [KWQTextContainer sharedInstance]];
......@@ -77,7 +78,7 @@
[fragment setGlyphRange: glyphRange];
[fragment setBoundingRect: boundingRect];
[fragmentCache setObject: fragment forKey: measureString];
[fragmentCache setObject: fragment forKey: [self string]];
[fragment release];
return fragment;
......@@ -227,7 +228,10 @@ static int trailingSpace = 0;
int newLength = [newString length];
[string release];
string = [newString retain];
// Make an immutable copy.
string = [[NSString stringWithString: newString] retain];
[_layoutManager textStorage: self
edited: NSTextStorageEditedCharacters
range: NSMakeRange (0, newLength)
......
......@@ -66,6 +66,10 @@ public:
int width(QChar) const;
int width(char) const;
int width(const QString &, int len=-1) const;
#if (defined(__APPLE__))
int _width (CFStringRef string) const;
#endif
int descent() const;
QRect boundingRect(const QString &, int len=-1) const;
QRect boundingRect(QChar) const;
......
......@@ -659,6 +659,13 @@ void RenderText::print( QPainter *p, int x, int y, int w, int h,
printObject(p, x, y, w, h, tx, ty);
}
#ifdef APPLE_CHANGES
#define OPTIMIZE_STRING_USAGE
#ifdef OPTIMIZE_STRING_USAGE
static CFMutableStringRef reuseableString = 0;
#endif
#endif
void RenderText::calcMinMaxWidth()
{
//kdDebug( 6040 ) << "Text::calcMinMaxWidth(): known=" << minMaxKnown() << endl;
......@@ -686,7 +693,15 @@ void RenderText::calcMinMaxWidth()
} while( i+wordlen < len && !(isBreakable( str->s, i+wordlen, str->l )) );
if (wordlen)
{
#if (defined(APPLE_CHANGES) && defined(OPTIMIZE_STRING_USAGE))
if (reuseableString == 0)
reuseableString = CFStringCreateMutableWithExternalCharactersNoCopy (kCFAllocatorDefault, (UniChar *)(str->s+i), wordlen, wordlen, kCFAllocatorDefault);
else
CFStringSetExternalCharactersNoCopy (reuseableString, (UniChar *)(str->s+i), wordlen, wordlen);
int w = _fm._width(reuseableString);
#else
int w = _fm.width(QConstString(str->s+i, wordlen).string());
#endif
currMinWidth += w;
currMaxWidth += w;
}
......@@ -705,7 +720,15 @@ void RenderText::calcMinMaxWidth()
{
if(currMinWidth > m_minWidth) m_minWidth = currMinWidth;
currMinWidth = 0;
#if (defined(APPLE_CHANGES) && defined(OPTIMIZE_STRING_USAGE))
if (reuseableString == 0)
reuseableString = CFStringCreateMutableWithExternalCharactersNoCopy (kCFAllocatorDefault, (UniChar *)(str->s+i+wordlen), wordlen, wordlen, kCFAllocatorDefault);
else
CFStringSetExternalCharactersNoCopy (reuseableString, (UniChar *)(str->s+i+wordlen), 1, 1);
currMaxWidth += _fm._width(reuseableString);
#else
currMaxWidth += _fm.width( *(str->s+i+wordlen) );
#endif
}
/* else if( c == '-')
{
......
......@@ -427,6 +427,12 @@ int QFontMetrics::width(const QString &qstring, int len) const
return stringWidth;
}
int QFontMetrics::_width(CFStringRef string) const
{
int stringWidth = ROUND_TO_INT([data->info rectForString: (NSString *)string].size.width);
return stringWidth;
}
QRect QFontMetrics::boundingRect(const QString &qstring, int len) const
{
......
......@@ -534,6 +534,8 @@ static int findExpensiveCount = 0;
static int findCheapCount = 0;
#endif
static int caseDelta = ('a' - 'A');
int QString::find(const char *chs, int index, bool caseSensitive) const
{
int pos = -1;
......@@ -574,42 +576,41 @@ int QString::find(const char *chs, int index, bool caseSensitive) const
fprintf (stdout, "findCount = %d, expensive = %d, cheap = %d\n", findCount, findExpensiveCount, findCheapCount);
#endif
if (len && (index >= 0) && (index < len)) {
UniChar firstC, c1, c2, otherCase_c2;
UniChar firstC, c1, c2;
const char *_chs;
int remaining = len - index, found = -1;
int compareToLength = strlen(chs);
internalBuffer = &internalBuffer[index];
_chs = chs;
firstC = (UniChar)(*_chs);
_chs = chs + 1;
firstC = (UniChar)(*chs);
while (remaining >= compareToLength){
if (*internalBuffer++ == firstC){
const UniChar *compareTo = internalBuffer;
int caseDelta = ('a' - 'A');
found = len - remaining;
_chs++;
while (*compareTo && *_chs){
while ( (c2 = (UniChar)(*_chs++)) ){
c1 = (UniChar)(*compareTo++);
c2 = (UniChar)(*_chs);
if (!caseSensitive){
if (c2 >= 'a' && c2 <= 'z')
otherCase_c2 = c2 - caseDelta;
else if (c2 >= 'A' && c2 <= 'Z')
otherCase_c2 = c2 + caseDelta;
else
otherCase_c2 = c2;
if (c1 != c2 && c1 != otherCase_c2)
break;
if (c2 >= 'a' && c2 <= 'z'){
if (c1 == c2 || c1 == c2 - caseDelta)
continue;
}
else if (c2 >= 'A' && c2 <= 'Z'){
if (c1 == c2 || c1 == c2 + caseDelta)
continue;
}
else if (c1 == c2)
continue;
}
else if (c1 != c2)
break;
_chs++;
else if (c1 == c2)
continue;
break;
}
if (!*_chs)
if (c2 == 0)
return found;
_chs = chs;
_chs = chs + 1;
}
remaining--;
}
......
......@@ -56,6 +56,7 @@
fragmentCache = [[NSMutableDictionary alloc] init];
[self setString: measureString];
glyphRange = [_layoutManager glyphRangeForCharacterRange:range actualCharacterRange:nil];
boundingRect = [_layoutManager boundingRectForGlyphRange: glyphRange inTextContainer: [KWQTextContainer sharedInstance]];
......@@ -77,7 +78,7 @@
[fragment setGlyphRange: glyphRange];
[fragment setBoundingRect: boundingRect];
[fragmentCache setObject: fragment forKey: measureString];
[fragmentCache setObject: fragment forKey: [self string]];
[fragment release];
return fragment;
......@@ -227,7 +228,10 @@ static int trailingSpace = 0;
int newLength = [newString length];
[string release];
string = [newString retain];
// Make an immutable copy.
string = [[NSString stringWithString: newString] retain];
[_layoutManager textStorage: self
edited: NSTextStorageEditedCharacters
range: NSMakeRange (0, newLength)
......
......@@ -66,6 +66,10 @@ public:
int width(QChar) const;
int width(char) const;
int width(const QString &, int len=-1) const;
#if (defined(__APPLE__))
int _width (CFStringRef string) const;
#endif
int descent() const;
QRect boundingRect(const QString &, int len=-1) const;
QRect boundingRect(QChar) const;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment