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 <[email protected]>
+
+ 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 <[email protected]>
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 <[email protected]>
+
+ 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 <[email protected]>
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 <[email protected]>
+
+ 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 <[email protected]>
[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);