summaryrefslogtreecommitdiffstats
path: root/wgpu
diff options
context:
space:
mode:
Diffstat (limited to 'wgpu')
-rw-r--r--wgpu/src/geometry.rs38
-rw-r--r--wgpu/src/image/vector.rs30
-rw-r--r--wgpu/src/lib.rs1
-rw-r--r--wgpu/src/shader/quad.wgsl14
4 files changed, 67 insertions, 16 deletions
diff --git a/wgpu/src/geometry.rs b/wgpu/src/geometry.rs
index be65ba36..8e6f77d7 100644
--- a/wgpu/src/geometry.rs
+++ b/wgpu/src/geometry.rs
@@ -253,6 +253,44 @@ impl geometry::frame::Backend for Frame {
.expect("Stroke path");
}
+ fn stroke_rectangle<'a>(
+ &mut self,
+ top_left: Point,
+ size: Size,
+ stroke: impl Into<Stroke<'a>>,
+ ) {
+ let stroke = stroke.into();
+
+ let mut buffer = self
+ .buffers
+ .get_stroke(&self.transforms.current.transform_style(stroke.style));
+
+ let top_left = self
+ .transforms
+ .current
+ .0
+ .transform_point(lyon::math::Point::new(top_left.x, top_left.y));
+
+ let size =
+ self.transforms.current.0.transform_vector(
+ lyon::math::Vector::new(size.width, size.height),
+ );
+
+ let mut options = tessellation::StrokeOptions::default();
+ options.line_width = stroke.width;
+ options.start_cap = into_line_cap(stroke.line_cap);
+ options.end_cap = into_line_cap(stroke.line_cap);
+ options.line_join = into_line_join(stroke.line_join);
+
+ self.stroke_tessellator
+ .tessellate_rectangle(
+ &lyon::math::Box2D::new(top_left, top_left + size),
+ &options,
+ buffer.as_mut(),
+ )
+ .expect("Stroke rectangle");
+ }
+
fn fill_text(&mut self, text: impl Into<geometry::Text>) {
let text = text.into();
diff --git a/wgpu/src/image/vector.rs b/wgpu/src/image/vector.rs
index 74e9924d..e55ade38 100644
--- a/wgpu/src/image/vector.rs
+++ b/wgpu/src/image/vector.rs
@@ -6,6 +6,7 @@ use resvg::tiny_skia;
use resvg::usvg;
use rustc_hash::{FxHashMap, FxHashSet};
use std::fs;
+use std::sync::Arc;
/// Entry in cache corresponding to an svg handle
pub enum Svg {
@@ -37,6 +38,7 @@ pub struct Cache {
svg_hits: FxHashSet<u64>,
rasterized_hits: FxHashSet<(u64, u32, u32, ColorFilter)>,
should_trim: bool,
+ fontdb: Option<Arc<usvg::fontdb::Database>>,
}
type ColorFilter = Option<[u8; 4]>;
@@ -48,23 +50,33 @@ impl Cache {
return self.svgs.get(&handle.id()).unwrap();
}
+ // TODO: Reuse `cosmic-text` font database
+ if self.fontdb.is_none() {
+ let mut fontdb = usvg::fontdb::Database::new();
+ fontdb.load_system_fonts();
+
+ self.fontdb = Some(Arc::new(fontdb));
+ }
+
+ let options = usvg::Options {
+ fontdb: self
+ .fontdb
+ .as_ref()
+ .expect("fontdb must be initialized")
+ .clone(),
+ ..usvg::Options::default()
+ };
+
let svg = match handle.data() {
svg::Data::Path(path) => fs::read_to_string(path)
.ok()
.and_then(|contents| {
- usvg::Tree::from_str(
- &contents,
- &usvg::Options::default(), // TODO: Set usvg::Options::fontdb
- )
- .ok()
+ usvg::Tree::from_str(&contents, &options).ok()
})
.map(Svg::Loaded)
.unwrap_or(Svg::NotFound),
svg::Data::Bytes(bytes) => {
- match usvg::Tree::from_data(
- bytes,
- &usvg::Options::default(), // TODO: Set usvg::Options::fontdb
- ) {
+ match usvg::Tree::from_data(bytes, &options) {
Ok(tree) => Svg::Loaded(tree),
Err(_) => Svg::NotFound,
}
diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs
index 39167514..d79f0dc8 100644
--- a/wgpu/src/lib.rs
+++ b/wgpu/src/lib.rs
@@ -408,6 +408,7 @@ impl Renderer {
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Top,
shaping: core::text::Shaping::Basic,
+ wrapping: core::text::Wrapping::Word,
};
renderer.fill_text(
diff --git a/wgpu/src/shader/quad.wgsl b/wgpu/src/shader/quad.wgsl
index a367d5e6..b213c8cf 100644
--- a/wgpu/src/shader/quad.wgsl
+++ b/wgpu/src/shader/quad.wgsl
@@ -22,14 +22,14 @@ fn rounded_box_sdf(to_center: vec2<f32>, size: vec2<f32>, radius: f32) -> f32 {
return length(max(abs(to_center) - size + vec2<f32>(radius, radius), vec2<f32>(0.0, 0.0))) - radius;
}
-// Based on the fragment position and the center of the quad, select one of the 4 radi.
+// Based on the fragment position and the center of the quad, select one of the 4 radii.
// Order matches CSS border radius attribute:
-// radi.x = top-left, radi.y = top-right, radi.z = bottom-right, radi.w = bottom-left
-fn select_border_radius(radi: vec4<f32>, position: vec2<f32>, center: vec2<f32>) -> f32 {
- var rx = radi.x;
- var ry = radi.y;
- rx = select(radi.x, radi.y, position.x > center.x);
- ry = select(radi.w, radi.z, position.x > center.x);
+// radii.x = top-left, radii.y = top-right, radii.z = bottom-right, radii.w = bottom-left
+fn select_border_radius(radii: vec4<f32>, position: vec2<f32>, center: vec2<f32>) -> f32 {
+ var rx = radii.x;
+ var ry = radii.y;
+ rx = select(radii.x, radii.y, position.x > center.x);
+ ry = select(radii.w, radii.z, position.x > center.x);
rx = select(rx, ry, position.y > center.y);
return rx;
}