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
//! Helper functions for manipulating Pixman regions from the Pixman library.
//!
//! [The Pixman library](http://www.pixman.org/) is a library for pixel
//! manipulation.
use std::mem;
use libc::{c_double, c_float, c_int};
use wlroots_sys::{pixman_region32_t, pixman_region32_init, wlr_region_scale,
wlr_region_transform, wlr_region_expand,
wlr_region_rotated_bounds, wlr_region_confine,
wl_output_transform};
/// A thin wrapper around a 32 bit Pixman region.
pub struct PixmanRegion32 {
pub region: pixman_region32_t
}
impl PixmanRegion32 {
/// Construct a new Pixman region.
pub fn new() -> Self {
unsafe {
// NOTE This is safe because the init function properly
// sets up the fields.
let mut region: pixman_region32_t = mem::uninitialized();
pixman_region32_init(&mut region);
PixmanRegion32 { region }
}
}
/// Scales a region, ie. multiplies all its coordinates by `scale`
/// and write out the result to `dest`.
///
/// The resulting coordinates are rounded up or down so that the new region
/// is at least as big as the original one.
pub fn scale(&self, dest: &mut PixmanRegion32, scale: c_float) {
unsafe {
let region_ptr = &self.region as *const _ as *mut _;
wlr_region_scale(&mut dest.region, region_ptr, scale);
}
}
/// Applies a transform to a region inside a box of size `width` x `height`.
/// Writes the result to `dest`.
pub fn transform(&self,
dest: &mut PixmanRegion32,
transform: wl_output_transform,
width: c_int,
height: c_int) {
unsafe {
let region_ptr = &self.region as *const _ as *mut _;
wlr_region_transform(&mut dest.region,
region_ptr,
transform,
width,
height);
}
}
/// Expands the region of `distance`. If `distance` is negative, it shrinks the
/// region. Writes the result to the `dest`.
pub fn expand(&self,
dest: &mut PixmanRegion32,
distance: c_int) {
unsafe {
let region_ptr = &self.region as *const _ as *mut _;
wlr_region_expand(&mut dest.region, region_ptr, distance);
}
}
/// Builds the smallest possible region that contains the region rotated
/// about the point in output space (ox, oy).
/// Writes the result to the `dest`.
pub fn rotated_bounds(&self,
dest: &mut PixmanRegion32,
rotation: c_float,
ox: c_int,
oy: c_int) {
unsafe {
let region_ptr = &self.region as *const _ as *mut _;
wlr_region_rotated_bounds(&mut dest.region,
region_ptr,
rotation,
ox,
oy);
}
}
/// Confines a region to the box formed by the points.
///
/// If it could not be confined by the points it will return an error.
pub fn confine(&mut self,
x1: c_double,
y1: c_double,
x2: c_double,
y2: c_double)
-> Result<(c_double, c_double), ()> {
unsafe {
let (mut x_out, mut y_out) = (0.0, 0.0);
let res = wlr_region_confine(&mut self.region,
x1,
y1,
x2,
y2,
&mut x_out,
&mut y_out);
match res {
true => Ok((x_out, y_out)),
false => Err(())
}
}
}
}