Skip to content

Commit 44ef8f7

Browse files
Extension of the Rect and IRect structs (#156)
* Extension of the Rect and IRect structs - Added round and intersect - Allow for the fact that mupdf may return invalid rectangles (x1<x0 or y1<y0) in case of empty result - Use mupdf C-library whenever possible (there is no union for fz_irect in mupdf-c) * Removed .clone() * refactor IRect::union, undo style changes * Added translate() operations
1 parent fd8e0dc commit 44ef8f7

File tree

1 file changed

+78
-55
lines changed

1 file changed

+78
-55
lines changed

src/rect.rs

Lines changed: 78 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -29,54 +29,66 @@ impl IRect {
2929
}
3030

3131
pub fn is_empty(&self) -> bool {
32-
self.x0 == self.x1 || self.y0 == self.y1
32+
self.x0 >= self.x1 || self.y0 >= self.y1
33+
}
34+
35+
pub fn is_valid(&self) -> bool {
36+
self.x0 <= self.x1 && self.y0 <= self.y1
3337
}
3438

3539
pub fn contains(&self, x: i32, y: i32) -> bool {
3640
if self.is_empty() {
37-
return false;
41+
false
42+
} else {
43+
x >= self.x0 && x < self.x1 && y >= self.y0 && y < self.y1
3844
}
39-
x >= self.x0 && x < self.x1 && y >= self.y0 && y < self.y1
4045
}
4146

4247
pub fn width(&self) -> i32 {
43-
self.x1 - self.x0
48+
if self.is_empty() {
49+
0
50+
} else {
51+
self.x1 - self.x0
52+
}
4453
}
4554

4655
pub fn height(&self) -> i32 {
47-
self.y1 - self.y0
56+
if self.is_empty() {
57+
0
58+
} else {
59+
self.y1 - self.y0
60+
}
4861
}
4962

5063
pub fn origin(&self) -> Point {
5164
Point::new(self.x0 as f32, self.y0 as f32)
5265
}
5366

5467
pub fn size(&self) -> Size {
55-
Size::new((self.x1 - self.x0) as f32, (self.y1 - self.y0) as f32)
68+
Size::new(self.width() as f32, self.height() as f32)
5669
}
5770

58-
pub fn r#union(&mut self, other: IRect) -> &mut Self {
59-
let IRect { x0, y0, x1, y1 } = other;
60-
if self.is_empty() {
61-
self.x0 = x0;
62-
self.y0 = y0;
63-
self.x1 = x1;
64-
self.y1 = y1;
71+
pub fn r#union(&self, other: IRect) -> Self {
72+
if !self.is_valid() {
73+
other
74+
} else if !other.is_valid() {
75+
*self
6576
} else {
66-
if x0 < self.x0 {
67-
self.x0 = x0;
68-
}
69-
if y0 < self.y0 {
70-
self.y0 = y0;
71-
}
72-
if x1 > self.x1 {
73-
self.x1 = x1;
74-
}
75-
if y1 > self.y1 {
76-
self.y1 = y1;
77+
IRect {
78+
x0: self.x0.min(other.x0),
79+
y0: self.y0.min(other.y0),
80+
x1: self.x1.max(other.x1),
81+
y1: self.y1.max(other.y1),
7782
}
7883
}
79-
self
84+
}
85+
86+
pub fn intersect(&self, rect: &Self) -> Self {
87+
unsafe { fz_intersect_irect((*self).into(), (*rect).into()) }.into()
88+
}
89+
90+
pub fn translate(&self, xoff: i32, yoff: i32) -> Self {
91+
unsafe { fz_translate_irect((*self).into(), xoff, yoff) }.into()
8092
}
8193
}
8294

@@ -100,6 +112,12 @@ impl From<IRect> for fz_irect {
100112
}
101113
}
102114

115+
impl From<Rect> for IRect {
116+
fn from(rect: Rect) -> Self {
117+
unsafe { fz_irect_from_rect(rect.into()) }.into()
118+
}
119+
}
120+
103121
/// A rectangle represented by two diagonally opposite corners at arbitrary coordinates
104122
#[derive(Debug, Clone, Copy, PartialEq, Default)]
105123
pub struct Rect {
@@ -122,54 +140,47 @@ impl Rect {
122140
}
123141

124142
pub fn is_empty(&self) -> bool {
125-
self.x0 == self.x1 || self.y0 == self.y1
143+
self.x0 >= self.x1 || self.y0 >= self.y1
144+
}
145+
146+
pub fn is_valid(&self) -> bool {
147+
self.x0 <= self.x1 && self.y0 <= self.y1
126148
}
127149

128150
pub fn contains(&self, x: f32, y: f32) -> bool {
129151
if self.is_empty() {
130-
return false;
152+
false
153+
} else {
154+
x >= self.x0 && x < self.x1 && y >= self.y0 && y < self.y1
131155
}
132-
x >= self.x0 && x < self.x1 && y >= self.y0 && y < self.y1
133156
}
134157

135158
pub fn width(&self) -> f32 {
136-
self.x1 - self.x0
159+
if self.is_empty() {
160+
0.0
161+
} else {
162+
self.x1 - self.x0
163+
}
137164
}
138165

139166
pub fn height(&self) -> f32 {
140-
self.y1 - self.y0
167+
if self.is_empty() {
168+
0.0
169+
} else {
170+
self.y1 - self.y0
171+
}
141172
}
142173

143174
pub fn origin(&self) -> Point {
144175
Point::new(self.x0, self.y0)
145176
}
146177

147178
pub fn size(&self) -> Size {
148-
Size::new(self.x1 - self.x0, self.y1 - self.y0)
179+
Size::new(self.width(), self.height())
149180
}
150181

151-
pub fn r#union(&mut self, other: Rect) -> &mut Self {
152-
let Rect { x0, y0, x1, y1 } = other;
153-
if self.is_empty() {
154-
self.x0 = x0;
155-
self.y0 = y0;
156-
self.x1 = x1;
157-
self.y1 = y1;
158-
} else {
159-
if x0 < self.x0 {
160-
self.x0 = x0;
161-
}
162-
if y0 < self.y0 {
163-
self.y0 = y0;
164-
}
165-
if x1 > self.x1 {
166-
self.x1 = x1;
167-
}
168-
if y1 > self.y1 {
169-
self.y1 = y1;
170-
}
171-
}
172-
self
182+
pub fn r#union(&self, other: &Self) -> Self {
183+
unsafe { fz_union_rect((*self).into(), (*other).into()) }.into()
173184
}
174185

175186
pub fn adjust_for_stroke(&self, stroke: &StrokeState, ctm: &Matrix) -> Result<Self, Error> {
@@ -185,8 +196,20 @@ impl Rect {
185196
.map(fz_rect::into)
186197
}
187198

188-
pub fn transform(self, matrix: &Matrix) -> Self {
189-
unsafe { fz_transform_rect(self.into(), matrix.into()) }.into()
199+
pub fn transform(&self, matrix: &Matrix) -> Self {
200+
unsafe { fz_transform_rect((*self).into(), matrix.into()) }.into()
201+
}
202+
203+
pub fn round(&self) -> IRect {
204+
unsafe { fz_round_rect((*self).into()) }.into()
205+
}
206+
207+
pub fn intersect(&self, rect: &Self) -> Self {
208+
unsafe { fz_intersect_rect((*self).into(), (*rect).into()) }.into()
209+
}
210+
211+
pub fn translate(&self, xoff: f32, yoff: f32) -> Self {
212+
unsafe { fz_translate_rect((*self).into(), xoff, yoff) }.into()
190213
}
191214
}
192215

0 commit comments

Comments
 (0)