| // Copyright 2024 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| use read_fonts::{FileRef, FontRef, ReadError}; |
| use skrifa::{string::StringId, MetadataProvider}; |
| |
| fn make_font_ref_internal<'a>(font_data: &'a [u8], index: u32) -> Result<FontRef<'a>, ReadError> { |
| match FileRef::new(font_data)? { |
| FileRef::Font(font_ref) => Ok(font_ref), |
| FileRef::Collection(collection) => collection.get(index), |
| } |
| } |
| |
| fn english_unique_font_names<'a>(font_bytes: &[u8], index: u32) -> Vec<String> { |
| if let Ok(font_ref) = make_font_ref_internal(font_bytes, index) { |
| let mut return_vec = Vec::new(); |
| for id in [StringId::FULL_NAME, StringId::POSTSCRIPT_NAME] { |
| if let Some(font_name) = font_ref.localized_strings(id).english_or_first() { |
| let name_added = font_name.to_string(); |
| return_vec.push(name_added); |
| } |
| } |
| return_vec |
| } else { |
| Vec::new() |
| } |
| } |
| |
| unsafe fn offset_first_table(font_bytes: &[u8]) -> u64 { |
| if let Ok(font_ref) = make_font_ref_internal(font_bytes, 0) { |
| // Get offset to first data table in the font file, |
| // which should be somewhat equivalent to the end |
| // of the TTC and OpenType font file headers. |
| font_ref |
| .table_directory |
| .table_records() |
| .iter() |
| .map(|item| item.offset) |
| .min() |
| .unwrap_or_default() |
| .get() |
| .into() |
| } else { |
| 0 |
| } |
| } |
| |
| fn indexable_num_fonts<'a>(font_bytes: &[u8]) -> u32 { |
| let maybe_font_or_collection = FileRef::new(font_bytes); |
| match maybe_font_or_collection { |
| Ok(FileRef::Collection(collection)) => collection.len(), |
| Ok(FileRef::Font(_)) => 1u32, |
| _ => 0u32, |
| } |
| } |
| |
| #[cxx::bridge(namespace = "name_table_access")] |
| #[allow(unused_unsafe)] |
| pub mod ffi { |
| extern "Rust" { |
| /// Returns true if the font or font collection is indexable and gives |
| /// the number of fonts contained in font or collection. 1 is |
| /// ambiguous and means either a single font file |
| /// or a collection, but since `english_unique_font_names` ignore the |
| /// argument if the font is not a collection, this is ok. |
| unsafe fn indexable_num_fonts<'a>(font_bytes: &[u8]) -> u32; |
| unsafe fn english_unique_font_names<'a>(font_bytes: &[u8], index: u32) -> Vec<String>; |
| unsafe fn offset_first_table(font_bytes: &[u8]) -> u64; |
| } |
| } |