diff options
author | Povilas Kanapickas <povilas@radix.lt> | 2014-02-13 02:10:07 +0200 |
---|---|---|
committer | Murray Cumming <murrayc@murrayc.com> | 2014-02-21 09:32:41 +0100 |
commit | f0d9932755acf407e936cc9d337388be37c8416e (patch) | |
tree | c73c3a7735d61714751ce161e428144798850b72 | |
parent | a3740cdc1d881df809cd59efa755c076bd4a6c7e (diff) |
Wrap cairo script device and script surface APIs
-rw-r--r-- | cairomm/context.cc | 6 | ||||
-rw-r--r-- | cairomm/filelist.am | 4 | ||||
-rw-r--r-- | cairomm/script.cc | 103 | ||||
-rw-r--r-- | cairomm/script.h | 137 | ||||
-rw-r--r-- | cairomm/script_surface.cc | 58 | ||||
-rw-r--r-- | cairomm/script_surface.h | 87 | ||||
-rw-r--r-- | cairomm/surface.cc | 13 |
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 |