summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/RenderPath.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering/RenderPath.cpp')
-rw-r--r--WebCore/rendering/RenderPath.cpp62
1 files changed, 33 insertions, 29 deletions
diff --git a/WebCore/rendering/RenderPath.cpp b/WebCore/rendering/RenderPath.cpp
index ccb9562..238a4e6 100644
--- a/WebCore/rendering/RenderPath.cpp
+++ b/WebCore/rendering/RenderPath.cpp
@@ -5,6 +5,7 @@
2009 Google, Inc.
2009 Dirk Schulze <krit@webkit.org>
Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ 2009 Jeff Schiller <codedread@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -30,6 +31,7 @@
#include "FloatPoint.h"
#include "FloatQuad.h"
#include "GraphicsContext.h"
+#include "HitTestRequest.h"
#include "PointerEventsHitRules.h"
#include "RenderSVGContainer.h"
#include "RenderSVGResourceFilter.h"
@@ -71,7 +73,7 @@ RenderPath::RenderPath(SVGStyledTransformableElement* node)
{
}
-bool RenderPath::fillContains(const FloatPoint& point, bool requiresFill) const
+bool RenderPath::fillContains(const FloatPoint& point, bool requiresFill, WindRule fillRule) const
{
if (!m_fillBoundingBox.contains(point))
return false;
@@ -79,7 +81,7 @@ bool RenderPath::fillContains(const FloatPoint& point, bool requiresFill) const
if (requiresFill && !RenderSVGResource::fillPaintingResource(this, style()))
return false;
- return m_path.contains(point, style()->svgStyle()->fillRule());
+ return m_path.contains(point, fillRule);
}
bool RenderPath::strokeContains(const FloatPoint& point, bool requiresStroke) const
@@ -130,16 +132,28 @@ void RenderPath::layout()
static inline void fillAndStrokePath(const Path& path, GraphicsContext* context, RenderPath* object)
{
context->beginPath();
+ RenderStyle* style = object->style();
- if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(object, object->style())) {
+ if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(object, style)) {
context->addPath(path);
- if (fillPaintingResource->applyResource(object, object->style(), context, ApplyToFillMode))
+ if (fillPaintingResource->applyResource(object, style, context, ApplyToFillMode))
fillPaintingResource->postApplyResource(object, context, ApplyToFillMode);
}
- if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(object, object->style())) {
- context->addPath(path);
- if (strokePaintingResource->applyResource(object, object->style(), context, ApplyToStrokeMode))
+ if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(object, style)) {
+ if (style->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE) {
+ SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(object->node());
+ AffineTransform transform = element->getScreenCTM();
+ if (!transform.isInvertible())
+ return;
+
+ Path transformedPath = path;
+ context->concatCTM(transform.inverse());
+ transformedPath.transform(transform);
+ context->addPath(transformedPath);
+ } else
+ context->addPath(path);
+ if (strokePaintingResource->applyResource(object, style, context, ApplyToStrokeMode))
strokePaintingResource->postApplyResource(object, context, ApplyToStrokeMode);
}
}
@@ -195,7 +209,7 @@ void RenderPath::addFocusRingRects(Vector<IntRect>& rects, int, int)
rects.append(rect);
}
-bool RenderPath::nodeAtFloatPoint(const HitTestRequest&, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
+bool RenderPath::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
{
// We only draw in the forground phase, so we only hit-test then.
if (hitTestAction != HitTestForeground)
@@ -203,17 +217,22 @@ bool RenderPath::nodeAtFloatPoint(const HitTestRequest&, HitTestResult& result,
FloatPoint localPoint = m_localTransform.inverse().mapPoint(pointInParent);
- PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_PATH_HITTESTING, style()->pointerEvents());
+ if (!pointInClippingArea(this, localPoint))
+ return false;
+ PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_PATH_HITTESTING, request, style()->pointerEvents());
bool isVisible = (style()->visibility() == VISIBLE);
if (isVisible || !hitRules.requireVisible) {
- if ((hitRules.canHitStroke && (style()->svgStyle()->hasStroke() || !hitRules.requireStroke) && strokeContains(localPoint, hitRules.requireStroke))
- || (hitRules.canHitFill && (style()->svgStyle()->hasFill() || !hitRules.requireFill) && fillContains(localPoint, hitRules.requireFill))) {
+ const SVGRenderStyle* svgStyle = style()->svgStyle();
+ WindRule fillRule = svgStyle->fillRule();
+ if (request.svgClipContent())
+ fillRule = svgStyle->clipRule();
+ if ((hitRules.canHitStroke && (svgStyle->hasStroke() || !hitRules.requireStroke) && strokeContains(localPoint, hitRules.requireStroke))
+ || (hitRules.canHitFill && (svgStyle->hasFill() || !hitRules.requireFill) && fillContains(localPoint, hitRules.requireFill, fillRule))) {
updateHitTestResult(result, roundedIntPoint(localPoint));
return true;
}
}
-
return false;
}
@@ -297,23 +316,8 @@ void RenderPath::updateCachedBoundaries()
}
// Cache smallest possible repaint rectangle
-
- // FIXME: We need to be careful here. We assume that there is no resource, if the rect is empty.
- FloatRect rect = filterBoundingBoxForRenderer(this);
- if (rect.isEmpty())
- m_repaintBoundingBox = m_strokeAndMarkerBoundingBox;
- else
- m_repaintBoundingBox = rect;
-
- rect = clipperBoundingBoxForRenderer(this);
- if (!rect.isEmpty())
- m_repaintBoundingBox.intersect(rect);
-
- rect = maskerBoundingBoxForRenderer(this);
- if (!rect.isEmpty())
- m_repaintBoundingBox.intersect(rect);
-
- svgStyle->inflateForShadow(m_repaintBoundingBox);
+ m_repaintBoundingBox = m_strokeAndMarkerBoundingBox;
+ intersectRepaintRectWithResources(this, m_repaintBoundingBox);
}
}