summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPovilas Kanapickas <povilas@radix.lt>2014-02-13 02:10:07 +0200
committerMurray Cumming <murrayc@murrayc.com>2014-02-21 09:32:41 +0100
commitf0d9932755acf407e936cc9d337388be37c8416e (patch)
treec73c3a7735d61714751ce161e428144798850b72
parenta3740cdc1d881df809cd59efa755c076bd4a6c7e (diff)
Wrap cairo script device and script surface APIs
-rw-r--r--cairomm/context.cc6
-rw-r--r--cairomm/filelist.am4
-rw-r--r--cairomm/script.cc103
-rw-r--r--cairomm/script.h137
-rw-r--r--cairomm/script_surface.cc58
-rw-r--r--cairomm/script_surface.h87
-rw-r--r--cairomm/surface.cc13
7 files changed, 407 insertions, 1 deletions
diff --git a/cairomm/context.cc b/cairomm/context.cc
index 95d33e2..bf70ef4 100644
--- a/cairomm/context.cc
+++ b/cairomm/context.cc
@@ -26,6 +26,7 @@
#include <cairomm/context_private.h>
#include <cairomm/private.h>
#include <cairomm/surface.h>
+#include <cairomm/script_surface.h>
#include <cairomm/scaledfont.h>
/* M_PI is defined in math.h in the case of Microsoft Visual C++ */
@@ -836,6 +837,11 @@ RefPtr<Surface> get_surface_wrapper (cairo_surface_t* surface)
return wrap_surface_quartz(surface);
break;
#endif
+#if CAIRO_HAS_SCRIPT_SURFACE
+ case CAIRO_SURFACE_TYPE_SCRIPT:
+ return RefPtr<ScriptSurface>(new ScriptSurface(surface, false));
+ break;
+#endif
#if CAIRO_HAS_WIN32_SURFACE
case CAIRO_SURFACE_TYPE_WIN32:
return wrap_surface_win32(surface);
diff --git a/cairomm/filelist.am b/cairomm/filelist.am
index 9f0b832..ab26483 100644
--- a/cairomm/filelist.am
+++ b/cairomm/filelist.am
@@ -17,6 +17,8 @@ cairomm_cc = \
quartz_surface.cc \
region.cc \
scaledfont.cc \
+ script.cc \
+ script_surface.cc \
surface.cc \
win32_font.cc \
win32_surface.cc \
@@ -37,6 +39,8 @@ cairomm_public_h = \
refptr.h \
region.h \
scaledfont.h \
+ script.h \
+ script_surface.h \
surface.h \
types.h \
win32_font.h \
diff --git a/cairomm/script.cc b/cairomm/script.cc
new file mode 100644
index 0000000..ac8b22e
--- /dev/null
+++ b/cairomm/script.cc
@@ -0,0 +1,103 @@
+/* Copyright (C) 2014 The cairomm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <cairomm/script_surface.h>
+#include <cairomm/private.h>
+
+namespace Cairo {
+
+#ifdef CAIRO_HAS_SCRIPT_SURFACE
+
+Script::Script(cairo_device_t* cobject, bool has_reference) :
+ Device(cobject, has_reference)
+{}
+
+Script::~Script()
+{
+ // script device is destroyed in base class
+}
+
+void Script::add_from_recording_surface(const RefPtr<ScriptSurface>& recording_surface)
+{
+ ErrorStatus status = cairo_script_from_recording_surface(m_cobject,
+ recording_surface->cobj());
+ check_status_and_throw_exception(status);
+}
+
+ScriptMode Script::get_mode() const
+{
+ return static_cast<ScriptMode>(cairo_script_get_mode(m_cobject));
+}
+
+void Script::set_mode(ScriptMode new_mode)
+{
+ cairo_script_set_mode(m_cobject, static_cast<cairo_script_mode_t>(new_mode));
+}
+
+void Script::write_comment(const std::string& comment)
+{
+ cairo_script_write_comment(m_cobject, comment.data(), comment.length());
+}
+
+RefPtr<Script> Script::create(const std::string& filename)
+{
+ cairo_device_t* cobject = cairo_script_create(filename.c_str());
+ check_status_and_throw_exception(cairo_device_status(cobject));
+ return RefPtr<Script>(new Script(cobject, true /* has reference */));
+}
+
+static cairo_user_data_key_t USER_DATA_KEY_DEVICE_WRITE_FUNC = {0};
+
+static void device_free_slot(void* data)
+{
+ // FIXME: duplicates free_slot in surface.cc
+ Surface::SlotWriteFunc* slot = static_cast<Surface::SlotWriteFunc*>(data);
+ delete slot;
+}
+
+cairo_status_t device_write_func_wrapper(void* closure, const unsigned char* data,
+ unsigned int length)
+{
+ // FIXME: duplicates free_slot in surface.cc
+ if (!closure)
+ return CAIRO_STATUS_WRITE_ERROR;
+ Surface::SlotWriteFunc* write_func = static_cast<Surface::SlotWriteFunc*>(closure);
+ return static_cast<cairo_status_t>((*write_func)(data, length));
+}
+
+static void set_write_slot(cairo_device_t* surface,
+ Surface::SlotWriteFunc* slot) {
+ // the slot will automatically be freed by device_free_slot() when the
+ // underlying C instance is destroyed
+ cairo_device_set_user_data(surface, &USER_DATA_KEY_DEVICE_WRITE_FUNC, slot,
+ &device_free_slot);
+}
+
+RefPtr<Script> Script::create_for_stream(const Surface::SlotWriteFunc& write_func)
+{
+ Surface::SlotWriteFunc* slot_copy = new Surface::SlotWriteFunc(write_func);
+ cairo_device_t* cobject = cairo_script_create_for_stream(device_write_func_wrapper,
+ slot_copy);
+ check_status_and_throw_exception(cairo_device_status(cobject));
+ set_write_slot(cobject, slot_copy);
+ return RefPtr<Script>(new Script(cobject, true /* has reference */));
+}
+
+#endif // CAIRO_HAS_SCRIPT_SURFACE
+
+} //namespace Cairo
diff --git a/cairomm/script.h b/cairomm/script.h
new file mode 100644
index 0000000..3bd4778
--- /dev/null
+++ b/cairomm/script.h
@@ -0,0 +1,137 @@
+/* Copyright (C) 2014 The cairomm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef __CAIROMM_SCRIPT_H
+#define __CAIROMM_SCRIPT_H
+
+#include <string>
+#include <cairomm/device.h>
+#include <cairomm/surface.h> // SlotWriteFunc
+#include <cairomm/enums.h>
+
+#ifdef CAIRO_HAS_SCRIPT_SURFACE
+#include <cairo-script.h>
+#endif
+
+namespace Cairo {
+
+#ifdef CAIRO_HAS_SCRIPT_SURFACE
+
+class ScriptSurface;
+
+/**
+ * A set of script output variants for the script surface.
+ *
+ * @since 1.12
+ */
+enum ScriptMode {
+
+ /// The output will be in readable text (default).
+ SCRIPT_MODE_ASCII = CAIRO_SCRIPT_MODE_ASCII,
+
+ /// The output will use byte codes.
+ SCRIPT_MODE_BINARY = CAIRO_SCRIPT_MODE_BINARY
+};
+
+/**
+ * The script surface provides the ability to render to a native script that
+ * matches the cairo drawing model. The scripts can be replayed using tools under
+ * the util/cairo-script directoriy, or with cairo-perf-trace.
+ *
+ * @since 1.12
+ */
+class Script : public Device {
+public:
+
+ /**
+ * Create a C++ wrapper for the C instance. This C++ instance should then be
+ * given to a RefPtr.
+ *
+ * @param cobject The C instance.
+ * @param has_reference whether we already have a reference. Otherwise, the
+ * constructor will take an extra reference.
+ *
+ * @since 1.12
+ */
+ explicit Script(cairo_device_t* cobject, bool has_reference = false);
+ virtual ~Script();
+
+ /**
+ * Converts the record operations in recording_surface into a script.
+ *
+ * @param recording_surface The recording surface to replay
+ *
+ * Throws an exception on error.
+ *
+ * @since 1.12
+ */
+ void add_from_recording_surface(const RefPtr<ScriptSurface>& recording_surface);
+
+ /**
+ * Queries the script for its current output mode.
+ *
+ * @since 1.12
+ */
+ ScriptMode get_mode() const;
+
+ /**
+ * Change the output mode of the script.
+ *
+ * @param mode The new mode.
+ *
+ * @since 1.12
+ */
+ void set_mode(ScriptMode new_mode);
+
+ /**
+ * Emit a string verbatim into the script.
+ *
+ * @param comment The string to emit
+ */
+ void write_comment(const std::string& comment);
+
+ /**
+ * Creates a output device for emitting the script, used when creating the
+ * individual surfaces.
+ *
+ * @param filename The name (path) of the file to write the script to.
+ *
+ * Throws an exception on error.
+ *
+ * @since 1.12
+ */
+ static RefPtr<Script> create(const std::string& filename);
+
+ /**
+ * Creates a output device for emitting the script, used when creating the
+ * individual surfaces.
+ *
+ * @param write_func Callback function passed the bytes written to the script
+ *
+ * @since 1.12
+ */
+ static RefPtr<Script> create_for_stream(const Surface::SlotWriteFunc& write_func);
+
+};
+
+#endif // CAIRO_HAS_SCRIPT_SURFACE
+
+} // namespace Cairo
+
+#endif //__CAIROMM_SCRIPT_SURFACE_H
+
diff --git a/cairomm/script_surface.cc b/cairomm/script_surface.cc
new file mode 100644
index 0000000..645bc62
--- /dev/null
+++ b/cairomm/script_surface.cc
@@ -0,0 +1,58 @@
+/* Copyright (C) 2014 The cairomm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <cairomm/script_surface.h>
+#include <cairomm/private.h>
+
+namespace Cairo {
+
+#ifdef CAIRO_HAS_SCRIPT_SURFACE
+
+ScriptSurface::ScriptSurface(cairo_surface_t* cobject, bool has_reference) :
+ Surface(cobject, has_reference)
+{}
+
+ScriptSurface::~ScriptSurface()
+{
+ // surface is destroyed in base class
+}
+
+RefPtr<ScriptSurface> ScriptSurface::create(const RefPtr<Script>& script,
+ Content content,
+ double width, double height)
+{
+ cairo_surface_t* cobject =
+ cairo_script_surface_create(script->cobj(), static_cast<cairo_content_t>(content),
+ width, height);
+ check_status_and_throw_exception(cairo_surface_status(cobject));
+ return RefPtr<ScriptSurface>(new ScriptSurface(cobject, true /* has reference */));
+}
+
+RefPtr<ScriptSurface>
+ ScriptSurface::create_for_target(const RefPtr<Script>& script,
+ const RefPtr<Surface>& target)
+{
+ cairo_surface_t* cobject =
+ cairo_script_surface_create_for_target(script->cobj(), target->cobj());
+ check_status_and_throw_exception(cairo_surface_status(cobject));
+ return RefPtr<ScriptSurface>(new ScriptSurface(cobject, true /* has reference */));
+}
+
+#endif // CAIRO_HAS_SCRIPT_SURFACE
+
+} //namespace Cairo
diff --git a/cairomm/script_surface.h b/cairomm/script_surface.h
new file mode 100644
index 0000000..ad73913
--- /dev/null
+++ b/cairomm/script_surface.h
@@ -0,0 +1,87 @@
+/* Copyright (C) 2014 The cairomm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef __CAIROMM_SCRIPT_SURFACE_H
+#define __CAIROMM_SCRIPT_SURFACE_H
+
+#include <cairomm/surface.h>
+#include <cairomm/script.h>
+
+namespace Cairo {
+
+#ifdef CAIRO_HAS_SCRIPT_SURFACE
+
+/**
+ * The script surface provides the ability to render to a native script that
+ * matches the cairo drawing model. The scripts can be replayed using tools under
+ * the util/cairo-script directoriy, or with cairo-perf-trace.
+ *
+ * @since 1.12
+ */
+class ScriptSurface : public Surface {
+public:
+
+ /**
+ * Create a C++ wrapper for the C instance. This C++ instance should then be
+ * given to a RefPtr.
+ *
+ * @param cobject The C instance.
+ * @param has_reference whether we already have a reference. Otherwise, the
+ * constructor will take an extra reference.
+ *
+ * @since 1.12
+ */
+ explicit ScriptSurface(cairo_surface_t* cobject, bool has_reference = false);
+ virtual ~ScriptSurface();
+
+ /**
+ * Create a new surface that will emit its rendering through script.
+ *
+ * Throws an exception on error.
+ *
+ * @param script The script (output device)
+ * @param content The content of the surface
+ * @param width Width in pixels
+ * @param height Height in pixels
+ *
+ * @since 1.12
+ */
+ static RefPtr<ScriptSurface> create(const RefPtr<Script>& script,
+ Content content, double width, double height);
+
+ /**
+ * Create a proxy surface that will render to target and record the operations
+ * to device.
+ *
+ * Throws an exception on error.
+ *
+ * @param script The script (output device)
+ * @param target A target surface to wrap
+ *
+ * @since 1.12
+ */
+ static RefPtr<ScriptSurface> create_for_target(const RefPtr<Script>& script,
+ const RefPtr<Surface>& target);
+};
+
+#endif // CAIRO_HAS_SCRIPT_SURFACE
+
+} // namespace Cairo
+
+#endif //__CAIROMM_SCRIPT_SURFACE_H
+
diff --git a/cairomm/surface.cc b/cairomm/surface.cc
index 88e72cf..5697295 100644
--- a/cairomm/surface.cc
+++ b/cairomm/surface.cc
@@ -17,6 +17,7 @@
*/
#include <cairomm/surface.h>
+#include <cairomm/script.h>
#include <cairomm/private.h>
namespace Cairo
@@ -246,7 +247,17 @@ RefPtr<Device> Surface::get_device()
if (!d)
return RefPtr<Device>();
- return RefPtr<Device>(new Device(d, true));
+ cairo_surface_type_t surface_type = cairo_surface_get_type(m_cobject);
+ switch (surface_type)
+ {
+#if CAIRO_HAS_SCRIPT_SURFACE
+ case CAIRO_SURFACE_TYPE_SCRIPT:
+ return RefPtr<Script>(new Script(d, true /* has reference */));
+ break;
+#endif
+ default:
+ return RefPtr<Device>(new Device(d, true /* has reference */));
+ }
}
void Surface::reference() const