[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

rjw rjw at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 06:22:11 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 7077c2f4216055f377c18bc49b2174a217c8dab9
Author: rjw <rjw at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Jun 28 21:13:50 2002 +0000

            Use float character measurement to determine selection
            region.  Necessary to ensure accuracy of selection
            region.  First step towards weaning khtml off int
            measurements.
    
            * khtml/rendering/font.cpp:
            (Font::floatWidth):
            (Font::floatCharacterWidth):
            * khtml/rendering/font.h:
            * khtml/rendering/render_text.cpp:
            (TextSlave::checkSelectionPoint):
            * kwq/KWQFontMetrics.mm:
            (QFontMetrics::floatWidth):
            (QFontMetrics::floatCharacterWidth):
            * kwq/WebCoreTextRenderer.h:
            * kwq/qt/qfontmetrics.h:
    
            Use float character measurement to determine selection
            region.  Necessary to ensure accuracy of selection
            region.  First step towards weaning khtml off int
            measurements.
    
            * WebCoreSupport.subproj/IFImageRenderer.m:
            (-[IFImageRenderer tileInRect:fromPoint:]):
            Cleaned up use of loadStatus.
            * WebCoreSupport.subproj/IFTextRenderer.m:
            (-[IFTextRenderer slowFloatWidthForCharacters:stringLength:fromCharacterPostion:numberOfCharacters:applyRounding:]):
            (-[IFTextRenderer floatWidthForCharacters:stringLength:characterPosition:]):
            (-[IFTextRenderer floatWidthForCharacters:stringLength:fromCharacterPosition:numberOfCharacters:applyRounding:attemptFontSubstitution:]):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@1469 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2002-12-03 b/WebCore/ChangeLog-2002-12-03
index 2539c57..09b2a82 100644
--- a/WebCore/ChangeLog-2002-12-03
+++ b/WebCore/ChangeLog-2002-12-03
@@ -1,3 +1,22 @@
+2002-06-28  Richard Williamson  <rjw at apple.com>
+
+        Use float character measurement to determine selection
+        region.  Necessary to ensure accuracy of selection
+        region.  First step towards weaning khtml off int
+        measurements.
+        
+        * khtml/rendering/font.cpp:
+        (Font::floatWidth):
+        (Font::floatCharacterWidth):
+        * khtml/rendering/font.h:
+        * khtml/rendering/render_text.cpp:
+        (TextSlave::checkSelectionPoint):
+        * kwq/KWQFontMetrics.mm:
+        (QFontMetrics::floatWidth):
+        (QFontMetrics::floatCharacterWidth):
+        * kwq/WebCoreTextRenderer.h:
+        * kwq/qt/qfontmetrics.h:
+
 2002-06-27  Chris Blumenberg  <cblu at apple.com>
 
 	Added an APPLE_CHANGES to fix 2894742. The attributes of an EMBED tag
diff --git a/WebCore/ChangeLog-2003-10-25 b/WebCore/ChangeLog-2003-10-25
index 2539c57..09b2a82 100644
--- a/WebCore/ChangeLog-2003-10-25
+++ b/WebCore/ChangeLog-2003-10-25
@@ -1,3 +1,22 @@
+2002-06-28  Richard Williamson  <rjw at apple.com>
+
+        Use float character measurement to determine selection
+        region.  Necessary to ensure accuracy of selection
+        region.  First step towards weaning khtml off int
+        measurements.
+        
+        * khtml/rendering/font.cpp:
+        (Font::floatWidth):
+        (Font::floatCharacterWidth):
+        * khtml/rendering/font.h:
+        * khtml/rendering/render_text.cpp:
+        (TextSlave::checkSelectionPoint):
+        * kwq/KWQFontMetrics.mm:
+        (QFontMetrics::floatWidth):
+        (QFontMetrics::floatCharacterWidth):
+        * kwq/WebCoreTextRenderer.h:
+        * kwq/qt/qfontmetrics.h:
+
 2002-06-27  Chris Blumenberg  <cblu at apple.com>
 
 	Added an APPLE_CHANGES to fix 2894742. The attributes of an EMBED tag
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 2539c57..09b2a82 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,22 @@
+2002-06-28  Richard Williamson  <rjw at apple.com>
+
+        Use float character measurement to determine selection
+        region.  Necessary to ensure accuracy of selection
+        region.  First step towards weaning khtml off int
+        measurements.
+        
+        * khtml/rendering/font.cpp:
+        (Font::floatWidth):
+        (Font::floatCharacterWidth):
+        * khtml/rendering/font.h:
+        * khtml/rendering/render_text.cpp:
+        (TextSlave::checkSelectionPoint):
+        * kwq/KWQFontMetrics.mm:
+        (QFontMetrics::floatWidth):
+        (QFontMetrics::floatCharacterWidth):
+        * kwq/WebCoreTextRenderer.h:
+        * kwq/qt/qfontmetrics.h:
+
 2002-06-27  Chris Blumenberg  <cblu at apple.com>
 
 	Added an APPLE_CHANGES to fix 2894742. The attributes of an EMBED tag
diff --git a/WebCore/khtml/rendering/font.cpp b/WebCore/khtml/rendering/font.cpp
index f18fd7c..af79681 100644
--- a/WebCore/khtml/rendering/font.cpp
+++ b/WebCore/khtml/rendering/font.cpp
@@ -106,6 +106,20 @@ void Font::drawText( QPainter *p, int x, int y, QChar *str, int slen, int pos, i
 }
 
 
+#ifdef APPLE_CHANGES
+float Font::floatWidth( QChar *chs, int slen, int pos, int len ) const
+{
+    return fm.floatWidth(chs, slen, pos, len);
+}
+
+
+float Font::floatCharacterWidth( QChar *chs, int slen, int pos) const
+{
+    return fm.floatCharacterWidth(chs, slen, pos);
+}
+#endif
+
+
 int Font::width( QChar *chs, int slen, int pos, int len ) const
 {
 #ifdef APPLE_CHANGES
diff --git a/WebCore/khtml/rendering/font.h b/WebCore/khtml/rendering/font.h
index e1229f2..973b86c 100644
--- a/WebCore/khtml/rendering/font.h
+++ b/WebCore/khtml/rendering/font.h
@@ -81,6 +81,10 @@ public:
     void drawText( QPainter *p, int x, int y, QChar *str, int slen, int pos, int len, int width,
                    QPainter::TextDirection d, int from=-1, int to=-1, QColor bg=QColor() ) const;
 
+#ifdef APPLE_CHANGES
+    float floatWidth( QChar *str, int slen, int pos, int len ) const;
+    float floatCharacterWidth( QChar *str, int slen, int pos ) const;
+#endif
     int width( QChar *str, int slen, int pos, int len ) const;
     int width( QChar *str, int slen, int pos ) const;
 
diff --git a/WebCore/khtml/rendering/render_text.cpp b/WebCore/khtml/rendering/render_text.cpp
index 1571581..05034ff 100644
--- a/WebCore/khtml/rendering/render_text.cpp
+++ b/WebCore/khtml/rendering/render_text.cpp
@@ -157,6 +157,35 @@ FindSelectionResult TextSlave::checkSelectionPoint(int _x, int _y, int _tx, int
         return m_reversed ? SelectionPointAfterInLine : SelectionPointBeforeInLine;
     }
 
+#ifdef APPLE_CHANGES
+    float delta = _x - (_tx + m_x);
+    //kdDebug(6040) << "TextSlave::checkSelectionPoint delta=" << delta << endl;
+    int pos = 0;
+    if ( m_reversed ) {
+	delta -= m_width;
+	while(pos < m_len) {
+	    float w = f->floatCharacterWidth( text->str->s, text->str->l, m_start + pos);
+	    float w2 = w/2;
+	    w -= w2;
+	    delta += w2;
+	    if(delta >= 0)
+	        break;
+	    pos++;
+	    delta += w;
+	}
+    } else {
+	while(pos < m_len) {
+	    float w = f->floatCharacterWidth( text->str->s, text->str->l, m_start + pos);
+	    float w2 = w/2;
+	    w -= w2;
+	    delta -= w2;
+	    if(delta <= 0) 
+	        break;
+	    pos++;
+	    delta -= w;
+	}
+    }
+#else
     int delta = _x - (_tx + m_x);
     //kdDebug(6040) << "TextSlave::checkSelectionPoint delta=" << delta << endl;
     int pos = 0;
@@ -182,6 +211,7 @@ FindSelectionResult TextSlave::checkSelectionPoint(int _x, int _y, int _tx, int
 	    delta -= w;
 	}
     }
+#endif
 //     kdDebug( 6040 ) << " Text  --> inside at position " << pos << endl;
     offset = pos;
     return SelectionPointInside;
diff --git a/WebCore/kwq/KWQFontMetrics.h b/WebCore/kwq/KWQFontMetrics.h
index debd42a..bcdf581 100644
--- a/WebCore/kwq/KWQFontMetrics.h
+++ b/WebCore/kwq/KWQFontMetrics.h
@@ -53,6 +53,8 @@ public:
     int width(const QString &, int len=-1) const;
     int charWidth(QString &s, int pos) const;
     int width(const QChar *, int len) const;
+    float floatWidth( QChar *uchars, int slen, int pos, int len ) const;
+    float floatCharacterWidth( QChar *uchars, int slen, int pos) const;
 
     QRect boundingRect(const QString &, int len=-1) const;
     QRect boundingRect(QChar) const;
diff --git a/WebCore/kwq/KWQFontMetrics.mm b/WebCore/kwq/KWQFontMetrics.mm
index e266259..6bbd2eb 100644
--- a/WebCore/kwq/KWQFontMetrics.mm
+++ b/WebCore/kwq/KWQFontMetrics.mm
@@ -126,6 +126,7 @@ int QFontMetrics::width(char c) const
     return [data->getRenderer() widthForCharacters:&ch length:1];
 }
 
+
 int QFontMetrics::width(const QString &qstring, int len) const
 {
     NSString *string;
@@ -137,22 +138,39 @@ int QFontMetrics::width(const QString &qstring, int len) const
     return [data->getRenderer() widthForString:string];
 }
 
+
 int QFontMetrics::width(const QChar *uchars, int len) const
 {
     return [data->getRenderer() widthForCharacters:(const UniChar *)uchars length:len];
 }
 
+
+float QFontMetrics::floatWidth( QChar *uchars, int slen, int pos, int len ) const
+{
+    return [data->getRenderer() floatWidthForCharacters:(const UniChar *)uchars stringLength:(unsigned)slen fromCharacterPosition: (int)pos numberOfCharacters: (int)len];
+}
+
+
+float QFontMetrics::floatCharacterWidth( QChar *uchars, int slen, int pos) const
+{
+    return [data->getRenderer() floatWidthForCharacters:(const UniChar *)uchars stringLength:(unsigned)slen characterPosition: (int)pos];
+}
+
+
+
 QRect QFontMetrics::boundingRect(const QString &qstring, int len) const
 {
     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));
 }
 
+
 QRect QFontMetrics::boundingRect(QChar qc) const
 {
     return QRect(0, 0, width(qc), height());
diff --git a/WebCore/kwq/WebCoreTextRenderer.h b/WebCore/kwq/WebCoreTextRenderer.h
index 7fba82c..fb0bb31 100644
--- a/WebCore/kwq/WebCoreTextRenderer.h
+++ b/WebCore/kwq/WebCoreTextRenderer.h
@@ -45,6 +45,8 @@
 
 - (float)floatWidthForCharacters:(const UniChar *)characters stringLength:(unsigned)stringLength fromCharacterPosition: (int)pos numberOfCharacters: (int)len;
 
+- (float)floatWidthForCharacters:(const UniChar *)characters stringLength:(unsigned)stringLength characterPosition: (int)pos;
+
 - (int)widthForCharacters:(const UniChar *)characters stringLength:(unsigned)stringLength fromCharacterPosition: (int)pos numberOfCharacters: (int)len;
 
 @end
diff --git a/WebCore/kwq/qt/qfontmetrics.h b/WebCore/kwq/qt/qfontmetrics.h
index debd42a..bcdf581 100644
--- a/WebCore/kwq/qt/qfontmetrics.h
+++ b/WebCore/kwq/qt/qfontmetrics.h
@@ -53,6 +53,8 @@ public:
     int width(const QString &, int len=-1) const;
     int charWidth(QString &s, int pos) const;
     int width(const QChar *, int len) const;
+    float floatWidth( QChar *uchars, int slen, int pos, int len ) const;
+    float floatCharacterWidth( QChar *uchars, int slen, int pos) const;
 
     QRect boundingRect(const QString &, int len=-1) const;
     QRect boundingRect(QChar) const;
diff --git a/WebKit/ChangeLog b/WebKit/ChangeLog
index 9528e28..d7f11ab 100644
--- a/WebKit/ChangeLog
+++ b/WebKit/ChangeLog
@@ -1,3 +1,18 @@
+2002-06-28  Richard Williamson  <rjw at apple.com>
+
+        Use float character measurement to determine selection
+        region.  Necessary to ensure accuracy of selection
+        region.  First step towards weaning khtml off int
+        measurements.
+
+        * WebCoreSupport.subproj/IFImageRenderer.m:
+        (-[IFImageRenderer tileInRect:fromPoint:]):
+        Cleaned up use of loadStatus.
+        * WebCoreSupport.subproj/IFTextRenderer.m:
+        (-[IFTextRenderer slowFloatWidthForCharacters:stringLength:fromCharacterPostion:numberOfCharacters:applyRounding:]):
+        (-[IFTextRenderer floatWidthForCharacters:stringLength:characterPosition:]):
+        (-[IFTextRenderer floatWidthForCharacters:stringLength:fromCharacterPosition:numberOfCharacters:applyRounding:attemptFontSubstitution:]):
+
 2002-06-28  Chris Blumenberg  <cblu at apple.com>
 
         * WebView.subproj/IFMainURLHandleClient.h:
diff --git a/WebKit/ChangeLog-2002-12-03 b/WebKit/ChangeLog-2002-12-03
index 9528e28..d7f11ab 100644
--- a/WebKit/ChangeLog-2002-12-03
+++ b/WebKit/ChangeLog-2002-12-03
@@ -1,3 +1,18 @@
+2002-06-28  Richard Williamson  <rjw at apple.com>
+
+        Use float character measurement to determine selection
+        region.  Necessary to ensure accuracy of selection
+        region.  First step towards weaning khtml off int
+        measurements.
+
+        * WebCoreSupport.subproj/IFImageRenderer.m:
+        (-[IFImageRenderer tileInRect:fromPoint:]):
+        Cleaned up use of loadStatus.
+        * WebCoreSupport.subproj/IFTextRenderer.m:
+        (-[IFTextRenderer slowFloatWidthForCharacters:stringLength:fromCharacterPostion:numberOfCharacters:applyRounding:]):
+        (-[IFTextRenderer floatWidthForCharacters:stringLength:characterPosition:]):
+        (-[IFTextRenderer floatWidthForCharacters:stringLength:fromCharacterPosition:numberOfCharacters:applyRounding:attemptFontSubstitution:]):
+
 2002-06-28  Chris Blumenberg  <cblu at apple.com>
 
         * WebView.subproj/IFMainURLHandleClient.h:
diff --git a/WebKit/WebCoreSupport.subproj/IFImageRenderer.m b/WebKit/WebCoreSupport.subproj/IFImageRenderer.m
index 717a828..cdc6385 100644
--- a/WebKit/WebCoreSupport.subproj/IFImageRenderer.m
+++ b/WebKit/WebCoreSupport.subproj/IFImageRenderer.m
@@ -234,7 +234,7 @@ static NSMutableArray *activeImageRenderers;
 {
     int currentStatus = [self loadStatus];
     
-    if ([self loadStatus] > 0 || [self loadStatus] == NSImageRepLoadStatusCompleted){
+    if (currentStatus > 0 || currentStatus == NSImageRepLoadStatusCompleted){
         if (statusOfCache != currentStatus){
             [patternColor release];
             patternColor = [[NSColor colorWithPatternImage:self] retain];
diff --git a/WebKit/WebCoreSupport.subproj/IFTextRenderer.m b/WebKit/WebCoreSupport.subproj/IFTextRenderer.m
index 1392859..08b9515 100644
--- a/WebKit/WebCoreSupport.subproj/IFTextRenderer.m
+++ b/WebKit/WebCoreSupport.subproj/IFTextRenderer.m
@@ -691,7 +691,7 @@ cleanup:
 - (float)slowFloatWidthForCharacters: (const UniChar *)characters stringLength: (unsigned)length fromCharacterPostion: (int)pos numberOfCharacters: (int)len applyRounding: (BOOL)applyRounding
 {
     float totalWidth = 0;
-    unsigned int i, numGlyphs;
+    unsigned int charPos = 0, clusterLength, i, numGlyphs;
     ATSGlyphVector glyphVector;
     IFGlyphWidth glyphWidth;
     ATSLayoutRecord *glyphRecord;
@@ -704,17 +704,38 @@ cleanup:
     glyphRecord = (ATSLayoutRecord *)glyphVector.firstRecord;
     for (i = 0; i < numGlyphs; i++){
         glyphID = glyphRecord->glyphID;
+
+        // Drop out early if we've measured to the end of the requested
+        // fragment.
+        if ((int)charPos - pos >= len){
+            if (glyphID == spaceGlyph){
+                totalWidth -= lastWidth;
+                totalWidth += ROUND_TO_INT(lastWidth);
+            }
+            break;
+        }
+
+        // No need to measure until we reach start of string.
+        if ((int)charPos < pos)
+            continue;
+        
+        clusterLength = findLengthOfCharacterCluster (&characters[charPos], length - charPos);
+
         glyphRecord = (ATSLayoutRecord *)((char *)glyphRecord + glyphVector.recordSize);
         glyphWidth = widthForGlyph(self, glyphToWidthMap, glyphID);
         if (glyphID == spaceGlyph && applyRounding){
-            if (lastWidth > 0){
+            if (totalWidth > 0 && lastWidth > 0){
                 totalWidth -= lastWidth;
                 totalWidth += ROUND_TO_INT(lastWidth);
             }
             glyphWidth = ROUND_TO_INT(glyphWidth);
         }
         lastWidth = glyphWidth;
-        totalWidth += lastWidth;
+        
+        if ((int)charPos >= pos)
+            totalWidth += lastWidth;
+
+        charPos += clusterLength;
     }
     ATSClearGlyphVector(&glyphVector);
     
@@ -722,6 +743,15 @@ cleanup:
 }
 
 
+- (float)floatWidthForCharacters:(const UniChar *)characters stringLength:(unsigned)stringLength characterPosition: (int)pos
+{
+    // Return the width of the first complete character at the specified position.  Even though
+    // the first 'character' may contain more than one unicode characters this method will
+    // work correctly.
+    return [self floatWidthForCharacters:characters stringLength:stringLength fromCharacterPosition:pos numberOfCharacters:1 applyRounding: YES attemptFontSubstitution: YES];
+}
+
+
 - (float)floatWidthForCharacters:(const UniChar *)characters stringLength:(unsigned)stringLength fromCharacterPosition: (int)pos numberOfCharacters: (int)len
 {
     return [self floatWidthForCharacters:characters stringLength:stringLength fromCharacterPosition:pos numberOfCharacters:len applyRounding: YES attemptFontSubstitution: YES];
@@ -737,17 +767,28 @@ cleanup:
     float lastWidth = 0;
     
     //printf("width: font %s, size %.1f, text \"%s\"\n", [[font fontName] cString], [font pointSize], [[NSString stringWithCharacters:characters length:length] UTF8String]);
-    
-    for (i = 0; i < stringLength; i++) {
+    for (i = pos; i < stringLength; i++) {
         UniChar c = characters[i];
         
         if (c == NON_BREAKING_SPACE) {
             c = SPACE;
         }
-        else if (IsNonBaseChar(c)){
-            return [self slowFloatWidthForCharacters: characters stringLength: stringLength fromCharacterPostion: pos numberOfCharacters: len applyRounding: applyRounding];
-        }
         
+        // Drop out early if we've measured to the end of the requested
+        // fragment.
+        if ((int)i - pos >= len){
+            // Check if next character is a space, if so we have to apply rounding.
+            if (c == SPACE){
+                totalWidth -= lastWidth;
+                totalWidth += ROUND_TO_INT(lastWidth);
+            }
+            break;
+        }
+
+        if (IsNonBaseChar(c)){
+            return [self slowFloatWidthForCharacters: &characters[pos] stringLength: stringLength-pos fromCharacterPostion: 0 numberOfCharacters: len applyRounding: applyRounding];
+        }
+
         glyphID = glyphForCharacter(characterToGlyphMap, c);
         if (glyphID == nonGlyphID) {
             glyphID = [self extendCharacterToGlyphMapToInclude: c];
@@ -756,14 +797,16 @@ cleanup:
         // Try to find a substitute font if this font didn't have a glyph for a character in the
         // string.  If one isn't found we end up drawing and measuring the 0 glyph, usually a box.
         if (glyphID == 0 && attemptSubstitution) {
+            // FIXME:  It may better to attempt to measure the entire string in the
+            // alternate font rather than character by character, as we often do
+            // substitution for the entire fragment (as we do in the drawing case.)
             clusterLength = findLengthOfCharacterCluster (&characters[i], stringLength - i);
             substituteFont = [self substituteFontForCharacters: &characters[i] length: clusterLength];
             if (substituteFont) {
-                //WEBKITDEBUGLEVEL (WEBKIT_LOG_FONTCACHE, "substituting %s for %s, missing 0x%04x\n", DEBUG_OBJECT(substituteFont), DEBUG_OBJECT([font displayName]), c);
                 lastWidth = [[[IFTextRendererFactory sharedFactory] rendererWithFont: substituteFont] floatWidthForCharacters: &characters[i] stringLength: clusterLength fromCharacterPosition: pos numberOfCharacters: len applyRounding: YES attemptFontSubstitution: NO];
             }
         }
-        
+
         if (glyphID > 0 || ((glyphID == 0) && substituteFont == nil)) {
             if (glyphID == spaceGlyph && applyRounding) {
                 if (lastWidth > 0){
@@ -775,7 +818,8 @@ cleanup:
             else
                 lastWidth = widthForGlyph(self, glyphToWidthMap, glyphID);
         }
-        totalWidth += lastWidth;                
+
+        totalWidth += lastWidth;       
     }
 
     return totalWidth;
diff --git a/WebKit/WebCoreSupport.subproj/WebImageRenderer.m b/WebKit/WebCoreSupport.subproj/WebImageRenderer.m
index 717a828..cdc6385 100644
--- a/WebKit/WebCoreSupport.subproj/WebImageRenderer.m
+++ b/WebKit/WebCoreSupport.subproj/WebImageRenderer.m
@@ -234,7 +234,7 @@ static NSMutableArray *activeImageRenderers;
 {
     int currentStatus = [self loadStatus];
     
-    if ([self loadStatus] > 0 || [self loadStatus] == NSImageRepLoadStatusCompleted){
+    if (currentStatus > 0 || currentStatus == NSImageRepLoadStatusCompleted){
         if (statusOfCache != currentStatus){
             [patternColor release];
             patternColor = [[NSColor colorWithPatternImage:self] retain];
diff --git a/WebKit/WebCoreSupport.subproj/WebTextRenderer.m b/WebKit/WebCoreSupport.subproj/WebTextRenderer.m
index 1392859..08b9515 100644
--- a/WebKit/WebCoreSupport.subproj/WebTextRenderer.m
+++ b/WebKit/WebCoreSupport.subproj/WebTextRenderer.m
@@ -691,7 +691,7 @@ cleanup:
 - (float)slowFloatWidthForCharacters: (const UniChar *)characters stringLength: (unsigned)length fromCharacterPostion: (int)pos numberOfCharacters: (int)len applyRounding: (BOOL)applyRounding
 {
     float totalWidth = 0;
-    unsigned int i, numGlyphs;
+    unsigned int charPos = 0, clusterLength, i, numGlyphs;
     ATSGlyphVector glyphVector;
     IFGlyphWidth glyphWidth;
     ATSLayoutRecord *glyphRecord;
@@ -704,17 +704,38 @@ cleanup:
     glyphRecord = (ATSLayoutRecord *)glyphVector.firstRecord;
     for (i = 0; i < numGlyphs; i++){
         glyphID = glyphRecord->glyphID;
+
+        // Drop out early if we've measured to the end of the requested
+        // fragment.
+        if ((int)charPos - pos >= len){
+            if (glyphID == spaceGlyph){
+                totalWidth -= lastWidth;
+                totalWidth += ROUND_TO_INT(lastWidth);
+            }
+            break;
+        }
+
+        // No need to measure until we reach start of string.
+        if ((int)charPos < pos)
+            continue;
+        
+        clusterLength = findLengthOfCharacterCluster (&characters[charPos], length - charPos);
+
         glyphRecord = (ATSLayoutRecord *)((char *)glyphRecord + glyphVector.recordSize);
         glyphWidth = widthForGlyph(self, glyphToWidthMap, glyphID);
         if (glyphID == spaceGlyph && applyRounding){
-            if (lastWidth > 0){
+            if (totalWidth > 0 && lastWidth > 0){
                 totalWidth -= lastWidth;
                 totalWidth += ROUND_TO_INT(lastWidth);
             }
             glyphWidth = ROUND_TO_INT(glyphWidth);
         }
         lastWidth = glyphWidth;
-        totalWidth += lastWidth;
+        
+        if ((int)charPos >= pos)
+            totalWidth += lastWidth;
+
+        charPos += clusterLength;
     }
     ATSClearGlyphVector(&glyphVector);
     
@@ -722,6 +743,15 @@ cleanup:
 }
 
 
+- (float)floatWidthForCharacters:(const UniChar *)characters stringLength:(unsigned)stringLength characterPosition: (int)pos
+{
+    // Return the width of the first complete character at the specified position.  Even though
+    // the first 'character' may contain more than one unicode characters this method will
+    // work correctly.
+    return [self floatWidthForCharacters:characters stringLength:stringLength fromCharacterPosition:pos numberOfCharacters:1 applyRounding: YES attemptFontSubstitution: YES];
+}
+
+
 - (float)floatWidthForCharacters:(const UniChar *)characters stringLength:(unsigned)stringLength fromCharacterPosition: (int)pos numberOfCharacters: (int)len
 {
     return [self floatWidthForCharacters:characters stringLength:stringLength fromCharacterPosition:pos numberOfCharacters:len applyRounding: YES attemptFontSubstitution: YES];
@@ -737,17 +767,28 @@ cleanup:
     float lastWidth = 0;
     
     //printf("width: font %s, size %.1f, text \"%s\"\n", [[font fontName] cString], [font pointSize], [[NSString stringWithCharacters:characters length:length] UTF8String]);
-    
-    for (i = 0; i < stringLength; i++) {
+    for (i = pos; i < stringLength; i++) {
         UniChar c = characters[i];
         
         if (c == NON_BREAKING_SPACE) {
             c = SPACE;
         }
-        else if (IsNonBaseChar(c)){
-            return [self slowFloatWidthForCharacters: characters stringLength: stringLength fromCharacterPostion: pos numberOfCharacters: len applyRounding: applyRounding];
-        }
         
+        // Drop out early if we've measured to the end of the requested
+        // fragment.
+        if ((int)i - pos >= len){
+            // Check if next character is a space, if so we have to apply rounding.
+            if (c == SPACE){
+                totalWidth -= lastWidth;
+                totalWidth += ROUND_TO_INT(lastWidth);
+            }
+            break;
+        }
+
+        if (IsNonBaseChar(c)){
+            return [self slowFloatWidthForCharacters: &characters[pos] stringLength: stringLength-pos fromCharacterPostion: 0 numberOfCharacters: len applyRounding: applyRounding];
+        }
+
         glyphID = glyphForCharacter(characterToGlyphMap, c);
         if (glyphID == nonGlyphID) {
             glyphID = [self extendCharacterToGlyphMapToInclude: c];
@@ -756,14 +797,16 @@ cleanup:
         // Try to find a substitute font if this font didn't have a glyph for a character in the
         // string.  If one isn't found we end up drawing and measuring the 0 glyph, usually a box.
         if (glyphID == 0 && attemptSubstitution) {
+            // FIXME:  It may better to attempt to measure the entire string in the
+            // alternate font rather than character by character, as we often do
+            // substitution for the entire fragment (as we do in the drawing case.)
             clusterLength = findLengthOfCharacterCluster (&characters[i], stringLength - i);
             substituteFont = [self substituteFontForCharacters: &characters[i] length: clusterLength];
             if (substituteFont) {
-                //WEBKITDEBUGLEVEL (WEBKIT_LOG_FONTCACHE, "substituting %s for %s, missing 0x%04x\n", DEBUG_OBJECT(substituteFont), DEBUG_OBJECT([font displayName]), c);
                 lastWidth = [[[IFTextRendererFactory sharedFactory] rendererWithFont: substituteFont] floatWidthForCharacters: &characters[i] stringLength: clusterLength fromCharacterPosition: pos numberOfCharacters: len applyRounding: YES attemptFontSubstitution: NO];
             }
         }
-        
+
         if (glyphID > 0 || ((glyphID == 0) && substituteFont == nil)) {
             if (glyphID == spaceGlyph && applyRounding) {
                 if (lastWidth > 0){
@@ -775,7 +818,8 @@ cleanup:
             else
                 lastWidth = widthForGlyph(self, glyphToWidthMap, glyphID);
         }
-        totalWidth += lastWidth;                
+
+        totalWidth += lastWidth;       
     }
 
     return totalWidth;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list