summaryrefslogtreecommitdiff
path: root/libs/cairo-1.16.0/doc/public/language-bindings.xml
diff options
context:
space:
mode:
Diffstat (limited to 'libs/cairo-1.16.0/doc/public/language-bindings.xml')
-rw-r--r--libs/cairo-1.16.0/doc/public/language-bindings.xml745
1 files changed, 0 insertions, 745 deletions
diff --git a/libs/cairo-1.16.0/doc/public/language-bindings.xml b/libs/cairo-1.16.0/doc/public/language-bindings.xml
deleted file mode 100644
index ce437ef..0000000
--- a/libs/cairo-1.16.0/doc/public/language-bindings.xml
+++ /dev/null
@@ -1,745 +0,0 @@
-<appendix id="language-bindings">
- <title>Creating a language binding for cairo</title>
- <para>
- While cairo is implemented and C, and has a C API, it is expected
- that many users of cairo will be using it from languages other
- than C. The glue that connects the core cairo library to another
- language is known as a <firstterm>language
- binding</firstterm>. This appendix attempts to collect together
- issues that come up when creating a language bindings for cairo
- and present standardized solutions to promote consistency among
- the different language bindings.
- </para>
- <sect1 id="bindings-general">
- <title>General considerations</title>
- <para>
- The naming of the central <link
- linkend="cairo-t"><type>cairo_t</type></link> type is a
- special exception. The object is “a cairo context” not “a
- cairo”, and names such as <type>cairo_t</type> rather than
- <type>cairo_context_t</type> and
- <function>cairo_set_source()</function> rather than
- <function>cairo_context_set_source()</function> are simply
- abbreviations to make the C API more palatable. In languages
- which have object-oriented syntax, this abbreviation is much
- less useful. In fact, if ‘Cairo’ is used as a namespace, then
- in many languages, you'd end up with a ridiculous type name
- like ‘Cairo.Cairo’. For this reason, and for inter-language
- consistency all object-oriented languages should name this
- type as if it were <type>cairo_context_t</type>.
- </para>
- <para>
- The punctuation and casing of the type names and
- method names of cairo should be changed to match the general
- convention of the language. In Java, where type names are written
- in StudlyCaps and method names in javaCaps, cairo_font_extents_t
- will become FontExtents and
- <literal>cairo_set_source(cr,source)</literal>,
- <literal>cr.setSource(source)</literal>.
- As compared to changing the punctuation, and casing, much
- more reluctance should be used in changing the method names
- themselves. Even if get is usually omitted from getters in
- your language, you shouldn't bind cairo_get_source() as
- cr.source().
- </para>
- </sect1>
- <sect1 id="bindings-memory">
- <title>Memory management</title>
- <para>
- The objects in cairo can roughly be divided into two types:
- reference-counted, opaque types like
- <link
- linkend="cairo-surface-t"><type>cairo_surface_t</type></link>
- and plain structures like
- <link
- linkend="cairo-glyph-t"><type>cairo_glyph_t</type></link>.
- <link
- linkend="cairo-path-t"><type>cairo_path_t</type></link>
- and
- <link
- linkend="cairo-path-data-t"><type>cairo_path_data_t</type></link>
- are special cases and are treated separately in this appendix.
- </para>
- <para>
- Refcounted opaque types all have a
- <function>..._reference()</function>
- function to increase the refcount by one and a
- <function>..._destroy()</function> to decrease the refcount
- by one. These should not be exposed to the user of the language
- binding, but rather used to implement memory management within
- the language binding. The simplest way to do memory management
- for a language binding is to treat the language binding object
- as a simple handle to the cairo object. The language binding
- object references the cairo object, and unreferences it when
- finalized. This is the recommended method, though there are
- a couple of caveats to be noted:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- Equality won't work as expected. You can have two language
- objects for the same cairo and they won't necessarily
- compare equal. If the language allows customizing the
- equality operation, then this is fixable by comparing
- the underlying pointers. It also can be fixed by creating
- at most one language object per cairo object, and
- uniquifying via a <firstterm>pin table</firstterm> (a hash
- table that goes from cairo object to language object).
- For <type>cairo_surface_t</type> you can use also
- <link
- linkend="cairo-surface-set-user-data"><function>cairo_surface_set_user_data()</function></link>
- instead of a separate pin table.
- </para>
- </listitem>
- <listitem>
- <para>
- Derivation from the language object doesn't work because
- you can lose the language object while keeping the Cairo
- object. Code like:
- </para>
-<programlisting>
-public class MySurface (ImageSurface) {
- public MySurface (width, height) {
- super (Format.ARGB32, width, height);
- }
- public int get42 () {
- return 42;
- }
-}
-
- cr = Cairo(MySurface(width, height));
- surface = cr.getTarget();
-</programlisting>
- <para>
- Can result in <varname>surface</varname> containing an
- <classname>ImageSurface</classname> not a <classname>MySurface</classname>.
- This is not easily fixable without creating memory leaks,
- and it's probably best to simply forbid deriving from the
- language objects.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- When a plain structure is used as a return value from cairo,
- this is done by passing it as a “out parameter”.
- </para>
-<programlisting>
-cairo_font_extents_t extents;
-
-cairo_font_extents (cr, &amp;extents);</programlisting>
- <para>
- In a language binding, this should typically be treated
- as a return value:
- </para>
-<programlisting>
-FontExtents extents = cr.fontExtents ();</programlisting>
- <para>
- A language binding has a choice in how it implements the
- language objects for plain structures. It can use a pure
- language object with fields corresponding to those of the C
- structure, and convert from and to the C structure when calling
- cairo functions or converting cairo return values. Or it
- can keep a pointer to the C structure internally and wrap
- it inside a language object much like occurs for refcounted
- objects. The choice should be invisible to the user: they should
- be able to imagine that it is implemented as a pure language
- object.
- </para>
- </sect1>
- <sect1 id="bindings-return-values">
- <title>Multiple return values</title>
- <para>
- There are a number of functions in the cairo API that have
- multiple <firstterm>out parameters</firstterm> or
- <firstterm>in-out parameters</firstterm>. In some languages
- these can be translated into multiple return values. In Python,
- what is:
- </para>
- <programlisting>
-cairo_user_to_device (cr, &amp;x, &amp;y);</programlisting>
- <para>
- can by mapped to:
- </para>
- <programlisting>
-(x, y) = cr.user_to_device (cr, x, y);</programlisting>
- <para>
- but many languages don't have provisions for multiple return
- values, so it is necessary to introduce auxiliary types.
- Most of the functions that require the auxiliary types
- require a type that would, in C, look like
- </para>
- <programlisting>
-typedef struct _cairo_point cairo_point_t;
-struct _cairo_point {
- double x;
- double y;
-}</programlisting>
- <para>
- The same type should be used both for functions that use a pair
- of coordinates as an absolute position, and functions that use
- a pair of coordinates as a displacement. While an argument could
- be made that having a separate “distance” type is more correct,
- it is more likely just to confuse users.
- </para>
- <programlisting>
-void
-cairo_user_to_device (cairo_t *cr, double *x, double *y);
-
-void
-cairo_user_to_device_distance (cairo_t *cr, double *dx, double *dy);
-
-void
-cairo_device_to_user (cairo_t *cr, double *x, double *y);
-
-void
-cairo_device_to_user_distance (cairo_t *cr, double *dx, double *dy);
-
-void
-cairo_matrix_transform_distance (cairo_matrix_t *matrix, double *dx, double *dy);
-
-void
-cairo_matrix_transform_point (cairo_matrix_t *matrix, double *x, double *y);
-
-void
-cairo_get_current_point (cairo_t *cr, double *x, double *y);
- </programlisting>
- <para>
- There are also a couple of functions that return four values
- representing a rectangle. These should be mapped to a
- “rectangle” type that looks like:
- </para>
- <programlisting>
-typedef struct _cairo_rectangle cairo_rectangle_t;
-struct _cairo_rectangle {
- double x;
- double y;
- double width;
- double height;
-}</programlisting>
- <para>
- The C function returns the rectangle as a set of two points to
- facilitate rounding to integral extents, but this isn't worth
- adding a “box” type to go along with the more obvious
- “rectangle” representation.
- </para>
- <remark>
- Q: Would it make sense here to define a standard
- <function>cairo_rectangle_round()</function> method
- that language bindings should map?
- </remark>
- <programlisting>
-void
-cairo_stroke_extents (cairo_t *cr,
- double *x1, double *y1,
- double *x2, double *y2);
-
-void
-cairo_fill_extents (cairo_t *cr,
- double *x1, double *y1,
- double *x2, double *y2);
- </programlisting>
- </sect1>
- <sect1 id="bindings-overloading">
- <title>Overloading and optional arguments</title>
- <para>
- Function overloading (having a several variants of a function
- with the same name and different arguments) is a language
- feature available in many languages but not in C.
- </para>
- <para>
- In general, language binding authors should use restraint in
- combining functions in the cairo API via function
- overloading. What may seem like an obvious overload now may
- turn out to be strange with future additions to cairo.
- It might seem logical to make
- <link
- linkend="cairo-set-source-rgb"><function>cairo_set_source_rgb()</function></link>
- an overload of <function>cairo_set_source()</function>, but future plans to add
- <function>cairo_set_source_rgb_premultiplied()</function>,
- which will also take three doubles make this a bad idea. For
- this reason, only the following pairs of functions should
- be combined via overloading
- </para>
- <programlisting>
-void
-cairo_set_source (cairo_t *cr, cairo_pattern_t *source);
-
-void
-cairo_set_source_surface (cairo_t *cr,
- cairo_surface_t *source,
- double surface_x,
- double surface_y);
-
-void
-cairo_mask (cairo_t *cr,
- cairo_pattern_t *pattern);
-
-void
-cairo_mask_surface (cairo_t *cr,
- cairo_surface_t *surface,
- double surface_x,
- double surface_y);
-
-cairo_surface_t *
-cairo_image_surface_create (cairo_format_t format,
- int width,
- int height);
-cairo_surface_t *
-cairo_image_surface_create_for_data (unsigned char *data,
- cairo_format_t format,
- int width,
- int height,
- int stride);
-
-cairo_status_t
-cairo_surface_write_to_png (cairo_surface_t *surface,
- const char *filename);
-
-cairo_status_t
-cairo_surface_write_to_png_stream (cairo_surface_t *surface,
- cairo_write_func_t write_func,
- void *closure);
-
-cairo_surface_t *
-cairo_image_surface_create_from_png (const char *filename);
-
-cairo_surface_t *
-cairo_image_surface_create_from_png_stream (cairo_read_func_t read_func,
- void *closure);
- </programlisting>
- <para>
- Note that there are cases where all constructors for a type
- aren't overloaded together. For example
- <link
- linkend="cairo-image-surface-create-from-png"><function>cairo_image_surface_create_from_png()</function></link>
- should <emphasis>not</emphasis> be overloaded together with
- <link
- linkend="cairo-image-surface-create"><function>cairo_image_surface_create()</function></link>.
- In such cases, the remaining constructors will typically need to
- be bound as static methods. In Java, for example, we might have:
- </para>
-<programlisting>
-Surface surface1 = ImageSurface(Format.RGB24, 100, 100);
-Surface surface2 = ImageSurface.createFromPNG("camera.png");</programlisting>
- <para>
- Some other overloads that add combinations not found in C may be
- convenient for users for language bindings that provide
- <type>cairo_point_t</type> and <type>cairo_rectangle_t</type>
- types, for example:
- </para>
- <programlisting>
-void
-cairo_move_to (cairo_t *cr,
- cairo_point_t *point);
-void
-cairo_rectangle (cairo_t *cr,
- cairo_rectangle_t *rectangle);
- </programlisting>
- </sect1>
- <sect1 id="bindings-streams">
- <title>Streams and File I/O</title>
- <para>
- Various places in the cairo API deal with reading and writing
- data, whether from and to files, or to other sources and
- destinations. In these cases, what is typically provided in the
- C API is a simple version that just takes a filename, and a
- complex version that takes a callback function.
- An example is the PNG handling functions:
- </para>
-<programlisting>
-cairo_surface_t *
-cairo_image_surface_create_from_png (const char *filename);
-
-cairo_surface_t *
-cairo_image_surface_create_from_png_stream (cairo_read_func_t read_func,
- void *closure);
-
-cairo_status_t
-cairo_surface_write_to_png (cairo_surface_t *surface,
- const char *filename);
-
-cairo_status_t
-cairo_surface_write_to_png_stream (cairo_surface_t *surface,
- cairo_write_func_t write_func,
- void *closure);</programlisting>
- <para>
- The expectation is that the filename version will be mapped
- literally in the language binding, but the callback version
- will be mapped to a version that takes a language stream
- object. For example, in Java, the four functions above
- might be mapped to:
- </para>
-<programlisting>
-static public ImageSurface createFromPNG (String filename) throws IOException;
-static public ImageSurface createFromPNG (InputStream stream) throws IOException;
-public void writeToPNG (String filename) throws IOException;
-public void writeToPNG (OutputStream stream) throws IOException;
-</programlisting>
- <para>
- In many cases, it will be better to
- implement the filename version internally
- using the stream version, rather than building it on top of the
- filename version in C. The reason for this is that will
- naturally give a more standard handling of file errors for
- the language, as seen in the above Java example, where
- <methodname>createFromPNG()</methodname> is marked as raising
- an exception. Propagating exceptions from inside the callback
- function to the caller will pose a challenge to the language
- binding implementor, since an exception must not propagate
- through the Cairo code. A technique that will be useful in
- some cases is to catch the exception in the callback,
- store the exception object inside a structure pointed to by
- <parameter>closure</parameter>, and then rethrow it once
- the function returns.
- </para>
- <remark>
- I'm not sure how to handle this for
- <link
- linkend="cairo-pdf-surface-create-for-stream"><function>cairo_pdf_surface_create_for_stream()</function></link>.
- Other than keep a “exception to rethrow” thread-specific
- variable
- that is checked after <emphasis>every</emphasis> call to a Cairo
- function.
- </remark>
- </sect1>
- <sect1 id="bindings-errors">
- <title>Error handling</title>
- <para>
- The error handling approach in C for Cairo has multiple
- elements:
- </para>
- <itemizedlist>
- <listitem><para>
- When a method on an object fails, the object is put into
- an error state. Subsequent operations on the object do
- nothing. The status of the object can be queried with
- a function like <link
- linkend="cairo-status"><function>status()</function></link>.
- </para></listitem>
- <listitem><para>
- Constructors, rather than
- returning <constant>NULL</constant> on out-of-memory failure,
- return a special singleton object on which all
- operations do nothing. Retrieving the status of the
- singleton object returns <constant>CAIRO_STATUS_NO_MEMORY</constant>
- </para>
- <remark>
- Is this going to apply to
- <type>cairo_surface_t</type> as well?
- </remark>
- <remark>
- What about cairo_copy_path_data()? It's probably going to
- have to return <constant>NULL</constant>.
- </remark>
- </listitem>
- <listitem><para>
- Errors propagate from object to object. Setting a pattern
- in an out-of-memory state as the source of a
- <type>cairo_t</type> puts the type into an error state.
- </para></listitem>
- </itemizedlist>
- <remark>Much of the above is not yet implemented at the time of
- this writing</remark>
- <para>
- A language binding could copy the C approach, and for a
- language without exceptions, this is likely the right thing
- to do. However, for a language with exceptions, exposing
- a completely different style of error handling for cairo
- would be strange. So, instead, status should be checked
- after every call to cairo, and exceptions thrown as necessary.
- </para>
- <para>
- One problem that can arise with this, in languages
- where handling exceptions is mandatory (like Java), is that almost
- every cairo function can result in a status being set,
- usually because of an out-of-memory condition. This could make
- cairo hard to use. To resolve this problem, let's classify then
- cairo status codes:
- </para>
-<programlisting>
-/* Memory */
-CAIRO_STATUS_NO_MEMORY,
-
-/* Programmer error */
-CAIRO_STATUS_INVALID_RESTORE
-CAIRO_STATUS_INVALID_POP_GROUP
-CAIRO_STATUS_NO_CURRENT_POINT
-CAIRO_STATUS_INVALID_MATRIX
-CAIRO_STATUS_NO_TARGET_SURFACE
-CAIRO_STATUS_INVALID_STRING
-CAIRO_STATUS_SURFACE_FINISHED
-CAIRO_STATUS_BAD_NESTING
-
-/* Language binding implementation */
-CAIRO_STATUS_NULL_POINTER
-CAIRO_STATUS_INVALID_PATH_DATA
-CAIRO_STATUS_SURFACE_TYPE_MISMATCH
-
-/* Other */
-CAIRO_STATUS_READ_ERROR
-CAIRO_STATUS_WRITE_ERROR
-</programlisting>
- <para>
- If we look at these, the
- <constant>CAIRO_STATUS_NO_MEMORY</constant>
- should map to the native out-of-memory exception, which could
- happen at any point in any case. Most of the others indicate
- programmer error, and handling them in user code would be
- silly. These should be mapped into whatever the language uses
- for assertion failures, rather than errors that are normally
- handled. (In Java, a subclass of Error rather than Exception,
- perhaps.) And <constant>CAIRO_STATUS_READ_ERROR</constant>,
- and <constant>CAIRO_STATUS_WRITE_ERROR</constant> can occur
- only in very specific places. (In fact, as described
- in <xref linkend="bindings-streams"/>, these errors may be
- mapped into the language's native I/O error types.)
- So, there really aren't exceptions that the programmer must
- handle at most points in the Cairo API.
- </para>
- </sect1>
- <sect1 id="bindings-patterns">
- <title>Patterns</title>
- <para>
- The cairo C API allows for creating a number of different types
- of patterns. All of these different types of patterns map to
- <link
- linkend="cairo-pattern-t"><type>cairo_pattern_t</type></link>
- in C, but in an object oriented language, there should instead
- be a hierarchy of types. (The functions that should map to
- constructors or static methods for the various types are listed
- after the type, methods on that type are listed below. Note that
- cairo_pattern_create_rgb() and cairo_pattern_create_rgba()
- should not be overloaded with each other as a SolidPattern()
- constructor, but should appear as static methods instead. This
- is to maintain code clarity by making it clear how the arguments
- relate to color components.)
- </para>
- <programlisting>
-cairo_pattern_t
- <link linkend="cairo-pattern-set-matrix"><function>cairo_pattern_set_matrix()</function></link>
- <link linkend="cairo-pattern-get-matrix"><function>cairo_pattern_get_matrix()</function></link>
- cairo_solid_pattern_t (<link linkend="cairo-pattern-create-rgb"><function>cairo_pattern_create_rgb()</function></link> and <link linkend="cairo-pattern-create-rgba"><function>cairo_pattern_create_rgba()</function></link>)
- cairo_surface_pattern_t (<link linkend="cairo-pattern-create-for-surface"><function>cairo_pattern_create_for_surface()</function></link>)
- <link linkend="cairo-pattern-set-extend"><function>cairo_pattern_set_extend()</function></link>
- <link linkend="cairo-pattern-get-extend"><function>cairo_pattern_get_extend()</function></link>
- <link linkend="cairo-pattern-set-filter"><function>cairo_pattern_set_filter()</function></link>
- <link linkend="cairo-pattern-get-filter"><function>cairo_pattern_get_filter()</function></link>
- cairo_gradient_t
- <link linkend="cairo-pattern-add-color-stop-rgb"><function>cairo_pattern_add_color_stop_rgb()</function></link>
- <link linkend="cairo-pattern-add-color-stop-rgba"><function>cairo_pattern_add_color_stop_rgba()</function></link>
- cairo_linear_gradient_t (<link linkend="cairo-pattern-create-linear"><function>cairo_pattern_create_linear()</function></link>)
- cairo_radial_gradient_t (<link linkend="cairo-pattern-create-radial"><function>cairo_pattern_create_radial()</function></link>)
- cairo_mesh_t (<link linkend="cairo-pattern-create-mesh"><function>cairo_pattern_create_mesh()</function></link>)
- <link linkend="cairo-mesh-pattern-begin-patch"><function>cairo_mesh_pattern_begin_patch()</function></link>
- <link linkend="cairo-mesh-pattern-end-patch"><function>cairo_mesh_pattern_end_patch()</function></link>
- <link linkend="cairo-mesh-pattern-move-to"><function>cairo_mesh_pattern_move_to()</function></link>
- <link linkend="cairo-mesh-pattern-line-to"><function>cairo_mesh_pattern_line_to()</function></link>
- <link linkend="cairo-mesh-pattern-curve-to"><function>cairo_mesh_pattern_curve_to()</function></link>
- <link linkend="cairo-mesh-pattern-set-control-point"><function>cairo_mesh_pattern_set_control_point()</function></link>
- <link linkend="cairo-mesh-pattern-set-corner-color-rgb"><function>cairo_mesh_pattern_set_corner_color_rgb()</function></link>
- <link linkend="cairo-mesh-pattern-set-corner-color-rgba"><function>cairo_mesh_pattern_set_corner_color_rgba()</function></link>
- <link linkend="cairo-mesh-pattern-get-patch-count"><function>cairo_mesh_pattern_get_patch_count()</function></link>
- <link linkend="cairo-mesh-pattern-get-path"><function>cairo_mesh_pattern_get_path()</function></link>
- <link linkend="cairo-mesh-pattern-get-control-point"><function>cairo_mesh_pattern_get_control_point()</function></link>
- <link linkend="cairo-mesh-pattern-get-corner-color-rgba"><function>cairo_mesh_pattern_get_corner_color_rgba()</function></link>
- </programlisting>
- <para>
- </para>
- </sect1>
- <sect1 id="bindings-surfaces">
- <title>Surfaces</title>
- <para>
- Like patterns, surfaces, which use only the
- <link
- linkend="cairo-surface-t"><type>cairo_surface_t</type></link>
- type in the C API should be broken up into a hierarchy of types
- in a language binding.
- </para>
- <programlisting>
-cairo_surface_t
- cairo_image_surface_t
- cairo_atsui_surface_t
- cairo_win32_surface_t
- cairo_xlib_surface_t
- cairo_beos_surface_t
- </programlisting>
- <para>
- Unlike patterns, the constructors and methods on these types are
- clearly named, and can be trivially associated with the
- appropriate subtype. Many language bindings will want to avoid
- binding the platform-specific subtypes at all, since the
- methods on these types are not useful without passing in native
- C types. Unless there is a language binding for Xlib available,
- there is no way to represent a XLib <type>Display</type> * in
- that language.
- </para>
- <para>
- This doesn't mean that platform-specific surface types can't
- be used in a language binding that doesn't bind the constructor.
- A very common situation is to use a cairo language binding in
- combination with a binding for a higher level system like
- the <ulink url="http://www.gtk.org/">GTK+</ulink> widget
- toolkit. In such a situation, the higher level toolkit provides
- ways to get references to platform specific surfaces.
- </para>
- <para>
- The <link
- linkend="cairo-surface-set-user-data"><function>cairo_surface_set_user_data()</function></link>,
- and <link
- linkend="cairo-surface-get-user-data"><function>cairo_surface_get_user_data()</function></link>
- methods are provided for use in language bindings, and should
- not be directly exposed to applications. One example of the use
- of these functions in a language binding is creating a binding for:
- </para>
-<programlisting>
-cairo_surface_t *
-<link linkend="cairo-image-surface-create-for-data"><function>cairo_image_surface_create_for_data</function></link> (unsigned char *data,
- cairo_format_t format,
- int width,
- int height,
- int stride);
-</programlisting>
- <para>
- The memory block passed in for <parameter>data</parameter> must be
- kept around until the surface is destroyed, so the language
- binding must have some way of determining when that happens. The
- way to do this is to use the <parameter>destroy</parameter>
- argument to <function>cairo_surface_set_user_data()</function>.
- </para>
- <remark>
- Some languages may not have a suitable “pointer to a block of
- data” type to pass in for <parameter>data</parameter>. And even
- where a language does have such a type, the user will be
- frequently able to cause the backing store to be reallocated
- to a different location or truncated. Should we recommend a
- standard type name and binding for a buffer object here?
- </remark>
- </sect1>
- <sect1 id="bindings-fonts">
- <title>Fonts</title>
- <para>
- Fonts are once more an area where there is a hierarchy of types:
- </para>
-<programlisting>
-cairo_font_face_t
- cairo_ft_font_face_t
- cairo_win32_font_face_t
-cairo_scaled_font_t
- cairo_ft_scaled_font_t
- cairo_win32_scaled_font_t
-</programlisting>
- <para>
- The methods on the subtypes are, however, not useful without
- bindings for fontconfig and FreeType or for the Win32 GDI,
- so most language bindings will choose not to bind these
- types.
- </para>
- <para>
- The <link
- linkend="cairo-font-face-set-user-data"><function>cairo_font_face_set_user_data()</function></link>,
- and <link
- linkend="cairo-font-face-get-user-data"><function>cairo_font_face_get_user_data()</function></link>
- methods are provided for use in language bindings, and should
- not be directly exposed to applications.
- </para>
- </sect1>
- <sect1 id="bindings-path">
- <title>cairo_path_t</title>
- <para>
- The <link linkend="cairo-path-t"><type>cairo_path_t</type></link> type is one
- area in which most language bindings will differ significantly
- from the C API. The C API for <type>cairo_path_t</type> is
- designed for efficiency and to avoid auxiliary objects that
- would be have to be manually memory managed by the
- application. However,
- a language binding should not present <type>cairo_path_t</type> as an
- array, but rather as an opaque that can be iterated
- over. Different languages have quite different conventions for
- how iterators work, so it is impossible to give an exact
- specification for how this API should work, but the type names
- and methods should be similar to the language's mapping of the following:
- </para>
- <programlisting>
-typedef struct cairo_path_iterator cairo_path_iterator_t;
-typedef struct cairo_path_element cairo_path_element_t;
-
-cairo_path_iterator_t *
-cairo_path_get_iterator (cairo_path_t *path);
-
-cairo_bool_t
-cairo_path_iterator_has_next (cairo_path_iterator_t *iterator);
-
-cairo_path_element_t *
-cairo_path_iterator_next (cairo_path_iterator_t *iterator);
-
-cairo_path_element_type_t
-cairo_path_element_get_type (cairo_path_element_t *element);
-
-void
-cairo_path_element_get_point (cairo_path_element_t *element,
- int index,
- double *x,
- double *y);
- </programlisting>
- <para>
- The above is written using the Java conventions for
- iterators. To illustrate how the API for PathIterator might
- depend on the native iteration conventions of the API, examine
- three versions of the loop, first written in a hypothetical Java
- binding:
- </para>
- <programlisting>
-PathIterator iter = cr.copyPath().iterator();
-while (cr.hasNext()) {
- PathElement element = iter.next();
- if (element.getType() == PathElementType.MOVE_TO) {
- Point p = element.getPoint(0);
- doMoveTo (p.x, p.y);
- }
-}</programlisting>
- <para>
- And then in a hypothetical C++ binding:
- </para>
- <programlisting>
-Path path = cr.copyPath();
-for (PathIterator iter = path.begin(); iter != path.end(); iter++) {
- PathElement element = *iter;
- if (element.getType() == PathElementType.MOVE_TO) {
- Point p = element.getPoint(0);
- doMoveTo (p.x, p.y);
- }
-}</programlisting>
- <para>
- And then finally in a Python binding:
- </para>
-<programlisting>
-for element in cr.copy_path():
- if element.getType == cairo.PATH_ELEMENT_MOVE_TO:
- (x, y) = element.getPoint(0)
- doMoveTo (x, y);</programlisting>
- <para>
- While many of the API elements stay the same in the three
- examples, the exact iteration mechanism is quite different, to
- match how users of the language would expect to iterate over
- a container.
- </para>
- <para>
- You should not present an API for mutating or for creating new
- <type>cairo_path_t</type> objects. In the future, these
- guidelines may be extended to present an API for creating a
- <type>cairo_path_t</type> from scratch for use with
- <link
- linkend="cairo-append-path"><function>cairo_append_path()</function></link>
- but the current expectation is that <function>cairo_append_path()</function> will
- mostly be used with paths from
- <link
- linkend="cairo-append-path"><function>cairo_copy_path()</function></link>.
- </para>
- </sect1>
-</appendix>
-<!--
-Local variables:
-mode: sgml
-sgml-parent-document: ("cairo-docs.xml" "book" "book" "appendix")
-End:
--->