Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
200
third-party/vendor/fontdue/src/table/kern.rs
vendored
Normal file
200
third-party/vendor/fontdue/src/table/kern.rs
vendored
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
use crate::table::parse::*;
|
||||
use hashbrown::HashMap;
|
||||
|
||||
// Apple: https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kern.html
|
||||
// Microsoft: https://docs.microsoft.com/en-us/typography/opentype/spec/kern
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TableKern {
|
||||
pub horizontal_mappings: HashMap<u32, i16>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct Header {
|
||||
pub version_major: u16,
|
||||
pub version_minor: u16,
|
||||
pub number_sub_tables: u32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct SubTableHeader {
|
||||
pub version: u16,
|
||||
pub length: usize,
|
||||
pub coverage: Coverage,
|
||||
pub format: u8,
|
||||
pub tuple_index: u16,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct Coverage {
|
||||
is_horizontal: bool,
|
||||
}
|
||||
|
||||
impl Coverage {
|
||||
pub const fn aat(cov: u8) -> Coverage {
|
||||
Coverage {
|
||||
is_horizontal: cov & 0x80 != 0x80,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn ot(cov: u8) -> Coverage {
|
||||
Coverage {
|
||||
is_horizontal: cov & 0x01 == 0x01,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TableKern {
|
||||
pub fn new(kern: &[u8]) -> Option<TableKern> {
|
||||
let mut stream = Stream::new(kern);
|
||||
let version_major = stream.read_u16()?;
|
||||
|
||||
let header;
|
||||
match version_major {
|
||||
0x0000 => header = Self::read_ot_header(&mut stream)?,
|
||||
0x0001 => header = Self::read_aat_header(&mut stream)?,
|
||||
_ => return None, // Font.kern: Unsupported kern table version.
|
||||
}
|
||||
|
||||
for _ in 0..header.number_sub_tables {
|
||||
let sub_table_start = stream.offset();
|
||||
let sub_header = if version_major == 0x0000 {
|
||||
Self::read_ot_subtable(&mut stream)?
|
||||
} else {
|
||||
Self::read_aat_subtable(&mut stream)?
|
||||
};
|
||||
match sub_header.format {
|
||||
// Ordered List of Kerning Pairs
|
||||
0 => {
|
||||
if sub_header.coverage.is_horizontal {
|
||||
let mappings = Self::read_format0(&mut stream)?;
|
||||
return Some(TableKern {
|
||||
horizontal_mappings: mappings,
|
||||
});
|
||||
}
|
||||
}
|
||||
// State Table for Contextual Kerning
|
||||
// 1 => { /* TODO: State Table for Contextual Kerning */ }
|
||||
// Simple n x m Array of Kerning Values
|
||||
// 2 => { /* TODO: Simple n x m Array of Kerning Values */ }
|
||||
// Simple n x m Array of Kerning Indices
|
||||
3 => {
|
||||
if sub_header.coverage.is_horizontal {
|
||||
let mappings = Self::read_format3(&mut stream)?;
|
||||
return Some(TableKern {
|
||||
horizontal_mappings: mappings,
|
||||
});
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
stream.seek(sub_table_start + sub_header.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None // Font.kern: No supported sub-table format available.
|
||||
}
|
||||
|
||||
fn read_format0(stream: &mut Stream) -> Option<HashMap<u32, i16>> {
|
||||
let pairs = stream.read_u16()?;
|
||||
stream.skip(6); // searchRange: u16, entrySelector: u16, rangeShift: u16
|
||||
let mut mappings = HashMap::new();
|
||||
for _ in 0..pairs {
|
||||
let left = stream.read_u16()?;
|
||||
let right = stream.read_u16()?;
|
||||
let id = u32::from(left) << 16 | u32::from(right);
|
||||
let value = stream.read_i16()?;
|
||||
mappings.insert(id, value);
|
||||
}
|
||||
Some(mappings)
|
||||
}
|
||||
|
||||
fn read_format3(stream: &mut Stream) -> Option<HashMap<u32, i16>> {
|
||||
let glyph_count = stream.read_u16()?;
|
||||
let kerning_values_count = stream.read_u8()?;
|
||||
let left_hand_classes_count = stream.read_u8()?;
|
||||
let right_hand_classes_count = stream.read_u8()?;
|
||||
stream.skip(1); // flags - reserved
|
||||
let indices_count = u16::from(left_hand_classes_count) * u16::from(right_hand_classes_count);
|
||||
|
||||
let kerning_values = stream.read_i16_slice(usize::from(kerning_values_count))?;
|
||||
let left_hand_classes = stream.read_u8_slice(usize::from(glyph_count))?;
|
||||
let right_hand_classes = stream.read_u8_slice(usize::from(glyph_count))?;
|
||||
let indices = stream.read_u8_slice(usize::from(indices_count))?;
|
||||
|
||||
let mut mappings = HashMap::new();
|
||||
for left in 0..glyph_count {
|
||||
for right in 0..glyph_count {
|
||||
if let Some((id, value)) = {
|
||||
let left_class = left_hand_classes.get(usize::from(left))?;
|
||||
let right_class = right_hand_classes.get(usize::from(right))?;
|
||||
|
||||
if left_class > left_hand_classes_count || right_class > right_hand_classes_count {
|
||||
continue;
|
||||
}
|
||||
|
||||
let index =
|
||||
u16::from(left_class) * u16::from(right_hand_classes_count) + u16::from(right_class);
|
||||
let index = indices.get(usize::from(index))?;
|
||||
let id = u32::from(left) << 16 | u32::from(right);
|
||||
let value = kerning_values.get(usize::from(index))?;
|
||||
Some((id, value))
|
||||
} {
|
||||
mappings.insert(id, value);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Some(mappings)
|
||||
}
|
||||
|
||||
fn read_ot_header(stream: &mut Stream) -> Option<Header> {
|
||||
let version_major = 0x0000;
|
||||
let version_minor = 0x0000;
|
||||
let number_sub_tables = stream.read_u16()? as u32;
|
||||
Some(Header {
|
||||
version_major,
|
||||
version_minor,
|
||||
number_sub_tables,
|
||||
})
|
||||
}
|
||||
|
||||
fn read_aat_header(stream: &mut Stream) -> Option<Header> {
|
||||
let version_major = 0x0001;
|
||||
let version_minor = stream.read_u16()?;
|
||||
let number_sub_tables = stream.read_u32()?;
|
||||
Some(Header {
|
||||
version_major,
|
||||
version_minor,
|
||||
number_sub_tables,
|
||||
})
|
||||
}
|
||||
|
||||
fn read_ot_subtable(stream: &mut Stream) -> Option<SubTableHeader> {
|
||||
let version = stream.read_u16()?;
|
||||
let length = stream.read_u16()? as usize;
|
||||
let format = stream.read_u8()?;
|
||||
let coverage = Coverage::ot(stream.read_u8()?);
|
||||
Some(SubTableHeader {
|
||||
version,
|
||||
length,
|
||||
coverage,
|
||||
format,
|
||||
tuple_index: 0,
|
||||
})
|
||||
}
|
||||
|
||||
fn read_aat_subtable(stream: &mut Stream) -> Option<SubTableHeader> {
|
||||
let length = stream.read_u32()? as usize;
|
||||
let coverage = Coverage::aat(stream.read_u8()?);
|
||||
let format = stream.read_u8()?;
|
||||
let tuple_index = stream.read_u16()?;
|
||||
Some(SubTableHeader {
|
||||
version: 0x0001,
|
||||
length,
|
||||
coverage,
|
||||
format,
|
||||
tuple_index,
|
||||
})
|
||||
}
|
||||
}
|
||||
4
third-party/vendor/fontdue/src/table/mod.rs
vendored
Normal file
4
third-party/vendor/fontdue/src/table/mod.rs
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
mod kern;
|
||||
pub mod parse;
|
||||
|
||||
pub use self::kern::*;
|
||||
196
third-party/vendor/fontdue/src/table/parse.rs
vendored
Normal file
196
third-party/vendor/fontdue/src/table/parse.rs
vendored
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
use core::convert::TryInto;
|
||||
|
||||
pub struct StreamSliceU8<'a>(&'a [u8]);
|
||||
pub struct StreamSliceU16<'a>(&'a [u8]);
|
||||
pub struct StreamSliceU32<'a>(&'a [u8]);
|
||||
impl<'a> StreamSliceU8<'a> {
|
||||
#[inline]
|
||||
pub fn get(&self, index: usize) -> Option<u8> {
|
||||
const SIZE: usize = 1;
|
||||
let offset = index * SIZE;
|
||||
let slice = self.0.get(offset..offset + SIZE)?;
|
||||
Some(slice[0])
|
||||
}
|
||||
}
|
||||
impl<'a> StreamSliceU16<'a> {
|
||||
#[inline]
|
||||
pub fn get(&self, index: usize) -> Option<u16> {
|
||||
const SIZE: usize = 2;
|
||||
let offset = index * SIZE;
|
||||
let slice = self.0.get(offset..offset + SIZE)?;
|
||||
Some(u16::from_be_bytes(slice.try_into().unwrap()))
|
||||
}
|
||||
}
|
||||
impl<'a> StreamSliceU32<'a> {
|
||||
#[inline]
|
||||
pub fn get(&self, index: usize) -> Option<u32> {
|
||||
const SIZE: usize = 4;
|
||||
let offset = index * SIZE;
|
||||
let slice = self.0.get(offset..offset + SIZE)?;
|
||||
Some(u32::from_be_bytes(slice.try_into().unwrap()))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StreamSliceI8<'a>(StreamSliceU8<'a>);
|
||||
pub struct StreamSliceI16<'a>(StreamSliceU16<'a>);
|
||||
pub struct StreamSliceI32<'a>(StreamSliceU32<'a>);
|
||||
impl<'a> StreamSliceI8<'a> {
|
||||
#[inline]
|
||||
pub fn get(&self, index: usize) -> Option<i8> {
|
||||
Some(unsafe { core::mem::transmute(self.0.get(index)?) })
|
||||
}
|
||||
}
|
||||
impl<'a> StreamSliceI16<'a> {
|
||||
#[inline]
|
||||
pub fn get(&self, index: usize) -> Option<i16> {
|
||||
Some(unsafe { core::mem::transmute(self.0.get(index)?) })
|
||||
}
|
||||
}
|
||||
impl<'a> StreamSliceI32<'a> {
|
||||
#[inline]
|
||||
pub fn get(&self, index: usize) -> Option<i32> {
|
||||
Some(unsafe { core::mem::transmute(self.0.get(index)?) })
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Stream<'a> {
|
||||
bytes: &'a [u8],
|
||||
offset: usize,
|
||||
}
|
||||
|
||||
impl<'a> Stream<'a> {
|
||||
pub const fn new(bytes: &'a [u8]) -> Stream<'a> {
|
||||
Stream {
|
||||
bytes,
|
||||
offset: 0,
|
||||
}
|
||||
}
|
||||
|
||||
// UTILITY
|
||||
|
||||
#[inline]
|
||||
pub fn reset(&mut self) {
|
||||
self.offset = 0;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn offset(&self) -> usize {
|
||||
self.offset
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn seek(&mut self, offset: usize) {
|
||||
self.offset = offset;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn skip(&mut self, offset: usize) {
|
||||
self.offset += offset;
|
||||
}
|
||||
|
||||
// UNSIGNED SLICE
|
||||
|
||||
#[inline]
|
||||
pub fn read_u8_slice(&mut self, len: usize) -> Option<StreamSliceU8<'a>> {
|
||||
let end = self.offset + len;
|
||||
self.bytes.get(self.offset..end).map(|slice| {
|
||||
self.offset = end;
|
||||
StreamSliceU8(slice)
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_u16_slice(&mut self, len: usize) -> Option<StreamSliceU16<'a>> {
|
||||
let end = self.offset + len * 2;
|
||||
self.bytes.get(self.offset..end).map(|slice| {
|
||||
self.offset = end;
|
||||
StreamSliceU16(slice)
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_u32_slice(&mut self, len: usize) -> Option<StreamSliceU32<'a>> {
|
||||
let end = self.offset + len * 4;
|
||||
self.bytes.get(self.offset..end).map(|slice| {
|
||||
self.offset = end;
|
||||
StreamSliceU32(slice)
|
||||
})
|
||||
}
|
||||
|
||||
// SIGNED SLICE
|
||||
|
||||
#[inline]
|
||||
pub fn read_i8_slice(&mut self, len: usize) -> Option<StreamSliceI8<'a>> {
|
||||
Some(StreamSliceI8(self.read_u8_slice(len)?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_i16_slice(&mut self, len: usize) -> Option<StreamSliceI16<'a>> {
|
||||
Some(StreamSliceI16(self.read_u16_slice(len)?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_i32_slice(&mut self, len: usize) -> Option<StreamSliceI32<'a>> {
|
||||
Some(StreamSliceI32(self.read_u32_slice(len)?))
|
||||
}
|
||||
|
||||
// UNSIGNED
|
||||
|
||||
#[inline]
|
||||
pub fn read_u8(&mut self) -> Option<u8> {
|
||||
const SIZE: usize = 1;
|
||||
let slice = self.bytes.get(self.offset..self.offset + SIZE)?;
|
||||
self.offset += SIZE;
|
||||
Some(slice[0])
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_u16(&mut self) -> Option<u16> {
|
||||
const SIZE: usize = 2;
|
||||
let slice = self.bytes.get(self.offset..self.offset + SIZE)?;
|
||||
self.offset += SIZE;
|
||||
Some(u16::from_be_bytes(slice.try_into().unwrap()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_u32(&mut self) -> Option<u32> {
|
||||
const SIZE: usize = 4;
|
||||
let slice = self.bytes.get(self.offset..self.offset + SIZE)?;
|
||||
self.offset += SIZE;
|
||||
Some(u32::from_be_bytes(slice.try_into().unwrap()))
|
||||
}
|
||||
|
||||
// SIGNED
|
||||
|
||||
#[inline]
|
||||
pub fn read_i8(&mut self) -> Option<i8> {
|
||||
Some(unsafe { core::mem::transmute(self.read_u8()?) })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_i16(&mut self) -> Option<i16> {
|
||||
Some(unsafe { core::mem::transmute(self.read_u16()?) })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_i32(&mut self) -> Option<i32> {
|
||||
Some(unsafe { core::mem::transmute(self.read_u32()?) })
|
||||
}
|
||||
|
||||
// FONT
|
||||
|
||||
#[inline]
|
||||
pub fn read_f2dot14(&mut self) -> Option<f32> {
|
||||
let val = self.read_i16()?;
|
||||
let result = val as f32 * (1.0 / (1 << 14) as f32);
|
||||
Some(result)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_tag(&mut self) -> Option<[u8; 4]> {
|
||||
const SIZE: usize = 4;
|
||||
let slice = self.bytes.get(self.offset..self.offset + SIZE)?;
|
||||
self.offset += SIZE;
|
||||
Some(slice.try_into().unwrap())
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue