Skip to content

Commit

Permalink
Merge branch 'main' into tt-hint-tests1
Browse files Browse the repository at this point in the history
  • Loading branch information
dfrg committed Mar 20, 2024
2 parents 86e8804 + d7bb979 commit 7c03942
Show file tree
Hide file tree
Showing 58 changed files with 216 additions and 585 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ members = [

[workspace.dependencies]
# dev dependencies
env_logger = "0.11"
pretty_assertions = "1.3.0"

[workspace.metadata.release]
Expand Down
2 changes: 1 addition & 1 deletion fauntlet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ readme = "README.md"
publish = false

[dependencies]
skrifa = { version = "0.17.0", path = "../skrifa" }
skrifa = { version = "0.18.0", path = "../skrifa" }
freetype-rs = "0.32.0"
memmap2 = "0.5.10"
rayon = "1.8.0"
Expand Down
4 changes: 2 additions & 2 deletions font-codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ name = "codegen"
path = "src/main.rs"

[dependencies]
font-types = { version = "0.4.3", path = "../font-types" }
font-types = { version = "0.5.1", path = "../font-types" }
rustfmt-wrapper = "0.2"
regex = "1.5"
miette = { version = "5.0", features = ["fancy"] }
Expand All @@ -23,9 +23,9 @@ toml = "0.7.5"
serde = {version = "1.0", features = ["derive"] }
xflags = "0.3.0"
log = "0.4"
env_logger = "0.10.0"
rayon = "1.5.3"
indexmap = "2.0"
env_logger.workspace = true

# cargo-release settings
[package.metadata.release]
Expand Down
3 changes: 2 additions & 1 deletion font-codegen/src/flags_enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ pub(crate) fn generate_flags(raw: &BitFlags) -> proc_macro2::TokenStream {

quote! {
#( #docs )*
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck::AnyBitPattern)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(transparent)]
pub struct #name { bits: #typ }
impl #name {
#( #variant_decls )*
Expand Down
11 changes: 3 additions & 8 deletions font-codegen/src/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub(crate) fn generate(item: &Record, all_items: &Items) -> syn::Result<TokenStr
#[repr(packed)]
}
});
let maybe_copy = is_zerocopy.then(|| quote!(Copy,));
let simple_record_traits = is_zerocopy.then(|| quote!(Copy, bytemuck::AnyBitPattern,));

let maybe_impl_fixed_size = is_zerocopy.then(|| {
let inner_types = item.fields.iter().map(|fld| fld.typ.cooked_type_tokens());
Expand All @@ -45,20 +45,15 @@ pub(crate) fn generate(item: &Record, all_items: &Items) -> syn::Result<TokenStr
const RAW_BYTE_LEN: usize = #( #inner_types::RAW_BYTE_LEN )+*;
}

impl sealed::Sealed for #name {}
/// SAFETY: see the [`FromBytes`] trait documentation.
unsafe impl FromBytes for #name {
fn this_trait_should_only_be_implemented_in_generated_code() {}
}
}
});
let maybe_impl_read_with_args = (has_read_args).then(|| generate_read_with_args(item));
let maybe_extra_traits = item
.gets_extra_traits(all_items)
.then(|| quote!(PartialEq, Eq, PartialOrd, Ord, Hash));
.then(|| quote!(PartialEq, Eq, PartialOrd, Ord, Hash,));
Ok(quote! {
#( #docs )*
#[derive(Clone, Debug, #maybe_copy #maybe_extra_traits)]
#[derive(Clone, Debug, #maybe_extra_traits #simple_record_traits )]
#repr_packed
pub struct #name #lifetime {
#( #field_docs pub #field_names: #field_types, )*
Expand Down
4 changes: 3 additions & 1 deletion font-types/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "font-types"
version = "0.4.3"
version = "0.5.1"
edition = "2021"
license = "MIT/Apache-2.0"
description = "Scalar types used in fonts."
Expand All @@ -9,6 +9,8 @@ readme = "README.md"
categories = ["text-processing"]

[dependencies]
# note: bytemuck version must be available in all deployment environments
bytemuck = {version = "=1.13.1", features = ["derive", "min_const_generics"], optional = true }
serde = { version = "1.0", features = ["derive"], optional = true }

[dev-dependencies]
Expand Down
4 changes: 0 additions & 4 deletions font-types/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,3 @@ projects that work with font data.

[opentype]: https://docs.microsoft.com/en-us/typography/opentype/

## Safety

Unsafe code is forbidden by a `#![forbid(unsafe_code)]` attribute in the root
of the library.
1 change: 1 addition & 0 deletions font-types/src/fixed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ macro_rules! fixed_impl {
($name:ident, $bits:literal, $fract_bits:literal, $ty:ty) => {
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bytemuck", derive(bytemuck::AnyBitPattern, bytemuck::NoUninit))]
#[repr(transparent)]
#[doc = concat!(stringify!($bits), "-bit signed fixed point number with ", stringify!($fract_bits), " bits of fraction." )]
pub struct $name($ty);
Expand Down
4 changes: 4 additions & 0 deletions font-types/src/fword.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ use super::Fixed;
/// 16-bit signed quantity in font design units.
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bytemuck", derive(bytemuck::AnyBitPattern))]
#[repr(transparent)]
pub struct FWord(i16);

/// 16-bit unsigned quantity in font design units.
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bytemuck", derive(bytemuck::AnyBitPattern))]
#[repr(transparent)]
pub struct UfWord(u16);

impl FWord {
Expand Down
2 changes: 2 additions & 0 deletions font-types/src/glyph_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
/// A 16-bit glyph identifier.
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bytemuck", derive(bytemuck::AnyBitPattern))]
#[repr(transparent)]
pub struct GlyphId(u16);

impl GlyphId {
Expand Down
1 change: 0 additions & 1 deletion font-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
//!
//! [data types]: https://docs.microsoft.com/en-us/typography/opentype/spec/otff#data-types
#![forbid(unsafe_code)]
#![deny(rustdoc::broken_intra_doc_links)]
#![cfg_attr(not(test), no_std)]

Expand Down
2 changes: 2 additions & 0 deletions font-types/src/longdatetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
/// This represented as a number of seconds since 12:00 midnight, January 1, 1904, UTC.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bytemuck", derive(bytemuck::AnyBitPattern))]
#[repr(transparent)]
pub struct LongDateTime(i64);

impl LongDateTime {
Expand Down
2 changes: 2 additions & 0 deletions font-types/src/name_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use core::fmt;
/// For more detail, see <https://learn.microsoft.com/en-us/typography/opentype/spec/name#name-ids>
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bytemuck", derive(bytemuck::AnyBitPattern))]
#[repr(transparent)]
pub struct NameId(u16);

impl NameId {
Expand Down
4 changes: 4 additions & 0 deletions font-types/src/offset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use crate::{Scalar, Uint24};
/// An offset of a given width for which NULL (zero) is a valid value.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bytemuck", derive(bytemuck::AnyBitPattern))]
#[repr(transparent)]
pub struct Nullable<T>(T);

// internal implementation detail; lets us implement Default for nullable offsets.
Expand Down Expand Up @@ -63,6 +65,8 @@ macro_rules! impl_offset {
/// the `None` case.
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bytemuck", derive(bytemuck::AnyBitPattern))]
#[repr(transparent)]
pub struct $name($rawty);

impl $name {
Expand Down
21 changes: 21 additions & 0 deletions font-types/src/point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssi
/// Two dimensional point with a generic coordinate type.
#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bytemuck", derive(bytemuck::AnyBitPattern))]
#[repr(C)]
pub struct Point<T> {
/// X coordinate.
Expand All @@ -11,6 +12,26 @@ pub struct Point<T> {
pub y: T,
}

/// SAFETY:
/// This trait has four preconditions:
///
/// 1. All fields in the struct must implement `NoUninit`
/// 2. The struct must be `#[repr(C)]` or `#[repr(transparent)]`
/// 3. The struct must not contain any padding bytes
/// 4. The struct must contain no generic parameters
///
/// We satisfy the first and second preconditions trivially. The third
/// condition is satisfied because the struct is repr(C) and contains
/// two fields of the same type which guarantees no padding.
///
/// The fourth condition is obviously not satisfied which is what
/// requires implementing this trait manually rather than deriving
/// it. This condition only exists because the bytemuck derive
/// macro cannot guarantee the first three conditions in a type
/// with generic parameters.
#[cfg(feature = "bytemuck")]
unsafe impl<T> bytemuck::NoUninit for Point<T> where T: bytemuck::NoUninit {}

impl<T> Point<T> {
/// Creates a new point with the given x and y coordinates.
#[inline(always)]
Expand Down
17 changes: 17 additions & 0 deletions font-types/src/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,18 @@ mod sealed {
///
/// This is only used in `Scalar`, as a way of expressing the condition that the
/// `Raw` type is always a fixed-size byte array.
#[cfg(not(feature = "bytemuck"))]
pub trait BeByteArray: Copy + AsRef<[u8]> {
/// Must always succeed for [u8; N] if slice.len() == N, must fail otherwise
fn from_slice(slice: &[u8]) -> Option<Self>;
}
#[cfg(feature = "bytemuck")]
pub trait BeByteArray:
Copy + AsRef<[u8]> + bytemuck::AnyBitPattern + bytemuck::Zeroable
{
/// Must always succeed for [u8; N] if slice.len() == N, must fail otherwise
fn from_slice(slice: &[u8]) -> Option<Self>;
}

impl<const N: usize> BeByteArray for [u8; N] {
fn from_slice(slice: &[u8]) -> Option<Self> {
Expand All @@ -66,6 +74,15 @@ mod sealed {
#[repr(transparent)]
pub struct BigEndian<T: Scalar>(pub(crate) T::Raw);

// # SAFETY:
//
// `BigEndian<T>` has the bound `T: Scalar`, and contains only a single value,
// `<T as Scalar>::Raw` which is only ever a byte array.
#[cfg(feature = "bytemuck")]
unsafe impl<T> bytemuck::Zeroable for BigEndian<T> where T: Scalar + Copy {}
#[cfg(feature = "bytemuck")]
unsafe impl<T> bytemuck::AnyBitPattern for BigEndian<T> where T: Scalar + Copy + 'static {}

impl<T: Scalar> BigEndian<T> {
/// construct a new `BigEndian<T>` from raw bytes
pub fn new(raw: T::Raw) -> BigEndian<T> {
Expand Down
2 changes: 2 additions & 0 deletions font-types/src/tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use std::{
///
/// [spec]: https://learn.microsoft.com/en-us/typography/opentype/spec/otff#data-types
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "bytemuck", derive(bytemuck::AnyBitPattern))]
#[repr(transparent)]
pub struct Tag([u8; 4]);

impl Tag {
Expand Down
2 changes: 2 additions & 0 deletions font-types/src/uint24.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/// 24-bit unsigned integer.
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bytemuck", derive(bytemuck::AnyBitPattern))]
#[repr(transparent)]
pub struct Uint24(u32);

impl Uint24 {
Expand Down
4 changes: 4 additions & 0 deletions font-types/src/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
/// additional details.
#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bytemuck", derive(bytemuck::AnyBitPattern))]
#[repr(transparent)]
pub struct Version16Dot16(u32);

/// A type representing a major, minor version pair.
Expand All @@ -16,6 +18,8 @@ pub struct Version16Dot16(u32);
/// parses out a version.
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bytemuck", derive(bytemuck::AnyBitPattern))]
#[repr(C)]
pub struct MajorMinor {
/// The major version number
pub major: u16,
Expand Down
4 changes: 2 additions & 2 deletions otexplorer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ publish = false

[dependencies]
xflags = "0.3.0"
read-fonts = { path = "../read-fonts",version = "0.17.0" }
font-types = { path = "../font-types",version = "0.4.3" }
read-fonts = { path = "../read-fonts",version = "0.18.0" }
font-types = { path = "../font-types",version = "0.5.1" }
ansi_term = "0.12.1"
atty = "0.2"

Expand Down
6 changes: 4 additions & 2 deletions read-fonts/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "read-fonts"
version = "0.17.0"
version = "0.18.0"
edition = "2021"
license = "MIT/Apache-2.0"
description = "Reading OpenType font files."
Expand All @@ -17,8 +17,10 @@ default = ["traversal"]
serde = ["dep:serde", "font-types/serde"]

[dependencies]
font-types = { version = "0.4.3", path = "../font-types" }
font-types = { version = "0.5.1", path = "../font-types", features = ["bytemuck"] }
serde = { version = "1.0", features = ["derive"], optional = true }
# note: bytemuck version must be available in all deployment environments
bytemuck = "=1.13.1"

[dev-dependencies]
font-test-data = { path = "../font-test-data" }
5 changes: 5 additions & 0 deletions read-fonts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ This crate handles parsing and reading of OpenType fonts. It is intended to be a
high performance implementation suitable for tasks such as [shaping][], while
still providing a convenient, high-level API.

## Safety

Unsafe code is forbidden by a `#![forbid(unsafe_code)]` attribute in the root
of the library.

## codegen

Much of the code in this crate is generated automatically. This generated code
Expand Down
9 changes: 1 addition & 8 deletions read-fonts/generated/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl<'a> std::fmt::Debug for TableDirectory<'a> {
}

/// Record for a table in a font.
#[derive(Clone, Debug, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct TableRecord {
Expand Down Expand Up @@ -167,13 +167,6 @@ impl FixedSize for TableRecord {
Tag::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN;
}

impl sealed::Sealed for TableRecord {}

/// SAFETY: see the [`FromBytes`] trait documentation.
unsafe impl FromBytes for TableRecord {
fn this_trait_should_only_be_implemented_in_generated_code() {}
}

#[cfg(feature = "traversal")]
impl<'a> SomeRecord<'a> for TableRecord {
fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
Expand Down
9 changes: 1 addition & 8 deletions read-fonts/generated/generated_avar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ impl<'a> SomeRecord<'a> for SegmentMaps<'a> {
}

/// [AxisValueMap](https://learn.microsoft.com/en-us/typography/opentype/spec/avar#table-formats) record
#[derive(Clone, Debug, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct AxisValueMap {
Expand All @@ -173,13 +173,6 @@ impl FixedSize for AxisValueMap {
const RAW_BYTE_LEN: usize = F2Dot14::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN;
}

impl sealed::Sealed for AxisValueMap {}

/// SAFETY: see the [`FromBytes`] trait documentation.
unsafe impl FromBytes for AxisValueMap {
fn this_trait_should_only_be_implemented_in_generated_code() {}
}

#[cfg(feature = "traversal")]
impl<'a> SomeRecord<'a> for AxisValueMap {
fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
Expand Down
Loading

0 comments on commit 7c03942

Please sign in to comment.