summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/rendering/svg
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-18 13:36:51 +0100
committerSteve Block <steveblock@google.com>2011-05-24 15:38:28 +0100
commit2fc2651226baac27029e38c9d6ef883fa32084db (patch)
treee396d4bf89dcce6ed02071be66212495b1df1dec /Source/WebCore/rendering/svg
parentb3725cedeb43722b3b175aaeff70552e562d2c94 (diff)
downloadexternal_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.zip
external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.tar.gz
external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.tar.bz2
Merge WebKit at r78450: Initial merge by git.
Change-Id: I6d3e5f1f868ec266a0aafdef66182ddc3f265dc1
Diffstat (limited to 'Source/WebCore/rendering/svg')
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGImage.cpp4
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGInlineText.cpp47
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGInlineText.h7
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp39
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceFilter.h3
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp12
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h23
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp5
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGRoot.cpp7
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGText.cpp21
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp5
-rw-r--r--Source/WebCore/rendering/svg/SVGInlineTextBox.cpp136
-rw-r--r--Source/WebCore/rendering/svg/SVGInlineTextBox.h4
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp2
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp26
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp2
-rw-r--r--Source/WebCore/rendering/svg/SVGTextMetrics.cpp29
-rw-r--r--Source/WebCore/rendering/svg/SVGTextMetrics.h3
-rw-r--r--Source/WebCore/rendering/svg/SVGTextQuery.cpp5
19 files changed, 279 insertions, 101 deletions
diff --git a/Source/WebCore/rendering/svg/RenderSVGImage.cpp b/Source/WebCore/rendering/svg/RenderSVGImage.cpp
index 0f5a55e..81a5cea 100644
--- a/Source/WebCore/rendering/svg/RenderSVGImage.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGImage.cpp
@@ -122,7 +122,7 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
PaintInfo savedInfo(childPaintInfo);
if (SVGRenderSupport::prepareToRenderSVGContent(this, childPaintInfo)) {
- Image* image = m_imageResource->image();
+ RefPtr<Image> image = m_imageResource->image();
FloatRect destRect = m_objectBoundingBox;
FloatRect srcRect(0, 0, image->width(), image->height());
@@ -130,7 +130,7 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
if (imageElement->preserveAspectRatio().align() != SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE)
imageElement->preserveAspectRatio().transformRect(destRect, srcRect);
- childPaintInfo.context->drawImage(image, ColorSpaceDeviceRGB, destRect, srcRect);
+ childPaintInfo.context->drawImage(image.get(), ColorSpaceDeviceRGB, destRect, srcRect);
}
SVGRenderSupport::finishRenderSVGContent(this, childPaintInfo, savedInfo.context);
diff --git a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
index 91ffb5c..a8aa0c8 100644
--- a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
@@ -26,11 +26,14 @@
#if ENABLE(SVG)
#include "RenderSVGInlineText.h"
+#include "CSSStyleSelector.h"
#include "FloatConversion.h"
#include "FloatQuad.h"
#include "RenderBlock.h"
#include "RenderSVGRoot.h"
#include "RenderSVGText.h"
+#include "Settings.h"
+#include "SVGImageBufferTools.h"
#include "SVGInlineTextBox.h"
#include "SVGRootInlineBox.h"
#include "VisiblePosition.h"
@@ -63,6 +66,7 @@ static PassRefPtr<StringImpl> applySVGWhitespaceRules(PassRefPtr<StringImpl> str
RenderSVGInlineText::RenderSVGInlineText(Node* n, PassRefPtr<StringImpl> string)
: RenderText(n, applySVGWhitespaceRules(string, false))
+ , m_scalingFactor(1)
{
}
@@ -74,6 +78,8 @@ void RenderSVGInlineText::styleDidChange(StyleDifference diff, const RenderStyle
// The text metrics may be influenced by style changes.
if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this))
textRenderer->setNeedsPositioningValuesUpdate();
+
+ updateScaledFont();
}
const RenderStyle* newStyle = style();
@@ -103,12 +109,12 @@ IntRect RenderSVGInlineText::localCaretRect(InlineBox* box, int caretOffset, int
// Use the edge of the selection rect to determine the caret rect.
if (static_cast<unsigned>(caretOffset) < textBox->start() + textBox->len()) {
IntRect rect = textBox->selectionRect(0, 0, caretOffset, caretOffset + 1);
- int x = box->isLeftToRightDirection() ? rect.x() : rect.right();
+ int x = box->isLeftToRightDirection() ? rect.x() : rect.maxX();
return IntRect(x, rect.y(), caretWidth, rect.height());
}
IntRect rect = textBox->selectionRect(0, 0, caretOffset - 1, caretOffset);
- int x = box->isLeftToRightDirection() ? rect.right() : rect.x();
+ int x = box->isLeftToRightDirection() ? rect.maxX() : rect.x();
return IntRect(x, rect.y(), caretWidth, rect.height());
}
@@ -159,9 +165,7 @@ VisiblePosition RenderSVGInlineText::positionForPoint(const IntPoint& point)
if (!firstTextBox() || !textLength())
return createVisiblePosition(0, DOWNSTREAM);
- RenderStyle* style = this->style();
- ASSERT(style);
- int baseline = style->font().ascent();
+ float baseline = m_scaledFont.fontMetrics().floatAscent();
RenderBlock* containingBlock = this->containingBlock();
ASSERT(containingBlock);
@@ -206,6 +210,39 @@ VisiblePosition RenderSVGInlineText::positionForPoint(const IntPoint& point)
return createVisiblePosition(offset + closestDistanceBox->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM);
}
+void RenderSVGInlineText::updateScaledFont()
+{
+ computeNewScaledFontForStyle(this, style(), m_scalingFactor, m_scaledFont);
+}
+
+void RenderSVGInlineText::computeNewScaledFontForStyle(RenderObject* renderer, const RenderStyle* style, float& scalingFactor, Font& scaledFont)
+{
+ ASSERT(style);
+ ASSERT(renderer);
+
+ Document* document = renderer->document();
+ ASSERT(document);
+
+ CSSStyleSelector* styleSelector = document->styleSelector();
+ ASSERT(styleSelector);
+
+ // Alter font-size to the right on-screen value, to avoid scaling the glyphs themselves.
+ AffineTransform ctm;
+ SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(renderer, ctm);
+ scalingFactor = narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2));
+ if (scalingFactor == 1 || !scalingFactor) {
+ scalingFactor = 1;
+ scaledFont = style->font();
+ return;
+ }
+
+ FontDescription fontDescription(style->fontDescription());
+ fontDescription.setComputedSize(fontDescription.computedSize() * scalingFactor);
+
+ scaledFont = Font(fontDescription, 0, 0);
+ scaledFont.update(styleSelector->fontSelector());
+}
+
}
#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGInlineText.h b/Source/WebCore/rendering/svg/RenderSVGInlineText.h
index f5247f6..9eed8cd 100644
--- a/Source/WebCore/rendering/svg/RenderSVGInlineText.h
+++ b/Source/WebCore/rendering/svg/RenderSVGInlineText.h
@@ -40,6 +40,11 @@ public:
const SVGTextLayoutAttributes& layoutAttributes() const { return m_attributes; }
void storeLayoutAttributes(const SVGTextLayoutAttributes& attributes) { m_attributes = attributes; }
+ float scalingFactor() const { return m_scalingFactor; }
+ const Font& scaledFont() const { return m_scaledFont; }
+ void updateScaledFont();
+ static void computeNewScaledFontForStyle(RenderObject*, const RenderStyle*, float& scalingFactor, Font& scaledFont);
+
private:
virtual const char* renderName() const { return "RenderSVGInlineText"; }
@@ -57,6 +62,8 @@ private:
virtual IntRect linesBoundingBox() const;
virtual InlineTextBox* createTextBox();
+ float m_scalingFactor;
+ Font m_scaledFont;
SVGTextLayoutAttributes m_attributes;
};
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
index 4ba4e0a..96514af 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
@@ -111,7 +111,7 @@ PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(Filter* fi
builder->clearEffects();
return 0;
}
- builder->appendEffectToEffectReferences(effect);
+ builder->appendEffectToEffectReferences(effect, effectElement->renderer());
effectElement->setStandardAttributes(primitiveBoundingBoxMode, effect.get());
builder->add(effectElement->result(), effect);
}
@@ -208,13 +208,13 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
if (!lastEffect)
return false;
- RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(lastEffect, filterData->filter.get());
+ RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(lastEffect);
FloatRect subRegion = lastEffect->maxEffectRect();
// At least one FilterEffect has a too big image size,
// recalculate the effect sizes with new scale factors.
if (!fitsInMaximumImageSize(subRegion.size(), scale)) {
filterData->filter->setFilterResolution(scale);
- RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(lastEffect, filterData->filter.get());
+ RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(lastEffect);
}
// If the drawingRegion is empty, we have something like <g filter=".."/>.
@@ -290,16 +290,19 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo
// This is the real filtering of the object. It just needs to be called on the
// initial filtering process. We just take the stored filter result on a
// second drawing.
- if (!filterData->builded) {
+ if (!filterData->builded)
filterData->filter->setSourceImage(filterData->sourceGraphicBuffer.release());
+
+ // Always true if filterData is just built (filterData->builded is false).
+ if (!lastEffect->hasResult()) {
lastEffect->apply();
#if !PLATFORM(CG)
ImageBuffer* resultImage = lastEffect->asImageBuffer();
if (resultImage)
resultImage->transformColorSpace(ColorSpaceLinearRGB, ColorSpaceDeviceRGB);
#endif
- filterData->builded = true;
}
+ filterData->builded = true;
ImageBuffer* resultImage = lastEffect->asImageBuffer();
if (resultImage) {
@@ -324,5 +327,31 @@ FloatRect RenderSVGResourceFilter::resourceBoundingBox(RenderObject* object)
return FloatRect();
}
+void RenderSVGResourceFilter::primitiveAttributeChanged(RenderObject* object, const QualifiedName& attribute)
+{
+ HashMap<RenderObject*, FilterData*>::iterator it = m_filter.begin();
+ HashMap<RenderObject*, FilterData*>::iterator end = m_filter.end();
+ SVGFilterPrimitiveStandardAttributes* primitve = static_cast<SVGFilterPrimitiveStandardAttributes*>(object->node());
+
+ for (; it != end; ++it) {
+ FilterData* filterData = it->second;
+ if (!filterData->builded)
+ continue;
+
+ SVGFilterBuilder* builder = filterData->builder.get();
+ FilterEffect* effect = builder->effectByRenderer(object);
+ if (!effect)
+ continue;
+ // Since all effects shares the same attribute value, all
+ // or none of them will be changed.
+ if (!primitve->setFilterEffectAttribute(effect, attribute))
+ return;
+ builder->clearResultsRecursive(effect);
+
+ // Repaint the image on the screen.
+ markClientForInvalidation(it->first, RepaintInvalidation);
+ }
+}
+
}
#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
index f9a15ce..c809f23 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
@@ -64,6 +64,7 @@ public:
virtual ~RenderSVGResourceFilter();
virtual const char* renderName() const { return "RenderSVGResourceFilter"; }
+ virtual bool isSVGResourceFilter() const { return true; }
virtual void removeAllClientsFromCache(bool markForInvalidation = true);
virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
@@ -78,6 +79,8 @@ public:
SVGUnitTypes::SVGUnitType filterUnits() const { return toUnitType(static_cast<SVGFilterElement*>(node())->filterUnits()); }
SVGUnitTypes::SVGUnitType primitiveUnits() const { return toUnitType(static_cast<SVGFilterElement*>(node())->primitiveUnits()); }
+ void primitiveAttributeChanged(RenderObject*, const QualifiedName&);
+
virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
static RenderSVGResourceType s_resourceType;
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
index fc7362e..64df700 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
@@ -29,25 +29,29 @@
#if ENABLE(SVG) && ENABLE(FILTERS)
#include "RenderSVGResourceFilterPrimitive.h"
+#include "RenderSVGResource.h"
#include "SVGFEImage.h"
+#include "SVGFilter.h"
namespace WebCore {
-FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(FilterEffect* effect, SVGFilter* filter)
+FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(FilterEffect* effect)
{
FloatRect uniteRect;
FloatRect subregionBoundingBox = effect->effectBoundaries();
FloatRect subregion = subregionBoundingBox;
+ SVGFilter* filter = static_cast<SVGFilter*>(effect->filter());
+ ASSERT(filter);
if (effect->filterEffectType() != FilterEffectTypeTile) {
// FETurbulence, FEImage and FEFlood don't have input effects, take the filter region as unite rect.
if (unsigned numberOfInputEffects = effect->inputEffects().size()) {
for (unsigned i = 0; i < numberOfInputEffects; ++i)
- uniteRect.unite(determineFilterPrimitiveSubregion(effect->inputEffect(i), filter));
+ uniteRect.unite(determineFilterPrimitiveSubregion(effect->inputEffect(i)));
} else
uniteRect = filter->filterRegionInUserSpace();
} else {
- determineFilterPrimitiveSubregion(effect->inputEffect(0), filter);
+ determineFilterPrimitiveSubregion(effect->inputEffect(0));
uniteRect = filter->filterRegionInUserSpace();
}
@@ -90,7 +94,7 @@ FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(Fi
// FEImage needs the unclipped subregion in absolute coordinates to determine the correct
// destination rect in combination with preserveAspectRatio.
if (effect->filterEffectType() == FilterEffectTypeImage)
- reinterpret_cast<FEImage*>(effect)->setAbsoluteSubregion(absoluteSubregion);
+ static_cast<FEImage*>(effect)->setAbsoluteSubregion(absoluteSubregion);
// Clip every filter effect to the filter region.
FloatRect absoluteScaledFilterRegion = filter->filterRegion();
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h
index f25f62e..8176d29 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h
@@ -30,25 +30,32 @@
#if ENABLE(SVG) && ENABLE(FILTERS)
#include "RenderSVGHiddenContainer.h"
-#include "SVGFilter.h"
-#include "SVGFilterPrimitiveStandardAttributes.h"
+#include "RenderSVGResourceFilter.h"
namespace WebCore {
+class FilterEffect;
+
class RenderSVGResourceFilterPrimitive : public RenderSVGHiddenContainer {
public:
-
- explicit RenderSVGResourceFilterPrimitive(SVGFilterPrimitiveStandardAttributes* filterPrimitiveElement)
+ explicit RenderSVGResourceFilterPrimitive(SVGStyledElement* filterPrimitiveElement)
: RenderSVGHiddenContainer(filterPrimitiveElement)
{
}
- // They depend on the RenderObject argument of RenderSVGResourceFilter::applyResource.
- static FloatRect determineFilterPrimitiveSubregion(FilterEffect*, SVGFilter*);
-
-private:
virtual const char* renderName() const { return "RenderSVGResourceFilterPrimitive"; }
virtual bool isSVGResourceFilterPrimitive() const { return true; }
+
+ // They depend on the RenderObject argument of RenderSVGResourceFilter::applyResource.
+ static FloatRect determineFilterPrimitiveSubregion(FilterEffect*);
+
+ inline void primitiveAttributeChanged(const QualifiedName& attribute)
+ {
+ RenderObject* filter = parent();
+ if (!filter || !filter->isSVGResourceFilter())
+ return;
+ static_cast<RenderSVGResourceFilter*>(filter)->primitiveAttributeChanged(this, attribute);
+ }
};
} // namespace WebCore
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp
index 2a68d92..fcad27f 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp
@@ -86,11 +86,10 @@ FloatRect RenderSVGResourceMarker::markerBoundaries(const AffineTransform& marke
const AffineTransform& RenderSVGResourceMarker::localToParentTransform() const
{
- AffineTransform viewportTranslation(viewportTransform());
- m_localToParentTransform = viewportTranslation.translateRight(m_viewport.x(), m_viewport.y());
+ m_localToParentTransform = AffineTransform::translation(m_viewport.x(), m_viewport.y()) * viewportTransform();
return m_localToParentTransform;
// If this class were ever given a localTransform(), then the above would read:
- // return viewportTransform() * localTransform() * viewportTranslation;
+ // return viewportTranslation * localTransform() * viewportTransform();
}
FloatPoint RenderSVGResourceMarker::referencePoint() const
diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
index 3a8dce9..30f72b9 100644
--- a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
@@ -261,18 +261,15 @@ IntSize RenderSVGRoot::borderOriginToContentBox() const
AffineTransform RenderSVGRoot::localToRepaintContainerTransform(const IntPoint& parentOriginInContainer) const
{
- AffineTransform parentToContainer(localToParentTransform());
- return parentToContainer.translateRight(parentOriginInContainer.x(), parentOriginInContainer.y());
+ return AffineTransform::translation(parentOriginInContainer.x(), parentOriginInContainer.y()) * localToParentTransform();
}
const AffineTransform& RenderSVGRoot::localToParentTransform() const
{
IntSize parentToBorderBoxOffset = parentOriginToBorderBox();
- AffineTransform borderBoxOriginToParentOrigin(localToBorderBoxTransform());
- borderBoxOriginToParentOrigin.translateRight(parentToBorderBoxOffset.width(), parentToBorderBoxOffset.height());
+ m_localToParentTransform = AffineTransform::translation(parentToBorderBoxOffset.width(), parentToBorderBoxOffset.height()) * localToBorderBoxTransform();
- m_localToParentTransform = borderBoxOriginToParentOrigin;
return m_localToParentTransform;
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGText.cpp b/Source/WebCore/rendering/svg/RenderSVGText.cpp
index dad0b70..56d9306 100644
--- a/Source/WebCore/rendering/svg/RenderSVGText.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGText.cpp
@@ -33,7 +33,7 @@
#include "GraphicsContext.h"
#include "HitTestRequest.h"
#include "PointerEventsHitRules.h"
-#include "RenderLayer.h"
+#include "RenderSVGInlineText.h"
#include "RenderSVGResource.h"
#include "RenderSVGRoot.h"
#include "SVGLengthList.h"
@@ -91,6 +91,18 @@ void RenderSVGText::mapLocalToContainer(RenderBoxModelObject* repaintContainer,
SVGRenderSupport::mapLocalToContainer(this, repaintContainer, fixed, useTransforms, transformState);
}
+static inline void recursiveUpdateScaledFont(RenderObject* start)
+{
+ for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
+ if (child->isSVGInlineText()) {
+ toRenderSVGInlineText(child)->updateScaledFont();
+ continue;
+ }
+
+ recursiveUpdateScaledFont(child);
+ }
+}
+
void RenderSVGText::layout()
{
ASSERT(needsLayout());
@@ -104,6 +116,13 @@ void RenderSVGText::layout()
updateCachedBoundariesInParents = true;
}
+ // If the root layout size changed (eg. window size changes) or the positioning values change, recompute the on-screen font size.
+ if (m_needsPositioningValuesUpdate || SVGRenderSupport::findTreeRootObject(this)->isLayoutSizeChanged()) {
+ recursiveUpdateScaledFont(this);
+ m_needsPositioningValuesUpdate = true;
+ updateCachedBoundariesInParents = true;
+ }
+
if (m_needsPositioningValuesUpdate) {
// Perform SVG text layout phase one (see SVGTextLayoutAttributesBuilder for details).
SVGTextLayoutAttributesBuilder layoutAttributesBuilder;
diff --git a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
index 7f4b6f7..0f2f273 100644
--- a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
@@ -72,11 +72,10 @@ AffineTransform RenderSVGViewportContainer::viewportTransform() const
const AffineTransform& RenderSVGViewportContainer::localToParentTransform() const
{
- AffineTransform viewportTranslation(viewportTransform());
- m_localToParentTransform = viewportTranslation.translateRight(m_viewport.x(), m_viewport.y());
+ m_localToParentTransform = AffineTransform::translation(m_viewport.x(), m_viewport.y()) * viewportTransform();
return m_localToParentTransform;
// If this class were ever given a localTransform(), then the above would read:
- // return viewportTransform() * localTransform() * viewportTranslation;
+ // return viewportTranslation * localTransform() * viewportTransform()
}
bool RenderSVGViewportContainer::pointIsInsideViewportClip(const FloatPoint& pointInParent)
diff --git a/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp b/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
index 2879f20..52976f2 100644
--- a/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
+++ b/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
@@ -30,6 +30,7 @@
#include "RenderSVGInlineText.h"
#include "RenderSVGResource.h"
#include "RenderSVGResourceSolidColor.h"
+#include "SVGImageBufferTools.h"
#include "SVGRootInlineBox.h"
#include "TextRun.h"
@@ -56,9 +57,12 @@ int SVGInlineTextBox::offsetForPosition(int, bool) const
int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragment, float position, bool includePartialGlyphs) const
{
- RenderText* textRenderer = this->textRenderer();
+ RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
ASSERT(textRenderer);
+ float scalingFactor = textRenderer->scalingFactor();
+ ASSERT(scalingFactor);
+
RenderStyle* style = textRenderer->style();
ASSERT(style);
@@ -69,7 +73,7 @@ int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragmen
if (!fragment.transform.isIdentity())
textRun.setHorizontalGlyphStretch(narrowPrecisionToFloat(fragment.transform.xScale()));
- return fragment.positionListOffset - start() + style->font().offsetForPosition(textRun, position, includePartialGlyphs);
+ return fragment.positionListOffset - start() + textRenderer->scaledFont().offsetForPosition(textRun, position * scalingFactor, includePartialGlyphs);
}
int SVGInlineTextBox::positionForOffset(int) const
@@ -82,10 +86,28 @@ int SVGInlineTextBox::positionForOffset(int) const
FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment& fragment, int startPosition, int endPosition, RenderStyle* style)
{
ASSERT(startPosition < endPosition);
+ ASSERT(style);
+
+ RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
+ ASSERT(textRenderer);
+
+ float scalingFactor = textRenderer->scalingFactor();
+ ASSERT(scalingFactor);
- const Font& font = style->font();
- FloatPoint textOrigin(fragment.x, fragment.y - font.ascent());
- return font.selectionRectForText(constructTextRun(style, fragment), textOrigin, fragment.height, startPosition, endPosition);
+ const Font& scaledFont = textRenderer->scaledFont();
+ const FontMetrics& scaledFontMetrics = scaledFont.fontMetrics();
+ FloatPoint textOrigin(fragment.x, fragment.y);
+ if (scalingFactor != 1)
+ textOrigin.scale(scalingFactor, scalingFactor);
+
+ textOrigin.move(0, -scaledFontMetrics.floatAscent());
+
+ FloatRect selectionRect = scaledFont.selectionRectForText(constructTextRun(style, fragment), textOrigin, fragment.height * scalingFactor, startPosition, endPosition);
+ if (scalingFactor == 1)
+ return selectionRect;
+
+ selectionRect.scale(1 / scalingFactor);
+ return selectionRect;
}
IntRect SVGInlineTextBox::selectionRect(int, int, int startPosition, int endPosition)
@@ -125,6 +147,13 @@ IntRect SVGInlineTextBox::selectionRect(int, int, int startPosition, int endPosi
return enclosingIntRect(selectionRect);
}
+static inline bool textShouldBePainted(RenderSVGInlineText* textRenderer)
+{
+ // Font::pixelSize(), returns FontDescription::computedPixelSize(), which returns "int(x + 0.5)".
+ // If the absolute font size on screen is below x=0.5, don't render anything.
+ return textRenderer->scaledFont().pixelSize();
+}
+
void SVGInlineTextBox::paintSelectionBackground(PaintInfo& paintInfo)
{
ASSERT(paintInfo.shouldPaintWithinRoot(renderer()));
@@ -148,6 +177,11 @@ void SVGInlineTextBox::paintSelectionBackground(PaintInfo& paintInfo)
if (!backgroundColor.isValid() || !backgroundColor.alpha())
return;
+ RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
+ ASSERT(textRenderer);
+ if (!textShouldBePainted(textRenderer))
+ return;
+
RenderStyle* style = parentRenderer->style();
ASSERT(style);
@@ -222,6 +256,11 @@ void SVGInlineTextBox::paint(PaintInfo& paintInfo, int, int)
if (!hasSelection && paintSelectedTextOnly)
return;
+ RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
+ ASSERT(textRenderer);
+ if (!textShouldBePainted(textRenderer))
+ return;
+
RenderStyle* style = parentRenderer->style();
ASSERT(style);
@@ -286,8 +325,9 @@ void SVGInlineTextBox::paint(PaintInfo& paintInfo, int, int)
ASSERT(!m_paintingResource);
}
-bool SVGInlineTextBox::acquirePaintingResource(GraphicsContext*& context, RenderObject* renderer, RenderStyle* style)
+bool SVGInlineTextBox::acquirePaintingResource(GraphicsContext*& context, float scalingFactor, RenderObject* renderer, RenderStyle* style)
{
+ ASSERT(scalingFactor);
ASSERT(renderer);
ASSERT(style);
ASSERT(m_paintingResourceMode != ApplyToDefaultMode);
@@ -315,6 +355,9 @@ bool SVGInlineTextBox::acquirePaintingResource(GraphicsContext*& context, Render
}
}
+ if (scalingFactor != 1 && m_paintingResourceMode & ApplyToStrokeMode)
+ context->setStrokeThickness(context->strokeThickness() * scalingFactor);
+
return true;
}
@@ -329,9 +372,9 @@ void SVGInlineTextBox::releasePaintingResource(GraphicsContext*& context, const
m_paintingResource = 0;
}
-bool SVGInlineTextBox::prepareGraphicsContextForTextPainting(GraphicsContext*& context, TextRun& textRun, RenderStyle* style)
+bool SVGInlineTextBox::prepareGraphicsContextForTextPainting(GraphicsContext*& context, float scalingFactor, TextRun& textRun, RenderStyle* style)
{
- bool acquiredResource = acquirePaintingResource(context, parent()->renderer(), style);
+ bool acquiredResource = acquirePaintingResource(context, scalingFactor, parent()->renderer(), style);
#if ENABLE(SVG_FONTS)
// SVG Fonts need access to the painting resource used to draw the current text chunk.
@@ -364,14 +407,12 @@ TextRun SVGInlineTextBox::constructTextRun(RenderStyle* style, const SVGTextFrag
, false /* allowTabs */
, 0 /* xPos, only relevant with allowTabs=true */
, 0 /* padding, only relevant for justified text, not relevant for SVG */
+ , TextRun::AllowTrailingExpansion
, direction() == RTL
, m_dirOverride || style->visuallyOrdered() /* directionalOverride */);
#if ENABLE(SVG_FONTS)
- RenderObject* parentRenderer = parent()->renderer();
- ASSERT(parentRenderer);
-
- run.setReferencingRenderObject(parentRenderer);
+ run.setReferencingRenderObject(text);
#endif
// Disable any word/character rounding.
@@ -409,16 +450,16 @@ bool SVGInlineTextBox::mapStartEndPositionsIntoFragmentCoordinates(const SVGText
return true;
}
-static inline float positionOffsetForDecoration(ETextDecoration decoration, const Font& font, float thickness)
+static inline float positionOffsetForDecoration(ETextDecoration decoration, const FontMetrics& fontMetrics, float thickness)
{
// FIXME: For SVG Fonts we need to use the attributes defined in the <font-face> if specified.
// Compatible with Batik/Opera.
if (decoration == UNDERLINE)
- return font.ascent() + thickness * 1.5f;
+ return fontMetrics.floatAscent() + thickness * 1.5f;
if (decoration == OVERLINE)
return thickness;
if (decoration == LINE_THROUGH)
- return font.ascent() * 5.0f / 8.0f;
+ return fontMetrics.floatAscent() * 5 / 8.0f;
ASSERT_NOT_REACHED();
return 0.0f;
@@ -486,22 +527,34 @@ void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, ETextD
RenderStyle* decorationStyle = decorationRenderer->style();
ASSERT(decorationStyle);
- const Font& font = decorationStyle->font();
+ float scalingFactor = 1;
+ Font scaledFont;
+ RenderSVGInlineText::computeNewScaledFontForStyle(decorationRenderer, decorationStyle, scalingFactor, scaledFont);
+ ASSERT(scalingFactor);
// The initial y value refers to overline position.
- float thickness = thicknessForDecoration(decoration, font);
+ float thickness = thicknessForDecoration(decoration, scaledFont);
if (fragment.width <= 0 && thickness <= 0)
return;
- float y = fragment.y - font.ascent() + positionOffsetForDecoration(decoration, font, thickness);
-
- Path path;
- path.addRect(FloatRect(fragment.x, y, fragment.width, thickness));
+ FloatPoint decorationOrigin(fragment.x, fragment.y);
+ float width = fragment.width;
+ const FontMetrics& scaledFontMetrics = scaledFont.fontMetrics();
context->save();
+ if (scalingFactor != 1) {
+ width *= scalingFactor;
+ decorationOrigin.scale(scalingFactor, scalingFactor);
+ context->scale(FloatSize(1 / scalingFactor, 1 / scalingFactor));
+ }
- if (acquirePaintingResource(context, decorationRenderer, decorationStyle))
+ decorationOrigin.move(0, -scaledFontMetrics.floatAscent() + positionOffsetForDecoration(decoration, scaledFontMetrics, thickness));
+
+ Path path;
+ path.addRect(FloatRect(decorationOrigin, FloatSize(width, thickness)));
+
+ if (acquirePaintingResource(context, scalingFactor, decorationRenderer, decorationStyle))
releasePaintingResource(context, &path);
context->restore();
@@ -509,21 +562,41 @@ void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, ETextD
void SVGInlineTextBox::paintTextWithShadows(GraphicsContext* context, RenderStyle* style, TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int endPosition)
{
- const Font& font = style->font();
+ RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
+ ASSERT(textRenderer);
+
+ float scalingFactor = textRenderer->scalingFactor();
+ ASSERT(scalingFactor);
+
+ const Font& scaledFont = textRenderer->scaledFont();
const ShadowData* shadow = style->textShadow();
FloatPoint textOrigin(fragment.x, fragment.y);
- FloatRect shadowRect(FloatPoint(textOrigin.x(), textOrigin.y() - font.ascent()), FloatSize(fragment.width, fragment.height));
+ FloatSize textSize(fragment.width, fragment.height);
+
+ if (scalingFactor != 1) {
+ textOrigin.scale(scalingFactor, scalingFactor);
+ textSize.scale(scalingFactor);
+ }
+
+ FloatRect shadowRect(FloatPoint(textOrigin.x(), textOrigin.y() - scaledFont.fontMetrics().floatAscent()), textSize);
do {
- if (!prepareGraphicsContextForTextPainting(context, textRun, style))
+ if (!prepareGraphicsContextForTextPainting(context, scalingFactor, textRun, style))
break;
FloatSize extraOffset;
if (shadow)
extraOffset = applyShadowToGraphicsContext(context, shadow, shadowRect, false /* stroked */, true /* opaque */, true /* horizontal */);
- font.drawText(context, textRun, textOrigin + extraOffset, startPosition, endPosition);
+ if (scalingFactor != 1)
+ context->scale(FloatSize(1 / scalingFactor, 1 / scalingFactor));
+
+ scaledFont.drawText(context, textRun, textOrigin + extraOffset, startPosition, endPosition);
+
+ if (scalingFactor != 1)
+ context->scale(FloatSize(scalingFactor, scalingFactor));
+
restoreGraphicsContextAfterTextPainting(context, textRun);
if (!shadow)
@@ -580,19 +653,18 @@ IntRect SVGInlineTextBox::calculateBoundaries() const
{
FloatRect textRect;
- RenderText* textRenderer = this->textRenderer();
+ RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
ASSERT(textRenderer);
- RenderStyle* style = textRenderer->style();
- ASSERT(style);
+ float scalingFactor = textRenderer->scalingFactor();
+ ASSERT(scalingFactor);
- int baseline = baselinePosition(AlphabeticBaseline);
- int heightDifference = baseline - style->font().ascent();
+ float baseline = textRenderer->scaledFont().fontMetrics().floatAscent() / scalingFactor;
unsigned textFragmentsSize = m_textFragments.size();
for (unsigned i = 0; i < textFragmentsSize; ++i) {
const SVGTextFragment& fragment = m_textFragments.at(i);
- FloatRect fragmentRect(fragment.x, fragment.y - baseline, fragment.width, fragment.height + heightDifference);
+ FloatRect fragmentRect(fragment.x, fragment.y - baseline, fragment.width, fragment.height);
if (!fragment.transform.isIdentity())
fragmentRect = fragment.transform.mapRect(fragmentRect);
diff --git a/Source/WebCore/rendering/svg/SVGInlineTextBox.h b/Source/WebCore/rendering/svg/SVGInlineTextBox.h
index 0458de0..f2ca303 100644
--- a/Source/WebCore/rendering/svg/SVGInlineTextBox.h
+++ b/Source/WebCore/rendering/svg/SVGInlineTextBox.h
@@ -66,10 +66,10 @@ public:
private:
TextRun constructTextRun(RenderStyle*, const SVGTextFragment&) const;
- bool acquirePaintingResource(GraphicsContext*&, RenderObject*, RenderStyle*);
+ bool acquirePaintingResource(GraphicsContext*&, float scalingFactor, RenderObject*, RenderStyle*);
void releasePaintingResource(GraphicsContext*&, const Path*);
- bool prepareGraphicsContextForTextPainting(GraphicsContext*&, TextRun&, RenderStyle*);
+ bool prepareGraphicsContextForTextPainting(GraphicsContext*&, float scalingFactor, TextRun&, RenderStyle*);
void restoreGraphicsContextAfterTextPainting(GraphicsContext*&, TextRun&);
void paintDecoration(GraphicsContext*, ETextDecoration, const SVGTextFragment&);
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp
index 3b28d2b..c25ed79 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp
@@ -310,7 +310,7 @@ void SVGTextLayoutEngine::finalizeTransformMatrices(Vector<SVGInlineTextBox*>& b
SVGTextFragment& fragment = fragments.at(i);
AffineTransform& transform = fragment.transform;
if (!transform.isIdentity()) {
- transform.translateRight(fragment.x, fragment.y);
+ transform = AffineTransform::translation(fragment.x, fragment.y) * transform;
transform.translate(-fragment.x, -fragment.y);
}
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp
index 3863322..4221f26 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp
@@ -49,9 +49,9 @@ float SVGTextLayoutEngineBaseline::calculateBaselineShift(const SVGRenderStyle*
case BS_BASELINE:
return 0;
case BS_SUB:
- return -m_font.height() / 2;
+ return -m_font.fontMetrics().floatHeight() / 2;
case BS_SUPER:
- return m_font.height() / 2;
+ return m_font.fontMetrics().floatHeight() / 2;
default:
ASSERT_NOT_REACHED();
return 0;
@@ -122,27 +122,29 @@ float SVGTextLayoutEngineBaseline::calculateAlignmentBaselineShift(bool isVertic
ASSERT(baseline != AB_AUTO);
}
+ const FontMetrics& fontMetrics = m_font.fontMetrics();
+
// Note: http://wiki.apache.org/xmlgraphics-fop/LineLayout/AlignmentHandling
switch (baseline) {
case AB_BASELINE:
return dominantBaselineToAlignmentBaseline(isVerticalText, textRendererParent);
case AB_BEFORE_EDGE:
case AB_TEXT_BEFORE_EDGE:
- return m_font.ascent();
+ return fontMetrics.floatAscent();
case AB_MIDDLE:
- return m_font.xHeight() / 2;
+ return fontMetrics.xHeight() / 2;
case AB_CENTRAL:
- return (m_font.ascent() - m_font.descent()) / 2;
+ return (fontMetrics.floatAscent() - fontMetrics.floatDescent()) / 2;
case AB_AFTER_EDGE:
case AB_TEXT_AFTER_EDGE:
case AB_IDEOGRAPHIC:
- return m_font.descent();
+ return fontMetrics.floatDescent();
case AB_ALPHABETIC:
return 0;
case AB_HANGING:
- return m_font.ascent() * 8 / 10.f;
+ return fontMetrics.floatAscent() * 8 / 10.f;
case AB_MATHEMATICAL:
- return m_font.ascent() / 2;
+ return fontMetrics.floatAscent() / 2;
default:
ASSERT_NOT_REACHED();
return 0;
@@ -192,12 +194,14 @@ float SVGTextLayoutEngineBaseline::calculateGlyphAdvanceAndOrientation(bool isVe
// Spec: If if the 'glyph-orientation-vertical' results in an orientation angle that is not a multiple of
// 180 degrees, then the current text position is incremented according to the horizontal metrics of the glyph.
+ const FontMetrics& fontMetrics = m_font.fontMetrics();
+
// Vertical orientation handling.
if (isVerticalText) {
- float ascentMinusDescent = m_font.ascent() - m_font.descent();
+ float ascentMinusDescent = fontMetrics.floatAscent() - fontMetrics.floatDescent();
if (!angle) {
xOrientationShift = (ascentMinusDescent - metrics.width()) / 2;
- yOrientationShift = m_font.ascent();
+ yOrientationShift = fontMetrics.floatAscent();
} else if (angle == 180)
xOrientationShift = (ascentMinusDescent + metrics.width()) / 2;
else if (angle == 270) {
@@ -217,7 +221,7 @@ float SVGTextLayoutEngineBaseline::calculateGlyphAdvanceAndOrientation(bool isVe
yOrientationShift = -metrics.width();
else if (angle == 180) {
xOrientationShift = metrics.width();
- yOrientationShift = -m_font.ascent();
+ yOrientationShift = -fontMetrics.floatAscent();
} else if (angle == 270)
xOrientationShift = metrics.width();
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp
index 6c54b67..e9aa127 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp
@@ -58,7 +58,7 @@ float SVGTextLayoutEngineSpacing::calculateSVGKerning(bool isVerticalText, const
m_lastGlyph = currentGlyph;
m_lastGlyph.isValid = true;
- kerning *= m_font.size() / m_font.primaryFont()->unitsPerEm();
+ kerning *= m_font.size() / m_font.fontMetrics().unitsPerEm();
return kerning;
#else
UNUSED_PARAM(isVerticalText);
diff --git a/Source/WebCore/rendering/svg/SVGTextMetrics.cpp b/Source/WebCore/rendering/svg/SVGTextMetrics.cpp
index ec8c2c6..ca20d3d 100644
--- a/Source/WebCore/rendering/svg/SVGTextMetrics.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextMetrics.cpp
@@ -34,16 +34,21 @@ SVGTextMetrics::SVGTextMetrics()
{
}
-SVGTextMetrics::SVGTextMetrics(const Font& font, const TextRun& run, unsigned position, unsigned textLength)
- : m_width(0)
- , m_height(0)
- , m_length(0)
+SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText* textRenderer, const TextRun& run, unsigned position, unsigned textLength)
{
+ ASSERT(textRenderer);
+
+ float scalingFactor = textRenderer->scalingFactor();
+ ASSERT(scalingFactor);
+
+ const Font& scaledFont = textRenderer->scaledFont();
+
int extraCharsAvailable = textLength - (position + run.length());
int length = 0;
- m_width = font.floatWidth(run, extraCharsAvailable, length, m_glyph.name);
- m_height = font.height();
+ // Calculate width/height using the scaled font, divide this result by the scalingFactor afterwards.
+ m_width = scaledFont.floatWidth(run, extraCharsAvailable, length, m_glyph.name) / scalingFactor;
+ m_height = scaledFont.fontMetrics().floatHeight() / scalingFactor;
m_glyph.unicodeString = String(run.characters(), length);
m_glyph.isValid = true;
@@ -71,8 +76,7 @@ static TextRun constructTextRun(RenderSVGInlineText* text, const UChar* characte
TextRun run(characters + position, length);
#if ENABLE(SVG_FONTS)
- ASSERT(text->parent());
- run.setReferencingRenderObject(text->parent());
+ run.setReferencingRenderObject(text);
#endif
// Disable any word/character rounding.
@@ -86,18 +90,13 @@ static TextRun constructTextRun(RenderSVGInlineText* text, const UChar* characte
SVGTextMetrics SVGTextMetrics::measureCharacterRange(RenderSVGInlineText* text, unsigned position, unsigned length)
{
ASSERT(text);
- ASSERT(text->style());
-
TextRun run(constructTextRun(text, text->characters(), position, length));
- return SVGTextMetrics(text->style()->font(), run, position, text->textLength());
+ return SVGTextMetrics(text, run, position, text->textLength());
}
void SVGTextMetrics::measureAllCharactersIndividually(RenderSVGInlineText* text, Vector<SVGTextMetrics>& allMetrics)
{
ASSERT(text);
- ASSERT(text->style());
-
- const Font& font = text->style()->font();
const UChar* characters = text->characters();
unsigned length = text->textLength();
@@ -105,7 +104,7 @@ void SVGTextMetrics::measureAllCharactersIndividually(RenderSVGInlineText* text,
for (unsigned position = 0; position < length; ) {
run.setText(characters + position, 1);
- SVGTextMetrics metrics(font, run, position, text->textLength());
+ SVGTextMetrics metrics(text, run, position, text->textLength());
allMetrics.append(metrics);
position += metrics.length();
}
diff --git a/Source/WebCore/rendering/svg/SVGTextMetrics.h b/Source/WebCore/rendering/svg/SVGTextMetrics.h
index ba18589..7ef0f7d 100644
--- a/Source/WebCore/rendering/svg/SVGTextMetrics.h
+++ b/Source/WebCore/rendering/svg/SVGTextMetrics.h
@@ -25,7 +25,6 @@
namespace WebCore {
-class Font;
class RenderSVGInlineText;
class TextRun;
@@ -64,7 +63,7 @@ public:
private:
SVGTextMetrics();
- SVGTextMetrics(const Font&, const TextRun&, unsigned position, unsigned textLength);
+ SVGTextMetrics(RenderSVGInlineText*, const TextRun&, unsigned position, unsigned textLength);
float m_width;
float m_height;
diff --git a/Source/WebCore/rendering/svg/SVGTextQuery.cpp b/Source/WebCore/rendering/svg/SVGTextQuery.cpp
index 42d511b..1a4cdab 100644
--- a/Source/WebCore/rendering/svg/SVGTextQuery.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextQuery.cpp
@@ -472,7 +472,10 @@ struct ExtentOfCharacterData : SVGTextQuery::Data {
static inline void calculateGlyphBoundaries(SVGTextQuery::Data* queryData, const SVGTextFragment& fragment, int startPosition, FloatRect& extent)
{
- extent.setLocation(FloatPoint(fragment.x, fragment.y - queryData->textRenderer->style()->font().ascent()));
+ float scalingFactor = queryData->textRenderer->scalingFactor();
+ ASSERT(scalingFactor);
+
+ extent.setLocation(FloatPoint(fragment.x, fragment.y - queryData->textRenderer->scaledFont().fontMetrics().floatAscent() / scalingFactor));
if (startPosition) {
SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textRenderer, fragment.positionListOffset, startPosition);