mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-12-29 02:31:05 +00:00
closes #473: implement Canvas Ellipse + M1239835
This commit is contained in:
parent
46b6faa6b2
commit
aebc3385bd
@ -51,6 +51,9 @@ public:
|
||||
void Arc(double x, double y, double radius,
|
||||
double startAngle, double endAngle, bool anticlockwise,
|
||||
ErrorResult& error);
|
||||
void Ellipse(double x, double y, double radiusX, double radiusY,
|
||||
double rotation, double startAngle, double endAngle,
|
||||
bool anticlockwise, ErrorResult& error);
|
||||
|
||||
void LineTo(const gfx::Point& aPoint);
|
||||
void BezierTo(const gfx::Point& aCP1,
|
||||
|
@ -2498,8 +2498,11 @@ CanvasRenderingContext2D::UpdateFilter()
|
||||
//
|
||||
|
||||
static bool
|
||||
ValidateRect(double& aX, double& aY, double& aWidth, double& aHeight)
|
||||
ValidateRect(double& aX, double& aY, double& aWidth, double& aHeight, bool aIsZeroSizeValid)
|
||||
{
|
||||
if (!aIsZeroSizeValid && (aWidth == 0.0 || aHeight == 0.0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// bug 1018527
|
||||
// The values of canvas API input are in double precision, but Moz2D APIs are
|
||||
@ -2530,7 +2533,8 @@ void
|
||||
CanvasRenderingContext2D::ClearRect(double x, double y, double w,
|
||||
double h)
|
||||
{
|
||||
if(!ValidateRect(x, y, w, h)) {
|
||||
// Do not allow zeros - it's a no-op at that point per spec.
|
||||
if (!ValidateRect(x, y, w, h, false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2547,7 +2551,7 @@ CanvasRenderingContext2D::FillRect(double x, double y, double w,
|
||||
{
|
||||
const ContextState &state = CurrentState();
|
||||
|
||||
if(!ValidateRect(x, y, w, h)) {
|
||||
if(!ValidateRect(x, y, w, h, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2625,7 +2629,7 @@ CanvasRenderingContext2D::StrokeRect(double x, double y, double w,
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ValidateRect(x, y, w, h)) {
|
||||
if(!ValidateRect(x, y, w, h, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2991,7 +2995,7 @@ CanvasRenderingContext2D::Arc(double x, double y, double r,
|
||||
double startAngle, double endAngle,
|
||||
bool anticlockwise, ErrorResult& error)
|
||||
{
|
||||
if (r < 0.0) {
|
||||
if (MOZ_UNLIKELY(r < 0.0)) {
|
||||
error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
return;
|
||||
}
|
||||
@ -3021,6 +3025,22 @@ CanvasRenderingContext2D::Rect(double x, double y, double w, double h)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CanvasRenderingContext2D::Ellipse(double aX, double aY, double aRadiusX, double aRadiusY,
|
||||
double aRotation, double aStartAngle, double aEndAngle,
|
||||
bool aAnticlockwise, ErrorResult& aError)
|
||||
{
|
||||
if (MOZ_UNLIKELY(aRadiusX < 0.0 || aRadiusY < 0.0)) {
|
||||
aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureWritablePath();
|
||||
|
||||
ArcToBezier(this, Point(aX, aY), Size(aRadiusX, aRadiusY), aStartAngle, aEndAngle,
|
||||
aAnticlockwise, aRotation);
|
||||
}
|
||||
|
||||
void
|
||||
CanvasRenderingContext2D::EnsureWritablePath()
|
||||
{
|
||||
@ -4402,8 +4422,8 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& image,
|
||||
MOZ_ASSERT(optional_argc == 0 || optional_argc == 2 || optional_argc == 6);
|
||||
|
||||
if (optional_argc == 6) {
|
||||
if (!ValidateRect(sx, sy, sw, sh) ||
|
||||
!ValidateRect(dx, dy, dw, dh)) {
|
||||
if (!ValidateRect(sx, sy, sw, sh, true) ||
|
||||
!ValidateRect(dx, dy, dw, dh, true)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -5918,6 +5938,22 @@ CanvasPath::Arc(double x, double y, double radius,
|
||||
ArcToBezier(this, Point(x, y), Size(radius, radius), startAngle, endAngle, anticlockwise);
|
||||
}
|
||||
|
||||
void
|
||||
CanvasPath::Ellipse(double x, double y, double radiusX, double radiusY,
|
||||
double rotation, double startAngle, double endAngle,
|
||||
bool anticlockwise, ErrorResult& error)
|
||||
{
|
||||
if (MOZ_UNLIKELY(radiusX < 0.0 || radiusY < 0.0)) {
|
||||
error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
EnsurePathBuilder();
|
||||
|
||||
ArcToBezier(this, Point(x, y), Size(radiusX, radiusY), startAngle, endAngle,
|
||||
anticlockwise, rotation);
|
||||
}
|
||||
|
||||
void
|
||||
CanvasPath::LineTo(const gfx::Point& aPoint)
|
||||
{
|
||||
|
@ -347,6 +347,9 @@ public:
|
||||
void Rect(double x, double y, double w, double h);
|
||||
void Arc(double x, double y, double radius, double startAngle,
|
||||
double endAngle, bool anticlockwise, mozilla::ErrorResult& error);
|
||||
void Ellipse(double aX, double aY, double aRadiusX, double aRadiusY,
|
||||
double aRotation, double aStartAngle, double aEndAngle,
|
||||
bool aAnticlockwise, ErrorResult& aError);
|
||||
|
||||
void GetMozCurrentTransform(JSContext* cx,
|
||||
JS::MutableHandle<JSObject*> result,
|
||||
|
@ -298,7 +298,9 @@ interface CanvasPathMethods {
|
||||
|
||||
[Throws, LenientFloat]
|
||||
void arc(double x, double y, double radius, double startAngle, double endAngle, optional boolean anticlockwise = false);
|
||||
// NOT IMPLEMENTED [LenientFloat] void ellipse(double x, double y, double radiusX, double radiusY, double rotation, double startAngle, double endAngle, boolean anticlockwise);
|
||||
|
||||
[Throws, LenientFloat]
|
||||
void ellipse(double x, double y, double radiusX, double radiusY, double rotation, double startAngle, double endAngle, optional boolean anticlockwise = false);
|
||||
};
|
||||
|
||||
interface CanvasGradient {
|
||||
|
@ -34,7 +34,8 @@ inline void PartialArcToBezier(T* aSink,
|
||||
const Size& aRadius,
|
||||
const Point& aStartPoint, const Point& aEndPoint,
|
||||
const Point& aStartOffset, const Point& aEndOffset,
|
||||
Float aKappaFactor = kKappaFactor)
|
||||
Float aKappaFactor = kKappaFactor,
|
||||
const Matrix& aTransform = Matrix())
|
||||
{
|
||||
Float kappaX = aKappaFactor * aRadius.width;
|
||||
Float kappaY = aKappaFactor * aRadius.height;
|
||||
@ -45,7 +46,7 @@ inline void PartialArcToBezier(T* aSink,
|
||||
Point cp2 =
|
||||
aEndPoint + Point(aEndOffset.y * kappaX, -aEndOffset.x * kappaY);
|
||||
|
||||
aSink->BezierTo(cp1, cp2, aEndPoint);
|
||||
aSink->BezierTo(aTransform * cp1, aTransform * cp2, aTransform * aEndPoint);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,7 +91,8 @@ inline void AcuteArcToBezier(T* aSink,
|
||||
|
||||
template <typename T>
|
||||
void ArcToBezier(T* aSink, const Point &aOrigin, const Size &aRadius,
|
||||
float aStartAngle, float aEndAngle, bool aAntiClockwise)
|
||||
float aStartAngle, float aEndAngle, bool aAntiClockwise,
|
||||
float aRotation = 0.0f)
|
||||
{
|
||||
Float sweepDirection = aAntiClockwise ? -1.0f : 1.0f;
|
||||
|
||||
@ -111,23 +113,24 @@ void ArcToBezier(T* aSink, const Point &aOrigin, const Size &aRadius,
|
||||
|
||||
Float currentStartAngle = aStartAngle;
|
||||
Point currentStartOffset(cosf(aStartAngle), sinf(aStartAngle));
|
||||
Point currentStartPoint(aOrigin.x + currentStartOffset.x * aRadius.width,
|
||||
aOrigin.y + currentStartOffset.y * aRadius.height);
|
||||
|
||||
aSink->LineTo(currentStartPoint);
|
||||
Point currentStartPoint(currentStartOffset.x * aRadius.width,
|
||||
currentStartOffset.y * aRadius.height);
|
||||
Matrix transform(cosf(aRotation), sinf(aRotation), -sinf(aRotation), cosf(aRotation), aOrigin.x, aOrigin.y);
|
||||
aSink->LineTo(transform * currentStartPoint);
|
||||
|
||||
while (arcSweepLeft > 0) {
|
||||
Float currentEndAngle =
|
||||
currentStartAngle + std::min(arcSweepLeft, Float(M_PI / 2.0f)) * sweepDirection;
|
||||
|
||||
Point currentEndOffset(cosf(currentEndAngle), sinf(currentEndAngle));
|
||||
Point currentEndPoint(aOrigin.x + currentEndOffset.x * aRadius.width,
|
||||
aOrigin.y + currentEndOffset.y * aRadius.height);
|
||||
Point currentEndPoint(currentEndOffset.x * aRadius.width,
|
||||
currentEndOffset.y * aRadius.height);
|
||||
|
||||
PartialArcToBezier(aSink, aRadius,
|
||||
currentStartPoint, currentEndPoint,
|
||||
currentStartOffset, currentEndOffset,
|
||||
ComputeKappaFactor(currentEndAngle - currentStartAngle));
|
||||
ComputeKappaFactor(currentEndAngle - currentStartAngle),
|
||||
transform);
|
||||
|
||||
// We guarantee here the current point is the start point of the next
|
||||
// curve segment.
|
||||
|
Loading…
Reference in New Issue
Block a user