Bug 926258 - Implement a Moz2D version of gfxPath. r=Bas

This commit is contained in:
Matt Woodrow 2013-10-15 16:23:21 +13:00
parent 806a534a20
commit ed0fc0853f
5 changed files with 59 additions and 12 deletions

View File

@ -448,6 +448,11 @@ public:
* mutable.
*/
virtual FillRule GetFillRule() const = 0;
virtual Float ComputeLength() { return 0; }
virtual Point ComputePointAtLength(Float aLength,
Point* aTangent) { return Point(); }
};
/* The PathBuilder class allows path creation. Once finish is called on the

View File

@ -275,25 +275,31 @@ gfxContext::ClosePath()
}
}
already_AddRefed<gfxPath> gfxContext::CopyPath() const
already_AddRefed<gfxPath> gfxContext::CopyPath()
{
nsRefPtr<gfxPath> path;
if (mCairo) {
nsRefPtr<gfxPath> path = new gfxPath(cairo_copy_path(mCairo));
return path.forget();
path = new gfxPath(cairo_copy_path(mCairo));
} else {
// XXX - This is not yet supported for Azure.
return nullptr;
EnsurePath();
path = new gfxPath(mPath);
}
return path.forget();
}
void gfxContext::AppendPath(gfxPath* path)
void gfxContext::SetPath(gfxPath* path)
{
if (mCairo) {
cairo_new_path(mCairo);
if (path->mPath->status == CAIRO_STATUS_SUCCESS && path->mPath->num_data != 0)
cairo_append_path(mCairo, path->mPath);
} else {
// XXX - This is not yet supported for Azure.
return;
MOZ_ASSERT(path->mMoz2DPath, "Can't mix cairo and azure paths!");
MOZ_ASSERT(path->mMoz2DPath->GetBackendType() == mDT->GetType());
mPath = path->mMoz2DPath;
mPathBuilder = nullptr;
mPathIsRect = false;
mTransformChanged = false;
}
}

View File

@ -131,12 +131,12 @@ public:
/**
* Copies the current path and returns the copy.
*/
already_AddRefed<gfxPath> CopyPath() const;
already_AddRefed<gfxPath> CopyPath();
/**
* Appends the given path to the current path.
*/
void AppendPath(gfxPath* path);
void SetPath(gfxPath* path);
/**
* Moves the pen to a new point without drawing a line.
@ -881,8 +881,7 @@ public:
void Restore()
{
if (mPath) {
mContext->NewPath();
mContext->AppendPath(mPath);
mContext->SetPath(mPath);
mPath = nullptr;
}
}

View File

@ -7,15 +7,25 @@
#include "gfxPoint.h"
#include "gfxPlatform.h"
#include "gfxASurface.h"
#include "mozilla/gfx/2D.h"
#include "cairo.h"
using namespace mozilla::gfx;
gfxPath::gfxPath(cairo_path_t* aPath)
: mPath(aPath)
, mFlattenedPath(nullptr)
{
}
gfxPath::gfxPath(Path* aPath)
: mPath(nullptr)
, mFlattenedPath(nullptr)
, mMoz2DPath(aPath)
{
}
gfxPath::~gfxPath()
{
cairo_path_destroy(mPath);
@ -75,6 +85,10 @@ CalcSubLengthAndAdvance(cairo_path_data_t *aData,
gfxFloat
gfxPath::GetLength()
{
if (mMoz2DPath) {
return mMoz2DPath->ComputeLength();
}
EnsureFlattenedPath();
gfxPoint start(0, 0); // start of current subpath
@ -92,6 +106,20 @@ gfxPath::GetLength()
gfxPoint
gfxPath::FindPoint(gfxPoint aOffset, gfxFloat *aAngle)
{
if (mMoz2DPath) {
Point tangent; // Unit vector tangent to the point we find.
Point result = mMoz2DPath->ComputePointAtLength(aOffset.x, &tangent);
// The y value of aOffset is the offset along the normal vector to apply
Point normal(-tangent.y, tangent.x);
result += normal * aOffset.y;
if (aAngle)
*aAngle = atan2(tangent.y, tangent.x);
return gfxPoint(result.x, result.y);
}
EnsureFlattenedPath();
gfxPoint start(0, 0); // start of current subpath

View File

@ -8,11 +8,18 @@
#include "gfxTypes.h"
#include "nsISupportsImpl.h"
#include "mozilla/RefPtr.h"
class gfxContext;
struct gfxPoint;
typedef struct cairo_path cairo_path_t;
namespace mozilla {
namespace gfx {
class Path;
}
}
/**
* Class representing a path. Can be created by copying the current path
* of a gfxContext.
@ -24,6 +31,7 @@ class gfxPath {
protected:
gfxPath(cairo_path_t* aPath);
gfxPath(mozilla::gfx::Path* aPath);
void EnsureFlattenedPath();
@ -48,6 +56,7 @@ public:
protected:
cairo_path_t* mPath;
cairo_path_t* mFlattenedPath;
mozilla::RefPtr<mozilla::gfx::Path> mMoz2DPath;
};
#endif