[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 06:10:41 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 458beceab617404dd35bf22716a4c8d66b5164a9
Author: darin <darin at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri May 3 18:36:23 2002 +0000

    WebCore:
    
    	* kwq/IFTextRenderer.h: Added.
    	* kwq/IFTextRendererFactory.h: Added.
    	* kwq/IFTextRendererFactory.m: Added.
    	These three are the new API for supplying text rendering machinery for WebCore.
    	The implementation is in WebKit. Later we might want to flesh out the default
    	implementation in WebCore so that it works OK by itself.
    
    	* khtml/rendering/font.cpp: (Font::width): Function is now "width" without
    	an underscore. We don't really need to hide the overload we added in this
    	case.
    
    	* kwq/qt/qfont.h: Simplify a lot. Doesn't hold an NSFont any more.
    	* kwq/KWQFont.mm:
    	(QFont::QFont): Eliminated the concept of "default font". Also, a QFont no
    	longer holds an NSFont object. That's handled inside IFTextRenderer machinery.
    	(QFont::~QFont): Simplify since we don't have an NSFont.
    	(QFont::setFamily): Simplify since we don't have an NSFont.
    	(QFont::setPixelSize): Simplify since we don't have an NSFont.
    	(QFont::setPixelSizeFloat): Simplify since we don't have an NSFont.
    	(QFont::setWeight): Simplify since we don't have an NSFont.
    	(QFont::weight): Fix a bug where it would return Normal for a QFont that was
    	both bold and italic.
    	(QFont::setItalic): Simplify since we don't have an NSFont.
    	(QFont::italic): Simplify since we have real "bool".
    	(QFont::bold): Simplify since we have real "bool".
    	(QFont::operator=): Simplify since we don't have an NSFont.
    	(QFont::operator==): Rewrite since we don't have an NSFont.
    
    	* kwq/qt/qfontmetrics.h: Simplify a little. The _width() method is now just an
    	overload of the width() method. The main change was removing the include of Cocoa.h.
    	* kwq/KWQFontMetrics.mm:
    	Move most of the code out of here into WebKit.
    	(QFontMetrics::ascent): Get it from the renderer.
    	(QFontMetrics::descent): Get it from the renderer.
    	(QFontMetrics::lineSpacing): Get it from the renderer.
    	(QFontMetrics::width): Get it from the renderer.
    	(QFontMetrics::boundingRect): Combine width and height that came from the renderer.
    	(QFontMetrics::size): Combine width and height that came from the renderer.
    
    	* kwq/Makefile.am: Add IFTextRendererFactory.m, remove KWQTextStorage.mm and KWQTextContainer.mm.
    	* kwq/KWQMetrics.h: Removed.
    	* kwq/KWQTextContainer.h: Removed.
    	* kwq/KWQTextContainer.mm: Removed.
    	* kwq/KWQTextStorage.h: Removed.
    	* kwq/KWQTextStorage.mm: Removed.
    
    	* kwq/KWQPainter.mm:
    	Move most of the code out of here into WebKit.
    	(QPainter::drawText): Call the renderer to do it.
    	(QPainter::drawUnderlineForText): Call the renderer to do it.
    
    	* libwebcore.exp: Export the IFTextRendererFactory class.
    
    WebKit:
    
    	* Misc.subproj/WebKitDebug.h: Add WEBKIT_LOG_MEMUSAGE, WEBKIT_LOG_FONTCACHE, and
    	WEBKIT_LOG_FONTCACHECHARMISS for font code moved here from WebCore.
    
    	* Resources/url_icon.tiff: New URL icon?
    
    	* WebCoreSupport.subproj/IFCachedTextRenderer.h: Added.
    	* WebCoreSupport.subproj/IFCachedTextRenderer.m: Added.
    	* WebCoreSupport.subproj/IFCachedTextRendererFactory.h: Added.
    	* WebCoreSupport.subproj/IFCachedTextRendererFactory.m: Added.
    	This has code moved here from WebCore.
    
    	* WebKit.pbproj/project.pbxproj: Add the new source files.
    
    	* Bookmarks.subproj/IFBookmarkLeaf.m:
    	(-[IFBookmarkLeaf setURLString:]): Use copy instead of initWithString.
    	* Bookmarks.subproj/IFBookmarkList.m:
    	(-[IFBookmarkList initWithTitle:image:group:]): Use copy instead of stringWithString.
    	(-[IFBookmarkList setTitle:]): Use copy instead of stringWithString.
    	* WebView.subproj/IFWebDataSourcePrivate.mm: (-[IFWebDataSource _setTitle:]):
    	Use mutableCopy instead of stringWithString.
    	* WebView.subproj/IFWebView.mm: (-[IFWebView initWithFrame:]): Use copy instead
    	of stringWithString.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@1092 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2002-12-03 b/WebCore/ChangeLog-2002-12-03
index 67cfa2d..2736300 100644
--- a/WebCore/ChangeLog-2002-12-03
+++ b/WebCore/ChangeLog-2002-12-03
@@ -1,3 +1,58 @@
+2002-05-03  Darin Adler  <darin at apple.com>
+
+	* kwq/IFTextRenderer.h: Added.
+	* kwq/IFTextRendererFactory.h: Added.
+	* kwq/IFTextRendererFactory.m: Added.
+	These three are the new API for supplying text rendering machinery for WebCore.
+	The implementation is in WebKit. Later we might want to flesh out the default
+	implementation in WebCore so that it works OK by itself.
+
+	* khtml/rendering/font.cpp: (Font::width): Function is now "width" without
+	an underscore. We don't really need to hide the overload we added in this
+	case.
+
+	* kwq/qt/qfont.h: Simplify a lot. Doesn't hold an NSFont any more.
+	* kwq/KWQFont.mm:
+	(QFont::QFont): Eliminated the concept of "default font". Also, a QFont no
+	longer holds an NSFont object. That's handled inside IFTextRenderer machinery.
+	(QFont::~QFont): Simplify since we don't have an NSFont.
+	(QFont::setFamily): Simplify since we don't have an NSFont.
+	(QFont::setPixelSize): Simplify since we don't have an NSFont.
+	(QFont::setPixelSizeFloat): Simplify since we don't have an NSFont.
+	(QFont::setWeight): Simplify since we don't have an NSFont.
+	(QFont::weight): Fix a bug where it would return Normal for a QFont that was
+	both bold and italic.
+	(QFont::setItalic): Simplify since we don't have an NSFont.
+	(QFont::italic): Simplify since we have real "bool".
+	(QFont::bold): Simplify since we have real "bool".
+	(QFont::operator=): Simplify since we don't have an NSFont.
+	(QFont::operator==): Rewrite since we don't have an NSFont.
+
+	* kwq/qt/qfontmetrics.h: Simplify a little. The _width() method is now just an
+	overload of the width() method. The main change was removing the include of Cocoa.h.
+	* kwq/KWQFontMetrics.mm:
+	Move most of the code out of here into WebKit.
+	(QFontMetrics::ascent): Get it from the renderer.
+	(QFontMetrics::descent): Get it from the renderer.
+	(QFontMetrics::lineSpacing): Get it from the renderer.
+	(QFontMetrics::width): Get it from the renderer.
+	(QFontMetrics::boundingRect): Combine width and height that came from the renderer.
+	(QFontMetrics::size): Combine width and height that came from the renderer.
+
+	* kwq/Makefile.am: Add IFTextRendererFactory.m, remove KWQTextStorage.mm and KWQTextContainer.mm.
+	* kwq/KWQMetrics.h: Removed.
+	* kwq/KWQTextContainer.h: Removed.
+	* kwq/KWQTextContainer.mm: Removed.
+	* kwq/KWQTextStorage.h: Removed.
+	* kwq/KWQTextStorage.mm: Removed.
+
+	* kwq/KWQPainter.mm:
+	Move most of the code out of here into WebKit.
+	(QPainter::drawText): Call the renderer to do it.
+	(QPainter::drawUnderlineForText): Call the renderer to do it.
+
+	* libwebcore.exp: Export the IFTextRendererFactory class.
+
 2002-04-26  Darin Adler  <darin at apple.com>
 
 	* kwq/make-mac-encodings.c: (main): One more place that needed a workaround
diff --git a/WebCore/ChangeLog-2003-10-25 b/WebCore/ChangeLog-2003-10-25
index 67cfa2d..2736300 100644
--- a/WebCore/ChangeLog-2003-10-25
+++ b/WebCore/ChangeLog-2003-10-25
@@ -1,3 +1,58 @@
+2002-05-03  Darin Adler  <darin at apple.com>
+
+	* kwq/IFTextRenderer.h: Added.
+	* kwq/IFTextRendererFactory.h: Added.
+	* kwq/IFTextRendererFactory.m: Added.
+	These three are the new API for supplying text rendering machinery for WebCore.
+	The implementation is in WebKit. Later we might want to flesh out the default
+	implementation in WebCore so that it works OK by itself.
+
+	* khtml/rendering/font.cpp: (Font::width): Function is now "width" without
+	an underscore. We don't really need to hide the overload we added in this
+	case.
+
+	* kwq/qt/qfont.h: Simplify a lot. Doesn't hold an NSFont any more.
+	* kwq/KWQFont.mm:
+	(QFont::QFont): Eliminated the concept of "default font". Also, a QFont no
+	longer holds an NSFont object. That's handled inside IFTextRenderer machinery.
+	(QFont::~QFont): Simplify since we don't have an NSFont.
+	(QFont::setFamily): Simplify since we don't have an NSFont.
+	(QFont::setPixelSize): Simplify since we don't have an NSFont.
+	(QFont::setPixelSizeFloat): Simplify since we don't have an NSFont.
+	(QFont::setWeight): Simplify since we don't have an NSFont.
+	(QFont::weight): Fix a bug where it would return Normal for a QFont that was
+	both bold and italic.
+	(QFont::setItalic): Simplify since we don't have an NSFont.
+	(QFont::italic): Simplify since we have real "bool".
+	(QFont::bold): Simplify since we have real "bool".
+	(QFont::operator=): Simplify since we don't have an NSFont.
+	(QFont::operator==): Rewrite since we don't have an NSFont.
+
+	* kwq/qt/qfontmetrics.h: Simplify a little. The _width() method is now just an
+	overload of the width() method. The main change was removing the include of Cocoa.h.
+	* kwq/KWQFontMetrics.mm:
+	Move most of the code out of here into WebKit.
+	(QFontMetrics::ascent): Get it from the renderer.
+	(QFontMetrics::descent): Get it from the renderer.
+	(QFontMetrics::lineSpacing): Get it from the renderer.
+	(QFontMetrics::width): Get it from the renderer.
+	(QFontMetrics::boundingRect): Combine width and height that came from the renderer.
+	(QFontMetrics::size): Combine width and height that came from the renderer.
+
+	* kwq/Makefile.am: Add IFTextRendererFactory.m, remove KWQTextStorage.mm and KWQTextContainer.mm.
+	* kwq/KWQMetrics.h: Removed.
+	* kwq/KWQTextContainer.h: Removed.
+	* kwq/KWQTextContainer.mm: Removed.
+	* kwq/KWQTextStorage.h: Removed.
+	* kwq/KWQTextStorage.mm: Removed.
+
+	* kwq/KWQPainter.mm:
+	Move most of the code out of here into WebKit.
+	(QPainter::drawText): Call the renderer to do it.
+	(QPainter::drawUnderlineForText): Call the renderer to do it.
+
+	* libwebcore.exp: Export the IFTextRendererFactory class.
+
 2002-04-26  Darin Adler  <darin at apple.com>
 
 	* kwq/make-mac-encodings.c: (main): One more place that needed a workaround
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 67cfa2d..2736300 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,58 @@
+2002-05-03  Darin Adler  <darin at apple.com>
+
+	* kwq/IFTextRenderer.h: Added.
+	* kwq/IFTextRendererFactory.h: Added.
+	* kwq/IFTextRendererFactory.m: Added.
+	These three are the new API for supplying text rendering machinery for WebCore.
+	The implementation is in WebKit. Later we might want to flesh out the default
+	implementation in WebCore so that it works OK by itself.
+
+	* khtml/rendering/font.cpp: (Font::width): Function is now "width" without
+	an underscore. We don't really need to hide the overload we added in this
+	case.
+
+	* kwq/qt/qfont.h: Simplify a lot. Doesn't hold an NSFont any more.
+	* kwq/KWQFont.mm:
+	(QFont::QFont): Eliminated the concept of "default font". Also, a QFont no
+	longer holds an NSFont object. That's handled inside IFTextRenderer machinery.
+	(QFont::~QFont): Simplify since we don't have an NSFont.
+	(QFont::setFamily): Simplify since we don't have an NSFont.
+	(QFont::setPixelSize): Simplify since we don't have an NSFont.
+	(QFont::setPixelSizeFloat): Simplify since we don't have an NSFont.
+	(QFont::setWeight): Simplify since we don't have an NSFont.
+	(QFont::weight): Fix a bug where it would return Normal for a QFont that was
+	both bold and italic.
+	(QFont::setItalic): Simplify since we don't have an NSFont.
+	(QFont::italic): Simplify since we have real "bool".
+	(QFont::bold): Simplify since we have real "bool".
+	(QFont::operator=): Simplify since we don't have an NSFont.
+	(QFont::operator==): Rewrite since we don't have an NSFont.
+
+	* kwq/qt/qfontmetrics.h: Simplify a little. The _width() method is now just an
+	overload of the width() method. The main change was removing the include of Cocoa.h.
+	* kwq/KWQFontMetrics.mm:
+	Move most of the code out of here into WebKit.
+	(QFontMetrics::ascent): Get it from the renderer.
+	(QFontMetrics::descent): Get it from the renderer.
+	(QFontMetrics::lineSpacing): Get it from the renderer.
+	(QFontMetrics::width): Get it from the renderer.
+	(QFontMetrics::boundingRect): Combine width and height that came from the renderer.
+	(QFontMetrics::size): Combine width and height that came from the renderer.
+
+	* kwq/Makefile.am: Add IFTextRendererFactory.m, remove KWQTextStorage.mm and KWQTextContainer.mm.
+	* kwq/KWQMetrics.h: Removed.
+	* kwq/KWQTextContainer.h: Removed.
+	* kwq/KWQTextContainer.mm: Removed.
+	* kwq/KWQTextStorage.h: Removed.
+	* kwq/KWQTextStorage.mm: Removed.
+
+	* kwq/KWQPainter.mm:
+	Move most of the code out of here into WebKit.
+	(QPainter::drawText): Call the renderer to do it.
+	(QPainter::drawUnderlineForText): Call the renderer to do it.
+
+	* libwebcore.exp: Export the IFTextRendererFactory class.
+
 2002-04-26  Darin Adler  <darin at apple.com>
 
 	* kwq/make-mac-encodings.c: (main): One more place that needed a workaround
diff --git a/WebCore/khtml/rendering/font.cpp b/WebCore/khtml/rendering/font.cpp
index 03b532b..46f3599 100644
--- a/WebCore/khtml/rendering/font.cpp
+++ b/WebCore/khtml/rendering/font.cpp
@@ -101,7 +101,7 @@ void Font::drawText( QPainter *p, int x, int y, QChar *str, int slen, int pos, i
 int Font::width( QChar *chs, int slen, int pos, int len ) const
 {
 #ifdef APPLE_CHANGES
-    return fm._width(chs + pos, kMin(len, slen - pos));
+    return fm.width(chs + pos, kMin(len, slen - pos));
 #else
     QString qstr = QConstString(chs+pos, slen-pos).string();
 
diff --git a/WebKit/Misc.subproj/IFException.m b/WebCore/kwq/IFTextRenderer.h
similarity index 67%
copy from WebKit/Misc.subproj/IFException.m
copy to WebCore/kwq/IFTextRenderer.h
index e1cfd38..23e681c 100644
--- a/WebKit/Misc.subproj/IFException.m
+++ b/WebCore/kwq/IFTextRenderer.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2001 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2002 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
@@ -22,7 +22,22 @@
  * (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>
 
-NSString * const IFMethodNotYetImplemented = @"IFMethodNotYetImplemented";
-NSString * const IFRuntimeError = @"IFRuntimeError";
+ at protocol IFTextRenderer <NSObject>
+
+- (int)widthForString:(NSString *)string;
+- (int)ascent;
+- (int)descent;
+- (int)lineSpacing;
+
+- (void)drawString:(NSString *)string atPoint:(NSPoint)point withColor:(NSColor *)color;
+- (void)drawUnderlineForString:(NSString *)string atPoint:(NSPoint)point withColor:(NSColor *)color;
+
+- (void)drawString:(NSString *)string inRect:(NSRect)rect withColor:(NSColor *)color paragraphStyle:(NSParagraphStyle *)style;
+
+// A way to bypass NSString for speed.
+- (int)widthForCharacters:(const UniChar *)characters length:(unsigned)length;
+
+ at end
diff --git a/WebCore/kwq/KWQTextContainer.h b/WebCore/kwq/IFTextRendererFactory.h
similarity index 80%
rename from WebCore/kwq/KWQTextContainer.h
rename to WebCore/kwq/IFTextRendererFactory.h
index 84693c5..a6e3210 100644
--- a/WebCore/kwq/KWQTextContainer.h
+++ b/WebCore/kwq/IFTextRendererFactory.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2001 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2002 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
@@ -23,12 +23,16 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#include <kwqdebug.h>
+#import <Cocoa/Cocoa.h>
 
+ at protocol IFTextRenderer;
 
- at interface KWQTextContainer : NSTextContainer
+ at interface IFTextRendererFactory : NSObject
 {
 }
-+ (KWQTextContainer *)sharedInstance;
+
++ (IFTextRendererFactory *)sharedFactory;
+- init;
+- (id <IFTextRenderer>)rendererWithFamily:(NSString *)family traits:(NSFontTraitMask)traits size:(float)size;
 
 @end
diff --git a/WebCore/kwq/KWQKJob.mm b/WebCore/kwq/IFTextRendererFactory.m
similarity index 71%
copy from WebCore/kwq/KWQKJob.mm
copy to WebCore/kwq/IFTextRendererFactory.m
index d19966e..78e438d 100644
--- a/WebCore/kwq/KWQKJob.mm
+++ b/WebCore/kwq/IFTextRendererFactory.m
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2001 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2002 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
@@ -23,25 +23,31 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#include <kwqdebug.h>
-#include <job.h>
+#import "IFTextRendererFactory.h"
+#import <kwqdebug.h>
 
-namespace KIO {
+ at implementation IFTextRendererFactory
 
-SimpleJob *http_update_cache(const KURL &, bool, time_t)
+static IFTextRendererFactory *sharedFactory;
+
++ (IFTextRendererFactory *)sharedFactory
 {
-    _logNotYetImplemented();
-    return 0L;
+    return sharedFactory;
 }
 
-TransferJob *get(const KURL &url, bool reload=false, bool showProgressInfo=true)
+- init
 {
-    TransferJob *result;
+    [super init];
     
-    result = new TransferJob(url, reload, showProgressInfo);
-
-    return result;
+    KWQ_ASSERT(!sharedFactory);
+    sharedFactory = [self retain];
+    
+    return self;
 }
 
-} // namespace KIO
+- (id <IFTextRenderer>)rendererWithFamily:(NSString *)family traits:(NSFontTraitMask)traits size:(float)size
+{
+    return nil;
+}
 
+ at end
diff --git a/WebCore/kwq/KWQFont.h b/WebCore/kwq/KWQFont.h
index 16164b8..ee46888 100644
--- a/WebCore/kwq/KWQFont.h
+++ b/WebCore/kwq/KWQFont.h
@@ -26,46 +26,27 @@
 #ifndef QFONT_H_
 #define QFONT_H_
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 class QString;
 class QPainter;
 
-#if (defined(__APPLE__) && defined(__OBJC__) && defined(__cplusplus))
-#define Fixed MacFixed
-#define Rect MacRect
-#define Boolean MacBoolean
-#import <Cocoa/Cocoa.h>
-#undef Fixed
-#undef Rect
-#undef Boolean
+#ifdef __OBJC__
+ at class NSString;
+#else
+typedef void NSString;
 #endif
 
-// class QFont =================================================================
-
 class QFont {
 public:
 
-    // typedefs ----------------------------------------------------------------
-    // enums -------------------------------------------------------------------
-
     enum CharSet { Latin1, Unicode };
     enum Weight { Normal = 50, Bold = 63 };
 
-    // constants ---------------------------------------------------------------
-    // static member functions -------------------------------------------------
-
-    // constructors, copy constructors, and destructors ------------------------
-
     QFont();
     QFont(const QFont &);
+    QFont &operator=(const QFont &);
 
     ~QFont();
 
-    // member functions --------------------------------------------------------
-
     int pixelSize() const;
     QString family() const;
     void setFamily(const QString &);
@@ -77,49 +58,18 @@ public:
     bool italic() const;
     bool bold() const;
 
-    // operators ---------------------------------------------------------------
-
-    QFont &operator=(const QFont &);
     bool operator==(const QFont &x) const;
-    bool operator!=(const QFont &x) const;
-
-#ifdef _KWQ_
-#if (defined(__APPLE__) && defined(__OBJC__) && defined(__cplusplus))
-    static NSFont *QFont::defaultNSFont();
-#endif
-#endif
-
-#if (defined(__APPLE__) && defined(__OBJC__) && defined(__cplusplus))
-        NSFont *getFont();
-#else
-        void *getFont();
-#endif
-
-// protected -------------------------------------------------------------------
-// private ---------------------------------------------------------------------
-private:
-#ifdef _KWQ_
-    void _initialize();
-    void _initializeWithFont(const QFont *);
-    void _free();
-#if (defined(__APPLE__) && defined(__OBJC__) && defined(__cplusplus))
-    void _setTrait (NSFontTraitMask mask);
-#endif
+    bool operator!=(const QFont &x) const { return !(*this == x); }
     
-#if (defined(__APPLE__) && defined(__OBJC__) && defined(__cplusplus))
-        NSFont *font;
-        NSString *_family;
-        int _trait;
-        float _size;
-#else
-        void *font;
-        void *_family;
-        int _trait;
-        float _size;
-#endif
+    NSString *getNSFamily() const { return _family; }
+    int getNSTraits() const { return _trait; }
+    float getNSSize() const { return _size; }
 
-#endif
+private:
+    NSString *_family;
+    int _trait;
+    float _size;
 
-}; // class QFont ==============================================================
+};
 
 #endif
diff --git a/WebCore/kwq/KWQFont.mm b/WebCore/kwq/KWQFont.mm
index 14056bf..c0daf4a 100644
--- a/WebCore/kwq/KWQFont.mm
+++ b/WebCore/kwq/KWQFont.mm
@@ -23,300 +23,113 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#include <qstring.h>
-#include <qfont.h>
-#include <kwqdebug.h>
+#import <qfont.h>
+#import <qstring.h>
 
-#import <Cocoa/Cocoa.h>
-
-/*
-    For this implementation Qt pixelSize is interpreted as Cocoa pointSize.
-*/
-
-static NSFont *defaultFont = 0;
-static NSString *defaultFontFamilyName;
-static float defaultFontSize;
-static int defaultFontTrait;
-
-static void
-loadDefaultFont()
-{
-    if (defaultFont)
-        return;
-    defaultFont = [[NSFont userFontOfSize: (float)12.0] retain];
-    defaultFontFamilyName = [[defaultFont familyName] retain];
-    defaultFontSize = [defaultFont pointSize];
-    defaultFontTrait = [[NSFontManager sharedFontManager] traitsOfFont:defaultFont] & (NSBoldFontMask | NSItalicFontMask);
-}
+#define Fixed MacFixed
+#define Rect MacRect
+#define Boolean MacBoolean
+#include <Cocoa/Cocoa.h>
+#undef Fixed
+#undef Rect
+#undef Boolean
 
 QFont::QFont()
+    : _family([@"" retain])
+    , _trait(0)
+    , _size(12.0)
 {
-    _initializeWithFont(0);
-}
-
-void QFont::_initializeWithFont(const QFont *withFont)
-{
-    if (withFont) {
-        font = [withFont->font retain];
-        _family = [withFont->_family retain];
-        _size = withFont->_size;
-        _trait = withFont->_trait;
-    } else {
-        loadDefaultFont();
-        font = [defaultFont retain];
-        _family = [defaultFontFamilyName retain];
-        _size = defaultFontSize;
-        _trait = defaultFontTrait;
-    }
 }
 
 QFont::QFont(const QFont &copyFrom)
+    : _family([copyFrom._family retain])
+    , _trait(copyFrom._trait)
+    , _size(copyFrom._size)
 {
-    _initializeWithFont(&copyFrom);
 }
 
 QFont::~QFont()
 {
-    _free();
-}
-
-void QFont::_free()
-{
     [_family release];
-    [font autorelease];
-    font = nil;
 }
 
 // member functions --------------------------------------------------------
 
-#ifdef DEBUG_GETFONT
-static int getFontCount = 0;
-#endif
-
-static NSMutableDictionary *fontCache = 0;
-
-// IFObjectHolder holds objects as keys in dictionaries without
-// copying.
- at interface IFFontCacheKey : NSObject
-{
-    NSString *string;
-    int trait;
-    float size;
-}
-
-- initWithString: (NSString *)str trait: (int)t size: (float)s;
-
- at end
-
- at implementation IFFontCacheKey
-
-- initWithString: (NSString *)str trait: (int)t size: (float)s;
-{
-    [super init];
-    string = [str retain];
-    trait = t;
-    size = s;
-    return self;
-}
-
-- (void)dealloc
-{
-    [string release];
-    [super dealloc];
-}
-
-- (id)copyWithZone:(NSZone *)zone
-{
-    return [self retain];
-}
-
-- (unsigned)hash
-{
-    return [string hash];
-}
-
-- (NSString *)string
-{
-    return string;
-}
-
-- (int)trait { return trait; }
-- (float)size { return size; }
-
-- (BOOL)isEqual:(id)o
-{
-    IFFontCacheKey *anObject = o;
-    if ([string isEqual: [anObject string]] && trait == [anObject trait] && size == [anObject size])
-        return YES;
-    return NO;
-}
-
- at end
-
-static NSArray *_availableFamiles = 0;
-
-NSFont *QFont::getFont()
-{
-    if (font == nil) {
-        NSString *fontKey;
-#ifdef DEBUG_GETFONT
-        getFontCount++;
-        fprintf (stdout, "getFountCount = %d, family = %s, traits = 0x%08x, size = %f\n", getFontCount, [_family lossyCString], _trait, _size);
-#endif
-        if (fontCache == nil){
-            fontCache = [[NSMutableDictionary alloc] init];
-        }
-        fontKey = [[IFFontCacheKey alloc] initWithString: _family trait: _trait size: _size];
-        font = [fontCache objectForKey:fontKey];
-        if (font == nil) {
-            font = [[NSFontManager sharedFontManager] fontWithFamily:_family traits:_trait weight:5 size:_size];
-            if (font == nil) {
-                if (_availableFamiles == 0)
-                    _availableFamiles = [[[NSFontManager sharedFontManager] availableFontFamilies] retain];
-                    
-                // FIXME:  For now do a simple case insensitive search for a matching font.
-                // The font manager requires exact name matches.  This will at least address the problem
-                // of matching arial to Arial, etc.
-                int i, count = [_availableFamiles count];
-                NSString *actualFamily;
-                for (i = 0; i < count; i++) {
-                    actualFamily = [_availableFamiles objectAtIndex: i];
-                    if ([_family caseInsensitiveCompare: actualFamily] == NSOrderedSame) {
-                        [_family release];
-                        _family = [actualFamily retain];
-                        font = [[NSFontManager sharedFontManager] fontWithFamily:_family traits:_trait weight:5 size:_size];
-                        break;
-                    }
-                }
-                if (font == nil) {
-                    KWQDEBUGLEVEL(KWQ_LOG_FONTCACHE, "unable to find font for family %s\n", [_family lossyCString]);
-                    loadDefaultFont();
-                    font = [[NSFontManager sharedFontManager] fontWithFamily:defaultFontFamilyName traits:_trait weight:5 size:_size];
-                }
-            }
-            [fontCache setObject: font forKey: fontKey];
-        }
-        [fontKey release];
-    }
-    return font;
-}
-        
-
 int QFont::pixelSize() const
 {
     return (int)_size;
 }
 
-
 QString QFont::family() const
 {
     return NSSTRING_TO_QSTRING(_family);
 }
 
-
 void QFont::setFamily(const QString &qfamilyName)
 {
     [_family release];
     _family = [_FAST_QSTRING_TO_NSSTRING(qfamilyName) retain];
-    [font autorelease];
-    font = nil;
 }
 
-
 void QFont::setPixelSize(int sz)
 {
-    setPixelSizeFloat(sz);
+    _size = sz;
 }
 
-
 void QFont::setPixelSizeFloat(float sz)
 {
-    if (sz != _size){
-        _size = sz;
-        [font autorelease];
-        font = nil;
-    }
+    _size = sz;
 }
 
-
 void QFont::setWeight(int weight)
 {
-    if (weight == Bold){
-        if (!bold()) {
-            [font autorelease];
-            font = nil;
-        }
+    if (weight == Bold) {
         _trait |= NSBoldFontMask;
     }
-    else if (weight == Normal){
-        if (bold()){
-            [font autorelease];
-            font = nil;
-        }
-        _trait = _trait & (~NSBoldFontMask);
+    else if (weight == Normal) {
+        _trait &= ~NSBoldFontMask;
     }
 }
 
-
 int QFont::weight() const
 {
-    if (_trait == NSBoldFontMask)
-        return Bold;
-    return Normal;
+    return bold() ? Bold : Normal;
 }
 
-
 bool QFont::setItalic(bool flag)
 {
-    if (flag){
-        if (!italic()){
-            [font autorelease];
-            font = nil;
-        }
+    if (flag) {
         _trait |= NSItalicFontMask;
-        return true;
     }
-    else{
-        if (italic()){
-            [font autorelease];
-            font = nil;
-        }
-        _trait = _trait & (~NSItalicFontMask);
-        return false;
+    else {
+        _trait &= ~NSItalicFontMask;
     }
+    return false;
 }
 
-
 bool QFont::italic() const
 {
-    return _trait & NSItalicFontMask ? TRUE : FALSE;
+    return _trait & NSItalicFontMask;
 }
 
-
 bool QFont::bold() const
 {
-    return _trait & NSBoldFontMask ? TRUE : FALSE;
+    return _trait & NSBoldFontMask;
 }
 
-
-// operators ---------------------------------------------------------------
-
 QFont &QFont::operator=(const QFont &assignFrom)
 {
-    _free();
-    _initializeWithFont(&assignFrom);
+    [assignFrom._family retain];
+    [_family release];
+    _family = assignFrom._family;
+    _trait = assignFrom._trait;
+    _size = assignFrom._size;
     return *this;
 }
 
-
 bool QFont::operator==(const QFont &compareFont) const
 {
-    // FIXME: This does not do the right thing when the font is nil
-    return [compareFont.font isEqual: font];
-}
-
-
-bool QFont::operator!=(const QFont &compareFont) const
-{
-    return !(operator==( compareFont ));
+    return [_family isEqual:compareFont._family]
+        && _trait == compareFont._trait
+        && _size == compareFont._size;
 }
diff --git a/WebCore/kwq/KWQFontMetrics.h b/WebCore/kwq/KWQFontMetrics.h
index 1858c15..1ca48a6 100644
--- a/WebCore/kwq/KWQFontMetrics.h
+++ b/WebCore/kwq/KWQFontMetrics.h
@@ -26,44 +26,22 @@
 #ifndef QFONTMETRICS_H_
 #define QFONTMETRICS_H_
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #include "qrect.h"
 #include "qsize.h"
 #include "qstring.h"
 #include "qfont.h"
 #include "qfontinfo.h"
 
-#if (defined(__APPLE__) && defined(__OBJC__) && defined(__cplusplus))
-#import <Cocoa/Cocoa.h>
-#endif
-
 class QFontMetricsPrivate;
 
-// class QFontMetrics ==========================================================
-
 class QFontMetrics {
 public:
 
-    // typedefs ----------------------------------------------------------------
-    // enums -------------------------------------------------------------------
-    // constants ---------------------------------------------------------------
-    // static member functions -------------------------------------------------
-
-    // constructors, copy constructors, and destructors ------------------------
-
     QFontMetrics();
     QFontMetrics(const QFont &);
     QFontMetrics(const QFontMetrics &);
-    ~QFontMetrics();
-
-    // operators ---------------------------------------------------------------
-
     QFontMetrics &operator=(const QFontMetrics &);
-
-    // member functions --------------------------------------------------------
+    ~QFontMetrics();
 
     int ascent() const;
     int descent() const;
@@ -73,10 +51,7 @@ 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;
-    int _width (const QChar *, int len) const;
-#endif
+    int width(const QChar *, int len) const;
 
     QRect boundingRect(const QString &, int len=-1) const;
     QRect boundingRect(QChar) const;
@@ -91,7 +66,7 @@ public:
 private:
     KWQRefPtr<QFontMetricsPrivate> data;
 
-}; // class QFontMetrics =======================================================
+};
 
 #endif
 
diff --git a/WebCore/kwq/KWQFontMetrics.mm b/WebCore/kwq/KWQFontMetrics.mm
index 3f52773..961c283 100644
--- a/WebCore/kwq/KWQFontMetrics.mm
+++ b/WebCore/kwq/KWQFontMetrics.mm
@@ -25,772 +25,46 @@
 
 #import <qfontmetrics.h>
 
-#import <math.h>
+#define Fixed MacFixed
+#define Rect MacRect
+#define Boolean MacBoolean
+#include <Cocoa/Cocoa.h>
+#undef Fixed
+#undef Rect
+#undef Boolean
+
+#import <qfont.h>
+#import <IFTextRendererFactory.h>
+#import <IFTextRenderer.h>
 #import <kwqdebug.h>
-#import <Cocoa/Cocoa.h>
 
-#define DIRECT_TO_CG
-
-#import <KWQMetrics.h>
-#import <KWQTextStorage.h>
-#import <KWQTextContainer.h>
-
-#define NON_BREAKING_SPACE 0xA0
-#define SPACE 0x20
-
-#define FLOOR_TO_INT(x) (int)(floor(x))
-//#define ROUND_TO_INT(x) (int)(((x) > (floor(x) + .5)) ? ceil(x) : floor(x))
-#define ROUND_TO_INT(x) (unsigned int)(x+.5)
-#define ROUND_TO_UINT(x) (unsigned int)(x+.5)
-#define ROUND_TO_USHORT(x) (unsigned int)(x+.5)
-#ifdef FOOOOFOOO
-static inline int ROUND_TO_INT (float x)
-{
-    int floored = (int)(x);
-    
-    if (((float)x) > ((float)(floored) + .5))
-        return (int)ceil(x);
-    return floored;
-}
-#endif
-
- at implementation KWQSmallLayoutFragment
-- (NSRange)glyphRange
-{
-    NSRange glyphRange;
-    
-    glyphRange.location = 0;
-    glyphRange.length = glyphRangeLength;
-    
-    return glyphRange;
-}
-
-- (void)setGlyphRange: (NSRange)r
-{
-    glyphRangeLength = r.length;
-}
-
-- (void)setBoundingRect: (NSRect)r
-{
-    width = (unsigned short)r.size.width;
-    height = (unsigned short)r.size.height;
-}
-
-- (NSRect)boundingRect
-{
-    NSRect boundingRect;
-    
-    boundingRect.origin.x = 0;
-    boundingRect.origin.y = 0;
-    boundingRect.size.width = (float)width;
-    boundingRect.size.height = (float)height;
-    
-#ifdef _DEBUG_LAYOUT_FRAGMENT
-    accessCount++;
-#endif
-
-    return boundingRect;
-}
-
-#ifdef _DEBUG_LAYOUT_FRAGMENT
-- (int)accessCount { return accessCount; }
-#endif
-
-#ifdef _DEBUG_LAYOUT_FRAGMENT
-- (NSComparisonResult)compare: (id)val
-{
-    if ([val accessCount] > accessCount)
-        return NSOrderedDescending;
-    else if ([val accessCount] < accessCount)
-        return NSOrderedAscending;
-    return NSOrderedSame;
-}
-
-#endif
-
- at end
-
- at implementation KWQLargeLayoutFragment
-- (NSRange)glyphRange
-{
-    return glyphRange;
-}
-
-- (void)setGlyphRange: (NSRange)r
-{
-    glyphRange = r;
-}
-
-- (void)setBoundingRect: (NSRect)r
-{
-    boundingRect = r;
-}
-
-- (NSRect)boundingRect
-{
-#ifdef _DEBUG_LAYOUT_FRAGMENT
-    accessCount++;
-#endif
-
-    return boundingRect;
-}
-
-#ifdef _DEBUG_LAYOUT_FRAGMENT
-- (int)accessCount { return accessCount; }
-#endif
-
-#ifdef _DEBUG_LAYOUT_FRAGMENT
-- (NSComparisonResult)compare: (id)val
-{
-    if ([val accessCount] > accessCount)
-        return NSOrderedDescending;
-    else if ([val accessCount] < accessCount)
-        return NSOrderedAscending;
-    return NSOrderedSame;
-}
-
-#endif
-
- at end
-
-static NSMutableDictionary *metricsCache = nil;
-
-/*
-    
-*/
- at implementation KWQLayoutInfo
-
-#ifdef DIRECT_TO_CG
-
-static void __IFInitATSGlyphVector(ATSGlyphVector *glyphVector, UInt32 numGlyphs) {
-    if (glyphVector->numAllocatedGlyphs == 0) {
-        ATSInitializeGlyphVector(numGlyphs, 0, glyphVector);
-
-//#warning Aki: 6/28/00 Need to reconsider these when we do bidi
-        ATSFree(glyphVector->levelIndexes);
-        glyphVector->levelIndexes = NULL;
-    } else if (glyphVector->numAllocatedGlyphs < numGlyphs) {
-        ATSGrowGlyphVector(numGlyphs - glyphVector->numAllocatedGlyphs, glyphVector);
-    }
-}
-
-static void __IFResetATSGlyphVector(ATSGlyphVector *glyphVector) {
-    ATSGlyphVector tmpVector = *glyphVector;
-
-    // Prevents glyph array & style settings from deallocated
-    glyphVector->firstRecord = NULL;
-    glyphVector->styleSettings = NULL;
-    glyphVector->levelIndexes = NULL;
-    ATSClearGlyphVector(glyphVector);
-
-    glyphVector->numAllocatedGlyphs = tmpVector.numAllocatedGlyphs;
-    glyphVector->recordSize = tmpVector.recordSize;
-    glyphVector->firstRecord = tmpVector.firstRecord;
-    glyphVector->styleSettings = tmpVector.styleSettings;
-    glyphVector->levelIndexes = tmpVector.levelIndexes;
-}
-
- at class NSCGSFont;
-
-static void __IFFillStyleWithAttributes(ATSUStyle style, NSFont *theFont) {
-    if (theFont) {
-        ATSUFontID fontId = (ATSUFontID)[theFont _atsFontID];
-        ATSUAttributeTag tag = kATSUFontTag;
-        ByteCount size = sizeof(ATSUFontID);
-        ATSUFontID *valueArray[1] = {&fontId};
-
-        if (fontId) {
-            if (ATSUSetAttributes(style, 1, &tag, &size, (void **)valueArray) != noErr)
-                [NSException raise:NSInternalInconsistencyException format:@"Failed to set font (%@) ATSUStyle 0x%X", theFont, style];
-
-#if 1
-//#warning Aki 7/20/2000 This code should be disabled once the brain dead bug 2499383 is fixed
-            {
-                ATSUFontFeatureType types[8] = {kDiacriticsType, kTypographicExtrasType, kFractionsType, kSmartSwashType, kSmartSwashType, kSmartSwashType, kSmartSwashType, kSmartSwashType};
-                ATSUFontFeatureSelector selectors[8] = {kDecomposeDiacriticsSelector, kSmartQuotesOffSelector, kNoFractionsSelector, kWordInitialSwashesOffSelector, kWordFinalSwashesOffSelector, kLineInitialSwashesOffSelector, kLineFinalSwashesOffSelector, kNonFinalSwashesOffSelector};
-                ATSUSetFontFeatures(style, 8, types, selectors);
-            }
-#endif
-        }
-    }
-}
-
-/* Convert non-breaking spaces into spaces. */
-static void ConvertCharactersToGlyphs(ATSStyleGroupPtr styleGroup, const UniChar *characters, int numCharacters, ATSGlyphVector *glyphs)
-{
-    int i;
-    UniChar localBuffer[LOCAL_GLYPH_BUFFER_SIZE];
-    UniChar *buffer = localBuffer;
-    
-    for (i = 0; i < numCharacters; i++) {
-        if (characters[i] == NON_BREAKING_SPACE) {
-            break;
-        }
-    }
-    
-    if (i < numCharacters) {
-        if (numCharacters > LOCAL_GLYPH_BUFFER_SIZE) {
-            buffer = (UniChar *)malloc(sizeof(UniChar) * numCharacters);
-        }
-        
-        for (i = 0; i < numCharacters; i++) {
-            if (characters[i] == NON_BREAKING_SPACE) {
-                buffer[i] = SPACE;
-            } else {
-                buffer[i] = characters[i];
-            }
-        }
-        
-        characters = buffer;
-    }
-    
-    ATSUConvertCharToGlyphs(styleGroup, characters, 0, numCharacters, 0, glyphs);
-    
-    if (buffer != localBuffer) {
-        free(buffer);
-    }
-}
-
-#endif
-
-- (void)drawString: (NSString *)string atPoint: (NSPoint)p withFont: (NSFont *)aFont color: (NSColor *)color
+struct QFontMetricsPrivate
 {
-#ifdef DIRECT_TO_CG
-    UniChar localBuffer[LOCAL_GLYPH_BUFFER_SIZE];
-    const UniChar *_internalBuffer = CFStringGetCharactersPtr ((CFStringRef)string);
-    const UniChar *internalBuffer;
-
-    if (!_internalBuffer){
-        // FIXME: Handle case where length > LOCAL_GLYPH_BUFFER_SIZE
-        CFStringGetCharacters((CFStringRef)string, CFRangeMake(0, CFStringGetLength((CFStringRef)string)), &localBuffer[0]);
-        internalBuffer = &localBuffer[0];
-    }
-    else
-        internalBuffer = _internalBuffer;
-
-    CGContextRef cgContext;
-
-    __IFInitATSGlyphVector(&_glyphVector, [string length]);
-
-    ConvertCharactersToGlyphs(_styleGroup, internalBuffer, [string length], &_glyphVector);
-
-    [color set];
-    [aFont set];
-    
-    if ([aFont glyphPacking] != NSNativeShortGlyphPacking &&
-        [aFont glyphPacking] != NSTwoByteGlyphPacking)
-        [NSException raise:NSInternalInconsistencyException format:@"%@: Don't know how to deal with font %@", self, [aFont displayName]];
-        
+    QFontMetricsPrivate(const QFont &font)
     {
-        int i, numGlyphs = _glyphVector.numGlyphs;
-        char localGlyphBuf[LOCAL_GLYPH_BUFFER_SIZE];
-        char *usedGlyphBuf, *glyphBufPtr, *glyphBuf = 0;
-        ATSLayoutRecord *glyphRecords = (ATSLayoutRecord *)_glyphVector.firstRecord;
-        
-        if (numGlyphs > LOCAL_GLYPH_BUFFER_SIZE/2)
-            usedGlyphBuf = glyphBufPtr = glyphBuf = (char *)malloc (numGlyphs * 2);
-        else
-            usedGlyphBuf = glyphBufPtr = &localGlyphBuf[0];
-            
-        for (i = 0; i < numGlyphs; i++){
-            *glyphBufPtr++ = (char)((glyphRecords->glyphID >> 8) & 0x00FF);
-            *glyphBufPtr++ = (char)(glyphRecords->glyphID & 0x00FF);
-            glyphRecords++;
-        }
-        cgContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
-        CGContextSetCharacterSpacing(cgContext, 0.0);
-        //CGContextShowGlyphsAtPoint (cgContext, p.x, p.y + lineHeight - 1 - ROUND_TO_INT(-[font descender]), (const short unsigned int *)usedGlyphBuf, numGlyphs);
-        CGContextShowGlyphsAtPoint (cgContext, p.x, p.y + [font defaultLineHeightForFont] - 1, (const short unsigned int *)usedGlyphBuf, numGlyphs);
-        
-        if (glyphBuf)
-            free (glyphBuf);
+        renderer = [[[IFTextRendererFactory sharedFactory] rendererWithFamily:font.getNSFamily() traits:font.getNSTraits() size:font.getNSSize()] retain];
     }
-
-    __IFResetATSGlyphVector(&_glyphVector);
-#else
-    id <KWQLayoutFragment> frag = [storage getFragmentForString: (NSString *)string];
-    NSLog (@"WARNING:  Unable to use CG for drawString:atPoint:withFont:color:\n");
-
-    [self setColor: color];
-    [textStorage setAttributes: [layoutInfo attributes]];
-    [textStorage setString: string];
-    [layoutManager drawGlyphsForGlyphRange:[frag glyphRange] atPoint:p];
-#endif
-}
-
-
-+ (void)drawString: (NSString *)string atPoint: (NSPoint)p withFont: (NSFont *)aFont color: (NSColor *)color
-{
-    KWQLayoutInfo *layoutInfo = [KWQLayoutInfo getMetricsForFont: aFont];
-    [layoutInfo drawString: string atPoint: p withFont: aFont color: color];
-}
-
-
-- (void)drawUnderlineForString: (NSString *)string atPoint: (NSPoint)p withFont: (NSFont *)aFont color: (NSColor *)color
-{
-#ifdef DIRECT_TO_CG
-    NSRect rect = [self rectForString: string];
-    NSGraphicsContext *graphicsContext = [NSGraphicsContext currentContext];
-    CGContextRef cgContext;
-    float lineWidth;
-    
-    [color set];
-
-    BOOL flag = [graphicsContext shouldAntialias];
-
-    [graphicsContext setShouldAntialias: NO];
-
-    cgContext = (CGContextRef)[graphicsContext graphicsPort];
-    lineWidth = 0.0;
-    if ([graphicsContext isDrawingToScreen] && lineWidth == 0.0) {
-        CGSize size = CGSizeApplyAffineTransform(CGSizeMake(1.0, 1.0), CGAffineTransformInvert(CGContextGetCTM(cgContext)));
-        lineWidth = size.width;
-    }
-    CGContextSetLineWidth(cgContext, lineWidth);
-    ///CGContextMoveToPoint(cgContext, p.x, p.y + lineHeight + 0.5 - ROUND_TO_INT(-[font descender]));
-    //CGContextAddLineToPoint(cgContext, p.x + rect.size.width, p.y + lineHeight + 0.5 - ROUND_TO_INT(-[font descender]));
-    CGContextMoveToPoint(cgContext, p.x, p.y + [font defaultLineHeightForFont] + 0.5);
-    CGContextAddLineToPoint(cgContext, p.x + rect.size.width, p.y + [font defaultLineHeightForFont] + 0.5);
-    CGContextStrokePath(cgContext);
-
-    [graphicsContext setShouldAntialias: flag];
-    
-#else
-    id <KWQLayoutFragment>frag = [storage getFragmentForString: (NSString *)string];
-
-    [self setColor: color];
-    [textStorage setAttributes: [self attributes]];
-    [textStorage setString: string];
-    NSRect lineRect = [self lineFragmentRectForGlyphAtIndex: 0 effectiveRange: 0];
-    [self underlineGlyphRange:[frag glyphRange] underlineType:NSSingleUnderlineStyle lineFragmentRect:lineRect lineFragmentGlyphRange:[frag glyphRange] containerOrigin:p];
-#endif
-}
-
-+ (void)drawUnderlineForString: (NSString *)string atPoint: (NSPoint)p withFont: (NSFont *)aFont color: (NSColor *)color
-{
-    KWQLayoutInfo *layoutInfo = [KWQLayoutInfo getMetricsForFont: aFont];
-    
-    [layoutInfo drawUnderlineForString: string atPoint: p withFont: aFont color: color];
-}
-
-
-#ifdef _DEBUG_LAYOUT_FRAGMENT
-+ (void)_dumpLayoutCache: (NSDictionary *)fragCache
-{
-    int i, count;
-    NSArray *stringKeys;
-    NSString *string;
-    id <KWQLayoutFragment>fragment;
-
-    if (fragCache == nil){
-        fprintf (stdout, "Fragment cache empty\n");
-        return;
-    }
-    fprintf (stdout, "  Hits   String\n");
-    
-    stringKeys = [fragCache keysSortedByValueUsingSelector:@selector(compare:)];
-    count = [stringKeys count];
-    for (i = 0; i < count; i++){
-        string = [stringKeys objectAtIndex: i];
-        fragment = [fragCache objectForKey: [stringKeys objectAtIndex: i]];
-        fprintf (stdout, "  %06d \"%s\"\n", [fragment accessCount], [string cString]);
-    }
-}
-
-+ (void)_dumpAllLayoutCaches
-{
-    int i, count;
-    NSFont *font;
-    NSArray *fontKeys;
-    KWQLayoutInfo *layoutInfo;
-    int totalObjects = 0;
-    
-    fontKeys = [metricsCache allKeys];
-    count = [fontKeys count];
-    for (i = 0; i < count; i++){
-        font = [fontKeys objectAtIndex: i];
-        layoutInfo = [metricsCache objectForKey: [fontKeys objectAtIndex: i]];
-        fprintf (stdout, "Cache information for font %s %f (%d objects)\n", [[font displayName] cString],[font pointSize], [[[layoutInfo textStorage] fragmentCache] count]);
-        [KWQLayoutInfo _dumpLayoutCache: [[layoutInfo textStorage] fragmentCache]];
-        totalObjects += [[[layoutInfo textStorage] fragmentCache] count];
-    }
-    fprintf (stdout, "Total cached objects %d\n", totalObjects);
-}
-
-#endif
-
-
-+ (KWQLayoutInfo *)getMetricsForFont: (NSFont *)aFont
-{
-    KWQLayoutInfo *info = (KWQLayoutInfo *)[metricsCache objectForKey: aFont];
-    if (info == nil){
-        info = [[KWQLayoutInfo alloc] initWithFont: aFont];
-        [KWQLayoutInfo setMetric: info forFont: aFont];
-        [info release];
-    }
-    return info;
-}
-
-
-+ (void)setMetric: (KWQLayoutInfo *)info forFont: (NSFont *)aFont
-{
-    if (metricsCache == nil)
-        metricsCache = [[NSMutableDictionary alloc] init];
-    [metricsCache setObject: info forKey: aFont];
-}
-
-
-- initWithFont: (NSFont *)aFont
-{
-    OSStatus errCode;
-
-    [super init];
-
-    font = [aFont retain];
-    lineHeight = ROUND_TO_INT([font ascender]) + ROUND_TO_INT(-[font descender]) + 1;
-
-#ifdef DIRECT_TO_CG
-    ATSUStyle style;
-    
-    if ((errCode = ATSUCreateStyle(&style)) != noErr)
-        [NSException raise:NSInternalInconsistencyException format:@"%@: Failed to alloc ATSUStyle %d", self, errCode];
-
-    __IFFillStyleWithAttributes(style, aFont);
-
-    if ((errCode = ATSUGetStyleGroup(style, &_styleGroup)) != noErr) {
-        [NSException raise:NSInternalInconsistencyException format:@"%@: Failed to create attribute group from ATSUStyle 0x%X %d", self, style, errCode];
-    }
-    
-    ATSUDisposeStyle(style);
-#else
-    textStorage = [[KWQTextStorage alloc] initWithFontAttribute: attributes];
-    layoutManager = [[NSLayoutManager alloc] init];
-
-    [layoutManager addTextContainer: [KWQTextContainer sharedInstance]];
-    [textStorage addLayoutManager: layoutManager];    
-
-    attributes = [[NSMutableDictionary dictionaryWithObjectsAndKeys:aFont, NSFontAttributeName, nil] retain];
-#endif
-    return self;
-}
-
-
-- (NSLayoutManager *)layoutManager
-{
-#ifdef DIRECT_TO_CG
-    return nil;
-#else
-    return layoutManager;
-#endif
-}
-
-
-- (KWQTextStorage *)textStorage
-{
-#ifdef DIRECT_TO_CG
-    return nil;
-#else
-    return textStorage;
-#endif
-}
-
-#define CONTEXT_DPI    (72.0)
-#define ScaleEmToUnits(X, U_PER_EM)    (X * ((1.0 * CONTEXT_DPI) / (CONTEXT_DPI * U_PER_EM)))
-#define ScaleUnitsToPoints(F, POINTS)  (F * POINTS)
-
-#ifdef DIRECT_TO_CG
-- (void)_initializeCaches
-{
-    unsigned int i, glyphsToCache;
-    int errorResult;
-    size_t numGlyphsInFont = CGFontGetNumberOfGlyphs([font _backingCGSFont]);
-    short unsigned int sequentialGlyphs[INITIAL_GLYPH_CACHE_MAX];
-    ATSLayoutRecord *glyphRecords;
-
-    KWQDEBUGLEVEL (KWQ_LOG_FONTCACHE, "Caching %s %.0f (%ld glyphs) ascent = %f, descent = %f, defaultLineHeightForFont = %f\n", [[font displayName] cString], [font pointSize], numGlyphsInFont, [font ascender], [font descender], [font defaultLineHeightForFont]); 
-
-    // Initially just cache the max of number of glyphs in font or
-    // INITIAL_GLYPH_CACHE_MAX.  Holes in the cache will be filled on demand
-    // in INCREMENTAL_GLYPH_CACHE_BLOCK chunks. 
-    if (numGlyphsInFont > INITIAL_GLYPH_CACHE_MAX)
-        glyphsToCache = INITIAL_GLYPH_CACHE_MAX;
-    else
-        glyphsToCache = numGlyphsInFont;
-    widthCacheSize = (int)numGlyphsInFont;
-    for (i = 0; i < glyphsToCache; i++)
-        sequentialGlyphs[i] = i;
-        
-    widthCache = (_IFGlyphWidth *)calloc (1, widthCacheSize * sizeof(_IFGlyphWidth));
-    
-    // Some glyphs can have zero width, so we have to use a non-zero value
-    // in empty slots to indicate they are uninitialized.
-    for (i = glyphsToCache; i < widthCacheSize; i++){
-        widthCache[i] = UNITIALIZED_GLYPH_WIDTH;
-    }
-    
-    CGContextRef cgContext;
-
-    cgContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
-    errorResult = CGFontGetGlyphScaledAdvances ([font _backingCGSFont], &sequentialGlyphs[0], glyphsToCache, widthCache, [font pointSize]);
-    if (errorResult == 0)
-        [NSException raise:NSInternalInconsistencyException format:@"Optimization assumption violation:  unable to cache glyph advances - for %@ %f", self, [font displayName], [font pointSize]];
-
-    unsigned int latinCount = LAST_CACHE_CHARACTER - FIRST_CACHE_CHARACTER + 1;
-    short unsigned int latinBuffer[LAST_CACHE_CHARACTER+1];
-    
-    for (i = FIRST_CACHE_CHARACTER; i <= LAST_CACHE_CHARACTER; i++){
-        latinBuffer[i] = i;
-    }
-
-    ATSGlyphVector latinGlyphVector;
-    ATSInitializeGlyphVector(latinCount, 0, &latinGlyphVector);
-    ConvertCharactersToGlyphs(_styleGroup, &latinBuffer[FIRST_CACHE_CHARACTER], latinCount, &latinGlyphVector);
-    if (latinGlyphVector.numGlyphs != latinCount)
-        [NSException raise:NSInternalInconsistencyException format:@"Optimization assumption violation:  ascii and glyphID count not equal - for %@ %f", self, [font displayName], [font pointSize]];
-        
-    unsigned int numGlyphs = latinGlyphVector.numGlyphs;
-    characterToGlyph = (ATSGlyphRef *)calloc (1, latinGlyphVector.numGlyphs * sizeof(ATSGlyphRef));
-    glyphRecords = (ATSLayoutRecord *)latinGlyphVector.firstRecord;
-    for (i = 0; i < numGlyphs; i++){
-        characterToGlyph[i] = glyphRecords[i].glyphID;
-    }
-    ATSClearGlyphVector(&latinGlyphVector);
-
-#define DEBUG_CACHE_SIZE
-#ifdef DEBUG_CACHE_SIZE
-    static int totalCacheSize = 0;
-    
-    totalCacheSize += widthCacheSize * sizeof(_IFGlyphWidth) + numGlyphs * sizeof(ATSGlyphRef) + sizeof(KWQLayoutInfo);
-    KWQDEBUGLEVEL (KWQ_LOG_MEMUSAGE, "memory usage in bytes:  widths = %ld, latin1 ext. character-to-glyph = %ld, total this cache = %ld, total all caches %d\n", widthCacheSize * sizeof(_IFGlyphWidth), numGlyphs * sizeof(ATSGlyphRef), widthCacheSize * sizeof(_IFGlyphWidth) + numGlyphs * sizeof(ATSGlyphRef) + sizeof(KWQLayoutInfo), totalCacheSize); 
-#endif
-}
-
-
-static NSRect _rectForString (KWQLayoutInfo *self, const UniChar *internalBuffer, unsigned int stringLength)
-{
-    float totalWidth = 0;
-    unsigned int i, index;
-    int glyphID;
-    ATSLayoutRecord *glyphRecords;
-    NSFont *font = [self font];
-    unsigned int numGlyphs;
-    _IFGlyphWidth *widthCache;
-    
-    ATSGlyphRef localCharacterToGlyph[LOCAL_GLYPH_BUFFER_SIZE];
-    ATSGlyphRef *usedCharacterToGlyph, *allocateCharacterToGlyph = 0;
-    
-    BOOL needCharToGlyphLookup = NO;
-
-
-    // Best case, and common case for latin1, performance will require two iterations over
-    // the internalBuffer.
-    // Pass 1 (on characters):  
-    //      Determine if we can use character-to-glyph map by comparing characters to cache
-    //      range.
-    // Pass 2 (on characters):  
-    //      Sum the widths using the character-to-glyph map and width cache.
-    
-    // FIXME:  For non-latin1 character sets we don't optimize.
-    // Worst case performance we must lookup the character-to-glyph map and lookup the glyph
-    // widths.
-    
-    if ([font glyphPacking] != NSNativeShortGlyphPacking &&
-        [font glyphPacking] != NSTwoByteGlyphPacking)
-	[NSException raise:NSInternalInconsistencyException format:@"%@: Don't know how to pack glyphs for font %@ %f", self, [font displayName], [font pointSize]];
-    
-    if (self->widthCache == 0)
-        [self _initializeCaches];
-    widthCache = self->widthCache;
-    
-    // Pass 1:
-    // Check if we can use the cached character-to-glyph map.  We only use the character-to-glyph map
-    // if ALL the characters in the string fall in the safe cache range.  This must be done
-    // to ensure that we don't match composable characters incorrectly.  This check could
-    // be smarter.  Also the character-to-glyph could be extended to support other ranges
-    // of unicode.  For now, we only optimize for latin1.
-    for (i = 0; i < stringLength; i++){
-        if (internalBuffer[i] < FIRST_CACHE_CHARACTER || internalBuffer[i] > LAST_CACHE_CHARACTER){
-            needCharToGlyphLookup = YES;
-            break;
-        }
-    }
-
-    // If we can't use the cached map, then calculate a map for this string.   Expensive.
-    if (needCharToGlyphLookup){
-        
-        KWQDEBUGLEVEL(KWQ_LOG_FONTCACHECHARMISS, "character-to-glyph cache miss for character 0x%04x in %s, %.0f\n", internalBuffer[i], [[font displayName] lossyCString], [font pointSize]);
-        __IFInitATSGlyphVector(&self->_glyphVector, stringLength);
-        ConvertCharactersToGlyphs(self->_styleGroup, internalBuffer, stringLength, &self->_glyphVector);
-        glyphRecords = (ATSLayoutRecord *)self->_glyphVector.firstRecord;
-        numGlyphs = self->_glyphVector.numGlyphs;
-
-        if (numGlyphs > LOCAL_GLYPH_BUFFER_SIZE)
-            usedCharacterToGlyph = allocateCharacterToGlyph = (ATSGlyphRef *)calloc (1, numGlyphs * sizeof(ATSGlyphRef));
-        else
-            usedCharacterToGlyph = &localCharacterToGlyph[0];
-            
-        for (i = 0; i < numGlyphs; i++){
-            glyphID = glyphRecords[i].glyphID;
-            usedCharacterToGlyph[i] = glyphID;
-            
-            // Fill the block of glyphs for the glyph needed. If we're going to incur the overhead
-            // of calling into CG, we may as well get a block of scaled glyph advances.
-            if (self->widthCache[glyphID] == UNITIALIZED_GLYPH_WIDTH){
-                short unsigned int sequentialGlyphs[INCREMENTAL_GLYPH_CACHE_BLOCK];
-                unsigned int blockStart, blockEnd, blockID;
-                int errorResult;
-                
-                blockStart = (glyphID / INCREMENTAL_GLYPH_CACHE_BLOCK) * INCREMENTAL_GLYPH_CACHE_BLOCK;
-                blockEnd = blockStart + INCREMENTAL_GLYPH_CACHE_BLOCK;
-                if (blockEnd > self->widthCacheSize)
-                    blockEnd = self->widthCacheSize;
-                KWQDEBUGLEVEL (KWQ_LOG_FONTCACHE, "width cache miss for glyph 0x%04x in %s, %.0f, filling block 0x%04x to 0x%04x\n", glyphID, [[font displayName] cString], [font pointSize], blockStart, blockEnd);
-                for (blockID = blockStart; blockID < blockEnd; blockID++)
-                    sequentialGlyphs[blockID-blockStart] = blockID;
-
-                errorResult = CGFontGetGlyphScaledAdvances ([font _backingCGSFont], &sequentialGlyphs[0], blockEnd-blockStart, &widthCache[blockStart], [font pointSize]);
-                if (errorResult == 0)
-                    [NSException raise:NSInternalInconsistencyException format:@"Optimization assumption violation:  unable to cache glyph widths - for %@ %f", self, [font displayName], [font pointSize]];
-            }
-        }
-
-        __IFResetATSGlyphVector(&self->_glyphVector);
-    }
-    else {
-        numGlyphs = stringLength;
-        usedCharacterToGlyph = self->characterToGlyph;
-    }
-    
-    // Pass 2:
-    // Sum the widths for all the glyphs.
-    if (needCharToGlyphLookup){
-        for (i = 0; i < numGlyphs; i++){
-            totalWidth += widthCache[usedCharacterToGlyph[i]];
-        }
-        
-        if (allocateCharacterToGlyph)
-            free (allocateCharacterToGlyph);
-    }
-    else {
-        for (i = 0; i < numGlyphs; i++){
-            index = internalBuffer[i]-FIRST_CACHE_CHARACTER;
-            totalWidth += widthCache[usedCharacterToGlyph[index]];
-        }
-    }
-    
-    return NSMakeRect (0,0,totalWidth, (float)self->lineHeight);
-}
-#endif
-
-
-- (NSRect)rectForString:(NSString *)string
- {
-#ifdef DIRECT_TO_CG
-    UniChar localBuffer[LOCAL_GLYPH_BUFFER_SIZE];
-    const UniChar *_internalBuffer = CFStringGetCharactersPtr ((CFStringRef)string);
-    const UniChar *internalBuffer;
-
-    if (!_internalBuffer){
-        CFStringGetCharacters((CFStringRef)string, CFRangeMake(0, CFStringGetLength((CFStringRef)string)), &localBuffer[0]);
-        internalBuffer = &localBuffer[0];
-    }
-    else
-        internalBuffer = _internalBuffer;
-
-    return _rectForString (self, internalBuffer, [string length]);
-#else
-    id <KWQLayoutFragment> cachedFragment;
-
-    cachedFragment = [textStorage getFragmentForString: string];
-    
-    return [cachedFragment boundingRect];
-#endif
-}
-
-
-- (void)setColor: (NSColor *)color
-{
-#ifndef DIRECT_TO_CG
-    [attributes setObject: color forKey: NSForegroundColorAttributeName];
-#endif
-}
-
-- (NSDictionary *)attributes
-{
-#ifdef DIRECT_TO_CG
-    return nil;
-#else
-    return attributes;
-#endif
-}
-
-- (int)lineHeight
-{
-    return lineHeight;
-}
-
-- (NSFont *)font
-{
-    return font;
-}
-
-- (void)dealloc
-{
-    [font release];
-#ifdef DIRECT_TO_CG
-    if (_styleGroup)
-        ATSUDisposeStyleGroup(_styleGroup);
-    if (_glyphVector.numAllocatedGlyphs > 0)
-        ATSClearGlyphVector(&_glyphVector);
-    free(widthCache);
-    free(characterToGlyph);
-#else
-    [attributes release];
-#endif
-    [super dealloc];
-}
-
- at end
-
-
-struct QFontMetricsPrivate {
-    QFontMetricsPrivate(NSFont *aFont)
+    ~QFontMetricsPrivate()
     {
-        refCount = 0;
-        font = [aFont retain];
-        info = nil;
-        ascent = -1;
-        descent = -1;
-        lineSpacing = -1;
+        [renderer release];
     }
-    ~QFontMetricsPrivate()
+    id <IFTextRenderer> getRenderer()
     {
-        [info release];
-        [font release];
+        return renderer;
     }
-    KWQLayoutInfo *getInfo();
+    
     int refCount;
-    NSFont *font;
-    int ascent;
-    int descent;
-    int lineSpacing;
+    
 private:
-    KWQLayoutInfo *info;
+    id <IFTextRenderer> renderer;
 };
 
-KWQLayoutInfo *QFontMetricsPrivate::getInfo()
-{
-    if (!info)
-        info = [[KWQLayoutInfo getMetricsForFont:font] retain];
-    return info;
-}
-
 QFontMetrics::QFontMetrics()
 {
 }
 
 QFontMetrics::QFontMetrics(const QFont &withFont)
-: data(new QFontMetricsPrivate(const_cast<QFont&>(withFont).getFont()))
+: data(new QFontMetricsPrivate(withFont))
 {
 }
 
@@ -816,16 +90,12 @@ int QFontMetrics::baselineOffset() const
 
 int QFontMetrics::ascent() const
 {
-    if (data->ascent < 0)
-        data->ascent = ROUND_TO_INT([data->font ascender]);
-    return data->ascent;
+    return [data->getRenderer() ascent];
 }
 
 int QFontMetrics::descent() const
 {
-    if (data->descent < 0)
-        data->descent = ROUND_TO_INT(-[data->font descender]);
-    return data->descent;
+    return [data->getRenderer() descent];
 }
 
 int QFontMetrics::height() const
@@ -837,21 +107,19 @@ int QFontMetrics::height() const
 
 int QFontMetrics::lineSpacing() const
 {
-    if (data->lineSpacing < 0)
-        data->lineSpacing = ROUND_TO_INT([data->font defaultLineHeightForFont]);
-    return data->lineSpacing;
+    return [data->getRenderer() lineSpacing];
 }
 
 int QFontMetrics::width(QChar qc) const
 {
-    unichar c = qc.unicode();
-    return ROUND_TO_INT(_rectForString(data->getInfo(), &c, 1).size.width);
+    UniChar c = qc.unicode();
+    return [data->getRenderer() widthForCharacters:&c length:1];
 }
 
 int QFontMetrics::width(char c) const
 {
-    unichar ch = (uchar) c;
-    return ROUND_TO_INT(_rectForString(data->getInfo(), &ch, 1).size.width);
+    UniChar ch = (uchar) c;
+    return [data->getRenderer() widthForCharacters:&ch length:1];
 }
 
 int QFontMetrics::width(const QString &qstring, int len) const
@@ -862,69 +130,38 @@ int QFontMetrics::width(const QString &qstring, int len) const
         string = QSTRING_TO_NSSTRING_LENGTH (qstring, len);
     else
         string = _FAST_QSTRING_TO_NSSTRING (qstring);
-    return ROUND_TO_INT([data->getInfo() rectForString: string].size.width);
+    return [data->getRenderer() widthForString:string];
 }
 
-int QFontMetrics::_width(const QChar *uchars, int len) const
-{
-    return ROUND_TO_INT(_rectForString(data->getInfo(), (const UniChar *)uchars, len).size.width);
-}
-
-
-int QFontMetrics::_width(CFStringRef string) const
+int QFontMetrics::width(const QChar *uchars, int len) const
 {
-    return ROUND_TO_INT([data->getInfo() rectForString: (NSString *)string].size.width);
+    return [data->getRenderer() widthForCharacters:(const UniChar *)uchars length:len];
 }
 
 QRect QFontMetrics::boundingRect(const QString &qstring, int len) const
 {
-    NSString *string;
-
-    if (len != -1)
-        string = QSTRING_TO_NSSTRING_LENGTH (qstring, len);
-    else
-        string = _FAST_QSTRING_TO_NSSTRING (qstring);
-    NSRect rect = [data->getInfo() rectForString: string];
-
-    return QRect(ROUND_TO_INT(rect.origin.x),
-            ROUND_TO_INT(rect.origin.y),
-            ROUND_TO_INT(rect.size.width),
-            ROUND_TO_INT(rect.size.height));
+    return QRect(0, 0, width(qstring, len), height());
 }
 
 QRect QFontMetrics::boundingRect(int x, int y, int width, int height, int flags, const QString &str) const
 {
-    // FIXME: need to support word wrapping
-    return QRect(x,y, width, height).intersect(boundingRect(str));
+    // FIXME: need to support word wrapping?
+    return QRect(x, y, width, height).intersect(boundingRect(str));
 }
 
 QRect QFontMetrics::boundingRect(QChar qc) const
 {
-    unichar c = qc.unicode();
-    NSRect rect = _rectForString(data->getInfo(), &c, 1);
-
-    return QRect(ROUND_TO_INT(rect.origin.x),
-            ROUND_TO_INT(rect.origin.y),
-            ROUND_TO_INT(rect.size.width),
-            ROUND_TO_INT(rect.size.height));
+    return QRect(0, 0, width(qc), height());
 }
 
 QSize QFontMetrics::size(int, const QString &qstring, int len, int tabstops, 
     int *tabarray, char **intern ) const
 {
-    if (tabstops != 0){
+    if (tabstops != 0) {
         KWQDEBUGLEVEL(KWQ_LOG_ERROR, "ERROR:  QFontMetrics::size() tabs not supported.\n");
     }
     
-    NSString *string;
-
-    if (len != -1)
-        string = QSTRING_TO_NSSTRING_LENGTH (qstring, len);
-    else
-        string = _FAST_QSTRING_TO_NSSTRING (qstring);
-    NSRect rect = [data->getInfo() rectForString: string];
-
-    return QSize (ROUND_TO_INT(rect.size.width),ROUND_TO_INT(rect.size.height));
+    return QSize(width(qstring, len), height());
 }
 
 int QFontMetrics::rightBearing(QChar) const
diff --git a/WebCore/kwq/KWQMetrics.h b/WebCore/kwq/KWQMetrics.h
deleted file mode 100644
index a1605bb..0000000
--- a/WebCore/kwq/KWQMetrics.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2001 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. 
- */
-#ifndef KWQMETRICS_H_
-#define KWQMETRICS_H_
-
-#import <Cocoa/Cocoa.h>
-
- at class KWQTextStorage;
-
-
-#ifdef DIRECT_TO_CG
-
-#define LOCAL_GLYPH_BUFFER_SIZE 1024
-
-#define INITIAL_GLYPH_CACHE_MAX 512
-#define INCREMENTAL_GLYPH_CACHE_BLOCK 1024
-
-#define UNITIALIZED_GLYPH_WIDTH 65535
-
-// These definitions are used to bound the character-to-glyph mapping cache.  The
-// range is limited to LATIN1.  When accessing the cache a check must be made to
-// determine that a character range does not include a composable charcter.
-
-// The first displayable character in latin1. (SPACE)
-#define FIRST_CACHE_CHARACTER (0x20)
-
-// The last character in latin1 extended A. (LATIN SMALL LETTER LONG S)
-#define LAST_CACHE_CHARACTER (0x17F)
-
-#define Boolean MacBoolean
-#define Fixed MacFixed
-#define Rect MacRect
-
-#import <ApplicationServices/ApplicationServices.h>
-#import <ATSUnicodePriv.h>
-#import <CoreGraphics/CGFontPrivate.h>
-
-#undef Fixed
-#undef Rect
-#undef Boolean
-
- at interface NSFont (IFPrivate)
-- (ATSUFontID)_atsFontID;
-- (CGFontRef) _backingCGSFont;
- at end
-
-//typedef unsigned short _IFGlyphWidth;
-typedef float _IFGlyphWidth;
-
-#endif
-
- at interface KWQLayoutInfo : NSObject
-{
-    NSFont *font;
-    int lineHeight;
-#ifdef DIRECT_TO_CG
-    ATSStyleGroupPtr _styleGroup;
-    ATSGlyphVector _glyphVector;
-    unsigned int widthCacheSize;
-    _IFGlyphWidth *widthCache;
-    ATSGlyphRef *characterToGlyph;
-#else
-    NSMutableDictionary *attributes;
-    NSLayoutManager *layoutManager;
-    KWQTextStorage *textStorage;
-#endif
-}
-
-+ (void)drawString: (NSString *)string atPoint: (NSPoint)p withFont: (NSFont *)font color: (NSColor *)color;
-+ (void)drawUnderlineForString: (NSString *)string atPoint: (NSPoint)p withFont: (NSFont *)font color: (NSColor *)color;
-+ (KWQLayoutInfo *)getMetricsForFont: (NSFont *)aFont;
-+ (void)setMetric: (KWQLayoutInfo *)info forFont: (NSFont *)aFont;
-- initWithFont: (NSFont *)aFont;
-- (NSRect)rectForString:(NSString *)string;
-- (NSLayoutManager *)layoutManager;
-- (KWQTextStorage *)textStorage;
-- (void)setColor: (NSColor *)color;
-- (NSDictionary *)attributes;
-- (int)lineHeight;
-- (NSFont *)font;
- at end
-
- at protocol KWQLayoutFragment <NSObject>
-- (void)setGlyphRange: (NSRange)r;
-- (NSRange)glyphRange;
-- (void)setBoundingRect: (NSRect)r;
-- (NSRect)boundingRect;
-
-#ifdef _DEBUG_LAYOUT_FRAGMENT
-- (int)accessCount;
-#endif
-
- at end
-
- at interface KWQSmallLayoutFragment : NSObject <KWQLayoutFragment>
-{
-    // Assumes 0,0 boundingRect origin and < UINT16_MAX width and height,
-    // and loss of precision for float to short is irrelevant.
-    unsigned short width;
-    unsigned short height;
-
-    // Assumes 0 location and < UINT16_MAX length.
-    unsigned short glyphRangeLength;
-#ifdef _DEBUG_LAYOUT_FRAGMENT
-    int accessCount;
-#endif
-}
- at end
-
- at interface KWQLargeLayoutFragment : NSObject <KWQLayoutFragment>
-{
-    NSRect boundingRect;
-    NSRange glyphRange;
-#ifdef _DEBUG_LAYOUT_FRAGMENT
-    int accessCount;
-#endif
-}
- at end
-
-#endif
diff --git a/WebCore/kwq/KWQPainter.mm b/WebCore/kwq/KWQPainter.mm
index 230f782..f2ef1cd 100644
--- a/WebCore/kwq/KWQPainter.mm
+++ b/WebCore/kwq/KWQPainter.mm
@@ -32,9 +32,8 @@
 
 #include <kwqdebug.h>
 
-#import <Cocoa/Cocoa.h>
-
-#import <KWQMetrics.h>
+#import <IFTextRendererFactory.h>
+#import <IFTextRenderer.h>
 
 
 struct QPainterPrivate {
@@ -475,70 +474,21 @@ void QPainter::drawTiledPixmap( int x, int y, int w, int h,
 }
 #endif
 
-#define FAST_CACHE_DRAWING 1
-
-#ifdef HACK_FAST_DRAWING
- at interface NSLayoutManager (Private)
-- (char *)_packedGlyphs:(NSMultibyteGlyphPacking)packing range:(NSRange)glyphRange length:(unsigned *)len;
- at end
-#endif
-
-#define FLOOR_TO_INT(x) (int)(floor(x))
-#define ROUND_TO_INT(x) (int)(((x) > floor(x) + .5) ? ceil(x) : floor(x))
-
 // y is the baseline
 void QPainter::drawText(int x, int y, const QString &qstring, int len)
 {
     NSString *string;
-    NSFont *font;
     
     _lockFocus();
     
-    //font = data->qfont.data->font;    
-    font = data->qfont.getFont();    
-
     if (len == -1)
         string = QSTRING_TO_NSSTRING(qstring);
     else
         string = QSTRING_TO_NSSTRING_LENGTH(qstring,len);
 
-    // This will draw the text from the top of the bounding box down.
-    // Qt expects to draw from the baseline.
-    // Remember that descender is negative.
-    y = y - (ROUND_TO_INT([font defaultLineHeightForFont]) - FLOOR_TO_INT(-[font descender]));
-
-#ifdef SLOW_SAFE_DRAWING
-
-    [string drawAtPoint:NSMakePoint(x, y) withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, data->qpen.color().color, NSForegroundColorAttributeName, nil]];
-
-#elif FAST_CACHE_DRAWING
-
-    [KWQLayoutInfo drawString: string atPoint: NSMakePoint(x, y) withFont: font color: data->qpen.color().color];
-
-#elif HACK_FAST_DRAWING
-
-    KWQLayoutInfo *metricsCache = [KWQLayoutInfo getMetricsForFont: font];
-    NSLayoutManager *layoutManager = [metricsCache layoutManagerForString: string];
-    if (layoutManager != nil){
-
-        [font set];
-        [data->qpen.color().color set];
-        
-        unsigned glyphLen;
-        char *glyphBuf;
-
-        NSGraphicsContext *graphicsContext = [NSGraphicsContext currentContext];
-        BOOL flag = [graphicsContext shouldAntialias];
-        [graphicsContext setShouldAntialias: NO];
-        
-        glyphBuf = [layoutManager _packedGlyphs:[font glyphPacking] range:NSMakeRange (0, numberOfGlyphs) length:&glyphLen];
-        [layoutManager showPackedGlyphs:glyphBuf length:glyphLen glyphRange:NSMakeRange (0, numberOfGlyphs)  atPoint:NSMakePoint(x, y) font:font color:data->qpen.color().color printingAdjustment:NSMakeSize(0.0, 0.0)];
-
-        [graphicsContext setShouldAntialias: flag];
-    }
-
-#endif
-
+    [[[IFTextRendererFactory sharedFactory]
+        rendererWithFamily:data->qfont.getNSFamily() traits:data->qfont.getNSTraits() size:data->qfont.getNSSize()]
+        drawString:string atPoint:NSMakePoint(x,y) withColor:data->qpen.color().color];
 
     _unlockFocus();
 }
@@ -563,36 +513,30 @@ void QPainter::drawText (int x, int y, const QString &qstring, int len, int pos,
 void QPainter::drawUnderlineForText(int x, int y, const QString &qstring, int len)
 {
     NSString *string;
-    NSFont *font;
     
     _lockFocus();
     
-    font = data->qfont.getFont();    
-
     if (len == -1)
         string = QSTRING_TO_NSSTRING(qstring);
     else
         string = QSTRING_TO_NSSTRING_LENGTH(qstring,len);
 
-    y = y - (ROUND_TO_INT([font defaultLineHeightForFont]) - FLOOR_TO_INT(-[font descender]));
-    [KWQLayoutInfo drawUnderlineForString: string atPoint: NSMakePoint(x, y) withFont: font color: data->qpen.color().color];
+    [[[IFTextRendererFactory sharedFactory]
+        rendererWithFamily:data->qfont.getNSFamily() traits:data->qfont.getNSTraits() size:data->qfont.getNSSize()]
+        drawUnderlineForString:string atPoint:NSMakePoint(x,y) withColor:data->qpen.color().color];
 
     _unlockFocus();
 }
 
 
-void QPainter::drawText(int x, int y, int w, int h, int flags, const QString&qstring, int len, 
+void QPainter::drawText(int x, int y, int w, int h, int flags, const QString &qstring, int len, 
     QRect *br, char **internal)
 {
     NSString *string;
-    NSFont *font;
     NSMutableParagraphStyle *style = [[[NSMutableParagraphStyle alloc] init] autorelease];
     
     _lockFocus();
     
-    //font = data->qfont.data->font;    
-    font = data->qfont.getFont();    
-        
     if (len == -1)
         string = QSTRING_TO_NSSTRING(qstring);
     else
@@ -613,7 +557,9 @@ void QPainter::drawText(int x, int y, int w, int h, int flags, const QString&qst
         [style setAlignment: NSLeftTextAlignment];
     }
     
-    [string drawInRect:NSMakeRect(x, y, w, h) withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, data->qpen.color().color, NSForegroundColorAttributeName, style, NSParagraphStyleAttributeName, nil]];
+    [[[IFTextRendererFactory sharedFactory]
+        rendererWithFamily:data->qfont.getNSFamily() traits:data->qfont.getNSTraits() size:data->qfont.getNSSize()]
+        drawString:string inRect:NSMakeRect(x, y, w, h) withColor:data->qpen.color().color paragraphStyle:style];
 
     _unlockFocus();
 }
diff --git a/WebCore/kwq/KWQTextContainer.mm b/WebCore/kwq/KWQTextContainer.mm
deleted file mode 100644
index 5601b2a..0000000
--- a/WebCore/kwq/KWQTextContainer.mm
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2001 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. 
- */
- 
- /*
-    This class an it's companion KWQTextStorage are used to optimize 
-    our interaction with NSLayoutManager.  They do very little.
-    KWQTextContainer has a fixed geometry.  It only ever containers
-    a short run of text corresponding to a khtml TextSlave.
-    
-    Both KWQTextStorage and KWQTextContainer are used as singletons.  They
-    are set/reset for layout and rendering.
- */
- 
-
-#import <Cocoa/Cocoa.h>
-
-#include <kwqdebug.h>
-
-#import <KWQTextContainer.h>
-
- at implementation KWQTextContainer
-
-const float LargeNumberForText = 1.0e7;
-
-static KWQTextContainer *sharedInstance = nil;
-
-+ (KWQTextContainer *)sharedInstance
-{
-    if (sharedInstance == nil)
-        sharedInstance = [[KWQTextContainer alloc] initWithContainerSize: NSMakeSize(0,0)];
-    return sharedInstance;
-}
-
-
-- (id)initWithContainerSize:(NSSize)aSize
-{
-    [super initWithContainerSize:aSize];
-    return self;
-}
-
-- (void)replaceLayoutManager:(NSLayoutManager *)aLayoutManager
-{
-    [NSException raise:@"NOT IMPLEMENTED" format:@"- (void)replaceLayoutManager:(NSLayoutManager *)aLayoutManager"];
-}
-
-- (BOOL)isSimpleRectangularTextContainer
-{
-    return YES;
-}
-
-- (BOOL)containsPoint:(NSPoint)aPoint
-{
-    return YES;
-}
-
-
-- (NSSize)containerSize
-{
-    return NSMakeSize(LargeNumberForText, LargeNumberForText);
-}
-
-
-- (void)setContainerSize:(NSSize)aSize
-{
-    [NSException raise:@"NOT IMPLEMENTED" format:@"- (void)setContainerSize:(NSSize)aSize"];
-}
-
-- (void)setHeightTracksTextView:(BOOL)flag
-{
-    [NSException raise:@"NOT IMPLEMENTED" format:@"- (void)setHeightTracksTextView:(BOOL)flag"];
-}
-
-- (BOOL)heightTracksTextView
-{
-    return NO;
-}
-
-- (void)setWidthTracksTextView:(BOOL)flag
-{
-    [NSException raise:@"NOT IMPLEMENTED" format:@"- (void)setWidthTracksTextView:(BOOL)flag"];
-}
-
-- (BOOL)widthTracksTextView
-{
-    return NO;
-}
-
-- (void)setLayoutManager:(NSLayoutManager *)aLayoutManager
-{
-}
-
-
-- (NSLayoutManager *)layoutManager
-{
-    [NSException raise:@"NOT IMPLEMENTED" format:@"- (NSLayoutManager *)layoutManager"];
-    return nil;
-}
-
-
-- (void)setLineFragmentPadding:(float)aFloat
-{
-}
-
-
-- (float)lineFragmentPadding
-{
-    return 0.0f;
-}
-
-
-- (void)setTextView:(NSTextView *)aTextView
-{
-}
-
-- (NSTextView *)textView
-{
-    return nil;
-}
-
-- (NSRect)lineFragmentRectForProposedRect:(NSRect)proposedRect sweepDirection:(NSLineSweepDirection)sweepDirection movementDirection:(NSLineMovementDirection)movementDirection remainingRect:(NSRect *)remainingRect
-{
-    return proposedRect;
-}
-
- at end
-
diff --git a/WebCore/kwq/KWQTextStorage.h b/WebCore/kwq/KWQTextStorage.h
deleted file mode 100644
index 4aaa978..0000000
--- a/WebCore/kwq/KWQTextStorage.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2001 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 <Cocoa/Cocoa.h> 
-
-#include <kwqdebug.h>
-
-#import <KWQMetrics.h>
-
- at interface KWQTextStorage : NSTextStorage
-{
-    NSDictionary *attributes;
-    NSString *string;
-    int stringCapacity;
-    NSMutableDictionary *fragmentCache;
-    NSLayoutManager *_layoutManager;
-#ifdef SPACE_OPTIMIZATION
-    id <KWQLayoutFragment> spaceFragment;
-    id <KWQLayoutFragment> expandedFragment;
-#endif
-}
-
-- (id)initWithFontAttribute:(NSDictionary *)attrs;
-- (void)setAttributes: (NSDictionary *)at;
-
-- (id <KWQLayoutFragment>)getFragmentForString: (NSString *)string;
-
-- (void)setString: (NSString *)dString;
-
-#ifdef _DEBUG_LAYOUT_FRAGMENT
-- (NSDictionary *)fragmentCache;
-#endif
-
- at end
diff --git a/WebCore/kwq/KWQTextStorage.mm b/WebCore/kwq/KWQTextStorage.mm
deleted file mode 100644
index 7ec7bab..0000000
--- a/WebCore/kwq/KWQTextStorage.mm
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (C) 2001 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 <Cocoa/Cocoa.h> 
-
-#include <kwqdebug.h>
-
-#import <KWQTextStorage.h>
-#import <KWQTextContainer.h>
-
-/*
-    This class is a dumb text storage implementation.  It is optimized for speed,
-    not flexibility.  It only support read-only text with font and color attributes.
-    
-    It is used, along with KWQTextContainer to spoof NSLayoutManager.  KWQTextStorage
-    and KWQTextContainer are both used as singletons.  They are set/reset to contain the
-    correct attributes (font and color only) during layout and rendering.
-*/
-
-#ifndef UINT16_MAX
-#define UINT16_MAX        65535
-#endif
-
- at implementation KWQTextStorage
-
-- (id <KWQLayoutFragment>)_buildFragmentForString: (NSString *)measureString
-{
-    id <KWQLayoutFragment> fragment;
-    NSRange range = NSMakeRange (0, [measureString length]);
-    NSRange glyphRange;
-    NSRect boundingRect;
-
-    if (fragmentCache == nil)
-        fragmentCache = [[NSMutableDictionary alloc] initWithCapacity: 1024*8];
-    
-    [self setString: measureString];
-    
-    glyphRange = [_layoutManager glyphRangeForCharacterRange:range actualCharacterRange:nil];
-    boundingRect = [_layoutManager boundingRectForGlyphRange: glyphRange inTextContainer: [KWQTextContainer sharedInstance]];
-    
-    bool useLargeFragment = NO;
-
-    if (boundingRect.origin.x != 0 || boundingRect.origin.y != 0 ||
-            glyphRange.location != 0 ||
-            glyphRange.length > UINT16_MAX || 
-            boundingRect.size.width > (float)UINT16_MAX ||
-            boundingRect.size.height > (float)UINT16_MAX){
-        useLargeFragment = YES;
-    }
-
-    if (useLargeFragment)
-        fragment = [[KWQLargeLayoutFragment alloc] init];
-    else
-        fragment = [[KWQSmallLayoutFragment alloc] init];
-
-    [fragment setGlyphRange: glyphRange];
-    [fragment setBoundingRect: boundingRect];
-
-    [fragmentCache setObject: fragment forKey: [self string]];
-    [fragment release];
-
-    return fragment;
-}
-
-
-- (id <KWQLayoutFragment>)getFragmentForString: (NSString *)fString
-{
-    id <KWQLayoutFragment> fragment;
-    
-#ifdef SPACE_OPTIMIZATION
-    bool hasLeadingSpace = NO, hasTrailingSpace = NO;
-    const UniChar *clippedStart = 0;
-    unsigned int clippedLength = 0, fragStringLength;
-    CFStringRef clippedString, fragString = (CFStringRef)fString;
-
-    fragStringLength = CFStringGetLength (fragString);
-    if (fragStringLength > 1){
-        const UniChar *internalBuffer = CFStringGetCharactersPtr((CFStringRef)fragString);
-        
-        if (internalBuffer){
-            clippedStart = internalBuffer;
-            clippedLength = fragStringLength;
-            if (*internalBuffer == ' '){
-                hasLeadingSpace = YES;
-                clippedStart++;
-                clippedLength--;
-            }
-            if (internalBuffer[fragStringLength-1] == ' '){
-                hasTrailingSpace = YES;
-                clippedLength--;
-            }
-
-            if (hasLeadingSpace || hasTrailingSpace){
-                NSRect boundingRect;
-                NSRange glyphRange;
-                
-                clippedString = CFStringCreateWithCharactersNoCopy (kCFAllocatorDefault, clippedStart, clippedLength, kCFAllocatorNull);
-                fragment = [fragmentCache objectForKey: (NSString *)clippedString];
-                if (!fragment)
-                    fragment = [self _buildFragmentForString: (NSString *)clippedString];
-                CFRelease (clippedString);
-                boundingRect = [fragment boundingRect];
-                glyphRange = [fragment glyphRange];
-                if (hasLeadingSpace){
-                    glyphRange.length++;
-                    boundingRect.size.width += [spaceFragment boundingRect].size.width;
-                }
-                if (hasTrailingSpace){
-                    glyphRange.length++;
-                    boundingRect.size.width += [spaceFragment boundingRect].size.width;
-                }
-                [expandedFragment setBoundingRect: boundingRect];
-                [expandedFragment setGlyphRange: glyphRange];
-                
-                return expandedFragment;
-            }
-        }
-    }
-#endif
-
-    fragment = [fragmentCache objectForKey: fString];
-    if (!fragment)
-        fragment = [self _buildFragmentForString: fString];
-        
-    return fragment;
-}
-
-#ifdef DEBUG_SPACE_OPTIMIZATION
-static int totalMeasurements = 0;
-static int leadingSpace = 0;
-static int trailingSpace = 0;
-#endif
-
-- (id)initWithFontAttribute:(NSDictionary *)attrs 
-{
-    attributes = [attrs retain];
-#ifdef SPACE_OPTIMIZATION
-    expandedFragment = [[KWQLargeLayoutFragment alloc] init];
-#endif
-    return self;
-}
-
-- (void)dealloc 
-{
-    [string release];
-    [fragmentCache release];
-    [attributes release];
-    [super dealloc];
-}
-
-#ifdef _DEBUG_LAYOUT_FRAGMENT
-- (NSDictionary *)fragmentCache { return fragmentCache; }
-#endif
-
-- (void)addLayoutManager:(id)obj {
-    _layoutManager = [obj retain];
-    [obj setTextStorage:self];
-#ifdef SPACE_OPTIMIZATION
-    spaceFragment = [self _buildFragmentForString: @" "];
-#endif
-}
-
-- (void)removeLayoutManager:(id)obj {
-    if (obj == _layoutManager){
-        [obj setTextStorage:nil];
-        [obj autorelease];
-    }
-}
-
-- (NSArray *)layoutManagers {
-    return [NSArray arrayWithObjects: _layoutManager, nil];
-}
-
-- (void)edited:(unsigned)mask range:(NSRange)oldRange changeInLength:(int)lengthChange
-{
-    KWQDEBUG ("not implemented");
-}
-
-- (void)ensureAttributesAreFixedInRange:(NSRange)range
-{
-    KWQDEBUG ("not implemented");
-}
-
-- (void)invalidateAttributesInRange:(NSRange)range
-{
-    KWQDEBUG ("not implemented");
-}
-
-- (unsigned)length 
-{
-    return [string length];
-}
-
-- (void)setAttributes: (NSDictionary *)at
-{
-    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];
-        
-        // Make an immutable copy.
-        string = [[NSString stringWithString: newString] retain];
-        
-        [_layoutManager textStorage: self 
-                edited: NSTextStorageEditedCharacters
-                range: NSMakeRange (0, newLength)
-                changeInLength: newLength - oldLength
-                invalidatedRange:NSMakeRange (0, newLength)];
-    }
-}
-
-- (NSString *)string 
-{
-    return string;
-}
-
-
-- (NSDictionary *)attributesAtIndex:(unsigned)location effectiveRange:(NSRangePointer)range 
-{
-    if (range != 0){
-        range->location = 0;
-        range->length = [self length];
-    }
-    return attributes;
-}
-
-
-- (NSDictionary *)attributesAtIndex:(unsigned)location longestEffectiveRange:(NSRangePointer)range inRange:(NSRange)rangeLimit
-{
-    if (range != 0){
-        range->location = rangeLimit.location;
-        range->length = rangeLimit.length;
-    }
-    return attributes;
-}
-
-
-- (id)attribute:(NSString *)attrName atIndex:(unsigned)location effectiveRange:(NSRangePointer)range 
-{
-    if (range != 0){
-        range->location = 0;
-        range->length = [self length];
-    }
-    return [attributes objectForKey: attrName];
-}
-
-
-- (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range 
-{
-    [NSException raise:@"NOT IMPLEMENTED" format:@"- (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range"];
-}
-
-
-- (void)replaceCharactersInRange:(NSRange)range withAttributedString:(NSAttributedString *)str 
-{
-    [NSException raise:@"NOT IMPLEMENTED" format:@"- (void)replaceCharactersInRange:(NSRange)range withAttributedString:(NSAttributedString *)str"];
-}
-
-
-- (void)addAttribute:(NSString *)name value:value range:(NSRange)range
-{
-    [NSException raise:@"NOT IMPLEMENTED" format:@"- (void)addAttribute:(NSString *)name value:value range:(NSRange)range"];
-}
-
-
-- (NSAttributedString *)attributedSubstringFromRange:(NSRange)aRange
-{
-    [NSException raise:@"NOT IMPLEMENTED" format:@"- (NSAttributedString *)attributedSubstringFromRange:(NSRange)aRange"];
-    return nil;
-}
-
- at end
-
diff --git a/WebCore/kwq/Makefile.am b/WebCore/kwq/Makefile.am
index 1de973a..8be53a5 100644
--- a/WebCore/kwq/Makefile.am
+++ b/WebCore/kwq/Makefile.am
@@ -5,6 +5,7 @@ libkwq_o_ldflags = -Wl,-r -nostdlib
 libkwq_o_AR = $(OBJCXXLD) $(AM_OBJCXXFLAGS) $(OBJCXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) $(libkwq_o_ldflags) -o
 
 libkwq_o_SOURCES = \
+	IFTextRendererFactory.m \
 	KWQApplication.mm \
 	KWQArrayImpl.mm \
 	KWQBitmap.mm \
@@ -110,9 +111,7 @@ libkwq_o_SOURCES = \
 	KWQStyle.mm \
 	KWQStyleSheet.mm \
 	KWQTextArea.mm \
-	KWQTextContainer.mm \
 	KWQTextEdit.mm \
-	KWQTextStorage.mm \
 	KWQTimer.mm \
 	KWQToolTip.mm \
 	KWQValueListImpl.mm \
diff --git a/WebCore/kwq/qt/qfont.h b/WebCore/kwq/qt/qfont.h
index 16164b8..ee46888 100644
--- a/WebCore/kwq/qt/qfont.h
+++ b/WebCore/kwq/qt/qfont.h
@@ -26,46 +26,27 @@
 #ifndef QFONT_H_
 #define QFONT_H_
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 class QString;
 class QPainter;
 
-#if (defined(__APPLE__) && defined(__OBJC__) && defined(__cplusplus))
-#define Fixed MacFixed
-#define Rect MacRect
-#define Boolean MacBoolean
-#import <Cocoa/Cocoa.h>
-#undef Fixed
-#undef Rect
-#undef Boolean
+#ifdef __OBJC__
+ at class NSString;
+#else
+typedef void NSString;
 #endif
 
-// class QFont =================================================================
-
 class QFont {
 public:
 
-    // typedefs ----------------------------------------------------------------
-    // enums -------------------------------------------------------------------
-
     enum CharSet { Latin1, Unicode };
     enum Weight { Normal = 50, Bold = 63 };
 
-    // constants ---------------------------------------------------------------
-    // static member functions -------------------------------------------------
-
-    // constructors, copy constructors, and destructors ------------------------
-
     QFont();
     QFont(const QFont &);
+    QFont &operator=(const QFont &);
 
     ~QFont();
 
-    // member functions --------------------------------------------------------
-
     int pixelSize() const;
     QString family() const;
     void setFamily(const QString &);
@@ -77,49 +58,18 @@ public:
     bool italic() const;
     bool bold() const;
 
-    // operators ---------------------------------------------------------------
-
-    QFont &operator=(const QFont &);
     bool operator==(const QFont &x) const;
-    bool operator!=(const QFont &x) const;
-
-#ifdef _KWQ_
-#if (defined(__APPLE__) && defined(__OBJC__) && defined(__cplusplus))
-    static NSFont *QFont::defaultNSFont();
-#endif
-#endif
-
-#if (defined(__APPLE__) && defined(__OBJC__) && defined(__cplusplus))
-        NSFont *getFont();
-#else
-        void *getFont();
-#endif
-
-// protected -------------------------------------------------------------------
-// private ---------------------------------------------------------------------
-private:
-#ifdef _KWQ_
-    void _initialize();
-    void _initializeWithFont(const QFont *);
-    void _free();
-#if (defined(__APPLE__) && defined(__OBJC__) && defined(__cplusplus))
-    void _setTrait (NSFontTraitMask mask);
-#endif
+    bool operator!=(const QFont &x) const { return !(*this == x); }
     
-#if (defined(__APPLE__) && defined(__OBJC__) && defined(__cplusplus))
-        NSFont *font;
-        NSString *_family;
-        int _trait;
-        float _size;
-#else
-        void *font;
-        void *_family;
-        int _trait;
-        float _size;
-#endif
+    NSString *getNSFamily() const { return _family; }
+    int getNSTraits() const { return _trait; }
+    float getNSSize() const { return _size; }
 
-#endif
+private:
+    NSString *_family;
+    int _trait;
+    float _size;
 
-}; // class QFont ==============================================================
+};
 
 #endif
diff --git a/WebCore/kwq/qt/qfontmetrics.h b/WebCore/kwq/qt/qfontmetrics.h
index 1858c15..1ca48a6 100644
--- a/WebCore/kwq/qt/qfontmetrics.h
+++ b/WebCore/kwq/qt/qfontmetrics.h
@@ -26,44 +26,22 @@
 #ifndef QFONTMETRICS_H_
 #define QFONTMETRICS_H_
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #include "qrect.h"
 #include "qsize.h"
 #include "qstring.h"
 #include "qfont.h"
 #include "qfontinfo.h"
 
-#if (defined(__APPLE__) && defined(__OBJC__) && defined(__cplusplus))
-#import <Cocoa/Cocoa.h>
-#endif
-
 class QFontMetricsPrivate;
 
-// class QFontMetrics ==========================================================
-
 class QFontMetrics {
 public:
 
-    // typedefs ----------------------------------------------------------------
-    // enums -------------------------------------------------------------------
-    // constants ---------------------------------------------------------------
-    // static member functions -------------------------------------------------
-
-    // constructors, copy constructors, and destructors ------------------------
-
     QFontMetrics();
     QFontMetrics(const QFont &);
     QFontMetrics(const QFontMetrics &);
-    ~QFontMetrics();
-
-    // operators ---------------------------------------------------------------
-
     QFontMetrics &operator=(const QFontMetrics &);
-
-    // member functions --------------------------------------------------------
+    ~QFontMetrics();
 
     int ascent() const;
     int descent() const;
@@ -73,10 +51,7 @@ 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;
-    int _width (const QChar *, int len) const;
-#endif
+    int width(const QChar *, int len) const;
 
     QRect boundingRect(const QString &, int len=-1) const;
     QRect boundingRect(QChar) const;
@@ -91,7 +66,7 @@ public:
 private:
     KWQRefPtr<QFontMetricsPrivate> data;
 
-}; // class QFontMetrics =======================================================
+};
 
 #endif
 
diff --git a/WebCore/libwebcore.exp b/WebCore/libwebcore.exp
index 3a8acc9..8260ddb 100644
--- a/WebCore/libwebcore.exp
+++ b/WebCore/libwebcore.exp
@@ -1,3 +1,4 @@
+.objc_class_name_IFTextRendererFactory
 .objc_class_name_WCPluginDatabase
 __Z27WCSetIFLoadProgressMakeFuncPFP11objc_objectvE
 __Z28WCSetIFWebDataSourceMakeFuncPFP11objc_objectPvE
diff --git a/WebKit/Bookmarks.subproj/IFBookmarkLeaf.m b/WebKit/Bookmarks.subproj/IFBookmarkLeaf.m
index b96fd9b..f879169 100644
--- a/WebKit/Bookmarks.subproj/IFBookmarkLeaf.m
+++ b/WebKit/Bookmarks.subproj/IFBookmarkLeaf.m
@@ -82,7 +82,7 @@
     }
 
     [_URLString release];
-    _URLString = [[NSString stringWithString:URLString] retain];
+    _URLString = [URLString copy];
 
     [[self _group] _bookmarkDidChange:self];    
 }
diff --git a/WebKit/Bookmarks.subproj/IFBookmarkList.m b/WebKit/Bookmarks.subproj/IFBookmarkList.m
index e4a0875..f29fdec 100644
--- a/WebKit/Bookmarks.subproj/IFBookmarkList.m
+++ b/WebKit/Bookmarks.subproj/IFBookmarkList.m
@@ -21,9 +21,9 @@
     
     [super init];
 
-    _title = [[NSString stringWithString:title] retain];
+    _title = [title copy];
     _image = [image retain];
-    _list = [[NSMutableArray array] retain];
+    _list = [[NSMutableArray alloc] init];
     [self _setGroup:group];
     
     return self;
@@ -49,7 +49,7 @@
     }
 
     [_title release];
-    _title = [[NSString stringWithString:title] retain];
+    _title = [title copy];
 
     [[self _group] _bookmarkDidChange:self]; 
 }
diff --git a/WebKit/Bookmarks.subproj/WebBookmarkLeaf.m b/WebKit/Bookmarks.subproj/WebBookmarkLeaf.m
index b96fd9b..f879169 100644
--- a/WebKit/Bookmarks.subproj/WebBookmarkLeaf.m
+++ b/WebKit/Bookmarks.subproj/WebBookmarkLeaf.m
@@ -82,7 +82,7 @@
     }
 
     [_URLString release];
-    _URLString = [[NSString stringWithString:URLString] retain];
+    _URLString = [URLString copy];
 
     [[self _group] _bookmarkDidChange:self];    
 }
diff --git a/WebKit/Bookmarks.subproj/WebBookmarkList.m b/WebKit/Bookmarks.subproj/WebBookmarkList.m
index e4a0875..f29fdec 100644
--- a/WebKit/Bookmarks.subproj/WebBookmarkList.m
+++ b/WebKit/Bookmarks.subproj/WebBookmarkList.m
@@ -21,9 +21,9 @@
     
     [super init];
 
-    _title = [[NSString stringWithString:title] retain];
+    _title = [title copy];
     _image = [image retain];
-    _list = [[NSMutableArray array] retain];
+    _list = [[NSMutableArray alloc] init];
     [self _setGroup:group];
     
     return self;
@@ -49,7 +49,7 @@
     }
 
     [_title release];
-    _title = [[NSString stringWithString:title] retain];
+    _title = [title copy];
 
     [[self _group] _bookmarkDidChange:self]; 
 }
diff --git a/WebKit/ChangeLog b/WebKit/ChangeLog
index 5dfc0c4..4908701 100644
--- a/WebKit/ChangeLog
+++ b/WebKit/ChangeLog
@@ -1,3 +1,28 @@
+2002-05-03  Darin Adler  <darin at apple.com>
+
+	* Misc.subproj/WebKitDebug.h: Add WEBKIT_LOG_MEMUSAGE, WEBKIT_LOG_FONTCACHE, and
+	WEBKIT_LOG_FONTCACHECHARMISS for font code moved here from WebCore.
+
+	* Resources/url_icon.tiff: New URL icon?
+
+	* WebCoreSupport.subproj/IFCachedTextRenderer.h: Added.
+	* WebCoreSupport.subproj/IFCachedTextRenderer.m: Added.
+	* WebCoreSupport.subproj/IFCachedTextRendererFactory.h: Added.
+	* WebCoreSupport.subproj/IFCachedTextRendererFactory.m: Added.
+	This has code moved here from WebCore.
+
+	* WebKit.pbproj/project.pbxproj: Add the new source files.
+
+	* Bookmarks.subproj/IFBookmarkLeaf.m:
+	(-[IFBookmarkLeaf setURLString:]): Use copy instead of initWithString.
+	* Bookmarks.subproj/IFBookmarkList.m:
+	(-[IFBookmarkList initWithTitle:image:group:]): Use copy instead of stringWithString.
+	(-[IFBookmarkList setTitle:]): Use copy instead of stringWithString.
+	* WebView.subproj/IFWebDataSourcePrivate.mm: (-[IFWebDataSource _setTitle:]):
+	Use mutableCopy instead of stringWithString.
+	* WebView.subproj/IFWebView.mm: (-[IFWebView initWithFrame:]): Use copy instead
+	of stringWithString.
+
 2002-05-02  John Sullivan  <sullivan at apple.com>
 
 	Changed API such that mutating methods can now be called on bookmark objects,
diff --git a/WebKit/ChangeLog-2002-12-03 b/WebKit/ChangeLog-2002-12-03
index 5dfc0c4..4908701 100644
--- a/WebKit/ChangeLog-2002-12-03
+++ b/WebKit/ChangeLog-2002-12-03
@@ -1,3 +1,28 @@
+2002-05-03  Darin Adler  <darin at apple.com>
+
+	* Misc.subproj/WebKitDebug.h: Add WEBKIT_LOG_MEMUSAGE, WEBKIT_LOG_FONTCACHE, and
+	WEBKIT_LOG_FONTCACHECHARMISS for font code moved here from WebCore.
+
+	* Resources/url_icon.tiff: New URL icon?
+
+	* WebCoreSupport.subproj/IFCachedTextRenderer.h: Added.
+	* WebCoreSupport.subproj/IFCachedTextRenderer.m: Added.
+	* WebCoreSupport.subproj/IFCachedTextRendererFactory.h: Added.
+	* WebCoreSupport.subproj/IFCachedTextRendererFactory.m: Added.
+	This has code moved here from WebCore.
+
+	* WebKit.pbproj/project.pbxproj: Add the new source files.
+
+	* Bookmarks.subproj/IFBookmarkLeaf.m:
+	(-[IFBookmarkLeaf setURLString:]): Use copy instead of initWithString.
+	* Bookmarks.subproj/IFBookmarkList.m:
+	(-[IFBookmarkList initWithTitle:image:group:]): Use copy instead of stringWithString.
+	(-[IFBookmarkList setTitle:]): Use copy instead of stringWithString.
+	* WebView.subproj/IFWebDataSourcePrivate.mm: (-[IFWebDataSource _setTitle:]):
+	Use mutableCopy instead of stringWithString.
+	* WebView.subproj/IFWebView.mm: (-[IFWebView initWithFrame:]): Use copy instead
+	of stringWithString.
+
 2002-05-02  John Sullivan  <sullivan at apple.com>
 
 	Changed API such that mutating methods can now be called on bookmark objects,
diff --git a/WebKit/Misc.subproj/WebKitDebug.h b/WebKit/Misc.subproj/WebKitDebug.h
index 5aab93f..8077f3c 100644
--- a/WebKit/Misc.subproj/WebKitDebug.h
+++ b/WebKit/Misc.subproj/WebKitDebug.h
@@ -27,6 +27,9 @@
 #define WEBKIT_LOG_GENERIC_ERROR		0x00000010
 #define WEBKIT_LOG_TIMING			0x00000020
 #define WEBKIT_LOG_LOADING			0x00000040
+#define WEBKIT_LOG_MEMUSAGE			0x00000080
+#define WEBKIT_LOG_FONTCACHE			0x00000100
+#define WEBKIT_LOG_FONTCACHECHARMISS		0x00000200
 #define WEBKIT_LOG_DOWNLOAD			0x00000800
 #define WEBKIT_LOG_DOCUMENTLOAD			0x00001000
 #define WEBKIT_LOG_PLUGINS			0x00002000
diff --git a/WebKit/Resources/url_icon.tiff b/WebKit/Resources/url_icon.tiff
index 20e0c16..22f11fd 100644
Binary files a/WebKit/Resources/url_icon.tiff and b/WebKit/Resources/url_icon.tiff differ
diff --git a/WebKit/WebCoreSupport.subproj/IFCachedTextRenderer.h b/WebKit/WebCoreSupport.subproj/IFCachedTextRenderer.h
new file mode 100644
index 0000000..5006785
--- /dev/null
+++ b/WebKit/WebCoreSupport.subproj/IFCachedTextRenderer.h
@@ -0,0 +1,30 @@
+//
+//  IFCachedTextRenderer.h
+//  WebKit
+//
+//  Created by Darin Adler on Thu May 02 2002.
+//  Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+//
+
+#import <IFTextRenderer.h>
+#import <ATSUnicodePriv.h>
+
+typedef float IFGlyphWidth;
+
+ at interface IFCachedTextRenderer : NSObject <IFTextRenderer>
+{
+    NSFont *font;
+    int ascent;
+    int descent;
+    int lineSpacing;
+    
+    ATSStyleGroupPtr styleGroup;
+    ATSGlyphVector glyphVector;
+    unsigned int widthCacheSize;
+    IFGlyphWidth *widthCache;
+    ATSGlyphRef *characterToGlyph;
+}
+
+- initWithFont:(NSFont *)font;
+
+ at end
diff --git a/WebCore/kwq/KWQFontMetrics.mm b/WebKit/WebCoreSupport.subproj/IFCachedTextRenderer.m
similarity index 60%
copy from WebCore/kwq/KWQFontMetrics.mm
copy to WebKit/WebCoreSupport.subproj/IFCachedTextRenderer.m
index 3f52773..8973c96 100644
--- a/WebCore/kwq/KWQFontMetrics.mm
+++ b/WebKit/WebCoreSupport.subproj/IFCachedTextRenderer.m
@@ -1,48 +1,29 @@
-/*
- * Copyright (C) 2001 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 <qfontmetrics.h>
-
-#import <math.h>
-#import <kwqdebug.h>
+//
+//  IFCachedTextRenderer.m
+//  WebKit
+//
+//  Created by Darin Adler on Thu May 02 2002.
+//  Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+//
+
+#import "IFCachedTextRenderer.h"
+
 #import <Cocoa/Cocoa.h>
 
-#define DIRECT_TO_CG
+#import <ApplicationServices/ApplicationServices.h>
+#import <CoreGraphics/CGFontPrivate.h>
+#import <WebKit/WebKitDebug.h>
 
-#import <KWQMetrics.h>
-#import <KWQTextStorage.h>
-#import <KWQTextContainer.h>
+#define DIRECT_TO_CG
 
 #define NON_BREAKING_SPACE 0xA0
 #define SPACE 0x20
 
 #define FLOOR_TO_INT(x) (int)(floor(x))
 //#define ROUND_TO_INT(x) (int)(((x) > (floor(x) + .5)) ? ceil(x) : floor(x))
-#define ROUND_TO_INT(x) (unsigned int)(x+.5)
-#define ROUND_TO_UINT(x) (unsigned int)(x+.5)
-#define ROUND_TO_USHORT(x) (unsigned int)(x+.5)
+#define ROUND_TO_INT(x) (unsigned int)((x)+.5)
+#define ROUND_TO_UINT(x) (unsigned int)((x)+.5)
+#define ROUND_TO_USHORT(x) (unsigned int)((x)+.5)
 #ifdef FOOOOFOOO
 static inline int ROUND_TO_INT (float x)
 {
@@ -54,7 +35,72 @@ static inline int ROUND_TO_INT (float x)
 }
 #endif
 
- at implementation KWQSmallLayoutFragment
+#ifdef DIRECT_TO_CG
+
+#define LOCAL_GLYPH_BUFFER_SIZE 1024
+
+#define INITIAL_GLYPH_CACHE_MAX 512
+#define INCREMENTAL_GLYPH_CACHE_BLOCK 1024
+
+#define UNITIALIZED_GLYPH_WIDTH 65535
+
+// These definitions are used to bound the character-to-glyph mapping cache.  The
+// range is limited to LATIN1.  When accessing the cache a check must be made to
+// determine that a character range does not include a composable charcter.
+
+// The first displayable character in latin1. (SPACE)
+#define FIRST_CACHE_CHARACTER (0x20)
+
+// The last character in latin1 extended A. (LATIN SMALL LETTER LONG S)
+#define LAST_CACHE_CHARACTER (0x17F)
+
+ at interface NSFont (IFPrivate)
+- (ATSUFontID)_atsFontID;
+- (CGFontRef) _backingCGSFont;
+ at end
+
+//typedef unsigned short IFGlyphWidth;
+
+#endif
+
+ at protocol IFLayoutFragment <NSObject>
+- (void)setGlyphRange: (NSRange)r;
+- (NSRange)glyphRange;
+- (void)setBoundingRect: (NSRect)r;
+- (NSRect)boundingRect;
+
+#ifdef _DEBUG_LAYOUT_FRAGMENT
+- (int)accessCount;
+#endif
+
+ at end
+
+ at interface IFSmallLayoutFragment : NSObject <IFLayoutFragment>
+{
+    // Assumes 0,0 boundingRect origin and < UINT16_MAX width and height,
+    // and loss of precision for float to short is irrelevant.
+    unsigned short width;
+    unsigned short height;
+
+    // Assumes 0 location and < UINT16_MAX length.
+    unsigned short glyphRangeLength;
+#ifdef _DEBUG_LAYOUT_FRAGMENT
+    int accessCount;
+#endif
+}
+ at end
+
+ at interface IFLargeLayoutFragment : NSObject <IFLayoutFragment>
+{
+    NSRect boundingRect;
+    NSRange glyphRange;
+#ifdef _DEBUG_LAYOUT_FRAGMENT
+    int accessCount;
+#endif
+}
+ at end
+
+ at implementation IFSmallLayoutFragment
 - (NSRange)glyphRange
 {
     NSRange glyphRange;
@@ -110,7 +156,7 @@ static inline int ROUND_TO_INT (float x)
 
 @end
 
- at implementation KWQLargeLayoutFragment
+ at implementation IFLargeLayoutFragment
 - (NSRange)glyphRange
 {
     return glyphRange;
@@ -153,13 +199,6 @@ static inline int ROUND_TO_INT (float x)
 
 @end
 
-static NSMutableDictionary *metricsCache = nil;
-
-/*
-    
-*/
- at implementation KWQLayoutInfo
-
 #ifdef DIRECT_TO_CG
 
 static void __IFInitATSGlyphVector(ATSGlyphVector *glyphVector, UInt32 numGlyphs) {
@@ -253,126 +292,9 @@ static void ConvertCharactersToGlyphs(ATSStyleGroupPtr styleGroup, const UniChar
 
 #endif
 
-- (void)drawString: (NSString *)string atPoint: (NSPoint)p withFont: (NSFont *)aFont color: (NSColor *)color
-{
-#ifdef DIRECT_TO_CG
-    UniChar localBuffer[LOCAL_GLYPH_BUFFER_SIZE];
-    const UniChar *_internalBuffer = CFStringGetCharactersPtr ((CFStringRef)string);
-    const UniChar *internalBuffer;
-
-    if (!_internalBuffer){
-        // FIXME: Handle case where length > LOCAL_GLYPH_BUFFER_SIZE
-        CFStringGetCharacters((CFStringRef)string, CFRangeMake(0, CFStringGetLength((CFStringRef)string)), &localBuffer[0]);
-        internalBuffer = &localBuffer[0];
-    }
-    else
-        internalBuffer = _internalBuffer;
-
-    CGContextRef cgContext;
-
-    __IFInitATSGlyphVector(&_glyphVector, [string length]);
-
-    ConvertCharactersToGlyphs(_styleGroup, internalBuffer, [string length], &_glyphVector);
-
-    [color set];
-    [aFont set];
-    
-    if ([aFont glyphPacking] != NSNativeShortGlyphPacking &&
-        [aFont glyphPacking] != NSTwoByteGlyphPacking)
-        [NSException raise:NSInternalInconsistencyException format:@"%@: Don't know how to deal with font %@", self, [aFont displayName]];
-        
-    {
-        int i, numGlyphs = _glyphVector.numGlyphs;
-        char localGlyphBuf[LOCAL_GLYPH_BUFFER_SIZE];
-        char *usedGlyphBuf, *glyphBufPtr, *glyphBuf = 0;
-        ATSLayoutRecord *glyphRecords = (ATSLayoutRecord *)_glyphVector.firstRecord;
-        
-        if (numGlyphs > LOCAL_GLYPH_BUFFER_SIZE/2)
-            usedGlyphBuf = glyphBufPtr = glyphBuf = (char *)malloc (numGlyphs * 2);
-        else
-            usedGlyphBuf = glyphBufPtr = &localGlyphBuf[0];
-            
-        for (i = 0; i < numGlyphs; i++){
-            *glyphBufPtr++ = (char)((glyphRecords->glyphID >> 8) & 0x00FF);
-            *glyphBufPtr++ = (char)(glyphRecords->glyphID & 0x00FF);
-            glyphRecords++;
-        }
-        cgContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
-        CGContextSetCharacterSpacing(cgContext, 0.0);
-        //CGContextShowGlyphsAtPoint (cgContext, p.x, p.y + lineHeight - 1 - ROUND_TO_INT(-[font descender]), (const short unsigned int *)usedGlyphBuf, numGlyphs);
-        CGContextShowGlyphsAtPoint (cgContext, p.x, p.y + [font defaultLineHeightForFont] - 1, (const short unsigned int *)usedGlyphBuf, numGlyphs);
-        
-        if (glyphBuf)
-            free (glyphBuf);
-    }
-
-    __IFResetATSGlyphVector(&_glyphVector);
-#else
-    id <KWQLayoutFragment> frag = [storage getFragmentForString: (NSString *)string];
-    NSLog (@"WARNING:  Unable to use CG for drawString:atPoint:withFont:color:\n");
-
-    [self setColor: color];
-    [textStorage setAttributes: [layoutInfo attributes]];
-    [textStorage setString: string];
-    [layoutManager drawGlyphsForGlyphRange:[frag glyphRange] atPoint:p];
-#endif
-}
-
-
-+ (void)drawString: (NSString *)string atPoint: (NSPoint)p withFont: (NSFont *)aFont color: (NSColor *)color
-{
-    KWQLayoutInfo *layoutInfo = [KWQLayoutInfo getMetricsForFont: aFont];
-    [layoutInfo drawString: string atPoint: p withFont: aFont color: color];
-}
-
-
-- (void)drawUnderlineForString: (NSString *)string atPoint: (NSPoint)p withFont: (NSFont *)aFont color: (NSColor *)color
-{
-#ifdef DIRECT_TO_CG
-    NSRect rect = [self rectForString: string];
-    NSGraphicsContext *graphicsContext = [NSGraphicsContext currentContext];
-    CGContextRef cgContext;
-    float lineWidth;
-    
-    [color set];
-
-    BOOL flag = [graphicsContext shouldAntialias];
-
-    [graphicsContext setShouldAntialias: NO];
-
-    cgContext = (CGContextRef)[graphicsContext graphicsPort];
-    lineWidth = 0.0;
-    if ([graphicsContext isDrawingToScreen] && lineWidth == 0.0) {
-        CGSize size = CGSizeApplyAffineTransform(CGSizeMake(1.0, 1.0), CGAffineTransformInvert(CGContextGetCTM(cgContext)));
-        lineWidth = size.width;
-    }
-    CGContextSetLineWidth(cgContext, lineWidth);
-    ///CGContextMoveToPoint(cgContext, p.x, p.y + lineHeight + 0.5 - ROUND_TO_INT(-[font descender]));
-    //CGContextAddLineToPoint(cgContext, p.x + rect.size.width, p.y + lineHeight + 0.5 - ROUND_TO_INT(-[font descender]));
-    CGContextMoveToPoint(cgContext, p.x, p.y + [font defaultLineHeightForFont] + 0.5);
-    CGContextAddLineToPoint(cgContext, p.x + rect.size.width, p.y + [font defaultLineHeightForFont] + 0.5);
-    CGContextStrokePath(cgContext);
-
-    [graphicsContext setShouldAntialias: flag];
-    
-#else
-    id <KWQLayoutFragment>frag = [storage getFragmentForString: (NSString *)string];
-
-    [self setColor: color];
-    [textStorage setAttributes: [self attributes]];
-    [textStorage setString: string];
-    NSRect lineRect = [self lineFragmentRectForGlyphAtIndex: 0 effectiveRange: 0];
-    [self underlineGlyphRange:[frag glyphRange] underlineType:NSSingleUnderlineStyle lineFragmentRect:lineRect lineFragmentGlyphRange:[frag glyphRange] containerOrigin:p];
-#endif
-}
-
-+ (void)drawUnderlineForString: (NSString *)string atPoint: (NSPoint)p withFont: (NSFont *)aFont color: (NSColor *)color
-{
-    KWQLayoutInfo *layoutInfo = [KWQLayoutInfo getMetricsForFont: aFont];
-    
-    [layoutInfo drawUnderlineForString: string atPoint: p withFont: aFont color: color];
-}
+#if 0
 
+ at implementation IFLayoutInfo
 
 #ifdef _DEBUG_LAYOUT_FRAGMENT
 + (void)_dumpLayoutCache: (NSDictionary *)fragCache
@@ -380,7 +302,7 @@ static void ConvertCharactersToGlyphs(ATSStyleGroupPtr styleGroup, const UniChar
     int i, count;
     NSArray *stringKeys;
     NSString *string;
-    id <KWQLayoutFragment>fragment;
+    id <IFLayoutFragment>fragment;
 
     if (fragCache == nil){
         fprintf (stdout, "Fragment cache empty\n");
@@ -402,7 +324,7 @@ static void ConvertCharactersToGlyphs(ATSStyleGroupPtr styleGroup, const UniChar
     int i, count;
     NSFont *font;
     NSArray *fontKeys;
-    KWQLayoutInfo *layoutInfo;
+    IFLayoutInfo *layoutInfo;
     int totalObjects = 0;
     
     fontKeys = [metricsCache allKeys];
@@ -411,7 +333,7 @@ static void ConvertCharactersToGlyphs(ATSStyleGroupPtr styleGroup, const UniChar
         font = [fontKeys objectAtIndex: i];
         layoutInfo = [metricsCache objectForKey: [fontKeys objectAtIndex: i]];
         fprintf (stdout, "Cache information for font %s %f (%d objects)\n", [[font displayName] cString],[font pointSize], [[[layoutInfo textStorage] fragmentCache] count]);
-        [KWQLayoutInfo _dumpLayoutCache: [[layoutInfo textStorage] fragmentCache]];
+        [IFLayoutInfo _dumpLayoutCache: [[layoutInfo textStorage] fragmentCache]];
         totalObjects += [[[layoutInfo textStorage] fragmentCache] count];
     }
     fprintf (stdout, "Total cached objects %d\n", totalObjects);
@@ -420,19 +342,19 @@ static void ConvertCharactersToGlyphs(ATSStyleGroupPtr styleGroup, const UniChar
 #endif
 
 
-+ (KWQLayoutInfo *)getMetricsForFont: (NSFont *)aFont
++ (IFLayoutInfo *)getMetricsForFont: (NSFont *)aFont
 {
-    KWQLayoutInfo *info = (KWQLayoutInfo *)[metricsCache objectForKey: aFont];
+    IFLayoutInfo *info = (IFLayoutInfo *)[metricsCache objectForKey: aFont];
     if (info == nil){
-        info = [[KWQLayoutInfo alloc] initWithFont: aFont];
-        [KWQLayoutInfo setMetric: info forFont: aFont];
+        info = [[IFLayoutInfo alloc] initWithFont: aFont];
+        [IFLayoutInfo setMetric: info forFont: aFont];
         [info release];
     }
     return info;
 }
 
 
-+ (void)setMetric: (KWQLayoutInfo *)info forFont: (NSFont *)aFont
++ (void)setMetric: (IFLayoutInfo *)info forFont: (NSFont *)aFont
 {
     if (metricsCache == nil)
         metricsCache = [[NSMutableDictionary alloc] init];
@@ -442,64 +364,22 @@ static void ConvertCharactersToGlyphs(ATSStyleGroupPtr styleGroup, const UniChar
 
 - initWithFont: (NSFont *)aFont
 {
-    OSStatus errCode;
-
     [super init];
 
     font = [aFont retain];
     lineHeight = ROUND_TO_INT([font ascender]) + ROUND_TO_INT(-[font descender]) + 1;
 
-#ifdef DIRECT_TO_CG
-    ATSUStyle style;
-    
-    if ((errCode = ATSUCreateStyle(&style)) != noErr)
-        [NSException raise:NSInternalInconsistencyException format:@"%@: Failed to alloc ATSUStyle %d", self, errCode];
-
-    __IFFillStyleWithAttributes(style, aFont);
-
-    if ((errCode = ATSUGetStyleGroup(style, &_styleGroup)) != noErr) {
-        [NSException raise:NSInternalInconsistencyException format:@"%@: Failed to create attribute group from ATSUStyle 0x%X %d", self, style, errCode];
-    }
-    
-    ATSUDisposeStyle(style);
-#else
-    textStorage = [[KWQTextStorage alloc] initWithFontAttribute: attributes];
-    layoutManager = [[NSLayoutManager alloc] init];
-
-    [layoutManager addTextContainer: [KWQTextContainer sharedInstance]];
-    [textStorage addLayoutManager: layoutManager];    
-
-    attributes = [[NSMutableDictionary dictionaryWithObjectsAndKeys:aFont, NSFontAttributeName, nil] retain];
-#endif
     return self;
 }
 
+ at end
 
-- (NSLayoutManager *)layoutManager
-{
-#ifdef DIRECT_TO_CG
-    return nil;
-#else
-    return layoutManager;
-#endif
-}
-
-
-- (KWQTextStorage *)textStorage
-{
-#ifdef DIRECT_TO_CG
-    return nil;
-#else
-    return textStorage;
 #endif
-}
 
-#define CONTEXT_DPI    (72.0)
-#define ScaleEmToUnits(X, U_PER_EM)    (X * ((1.0 * CONTEXT_DPI) / (CONTEXT_DPI * U_PER_EM)))
-#define ScaleUnitsToPoints(F, POINTS)  (F * POINTS)
+ at implementation IFCachedTextRenderer
 
 #ifdef DIRECT_TO_CG
-- (void)_initializeCaches
+- (void)initializeCaches
 {
     unsigned int i, glyphsToCache;
     int errorResult;
@@ -507,7 +387,7 @@ static void ConvertCharactersToGlyphs(ATSStyleGroupPtr styleGroup, const UniChar
     short unsigned int sequentialGlyphs[INITIAL_GLYPH_CACHE_MAX];
     ATSLayoutRecord *glyphRecords;
 
-    KWQDEBUGLEVEL (KWQ_LOG_FONTCACHE, "Caching %s %.0f (%ld glyphs) ascent = %f, descent = %f, defaultLineHeightForFont = %f\n", [[font displayName] cString], [font pointSize], numGlyphsInFont, [font ascender], [font descender], [font defaultLineHeightForFont]); 
+    WEBKITDEBUGLEVEL (WEBKIT_LOG_FONTCACHE, "Caching %s %.0f (%ld glyphs) ascent = %f, descent = %f, defaultLineHeightForFont = %f\n", [[font displayName] cString], [font pointSize], numGlyphsInFont, [font ascender], [font descender], [font defaultLineHeightForFont]); 
 
     // Initially just cache the max of number of glyphs in font or
     // INITIAL_GLYPH_CACHE_MAX.  Holes in the cache will be filled on demand
@@ -520,7 +400,7 @@ static void ConvertCharactersToGlyphs(ATSStyleGroupPtr styleGroup, const UniChar
     for (i = 0; i < glyphsToCache; i++)
         sequentialGlyphs[i] = i;
         
-    widthCache = (_IFGlyphWidth *)calloc (1, widthCacheSize * sizeof(_IFGlyphWidth));
+    widthCache = (IFGlyphWidth *)calloc (1, widthCacheSize * sizeof(IFGlyphWidth));
     
     // Some glyphs can have zero width, so we have to use a non-zero value
     // in empty slots to indicate they are uninitialized.
@@ -544,7 +424,7 @@ static void ConvertCharactersToGlyphs(ATSStyleGroupPtr styleGroup, const UniChar
 
     ATSGlyphVector latinGlyphVector;
     ATSInitializeGlyphVector(latinCount, 0, &latinGlyphVector);
-    ConvertCharactersToGlyphs(_styleGroup, &latinBuffer[FIRST_CACHE_CHARACTER], latinCount, &latinGlyphVector);
+    ConvertCharactersToGlyphs(styleGroup, &latinBuffer[FIRST_CACHE_CHARACTER], latinCount, &latinGlyphVector);
     if (latinGlyphVector.numGlyphs != latinCount)
         [NSException raise:NSInternalInconsistencyException format:@"Optimization assumption violation:  ascii and glyphID count not equal - for %@ %f", self, [font displayName], [font pointSize]];
         
@@ -560,21 +440,234 @@ static void ConvertCharactersToGlyphs(ATSStyleGroupPtr styleGroup, const UniChar
 #ifdef DEBUG_CACHE_SIZE
     static int totalCacheSize = 0;
     
-    totalCacheSize += widthCacheSize * sizeof(_IFGlyphWidth) + numGlyphs * sizeof(ATSGlyphRef) + sizeof(KWQLayoutInfo);
-    KWQDEBUGLEVEL (KWQ_LOG_MEMUSAGE, "memory usage in bytes:  widths = %ld, latin1 ext. character-to-glyph = %ld, total this cache = %ld, total all caches %d\n", widthCacheSize * sizeof(_IFGlyphWidth), numGlyphs * sizeof(ATSGlyphRef), widthCacheSize * sizeof(_IFGlyphWidth) + numGlyphs * sizeof(ATSGlyphRef) + sizeof(KWQLayoutInfo), totalCacheSize); 
+    totalCacheSize += widthCacheSize * sizeof(IFGlyphWidth) + numGlyphs * sizeof(ATSGlyphRef) + sizeof(*self);
+    WEBKITDEBUGLEVEL (WEBKIT_LOG_MEMUSAGE, "memory usage in bytes:  widths = %ld, latin1 ext. character-to-glyph = %ld, total this cache = %ld, total all caches %d\n", widthCacheSize * sizeof(IFGlyphWidth), numGlyphs * sizeof(ATSGlyphRef), widthCacheSize * sizeof(IFGlyphWidth) + numGlyphs * sizeof(ATSGlyphRef) + sizeof(*self), totalCacheSize); 
 #endif
 }
 
+#endif
 
-static NSRect _rectForString (KWQLayoutInfo *self, const UniChar *internalBuffer, unsigned int stringLength)
+- initWithFont:(NSFont *)f
+{
+    [super init];
+    
+    font = [f retain];
+    ascent = -1;
+    descent = -1;
+    lineSpacing = -1;
+    
+#ifdef DIRECT_TO_CG
+    OSStatus errCode;
+    ATSUStyle style;
+    
+    if ((errCode = ATSUCreateStyle(&style)) != noErr)
+        [NSException raise:NSInternalInconsistencyException format:@"%@: Failed to alloc ATSUStyle %d", self, errCode];
+
+    __IFFillStyleWithAttributes(style, font);
+
+    if ((errCode = ATSUGetStyleGroup(style, &styleGroup)) != noErr) {
+        [NSException raise:NSInternalInconsistencyException format:@"%@: Failed to create attribute group from ATSUStyle 0x%X %d", self, style, errCode];
+    }
+    
+    ATSUDisposeStyle(style);
+#else
+    textStorage = [[KWQTextStorage alloc] initWithFontAttribute: attributes];
+    layoutManager = [[NSLayoutManager alloc] init];
+
+    [layoutManager addTextContainer: [KWQTextContainer sharedInstance]];
+    [textStorage addLayoutManager: layoutManager];    
+
+    attributes = [[NSMutableDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil] retain];
+#endif
+
+    return self;
+}
+
+- (void)dealloc
+{
+    [font release];
+
+    if (styleGroup)
+        ATSUDisposeStyleGroup(styleGroup);
+    if (glyphVector.numAllocatedGlyphs > 0)
+        ATSClearGlyphVector(&glyphVector);
+    free(widthCache);
+    free(characterToGlyph);
+    
+    [super dealloc];
+}
+
+- (int)widthForString:(NSString *)string
+{
+#ifdef DIRECT_TO_CG
+    UniChar localBuffer[LOCAL_GLYPH_BUFFER_SIZE];
+    const UniChar *_internalBuffer = CFStringGetCharactersPtr ((CFStringRef)string);
+    const UniChar *internalBuffer;
+
+    if (!_internalBuffer) {
+        // FIXME: What if string is larger than LOCAL_GLYPH_BUFFER_SIZE?
+        CFStringGetCharacters((CFStringRef)string, CFRangeMake(0, CFStringGetLength((CFStringRef)string)), &localBuffer[0]);
+        internalBuffer = &localBuffer[0];
+    }
+    else
+        internalBuffer = _internalBuffer;
+
+    return [self widthForCharacters:internalBuffer length:[string length]];
+#else
+    id <IFLayoutFragment> cachedFragment;
+
+    cachedFragment = [textStorage getFragmentForString: string];
+    
+    return [cachedFragment boundingRect];
+#endif
+}
+
+- (int)ascent
+{
+    if (ascent < 0)  {
+        ascent = ROUND_TO_INT([font ascender]);
+    }
+    return ascent;
+}
+
+- (int)descent
+{
+    if (descent < 0)  {
+        descent = ROUND_TO_INT(-[font descender]);
+    }
+    return descent;
+}
+
+- (int)lineSpacing
+{
+    if (lineSpacing < 0) {
+        lineSpacing = ROUND_TO_INT([font defaultLineHeightForFont]);
+    }
+    return lineSpacing;
+}
+
+- (void)drawString:(NSString *)string atPoint:(NSPoint)point withColor:(NSColor *)color
+{
+    // This will draw the text from the top of the bounding box down.
+    // Qt expects to draw from the baseline.
+    // Remember that descender is negative.
+    point.y -= [self lineSpacing] - [self descent];
+    
+#ifdef DIRECT_TO_CG
+    UniChar localBuffer[LOCAL_GLYPH_BUFFER_SIZE];
+    const UniChar *_internalBuffer = CFStringGetCharactersPtr ((CFStringRef)string);
+    const UniChar *internalBuffer;
+
+    if (!_internalBuffer){
+        // FIXME: Handle case where length > LOCAL_GLYPH_BUFFER_SIZE
+        CFStringGetCharacters((CFStringRef)string, CFRangeMake(0, CFStringGetLength((CFStringRef)string)), &localBuffer[0]);
+        internalBuffer = &localBuffer[0];
+    }
+    else
+        internalBuffer = _internalBuffer;
+
+    CGContextRef cgContext;
+
+    __IFInitATSGlyphVector(&glyphVector, [string length]);
+
+    ConvertCharactersToGlyphs(styleGroup, internalBuffer, [string length], &glyphVector);
+
+    [color set];
+    [font set];
+    
+    if ([font glyphPacking] != NSNativeShortGlyphPacking &&
+        [font glyphPacking] != NSTwoByteGlyphPacking)
+        [NSException raise:NSInternalInconsistencyException format:@"%@: Don't know how to deal with font %@", self, [font displayName]];
+        
+    {
+        int i, numGlyphs = glyphVector.numGlyphs;
+        char localGlyphBuf[LOCAL_GLYPH_BUFFER_SIZE];
+        char *usedGlyphBuf, *glyphBufPtr, *glyphBuf = 0;
+        ATSLayoutRecord *glyphRecords = (ATSLayoutRecord *)glyphVector.firstRecord;
+        
+        if (numGlyphs > LOCAL_GLYPH_BUFFER_SIZE/2)
+            usedGlyphBuf = glyphBufPtr = glyphBuf = (char *)malloc (numGlyphs * 2);
+        else
+            usedGlyphBuf = glyphBufPtr = &localGlyphBuf[0];
+            
+        for (i = 0; i < numGlyphs; i++){
+            *glyphBufPtr++ = (char)((glyphRecords->glyphID >> 8) & 0x00FF);
+            *glyphBufPtr++ = (char)(glyphRecords->glyphID & 0x00FF);
+            glyphRecords++;
+        }
+        cgContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
+        CGContextSetCharacterSpacing(cgContext, 0.0);
+        //CGContextShowGlyphsAtPoint (cgContext, p.x, p.y + lineHeight - 1 - ROUND_TO_INT(-[font descender]), (const short unsigned int *)usedGlyphBuf, numGlyphs);
+        CGContextShowGlyphsAtPoint (cgContext, point.x, point.y + [font defaultLineHeightForFont] - 1, (const short unsigned int *)usedGlyphBuf, numGlyphs);
+        
+        if (glyphBuf)
+            free (glyphBuf);
+    }
+
+    __IFResetATSGlyphVector(&glyphVector);
+#else
+    id <IFLayoutFragment> frag = [storage getFragmentForString: (NSString *)string];
+    NSLog (@"WARNING:  Unable to use CG for drawString:atPoint:withFont:color:\n");
+
+    [self setColor: color];
+    [textStorage setAttributes: [layoutInfo attributes]];
+    [textStorage setString: string];
+    [layoutManager drawGlyphsForGlyphRange:[frag glyphRange] atPoint:p];
+#endif
+}
+
+- (void)drawUnderlineForString:(NSString *)string atPoint:(NSPoint)point withColor:(NSColor *)color
+{
+    // This will draw the text from the top of the bounding box down.
+    // Qt expects to draw from the baseline.
+    // Remember that descender is negative.
+    point.y -= [self lineSpacing] - [self descent];
+    
+#ifdef DIRECT_TO_CG
+    int width = [self widthForString: string];
+    NSGraphicsContext *graphicsContext = [NSGraphicsContext currentContext];
+    CGContextRef cgContext;
+    float lineWidth;
+    
+    [color set];
+
+    BOOL flag = [graphicsContext shouldAntialias];
+
+    [graphicsContext setShouldAntialias: NO];
+
+    cgContext = (CGContextRef)[graphicsContext graphicsPort];
+    lineWidth = 0.0;
+    if ([graphicsContext isDrawingToScreen] && lineWidth == 0.0) {
+        CGSize size = CGSizeApplyAffineTransform(CGSizeMake(1.0, 1.0), CGAffineTransformInvert(CGContextGetCTM(cgContext)));
+        lineWidth = size.width;
+    }
+    CGContextSetLineWidth(cgContext, lineWidth);
+    ///CGContextMoveToPoint(cgContext, p.x, p.y + lineHeight + 0.5 - ROUND_TO_INT(-[font descender]));
+    //CGContextAddLineToPoint(cgContext, p.x + rect.size.width, p.y + lineHeight + 0.5 - ROUND_TO_INT(-[font descender]));
+    CGContextMoveToPoint(cgContext, point.x, point.y + [font defaultLineHeightForFont] + 0.5);
+    CGContextAddLineToPoint(cgContext, point.x + width, point.y + [font defaultLineHeightForFont] + 0.5);
+    CGContextStrokePath(cgContext);
+
+    [graphicsContext setShouldAntialias: flag];
+    
+#else
+    id <IFLayoutFragment>frag = [storage getFragmentForString: (NSString *)string];
+
+    [self setColor: color];
+    [textStorage setAttributes: [self attributes]];
+    [textStorage setString: string];
+    NSRect lineRect = [self lineFragmentRectForGlyphAtIndex: 0 effectiveRange: 0];
+    [self underlineGlyphRange:[frag glyphRange] underlineType:NSSingleUnderlineStyle lineFragmentRect:lineRect lineFragmentGlyphRange:[frag glyphRange] containerOrigin:p];
+#endif
+}
+
+- (int)widthForCharacters:(const UniChar *)characters length:(unsigned)length
 {
     float totalWidth = 0;
     unsigned int i, index;
     int glyphID;
     ATSLayoutRecord *glyphRecords;
-    NSFont *font = [self font];
     unsigned int numGlyphs;
-    _IFGlyphWidth *widthCache;
     
     ATSGlyphRef localCharacterToGlyph[LOCAL_GLYPH_BUFFER_SIZE];
     ATSGlyphRef *usedCharacterToGlyph, *allocateCharacterToGlyph = 0;
@@ -598,9 +691,8 @@ static NSRect _rectForString (KWQLayoutInfo *self, const UniChar *internalBuffer
         [font glyphPacking] != NSTwoByteGlyphPacking)
 	[NSException raise:NSInternalInconsistencyException format:@"%@: Don't know how to pack glyphs for font %@ %f", self, [font displayName], [font pointSize]];
     
-    if (self->widthCache == 0)
-        [self _initializeCaches];
-    widthCache = self->widthCache;
+    if (widthCache == 0)
+        [self initializeCaches];
     
     // Pass 1:
     // Check if we can use the cached character-to-glyph map.  We only use the character-to-glyph map
@@ -608,8 +700,8 @@ static NSRect _rectForString (KWQLayoutInfo *self, const UniChar *internalBuffer
     // to ensure that we don't match composable characters incorrectly.  This check could
     // be smarter.  Also the character-to-glyph could be extended to support other ranges
     // of unicode.  For now, we only optimize for latin1.
-    for (i = 0; i < stringLength; i++){
-        if (internalBuffer[i] < FIRST_CACHE_CHARACTER || internalBuffer[i] > LAST_CACHE_CHARACTER){
+    for (i = 0; i < length; i++){
+        if (characters[i] < FIRST_CACHE_CHARACTER || characters[i] > LAST_CACHE_CHARACTER){
             needCharToGlyphLookup = YES;
             break;
         }
@@ -618,11 +710,11 @@ static NSRect _rectForString (KWQLayoutInfo *self, const UniChar *internalBuffer
     // If we can't use the cached map, then calculate a map for this string.   Expensive.
     if (needCharToGlyphLookup){
         
-        KWQDEBUGLEVEL(KWQ_LOG_FONTCACHECHARMISS, "character-to-glyph cache miss for character 0x%04x in %s, %.0f\n", internalBuffer[i], [[font displayName] lossyCString], [font pointSize]);
-        __IFInitATSGlyphVector(&self->_glyphVector, stringLength);
-        ConvertCharactersToGlyphs(self->_styleGroup, internalBuffer, stringLength, &self->_glyphVector);
-        glyphRecords = (ATSLayoutRecord *)self->_glyphVector.firstRecord;
-        numGlyphs = self->_glyphVector.numGlyphs;
+        WEBKITDEBUGLEVEL(WEBKIT_LOG_FONTCACHECHARMISS, "character-to-glyph cache miss for character 0x%04x in %s, %.0f\n", characters[i], [[font displayName] lossyCString], [font pointSize]);
+        __IFInitATSGlyphVector(&glyphVector, length);
+        ConvertCharactersToGlyphs(styleGroup, characters, length, &glyphVector);
+        glyphRecords = (ATSLayoutRecord *)glyphVector.firstRecord;
+        numGlyphs = glyphVector.numGlyphs;
 
         if (numGlyphs > LOCAL_GLYPH_BUFFER_SIZE)
             usedCharacterToGlyph = allocateCharacterToGlyph = (ATSGlyphRef *)calloc (1, numGlyphs * sizeof(ATSGlyphRef));
@@ -635,16 +727,16 @@ static NSRect _rectForString (KWQLayoutInfo *self, const UniChar *internalBuffer
             
             // Fill the block of glyphs for the glyph needed. If we're going to incur the overhead
             // of calling into CG, we may as well get a block of scaled glyph advances.
-            if (self->widthCache[glyphID] == UNITIALIZED_GLYPH_WIDTH){
+            if (widthCache[glyphID] == UNITIALIZED_GLYPH_WIDTH){
                 short unsigned int sequentialGlyphs[INCREMENTAL_GLYPH_CACHE_BLOCK];
                 unsigned int blockStart, blockEnd, blockID;
                 int errorResult;
                 
                 blockStart = (glyphID / INCREMENTAL_GLYPH_CACHE_BLOCK) * INCREMENTAL_GLYPH_CACHE_BLOCK;
                 blockEnd = blockStart + INCREMENTAL_GLYPH_CACHE_BLOCK;
-                if (blockEnd > self->widthCacheSize)
-                    blockEnd = self->widthCacheSize;
-                KWQDEBUGLEVEL (KWQ_LOG_FONTCACHE, "width cache miss for glyph 0x%04x in %s, %.0f, filling block 0x%04x to 0x%04x\n", glyphID, [[font displayName] cString], [font pointSize], blockStart, blockEnd);
+                if (blockEnd > widthCacheSize)
+                    blockEnd = widthCacheSize;
+                WEBKITDEBUGLEVEL (WEBKIT_LOG_FONTCACHE, "width cache miss for glyph 0x%04x in %s, %.0f, filling block 0x%04x to 0x%04x\n", glyphID, [[font displayName] cString], [font pointSize], blockStart, blockEnd);
                 for (blockID = blockStart; blockID < blockEnd; blockID++)
                     sequentialGlyphs[blockID-blockStart] = blockID;
 
@@ -654,11 +746,11 @@ static NSRect _rectForString (KWQLayoutInfo *self, const UniChar *internalBuffer
             }
         }
 
-        __IFResetATSGlyphVector(&self->_glyphVector);
+        __IFResetATSGlyphVector(&glyphVector);
     }
     else {
-        numGlyphs = stringLength;
-        usedCharacterToGlyph = self->characterToGlyph;
+        numGlyphs = length;
+        usedCharacterToGlyph = characterToGlyph;
     }
     
     // Pass 2:
@@ -673,268 +765,21 @@ static NSRect _rectForString (KWQLayoutInfo *self, const UniChar *internalBuffer
     }
     else {
         for (i = 0; i < numGlyphs; i++){
-            index = internalBuffer[i]-FIRST_CACHE_CHARACTER;
+            index = characters[i]-FIRST_CACHE_CHARACTER;
             totalWidth += widthCache[usedCharacterToGlyph[index]];
         }
     }
     
-    return NSMakeRect (0,0,totalWidth, (float)self->lineHeight);
-}
-#endif
-
-
-- (NSRect)rectForString:(NSString *)string
- {
-#ifdef DIRECT_TO_CG
-    UniChar localBuffer[LOCAL_GLYPH_BUFFER_SIZE];
-    const UniChar *_internalBuffer = CFStringGetCharactersPtr ((CFStringRef)string);
-    const UniChar *internalBuffer;
-
-    if (!_internalBuffer){
-        CFStringGetCharacters((CFStringRef)string, CFRangeMake(0, CFStringGetLength((CFStringRef)string)), &localBuffer[0]);
-        internalBuffer = &localBuffer[0];
-    }
-    else
-        internalBuffer = _internalBuffer;
-
-    return _rectForString (self, internalBuffer, [string length]);
-#else
-    id <KWQLayoutFragment> cachedFragment;
-
-    cachedFragment = [textStorage getFragmentForString: string];
-    
-    return [cachedFragment boundingRect];
-#endif
-}
-
-
-- (void)setColor: (NSColor *)color
-{
-#ifndef DIRECT_TO_CG
-    [attributes setObject: color forKey: NSForegroundColorAttributeName];
-#endif
-}
-
-- (NSDictionary *)attributes
-{
-#ifdef DIRECT_TO_CG
-    return nil;
-#else
-    return attributes;
-#endif
-}
-
-- (int)lineHeight
-{
-    return lineHeight;
+    return totalWidth;
 }
 
-- (NSFont *)font
+- (void)drawString:(NSString *)string inRect:(NSRect)rect withColor:(NSColor *)color paragraphStyle:(NSParagraphStyle *)style
 {
-    return font;
-}
-
-- (void)dealloc
-{
-    [font release];
-#ifdef DIRECT_TO_CG
-    if (_styleGroup)
-        ATSUDisposeStyleGroup(_styleGroup);
-    if (_glyphVector.numAllocatedGlyphs > 0)
-        ATSClearGlyphVector(&_glyphVector);
-    free(widthCache);
-    free(characterToGlyph);
-#else
-    [attributes release];
-#endif
-    [super dealloc];
+    [string drawInRect:rect withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
+        font, NSFontAttributeName,
+        color, NSForegroundColorAttributeName,
+        style, NSParagraphStyleAttributeName,
+        nil]];
 }
 
 @end
-
-
-struct QFontMetricsPrivate {
-    QFontMetricsPrivate(NSFont *aFont)
-    {
-        refCount = 0;
-        font = [aFont retain];
-        info = nil;
-        ascent = -1;
-        descent = -1;
-        lineSpacing = -1;
-    }
-    ~QFontMetricsPrivate()
-    {
-        [info release];
-        [font release];
-    }
-    KWQLayoutInfo *getInfo();
-    int refCount;
-    NSFont *font;
-    int ascent;
-    int descent;
-    int lineSpacing;
-private:
-    KWQLayoutInfo *info;
-};
-
-KWQLayoutInfo *QFontMetricsPrivate::getInfo()
-{
-    if (!info)
-        info = [[KWQLayoutInfo getMetricsForFont:font] retain];
-    return info;
-}
-
-QFontMetrics::QFontMetrics()
-{
-}
-
-QFontMetrics::QFontMetrics(const QFont &withFont)
-: data(new QFontMetricsPrivate(const_cast<QFont&>(withFont).getFont()))
-{
-}
-
-QFontMetrics::QFontMetrics(const QFontMetrics &withFont)
-: data(withFont.data)
-{
-}
-
-QFontMetrics::~QFontMetrics()
-{
-}
-
-QFontMetrics &QFontMetrics::operator=(const QFontMetrics &withFont)
-{
-    data = withFont.data;
-    return *this;
-}
-
-int QFontMetrics::baselineOffset() const
-{
-    return ascent();
-}
-
-int QFontMetrics::ascent() const
-{
-    if (data->ascent < 0)
-        data->ascent = ROUND_TO_INT([data->font ascender]);
-    return data->ascent;
-}
-
-int QFontMetrics::descent() const
-{
-    if (data->descent < 0)
-        data->descent = ROUND_TO_INT(-[data->font descender]);
-    return data->descent;
-}
-
-int QFontMetrics::height() const
-{
-    // According to Qt documentation: 
-    // "This is always equal to ascent()+descent()+1 (the 1 is for the base line)."
-    return ascent() + descent() + 1;
-}
-
-int QFontMetrics::lineSpacing() const
-{
-    if (data->lineSpacing < 0)
-        data->lineSpacing = ROUND_TO_INT([data->font defaultLineHeightForFont]);
-    return data->lineSpacing;
-}
-
-int QFontMetrics::width(QChar qc) const
-{
-    unichar c = qc.unicode();
-    return ROUND_TO_INT(_rectForString(data->getInfo(), &c, 1).size.width);
-}
-
-int QFontMetrics::width(char c) const
-{
-    unichar ch = (uchar) c;
-    return ROUND_TO_INT(_rectForString(data->getInfo(), &ch, 1).size.width);
-}
-
-int QFontMetrics::width(const QString &qstring, int len) const
-{
-    NSString *string;
-
-    if (len != -1)
-        string = QSTRING_TO_NSSTRING_LENGTH (qstring, len);
-    else
-        string = _FAST_QSTRING_TO_NSSTRING (qstring);
-    return ROUND_TO_INT([data->getInfo() rectForString: string].size.width);
-}
-
-int QFontMetrics::_width(const QChar *uchars, int len) const
-{
-    return ROUND_TO_INT(_rectForString(data->getInfo(), (const UniChar *)uchars, len).size.width);
-}
-
-
-int QFontMetrics::_width(CFStringRef string) const
-{
-    return ROUND_TO_INT([data->getInfo() rectForString: (NSString *)string].size.width);
-}
-
-QRect QFontMetrics::boundingRect(const QString &qstring, int len) const
-{
-    NSString *string;
-
-    if (len != -1)
-        string = QSTRING_TO_NSSTRING_LENGTH (qstring, len);
-    else
-        string = _FAST_QSTRING_TO_NSSTRING (qstring);
-    NSRect rect = [data->getInfo() rectForString: string];
-
-    return QRect(ROUND_TO_INT(rect.origin.x),
-            ROUND_TO_INT(rect.origin.y),
-            ROUND_TO_INT(rect.size.width),
-            ROUND_TO_INT(rect.size.height));
-}
-
-QRect QFontMetrics::boundingRect(int x, int y, int width, int height, int flags, const QString &str) const
-{
-    // FIXME: need to support word wrapping
-    return QRect(x,y, width, height).intersect(boundingRect(str));
-}
-
-QRect QFontMetrics::boundingRect(QChar qc) const
-{
-    unichar c = qc.unicode();
-    NSRect rect = _rectForString(data->getInfo(), &c, 1);
-
-    return QRect(ROUND_TO_INT(rect.origin.x),
-            ROUND_TO_INT(rect.origin.y),
-            ROUND_TO_INT(rect.size.width),
-            ROUND_TO_INT(rect.size.height));
-}
-
-QSize QFontMetrics::size(int, const QString &qstring, int len, int tabstops, 
-    int *tabarray, char **intern ) const
-{
-    if (tabstops != 0){
-        KWQDEBUGLEVEL(KWQ_LOG_ERROR, "ERROR:  QFontMetrics::size() tabs not supported.\n");
-    }
-    
-    NSString *string;
-
-    if (len != -1)
-        string = QSTRING_TO_NSSTRING_LENGTH (qstring, len);
-    else
-        string = _FAST_QSTRING_TO_NSSTRING (qstring);
-    NSRect rect = [data->getInfo() rectForString: string];
-
-    return QSize (ROUND_TO_INT(rect.size.width),ROUND_TO_INT(rect.size.height));
-}
-
-int QFontMetrics::rightBearing(QChar) const
-{
-    _logNotYetImplemented();
-    return 0;
-}
-
-int QFontMetrics::leftBearing(QChar) const
-{
-    _logNotYetImplemented();
-    return 0;
-}
diff --git a/WebKit/WebCoreSupport.subproj/IFCachedTextRendererFactory.h b/WebKit/WebCoreSupport.subproj/IFCachedTextRendererFactory.h
new file mode 100644
index 0000000..f73be04
--- /dev/null
+++ b/WebKit/WebCoreSupport.subproj/IFCachedTextRendererFactory.h
@@ -0,0 +1,19 @@
+//
+//  IFCachedTextRendererFactory.h
+//  WebKit
+//
+//  Created by Darin Adler on Thu May 02 2002.
+//  Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+//
+
+#import <IFTextRendererFactory.h>
+
+ at interface IFCachedTextRendererFactory : IFTextRendererFactory
+{
+    NSMutableDictionary *cache;
+}
+
++ (void)createSharedFactory;
+- init;
+
+ at end
diff --git a/WebKit/WebCoreSupport.subproj/IFCachedTextRendererFactory.m b/WebKit/WebCoreSupport.subproj/IFCachedTextRendererFactory.m
new file mode 100644
index 0000000..cd9c1f0
--- /dev/null
+++ b/WebKit/WebCoreSupport.subproj/IFCachedTextRendererFactory.m
@@ -0,0 +1,159 @@
+//
+//  IFCachedTextRendererFactory.m
+//  WebKit
+//
+//  Created by Darin Adler on Thu May 02 2002.
+//  Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+//
+
+#import <WebKit/IFCachedTextRendererFactory.h>
+#import <WebKit/IFCachedTextRenderer.h>
+#import <WebKit/WebKitDebug.h>
+
+ at interface IFFontCacheKey : NSObject
+{
+    NSString *family;
+    NSFontTraitMask traits;
+    float size;
+}
+
+- initWithFamily:(NSString *)f traits:(NSFontTraitMask)t size:(float)s;
+
+ at end
+
+ at implementation IFFontCacheKey
+
+- initWithFamily:(NSString *)f traits:(NSFontTraitMask)t size:(float)s;
+{
+    [super init];
+    family = [f copy];
+    traits = t;
+    size = s;
+    return self;
+}
+
+- (void)dealloc
+{
+    [family release];
+    [super dealloc];
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+    return [self retain];
+}
+
+- (unsigned)hash
+{
+    return [family hash] ^ traits ^ (int)size;
+}
+
+- (BOOL)isEqual:(id)o
+{
+    IFFontCacheKey *other = o;
+    return [self class] == [other class]
+        && [family isEqual:other->family]
+        && traits == other->traits
+        && size == other->size;
+}
+
+ at end
+
+ at implementation IFCachedTextRendererFactory
+
++ (void)createSharedFactory;
+{
+    if (![IFTextRendererFactory sharedFactory]) {
+        [[[IFCachedTextRendererFactory alloc] init] release];
+    }
+    WEBKIT_ASSERT([[IFTextRendererFactory sharedFactory] isMemberOfClass:[IFCachedTextRendererFactory class]]);
+}
+
+- init
+{
+    [super init];
+    
+    cache = [[NSMutableDictionary alloc] init];
+    
+    return self;
+}
+
+- (void)dealloc
+{
+    [cache release];
+    
+    [super dealloc];
+}
+
+- (id <IFTextRenderer>)rendererWithFont:(NSFont *)font
+{
+    IFCachedTextRenderer *renderer = [cache objectForKey:font];
+    if (renderer == nil) {
+        renderer = [[IFCachedTextRenderer alloc] initWithFont:font];
+        [cache setObject:renderer forKey:font];
+        [renderer release];
+    }
+    return renderer;
+}
+
+- (NSFont *)fontWithFamily:(NSString *)family traits:(NSFontTraitMask)traits size:(float)size
+{
+    NSFont *font;
+    NSEnumerator *e;
+    NSString *availableFamily;
+    
+    font = [[NSFontManager sharedFontManager] fontWithFamily:family traits:traits weight:5 size:size];
+    if (font != nil) {
+        return font;
+    }
+    
+    // FIXME:  For now do a simple case insensitive search for a matching font.
+    // The font manager requires exact name matches.  This will at least address the problem
+    // of matching arial to Arial, etc.
+    e = [[[NSFontManager sharedFontManager] availableFontFamilies] objectEnumerator];
+    while ((availableFamily = [e nextObject])) {
+        if ([family caseInsensitiveCompare:availableFamily] == NSOrderedSame) {
+            font = [[NSFontManager sharedFontManager] fontWithFamily:availableFamily traits:traits weight:5 size:size];
+            if (font != nil) {
+                return font;
+            }
+        }
+    }
+            
+    WEBKITDEBUGLEVEL(WEBKIT_LOG_FONTCACHE, "unable to find font for family %s", [family lossyCString]);
+    return [[NSFontManager sharedFontManager] fontWithFamily:@"Helvetica" traits:traits weight:5 size:size];
+}
+
+- (NSFont *)cachedFontWithFamily:(NSString *)family traits:(NSFontTraitMask)traits size:(float)size
+{
+    static NSMutableDictionary *fontCache = nil;
+    NSString *fontKey;
+    NSFont *font;
+    
+#ifdef DEBUG_GETFONT
+    static int getFontCount = 0;
+    getFontCount++;
+    printf("getFountCount = %d, family = %s, traits = 0x%08x, size = %f\n", getFontCount, [_family lossyCString], _trait, _size);
+#endif
+
+    if (!fontCache) {
+        fontCache = [[NSMutableDictionary alloc] init];
+    }
+    
+    fontKey = [[IFFontCacheKey alloc] initWithFamily:family traits:traits size:size];
+    font = [fontCache objectForKey:fontKey];
+    if (font == nil) {
+        font = [self fontWithFamily:family traits:traits size:size];
+        [fontCache setObject:font forKey:fontKey];
+    }
+    [fontKey release];
+    
+    return font;
+}
+
+- (id <IFTextRenderer>)rendererWithFamily:(NSString *)family traits:(NSFontTraitMask)traits size:(float)size
+{
+    return [self rendererWithFont:[self cachedFontWithFamily:family traits:traits size:size]];
+}
+
+ at end
diff --git a/WebKit/WebKit.pbproj/project.pbxproj b/WebKit/WebKit.pbproj/project.pbxproj
index f941892..769ea28 100644
--- a/WebKit/WebKit.pbproj/project.pbxproj
+++ b/WebKit/WebKit.pbproj/project.pbxproj
@@ -94,6 +94,7 @@
 				25A8176801B5474B0ECA149E,
 				F5065217027F555001C1A526,
 				F5F084B8024BBFFE01CA1520,
+				F5B36B400281DE87018635CB,
 				F5EBC45202134BB601CA1520,
 				089C1665FE841158C02AAC07,
 				0867D69AFE84028FC02AAC07,
@@ -134,7 +135,7 @@
 				DYLIB_COMPATIBILITY_VERSION = 1;
 				DYLIB_CURRENT_VERSION = 1;
 				FRAMEWORK_VERSION = A;
-				HEADER_SEARCH_PATHS = ".. ../JavaScriptCore ../WebCore/khtml ../WebCore/kwq ../WebCore/kwq/kdecore ../WebCore/kwq/khtml ../WebCore/kwq/kparts ../WebCore/kwq/qt";
+				HEADER_SEARCH_PATHS = ".. ../JavaScriptCore ../WebCore/khtml ../WebCore/kwq ../WebCore/kwq/kdecore ../WebCore/kwq/khtml ../WebCore/kwq/kparts ../WebCore/kwq/qt /System/Library/Frameworks/ApplicationServices.framework/Frameworks/QD.framework/PrivateHeaders";
 				INSTALL_PATH = "";
 				LIBRARY_SEARCH_PATHS = "";
 				OPTIMIZATION_CFLAGS = "-Os";
@@ -154,8 +155,8 @@
 			productName = WebKit;
 			productReference = 034768E0FF38A50411DB9C8B;
 			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
-<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
-<plist version=\"0.9\">
+<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
 <dict>
 	<key>CFBundleDevelopmentRegion</key>
 	<string>English</string>
@@ -225,6 +226,8 @@
 				F5065224027F557E01C1A526,
 				F5065226027F557E01C1A526,
 				F5065228027F557E01C1A526,
+				F5B36B430281DF55018635CB,
+				F5B36B470281DF9C018635CB,
 				F50AD3880282028B01C1A526,
 			);
 			isa = PBXHeadersBuildPhase;
@@ -278,6 +281,8 @@
 				F5065225027F557E01C1A526,
 				F5065227027F557E01C1A526,
 				F5065229027F557E01C1A526,
+				F5B36B440281DF55018635CB,
+				F5B36B480281DF9C018635CB,
 			);
 			isa = PBXSourcesBuildPhase;
 		};
@@ -1491,6 +1496,65 @@
 			settings = {
 			};
 		};
+		F5B36B400281DE87018635CB = {
+			children = (
+				F5B36B450281DF9C018635CB,
+				F5B36B460281DF9C018635CB,
+				F5B36B410281DF55018635CB,
+				F5B36B420281DF55018635CB,
+			);
+			isa = PBXGroup;
+			name = WebCoreSupport;
+			refType = 4;
+		};
+		F5B36B410281DF55018635CB = {
+			isa = PBXFileReference;
+			name = IFCachedTextRenderer.h;
+			path = WebCoreSupport.subproj/IFCachedTextRenderer.h;
+			refType = 4;
+		};
+		F5B36B420281DF55018635CB = {
+			isa = PBXFileReference;
+			name = IFCachedTextRenderer.m;
+			path = WebCoreSupport.subproj/IFCachedTextRenderer.m;
+			refType = 4;
+		};
+		F5B36B430281DF55018635CB = {
+			fileRef = F5B36B410281DF55018635CB;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5B36B440281DF55018635CB = {
+			fileRef = F5B36B420281DF55018635CB;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5B36B450281DF9C018635CB = {
+			isa = PBXFileReference;
+			name = IFCachedTextRendererFactory.h;
+			path = WebCoreSupport.subproj/IFCachedTextRendererFactory.h;
+			refType = 4;
+		};
+		F5B36B460281DF9C018635CB = {
+			isa = PBXFileReference;
+			name = IFCachedTextRendererFactory.m;
+			path = WebCoreSupport.subproj/IFCachedTextRendererFactory.m;
+			refType = 4;
+		};
+		F5B36B470281DF9C018635CB = {
+			fileRef = F5B36B450281DF9C018635CB;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5B36B480281DF9C018635CB = {
+			fileRef = F5B36B460281DF9C018635CB;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
 		F5B67130023EDF8901C1A525 = {
 			isa = PBXFileReference;
 			name = url_icon.tiff;
diff --git a/WebKit/WebView.subproj/IFWebDataSourcePrivate.mm b/WebKit/WebView.subproj/IFWebDataSourcePrivate.mm
index b50c865..ad65052 100644
--- a/WebKit/WebView.subproj/IFWebDataSourcePrivate.mm
+++ b/WebKit/WebView.subproj/IFWebDataSourcePrivate.mm
@@ -232,10 +232,16 @@
 
 - (void)_setTitle:(NSString *)title
 {
-    NSMutableString *trimmed = [NSMutableString stringWithString:title];
-    CFStringTrimWhitespace((CFMutableStringRef) trimmed);
-    if ([trimmed length] == 0) {
+    NSMutableString *trimmed;
+    if (title == nil) {
         trimmed = nil;
+    } else {
+        trimmed = [[title mutableCopy] autorelease];
+        CFStringTrimWhitespace((CFMutableStringRef) trimmed);
+        if ([trimmed length] == 0)
+            trimmed = nil;
+    }
+    if (trimmed == nil) {
         if (_private->pageTitle == nil)
             return;
     } else {
@@ -244,7 +250,7 @@
     }
     
     [_private->pageTitle autorelease];
-    _private->pageTitle = [[NSString stringWithString:trimmed] retain];
+    _private->pageTitle = [trimmed copy];
     
     // The title doesn't get communicated to the controller until
     // we reach the committed state for this data source's frame.
diff --git a/WebKit/WebView.subproj/IFWebView.mm b/WebKit/WebView.subproj/IFWebView.mm
index 077bf42..25ecab7 100644
--- a/WebKit/WebView.subproj/IFWebView.mm
+++ b/WebKit/WebView.subproj/IFWebView.mm
@@ -8,6 +8,7 @@
 #import <WebKit/IFBaseWebController.h>
 #import <WebKit/IFDynamicScrollBarsView.h>
 #import <WebKit/IFException.h>
+#import <WebKit/IFCachedTextRendererFactory.h>
 #import <WebKit/WebKitDebug.h>
 
 // KDE related includes
@@ -24,6 +25,8 @@
 {
     [super initWithFrame: frame];
 
+    [IFCachedTextRendererFactory createSharedFactory];
+    
     _private = [[IFWebViewPrivate alloc] init];
 
     _private->isFlipped = YES;
diff --git a/WebKit/WebView.subproj/WebDataSourcePrivate.m b/WebKit/WebView.subproj/WebDataSourcePrivate.m
index b50c865..ad65052 100644
--- a/WebKit/WebView.subproj/WebDataSourcePrivate.m
+++ b/WebKit/WebView.subproj/WebDataSourcePrivate.m
@@ -232,10 +232,16 @@
 
 - (void)_setTitle:(NSString *)title
 {
-    NSMutableString *trimmed = [NSMutableString stringWithString:title];
-    CFStringTrimWhitespace((CFMutableStringRef) trimmed);
-    if ([trimmed length] == 0) {
+    NSMutableString *trimmed;
+    if (title == nil) {
         trimmed = nil;
+    } else {
+        trimmed = [[title mutableCopy] autorelease];
+        CFStringTrimWhitespace((CFMutableStringRef) trimmed);
+        if ([trimmed length] == 0)
+            trimmed = nil;
+    }
+    if (trimmed == nil) {
         if (_private->pageTitle == nil)
             return;
     } else {
@@ -244,7 +250,7 @@
     }
     
     [_private->pageTitle autorelease];
-    _private->pageTitle = [[NSString stringWithString:trimmed] retain];
+    _private->pageTitle = [trimmed copy];
     
     // The title doesn't get communicated to the controller until
     // we reach the committed state for this data source's frame.
diff --git a/WebKit/WebView.subproj/WebFrameView.m b/WebKit/WebView.subproj/WebFrameView.m
index 077bf42..25ecab7 100644
--- a/WebKit/WebView.subproj/WebFrameView.m
+++ b/WebKit/WebView.subproj/WebFrameView.m
@@ -8,6 +8,7 @@
 #import <WebKit/IFBaseWebController.h>
 #import <WebKit/IFDynamicScrollBarsView.h>
 #import <WebKit/IFException.h>
+#import <WebKit/IFCachedTextRendererFactory.h>
 #import <WebKit/WebKitDebug.h>
 
 // KDE related includes
@@ -24,6 +25,8 @@
 {
     [super initWithFrame: frame];
 
+    [IFCachedTextRendererFactory createSharedFactory];
+    
     _private = [[IFWebViewPrivate alloc] init];
 
     _private->isFlipped = YES;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list