summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--graphics/src/damage.rs5
-rw-r--r--graphics/src/primitive.rs2
-rw-r--r--graphics/src/text.rs27
-rw-r--r--tiny_skia/src/backend.rs30
-rw-r--r--tiny_skia/src/text.rs29
-rw-r--r--wgpu/src/layer.rs15
-rw-r--r--wgpu/src/layer/text.rs5
-rw-r--r--wgpu/src/text.rs22
8 files changed, 131 insertions, 4 deletions
diff --git a/graphics/src/damage.rs b/graphics/src/damage.rs
index 595cc274..59e9f5b4 100644
--- a/graphics/src/damage.rs
+++ b/graphics/src/damage.rs
@@ -73,6 +73,11 @@ impl<T: Damage> Damage for Primitive<T> {
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::Image { bounds, .. }
| Self::Svg { bounds, .. } => bounds.expand(1.0),
diff --git a/graphics/src/primitive.rs b/graphics/src/primitive.rs
index ed75776c..20affaaf 100644
--- a/graphics/src/primitive.rs
+++ b/graphics/src/primitive.rs
@@ -57,6 +57,8 @@ pub enum Primitive<T> {
/// The clip bounds of the editor.
clip_bounds: Rectangle,
},
+ /// A raw `cosmic-text` primitive
+ RawText(crate::text::Raw),
/// A quad primitive
Quad {
/// The bounds of the quad
diff --git a/graphics/src/text.rs b/graphics/src/text.rs
index fc7694c2..8fd037fe 100644
--- a/graphics/src/text.rs
+++ b/graphics/src/text.rs
@@ -12,11 +12,11 @@ pub use cosmic_text;
use crate::color;
use crate::core::font::{self, Font};
use crate::core::text::Shaping;
-use crate::core::{Color, Size};
+use crate::core::{Color, Point, Rectangle, Size};
use once_cell::sync::OnceCell;
use std::borrow::Cow;
-use std::sync::{Arc, RwLock};
+use std::sync::{Arc, RwLock, Weak};
/// Returns the global [`FontSystem`].
pub fn font_system() -> &'static RwLock<FontSystem> {
@@ -68,6 +68,29 @@ impl FontSystem {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
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`].
pub fn measure(buffer: &cosmic_text::Buffer) -> Size {
let (width, total_lines) = buffer
diff --git a/tiny_skia/src/backend.rs b/tiny_skia/src/backend.rs
index 3e9bd2a5..706db40e 100644
--- a/tiny_skia/src/backend.rs
+++ b/tiny_skia/src/backend.rs
@@ -1,5 +1,6 @@
use crate::core::{Background, Color, Gradient, Rectangle, Vector};
use crate::graphics::backend;
+use crate::graphics::text;
use crate::graphics::Viewport;
use crate::primitive::{self, Primitive};
@@ -444,6 +445,35 @@ impl Backend {
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")]
Primitive::Image {
handle,
diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs
index 70e95d01..a5a0a1b6 100644
--- a/tiny_skia/src/text.rs
+++ b/tiny_skia/src/text.rs
@@ -1,6 +1,6 @@
use crate::core::alignment;
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::text::cache::{self, Cache};
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) {
self.cache.get_mut().trim();
self.glyph_cache.trim();
diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs
index 557a7633..4ad12a88 100644
--- a/wgpu/src/layer.rs
+++ b/wgpu/src/layer.rs
@@ -177,6 +177,21 @@ impl<'a> Layer<'a> {
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 {
bounds,
background,
diff --git a/wgpu/src/layer/text.rs b/wgpu/src/layer/text.rs
index df2f2875..37ee5247 100644
--- a/wgpu/src/layer/text.rs
+++ b/wgpu/src/layer/text.rs
@@ -1,6 +1,7 @@
use crate::core::alignment;
use crate::core::text;
use crate::core::{Color, Font, Pixels, Point, Rectangle};
+use crate::graphics;
use crate::graphics::text::editor;
use crate::graphics::text::paragraph;
@@ -23,8 +24,10 @@ pub enum Text<'a> {
color: Color,
clip_bounds: Rectangle,
},
- /// A cached text.
+ /// Some cached text.
Cached(Cached<'a>),
+ /// Some raw text.
+ Raw(graphics::text::Raw),
}
#[derive(Debug, Clone)]
diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs
index 888b1924..dca09cb8 100644
--- a/wgpu/src/text.rs
+++ b/wgpu/src/text.rs
@@ -7,6 +7,7 @@ use crate::layer::Text;
use std::borrow::Cow;
use std::cell::RefCell;
+use std::sync::Arc;
#[allow(missing_debug_implementations)]
pub struct Pipeline {
@@ -76,6 +77,7 @@ impl Pipeline {
Paragraph(Paragraph),
Editor(Editor),
Cache(cache::KeyHash),
+ Raw(Arc<glyphon::Buffer>),
}
let allocations: Vec<_> = sections
@@ -107,6 +109,7 @@ impl Pipeline {
Some(Allocation::Cache(key))
}
+ Text::Raw(text) => text.buffer.upgrade().map(Allocation::Raw),
})
.collect();
@@ -185,6 +188,25 @@ impl Pipeline {
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;