Expose Cairo path copy/append functions through Thebes - bug 445616 r=vlad
authorEric Butler <ebutler@mozilla.com>
Fri, 18 Jul 2008 11:26:02 -0700
changeset 16042 62190e519f773165afe2109b8954b5e7f0df6bb7
parent 16041 ab1888ef44bef18da25cb80cb5e805253cee019d
child 16043 7221a9a9caf7196b0bff9fac0362c0752010037a
push idunknown
push userunknown
push dateunknown
reviewersvlad
bugs445616
milestone1.9.1a1pre
Expose Cairo path copy/append functions through Thebes - bug 445616 r=vlad
gfx/thebes/public/gfxContext.h
gfx/thebes/public/gfxPath.h
gfx/thebes/src/gfxContext.cpp
gfx/thebes/src/gfxPath.cpp
--- a/gfx/thebes/public/gfxContext.h
+++ b/gfx/thebes/public/gfxContext.h
@@ -136,16 +136,26 @@ public:
     /**
      * Closes the path, i.e. connects the last drawn point to the first one.
      *
      * Filling a path will implicitly close it.
      */
     void ClosePath();
 
     /**
+     * Copies the current path and returns the copy.
+     */
+    already_AddRefed<gfxPath> CopyPath();
+
+    /**
+     * Appends the given path to the current path.
+     */
+    void AppendPath(gfxPath* path);
+
+    /**
      * Moves the pen to a new point without drawing a line.
      */
     void MoveTo(const gfxPoint& pt);
 
     /**
      * Creates a new subpath starting at the current point.
      * Equivalent to MoveTo(CurrentPoint()).
      */
--- a/gfx/thebes/public/gfxPath.h
+++ b/gfx/thebes/public/gfxPath.h
@@ -34,38 +34,61 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef GFX_PATH_H
 #define GFX_PATH_H
 
 #include "gfxTypes.h"
 
+class gfxContext;
 struct gfxPoint;
 typedef struct cairo_path cairo_path_t;
 
-class THEBES_API gfxFlattenedPath {
+/**
+ * Class representing a path. Can be created by copying the current path
+ * of a gfxContext.
+ */
+class THEBES_API gfxPath {
     THEBES_INLINE_DECL_REFCOUNTING(gfxPath)
 
+    friend class gfxContext;
+
+protected:
+    gfxPath(cairo_path_t* aPath);
+
 public:
-    gfxFlattenedPath(cairo_path_t *aPath);
-    ~gfxFlattenedPath();
+    virtual ~gfxPath();
+
+protected:
+    cairo_path_t* mPath;
+};
+
+/**
+ * Specialization of a path that only contains linear pieces. Can be created
+ * from the existing path of a gfxContext.
+ */
+class THEBES_API gfxFlattenedPath : public gfxPath {
+    friend class gfxContext;
+
+protected:
+    gfxFlattenedPath(cairo_path_t* aPath);
+
+public:
+    virtual ~gfxFlattenedPath();
 
     /**
      * Returns calculated total length of path
      */
     gfxFloat GetLength();
 
     /**
      * Returns a point a certain distance along the path.  Return is
      * first or last point of the path if the requested length offset
      * is outside the range for the path.
      * @param aOffset offset inpath parameter space (x=length, y=normal offset)
      * @param aAngle optional - output tangent
      */
     gfxPoint FindPoint(gfxPoint aOffset,
-                       gfxFloat *aAngle = nsnull);
-
-protected:
-    cairo_path_t *mPath;
+                       gfxFloat* aAngle = nsnull);
 };
 
 #endif
--- a/gfx/thebes/src/gfxContext.cpp
+++ b/gfx/thebes/src/gfxContext.cpp
@@ -111,16 +111,28 @@ gfxContext::NewPath()
 }
 
 void
 gfxContext::ClosePath()
 {
     cairo_close_path(mCairo);
 }
 
+already_AddRefed<gfxPath> gfxContext::CopyPath()
+{
+    nsRefPtr<gfxPath> path = new gfxPath(cairo_copy_path(mCairo));
+    return path.forget();
+}
+
+void gfxContext::AppendPath(gfxPath* path)
+{
+    if (path->mPath->status == CAIRO_STATUS_SUCCESS && path->mPath->num_data != 0)
+        cairo_append_path(mCairo, path->mPath);
+}
+
 gfxPoint
 gfxContext::CurrentPoint() const
 {
     double x, y;
     cairo_get_current_point(mCairo, &x, &y);
     return gfxPoint(x, y);
 }
 
--- a/gfx/thebes/src/gfxPath.cpp
+++ b/gfx/thebes/src/gfxPath.cpp
@@ -34,23 +34,31 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "gfxPath.h"
 #include "gfxPoint.h"
 
 #include "cairo.h"
 
-gfxFlattenedPath::gfxFlattenedPath(cairo_path_t *aPath) : mPath(aPath)
+gfxPath::gfxPath(cairo_path_t* aPath) : mPath(aPath)
+{
+}
+
+gfxPath::~gfxPath()
+{
+    cairo_path_destroy(mPath);
+}
+
+gfxFlattenedPath::gfxFlattenedPath(cairo_path_t* aPath) : gfxPath(aPath)
 {
 }
 
 gfxFlattenedPath::~gfxFlattenedPath()
 {
-    cairo_path_destroy(mPath);
 }
 
 static gfxFloat
 CalcSubLengthAndAdvance(cairo_path_data_t *aData,
                         gfxPoint &aPathStart, gfxPoint &aCurrent)
 {
     float sublength = 0;