Bug 1168527 - Add support to gfxContext for clip exporting. r=jrmuizel
authorAndrew Comminos <acomminos@mozilla.com>
Tue, 09 Jun 2015 13:46:09 -0400
changeset 267919 ff75c7e0b5d4a0bfc78bb8df12f25716b12b3481
parent 267918 7f6477aa22705018bd534f98049e49a1f064f35c
child 267920 85ca98c22bdc7216afbe6b20d50c129622f3c590
push id8157
push userjlund@mozilla.com
push dateMon, 29 Jun 2015 20:36:23 +0000
treeherdermozilla-aurora@d480e05bd276 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1168527
milestone41.0a1
Bug 1168527 - Add support to gfxContext for clip exporting. r=jrmuizel
gfx/thebes/gfxContext.cpp
gfx/thebes/gfxContext.h
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -632,16 +632,50 @@ gfxContext::HasComplexClip() const
     if (mStateStack[i].clipWasReset) {
       break;
     }
   }
   return false;
 }
 
 bool
+gfxContext::ExportClip(ClipExporter& aExporter)
+{
+  unsigned int lastReset = 0;
+  for (int i = mStateStack.Length() - 1; i > 0; i--) {
+    if (mStateStack[i].clipWasReset) {
+      lastReset = i;
+      break;
+    }
+  }
+
+  for (unsigned int i = lastReset; i < mStateStack.Length(); i++) {
+    for (unsigned int c = 0; c < mStateStack[i].pushedClips.Length(); c++) {
+      AzureState::PushedClip &clip = mStateStack[i].pushedClips[c];
+      gfx::Matrix transform = clip.transform;
+      transform.PostTranslate(-GetDeviceOffset());
+
+      aExporter.BeginClip(transform);
+      if (clip.path) {
+        clip.path->StreamToSink(&aExporter);
+      } else {
+        aExporter.MoveTo(clip.rect.TopLeft());
+        aExporter.LineTo(clip.rect.TopRight());
+        aExporter.LineTo(clip.rect.BottomRight());
+        aExporter.LineTo(clip.rect.BottomLeft());
+        aExporter.Close();
+      }
+      aExporter.EndClip();
+    }
+  }
+
+  return true;
+}
+
+bool
 gfxContext::ClipContainsRect(const gfxRect& aRect)
 {
   unsigned int lastReset = 0;
   for (int i = mStateStack.Length() - 2; i > 0; i--) {
     if (mStateStack[i].clipWasReset) {
       lastReset = i;
       break;
     }
--- a/gfx/thebes/gfxContext.h
+++ b/gfx/thebes/gfxContext.h
@@ -23,16 +23,18 @@ class GlyphBufferAzure;
 template <typename T> class FallibleTArray;
 
 namespace mozilla {
 namespace gfx {
 struct RectCornerRadii;
 }
 }
 
+class ClipExporter;
+
 /**
  * This is the main class for doing actual drawing. It is initialized using
  * a surface and can be drawn on. It manages various state information like
  * a current transformation matrix (CTM), a current path, current color,
  * etc.
  *
  * All drawing happens by creating a path and then stroking or filling it.
  * The functions like Rectangle and Arc do not do any drawing themselves.
@@ -452,16 +454,21 @@ public:
 
     /**
      * Returns true if the given rectangle is fully contained in the current clip. 
      * This is conservative; it may return false even when the given rectangle is 
      * fully contained by the current clip.
      */
     bool ClipContainsRect(const gfxRect& aRect);
 
+     /**
+      * Exports the current clip using the provided exporter.
+      */
+    bool ExportClip(ClipExporter& aExporter);
+
     /**
      * Groups
      */
     void PushGroup(gfxContentType content = gfxContentType::COLOR);
     /**
      * Like PushGroup, but if the current surface is gfxContentType::COLOR and
      * content is gfxContentType::COLOR_ALPHA, makes the pushed surface gfxContentType::COLOR
      * instead and copies the contents of the current surface to the pushed
@@ -723,9 +730,17 @@ private:
     mozilla::AlignedStorage2<mozilla::gfx::ColorPattern> mColorPattern;
     mozilla::AlignedStorage2<mozilla::gfx::SurfacePattern> mSurfacePattern;
   };
 
   gfxContext *mContext;
   mozilla::gfx::Pattern *mPattern;
 };
 
+/* This interface should be implemented to handle exporting the clip from a context.
+ */
+class ClipExporter : public mozilla::gfx::PathSink {
+public:
+  virtual void BeginClip(const mozilla::gfx::Matrix& aMatrix) = 0;
+  virtual void EndClip() = 0;
+};
+
 #endif /* GFX_CONTEXT_H */