1use gdk_pixbuf_sys;
6use gio;
7use glib;
8use glib::object::IsA;
9use glib::object::ObjectType as ObjectType_;
10use glib::translate::*;
11use glib::GString;
12use glib::StaticType;
13use glib::Value;
14use gobject_sys;
15use std::fmt;
16use std::ptr;
17use Colorspace;
18use Error;
19use InterpType;
20use PixbufFormat;
21use PixbufRotation;
22
23glib_wrapper! {
24 pub struct Pixbuf(Object<gdk_pixbuf_sys::GdkPixbuf, PixbufClass>) @implements gio::Icon, gio::LoadableIcon;
25
26 match fn {
27 get_type => || gdk_pixbuf_sys::gdk_pixbuf_get_type(),
28 }
29}
30
31impl Pixbuf {
32 pub fn new(
33 colorspace: Colorspace,
34 has_alpha: bool,
35 bits_per_sample: i32,
36 width: i32,
37 height: i32,
38 ) -> Option<Pixbuf> {
39 unsafe {
40 from_glib_full(gdk_pixbuf_sys::gdk_pixbuf_new(
41 colorspace.to_glib(),
42 has_alpha.to_glib(),
43 bits_per_sample,
44 width,
45 height,
46 ))
47 }
48 }
49
50 #[cfg(any(feature = "v2_32", feature = "dox"))]
51 pub fn new_from_bytes(
52 data: &glib::Bytes,
53 colorspace: Colorspace,
54 has_alpha: bool,
55 bits_per_sample: i32,
56 width: i32,
57 height: i32,
58 rowstride: i32,
59 ) -> Pixbuf {
60 unsafe {
61 from_glib_full(gdk_pixbuf_sys::gdk_pixbuf_new_from_bytes(
62 data.to_glib_none().0,
63 colorspace.to_glib(),
64 has_alpha.to_glib(),
65 bits_per_sample,
66 width,
67 height,
68 rowstride,
69 ))
70 }
71 }
72
73 #[cfg_attr(feature = "v2_32", deprecated)]
78 pub fn new_from_inline(data: &[u8], copy_pixels: bool) -> Result<Pixbuf, Error> {
79 let data_length = data.len() as i32;
80 unsafe {
81 let mut error = ptr::null_mut();
82 let ret = gdk_pixbuf_sys::gdk_pixbuf_new_from_inline(
83 data_length,
84 data.to_glib_none().0,
85 copy_pixels.to_glib(),
86 &mut error,
87 );
88 if error.is_null() {
89 Ok(from_glib_full(ret))
90 } else {
91 Err(from_glib_full(error))
92 }
93 }
94 }
95
96 pub fn new_from_resource(resource_path: &str) -> Result<Pixbuf, Error> {
97 unsafe {
98 let mut error = ptr::null_mut();
99 let ret = gdk_pixbuf_sys::gdk_pixbuf_new_from_resource(
100 resource_path.to_glib_none().0,
101 &mut error,
102 );
103 if error.is_null() {
104 Ok(from_glib_full(ret))
105 } else {
106 Err(from_glib_full(error))
107 }
108 }
109 }
110
111 pub fn new_from_resource_at_scale(
112 resource_path: &str,
113 width: i32,
114 height: i32,
115 preserve_aspect_ratio: bool,
116 ) -> Result<Pixbuf, Error> {
117 unsafe {
118 let mut error = ptr::null_mut();
119 let ret = gdk_pixbuf_sys::gdk_pixbuf_new_from_resource_at_scale(
120 resource_path.to_glib_none().0,
121 width,
122 height,
123 preserve_aspect_ratio.to_glib(),
124 &mut error,
125 );
126 if error.is_null() {
127 Ok(from_glib_full(ret))
128 } else {
129 Err(from_glib_full(error))
130 }
131 }
132 }
133
134 pub fn new_from_stream<P: IsA<gio::InputStream>, Q: IsA<gio::Cancellable>>(
135 stream: &P,
136 cancellable: Option<&Q>,
137 ) -> Result<Pixbuf, Error> {
138 unsafe {
139 let mut error = ptr::null_mut();
140 let ret = gdk_pixbuf_sys::gdk_pixbuf_new_from_stream(
141 stream.as_ref().to_glib_none().0,
142 cancellable.map(|p| p.as_ref()).to_glib_none().0,
143 &mut error,
144 );
145 if error.is_null() {
146 Ok(from_glib_full(ret))
147 } else {
148 Err(from_glib_full(error))
149 }
150 }
151 }
152
153 pub fn new_from_stream_at_scale<P: IsA<gio::InputStream>, Q: IsA<gio::Cancellable>>(
154 stream: &P,
155 width: i32,
156 height: i32,
157 preserve_aspect_ratio: bool,
158 cancellable: Option<&Q>,
159 ) -> Result<Pixbuf, Error> {
160 unsafe {
161 let mut error = ptr::null_mut();
162 let ret = gdk_pixbuf_sys::gdk_pixbuf_new_from_stream_at_scale(
163 stream.as_ref().to_glib_none().0,
164 width,
165 height,
166 preserve_aspect_ratio.to_glib(),
167 cancellable.map(|p| p.as_ref()).to_glib_none().0,
168 &mut error,
169 );
170 if error.is_null() {
171 Ok(from_glib_full(ret))
172 } else {
173 Err(from_glib_full(error))
174 }
175 }
176 }
177
178 pub fn new_from_xpm_data(data: &[&str]) -> Pixbuf {
179 unsafe {
180 from_glib_full(gdk_pixbuf_sys::gdk_pixbuf_new_from_xpm_data(
181 data.to_glib_none().0,
182 ))
183 }
184 }
185
186 pub fn add_alpha(&self, substitute_color: bool, r: u8, g: u8, b: u8) -> Option<Pixbuf> {
187 unsafe {
188 from_glib_full(gdk_pixbuf_sys::gdk_pixbuf_add_alpha(
189 self.to_glib_none().0,
190 substitute_color.to_glib(),
191 r,
192 g,
193 b,
194 ))
195 }
196 }
197
198 pub fn apply_embedded_orientation(&self) -> Option<Pixbuf> {
199 unsafe {
200 from_glib_full(gdk_pixbuf_sys::gdk_pixbuf_apply_embedded_orientation(
201 self.to_glib_none().0,
202 ))
203 }
204 }
205
206 pub fn composite(
207 &self,
208 dest: &Pixbuf,
209 dest_x: i32,
210 dest_y: i32,
211 dest_width: i32,
212 dest_height: i32,
213 offset_x: f64,
214 offset_y: f64,
215 scale_x: f64,
216 scale_y: f64,
217 interp_type: InterpType,
218 overall_alpha: i32,
219 ) {
220 unsafe {
221 gdk_pixbuf_sys::gdk_pixbuf_composite(
222 self.to_glib_none().0,
223 dest.to_glib_none().0,
224 dest_x,
225 dest_y,
226 dest_width,
227 dest_height,
228 offset_x,
229 offset_y,
230 scale_x,
231 scale_y,
232 interp_type.to_glib(),
233 overall_alpha,
234 );
235 }
236 }
237
238 pub fn composite_color(
239 &self,
240 dest: &Pixbuf,
241 dest_x: i32,
242 dest_y: i32,
243 dest_width: i32,
244 dest_height: i32,
245 offset_x: f64,
246 offset_y: f64,
247 scale_x: f64,
248 scale_y: f64,
249 interp_type: InterpType,
250 overall_alpha: i32,
251 check_x: i32,
252 check_y: i32,
253 check_size: i32,
254 color1: u32,
255 color2: u32,
256 ) {
257 unsafe {
258 gdk_pixbuf_sys::gdk_pixbuf_composite_color(
259 self.to_glib_none().0,
260 dest.to_glib_none().0,
261 dest_x,
262 dest_y,
263 dest_width,
264 dest_height,
265 offset_x,
266 offset_y,
267 scale_x,
268 scale_y,
269 interp_type.to_glib(),
270 overall_alpha,
271 check_x,
272 check_y,
273 check_size,
274 color1,
275 color2,
276 );
277 }
278 }
279
280 pub fn composite_color_simple(
281 &self,
282 dest_width: i32,
283 dest_height: i32,
284 interp_type: InterpType,
285 overall_alpha: i32,
286 check_size: i32,
287 color1: u32,
288 color2: u32,
289 ) -> Option<Pixbuf> {
290 unsafe {
291 from_glib_full(gdk_pixbuf_sys::gdk_pixbuf_composite_color_simple(
292 self.to_glib_none().0,
293 dest_width,
294 dest_height,
295 interp_type.to_glib(),
296 overall_alpha,
297 check_size,
298 color1,
299 color2,
300 ))
301 }
302 }
303
304 pub fn copy(&self) -> Option<Pixbuf> {
305 unsafe { from_glib_full(gdk_pixbuf_sys::gdk_pixbuf_copy(self.to_glib_none().0)) }
306 }
307
308 pub fn copy_area(
309 &self,
310 src_x: i32,
311 src_y: i32,
312 width: i32,
313 height: i32,
314 dest_pixbuf: &Pixbuf,
315 dest_x: i32,
316 dest_y: i32,
317 ) {
318 unsafe {
319 gdk_pixbuf_sys::gdk_pixbuf_copy_area(
320 self.to_glib_none().0,
321 src_x,
322 src_y,
323 width,
324 height,
325 dest_pixbuf.to_glib_none().0,
326 dest_x,
327 dest_y,
328 );
329 }
330 }
331
332 #[cfg(any(feature = "v2_36", feature = "dox"))]
333 pub fn copy_options(&self, dest_pixbuf: &Pixbuf) -> bool {
334 unsafe {
335 from_glib(gdk_pixbuf_sys::gdk_pixbuf_copy_options(
336 self.to_glib_none().0,
337 dest_pixbuf.to_glib_none().0,
338 ))
339 }
340 }
341
342 pub fn fill(&self, pixel: u32) {
343 unsafe {
344 gdk_pixbuf_sys::gdk_pixbuf_fill(self.to_glib_none().0, pixel);
345 }
346 }
347
348 pub fn flip(&self, horizontal: bool) -> Option<Pixbuf> {
349 unsafe {
350 from_glib_full(gdk_pixbuf_sys::gdk_pixbuf_flip(
351 self.to_glib_none().0,
352 horizontal.to_glib(),
353 ))
354 }
355 }
356
357 pub fn get_bits_per_sample(&self) -> i32 {
358 unsafe { gdk_pixbuf_sys::gdk_pixbuf_get_bits_per_sample(self.to_glib_none().0) }
359 }
360
361 pub fn get_byte_length(&self) -> usize {
362 unsafe { gdk_pixbuf_sys::gdk_pixbuf_get_byte_length(self.to_glib_none().0) }
363 }
364
365 pub fn get_colorspace(&self) -> Colorspace {
366 unsafe {
367 from_glib(gdk_pixbuf_sys::gdk_pixbuf_get_colorspace(
368 self.to_glib_none().0,
369 ))
370 }
371 }
372
373 pub fn get_has_alpha(&self) -> bool {
374 unsafe {
375 from_glib(gdk_pixbuf_sys::gdk_pixbuf_get_has_alpha(
376 self.to_glib_none().0,
377 ))
378 }
379 }
380
381 pub fn get_height(&self) -> i32 {
382 unsafe { gdk_pixbuf_sys::gdk_pixbuf_get_height(self.to_glib_none().0) }
383 }
384
385 pub fn get_n_channels(&self) -> i32 {
386 unsafe { gdk_pixbuf_sys::gdk_pixbuf_get_n_channels(self.to_glib_none().0) }
387 }
388
389 pub fn get_option(&self, key: &str) -> Option<GString> {
390 unsafe {
391 from_glib_none(gdk_pixbuf_sys::gdk_pixbuf_get_option(
392 self.to_glib_none().0,
393 key.to_glib_none().0,
394 ))
395 }
396 }
397
398 pub fn get_rowstride(&self) -> i32 {
404 unsafe { gdk_pixbuf_sys::gdk_pixbuf_get_rowstride(self.to_glib_none().0) }
405 }
406
407 pub fn get_width(&self) -> i32 {
408 unsafe { gdk_pixbuf_sys::gdk_pixbuf_get_width(self.to_glib_none().0) }
409 }
410
411 pub fn new_subpixbuf(&self, src_x: i32, src_y: i32, width: i32, height: i32) -> Option<Pixbuf> {
412 unsafe {
413 from_glib_full(gdk_pixbuf_sys::gdk_pixbuf_new_subpixbuf(
414 self.to_glib_none().0,
415 src_x,
416 src_y,
417 width,
418 height,
419 ))
420 }
421 }
422
423 #[cfg(any(feature = "v2_32", feature = "dox"))]
424 pub fn read_pixel_bytes(&self) -> Option<glib::Bytes> {
425 unsafe {
426 from_glib_full(gdk_pixbuf_sys::gdk_pixbuf_read_pixel_bytes(
427 self.to_glib_none().0,
428 ))
429 }
430 }
431
432 #[cfg(any(feature = "v2_36", feature = "dox"))]
433 pub fn remove_option(&self, key: &str) -> bool {
434 unsafe {
435 from_glib(gdk_pixbuf_sys::gdk_pixbuf_remove_option(
436 self.to_glib_none().0,
437 key.to_glib_none().0,
438 ))
439 }
440 }
441
442 pub fn rotate_simple(&self, angle: PixbufRotation) -> Option<Pixbuf> {
443 unsafe {
444 from_glib_full(gdk_pixbuf_sys::gdk_pixbuf_rotate_simple(
445 self.to_glib_none().0,
446 angle.to_glib(),
447 ))
448 }
449 }
450
451 pub fn saturate_and_pixelate(&self, dest: &Pixbuf, saturation: f32, pixelate: bool) {
452 unsafe {
453 gdk_pixbuf_sys::gdk_pixbuf_saturate_and_pixelate(
454 self.to_glib_none().0,
455 dest.to_glib_none().0,
456 saturation,
457 pixelate.to_glib(),
458 );
459 }
460 }
461
462 pub fn scale(
511 &self,
512 dest: &Pixbuf,
513 dest_x: i32,
514 dest_y: i32,
515 dest_width: i32,
516 dest_height: i32,
517 offset_x: f64,
518 offset_y: f64,
519 scale_x: f64,
520 scale_y: f64,
521 interp_type: InterpType,
522 ) {
523 unsafe {
524 gdk_pixbuf_sys::gdk_pixbuf_scale(
525 self.to_glib_none().0,
526 dest.to_glib_none().0,
527 dest_x,
528 dest_y,
529 dest_width,
530 dest_height,
531 offset_x,
532 offset_y,
533 scale_x,
534 scale_y,
535 interp_type.to_glib(),
536 );
537 }
538 }
539
540 pub fn scale_simple(
541 &self,
542 dest_width: i32,
543 dest_height: i32,
544 interp_type: InterpType,
545 ) -> Option<Pixbuf> {
546 unsafe {
547 from_glib_full(gdk_pixbuf_sys::gdk_pixbuf_scale_simple(
548 self.to_glib_none().0,
549 dest_width,
550 dest_height,
551 interp_type.to_glib(),
552 ))
553 }
554 }
555
556 pub fn set_option(&self, key: &str, value: &str) -> bool {
557 unsafe {
558 from_glib(gdk_pixbuf_sys::gdk_pixbuf_set_option(
559 self.to_glib_none().0,
560 key.to_glib_none().0,
561 value.to_glib_none().0,
562 ))
563 }
564 }
565
566 pub fn get_property_pixel_bytes(&self) -> Option<glib::Bytes> {
567 unsafe {
568 let mut value = Value::from_type(<glib::Bytes as StaticType>::static_type());
569 gobject_sys::g_object_get_property(
570 self.as_ptr() as *mut gobject_sys::GObject,
571 b"pixel-bytes\0".as_ptr() as *const _,
572 value.to_glib_none_mut().0,
573 );
574 value.get()
575 }
576 }
577
578 #[cfg(any(feature = "v2_36_8", feature = "dox"))]
587 pub fn calculate_rowstride(
588 colorspace: Colorspace,
589 has_alpha: bool,
590 bits_per_sample: i32,
591 width: i32,
592 height: i32,
593 ) -> i32 {
594 unsafe {
595 gdk_pixbuf_sys::gdk_pixbuf_calculate_rowstride(
596 colorspace.to_glib(),
597 has_alpha.to_glib(),
598 bits_per_sample,
599 width,
600 height,
601 )
602 }
603 }
604
605 pub fn get_formats() -> Vec<PixbufFormat> {
606 unsafe {
607 FromGlibPtrContainer::from_glib_container(gdk_pixbuf_sys::gdk_pixbuf_get_formats())
608 }
609 }
610}
611
612impl fmt::Display for Pixbuf {
613 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
614 write!(f, "Pixbuf")
615 }
616}