wallet: editbox clip the rendered text properly

This commit is contained in:
darkfi
2024-07-06 10:44:44 +02:00
parent 01f3d5d000
commit 04ede06c9c
4 changed files with 66 additions and 27 deletions

View File

@@ -324,19 +324,22 @@ impl App {
node.set_property_bool("is_active", true).unwrap();
let prop = node.get_property("rect").unwrap();
prop.set_f32(0, 150.).unwrap();
let code = vec![Op::Sub((
Box::new(Op::LoadVar("h".to_string())),
Box::new(Op::ConstFloat32(60.)),
))];
prop.set_expr(1, code).unwrap();
let code = vec![Op::Sub((
Box::new(Op::LoadVar("w".to_string())),
Box::new(Op::ConstFloat32(120.)),
))];
prop.set_expr(2, code).unwrap();
prop.set_f32(1, 150.).unwrap();
prop.set_f32(2, 380.).unwrap();
//let code = vec![Op::Sub((
// Box::new(Op::LoadVar("h".to_string())),
// Box::new(Op::ConstFloat32(60.)),
//))];
//prop.set_expr(1, code).unwrap();
//let code = vec![Op::Sub((
// Box::new(Op::LoadVar("w".to_string())),
// Box::new(Op::ConstFloat32(120.)),
//))];
//prop.set_expr(2, code).unwrap();
prop.set_f32(3, 60.).unwrap();
node.set_property_f32("baseline", 40.).unwrap();
node.set_property_f32("font_size", 20.).unwrap();
node.set_property_f32("font_size", 40.).unwrap();
node.set_property_str("text", "hello king!😁🍆jelly 🍆1234").unwrap();
let prop = node.get_property("text_color").unwrap();
prop.set_f32(0, 1.).unwrap();
@@ -357,6 +360,7 @@ impl App {
prop.set_null(0).unwrap();
prop.set_null(1).unwrap();
node.set_property_u32("z_index", 1).unwrap();
node.set_property_bool("debug", true).unwrap();
drop(sg);
let pimpl = EditBox::new(

View File

@@ -139,6 +139,13 @@ impl Rectangle {
point.y <= self.y + self.h
}
pub fn rhs(&self) -> f32 {
self.x + self.w
}
pub fn bhs(&self) -> f32 {
self.y + self.h
}
pub fn top_left(&self) -> Point {
Point { x: self.x, y: self.y }
}

View File

@@ -34,26 +34,47 @@ impl MeshBuilder {
}
pub fn append(&mut self, mut verts: Vec<Vertex>, indices: Vec<u16>) {
if let Some(clipper) = &self.clipper {
for vert in &mut verts {
let mut vpos = vert.pos();
clipper.clip_point(&mut vpos);
vert.set_pos(&vpos);
}
}
let mut indices = indices.into_iter().map(|i| i + self.verts.len() as u16).collect();
self.verts.append(&mut verts);
self.indices.append(&mut indices);
}
pub fn draw_box(&mut self, obj: &Rectangle, color: Color, uv: &Rectangle) {
let (x1, y1) = obj.top_left().unpack();
let (x2, y2) = obj.bottom_right().unpack();
let clipped = match &self.clipper {
Some(clipper) => {
let Some(clipped) = clipper.clip(&obj) else {
return;
};
clipped
}
None => obj.clone(),
};
let (x1, y1) = clipped.top_left().unpack();
let (x2, y2) = clipped.bottom_right().unpack();
let (u1, v1) = uv.top_left().unpack();
let (u2, v2) = uv.bottom_right().unpack();
// Interpolate UV coords
assert!(obj.w >= clipped.w);
assert!(obj.h >= clipped.h);
let i = (clipped.x - obj.x) / obj.w;
let clip_u1 = u1 + i*(u2 - u1);
let i = (clipped.rhs() - obj.x) / obj.w;
let clip_u2 = u1 + i*(u2 - u1);
let i = (clipped.y - obj.y) / obj.h;
let clip_v1 = v1 + i*(v2 - v1);
let i = (clipped.bhs() - obj.y) / obj.h;
let clip_v2 = v1 + i*(v2 - v1);
let (u1, u2) = (clip_u1, clip_u2);
let (v1, v2) = (clip_v1, clip_v2);
let verts = vec![
// top left
Vertex { pos: [x1, y1], color, uv: [u1, v1] },

View File

@@ -246,18 +246,21 @@ impl EditBox {
/// Called whenever the text or any text property changes.
/// Not related to cursor, text highlighting or bounding (clip) rects.
async fn regen_mesh(&self, clip: &Rectangle) -> TextRenderInfo {
async fn regen_mesh(&self, mut clip: Rectangle) -> TextRenderInfo {
clip.x = 0.;
clip.y = 0.;
let text = self.text.get();
let font_size = self.font_size.get();
let text_color = self.text_color.get();
let baseline = self.baseline.get();
let debug = self.debug.get();
debug!(target: "ui::editbox", "Rendering text '{}'", text);
debug!(target: "ui::editbox", "Rendering text '{}' clip={:?}", text, clip);
let glyphs = self.glyphs.lock().unwrap().clone();
let atlas = text2::make_texture_atlas(&self.render_api, font_size, &glyphs).await.unwrap();
let mut mesh = MeshBuilder::new();
let mut mesh = MeshBuilder::with_clip(clip.clone());
let mut glyph_pos_iter = GlyphPositionIter::new(font_size, &glyphs, baseline);
for ((uv_rect, glyph_rect), glyph) in
atlas.uv_rects.into_iter().zip(glyph_pos_iter).zip(glyphs.iter())
@@ -270,6 +273,10 @@ impl EditBox {
mesh.draw_box(&glyph_rect, color, &uv_rect);
}
if debug {
mesh.draw_outline(&clip, COLOR_BLUE, 1.);
}
let mesh = mesh.alloc(&self.render_api).await.unwrap();
TextRenderInfo { mesh, texture_id: atlas.texture_id }
@@ -438,11 +445,14 @@ impl EditBox {
panic!("Node {:?} bad rect property", node);
};
rect.x += parent_rect.x;
rect.y += parent_rect.y;
let render_info = self.render_info.lock().unwrap().clone();
let render_info = match render_info {
Some(render_info) => render_info,
None => {
let render_info = self.regen_mesh(&rect).await;
let render_info = self.regen_mesh(rect.clone()).await;
*self.render_info.lock().unwrap() = Some(render_info.clone());
render_info
}
@@ -455,9 +465,6 @@ impl EditBox {
num_elements: render_info.mesh.num_elements,
};
rect.x += parent_rect.x;
rect.y += parent_rect.x;
let off_x = rect.x / parent_rect.w;
let off_y = rect.y / parent_rect.h;
let scale_x = 1. / parent_rect.w;