Title: [131365] trunk/Source
Revision
131365
Author
m...@apple.com
Date
2012-10-15 14:50:53 -0700 (Mon, 15 Oct 2012)

Log Message

Source/WebCore: WebCore part of <rdar://problem/12470680> Font’s fast code path doesn’t support kerning and ligatures
https://bugs.webkit.org/show_bug.cgi?id=99113

Reviewed by Tim Horton.

* WebCore.exp.in: Exported wkCTFontTransformGlyphs.
* platform/graphics/Font.cpp:
(WebCore::Font::width): Added a local GlyphBuffer to pass to floatWidthForSimpleText().
(WebCore::Font::codePath): Rather than always use the complex code path when any typesetting
features are enabled, changed to do so only if WidthIterator doesn’t support this Font’s
typesetting features.
* platform/graphics/FontFastPath.cpp:
(WebCore::Font::getGlyphsAndAdvancesForSimpleText): Added a local GlyphBuffer to pass to
WidthIterator::advance() when advancing to or from the range of interest. Added a FIXME
about how this is not entirely correct when kerning or ligatures are enabled.
(WebCore::Font::selectionRectForSimpleText): Added a local GlyphBuffer to pass to
WidthIterator::advance() when advancing to or from the range of interest.
(WebCore::Font::offsetForPositionForSimpleText): Updated for the change to
WidthIterator::advanceOneCharacter().
* platform/graphics/SimpleFontData.h:
(WebCore::SimpleFontData::applyTransforms): Added. Calls wkCTFontTransformGlyphs() where
available.
* platform/graphics/WidthIterator.cpp:
(WebCore::WidthIterator::WidthIterator): Added initializer for the new m_typesettingFeatures
data member.
(OriginalAdvancesForCharacterTreatedAsSpace): Added this data type, used to track spaces and
characters treated as spaces.
(WebCore::applyFontTransforms): Added. Applies shaping and positioning transforms, as
required by the typesetting features, to the glyphs recently added to a GlyphBuffer, while
maintaining the advances of characters that are treated as spaces and the characters
preceding them, if necessary.
(WebCore::WidthIterator::advanceInternal): Added calls to applyFontTransforms() at the end
of each contiguous run of glyphs from the same font. Also added code to maintain a vector
of spaces and characters treated as space.
(WebCore::WidthIterator::advanceOneCharacter): Changed the parameter type from a pointer to
a reference.
* platform/graphics/WidthIterator.h:
(WebCore::WidthIterator::supportsTypesettingFeatures): Added. Returns whether WidthIterator
instances support the typesetting features of the given font. Returns true if the font is
not a screen font and its typesetting features are kerning, ligatures or both.
(WebCore::WidthIterator::shouldApplyFontTransforms): Added. Returns true if the typesetting
features include kerning or ligatures.
* platform/mac/WebCoreSystemInterface.h: Defined wkCTFontTransformOptions and declared
wkCTFontTransformGlyphs.
* platform/mac/WebCoreSystemInterface.mm: Defined wkCTFontTransformGlyphs.
* rendering/svg/SVGTextMetricsBuilder.cpp:
(WebCore::SVGTextMetricsBuilder::advanceSimpleText): Added a local GlyphBuffer to pass to
WidthIterator::advance().
* rendering/svg/SVGTextRunRenderingContext.cpp:
(WebCore::SVGTextRunRenderingContext::floatWidthUsingSVGFont): Ditto.

Source/WebKit/mac: WebKit/mac part of <rdar://problem/12470680> Font’s fast code path doesn’t support kerning and ligatures
https://bugs.webkit.org/show_bug.cgi?id=99113

Reviewed by Tim Horton.

* WebCoreSupport/WebSystemInterface.mm:
(InitWebCoreSystemInterface): Added wkCTFontTransformGlyphs.

Source/WebKit2: WebKit2 part of <rdar://problem/12470680> Font’s fast code path doesn’t support kerning and ligatures
https://bugs.webkit.org/show_bug.cgi?id=99113

Reviewed by Tim Horton.

* WebProcess/WebCoreSupport/mac/WebSystemInterface.mm:
(InitWebCoreSystemInterface): Added wkCTFontTransformGlyphs.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (131364 => 131365)


--- trunk/Source/WebCore/ChangeLog	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebCore/ChangeLog	2012-10-15 21:50:53 UTC (rev 131365)
@@ -1,3 +1,56 @@
+2012-10-15  Dan Bernstein  <m...@apple.com>
+
+        WebCore part of <rdar://problem/12470680> Font’s fast code path doesn’t support kerning and ligatures
+        https://bugs.webkit.org/show_bug.cgi?id=99113
+
+        Reviewed by Tim Horton.
+
+        * WebCore.exp.in: Exported wkCTFontTransformGlyphs.
+        * platform/graphics/Font.cpp:
+        (WebCore::Font::width): Added a local GlyphBuffer to pass to floatWidthForSimpleText().
+        (WebCore::Font::codePath): Rather than always use the complex code path when any typesetting
+        features are enabled, changed to do so only if WidthIterator doesn’t support this Font’s
+        typesetting features.
+        * platform/graphics/FontFastPath.cpp:
+        (WebCore::Font::getGlyphsAndAdvancesForSimpleText): Added a local GlyphBuffer to pass to
+        WidthIterator::advance() when advancing to or from the range of interest. Added a FIXME
+        about how this is not entirely correct when kerning or ligatures are enabled.
+        (WebCore::Font::selectionRectForSimpleText): Added a local GlyphBuffer to pass to
+        WidthIterator::advance() when advancing to or from the range of interest.
+        (WebCore::Font::offsetForPositionForSimpleText): Updated for the change to
+        WidthIterator::advanceOneCharacter().
+        * platform/graphics/SimpleFontData.h:
+        (WebCore::SimpleFontData::applyTransforms): Added. Calls wkCTFontTransformGlyphs() where
+        available.
+        * platform/graphics/WidthIterator.cpp:
+        (WebCore::WidthIterator::WidthIterator): Added initializer for the new m_typesettingFeatures
+        data member.
+        (OriginalAdvancesForCharacterTreatedAsSpace): Added this data type, used to track spaces and
+        characters treated as spaces.
+        (WebCore::applyFontTransforms): Added. Applies shaping and positioning transforms, as
+        required by the typesetting features, to the glyphs recently added to a GlyphBuffer, while
+        maintaining the advances of characters that are treated as spaces and the characters
+        preceding them, if necessary.
+        (WebCore::WidthIterator::advanceInternal): Added calls to applyFontTransforms() at the end
+        of each contiguous run of glyphs from the same font. Also added code to maintain a vector
+        of spaces and characters treated as space.
+        (WebCore::WidthIterator::advanceOneCharacter): Changed the parameter type from a pointer to
+        a reference.
+        * platform/graphics/WidthIterator.h:
+        (WebCore::WidthIterator::supportsTypesettingFeatures): Added. Returns whether WidthIterator
+        instances support the typesetting features of the given font. Returns true if the font is
+        not a screen font and its typesetting features are kerning, ligatures or both.
+        (WebCore::WidthIterator::shouldApplyFontTransforms): Added. Returns true if the typesetting
+        features include kerning or ligatures.
+        * platform/mac/WebCoreSystemInterface.h: Defined wkCTFontTransformOptions and declared
+        wkCTFontTransformGlyphs.
+        * platform/mac/WebCoreSystemInterface.mm: Defined wkCTFontTransformGlyphs.
+        * rendering/svg/SVGTextMetricsBuilder.cpp:
+        (WebCore::SVGTextMetricsBuilder::advanceSimpleText): Added a local GlyphBuffer to pass to
+        WidthIterator::advance().
+        * rendering/svg/SVGTextRunRenderingContext.cpp:
+        (WebCore::SVGTextRunRenderingContext::floatWidthUsingSVGFont): Ditto.
+
 2012-10-15  Mark Lam  <mark....@apple.com>
 
         Fix build broken by r131348.

Modified: trunk/Source/WebCore/WebCore.exp.in (131364 => 131365)


--- trunk/Source/WebCore/WebCore.exp.in	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebCore/WebCore.exp.in	2012-10-15 21:50:53 UTC (rev 131365)
@@ -1457,6 +1457,9 @@
 _wkCGContextDrawsWithCorrectShadowOffsets
 #endif
 _wkCGPatternCreateWithImageAndTransform
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+_wkCTFontTransformGlyphs
+#endif
 _wkCopyCFLocalizationPreferredName
 _wkCopyCFURLResponseSuggestedFilename
 _wkCopyCONNECTProxyResponse

Modified: trunk/Source/WebCore/platform/graphics/Font.cpp (131364 => 131365)


--- trunk/Source/WebCore/platform/graphics/Font.cpp	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebCore/platform/graphics/Font.cpp	2012-10-15 21:50:53 UTC (rev 131365)
@@ -187,7 +187,8 @@
         // If the complex text implementation cannot return fallback fonts, avoid
         // returning them for simple text as well.
         static bool returnFallbackFonts = canReturnFallbackFontsForComplexText();
-        return floatWidthForSimpleText(run, 0, returnFallbackFonts ? fallbackFonts : 0, codePathToUse == SimpleWithGlyphOverflow || (glyphOverflow && glyphOverflow->computeBounds) ? glyphOverflow : 0);
+        GlyphBuffer glyphBuffer;
+        return floatWidthForSimpleText(run, &glyphBuffer, returnFallbackFonts ? fallbackFonts : 0, codePathToUse == SimpleWithGlyphOverflow || (glyphOverflow && glyphOverflow->computeBounds) ? glyphOverflow : 0);
     }
 
     return floatWidthForComplexText(run, fallbackFonts, glyphOverflow);
@@ -314,7 +315,7 @@
     if (m_fontDescription.featureSettings() && m_fontDescription.featureSettings()->size() > 0)
         return Complex;
     
-    if (run.length() > 1 && typesettingFeatures())
+    if (run.length() > 1 && !WidthIterator::supportsTypesettingFeatures(*this))
         return Complex;
 
     if (!run.characterScanForCodePath())

Modified: trunk/Source/WebCore/platform/graphics/FontFastPath.cpp (131364 => 131365)


--- trunk/Source/WebCore/platform/graphics/FontFastPath.cpp	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebCore/platform/graphics/FontFastPath.cpp	2012-10-15 21:50:53 UTC (rev 131365)
@@ -328,7 +328,10 @@
     float initialAdvance;
 
     WidthIterator it(this, run, 0, false, forTextEmphasis);
-    it.advance(from);
+    // FIXME: Using separate glyph buffers for the prefix and the suffix is incorrect when kerning or
+    // ligatures are enabled.
+    GlyphBuffer localGlyphBuffer;
+    it.advance(from, &localGlyphBuffer);
     float beforeWidth = it.m_runWidthSoFar;
     it.advance(to, &glyphBuffer);
 
@@ -339,7 +342,7 @@
 
     if (run.rtl()) {
         float finalRoundingWidth = it.m_finalRoundingWidth;
-        it.advance(run.length());
+        it.advance(run.length(), &localGlyphBuffer);
         initialAdvance = finalRoundingWidth + it.m_runWidthSoFar - afterWidth;
     } else
         initialAdvance = beforeWidth;
@@ -483,15 +486,16 @@
 
 FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint& point, int h, int from, int to) const
 {
+    GlyphBuffer glyphBuffer;
     WidthIterator it(this, run);
-    it.advance(from);
+    it.advance(from, &glyphBuffer);
     float beforeWidth = it.m_runWidthSoFar;
-    it.advance(to);
+    it.advance(to, &glyphBuffer);
     float afterWidth = it.m_runWidthSoFar;
 
     // Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning.
     if (run.rtl()) {
-        it.advance(run.length());
+        it.advance(run.length(), &glyphBuffer);
         float totalWidth = it.m_runWidthSoFar;
         return FloatRect(floorf(point.x() + totalWidth - afterWidth), point.y(), roundf(point.x() + totalWidth - beforeWidth) - floorf(point.x() + totalWidth - afterWidth), h);
     }
@@ -511,7 +515,7 @@
         while (1) {
             offset = it.m_currentCharacter;
             float w;
-            if (!it.advanceOneCharacter(w, &localGlyphBuffer))
+            if (!it.advanceOneCharacter(w, localGlyphBuffer))
                 break;
             delta += w;
             if (includePartialGlyphs) {
@@ -526,7 +530,7 @@
         while (1) {
             offset = it.m_currentCharacter;
             float w;
-            if (!it.advanceOneCharacter(w, &localGlyphBuffer))
+            if (!it.advanceOneCharacter(w, localGlyphBuffer))
                 break;
             delta -= w;
             if (includePartialGlyphs) {

Modified: trunk/Source/WebCore/platform/graphics/GlyphBuffer.h (131364 => 131365)


--- trunk/Source/WebCore/platform/graphics/GlyphBuffer.h	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebCore/platform/graphics/GlyphBuffer.h	2012-10-15 21:50:53 UTC (rev 131365)
@@ -63,11 +63,32 @@
 // CG uses CGSize instead of FloatSize so that the result of advances()
 // can be passed directly to CGContextShowGlyphsWithAdvances in FontMac.mm
 #if USE(CG) || (OS(DARWIN) && (PLATFORM(WX) || PLATFORM(CHROMIUM)))
-typedef CGSize GlyphBufferAdvance;
+struct GlyphBufferAdvance : CGSize {
+public:
+    GlyphBufferAdvance(CGSize size) : CGSize(size)
+    {
+    }
+
+    void setWidth(CGFloat width) { this->CGSize::width = width; }
+    CGFloat width() const { return this->CGSize::width; }
+};
 #elif OS(WINCE)
 // There is no cross-platform code that uses the height of GlyphBufferAdvance,
 // so we can save memory space on embedded devices by storing only the width
-typedef float GlyphBufferAdvance;
+struct GlyphBufferAdvance {
+public:
+    GlyphBufferAdvance(float width)
+        : advance(width)
+    {
+    }
+
+    void setWidth(float width) { advance = width; }
+    float& width() { return advance; }
+    const float& width() const { return advance; }
+
+private:
+    float advance;
+};
 #else
 typedef FloatSize GlyphBufferAdvance;
 #endif
@@ -126,13 +147,7 @@
 
     float advanceAt(int index) const
     {
-#if USE(CG) || (OS(DARWIN) && (PLATFORM(WX) || PLATFORM(CHROMIUM)))
-        return m_advances[index].width;
-#elif OS(WINCE)
-        return m_advances[index];
-#else
         return m_advances[index].width();
-#endif
     }
 
     FloatSize offsetAt(int index) const
@@ -196,13 +211,7 @@
     {
         ASSERT(!isEmpty());
         GlyphBufferAdvance& lastAdvance = m_advances.last();
-#if USE(CG) || (OS(DARWIN) && (PLATFORM(WX) || PLATFORM(CHROMIUM)))
-        lastAdvance.width += width;
-#elif OS(WINCE)
-        lastAdvance += width;
-#else
-        lastAdvance += FloatSize(width, 0);
-#endif
+        lastAdvance.setWidth(lastAdvance.width() + width);
     }
 
 private:

Modified: trunk/Source/WebCore/platform/graphics/SimpleFontData.h (131364 => 131365)


--- trunk/Source/WebCore/platform/graphics/SimpleFontData.h	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebCore/platform/graphics/SimpleFontData.h	2012-10-15 21:50:53 UTC (rev 131365)
@@ -29,6 +29,7 @@
 #include "FontMetrics.h"
 #include "FontPlatformData.h"
 #include "FloatRect.h"
+#include "GlyphBuffer.h"
 #include "GlyphMetricsMap.h"
 #include "GlyphPageTreeNode.h"
 #if ENABLE(OPENTYPE_VERTICAL)
@@ -37,8 +38,13 @@
 #include "TypesettingFeatures.h"
 #include <wtf/OwnPtr.h>
 #include <wtf/PassOwnPtr.h>
+#include <wtf/UnusedParam.h>
 #include <wtf/text/StringHash.h>
 
+#if PLATFORM(MAC)
+#include "WebCoreSystemInterface.h"
+#endif
+
 #if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) || (PLATFORM(WX) && OS(DARWIN))
 #include <wtf/RetainPtr.h>
 #endif
@@ -190,6 +196,21 @@
     bool canRenderCombiningCharacterSequence(const UChar*, size_t) const;
 #endif
 
+    bool applyTransforms(GlyphBufferGlyph* glyphs, GlyphBufferAdvance* advances, size_t glyphCount, TypesettingFeatures typesettingFeatures) const
+    {
+#if !PLATFORM(MAC) || __MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
+        UNUSED_PARAM(glyphs);
+        UNUSED_PARAM(advances);
+        UNUSED_PARAM(glyphCount);
+        UNUSED_PARAM(typesettingFeatures);
+        ASSERT_NOT_REACHED();
+        return false;
+#else
+    wkCTFontTransformOptions options = (typesettingFeatures & Kerning ? wkCTFontTransformApplyPositioning : 0) | (typesettingFeatures & Ligatures ? wkCTFontTransformApplyShaping : 0);
+    return wkCTFontTransformGlyphs(m_platformData.ctFont(), glyphs, reinterpret_cast<CGSize*>(advances), glyphCount, options);
+#endif
+    }
+
 #if PLATFORM(QT)
     QRawFont getQtRawFont() const { return m_platformData.rawFont(); }
 #endif

Modified: trunk/Source/WebCore/platform/graphics/WidthIterator.cpp (131364 => 131365)


--- trunk/Source/WebCore/platform/graphics/WidthIterator.cpp	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebCore/platform/graphics/WidthIterator.cpp	2012-10-15 21:50:53 UTC (rev 131365)
@@ -43,6 +43,7 @@
     , m_runWidthSoFar(0)
     , m_isAfterExpansion(!run.allowsLeadingExpansion())
     , m_finalRoundingWidth(0)
+    , m_typesettingFeatures(font->typesettingFeatures())
     , m_fallbackFonts(fallbackFonts)
     , m_accountForGlyphBounds(accountForGlyphBounds)
     , m_maxGlyphBoundingBoxY(numeric_limits<float>::min())
@@ -84,6 +85,66 @@
     return m_font->glyphDataForCharacter(character, mirror);
 }
 
+struct OriginalAdvancesForCharacterTreatedAsSpace {
+public:
+    OriginalAdvancesForCharacterTreatedAsSpace(bool isSpace, float advanceBefore, float advanceAt)
+        : characterIsSpace(isSpace)
+        , advanceBeforeCharacter(advanceBefore)
+        , advanceAtCharacter(advanceAt)
+    {
+    }
+
+    bool characterIsSpace;
+    float advanceBeforeCharacter;
+    float advanceAtCharacter;
+};
+
+typedef Vector<pair<int, OriginalAdvancesForCharacterTreatedAsSpace>, 64> CharactersTreatedAsSpace;
+
+static inline float applyFontTransforms(GlyphBuffer* glyphBuffer, bool ltr, int& lastGlyphCount, const SimpleFontData* fontData, TypesettingFeatures typesettingFeatures, CharactersTreatedAsSpace& charactersTreatedAsSpace)
+{
+    ASSERT(typesettingFeatures & (Kerning | Ligatures));
+
+    if (!glyphBuffer)
+        return 0;
+
+    int glyphBufferSize = glyphBuffer->size();
+    if (glyphBuffer->size() <= lastGlyphCount)
+        return 0;
+
+    GlyphBufferAdvance* advances = glyphBuffer->advances(0);
+    float widthDifference = 0;
+    for (int i = lastGlyphCount; i < glyphBufferSize; ++i)
+        widthDifference -= advances[i].width();
+
+    if (!ltr) {
+        for (int i = 0, end = glyphBuffer->size() - 1; i < glyphBuffer->size() / 2; ++i, --end)
+            glyphBuffer->swap(i, end);
+    }
+
+    fontData->applyTransforms(glyphBuffer->glyphs(lastGlyphCount), advances + lastGlyphCount, glyphBufferSize - lastGlyphCount, typesettingFeatures);
+
+    if (!ltr) {
+        for (int i = 0, end = glyphBuffer->size() - 1; i < glyphBuffer->size() / 2; ++i, --end)
+            glyphBuffer->swap(i, end);
+    }
+
+    for (size_t i = 0; i < charactersTreatedAsSpace.size(); ++i) {
+        int spaceOffset = charactersTreatedAsSpace[i].first;
+        const OriginalAdvancesForCharacterTreatedAsSpace& originalAdvances = charactersTreatedAsSpace[i].second;
+        if (spaceOffset && !originalAdvances.characterIsSpace)
+            glyphBuffer->advances(spaceOffset - 1)->setWidth(originalAdvances.advanceBeforeCharacter);
+        glyphBuffer->advances(spaceOffset)->setWidth(originalAdvances.advanceAtCharacter);
+    }
+    charactersTreatedAsSpace.clear();
+
+    for (int i = lastGlyphCount; i < glyphBufferSize; ++i)
+        widthDifference += advances[i].width();
+
+    lastGlyphCount = glyphBufferSize;
+    return widthDifference;
+}
+
 template <typename TextIterator>
 inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, GlyphBuffer* glyphBuffer)
 {
@@ -99,10 +160,11 @@
 
     const SimpleFontData* primaryFont = m_font->primaryFont();
     const SimpleFontData* lastFontData = primaryFont;
+    int lastGlyphCount = glyphBuffer ? glyphBuffer->size() : 0;
 
     UChar32 character = 0;
     unsigned clusterLength = 0;
-
+    CharactersTreatedAsSpace charactersTreatedAsSpace;
     while (textIterator.consume(character, clusterLength)) {
         unsigned advanceLength = clusterLength;
         const GlyphData& glyphData = glyphDataForCharacter(character, rtl, textIterator.currentCharacter(), advanceLength);
@@ -132,6 +194,9 @@
         }
 
         if (fontData != lastFontData && width) {
+            if (shouldApplyFontTransforms())
+                m_runWidthSoFar += applyFontTransforms(glyphBuffer, m_run.ltr(), lastGlyphCount, lastFontData, m_typesettingFeatures, charactersTreatedAsSpace);
+
             lastFontData = fontData;
             if (m_fallbackFonts && fontData != primaryFont) {
                 // FIXME: This does a little extra work that could be avoided if
@@ -187,6 +252,10 @@
                 m_isAfterExpansion = false;
         }
 
+        if (shouldApplyFontTransforms() && glyphBuffer && Font::treatAsSpace(character))
+            charactersTreatedAsSpace.append(make_pair(glyphBuffer->size(),
+                OriginalAdvancesForCharacterTreatedAsSpace(character == ' ', glyphBuffer->size() ? glyphBuffer->advanceAt(glyphBuffer->size() - 1) : 0, width)));
+
         if (m_accountForGlyphBounds) {
             bounds = fontData->boundsForGlyph(glyph);
             if (!textIterator.currentCharacter())
@@ -239,6 +308,9 @@
         }
     }
 
+    if (shouldApplyFontTransforms())
+        m_runWidthSoFar += applyFontTransforms(glyphBuffer, m_run.ltr(), lastGlyphCount, lastFontData, m_typesettingFeatures, charactersTreatedAsSpace);
+
     unsigned consumedCharacters = textIterator.currentCharacter() - m_currentCharacter;
     m_currentCharacter = textIterator.currentCharacter();
     m_runWidthSoFar += widthSinceLastRounding;
@@ -265,15 +337,15 @@
     return advanceInternal(textIterator, glyphBuffer);
 }
 
-bool WidthIterator::advanceOneCharacter(float& width, GlyphBuffer* glyphBuffer)
+bool WidthIterator::advanceOneCharacter(float& width, GlyphBuffer& glyphBuffer)
 {
-    int oldSize = glyphBuffer->size();
-    advance(m_currentCharacter + 1, glyphBuffer);
+    int oldSize = glyphBuffer.size();
+    advance(m_currentCharacter + 1, &glyphBuffer);
     float w = 0;
-    for (int i = oldSize; i < glyphBuffer->size(); ++i)
-        w += glyphBuffer->advanceAt(i);
+    for (int i = oldSize; i < glyphBuffer.size(); ++i)
+        w += glyphBuffer.advanceAt(i);
     width = w;
-    return glyphBuffer->size() > oldSize;
+    return glyphBuffer.size() > oldSize;
 }
 
 }

Modified: trunk/Source/WebCore/platform/graphics/WidthIterator.h (131364 => 131365)


--- trunk/Source/WebCore/platform/graphics/WidthIterator.h	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebCore/platform/graphics/WidthIterator.h	2012-10-15 21:50:53 UTC (rev 131365)
@@ -22,6 +22,7 @@
 #ifndef WidthIterator_h
 #define WidthIterator_h
 
+#include "Font.h"
 #include "SVGGlyph.h"
 #include <wtf/HashSet.h>
 #include <wtf/Vector.h>
@@ -40,8 +41,8 @@
 public:
     WidthIterator(const Font*, const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, bool accountForGlyphBounds = false, bool forTextEmphasis = false);
 
-    unsigned advance(int to, GlyphBuffer* = 0);
-    bool advanceOneCharacter(float& width, GlyphBuffer* = 0);
+    unsigned advance(int to, GlyphBuffer*);
+    bool advanceOneCharacter(float& width, GlyphBuffer&);
 
     float maxGlyphBoundingBoxY() const { ASSERT(m_accountForGlyphBounds); return m_maxGlyphBoundingBoxY; }
     float minGlyphBoundingBoxY() const { ASSERT(m_accountForGlyphBounds); return m_minGlyphBoundingBoxY; }
@@ -57,6 +58,18 @@
     Vector<SVGGlyph::ArabicForm>& arabicForms() { return m_arabicForms; }
 #endif
 
+    static bool supportsTypesettingFeatures(const Font& font)
+    {
+#if !PLATFORM(MAC) || __MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
+        return !font.typesettingFeatures();
+#else
+        if (!font.isPrinterFont())
+            return !font.typesettingFeatures();
+
+        return !(font.typesettingFeatures() & ~(Kerning | Ligatures));
+#endif
+    }
+
     const Font* m_font;
 
     const TextRun& m_run;
@@ -78,6 +91,9 @@
     template <typename TextIterator>
     inline unsigned advanceInternal(TextIterator&, GlyphBuffer*);
 
+    bool shouldApplyFontTransforms() const { return m_typesettingFeatures & (Kerning | Ligatures); }
+
+    TypesettingFeatures m_typesettingFeatures;
     HashSet<const SimpleFontData*>* m_fallbackFonts;
     bool m_accountForGlyphBounds;
     float m_maxGlyphBoundingBoxY;

Modified: trunk/Source/WebCore/platform/graphics/mac/FontMac.mm (131364 => 131365)


--- trunk/Source/WebCore/platform/graphics/mac/FontMac.mm	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebCore/platform/graphics/mac/FontMac.mm	2012-10-15 21:50:53 UTC (rev 131365)
@@ -241,15 +241,15 @@
         float shadowTextX = point.x() + shadowOffset.width();
         // If shadows are ignoring transforms, then we haven't applied the Y coordinate flip yet, so down is negative.
         float shadowTextY = point.y() + shadowOffset.height() * (context->shadowsIgnoreTransforms() ? -1 : 1);
-        showGlyphsWithAdvances(FloatPoint(shadowTextX, shadowTextY), font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+        showGlyphsWithAdvances(FloatPoint(shadowTextX, shadowTextY), font, cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
         if (syntheticBoldOffset)
-            showGlyphsWithAdvances(FloatPoint(shadowTextX + syntheticBoldOffset, shadowTextY), font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+            showGlyphsWithAdvances(FloatPoint(shadowTextX + syntheticBoldOffset, shadowTextY), font, cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
         context->setFillColor(fillColor, fillColorSpace);
     }
 
-    showGlyphsWithAdvances(point, font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+    showGlyphsWithAdvances(point, font, cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
     if (syntheticBoldOffset)
-        showGlyphsWithAdvances(FloatPoint(point.x() + syntheticBoldOffset, point.y()), font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+        showGlyphsWithAdvances(FloatPoint(point.x() + syntheticBoldOffset, point.y()), font, cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
 
     if (hasSimpleShadow)
         context->setShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace);

Modified: trunk/Source/WebCore/platform/graphics/win/FontCGWin.cpp (131364 => 131365)


--- trunk/Source/WebCore/platform/graphics/win/FontCGWin.cpp	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebCore/platform/graphics/win/FontCGWin.cpp	2012-10-15 21:50:53 UTC (rev 131365)
@@ -197,19 +197,19 @@
         // If shadows are ignoring transforms, then we haven't applied the Y coordinate flip yet, so down is negative.
         float shadowTextY = point.y() + translation.height() + shadowOffset.height() * (graphicsContext->shadowsIgnoreTransforms() ? -1 : 1);
         CGContextSetTextPosition(cgContext, shadowTextX, shadowTextY);
-        CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+        CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
         if (font->syntheticBoldOffset()) {
             CGContextSetTextPosition(cgContext, point.x() + translation.width() + shadowOffset.width() + font->syntheticBoldOffset(), point.y() + translation.height() + shadowOffset.height());
-            CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+            CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
         }
         graphicsContext->setFillColor(fillColor, ColorSpaceDeviceRGB);
     }
 
     CGContextSetTextPosition(cgContext, point.x() + translation.width(), point.y() + translation.height());
-    CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+    CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
     if (font->syntheticBoldOffset()) {
         CGContextSetTextPosition(cgContext, point.x() + translation.width() + font->syntheticBoldOffset(), point.y() + translation.height());
-        CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+        CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
     }
 
     if (hasSimpleShadow)

Modified: trunk/Source/WebCore/platform/mac/WebCoreSystemInterface.h (131364 => 131365)


--- trunk/Source/WebCore/platform/mac/WebCoreSystemInterface.h	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebCore/platform/mac/WebCoreSystemInterface.h	2012-10-15 21:50:53 UTC (rev 131365)
@@ -235,6 +235,17 @@
 
 extern CTLineRef (*wkCreateCTLineWithUniCharProvider)(const UniChar* (*provide)(CFIndex stringIndex, CFIndex* charCount, CFDictionaryRef* attributes, void*), void (*dispose)(const UniChar* chars, void*), void*);
 
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+enum {
+    wkCTFontTransformApplyShaping = (1 << 0),
+    wkCTFontTransformApplyPositioning = (1 << 1)
+};
+
+typedef int wkCTFontTransformOptions;
+
+extern bool (*wkCTFontTransformGlyphs)(CTFontRef font, CGGlyph glyphs[], CGSize advances[], CFIndex count, wkCTFontTransformOptions options);
+#endif
+
 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
 
 extern CTTypesetterRef (*wkCreateCTTypesetterWithUniCharProviderAndOptions)(const UniChar* (*provide)(CFIndex stringIndex, CFIndex* charCount, CFDictionaryRef* attributes, void*), void (*dispose)(const UniChar* chars, void*), void*, CFDictionaryRef options);

Modified: trunk/Source/WebCore/platform/mac/WebCoreSystemInterface.mm (131364 => 131365)


--- trunk/Source/WebCore/platform/mac/WebCoreSystemInterface.mm	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebCore/platform/mac/WebCoreSystemInterface.mm	2012-10-15 21:50:53 UTC (rev 131365)
@@ -136,6 +136,10 @@
 #endif
 
 CTLineRef (*wkCreateCTLineWithUniCharProvider)(const UniChar* (*provide)(CFIndex stringIndex, CFIndex* charCount, CFDictionaryRef* attributes, void*), void (*dispose)(const UniChar* chars, void*), void*);
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+bool (*wkCTFontTransformGlyphs)(CTFontRef font, CGGlyph glyphs[], CGSize advances[], CFIndex count, wkCTFontTransformOptions options);
+#endif
+
 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
 CTTypesetterRef (*wkCreateCTTypesetterWithUniCharProviderAndOptions)(const UniChar* (*provide)(CFIndex stringIndex, CFIndex* charCount, CFDictionaryRef* attributes, void*), void (*dispose)(const UniChar* chars, void*), void*, CFDictionaryRef options);
 

Modified: trunk/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.cpp (131364 => 131365)


--- trunk/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.cpp	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.cpp	2012-10-15 21:50:53 UTC (rev 131365)
@@ -58,7 +58,8 @@
 
 void SVGTextMetricsBuilder::advanceSimpleText()
 {
-    unsigned metricsLength = m_simpleWidthIterator->advance(m_textPosition + 1);
+    GlyphBuffer glyphBuffer;
+    unsigned metricsLength = m_simpleWidthIterator->advance(m_textPosition + 1, &glyphBuffer);
     if (!metricsLength) {
         m_currentMetrics = SVGTextMetrics();
         return;

Modified: trunk/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp (131364 => 131365)


--- trunk/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp	2012-10-15 21:50:53 UTC (rev 131365)
@@ -76,7 +76,8 @@
 float SVGTextRunRenderingContext::floatWidthUsingSVGFont(const Font& font, const TextRun& run, int& charsConsumed, String& glyphName) const
 {
     WidthIterator it(&font, run);
-    charsConsumed += it.advance(run.length());
+    GlyphBuffer glyphBuffer;
+    charsConsumed += it.advance(run.length(), &glyphBuffer);
     glyphName = it.lastGlyphName();
     return it.runWidthSoFar();
 }

Modified: trunk/Source/WebKit/mac/ChangeLog (131364 => 131365)


--- trunk/Source/WebKit/mac/ChangeLog	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebKit/mac/ChangeLog	2012-10-15 21:50:53 UTC (rev 131365)
@@ -1,3 +1,13 @@
+2012-10-15  Dan Bernstein  <m...@apple.com>
+
+        WebKit/mac part of <rdar://problem/12470680> Font’s fast code path doesn’t support kerning and ligatures
+        https://bugs.webkit.org/show_bug.cgi?id=99113
+
+        Reviewed by Tim Horton.
+
+        * WebCoreSupport/WebSystemInterface.mm:
+        (InitWebCoreSystemInterface): Added wkCTFontTransformGlyphs.
+
 2012-10-15  David Kilzer  <ddkil...@apple.com>
 
         Move framework and library linking into WebKit.xcconfig

Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebSystemInterface.mm (131364 => 131365)


--- trunk/Source/WebKit/mac/WebCoreSupport/WebSystemInterface.mm	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebSystemInterface.mm	2012-10-15 21:50:53 UTC (rev 131365)
@@ -52,6 +52,9 @@
 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
     INIT(CGContextDrawsWithCorrectShadowOffsets);
 #endif
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+    INIT(CTFontTransformGlyphs);
+#endif
     INIT(CopyCFLocalizationPreferredName);
     INIT(CopyCONNECTProxyResponse);
     INIT(CopyNSURLResponseStatusLine);

Modified: trunk/Source/WebKit2/ChangeLog (131364 => 131365)


--- trunk/Source/WebKit2/ChangeLog	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebKit2/ChangeLog	2012-10-15 21:50:53 UTC (rev 131365)
@@ -1,3 +1,13 @@
+2012-10-15  Dan Bernstein  <m...@apple.com>
+
+        WebKit2 part of <rdar://problem/12470680> Font’s fast code path doesn’t support kerning and ligatures
+        https://bugs.webkit.org/show_bug.cgi?id=99113
+
+        Reviewed by Tim Horton.
+
+        * WebProcess/WebCoreSupport/mac/WebSystemInterface.mm:
+        (InitWebCoreSystemInterface): Added wkCTFontTransformGlyphs.
+
 2012-10-15  Christophe Dumez  <christophe.du...@intel.com>
 
         [WK2][CAIRO] Use cairo_format_stride_for_width() in ShareableBitmap

Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebSystemInterface.mm (131364 => 131365)


--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebSystemInterface.mm	2012-10-15 21:42:28 UTC (rev 131364)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebSystemInterface.mm	2012-10-15 21:50:53 UTC (rev 131365)
@@ -47,6 +47,9 @@
 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
         INIT(CGContextDrawsWithCorrectShadowOffsets);
 #endif
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+        INIT(CTFontTransformGlyphs);
+#endif
         INIT(CopyCONNECTProxyResponse);
         INIT(CopyNSURLResponseStatusLine);
         INIT(CreateCTLineWithUniCharProvider);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to