Skip to content
Merged
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
4 changes: 3 additions & 1 deletion parley/src/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ use parley_engine::break_overrides::LineBreakOverrideFn;

use parley_engine::AnalysisOptions;

use parlance::WordBreak;
use parlance::{BaseDirection, WordBreak};

pub(crate) fn analyze_text<B: Brush>(
lcx: &mut LayoutContext<B>,
text: &str,
base_direction: BaseDirection,
line_break_override: Option<&LineBreakOverrideFn>,
) {
let text = if text.is_empty() { " " } else { text };
Expand All @@ -26,6 +27,7 @@ pub(crate) fn analyze_text<B: Brush>(
}));

let options = AnalysisOptions {
base_direction,
word_break: &lcx.word_break,
line_break_override,
};
Expand Down
136 changes: 76 additions & 60 deletions parley/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,46 @@ use super::layout::Layout;

use alloc::string::String;
use core::ops::{Bound, Range, RangeBounds};
use parlance::BaseDirection;
use parley_engine::break_overrides::LineBreakOverrideFn;

use crate::InlineBoxKind;
use crate::inline_box::InlineBox;
use crate::resolve::{ResolvedStyle, StyleRun, tree::ItemKind};

#[derive(Clone, Copy)]
pub(crate) struct BuilderOptions<'a> {
scale: f32,
quantize: bool,
base_direction: BaseDirection,
line_break_override: Option<&'a LineBreakOverrideFn>,
}

impl BuilderOptions<'_> {
pub(crate) fn new(scale: f32, quantize: bool) -> Self {
Self {
scale,
quantize,
base_direction: BaseDirection::Auto,
line_break_override: None,
}
}
}

/// Builder for constructing a text layout with ranged attributes.
#[must_use]
pub struct RangedBuilder<'a, B: Brush> {
pub(crate) scale: f32,
pub(crate) quantize: bool,
pub(crate) options: BuilderOptions<'a>,
pub(crate) lcx: &'a mut LayoutContext<B>,
pub(crate) fcx: &'a mut FontContext,
pub(crate) line_break_override: Option<&'a LineBreakOverrideFn>,
}

impl<'b, B: Brush> RangedBuilder<'b, B> {
pub fn push_default<'a>(&mut self, property: impl Into<StyleProperty<'a, B>>) {
let resolved = self
.lcx
.rcx
.resolve_property(self.fcx, &property.into(), self.scale);
let resolved =
self.lcx
.rcx
.resolve_property(self.fcx, &property.into(), self.options.scale);
self.lcx.ranged_style_builder.push_default(resolved);
}

Expand All @@ -41,22 +59,29 @@ impl<'b, B: Brush> RangedBuilder<'b, B> {
property: impl Into<StyleProperty<'a, B>>,
range: impl RangeBounds<usize>,
) {
let resolved = self
.lcx
.rcx
.resolve_property(self.fcx, &property.into(), self.scale);
let resolved =
self.lcx
.rcx
.resolve_property(self.fcx, &property.into(), self.options.scale);
self.lcx.ranged_style_builder.push(resolved, range);
}

pub fn push_inline_box(&mut self, inline_box: InlineBox) {
self.lcx.inline_boxes.push(inline_box);
}

/// Sets the paragraph's base direction.
///
/// The default is [`BaseDirection::Auto`], which infers the direction from the text.
pub fn set_base_direction(&mut self, base_direction: BaseDirection) {
self.options.base_direction = base_direction;
}

/// Set the callback which will be called as a first provider of line breaking decisions.
///
/// See [`LineBreakOverrideFn`] for more details.
pub fn set_line_break_override(&mut self, overrides: Option<&'b LineBreakOverrideFn>) {
self.line_break_override = overrides;
self.options.line_break_override = overrides;
}

pub fn build_into(self, layout: &mut Layout<B>, text: impl AsRef<str>) {
Expand All @@ -66,15 +91,7 @@ impl<'b, B: Brush> RangedBuilder<'b, B> {
.finish(&mut self.lcx.style_table, &mut self.lcx.style_runs);

// Call generic layout builder method
build_into_layout(
layout,
self.scale,
self.quantize,
text.as_ref(),
self.lcx,
self.fcx,
self.line_break_override,
);
build_into_layout(layout, text.as_ref(), self.lcx, self.fcx, self.options);
}

pub fn build(self, text: impl AsRef<str>) -> Layout<B> {
Expand All @@ -88,13 +105,11 @@ impl<'b, B: Brush> RangedBuilder<'b, B> {
/// indexed style runs.
#[must_use]
pub struct StyleRunBuilder<'a, B: Brush> {
pub(crate) scale: f32,
pub(crate) quantize: bool,
pub(crate) options: BuilderOptions<'a>,
pub(crate) len: usize,
pub(crate) lcx: &'a mut LayoutContext<B>,
pub(crate) fcx: &'a mut FontContext,
pub(crate) cursor: usize,
pub(crate) line_break_override: Option<&'a LineBreakOverrideFn>,
}

impl<'b, B: Brush> StyleRunBuilder<'b, B> {
Expand All @@ -117,7 +132,7 @@ impl<'b, B: Brush> StyleRunBuilder<'b, B> {
let resolved = self
.lcx
.rcx
.resolve_entire_style_set(self.fcx, &style, self.scale);
.resolve_entire_style_set(self.fcx, &style, self.options.scale);
let style_index = self.lcx.style_table.len();
assert!(style_index <= u16::MAX as usize, "too many styles");
self.lcx.style_table.push(resolved);
Expand Down Expand Up @@ -153,27 +168,26 @@ impl<'b, B: Brush> StyleRunBuilder<'b, B> {
self.lcx.inline_boxes.push(inline_box);
}

/// Sets the paragraph's base direction.
///
/// The default is [`BaseDirection::Auto`], which infers the direction from the text.
pub fn set_base_direction(&mut self, base_direction: BaseDirection) {
self.options.base_direction = base_direction;
}

/// Set the callback which will be called as a first provider of line breaking decisions.
///
/// See [`LineBreakOverrideFn`] for more details.
pub fn set_line_break_override(&mut self, overrides: Option<&'b LineBreakOverrideFn>) {
self.line_break_override = overrides;
self.options.line_break_override = overrides;
}

pub fn build_into(self, layout: &mut Layout<B>, text: impl AsRef<str>) {
assert!(
self.cursor == self.len,
"StyleRunBuilder requires runs that cover the full text"
);
build_into_layout(
layout,
self.scale,
self.quantize,
text.as_ref(),
self.lcx,
self.fcx,
self.line_break_override,
);
build_into_layout(layout, text.as_ref(), self.lcx, self.fcx, self.options);
}

pub fn build(self, text: impl AsRef<str>) -> Layout<B> {
Expand All @@ -186,19 +200,17 @@ impl<'b, B: Brush> StyleRunBuilder<'b, B> {
/// Builder for constructing a text layout with a tree of attributes.
#[must_use]
pub struct TreeBuilder<'a, B: Brush> {
pub(crate) scale: f32,
pub(crate) quantize: bool,
pub(crate) options: BuilderOptions<'a>,
pub(crate) lcx: &'a mut LayoutContext<B>,
pub(crate) fcx: &'a mut FontContext,
pub(crate) line_break_override: Option<&'a LineBreakOverrideFn>,
}

impl<'b, B: Brush> TreeBuilder<'b, B> {
pub fn push_style_span(&mut self, style: TextStyle<'_, '_, B>) {
let resolved = self
.lcx
.rcx
.resolve_entire_style_set(self.fcx, &style, self.scale);
.resolve_entire_style_set(self.fcx, &style, self.options.scale);
self.lcx.tree_style_builder.push_style_span(resolved);
}

Expand All @@ -209,11 +221,13 @@ impl<'b, B: Brush> TreeBuilder<'b, B> {
's: 'iter,
B: 'iter,
{
self.lcx.tree_style_builder.push_style_modification_span(
properties
.into_iter()
.map(|p| self.lcx.rcx.resolve_property(self.fcx, p, self.scale)),
);
self.lcx
.tree_style_builder
.push_style_modification_span(properties.into_iter().map(|p| {
self.lcx
.rcx
.resolve_property(self.fcx, p, self.options.scale)
}));
}

pub fn pop_style_span(&mut self) {
Expand Down Expand Up @@ -244,11 +258,18 @@ impl<'b, B: Brush> TreeBuilder<'b, B> {
.set_white_space_mode(white_space_collapse);
}

/// Sets the paragraph's base direction.
///
/// The default is [`BaseDirection::Auto`], which infers the direction from the text.
pub fn set_base_direction(&mut self, base_direction: BaseDirection) {
self.options.base_direction = base_direction;
}

/// Set the callback which will be called as a first provider of line breaking decisions.
///
/// See [`LineBreakOverrideFn`] for more details.
pub fn set_line_break_override(&mut self, overrides: Option<&'b LineBreakOverrideFn>) {
self.line_break_override = overrides;
self.options.line_break_override = overrides;
}

#[inline]
Expand All @@ -260,15 +281,7 @@ impl<'b, B: Brush> TreeBuilder<'b, B> {
.finish(&mut self.lcx.style_table, &mut self.lcx.style_runs);

// Call generic layout builder method
build_into_layout(
layout,
self.scale,
self.quantize,
&text,
self.lcx,
self.fcx,
self.line_break_override,
);
build_into_layout(layout, &text, self.lcx, self.fcx, self.options);

text
}
Expand All @@ -283,12 +296,10 @@ impl<'b, B: Brush> TreeBuilder<'b, B> {

fn build_into_layout<B: Brush>(
layout: &mut Layout<B>,
scale: f32,
quantize: bool,
text: &str,
lcx: &mut LayoutContext<B>,
fcx: &mut FontContext,
line_break_override: Option<&LineBreakOverrideFn>,
options: BuilderOptions<'_>,
) {
if text.is_empty() && lcx.style_runs.is_empty() {
lcx.style_table.push(ResolvedStyle::default());
Expand All @@ -302,11 +313,16 @@ fn build_into_layout<B: Brush>(
"at least one style run is required"
);

crate::analysis::analyze_text(lcx, text, line_break_override);
crate::analysis::analyze_text(
lcx,
text,
options.base_direction,
options.line_break_override,
);

layout.data.clear();
layout.data.scale = scale;
layout.data.quantize = quantize;
layout.data.scale = options.scale;
layout.data.quantize = options.quantize;
layout.data.base_level = lcx.analysis.paragraph_level();
layout.data.text_len = text.len();

Expand Down
14 changes: 4 additions & 10 deletions parley/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use parlance::WordBreak;
use parley_engine::{Analysis, AnalysisDataSources, Analyzer, Shaper};

use super::FontContext;
use super::builder::{RangedBuilder, StyleRunBuilder};
use super::builder::{BuilderOptions, RangedBuilder, StyleRunBuilder};
use super::resolve::tree::TreeStyleBuilder;
use super::resolve::{RangedStyleBuilder, ResolveContext, ResolvedStyle, StyleRun};
use super::style::{Brush, TextStyle};
Expand Down Expand Up @@ -108,11 +108,9 @@ impl<B: Brush> LayoutContext<B> {
fcx.source_cache.prune(128, false);

RangedBuilder {
scale,
quantize,
options: BuilderOptions::new(scale, quantize),
lcx: self,
fcx,
line_break_override: None,
}
}

Expand All @@ -136,13 +134,11 @@ impl<B: Brush> LayoutContext<B> {
fcx.source_cache.prune(128, false);

StyleRunBuilder {
scale,
quantize,
options: BuilderOptions::new(scale, quantize),
len: text.len(),
lcx: self,
fcx,
cursor: 0,
line_break_override: None,
}
}

Expand Down Expand Up @@ -180,11 +176,9 @@ impl<B: Brush> LayoutContext<B> {
fcx.source_cache.prune(128, false);

TreeBuilder {
scale,
quantize,
options: BuilderOptions::new(scale, quantize),
lcx: self,
fcx,
line_break_override: None,
}
}

Expand Down
1 change: 1 addition & 0 deletions parley/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ pub mod style;
mod tests;

pub use linebender_resource_handle::FontData;
pub use parlance::BaseDirection;
pub use parley_engine::break_overrides::{
AsciiLineBreakTable, AsciiLineBreakTableBuilder, CHROMIUM_LINE_BREAK_OVERRIDE,
LineBreakContext, LineBreakOverrideFn,
Expand Down
Loading
Loading