Skip to content

Commit

Permalink
feat: text_height attribute to control the height behavior of text (#…
Browse files Browse the repository at this point in the history
…976)

* feat: `text_height` attribute to control the height behavior of text

* update mocked apis

* clean up
  • Loading branch information
marc2332 authored Oct 12, 2024
1 parent 70403bc commit 66523af
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 7 deletions.
1 change: 1 addition & 0 deletions crates/components/src/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ pub fn ButtonBase(
corner_radius: "{corner_radius}",
background: "{background}",
text_align: "center",
text_height: "disable-least-ascent",
main_align: "center",
cross_align: "center",
{&children}
Expand Down
1 change: 1 addition & 0 deletions crates/components/src/progress_bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ pub fn ProgressBar(
width: "100%",
color: "{color}",
max_lines: "1",
text_height: "disable-least-ascent",
"{progress.floor()}%"
}
}
Expand Down
4 changes: 3 additions & 1 deletion crates/core/src/render/utils/label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ pub fn create_label(
paragraph_style.set_text_align(font_style.text_align);
paragraph_style.set_max_lines(font_style.max_lines);
paragraph_style.set_replace_tab_characters(true);
paragraph_style.set_text_height_behavior(font_style.text_height);

if let Some(ellipsis) = font_style.text_overflow.get_ellipsis() {
paragraph_style.set_ellipsis(ellipsis);
}

let text_style = font_style.text_style(default_font_family, scale_factor);
let text_style =
font_style.text_style(default_font_family, scale_factor, font_style.text_height);
paragraph_style.set_text_style(&text_style);

let mut paragraph_builder = ParagraphBuilder::new(&paragraph_style, font_collection);
Expand Down
12 changes: 9 additions & 3 deletions crates/core/src/render/utils/paragraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@ pub fn create_paragraph(
paragraph_style.set_text_align(font_style.text_align);
paragraph_style.set_max_lines(font_style.max_lines);
paragraph_style.set_replace_tab_characters(true);
paragraph_style.set_text_height_behavior(font_style.text_height);

if let Some(ellipsis) = font_style.text_overflow.get_ellipsis() {
paragraph_style.set_ellipsis(ellipsis);
}

let mut paragraph_builder = ParagraphBuilder::new(&paragraph_style, font_collection);

let text_style = font_style.text_style(default_font_family, scale_factor);
let text_style =
font_style.text_style(default_font_family, scale_factor, font_style.text_height);
paragraph_builder.push_style(&text_style);

for text_span in node.children() {
Expand All @@ -52,8 +54,12 @@ pub fn create_paragraph(
let text_nodes = text_span.children();
let text_node = *text_nodes.first().unwrap();
let text_node_type = &*text_node.node_type();
let font_style = text_span.get::<FontStyleState>().unwrap();
let text_style = font_style.text_style(default_font_family, scale_factor);
let text_font_style = text_span.get::<FontStyleState>().unwrap();
let text_style = text_font_style.text_style(
default_font_family,
scale_factor,
font_style.text_height,
);
paragraph_builder.push_style(&text_style);

if let NodeType::Text(text) = text_node_type {
Expand Down
22 changes: 22 additions & 0 deletions crates/elements/src/_docs/attributes/text_height.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Specify the text height behavior.

Accepted values:

- `disable-all` (default)
- `all`
- `disable-first-ascent`
- `disable-least-ascent`

### Example

```rust, no_run
# use freya::prelude::*;
fn app() -> Element {
rsx!(
label {
text_height: "disable-all",
"Hello, World!"
}
)
}
```
6 changes: 6 additions & 0 deletions crates/elements/src/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ builder_constructors! {
letter_spacing: String,
#[doc = include_str!("_docs/attributes/word_spacing.md")]
word_spacing: String,
#[doc = include_str!("_docs/attributes/text_height.md")]
text_height: String,

// Transform
#[doc = include_str!("_docs/attributes/rotate.md")]
Expand Down Expand Up @@ -407,6 +409,8 @@ builder_constructors! {
letter_spacing: String,
#[doc = include_str!("_docs/attributes/word_spacing.md")]
word_spacing: String,
#[doc = include_str!("_docs/attributes/text_height.md")]
text_height: String,

// Transform
#[doc = include_str!("_docs/attributes/rotate.md")]
Expand Down Expand Up @@ -563,6 +567,8 @@ builder_constructors! {
letter_spacing: String,
#[doc = include_str!("_docs/attributes/word_spacing.md")]
word_spacing: String,
#[doc = include_str!("_docs/attributes/text_height.md")]
text_height: String,

// Transform
#[doc = include_str!("_docs/attributes/rotate.md")]
Expand Down
14 changes: 12 additions & 2 deletions crates/engine/src/mocked.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,18 @@ impl TextStyle {
pub fn set_placeholder(&mut self) -> &mut Self {
unimplemented!("This is mocked")
}

pub fn set_height_behavior(&mut self, behavior: TextHeightBehavior) {
unimplemented!("This is mocked")
}
}

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum TextHeightBehavior {
All = 0,
DisableFirstAscent = 1,
DisableLastDescent = 2,
DisableAll = 3,
}

pub struct Typeface;
Expand Down Expand Up @@ -988,8 +1000,6 @@ impl From<&FontCollection> for FontCollection {

pub struct StrutStyle;

pub struct TextHeightBehavior;

#[repr(i32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum TextDirection {
Expand Down
2 changes: 2 additions & 0 deletions crates/native-core/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub enum AttributeName {
DecorationColor,
DecorationStyle,
TextOverflow,
TextHeight,
Rotate,
Overflow,
Margin,
Expand Down Expand Up @@ -253,6 +254,7 @@ impl FromStr for AttributeName {
"decoration_color" => Ok(AttributeName::DecorationColor),
"decoration_style" => Ok(AttributeName::DecorationStyle),
"text_overflow" => Ok(AttributeName::TextOverflow),
"text_height" => Ok(AttributeName::TextHeight),
"rotate" => Ok(AttributeName::Rotate),
"overflow" => Ok(AttributeName::Overflow),
"margin" => Ok(AttributeName::Margin),
Expand Down
24 changes: 23 additions & 1 deletion crates/state/src/font_style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use crate::{
ExtSplit,
Parse,
ParseAttribute,
TextHeight,
TextOverflow,
};

Expand All @@ -45,10 +46,16 @@ pub struct FontStyleState {
pub text_align: TextAlign,
pub max_lines: Option<usize>,
pub text_overflow: TextOverflow,
pub text_height: TextHeightBehavior,
}

impl FontStyleState {
pub fn text_style(&self, default_font_family: &[String], scale_factor: f32) -> TextStyle {
pub fn text_style(
&self,
default_font_family: &[String],
scale_factor: f32,
paragraph_text_height: TextHeightBehavior,
) -> TextStyle {
let mut text_style = TextStyle::new();
let mut font_family = self.font_family.clone();

Expand All @@ -66,6 +73,11 @@ impl FontStyleState {
.set_word_spacing(self.word_spacing)
.set_letter_spacing(self.letter_spacing);

if paragraph_text_height.needs_custom_height() {
text_style.set_height_override(true);
text_style.set_half_leading(true);
}

if let Some(line_height) = self.line_height {
text_style.set_height_override(true).set_height(line_height);
}
Expand Down Expand Up @@ -102,6 +114,7 @@ impl Default for FontStyleState {
text_align: TextAlign::default(),
max_lines: None,
text_overflow: TextOverflow::default(),
text_height: TextHeightBehavior::DisableAll,
}
}
}
Expand Down Expand Up @@ -234,6 +247,14 @@ impl ParseAttribute for FontStyleState {
}
}
}
AttributeName::TextHeight => {
let value = attr.value.as_text();
if let Some(value) = value {
if let Ok(text_height) = TextHeightBehavior::parse(value) {
self.text_height = text_height;
}
}
}
_ => {}
}

Expand Down Expand Up @@ -267,6 +288,7 @@ impl State<CustomAttributeValues> for FontStyleState {
AttributeName::DecorationColor,
AttributeName::DecorationStyle,
AttributeName::TextOverflow,
AttributeName::TextHeight,
]));

fn update<'a>(
Expand Down
2 changes: 2 additions & 0 deletions crates/state/src/values/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod overflow;
mod position;
mod shadow;
mod size;
mod text_height;
mod text_shadow;

pub use border::*;
Expand All @@ -30,3 +31,4 @@ pub use highlight::*;
pub use overflow::*;
pub use shadow::*;
pub use size::*;
pub use text_height::*;
31 changes: 31 additions & 0 deletions crates/state/src/values/text_height.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use freya_engine::prelude::*;

use crate::{
Parse,
ParseError,
};

impl Parse for TextHeightBehavior {
fn parse(value: &str) -> Result<Self, ParseError> {
match value {
"all" => Ok(TextHeightBehavior::All),
"disable-first-ascent" => Ok(TextHeightBehavior::DisableFirstAscent),
"disable-least-ascent" => Ok(TextHeightBehavior::DisableLastDescent),
"disable-all" => Ok(TextHeightBehavior::DisableAll),
_ => Err(ParseError),
}
}
}

pub trait TextHeight {
fn needs_custom_height(&self) -> bool;
}

impl TextHeight for TextHeightBehavior {
fn needs_custom_height(&self) -> bool {
matches!(
self,
Self::All | Self::DisableFirstAscent | Self::DisableLastDescent
)
}
}

0 comments on commit 66523af

Please sign in to comment.