1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
|
<?xml version="1.0"?>
<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
<!ENTITY gdk-pixbuf "<application>gdk-pixbuf</application>">
<!ENTITY Imlib "<application>Imlib</application>">
]>
<appendix>
<title>Porting applications from &Imlib; to &gdk-pixbuf;</title>
<para>
This appendix contains the basic steps needed to port an
application that uses the &Imlib; library to use &gdk-pixbuf;
instead.
</para>
<note>
<para>
This appendix refers to version 1 of the &Imlib; library; this
discussion is not relevant to Imlib 2. Also, we discuss the
gdk_imlib API instead of the Xlib-based API.
</para>
</note>
<!-- Introduction -->
<sect1>
<title>Introduction</title>
<para>
Prior to the GNOME 1.2 platform, the &Imlib; library was the
preferred way of loading and rendering images in GNOME
applications. Unfortunately, &Imlib; has important design
limitations that make it hard to write efficient and highly
modular applications.
</para>
<para>
The &gdk-pixbuf; library was designed as a solution to
&Imlib;'s shortcomings. It provides a simple, orthogonal API
and convenience functions for the most common operations. In
addition, it supports full transparency information for
images, or alpha channel. More importantly, it has
well-defined semantics for memory management through the use
of reference counting; &Imlib; has an intractably complex
memory management mechanism and cache that will make your head
spin.
</para>
</sect1>
<!-- Differences between Imlib and gdk-pixbuf -->
<sect1>
<title>Differences between &Imlib; and &gdk-pixbuf;</title>
<para>
Generally, applications that use &Imlib; do not have to be
changed extensively to use &gdk-pixbuf;; its simple and
flexible API makes things easy. This section describes the
differences between &Imlib; and &gdk-pixbuf;; you should take
these into account when modifying your applications to use
&gdk-pixbuf;.
</para>
<!-- Initialization -->
<sect2>
<title>Initialization</title>
<para>
The &gdk-pixbuf; library does not need to be initialized.
</para>
<note>
<para>
In GNOME applications you normally don't need to
initialize &Imlib;, as <function>gnome_init()</function>
calls <function>gdk_imlib_init()</function> automatically.
</para>
</note>
</sect2>
<!-- Memory management -->
<sect2>
<title>Memory management</title>
<para>
The &gdk-pixbuf; library provides a simple, well-defined
memory management mechanism for images in the form of
reference counting. This makes it very convenient to use
for large-scale applications that need to share images
between different parts of the program. In stark contrast,
&Imlib; has a terribly complex mechanism of an image and
pixmap cache which makes it very hard for applications to
share image structures between different parts of the
program. Unfortunately this mechanism makes things very
prone to memory leaks and tricky bugs.
</para>
<para>
The basic principle in &gdk-pixbuf; is that when you obtain
a new <link linkend="GdkPixbuf">GdkPixbuf</link> structure,
it is created with an initial reference count of 1. When
another part of the program wants to keep a reference to the
pixbuf, it should call <function>g_object_ref()</function>;
this will increase the reference count by 1. When some part
of the program does not need to keep a reference to a pixbuf
anymore and wants to release the pixbuf, it should call
<function>g_object_unref()</function>; this will decrease
the reference count by 1. When the reference count drops to
zero, the pixbuf gets destroyed or
<emphasis>finalized</emphasis> and its memory is freed.
</para>
<para>
For applications that need to implement a cache of loaded
images, &gdk-pixbuf; provides a way to hook to the last
unreference operation of a pixbuf; instead of finalizing the
pixbuf, the user-installed hook can decide to keep it around
in a cache instead.
</para>
<para>
Finally, &gdk-pixbuf; does not provide a cache of rendered
pixmaps. This is unnecessary for most applications, since
the scaling and rendering functions are quite fast and
applications may need to use subtly different values each
time they call these functions, for example, to take into
account dithering and zooming offsets.
</para>
<para>
Most applications will simply need to call
<function>g_object_ref()</function> when they want to keep
an extra reference to a pixbuf, and then
<function>g_object_unref()</function> when they are done
with it.
</para>
</sect2>
<!-- The Rendering Process -->
<sect2>
<title>The Rendering Process</title>
<para>
The &gdk-pixbuf; library has the policy of always rendering
pixbufs to GDK drawables you provide; it will not create
them for you. This is in general more flexible than
&Imlib;'s policy of always creating a pixmap and making you
use that instead.
</para>
<para>
The disadvantage of always having a pixmap created for you
is that it wastes memory in the X server if you intend to
copy that rendered data onto another drawable, for example,
the final destination window or a temporary pixmap for
drawing. This is the most common case, unfortunately, so
the &Imlib; policy introduces unnecessary copying.
</para>
<para>
Also, &Imlib; can only render pixmaps that are the whole
size of the source image; you cannot render just a subset
region of the image. This is inconvenient for applications
that need to render small portions at a time, such as
applications that do scrolling. Since the whole image must
be rendered at a time, this can lead to performance and
memory usage problems.
</para>
<para>
The &gdk-pixbuf; library lets you render any rectangular
region from an image onto any drawable that you provide.
This lets the application have fine control the way images
are rendered.
</para>
</sect2>
</sect1>
<!-- Converting Applications to gdk-pixbuf -->
<sect1>
<title>Converting Applications to &gdk-pixbuf;</title>
<para>
This sections describes the actual changes you need to make in
an &Imlib; program to make it use &gdk-pixbuf; instead.
</para>
<!-- Image loading and creation -->
<sect2>
<title>Image loading and creation</title>
<para>
The &gdk-pixbuf; library can load image files synchronously
(i.e. with a single function call), create images from RGB
data in memory, and as a convenience, it can also create
images from inline XPM data.
</para>
<para>
To load an image file in a single function call, simply use
<function>gdk_pixbuf_new_from_file()</function>. Note that
this will make the program block until the whole file has
been read. This function effectively replaces
<function>gdk_imlib_load_image()</function>.
</para>
<para>
If you have RGB data in memory, you can use
<function>gdk_pixbuf_new_from_data()</function> to create a
pixbuf out of it; this is a replacement for
<function>gdk_imlib_create_image_from_data()</function>.
&gdk-pixbuf; does not copy the image data; it is up to you
to define the ownership policy by providing a destroy
notification function that will be called when the image
data needs to be freed. The function you provide can then
free the data or do something else, as appropriate.
</para>
<para>
As a convenience, you can use the
<function>gdk_pixbuf_new_from_xpm_data()</function> function
to create a pixbuf out of inline XPM data that was compiled
into your C program. This is a replacement for
<function>gdk_imlib_create_image_from_xpm_data()</function>.
</para>
<para>
After you have created a pixbuf, you can manipulate it in
any way you please and then finally call
<function>g_object_unref()</function> when you are done
with it. This can be thought of as a replacement for
<function>gdk_imlib_destroy_image()</function> but with much
cleaner semantics.
</para>
</sect2>
<!-- Rendering Images -->
<sect2>
<title>Rendering Images</title>
<para>
Applications that use &Imlib; must first call
<function>gdk_imlib_render()</function> to render the whole
image data onto a pixmap that &Imlib; creates. Then they
must copy that pixmap's data into the final destination for
the image.
</para>
<para>
In contrast, &gdk-pixbuf; provides convenience functions to
render arbitrary rectangular regions of an image onto a
drawable that your application provides. You can use
<function>gdk_draw_pixbuf()</function> to do this; having
your application provide the destination drawable and
specify an arbitrary region means your application has
complete control over the way images are rendered.
</para>
<para>
As a convenience, &gdk-pixbuf; also provides the
<function>gdk_pixbuf_render_pixmap_and_mask()</function>
function; this will create new pixmap and mask drawables for
a whole pixbuf and render the image data onto them. Only
trivially simple applications should find a use for this
function, since usually you want finer control of how things
are rendered.
</para>
</sect2>
<!-- Scaling Images -->
<sect2>
<title>Scaling Images</title>
<para>
&Imlib; lets you render scaled image data at the time you
call <function>gdk_imlib_render()</function>. Again, this
unfortunately scales and renders the whole image onto a new
pixmap.
</para>
<para>
&gdk-pixbuf; provides a number of functions that do scaling
of arbitrary regions of a source pixbuf onto a destination
one. These functions can also perform compositing
operations against the data in the destination pixbuf or
against a solid color or a colored checkerboard.
<footnote>
<para>
You can use a colored checkerboard as the background for
compositing when you want to provide a visual indication
that the image has partially opaque areas. This is
normally used in image editing and viewing programs.
</para>
<para>
Compositing against a single solid color is actually a
special case of a checkerboard; it simply uses checks of
the same color.
</para>
</footnote>
</para>
<para>
Very simple applications may find it sufficient to use
<function>gdk_pixbuf_scale_simple()</function> or
<function>gdk_pixbuf_composite_color_simple()</function>.
These functions scale the whole source image at a time and
create a new pixbuf with the result.
</para>
<para>
More sophisticated applications will need to use
<function>gdk_pixbuf_scale()</function>,
<function>gdk_pixbuf_composite()</function>, or
<function>gdk_pixbuf_composite_color()</function> instead.
These functions let you scale and composite an arbitrary
region of the source pixbuf onto a destination pixbuf that
you provide.
</para>
</sect2>
<!-- Getting Image Data from a Drawable -->
<sect2>
<title>Getting Image Data from a Drawable</title>
<para>
&Imlib; lets you create an image by fetching a drawable's
contents from the X server and converting those into RGB
data. This is done with the
<function>gdk_imlib_create_image_from_drawable()</function>
function.
</para>
<para>
&gdk-pixbuf; provides the
<function>gdk_pixbuf_get_from_drawable()</function> function
instead. It lets you specify a destination pixbuf instead
of always creating a new one for you.
</para>
</sect2>
</sect1>
</appendix>
<!--
Local variables:
mode: sgml
sgml-parent-document: ("gdk-pixbuf.sgml" "book" "book" "")
End:
-->
|