summaryrefslogtreecommitdiffstats
path: root/glow/src/backend.rs
diff options
context:
space:
mode:
Diffstat (limited to 'glow/src/backend.rs')
-rw-r--r--glow/src/backend.rs280
1 files changed, 0 insertions, 280 deletions
diff --git a/glow/src/backend.rs b/glow/src/backend.rs
deleted file mode 100644
index 36a34eda..00000000
--- a/glow/src/backend.rs
+++ /dev/null
@@ -1,280 +0,0 @@
-#[cfg(any(feature = "image", feature = "svg"))]
-use crate::image;
-use crate::quad;
-use crate::text;
-use crate::{program, triangle};
-use crate::{Settings, Transformation, Viewport};
-
-use iced_graphics::backend;
-use iced_graphics::font;
-use iced_graphics::{Layer, Primitive};
-use iced_native::alignment;
-use iced_native::{Font, Size};
-
-/// A [`glow`] graphics backend for [`iced`].
-///
-/// [`glow`]: https://github.com/grovesNL/glow
-/// [`iced`]: https://github.com/iced-rs/iced
-#[derive(Debug)]
-pub struct Backend {
- #[cfg(any(feature = "image", feature = "svg"))]
- image_pipeline: image::Pipeline,
- quad_pipeline: quad::Pipeline,
- text_pipeline: text::Pipeline,
- triangle_pipeline: triangle::Pipeline,
- default_text_size: f32,
-}
-
-impl Backend {
- /// Creates a new [`Backend`].
- pub fn new(gl: &glow::Context, settings: Settings) -> Self {
- let text_pipeline = text::Pipeline::new(
- gl,
- settings.default_font,
- settings.text_multithreading,
- );
-
- let shader_version = program::Version::new(gl);
-
- #[cfg(any(feature = "image", feature = "svg"))]
- let image_pipeline = image::Pipeline::new(gl, &shader_version);
- let quad_pipeline = quad::Pipeline::new(gl, &shader_version);
- let triangle_pipeline = triangle::Pipeline::new(gl, &shader_version);
-
- Self {
- #[cfg(any(feature = "image", feature = "svg"))]
- image_pipeline,
- quad_pipeline,
- text_pipeline,
- triangle_pipeline,
- default_text_size: settings.default_text_size,
- }
- }
-
- /// Draws the provided primitives in the default framebuffer.
- ///
- /// The text provided as overlay will be rendered on top of the primitives.
- /// This is useful for rendering debug information.
- pub fn present<T: AsRef<str>>(
- &mut self,
- gl: &glow::Context,
- primitives: &[Primitive],
- viewport: &Viewport,
- overlay_text: &[T],
- ) {
- let viewport_size = viewport.physical_size();
- let scale_factor = viewport.scale_factor() as f32;
- let projection = viewport.projection();
-
- let mut layers = Layer::generate(primitives, viewport);
- layers.push(Layer::overlay(overlay_text, viewport));
-
- for layer in layers {
- self.flush(
- gl,
- scale_factor,
- projection,
- &layer,
- viewport_size.height,
- );
- }
-
- #[cfg(any(feature = "image", feature = "svg"))]
- self.image_pipeline.trim_cache(gl);
- }
-
- fn flush(
- &mut self,
- gl: &glow::Context,
- scale_factor: f32,
- transformation: Transformation,
- layer: &Layer<'_>,
- target_height: u32,
- ) {
- let mut bounds = (layer.bounds * scale_factor).snap();
-
- if bounds.width < 1 || bounds.height < 1 {
- return;
- }
-
- bounds.height = bounds.height.min(target_height);
-
- if !layer.quads.is_empty() {
- self.quad_pipeline.draw(
- gl,
- target_height,
- &layer.quads,
- transformation,
- scale_factor,
- bounds,
- );
- }
-
- if !layer.meshes.is_empty() {
- let scaled = transformation
- * Transformation::scale(scale_factor, scale_factor);
-
- self.triangle_pipeline.draw(
- &layer.meshes,
- gl,
- target_height,
- scaled,
- scale_factor,
- );
- }
-
- #[cfg(any(feature = "image", feature = "svg"))]
- if !layer.images.is_empty() {
- let scaled = transformation
- * Transformation::scale(scale_factor, scale_factor);
-
- self.image_pipeline.draw(
- gl,
- target_height,
- scaled,
- scale_factor,
- &layer.images,
- bounds,
- );
- }
-
- if !layer.text.is_empty() {
- for text in layer.text.iter() {
- // Target physical coordinates directly to avoid blurry text
- let text = glow_glyph::Section {
- // TODO: We `round` here to avoid rerasterizing text when
- // its position changes slightly. This can make text feel a
- // bit "jumpy". We may be able to do better once we improve
- // our text rendering/caching pipeline.
- screen_position: (
- (text.bounds.x * scale_factor).round(),
- (text.bounds.y * scale_factor).round(),
- ),
- // TODO: Fix precision issues with some scale factors.
- //
- // The `ceil` here can cause some words to render on the
- // same line when they should not.
- //
- // Ideally, `wgpu_glyph` should be able to compute layout
- // using logical positions, and then apply the proper
- // scaling when rendering. This would ensure that both
- // measuring and rendering follow the same layout rules.
- bounds: (
- (text.bounds.width * scale_factor).ceil(),
- (text.bounds.height * scale_factor).ceil(),
- ),
- text: vec![glow_glyph::Text {
- text: text.content,
- scale: glow_glyph::ab_glyph::PxScale {
- x: text.size * scale_factor,
- y: text.size * scale_factor,
- },
- font_id: self.text_pipeline.find_font(text.font),
- extra: glow_glyph::Extra {
- color: text.color,
- z: 0.0,
- },
- }],
- layout: glow_glyph::Layout::default()
- .h_align(match text.horizontal_alignment {
- alignment::Horizontal::Left => {
- glow_glyph::HorizontalAlign::Left
- }
- alignment::Horizontal::Center => {
- glow_glyph::HorizontalAlign::Center
- }
- alignment::Horizontal::Right => {
- glow_glyph::HorizontalAlign::Right
- }
- })
- .v_align(match text.vertical_alignment {
- alignment::Vertical::Top => {
- glow_glyph::VerticalAlign::Top
- }
- alignment::Vertical::Center => {
- glow_glyph::VerticalAlign::Center
- }
- alignment::Vertical::Bottom => {
- glow_glyph::VerticalAlign::Bottom
- }
- }),
- };
-
- self.text_pipeline.queue(text);
- }
-
- self.text_pipeline.draw_queued(
- gl,
- transformation,
- glow_glyph::Region {
- x: bounds.x,
- y: target_height - (bounds.y + bounds.height),
- width: bounds.width,
- height: bounds.height,
- },
- );
- }
- }
-}
-
-impl iced_graphics::Backend for Backend {
- fn trim_measurements(&mut self) {
- self.text_pipeline.trim_measurement_cache()
- }
-}
-
-impl backend::Text for Backend {
- const ICON_FONT: Font = font::ICONS;
- const CHECKMARK_ICON: char = font::CHECKMARK_ICON;
- const ARROW_DOWN_ICON: char = font::ARROW_DOWN_ICON;
-
- fn default_size(&self) -> f32 {
- self.default_text_size
- }
-
- fn measure(
- &self,
- contents: &str,
- size: f32,
- font: Font,
- bounds: Size,
- ) -> (f32, f32) {
- self.text_pipeline.measure(contents, size, font, bounds)
- }
-
- fn hit_test(
- &self,
- contents: &str,
- size: f32,
- font: Font,
- bounds: Size,
- point: iced_native::Point,
- nearest_only: bool,
- ) -> Option<text::Hit> {
- self.text_pipeline.hit_test(
- contents,
- size,
- font,
- bounds,
- point,
- nearest_only,
- )
- }
-}
-
-#[cfg(feature = "image")]
-impl backend::Image for Backend {
- fn dimensions(&self, handle: &iced_native::image::Handle) -> Size<u32> {
- self.image_pipeline.dimensions(handle)
- }
-}
-
-#[cfg(feature = "svg")]
-impl backend::Svg for Backend {
- fn viewport_dimensions(
- &self,
- handle: &iced_native::svg::Handle,
- ) -> Size<u32> {
- self.image_pipeline.viewport_dimensions(handle)
- }
-}