blend2d 0.1.1

Rust bindings for blend2d
Documentation
use core::slice;

use crate::{
    error::{errcode_to_result, Result},
    geometry::{BoxI, PointI},
    variant::WrappedBlCore,
    BooleanOp,
};

use ffi::BLRegionType::*;
use std::borrow::Borrow;
bl_enum! {
    pub enum RegionType {
        Empty   = BL_REGION_TYPE_EMPTY,
        Rect    = BL_REGION_TYPE_RECT,
        Complex = BL_REGION_TYPE_COMPLEX,
    }
    Default => Empty
}

#[repr(transparent)]
pub struct Region {
    core: ffi::BLRegionCore,
}

unsafe impl WrappedBlCore for Region {
    type Core = ffi::BLRegionCore;
    const IMPL_TYPE_INDEX: usize = ffi::BLImplType::BL_IMPL_TYPE_REGION as usize;
}

impl Region {
    #[inline]
    pub fn new() -> Self {
        Region {
            core: *Self::none(),
        }
    }

    #[inline]
    pub fn region_type(&mut self) -> RegionType {
        unsafe { ffi::blRegionGetType(self.core_mut()).into() }
    }

    #[inline]
    pub fn is_empty(&self) -> bool {
        self.data().len() == 0
    }

    #[inline]
    pub fn is_rect(&self) -> bool {
        self.data().len() == 1
    }

    #[inline]
    pub fn is_complex(&self) -> bool {
        self.data().len() > 1
    }

    #[inline]
    pub fn data(&self) -> &[BoxI] {
        unsafe {
            let t = self.impl_().__bindgen_anon_1.__bindgen_anon_1;
            slice::from_raw_parts(t.data as *const _, t.size)
        }
    }

    #[inline]
    pub fn len(&self) -> usize {
        self.data().len()
    }

    #[inline]
    pub fn capacity(&self) -> usize {
        self.impl_().capacity
    }

    #[inline]
    pub fn bounding_box(&self) -> &BoxI {
        unsafe { &*(&self.impl_().boundingBox as *const _ as *const _) }
    }

    #[inline]
    pub fn clear(&mut self) -> Result<()> {
        unsafe { errcode_to_result(ffi::blRegionClear(self.core_mut())) }
    }

    #[inline]
    pub fn reserve(&mut self, n: usize) {
        self.try_reserve(n).unwrap()
    }

    #[inline]
    pub fn try_reserve(&mut self, n: usize) -> Result<()> {
        unsafe { errcode_to_result(ffi::blRegionReserve(self.core_mut(), n)) }
    }

    #[inline]
    pub fn shrink_to_fit(&mut self) {
        unsafe { errcode_to_result(ffi::blRegionShrink(self.core_mut())).unwrap() }
    }

    #[inline]
    pub fn combine(&mut self, other: &Self, op: BooleanOp) -> Result<()> {
        unsafe {
            errcode_to_result(ffi::blRegionCombine(
                self.core_mut(),
                self.core(),
                other.core(),
                op.into(),
            ))
        }
    }

    #[inline]
    pub fn combine_rb(&mut self, b: &BoxI, op: BooleanOp) -> Result<()> {
        unsafe {
            errcode_to_result(ffi::blRegionCombineRB(
                self.core_mut(),
                self.core(),
                &b as *const _ as *const _,
                op.into(),
            ))
        }
    }

    #[inline]
    pub fn combine_br(&mut self, b: &BoxI, op: BooleanOp) -> Result<()> {
        unsafe {
            errcode_to_result(ffi::blRegionCombineBR(
                self.core_mut(),
                &b as *const _ as *const _,
                self.core(),
                op.into(),
            ))
        }
    }

    #[inline]
    pub fn combine_bb(&mut self, b: &BoxI, b2: &BoxI, op: BooleanOp) -> Result<()> {
        unsafe {
            errcode_to_result(ffi::blRegionCombineBB(
                self.core_mut(),
                &b as *const _ as *const _,
                &b2 as *const _ as *const _,
                op.into(),
            ))
        }
    }

    #[inline]
    pub fn translate(&mut self, p: &PointI) -> Result<()> {
        unsafe {
            errcode_to_result(ffi::blRegionTranslate(
                self.core_mut(),
                self.core(),
                p as *const _ as *const _,
            ))
        }
    }

    #[inline]
    pub fn translate_and_clip(&mut self, p: &PointI, clip: &BoxI) -> Result<()> {
        unsafe {
            errcode_to_result(ffi::blRegionTranslateAndClip(
                self.core_mut(),
                self.core(),
                p as *const _ as *const _,
                clip as *const _ as *const _,
            ))
        }
    }

    #[inline]
    pub fn intersect_and_clip(&mut self, region: &Region, clip: &BoxI) -> Result<()> {
        unsafe {
            errcode_to_result(ffi::blRegionIntersectAndClip(
                self.core_mut(),
                self.core(),
                region.core(),
                clip as *const _ as *const _,
            ))
        }
    }

    #[inline]
    pub fn hit_test(&mut self, p: &PointI) -> Result<()> {
        unsafe {
            errcode_to_result(ffi::blRegionHitTest(
                self.core_mut(),
                p as *const _ as *const _,
            ))
        }
    }

    #[inline]
    pub fn hit_test_box(&mut self, b: &BoxI) -> Result<()> {
        unsafe {
            errcode_to_result(ffi::blRegionHitTestBoxI(
                self.core_mut(),
                b as *const _ as *const _,
            ))
        }
    }
}

impl AsRef<[BoxI]> for Region {
    #[inline]
    fn as_ref(&self) -> &[BoxI] {
        self.data()
    }
}

impl Borrow<[BoxI]> for Region {
    #[inline]
    fn borrow(&self) -> &[BoxI] {
        self.data()
    }
}

impl Default for Region {
    #[inline]
    fn default() -> Self {
        Self::new()
    }
}

impl PartialEq for Region {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        unsafe { ffi::blRegionEquals(self.core(), other.core()) }
    }
}

impl Clone for Region {
    fn clone(&self) -> Self {
        let mut new = Self::new();
        unsafe { ffi::blRegionAssignDeep(new.core_mut(), self.core()) };
        new
    }
}

impl Drop for Region {
    fn drop(&mut self) {
        unsafe { ffi::blRegionReset(&mut self.core) };
    }
}