1use std::sync::atomic::{AtomicU64, Ordering};
28use std::sync::{Arc, OnceLock};
29
30use iced::widget::image;
31
32pub mod engines;
34pub use engines::{Engine, PageType, PixelFormat, ViewId};
35
36mod webview;
37pub use basic::{Action, WebView};
38pub use webview::{advanced, basic};
39
40#[cfg(feature = "blitz")]
41pub use engines::blitz::Blitz;
42
43#[cfg(feature = "litehtml")]
44pub use engines::litehtml::Litehtml;
45
46#[cfg(feature = "servo")]
47pub use engines::servo::Servo;
48
49#[cfg(feature = "cef")]
50pub use engines::cef_engine::{cef_subprocess_check, Cef};
51
52pub(crate) mod util;
53
54#[cfg(any(feature = "litehtml", feature = "blitz"))]
55pub(crate) mod fetch;
56
57static FRAME_GENERATION: AtomicU64 = AtomicU64::new(0);
59
60fn next_generation() -> u64 {
61 FRAME_GENERATION.fetch_add(1, Ordering::Relaxed)
62}
63
64#[cfg_attr(
66 not(any(feature = "servo", feature = "cef", feature = "blitz")),
67 allow(dead_code)
68)]
69#[derive(Clone, Debug)]
70pub struct FramePixels {
71 pub(crate) data: Arc<Vec<u8>>,
72 pub(crate) generation: u64,
73}
74
75#[derive(Clone, Debug)]
77pub struct ImageInfo {
78 width: u32,
79 height: u32,
80 handle: Arc<OnceLock<image::Handle>>,
81 raw_pixels: Arc<Vec<u8>>,
82 generation: u64,
83}
84
85impl Default for ImageInfo {
86 fn default() -> Self {
87 Self::blank(Self::WIDTH, Self::HEIGHT)
88 }
89}
90
91impl ImageInfo {
92 const WIDTH: u32 = 800;
94 const HEIGHT: u32 = 800;
95
96 #[allow(dead_code)]
97 fn new(mut pixels: Vec<u8>, format: PixelFormat, width: u32, height: u32) -> Self {
98 pixels.truncate(pixels.len() / 4 * 4);
100
101 if let PixelFormat::Bgra = format {
102 pixels
103 .as_chunks_mut::<4>()
104 .0
105 .iter_mut()
106 .for_each(|chunk| chunk.swap(0, 2));
107 }
108
109 Self {
110 width,
111 height,
112 handle: Arc::new(OnceLock::new()),
113 raw_pixels: Arc::new(pixels),
114 generation: next_generation(),
115 }
116 }
117
118 pub fn as_handle(&self) -> image::Handle {
123 self.handle
124 .get_or_init(|| {
125 image::Handle::from_rgba(self.width, self.height, (*self.raw_pixels).clone())
126 })
127 .clone()
128 }
129
130 pub fn image_width(&self) -> u32 {
132 self.width
133 }
134
135 pub fn image_height(&self) -> u32 {
137 self.height
138 }
139
140 pub fn pixels(&self) -> FramePixels {
142 FramePixels {
143 data: Arc::clone(&self.raw_pixels),
144 generation: self.generation,
145 }
146 }
147
148 fn blank(width: u32, height: u32) -> Self {
149 let (w, h) = (width as usize)
151 .checked_mul(height as usize)
152 .and_then(|n| n.checked_mul(4))
153 .map_or((1u32, 1u32), |_| (width, height));
154
155 Self {
156 width: w,
157 height: h,
158 handle: Arc::new(OnceLock::new()),
159 raw_pixels: Arc::new(vec![255; w as usize * h as usize * 4]),
160 generation: next_generation(),
161 }
162 }
163}