summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/SVGRootInlineBox.cpp
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2010-05-11 18:35:50 +0100
committerBen Murdoch <benm@google.com>2010-05-14 10:23:05 +0100
commit21939df44de1705786c545cd1bf519d47250322d (patch)
treeef56c310f5c0cdc379c2abb2e212308a3281ce20 /WebCore/rendering/SVGRootInlineBox.cpp
parent4ff1d8891d520763f17675827154340c7c740f90 (diff)
downloadexternal_webkit-21939df44de1705786c545cd1bf519d47250322d.zip
external_webkit-21939df44de1705786c545cd1bf519d47250322d.tar.gz
external_webkit-21939df44de1705786c545cd1bf519d47250322d.tar.bz2
Merge Webkit at r58956: Initial merge by Git.
Change-Id: I1d9fb60ea2c3f2ddc04c17a871acdb39353be228
Diffstat (limited to 'WebCore/rendering/SVGRootInlineBox.cpp')
-rw-r--r--WebCore/rendering/SVGRootInlineBox.cpp165
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) {