diff options
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.xml | 745 |
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, &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, &x, &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: ---> |