breadx_image/
subimage.rs

1//               Copyright John Nunley, 2022.
2// Distributed under the Boost Software License, Version 1.0.
3//       (See accompanying file LICENSE or copy at
4//         https://www.boost.org/LICENSE_1_0.txt)
5
6use super::Image;
7use breadx::{
8    display::{from_void_request, RawRequest},
9    protocol::xproto::{Drawable, Gcontext},
10};
11
12impl<Storage: AsRef<[u8]> + ?Sized> Image<Storage> {
13    /// Get a `PutImageRequest` that could be used to send a part of this
14    /// image to the display.
15    #[allow(clippy::too_many_arguments)]
16    pub fn put_subimage_request<R>(
17        &self,
18        drawable: impl Into<Drawable>,
19        gc: impl Into<Gcontext>,
20        src_x: usize,
21        src_y: usize,
22        width: usize,
23        height: usize,
24        dst_x: i16,
25        dst_y: i16,
26        discard_reply: bool,
27        raw_request_handler: impl FnOnce(RawRequest<'_, '_>) -> R,
28    ) -> R {
29        let drawable = drawable.into();
30        let gc = gc.into();
31
32        // simple case: src_x/y are 0, and width/height are equal to image's
33        // then this degenerates into a put_image_request() call
34        if (src_x, src_y, width, height) == (0, 0, self.width as usize, self.height as usize) {
35            let pir = self.put_image_request(drawable, gc, dst_x, dst_y);
36            return from_void_request(pir, discard_reply, raw_request_handler);
37        }
38
39        // optimized case: if we are a ZPixmap image, and the first pixel of each row of a theoretical
40        // cropped image is on a byte boundary, then we can create a raw request uses I/O slices to
41        // contain each row of the cropped image. this ensures no actual byte copying is done, which
42        // in the best case can save a lot of time.
43
44        // TODO
45
46        // degenerate case: no optimization is possible, this simplifies down to
47        // crop() then put_image_request()
48        let cropped = self.crop(src_x, src_y, width, height);
49        let pir = cropped.put_image_request(drawable, gc, dst_x, dst_y);
50        from_void_request(pir, discard_reply, raw_request_handler)
51    }
52}