diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9068122..e6d5677 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,6 +25,16 @@ jobs: - uses: Swatinem/rust-cache@v2 - run: cargo test + build-no-std: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + # Use a target without `std` to make sure we don't link to `std` + target: x86_64-unknown-none + - run: cargo build --target x86_64-unknown-none --no-default-features --features libm + miri: name: Miri runs-on: ubuntu-latest diff --git a/Cargo.toml b/Cargo.toml index 6a23af1..da3a036 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,12 +12,16 @@ homepage = "https://github.com/dfrg/swash" readme = "README.md" [features] -default = ["scale", "render"] +default = ["std", "scale", "render"] + +libm = ["dep:core_maths", "skrifa/libm"] +std = ["skrifa/std"] scale = ["dep:yazi", "dep:zeno"] render = ["scale", "zeno/eval"] [dependencies] -yazi = { version = "0.1.6", optional = true } +core_maths = { version = "0.1.0", optional = true } +yazi = { version = "0.1.6", optional = true, default-features = false } zeno = { version = "0.2.2", optional = true, default-features = false } -skrifa = { version = "0.20.0" } +skrifa = { version = "0.20.0", default-features = false } diff --git a/src/cache.rs b/src/cache.rs index 2ce63dd..0c720ee 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -1,4 +1,5 @@ use super::FontRef; +use alloc::vec::Vec; /// Uniquely generated value for identifying and caching fonts. #[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)] diff --git a/src/internal/mod.rs b/src/internal/mod.rs index db0fb03..05e4f24 100644 --- a/src/internal/mod.rs +++ b/src/internal/mod.rs @@ -79,6 +79,7 @@ pub trait RawFont<'a>: Sized { /// Returns the offset to the table directory. fn offset(&self) -> u32; + #[cfg(feature = "std")] fn dump_tables(&self) -> Option<()> { let base = self.offset() as usize; let b = Bytes::new(self.data()); diff --git a/src/internal/vorg.rs b/src/internal/vorg.rs index a2b2369..1902f5c 100644 --- a/src/internal/vorg.rs +++ b/src/internal/vorg.rs @@ -16,7 +16,7 @@ pub fn origin(data: &[u8], vorg: u32, glyph_id: u16) -> Option { let mut l = 0; let mut h = count; while l < h { - use std::cmp::Ordering::*; + use core::cmp::Ordering::*; let i = (l + h) / 2; let rec = base + 8 + i * 4; let g = b.read::(rec)?; diff --git a/src/lib.rs b/src/lib.rs index c6f04c0..13000ee 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,6 +27,8 @@ the respective modules. #![allow(clippy::needless_lifetimes)] #![allow(clippy::redundant_static_lifetimes)] #![allow(clippy::too_many_arguments)] +#![cfg_attr(not(any(test, feature = "std")), no_std)] +extern crate alloc; #[cfg(feature = "scale")] pub use zeno; diff --git a/src/scale/bitmap/mod.rs b/src/scale/bitmap/mod.rs index bcb7ea3..0272dea 100644 --- a/src/scale/bitmap/mod.rs +++ b/src/scale/bitmap/mod.rs @@ -2,6 +2,10 @@ #![allow(dead_code)] +use alloc::vec::Vec; +#[cfg(feature = "libm")] +use core_maths::CoreFloat; + mod png; /// Decodes a PNG image. @@ -345,7 +349,7 @@ fn sample_dir( } fn sinc(t: f32) -> f32 { - let a = t * std::f32::consts::PI; + let a = t * core::f32::consts::PI; if t == 0. { 1. } else { @@ -403,5 +407,5 @@ fn nearest(_x: f32) -> f32 { } fn gaussian(x: f32, r: f32) -> f32 { - ((2. * std::f32::consts::PI).sqrt() * r).recip() * (-x.powi(2) / (2. * r.powi(2))).exp() + ((2. * core::f32::consts::PI).sqrt() * r).recip() * (-x.powi(2) / (2. * r.powi(2))).exp() } diff --git a/src/scale/bitmap/png.rs b/src/scale/bitmap/png.rs index 44abce5..2339990 100644 --- a/src/scale/bitmap/png.rs +++ b/src/scale/bitmap/png.rs @@ -1,5 +1,7 @@ //! PNG decoder. +use alloc::vec::Vec; + /// PNG magic bytes. pub const SIGNATURE: [u8; 8] = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]; @@ -24,10 +26,12 @@ pub enum DecodeError { CorruptData, /// An "end of file" was reached prematurely. UnexpectedEof, + #[cfg(feature = "std")] /// Underlying IO error. Io(std::io::Error), } +#[cfg(feature = "std")] impl From for DecodeError { fn from(e: std::io::Error) -> Self { Self::Io(e) @@ -328,7 +332,7 @@ fn decode_data( normalize(line, out_line, depth, has_palette, cols, trunc_16)?; E::emit(&state, out_line, target, start, y, w, inc, cols)?; } - std::mem::swap(&mut prev_line, &mut line); + core::mem::swap(&mut prev_line, &mut line); y += row_inc; } if pass == 6 { @@ -348,7 +352,7 @@ fn decode_data( let ty = *source.get(0)?; defilter(ty, source.get(1..)?, line, prev_line, bwidth)?; E::emit(&state, line, target, 0, y, w, 1, w)?; - std::mem::swap(&mut prev_line, &mut line); + core::mem::swap(&mut prev_line, &mut line); } } else { for y in 0..h { @@ -359,7 +363,7 @@ fn decode_data( defilter(ty, source.get(1..)?, line, prev_line, bwidth)?; normalize(line, out_line, depth, has_palette, w, trunc_16)?; E::emit(&state, out_line, target, 0, y, w, 1, w)?; - std::mem::swap(&mut prev_line, &mut line); + core::mem::swap(&mut prev_line, &mut line); } } Some(()) diff --git a/src/scale/hinting_cache.rs b/src/scale/hinting_cache.rs index 83e0461..807ba72 100644 --- a/src/scale/hinting_cache.rs +++ b/src/scale/hinting_cache.rs @@ -1,9 +1,11 @@ +use alloc::vec::Vec; use skrifa::{ instance::{NormalizedCoord, Size}, outline::{ HintingInstance, HintingMode, LcdLayout, OutlineGlyphCollection, OutlineGlyphFormat, }, }; + /// We keep this small to enable a simple LRU cache with a linear /// search. Regenerating hinting data is low to medium cost so it's fine /// to redo it occasionally. diff --git a/src/scale/image.rs b/src/scale/image.rs index cb09dbd..d5b18ab 100644 --- a/src/scale/image.rs +++ b/src/scale/image.rs @@ -3,6 +3,7 @@ Rendered glyph image. */ use super::Source; +use alloc::vec::Vec; use zeno::Placement; /// Content of a scaled glyph image. diff --git a/src/scale/mod.rs b/src/scale/mod.rs index e022ea6..49116e9 100644 --- a/src/scale/mod.rs +++ b/src/scale/mod.rs @@ -232,7 +232,10 @@ use skrifa::{ use super::internal; use super::{cache::FontCache, setting::Setting, FontRef, GlyphId, NormalizedCoord}; +use alloc::vec::Vec; use core::borrow::Borrow; +#[cfg(feature = "libm")] +use core_maths::CoreFloat; use proxy::*; #[cfg(feature = "render")] use zeno::{Format, Mask, Origin, Scratch, Style, Transform, Vector}; diff --git a/src/scale/outline.rs b/src/scale/outline.rs index 055dd77..c2986ef 100644 --- a/src/scale/outline.rs +++ b/src/scale/outline.rs @@ -2,6 +2,7 @@ Glyph outline. */ +use alloc::vec::Vec; use zeno::{Bounds, PathData, Point, Transform, Verb}; /// Scaled glyph outline represented as a collection of layers and a sequence diff --git a/src/shape/at.rs b/src/shape/at.rs index 90e8b2f..0117ff2 100644 --- a/src/shape/at.rs +++ b/src/shape/at.rs @@ -1,6 +1,8 @@ use super::internal::{at::*, *}; use super::{buffer::*, feature::*, Direction}; use crate::text::Script; + +use alloc::vec::Vec; use core::ops::Range; pub type FeatureBit = u16; diff --git a/src/shape/buffer.rs b/src/shape/buffer.rs index 7ff7fc6..daa1baa 100644 --- a/src/shape/buffer.rs +++ b/src/shape/buffer.rs @@ -4,6 +4,8 @@ use crate::text::{ cluster::{Char, CharCluster, ClusterInfo, ShapeClass, SourceRange, MAX_CLUSTER_SIZE}, JoiningType, }; + +use alloc::vec::Vec; use core::ops::Range; // Glyph flags. diff --git a/src/shape/cache.rs b/src/shape/cache.rs index fa6b31a..19d8677 100644 --- a/src/shape/cache.rs +++ b/src/shape/cache.rs @@ -3,6 +3,8 @@ use super::engine::EngineMetadata; use super::internal::var::Fvar; use crate::{charmap::CharmapProxy, metrics::MetricsProxy, FontRef}; +use alloc::vec::Vec; + pub type Epoch = u64; pub struct FontEntry { diff --git a/src/shape/engine.rs b/src/shape/engine.rs index f1f614d..ded4be4 100644 --- a/src/shape/engine.rs +++ b/src/shape/engine.rs @@ -5,6 +5,7 @@ use super::internal::{self, at::Gdef, raw_tag, Bytes, RawFont, RawTag}; use crate::font::FontRef; use crate::text::{Language, Script}; +use alloc::vec::Vec; use core::ops::Range; /// Shaping engine that handles the various methods available in diff --git a/src/shape/mod.rs b/src/shape/mod.rs index 56bd348..91753a9 100644 --- a/src/shape/mod.rs +++ b/src/shape/mod.rs @@ -264,6 +264,7 @@ use crate::text::{ cluster::{CharCluster, Parser, ShapeClass, Token}, Language, Script, }; +use alloc::vec::Vec; use at::{FeatureMask, FeatureStore, FeatureStoreBuilder}; use buffer::*; use cache::{FeatureCache, FontEntry}; diff --git a/src/strike.rs b/src/strike.rs index cb681c8..33facac 100644 --- a/src/strike.rs +++ b/src/strike.rs @@ -3,6 +3,11 @@ use super::internal::*; use super::{FontRef, GlyphId}; +#[cfg(feature = "scale")] +use alloc::vec::Vec; +#[cfg(all(feature = "libm", feature = "scale"))] +use core_maths::CoreFloat; + /// Proxy for rematerializing strike collections. #[derive(Copy, Clone)] pub struct BitmapStrikesProxy { diff --git a/src/string.rs b/src/string.rs index e32ccaa..78733c4 100644 --- a/src/string.rs +++ b/src/string.rs @@ -2,7 +2,7 @@ Localized names and other metadata. */ -use std::fmt::Write; +use core::fmt::Write; use super::internal::*; use super::FontRef;