<commit_before>use std::cell::Cell;

use cairo::{self, MatrixTrait};

use crate::attributes::Attribute;
use crate::bbox::BoundingBox;
use crate::coord_units::CoordUnits;
use crate::drawing_ctx::DrawingCtx;
use crate::error::RenderingError;
use crate::node::{NodeResult, NodeTrait, RsvgNode};
use crate::parsers::ParseValue;
use crate::property_bag::PropertyBag;

coord_units!(ClipPathUnits, CoordUnits::UserSpaceOnUse);

pub struct NodeClipPath {
    units: Cell<ClipPathUnits>,
}

impl NodeClipPath {
    pub fn new() -> NodeClipPath {
        NodeClipPath {
            units: Cell::new(ClipPathUnits::default()),
        }
    }

    pub fn get_units(&self) -> ClipPathUnits {
        self.units.get()
    }

    pub fn to_cairo_context(
        &self,
        node: &RsvgNode,
        affine_before_clip: &cairo::Matrix,
        draw_ctx: &mut DrawingCtx,
        bbox: &BoundingBox,
    ) -> Result<(), RenderingError> {
        let cascaded = node.get_cascaded_values();

        let clip_units = self.units.get();

        let child_matrix = if clip_units == ClipPathUnits(CoordUnits::ObjectBoundingBox) {
            if bbox.rect.is_none() {
                // The node being clipped is empty / doesn't have a
                // bounding box, so there's nothing to clip!
                return Ok(());
            }

            let rect = bbox.rect.as_ref().unwrap();

            let bbtransform = cairo::Matrix::new(rect.width, 0.0, 0.0, rect.height, rect.x, rect.y);
            cairo::Matrix::multiply(&bbtransform, affine_before_clip)
        } else {
            *affine_before_clip
        };

        let cr = draw_ctx.get_cairo_context();
        let save_affine = cr.get_matrix();
        cr.set_matrix(child_matrix);

        // here we don't push a layer because we are clipping
        let res = node.draw_children(&cascaded, draw_ctx, true);
<commit_msg>NodeClipPath.to_cairo_context() - reorder code a bit<commit_after>use std::cell::Cell;

use cairo::{self, MatrixTrait};

use crate::attributes::Attribute;
use crate::bbox::BoundingBox;
use crate::coord_units::CoordUnits;
use crate::drawing_ctx::DrawingCtx;
use crate::error::RenderingError;
use crate::node::{NodeResult, NodeTrait, RsvgNode};
use crate::parsers::ParseValue;
use crate::property_bag::PropertyBag;

coord_units!(ClipPathUnits, CoordUnits::UserSpaceOnUse);

pub struct NodeClipPath {
    units: Cell<ClipPathUnits>,
}

impl NodeClipPath {
    pub fn new() -> NodeClipPath {
        NodeClipPath {
            units: Cell::new(ClipPathUnits::default()),
        }
    }

    pub fn get_units(&self) -> ClipPathUnits {
        self.units.get()
    }

    pub fn to_cairo_context(
        &self,
        node: &RsvgNode,
        affine_before_clip: &cairo::Matrix,
        draw_ctx: &mut DrawingCtx,
        bbox: &BoundingBox,
    ) -> Result<(), RenderingError> {
        let cascaded = node.get_cascaded_values();

        let clip_units = self.units.get();

        let cr = draw_ctx.get_cairo_context();
        let save_affine = cr.get_matrix();

        let child_matrix = if clip_units == ClipPathUnits(CoordUnits::ObjectBoundingBox) {
            if bbox.rect.is_none() {
                // The node being clipped is empty / doesn't have a
                // bounding box, so there's nothing to clip!
                return Ok(());
            }

            let rect = bbox.rect.as_ref().unwrap();

            let bbtransform = cairo::Matrix::new(rect.width, 0.0, 0.0, rect.height, rect.x, rect.y);
            cairo::Matrix::multiply(&bbtransform, affine_before_clip)
        } else {
            *affine_before_clip
        };

        cr.set_matrix(child_matrix);

        // here we don't push a layer because we are clipping
        let res = node.draw_children(&cascaded, draw_ctx, true);

{'fraction_non_alphanumeric': 0.12335266209804956, 'fraction_numerical': 0.0021085925144965737, 'mean_word_length': 2.7096774193548385, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1187074', 'n_tokens_mistral': 1206, 'n_tokens_neox': 1190, 'n_words': 258}