sixtyfps_compilerlib/passes/
optimize_useless_rectangles.rs

1// Copyright © SixtyFPS GmbH <info@sixtyfps.io>
2// SPDX-License-Identifier: (GPL-3.0-only OR LicenseRef-SixtyFPS-commercial)
3
4//! Remove the rectangles that serves no purposes
5//!
6//! Rectangles which do not draw anything and have no x or y don't need to be in
7//! the item tree, we can just remove them.
8
9use crate::{langtype::Type, object_tree::*};
10use std::rc::Rc;
11
12pub fn optimize_useless_rectangles(root_component: &Rc<Component>) {
13    recurse_elem_including_sub_components(root_component, &(), &mut |parent, _| {
14        let mut parent = parent.borrow_mut();
15        let children = std::mem::take(&mut parent.children);
16
17        for elem in children {
18            if !can_optimize(&elem) {
19                parent.children.push(elem);
20                continue;
21            }
22
23            parent.children.extend(std::mem::take(&mut elem.borrow_mut().children));
24
25            parent
26                .enclosing_component
27                .upgrade()
28                .unwrap()
29                .optimized_elements
30                .borrow_mut()
31                .push(elem);
32        }
33    });
34}
35
36/// Check that this is a element we can optimize
37fn can_optimize(elem: &ElementRc) -> bool {
38    let e = elem.borrow();
39    if e.is_flickable_viewport || e.child_of_layout {
40        return false;
41    };
42
43    let base_type = match &e.base_type {
44        Type::Builtin(base_type) if base_type.name == "Rectangle" => base_type,
45        _ => return false,
46    };
47
48    // Check that no Rectangle property other than height and width are set
49    let analysis = e.property_analysis.borrow();
50    !e.bindings.keys().chain(analysis.iter().filter(|(_, v)| v.is_set).map(|(k, _)| k)).any(|k| {
51        !matches!(k.as_str(), "height" | "width")
52            && !e.property_declarations.contains_key(k.as_str())
53            && base_type.properties.contains_key(k.as_str())
54    })
55}