diff --git a/Cargo.toml b/Cargo.toml index ace8a26df..1f862bac1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ members = [ [workspace.dependencies] # dev dependencies +env_logger = "0.11" pretty_assertions = "1.3.0" [workspace.metadata.release] diff --git a/fauntlet/Cargo.toml b/fauntlet/Cargo.toml index a81ec4783..5e09b0242 100644 --- a/fauntlet/Cargo.toml +++ b/fauntlet/Cargo.toml @@ -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" diff --git a/font-codegen/Cargo.toml b/font-codegen/Cargo.toml index 8758ff668..295f02518 100644 --- a/font-codegen/Cargo.toml +++ b/font-codegen/Cargo.toml @@ -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"] } @@ -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] diff --git a/font-codegen/src/flags_enums.rs b/font-codegen/src/flags_enums.rs index 59ca7ef6f..0eab85497 100644 --- a/font-codegen/src/flags_enums.rs +++ b/font-codegen/src/flags_enums.rs @@ -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 )* diff --git a/font-codegen/src/record.rs b/font-codegen/src/record.rs index 0a218c635..5287c5c91 100644 --- a/font-codegen/src/record.rs +++ b/font-codegen/src/record.rs @@ -36,7 +36,7 @@ pub(crate) fn generate(item: &Record, all_items: &Items) -> syn::Result syn::Result { #[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); diff --git a/font-types/src/fword.rs b/font-types/src/fword.rs index 724a09c89..1f1071a34 100644 --- a/font-types/src/fword.rs +++ b/font-types/src/fword.rs @@ -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 { diff --git a/font-types/src/glyph_id.rs b/font-types/src/glyph_id.rs index 84a5effab..217f550fc 100644 --- a/font-types/src/glyph_id.rs +++ b/font-types/src/glyph_id.rs @@ -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 { diff --git a/font-types/src/lib.rs b/font-types/src/lib.rs index 82aaa08d6..ba30c3da5 100644 --- a/font-types/src/lib.rs +++ b/font-types/src/lib.rs @@ -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)] diff --git a/font-types/src/longdatetime.rs b/font-types/src/longdatetime.rs index e4a1c0d94..654ed7bb3 100644 --- a/font-types/src/longdatetime.rs +++ b/font-types/src/longdatetime.rs @@ -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 { diff --git a/font-types/src/name_id.rs b/font-types/src/name_id.rs index 5fd690e69..40c4dfa5e 100644 --- a/font-types/src/name_id.rs +++ b/font-types/src/name_id.rs @@ -17,6 +17,8 @@ use core::fmt; /// For more detail, see #[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 { diff --git a/font-types/src/offset.rs b/font-types/src/offset.rs index 89acf321a..19cf2eaea 100644 --- a/font-types/src/offset.rs +++ b/font-types/src/offset.rs @@ -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); // internal implementation detail; lets us implement Default for nullable offsets. @@ -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 { diff --git a/font-types/src/point.rs b/font-types/src/point.rs index 35b227f0d..b10eb3afc 100644 --- a/font-types/src/point.rs +++ b/font-types/src/point.rs @@ -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 { /// X coordinate. @@ -11,6 +12,26 @@ pub struct Point { 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 bytemuck::NoUninit for Point where T: bytemuck::NoUninit {} + impl Point { /// Creates a new point with the given x and y coordinates. #[inline(always)] diff --git a/font-types/src/raw.rs b/font-types/src/raw.rs index 7e687f456..1a63e1b87 100644 --- a/font-types/src/raw.rs +++ b/font-types/src/raw.rs @@ -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; } + #[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; + } impl BeByteArray for [u8; N] { fn from_slice(slice: &[u8]) -> Option { @@ -66,6 +74,15 @@ mod sealed { #[repr(transparent)] pub struct BigEndian(pub(crate) T::Raw); +// # SAFETY: +// +// `BigEndian` has the bound `T: Scalar`, and contains only a single value, +// `::Raw` which is only ever a byte array. +#[cfg(feature = "bytemuck")] +unsafe impl bytemuck::Zeroable for BigEndian where T: Scalar + Copy {} +#[cfg(feature = "bytemuck")] +unsafe impl bytemuck::AnyBitPattern for BigEndian where T: Scalar + Copy + 'static {} + impl BigEndian { /// construct a new `BigEndian` from raw bytes pub fn new(raw: T::Raw) -> BigEndian { diff --git a/font-types/src/tag.rs b/font-types/src/tag.rs index 402470125..b75fe5552 100644 --- a/font-types/src/tag.rs +++ b/font-types/src/tag.rs @@ -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 { diff --git a/font-types/src/uint24.rs b/font-types/src/uint24.rs index e86fdaccc..4f3203fdf 100644 --- a/font-types/src/uint24.rs +++ b/font-types/src/uint24.rs @@ -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 { diff --git a/font-types/src/version.rs b/font-types/src/version.rs index d14f463a3..e9eda100e 100644 --- a/font-types/src/version.rs +++ b/font-types/src/version.rs @@ -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. @@ -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, diff --git a/otexplorer/Cargo.toml b/otexplorer/Cargo.toml index e2048802d..ed4a533aa 100644 --- a/otexplorer/Cargo.toml +++ b/otexplorer/Cargo.toml @@ -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" diff --git a/read-fonts/Cargo.toml b/read-fonts/Cargo.toml index d6000d788..8a0c4a47b 100644 --- a/read-fonts/Cargo.toml +++ b/read-fonts/Cargo.toml @@ -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." @@ -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" } diff --git a/read-fonts/README.md b/read-fonts/README.md index fd2810455..d1bb66b0c 100644 --- a/read-fonts/README.md +++ b/read-fonts/README.md @@ -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 diff --git a/read-fonts/generated/font.rs b/read-fonts/generated/font.rs index 70b7b1b56..70cc12ba6 100644 --- a/read-fonts/generated/font.rs +++ b/read-fonts/generated/font.rs @@ -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 { @@ -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> { diff --git a/read-fonts/generated/generated_avar.rs b/read-fonts/generated/generated_avar.rs index f813a9825..01186779d 100644 --- a/read-fonts/generated/generated_avar.rs +++ b/read-fonts/generated/generated_avar.rs @@ -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 { @@ -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> { diff --git a/read-fonts/generated/generated_base.rs b/read-fonts/generated/generated_base.rs index a00903eb8..e4599647c 100644 --- a/read-fonts/generated/generated_base.rs +++ b/read-fonts/generated/generated_base.rs @@ -368,7 +368,7 @@ impl<'a> std::fmt::Debug for BaseScriptList<'a> { } /// [BaseScriptRecord](https://learn.microsoft.com/en-us/typography/opentype/spec/base#basescriptrecord) -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct BaseScriptRecord { @@ -402,13 +402,6 @@ impl FixedSize for BaseScriptRecord { const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN; } -impl sealed::Sealed for BaseScriptRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for BaseScriptRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for BaseScriptRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -550,7 +543,7 @@ impl<'a> std::fmt::Debug for BaseScript<'a> { } /// [BaseLangSysRecord](https://learn.microsoft.com/en-us/typography/opentype/spec/base#baselangsysrecord) -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct BaseLangSysRecord { @@ -584,13 +577,6 @@ impl FixedSize for BaseLangSysRecord { const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN; } -impl sealed::Sealed for BaseLangSysRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for BaseLangSysRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for BaseLangSysRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -839,7 +825,7 @@ impl<'a> std::fmt::Debug for MinMax<'a> { } /// [FeatMinMaxRecord](https://learn.microsoft.com/en-us/typography/opentype/spec/base#baselangsysrecord) -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct FeatMinMaxRecord { @@ -896,13 +882,6 @@ impl FixedSize for FeatMinMaxRecord { const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN; } -impl sealed::Sealed for FeatMinMaxRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for FeatMinMaxRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for FeatMinMaxRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { diff --git a/read-fonts/generated/generated_bitmap.rs b/read-fonts/generated/generated_bitmap.rs index 307f8be13..0efdeb6de 100644 --- a/read-fonts/generated/generated_bitmap.rs +++ b/read-fonts/generated/generated_bitmap.rs @@ -6,7 +6,7 @@ use crate::codegen_prelude::*; /// [BitmapSize](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#bitmapsize-record) 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 BitmapSize { @@ -115,13 +115,6 @@ impl FixedSize for BitmapSize { + BitmapFlags::RAW_BYTE_LEN; } -impl sealed::Sealed for BitmapSize {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for BitmapSize { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for BitmapSize { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -154,7 +147,7 @@ impl<'a> SomeRecord<'a> for BitmapSize { } /// [SbitLineMetrics](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#sbitlinemetrics-record) 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 SbitLineMetrics { @@ -237,13 +230,6 @@ impl FixedSize for SbitLineMetrics { + i8::RAW_BYTE_LEN; } -impl sealed::Sealed for SbitLineMetrics {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for SbitLineMetrics { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for SbitLineMetrics { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -276,8 +262,9 @@ impl<'a> SomeRecord<'a> for SbitLineMetrics { } /// [Bitmap flags](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#bitmap-flags). -#[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 BitmapFlags { bits: u8, } @@ -583,7 +570,7 @@ impl<'a> From for FieldType<'a> { } /// [BigGlyphMetrics](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#bigglyphmetrics) 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 BigGlyphMetrics { @@ -658,13 +645,6 @@ impl FixedSize for BigGlyphMetrics { + u8::RAW_BYTE_LEN; } -impl sealed::Sealed for BigGlyphMetrics {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for BigGlyphMetrics { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for BigGlyphMetrics { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -687,7 +667,7 @@ impl<'a> SomeRecord<'a> for BigGlyphMetrics { } /// [SmallGlyphMetrics](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#smallglyphmetrics) 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 SmallGlyphMetrics { @@ -738,13 +718,6 @@ impl FixedSize for SmallGlyphMetrics { + u8::RAW_BYTE_LEN; } -impl sealed::Sealed for SmallGlyphMetrics {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for SmallGlyphMetrics { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for SmallGlyphMetrics { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -1354,7 +1327,7 @@ impl<'a> std::fmt::Debug for IndexSubtable4<'a> { } /// [GlyphIdOffsetPair](https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#glyphidoffsetpair-record) 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 GlyphIdOffsetPair { @@ -1380,13 +1353,6 @@ impl FixedSize for GlyphIdOffsetPair { const RAW_BYTE_LEN: usize = GlyphId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; } -impl sealed::Sealed for GlyphIdOffsetPair {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for GlyphIdOffsetPair { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for GlyphIdOffsetPair { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -1545,7 +1511,7 @@ impl<'a> std::fmt::Debug for IndexSubtable5<'a> { } /// [EbdtComponent](https://learn.microsoft.com/en-us/typography/opentype/spec/ebdt#ebdtcomponent-record) 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 BdtComponent { @@ -1578,13 +1544,6 @@ impl FixedSize for BdtComponent { const RAW_BYTE_LEN: usize = GlyphId::RAW_BYTE_LEN + i8::RAW_BYTE_LEN + i8::RAW_BYTE_LEN; } -impl sealed::Sealed for BdtComponent {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for BdtComponent { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for BdtComponent { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { diff --git a/read-fonts/generated/generated_cmap.rs b/read-fonts/generated/generated_cmap.rs index f94170f4e..b213a05a5 100644 --- a/read-fonts/generated/generated_cmap.rs +++ b/read-fonts/generated/generated_cmap.rs @@ -97,7 +97,7 @@ impl<'a> std::fmt::Debug for Cmap<'a> { } /// [Encoding Record](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#encoding-records-and-encodings) -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct EncodingRecord { @@ -142,13 +142,6 @@ impl FixedSize for EncodingRecord { PlatformId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN; } -impl sealed::Sealed for EncodingRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for EncodingRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for EncodingRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -498,7 +491,7 @@ impl<'a> std::fmt::Debug for Cmap2<'a> { } /// Part of [Cmap2] -#[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 SubHeader { @@ -539,13 +532,6 @@ impl FixedSize for SubHeader { u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + i16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; } -impl sealed::Sealed for SubHeader {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for SubHeader { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for SubHeader { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -1038,7 +1024,7 @@ impl<'a> std::fmt::Debug for Cmap8<'a> { } /// Used in [Cmap8] and [Cmap12] -#[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 SequentialMapGroup { @@ -1079,13 +1065,6 @@ impl FixedSize for SequentialMapGroup { const RAW_BYTE_LEN: usize = u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN; } -impl sealed::Sealed for SequentialMapGroup {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for SequentialMapGroup { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for SequentialMapGroup { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -1468,7 +1447,7 @@ impl<'a> std::fmt::Debug for Cmap13<'a> { } /// Part of [Cmap13] -#[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 ConstantMapGroup { @@ -1503,13 +1482,6 @@ impl FixedSize for ConstantMapGroup { const RAW_BYTE_LEN: usize = u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN; } -impl sealed::Sealed for ConstantMapGroup {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for ConstantMapGroup { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for ConstantMapGroup { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -1634,7 +1606,7 @@ impl<'a> std::fmt::Debug for Cmap14<'a> { } /// Part of [Cmap14] -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct VariationSelector { @@ -1693,13 +1665,6 @@ impl FixedSize for VariationSelector { Uint24::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN; } -impl sealed::Sealed for VariationSelector {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for VariationSelector { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for VariationSelector { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -1872,7 +1837,7 @@ impl<'a> std::fmt::Debug for NonDefaultUvs<'a> { } /// Part of [Cmap14] -#[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 UvsMapping { @@ -1898,13 +1863,6 @@ impl FixedSize for UvsMapping { const RAW_BYTE_LEN: usize = Uint24::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; } -impl sealed::Sealed for UvsMapping {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for UvsMapping { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for UvsMapping { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -1921,7 +1879,7 @@ impl<'a> SomeRecord<'a> for UvsMapping { } /// Part of [Cmap14] -#[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 UnicodeRange { @@ -1947,13 +1905,6 @@ impl FixedSize for UnicodeRange { const RAW_BYTE_LEN: usize = Uint24::RAW_BYTE_LEN + u8::RAW_BYTE_LEN; } -impl sealed::Sealed for UnicodeRange {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for UnicodeRange { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for UnicodeRange { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { diff --git a/read-fonts/generated/generated_colr.rs b/read-fonts/generated/generated_colr.rs index 3dd2991ff..b08349337 100644 --- a/read-fonts/generated/generated_colr.rs +++ b/read-fonts/generated/generated_colr.rs @@ -295,7 +295,7 @@ impl<'a> std::fmt::Debug for Colr<'a> { } /// [BaseGlyph](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyph-and-layer-records) 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 BaseGlyph { @@ -328,13 +328,6 @@ impl FixedSize for BaseGlyph { const RAW_BYTE_LEN: usize = GlyphId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; } -impl sealed::Sealed for BaseGlyph {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for BaseGlyph { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for BaseGlyph { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -352,7 +345,7 @@ impl<'a> SomeRecord<'a> for BaseGlyph { } /// [Layer](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyph-and-layer-records) 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 Layer { @@ -378,13 +371,6 @@ impl FixedSize for Layer { const RAW_BYTE_LEN: usize = GlyphId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; } -impl sealed::Sealed for Layer {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for Layer { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for Layer { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -478,7 +464,7 @@ impl<'a> std::fmt::Debug for BaseGlyphList<'a> { } /// [BaseGlyphPaint](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct BaseGlyphPaint { @@ -512,13 +498,6 @@ impl FixedSize for BaseGlyphPaint { const RAW_BYTE_LEN: usize = GlyphId::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN; } -impl sealed::Sealed for BaseGlyphPaint {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for BaseGlyphPaint { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for BaseGlyphPaint { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -710,7 +689,7 @@ impl<'a> std::fmt::Debug for ClipList<'a> { } /// [Clip](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#baseglyphlist-layerlist-and-cliplist) record -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct Clip { @@ -752,13 +731,6 @@ impl FixedSize for Clip { GlyphId::RAW_BYTE_LEN + GlyphId::RAW_BYTE_LEN + Offset24::RAW_BYTE_LEN; } -impl sealed::Sealed for Clip {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for Clip { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for Clip { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -1084,7 +1056,7 @@ impl<'a> std::fmt::Debug for ClipBoxFormat2<'a> { } /// [ColorIndex](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) 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 ColorIndex { @@ -1110,13 +1082,6 @@ impl FixedSize for ColorIndex { const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN; } -impl sealed::Sealed for ColorIndex {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for ColorIndex { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for ColorIndex { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -1133,7 +1098,7 @@ impl<'a> SomeRecord<'a> for ColorIndex { } /// [VarColorIndex](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) 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 VarColorIndex { @@ -1166,13 +1131,6 @@ impl FixedSize for VarColorIndex { const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + u32::RAW_BYTE_LEN; } -impl sealed::Sealed for VarColorIndex {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for VarColorIndex { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for VarColorIndex { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -1190,7 +1148,7 @@ impl<'a> SomeRecord<'a> for VarColorIndex { } /// [ColorStop](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) 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 ColorStop { @@ -1223,13 +1181,6 @@ impl FixedSize for ColorStop { const RAW_BYTE_LEN: usize = F2Dot14::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN; } -impl sealed::Sealed for ColorStop {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for ColorStop { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for ColorStop { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -1247,7 +1198,7 @@ impl<'a> SomeRecord<'a> for ColorStop { } /// [VarColorStop](https://learn.microsoft.com/en-us/typography/opentype/spec/colr#color-references-colorstop-and-colorline) 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 VarColorStop { @@ -1288,13 +1239,6 @@ impl FixedSize for VarColorStop { F2Dot14::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + u32::RAW_BYTE_LEN; } -impl sealed::Sealed for VarColorStop {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for VarColorStop { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for VarColorStop { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { diff --git a/read-fonts/generated/generated_cpal.rs b/read-fonts/generated/generated_cpal.rs index 81d4b6013..9a5ceac02 100644 --- a/read-fonts/generated/generated_cpal.rs +++ b/read-fonts/generated/generated_cpal.rs @@ -266,8 +266,9 @@ impl<'a> std::fmt::Debug for Cpal<'a> { } /// The [PaletteType](https://learn.microsoft.com/en-us/typography/opentype/spec/cpal#palette-type-array) flags. -#[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 PaletteType { bits: u32, } @@ -579,7 +580,7 @@ impl<'a> From for FieldType<'a> { } /// [CPAL (Color Record)](https://learn.microsoft.com/en-us/typography/opentype/spec/cpal#palette-entries-and-color-records) 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 ColorRecord { @@ -620,13 +621,6 @@ impl FixedSize for ColorRecord { u8::RAW_BYTE_LEN + u8::RAW_BYTE_LEN + u8::RAW_BYTE_LEN + u8::RAW_BYTE_LEN; } -impl sealed::Sealed for ColorRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for ColorRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for ColorRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { diff --git a/read-fonts/generated/generated_fvar.rs b/read-fonts/generated/generated_fvar.rs index 05f11ef96..3c26fd005 100644 --- a/read-fonts/generated/generated_fvar.rs +++ b/read-fonts/generated/generated_fvar.rs @@ -268,7 +268,7 @@ impl<'a> std::fmt::Debug for AxisInstanceArrays<'a> { } /// The [VariationAxisRecord](https://learn.microsoft.com/en-us/typography/opentype/spec/fvar#variationaxisrecord) -#[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 VariationAxisRecord { @@ -327,13 +327,6 @@ impl FixedSize for VariationAxisRecord { + NameId::RAW_BYTE_LEN; } -impl sealed::Sealed for VariationAxisRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for VariationAxisRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for VariationAxisRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { diff --git a/read-fonts/generated/generated_glyf.rs b/read-fonts/generated/generated_glyf.rs index 5d1d36fe7..660568404 100644 --- a/read-fonts/generated/generated_glyf.rs +++ b/read-fonts/generated/generated_glyf.rs @@ -218,8 +218,9 @@ impl<'a> std::fmt::Debug for SimpleGlyph<'a> { } /// Flags used in [SimpleGlyph] -#[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 SimpleGlyphFlags { bits: u8, } @@ -727,8 +728,9 @@ impl<'a> std::fmt::Debug for CompositeGlyph<'a> { } /// Flags used in [CompositeGlyph] -#[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 CompositeGlyphFlags { bits: u16, } diff --git a/read-fonts/generated/generated_gpos.rs b/read-fonts/generated/generated_gpos.rs index 6a102c6fa..61988233c 100644 --- a/read-fonts/generated/generated_gpos.rs +++ b/read-fonts/generated/generated_gpos.rs @@ -246,8 +246,9 @@ impl<'a> std::fmt::Debug for PositionLookup<'a> { } /// See [ValueRecord] -#[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 ValueFormat { bits: u16, } @@ -1037,7 +1038,7 @@ impl<'a> std::fmt::Debug for MarkArray<'a> { } /// Part of [MarkArray] -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct MarkRecord { @@ -1071,13 +1072,6 @@ impl FixedSize for MarkRecord { const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN; } -impl sealed::Sealed for MarkRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for MarkRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for MarkRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -2331,7 +2325,7 @@ impl<'a> std::fmt::Debug for CursivePosFormat1<'a> { } /// Part of [CursivePosFormat1] -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct EntryExitRecord { @@ -2385,13 +2379,6 @@ impl FixedSize for EntryExitRecord { const RAW_BYTE_LEN: usize = Offset16::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN; } -impl sealed::Sealed for EntryExitRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for EntryExitRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for EntryExitRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { diff --git a/read-fonts/generated/generated_gvar.rs b/read-fonts/generated/generated_gvar.rs index c5fe8a147..d0389f244 100644 --- a/read-fonts/generated/generated_gvar.rs +++ b/read-fonts/generated/generated_gvar.rs @@ -176,8 +176,9 @@ impl<'a> std::fmt::Debug for Gvar<'a> { } } -#[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 GvarFlags { bits: u16, } diff --git a/read-fonts/generated/generated_head.rs b/read-fonts/generated/generated_head.rs index adb4df609..9e9fdd8dc 100644 --- a/read-fonts/generated/generated_head.rs +++ b/read-fonts/generated/generated_head.rs @@ -6,8 +6,9 @@ use crate::codegen_prelude::*; /// The `macStyle` field for the head table. -#[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 MacStyle { bits: u16, } diff --git a/read-fonts/generated/generated_hmtx.rs b/read-fonts/generated/generated_hmtx.rs index 4a73fd042..bbb48802e 100644 --- a/read-fonts/generated/generated_hmtx.rs +++ b/read-fonts/generated/generated_hmtx.rs @@ -111,7 +111,7 @@ impl<'a> std::fmt::Debug for Hmtx<'a> { } } -#[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 LongMetric { @@ -137,13 +137,6 @@ impl FixedSize for LongMetric { const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + i16::RAW_BYTE_LEN; } -impl sealed::Sealed for LongMetric {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for LongMetric { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for LongMetric { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { diff --git a/read-fonts/generated/generated_layout.rs b/read-fonts/generated/generated_layout.rs index 87b1b9999..18986da53 100644 --- a/read-fonts/generated/generated_layout.rs +++ b/read-fonts/generated/generated_layout.rs @@ -81,7 +81,7 @@ impl<'a> std::fmt::Debug for ScriptList<'a> { } /// [Script Record](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#script-list-table-and-script-record) -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct ScriptRecord { @@ -115,13 +115,6 @@ impl FixedSize for ScriptRecord { const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN; } -impl sealed::Sealed for ScriptRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for ScriptRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for ScriptRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -238,7 +231,7 @@ impl<'a> std::fmt::Debug for Script<'a> { } } -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct LangSysRecord { @@ -272,13 +265,6 @@ impl FixedSize for LangSysRecord { const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN; } -impl sealed::Sealed for LangSysRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for LangSysRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for LangSysRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -467,7 +453,7 @@ impl<'a> std::fmt::Debug for FeatureList<'a> { } /// Part of [FeatureList] -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct FeatureRecord { @@ -502,13 +488,6 @@ impl FixedSize for FeatureRecord { const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN; } -impl sealed::Sealed for FeatureRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for FeatureRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for FeatureRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -1119,7 +1098,7 @@ impl<'a> std::fmt::Debug for CoverageFormat2<'a> { } /// Used in [CoverageFormat2] -#[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 RangeRecord { @@ -1152,13 +1131,6 @@ impl FixedSize for RangeRecord { const RAW_BYTE_LEN: usize = GlyphId::RAW_BYTE_LEN + GlyphId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; } -impl sealed::Sealed for RangeRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for RangeRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for RangeRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -1422,7 +1394,7 @@ impl<'a> std::fmt::Debug for ClassDefFormat2<'a> { } /// Used in [ClassDefFormat2] -#[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 ClassRangeRecord { @@ -1455,13 +1427,6 @@ impl FixedSize for ClassRangeRecord { const RAW_BYTE_LEN: usize = GlyphId::RAW_BYTE_LEN + GlyphId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; } -impl sealed::Sealed for ClassRangeRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for ClassRangeRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for ClassRangeRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -1534,7 +1499,7 @@ impl<'a> SomeTable<'a> for ClassDef<'a> { } /// [Sequence Lookup Record](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-lookup-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 SequenceLookupRecord { @@ -1560,13 +1525,6 @@ impl FixedSize for SequenceLookupRecord { const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; } -impl sealed::Sealed for SequenceLookupRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for SequenceLookupRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for SequenceLookupRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -3979,7 +3937,7 @@ impl<'a> std::fmt::Debug for FeatureVariations<'a> { } /// Part of [FeatureVariations] -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct FeatureVariationRecord { @@ -4033,13 +3991,6 @@ impl FixedSize for FeatureVariationRecord { const RAW_BYTE_LEN: usize = Offset32::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN; } -impl sealed::Sealed for FeatureVariationRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for FeatureVariationRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for FeatureVariationRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -4342,7 +4293,7 @@ impl<'a> std::fmt::Debug for FeatureTableSubstitution<'a> { } /// Used in [FeatureTableSubstitution] -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct FeatureTableSubstitutionRecord { @@ -4370,13 +4321,6 @@ impl FixedSize for FeatureTableSubstitutionRecord { const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN; } -impl sealed::Sealed for FeatureTableSubstitutionRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for FeatureTableSubstitutionRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for FeatureTableSubstitutionRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { diff --git a/read-fonts/generated/generated_mvar.rs b/read-fonts/generated/generated_mvar.rs index 5e54ae81a..2056ebc5f 100644 --- a/read-fonts/generated/generated_mvar.rs +++ b/read-fonts/generated/generated_mvar.rs @@ -140,7 +140,7 @@ impl<'a> std::fmt::Debug for Mvar<'a> { } /// [ValueRecord](https://learn.microsoft.com/en-us/typography/opentype/spec/mvar#table-formats) metrics variation 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 ValueRecord { @@ -173,13 +173,6 @@ impl FixedSize for ValueRecord { const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; } -impl sealed::Sealed for ValueRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for ValueRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for ValueRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { diff --git a/read-fonts/generated/generated_name.rs b/read-fonts/generated/generated_name.rs index 922131aaf..e04d5d4a9 100644 --- a/read-fonts/generated/generated_name.rs +++ b/read-fonts/generated/generated_name.rs @@ -167,7 +167,7 @@ impl<'a> std::fmt::Debug for Name<'a> { } /// Part of [Name] -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct LangTagRecord { @@ -195,13 +195,6 @@ impl FixedSize for LangTagRecord { const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN; } -impl sealed::Sealed for LangTagRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for LangTagRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for LangTagRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -218,7 +211,7 @@ impl<'a> SomeRecord<'a> for LangTagRecord { } ///[Name Records](https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-records) -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct NameRecord { @@ -277,13 +270,6 @@ impl FixedSize for NameRecord { + Offset16::RAW_BYTE_LEN; } -impl sealed::Sealed for NameRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for NameRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for NameRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { diff --git a/read-fonts/generated/generated_os2.rs b/read-fonts/generated/generated_os2.rs index 01daddbed..8b32bf741 100644 --- a/read-fonts/generated/generated_os2.rs +++ b/read-fonts/generated/generated_os2.rs @@ -6,8 +6,9 @@ use crate::codegen_prelude::*; /// OS/2 [selection flags](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#fsselection) -#[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 SelectionFlags { bits: u16, } diff --git a/read-fonts/generated/generated_postscript.rs b/read-fonts/generated/generated_postscript.rs index a6fc33777..9c9af67f1 100644 --- a/read-fonts/generated/generated_postscript.rs +++ b/read-fonts/generated/generated_postscript.rs @@ -428,7 +428,7 @@ impl<'a> std::fmt::Debug for FdSelectFormat3<'a> { } /// Range struct for FdSelect format 3. -#[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 FdSelectRange3 { @@ -454,13 +454,6 @@ impl FixedSize for FdSelectRange3 { const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u8::RAW_BYTE_LEN; } -impl sealed::Sealed for FdSelectRange3 {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for FdSelectRange3 { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for FdSelectRange3 { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -578,7 +571,7 @@ impl<'a> std::fmt::Debug for FdSelectFormat4<'a> { } /// Range struct for FdSelect format 4. -#[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 FdSelectRange4 { @@ -604,13 +597,6 @@ impl FixedSize for FdSelectRange4 { const RAW_BYTE_LEN: usize = u32::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; } -impl sealed::Sealed for FdSelectRange4 {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for FdSelectRange4 { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for FdSelectRange4 { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { diff --git a/read-fonts/generated/generated_sbix.rs b/read-fonts/generated/generated_sbix.rs index 640f90de6..efb58040a 100644 --- a/read-fonts/generated/generated_sbix.rs +++ b/read-fonts/generated/generated_sbix.rs @@ -6,8 +6,9 @@ use crate::codegen_prelude::*; /// Sbix header flags. -#[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 HeaderFlags { bits: u16, } diff --git a/read-fonts/generated/generated_stat.rs b/read-fonts/generated/generated_stat.rs index 4e3e77282..c724ba964 100644 --- a/read-fonts/generated/generated_stat.rs +++ b/read-fonts/generated/generated_stat.rs @@ -188,7 +188,7 @@ impl<'a> std::fmt::Debug for Stat<'a> { } /// [Axis Records](https://docs.microsoft.com/en-us/typography/opentype/spec/stat#axis-records) -#[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 AxisRecord { @@ -227,13 +227,6 @@ impl FixedSize for AxisRecord { const RAW_BYTE_LEN: usize = Tag::RAW_BYTE_LEN + NameId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; } -impl sealed::Sealed for AxisRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for AxisRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for AxisRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -902,7 +895,7 @@ impl<'a> std::fmt::Debug for AxisValueFormat4<'a> { } /// Part of [AxisValueFormat4] -#[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 AxisValueRecord { @@ -930,13 +923,6 @@ impl FixedSize for AxisValueRecord { const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + Fixed::RAW_BYTE_LEN; } -impl sealed::Sealed for AxisValueRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for AxisValueRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for AxisValueRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -953,8 +939,9 @@ impl<'a> SomeRecord<'a> for AxisValueRecord { } /// [Axis value table flags](https://docs.microsoft.com/en-us/typography/opentype/spec/stat#flags). -#[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 AxisValueTableFlags { bits: u16, } diff --git a/read-fonts/generated/generated_test_enum.rs b/read-fonts/generated/generated_test_enum.rs index 4749729a7..cea55b51b 100644 --- a/read-fonts/generated/generated_test_enum.rs +++ b/read-fonts/generated/generated_test_enum.rs @@ -96,7 +96,7 @@ impl<'a> From for FieldType<'a> { } } -#[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 MyRecord { @@ -118,13 +118,6 @@ impl FixedSize for MyRecord { const RAW_BYTE_LEN: usize = MyEnum1::RAW_BYTE_LEN + MyEnum2::RAW_BYTE_LEN; } -impl sealed::Sealed for MyRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for MyRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for MyRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { diff --git a/read-fonts/generated/generated_test_flags.rs b/read-fonts/generated/generated_test_flags.rs index 7e48a4b41..b8b24b737 100644 --- a/read-fonts/generated/generated_test_flags.rs +++ b/read-fonts/generated/generated_test_flags.rs @@ -6,8 +6,9 @@ use crate::codegen_prelude::*; /// Some flags! -#[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 ValueFormat { bits: u16, } diff --git a/read-fonts/generated/generated_test_offsets_arrays.rs b/read-fonts/generated/generated_test_offsets_arrays.rs index 964656886..3b8faa6ea 100644 --- a/read-fonts/generated/generated_test_offsets_arrays.rs +++ b/read-fonts/generated/generated_test_offsets_arrays.rs @@ -699,7 +699,7 @@ impl<'a> std::fmt::Debug for Dummy<'a> { } } -#[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 Shmecord { @@ -721,13 +721,6 @@ impl FixedSize for Shmecord { const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN; } -impl sealed::Sealed for Shmecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for Shmecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for Shmecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { diff --git a/read-fonts/generated/generated_test_records.rs b/read-fonts/generated/generated_test_records.rs index 46c351747..7747304e2 100644 --- a/read-fonts/generated/generated_test_records.rs +++ b/read-fonts/generated/generated_test_records.rs @@ -125,7 +125,7 @@ impl<'a> std::fmt::Debug for BasicTable<'a> { } } -#[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 SimpleRecord { @@ -147,13 +147,6 @@ impl FixedSize for SimpleRecord { const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN; } -impl sealed::Sealed for SimpleRecord {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for SimpleRecord { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for SimpleRecord { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { @@ -240,7 +233,7 @@ impl<'a> SomeRecord<'a> for ContainsArrays<'a> { } } -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)] #[repr(C)] #[repr(packed)] pub struct ContainsOffests { @@ -282,13 +275,6 @@ impl FixedSize for ContainsOffests { const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + Offset16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN; } -impl sealed::Sealed for ContainsOffests {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for ContainsOffests { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for ContainsOffests { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { diff --git a/read-fonts/generated/generated_variations.rs b/read-fonts/generated/generated_variations.rs index 99101645f..21b6aec87 100644 --- a/read-fonts/generated/generated_variations.rs +++ b/read-fonts/generated/generated_variations.rs @@ -451,8 +451,9 @@ impl<'a> SomeTable<'a> for DeltaSetIndexMap<'a> { } /// Entry format for a [DeltaSetIndexMap]. -#[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 EntryFormat { bits: u8, } @@ -920,7 +921,7 @@ impl<'a> SomeRecord<'a> for VariationRegion<'a> { } /// The [RegionAxisCoordinates](https://learn.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#variation-regions) 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 RegionAxisCoordinates { @@ -954,13 +955,6 @@ impl FixedSize for RegionAxisCoordinates { F2Dot14::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN + F2Dot14::RAW_BYTE_LEN; } -impl sealed::Sealed for RegionAxisCoordinates {} - -/// SAFETY: see the [`FromBytes`] trait documentation. -unsafe impl FromBytes for RegionAxisCoordinates { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - #[cfg(feature = "traversal")] impl<'a> SomeRecord<'a> for RegionAxisCoordinates { fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { diff --git a/read-fonts/src/array.rs b/read-fonts/src/array.rs index 5394a62b3..9709b252d 100644 --- a/read-fonts/src/array.rs +++ b/read-fonts/src/array.rs @@ -1,6 +1,8 @@ //! Custom array types -use crate::codegen_prelude::FromBytes; +use bytemuck::AnyBitPattern; +use font_types::FixedSize; + use crate::read::{ComputeSize, FontReadWithArgs, ReadArgs, VarSize}; use crate::{FontData, FontRead, ReadError}; @@ -143,11 +145,11 @@ impl<'a, T> FontRead<'a> for VarLenArray<'a, T> { } } -impl<'a, T: FromBytes> ReadArgs for &'a [T] { +impl<'a, T: AnyBitPattern> ReadArgs for &'a [T] { type Args = u16; } -impl<'a, T: FromBytes> FontReadWithArgs<'a> for &'a [T] { +impl<'a, T: AnyBitPattern + FixedSize> FontReadWithArgs<'a> for &'a [T] { fn read_with_args(data: FontData<'a>, args: &u16) -> Result { let len = *args as usize * T::RAW_BYTE_LEN; data.read_array(0..len) diff --git a/read-fonts/src/font_data.rs b/read-fonts/src/font_data.rs index 005e67fd5..2a10dc48b 100644 --- a/read-fonts/src/font_data.rs +++ b/read-fonts/src/font_data.rs @@ -2,10 +2,11 @@ use std::ops::{Range, RangeBounds}; +use bytemuck::AnyBitPattern; use types::{BigEndian, FixedSize, Scalar}; use crate::array::ComputedArray; -use crate::read::{ComputeSize, FontReadWithArgs, FromBytes, ReadError}; +use crate::read::{ComputeSize, FontReadWithArgs, ReadError}; use crate::table_ref::TableRef; use crate::FontRead; @@ -115,33 +116,14 @@ impl<'a> FontData<'a> { /// other than one, or has any internal padding. /// /// [`read_ref_unchecked`]: [Self::read_ref_unchecked] - pub fn read_ref_at(&self, offset: usize) -> Result<&'a T, ReadError> { - assert_ne!(std::mem::size_of::(), 0); - // assert we have no padding. - // `T::RAW_BYTE_LEN` is computed by recursively taking the raw length of - // any fields of `T`; if `size_of::() == T::RAW_BYTE_LEN`` we know that - // `T` contains no padding. - assert_eq!(std::mem::size_of::(), T::RAW_BYTE_LEN); - assert_eq!(std::mem::align_of::(), 1); + pub fn read_ref_at( + &self, + offset: usize, + ) -> Result<&'a T, ReadError> { self.bytes .get(offset..offset + T::RAW_BYTE_LEN) - .ok_or(ReadError::OutOfBounds)?; - - // SAFETY: if we have reached this point without hitting an assert or - // returning an error, our invariants are met. - unsafe { Ok(self.read_ref_unchecked(offset)) } - } - - /// Interpret the bytes at `offset` as a reference to some type `T`. - /// - /// # Safety - /// - /// `T` must be a struct or scalar that has alignment of 1, a non-zero size, - /// and no internal padding, and offset must point to a slice of bytes that - /// has length >= `size_of::()`. - unsafe fn read_ref_unchecked(&self, offset: usize) -> &'a T { - let bytes = self.bytes.get_unchecked(offset..offset + T::RAW_BYTE_LEN); - &*(bytes.as_ptr() as *const T) + .ok_or(ReadError::OutOfBounds) + .map(bytemuck::from_bytes) } /// Interpret the bytes at the provided offset as a slice of `T`. @@ -158,14 +140,10 @@ impl<'a> FontData<'a> { /// other than one, or has any internal padding. /// /// [`read_array_unchecked`]: [Self::read_array_unchecked] - pub fn read_array(&self, range: Range) -> Result<&'a [T], ReadError> { - assert_ne!(std::mem::size_of::(), 0); - // assert we have no padding. - // `T::RAW_BYTE_LEN` is computed by recursively taking the raw length of - // any fields of `T`; if `size_of::() == T::RAW_BYTE_LEN`` we know that - // `T` contains no padding. - assert_eq!(std::mem::size_of::(), T::RAW_BYTE_LEN); - assert_eq!(std::mem::align_of::(), 1); + pub fn read_array( + &self, + range: Range, + ) -> Result<&'a [T], ReadError> { let bytes = self .bytes .get(range.clone()) @@ -173,22 +151,7 @@ impl<'a> FontData<'a> { if bytes.len() % std::mem::size_of::() != 0 { return Err(ReadError::InvalidArrayLen); }; - // SAFETY: if we have reached this point without hitting an assert or - // returning an error, our invariants are met. - unsafe { Ok(self.read_array_unchecked(range)) } - } - - /// Interpret the bytes at `offset` as a reference to some type `T`. - /// - /// # Safety - /// - /// `T` must be a struct or scalar that has alignment of 1, a non-zero size, - /// and no internal padding, and `range` must have a length that is non-zero - /// and is a multiple of `size_of::()`. - unsafe fn read_array_unchecked(&self, range: Range) -> &'a [T] { - let bytes = self.bytes.get_unchecked(range); - let elems = bytes.len() / std::mem::size_of::(); - std::slice::from_raw_parts(bytes.as_ptr() as *const _, elems) + Ok(bytemuck::cast_slice(bytes)) } pub(crate) fn cursor(&self) -> Cursor<'a> { @@ -252,7 +215,10 @@ impl<'a> Cursor<'a> { temp } - pub(crate) fn read_array(&mut self, n_elem: usize) -> Result<&'a [T], ReadError> { + pub(crate) fn read_array( + &mut self, + n_elem: usize, + ) -> Result<&'a [T], ReadError> { let len = n_elem * T::RAW_BYTE_LEN; let temp = self.data.read_array(self.pos..self.pos + len); self.pos += len; diff --git a/read-fonts/src/lib.rs b/read-fonts/src/lib.rs index 6440b867c..5d42ec19d 100644 --- a/read-fonts/src/lib.rs +++ b/read-fonts/src/lib.rs @@ -56,6 +56,7 @@ //! [NameString]: tables::name::NameString //! [table-directory]: https://learn.microsoft.com/en-us/typography/opentype/spec/otff#table-directory +#![forbid(unsafe_code)] #![deny(rustdoc::broken_intra_doc_links)] #![cfg_attr(not(feature = "std"), no_std)] @@ -91,7 +92,7 @@ pub mod scaler_test; pub use font_data::FontData; pub use offset::{Offset, ResolveNullableOffset, ResolveOffset}; pub use offset_array::{ArrayOfNullableOffsets, ArrayOfOffsets}; -pub use read::{ComputeSize, FontRead, FontReadWithArgs, FromBytes, ReadArgs, ReadError, VarSize}; +pub use read::{ComputeSize, FontRead, FontReadWithArgs, ReadArgs, ReadError, VarSize}; pub use table_provider::{TableProvider, TopLevelTable}; pub use table_ref::TableRef; @@ -105,9 +106,9 @@ pub(crate) mod codegen_prelude { pub use crate::font_data::{Cursor, FontData}; pub use crate::offset::{Offset, ResolveNullableOffset, ResolveOffset}; pub use crate::offset_array::{ArrayOfNullableOffsets, ArrayOfOffsets}; - pub(crate) use crate::read::sealed; + //pub(crate) use crate::read::sealed; pub use crate::read::{ - ComputeSize, FontRead, FontReadWithArgs, Format, FromBytes, ReadArgs, ReadError, VarSize, + ComputeSize, FontRead, FontReadWithArgs, Format, ReadArgs, ReadError, VarSize, }; pub use crate::table_provider::TopLevelTable; pub use crate::table_ref::TableRef; diff --git a/read-fonts/src/read.rs b/read-fonts/src/read.rs index 15615a75c..1e17ab9f7 100644 --- a/read-fonts/src/read.rs +++ b/read-fonts/src/read.rs @@ -1,6 +1,6 @@ //! Traits for interpreting font data -use types::{BigEndian, FixedSize, Scalar, Tag}; +use types::{FixedSize, Scalar, Tag}; use crate::font_data::FontData; @@ -94,56 +94,6 @@ pub trait VarSize { } } -/// A marker trait for types that can read from a big-endian buffer without copying. -/// -/// This is used as a trait bound on certain methods on [`FontData`] (such as -/// [`FontData::read_ref_at`] and [`FontData::read_array`]) in order to ensure -/// that those methods are only used with types that uphold certain safety -/// guarantees. -/// -/// WARNING: Do not implement this trait manually. Implementations are created -/// where appropriate during code generation, and there should be no conditions -/// under which this trait could be implemented, but cannot be implemented by -/// codegen. -/// -/// # Safety -/// -/// If a type `T` implements `FromBytes` then unsafe code may assume that it is -/// safe to interpret any sequence of bytes with length equal to -/// `std::mem::size_of::()` as `T`. -/// -/// we additionally ensure the following conditions: -/// -/// - the type must have no internal padding -/// - `std::mem::align_of::() == 1` -/// - for structs, the type is `repr(packed)` and `repr(C)`, and all fields are -/// also `FromBytes` -/// -/// In practice, this trait is only implemented for `u8`, `BigEndian`, -/// and for structs where all fields are those base types. -pub unsafe trait FromBytes: FixedSize + sealed::Sealed { - /// You should not be implementing this trait! - #[doc(hidden)] - fn this_trait_should_only_be_implemented_in_generated_code(); -} - -// a sealed trait. see -pub(crate) mod sealed { - pub trait Sealed {} -} - -impl sealed::Sealed for u8 {} -// SAFETY: any byte can be interpreted as any other byte -unsafe impl FromBytes for u8 { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - -impl sealed::Sealed for BigEndian {} -// SAFETY: BigEndian is always wrapper around a transparent fixed-size byte array -unsafe impl FromBytes for BigEndian { - fn this_trait_should_only_be_implemented_in_generated_code() {} -} - /// An error that occurs when reading font data #[derive(Debug, Clone)] pub enum ReadError { diff --git a/read-fonts/src/tables/glyf.rs b/read-fonts/src/tables/glyf.rs index 9072ffb50..ce2cf821e 100644 --- a/read-fonts/src/tables/glyf.rs +++ b/read-fonts/src/tables/glyf.rs @@ -35,7 +35,9 @@ impl PointMarker { /// Some properties, such as on- and off-curve flags are intrinsic to the point /// itself. Others, designated as markers are set and cleared while an outline /// is being transformed during variation application and hinting. -#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] +#[derive( + Copy, Clone, PartialEq, Eq, Default, Debug, bytemuck::AnyBitPattern, bytemuck::NoUninit, +)] #[repr(transparent)] pub struct PointFlags(u8); diff --git a/read-fonts/src/tables/post.rs b/read-fonts/src/tables/post.rs index 5cc29a7d4..f81c0b0ab 100644 --- a/read-fonts/src/tables/post.rs +++ b/read-fonts/src/tables/post.rs @@ -72,10 +72,9 @@ impl<'a> FontRead<'a> for PString<'a> { .as_bytes() .get(1..len as usize + 1) .ok_or(ReadError::OutOfBounds)?; + if pstring.is_ascii() { - // SAFETY: `pstring` must be valid UTF-8, which is known to be the - // case since ASCII is a subset of UTF-8 and `is_ascii()` is true. - Ok(PString(unsafe { std::str::from_utf8_unchecked(pstring) })) + Ok(PString(std::str::from_utf8(pstring).unwrap())) } else { //FIXME not really sure how we want to handle this? Err(ReadError::MalformedData("Must be valid ascii")) diff --git a/skrifa/Cargo.toml b/skrifa/Cargo.toml index d06929c74..39025a8ba 100644 --- a/skrifa/Cargo.toml +++ b/skrifa/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "skrifa" -version = "0.17.0" +version = "0.18.0" edition = "2021" license = "MIT/Apache-2.0" description = "Metadata reader and glyph scaler for OpenType fonts." @@ -15,12 +15,14 @@ traversal = ["std", "read-fonts/traversal"] libm = ["dep:core_maths"] [dependencies] -read-fonts = { version = "0.17.0", path = "../read-fonts", default-features = false } +read-fonts = { version = "0.18.0", path = "../read-fonts", default-features = false } core_maths = { version = "0.1", 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" } -read-fonts = { version = "0.17.0", path = "../read-fonts", features = [ +read-fonts = { version = "0.18.0", path = "../read-fonts", features = [ "scaler_test", "serde", ] } diff --git a/skrifa/README.md b/skrifa/README.md index 315e6bc49..ba4635840 100644 --- a/skrifa/README.md +++ b/skrifa/README.md @@ -60,3 +60,8 @@ corrupted/malicious font files. Please file an issue if this occurs. Following along with our theme, *skrifa* is Old Norse for "write" or "it is written." And so it is named. + +## Safety + +Unsafe code is forbidden by a `#![forbid(unsafe_code)]` attribute in the root +of the library. diff --git a/skrifa/src/lib.rs b/skrifa/src/lib.rs index 063493386..0ad12979e 100644 --- a/skrifa/src/lib.rs +++ b/skrifa/src/lib.rs @@ -11,6 +11,7 @@ //! See the [readme](https://github.com/googlefonts/fontations/blob/main/skrifa/README.md) //! for additional details. +#![forbid(unsafe_code)] #![cfg_attr(not(any(test, feature = "std")), no_std)] #[cfg(not(any(feature = "libm", feature = "std")))] diff --git a/skrifa/src/outline/glyf/memory.rs b/skrifa/src/outline/glyf/memory.rs index 156e7dde9..79484efc1 100644 --- a/skrifa/src/outline/glyf/memory.rs +++ b/skrifa/src/outline/glyf/memory.rs @@ -101,26 +101,14 @@ impl<'a> OutlineMemory<'a> { } } -/// Trait that defines which types may be used as element types for -/// `alloc_slice`. -/// -/// # Safety -/// This must only be implemented for types that contain no internal padding -/// and for which all bit patterns are valid. -unsafe trait TransmuteElement: Sized + Copy {} - -unsafe impl TransmuteElement for u16 {} -unsafe impl TransmuteElement for i32 {} -unsafe impl TransmuteElement for Fixed {} -unsafe impl TransmuteElement for F26Dot6 {} -unsafe impl TransmuteElement for PointFlags {} -unsafe impl TransmuteElement for Point where T: TransmuteElement {} - /// Allocates a mutable slice of `T` of the given length from the specified /// buffer. /// /// Returns the allocated slice and the remainder of the buffer. -fn alloc_slice(buf: &mut [u8], len: usize) -> Option<(&mut [T], &mut [u8])> { +fn alloc_slice(buf: &mut [u8], len: usize) -> Option<(&mut [T], &mut [u8])> +where + T: bytemuck::AnyBitPattern + bytemuck::NoUninit, +{ if len == 0 { return Some((Default::default(), buf)); } @@ -136,11 +124,8 @@ fn alloc_slice(buf: &mut [u8], len: usize) -> Option<(&mut return None; } let (slice_buf, rest) = buf.split_at_mut(len_in_bytes); - // SAFETY: Alignment and size requirements have been checked in 1) and - // 2) above, respectively. - // Element types are limited by the `TransmuteElement` trait which - // defines requirements for transmutation and is private to this module. - let slice = unsafe { std::slice::from_raw_parts_mut(slice_buf.as_mut_ptr() as *mut T, len) }; + // Bytemuck handles all safety guarantees here. + let slice = bytemuck::try_cast_slice_mut(slice_buf).ok()?; Some((slice, rest)) } diff --git a/write-fonts/Cargo.toml b/write-fonts/Cargo.toml index 346e3ce9f..75bef5672 100644 --- a/write-fonts/Cargo.toml +++ b/write-fonts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "write-fonts" -version = "0.24.0" +version = "0.26.0" edition = "2021" license = "MIT/Apache-2.0" description = "Writing font files." @@ -9,13 +9,13 @@ readme = "README.md" categories = ["text-processing", "parsing", "graphics"] [features] -default = ["dot2"] +default = [] read = [] serde = ["dep:serde", "font-types/serde", "read-fonts/serde"] [dependencies] -font-types = { version = "0.4.3", path = "../font-types" } -read-fonts = { version = "0.17.0", path = "../read-fonts" } +font-types = { version = "0.5.1", path = "../font-types" } +read-fonts = { version = "0.18.0", path = "../read-fonts" } log = "0.4" kurbo = "0.11.0" dot2 = { version = "1.0", optional = true } @@ -26,10 +26,11 @@ indexmap = "2.0" diff = "0.1.12" ansi_term = "0.12.1" font-test-data = { path = "../font-test-data" } -read-fonts = { version = "0.17.0", path = "../read-fonts", features = [ +read-fonts = { version = "0.18.0", path = "../read-fonts", features = [ "codegen_test", ] } -env_logger = "0.10.0" rstest = "0.18.0" -pretty_assertions.workspace = true bincode = "1.0" + +pretty_assertions.workspace = true +env_logger.workspace = true