Introduce RawText to Primitive in iced_graphics
This should allow users to directly render a `cosmic_text::Buffer`.
This commit is contained in:
parent
fc285d3e46
commit
603832e66c
8 changed files with 131 additions and 4 deletions
|
|
@ -73,6 +73,11 @@ impl<T: Damage> Damage for Primitive<T> {
|
||||||
|
|
||||||
bounds.expand(1.5)
|
bounds.expand(1.5)
|
||||||
}
|
}
|
||||||
|
Self::RawText(raw) => {
|
||||||
|
// TODO: Add `size` field to `raw` to compute more accurate
|
||||||
|
// damage bounds (?)
|
||||||
|
raw.clip_bounds.expand(1.5)
|
||||||
|
}
|
||||||
Self::Quad { bounds, .. }
|
Self::Quad { bounds, .. }
|
||||||
| Self::Image { bounds, .. }
|
| Self::Image { bounds, .. }
|
||||||
| Self::Svg { bounds, .. } => bounds.expand(1.0),
|
| Self::Svg { bounds, .. } => bounds.expand(1.0),
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,8 @@ pub enum Primitive<T> {
|
||||||
/// The clip bounds of the editor.
|
/// The clip bounds of the editor.
|
||||||
clip_bounds: Rectangle,
|
clip_bounds: Rectangle,
|
||||||
},
|
},
|
||||||
|
/// A raw `cosmic-text` primitive
|
||||||
|
RawText(crate::text::Raw),
|
||||||
/// A quad primitive
|
/// A quad primitive
|
||||||
Quad {
|
Quad {
|
||||||
/// The bounds of the quad
|
/// The bounds of the quad
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,11 @@ pub use cosmic_text;
|
||||||
use crate::color;
|
use crate::color;
|
||||||
use crate::core::font::{self, Font};
|
use crate::core::font::{self, Font};
|
||||||
use crate::core::text::Shaping;
|
use crate::core::text::Shaping;
|
||||||
use crate::core::{Color, Size};
|
use crate::core::{Color, Point, Rectangle, Size};
|
||||||
|
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock, Weak};
|
||||||
|
|
||||||
/// Returns the global [`FontSystem`].
|
/// Returns the global [`FontSystem`].
|
||||||
pub fn font_system() -> &'static RwLock<FontSystem> {
|
pub fn font_system() -> &'static RwLock<FontSystem> {
|
||||||
|
|
@ -68,6 +68,29 @@ impl FontSystem {
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
pub struct Version(u32);
|
pub struct Version(u32);
|
||||||
|
|
||||||
|
/// A weak reference to a [`cosmic-text::Buffer`] that can be drawn.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Raw {
|
||||||
|
/// A weak reference to a [`cosmic_text::Buffer`].
|
||||||
|
pub buffer: Weak<cosmic_text::Buffer>,
|
||||||
|
/// The position of the text.
|
||||||
|
pub position: Point,
|
||||||
|
/// The color of the text.
|
||||||
|
pub color: Color,
|
||||||
|
/// The clip bounds of the text.
|
||||||
|
pub clip_bounds: Rectangle,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for Raw {
|
||||||
|
fn eq(&self, _other: &Self) -> bool {
|
||||||
|
// TODO: There is no proper way to compare raw buffers
|
||||||
|
// For now, no two instances of `Raw` text will be equal.
|
||||||
|
// This should be fine, but could trigger unnecessary redraws
|
||||||
|
// in the future.
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Measures the dimensions of the given [`cosmic_text::Buffer`].
|
/// Measures the dimensions of the given [`cosmic_text::Buffer`].
|
||||||
pub fn measure(buffer: &cosmic_text::Buffer) -> Size {
|
pub fn measure(buffer: &cosmic_text::Buffer) -> Size {
|
||||||
let (width, total_lines) = buffer
|
let (width, total_lines) = buffer
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::core::{Background, Color, Gradient, Rectangle, Vector};
|
use crate::core::{Background, Color, Gradient, Rectangle, Vector};
|
||||||
use crate::graphics::backend;
|
use crate::graphics::backend;
|
||||||
|
use crate::graphics::text;
|
||||||
use crate::graphics::Viewport;
|
use crate::graphics::Viewport;
|
||||||
use crate::primitive::{self, Primitive};
|
use crate::primitive::{self, Primitive};
|
||||||
|
|
||||||
|
|
@ -444,6 +445,35 @@ impl Backend {
|
||||||
clip_mask,
|
clip_mask,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Primitive::RawText(text::Raw {
|
||||||
|
buffer,
|
||||||
|
position,
|
||||||
|
color,
|
||||||
|
clip_bounds: text_clip_bounds,
|
||||||
|
}) => {
|
||||||
|
let Some(buffer) = buffer.upgrade() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let physical_bounds =
|
||||||
|
(*text_clip_bounds + translation) * scale_factor;
|
||||||
|
|
||||||
|
if !clip_bounds.intersects(&physical_bounds) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let clip_mask = (!physical_bounds.is_within(&clip_bounds))
|
||||||
|
.then_some(clip_mask as &_);
|
||||||
|
|
||||||
|
self.text_pipeline.draw_raw(
|
||||||
|
&buffer,
|
||||||
|
*position + translation,
|
||||||
|
*color,
|
||||||
|
scale_factor,
|
||||||
|
pixels,
|
||||||
|
clip_mask,
|
||||||
|
);
|
||||||
|
}
|
||||||
#[cfg(feature = "image")]
|
#[cfg(feature = "image")]
|
||||||
Primitive::Image {
|
Primitive::Image {
|
||||||
handle,
|
handle,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::core::alignment;
|
use crate::core::alignment;
|
||||||
use crate::core::text::{LineHeight, Shaping};
|
use crate::core::text::{LineHeight, Shaping};
|
||||||
use crate::core::{Color, Font, Pixels, Point, Rectangle};
|
use crate::core::{Color, Font, Pixels, Point, Rectangle, Size};
|
||||||
use crate::graphics::color;
|
use crate::graphics::color;
|
||||||
use crate::graphics::text::cache::{self, Cache};
|
use crate::graphics::text::cache::{self, Cache};
|
||||||
use crate::graphics::text::editor;
|
use crate::graphics::text::editor;
|
||||||
|
|
@ -149,6 +149,33 @@ impl Pipeline {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn draw_raw(
|
||||||
|
&mut self,
|
||||||
|
buffer: &cosmic_text::Buffer,
|
||||||
|
position: Point,
|
||||||
|
color: Color,
|
||||||
|
scale_factor: f32,
|
||||||
|
pixels: &mut tiny_skia::PixmapMut<'_>,
|
||||||
|
clip_mask: Option<&tiny_skia::Mask>,
|
||||||
|
) {
|
||||||
|
let mut font_system = font_system().write().expect("Write font system");
|
||||||
|
|
||||||
|
let (width, height) = buffer.size();
|
||||||
|
|
||||||
|
draw(
|
||||||
|
font_system.raw(),
|
||||||
|
&mut self.glyph_cache,
|
||||||
|
buffer,
|
||||||
|
Rectangle::new(position, Size::new(width, height)),
|
||||||
|
color,
|
||||||
|
alignment::Horizontal::Left,
|
||||||
|
alignment::Vertical::Top,
|
||||||
|
scale_factor,
|
||||||
|
pixels,
|
||||||
|
clip_mask,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn trim_cache(&mut self) {
|
pub fn trim_cache(&mut self) {
|
||||||
self.cache.get_mut().trim();
|
self.cache.get_mut().trim();
|
||||||
self.glyph_cache.trim();
|
self.glyph_cache.trim();
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,21 @@ impl<'a> Layer<'a> {
|
||||||
clip_bounds: *clip_bounds + translation,
|
clip_bounds: *clip_bounds + translation,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
graphics::Primitive::RawText(graphics::text::Raw {
|
||||||
|
buffer,
|
||||||
|
position,
|
||||||
|
color,
|
||||||
|
clip_bounds,
|
||||||
|
}) => {
|
||||||
|
let layer = &mut layers[current_layer];
|
||||||
|
|
||||||
|
layer.text.push(Text::Raw(graphics::text::Raw {
|
||||||
|
buffer: buffer.clone(),
|
||||||
|
position: *position + translation,
|
||||||
|
color: *color,
|
||||||
|
clip_bounds: *clip_bounds + translation,
|
||||||
|
}));
|
||||||
|
}
|
||||||
Primitive::Quad {
|
Primitive::Quad {
|
||||||
bounds,
|
bounds,
|
||||||
background,
|
background,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::core::alignment;
|
use crate::core::alignment;
|
||||||
use crate::core::text;
|
use crate::core::text;
|
||||||
use crate::core::{Color, Font, Pixels, Point, Rectangle};
|
use crate::core::{Color, Font, Pixels, Point, Rectangle};
|
||||||
|
use crate::graphics;
|
||||||
use crate::graphics::text::editor;
|
use crate::graphics::text::editor;
|
||||||
use crate::graphics::text::paragraph;
|
use crate::graphics::text::paragraph;
|
||||||
|
|
||||||
|
|
@ -23,8 +24,10 @@ pub enum Text<'a> {
|
||||||
color: Color,
|
color: Color,
|
||||||
clip_bounds: Rectangle,
|
clip_bounds: Rectangle,
|
||||||
},
|
},
|
||||||
/// A cached text.
|
/// Some cached text.
|
||||||
Cached(Cached<'a>),
|
Cached(Cached<'a>),
|
||||||
|
/// Some raw text.
|
||||||
|
Raw(graphics::text::Raw),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ use crate::layer::Text;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
pub struct Pipeline {
|
pub struct Pipeline {
|
||||||
|
|
@ -76,6 +77,7 @@ impl Pipeline {
|
||||||
Paragraph(Paragraph),
|
Paragraph(Paragraph),
|
||||||
Editor(Editor),
|
Editor(Editor),
|
||||||
Cache(cache::KeyHash),
|
Cache(cache::KeyHash),
|
||||||
|
Raw(Arc<glyphon::Buffer>),
|
||||||
}
|
}
|
||||||
|
|
||||||
let allocations: Vec<_> = sections
|
let allocations: Vec<_> = sections
|
||||||
|
|
@ -107,6 +109,7 @@ impl Pipeline {
|
||||||
|
|
||||||
Some(Allocation::Cache(key))
|
Some(Allocation::Cache(key))
|
||||||
}
|
}
|
||||||
|
Text::Raw(text) => text.buffer.upgrade().map(Allocation::Raw),
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
|
@ -185,6 +188,25 @@ impl Pipeline {
|
||||||
text.clip_bounds,
|
text.clip_bounds,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Text::Raw(text) => {
|
||||||
|
let Some(Allocation::Raw(buffer)) = allocation else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
|
let (width, height) = buffer.size();
|
||||||
|
|
||||||
|
(
|
||||||
|
buffer.as_ref(),
|
||||||
|
Rectangle::new(
|
||||||
|
text.position,
|
||||||
|
Size::new(width, height),
|
||||||
|
),
|
||||||
|
alignment::Horizontal::Left,
|
||||||
|
alignment::Vertical::Top,
|
||||||
|
text.color,
|
||||||
|
text.clip_bounds,
|
||||||
|
)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let bounds = bounds * scale_factor;
|
let bounds = bounds * scale_factor;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue