Skip to content
This repository has been archived by the owner on Nov 26, 2024. It is now read-only.

Commit

Permalink
#58 removed paragraph as it was overkill (KISS)
Browse files Browse the repository at this point in the history
  • Loading branch information
bennobuilder committed Mar 22, 2024
1 parent 7f2f5e5 commit c2736ac
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 92 deletions.
84 changes: 66 additions & 18 deletions crates/attributed_string/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,26 @@ use attrs::{Attrs, AttrsInterval, AttrsIntervals};
use fonts_cache::FontsCache;
use glam::Vec2;
use rust_lapper::Lapper;
use tokens::{layout::paragraph::ParagraphToken, span::SpanToken};
use tokens::{
line::{LineToken, SpanRange},
span::SpanToken,
};

#[derive(Debug, Clone)]
struct AttributedString {
text: String,
shape_tokens: Vec<SpanToken>,
layout_tokens: Vec<ParagraphToken>,
spans: Vec<SpanToken>,
lines: Vec<LineToken>,
attrs_intervals: AttrsIntervals,
bbox: Vec2,
config: AttributedStringConfig,
}

impl AttributedString {
pub fn new(text: String, mut attrs_intervals: Vec<AttrsInterval>, bbox: Vec2) -> Self {
pub fn new(
text: String,
mut attrs_intervals: Vec<AttrsInterval>,
config: AttributedStringConfig,
) -> Self {
if attrs_intervals.is_empty() {
attrs_intervals.push(AttrsInterval {
start: 0,
Expand All @@ -33,14 +40,14 @@ impl AttributedString {

return Self {
text,
shape_tokens: Vec::new(),
layout_tokens: Vec::new(),
spans: Vec::new(),
lines: Vec::new(),
attrs_intervals: Lapper::new(attrs_intervals),
bbox,
config,
};
}

pub fn tokenize(&mut self, fonts_cache: &mut FontsCache) {
pub fn tokenize_text(&mut self, fonts_cache: &mut FontsCache) {
self.devide_overlapping_attrs();

let mut spans: Vec<SpanToken> = Vec::new();
Expand Down Expand Up @@ -82,7 +89,7 @@ impl AttributedString {
));
}

self.shape_tokens = spans;
self.spans = spans;
}

pub fn devide_overlapping_attrs(&mut self) {
Expand All @@ -96,12 +103,30 @@ impl AttributedString {
}

pub fn layout(&mut self) {
// TODO: Layout tokens by createing lines, ..
let mut lines: Vec<LineToken> = Vec::new();

match self.config.line_wrap {
LineWrap::None => {
let mut span_ranges: Vec<SpanRange> = Vec::new();
for (index, span) in self.spans.iter().enumerate() {
span_ranges.push(SpanRange::from_span(index, &span));
}
lines.push(LineToken::new(span_ranges));
}
// TODO: Other line wrap implementations
_ => {}
}

for line in lines.iter() {
// TODO
}

self.lines = lines;
}

pub fn to_path(&self) {
// TODO
for span in self.shape_tokens.iter() {
for span in self.spans.iter() {
for glyph in span.iter_glyphs() {
log::info!(
"Glyph: Range({:?}), {:?}, AttrsIndex({})",
Expand All @@ -114,6 +139,25 @@ impl AttributedString {
}
}

#[derive(Debug, Default, Clone)]
struct AttributedStringConfig {
pub bbox: Vec2,
pub line_wrap: LineWrap,
}

#[derive(Debug, Default, Clone, Copy)]
pub enum LineWrap {
/// No wrapping
#[default]
None,
/// Wraps at a glyph level
Glyph,
/// Wraps at the word level
Word,
/// Wraps at the word level, or fallback to glyph level if a word can't fit on a line by itself
WordOrGlyph,
}

#[cfg(test)]
mod tests {
use self::attrs::FontFamily;
Expand Down Expand Up @@ -153,16 +197,20 @@ mod tests {
},
];

let mut attributed_string =
AttributedString::new(text, attrs_intervals, Vec2::new(100.0, 50.0));
let mut attributed_string = AttributedString::new(
text,
attrs_intervals,
AttributedStringConfig {
bbox: Vec2::new(100.0, 100.0),
..Default::default()
},
);

attributed_string.tokenize(&mut fonts_cache);
attributed_string.tokenize_text(&mut fonts_cache);
attributed_string.layout();
attributed_string.to_path();

// println!("{:#?}", attributed_string);

assert_eq!(attributed_string.shape_tokens.is_empty(), false);
assert_eq!(attributed_string.spans.is_empty(), false);
}

#[test]
Expand Down
21 changes: 0 additions & 21 deletions crates/attributed_string/src/tokens/layout/line.rs

This file was deleted.

25 changes: 0 additions & 25 deletions crates/attributed_string/src/tokens/layout/mod.rs

This file was deleted.

27 changes: 0 additions & 27 deletions crates/attributed_string/src/tokens/layout/paragraph.rs

This file was deleted.

69 changes: 69 additions & 0 deletions crates/attributed_string/src/tokens/line.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use std::ops::Range;

use super::span::SpanToken;

/// Represents a line of text.
#[derive(Debug, Clone)]
pub struct LineToken {
span_ranges: Vec<SpanRange>,
}

impl LineToken {
pub fn new(mut span_ranges: Vec<SpanRange>) -> Self {
sort_span_ranges(&mut span_ranges);
Self { span_ranges }
}

pub fn get_range(&self) -> Range<usize> {
let start = self
.span_ranges
.first()
.map(|sr| sr.range.start)
.unwrap_or_default();
let end = self
.span_ranges
.last()
.map(|sr| sr.range.end)
.unwrap_or_default();

return start..end;
}

pub fn get_span_ranges(&self) -> &Vec<SpanRange> {
&self.span_ranges
}

pub fn push_span_range(&mut self, span_range: SpanRange) {
self.span_ranges.push(span_range);
sort_span_ranges(&mut self.span_ranges);
}
}

#[derive(Debug, Clone)]
pub struct SpanRange {
index: usize,
range: Range<usize>,
}

impl SpanRange {
pub fn new(index: usize, range: Range<usize>) -> Self {
Self { index, range }
}

pub fn from_span(index: usize, span: &SpanToken) -> Self {
Self {
index,
range: span.get_range().clone(),
}
}
}

pub fn sort_span_ranges(span_ranges: &mut Vec<SpanRange>) {
span_ranges.sort_by(|a, b| {
// First, compare by index
a.index
.cmp(&b.index)
// If indices are equal, compare by the ending point of the range
.then_with(|| a.range.end.cmp(&b.range.end))
});
}
2 changes: 1 addition & 1 deletion crates/attributed_string/src/tokens/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pub mod layout;
pub mod line;
pub mod shape;
pub mod span;

0 comments on commit c2736ac

Please sign in to comment.