summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/svg
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2013-09-27 14:45:02 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-01 19:37:11 +0200
commit2c4ff38a22a2d6d13ab4a833082cc76f65af3b4f (patch)
treefd45094b1832e2210c35a4b9beaa1455778fba4c /Source/WebCore/rendering/svg
parente4dcbab26b8b25df40b7d8937ac1306f4e19c84e (diff)
downloadqtwebkit-2c4ff38a22a2d6d13ab4a833082cc76f65af3b4f.tar.gz
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/rendering/svg')
-rw-r--r--Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp42
-rw-r--r--Source/WebCore/rendering/svg/SVGTextRunRenderingContext.h1
2 files changed, 42 insertions, 1 deletions
diff --git a/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp b/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp
index f94b283e6..7474adfbf 100644
--- a/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp
@@ -81,7 +81,47 @@ float SVGTextRunRenderingContext::floatWidthUsingSVGFont(const Font& font, const
glyphName = it.lastGlyphName();
return it.runWidthSoFar();
}
-
+
+bool SVGTextRunRenderingContext::applySVGKerning(const SimpleFontData* fontData, WidthIterator& iterator, GlyphBuffer* glyphBuffer, int from) const
+{
+ ASSERT(glyphBuffer);
+ ASSERT(glyphBuffer->size() > 1);
+ SVGFontElement* fontElement = 0;
+ SVGFontFaceElement* fontFaceElement = 0;
+
+ svgFontAndFontFaceElementForFontData(fontData, fontFaceElement, fontElement);
+ if (!fontElement || !fontFaceElement)
+ return false;
+
+ float scale = scaleEmToUnits(fontData->platformData().size(), fontFaceElement->unitsPerEm());
+
+ String lastGlyphName;
+ String lastUnicodeString;
+ int characterOffset = iterator.m_currentCharacter;
+ String text = iterator.run().string();
+ const int glyphCount = glyphBuffer->size() - from;
+ GlyphBufferAdvance* advances = glyphBuffer->advances(from);
+
+ for (int i = 0; i < glyphCount; ++i) {
+ Glyph glyph = glyphBuffer->glyphAt(from + i);
+ if (!glyph)
+ continue;
+ float kerning = 0;
+ SVGGlyph svgGlyph = fontElement->svgGlyphForGlyph(glyph);
+ String unicodeString = text.substring(characterOffset, svgGlyph.unicodeStringLength);
+ if (i >= 1) {
+ // FIXME: Support vertical text.
+ kerning = fontElement->horizontalKerningForPairOfStringsAndGlyphs(lastUnicodeString, lastGlyphName, unicodeString, svgGlyph.glyphName);
+ advances[i - 1].setWidth(advances[i - 1].width() - kerning * scale);
+ }
+ lastGlyphName = svgGlyph.glyphName;
+ lastUnicodeString = unicodeString;
+ characterOffset += svgGlyph.unicodeStringLength;
+ }
+
+ return true;
+}
+
void SVGTextRunRenderingContext::drawSVGGlyphs(GraphicsContext* context, const TextRun& run, const SimpleFontData* fontData, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const
{
SVGFontElement* fontElement = 0;
diff --git a/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.h b/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.h
index bb92bea8c..04b724685 100644
--- a/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.h
+++ b/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.h
@@ -45,6 +45,7 @@ public:
virtual GlyphData glyphDataForCharacter(const Font&, const TextRun&, WidthIterator&, UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength);
virtual void drawSVGGlyphs(GraphicsContext*, const TextRun&, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const;
virtual float floatWidthUsingSVGFont(const Font&, const TextRun&, int& charsConsumed, String& glyphName) const;
+ virtual bool applySVGKerning(const SimpleFontData*, WidthIterator&, GlyphBuffer*, int from) const;
#endif
private: