[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677
rjw
rjw at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 05:57:21 UTC 2009
The following commit has been merged in the debian/unstable branch:
commit d8ce265c8c1d9f9fd50ba3d775483fc553280a3c
Author: rjw <rjw at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Wed Mar 13 18:34:53 2002 +0000
Re-worked fragment cache to minimize memory usage.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@730 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog-2002-12-03 b/WebCore/ChangeLog-2002-12-03
index 9f89e9f..dfadab2 100644
--- a/WebCore/ChangeLog-2002-12-03
+++ b/WebCore/ChangeLog-2002-12-03
@@ -1,3 +1,22 @@
+2002-03-13 Richard Williamson <rjw at apple.com>
+
+ Re-worked fragment cache to minimize memory usage.
+
+ * src/kwq/KWQFontMetrics.mm: (-[KWQLayoutFragment glyphRange]),
+ (-[KWQLayoutFragment setGlyphRangeLength:]), (-[KWQLayoutFragment
+ setBoundingRectSize:]), (-[KWQLayoutFragment boundingRect]), (+[KWQLayoutInfo
+ drawString:atPoint:withFont:color:]), (+[KWQLayoutInfo
+ drawUnderlineForString:atPoint:withFont:color:]), (-[KWQLayoutInfo
+ initWithFont:]), (-[KWQLayoutInfo layoutManager]), (-[KWQLayoutInfo
+ textStorage]), (-[KWQLayoutInfo rectForString:]):
+ * src/kwq/KWQMetrics.h:
+ * src/kwq/KWQTextStorage.h:
+ * src/kwq/KWQTextStorage.mm: (-[KWQTextStorage getFragmentForString:]),
+ (-[KWQTextStorage addFragmentForString:]), (-[KWQTextStorage
+ initWithFontAttribute:]), (-[KWQTextStorage dealloc]), (-[KWQTextStorage
+ length]), (-[KWQTextStorage setAttributes:]), (-[KWQTextStorage setString:]),
+ (-[KWQTextStorage string]):
+
2002-03-13 Kenneth Kocienda <kocienda at apple.com>
Updated for new didRedirectToURL callback. This is a partial fix for this bug:
diff --git a/WebCore/ChangeLog-2003-10-25 b/WebCore/ChangeLog-2003-10-25
index 9f89e9f..dfadab2 100644
--- a/WebCore/ChangeLog-2003-10-25
+++ b/WebCore/ChangeLog-2003-10-25
@@ -1,3 +1,22 @@
+2002-03-13 Richard Williamson <rjw at apple.com>
+
+ Re-worked fragment cache to minimize memory usage.
+
+ * src/kwq/KWQFontMetrics.mm: (-[KWQLayoutFragment glyphRange]),
+ (-[KWQLayoutFragment setGlyphRangeLength:]), (-[KWQLayoutFragment
+ setBoundingRectSize:]), (-[KWQLayoutFragment boundingRect]), (+[KWQLayoutInfo
+ drawString:atPoint:withFont:color:]), (+[KWQLayoutInfo
+ drawUnderlineForString:atPoint:withFont:color:]), (-[KWQLayoutInfo
+ initWithFont:]), (-[KWQLayoutInfo layoutManager]), (-[KWQLayoutInfo
+ textStorage]), (-[KWQLayoutInfo rectForString:]):
+ * src/kwq/KWQMetrics.h:
+ * src/kwq/KWQTextStorage.h:
+ * src/kwq/KWQTextStorage.mm: (-[KWQTextStorage getFragmentForString:]),
+ (-[KWQTextStorage addFragmentForString:]), (-[KWQTextStorage
+ initWithFontAttribute:]), (-[KWQTextStorage dealloc]), (-[KWQTextStorage
+ length]), (-[KWQTextStorage setAttributes:]), (-[KWQTextStorage setString:]),
+ (-[KWQTextStorage string]):
+
2002-03-13 Kenneth Kocienda <kocienda at apple.com>
Updated for new didRedirectToURL callback. This is a partial fix for this bug:
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 9f89e9f..dfadab2 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,22 @@
+2002-03-13 Richard Williamson <rjw at apple.com>
+
+ Re-worked fragment cache to minimize memory usage.
+
+ * src/kwq/KWQFontMetrics.mm: (-[KWQLayoutFragment glyphRange]),
+ (-[KWQLayoutFragment setGlyphRangeLength:]), (-[KWQLayoutFragment
+ setBoundingRectSize:]), (-[KWQLayoutFragment boundingRect]), (+[KWQLayoutInfo
+ drawString:atPoint:withFont:color:]), (+[KWQLayoutInfo
+ drawUnderlineForString:atPoint:withFont:color:]), (-[KWQLayoutInfo
+ initWithFont:]), (-[KWQLayoutInfo layoutManager]), (-[KWQLayoutInfo
+ textStorage]), (-[KWQLayoutInfo rectForString:]):
+ * src/kwq/KWQMetrics.h:
+ * src/kwq/KWQTextStorage.h:
+ * src/kwq/KWQTextStorage.mm: (-[KWQTextStorage getFragmentForString:]),
+ (-[KWQTextStorage addFragmentForString:]), (-[KWQTextStorage
+ initWithFontAttribute:]), (-[KWQTextStorage dealloc]), (-[KWQTextStorage
+ length]), (-[KWQTextStorage setAttributes:]), (-[KWQTextStorage setString:]),
+ (-[KWQTextStorage string]):
+
2002-03-13 Kenneth Kocienda <kocienda at apple.com>
Updated for new didRedirectToURL callback. This is a partial fix for this bug:
diff --git a/WebCore/kwq/KWQFontMetrics.mm b/WebCore/kwq/KWQFontMetrics.mm
index e64bbc0..623666f 100644
--- a/WebCore/kwq/KWQFontMetrics.mm
+++ b/WebCore/kwq/KWQFontMetrics.mm
@@ -39,44 +39,38 @@ const float LargeNumberForText = 1.0e7;
@implementation KWQLayoutFragment
-- initWithString: (NSString *)str attributes: (NSDictionary *)attrs
+- (NSRange)glyphRange
{
- [super init];
-
- textStorage = [[KWQTextStorage alloc] initWithString:str attributes: attrs];
- //textContainer = [[KWQTextContainer alloc] initWithContainerSize:NSMakeSize(LargeNumberForText, LargeNumberForText)];
- layoutManager = [[NSLayoutManager alloc] init];
-
- [layoutManager addTextContainer: [KWQTextContainer sharedInstance]];
- [textStorage addLayoutManager: layoutManager];
-
- //[textContainer setLineFragmentPadding:0.0f];
-
- cachedRect = NO;
+ NSRange glyphRange;
+
+ glyphRange.location = 0;
+ glyphRange.length = glyphRangeLength;
+
+ return glyphRange;
+}
-#ifdef _DEBUG_LAYOUT_FRAGMENT
- _accessCount = 0;
-#endif
+- (void)setGlyphRangeLength: (unsigned int)l
+{
+ glyphRangeLength = l;
+}
- return self;
+- (void)setBoundingRectSize: (NSSize)s
+{
+ boundingRectSize = s;
}
- (NSRect)boundingRect
{
- if (!cachedRect){
- unsigned numberOfGlyphs = [layoutManager numberOfGlyphs];
- boundingRect = [layoutManager boundingRectForGlyphRange: NSMakeRange (0, numberOfGlyphs) inTextContainer: [KWQTextContainer sharedInstance]];
- cachedRect = YES;
- }
-#ifdef _DEBUG_LAYOUT_FRAGMENT
- _accessCount++;
-#endif
+ NSRect boundingRect;
+
+ boundingRect.origin.x = 0;
+ boundingRect.origin.y = 0;
+ boundingRect.size = boundingRectSize;
+
return boundingRect;
}
#ifdef _DEBUG_LAYOUT_FRAGMENT
-- (int)_accessCount { return _accessCount; }
-
- (NSComparisonResult)compare: (id)val
{
if ([val _accessCount] > _accessCount)
@@ -88,13 +82,6 @@ const float LargeNumberForText = 1.0e7;
#endif
-- (void)dealloc
-{
- [textStorage release];
- //[textContainer release];
- [layoutManager release];
- [super dealloc];
-}
@end
@@ -107,28 +94,36 @@ static NSMutableDictionary *metricsCache = nil;
+ (void)drawString: (NSString *)string atPoint: (NSPoint)p withFont: (NSFont *)font color: (NSColor *)color
{
- KWQLayoutInfo *metricsCache = [KWQLayoutInfo getMetricsForFont: font];
- NSLayoutManager *layoutManager = [metricsCache layoutManagerForString: string];
- if (layoutManager != nil){
- unsigned numberOfGlyphs = [layoutManager numberOfGlyphs];
- [metricsCache setColor: color];
- [metricsCache setFont: font];
- [KWQTextStorage setString: string attributes: [metricsCache attributes]];
- [layoutManager drawGlyphsForGlyphRange:NSMakeRange (0, numberOfGlyphs) atPoint:p];
+ KWQLayoutInfo *layoutInfo = [KWQLayoutInfo getMetricsForFont: font];
+ NSLayoutManager *manager = [layoutInfo layoutManager];
+ KWQTextStorage *storage = [layoutInfo textStorage];
+
+ if (manager != nil){
+ KWQLayoutFragment *frag = [storage getFragmentForString: (NSString *)string];
+
+ [layoutInfo setColor: color];
+ [layoutInfo setFont: font];
+ [[layoutInfo textStorage] setAttributes: [layoutInfo attributes]];
+ [[layoutInfo textStorage] setString: string];
+ [manager drawGlyphsForGlyphRange:[frag glyphRange] atPoint:p];
}
}
+ (void)drawUnderlineForString: (NSString *)string atPoint: (NSPoint)p withFont: (NSFont *)font color: (NSColor *)color
{
- KWQLayoutInfo *metricsCache = [KWQLayoutInfo getMetricsForFont: font];
- NSLayoutManager *layoutManager = [metricsCache layoutManagerForString: string];
- if (layoutManager != nil){
- unsigned numberOfGlyphs = [layoutManager numberOfGlyphs];
- [metricsCache setColor: color];
- [metricsCache setFont: font];
- [KWQTextStorage setString: string attributes: [metricsCache attributes]];
- NSRect lineRect = [layoutManager lineFragmentRectForGlyphAtIndex: 0 effectiveRange: 0];
- [layoutManager underlineGlyphRange:NSMakeRange (0, numberOfGlyphs) underlineType:NSSingleUnderlineStyle lineFragmentRect:lineRect lineFragmentGlyphRange:NSMakeRange (0, numberOfGlyphs) containerOrigin:p];
+ KWQLayoutInfo *layoutInfo = [KWQLayoutInfo getMetricsForFont: font];
+ NSLayoutManager *manager = [layoutInfo layoutManager];
+ KWQTextStorage *storage = [layoutInfo textStorage];
+
+ if (manager != nil){
+ KWQLayoutFragment *frag = [storage getFragmentForString: (NSString *)string];
+
+ [layoutInfo setColor: color];
+ [layoutInfo setFont: font];
+ [[layoutInfo textStorage] setAttributes: [layoutInfo attributes]];
+ [[layoutInfo textStorage] setString: string];
+ NSRect lineRect = [manager lineFragmentRectForGlyphAtIndex: 0 effectiveRange: 0];
+ [manager underlineGlyphRange:[frag glyphRange] underlineType:NSSingleUnderlineStyle lineFragmentRect:lineRect lineFragmentGlyphRange:[frag glyphRange] containerOrigin:p];
}
}
@@ -205,48 +200,44 @@ static NSMutableDictionary *metricsCache = nil;
{
[super init];
attributes = [[NSMutableDictionary dictionaryWithObjectsAndKeys:aFont, NSFontAttributeName, nil] retain];
+
+ textStorage = [[KWQTextStorage alloc] initWithFontAttribute: attributes];
+ layoutManager = [[NSLayoutManager alloc] init];
+
+ [layoutManager addTextContainer: [KWQTextContainer sharedInstance]];
+ [textStorage addLayoutManager: layoutManager];
+
return self;
}
-- (NSLayoutManager *)layoutManagerForString: (NSString *)string
+- (NSLayoutManager *)layoutManager
{
- KWQLayoutFragment *cachedValue;
-
- if (fragmentCache == nil){
- fragmentCache = [[NSMutableDictionary alloc] init];
- }
+ return layoutManager;
+}
- cachedValue = [fragmentCache objectForKey: string];
- if (cachedValue == nil){
- return nil;
- }
- return cachedValue->layoutManager;
+- (KWQTextStorage *)textStorage
+{
+ return textStorage;
}
+
- (NSRect)rectForString:(NSString *)string
{
KWQLayoutFragment *cachedFragment, *fragment;
- if (fragmentCache == nil){
- fragmentCache = [[NSMutableDictionary alloc] init];
- }
-
- cachedFragment = [fragmentCache objectForKey: string];
+ cachedFragment = [textStorage getFragmentForString: string];
if (cachedFragment != nil){
-#ifdef _DEBUG_LAYOUT_FRAGMENT
- cachedFragment->_accessCount++;
-#endif
- return cachedFragment->boundingRect;
+ return [cachedFragment boundingRect];
}
- fragment = [[KWQLayoutFragment alloc] initWithString: string attributes: attributes];
- [fragmentCache setObject: fragment forKey: string];
-
+ fragment = [textStorage addFragmentForString: string];
+
return [fragment boundingRect];
}
-
+
+
- (void)setColor: (NSColor *)color
{
[attributes setObject: color forKey: NSForegroundColorAttributeName];
diff --git a/WebCore/kwq/KWQMetrics.h b/WebCore/kwq/KWQMetrics.h
index ba82b12..5f7ebef 100644
--- a/WebCore/kwq/KWQMetrics.h
+++ b/WebCore/kwq/KWQMetrics.h
@@ -27,12 +27,13 @@
#import <Cocoa/Cocoa.h>
-#define _DEBUG_LAYOUT_FRAGMENT
+ at class KWQTextStorage;
@interface KWQLayoutInfo : NSObject
{
NSMutableDictionary *attributes;
- NSMutableDictionary *fragmentCache;
+ NSLayoutManager *layoutManager;
+ KWQTextStorage *textStorage;
}
+ (void)drawString: (NSString *)string atPoint: (NSPoint)p withFont: (NSFont *)font color: (NSColor *)color;
@@ -41,34 +42,24 @@
+ (void)setMetric: (KWQLayoutInfo *)info forFont: (NSFont *)aFont;
- initWithFont: (NSFont *)aFont;
- (NSRect)rectForString:(NSString *)string;
-- (NSLayoutManager *)layoutManagerForString: (NSString *)string;
+- (NSLayoutManager *)layoutManager;
+- (KWQTextStorage *)textStorage;
- (void)setColor: (NSColor *)color;
- (void)setFont: (NSFont *)aFont;
- (NSDictionary *)attributes;
-#ifdef _DEBUG_LAYOUT_FRAGMENT
-- (NSDictionary *)_fragmentCache;
-#endif
@end
@interface KWQLayoutFragment : NSObject
{
- NSTextStorage *textStorage;
- NSTextContainer *textContainer;
- NSLayoutManager *layoutManager;
- NSRect boundingRect;
-#ifdef _DEBUG_LAYOUT_FRAGMENT
- int _accessCount;
-#endif
- BOOL cachedRect;
+ NSSize boundingRectSize; // Is origin always zero? Only need size.
+ unsigned int glyphRangeLength; // Is location always zero? Only need length.
}
-- initWithString: (NSString *)storage attributes: (NSDictionary *)attrs;
-- (NSRect)boundingRect;
-- (void)dealloc;
-#ifdef _DEBUG_LAYOUT_FRAGMENT
-- (int)_accessCount;
-#endif
+- (void)setGlyphRangeLength: (unsigned int)l;
+- (NSRange)glyphRange;
+- (void)setBoundingRectSize: (NSSize)s;
+- (NSRect)boundingRect;
@end
diff --git a/WebCore/kwq/KWQTextStorage.h b/WebCore/kwq/KWQTextStorage.h
index 2632153..0d8da50 100644
--- a/WebCore/kwq/KWQTextStorage.h
+++ b/WebCore/kwq/KWQTextStorage.h
@@ -22,18 +22,27 @@
* (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 <Cocoa/Cocoa.h>
#include <kwqdebug.h>
+#import <KWQMetrics.h>
@interface KWQTextStorage : NSTextStorage
{
- NSString *attrString;
NSDictionary *attributes;
+ NSString *string;
+ int stringCapacity;
+ NSMutableDictionary *fragmentCache;
NSLayoutManager *_layoutManager;
}
-+ (void)setString:(NSString *)str attributes:(NSDictionary *)attrs;
-- (void)setString: (NSString *)aString attributes: (NSDictionary *)at;
+- (id)initWithFontAttribute:(NSDictionary *)attrs;
+- (void)setAttributes: (NSDictionary *)at;
+
+- (KWQLayoutFragment *)getFragmentForString: (NSString *)string;
+- (KWQLayoutFragment *)addFragmentForString: (NSString *)string;
+
+- (void)setString: (NSString *)dString;
@end
diff --git a/WebCore/kwq/KWQTextStorage.mm b/WebCore/kwq/KWQTextStorage.mm
index 12efc33..22b70eb 100644
--- a/WebCore/kwq/KWQTextStorage.mm
+++ b/WebCore/kwq/KWQTextStorage.mm
@@ -28,6 +28,7 @@
#include <kwqdebug.h>
#import <KWQTextStorage.h>
+#import <KWQTextContainer.h>
/*
This class is a dumb text storage implementation. It is optimized for speed,
@@ -40,31 +41,59 @@
@implementation KWQTextStorage
-static KWQTextStorage *sharedInstance = nil;
-
-+ (KWQTextStorage *)sharedInstance
+- (KWQLayoutFragment *)getFragmentForString: (NSString *)fragString
{
- if (sharedInstance == nil)
- sharedInstance = [[KWQTextStorage alloc] init];
- return sharedInstance;
+ return [fragmentCache objectForKey: fragString];
}
-+ (void)setString:(NSString *)str attributes:(NSDictionary *)attrs
+- (KWQLayoutFragment *)addFragmentForString: (NSString *)fragString
{
- [[KWQTextStorage sharedInstance] setString: str attributes: attrs];
+ KWQLayoutFragment *fragment;
+
+ if (fragmentCache == nil)
+ fragmentCache = [[NSMutableDictionary alloc] init];
+
+ int fragStringLength = [fragString length];
+
+ fragment = [[KWQLayoutFragment alloc] init];
+
+ [fragmentCache setObject: fragment forKey: fragString];
+
+ [self setString: fragString];
+
+ NSRange range = NSMakeRange (0, fragStringLength);
+ NSRange glyphRange = [_layoutManager glyphRangeForCharacterRange:range actualCharacterRange:nil];
+
+ if (glyphRange.location != 0){
+ [NSException raise:@"OPTIMIZATION ASSUMPTION VIOLATED" format:@"glyphRange.location != 0"];
+ }
+
+ [fragment setGlyphRangeLength: glyphRange.length];
+
+ NSRect boundingRect = [_layoutManager boundingRectForGlyphRange: glyphRange inTextContainer: [KWQTextContainer sharedInstance]];
+
+ if (boundingRect.origin.x != 0 || boundingRect.origin.y != 0){
+ [NSException raise:@"OPTIMIZATION ASSUMPTION VIOLATED" format:@"bounding rect origin not 0,0"];
+ }
+
+ [fragment setBoundingRectSize: boundingRect.size];
+
+ [fragment release];
+
+ return fragment;
}
-- (id)initWithString:(NSString *)str attributes:(NSDictionary *)attrs
+- (id)initWithFontAttribute:(NSDictionary *)attrs
{
- attrString = [str retain];
attributes = [attrs retain];
return self;
}
- (void)dealloc
{
+ [string release];
+ [fragmentCache release];
[attributes release];
- [attrString release];
[super dealloc];
}
@@ -101,26 +130,36 @@ static KWQTextStorage *sharedInstance = nil;
- (unsigned)length
{
- return [attrString length];
+ return [string length];
}
-- (void)setString: (NSString *)aString attributes: (NSDictionary *)at
+- (void)setAttributes: (NSDictionary *)at
{
- if (aString != attrString){
- [attrString release];
- attrString = [aString retain];
- }
-
if (at != attributes){
[attributes release];
attributes = [at retain];
}
}
+- (void)setString: (NSString *)newString
+{
+ if (newString != string){
+ int oldLength = [self length];
+ int newLength = [newString length];
+
+ [string release];
+ string = [newString retain];
+ [_layoutManager textStorage: self
+ edited: NSTextStorageEditedCharacters
+ range: NSMakeRange (0, newLength)
+ changeInLength: newLength - oldLength
+ invalidatedRange:NSMakeRange (0, newLength)];
+ }
+}
- (NSString *)string
{
- return attrString;
+ return string;
}
diff --git a/WebCore/src/kwq/KWQFontMetrics.mm b/WebCore/src/kwq/KWQFontMetrics.mm
index e64bbc0..623666f 100644
--- a/WebCore/src/kwq/KWQFontMetrics.mm
+++ b/WebCore/src/kwq/KWQFontMetrics.mm
@@ -39,44 +39,38 @@ const float LargeNumberForText = 1.0e7;
@implementation KWQLayoutFragment
-- initWithString: (NSString *)str attributes: (NSDictionary *)attrs
+- (NSRange)glyphRange
{
- [super init];
-
- textStorage = [[KWQTextStorage alloc] initWithString:str attributes: attrs];
- //textContainer = [[KWQTextContainer alloc] initWithContainerSize:NSMakeSize(LargeNumberForText, LargeNumberForText)];
- layoutManager = [[NSLayoutManager alloc] init];
-
- [layoutManager addTextContainer: [KWQTextContainer sharedInstance]];
- [textStorage addLayoutManager: layoutManager];
-
- //[textContainer setLineFragmentPadding:0.0f];
-
- cachedRect = NO;
+ NSRange glyphRange;
+
+ glyphRange.location = 0;
+ glyphRange.length = glyphRangeLength;
+
+ return glyphRange;
+}
-#ifdef _DEBUG_LAYOUT_FRAGMENT
- _accessCount = 0;
-#endif
+- (void)setGlyphRangeLength: (unsigned int)l
+{
+ glyphRangeLength = l;
+}
- return self;
+- (void)setBoundingRectSize: (NSSize)s
+{
+ boundingRectSize = s;
}
- (NSRect)boundingRect
{
- if (!cachedRect){
- unsigned numberOfGlyphs = [layoutManager numberOfGlyphs];
- boundingRect = [layoutManager boundingRectForGlyphRange: NSMakeRange (0, numberOfGlyphs) inTextContainer: [KWQTextContainer sharedInstance]];
- cachedRect = YES;
- }
-#ifdef _DEBUG_LAYOUT_FRAGMENT
- _accessCount++;
-#endif
+ NSRect boundingRect;
+
+ boundingRect.origin.x = 0;
+ boundingRect.origin.y = 0;
+ boundingRect.size = boundingRectSize;
+
return boundingRect;
}
#ifdef _DEBUG_LAYOUT_FRAGMENT
-- (int)_accessCount { return _accessCount; }
-
- (NSComparisonResult)compare: (id)val
{
if ([val _accessCount] > _accessCount)
@@ -88,13 +82,6 @@ const float LargeNumberForText = 1.0e7;
#endif
-- (void)dealloc
-{
- [textStorage release];
- //[textContainer release];
- [layoutManager release];
- [super dealloc];
-}
@end
@@ -107,28 +94,36 @@ static NSMutableDictionary *metricsCache = nil;
+ (void)drawString: (NSString *)string atPoint: (NSPoint)p withFont: (NSFont *)font color: (NSColor *)color
{
- KWQLayoutInfo *metricsCache = [KWQLayoutInfo getMetricsForFont: font];
- NSLayoutManager *layoutManager = [metricsCache layoutManagerForString: string];
- if (layoutManager != nil){
- unsigned numberOfGlyphs = [layoutManager numberOfGlyphs];
- [metricsCache setColor: color];
- [metricsCache setFont: font];
- [KWQTextStorage setString: string attributes: [metricsCache attributes]];
- [layoutManager drawGlyphsForGlyphRange:NSMakeRange (0, numberOfGlyphs) atPoint:p];
+ KWQLayoutInfo *layoutInfo = [KWQLayoutInfo getMetricsForFont: font];
+ NSLayoutManager *manager = [layoutInfo layoutManager];
+ KWQTextStorage *storage = [layoutInfo textStorage];
+
+ if (manager != nil){
+ KWQLayoutFragment *frag = [storage getFragmentForString: (NSString *)string];
+
+ [layoutInfo setColor: color];
+ [layoutInfo setFont: font];
+ [[layoutInfo textStorage] setAttributes: [layoutInfo attributes]];
+ [[layoutInfo textStorage] setString: string];
+ [manager drawGlyphsForGlyphRange:[frag glyphRange] atPoint:p];
}
}
+ (void)drawUnderlineForString: (NSString *)string atPoint: (NSPoint)p withFont: (NSFont *)font color: (NSColor *)color
{
- KWQLayoutInfo *metricsCache = [KWQLayoutInfo getMetricsForFont: font];
- NSLayoutManager *layoutManager = [metricsCache layoutManagerForString: string];
- if (layoutManager != nil){
- unsigned numberOfGlyphs = [layoutManager numberOfGlyphs];
- [metricsCache setColor: color];
- [metricsCache setFont: font];
- [KWQTextStorage setString: string attributes: [metricsCache attributes]];
- NSRect lineRect = [layoutManager lineFragmentRectForGlyphAtIndex: 0 effectiveRange: 0];
- [layoutManager underlineGlyphRange:NSMakeRange (0, numberOfGlyphs) underlineType:NSSingleUnderlineStyle lineFragmentRect:lineRect lineFragmentGlyphRange:NSMakeRange (0, numberOfGlyphs) containerOrigin:p];
+ KWQLayoutInfo *layoutInfo = [KWQLayoutInfo getMetricsForFont: font];
+ NSLayoutManager *manager = [layoutInfo layoutManager];
+ KWQTextStorage *storage = [layoutInfo textStorage];
+
+ if (manager != nil){
+ KWQLayoutFragment *frag = [storage getFragmentForString: (NSString *)string];
+
+ [layoutInfo setColor: color];
+ [layoutInfo setFont: font];
+ [[layoutInfo textStorage] setAttributes: [layoutInfo attributes]];
+ [[layoutInfo textStorage] setString: string];
+ NSRect lineRect = [manager lineFragmentRectForGlyphAtIndex: 0 effectiveRange: 0];
+ [manager underlineGlyphRange:[frag glyphRange] underlineType:NSSingleUnderlineStyle lineFragmentRect:lineRect lineFragmentGlyphRange:[frag glyphRange] containerOrigin:p];
}
}
@@ -205,48 +200,44 @@ static NSMutableDictionary *metricsCache = nil;
{
[super init];
attributes = [[NSMutableDictionary dictionaryWithObjectsAndKeys:aFont, NSFontAttributeName, nil] retain];
+
+ textStorage = [[KWQTextStorage alloc] initWithFontAttribute: attributes];
+ layoutManager = [[NSLayoutManager alloc] init];
+
+ [layoutManager addTextContainer: [KWQTextContainer sharedInstance]];
+ [textStorage addLayoutManager: layoutManager];
+
return self;
}
-- (NSLayoutManager *)layoutManagerForString: (NSString *)string
+- (NSLayoutManager *)layoutManager
{
- KWQLayoutFragment *cachedValue;
-
- if (fragmentCache == nil){
- fragmentCache = [[NSMutableDictionary alloc] init];
- }
+ return layoutManager;
+}
- cachedValue = [fragmentCache objectForKey: string];
- if (cachedValue == nil){
- return nil;
- }
- return cachedValue->layoutManager;
+- (KWQTextStorage *)textStorage
+{
+ return textStorage;
}
+
- (NSRect)rectForString:(NSString *)string
{
KWQLayoutFragment *cachedFragment, *fragment;
- if (fragmentCache == nil){
- fragmentCache = [[NSMutableDictionary alloc] init];
- }
-
- cachedFragment = [fragmentCache objectForKey: string];
+ cachedFragment = [textStorage getFragmentForString: string];
if (cachedFragment != nil){
-#ifdef _DEBUG_LAYOUT_FRAGMENT
- cachedFragment->_accessCount++;
-#endif
- return cachedFragment->boundingRect;
+ return [cachedFragment boundingRect];
}
- fragment = [[KWQLayoutFragment alloc] initWithString: string attributes: attributes];
- [fragmentCache setObject: fragment forKey: string];
-
+ fragment = [textStorage addFragmentForString: string];
+
return [fragment boundingRect];
}
-
+
+
- (void)setColor: (NSColor *)color
{
[attributes setObject: color forKey: NSForegroundColorAttributeName];
diff --git a/WebCore/src/kwq/KWQMetrics.h b/WebCore/src/kwq/KWQMetrics.h
index ba82b12..5f7ebef 100644
--- a/WebCore/src/kwq/KWQMetrics.h
+++ b/WebCore/src/kwq/KWQMetrics.h
@@ -27,12 +27,13 @@
#import <Cocoa/Cocoa.h>
-#define _DEBUG_LAYOUT_FRAGMENT
+ at class KWQTextStorage;
@interface KWQLayoutInfo : NSObject
{
NSMutableDictionary *attributes;
- NSMutableDictionary *fragmentCache;
+ NSLayoutManager *layoutManager;
+ KWQTextStorage *textStorage;
}
+ (void)drawString: (NSString *)string atPoint: (NSPoint)p withFont: (NSFont *)font color: (NSColor *)color;
@@ -41,34 +42,24 @@
+ (void)setMetric: (KWQLayoutInfo *)info forFont: (NSFont *)aFont;
- initWithFont: (NSFont *)aFont;
- (NSRect)rectForString:(NSString *)string;
-- (NSLayoutManager *)layoutManagerForString: (NSString *)string;
+- (NSLayoutManager *)layoutManager;
+- (KWQTextStorage *)textStorage;
- (void)setColor: (NSColor *)color;
- (void)setFont: (NSFont *)aFont;
- (NSDictionary *)attributes;
-#ifdef _DEBUG_LAYOUT_FRAGMENT
-- (NSDictionary *)_fragmentCache;
-#endif
@end
@interface KWQLayoutFragment : NSObject
{
- NSTextStorage *textStorage;
- NSTextContainer *textContainer;
- NSLayoutManager *layoutManager;
- NSRect boundingRect;
-#ifdef _DEBUG_LAYOUT_FRAGMENT
- int _accessCount;
-#endif
- BOOL cachedRect;
+ NSSize boundingRectSize; // Is origin always zero? Only need size.
+ unsigned int glyphRangeLength; // Is location always zero? Only need length.
}
-- initWithString: (NSString *)storage attributes: (NSDictionary *)attrs;
-- (NSRect)boundingRect;
-- (void)dealloc;
-#ifdef _DEBUG_LAYOUT_FRAGMENT
-- (int)_accessCount;
-#endif
+- (void)setGlyphRangeLength: (unsigned int)l;
+- (NSRange)glyphRange;
+- (void)setBoundingRectSize: (NSSize)s;
+- (NSRect)boundingRect;
@end
diff --git a/WebCore/src/kwq/KWQTextStorage.h b/WebCore/src/kwq/KWQTextStorage.h
index 2632153..0d8da50 100644
--- a/WebCore/src/kwq/KWQTextStorage.h
+++ b/WebCore/src/kwq/KWQTextStorage.h
@@ -22,18 +22,27 @@
* (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 <Cocoa/Cocoa.h>
#include <kwqdebug.h>
+#import <KWQMetrics.h>
@interface KWQTextStorage : NSTextStorage
{
- NSString *attrString;
NSDictionary *attributes;
+ NSString *string;
+ int stringCapacity;
+ NSMutableDictionary *fragmentCache;
NSLayoutManager *_layoutManager;
}
-+ (void)setString:(NSString *)str attributes:(NSDictionary *)attrs;
-- (void)setString: (NSString *)aString attributes: (NSDictionary *)at;
+- (id)initWithFontAttribute:(NSDictionary *)attrs;
+- (void)setAttributes: (NSDictionary *)at;
+
+- (KWQLayoutFragment *)getFragmentForString: (NSString *)string;
+- (KWQLayoutFragment *)addFragmentForString: (NSString *)string;
+
+- (void)setString: (NSString *)dString;
@end
diff --git a/WebCore/src/kwq/KWQTextStorage.mm b/WebCore/src/kwq/KWQTextStorage.mm
index 12efc33..22b70eb 100644
--- a/WebCore/src/kwq/KWQTextStorage.mm
+++ b/WebCore/src/kwq/KWQTextStorage.mm
@@ -28,6 +28,7 @@
#include <kwqdebug.h>
#import <KWQTextStorage.h>
+#import <KWQTextContainer.h>
/*
This class is a dumb text storage implementation. It is optimized for speed,
@@ -40,31 +41,59 @@
@implementation KWQTextStorage
-static KWQTextStorage *sharedInstance = nil;
-
-+ (KWQTextStorage *)sharedInstance
+- (KWQLayoutFragment *)getFragmentForString: (NSString *)fragString
{
- if (sharedInstance == nil)
- sharedInstance = [[KWQTextStorage alloc] init];
- return sharedInstance;
+ return [fragmentCache objectForKey: fragString];
}
-+ (void)setString:(NSString *)str attributes:(NSDictionary *)attrs
+- (KWQLayoutFragment *)addFragmentForString: (NSString *)fragString
{
- [[KWQTextStorage sharedInstance] setString: str attributes: attrs];
+ KWQLayoutFragment *fragment;
+
+ if (fragmentCache == nil)
+ fragmentCache = [[NSMutableDictionary alloc] init];
+
+ int fragStringLength = [fragString length];
+
+ fragment = [[KWQLayoutFragment alloc] init];
+
+ [fragmentCache setObject: fragment forKey: fragString];
+
+ [self setString: fragString];
+
+ NSRange range = NSMakeRange (0, fragStringLength);
+ NSRange glyphRange = [_layoutManager glyphRangeForCharacterRange:range actualCharacterRange:nil];
+
+ if (glyphRange.location != 0){
+ [NSException raise:@"OPTIMIZATION ASSUMPTION VIOLATED" format:@"glyphRange.location != 0"];
+ }
+
+ [fragment setGlyphRangeLength: glyphRange.length];
+
+ NSRect boundingRect = [_layoutManager boundingRectForGlyphRange: glyphRange inTextContainer: [KWQTextContainer sharedInstance]];
+
+ if (boundingRect.origin.x != 0 || boundingRect.origin.y != 0){
+ [NSException raise:@"OPTIMIZATION ASSUMPTION VIOLATED" format:@"bounding rect origin not 0,0"];
+ }
+
+ [fragment setBoundingRectSize: boundingRect.size];
+
+ [fragment release];
+
+ return fragment;
}
-- (id)initWithString:(NSString *)str attributes:(NSDictionary *)attrs
+- (id)initWithFontAttribute:(NSDictionary *)attrs
{
- attrString = [str retain];
attributes = [attrs retain];
return self;
}
- (void)dealloc
{
+ [string release];
+ [fragmentCache release];
[attributes release];
- [attrString release];
[super dealloc];
}
@@ -101,26 +130,36 @@ static KWQTextStorage *sharedInstance = nil;
- (unsigned)length
{
- return [attrString length];
+ return [string length];
}
-- (void)setString: (NSString *)aString attributes: (NSDictionary *)at
+- (void)setAttributes: (NSDictionary *)at
{
- if (aString != attrString){
- [attrString release];
- attrString = [aString retain];
- }
-
if (at != attributes){
[attributes release];
attributes = [at retain];
}
}
+- (void)setString: (NSString *)newString
+{
+ if (newString != string){
+ int oldLength = [self length];
+ int newLength = [newString length];
+
+ [string release];
+ string = [newString retain];
+ [_layoutManager textStorage: self
+ edited: NSTextStorageEditedCharacters
+ range: NSMakeRange (0, newLength)
+ changeInLength: newLength - oldLength
+ invalidatedRange:NSMakeRange (0, newLength)];
+ }
+}
- (NSString *)string
{
- return attrString;
+ return string;
}
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list