Working parley layout

This commit is contained in:
Blaž Hrastnik 2022-04-15 16:32:10 +09:00
parent e60e9099ca
commit 89a0be10e8
No known key found for this signature in database
GPG Key ID: 1238B9C4AD889640
4 changed files with 92 additions and 15 deletions

17
Cargo.lock generated
View File

@ -673,6 +673,14 @@ dependencies = [
"percent-encoding",
]
[[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"
@ -1080,6 +1088,7 @@ dependencies = [
"image",
"instant",
"lyon",
"parley",
"pollster",
"resource",
"swash",
@ -1734,6 +1743,14 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "parley"
version = "0.1.0"
dependencies = [
"fount",
"swash",
]
[[package]]
name = "percent-encoding"
version = "2.1.0"

View File

@ -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"

View File

@ -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 @@ pub fn as_ref(&self) -> FontRef {
}
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());
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 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
}

View File

@ -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
);
}