summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón <hector@hecrj.dev>2024-07-17 13:00:00 +0200
committerLibravatar GitHub <noreply@github.com>2024-07-17 13:00:00 +0200
commit616689ca54942a13aac3615e571ae995ad4571b6 (patch)
tree763d8926cfa2be97dffa858a04036e207fd06ec8
parentb518e30610fa53691c727852f70b497dd19cfc7a (diff)
downloadiced-616689ca54942a13aac3615e571ae995ad4571b6.tar.gz
iced-616689ca54942a13aac3615e571ae995ad4571b6.tar.bz2
iced-616689ca54942a13aac3615e571ae995ad4571b6.zip
Update `cosmic-text` and `resvg` (#2416)
* Update `cosmic-text`, `glyphon`, and `resvg` * Fix slow font fallback with `Shaping::Basic` in `cosmic-text` * Update `cosmic-text` and `resvg` * Update `cosmic-text` * Fix `SelectAll` action in `editor` * Fix some panics in `graphics::text::editor` * Remove empty `if` statement in `tiny_skia::vector` * Update `cosmic-text`, `glyphon`, and `rustc-hash`
-rw-r--r--Cargo.toml8
-rw-r--r--graphics/src/geometry/text.rs5
-rw-r--r--graphics/src/text/cache.rs4
-rw-r--r--graphics/src/text/editor.rs289
-rw-r--r--graphics/src/text/paragraph.rs8
-rw-r--r--tiny_skia/src/engine.rs10
-rw-r--r--tiny_skia/src/text.rs8
-rw-r--r--tiny_skia/src/vector.rs34
-rw-r--r--wgpu/src/image/vector.rs35
-rw-r--r--wgpu/src/text.rs8
10 files changed, 187 insertions, 222 deletions
diff --git a/Cargo.toml b/Cargo.toml
index b85900cf..bc566bf6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -138,11 +138,11 @@ async-std = "1.0"
bitflags = "2.0"
bytemuck = { version = "1.0", features = ["derive"] }
bytes = "1.6"
-cosmic-text = "0.10"
+cosmic-text = "0.12"
dark-light = "1.0"
futures = "0.3"
glam = "0.25"
-glyphon = { git = "https://github.com/hecrj/glyphon.git", rev = "f07e7bab705e69d39a5e6e52c73039a93c4552f8" }
+glyphon = { git = "https://github.com/hecrj/glyphon.git", rev = "feef9f5630c2adb3528937e55f7bfad2da561a65" }
guillotiere = "0.6"
half = "2.2"
image = "0.24"
@@ -157,8 +157,8 @@ ouroboros = "0.18"
palette = "0.7"
qrcode = { version = "0.13", default-features = false }
raw-window-handle = "0.6"
-resvg = "0.36"
-rustc-hash = "1.0"
+resvg = "0.42"
+rustc-hash = "2.0"
smol = "1.0"
smol_str = "0.2"
softbuffer = "0.4"
diff --git a/graphics/src/geometry/text.rs b/graphics/src/geometry/text.rs
index d314e85e..90147f87 100644
--- a/graphics/src/geometry/text.rs
+++ b/graphics/src/geometry/text.rs
@@ -43,6 +43,7 @@ impl Text {
let mut buffer = cosmic_text::BufferLine::new(
&self.content,
+ cosmic_text::LineEnding::default(),
cosmic_text::AttrsList::new(text::to_attributes(self.font)),
text::to_shaping(self.shaping),
);
@@ -50,8 +51,10 @@ impl Text {
let layout = buffer.layout(
font_system.raw(),
self.size.0,
- f32::MAX,
+ None,
cosmic_text::Wrap::None,
+ None,
+ 4,
);
let translation_x = match self.horizontal_alignment {
diff --git a/graphics/src/text/cache.rs b/graphics/src/text/cache.rs
index 822b61c4..e64d93f1 100644
--- a/graphics/src/text/cache.rs
+++ b/graphics/src/text/cache.rs
@@ -48,8 +48,8 @@ impl Cache {
buffer.set_size(
font_system,
- key.bounds.width,
- key.bounds.height.max(key.line_height),
+ Some(key.bounds.width),
+ Some(key.bounds.height.max(key.line_height)),
);
buffer.set_text(
font_system,
diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs
index 36b4ca6e..3e6ef70c 100644
--- a/graphics/src/text/editor.rs
+++ b/graphics/src/text/editor.rs
@@ -17,7 +17,7 @@ use std::sync::{self, Arc};
pub struct Editor(Option<Arc<Internal>>);
struct Internal {
- editor: cosmic_text::Editor,
+ editor: cosmic_text::Editor<'static>,
font: Font,
bounds: Size,
topmost_line_changed: Option<usize>,
@@ -32,7 +32,7 @@ impl Editor {
/// Returns the buffer of the [`Editor`].
pub fn buffer(&self) -> &cosmic_text::Buffer {
- self.internal().editor.buffer()
+ buffer_from_editor(&self.internal().editor)
}
/// Creates a [`Weak`] reference to the [`Editor`].
@@ -101,16 +101,10 @@ impl editor::Editor for Editor {
let internal = self.internal();
let cursor = internal.editor.cursor();
- let buffer = internal.editor.buffer();
-
- match internal.editor.select_opt() {
- Some(selection) => {
- let (start, end) = if cursor < selection {
- (cursor, selection)
- } else {
- (selection, cursor)
- };
+ let buffer = buffer_from_editor(&internal.editor);
+ match internal.editor.selection_bounds() {
+ Some((start, end)) => {
let line_height = buffer.metrics().line_height;
let selected_lines = end.line - start.line + 1;
@@ -142,7 +136,8 @@ impl editor::Editor for Editor {
width,
y: (visual_line as i32 + visual_lines_offset)
as f32
- * line_height,
+ * line_height
+ - buffer.scroll().vertical,
height: line_height,
})
} else {
@@ -224,7 +219,8 @@ impl editor::Editor for Editor {
Cursor::Caret(Point::new(
offset,
(visual_lines_offset + visual_line as i32) as f32
- * line_height,
+ * line_height
+ - buffer.scroll().vertical,
))
}
}
@@ -252,16 +248,8 @@ impl editor::Editor for Editor {
match action {
// Motion events
Action::Move(motion) => {
- if let Some(selection) = editor.select_opt() {
- let cursor = editor.cursor();
-
- let (left, right) = if cursor < selection {
- (cursor, selection)
- } else {
- (selection, cursor)
- };
-
- editor.set_select_opt(None);
+ if let Some((start, end)) = editor.selection_bounds() {
+ editor.set_selection(cosmic_text::Selection::None);
match motion {
// These motions are performed as-is even when a selection
@@ -272,17 +260,20 @@ impl editor::Editor for Editor {
| Motion::DocumentEnd => {
editor.action(
font_system.raw(),
- motion_to_action(motion),
+ cosmic_text::Action::Motion(to_motion(motion)),
);
}
// Other motions simply move the cursor to one end of the selection
_ => editor.set_cursor(match motion.direction() {
- Direction::Left => left,
- Direction::Right => right,
+ Direction::Left => start,
+ Direction::Right => end,
}),
}
} else {
- editor.action(font_system.raw(), motion_to_action(motion));
+ editor.action(
+ font_system.raw(),
+ cosmic_text::Action::Motion(to_motion(motion)),
+ );
}
}
@@ -290,103 +281,36 @@ impl editor::Editor for Editor {
Action::Select(motion) => {
let cursor = editor.cursor();
- if editor.select_opt().is_none() {
- editor.set_select_opt(Some(cursor));
+ if editor.selection_bounds().is_none() {
+ editor
+ .set_selection(cosmic_text::Selection::Normal(cursor));
}
- editor.action(font_system.raw(), motion_to_action(motion));
+ editor.action(
+ font_system.raw(),
+ cosmic_text::Action::Motion(to_motion(motion)),
+ );
// Deselect if selection matches cursor position
- if let Some(selection) = editor.select_opt() {
- let cursor = editor.cursor();
-
- if cursor.line == selection.line
- && cursor.index == selection.index
- {
- editor.set_select_opt(None);
+ if let Some((start, end)) = editor.selection_bounds() {
+ if start.line == end.line && start.index == end.index {
+ editor.set_selection(cosmic_text::Selection::None);
}
}
}
Action::SelectWord => {
- use unicode_segmentation::UnicodeSegmentation;
-
let cursor = editor.cursor();
- if let Some(line) = editor.buffer().lines.get(cursor.line) {
- let (start, end) =
- UnicodeSegmentation::unicode_word_indices(line.text())
- // Split words with dots
- .flat_map(|(i, word)| {
- word.split('.').scan(i, |current, word| {
- let start = *current;
- *current += word.len() + 1;
-
- Some((start, word))
- })
- })
- // Turn words into ranges
- .map(|(i, word)| (i, i + word.len()))
- // Find the word at cursor
- .find(|&(start, end)| {
- start <= cursor.index && cursor.index < end
- })
- // Cursor is not in a word. Let's select its punctuation cluster.
- .unwrap_or_else(|| {
- let start = line.text()[..cursor.index]
- .char_indices()
- .rev()
- .take_while(|(_, c)| {
- c.is_ascii_punctuation()
- })
- .map(|(i, _)| i)
- .last()
- .unwrap_or(cursor.index);
-
- let end = line.text()[cursor.index..]
- .char_indices()
- .skip_while(|(_, c)| {
- c.is_ascii_punctuation()
- })
- .map(|(i, _)| i + cursor.index)
- .next()
- .unwrap_or(cursor.index);
-
- (start, end)
- });
-
- if start != end {
- editor.set_cursor(cosmic_text::Cursor {
- index: start,
- ..cursor
- });
-
- editor.set_select_opt(Some(cosmic_text::Cursor {
- index: end,
- ..cursor
- }));
- }
- }
+ editor.set_selection(cosmic_text::Selection::Word(cursor));
}
Action::SelectLine => {
let cursor = editor.cursor();
- if let Some(line_length) = editor
- .buffer()
- .lines
- .get(cursor.line)
- .map(|line| line.text().len())
- {
- editor
- .set_cursor(cosmic_text::Cursor { index: 0, ..cursor });
-
- editor.set_select_opt(Some(cosmic_text::Cursor {
- index: line_length,
- ..cursor
- }));
- }
+ editor.set_selection(cosmic_text::Selection::Line(cursor));
}
Action::SelectAll => {
- let buffer = editor.buffer();
+ let buffer = buffer_from_editor(editor);
+
if buffer.lines.len() > 1
|| buffer
.lines
@@ -394,15 +318,20 @@ impl editor::Editor for Editor {
.is_some_and(|line| !line.text().is_empty())
{
let cursor = editor.cursor();
- editor.set_select_opt(Some(cosmic_text::Cursor {
- line: 0,
- index: 0,
- ..cursor
- }));
+
+ editor.set_selection(cosmic_text::Selection::Normal(
+ cosmic_text::Cursor {
+ line: 0,
+ index: 0,
+ ..cursor
+ },
+ ));
editor.action(
font_system.raw(),
- motion_to_action(Motion::DocumentEnd),
+ cosmic_text::Action::Motion(
+ cosmic_text::Motion::BufferEnd,
+ ),
);
}
}
@@ -440,10 +369,12 @@ impl editor::Editor for Editor {
}
let cursor = editor.cursor();
- let selection = editor.select_opt().unwrap_or(cursor);
+ let selection_start = editor
+ .selection_bounds()
+ .map(|(start, _)| start)
+ .unwrap_or(cursor);
- internal.topmost_line_changed =
- Some(cursor.min(selection).line);
+ internal.topmost_line_changed = Some(selection_start.line);
}
// Mouse events
@@ -466,13 +397,9 @@ impl editor::Editor for Editor {
);
// Deselect if selection matches cursor position
- if let Some(selection) = editor.select_opt() {
- let cursor = editor.cursor();
-
- if cursor.line == selection.line
- && cursor.index == selection.index
- {
- editor.set_select_opt(None);
+ if let Some((start, end)) = editor.selection_bounds() {
+ if start.line == end.line && start.index == end.index {
+ editor.set_selection(cosmic_text::Selection::None);
}
}
}
@@ -494,7 +421,7 @@ impl editor::Editor for Editor {
fn min_bounds(&self) -> Size {
let internal = self.internal();
- text::measure(internal.editor.buffer())
+ text::measure(buffer_from_editor(&internal.editor))
}
fn update(
@@ -517,7 +444,10 @@ impl editor::Editor for Editor {
if font_system.version() != internal.version {
log::trace!("Updating `FontSystem` of `Editor`...");
- for line in internal.editor.buffer_mut().lines.iter_mut() {
+ for line in buffer_mut_from_editor(&mut internal.editor)
+ .lines
+ .iter_mut()
+ {
line.reset();
}
@@ -528,7 +458,10 @@ impl editor::Editor for Editor {
if new_font != internal.font {
log::trace!("Updating font of `Editor`...");
- for line in internal.editor.buffer_mut().lines.iter_mut() {
+ for line in buffer_mut_from_editor(&mut internal.editor)
+ .lines
+ .iter_mut()
+ {
let _ = line.set_attrs_list(cosmic_text::AttrsList::new(
text::to_attributes(new_font),
));
@@ -538,7 +471,7 @@ impl editor::Editor for Editor {
internal.topmost_line_changed = Some(0);
}
- let metrics = internal.editor.buffer().metrics();
+ let metrics = buffer_from_editor(&internal.editor).metrics();
let new_line_height = new_line_height.to_absolute(new_size);
if new_size.0 != metrics.font_size
@@ -546,7 +479,7 @@ impl editor::Editor for Editor {
{
log::trace!("Updating `Metrics` of `Editor`...");
- internal.editor.buffer_mut().set_metrics(
+ buffer_mut_from_editor(&mut internal.editor).set_metrics(
font_system.raw(),
cosmic_text::Metrics::new(new_size.0, new_line_height.0),
);
@@ -555,10 +488,10 @@ impl editor::Editor for Editor {
if new_bounds != internal.bounds {
log::trace!("Updating size of `Editor`...");
- internal.editor.buffer_mut().set_size(
+ buffer_mut_from_editor(&mut internal.editor).set_size(
font_system.raw(),
- new_bounds.width,
- new_bounds.height,
+ Some(new_bounds.width),
+ Some(new_bounds.height),
);
internal.bounds = new_bounds;
@@ -573,7 +506,7 @@ impl editor::Editor for Editor {
new_highlighter.change_line(topmost_line_changed);
}
- internal.editor.shape_as_needed(font_system.raw());
+ internal.editor.shape_as_needed(font_system.raw(), false);
self.0 = Some(Arc::new(internal));
}
@@ -585,12 +518,13 @@ impl editor::Editor for Editor {
format_highlight: impl Fn(&H::Highlight) -> highlighter::Format<Self::Font>,
) {
let internal = self.internal();
- let buffer = internal.editor.buffer();
+ let buffer = buffer_from_editor(&internal.editor);
- let mut window = buffer.scroll() + buffer.visible_lines();
+ let scroll = buffer.scroll();
+ let mut window = (internal.bounds.height / buffer.metrics().line_height)
+ .ceil() as i32;
- let last_visible_line = buffer
- .lines
+ let last_visible_line = buffer.lines[scroll.line..]
.iter()
.enumerate()
.find_map(|(i, line)| {
@@ -604,7 +538,7 @@ impl editor::Editor for Editor {
window -= visible_lines;
None
} else {
- Some(i)
+ Some(scroll.line + i)
}
})
.unwrap_or(buffer.lines.len().saturating_sub(1));
@@ -626,7 +560,7 @@ impl editor::Editor for Editor {
let attributes = text::to_attributes(font);
- for line in &mut internal.editor.buffer_mut().lines
+ for line in &mut buffer_mut_from_editor(&mut internal.editor).lines
[current_line..=last_visible_line]
{
let mut list = cosmic_text::AttrsList::new(attributes);
@@ -652,7 +586,7 @@ impl editor::Editor for Editor {
let _ = line.set_attrs_list(list);
}
- internal.editor.shape_as_needed(font_system.raw());
+ internal.editor.shape_as_needed(font_system.raw(), false);
self.0 = Some(Arc::new(internal));
}
@@ -668,7 +602,8 @@ impl PartialEq for Internal {
fn eq(&self, other: &Self) -> bool {
self.font == other.font
&& self.bounds == other.bounds
- && self.editor.buffer().metrics() == other.editor.buffer().metrics()
+ && buffer_from_editor(&self.editor).metrics()
+ == buffer_from_editor(&other.editor).metrics()
}
}
@@ -730,7 +665,8 @@ fn highlight_line(
let layout = line
.layout_opt()
.as_ref()
- .expect("Line layout should be cached");
+ .map(Vec::as_slice)
+ .unwrap_or_default();
layout.iter().map(move |visual_line| {
let start = visual_line
@@ -773,34 +709,61 @@ fn highlight_line(
}
fn visual_lines_offset(line: usize, buffer: &cosmic_text::Buffer) -> i32 {
- let visual_lines_before_start: usize = buffer
- .lines
+ let scroll = buffer.scroll();
+
+ let start = scroll.line.min(line);
+ let end = scroll.line.max(line);
+
+ let visual_lines_offset: usize = buffer.lines[start..]
.iter()
- .take(line)
+ .take(end - start)
.map(|line| {
- line.layout_opt()
- .as_ref()
- .expect("Line layout should be cached")
- .len()
+ line.layout_opt().as_ref().map(Vec::len).unwrap_or_default()
})
.sum();
- visual_lines_before_start as i32 - buffer.scroll()
+ visual_lines_offset as i32 * if scroll.line < line { 1 } else { -1 }
}
-fn motion_to_action(motion: Motion) -> cosmic_text::Action {
+fn to_motion(motion: Motion) -> cosmic_text::Motion {
match motion {
- Motion::Left => cosmic_text::Action::Left,
- Motion::Right => cosmic_text::Action::Right,
- Motion::Up => cosmic_text::Action::Up,
- Motion::Down => cosmic_text::Action::Down,
- Motion::WordLeft => cosmic_text::Action::LeftWord,
- Motion::WordRight => cosmic_text::Action::RightWord,
- Motion::Home => cosmic_text::Action::Home,
- Motion::End => cosmic_text::Action::End,
- Motion::PageUp => cosmic_text::Action::PageUp,
- Motion::PageDown => cosmic_text::Action::PageDown,
- Motion::DocumentStart => cosmic_text::Action::BufferStart,
- Motion::DocumentEnd => cosmic_text::Action::BufferEnd,
+ Motion::Left => cosmic_text::Motion::Left,
+ Motion::Right => cosmic_text::Motion::Right,
+ Motion::Up => cosmic_text::Motion::Up,
+ Motion::Down => cosmic_text::Motion::Down,
+ Motion::WordLeft => cosmic_text::Motion::LeftWord,
+ Motion::WordRight => cosmic_text::Motion::RightWord,
+ Motion::Home => cosmic_text::Motion::Home,
+ Motion::End => cosmic_text::Motion::End,
+ Motion::PageUp => cosmic_text::Motion::PageUp,
+ Motion::PageDown => cosmic_text::Motion::PageDown,
+ Motion::DocumentStart => cosmic_text::Motion::BufferStart,
+ Motion::DocumentEnd => cosmic_text::Motion::BufferEnd,
+ }
+}
+
+fn buffer_from_editor<'a, 'b>(
+ editor: &'a impl cosmic_text::Edit<'b>,
+) -> &'a cosmic_text::Buffer
+where
+ 'b: 'a,
+{
+ match editor.buffer_ref() {
+ cosmic_text::BufferRef::Owned(buffer) => buffer,
+ cosmic_text::BufferRef::Borrowed(buffer) => buffer,
+ cosmic_text::BufferRef::Arc(buffer) => buffer,
+ }
+}
+
+fn buffer_mut_from_editor<'a, 'b>(
+ editor: &'a mut impl cosmic_text::Edit<'b>,
+) -> &'a mut cosmic_text::Buffer
+where
+ 'b: 'a,
+{
+ match editor.buffer_ref_mut() {
+ cosmic_text::BufferRef::Owned(buffer) => buffer,
+ cosmic_text::BufferRef::Borrowed(buffer) => buffer,
+ cosmic_text::BufferRef::Arc(_buffer) => unreachable!(),
}
}
diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs
index 31a323ac..a5fefe8f 100644
--- a/graphics/src/text/paragraph.rs
+++ b/graphics/src/text/paragraph.rs
@@ -77,8 +77,8 @@ impl core::text::Paragraph for Paragraph {
buffer.set_size(
font_system.raw(),
- text.bounds.width,
- text.bounds.height,
+ Some(text.bounds.width),
+ Some(text.bounds.height),
);
buffer.set_text(
@@ -116,8 +116,8 @@ impl core::text::Paragraph for Paragraph {
internal.buffer.set_size(
font_system.raw(),
- new_bounds.width,
- new_bounds.height,
+ Some(new_bounds.width),
+ Some(new_bounds.height),
);
internal.bounds = new_bounds;
diff --git a/tiny_skia/src/engine.rs b/tiny_skia/src/engine.rs
index 028b304f..898657c8 100644
--- a/tiny_skia/src/engine.rs
+++ b/tiny_skia/src/engine.rs
@@ -439,9 +439,13 @@ impl Engine {
let transformation = transformation * *local_transformation;
let (width, height) = buffer.size();
- let physical_bounds =
- Rectangle::new(raw.position, Size::new(width, height))
- * transformation;
+ let physical_bounds = Rectangle::new(
+ raw.position,
+ Size::new(
+ width.unwrap_or(clip_bounds.width),
+ height.unwrap_or(clip_bounds.height),
+ ),
+ ) * transformation;
if !clip_bounds.intersects(&physical_bounds) {
return;
diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs
index c71deb10..0fc3d1f7 100644
--- a/tiny_skia/src/text.rs
+++ b/tiny_skia/src/text.rs
@@ -169,7 +169,13 @@ impl Pipeline {
font_system.raw(),
&mut self.glyph_cache,
buffer,
- Rectangle::new(position, Size::new(width, height)),
+ Rectangle::new(
+ position,
+ Size::new(
+ width.unwrap_or(pixels.width() as f32),
+ height.unwrap_or(pixels.height() as f32),
+ ),
+ ),
color,
alignment::Horizontal::Left,
alignment::Vertical::Top,
diff --git a/tiny_skia/src/vector.rs b/tiny_skia/src/vector.rs
index bbe08cb8..8a15f47f 100644
--- a/tiny_skia/src/vector.rs
+++ b/tiny_skia/src/vector.rs
@@ -1,8 +1,7 @@
use crate::core::svg::{Data, Handle};
use crate::core::{Color, Rectangle, Size};
-use crate::graphics::text;
-use resvg::usvg::{self, TreeTextToPath};
+use resvg::usvg;
use rustc_hash::{FxHashMap, FxHashSet};
use tiny_skia::Transform;
@@ -80,35 +79,28 @@ struct RasterKey {
impl Cache {
fn load(&mut self, handle: &Handle) -> Option<&usvg::Tree> {
- use usvg::TreeParsing;
-
let id = handle.id();
if let hash_map::Entry::Vacant(entry) = self.trees.entry(id) {
- let mut svg = match handle.data() {
+ let svg = match handle.data() {
Data::Path(path) => {
fs::read_to_string(path).ok().and_then(|contents| {
usvg::Tree::from_str(
&contents,
- &usvg::Options::default(),
+ &usvg::Options::default(), // TODO: Set usvg::Options::fontdb
)
.ok()
})
}
Data::Bytes(bytes) => {
- usvg::Tree::from_data(bytes, &usvg::Options::default()).ok()
+ usvg::Tree::from_data(
+ bytes,
+ &usvg::Options::default(), // TODO: Set usvg::Options::fontdb
+ )
+ .ok()
}
};
- if let Some(svg) = &mut svg {
- if svg.has_text_nodes() {
- let mut font_system =
- text::font_system().write().expect("Write font system");
-
- svg.convert_text(font_system.raw().db_mut());
- }
- }
-
let _ = entry.insert(svg);
}
@@ -118,11 +110,9 @@ impl Cache {
fn viewport_dimensions(&mut self, handle: &Handle) -> Option<Size<u32>> {
let tree = self.load(handle)?;
+ let size = tree.size();
- Some(Size::new(
- tree.size.width() as u32,
- tree.size.height() as u32,
- ))
+ Some(Size::new(size.width() as u32, size.height() as u32))
}
fn draw(
@@ -147,7 +137,7 @@ impl Cache {
let mut image = tiny_skia::Pixmap::new(size.width, size.height)?;
- let tree_size = tree.size.to_int_size();
+ let tree_size = tree.size().to_int_size();
let target_size = if size.width > size.height {
tree_size.scale_to_width(size.width)
@@ -167,7 +157,7 @@ impl Cache {
tiny_skia::Transform::default()
};
- resvg::Tree::from_usvg(tree).render(transform, &mut image.as_mut());
+ resvg::render(tree, transform, &mut image.as_mut());
if let Some([r, g, b, _]) = key.color {
// Apply color filter
diff --git a/wgpu/src/image/vector.rs b/wgpu/src/image/vector.rs
index c6d829af..74e9924d 100644
--- a/wgpu/src/image/vector.rs
+++ b/wgpu/src/image/vector.rs
@@ -1,10 +1,9 @@
use crate::core::svg;
use crate::core::{Color, Size};
-use crate::graphics::text;
use crate::image::atlas::{self, Atlas};
use resvg::tiny_skia;
-use resvg::usvg::{self, TreeTextToPath};
+use resvg::usvg;
use rustc_hash::{FxHashMap, FxHashSet};
use std::fs;
@@ -21,7 +20,7 @@ impl Svg {
pub fn viewport_dimensions(&self) -> Size<u32> {
match self {
Svg::Loaded(tree) => {
- let size = tree.size;
+ let size = tree.size();
Size::new(size.width() as u32, size.height() as u32)
}
@@ -45,38 +44,33 @@ type ColorFilter = Option<[u8; 4]>;
impl Cache {
/// Load svg
pub fn load(&mut self, handle: &svg::Handle) -> &Svg {
- use usvg::TreeParsing;
-
if self.svgs.contains_key(&handle.id()) {
return self.svgs.get(&handle.id()).unwrap();
}
- let mut svg = match handle.data() {
+ 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())
- .ok()
+ usvg::Tree::from_str(
+ &contents,
+ &usvg::Options::default(), // TODO: Set usvg::Options::fontdb
+ )
+ .ok()
})
.map(Svg::Loaded)
.unwrap_or(Svg::NotFound),
svg::Data::Bytes(bytes) => {
- match usvg::Tree::from_data(bytes, &usvg::Options::default()) {
+ match usvg::Tree::from_data(
+ bytes,
+ &usvg::Options::default(), // TODO: Set usvg::Options::fontdb
+ ) {
Ok(tree) => Svg::Loaded(tree),
Err(_) => Svg::NotFound,
}
}
};
- if let Svg::Loaded(svg) = &mut svg {
- if svg.has_text_nodes() {
- let mut font_system =
- text::font_system().write().expect("Write font system");
-
- svg.convert_text(font_system.raw().db_mut());
- }
- }
-
self.should_trim = true;
let _ = self.svgs.insert(handle.id(), svg);
@@ -127,7 +121,7 @@ impl Cache {
// It would be cool to be able to smooth resize the `svg` example.
let mut img = tiny_skia::Pixmap::new(width, height)?;
- let tree_size = tree.size.to_int_size();
+ let tree_size = tree.size().to_int_size();
let target_size = if width > height {
tree_size.scale_to_width(width)
@@ -147,8 +141,7 @@ impl Cache {
tiny_skia::Transform::default()
};
- resvg::Tree::from_usvg(tree)
- .render(transform, &mut img.as_mut());
+ resvg::render(tree, transform, &mut img.as_mut());
let mut rgba = img.take();
diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs
index 05db5f80..bf7eae18 100644
--- a/wgpu/src/text.rs
+++ b/wgpu/src/text.rs
@@ -585,7 +585,13 @@ fn prepare(
(
buffer.as_ref(),
- Rectangle::new(raw.position, Size::new(width, height)),
+ Rectangle::new(
+ raw.position,
+ Size::new(
+ width.unwrap_or(layer_bounds.width),
+ height.unwrap_or(layer_bounds.height),
+ ),
+ ),
alignment::Horizontal::Left,
alignment::Vertical::Top,
raw.color,