use alloc::sync::Arc;
use alloc::vec::Vec;
use crate::DrawSink;
use crate::color::{AlphaColor, Srgb};
use crate::kurbo::{Affine, BezPath, Rect};
use crate::peniko::{BlendMode, Gradient};
use vello_common::paint::PaintType;
#[derive(Clone, Debug)]
pub enum AtlasPaint {
Solid(AlphaColor<Srgb>),
Gradient(Gradient),
}
impl From<AlphaColor<Srgb>> for AtlasPaint {
fn from(c: AlphaColor<Srgb>) -> Self {
Self::Solid(c)
}
}
impl From<Gradient> for AtlasPaint {
fn from(g: Gradient) -> Self {
Self::Gradient(g)
}
}
impl From<AtlasPaint> for PaintType {
fn from(paint: AtlasPaint) -> Self {
match paint {
AtlasPaint::Solid(color) => Self::Solid(color),
AtlasPaint::Gradient(gradient) => Self::Gradient(gradient),
}
}
}
#[derive(Clone, Debug)]
pub enum AtlasCommand {
SetTransform(Affine),
SetPaint(AtlasPaint),
SetPaintTransform(Affine),
FillPath(Arc<BezPath>),
FillRect(Rect),
PushClipLayer(Arc<BezPath>),
PushClipPath(Arc<BezPath>),
PushBlendLayer(BlendMode),
PopLayer,
PopClipPath,
}
pub struct AtlasCommandRecorder {
pub page_index: u32,
pub commands: Vec<AtlasCommand>,
pub(crate) width: u16,
pub(crate) height: u16,
}
impl AtlasCommandRecorder {
pub fn new(page_index: u32, width: u16, height: u16) -> Self {
Self {
page_index,
commands: Vec::new(),
width,
height,
}
}
}
impl DrawSink for AtlasCommandRecorder {
#[inline]
fn set_transform(&mut self, t: Affine) {
self.commands.push(AtlasCommand::SetTransform(t));
}
#[inline]
fn set_paint(&mut self, paint: AtlasPaint) {
self.commands.push(AtlasCommand::SetPaint(paint));
}
#[inline]
fn set_paint_transform(&mut self, t: Affine) {
self.commands.push(AtlasCommand::SetPaintTransform(t));
}
#[inline]
fn fill_path(&mut self, path: &BezPath) {
self.commands
.push(AtlasCommand::FillPath(Arc::new(path.clone())));
}
#[inline]
fn fill_rect(&mut self, rect: &Rect) {
self.commands.push(AtlasCommand::FillRect(*rect));
}
#[inline]
fn push_clip_layer(&mut self, clip: &BezPath) {
self.commands
.push(AtlasCommand::PushClipLayer(Arc::new(clip.clone())));
}
#[inline]
fn push_clip_path(&mut self, clip: &BezPath) {
self.commands
.push(AtlasCommand::PushClipPath(Arc::new(clip.clone())));
}
#[inline]
fn push_blend_layer(&mut self, blend_mode: BlendMode) {
self.commands.push(AtlasCommand::PushBlendLayer(blend_mode));
}
#[inline]
fn pop_layer(&mut self) {
self.commands.push(AtlasCommand::PopLayer);
}
#[inline]
fn pop_clip_path(&mut self) {
self.commands.push(AtlasCommand::PopClipPath);
}
#[inline]
fn width(&self) -> u16 {
self.width
}
#[inline]
fn height(&self) -> u16 {
self.height
}
}
impl core::fmt::Debug for AtlasCommandRecorder {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("AtlasCommandRecorder")
.field("page_index", &self.page_index)
.field("commands", &self.commands.len())
.field("width", &self.width)
.field("height", &self.height)
.finish()
}
}