Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pixel ratio config, document Style/Layout as logical/physical pixels #478

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 20 additions & 18 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,31 @@

### Breaking

Many APIs have been renamed to replace `points` or `Points` with `length` or `Length`.
This new name better describes one-dimentional measure of space in some unspecified unit
which is often unrelated to the PostScript point or the CSS `pt` unit.
- Previously, absolute length values in `Style` and `Layout` were measured in some unspecified abstract unit whose meaning was chosen by Taffy users. Instead, they are now redefinied so that `Style` uses "logical pixel" which correspond to CSS `px`, while `Layout` contains "output pixels" which are recommended to use as device pixels. A new pixel ratio configuration controls the relationship between these two units. See `Taffy::set_pixel_ratio` documentation for details.

This also removes a misleading similarity with the 2D `Point`,
whose components can have any unit and are not even necessarily absolute lengths.
- Many APIs have been renamed to replace `points` or `Points` with `length` or `Length`.
The previous name suggested the PostScript point or the CSS `pt` unit,
but per the above these values are now measured in CSS `px`.

Example usage change:
This also removes a misleading similarity with the 2D `Point` struct,
whose components can have any unit and are not even necessarily absolute lengths.

```diff
use taffy::prelude::*;
Example usage change:

// …
```diff
use taffy::prelude::*;

let header_node = taffy
.new_leaf(
Style {
- size: Size { width: points(800.0), height: points(100.0) },
+ size: Size { width: length(800.0), height: length(100.0) },
..Default::default()
},
).unwrap();
```
// …

let header_node = taffy
.new_leaf(
Style {
- size: Size { width: points(800.0), height: points(100.0) },
+ size: Size { width: length(800.0), height: length(100.0) },
..Default::default()
},
).unwrap();
```

### Removed

Expand Down
17 changes: 11 additions & 6 deletions src/style/dimension.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Style types for representing lengths / sizes

use crate::geometry::{Rect, Size};
#[cfg(doc)]
use crate::prelude::Taffy;
use crate::style_helpers::{FromLength, FromPercent, TaffyAuto, TaffyMaxContent, TaffyMinContent, TaffyZero};
use crate::util::sys::abs;

Expand All @@ -10,8 +12,9 @@ use crate::util::sys::abs;
#[derive(Copy, Clone, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum LengthPercentage {
/// An absolute length in some abstract units. Users of Taffy may define what they correspond
/// to in their application (pixels, logical pixels, mm, etc) as they see fit.
/// An absolute length in CSS `px` units a.k.a. logical pixels.
///
/// See [`Taffy::set_pixel_ratio`].
Length(f32),
/// The dimension is stored in percentage relative to the parent item.
Percent(f32),
Expand All @@ -36,8 +39,9 @@ impl FromPercent for LengthPercentage {
#[derive(Copy, Clone, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum LengthPercentageAuto {
/// An absolute length in some abstract units. Users of Taffy may define what they correspond
/// to in their application (pixels, logical pixels, mm, etc) as they see fit.
/// An absolute length in CSS `px` units a.k.a. logical pixels.
///
/// See [`Taffy::set_pixel_ratio`].
Length(f32),
/// The dimension is stored in percentage relative to the parent item.
Percent(f32),
Expand Down Expand Up @@ -90,8 +94,9 @@ impl LengthPercentageAuto {
#[derive(Copy, Clone, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Dimension {
/// An absolute length in some abstract units. Users of Taffy may define what they correspond
/// to in their application (pixels, logical pixels, mm, etc) as they see fit.
/// An absolute length in CSS `px` units a.k.a. logical pixels.
///
/// See [`Taffy::set_pixel_ratio`].
Length(f32),
/// The dimension is stored in percentage relative to the parent item.
Percent(f32),
Expand Down
13 changes: 11 additions & 2 deletions src/tree/layout.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Final data structures that represent the high-level UI layout

use crate::geometry::{Point, Size};
#[cfg(doc)]
use crate::prelude::Taffy;

/// Whether we are performing a full layout, or we merely need to size the node
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -31,6 +33,7 @@ pub enum SizingMode {
pub struct SizeAndBaselines {
/// The size of the node
pub size: Size<f32>,

/// The first baseline of the node in each dimension, if any
pub first_baselines: Point<Option<f32>>,
}
Expand All @@ -49,9 +52,15 @@ pub struct Layout {
/// Nodes with a higher order should be rendered on top of those with a lower order.
/// This is effectively a topological sort of each tree.
pub order: u32,
/// The width and height of the node

/// The width and height of the node, in output pixels.
///
/// See [`Taffy::set_pixel_ratio`].
pub size: Size<f32>,
/// The bottom-left corner of the node

/// The bottom-left corner of the node, in output pixels.
///
/// See [`Taffy::set_pixel_ratio`].
pub location: Point<f32>,
}

Expand Down
34 changes: 31 additions & 3 deletions src/tree/taffy_tree/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@ use super::{TaffyError, TaffyResult};
pub(crate) struct TaffyConfig {
/// Whether to round layout values
pub(crate) use_rounding: bool,

/// Number of output length units per input length units.
/// See `pixel_ratio` and `set_pixel_ratio` methods.
pub(crate) pixel_ratio: f32,
}

impl Default for TaffyConfig {
fn default() -> Self {
Self { use_rounding: true }
Self { use_rounding: true, pixel_ratio: 1.0 }
}
}

Expand Down Expand Up @@ -144,16 +148,40 @@ impl Taffy {
}
}

/// Enable rounding of layout values. Rounding is enabled by default.
/// Enable rounding of sizes and locations in [`Layout`].
/// Rounding is enabled by default.
pub fn enable_rounding(&mut self) {
self.config.use_rounding = true;
}

/// Disable rounding of layout values. Rounding is enabled by default.
/// Disable rounding of sizes and locations in [`Layout`].
/// Rounding is enabled by default.
pub fn disable_rounding(&mut self) {
self.config.use_rounding = false;
}

/// Returns the current pixel ratio. See [`set_pixel_ratio`][Self::set_pixel_ratio].
pub fn pixel_ratio(&self) -> f32 {
self.config.pixel_ratio
}

/// Sets the pixel ratio: the number of output pixels per logical pixels.
///
/// Absolute length values in [`style`][crate::style] are measured in **logical pixels**
/// and correspond to CSS the `px` unit.
///
/// Sizes and locations in [`Layout`] are measured in output pixels.
/// When rendering to screen media, it is recommended to use them as **physical pixels**
/// a.k.a. [device pixels](https://drafts.csswg.org/css-values/#device-pixel)
/// and set the pixel ratio to the whole number that makes a logical pixel best approximate
/// the [reference pixel](https://drafts.csswg.org/css-values/#reference-pixel),
/// (the visual angle of one pixel on a 96dpi device held at arm’s length).
///
/// The default is 1.0.
pub fn set_pixel_ratio(&mut self, new_pixel_ratio: f32) {
self.config.pixel_ratio = new_pixel_ratio
}

/// Creates and adds a new unattached leaf node to the tree, and returns the node of the new node
pub fn new_leaf(&mut self, layout: Style) -> TaffyResult<NodeId> {
let id = self.nodes.insert(NodeData::new(layout));
Expand Down