Refactor some image traits a bit
- Use `Size<u32>` were applicable. - Rename `TextureStore` to `image::Storage`. - Rename `TextureStoreEntry` to `image::storage::Entry`. - Wire up `viewport_dimensions` to `iced_glow` for `Svg`.
This commit is contained in:
parent
5575e6ea08
commit
8ce8d374b1
20 changed files with 164 additions and 127 deletions
|
|
@ -258,7 +258,7 @@ impl backend::Text for Backend {
|
||||||
|
|
||||||
#[cfg(feature = "image_rs")]
|
#[cfg(feature = "image_rs")]
|
||||||
impl backend::Image for Backend {
|
impl backend::Image for Backend {
|
||||||
fn dimensions(&self, handle: &iced_native::image::Handle) -> (u32, u32) {
|
fn dimensions(&self, handle: &iced_native::image::Handle) -> Size<u32> {
|
||||||
self.image_pipeline.dimensions(handle)
|
self.image_pipeline.dimensions(handle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -267,8 +267,8 @@ impl backend::Image for Backend {
|
||||||
impl backend::Svg for Backend {
|
impl backend::Svg for Backend {
|
||||||
fn viewport_dimensions(
|
fn viewport_dimensions(
|
||||||
&self,
|
&self,
|
||||||
_handle: &iced_native::svg::Handle,
|
handle: &iced_native::svg::Handle,
|
||||||
) -> (u32, u32) {
|
) -> Size<u32> {
|
||||||
(50, 50)
|
self.image_pipeline.viewport_dimensions(handle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,24 @@
|
||||||
use crate::program::{self, Shader};
|
mod storage;
|
||||||
use crate::Transformation;
|
|
||||||
use glow::HasContext;
|
use storage::Storage;
|
||||||
use iced_graphics::layer;
|
|
||||||
#[cfg(feature = "image_rs")]
|
|
||||||
use std::cell::RefCell;
|
|
||||||
|
|
||||||
pub use iced_graphics::triangle::{Mesh2D, Vertex2D};
|
pub use iced_graphics::triangle::{Mesh2D, Vertex2D};
|
||||||
|
|
||||||
|
use crate::program::{self, Shader};
|
||||||
|
use crate::Transformation;
|
||||||
|
|
||||||
#[cfg(feature = "image_rs")]
|
#[cfg(feature = "image_rs")]
|
||||||
use iced_graphics::image::raster;
|
use iced_graphics::image::raster;
|
||||||
|
|
||||||
#[cfg(feature = "svg")]
|
#[cfg(feature = "svg")]
|
||||||
use iced_graphics::image::vector;
|
use iced_graphics::image::vector;
|
||||||
|
|
||||||
mod textures;
|
use iced_graphics::layer;
|
||||||
use textures::{Entry, Textures};
|
use iced_graphics::Size;
|
||||||
|
|
||||||
|
use glow::HasContext;
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct Pipeline {
|
pub(crate) struct Pipeline {
|
||||||
|
|
@ -22,11 +26,11 @@ pub(crate) struct Pipeline {
|
||||||
vertex_array: <glow::Context as HasContext>::VertexArray,
|
vertex_array: <glow::Context as HasContext>::VertexArray,
|
||||||
vertex_buffer: <glow::Context as HasContext>::Buffer,
|
vertex_buffer: <glow::Context as HasContext>::Buffer,
|
||||||
transform_location: <glow::Context as HasContext>::UniformLocation,
|
transform_location: <glow::Context as HasContext>::UniformLocation,
|
||||||
textures: Textures,
|
storage: Storage,
|
||||||
#[cfg(feature = "image_rs")]
|
#[cfg(feature = "image_rs")]
|
||||||
raster_cache: RefCell<raster::Cache<Textures>>,
|
raster_cache: RefCell<raster::Cache<Storage>>,
|
||||||
#[cfg(feature = "svg")]
|
#[cfg(feature = "svg")]
|
||||||
vector_cache: vector::Cache<Textures>,
|
vector_cache: RefCell<vector::Cache<Storage>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pipeline {
|
impl Pipeline {
|
||||||
|
|
@ -110,22 +114,30 @@ impl Pipeline {
|
||||||
vertex_array,
|
vertex_array,
|
||||||
vertex_buffer,
|
vertex_buffer,
|
||||||
transform_location,
|
transform_location,
|
||||||
textures: Textures::new(),
|
storage: Storage::default(),
|
||||||
#[cfg(feature = "image_rs")]
|
#[cfg(feature = "image_rs")]
|
||||||
raster_cache: RefCell::new(raster::Cache::default()),
|
raster_cache: RefCell::new(raster::Cache::default()),
|
||||||
#[cfg(feature = "svg")]
|
#[cfg(feature = "svg")]
|
||||||
vector_cache: vector::Cache::default(),
|
vector_cache: RefCell::new(vector::Cache::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "image_rs")]
|
#[cfg(feature = "image_rs")]
|
||||||
pub fn dimensions(
|
pub fn dimensions(&self, handle: &iced_native::image::Handle) -> Size<u32> {
|
||||||
&self,
|
|
||||||
handle: &iced_native::image::Handle,
|
|
||||||
) -> (u32, u32) {
|
|
||||||
self.raster_cache.borrow_mut().load(handle).dimensions()
|
self.raster_cache.borrow_mut().load(handle).dimensions()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "svg")]
|
||||||
|
pub fn viewport_dimensions(
|
||||||
|
&self,
|
||||||
|
handle: &iced_native::svg::Handle,
|
||||||
|
) -> Size<u32> {
|
||||||
|
let mut cache = self.vector_cache.borrow_mut();
|
||||||
|
let svg = cache.load(handle);
|
||||||
|
|
||||||
|
svg.viewport_dimensions()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn draw(
|
pub fn draw(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut gl: &glow::Context,
|
mut gl: &glow::Context,
|
||||||
|
|
@ -141,11 +153,15 @@ impl Pipeline {
|
||||||
|
|
||||||
#[cfg(feature = "image_rs")]
|
#[cfg(feature = "image_rs")]
|
||||||
let mut raster_cache = self.raster_cache.borrow_mut();
|
let mut raster_cache = self.raster_cache.borrow_mut();
|
||||||
|
|
||||||
|
#[cfg(feature = "svg")]
|
||||||
|
let mut vector_cache = self.vector_cache.borrow_mut();
|
||||||
|
|
||||||
for image in images {
|
for image in images {
|
||||||
let (entry, bounds) = match &image {
|
let (entry, bounds) = match &image {
|
||||||
#[cfg(feature = "image_rs")]
|
#[cfg(feature = "image_rs")]
|
||||||
layer::Image::Raster { handle, bounds } => (
|
layer::Image::Raster { handle, bounds } => (
|
||||||
raster_cache.upload(handle, &mut gl, &mut self.textures),
|
raster_cache.upload(handle, &mut gl, &mut self.storage),
|
||||||
bounds,
|
bounds,
|
||||||
),
|
),
|
||||||
#[cfg(not(feature = "image_rs"))]
|
#[cfg(not(feature = "image_rs"))]
|
||||||
|
|
@ -155,12 +171,12 @@ impl Pipeline {
|
||||||
layer::Image::Vector { handle, bounds } => {
|
layer::Image::Vector { handle, bounds } => {
|
||||||
let size = [bounds.width, bounds.height];
|
let size = [bounds.width, bounds.height];
|
||||||
(
|
(
|
||||||
self.vector_cache.upload(
|
vector_cache.upload(
|
||||||
handle,
|
handle,
|
||||||
size,
|
size,
|
||||||
_scale_factor,
|
_scale_factor,
|
||||||
&mut gl,
|
&mut gl,
|
||||||
&mut self.textures,
|
&mut self.storage,
|
||||||
),
|
),
|
||||||
bounds,
|
bounds,
|
||||||
)
|
)
|
||||||
|
|
@ -171,7 +187,7 @@ impl Pipeline {
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some(Entry { texture, .. }) = entry {
|
if let Some(storage::Entry { texture, .. }) = entry {
|
||||||
gl.bind_texture(glow::TEXTURE_2D, Some(*texture))
|
gl.bind_texture(glow::TEXTURE_2D, Some(*texture))
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -204,9 +220,11 @@ impl Pipeline {
|
||||||
#[cfg(feature = "image_rs")]
|
#[cfg(feature = "image_rs")]
|
||||||
self.raster_cache
|
self.raster_cache
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.trim(&mut self.textures, &mut gl);
|
.trim(&mut self.storage, &mut gl);
|
||||||
|
|
||||||
#[cfg(feature = "svg")]
|
#[cfg(feature = "svg")]
|
||||||
self.vector_cache.trim(&mut self.textures, &mut gl);
|
self.vector_cache
|
||||||
|
.borrow_mut()
|
||||||
|
.trim(&mut self.storage, &mut gl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,12 @@
|
||||||
|
use iced_graphics::image;
|
||||||
|
use iced_graphics::Size;
|
||||||
|
|
||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
use iced_graphics::image::{TextureStore, TextureStoreEntry};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Textures;
|
pub struct Storage;
|
||||||
|
|
||||||
impl Textures {
|
impl image::Storage for Storage {
|
||||||
pub fn new() -> Self {
|
|
||||||
Self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TextureStore for Textures {
|
|
||||||
type Entry = Entry;
|
type Entry = Entry;
|
||||||
type State<'a> = &'a glow::Context;
|
type State<'a> = &'a glow::Context;
|
||||||
|
|
||||||
|
|
@ -58,7 +54,7 @@ impl TextureStore for Textures {
|
||||||
gl.bind_texture(glow::TEXTURE_2D, None);
|
gl.bind_texture(glow::TEXTURE_2D, None);
|
||||||
|
|
||||||
Some(Entry {
|
Some(Entry {
|
||||||
size: (width, height),
|
size: Size::new(width, height),
|
||||||
texture,
|
texture,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -71,12 +67,12 @@ impl TextureStore for Textures {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Entry {
|
pub struct Entry {
|
||||||
size: (u32, u32),
|
size: Size<u32>,
|
||||||
pub texture: glow::NativeTexture,
|
pub(super) texture: glow::NativeTexture,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextureStoreEntry for Entry {
|
impl image::storage::Entry for Entry {
|
||||||
fn size(&self) -> (u32, u32) {
|
fn size(&self) -> Size<u32> {
|
||||||
self.size
|
self.size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -66,11 +66,11 @@ pub trait Text {
|
||||||
/// A graphics backend that supports image rendering.
|
/// A graphics backend that supports image rendering.
|
||||||
pub trait Image {
|
pub trait Image {
|
||||||
/// Returns the dimensions of the provided image.
|
/// Returns the dimensions of the provided image.
|
||||||
fn dimensions(&self, handle: &image::Handle) -> (u32, u32);
|
fn dimensions(&self, handle: &image::Handle) -> Size<u32>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A graphics backend that supports SVG rendering.
|
/// A graphics backend that supports SVG rendering.
|
||||||
pub trait Svg {
|
pub trait Svg {
|
||||||
/// Returns the viewport dimensions of the provided SVG.
|
/// Returns the viewport dimensions of the provided SVG.
|
||||||
fn viewport_dimensions(&self, handle: &svg::Handle) -> (u32, u32);
|
fn viewport_dimensions(&self, handle: &svg::Handle) -> Size<u32>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,10 @@
|
||||||
//! Image loading and caching
|
//! Render images.
|
||||||
|
|
||||||
use std::fmt::Debug;
|
|
||||||
|
|
||||||
#[cfg(feature = "image_rs")]
|
#[cfg(feature = "image_rs")]
|
||||||
pub mod raster;
|
pub mod raster;
|
||||||
|
|
||||||
#[cfg(feature = "svg")]
|
#[cfg(feature = "svg")]
|
||||||
pub mod vector;
|
pub mod vector;
|
||||||
|
|
||||||
/// Entry in the texture store
|
pub mod storage;
|
||||||
pub trait TextureStoreEntry: Debug {
|
|
||||||
/// Width and height of the entry
|
|
||||||
fn size(&self) -> (u32, u32);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Stores cached image data for use in rendering
|
pub use storage::Storage;
|
||||||
pub trait TextureStore {
|
|
||||||
/// Entry in the texture store
|
|
||||||
type Entry: TextureStoreEntry;
|
|
||||||
/// State passed to upload/remove
|
|
||||||
type State<'a>;
|
|
||||||
|
|
||||||
/// Upload image data
|
|
||||||
fn upload(
|
|
||||||
&mut self,
|
|
||||||
width: u32,
|
|
||||||
height: u32,
|
|
||||||
data: &[u8],
|
|
||||||
state: &mut Self::State<'_>,
|
|
||||||
) -> Option<Self::Entry>;
|
|
||||||
/// Remome image from store
|
|
||||||
fn remove(&mut self, entry: &Self::Entry, state: &mut Self::State<'_>);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
//! Raster image loading and caching
|
//! Raster image loading and caching.
|
||||||
|
use crate::image::Storage;
|
||||||
|
use crate::Size;
|
||||||
|
|
||||||
use iced_native::image;
|
use iced_native::image;
|
||||||
use std::collections::{HashMap, HashSet};
|
|
||||||
|
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
use super::{TextureStore, TextureStoreEntry};
|
|
||||||
|
|
||||||
/// Entry in cache corresponding to an image handle
|
/// Entry in cache corresponding to an image handle
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Memory<T: TextureStore> {
|
pub enum Memory<T: Storage> {
|
||||||
/// Image data on host
|
/// Image data on host
|
||||||
Host(::image_rs::ImageBuffer<::image_rs::Rgba<u8>, Vec<u8>>),
|
Host(::image_rs::ImageBuffer<::image_rs::Rgba<u8>, Vec<u8>>),
|
||||||
/// Texture store entry
|
/// Texture store entry
|
||||||
|
|
@ -20,26 +20,32 @@ pub enum Memory<T: TextureStore> {
|
||||||
Invalid,
|
Invalid,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: TextureStore> Memory<T> {
|
impl<T: Storage> Memory<T> {
|
||||||
/// Width and height of image
|
/// Width and height of image
|
||||||
pub fn dimensions(&self) -> (u32, u32) {
|
pub fn dimensions(&self) -> Size<u32> {
|
||||||
|
use crate::image::storage::Entry;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Memory::Host(image) => image.dimensions(),
|
Memory::Host(image) => {
|
||||||
|
let (width, height) = image.dimensions();
|
||||||
|
|
||||||
|
Size::new(width, height)
|
||||||
|
}
|
||||||
Memory::Device(entry) => entry.size(),
|
Memory::Device(entry) => entry.size(),
|
||||||
Memory::NotFound => (1, 1),
|
Memory::NotFound => Size::new(1, 1),
|
||||||
Memory::Invalid => (1, 1),
|
Memory::Invalid => Size::new(1, 1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Caches image raster data
|
/// Caches image raster data
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Cache<T: TextureStore> {
|
pub struct Cache<T: Storage> {
|
||||||
map: HashMap<u64, Memory<T>>,
|
map: HashMap<u64, Memory<T>>,
|
||||||
hits: HashSet<u64>,
|
hits: HashSet<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: TextureStore> Cache<T> {
|
impl<T: Storage> Cache<T> {
|
||||||
/// Load image
|
/// Load image
|
||||||
pub fn load(&mut self, handle: &image::Handle) -> &mut Memory<T> {
|
pub fn load(&mut self, handle: &image::Handle) -> &mut Memory<T> {
|
||||||
if self.contains(handle) {
|
if self.contains(handle) {
|
||||||
|
|
@ -153,7 +159,7 @@ impl<T: TextureStore> Cache<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: TextureStore> Default for Cache<T> {
|
impl<T: Storage> Default for Cache<T> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
map: HashMap::new(),
|
map: HashMap::new(),
|
||||||
|
|
|
||||||
31
graphics/src/image/storage.rs
Normal file
31
graphics/src/image/storage.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
//! Store images.
|
||||||
|
use crate::Size;
|
||||||
|
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
/// Stores cached image data for use in rendering
|
||||||
|
pub trait Storage {
|
||||||
|
/// The type of an [`Entry`] in the [`Storage`].
|
||||||
|
type Entry: Entry;
|
||||||
|
|
||||||
|
/// State provided to upload or remove a [`Self::Entry`].
|
||||||
|
type State<'a>;
|
||||||
|
|
||||||
|
/// Upload the image data of a [`Self::Entry`].
|
||||||
|
fn upload(
|
||||||
|
&mut self,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
data: &[u8],
|
||||||
|
state: &mut Self::State<'_>,
|
||||||
|
) -> Option<Self::Entry>;
|
||||||
|
|
||||||
|
/// Romve a [`Self::Entry`] from the [`Storage`].
|
||||||
|
fn remove(&mut self, entry: &Self::Entry, state: &mut Self::State<'_>);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An entry in some [`Storage`],
|
||||||
|
pub trait Entry: Debug {
|
||||||
|
/// The [`Size`] of the [`Entry`].
|
||||||
|
fn size(&self) -> Size<u32>;
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
//! Vector image loading and caching
|
//! Vector image loading and caching
|
||||||
|
use crate::image::Storage;
|
||||||
|
|
||||||
use iced_native::svg;
|
use iced_native::svg;
|
||||||
|
use iced_native::Size;
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
use super::TextureStore;
|
|
||||||
|
|
||||||
/// Entry in cache corresponding to an svg handle
|
/// Entry in cache corresponding to an svg handle
|
||||||
pub enum Svg {
|
pub enum Svg {
|
||||||
/// Parsed svg
|
/// Parsed svg
|
||||||
|
|
@ -17,28 +17,28 @@ pub enum Svg {
|
||||||
|
|
||||||
impl Svg {
|
impl Svg {
|
||||||
/// Viewport width and height
|
/// Viewport width and height
|
||||||
pub fn viewport_dimensions(&self) -> (u32, u32) {
|
pub fn viewport_dimensions(&self) -> Size<u32> {
|
||||||
match self {
|
match self {
|
||||||
Svg::Loaded(tree) => {
|
Svg::Loaded(tree) => {
|
||||||
let size = tree.svg_node().size;
|
let size = tree.svg_node().size;
|
||||||
|
|
||||||
(size.width() as u32, size.height() as u32)
|
Size::new(size.width() as u32, size.height() as u32)
|
||||||
}
|
}
|
||||||
Svg::NotFound => (1, 1),
|
Svg::NotFound => Size::new(1, 1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Caches svg vector and raster data
|
/// Caches svg vector and raster data
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Cache<T: TextureStore> {
|
pub struct Cache<T: Storage> {
|
||||||
svgs: HashMap<u64, Svg>,
|
svgs: HashMap<u64, Svg>,
|
||||||
rasterized: HashMap<(u64, u32, u32), T::Entry>,
|
rasterized: HashMap<(u64, u32, u32), T::Entry>,
|
||||||
svg_hits: HashSet<u64>,
|
svg_hits: HashSet<u64>,
|
||||||
rasterized_hits: HashSet<(u64, u32, u32)>,
|
rasterized_hits: HashSet<(u64, u32, u32)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: TextureStore> Cache<T> {
|
impl<T: Storage> Cache<T> {
|
||||||
/// Load svg
|
/// Load svg
|
||||||
pub fn load(&mut self, handle: &svg::Handle) -> &Svg {
|
pub fn load(&mut self, handle: &svg::Handle) -> &Svg {
|
||||||
if self.svgs.contains_key(&handle.id()) {
|
if self.svgs.contains_key(&handle.id()) {
|
||||||
|
|
@ -162,7 +162,7 @@ impl<T: TextureStore> Cache<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: TextureStore> Default for Cache<T> {
|
impl<T: Storage> Default for Cache<T> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
svgs: HashMap::new(),
|
svgs: HashMap::new(),
|
||||||
|
|
|
||||||
|
|
@ -183,7 +183,7 @@ where
|
||||||
{
|
{
|
||||||
type Handle = image::Handle;
|
type Handle = image::Handle;
|
||||||
|
|
||||||
fn dimensions(&self, handle: &image::Handle) -> (u32, u32) {
|
fn dimensions(&self, handle: &image::Handle) -> Size<u32> {
|
||||||
self.backend().dimensions(handle)
|
self.backend().dimensions(handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,7 +196,7 @@ impl<B, T> svg::Renderer for Renderer<B, T>
|
||||||
where
|
where
|
||||||
B: Backend + backend::Svg,
|
B: Backend + backend::Svg,
|
||||||
{
|
{
|
||||||
fn dimensions(&self, handle: &svg::Handle) -> (u32, u32) {
|
fn dimensions(&self, handle: &svg::Handle) -> Size<u32> {
|
||||||
self.backend().viewport_dimensions(handle)
|
self.backend().viewport_dimensions(handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//! Load and draw raster graphics.
|
//! Load and draw raster graphics.
|
||||||
use crate::{Hasher, Rectangle};
|
use crate::{Hasher, Rectangle, Size};
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::hash::{Hash, Hasher as _};
|
use std::hash::{Hash, Hasher as _};
|
||||||
|
|
@ -126,7 +126,7 @@ pub trait Renderer: crate::Renderer {
|
||||||
type Handle: Clone + Hash;
|
type Handle: Clone + Hash;
|
||||||
|
|
||||||
/// Returns the dimensions of an image for the given [`Handle`].
|
/// Returns the dimensions of an image for the given [`Handle`].
|
||||||
fn dimensions(&self, handle: &Self::Handle) -> (u32, u32);
|
fn dimensions(&self, handle: &Self::Handle) -> Size<u32>;
|
||||||
|
|
||||||
/// Draws an image with the given [`Handle`] and inside the provided
|
/// Draws an image with the given [`Handle`] and inside the provided
|
||||||
/// `bounds`.
|
/// `bounds`.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//! Load and draw vector graphics.
|
//! Load and draw vector graphics.
|
||||||
use crate::{Hasher, Rectangle};
|
use crate::{Hasher, Rectangle, Size};
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::hash::{Hash, Hasher as _};
|
use std::hash::{Hash, Hasher as _};
|
||||||
|
|
@ -82,7 +82,7 @@ impl std::fmt::Debug for Data {
|
||||||
/// [renderer]: crate::renderer
|
/// [renderer]: crate::renderer
|
||||||
pub trait Renderer: crate::Renderer {
|
pub trait Renderer: crate::Renderer {
|
||||||
/// Returns the default dimensions of an SVG for the given [`Handle`].
|
/// Returns the default dimensions of an SVG for the given [`Handle`].
|
||||||
fn dimensions(&self, handle: &Handle) -> (u32, u32);
|
fn dimensions(&self, handle: &Handle) -> Size<u32>;
|
||||||
|
|
||||||
/// Draws an SVG with the given [`Handle`] and inside the provided `bounds`.
|
/// Draws an SVG with the given [`Handle`] and inside the provided `bounds`.
|
||||||
fn draw(&mut self, handle: Handle, bounds: Rectangle);
|
fn draw(&mut self, handle: Handle, bounds: Rectangle);
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ where
|
||||||
{
|
{
|
||||||
// The raw w/h of the underlying image
|
// The raw w/h of the underlying image
|
||||||
let image_size = {
|
let image_size = {
|
||||||
let (width, height) = renderer.dimensions(handle);
|
let Size { width, height } = renderer.dimensions(handle);
|
||||||
|
|
||||||
Size::new(width as f32, height as f32)
|
Size::new(width as f32, height as f32)
|
||||||
};
|
};
|
||||||
|
|
@ -149,7 +149,7 @@ where
|
||||||
_cursor_position: Point,
|
_cursor_position: Point,
|
||||||
_viewport: &Rectangle,
|
_viewport: &Rectangle,
|
||||||
) {
|
) {
|
||||||
let (width, height) = renderer.dimensions(&self.handle);
|
let Size { width, height } = renderer.dimensions(&self.handle);
|
||||||
let image_size = Size::new(width as f32, height as f32);
|
let image_size = Size::new(width as f32, height as f32);
|
||||||
|
|
||||||
let bounds = layout.bounds();
|
let bounds = layout.bounds();
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ where
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
limits: &layout::Limits,
|
limits: &layout::Limits,
|
||||||
) -> layout::Node {
|
) -> layout::Node {
|
||||||
let (width, height) = renderer.dimensions(&self.handle);
|
let Size { width, height } = renderer.dimensions(&self.handle);
|
||||||
|
|
||||||
let mut size = limits
|
let mut size = limits
|
||||||
.width(self.width)
|
.width(self.width)
|
||||||
|
|
@ -409,7 +409,7 @@ pub fn image_size<Renderer>(
|
||||||
where
|
where
|
||||||
Renderer: image::Renderer,
|
Renderer: image::Renderer,
|
||||||
{
|
{
|
||||||
let (width, height) = renderer.dimensions(handle);
|
let Size { width, height } = renderer.dimensions(handle);
|
||||||
|
|
||||||
let (width, height) = {
|
let (width, height) = {
|
||||||
let dimensions = (width as f32, height as f32);
|
let dimensions = (width as f32, height as f32);
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ where
|
||||||
limits: &layout::Limits,
|
limits: &layout::Limits,
|
||||||
) -> layout::Node {
|
) -> layout::Node {
|
||||||
// The raw w/h of the underlying image
|
// The raw w/h of the underlying image
|
||||||
let (width, height) = renderer.dimensions(&self.handle);
|
let Size { width, height } = renderer.dimensions(&self.handle);
|
||||||
let image_size = Size::new(width as f32, height as f32);
|
let image_size = Size::new(width as f32, height as f32);
|
||||||
|
|
||||||
// The size to be available to the widget prior to `Shrink`ing
|
// The size to be available to the widget prior to `Shrink`ing
|
||||||
|
|
@ -120,7 +120,7 @@ where
|
||||||
_cursor_position: Point,
|
_cursor_position: Point,
|
||||||
_viewport: &Rectangle,
|
_viewport: &Rectangle,
|
||||||
) {
|
) {
|
||||||
let (width, height) = renderer.dimensions(&self.handle);
|
let Size { width, height } = renderer.dimensions(&self.handle);
|
||||||
let image_size = Size::new(width as f32, height as f32);
|
let image_size = Size::new(width as f32, height as f32);
|
||||||
|
|
||||||
let bounds = layout.bounds();
|
let bounds = layout.bounds();
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,7 @@ impl backend::Text for Backend {
|
||||||
|
|
||||||
#[cfg(feature = "image_rs")]
|
#[cfg(feature = "image_rs")]
|
||||||
impl backend::Image for Backend {
|
impl backend::Image for Backend {
|
||||||
fn dimensions(&self, handle: &iced_native::image::Handle) -> (u32, u32) {
|
fn dimensions(&self, handle: &iced_native::image::Handle) -> Size<u32> {
|
||||||
self.image_pipeline.dimensions(handle)
|
self.image_pipeline.dimensions(handle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -306,7 +306,7 @@ impl backend::Svg for Backend {
|
||||||
fn viewport_dimensions(
|
fn viewport_dimensions(
|
||||||
&self,
|
&self,
|
||||||
handle: &iced_native::svg::Handle,
|
handle: &iced_native::svg::Handle,
|
||||||
) -> (u32, u32) {
|
) -> Size<u32> {
|
||||||
self.image_pipeline.viewport_dimensions(handle)
|
self.image_pipeline.viewport_dimensions(handle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ use crate::Transformation;
|
||||||
use atlas::Atlas;
|
use atlas::Atlas;
|
||||||
|
|
||||||
use iced_graphics::layer;
|
use iced_graphics::layer;
|
||||||
use iced_native::Rectangle;
|
use iced_native::{Rectangle, Size};
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
|
@ -262,7 +263,7 @@ impl Pipeline {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "image_rs")]
|
#[cfg(feature = "image_rs")]
|
||||||
pub fn dimensions(&self, handle: &image::Handle) -> (u32, u32) {
|
pub fn dimensions(&self, handle: &image::Handle) -> Size<u32> {
|
||||||
let mut cache = self.raster_cache.borrow_mut();
|
let mut cache = self.raster_cache.borrow_mut();
|
||||||
let memory = cache.load(handle);
|
let memory = cache.load(handle);
|
||||||
|
|
||||||
|
|
@ -270,7 +271,7 @@ impl Pipeline {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "svg")]
|
#[cfg(feature = "svg")]
|
||||||
pub fn viewport_dimensions(&self, handle: &svg::Handle) -> (u32, u32) {
|
pub fn viewport_dimensions(&self, handle: &svg::Handle) -> Size<u32> {
|
||||||
let mut cache = self.vector_cache.borrow_mut();
|
let mut cache = self.vector_cache.borrow_mut();
|
||||||
let svg = cache.load(handle);
|
let svg = cache.load(handle);
|
||||||
|
|
||||||
|
|
@ -515,15 +516,18 @@ fn add_instances(
|
||||||
add_instance(image_position, image_size, allocation, instances);
|
add_instance(image_position, image_size, allocation, instances);
|
||||||
}
|
}
|
||||||
atlas::Entry::Fragmented { fragments, size } => {
|
atlas::Entry::Fragmented { fragments, size } => {
|
||||||
let scaling_x = image_size[0] / size.0 as f32;
|
let scaling_x = image_size[0] / size.width as f32;
|
||||||
let scaling_y = image_size[1] / size.1 as f32;
|
let scaling_y = image_size[1] / size.height as f32;
|
||||||
|
|
||||||
for fragment in fragments {
|
for fragment in fragments {
|
||||||
let allocation = &fragment.allocation;
|
let allocation = &fragment.allocation;
|
||||||
|
|
||||||
let [x, y] = image_position;
|
let [x, y] = image_position;
|
||||||
let (fragment_x, fragment_y) = fragment.position;
|
let (fragment_x, fragment_y) = fragment.position;
|
||||||
let (fragment_width, fragment_height) = allocation.size();
|
let Size {
|
||||||
|
width: fragment_width,
|
||||||
|
height: fragment_height,
|
||||||
|
} = allocation.size();
|
||||||
|
|
||||||
let position = [
|
let position = [
|
||||||
x + fragment_x as f32 * scaling_x,
|
x + fragment_x as f32 * scaling_x,
|
||||||
|
|
@ -549,7 +553,7 @@ fn add_instance(
|
||||||
instances: &mut Vec<Instance>,
|
instances: &mut Vec<Instance>,
|
||||||
) {
|
) {
|
||||||
let (x, y) = allocation.position();
|
let (x, y) = allocation.position();
|
||||||
let (width, height) = allocation.size();
|
let Size { width, height } = allocation.size();
|
||||||
let layer = allocation.layer();
|
let layer = allocation.layer();
|
||||||
|
|
||||||
let instance = Instance {
|
let instance = Instance {
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,6 @@ mod allocation;
|
||||||
mod allocator;
|
mod allocator;
|
||||||
mod layer;
|
mod layer;
|
||||||
|
|
||||||
use iced_graphics::image::TextureStore;
|
|
||||||
use std::num::NonZeroU32;
|
|
||||||
|
|
||||||
pub use allocation::Allocation;
|
pub use allocation::Allocation;
|
||||||
pub use entry::Entry;
|
pub use entry::Entry;
|
||||||
pub use layer::Layer;
|
pub use layer::Layer;
|
||||||
|
|
@ -15,6 +12,11 @@ use allocator::Allocator;
|
||||||
|
|
||||||
pub const SIZE: u32 = 2048;
|
pub const SIZE: u32 = 2048;
|
||||||
|
|
||||||
|
use iced_graphics::image;
|
||||||
|
use iced_graphics::Size;
|
||||||
|
|
||||||
|
use std::num::NonZeroU32;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Atlas {
|
pub struct Atlas {
|
||||||
texture: wgpu::Texture,
|
texture: wgpu::Texture,
|
||||||
|
|
@ -112,7 +114,7 @@ impl Atlas {
|
||||||
}
|
}
|
||||||
|
|
||||||
return Some(Entry::Fragmented {
|
return Some(Entry::Fragmented {
|
||||||
size: (width, height),
|
size: Size::new(width, height),
|
||||||
fragments,
|
fragments,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -192,7 +194,7 @@ impl Atlas {
|
||||||
encoder: &mut wgpu::CommandEncoder,
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
) {
|
) {
|
||||||
let (x, y) = allocation.position();
|
let (x, y) = allocation.position();
|
||||||
let (width, height) = allocation.size();
|
let Size { width, height } = allocation.size();
|
||||||
let layer = allocation.layer();
|
let layer = allocation.layer();
|
||||||
|
|
||||||
let extent = wgpu::Extent3d {
|
let extent = wgpu::Extent3d {
|
||||||
|
|
@ -297,7 +299,7 @@ impl Atlas {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextureStore for Atlas {
|
impl image::Storage for Atlas {
|
||||||
type Entry = Entry;
|
type Entry = Entry;
|
||||||
type State<'a> = (&'a wgpu::Device, &'a mut wgpu::CommandEncoder);
|
type State<'a> = (&'a wgpu::Device, &'a mut wgpu::CommandEncoder);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
use crate::image::atlas::{self, allocator};
|
use crate::image::atlas::{self, allocator};
|
||||||
|
|
||||||
|
use iced_graphics::Size;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Allocation {
|
pub enum Allocation {
|
||||||
Partial {
|
Partial {
|
||||||
|
|
@ -19,10 +21,10 @@ impl Allocation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn size(&self) -> (u32, u32) {
|
pub fn size(&self) -> Size<u32> {
|
||||||
match self {
|
match self {
|
||||||
Allocation::Partial { region, .. } => region.size(),
|
Allocation::Partial { region, .. } => region.size(),
|
||||||
Allocation::Full { .. } => (atlas::SIZE, atlas::SIZE),
|
Allocation::Full { .. } => Size::new(atlas::SIZE, atlas::SIZE),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,10 +46,10 @@ impl Region {
|
||||||
(rectangle.min.x as u32, rectangle.min.y as u32)
|
(rectangle.min.x as u32, rectangle.min.y as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn size(&self) -> (u32, u32) {
|
pub fn size(&self) -> iced_graphics::Size<u32> {
|
||||||
let size = self.allocation.rectangle.size();
|
let size = self.allocation.rectangle.size();
|
||||||
|
|
||||||
(size.width as u32, size.height as u32)
|
iced_graphics::Size::new(size.width as u32, size.height as u32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,19 @@
|
||||||
use crate::image::atlas;
|
use crate::image::atlas;
|
||||||
use iced_graphics::image::TextureStoreEntry;
|
|
||||||
|
use iced_graphics::image;
|
||||||
|
use iced_graphics::Size;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Entry {
|
pub enum Entry {
|
||||||
Contiguous(atlas::Allocation),
|
Contiguous(atlas::Allocation),
|
||||||
Fragmented {
|
Fragmented {
|
||||||
size: (u32, u32),
|
size: Size<u32>,
|
||||||
fragments: Vec<Fragment>,
|
fragments: Vec<Fragment>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextureStoreEntry for Entry {
|
impl image::storage::Entry for Entry {
|
||||||
fn size(&self) -> (u32, u32) {
|
fn size(&self) -> Size<u32> {
|
||||||
match self {
|
match self {
|
||||||
Entry::Contiguous(allocation) => allocation.size(),
|
Entry::Contiguous(allocation) => allocation.size(),
|
||||||
Entry::Fragmented { size, .. } => *size,
|
Entry::Fragmented { size, .. } => *size,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue