diff options
Diffstat (limited to 'WebCore/rendering/SVGRootInlineBox.cpp')
-rw-r--r-- | WebCore/rendering/SVGRootInlineBox.cpp | 165 |
1 files changed, 88 insertions, 77 deletions
diff --git a/WebCore/rendering/SVGRootInlineBox.cpp b/WebCore/rendering/SVGRootInlineBox.cpp index 89b4375..6c99b1a 100644 --- a/WebCore/rendering/SVGRootInlineBox.cpp +++ b/WebCore/rendering/SVGRootInlineBox.cpp @@ -4,6 +4,7 @@ * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz> * (C) 2006 Apple Computer Inc. * (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) Research In Motion Limited 2010. 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 @@ -32,12 +33,12 @@ #include "Frame.h" #include "GraphicsContext.h" #include "RenderBlock.h" +#include "RenderSVGResource.h" #include "RenderSVGResourceFilter.h" #include "RenderSVGRoot.h" #include "SVGInlineFlowBox.h" #include "SVGInlineTextBox.h" #include "SVGFontElement.h" -#include "SVGPaintServer.h" #include "SVGRenderStyleDefs.h" #include "SVGRenderSupport.h" #include "SVGTextPositioningElement.h" @@ -319,7 +320,7 @@ FloatPoint topLeftPositionOfCharacterRange(Vector<SVGChar>::iterator it, Vector< } // Helper function -static float calculateKerning(RenderObject* item) +static float calculateCSSKerning(RenderObject* item) { const Font& font = item->style()->font(); const SVGRenderStyle* svgStyle = item->style()->svgStyle(); @@ -335,6 +336,40 @@ static float calculateKerning(RenderObject* item) return kerning; } +static bool applySVGKerning(SVGCharacterLayoutInfo& info, RenderObject* item, LastGlyphInfo& lastGlyph, const String& unicodeString, const String& glyphName) +{ +#if ENABLE(SVG_FONTS) + float kerning = 0.0f; + const RenderStyle* style = item->style(); + SVGFontElement* svgFont = 0; + if (style->font().isSVGFont()) + svgFont = style->font().svgFont(); + + if (lastGlyph.isValid && style->font().isSVGFont()) + kerning = svgFont->getHorizontalKerningPairForStringsAndGlyphs(lastGlyph.unicode, lastGlyph.glyphName, unicodeString, glyphName); + + if (style->font().isSVGFont()) { + lastGlyph.unicode = unicodeString; + lastGlyph.glyphName = glyphName; + lastGlyph.isValid = true; + kerning *= style->font().size() / style->font().primaryFont()->unitsPerEm(); + } else + lastGlyph.isValid = false; + + if (kerning != 0.0f) { + info.curx -= kerning; + return true; + } +#else + UNUSED_PARAM(info); + UNUSED_PARAM(item); + UNUSED_PARAM(lastGlyph); + UNUSED_PARAM(unicodeString); + UNUSED_PARAM(glyphName); +#endif + return false; +} + // Helper class for paint() struct SVGRootInlineBoxPaintWalker { SVGRootInlineBoxPaintWalker(SVGRootInlineBox* rootBox, RenderSVGResourceFilter* rootFilter, RenderObject::PaintInfo paintInfo, int tx, int ty) @@ -345,10 +380,10 @@ struct SVGRootInlineBoxPaintWalker { , m_boundingBox(tx + rootBox->x(), ty + rootBox->y(), rootBox->width(), rootBox->height()) , m_filter(0) , m_rootFilter(rootFilter) - , m_fillPaintServer(0) - , m_strokePaintServer(0) - , m_fillPaintServerObject(0) - , m_strokePaintServerObject(0) + , m_fillPaintingResource(0) + , m_strokePaintingResource(0) + , m_fillPaintingResourceObject(0) + , m_strokePaintingResourceObject(0) , m_tx(tx) , m_ty(ty) { @@ -357,10 +392,10 @@ struct SVGRootInlineBoxPaintWalker { ~SVGRootInlineBoxPaintWalker() { ASSERT(!m_filter); - ASSERT(!m_fillPaintServer); - ASSERT(!m_fillPaintServerObject); - ASSERT(!m_strokePaintServer); - ASSERT(!m_strokePaintServerObject); + ASSERT(!m_fillPaintingResource); + ASSERT(!m_fillPaintingResourceObject); + ASSERT(!m_strokePaintingResource); + ASSERT(!m_strokePaintingResourceObject); ASSERT(!m_chunkStarted); } @@ -373,24 +408,22 @@ struct SVGRootInlineBoxPaintWalker { void teardownFillPaintServer() { - if (!m_fillPaintServer) + if (!m_fillPaintingResource) return; - m_fillPaintServer->teardown(m_paintInfo.context, m_fillPaintServerObject, ApplyToFillTargetType, true); - - m_fillPaintServer = 0; - m_fillPaintServerObject = 0; + m_fillPaintingResource->postApplyResource(m_fillPaintingResourceObject, m_paintInfo.context, ApplyToFillMode | ApplyToTextMode); + m_fillPaintingResource = 0; + m_fillPaintingResourceObject = 0; } void teardownStrokePaintServer() { - if (!m_strokePaintServer) + if (!m_strokePaintingResource) return; - m_strokePaintServer->teardown(m_paintInfo.context, m_strokePaintServerObject, ApplyToStrokeTargetType, true); - - m_strokePaintServer = 0; - m_strokePaintServerObject = 0; + m_strokePaintingResource->postApplyResource(m_strokePaintingResourceObject, m_paintInfo.context, ApplyToStrokeMode | ApplyToTextMode); + m_strokePaintingResource = 0; + m_strokePaintingResourceObject = 0; } void chunkStartCallback(InlineBox* box) @@ -437,7 +470,7 @@ struct SVGRootInlineBoxPaintWalker { m_paintInfo.rect = m_savedInfo.rect; } - bool setupBackground(SVGInlineTextBox* /*box*/) + bool setupBackground(SVGInlineTextBox*) { m_textPaintInfo.subphase = SVGTextPaintSubphaseBackground; return true; @@ -451,14 +484,14 @@ struct SVGRootInlineBoxPaintWalker { RenderObject* object = flowBox->renderer(); ASSERT(object); - ASSERT(!m_strokePaintServer); + ASSERT(!m_strokePaintingResource); teardownFillPaintServer(); m_textPaintInfo.subphase = SVGTextPaintSubphaseGlyphFill; - m_fillPaintServer = SVGPaintServer::fillPaintServer(object->style(), object); - if (m_fillPaintServer) { - m_fillPaintServer->setup(m_paintInfo.context, object, ApplyToFillTargetType, true); - m_fillPaintServerObject = object; + m_fillPaintingResource = RenderSVGResource::fillPaintingResource(object, object->style()); + if (m_fillPaintingResource) { + m_fillPaintingResource->applyResource(object, object->style(), m_paintInfo.context, ApplyToFillMode | ApplyToTextMode); + m_fillPaintingResourceObject = object; return true; } @@ -476,17 +509,17 @@ struct SVGRootInlineBoxPaintWalker { if (!style) style = object->style(); - ASSERT(!m_strokePaintServer); + ASSERT(!m_strokePaintingResource); teardownFillPaintServer(); if (!mayHaveSelection(box)) return false; m_textPaintInfo.subphase = SVGTextPaintSubphaseGlyphFillSelection; - m_fillPaintServer = SVGPaintServer::fillPaintServer(style, object); - if (m_fillPaintServer) { - m_fillPaintServer->setup(m_paintInfo.context, object, style, ApplyToFillTargetType, true); - m_fillPaintServerObject = object; + m_fillPaintingResource = RenderSVGResource::fillPaintingResource(object, style); + if (m_fillPaintingResource) { + m_fillPaintingResource->applyResource(object, style, m_paintInfo.context, ApplyToFillMode | ApplyToTextMode); + m_fillPaintingResourceObject = object; return true; } @@ -506,11 +539,10 @@ struct SVGRootInlineBoxPaintWalker { teardownStrokePaintServer(); m_textPaintInfo.subphase = SVGTextPaintSubphaseGlyphStroke; - m_strokePaintServer = SVGPaintServer::strokePaintServer(object->style(), object); - - if (m_strokePaintServer) { - m_strokePaintServer->setup(m_paintInfo.context, object, ApplyToStrokeTargetType, true); - m_strokePaintServerObject = object; + m_strokePaintingResource = RenderSVGResource::strokePaintingResource(object, object->style()); + if (m_strokePaintingResource) { + m_strokePaintingResource->applyResource(object, object->style(), m_paintInfo.context, ApplyToStrokeMode | ApplyToTextMode); + m_strokePaintingResourceObject = object; return true; } @@ -536,17 +568,17 @@ struct SVGRootInlineBoxPaintWalker { return false; m_textPaintInfo.subphase = SVGTextPaintSubphaseGlyphStrokeSelection; - m_strokePaintServer = SVGPaintServer::strokePaintServer(style, object); - if (m_strokePaintServer) { - m_strokePaintServer->setup(m_paintInfo.context, object, style, ApplyToStrokeTargetType, true); - m_strokePaintServerObject = object; + m_strokePaintingResource = RenderSVGResource::strokePaintingResource(object, style); + if (m_strokePaintingResource) { + m_strokePaintingResource->applyResource(object, style, m_paintInfo.context, ApplyToStrokeMode | ApplyToTextMode); + m_strokePaintingResourceObject = object; return true; } return false; } - bool setupForeground(SVGInlineTextBox* /*box*/) + bool setupForeground(SVGInlineTextBox*) { teardownFillPaintServer(); teardownStrokePaintServer(); @@ -556,17 +588,17 @@ struct SVGRootInlineBoxPaintWalker { return true; } - SVGPaintServer* activePaintServer() const + RenderSVGResource* activePaintingResource() const { switch (m_textPaintInfo.subphase) { case SVGTextPaintSubphaseGlyphFill: case SVGTextPaintSubphaseGlyphFillSelection: - ASSERT(m_fillPaintServer); - return m_fillPaintServer; + ASSERT(m_fillPaintingResource); + return m_fillPaintingResource; case SVGTextPaintSubphaseGlyphStroke: case SVGTextPaintSubphaseGlyphStrokeSelection: - ASSERT(m_strokePaintServer); - return m_strokePaintServer; + ASSERT(m_strokePaintingResource); + return m_strokePaintingResource; case SVGTextPaintSubphaseBackground: case SVGTextPaintSubphaseForeground: default: @@ -646,7 +678,7 @@ struct SVGRootInlineBoxPaintWalker { textBox->paintDecoration(OVERLINE, m_paintInfo.context, decorationOrigin.x(), decorationOrigin.y(), textWidth, *it, info); // Paint text - m_textPaintInfo.activePaintServer = activePaintServer(); + m_textPaintInfo.activePaintingResource = activePaintingResource(); textBox->paintCharacters(m_paintInfo, m_tx, m_ty, *it, stringStart, stringLength, m_textPaintInfo); // Paint decorations, that have to be drawn afterwards @@ -672,11 +704,11 @@ private: RenderSVGResourceFilter* m_filter; RenderSVGResourceFilter* m_rootFilter; - SVGPaintServer* m_fillPaintServer; - SVGPaintServer* m_strokePaintServer; + RenderSVGResource* m_fillPaintingResource; + RenderSVGResource* m_strokePaintingResource; - RenderObject* m_fillPaintServerObject; - RenderObject* m_strokePaintServerObject; + RenderObject* m_fillPaintingResourceObject; + RenderObject* m_strokePaintingResourceObject; int m_tx; int m_ty; @@ -1296,7 +1328,7 @@ void SVGRootInlineBox::buildLayoutInformationForTextBox(SVGCharacterLayoutInfo& } // Take letter & word spacing and kerning into account - float spacing = font.letterSpacing() + calculateKerning(textBox->renderer()->node()->renderer()); + float spacing = font.letterSpacing() + calculateCSSKerning(textBox->renderer()->node()->renderer()); const UChar* currentCharacter = text->characters() + (textBox->direction() == RTL ? textBox->end() - i : textBox->start() + i); const UChar* lastCharacter = 0; @@ -1309,7 +1341,9 @@ void SVGRootInlineBox::buildLayoutInformationForTextBox(SVGCharacterLayoutInfo& lastCharacter = text->characters() + textBox->start() + i - 1; } - if (info.nextDrawnSeperated || spacing != 0.0f) { + // FIXME: SVG Kerning doesn't get applied on texts on path. + bool appliedSVGKerning = applySVGKerning(info, textBox->renderer()->node()->renderer(), lastGlyph, unicodeStr, glyphName); + if (info.nextDrawnSeperated || spacing != 0.0f || appliedSVGKerning) { info.nextDrawnSeperated = false; svgChar.drawnSeperated = true; } @@ -1414,35 +1448,12 @@ void SVGRootInlineBox::buildLayoutInformationForTextBox(SVGCharacterLayoutInfo& } } - float kerning = 0.0f; -#if ENABLE(SVG_FONTS) - SVGFontElement* svgFont = 0; - if (style->font().isSVGFont()) - svgFont = style->font().svgFont(); - - if (lastGlyph.isValid && style->font().isSVGFont()) { - SVGHorizontalKerningPair kerningPair; - if (svgFont->getHorizontalKerningPairForStringsAndGlyphs(lastGlyph.unicode, lastGlyph.glyphName, unicodeStr, glyphName, kerningPair)) - kerning = narrowPrecisionToFloat(kerningPair.kerning); - } - - if (style->font().isSVGFont()) { - lastGlyph.unicode = unicodeStr; - lastGlyph.glyphName = glyphName; - lastGlyph.isValid = true; - kerning *= style->font().size() / style->font().primaryFont()->unitsPerEm(); - } else - lastGlyph.isValid = false; -#endif - - svgChar.x -= kerning; - // Advance to new position if (isVerticalText) { svgChar.drawnSeperated = true; info.cury += glyphAdvance + spacing; } else - info.curx += glyphAdvance + spacing - kerning; + info.curx += glyphAdvance + spacing; // Advance to next character group for (int k = 0; k < charsConsumed; ++k) { |