sdocx 1.0.0

Reverse-engineered tooling and SDK for converting Samsung Notes (.sdocx) files
Documentation
#![cfg_attr(not(test), allow(dead_code))]

#[derive(Debug, Clone, Copy)]
pub(in crate::render) struct NativeCellTextClipContext {
    model_rect: [f32; 4],
    caller_origin: [f32; 2],
    model_height: f32,
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub(in crate::render) enum NativeCellRunClip {
    Unclipped,
    Clipped {
        world_rect: [f32; 4],
        intersects_source: bool,
    },
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
#[error("native cell clipping has invalid or overflowing geometry")]
pub(in crate::render) struct NativeCellClipError;

impl NativeCellTextClipContext {
    pub fn new(model_rect: [f32; 4], caller_origin: [f32; 2]) -> Result<Self, NativeCellClipError> {
        let model_height = model_rect[3] - model_rect[1];
        if !model_rect
            .into_iter()
            .chain(caller_origin)
            .chain([model_height])
            .all(f32::is_finite)
        {
            return Err(NativeCellClipError);
        }
        Ok(Self {
            model_rect,
            caller_origin,
            model_height,
        })
    }

    pub fn decide(
        self,
        local_run_rect: [f32; 4],
    ) -> Result<NativeCellRunClip, NativeCellClipError> {
        if !local_run_rect.into_iter().all(f32::is_finite) {
            return Err(NativeCellClipError);
        }
        if local_run_rect[3] <= self.model_height {
            return Ok(NativeCellRunClip::Unclipped);
        }
        let [left, top, right, bottom] = local_run_rect;
        let [x, y] = self.caller_origin;
        let mut world_rect = [left + x, top + y, right + x, bottom + y];
        if !world_rect.into_iter().all(f32::is_finite) {
            return Err(NativeCellClipError);
        }
        let intersects_source = world_rect[0] < self.model_rect[2]
            && self.model_rect[0] < world_rect[2]
            && world_rect[1] < self.model_rect[3]
            && self.model_rect[1] < world_rect[3];
        if intersects_source {
            for axis in 0..2 {
                if world_rect[axis] < self.model_rect[axis] {
                    world_rect[axis] = self.model_rect[axis];
                }
                if world_rect[axis + 2] > self.model_rect[axis + 2] {
                    world_rect[axis + 2] = self.model_rect[axis + 2];
                }
            }
        }
        Ok(NativeCellRunClip::Clipped {
            world_rect,
            intersects_source,
        })
    }
}

#[cfg(all(test, feature = "serde"))]
#[path = "native_cell_clip/fixture_tests.rs"]
mod fixture_tests;

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn finite_admission_rejects_overflow_without_normalizing_native_dimensions() {
        assert!(
            NativeCellTextClipContext::new([0.0, -f32::MAX, 10.0, f32::MAX], [0.0; 2]).is_err()
        );
        assert!(NativeCellTextClipContext::new([f32::NAN, 0.0, 10.0, 10.0], [0.0; 2]).is_err());
        assert!(
            NativeCellTextClipContext::new([0.0, 0.0, 10.0, 10.0], [f32::INFINITY, 0.0]).is_err()
        );
        let context =
            NativeCellTextClipContext::new([0.0, 0.0, 10.0, 0.0], [f32::MAX, 0.0]).unwrap();
        assert!(context.decide([f32::MAX, 0.0, f32::MAX, 1.0]).is_err());
        let inverted = NativeCellTextClipContext::new([10.0, 10.0, 0.0, 0.0], [0.0; 2]).unwrap();
        assert_eq!(
            inverted.decide([1.0, 1.0, 5.0, 5.0]).unwrap(),
            NativeCellRunClip::Clipped {
                world_rect: [1.0, 1.0, 5.0, 5.0],
                intersects_source: false,
            }
        );
    }

    #[test]
    fn equal_intersection_edges_keep_the_translated_rectangle_bits() {
        let context = NativeCellTextClipContext::new([0.0, 0.0, 10.0, 10.0], [-0.0, -0.0]).unwrap();
        let NativeCellRunClip::Clipped {
            world_rect,
            intersects_source,
        } = context.decide([-0.0, -0.0, 10.0, 11.0]).unwrap()
        else {
            panic!("run must exceed source height");
        };
        assert!(intersects_source);
        assert_eq!(
            world_rect.map(f32::to_bits),
            [-0.0_f32, -0.0, 10.0, 10.0].map(f32::to_bits)
        );
    }
}