add more methods and operations to Size_
MODIFY
src/manual/core/size.rs
src/manual/core/size.rs
+use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
+
+use num::{NumCast, ToPrimitive, Zero};
+
+use crate::core::{Point_, ValidPointType};
+
valid_types!(ValidSizeType, i32, i64, f32, f64);
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq)]
+/// [docs.opencv.org](https://docs.opencv.org/master/d6/d50/classcv_1_1Size__.html)
pub struct Size_<T: ValidSizeType> {
pub width: T,
pub height: T,
}
impl<T: ValidSizeType> Size_<T> {
+ #[inline]
pub fn new(width: T, height: T) -> Self {
Self { width, height }
}
+
+ #[inline]
+ pub fn from_point(pt: Point_<T>) -> Self where T: ValidPointType {
+ Self { width: pt.x, height: pt.y }
+ }
+
+ #[inline]
+ pub fn area(self) -> T where T: Mul<Output=T> {
+ self.width * self.height
+ }
+
+ #[inline]
+ pub fn empty(self) -> bool where T: Zero + PartialOrd {
+ self.width <= T::zero() || self.height <= T::zero()
+ }
+
+ #[inline]
+ pub fn to<D: ValidSizeType + NumCast>(self) -> Option<Size_<D>> where T: ToPrimitive {
+ Some(Size_ { width: D::from(self.width)?, height: D::from(self.height)? })
+ }
}
impl<T: ValidSizeType + Default> Default for Size_<T> {
@@ -18,3 +46,91 @@ impl<T: ValidSizeType + Default> Default for Size_<T> {
Self { width: Default::default(), height: Default::default() }
}
}
+
+impl<T> Add for Size_<T>
+ where
+ T: ValidSizeType + AddAssign,
+{
+ type Output = Size_<T>;
+
+ fn add(mut self, rhs: Size_<T>) -> Self::Output {
+ self += rhs;
+ self
+ }
+}
+
+impl<T> Sub for Size_<T>
+ where
+ T: ValidSizeType + SubAssign,
+{
+ type Output = Size_<T>;
+
+ fn sub(mut self, rhs: Size_<T>) -> Self::Output {
+ self -= rhs;
+ self
+ }
+}
+
+impl<T> Mul<T> for Size_<T>
+ where
+ T: ValidSizeType + MulAssign
+{
+ type Output = Size_<T>;
+
+ fn mul(mut self, rhs: T) -> Self::Output {
+ self *= rhs;
+ self
+ }
+}
+
+impl<T> Div<T> for Size_<T>
+ where
+ T: ValidSizeType + DivAssign
+{
+ type Output = Size_<T>;
+
+ fn div(mut self, rhs: T) -> Self::Output {
+ self /= rhs;
+ self
+ }
+}
+
+impl<T> AddAssign for Size_<T>
+ where
+ T: ValidSizeType + AddAssign,
+{
+ fn add_assign(&mut self, rhs: Size_<T>) {
+ self.width += rhs.width;
+ self.height += rhs.height;
+ }
+}
+
+impl<T> SubAssign for Size_<T>
+ where
+ T: ValidSizeType + SubAssign,
+{
+ fn sub_assign(&mut self, rhs: Size_<T>) {
+ self.width -= rhs.width;
+ self.height -= rhs.height;
+ }
+}
+
+impl<T> MulAssign<T> for Size_<T>
+ where
+ T: ValidSizeType + MulAssign
+{
+ fn mul_assign(&mut self, rhs: T) {
+ self.width *= rhs;
+ self.height *= rhs;
+ }
+}
+
+impl<T> DivAssign<T> for Size_<T>
+ where
+ T: ValidSizeType + DivAssign
+{
+ fn div_assign(&mut self, rhs: T) {
+ self.width /= rhs;
+ self.height /= rhs;
+ }
+}

MODIFY
tests/rect.rs
tests/rect.rs
@@ -85,7 +85,9 @@ fn rect_constructor() {
fn rect_methods() {
let mut rect = Rect2d::new(10., 20., 100., 200.);
assert!(!rect.empty());
+ assert_eq!(rect.empty(), rect.size().empty());
assert_eq!(20000., rect.area());
+ assert_eq!(rect.area(), rect.size().area());
assert_eq!(Point2d::new(10., 20.), rect.tl());
assert_eq!(Point2d::new(110., 220.), rect.br());
assert_eq!(Size2d::new(100., 200.), rect.size());
@@ -93,6 +95,7 @@ fn rect_methods() {
assert!(!rect.contains(Point2d::new(120., 120.)));
rect.width = 0.;
assert!(rect.empty());
+ assert_eq!(rect.empty(), rect.size().empty());
}
#[test]

ADD
tests/size.rs
+use opencv::core::{Point2d, Size, Size2d, Size2f, Size2i};
+
+#[test]
+fn size_add() {
+ let src = Size::new(0, 0);
+
+ let res = Size::new(50, 50);
+ {
+ let src = src.clone();
+ let out = src + Size::new(50, 50);
+ assert_eq!(out, res);
+ }
+
+ {
+ let mut out = src.clone();
+ out += Size::new(50, 50);
+ assert_eq!(out, res);
+ }
+}
+
+#[test]
+fn size_sub() {
+ let src = Size::new(50, 50);
+
+ let res = Size::new(25, 25);
+ {
+ let src = src.clone();
+ let out = src - Size::new(25, 25);
+ assert_eq!(out, res);
+ }
+
+ {
+ let mut out = src.clone();
+ out -= Size::new(25, 25);
+ assert_eq!(out, res);
+ }
+}
+
+#[test]
+fn size_mul() {
+ let src = Size2f::new(50., 50.);
+
+ let res = Size2f::new(100., 100.);
+ {
+ let src = src.clone();
+ let out = src * 2.;
+ assert_eq!(out, res);
+ }
+
+ {
+ let mut out = src.clone();
+ out *= 2.;
+ assert_eq!(out, res);
+ }
+}
+
+#[test]
+fn size_div() {
+ let src = Size::new(50, 50);
+
+ let res = Size::new(25, 25);
+ {
+ let src = src.clone();
+ let out = src / 2;
+ assert_eq!(out, res);
+ }
+
+ {
+ let mut out = src.clone();
+ out /= 2;
+ assert_eq!(out, res);
+ }
+}
+
+#[test]
+fn size_methods() {
+ let mut size = Size2d::new(10., 20.);
+ assert!(!size.empty());
+ assert_eq!(200., size.area());
+ size.width = 0.;
+ assert!(size.empty());
+}
+
+#[test]
+fn size_conv() {
+ let sizef = Size2d::new(1.2, 2.3);
+ assert_eq!(Size2i::new(1, 2), sizef.to::<i32>().unwrap());
+ assert_eq!(Size2f::new(1.2, 2.3), sizef.to::<f32>().unwrap());
+ let sizei = Size2i::new(1, 2);
+ assert_eq!(Size2f::new(1., 2.), sizei.to::<f32>().unwrap());
+
+ assert_eq!(Size2d::new(10., 20.), Size2d::from_point(Point2d::new(10., 20.)));
+}

add more methods and operations to Size_