pub fn compile(sfnt_version: u32, tables: Vec<(Tag, Bytes)>) -> Bytes {
    log::info!(
        "SFNT version: 0x{:X}{}",
        sfnt_version,
        Tag::from_u32(sfnt_version).map_or(String::new(), |x| format!(" ({})", x))
    );
    log::info!("Write Table Directory Preamble");

    let length = PREAMBLE_SIZE
        + (tables.len() * TABLE_RECORD_SIZE)
        + tables.iter().map(|(_, x)| x.len()).sum::<usize>();
    let mut buf = BytesMut::with_capacity(length);

    buf.put_u32(sfnt_version);

    let num_tables: u16 = tables.len() as u16;
    buf.put_u16(num_tables);

    let search_range: u16 = 16 * 2u16.pow((num_tables as f64).log2().floor() as u32);
    buf.put_u16(search_range);

    let entry_selector: u16 = (num_tables as f64).log2().floor() as u16;
    buf.put_u16(entry_selector);

    let range_shift: u16 = num_tables * 16 - search_range;
    buf.put_u16(range_shift);

    log::info!("Write Table Records");

    let mut offset: u32 = (PREAMBLE_SIZE + (tables.len() * TABLE_RECORD_SIZE)) as u32;

    for (tag, table) in &tables {
        let tag = *tag;
        buf.put_u32(tag.into());

        let checksum = table_checksum(table);
        buf.put_u32(checksum);

        buf.put_u32(offset);

        let len = table.len() as u32;
        buf.put_u32(len);

        let padding = (4 - (len % 4)) % 4;
        offset += len + padding;
    }

    log::info!("Write Tables");

    for (tag, table) in tables {
        log::info!("writing table '{}' ...", tag);

        let len = table.len();

        buf.put(table);

        let padding = (4 - (len % 4)) % 4;

        for _ in 0..padding {
            buf.put_u8(0);
        }
    }

    assert_eq!(length, buf.len());

    buf.freeze()
}
/// Compiles an SFNT font.
///
/// `sfnt_version` is written to the first four bytes of the font.
/// The tables are written in the given order to the font.
///
/// # Example
///
/// ```
/// # use informa::ctx::Context;
/// # use informa::data::Source;
/// # use informa::sfnt::types::Tag;
/// # use informa::sfnt::compile;
/// use informa::sfnt::tables;
///
/// let ctx = Context::default();
/// let source = Source::default();
/// let sfnt_version = Tag(*b"OTTO").as_u32();
/// let tables = vec![
///     (Tag(*b"cmap"), tables::cmap::compile(&source.character_map, ctx)),
///     // ... tables ...
/// ];
///
/// let font = compile(sfnt_version, tables);
/// ```
Compiles an SFNT font.
`sfnt_version` is written to the first four bytes of the font.
The tables are written in the given order to the font.
Compiles an SFNT font . ` sfnt_version ` is written to the first four bytes of the font . The tables are written in the given order to the font .
pub fn compile(sfnt_version: u32, tables: Vec<(Tag, Bytes)>) -> Bytes {
    log::info!(
        "SFNT version: 0x{:X}{}",
        sfnt_version,
        Tag::from_u32(sfnt_version).map_or(String::new(), |x| format!(" ({})", x))
    );
    log::info!("Write Table Directory Preamble");
    let length = PREAMBLE_SIZE
        + (tables.len() * TABLE_RECORD_SIZE)
        + tables.iter().map(|(_, x)| x.len()).sum::<usize>();
    let mut buf = BytesMut::with_capacity(length);
    buf.put_u32(sfnt_version);
    let num_tables: u16 = tables.len() as u16;
    buf.put_u16(num_tables);
    let search_range: u16 = 16 * 2u16.pow((num_tables as f64).log2().floor() as u32);
    buf.put_u16(search_range);
    let entry_selector: u16 = (num_tables as f64).log2().floor() as u16;
    buf.put_u16(entry_selector);
    let range_shift: u16 = num_tables * 16 - search_range;
    buf.put_u16(range_shift);
    log::info!("Write Table Records");
    let mut offset: u32 = (PREAMBLE_SIZE + (tables.len() * TABLE_RECORD_SIZE)) as u32;
    for (tag, table) in &tables {
        let tag = *tag;
        buf.put_u32(tag.into());
        let checksum = table_checksum(table);
        buf.put_u32(checksum);
        buf.put_u32(offset);
        let len = table.len() as u32;
        buf.put_u32(len);
        let padding = (4 - (len % 4)) % 4;
        offset += len + padding;
    }
    log::info!("Write Tables");
    for (tag, table) in tables {
        log::info!("writing table '{}' ...", tag);
        let len = table.len();
        buf.put(table);
        let padding = (4 - (len % 4)) % 4;
        for _ in 0..padding {
            buf.put_u8(0);
        }
    }
    assert_eq!(length, buf.len());
    buf.freeze()
}
pub fn compile ( sfnt_version : u32 , tables : Vec < ( Tag , Bytes ) > ) -> Bytes { log :: info ! ( " " sfnt_version Tag from_u32 ( sfnt_version ) map_or ( String new ( ) x format ( " " x ) ) ) ; log :: info ! ( " " ) ; let length = PREAMBLE_SIZE + ( tables . len ( ) * TABLE_RECORD_SIZE ) + tables . iter ( ) . map ( | ( _ , x ) | x . len ( ) ) . sum :: < usize > ( ) ; let mut buf = BytesMut :: with_capacity ( length ) ; buf . put_u32 ( sfnt_version ) ; let num_tables : u16 = tables . len ( ) as u16 ; buf . put_u16 ( num_tables ) ; let search_range : u16 = 16 * 2u16 . pow ( ( num_tables as f64 ) . log2 ( ) . floor ( ) as u32 ) ; buf . put_u16 ( search_range ) ; let entry_selector : u16 = ( num_tables as f64 ) . log2 ( ) . floor ( ) as u16 ; buf . put_u16 ( entry_selector ) ; let range_shift : u16 = num_tables * 16 - search_range ; buf . put_u16 ( range_shift ) ; log :: info ! ( " " ) ; let mut offset : u32 = ( PREAMBLE_SIZE + ( tables . len ( ) * TABLE_RECORD_SIZE ) ) as u32 ; for ( tag , table ) in & tables { let tag = * tag ; buf . put_u32 ( tag . into ( ) ) ; let checksum = table_checksum ( table ) ; buf . put_u32 ( checksum ) ; buf . put_u32 ( offset ) ; let len = table . len ( ) as u32 ; buf . put_u32 ( len ) ; let padding = ( 4 - ( len % 4 ) ) % 4 ; offset += len + padding ; } log :: info ! ( " " ) ; for ( tag , table ) in tables { log :: info ! ( " " tag ) ; let len = table . len ( ) ; buf . put ( table ) ; let padding = ( 4 - ( len % 4 ) ) % 4 ; for _ in 0 .. padding { buf . put_u8 ( 0 ) ; } } assert_eq ! ( length buf len ( ) ) ; buf . freeze ( ) }
Compiles an SFNT font.
Compiles an SFNT font .
sfnt_version
u32
tables
Vec<(Tag, Bytes)>
sfnt_version
u32
tables
Vec<(Tag, Bytes)>
example
None
use informa::ctx::context;
None
use informa::data::source;
None
use informa::sfnt::types::tag;
None
use informa::sfnt::compile;
use informa::sfnt::tables.

let ctx = Context::default();
let source = Source::default();
let sfnt_version = Tag(*b"OTTO").as_u32();
let tables = vec![
(Tag(*b"cmap"), tables::cmap::compile(&source.character_map, ctx)),
tables
].

let font = compile(sfnt_version, tables);
```
use informa :: sfnt :: tables . let ctx = Context :: default () ; let source = Source :: default () ; let sfnt_version = Tag ( * b " OTTO " ) . as_u32 () ; let tables = vec! [ ( Tag ( * b " cmap " ) tables :: cmap :: compile ( &source . character_map ctx )) tables ] . let font = compile ( sfnt_version tables ) ; ` ` `