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

Minor improvements to layout API #145

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
100 changes: 98 additions & 2 deletions src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,15 @@ pub struct LayoutSettings {
pub wrap_hard_breaks: bool,
}

impl Default for LayoutSettings {
fn default() -> LayoutSettings {
impl LayoutSettings {
/// Instatiates a builder for the LayoutSettings allowing for easier configuration.
pub const fn builder() -> LayoutSettingsBuilder {
LayoutSettingsBuilder::new()
}

/// Const version of the default function allowing, required for implementing the const
/// LayoutSettingsBuilder.
const fn const_default() -> Self {
LayoutSettings {
x: 0.0,
y: 0.0,
Expand All @@ -102,6 +109,87 @@ impl Default for LayoutSettings {
}
}

impl Default for LayoutSettings {
fn default() -> LayoutSettings {
Self::const_default()
}
}

/// Builder helper for the construction of LayoutSettings.
/// When instatianting the builder a default LayoutSettings is used, by calling the various
/// configuration methods you can change the values, the methods consume an instance of the builder
/// and return a new one with the setting modified allowing the chaining of methods.
pub struct LayoutSettingsBuilder {
/// The layout settings that are being configured
value: LayoutSettings
}

impl LayoutSettingsBuilder {
/// Instatiates a new LayoutSettingsBuilder
pub const fn new() -> Self {
let settings = LayoutSettings::const_default();
Self {
value: settings
}
}
/// The leftmost boundary of the text region.
pub const fn x(mut self, x: f32) -> Self {
self.value.x = x;
self
}
/// The topmost boundary of the text region.
pub const fn y(mut self, y: f32) -> Self {
self.value.y = y;
self
}
/// An optional rightmost boundary on the text region. A line of text that exceeds the
/// max_width is wrapped to the line below. If the width of a glyph is larger than the
/// max_width, the glyph will overflow past the max_width. The application is responsible for
/// handling the overflow.
pub const fn max_width(mut self, max_width: Option<f32>) -> Self {
self.value.max_width = max_width;
self
}
/// An optional bottom boundary on the text region. This is used for positioning the
/// vertical_align option. Text that exceeds the defined max_height will overflow past it. The
/// application is responsible for handling the overflow.
pub const fn max_height(mut self, max_height: Option<f32>) -> Self {
self.value.max_height = max_height;
self
}
/// The default is Left. This option does nothing if the max_width isn't set.
pub const fn horizontal_align(mut self, horizontal_align: HorizontalAlign) -> Self {
self.value.horizontal_align = horizontal_align;
self
}
/// The default is Top. This option does nothing if the max_height isn't set.
pub const fn vertical_align(mut self, vertical_align: VerticalAlign) -> Self {
self.value.vertical_align = vertical_align;
self
}
/// The height of each line as a multiplier of the default.
pub const fn line_height(mut self, line_height: f32) -> Self {
self.value.line_height = line_height;
self
}
/// The default is Word. Wrap style is a hint for how strings of text should be wrapped to the
/// next line. Line wrapping can happen when the max width/height is reached.
pub const fn wrap_style(mut self, wrap_style: WrapStyle) -> Self {
self.value.wrap_style = wrap_style;
self
}
/// The default is true. This option enables hard breaks, like new line characters, to
/// prematurely wrap lines. If false, hard breaks will not prematurely create a new line.
pub const fn wrap_hard_breaks(mut self, wrap_hard_breaks: bool) -> Self {
self.value.wrap_hard_breaks = wrap_hard_breaks;
self
}
/// Creates LayoutSettings instance from the parameters set in the builder.
pub const fn build(self) -> LayoutSettings {
self.value
}
}

/// Configuration for rasterizing a glyph. This struct is also a hashable key that can be used to
/// uniquely identify a rasterized glyph for applications that want to cache glyphs.
#[derive(Debug, Copy, Clone)]
Expand Down Expand Up @@ -304,9 +392,17 @@ pub struct Layout<U: Copy + Clone = ()> {
impl<'a, U: Copy + Clone> Layout<U> {
/// Creates a layout instance. This requires the direction that the Y coordinate increases in.
/// Layout needs to be aware of your coordinate system to place the glyphs correctly.
/// If you want to construct a layout with settings you can use the Layout::with_settings
/// function.
pub fn new(coordinate_system: CoordinateSystem) -> Layout<U> {
let settings = LayoutSettings::default();
Self::with_settings(coordinate_system, settings)
}

/// Creates a layout instance with settings. This requires the direction that the Y coordinate
/// increases in.
/// Layout needs to be aware of your coordinate system to place the glyphs correctly.
pub fn with_settings(coordinate_system: CoordinateSystem, settings: LayoutSettings) -> Layout<U> {
let mut layout = Layout {
flip: coordinate_system == CoordinateSystem::PositiveYDown,
x: 0.0,
Expand Down