[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