Added 8 bit path to WidthIterator::advance()
authormsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 13 Sep 2012 21:03:55 +0000 (21:03 +0000)
committermsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 13 Sep 2012 21:03:55 +0000 (21:03 +0000)
https://bugs.webkit.org/show_bug.cgi?id=96590

Reviewed by Geoffrey Garen.

Source/WebCore:

Added 8 bit path to advance() by adding a templatized advanceInternal private
method and added a simple 8 bit Latin-1 TextIterator.  Updated SurrogatePairAwareTextIterator
by making both consume() and advance() inlined and adding consumeSlowCase() for
surrogate handling.  These changes are a performance progression on the Layout tests.

No new tests because of no behavior changes.

* GNUmakefile.list.am:
* Target.pri:
* WebCore.gypi:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* platform/graphics/Latin1TextIterator.h: Copied from Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.h.
(Latin1TextIterator):
(WebCore::Latin1TextIterator::Latin1TextIterator):
(WebCore::Latin1TextIterator::consume):
(WebCore::Latin1TextIterator::advance):
(WebCore::Latin1TextIterator::characters):
* platform/graphics/SurrogatePairAwareTextIterator.cpp:
(WebCore::SurrogatePairAwareTextIterator::consumeSlowCase):
* platform/graphics/SurrogatePairAwareTextIterator.h:
(WebCore::SurrogatePairAwareTextIterator::consume):
(SurrogatePairAwareTextIterator):
(WebCore::SurrogatePairAwareTextIterator::advance):
* platform/graphics/WidthIterator.cpp:
(WebCore::WidthIterator::advanceInternal):
(WebCore::WidthIterator::advance):
* platform/graphics/WidthIterator.h:
(WidthIterator):

Source/WTF:

Added new character constant for Hiragana Letter Small A.

* wtf/unicode/CharacterNames.h:
(Unicode):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@128504 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
Source/WTF/ChangeLog
Source/WTF/wtf/unicode/CharacterNames.h
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/Target.pri
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/platform/graphics/Latin1TextIterator.h [new file with mode: 0644]
Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.cpp
Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.h
Source/WebCore/platform/graphics/WidthIterator.cpp
Source/WebCore/platform/graphics/WidthIterator.h

index 812fe00..2dbd3f7 100644 (file)
@@ -1,3 +1,15 @@
+2012-09-13  Michael Saboff  <msaboff@apple.com>
+
+        Added 8 bit path to WidthIterator::advance()
+        https://bugs.webkit.org/show_bug.cgi?id=96590
+
+        Reviewed by Geoffrey Garen.
+
+        Added new character constant for Hiragana Letter Small A.
+
+        * wtf/unicode/CharacterNames.h:
+        (Unicode):
+
 2012-09-13  Ilya Tikhonovsky  <loislo@chromium.org>
 
         Web Inspector: NMI: instrument KURL directly.
index 78b7bf7..c36dfd0 100644 (file)
@@ -49,6 +49,7 @@ const UChar ethiopicWordspace = 0x1361;
 const UChar fisheye = 0x25C9;
 const UChar hebrewPunctuationGeresh = 0x05F3;
 const UChar hebrewPunctuationGershayim = 0x05F4;
+const UChar HiraganaLetterSmallA = 0x3041;
 const UChar horizontalEllipsis = 0x2026;
 const UChar hyphen = 0x2010;
 const UChar hyphenMinus = 0x002D;
@@ -104,6 +105,7 @@ using WTF::Unicode::ethiopicWordspace;
 using WTF::Unicode::fisheye;
 using WTF::Unicode::hebrewPunctuationGeresh;
 using WTF::Unicode::hebrewPunctuationGershayim;
+using WTF::Unicode::HiraganaLetterSmallA;
 using WTF::Unicode::horizontalEllipsis;
 using WTF::Unicode::hyphen;
 using WTF::Unicode::hyphenMinus;
index 6474026..024d28a 100644 (file)
@@ -1,3 +1,40 @@
+2012-09-13  Michael Saboff  <msaboff@apple.com>
+
+        Added 8 bit path to WidthIterator::advance()
+        https://bugs.webkit.org/show_bug.cgi?id=96590
+
+        Reviewed by Geoffrey Garen.
+
+        Added 8 bit path to advance() by adding a templatized advanceInternal private
+        method and added a simple 8 bit Latin-1 TextIterator.  Updated SurrogatePairAwareTextIterator
+        by making both consume() and advance() inlined and adding consumeSlowCase() for
+        surrogate handling.  These changes are a performance progression on the Layout tests.
+
+        No new tests because of no behavior changes.
+
+        * GNUmakefile.list.am:
+        * Target.pri:
+        * WebCore.gypi:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/graphics/Latin1TextIterator.h: Copied from Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.h.
+        (Latin1TextIterator):
+        (WebCore::Latin1TextIterator::Latin1TextIterator):
+        (WebCore::Latin1TextIterator::consume):
+        (WebCore::Latin1TextIterator::advance):
+        (WebCore::Latin1TextIterator::characters):
+        * platform/graphics/SurrogatePairAwareTextIterator.cpp:
+        (WebCore::SurrogatePairAwareTextIterator::consumeSlowCase):
+        * platform/graphics/SurrogatePairAwareTextIterator.h:
+        (WebCore::SurrogatePairAwareTextIterator::consume):
+        (SurrogatePairAwareTextIterator):
+        (WebCore::SurrogatePairAwareTextIterator::advance):
+        * platform/graphics/WidthIterator.cpp:
+        (WebCore::WidthIterator::advanceInternal):
+        (WebCore::WidthIterator::advance):
+        * platform/graphics/WidthIterator.h:
+        (WidthIterator):
+
 2012-09-13  Yong Li  <yoli@rim.com>
 
         [BlackBerry] ResourceRequest string optimizations
index 39502bf..ba7cbdc 100644 (file)
@@ -4419,6 +4419,7 @@ webcore_sources += \
        Source/WebCore/platform/graphics/IntRect.h \
        Source/WebCore/platform/graphics/IntSize.h \
        Source/WebCore/platform/graphics/IntSizeHash.h \
+       Source/WebCore/platform/graphics/Latin1TextIterator.h \
        Source/WebCore/platform/graphics/MediaPlayer.cpp \
        Source/WebCore/platform/graphics/MediaPlayer.h \
        Source/WebCore/platform/graphics/MediaPlayerPrivate.h \
index 5199372..33e78e1 100644 (file)
@@ -2115,6 +2115,7 @@ HEADERS += \
     platform/graphics/IntPoint.h \
     platform/graphics/IntPointHash.h \
     platform/graphics/IntRect.h \
+    platform/graphics/Latin1TextIterator.h \
     platform/graphics/MediaPlayer.h \
     platform/graphics/NativeImagePtr.h \
     platform/graphics/opentype/OpenTypeVerticalData.h \
index 7f09777..0925725 100644 (file)
             'platform/graphics/ImageBuffer.cpp',
             'platform/graphics/ImageOrientation.cpp',
             'platform/graphics/ImageSource.cpp',
+            'platform/graphics/Latin1TextIterator.h',
             'platform/graphics/MediaPlayer.cpp',
             'platform/graphics/MediaPlayerPrivate.h',
             'platform/graphics/NativeImagePtr.h' ,
index f3361cb..04587e9 100755 (executable)
                                        >
                                </File>
                                <File
+                                       RelativePath="..\platform\graphics\Latin1TextIterator.h"
+                                       >
+                               </File>
+                               <File
                                        RelativePath="..\platform\text\LineBreakIteratorPoolICU.h"
                                        >
                                </File>
index 1b02472..1557fe9 100644 (file)
                FE6FD48D0F676E9300092873 /* JSCoordinates.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE6FD48B0F676E9300092873 /* JSCoordinates.cpp */; };
                FE6FD48E0F676E9300092873 /* JSCoordinates.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6FD48C0F676E9300092873 /* JSCoordinates.h */; };
                FE700DD10F92D81A008E2BFE /* JSCoordinatesCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE700DD00F92D81A008E2BFE /* JSCoordinatesCustom.cpp */; };
-               FFD86E7815F9583600047233 /* JSDependentRetained.h in Headers */ = {isa = PBXBuildFile; fileRef = FFD86E7715F9583600047233 /* JSDependentRetained.h */; };
                FE80D7AB0E9C1ED2000D6F75 /* JSGeolocationCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80D7A60E9C1ED2000D6F75 /* JSGeolocationCustom.cpp */; };
                FE80DA630E9C4703000D6F75 /* JSGeolocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80DA5F0E9C4703000D6F75 /* JSGeolocation.cpp */; };
                FE80DA640E9C4703000D6F75 /* JSGeolocation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80DA600E9C4703000D6F75 /* JSGeolocation.h */; };
                FE80DA720E9C472F000D6F75 /* JSPositionError.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80DA6E0E9C472F000D6F75 /* JSPositionError.h */; };
                FFD5B97A135CC97800D5E92A /* PageVisibilityState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FFD5B977135CC97800D5E92A /* PageVisibilityState.cpp */; };
                FFD5B97B135CC97800D5E92A /* PageVisibilityState.h in Headers */ = {isa = PBXBuildFile; fileRef = FFD5B978135CC97800D5E92A /* PageVisibilityState.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               FFD86E7815F9583600047233 /* JSDependentRetained.h in Headers */ = {isa = PBXBuildFile; fileRef = FFD86E7715F9583600047233 /* JSDependentRetained.h */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
                65C97AF208EA908800ACD273 /* config.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 0; };
                65CBFEF70974F607001DAC25 /* FrameView.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FrameView.cpp; sourceTree = "<group>"; };
                65CBFEF80974F607001DAC25 /* FrameView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FrameView.h; sourceTree = "<group>"; };
+               65CC6BED16014EC0000ED27D /* Latin1TextIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Latin1TextIterator.h; sourceTree = "<group>"; };
                65DF31D809D1C122000BE325 /* JSAttr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSAttr.cpp; sourceTree = "<group>"; };
                65DF31D909D1C123000BE325 /* JSAttr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSAttr.h; sourceTree = "<group>"; };
                65DF31DF09D1CC60000BE325 /* JSCharacterData.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSCharacterData.cpp; sourceTree = "<group>"; };
                FE6FD48B0F676E9300092873 /* JSCoordinates.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCoordinates.cpp; sourceTree = "<group>"; };
                FE6FD48C0F676E9300092873 /* JSCoordinates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCoordinates.h; sourceTree = "<group>"; };
                FE700DD00F92D81A008E2BFE /* JSCoordinatesCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCoordinatesCustom.cpp; sourceTree = "<group>"; };
-               FFD86E7715F9583600047233 /* JSDependentRetained.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDependentRetained.h; sourceTree = "<group>"; };
                FE80D7A60E9C1ED2000D6F75 /* JSGeolocationCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGeolocationCustom.cpp; sourceTree = "<group>"; };
                FE80DA5F0E9C4703000D6F75 /* JSGeolocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGeolocation.cpp; sourceTree = "<group>"; };
                FE80DA600E9C4703000D6F75 /* JSGeolocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGeolocation.h; sourceTree = "<group>"; };
                FE80DA6E0E9C472F000D6F75 /* JSPositionError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPositionError.h; sourceTree = "<group>"; };
                FFD5B977135CC97800D5E92A /* PageVisibilityState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageVisibilityState.cpp; sourceTree = "<group>"; };
                FFD5B978135CC97800D5E92A /* PageVisibilityState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageVisibilityState.h; sourceTree = "<group>"; };
+               FFD86E7715F9583600047233 /* JSDependentRetained.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDependentRetained.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
                                B23540F00D00782E002382FA /* StringTruncator.cpp */,
                                B23540F10D00782E002382FA /* StringTruncator.h */,
                                087558C313B4A57D00F49307 /* SurrogatePairAwareTextIterator.cpp */,
+                               65CC6BED16014EC0000ED27D /* Latin1TextIterator.h */,
                                087558C413B4A57D00F49307 /* SurrogatePairAwareTextIterator.h */,
                                087E0AF413606D0B00FA4BA8 /* SVGGlyph.cpp */,
                                087E0AF513606D0B00FA4BA8 /* SVGGlyph.h */,
diff --git a/Source/WebCore/platform/graphics/Latin1TextIterator.h b/Source/WebCore/platform/graphics/Latin1TextIterator.h
new file mode 100644 (file)
index 0000000..4d74043
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef Latin1TextIterator_h
+#define Latin1TextIterator_h
+
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class Latin1TextIterator {
+public:
+    // The passed in LChar pointer starts at 'currentCharacter'. The iterator operates on the range [currentCharacter, lastCharacter].
+    // 'endCharacter' denotes the maximum length of the UChar array, which might exceed 'lastCharacter'.
+    Latin1TextIterator(const LChar* characters, int currentCharacter, int lastCharacter, int endCharacter)
+        : m_characters(characters)
+        , m_currentCharacter(currentCharacter)
+        , m_lastCharacter(lastCharacter)
+        , m_endCharacter(endCharacter)
+    {
+    }
+
+    bool consume(UChar32& character, unsigned& clusterLength)
+    {
+        if (m_currentCharacter >= m_lastCharacter)
+            return false;
+
+        character = *m_characters;
+        clusterLength = 1;
+        return true;
+    }
+
+    void advance(unsigned advanceLength)
+    {
+        m_characters += advanceLength;
+        m_currentCharacter += advanceLength;
+    }
+
+    int currentCharacter() const { return m_currentCharacter; }
+    const LChar* characters() const { return m_characters; }
+
+private:
+    const LChar* m_characters;
+    int m_currentCharacter;
+    int m_lastCharacter;
+    int m_endCharacter;
+};
+
+}
+
+#endif
index ac0bae3..11da4b9 100644 (file)
@@ -40,17 +40,8 @@ SurrogatePairAwareTextIterator::SurrogatePairAwareTextIterator(const UChar* char
 {
 }
 
-bool SurrogatePairAwareTextIterator::consume(UChar32& character, unsigned& clusterLength)
+bool SurrogatePairAwareTextIterator::consumeSlowCase(UChar32& character, unsigned& clusterLength)
 {
-    if (m_currentCharacter >= m_lastCharacter)
-        return false;
-
-    character = *m_characters;
-    clusterLength = 1;
-
-    if (character < 0x3041)
-        return true;
-
     if (character <= 0x30FE) {
         // Deal with Hiragana and Katakana voiced and semi-voiced syllables.
         // Normalize into composed form, and then look for glyph with base + combined mark.
@@ -83,12 +74,6 @@ bool SurrogatePairAwareTextIterator::consume(UChar32& character, unsigned& clust
     return true;
 }
 
-void SurrogatePairAwareTextIterator::advance(unsigned advanceLength)
-{
-    m_characters += advanceLength;
-    m_currentCharacter += advanceLength;
-}
-
 UChar32 SurrogatePairAwareTextIterator::normalizeVoicingMarks()
 {
     // According to http://www.unicode.org/Public/UNIDATA/UCD.html#Canonical_Combining_Class_Values
index 1d56eb8..85c9694 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef SurrogatePairAwareTextIterator_h
 #define SurrogatePairAwareTextIterator_h
 
+#include <wtf/unicode/CharacterNames.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
@@ -31,13 +32,31 @@ public:
     // 'endCharacter' denotes the maximum length of the UChar array, which might exceed 'lastCharacter'.
     SurrogatePairAwareTextIterator(const UChar*, int currentCharacter, int lastCharacter, int endCharacter);
 
-    bool consume(UChar32& character, unsigned& clusterLength);
-    void advance(unsigned advanceLength);
+    inline bool consume(UChar32& character, unsigned& clusterLength)
+    {
+        if (m_currentCharacter >= m_lastCharacter)
+            return false;
+
+        character = *m_characters;
+        clusterLength = 1;
+
+        if (character < HiraganaLetterSmallA)
+            return true;
+
+        return consumeSlowCase(character, clusterLength);
+    }
+
+    void advance(unsigned advanceLength)
+    {
+        m_characters += advanceLength;
+        m_currentCharacter += advanceLength;
+    }
 
     int currentCharacter() const { return m_currentCharacter; }
     const UChar* characters() const { return m_characters; }
 
 private:
+    bool consumeSlowCase(UChar32&, unsigned&);
     UChar32 normalizeVoicingMarks();
 
     const UChar* m_characters;
index 85d820f..3530581 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "Font.h"
 #include "GlyphBuffer.h"
+#include "Latin1TextIterator.h"
 #include "SimpleFontData.h"
 #include "SurrogatePairAwareTextIterator.h"
 #include "TextRun.h"
@@ -83,14 +84,9 @@ GlyphData WidthIterator::glyphDataForCharacter(UChar32 character, bool mirror, i
     return m_font->glyphDataForCharacter(character, mirror);
 }
 
-unsigned WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
+template <typename TextIterator>
+inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, GlyphBuffer* glyphBuffer)
 {
-    if (offset > m_run.length())
-        offset = m_run.length();
-
-    if (int(m_currentCharacter) >= offset)
-        return 0;
-
     bool rtl = m_run.rtl();
     bool hasExtraSpacing = (m_font->letterSpacing() || m_font->wordSpacing() || m_expansion) && !m_run.spacingDisabled();
 
@@ -106,7 +102,7 @@ unsigned WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
 
     UChar32 character = 0;
     unsigned clusterLength = 0;
-    SurrogatePairAwareTextIterator textIterator(m_run.data16(m_currentCharacter), m_currentCharacter, offset, m_run.length());
+
     while (textIterator.consume(character, clusterLength)) {
         unsigned advanceLength = clusterLength;
         const GlyphData& glyphData = glyphDataForCharacter(character, rtl, textIterator.currentCharacter(), advanceLength);
@@ -204,7 +200,7 @@ unsigned WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
         // Advance past the character we just dealt with.
         textIterator.advance(advanceLength);
 
-        float oldWidth = width; 
+        float oldWidth = width;
 
         // Force characters that are used to determine word boundaries for the rounding hack
         // to be integer width, so following words will start on an integer boundary.
@@ -222,7 +218,7 @@ unsigned WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
             // Check to see if the next character is a "rounding hack character", if so, adjust
             // width so that the total run width will be on an integer boundary.
             if ((m_run.applyWordRounding() && textIterator.currentCharacter() < m_run.length() && Font::isRoundingHackCharacter(*(textIterator.characters())))
-                    || (m_run.applyRunRounding() && textIterator.currentCharacter() >= m_run.length())) {
+                || (m_run.applyRunRounding() && textIterator.currentCharacter() >= m_run.length())) {
                 float totalWidth = widthSinceLastRounding + width;
                 widthSinceLastRounding = ceilf(totalWidth);
                 width += widthSinceLastRounding - totalWidth;
@@ -251,6 +247,25 @@ unsigned WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
     return consumedCharacters;
 }
 
+unsigned WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
+{
+    int length = m_run.length();
+
+    if (offset > length)
+        offset = length;
+
+    if (m_currentCharacter >= static_cast<unsigned>(offset))
+        return 0;
+
+    if (m_run.is8Bit()) {
+        Latin1TextIterator textIterator(m_run.data8(m_currentCharacter), m_currentCharacter, offset, length);
+        return advanceInternal(textIterator, glyphBuffer);
+    }
+
+    SurrogatePairAwareTextIterator textIterator(m_run.data16(m_currentCharacter), m_currentCharacter, offset, length);
+    return advanceInternal(textIterator, glyphBuffer);
+}
+
 bool WidthIterator::advanceOneCharacter(float& width, GlyphBuffer* glyphBuffer)
 {
     int oldSize = glyphBuffer->size();
index 60b9374..9118b65 100644 (file)
@@ -73,6 +73,8 @@ struct WidthIterator {
 
 private:
     GlyphData glyphDataForCharacter(UChar32, bool mirror, int currentCharacter, unsigned& advanceLength);
+    template <typename TextIterator>
+    inline unsigned advanceInternal(TextIterator&, GlyphBuffer*);
 
     HashSet<const SimpleFontData*>* m_fallbackFonts;
     bool m_accountForGlyphBounds;