829 lines · 26.6 KB · Rust
RawDownload
// todo("windows"): remove#![cfg_attr(windows, allow(dead_code))] use schemars::JsonSchema;use serde::{Deserialize, Serialize}; use crate::{    AtlasTextureId, AtlasTile, Background, Bounds, ContentMask, Corners, Edges, Hsla, Pixels,    Point, Radians, ScaledPixels, Size, bounds_tree::BoundsTree, point,};use std::{fmt::Debug, iter::Peekable, ops::Range, slice}; #[allow(non_camel_case_types, unused)]pub(crate) type PathVertex_ScaledPixels = PathVertex<ScaledPixels>; pub(crate) type DrawOrder = u32; #[derive(Default)]pub(crate) struct Scene {    pub(crate) paint_operations: Vec<PaintOperation>,    primitive_bounds: BoundsTree<ScaledPixels>,    layer_stack: Vec<DrawOrder>,    pub(crate) shadows: Vec<Shadow>,    pub(crate) quads: Vec<Quad>,    pub(crate) paths: Vec<Path<ScaledPixels>>,    pub(crate) underlines: Vec<Underline>,    pub(crate) monochrome_sprites: Vec<MonochromeSprite>,    pub(crate) polychrome_sprites: Vec<PolychromeSprite>,    pub(crate) surfaces: Vec<PaintSurface>,} impl Scene {    pub fn clear(&mut self) {        self.paint_operations.clear();        self.primitive_bounds.clear();        self.layer_stack.clear();        self.paths.clear();        self.shadows.clear();        self.quads.clear();        self.underlines.clear();        self.monochrome_sprites.clear();        self.polychrome_sprites.clear();        self.surfaces.clear();    }     #[cfg_attr(        all(            any(target_os = "linux", target_os = "freebsd"),            not(any(feature = "x11", feature = "wayland"))        ),        allow(dead_code)    )]    pub fn paths(&self) -> &[Path<ScaledPixels>] {        &self.paths    }     pub fn len(&self) -> usize {        self.paint_operations.len()    }     pub fn push_layer(&mut self, bounds: Bounds<ScaledPixels>) {        let order = self.primitive_bounds.insert(bounds);        self.layer_stack.push(order);        self.paint_operations            .push(PaintOperation::StartLayer(bounds));    }     pub fn pop_layer(&mut self) {        self.layer_stack.pop();        self.paint_operations.push(PaintOperation::EndLayer);    }     pub fn insert_primitive(&mut self, primitive: impl Into<Primitive>) {        let mut primitive = primitive.into();        let clipped_bounds = primitive            .bounds()            .intersect(&primitive.content_mask().bounds);         if clipped_bounds.is_empty() {            return;        }         let order = self            .layer_stack            .last()            .copied()            .unwrap_or_else(|| self.primitive_bounds.insert(clipped_bounds));        match &mut primitive {            Primitive::Shadow(shadow) => {                shadow.order = order;                self.shadows.push(shadow.clone());            }            Primitive::Quad(quad) => {                quad.order = order;                self.quads.push(quad.clone());            }            Primitive::Path(path) => {                path.order = order;                path.id = PathId(self.paths.len());                self.paths.push(path.clone());            }            Primitive::Underline(underline) => {                underline.order = order;                self.underlines.push(underline.clone());            }            Primitive::MonochromeSprite(sprite) => {                sprite.order = order;                self.monochrome_sprites.push(sprite.clone());            }            Primitive::PolychromeSprite(sprite) => {                sprite.order = order;                self.polychrome_sprites.push(sprite.clone());            }            Primitive::Surface(surface) => {                surface.order = order;                self.surfaces.push(surface.clone());            }        }        self.paint_operations            .push(PaintOperation::Primitive(primitive));    }     pub fn replay(&mut self, range: Range<usize>, prev_scene: &Scene) {        for operation in &prev_scene.paint_operations[range] {            match operation {                PaintOperation::Primitive(primitive) => self.insert_primitive(primitive.clone()),                PaintOperation::StartLayer(bounds) => self.push_layer(*bounds),                PaintOperation::EndLayer => self.pop_layer(),            }        }    }     pub fn finish(&mut self) {        self.shadows.sort_by_key(|shadow| shadow.order);        self.quads.sort_by_key(|quad| quad.order);        self.paths.sort_by_key(|path| path.order);        self.underlines.sort_by_key(|underline| underline.order);        self.monochrome_sprites            .sort_by_key(|sprite| (sprite.order, sprite.tile.tile_id));        self.polychrome_sprites            .sort_by_key(|sprite| (sprite.order, sprite.tile.tile_id));        self.surfaces.sort_by_key(|surface| surface.order);    }     #[cfg_attr(        all(            any(target_os = "linux", target_os = "freebsd"),            not(any(feature = "x11", feature = "wayland"))        ),        allow(dead_code)    )]    pub(crate) fn batches(&self) -> impl Iterator<Item = PrimitiveBatch> {        BatchIterator {            shadows: &self.shadows,            shadows_start: 0,            shadows_iter: self.shadows.iter().peekable(),            quads: &self.quads,            quads_start: 0,            quads_iter: self.quads.iter().peekable(),            paths: &self.paths,            paths_start: 0,            paths_iter: self.paths.iter().peekable(),            underlines: &self.underlines,            underlines_start: 0,            underlines_iter: self.underlines.iter().peekable(),            monochrome_sprites: &self.monochrome_sprites,            monochrome_sprites_start: 0,            monochrome_sprites_iter: self.monochrome_sprites.iter().peekable(),            polychrome_sprites: &self.polychrome_sprites,            polychrome_sprites_start: 0,            polychrome_sprites_iter: self.polychrome_sprites.iter().peekable(),            surfaces: &self.surfaces,            surfaces_start: 0,            surfaces_iter: self.surfaces.iter().peekable(),        }    }} #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Default)]#[cfg_attr(    all(        any(target_os = "linux", target_os = "freebsd"),        not(any(feature = "x11", feature = "wayland"))    ),    allow(dead_code))]pub(crate) enum PrimitiveKind {    Shadow,    #[default]    Quad,    Path,    Underline,    MonochromeSprite,    PolychromeSprite,    Surface,} pub(crate) enum PaintOperation {    Primitive(Primitive),    StartLayer(Bounds<ScaledPixels>),    EndLayer,} #[derive(Clone)]pub(crate) enum Primitive {    Shadow(Shadow),    Quad(Quad),    Path(Path<ScaledPixels>),    Underline(Underline),    MonochromeSprite(MonochromeSprite),    PolychromeSprite(PolychromeSprite),    Surface(PaintSurface),} impl Primitive {    pub fn bounds(&self) -> &Bounds<ScaledPixels> {        match self {            Primitive::Shadow(shadow) => &shadow.bounds,            Primitive::Quad(quad) => &quad.bounds,            Primitive::Path(path) => &path.bounds,            Primitive::Underline(underline) => &underline.bounds,            Primitive::MonochromeSprite(sprite) => &sprite.bounds,            Primitive::PolychromeSprite(sprite) => &sprite.bounds,            Primitive::Surface(surface) => &surface.bounds,        }    }     pub fn content_mask(&self) -> &ContentMask<ScaledPixels> {        match self {            Primitive::Shadow(shadow) => &shadow.content_mask,            Primitive::Quad(quad) => &quad.content_mask,            Primitive::Path(path) => &path.content_mask,            Primitive::Underline(underline) => &underline.content_mask,            Primitive::MonochromeSprite(sprite) => &sprite.content_mask,            Primitive::PolychromeSprite(sprite) => &sprite.content_mask,            Primitive::Surface(surface) => &surface.content_mask,        }    }} #[cfg_attr(    all(        any(target_os = "linux", target_os = "freebsd"),        not(any(feature = "x11", feature = "wayland"))    ),    allow(dead_code))]struct BatchIterator<'a> {    shadows: &'a [Shadow],    shadows_start: usize,    shadows_iter: Peekable<slice::Iter<'a, Shadow>>,    quads: &'a [Quad],    quads_start: usize,    quads_iter: Peekable<slice::Iter<'a, Quad>>,    paths: &'a [Path<ScaledPixels>],    paths_start: usize,    paths_iter: Peekable<slice::Iter<'a, Path<ScaledPixels>>>,    underlines: &'a [Underline],    underlines_start: usize,    underlines_iter: Peekable<slice::Iter<'a, Underline>>,    monochrome_sprites: &'a [MonochromeSprite],    monochrome_sprites_start: usize,    monochrome_sprites_iter: Peekable<slice::Iter<'a, MonochromeSprite>>,    polychrome_sprites: &'a [PolychromeSprite],    polychrome_sprites_start: usize,    polychrome_sprites_iter: Peekable<slice::Iter<'a, PolychromeSprite>>,    surfaces: &'a [PaintSurface],    surfaces_start: usize,    surfaces_iter: Peekable<slice::Iter<'a, PaintSurface>>,} impl<'a> Iterator for BatchIterator<'a> {    type Item = PrimitiveBatch<'a>;     fn next(&mut self) -> Option<Self::Item> {        let mut orders_and_kinds = [            (                self.shadows_iter.peek().map(|s| s.order),                PrimitiveKind::Shadow,            ),            (self.quads_iter.peek().map(|q| q.order), PrimitiveKind::Quad),            (self.paths_iter.peek().map(|q| q.order), PrimitiveKind::Path),            (                self.underlines_iter.peek().map(|u| u.order),                PrimitiveKind::Underline,            ),            (                self.monochrome_sprites_iter.peek().map(|s| s.order),                PrimitiveKind::MonochromeSprite,            ),            (                self.polychrome_sprites_iter.peek().map(|s| s.order),                PrimitiveKind::PolychromeSprite,            ),            (                self.surfaces_iter.peek().map(|s| s.order),                PrimitiveKind::Surface,            ),        ];        orders_and_kinds.sort_by_key(|(order, kind)| (order.unwrap_or(u32::MAX), *kind));         let first = orders_and_kinds[0];        let second = orders_and_kinds[1];        let (batch_kind, max_order_and_kind) = if first.0.is_some() {            (first.1, (second.0.unwrap_or(u32::MAX), second.1))        } else {            return None;        };         match batch_kind {            PrimitiveKind::Shadow => {                let shadows_start = self.shadows_start;                let mut shadows_end = shadows_start + 1;                self.shadows_iter.next();                while self                    .shadows_iter                    .next_if(|shadow| (shadow.order, batch_kind) < max_order_and_kind)                    .is_some()                {                    shadows_end += 1;                }                self.shadows_start = shadows_end;                Some(PrimitiveBatch::Shadows(                    &self.shadows[shadows_start..shadows_end],                ))            }            PrimitiveKind::Quad => {                let quads_start = self.quads_start;                let mut quads_end = quads_start + 1;                self.quads_iter.next();                while self                    .quads_iter                    .next_if(|quad| (quad.order, batch_kind) < max_order_and_kind)                    .is_some()                {                    quads_end += 1;                }                self.quads_start = quads_end;                Some(PrimitiveBatch::Quads(&self.quads[quads_start..quads_end]))            }            PrimitiveKind::Path => {                let paths_start = self.paths_start;                let mut paths_end = paths_start + 1;                self.paths_iter.next();                while self                    .paths_iter                    .next_if(|path| (path.order, batch_kind) < max_order_and_kind)                    .is_some()                {                    paths_end += 1;                }                self.paths_start = paths_end;                Some(PrimitiveBatch::Paths(&self.paths[paths_start..paths_end]))            }            PrimitiveKind::Underline => {                let underlines_start = self.underlines_start;                let mut underlines_end = underlines_start + 1;                self.underlines_iter.next();                while self                    .underlines_iter                    .next_if(|underline| (underline.order, batch_kind) < max_order_and_kind)                    .is_some()                {                    underlines_end += 1;                }                self.underlines_start = underlines_end;                Some(PrimitiveBatch::Underlines(                    &self.underlines[underlines_start..underlines_end],                ))            }            PrimitiveKind::MonochromeSprite => {                let texture_id = self.monochrome_sprites_iter.peek().unwrap().tile.texture_id;                let sprites_start = self.monochrome_sprites_start;                let mut sprites_end = sprites_start + 1;                self.monochrome_sprites_iter.next();                while self                    .monochrome_sprites_iter                    .next_if(|sprite| {                        (sprite.order, batch_kind) < max_order_and_kind                            && sprite.tile.texture_id == texture_id                    })                    .is_some()                {                    sprites_end += 1;                }                self.monochrome_sprites_start = sprites_end;                Some(PrimitiveBatch::MonochromeSprites {                    texture_id,                    sprites: &self.monochrome_sprites[sprites_start..sprites_end],                })            }            PrimitiveKind::PolychromeSprite => {                let texture_id = self.polychrome_sprites_iter.peek().unwrap().tile.texture_id;                let sprites_start = self.polychrome_sprites_start;                let mut sprites_end = self.polychrome_sprites_start + 1;                self.polychrome_sprites_iter.next();                while self                    .polychrome_sprites_iter                    .next_if(|sprite| {                        (sprite.order, batch_kind) < max_order_and_kind                            && sprite.tile.texture_id == texture_id                    })                    .is_some()                {                    sprites_end += 1;                }                self.polychrome_sprites_start = sprites_end;                Some(PrimitiveBatch::PolychromeSprites {                    texture_id,                    sprites: &self.polychrome_sprites[sprites_start..sprites_end],                })            }            PrimitiveKind::Surface => {                let surfaces_start = self.surfaces_start;                let mut surfaces_end = surfaces_start + 1;                self.surfaces_iter.next();                while self                    .surfaces_iter                    .next_if(|surface| (surface.order, batch_kind) < max_order_and_kind)                    .is_some()                {                    surfaces_end += 1;                }                self.surfaces_start = surfaces_end;                Some(PrimitiveBatch::Surfaces(                    &self.surfaces[surfaces_start..surfaces_end],                ))            }        }    }} #[derive(Debug)]#[cfg_attr(    all(        any(target_os = "linux", target_os = "freebsd"),        not(any(feature = "x11", feature = "wayland"))    ),    allow(dead_code))]pub(crate) enum PrimitiveBatch<'a> {    Shadows(&'a [Shadow]),    Quads(&'a [Quad]),    Paths(&'a [Path<ScaledPixels>]),    Underlines(&'a [Underline]),    MonochromeSprites {        texture_id: AtlasTextureId,        sprites: &'a [MonochromeSprite],    },    PolychromeSprites {        texture_id: AtlasTextureId,        sprites: &'a [PolychromeSprite],    },    Surfaces(&'a [PaintSurface]),} #[derive(Default, Debug, Clone)]#[repr(C)]pub(crate) struct Quad {    pub order: DrawOrder,    pub border_style: BorderStyle,    pub bounds: Bounds<ScaledPixels>,    pub content_mask: ContentMask<ScaledPixels>,    pub background: Background,    pub border_color: Hsla,    pub corner_radii: Corners<ScaledPixels>,    pub border_widths: Edges<ScaledPixels>,} impl From<Quad> for Primitive {    fn from(quad: Quad) -> Self {        Primitive::Quad(quad)    }} #[derive(Debug, Clone)]#[repr(C)]pub(crate) struct Underline {    pub order: DrawOrder,    pub pad: u32, // align to 8 bytes    pub bounds: Bounds<ScaledPixels>,    pub content_mask: ContentMask<ScaledPixels>,    pub color: Hsla,    pub thickness: ScaledPixels,    pub wavy: bool,} impl From<Underline> for Primitive {    fn from(underline: Underline) -> Self {        Primitive::Underline(underline)    }} #[derive(Debug, Clone)]#[repr(C)]pub(crate) struct Shadow {    pub order: DrawOrder,    pub blur_radius: ScaledPixels,    pub bounds: Bounds<ScaledPixels>,    pub corner_radii: Corners<ScaledPixels>,

Lines 1–500 of 829.