+2008-01-27 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Test case for canvas.pointInPath
+
+ * fast/canvas/pointInPath-expected.txt: Added.
+ * fast/canvas/pointInPath.html: Added.
+ * fast/canvas/pointInPath.js: Added.
+
2008-01-27 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Darin.
--- /dev/null
+Series of tests for Canvas.isPointInPath
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Rectangle at (0,0) 20x20
+PASS ctx.isPointInPath(5, 5) is true
+PASS ctx.isPointInPath(10, 10) is true
+PASS ctx.isPointInPath(20, 20) is true
+PASS ctx.isPointInPath(30, 30) is false
+PASS ctx.isPointInPath(-1, 10) is false
+PASS ctx.isPointInPath(10, -1) is false
+Translate context (10,10)
+PASS ctx.isPointInPath(5, 5) is true
+PASS ctx.isPointInPath(10, 10) is true
+PASS ctx.isPointInPath(20, 20) is true
+PASS ctx.isPointInPath(30, 30) is false
+PASS ctx.isPointInPath(-1, 10) is false
+PASS ctx.isPointInPath(10, -1) is false
+Collapse ctm to non-invertible matrix
+PASS ctx.isPointInPath(5, 5) is false
+PASS ctx.isPointInPath(10, 10) is false
+PASS ctx.isPointInPath(20, 20) is false
+PASS ctx.isPointInPath(30, 30) is false
+PASS ctx.isPointInPath(-1, 10) is false
+PASS ctx.isPointInPath(10, -1) is false
+Resetting context to a clean state
+Translate context (10,10)
+Rectangle at (0,0) 20x20
+PASS ctx.isPointInPath(5, 5) is false
+PASS ctx.isPointInPath(10, 10) is true
+PASS ctx.isPointInPath(20, 20) is true
+PASS ctx.isPointInPath(30, 30) is true
+PASS ctx.isPointInPath(-1, 10) is false
+PASS ctx.isPointInPath(10, -1) is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<canvas id="canvas"></canvas>
+<script src="pointInPath.js"></script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
--- /dev/null
+description("Series of tests for Canvas.isPointInPath");
+
+ctx = document.getElementById("canvas").getContext("2d");
+ctx.save();
+debug("Rectangle at (0,0) 20x20");
+ctx.rect(0, 0, 20, 20);
+shouldBe("ctx.isPointInPath(5, 5)", "true");
+shouldBe("ctx.isPointInPath(10, 10)", "true");
+shouldBe("ctx.isPointInPath(20, 20)", "true");
+shouldBe("ctx.isPointInPath(30, 30)", "false");
+shouldBe("ctx.isPointInPath(-1, 10)", "false");
+shouldBe("ctx.isPointInPath(10, -1)", "false");
+debug("Translate context (10,10)");
+ctx.translate(10,10);
+shouldBe("ctx.isPointInPath(5, 5)", "true");
+shouldBe("ctx.isPointInPath(10, 10)", "true");
+shouldBe("ctx.isPointInPath(20, 20)", "true");
+shouldBe("ctx.isPointInPath(30, 30)", "false");
+shouldBe("ctx.isPointInPath(-1, 10)", "false");
+shouldBe("ctx.isPointInPath(10, -1)", "false");
+debug("Collapse ctm to non-invertible matrix");
+ctx.scale(0,0);
+shouldBe("ctx.isPointInPath(5, 5)", "false");
+shouldBe("ctx.isPointInPath(10, 10)", "false");
+shouldBe("ctx.isPointInPath(20, 20)", "false");
+shouldBe("ctx.isPointInPath(30, 30)", "false");
+shouldBe("ctx.isPointInPath(-1, 10)", "false");
+shouldBe("ctx.isPointInPath(10, -1)", "false");
+debug("Resetting context to a clean state");
+ctx.restore();
+ctx.beginPath();
+debug("Translate context (10,10)");
+ctx.translate(10,10);
+debug("Rectangle at (0,0) 20x20");
+ctx.rect(0, 0, 20, 20);
+shouldBe("ctx.isPointInPath(5, 5)", "false");
+shouldBe("ctx.isPointInPath(10, 10)", "true");
+shouldBe("ctx.isPointInPath(20, 20)", "true");
+shouldBe("ctx.isPointInPath(30, 30)", "true");
+shouldBe("ctx.isPointInPath(-1, 10)", "false");
+shouldBe("ctx.isPointInPath(10, -1)", "false");
+
+var successfullyParsed = true;
+2008-01-27 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Bug 16629: <canvas> does not support isPointInPath()
+
+ Relatively trivial change to implement pointInPath and add
+ it to the bindings. Most of this patch is the addition of
+ GraphicsContext::getCTM() by pulling the various platform
+ implementations from CanvasRenderingContext2D::willDraw
+
+ Test: fast/canvas/pointInPath.html
+
+ * html/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::isPointInPath):
+ (WebCore::CanvasRenderingContext2D::willDraw):
+ * html/CanvasRenderingContext2D.h:
+ * html/CanvasRenderingContext2D.idl:
+ * platform/graphics/AffineTransform.cpp:
+ (WebCore::AffineTransform::mapPoint):
+ Support mapping of FloatRects
+ * platform/graphics/AffineTransform.h:
+ * platform/graphics/GraphicsContext.h:
+ * platform/graphics/cairo/GraphicsContextCairo.cpp:
+ (WebCore::GraphicsContext::getCTM):
+ * platform/graphics/cg/GraphicsContextCG.cpp:
+ (WebCore::GraphicsContext::getCTM):
+ * platform/graphics/qt/GraphicsContextQt.cpp:
+ (WebCore::GraphicsContext::getCTM):
+
2008-01-27 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Darin.
clearPathForDashboardBackwardCompatibilityMode();
}
+bool CanvasRenderingContext2D::isPointInPath(const float x, const float y)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return false;
+ FloatPoint point(x, y);
+ // We have to invert the current transform to ensure we correctly handle the
+ // transforms applied to the current path.
+ AffineTransform ctm = c->getCTM();
+ if (!ctm.isInvertible())
+ return false;
+ FloatPoint transformedPoint = ctm.inverse().mapPoint(point);
+ return state().m_path.contains(transformedPoint);
+}
+
void CanvasRenderingContext2D::clearRect(float x, float y, float width, float height, ExceptionCode& ec)
{
ec = 0;
GraphicsContext* c = drawingContext();
if (!c)
return;
-
- AffineTransform transform;
-#if PLATFORM(CG)
- transform = CGContextGetCTM(c->platformContext());
-#elif PLATFORM(CAIRO)
- cairo_t* cr = c->platformContext();
- cairo_matrix_t m;
- cairo_get_matrix(cr, &m);
- transform = m;
-#elif PLATFORM(QT)
- transform = c->platformContext()->combinedMatrix();
-#else
- notImplemented();
- FloatRect completeBounds(0, 0, m_canvas->width(), m_canvas->height());
- m_canvas->willDraw(completeBounds);
- return;
-#endif
-
- m_canvas->willDraw(transform.mapRect(r));
+
+ m_canvas->willDraw(c->getCTM().mapRect(r));
}
GraphicsContext* CanvasRenderingContext2D::drawingContext() const
void stroke();
void clip();
+ bool isPointInPath(const float x, const float y);
+
void clearRect(float x, float y, float width, float height, ExceptionCode&);
void fillRect(float x, float y, float width, float height, ExceptionCode&);
void strokeRect(float x, float y, float width, float height, ExceptionCode&);
void fill();
void stroke();
void clip();
+ boolean isPointInPath(in float x, in float y);
// other
return IntPoint(lround(x2), lround(y2));
}
+FloatPoint AffineTransform::mapPoint(const FloatPoint& point) const
+{
+ double x2, y2;
+ map(point.x(), point.y(), &x2, &y2);
+
+ return FloatPoint(static_cast<float>(x2), static_cast<float>(y2));
+}
+
}
class IntPoint;
class IntRect;
+class FloatPoint;
class FloatRect;
class AffineTransform {
void setMatrix(double a, double b, double c, double d, double e, double f);
void map(double x, double y, double *x2, double *y2) const;
IntPoint mapPoint(const IntPoint&) const;
+ FloatPoint mapPoint(const FloatPoint&) const;
IntRect mapRect(const IntRect&) const;
FloatRect mapRect(const FloatRect&) const;
void setURLForRect(const KURL&, const IntRect&);
void concatCTM(const AffineTransform&);
+ AffineTransform getCTM() const;
void setUseAntialiasing(bool = true);
delete m_data;
}
+AffineTransform GraphicsContext::getCTM() const
+{
+ cairo_t* cr = platformContext();
+ cairo_matrix_t m;
+ cairo_get_matrix(cr, &m);
+ return m;
+}
+
cairo_t* GraphicsContext::platformContext() const
{
return m_data->cr;
m_data->m_userToDeviceTransformKnownToBeIdentity = false;
}
+AffineTransform GraphicsContext::getCTM() const
+{
+ return CGContextGetCTM(platformContext());
+}
+
FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
{
// It is not enough just to round to pixels in device space. The rotation part of the
return m_data->p();
}
+AffineTransform GraphicsContext::getCTM() const
+{
+ return platformContext()->combinedMatrix();
+}
+
void GraphicsContext::savePlatformState()
{
m_data->p()->save();