Skip to content

Commit

Permalink
Add a feature for enabling compilation for no_std
Browse files Browse the repository at this point in the history
This commit adds two new features: "std" (which is enabled by default)
and "libm". When "std" is enabled, floating point intrinsics are used
from libstd. When "libm" is enabled, it brings in the pure Rust libm
implementation to handle floating point instrinsics in software mode.

By disabling the "std" feature and enabling "libm", this crate can be
effectively used on no_std platforms, like embedded systems.

This is a breaking change, as it adds an "std" default feature that,
when disabled without enabling "libm", causes a compile error. Users who
are currently using zeno with "default-features = false" without
preparation will have their compilation break.

Rel: dfrg/swash#4

Signed-off-by: John Nunley <[email protected]>
  • Loading branch information
notgull committed Sep 5, 2023
1 parent a1928c8 commit cf36dbb
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 2 deletions.
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ homepage = "https://github.com/dfrg/zeno"
readme = "README.md"

[dependencies]
libm = { version = "0.2.7", default-features = false, optional = true }

[features]
default = ["eval"]
default = ["eval", "std"]
eval = []
std = []

2 changes: 2 additions & 0 deletions src/geometry.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Geometric primitives.

use crate::F32Ext;

use core::borrow::Borrow;
use core::ops::{Add, Div, Mul, Sub};

Expand Down
79 changes: 78 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,13 @@ constructors are provided which take a scratch instance as an argument and
redirect all transient allocations to the reusable storage.
*/

#![cfg_attr(not(feature = "std"), no_std)]

#[cfg(not(any(feature = "std", feature = "libm")))]
compile_error! { "Either the std or libm feature must be enabled" }

extern crate alloc;

mod command;
mod geometry;
#[cfg(feature = "eval")]
Expand Down Expand Up @@ -301,7 +308,77 @@ pub use svg_parser::validate_svg;
#[cfg(feature = "eval")]
pub use traversal::{Vertex, Vertices, Walk};

macro_rules! define_f32_ext {
($($fpname:ident($($argname:ident: $argty:ty),*) -> $ret:ty => $libmname:ident;)*) => {
/// An extension trait defining floating point operations.
trait F32Ext {
$(
fn $fpname(self, $($argname:$argty),*) -> $ret;
)*
}

#[cfg(feature = "std")]
impl F32Ext for f32 {
$(
fn $fpname(self, $($argname:$argty),*) -> $ret {
// This instrinsic is natively defined in libstd.
f32::$fpname(self, $($argname),*)
}
)*
}

#[cfg(all(not(feature = "std"), feature = "libm"))]
impl F32Ext for f32 {
$(
fn $fpname(self, $($argname:$argty),*) -> $ret {
// Use the libm version of this instrinsic.
<$ret>::libm_cvt(libm::$libmname(
self.into(),
$(($argname).into()),*
) as _)
}
)*
}
}
}

define_f32_ext! {
abs() -> f32 => fabs;
acos() -> f32 => acos;
atan2(x:f32) -> f32 => atan2;
ceil() -> f32 => ceil;
cos() -> f32 => cos;
floor() -> f32 => floor;
sin_cos() -> (f32, f32) => sincos;
sqrt() -> f32 => sqrt;
powf(x:f32) -> f32 => powf;
powi(x:i32) -> f32 => pow;
tan() -> f32 => tan;
}

#[cfg(all(not(feature = "std"), feature = "libm"))]
trait LibmCvt {
type Input;
fn libm_cvt(input: Self::Input) -> Self;
}

#[cfg(all(not(feature = "std"), feature = "libm"))]
impl LibmCvt for f32 {
type Input = f64;
fn libm_cvt(input: f64) -> f32 {
input as f32
}
}

#[cfg(all(not(feature = "std"), feature = "libm"))]
impl LibmCvt for (f32, f32) {
type Input = (f64, f64);
fn libm_cvt((a, b): (f64, f64)) -> (f32, f32) {
(a as f32, b as f32)
}
}

// Prep for no_std support when core supports FP intrinsics.
mod lib {
pub use std::vec::Vec;
pub use alloc::vec::Vec;
}
1 change: 1 addition & 0 deletions src/path_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use super::command::Command;
use super::geometry::{Angle, BoundsBuilder, Point, Transform};
use super::F32Ext;

use crate::lib::Vec;

Expand Down
1 change: 1 addition & 0 deletions src/segment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use super::command::Command;
use super::geometry::*;
use super::F32Ext;

use core::borrow::Borrow;

Expand Down

0 comments on commit cf36dbb

Please sign in to comment.