[fontations] Implement get_nominal_glyphs()

Shapes now.
This commit is contained in:
Behdad Esfahbod 2025-03-04 05:18:43 -07:00 committed by Khaled Hosny
parent e801e484f1
commit afe1af8fa9

View file

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