⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 language-bindings.xml

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 XML
📖 第 1 页 / 共 2 页
字号:
    <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-callback"><function>cairo_pdf_surface_create_for_callback()</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_RESTORECAIRO_STATUS_INVALID_POP_GROUPCAIRO_STATUS_NO_CURRENT_POINTCAIRO_STATUS_INVALID_MATRIXCAIRO_STATUS_NO_TARGET_SURFACECAIRO_STATUS_INVALID_STRINGCAIRO_STATUS_SURFACE_FINISHEDCAIRO_STATUS_BAD_NESTING/* Language binding implementation */CAIRO_STATUS_NULL_POINTERCAIRO_STATUS_INVALID_PATH_DATACAIRO_STATUS_SURFACE_TYPE_MISMATCH/* Other */      CAIRO_STATUS_READ_ERRORCAIRO_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 for the various types are listed after the type,      methods on that type are listed below)    </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   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>)    </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_tcairo_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_tcairo_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_tcairo_path_element_get_type (cairo_path_element_t *element);      voidcairo_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: sgmlsgml-parent-document: ("cairo-docs.xml" "book" "book" "appendix")End:-->

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -