Remove script access to TextLayout GlyphPositions

This commit is contained in:
marceline-cramer 2022-07-23 02:39:34 -06:00
parent ca1841af10
commit da4fce3d19
7 changed files with 37 additions and 103 deletions

View File

@ -1,7 +1,6 @@
use crate::{Color, Vec2};
use bitflags::bitflags;
use canary_script::GlyphPosition;
use canary_script::Panel;
use canary_script::{Panel, TextLayout};
pub enum Corner {
TopRight,
@ -330,9 +329,9 @@ impl DrawContext {
self.draw_rect(inner_rect, color);
}
pub fn draw_text(
pub fn draw_text_layout(
&self,
glyphs: &[GlyphPosition],
layout: &TextLayout,
mut offset: Vec2,
scale: f32,
mut color: Color,
@ -345,7 +344,8 @@ impl DrawContext {
color.a *= opacity;
}
self.panel.draw_glyphs(glyphs, offset.into(), scale, color);
self.panel
.draw_text_layout(layout, offset.into(), scale, color);
}
pub fn get_clip_rect(&self) -> &Option<Rect> {

View File

@ -1,7 +1,7 @@
use crate::anim::Animation;
use crate::draw::{CornerFlags, DrawContext, Rect};
use crate::{Color, CursorEventKind, Vec2};
use canary_script::{Font, GlyphPosition, TextLayout};
use canary_script::{Font, TextLayout};
use keyframe::functions::*;
pub mod button;

View File

@ -22,7 +22,7 @@ pub struct Label {
baseline: f32,
center_y: bool,
dirty: bool,
glyphs: Vec<GlyphPosition>,
layout: Option<TextLayout>,
bounds: Rect,
offset: Vec2,
}
@ -48,7 +48,7 @@ impl Label {
baseline,
center_y,
dirty: true,
glyphs: Vec::new(),
layout: None,
bounds: Rect::from_xy_size(Vec2::ZERO, Vec2::ZERO),
offset: Vec2::ZERO,
}
@ -61,7 +61,6 @@ impl Widget for Label {
let layout = TextLayout::new(&self.text.font, &self.text.text);
let bounds = Rect::from(layout.get_bounds()).scale(self.scale);
self.bounds = bounds;
self.glyphs = layout.get_glyphs();
let xoff = match self.alignment {
HorizontalAlignment::Left => self.left - bounds.bl.x,
HorizontalAlignment::Right => self.right - bounds.tr.x,
@ -82,9 +81,11 @@ impl Widget for Label {
self.offset = Vec2::new(xoff, yoff + self.baseline);
self.dirty = false;
self.layout = Some(layout);
}
ctx.draw_text(&self.glyphs, self.offset, self.scale, self.color);
if let Some(layout) = self.layout.as_ref() {
ctx.draw_text_layout(layout, self.offset, self.scale, self.color);
}
}
}

View File

@ -95,18 +95,10 @@ impl Panel {
}
}
pub fn draw_glyphs(&self, glyphs: &[GlyphPosition], offset: Vec2, scale: f32, color: Color) {
pub fn draw_text_layout(&self, layout: &TextLayout, offset: Vec2, scale: f32, color: Color) {
unsafe {
draw_glyphs(
glyphs.as_ptr() as u32,
glyphs.len() as u32,
offset.x,
offset.y,
scale,
color.r,
color.g,
color.b,
color.a,
draw_text_layout(
layout.0, offset.x, offset.y, scale, color.r, color.g, color.b, color.a,
)
}
}
@ -165,16 +157,6 @@ impl TextLayout {
bounds
}
}
pub fn get_glyphs(&self) -> Vec<GlyphPosition> {
unsafe {
let num = text_layout_get_glyphs_num(self.0) as usize;
let mut glyphs = Vec::with_capacity(num);
glyphs.set_len(num);
text_layout_get_glyphs_data(self.0, glyphs.as_ptr() as u32, num as u32);
glyphs
}
}
}
impl Drop for TextLayout {
@ -185,24 +167,10 @@ impl Drop for TextLayout {
extern "C" {
fn draw_indexed(vertices_ptr: u32, vertices_num: u32, indices_ptr: u32, indices_num: u32);
fn draw_glyphs(
glyphs_ptr: u32,
glyphs_len: u32,
xoff: f32,
yoff: f32,
scale: f32,
r: f32,
g: f32,
b: f32,
a: f32,
);
fn draw_text_layout(id: u32, xoff: f32, yoff: f32, scale: f32, r: f32, g: f32, b: f32, a: f32);
fn font_load(family_ptr: u32, family_len: u32) -> u32;
fn text_layout_new(font_id: u32, text_ptr: u32, text_len: u32) -> u32;
fn text_layout_delete(id: u32);
fn text_layout_get_bounds(id: u32, rect_ptr: u32);
fn text_layout_get_glyphs_num(id: u32) -> u32;
fn text_layout_get_glyphs_data(id: u32, glyphs_ptr: u32, glyphs_num: u32);
}

View File

@ -84,17 +84,6 @@ impl Rect {
};
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Pod, Zeroable)]
pub struct GlyphPosition {
pub face: u16,
pub index: u16,
pub hori_advance: i32,
pub vert_advance: i32,
pub xoff: i32,
pub yoff: i32,
}
#[cfg(feature = "glam")]
mod glam_interop {
use super::*;

View File

@ -13,7 +13,7 @@ pub mod text;
pub trait ScriptAbi {
fn start_draw(&self);
fn draw_indexed(&self, vertices: &[MeshVertex], indices: &[MeshIndex]);
fn draw_glyphs(&self, glyphs: &[GlyphPosition], offset: Vec2, scale: f32, color: Color);
fn draw_text_layout(&self, id: u32, offset: Vec2, scale: f32, color: Color);
fn with_draw_commands(&self, f: impl FnOnce(&[DrawCommand]));
fn font_load(&self, family: &str) -> u32;
@ -21,8 +21,6 @@ pub trait ScriptAbi {
fn text_layout_new(&self, font_id: u32, text: &str) -> u32;
fn text_layout_delete(&self, id: u32);
fn text_layout_get_bounds(&self, id: u32, rect: &mut Rect);
fn text_layout_get_glyphs_num(&self, id: u32) -> u32;
fn text_layout_get_glyphs_data(&self, id: u32, glyphs: &mut [GlyphPosition]);
}
pub trait ScriptInstance {
@ -108,10 +106,9 @@ impl<T: ScriptAbi> WasmtimeScript<T> {
linker.func_wrap(
module,
"draw_glyphs",
|mut caller: wasmtime::Caller<'_, T>,
glyphs_ptr: u32,
glyphs_num: u32,
"draw_text_layout",
|caller: wasmtime::Caller<'_, T>,
id: u32,
xoff: f32,
yoff: f32,
scale: f32,
@ -119,10 +116,9 @@ impl<T: ScriptAbi> WasmtimeScript<T> {
g: f32,
b: f32,
a: f32| {
let glyphs = Self::get_memory_slice(&mut caller, glyphs_ptr, glyphs_num);
let offset = Vec2 { x: xoff, y: yoff };
let color = Color { r, g, b, a };
caller.data().draw_glyphs(glyphs, offset, scale, color);
caller.data().draw_text_layout(id, offset, scale, color);
},
)?;
@ -147,7 +143,7 @@ impl<T: ScriptAbi> WasmtimeScript<T> {
linker.func_wrap(
module,
"text_layout_delete",
|mut caller: wasmtime::Caller<'_, T>, id: u32| caller.data().text_layout_delete(id),
|caller: wasmtime::Caller<'_, T>, id: u32| caller.data().text_layout_delete(id),
)?;
linker.func_wrap(
@ -159,24 +155,6 @@ impl<T: ScriptAbi> WasmtimeScript<T> {
},
)?;
linker.func_wrap(
module,
"text_layout_get_glyphs_num",
|mut caller: wasmtime::Caller<'_, T>, id: u32| {
caller.data().text_layout_get_glyphs_num(id)
},
)?;
linker.func_wrap(
module,
"text_layout_get_glyphs_data",
|mut caller: wasmtime::Caller<'_, T>, id: u32, glyphs_ptr: u32, glyphs_num: u32| {
let glyphs: &mut [GlyphPosition] =
Self::get_memory_slice(&mut caller, glyphs_ptr, glyphs_num);
caller.data().text_layout_get_glyphs_data(id, glyphs);
},
)?;
Ok(())
}
@ -266,8 +244,10 @@ impl ScriptAbi for ScriptAbiImpl {
})
}
fn draw_glyphs(&self, glyphs: &[GlyphPosition], offset: Vec2, scale: f32, color: Color) {
fn draw_text_layout(&self, id: u32, offset: Vec2, scale: f32, color: Color) {
// TODO multiple fonts per layout
let layouts = self.text_layouts.read();
let glyphs = layouts.get(id as usize).unwrap().glyphs.as_slice();
let loaded = self.loaded_fonts.read();
let font = loaded.get(glyphs[0].face as usize).unwrap();
let cmds = font.draw(glyphs, offset, scale, color);
@ -308,19 +288,4 @@ impl ScriptAbi for ScriptAbiImpl {
let src = self.text_layouts.read().get(id as usize).unwrap().bounds;
let _ = std::mem::replace(dst, src);
}
fn text_layout_get_glyphs_num(&self, id: u32) -> u32 {
self.text_layouts
.read()
.get(id as usize)
.unwrap()
.glyphs
.len() as u32
}
fn text_layout_get_glyphs_data(&self, id: u32, dst: &mut [GlyphPosition]) {
let layouts = self.text_layouts.read();
let src = layouts.get(id as usize).unwrap().glyphs.as_slice();
dst.copy_from_slice(src);
}
}

View File

@ -10,7 +10,7 @@ use allsorts::pathfinder_geometry::{line_segment::LineSegment2F, vector::Vector2
use allsorts::tables::{glyf::GlyfTable, loca::LocaTable};
use allsorts::tables::{FontTableProvider, SfntVersion};
use allsorts::{tag, Font as AllsortsFont};
use canary_types::{Color, GlyphPosition, Rect, Vec2};
use canary_types::{Color, Rect, Vec2};
use lyon::path::Path;
use ouroboros::self_referencing;
use parking_lot::{Mutex, RwLock};
@ -196,6 +196,17 @@ pub struct GlyphMesh {
indices: Vec<u32>,
}
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct GlyphPosition {
pub face: u16,
pub index: u16,
pub hori_advance: i32,
pub vert_advance: i32,
pub xoff: i32,
pub yoff: i32,
}
pub struct TextLayout {
pub bounds: Rect,
pub glyphs: Vec<GlyphPosition>,