Added text rendering to rust bindings
This commit is contained in:
parent
40f15643d9
commit
2e9e07d568
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -5,3 +5,12 @@ version = 4
|
||||
[[package]]
|
||||
name = "daria"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "1.0.0-alpha.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e136bfa874086c78f34d6eba98c423fefe464ce57f38164d16893ba8ed358e70"
|
||||
|
||||
@ -10,3 +10,5 @@ path = "src/l3/r4/r4d.rs"
|
||||
[lib]
|
||||
name = "alice_and_misc"
|
||||
path = "src/l2/allie_rs/lib.rs"
|
||||
[dependencies]
|
||||
libc = "1.0.0-alpha.3"
|
||||
|
||||
@ -25,6 +25,7 @@ void allie_Alice_lucy_cache_add_glyphs(Alice* alice, VecLucyGlyphCachingRequest
|
||||
Alice_lucy_cache_add_glyphs(alice, req);
|
||||
}
|
||||
|
||||
// todo: transition to cvec4 from vec4 color (vec4 color makes no sense for fonts)
|
||||
void allie_Alice_lucy_renderer_add_simple_label(Alice* alice, RBTreeNodeLucyFaceFixedSize* ffs,
|
||||
vec4 color, S32 additional_y_advance, SpanU8 text, ivec2 start_pos
|
||||
) {
|
||||
|
||||
103
src/l2/allie_rs/alice.rs
Normal file
103
src/l2/allie_rs/alice.rs
Normal file
@ -0,0 +1,103 @@
|
||||
use std::ffi::{c_void};
|
||||
use std::marker::PhantomData;
|
||||
use crate::geom::{*};
|
||||
use crate::allie;
|
||||
use crate::allie::CSpan;
|
||||
use crate::uint_segments::{U32Segment};
|
||||
|
||||
pub struct LucyFaceFixedSize {
|
||||
opa: allie::LucyFaceFixedSize,
|
||||
}
|
||||
|
||||
impl Drop for LucyFaceFixedSize {
|
||||
fn drop(&mut self) {
|
||||
// todo: so something
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LucyFace {
|
||||
opa: allie::LucyFace,
|
||||
}
|
||||
|
||||
impl LucyFace {
|
||||
pub fn of_size(&self, size: u32) -> LucyFaceFixedSize{
|
||||
LucyFaceFixedSize{opa: unsafe { allie::LucyFace_of_size(self.opa, size) }}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Drop for LucyFace {
|
||||
fn drop(&mut self) {
|
||||
// todo: oh what should I do
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct Alice {
|
||||
opa: allie::Alice,
|
||||
}
|
||||
|
||||
pub struct AliceCallbacks<'a> {
|
||||
pub on_wl_pointer_button: Box<dyn FnMut(u32, u32) + 'a>,
|
||||
pub on_wl_keyboard_key: Box<dyn FnMut(u32, u32) + 'a>,
|
||||
pub on_another_frame: Box<dyn FnMut(f32) + 'a>,
|
||||
pub on_wl_pointer_motion: Box<dyn FnMut(vec2) +'a>,
|
||||
}
|
||||
|
||||
pub struct LucyGlyphCachingRequest<'a> {
|
||||
pub sized_face: &'a mut LucyFaceFixedSize,
|
||||
pub codepoint_ranges: Vec<U32Segment>,
|
||||
}
|
||||
impl<'a> From<& LucyGlyphCachingRequest<'a>> for allie::LucyGlyphCachingRequest<'a> {
|
||||
fn from(value: & LucyGlyphCachingRequest<'a>) -> Self {
|
||||
Self{phantom: PhantomData,
|
||||
sized_face: value.sized_face.opa,
|
||||
codepoint_ranges: allie::CVec::<U32Segment>::from(&value.codepoint_ranges)}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Alice {
|
||||
pub fn new() -> Self {
|
||||
Alice{opa: unsafe { allie::Alice_new() }}
|
||||
}
|
||||
|
||||
pub fn mainloop<'a>(&'a self, mut cb: AliceCallbacks<'a>) {
|
||||
let guest_data = (&raw mut cb) as allie::Alice;
|
||||
|
||||
let a_cb = allie::AliceCallbacks {
|
||||
guest: guest_data,
|
||||
on_wl_pointer_button: allie::AliceCallbacks_on_wl_pointer_button,
|
||||
on_wl_keyboard_key: allie::AliceCallbacks_on_wl_keyboard_key,
|
||||
on_another_frame: allie::AliceCallbacks_on_another_frame,
|
||||
on_wl_pointer_motion: allie::AliceCallbacks_on_wl_pointer_motion,
|
||||
};
|
||||
|
||||
unsafe{ allie::Alice_mainloop(self.opa, &a_cb) };
|
||||
}
|
||||
|
||||
pub fn set_clear_color(&self, color: vec4) {
|
||||
unsafe { allie::Alice_set_clear_color(self.opa, color) };
|
||||
}
|
||||
|
||||
pub fn new_lucy_face(&self, path: &str) -> LucyFace{
|
||||
LucyFace{opa: unsafe { allie::Alice_new_LucyFace(self.opa, allie::CVec::<u8>::from(path)) } }
|
||||
}
|
||||
|
||||
pub fn lucy_cache_add_glyphs(&self, req: Vec<LucyGlyphCachingRequest>){
|
||||
let a_req = allie::CVec::<allie::LucyGlyphCachingRequest>::from(&req);
|
||||
unsafe { allie::Alice_lucy_cache_add_glyphs(self.opa, a_req) };
|
||||
}
|
||||
|
||||
pub fn lucy_renderer_add_simple_label(&self, ffs: &LucyFaceFixedSize, color: vec4,
|
||||
additional_y_advance: i32, text: &str, start_pos: ivec2
|
||||
) {
|
||||
unsafe { allie::Alice_lucy_renderer_add_simple_label(self.opa, ffs.opa, color,
|
||||
additional_y_advance, allie::CSpan::<u8>::from(text), start_pos) }
|
||||
}
|
||||
}
|
||||
impl Drop for Alice {
|
||||
fn drop(&mut self) {
|
||||
// todo: do something
|
||||
}
|
||||
}
|
||||
131
src/l2/allie_rs/allie.rs
Normal file
131
src/l2/allie_rs/allie.rs
Normal file
@ -0,0 +1,131 @@
|
||||
use std::ffi::c_void;
|
||||
use crate::alice;
|
||||
use crate::geom::{vec2, vec4, ivec2};
|
||||
use std::ptr::copy_nonoverlapping;
|
||||
use std::ptr;
|
||||
use libc::{calloc, free};
|
||||
use std::mem::size_of;
|
||||
use std::marker::PhantomData;
|
||||
use crate::uint_segments::{*};
|
||||
|
||||
/* usize is u64, ok? */
|
||||
// fn safe_calloc(nobj: usize, size: usize) -> *mut c_void{
|
||||
// let p = unsafe { calloc(nobj, size) };
|
||||
// if (p.is_null()){ panic!("calloc: Not enough memory\n") }
|
||||
// p
|
||||
// }
|
||||
|
||||
fn safe_calloc<T>(nobj: usize) ->* mut T {
|
||||
let p = unsafe { calloc(nobj, size_of::<T>()) };
|
||||
if (p.is_null()){ panic!("calloc: Not enough memory\n") }
|
||||
p as *mut T
|
||||
}
|
||||
|
||||
pub type Alice = *mut c_void;
|
||||
pub type LucyFace = *mut c_void;
|
||||
pub type LucyFaceFixedSize = *mut c_void;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CSpan<'a, T> {
|
||||
phantom: PhantomData<&'a T>,
|
||||
data: *const T,
|
||||
len: u64
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for CSpan<'a, u8> {
|
||||
fn from(s: &'a str) -> Self {
|
||||
let data: *const u8 = s.as_ptr();
|
||||
Self{phantom: PhantomData, data, len: s.len() as u64}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CVec<T> {
|
||||
buf: *mut T,
|
||||
len: u64, capacity: u64
|
||||
}
|
||||
|
||||
impl<'a, Td, Ts> From<&'a Vec<Ts>> for CVec<Td> where Td: From<&'a Ts>{
|
||||
fn from(value: &'a Vec<Ts>) -> Self {
|
||||
let buf: *mut Td = safe_calloc(value.len());
|
||||
for (i, src) in value.iter().enumerate() {
|
||||
unsafe { ptr::write(buf.add(i), Td::from(src)) };
|
||||
}
|
||||
Self {buf, len: value.len() as u64, capacity: value.len() as u64}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for CVec<u8> {
|
||||
fn from(s: &str) -> Self {
|
||||
let buf: *mut u8 = safe_calloc(s.len());
|
||||
unsafe { copy_nonoverlapping(s.as_ptr(), buf, s.len()) };
|
||||
Self{buf, len: s.len() as u64, capacity: s.len() as u64}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for CVec<T>{
|
||||
fn drop(&mut self) {
|
||||
unsafe { free(self.buf as *mut c_void) };
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct LucyGlyphCachingRequest<'a> {
|
||||
pub phantom: PhantomData<&'a u8>,
|
||||
pub sized_face: LucyFaceFixedSize,
|
||||
pub codepoint_ranges: CVec<U32Segment>,
|
||||
}
|
||||
/* Copying from Rust analog type to C allie type will be implemented outside */
|
||||
|
||||
|
||||
#[repr(C)]
|
||||
pub struct AliceCallbacks {
|
||||
pub guest: Alice,
|
||||
/* guest data, button, btn action */
|
||||
pub on_wl_pointer_button: extern "C" fn (Alice, u32, u32),
|
||||
/* guest data, keysym, key action (wl_keyboard_key_state) */
|
||||
pub on_wl_keyboard_key: extern "C" fn (Alice, u32, u32),
|
||||
/* guest data, passed time */
|
||||
pub on_another_frame: extern "C" fn (Alice, f32),
|
||||
pub on_wl_pointer_motion: extern "C" fn (Alice, vec2),
|
||||
}
|
||||
|
||||
unsafe extern "C" {
|
||||
#[link_name="Alice_new"]
|
||||
pub fn Alice_new() -> Alice;
|
||||
#[link_name="Alice_mainloop"]
|
||||
pub fn Alice_mainloop(alice: Alice, cb: *const AliceCallbacks);
|
||||
#[link_name="Alice_set_clear_color"]
|
||||
pub fn Alice_set_clear_color(alice: Alice, color: vec4);
|
||||
#[link_name="Alice_new_LucyFace"]
|
||||
pub fn Alice_new_LucyFace(alice: Alice, path: CVec<u8>) -> LucyFace;
|
||||
#[link_name="LucyFace_of_size"]
|
||||
pub fn LucyFace_of_size(alice: LucyFace, size: u32) -> LucyFaceFixedSize;
|
||||
#[link_name="Alice_lucy_cache_add_glyphs"]
|
||||
pub fn Alice_lucy_cache_add_glyphs(alice: Alice, req: CVec<LucyGlyphCachingRequest>);
|
||||
#[link_name="Alice_lucy_renderer_add_simple_label"]
|
||||
pub fn Alice_lucy_renderer_add_simple_label( /* todo: make color cvec4 */
|
||||
alice: Alice, ffs: LucyFaceFixedSize,
|
||||
color: vec4, additional_y_advance: i32, text: CSpan<u8>, start_pos: ivec2);
|
||||
}
|
||||
|
||||
pub extern "C" fn AliceCallbacks_on_wl_pointer_button(dt: Alice, button: u32, act: u32){
|
||||
let cb: &mut alice::AliceCallbacks = unsafe { &mut *(dt as *mut alice::AliceCallbacks) };
|
||||
(cb.on_wl_pointer_button)(button, act);
|
||||
}
|
||||
|
||||
pub extern "C" fn AliceCallbacks_on_wl_keyboard_key(dt: Alice, keysym: u32, act: u32){
|
||||
let cb: &mut alice::AliceCallbacks = unsafe { &mut *(dt as *mut alice::AliceCallbacks) };
|
||||
(cb.on_wl_keyboard_key)(keysym, act);
|
||||
}
|
||||
|
||||
pub extern "C" fn AliceCallbacks_on_another_frame(dt: Alice, fl: f32){
|
||||
let cb: &mut alice::AliceCallbacks = unsafe { &mut *(dt as *mut alice::AliceCallbacks) };
|
||||
(cb.on_another_frame)(fl);
|
||||
}
|
||||
|
||||
pub extern "C" fn AliceCallbacks_on_wl_pointer_motion(dt: Alice, pos: vec2){
|
||||
let cb: &mut alice::AliceCallbacks = unsafe { &mut *(dt as *mut alice::AliceCallbacks) };
|
||||
(cb.on_wl_pointer_motion)(pos);
|
||||
}
|
||||
@ -9,6 +9,7 @@ impl AssertTrue for Assert<true>{}
|
||||
|
||||
/* Turn out for tuple struct, where clause goes after the field list */
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct GeomVec<T, const N: usize> (pub [T; N]) where T: Copy + Clone;
|
||||
|
||||
impl<T, const N: usize> Add for GeomVec<T, N> where
|
||||
@ -21,19 +22,6 @@ impl<T, const N: usize> Add for GeomVec<T, N> where
|
||||
}
|
||||
}
|
||||
|
||||
trait HasY {
|
||||
fn has_foo() -> bool {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// impl<T, const N: usize> HasY for GeomVec<T, N> where
|
||||
// T: Copy + Clone,
|
||||
// Assert<{N >= 1}> : AssertTrue {
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
impl<T, const N: usize> GeomVec<T, N> where
|
||||
T: Copy + Clone,
|
||||
Assert<{N >= 1}> : AssertTrue {
|
||||
|
||||
@ -9,89 +9,6 @@
|
||||
/* *c_void is nothing special, it is the same as *u8 for example */
|
||||
pub mod geom;
|
||||
pub mod int_primitives;
|
||||
|
||||
use std::ffi::{c_void};
|
||||
use geom::{*};
|
||||
|
||||
type VoidPtr = *mut c_void;
|
||||
|
||||
#[repr(C)]
|
||||
struct allie_AliceCallbacks{
|
||||
guest: VoidPtr,
|
||||
/* guest data, button, btn action */
|
||||
on_wl_pointer_button: extern "C" fn (VoidPtr, u32, u32),
|
||||
/* guest data, keysym, key action (wl_keyboard_key_state) */
|
||||
on_wl_keyboard_key: extern "C" fn (VoidPtr, u32, u32),
|
||||
/* guest data, passed time */
|
||||
on_another_frame: extern "C" fn (VoidPtr, f32),
|
||||
on_wl_pointer_motion: extern "C" fn (VoidPtr, vec2),
|
||||
}
|
||||
|
||||
unsafe extern "C" {
|
||||
#[link_name="Alice_new"]
|
||||
fn allie_Alice_new() -> *mut c_void;
|
||||
#[link_name="Alice_mainloop"]
|
||||
fn allie_Alice_mainloop(alice: VoidPtr, cb: *const allie_AliceCallbacks);
|
||||
#[link_name="Alice_set_clear_color"]
|
||||
fn allie_Alice_set_clear_color(alice: VoidPtr, color: vec4);
|
||||
}
|
||||
|
||||
pub struct Alice {
|
||||
opa: *mut c_void,
|
||||
}
|
||||
|
||||
pub struct AliceCallbacks {
|
||||
pub on_wl_pointer_button: Box<dyn FnMut(u32, u32)>,
|
||||
pub on_wl_keyboard_key: Box<dyn FnMut(u32, u32)>,
|
||||
pub on_another_frame: Box<dyn FnMut(f32)>,
|
||||
pub on_wl_pointer_motion: Box<dyn FnMut(vec2)>,
|
||||
}
|
||||
|
||||
extern "C" fn allie_AliceCallbacks_on_wl_pointer_button(dt: VoidPtr, button: u32, act: u32){
|
||||
let cb: &mut AliceCallbacks = unsafe { &mut *(dt as *mut AliceCallbacks) };
|
||||
(cb.on_wl_pointer_button)(button, act);
|
||||
}
|
||||
|
||||
extern "C" fn allie_AliceCallbacks_on_wl_keyboard_key(dt: VoidPtr, keysym: u32, act: u32){
|
||||
let cb: &mut AliceCallbacks = unsafe { &mut *(dt as *mut AliceCallbacks) };
|
||||
(cb.on_wl_keyboard_key)(keysym, act);
|
||||
}
|
||||
|
||||
extern "C" fn allie_AliceCallbacks_on_another_frame(dt: VoidPtr, fl: f32){
|
||||
let cb: &mut AliceCallbacks = unsafe { &mut *(dt as *mut AliceCallbacks) };
|
||||
(cb.on_another_frame)(fl);
|
||||
}
|
||||
|
||||
extern "C" fn allie_AliceCallbacks_on_wl_pointer_motion(dt: VoidPtr, pos: vec2){
|
||||
let cb: &mut AliceCallbacks = unsafe { &mut *(dt as *mut AliceCallbacks) };
|
||||
(cb.on_wl_pointer_motion)(pos);
|
||||
}
|
||||
|
||||
impl Alice {
|
||||
pub fn new() -> Self {
|
||||
Alice{opa: unsafe { allie_Alice_new() }}
|
||||
}
|
||||
|
||||
pub fn mainloop(&self, mut cb: AliceCallbacks) {
|
||||
let guest_data = (&raw mut cb) as VoidPtr;
|
||||
|
||||
let a_cb = allie_AliceCallbacks {
|
||||
guest: guest_data,
|
||||
on_wl_pointer_button: allie_AliceCallbacks_on_wl_pointer_button,
|
||||
on_wl_keyboard_key: allie_AliceCallbacks_on_wl_keyboard_key,
|
||||
on_another_frame: allie_AliceCallbacks_on_another_frame,
|
||||
on_wl_pointer_motion: allie_AliceCallbacks_on_wl_pointer_motion,
|
||||
};
|
||||
|
||||
unsafe{ allie_Alice_mainloop(self.opa, &a_cb) };
|
||||
}
|
||||
|
||||
pub fn set_clear_color(&self, color: vec4) {
|
||||
unsafe { allie_Alice_set_clear_color(self.opa, color) };
|
||||
}
|
||||
}
|
||||
impl Drop for Alice {
|
||||
fn drop(&mut self) {
|
||||
// todo: do something
|
||||
}
|
||||
}
|
||||
mod allie;
|
||||
pub mod alice;
|
||||
pub mod uint_segments;
|
||||
|
||||
20
src/l2/allie_rs/uint_segments.rs
Normal file
20
src/l2/allie_rs/uint_segments.rs
Normal file
@ -0,0 +1,20 @@
|
||||
/* I am not proud of this */
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct UIntSegment<T: Copy>{
|
||||
pub start: T,
|
||||
pub len: T,
|
||||
}
|
||||
|
||||
impl<T: Copy> UIntSegment<T> {
|
||||
pub fn new(start: T, len: T) -> Self{ Self {start, len} }
|
||||
}
|
||||
|
||||
pub type U32Segment = UIntSegment<u32>;
|
||||
pub type U64Segment = UIntSegment<u64>;
|
||||
|
||||
/* Common sense decided to die */
|
||||
impl<T: Copy> From<& UIntSegment<T>> for UIntSegment<T> {
|
||||
fn from(value: &UIntSegment<T>) -> Self { *value }
|
||||
}
|
||||
@ -1,11 +1,18 @@
|
||||
use alice_and_misc::{*};
|
||||
use alice_and_misc::alice::{*};
|
||||
use alice_and_misc::geom::{*};
|
||||
use alice_and_misc::uint_segments::U32Segment;
|
||||
|
||||
fn main() {
|
||||
let v = vec2(1.0, 2.0);
|
||||
|
||||
let alice = Alice::new();
|
||||
alice.set_clear_color(vec4(0., 1., 0., 1.));
|
||||
let mut alice = Alice::new();
|
||||
alice.set_clear_color(vec4(0., 0.5, 0.5, 1.));
|
||||
let mut face = alice.new_lucy_face("./src/l3/fonts/DMSerifText-Regular.ttf");
|
||||
let mut face_40 = face.of_size(40);
|
||||
alice.lucy_cache_add_glyphs(vec![
|
||||
LucyGlyphCachingRequest{sized_face: &mut face_40,
|
||||
codepoint_ranges: vec![U32Segment::new(32, 126 - 32 + 1)]}
|
||||
]);
|
||||
alice.mainloop(AliceCallbacks{
|
||||
on_wl_pointer_button: Box::new(|_: u32, _: u32| {
|
||||
println!("pointer button")
|
||||
@ -14,7 +21,8 @@ fn main() {
|
||||
println!("keyboard key");
|
||||
}),
|
||||
on_another_frame: Box::new(|_: f32| {
|
||||
|
||||
alice.lucy_renderer_add_simple_label(&face_40, vec4(1., 0.5, 0., 1.),
|
||||
0, "Hello from Rust", ivec2(40, 40));
|
||||
}),
|
||||
on_wl_pointer_motion: Box::new(|_: vec2| {
|
||||
println!("pointer motion");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user