diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2013-09-27 14:45:02 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-01 19:37:11 +0200 |
commit | 2c4ff38a22a2d6d13ab4a833082cc76f65af3b4f (patch) | |
tree | fd45094b1832e2210c35a4b9beaa1455778fba4c /Source/WebCore/platform | |
parent | e4dcbab26b8b25df40b7d8937ac1306f4e19c84e (diff) |
Support kerning with SVG web fonts
https://bugs.webkit.org/show_bug.cgi?id=117540
Reviewed by Stephen Chenney.
Adds the glue to WidthIterator to take advantage of kerning in SVG web fonts.
To supply SVG font kerning with its required text input, the signature of
applyFontTransforms has been extended.
Since SVG font kerning was extremely slow, it has been sped up by replacing
the iteration over all possible kerning definitions with a hash-map based
lookup of the leading symbol to be kerned. The new algorithm provides a
roughly 100x speed-up in SVG font kerning.
Test: fast/text/svg-font-face-with-kerning.html
* platform/graphics/TextRun.h:
(WebCore::TextRun::string):
* platform/graphics/WidthIterator.cpp:
(WebCore::applyFontTransforms):
(WebCore::WidthIterator::advanceInternal):
* rendering/svg/SVGTextRunRenderingContext.cpp:
(WebCore::SVGTextRunRenderingContext::applySVGKerning):
* rendering/svg/SVGTextRunRenderingContext.h:
* svg/SVGFontElement.cpp:
(WebCore::SVGFontElement::invalidateGlyphCache):
(WebCore::SVGFontElement::ensureGlyphCache):
(WebCore::SVGKerningMap::clear):
(WebCore::SVGKerningMap::insert):
(WebCore::stringMatchesUnicodeRange):
(WebCore::stringMatchesGlyphName):
(WebCore::stringMatchesUnicodeName):
(WebCore::matches):
(WebCore::kerningForPairOfStringsAndGlyphs):
(WebCore::SVGFontElement::horizontalKerningForPairOfStringsAndGlyphs):
(WebCore::SVGFontElement::verticalKerningForPairOfStringsAndGlyphs):
* svg/SVGFontElement.h:
(WebCore::SVGKerning::SVGKerning):
(WebCore::SVGKerningMap::isEmpty):
* svg/SVGHKernElement.cpp:
(WebCore::SVGHKernElement::buildHorizontalKerningPair):
* svg/SVGHKernElement.h:
* svg/SVGVKernElement.cpp:
(WebCore::SVGVKernElement::buildVerticalKerningPair):
* svg/SVGVKernElement.h:
Change-Id: I309d05b57df3a85fa9720e56f4ace53d5d1d8cf5
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@156393 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/WebCore/platform')
-rw-r--r-- | Source/WebCore/platform/graphics/TextRun.h | 7 | ||||
-rw-r--r-- | Source/WebCore/platform/graphics/WidthIterator.cpp | 17 | ||||
-rw-r--r-- | Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp | 4 |
3 files changed, 23 insertions, 5 deletions
diff --git a/Source/WebCore/platform/graphics/TextRun.h b/Source/WebCore/platform/graphics/TextRun.h index 895a1e95d..2a194cc9c 100644 --- a/Source/WebCore/platform/graphics/TextRun.h +++ b/Source/WebCore/platform/graphics/TextRun.h @@ -165,6 +165,12 @@ public: bool is8Bit() const { return m_is8Bit; } int length() const { return m_len; } int charactersLength() const { return m_charactersLength; } + String string() const + { + if (is8Bit()) + return String(m_data.characters8, m_len); + return String(m_data.characters16, m_len); + } #if ENABLE(8BIT_TEXTRUN) void setText(const LChar* c, unsigned len) { m_data.characters8 = c; m_len = len; m_is8Bit = true;} @@ -209,6 +215,7 @@ public: virtual GlyphData glyphDataForCharacter(const Font&, const TextRun&, WidthIterator&, UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength) = 0; virtual void drawSVGGlyphs(GraphicsContext*, const TextRun&, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const = 0; virtual float floatWidthUsingSVGFont(const Font&, const TextRun&, int& charsConsumed, String& glyphName) const = 0; + virtual bool applySVGKerning(const SimpleFontData*, WidthIterator&, GlyphBuffer*, int from) const = 0; #endif }; diff --git a/Source/WebCore/platform/graphics/WidthIterator.cpp b/Source/WebCore/platform/graphics/WidthIterator.cpp index 5fcf94969..e8b620f8a 100644 --- a/Source/WebCore/platform/graphics/WidthIterator.cpp +++ b/Source/WebCore/platform/graphics/WidthIterator.cpp @@ -102,7 +102,7 @@ public: typedef Vector<pair<int, OriginalAdvancesForCharacterTreatedAsSpace>, 64> CharactersTreatedAsSpace; -static inline float applyFontTransforms(GlyphBuffer* glyphBuffer, bool ltr, int& lastGlyphCount, const SimpleFontData* fontData, TypesettingFeatures typesettingFeatures, CharactersTreatedAsSpace& charactersTreatedAsSpace) +static inline float applyFontTransforms(GlyphBuffer* glyphBuffer, bool ltr, int& lastGlyphCount, const SimpleFontData* fontData, WidthIterator& iterator, TypesettingFeatures typesettingFeatures, CharactersTreatedAsSpace& charactersTreatedAsSpace) { ASSERT(typesettingFeatures & (Kerning | Ligatures)); @@ -121,7 +121,16 @@ static inline float applyFontTransforms(GlyphBuffer* glyphBuffer, bool ltr, int& if (!ltr) glyphBuffer->reverse(lastGlyphCount, glyphBufferSize - lastGlyphCount); - fontData->applyTransforms(glyphBuffer->glyphs(lastGlyphCount), advances + lastGlyphCount, glyphBufferSize - lastGlyphCount, typesettingFeatures); +#if ENABLE(SVG_FONTS) + // We need to handle transforms on SVG fonts internally, since they are rendered internally. + if (fontData->isSVGFont()) { + ASSERT(iterator.run().renderingContext()); + // SVG font ligatures are handled during glyph selection, only kerning remaining. + if (typesettingFeatures & Kerning) + iterator.run().renderingContext()->applySVGKerning(fontData, iterator, glyphBuffer, lastGlyphCount); + } else +#endif + fontData->applyTransforms(glyphBuffer->glyphs(lastGlyphCount), advances + lastGlyphCount, glyphBufferSize - lastGlyphCount, typesettingFeatures); if (!ltr) glyphBuffer->reverse(lastGlyphCount, glyphBufferSize - lastGlyphCount); @@ -193,7 +202,7 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph if (fontData != lastFontData && width) { if (shouldApplyFontTransforms()) { - m_runWidthSoFar += applyFontTransforms(glyphBuffer, m_run.ltr(), lastGlyphCount, lastFontData, m_typesettingFeatures, charactersTreatedAsSpace); + m_runWidthSoFar += applyFontTransforms(glyphBuffer, m_run.ltr(), lastGlyphCount, lastFontData, *this, m_typesettingFeatures, charactersTreatedAsSpace); lastGlyphCount = glyphBuffer->size(); // applyFontTransforms doesn't update when there had been only one glyph. } @@ -315,7 +324,7 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph } if (shouldApplyFontTransforms()) - m_runWidthSoFar += applyFontTransforms(glyphBuffer, m_run.ltr(), lastGlyphCount, lastFontData, m_typesettingFeatures, charactersTreatedAsSpace); + m_runWidthSoFar += applyFontTransforms(glyphBuffer, m_run.ltr(), lastGlyphCount, lastFontData, *this, m_typesettingFeatures, charactersTreatedAsSpace); unsigned consumedCharacters = textIterator.currentCharacter() - m_currentCharacter; m_currentCharacter = textIterator.currentCharacter(); diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp index 80c253543..7e7babbcd 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp @@ -72,8 +72,10 @@ void TextureMapperLayer::computeTransformsRecursive() m_state.maskLayer->computeTransformsRecursive(); if (m_state.replicaLayer) m_state.replicaLayer->computeTransformsRecursive(); - for (size_t i = 0; i < m_children.size(); ++i) + for (size_t i = 0; i < m_children.size(); ++i) { + RELEASE_ASSERT(m_children[i]->m_parent == this); m_children[i]->computeTransformsRecursive(); + } // Reorder children if needed on the way back up. if (m_state.preserves3D) |