Bug 827053 - Add support for winding in fill + clip + isPointInPath + tests the feature. r=bas

This commit is contained in:
Rik Cabanier 2013-01-16 21:55:43 -05:00
Родитель 6e038d2b99
Коммит 3a85a98855
7 изменённых файлов: 157 добавлений и 14 удалений

Просмотреть файл

@ -1636,9 +1636,9 @@ CanvasRenderingContext2D::BeginPath()
}
void
CanvasRenderingContext2D::Fill()
CanvasRenderingContext2D::Fill(const CanvasWindingRule& winding)
{
EnsureUserSpacePath();
EnsureUserSpacePath(winding);
if (!mPath) {
return;
@ -1687,9 +1687,9 @@ CanvasRenderingContext2D::Stroke()
}
void
CanvasRenderingContext2D::Clip()
CanvasRenderingContext2D::Clip(const CanvasWindingRule& winding)
{
EnsureUserSpacePath();
EnsureUserSpacePath(winding);
if (!mPath) {
return;
@ -1848,9 +1848,11 @@ CanvasRenderingContext2D::EnsureWritablePath()
}
void
CanvasRenderingContext2D::EnsureUserSpacePath()
CanvasRenderingContext2D::EnsureUserSpacePath(const CanvasWindingRule& winding)
{
FillRule fillRule = CurrentState().fillRule;
if(winding == CanvasWindingRuleValues::Evenodd)
fillRule = FILL_EVEN_ODD;
if (!mPath && !mPathBuilder && !mDSPathBuilder) {
EnsureTarget();
@ -2836,19 +2838,21 @@ CanvasRenderingContext2D::SetMozDashOffset(double mozDashOffset)
}
bool
CanvasRenderingContext2D::IsPointInPath(double x, double y)
CanvasRenderingContext2D::IsPointInPath(double x, double y, const CanvasWindingRule& winding)
{
if (!FloatValidate(x,y)) {
return false;
}
EnsureUserSpacePath();
EnsureUserSpacePath(winding);
if (!mPath) {
return false;
}
if (mPathTransformWillUpdate) {
return mPath->ContainsPoint(Point(x, y), mPathToDS);
}
return mPath->ContainsPoint(Point(x, y), mTarget->GetTransform());
}

Просмотреть файл

@ -17,6 +17,7 @@
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/ImageData.h"
#include "mozilla/dom/UnionTypes.h"
#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
#define NS_CANVASGRADIENTAZURE_PRIVATE_IID \
{0x28425a6a, 0x90e0, 0x4d42, {0x9c, 0x75, 0xff, 0x60, 0x09, 0xb3, 0x10, 0xa8}}
@ -238,10 +239,10 @@ public:
void FillRect(double x, double y, double w, double h);
void StrokeRect(double x, double y, double w, double h);
void BeginPath();
void Fill();
void Fill(const CanvasWindingRule& winding);
void Stroke();
void Clip();
bool IsPointInPath(double x, double y);
void Clip(const CanvasWindingRule& winding);
bool IsPointInPath(double x, double y, const CanvasWindingRule& winding);
bool IsPointInStroke(double x, double y);
void FillText(const nsAString& text, double x, double y,
const mozilla::dom::Optional<double>& maxWidth,
@ -587,7 +588,7 @@ protected:
void EnsureWritablePath();
// Ensures a path in UserSpace is available.
void EnsureUserSpacePath();
void EnsureUserSpacePath(const CanvasWindingRule& winding = CanvasWindingRuleValues::Nonzero);
/**
* Needs to be called before updating the transform. This makes a call to

Просмотреть файл

@ -36,6 +36,7 @@ MOCHITEST_FILES = \
test_drawImageIncomplete.html \
test_canvas_font_setter.html \
test_2d.clearRect.image.offscreen.html \
test_2d.clip.winding.html \
test_2d.composite.canvas.destination-atop.html \
test_2d.composite.canvas.destination-in.html \
test_2d.composite.canvas.source-in.html \
@ -93,6 +94,8 @@ MOCHITEST_FILES = \
test_2d.composite.uncovered.fill.color.html \
test_2d.composite.uncovered.fill.luminosity.html \
test_2d.drawImage.zerocanvas.html \
test_2d.fill.winding.html \
test_2d.isPointInPath.winding.html \
test_2d.strokeRect.zero.5.html \
test_toBlob.html \
test_toDataURL_alpha.html \

Просмотреть файл

@ -0,0 +1,53 @@
<!DOCTYPE HTML>
<title>Canvas test: 2d.clip.winding</title>
<script src="/MochiKit/MochiKit.js"></script>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<body>
<canvas id="c" width="100" height="100"><p class="fallback">FAIL (fallback content)</p></canvas>
<script>
function isPixel(ctx, x,y, r,g,b,a, pos, colour, d) {
var pixel = ctx.getImageData(x, y, 1, 1);
var pr = pixel.data[0],
pg = pixel.data[1],
pb = pixel.data[2],
pa = pixel.data[3];
ok(r-d <= pr && pr <= r+d &&
g-d <= pg && pg <= g+d &&
b-d <= pb && pb <= b+d &&
a-d <= pa && pa <= a+d,
"pixel "+pos+" is "+pr+","+pg+","+pb+","+pa+"; expected "+colour+" +/- "+d);
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(function () {
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgb(255,0,0)';
ctx.fillRect(0, 0, 100, 100);
ctx.fillStyle = 'rgb(0,255,0)';
ctx.beginPath();
ctx.rect(0, 0, 100, 100);
ctx.rect(25, 25, 50, 50);
ctx.clip();
ctx.beginPath();
ctx.fillRect(0, 0, 100, 100);
isPixel(ctx, 50,50, 0,255,0,255, "50,50", "0,255,0,255", 5);
ctx.fillStyle = 'rgb(255,0,0)';
ctx.fillRect(0, 0, 100, 100);
ctx.fillStyle = 'rgb(0,255,0)';
ctx.beginPath();
ctx.rect(0, 0, 100, 100);
ctx.rect(25, 25, 50, 50);
ctx.clip('evenodd');
ctx.fillRect(0, 0, 100, 100);
isPixel(ctx, 50,50, 255,0,0,255, "50,50", "255,0,0,255", 5);
SimpleTest.finish();
});
</script>

Просмотреть файл

@ -0,0 +1,51 @@
<!DOCTYPE HTML>
<title>Canvas test: 2d.fill.winding</title>
<script src="/MochiKit/MochiKit.js"></script>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<body>
<canvas id="c" width="100" height="100"><p class="fallback">FAIL (fallback content)</p></canvas>
<script>
function isPixel(ctx, x,y, r,g,b,a, pos, colour, d) {
var pixel = ctx.getImageData(x, y, 1, 1);
var pr = pixel.data[0],
pg = pixel.data[1],
pb = pixel.data[2],
pa = pixel.data[3];
ok(r-d <= pr && pr <= r+d &&
g-d <= pg && pg <= g+d &&
b-d <= pb && pb <= b+d &&
a-d <= pa && pa <= a+d,
"pixel "+pos+" is "+pr+","+pg+","+pb+","+pa+"; expected "+colour+" +/- "+d);
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(function () {
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgb(255,0,0)';
ctx.beginPath();
ctx.fillRect(0, 0, 100, 100);
ctx.fillStyle = 'rgb(0,255,0)';
ctx.beginPath();
ctx.rect(0, 0, 100, 100);
ctx.rect(25, 25, 50, 50);
ctx.fill();
isPixel(ctx, 50,50, 0,255,0,255, "50,50", "0,255,0,255", 5);
ctx.fillStyle = 'rgb(255,0,0)';
ctx.fillRect(0, 0, 100, 100);
ctx.fillStyle = 'rgb(0,255,0)';
ctx.beginPath();
ctx.rect(0, 0, 100, 100);
ctx.rect(25, 25, 50, 50);
ctx.fill('evenodd');
isPixel(ctx, 50,50, 255,0,0,255, "50,50", "255,0,0,255", 5);
SimpleTest.finish();
});
</script>

Просмотреть файл

@ -0,0 +1,29 @@
<!DOCTYPE HTML>
<title>Canvas test: 2d.isPointInPath.winding</title>
<script src="/MochiKit/MochiKit.js"></script>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<body>
<canvas id="c" width="100" height="100"><p class="fallback">FAIL (fallback content)</p></canvas>
<script>
SimpleTest.waitForExplicitFinish();
addLoadEvent(function () {
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.rect(0, 0, 100, 100);
ctx.rect(25, 25, 50, 50);
ok(ctx.isPointInPath(50, 50));
ctx.beginPath();
ctx.rect(0, 0, 100, 100);
ctx.rect(25, 25, 50, 50);
ok(ctx.isPointInPath(50, 50, 'evenodd') == false);
SimpleTest.finish();
});
</script>

Просмотреть файл

@ -20,6 +20,8 @@ interface TextMetrics;
interface Window;
interface XULElement;
enum CanvasWindingRule { "nonzero", "evenodd" };
interface CanvasRenderingContext2D {
// back-reference to the canvas. Might be null if we're not
@ -80,7 +82,7 @@ interface CanvasRenderingContext2D {
// path API (see also CanvasPathMethods)
void beginPath();
void fill();
void fill(optional CanvasWindingRule winding = "nonzero");
// NOT IMPLEMENTED void fill(Path path);
void stroke();
// NOT IMPLEMENTED void stroke(Path path);
@ -90,10 +92,10 @@ interface CanvasRenderingContext2D {
// NOT IMPLEMENTED boolean drawCustomFocusRing(Path path, Element element);
// NOT IMPLEMENTED void scrollPathIntoView();
// NOT IMPLEMENTED void scrollPathIntoView(Path path);
void clip();
void clip(optional CanvasWindingRule winding = "nonzero");
// NOT IMPLEMENTED void clip(Path path);
// NOT IMPLEMENTED void resetClip();
boolean isPointInPath(unrestricted double x, unrestricted double y);
boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasWindingRule winding = "nonzero");
// NOT IMPLEMENTED boolean isPointInPath(Path path, unrestricted double x, unrestricted double y);
boolean isPointInStroke(double x, double y);