1//! Module containing renderer implementations.
2
3use imgref::ImgVec;
4use rgb::RGBA8;
5
6use crate::{
7 geometry::Position, paint::GlyphTexture, Color, CompositeOperationState, ErrorKind, FillRule, ImageFilter, ImageId,
8 ImageInfo, ImageSource, ImageStore,
9};
10
11mod opengl;
12pub use opengl::OpenGl;
13
14mod void;
15pub use void::Void;
16
17mod params;
18pub(crate) use params::Params;
19
20#[derive(Copy, Clone, Default, Debug)]
21pub struct Drawable {
22 pub(crate) fill_verts: Option<(usize, usize)>,
23 pub(crate) stroke_verts: Option<(usize, usize)>,
24}
25
26#[derive(Debug)]
27pub enum CommandType {
28 SetRenderTarget(RenderTarget),
29 ClearRect {
30 x: u32,
31 y: u32,
32 width: u32,
33 height: u32,
34 color: Color,
35 },
36 ConvexFill {
37 params: Params,
38 },
39 ConcaveFill {
40 stencil_params: Params,
41 fill_params: Params,
42 },
43 Stroke {
44 params: Params,
45 },
46 StencilStroke {
47 params1: Params,
48 params2: Params,
49 },
50 Triangles {
51 params: Params,
52 },
53 RenderFilteredImage {
54 target_image: ImageId,
55 filter: ImageFilter,
56 },
57}
58
59#[derive(Debug)]
60pub struct Command {
61 pub(crate) cmd_type: CommandType,
62 pub(crate) drawables: Vec<Drawable>,
63 pub(crate) triangles_verts: Option<(usize, usize)>,
64 pub(crate) image: Option<ImageId>,
65 pub(crate) glyph_texture: GlyphTexture,
66 pub(crate) fill_rule: FillRule,
67 pub(crate) composite_operation: CompositeOperationState,
68}
69
70impl Command {
71 pub fn new(flavor: CommandType) -> Self {
72 Self {
73 cmd_type: flavor,
74 drawables: Default::default(),
75 triangles_verts: Default::default(),
76 image: Default::default(),
77 glyph_texture: Default::default(),
78 fill_rule: Default::default(),
79 composite_operation: Default::default(),
80 }
81 }
82}
83
84#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
85pub enum RenderTarget {
86 Screen,
87 Image(ImageId),
88}
89
90/// This is the main renderer trait that the [Canvas](../struct.Canvas.html) draws to.
91pub trait Renderer {
92 type Image;
93 type NativeTexture;
94
95 fn set_size(&mut self, width: u32, height: u32, dpi: f32);
96
97 fn render(&mut self, images: &mut ImageStore<Self::Image>, verts: &[Vertex], commands: Vec<Command>);
98
99 fn alloc_image(&mut self, info: ImageInfo) -> Result<Self::Image, ErrorKind>;
100 fn create_image_from_native_texture(
101 &mut self,
102 native_texture: Self::NativeTexture,
103 info: ImageInfo,
104 ) -> Result<Self::Image, ErrorKind>;
105 fn update_image(&mut self, image: &mut Self::Image, data: ImageSource, x: usize, y: usize)
106 -> Result<(), ErrorKind>;
107 #[allow(unused_variables)]
108 fn get_native_texture(&self, image: &Self::Image) -> Result<Self::NativeTexture, ErrorKind> {
109 Err(ErrorKind::UnsupportedImageFormat)
110 }
111 fn delete_image(&mut self, image: Self::Image, image_id: ImageId);
112
113 fn screenshot(&mut self) -> Result<ImgVec<RGBA8>, ErrorKind>;
114}
115
116/// Vertex struct for specifying triangle geometry
117#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Default)]
118#[repr(C)]
119pub struct Vertex {
120 pub x: f32,
121 pub y: f32,
122 pub u: f32,
123 pub v: f32,
124}
125
126impl Vertex {
127 pub(crate) fn pos(position: Position, u: f32, v: f32) -> Self {
128 let Position { x: f32, y: f32 } = position;
129 Self { x, y, u, v }
130 }
131
132 pub fn new(x: f32, y: f32, u: f32, v: f32) -> Self {
133 Self { x, y, u, v }
134 }
135
136 pub fn set(&mut self, x: f32, y: f32, u: f32, v: f32) {
137 *self = Self { x, y, u, v };
138 }
139}
140
141#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
142pub enum ShaderType {
143 FillGradient,
144 FillImage,
145 Stencil,
146 FillImageGradient,
147 FilterImage,
148 FillColor,
149 TextureCopyUnclipped,
150}
151
152impl Default for ShaderType {
153 fn default() -> Self {
154 Self::FillGradient
155 }
156}
157
158impl ShaderType {
159 pub fn to_u8(self) -> u8 {
160 match self {
161 Self::FillGradient => 0,
162 Self::FillImage => 1,
163 Self::Stencil => 2,
164 Self::FillImageGradient => 3,
165 Self::FilterImage => 4,
166 Self::FillColor => 5,
167 Self::TextureCopyUnclipped => 6,
168 }
169 }
170 pub fn to_f32(self) -> f32 {
171 self.to_u8() as f32
172 }
173}
174