Skip to content
This repository has been archived by the owner on Nov 26, 2024. It is now read-only.

Commit

Permalink
#58 wip to_path (not working)
Browse files Browse the repository at this point in the history
  • Loading branch information
bennobuilder committed Mar 23, 2024
1 parent 945b1bc commit 71a7eff
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 15 deletions.
1 change: 1 addition & 0 deletions crates/attributed_string/src/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ impl Font {
end: range.end, // Set later to adjust for glyph clusters (graphemes)
},
advance,
size: advance,
offset,
ascent,
descent,
Expand Down
1 change: 1 addition & 0 deletions crates/attributed_string/src/glyph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub struct Glyph {
pub font_id: FontId,
pub glyph_id: GlyphId,
pub range: Range<usize>,
pub size: Vec2,
pub advance: Vec2,
pub offset: Vec2,
pub ascent: f32,
Expand Down
88 changes: 73 additions & 15 deletions crates/attributed_string/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,22 +154,76 @@ impl AttributedString {
self.lines = lines;
}

pub fn to_path(&self) {
// TODO
pub fn to_path(&self, fonts_cache: &mut FontsCache) -> Option<tiny_skia_path::Path> {
let mut text_builder = tiny_skia_path::PathBuilder::new();

for span in self.spans.iter() {
for (cluster, byte_index) in span.iter_glyph_clusters() {
for glyph in cluster {
log::info!(
"Glyph: Range({:?}), {:?}, AttrsIndex({}), {:?}, ByteIndex({})",
glyph.get_range(),
span.get_level(),
span.get_attrs_index(),
glyph.get_transform(),
byte_index
);
let attrs = &self.attrs_intervals.intervals[span.get_attrs_index()].val;
let mut span_builder = tiny_skia_path::PathBuilder::new();

if let Some(font) = fonts_cache.get_font_by_attrs(attrs) {
let font_size = attrs.get_font_size();

for (cluster, byte_index) in span.iter_glyph_clusters() {
let mut cluster_builder = tiny_skia_path::PathBuilder::new();
let mut width = 0.0;
let mut x: f32 = 0.0;

for glyph_token in cluster {
log::info!(
"Glyph: Range({:?}), {:?}, AttrsIndex({}), {:?}, ByteIndex({})",
glyph_token.get_range(),
span.get_level(),
span.get_attrs_index(),
glyph_token.get_transform(),
byte_index
);

let sx = font.scale(font_size);

if let Some(outline) = font.outline(glyph_token.get_glyph().glyph_id) {
// By default, glyphs are upside-down, so we have to mirror them
let mut transform = tiny_skia_path::Transform::from_scale(1.0, -1.0);

// Scale to font-size
transform = transform.pre_scale(sx, sx);

// Apply offset.
//
// The first glyph in the cluster will have an offset from 0x0,
// but the later one will have an offset from the "current position".
// So we have to keep an advance.
transform = transform.pre_translate(
x + glyph_token.get_glyph().offset.x
+ glyph_token.get_transform().x,
glyph_token.get_glyph().offset.y + glyph_token.get_transform().y,
);

if let Some(outline) = outline.transform(transform) {
cluster_builder.push_path(&outline);
}
}

x += glyph_token.get_glyph().advance.x;

let glyph_width = glyph_token.get_glyph().advance.x * sx;
if glyph_width > width {
width = glyph_width;
}
}

if let Some(path) = cluster_builder.finish() {
span_builder.push_path(&path);
}
}
}

if let Some(path) = span_builder.finish() {
text_builder.push_path(&path);
}
}

return text_builder.finish();
}
}

Expand Down Expand Up @@ -211,7 +265,8 @@ mod tests {
let mut fonts_cache = FontsCache::new();
fonts_cache.load_system_fonts();

let text = String::from("Hello, world!\nשלום עולם!\nThis is a mix of English and Hebrew.");
// let text = String::from("Hello, world!\nשלום עולם!\nThis is a mix of English and Hebrew.");
let text = String::from("Hello, world!");
let attrs_intervals = vec![
AttrsInterval {
start: 0,
Expand Down Expand Up @@ -242,9 +297,12 @@ mod tests {

attributed_string.tokenize_text(&mut fonts_cache);
attributed_string.layout();
attributed_string.to_path();
let path = attributed_string.to_path(&mut fonts_cache);

// https://yqnn.github.io/svg-path-editor/
log::info!("{:?}", path);

assert_eq!(attributed_string.spans.is_empty(), false);
assert_eq!(path.is_some(), true);
}

#[test]
Expand Down

0 comments on commit 71a7eff

Please sign in to comment.