summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--cairomm/context.cc55
-rw-r--r--cairomm/context.h120
3 files changed, 181 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 3acb925..cc0bb49 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2006-06-23 Jonathon Jongsma <jonathon.jongsma@gmail.com>
+ * cairomm/context.cc:
+ * cairomm/context.h: added Context::new_sub_path() and new push/pop group
+ API.
+
+2006-06-23 Jonathon Jongsma <jonathon.jongsma@gmail.com>
+
* cairomm/enums.h: fix stupid error from last commit
2006-06-23 Jonathon Jongsma <jonathon.jongsma@gmail.com>
diff --git a/cairomm/context.cc b/cairomm/context.cc
index c5d2bb8..2a57ab9 100644
--- a/cairomm/context.cc
+++ b/cairomm/context.cc
@@ -229,6 +229,12 @@ void Context::clear_path()
check_object_status_and_throw_exception(*this);
}
+void Context::new_sub_path()
+{
+ cairo_new_sub_path(m_cobject);
+ check_object_status_and_throw_exception(*this);
+}
+
void Context::move_to(double x, double y)
{
cairo_move_to(m_cobject, x, y);
@@ -604,6 +610,55 @@ void Context::append_path(const Path& path)
check_object_status_and_throw_exception(*this);
}
+void Context::push_group()
+{
+ cairo_push_group(m_cobject);
+ check_object_status_and_throw_exception(*this);
+}
+
+void Context::push_group_with_content(Content content)
+{
+ cairo_push_group_with_content(m_cobject, static_cast<cairo_content_t>(content));
+ check_object_status_and_throw_exception(*this);
+}
+
+RefPtr<Pattern> Context::pop_group()
+{
+ cairo_pattern_t* pattern = cairo_pop_group(m_cobject);
+ check_object_status_and_throw_exception(*this);
+ return RefPtr<Pattern>(new Pattern(pattern));
+}
+
+void Context::pop_group_to_source()
+{
+ cairo_pop_group_to_source(m_cobject);
+ check_object_status_and_throw_exception(*this);
+}
+
+RefPtr<Surface> Context::get_group_target()
+{
+ cairo_surface_t* surface = cairo_get_group_target(m_cobject);
+ // surface can be NULL if you're not between push/pop group calls
+ if (surface == NULL)
+ {
+ // FIXME: is this really the right way to handle this?
+ throw_exception(CAIRO_STATUS_NULL_POINTER);
+ }
+ return RefPtr<Surface>(new Surface(surface, false));
+}
+
+RefPtr<const Surface> Context::get_group_target() const
+{
+ cairo_surface_t* surface = cairo_get_group_target(m_cobject);
+ // surface can be NULL if you're not between push/pop group calls
+ if (surface == NULL)
+ {
+ // FIXME: is this really the right way to handle this?
+ throw_exception(CAIRO_STATUS_NULL_POINTER);
+ }
+ return RefPtr<const Surface>(new Surface(surface, false));
+}
+
} //namespace Cairo
// vim: ts=2 sw=2 et
diff --git a/cairomm/context.h b/cairomm/context.h
index 13cbd6d..28fb248 100644
--- a/cairomm/context.h
+++ b/cairomm/context.h
@@ -356,6 +356,19 @@ public:
*/
void clear_path();
+ /** Begin a new subpath. Note that the existing path is not affected. After
+ * this call there will be no current point.
+ *
+ * In many cases, this call is not needed since new subpaths are frequently
+ * started with move_to().
+ *
+ * A call to new_sub_path() is particularly useful when beginning a new
+ * subpath with one of the arc() calls. This makes things easier as it is no
+ * longer necessary to manually compute the arc's initial coordinates for a
+ * call to move_to().
+ */
+ void new_sub_path();
+
/** If the current subpath is not empty, begin a new subpath. After this call
* the current point will be (x, y).
*
@@ -780,6 +793,113 @@ public:
*/
void append_path(const Path& path);
+ /** Temporarily redirects drawing to an intermediate surface known as a group.
+ * The redirection lasts until the group is completed by a call to pop_group()
+ * or pop_group_to_source(). These calls provide the result of any drawing to
+ * the group as a pattern, (either as an explicit object, or set as the source
+ * pattern).
+ *
+ * This group functionality can be convenient for performing intermediate
+ * compositing. One common use of a group is to render objects as opaque
+ * within the group, (so that they occlude each other), and then blend the
+ * result with translucence onto the destination.
+ *
+ * Groups can be nested arbitrarily deep by making balanced calls to
+ * push_group()/pop_group(). Each call pushes/pops the new target group
+ * onto/from a stack.
+ *
+ * The push_group() function calls save() so that any changes to the graphics
+ * state will not be visible outside the group, (the pop_group functions call
+ * restore()).
+ *
+ * By default the intermediate group will have a content type of
+ * CONTENT_COLOR_ALPHA. Other content types can be chosen for the group by
+ * using push_group_with_content() instead.
+ *
+ * As an example, here is how one might fill and stroke a path with
+ * translucence, but without any portion of the fill being visible under the
+ * stroke:
+ *
+ * @code
+ * cr->push_group();
+ * cr->set_source(fill_pattern);
+ * cr->fill_preserve();
+ * cr->set_source(stroke_pattern);
+ * cr->stroke();
+ * cr->pop_group_to_source();
+ * cr->paint_with_alpha(alpha);
+ * @endcode
+ */
+ void push_group();
+
+ /**
+ * Temporarily redirects drawing to an intermediate surface known as a
+ * group. The redirection lasts until the group is completed by a call
+ * to pop_group() or pop_group_to_source(). These calls provide the result of
+ * any drawing to the group as a pattern, (either as an explicit object, or set
+ * as the source pattern).
+ *
+ * The group will have a content type of @content. The ability to control this
+ * content type is the only distinction between this function and push_group()
+ * which you should see for a more detailed description of group rendering.
+ *
+ * \param content: indicates the type of group that will be created
+ */
+ void push_group_with_content(Content content);
+
+ /**
+ * Terminates the redirection begun by a call to push_group() or
+ * push_group_with_content() and returns a new pattern containing the results
+ * of all drawing operations performed to the group.
+ *
+ * The pop_group() function calls restore(), (balancing a call to save() by
+ * the push_group function), so that any changes to the graphics state will
+ * not be visible outside the group.
+ *
+ * \return a (surface) pattern containing the results of all drawing
+ * operations performed to the group.
+ **/
+ RefPtr<Pattern> pop_group();
+
+ /**
+ * Terminates the redirection begun by a call to push_group() or
+ * push_group_with_content() and installs the resulting pattern as the source
+ * pattern in the given cairo Context.
+ *
+ * The behavior of this function is equivalent to the sequence of operations:
+ *
+ * @code
+ * RefPtr<Pattern> group = cr->pop_group();
+ * cr->set_source(group);
+ * @endcode
+ *
+ * but is more convenient as their is no need for a variable to store
+ * the short-lived pointer to the pattern.
+ *
+ * The pop_group() function calls restore(), (balancing a call to save() by
+ * the push_group function), so that any changes to the graphics state will
+ * not be visible outside the group.
+ **/
+ void pop_group_to_source();
+
+ /**
+ * Gets the target surface for the current group as started by the most recent
+ * call to push_group() or push_group_with_content().
+ *
+ * This function will return NULL if called "outside" of any group rendering
+ * blocks, (that is, after the last balancing call to pop_group() or
+ * pop_group_to_source()).
+ *
+ * @exception
+ *
+ **/
+ RefPtr<Surface> get_group_target();
+
+ /**
+ * Same as the non-const version but returns a reference to a const Surface
+ */
+ RefPtr<const Surface> get_group_target() const;
+
/** The base cairo C type that is wrapped by Cairo::Context
*/
typedef cairo_t cobject;