Unnamed repository; edit this file 'description' to name the repository.
Working parley layout
Blaž Hrastnik 2022-05-01
parent e60e909 · commit 89a0be1
-rw-r--r--Cargo.lock17
-rw-r--r--helix-ui/Cargo.toml1
-rw-r--r--helix-ui/src/main.rs84
-rw-r--r--helix-ui/src/shader.wgsl5
4 files changed, 92 insertions, 15 deletions
diff --git a/Cargo.lock b/Cargo.lock
index adbe8301..59383612 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -674,6 +674,14 @@ dependencies = [
]
[[package]]
+name = "fount"
+version = "0.1.0"
+source = "git+https://github.com/dfrg/fount#8f9259ef6b634c434f3dd9472f5200565e5dcd81"
+dependencies = [
+ "swash",
+]
+
+[[package]]
name = "futures-core"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1080,6 +1088,7 @@ dependencies = [
"image",
"instant",
"lyon",
+ "parley",
"pollster",
"resource",
"swash",
@@ -1735,6 +1744,14 @@ dependencies = [
]
[[package]]
+name = "parley"
+version = "0.1.0"
+dependencies = [
+ "fount",
+ "swash",
+]
+
+[[package]]
name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/helix-ui/Cargo.toml b/helix-ui/Cargo.toml
index 3bdcfb42..ae60e575 100644
--- a/helix-ui/Cargo.toml
+++ b/helix-ui/Cargo.toml
@@ -19,6 +19,7 @@ instant = "0.1.12"
# swash = "0.1.4"
swash = { git = "https://github.com/dfrg/swash" }
# parley = { git = "https://github.com/dfrg/parley" }
+parley = { path = "../../parley" }
lyon = "0.17.10"
diff --git a/helix-ui/src/main.rs b/helix-ui/src/main.rs
index 41d3330a..d4c2d0b7 100644
--- a/helix-ui/src/main.rs
+++ b/helix-ui/src/main.rs
@@ -1,3 +1,8 @@
+use parley::{
+ layout::Alignment,
+ style::{FontFamily, FontStack, StyleProperty},
+ FontContext, LayoutContext,
+};
use std::borrow::Cow;
use winit::{
event::{Event, WindowEvent},
@@ -97,7 +102,8 @@ impl Font {
}
fn font() -> VertexBuffers<Vertex, u16> {
- let font = Font::from_file("assets/fonts/Inter Variable/Inter.ttf", 0).unwrap();
+ // let font = Font::from_file("assets/fonts/Inter Variable/Inter.ttf", 0).unwrap();
+ let font = Font::from_file("assets/fonts/ttf/FiraCode-Regular.ttf", 0).unwrap();
let font = font.as_ref();
// -- Shaping
@@ -106,8 +112,8 @@ fn font() -> VertexBuffers<Vertex, u16> {
let mut shaper = context
.builder(font)
.script(Script::Latin)
- .size(14.)
- .variations(&[("wght", 520.5)])
+ .size(12.)
+ .variations(&[("wght", 400.0)])
.build();
shaper.add_str("a quick brown fox?");
@@ -146,23 +152,74 @@ fn font() -> VertexBuffers<Vertex, u16> {
.builder(font)
.hint(true)
.size(12.)
- .variations(&[("wght", 520.5)])
+ .variations(&[("wght", 400.0)])
.build();
- let glyph_id = font.charmap().map('Q');
+ let glyph_id = font.charmap().map('H');
let outline = scaler.scale_outline(glyph_id).unwrap();
- // -- Tesselation
+ // -- Layout
- // let mut encoder = Path::builder().transformed(Transform::new(
- // 0.01, 0., //
- // 0., 0.01, //
- // 0., 0.,
- // ));
+ let mut font_ctx = FontContext::new();
+ let font_family = font_ctx.register_fonts(font.data.to_vec()).unwrap();
+ let mut layout_ctx: LayoutContext<[u8; 4]> = LayoutContext::new();
+ // Encode glyphs into lyon paths
let mut encoder = Path::builder();
+ let mut encoder = encoder.transformed(Transform::default());
+
+ let mut builder = layout_ctx.ranged_builder(&mut font_ctx, "fn draw_edit_box_base<T: Renderer>(canvas: &mut Canvas<T>, x: f32, y: f32, w: f32, h: f32) { ", 1.);
+ builder.push_default(&StyleProperty::FontStack(FontStack::Single(
+ FontFamily::Named(&font_family),
+ )));
+ builder.push_default(&StyleProperty::FontSize(12.));
+ builder.push_default(&StyleProperty::Brush([255, 255, 255, 255]));
+ // builder.push() with range to set styling
+ let mut layout = builder.build();
+ let max_width = None;
+ layout.break_all_lines(max_width, Alignment::Start);
+
+ for line in layout.lines() {
+ let mut last_x = 0.0;
+ let mut last_y = 0.0;
+
+ for glyph_run in line.glyph_runs() {
+ let run = glyph_run.run();
+ // let color = &glyph_run.style().brush.0;
+ let font = run.font();
+ let font = font.as_ref();
+
+ let mut first = true;
+
+ // TODO: move let scaler here
+ for glyph in glyph_run.positioned_glyphs() {
+ let delta_x = glyph.x - last_x;
+ let delta_y = glyph.y - last_y;
+
+ last_x = glyph.x;
+ last_y = glyph.y;
+
+ if first {
+ // TODO:
+ }
+ first = false;
+
+ // TODO: each glyph will need a translate+scale along with the glyph
+ // or we could run the pipeline per letter?
- append_outline(&mut encoder, outline.verbs(), outline.points());
+ encoder.set_transform(Transform::new(
+ 1.0, 0.0, //
+ 0.0, -1.0, // invert y axis
+ glyph.x, glyph.y,
+ ));
+ if let Some(outline) = scaler.scale_outline(glyph.id) {
+ append_outline(&mut encoder, outline.verbs(), outline.points());
+ };
+ }
+ }
+ }
+
+ // -- Tesselation
let path = encoder.build();
let mut geometry: VertexBuffers<Vertex, u16> = VertexBuffers::new();
@@ -173,7 +230,7 @@ fn font() -> VertexBuffers<Vertex, u16> {
tessellator
.tessellate_path(
&path,
- &FillOptions::default(),
+ &FillOptions::non_zero().with_tolerance(0.01), // defaults to 0.1, compare further
&mut BuffersBuilder::new(&mut geometry, |vertex: FillVertex| Vertex {
position: vertex.position().to_array(),
}),
@@ -181,7 +238,6 @@ fn font() -> VertexBuffers<Vertex, u16> {
.unwrap();
}
- println!("{:?}", geometry);
geometry
}
diff --git a/helix-ui/src/shader.wgsl b/helix-ui/src/shader.wgsl
index f8d654d7..bb529648 100644
--- a/helix-ui/src/shader.wgsl
+++ b/helix-ui/src/shader.wgsl
@@ -14,7 +14,10 @@ var<uniform> view: View;
fn vs_main([[location(0)]] input: vec2<f32>) -> [[builtin(position)]] vec4<f32> {
// TODO: scale by hidpi factor?
return vec4<f32>(
- input.xy / view.size.xy * 2.0 * 1.5,
+
+ 2.0 * input.x / view.size.x - 1.0,
+ 1.0 - 2.0 * input.y / view.size.y,
+ // input.xy / view.size.xy * 2.0,
0.0, 1.0
);
}