From afe1af8fa9de0c05cda5151059ecac37ecd16bda Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 4 Mar 2025 05:18:43 -0700 Subject: [PATCH] [fontations] Implement get_nominal_glyphs() Shapes now. --- src/fontations/lib.rs | 49 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/src/fontations/lib.rs b/src/fontations/lib.rs index 1e01a3b78..470a9f414 100644 --- a/src/fontations/lib.rs +++ b/src/fontations/lib.rs @@ -5,13 +5,14 @@ include!(concat!(env!("OUT_DIR"), "/hb.rs")); use std::os::raw::{c_void}; use std::ptr::{null_mut}; -use skrifa::{MetadataProvider, GlyphId}; +use skrifa::{charmap, GlyphId, MetadataProvider}; use skrifa::font::FontRef; use skrifa::instance::{Location, Size}; // A struct for storing your “fontations” data #[repr(C)] -struct FontationsData { +struct FontationsData +{ font_ref: FontRef<'static>, } @@ -22,6 +23,32 @@ extern "C" fn _hb_fontations_data_destroy(ptr: *mut c_void) { // TODO } +extern "C" fn _hb_fontations_get_nominal_glyphs( + _font: *mut hb_font_t, + font_data: *mut ::std::os::raw::c_void, + count: ::std::os::raw::c_uint, + first_unicode: *const hb_codepoint_t, + unicode_stride: ::std::os::raw::c_uint, + first_glyph: *mut hb_codepoint_t, + glyph_stride: ::std::os::raw::c_uint, + _user_data: *mut ::std::os::raw::c_void, +) -> ::std::os::raw::c_uint +{ + let data = unsafe { + assert!(!font_data.is_null()); + &*(font_data as *const FontationsData) + }; + let font_ref = &data.font_ref; + let char_map = charmap::Charmap::new(font_ref); + + for i in 0..count { + let unicode = unsafe { *(first_unicode as *const u8).offset((i * unicode_stride) as isize) as *const hb_codepoint_t }; + let glyph = u32::from(char_map.map(unicode as u32).unwrap_or(GlyphId::new(0))); + unsafe { *((first_glyph as *mut u8).offset((i * glyph_stride) as isize) as *mut hb_codepoint_t) = glyph as hb_codepoint_t; } + } + + count +} extern "C" fn _hb_fontations_get_glyph_h_advances( font: *mut hb_font_t, font_data: *mut ::std::os::raw::c_void, @@ -31,7 +58,8 @@ extern "C" fn _hb_fontations_get_glyph_h_advances( first_advance: *mut hb_position_t, advance_stride: ::std::os::raw::c_uint, _user_data: *mut ::std::os::raw::c_void, -) { +) +{ let data = unsafe { assert!(!font_data.is_null()); &*(font_data as *const FontationsData) @@ -45,17 +73,19 @@ extern "C" fn _hb_fontations_get_glyph_h_advances( let glyph_metrics = font_ref.glyph_metrics(size, &location); for i in 0..count { - let glyph = unsafe { *first_glyph.offset((i * glyph_stride) as isize) }; - let glyph_id = GlyphId::new(glyph); - let advance = glyph_metrics.advance_width(glyph_id).unwrap_or_default(); - unsafe { *first_advance.offset((i * advance_stride) as isize) = advance as hb_position_t; } + let glyph = unsafe { *(first_glyph as *const u8).offset((i * glyph_stride) as isize) as *const hb_codepoint_t }; + let glyph_id = GlyphId::new(glyph as u32); + let advance = glyph_metrics.advance_width(glyph_id).unwrap_or_default().round() as i32; + unsafe { *((first_advance as *mut u8).offset((i * advance_stride) as isize) as *mut hb_position_t) = advance as hb_position_t; } } } -fn _hb_fontations_font_funcs_create() -> *mut hb_font_funcs_t { +fn _hb_fontations_font_funcs_create() -> *mut hb_font_funcs_t +{ let ffuncs = unsafe { hb_font_funcs_create() }; unsafe { + hb_font_funcs_set_nominal_glyphs_func(ffuncs, Some(_hb_fontations_get_nominal_glyphs), null_mut(), None); hb_font_funcs_set_glyph_h_advances_func(ffuncs, Some(_hb_fontations_get_glyph_h_advances), null_mut(), None); } @@ -66,7 +96,8 @@ fn _hb_fontations_font_funcs_create() -> *mut hb_font_funcs_t { #[no_mangle] pub extern "C" fn hb_fontations_font_set_funcs( font: *mut hb_font_t, -) { +) +{ let ffuncs = _hb_fontations_font_funcs_create (); let face_index = unsafe { hb_face_get_index(hb_font_get_face(font)) };