dpi: make no_std compatible
This commit is contained in:
parent
24e2c6914a
commit
ecc884ac91
8 changed files with 179 additions and 14 deletions
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
|
|
@ -185,6 +185,12 @@ jobs:
|
|||
contains(matrix.platform.name, 'Linux 64bit') &&
|
||||
matrix.toolchain != '1.73'
|
||||
run: cargo test -p dpi
|
||||
|
||||
- name: Check dpi crate (no_std)
|
||||
if: >
|
||||
contains(matrix.platform.name, 'Linux 64bit') &&
|
||||
matrix.toolchain != '1.73'
|
||||
run: cargo check -p dpi --no-default-features
|
||||
|
||||
- name: Build tests
|
||||
if: >
|
||||
|
|
|
|||
|
|
@ -71,3 +71,9 @@ same MSRV policy.
|
|||
### Platform-specific usage
|
||||
|
||||
Check out the [`winit::platform`](https://docs.rs/winit/latest/winit/platform/index.html) module for platform-specific usage.
|
||||
|
||||
### Repository License
|
||||
|
||||
Note that the license in `LICENSE` doesn't apply in full to the DPI package [./dpi](./dpi).
|
||||
Full details can be found in that folder's README.
|
||||
<!-- This doesn't apply to users of the Winit crate, but this is also the repository level README -->
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ Unreleased` header.
|
|||
## Unreleased
|
||||
|
||||
- Added `Insets`, `LogicalInsets` and `PhysicalInsets` types.
|
||||
- Make `no_std` compatible. If you use this functionality, DPI's license has changed.
|
||||
|
||||
## 0.1.1
|
||||
|
||||
|
|
|
|||
|
|
@ -3,16 +3,22 @@ categories = ["gui"]
|
|||
description = "Types for handling UI scaling"
|
||||
edition.workspace = true
|
||||
keywords = ["DPI", "HiDPI", "scale-factor"]
|
||||
license.workspace = true
|
||||
# N.B. This is "AND", because of the imported libm code.
|
||||
license = "Apache-2.0 AND MIT"
|
||||
name = "dpi"
|
||||
repository.workspace = true
|
||||
rust-version.workspace = true
|
||||
version = "0.1.1"
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
|
||||
mint = ["dep:mint"]
|
||||
serde = ["dep:serde"]
|
||||
|
||||
# Access mathematical functions using the standard library implementations
|
||||
std = []
|
||||
|
||||
[dependencies]
|
||||
mint = { workspace = true, optional = true }
|
||||
serde = { workspace = true, optional = true }
|
||||
|
|
|
|||
51
dpi/LICENSE-LIBM-MIT
Normal file
51
dpi/LICENSE-LIBM-MIT
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
rust-lang/libm as a whole is available for use under the MIT license:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
This Rust library contains the following copyrights:
|
||||
|
||||
Copyright (c) 2018 Jorge Aparicio
|
||||
|
||||
Portions of this software are derived from third-party works licensed under
|
||||
terms compatible with the above MIT license:
|
||||
|
||||
* musl libc https://www.musl-libc.org/. This library contains the following
|
||||
copyright:
|
||||
|
||||
Copyright © 2005-2020 Rich Felker, et al.
|
||||
|
||||
* The CORE-MATH project https://core-math.gitlabpages.inria.fr/. CORE-MATH
|
||||
routines are available under the MIT license on a per-file basis.
|
||||
|
||||
The musl libc COPYRIGHT file also includes the following notice relevant to
|
||||
math portions of the library:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Much of the math library code (src/math/* and src/complex/*) is
|
||||
Copyright © 1993,2004 Sun Microsystems or
|
||||
Copyright © 2003-2011 David Schultz or
|
||||
Copyright © 2003-2009 Steven G. Kargl or
|
||||
Copyright © 2003-2009 Bruce D. Evans or
|
||||
Copyright © 2008 Stephen L. Moshier or
|
||||
Copyright © 2017-2018 Arm Limited
|
||||
and labelled as such in comments in the individual source files. All
|
||||
have been licensed under extremely permissive terms.
|
||||
------------------------------------------------------------------------------
|
||||
18
dpi/README.md
Normal file
18
dpi/README.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# DPI
|
||||
|
||||
Full docs can be found on docs.rs.
|
||||
|
||||
## License
|
||||
|
||||
Most of DPI is licensed under the Apache License, Version 2.0 ([LICENSE](LICENSE)).
|
||||
All files except for `src/libm.rs` (and `LICENSE-LIBM-MIT`) are available solely under that license.
|
||||
|
||||
For its `no_std` support, DPI uses code from the [libm](https://crates.io/crates/libm) crate.
|
||||
This is in the `libm.rs` file, and is licensed solely under the MIT Licence ([LICENSE-LIBM-MIT](LICENSE-LIBM-MIT)).
|
||||
That file contains details of all potentially applicable copyright notices.
|
||||
This is feature gated to only be included if you disable the `std` feature, otherwise it will not be compiled into your final binary
|
||||
(and so these license terms will not apply).
|
||||
|
||||
Overall, this means that the license for this crate depends on what features you have enabled.
|
||||
If you enable the `std` feature, then DPI uses only code available under the Apache-2.0 license, and so can be used under the terms of that license.
|
||||
However, if you disable the `std` feature, then both these licenses must be followed to use the crate as a whole.
|
||||
|
|
@ -54,13 +54,25 @@
|
|||
//!
|
||||
//! * `serde`: Enables serialization/deserialization of certain types with [Serde](https://crates.io/crates/serde).
|
||||
//! * `mint`: Enables mint (math interoperability standard types) conversions.
|
||||
//! * `std` (enabled by default): Uses the standard library mathematical functions (normally through
|
||||
//! your target platform's libm). This feature also changes the library's license from `Apache-2.0
|
||||
//! AND MIT` to `APACHE-2.0` (only). For full details, see the package README.
|
||||
//!
|
||||
//! To use this library on a target without the standard library available, you should disable
|
||||
//! default features (thus disabling the `std` feature, with the license consequences thereof).
|
||||
//!
|
||||
//! [points]: https://en.wikipedia.org/wiki/Point_(typography)
|
||||
//! [picas]: https://en.wikipedia.org/wiki/Pica_(typography)
|
||||
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg_hide), doc(cfg_hide(doc, docsrs)))]
|
||||
#![forbid(unsafe_code)]
|
||||
#![cfg_attr(feature = "std", forbid(unsafe_code))]
|
||||
#![no_std]
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
mod libm;
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
extern crate std;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
@ -74,32 +86,32 @@ pub trait Pixel: Copy + Into<f64> {
|
|||
|
||||
impl Pixel for u8 {
|
||||
fn from_f64(f: f64) -> Self {
|
||||
f.round() as u8
|
||||
round(f) as u8
|
||||
}
|
||||
}
|
||||
impl Pixel for u16 {
|
||||
fn from_f64(f: f64) -> Self {
|
||||
f.round() as u16
|
||||
round(f) as u16
|
||||
}
|
||||
}
|
||||
impl Pixel for u32 {
|
||||
fn from_f64(f: f64) -> Self {
|
||||
f.round() as u32
|
||||
round(f) as u32
|
||||
}
|
||||
}
|
||||
impl Pixel for i8 {
|
||||
fn from_f64(f: f64) -> Self {
|
||||
f.round() as i8
|
||||
round(f) as i8
|
||||
}
|
||||
}
|
||||
impl Pixel for i16 {
|
||||
fn from_f64(f: f64) -> Self {
|
||||
f.round() as i16
|
||||
round(f) as i16
|
||||
}
|
||||
}
|
||||
impl Pixel for i32 {
|
||||
fn from_f64(f: f64) -> Self {
|
||||
f.round() as i32
|
||||
round(f) as i32
|
||||
}
|
||||
}
|
||||
impl Pixel for f32 {
|
||||
|
|
@ -113,6 +125,15 @@ impl Pixel for f64 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Round f to the closest integer, rounding away from `0.0`
|
||||
#[inline]
|
||||
fn round(f: f64) -> f64 {
|
||||
#[cfg(feature = "std")]
|
||||
return f.round();
|
||||
#[cfg(not(feature = "std"))]
|
||||
return libm::round(f);
|
||||
}
|
||||
|
||||
/// Checks that the scale factor is a normal positive `f64`.
|
||||
///
|
||||
/// All functions that take a scale factor assert that this will return `true`. If you're sourcing
|
||||
|
|
@ -1270,20 +1291,20 @@ mod tests {
|
|||
// Eat coverage for the Debug impls et al
|
||||
#[test]
|
||||
fn ensure_attrs_do_not_panic() {
|
||||
let _ = format!("{:?}", LogicalPosition::<u32>::default().clone());
|
||||
let _ = std::format!("{:?}", LogicalPosition::<u32>::default().clone());
|
||||
HashSet::new().insert(LogicalPosition::<u32>::default());
|
||||
|
||||
let _ = format!("{:?}", PhysicalPosition::<u32>::default().clone());
|
||||
let _ = std::format!("{:?}", PhysicalPosition::<u32>::default().clone());
|
||||
HashSet::new().insert(PhysicalPosition::<u32>::default());
|
||||
|
||||
let _ = format!("{:?}", LogicalSize::<u32>::default().clone());
|
||||
let _ = std::format!("{:?}", LogicalSize::<u32>::default().clone());
|
||||
HashSet::new().insert(LogicalSize::<u32>::default());
|
||||
|
||||
let _ = format!("{:?}", PhysicalSize::<u32>::default().clone());
|
||||
let _ = std::format!("{:?}", PhysicalSize::<u32>::default().clone());
|
||||
HashSet::new().insert(PhysicalSize::<u32>::default());
|
||||
|
||||
let _ = format!("{:?}", Size::Physical((1, 2).into()).clone());
|
||||
let _ = format!("{:?}", Position::Physical((1, 2).into()).clone());
|
||||
let _ = std::format!("{:?}", Size::Physical((1, 2).into()).clone());
|
||||
let _ = std::format!("{:?}", Position::Physical((1, 2).into()).clone());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
56
dpi/src/libm.rs
Normal file
56
dpi/src/libm.rs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (c) 2018 Jorge Aparicio
|
||||
// Copyright © 2005-2020 Rich Felker, et al.
|
||||
// Copyright © 1993,2004 Sun Microsystems or
|
||||
// Copyright © 2003-2011 David Schultz or
|
||||
// Copyright © 2003-2009 Steven G. Kargl or
|
||||
// Copyright © 2003-2009 Bruce D. Evans or
|
||||
// Copyright © 2008 Stephen L. Moshier or
|
||||
// Copyright © 2017-2018 Arm Limited
|
||||
// SPDX-License-Identifier: MIT
|
||||
// This file is licensed solely under the terms discussed in LICENSE-LIBM-MIT at the crate root.
|
||||
// See the package-level README for full details.
|
||||
|
||||
// Taken from https://github.com/rust-lang/libm/blob/master/src/math/mod.rs#L1
|
||||
macro_rules! force_eval {
|
||||
($e:expr) => {
|
||||
unsafe { ::core::ptr::read_volatile(&$e) }
|
||||
};
|
||||
}
|
||||
|
||||
// Taken from https://github.com/rust-lang/libm/blob/libm-v0.2.11/src/math/round.rs
|
||||
pub(crate) fn round(x: f64) -> f64 {
|
||||
trunc(x + copysign(0.5 - 0.25 * f64::EPSILON, x))
|
||||
}
|
||||
|
||||
// Adapted from: https://github.com/rust-lang/libm/blob/libm-v0.2.11/src/math/trunc.rs#L8-L12
|
||||
#[allow(clippy::needless_late_init /*, reason = "The original libm code uses this style" */)]
|
||||
fn trunc(x: f64) -> f64 {
|
||||
let x1p120 = f64::from_bits(0x4770000000000000); // 0x1p120f === 2 ^ 120
|
||||
|
||||
let mut i: u64 = x.to_bits();
|
||||
let mut e: i64 = ((i >> 52) & 0x7ff) as i64 - 0x3ff + 12;
|
||||
let m: u64;
|
||||
|
||||
if e >= 52 + 12 {
|
||||
return x;
|
||||
}
|
||||
if e < 12 {
|
||||
e = 1;
|
||||
}
|
||||
m = -1i64 as u64 >> e;
|
||||
if (i & m) == 0 {
|
||||
return x;
|
||||
}
|
||||
force_eval!(x + x1p120);
|
||||
i &= !m;
|
||||
f64::from_bits(i)
|
||||
}
|
||||
|
||||
// Taken from https://github.com/rust-lang/libm/blob/libm-v0.2.11/src/math/copysign.rs
|
||||
fn copysign(x: f64, y: f64) -> f64 {
|
||||
let mut ux = x.to_bits();
|
||||
let uy = y.to_bits();
|
||||
ux &= (!0) >> 1;
|
||||
ux |= uy & (1 << 63);
|
||||
f64::from_bits(ux)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue