mirror of https://github.com/helix-editor/helix
Working parley layout
parent
e60e9099ca
commit
89a0be10e8
|
@ -673,6 +673,14 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fount"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/dfrg/fount#8f9259ef6b634c434f3dd9472f5200565e5dcd81"
|
||||||
|
dependencies = [
|
||||||
|
"swash",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.21"
|
version = "0.3.21"
|
||||||
|
@ -1080,6 +1088,7 @@ dependencies = [
|
||||||
"image",
|
"image",
|
||||||
"instant",
|
"instant",
|
||||||
"lyon",
|
"lyon",
|
||||||
|
"parley",
|
||||||
"pollster",
|
"pollster",
|
||||||
"resource",
|
"resource",
|
||||||
"swash",
|
"swash",
|
||||||
|
@ -1734,6 +1743,14 @@ dependencies = [
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parley"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"fount",
|
||||||
|
"swash",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.1.0"
|
version = "2.1.0"
|
||||||
|
|
|
@ -19,6 +19,7 @@ instant = "0.1.12"
|
||||||
# swash = "0.1.4"
|
# swash = "0.1.4"
|
||||||
swash = { git = "https://github.com/dfrg/swash" }
|
swash = { git = "https://github.com/dfrg/swash" }
|
||||||
# parley = { git = "https://github.com/dfrg/parley" }
|
# parley = { git = "https://github.com/dfrg/parley" }
|
||||||
|
parley = { path = "../../parley" }
|
||||||
|
|
||||||
lyon = "0.17.10"
|
lyon = "0.17.10"
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
use parley::{
|
||||||
|
layout::Alignment,
|
||||||
|
style::{FontFamily, FontStack, StyleProperty},
|
||||||
|
FontContext, LayoutContext,
|
||||||
|
};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use winit::{
|
use winit::{
|
||||||
event::{Event, WindowEvent},
|
event::{Event, WindowEvent},
|
||||||
|
@ -97,7 +102,8 @@ impl Font {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn font() -> VertexBuffers<Vertex, u16> {
|
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();
|
let font = font.as_ref();
|
||||||
|
|
||||||
// -- Shaping
|
// -- Shaping
|
||||||
|
@ -106,8 +112,8 @@ fn font() -> VertexBuffers<Vertex, u16> {
|
||||||
let mut shaper = context
|
let mut shaper = context
|
||||||
.builder(font)
|
.builder(font)
|
||||||
.script(Script::Latin)
|
.script(Script::Latin)
|
||||||
.size(14.)
|
.size(12.)
|
||||||
.variations(&[("wght", 520.5)])
|
.variations(&[("wght", 400.0)])
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
shaper.add_str("a quick brown fox?");
|
shaper.add_str("a quick brown fox?");
|
||||||
|
@ -146,23 +152,74 @@ fn font() -> VertexBuffers<Vertex, u16> {
|
||||||
.builder(font)
|
.builder(font)
|
||||||
.hint(true)
|
.hint(true)
|
||||||
.size(12.)
|
.size(12.)
|
||||||
.variations(&[("wght", 520.5)])
|
.variations(&[("wght", 400.0)])
|
||||||
.build();
|
.build();
|
||||||
let glyph_id = font.charmap().map('Q');
|
let glyph_id = font.charmap().map('H');
|
||||||
let outline = scaler.scale_outline(glyph_id).unwrap();
|
let outline = scaler.scale_outline(glyph_id).unwrap();
|
||||||
|
|
||||||
// -- Tesselation
|
// -- Layout
|
||||||
|
|
||||||
// let mut encoder = Path::builder().transformed(Transform::new(
|
let mut font_ctx = FontContext::new();
|
||||||
// 0.01, 0., //
|
let font_family = font_ctx.register_fonts(font.data.to_vec()).unwrap();
|
||||||
// 0., 0.01, //
|
let mut layout_ctx: LayoutContext<[u8; 4]> = LayoutContext::new();
|
||||||
// 0., 0.,
|
|
||||||
// ));
|
|
||||||
|
|
||||||
|
// Encode glyphs into lyon paths
|
||||||
let mut encoder = Path::builder();
|
let mut encoder = Path::builder();
|
||||||
|
let mut encoder = encoder.transformed(Transform::default());
|
||||||
|
|
||||||
append_outline(&mut encoder, outline.verbs(), outline.points());
|
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?
|
||||||
|
|
||||||
|
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 path = encoder.build();
|
||||||
|
|
||||||
let mut geometry: VertexBuffers<Vertex, u16> = VertexBuffers::new();
|
let mut geometry: VertexBuffers<Vertex, u16> = VertexBuffers::new();
|
||||||
|
@ -173,7 +230,7 @@ fn font() -> VertexBuffers<Vertex, u16> {
|
||||||
tessellator
|
tessellator
|
||||||
.tessellate_path(
|
.tessellate_path(
|
||||||
&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 {
|
&mut BuffersBuilder::new(&mut geometry, |vertex: FillVertex| Vertex {
|
||||||
position: vertex.position().to_array(),
|
position: vertex.position().to_array(),
|
||||||
}),
|
}),
|
||||||
|
@ -181,7 +238,6 @@ fn font() -> VertexBuffers<Vertex, u16> {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("{:?}", geometry);
|
|
||||||
geometry
|
geometry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,10 @@ var<uniform> view: View;
|
||||||
fn vs_main([[location(0)]] input: vec2<f32>) -> [[builtin(position)]] vec4<f32> {
|
fn vs_main([[location(0)]] input: vec2<f32>) -> [[builtin(position)]] vec4<f32> {
|
||||||
// TODO: scale by hidpi factor?
|
// TODO: scale by hidpi factor?
|
||||||
return vec4<f32>(
|
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
|
0.0, 1.0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue