Skip to content

Commit

Permalink
fix: complex composition calculation not correct
Browse files Browse the repository at this point in the history
  • Loading branch information
zimond committed Aug 4, 2024
1 parent 8d75e75 commit 7429630
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 26 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fontkit-rs",
"version": "0.0.11-beta.3",
"version": "0.0.11-beta.5",
"description": "Toolkit used to load, match, measure, and render texts",
"main": "index.js",
"directories": {
Expand Down
10 changes: 4 additions & 6 deletions src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,14 +288,12 @@ impl TextMetrics {
if self.units == 0 {
return 0.0;
}
let factor = font_size / self.units as f32;
let positions = self.positions.read().unwrap();
positions.iter().take(index).fold(0.0, |current, p| {
current
+ p.kerning as f32 * factor
+ p.metrics.advanced_x as f32 * factor
+ letter_spacing
})
current + p.kerning as f32 + p.metrics.advanced_x as f32
}) * font_size
/ self.units as f32
+ letter_spacing * (index as f32)
}

pub fn width_trim_start(&self, font_size: f32, letter_spacing: f32) -> f32 {
Expand Down
35 changes: 18 additions & 17 deletions src/metrics/compose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ where
}
is_first_line = false;
let line_width = line.width();
if width - (line_width + current_line_width) >= -0.01 {
if width - (line_width + current_line_width) >= -0.1 {
// Current line fits, push all of its spans into current line
current_line_width += line_width;
current_line.spans.append(&mut line.spans);
Expand All @@ -195,7 +195,7 @@ where
// Go through spans to get the first not-fitting span
let index = line.spans.iter().position(|span| {
let span_width = span.width();
if span_width + current_line_width <= width {
if span_width + current_line_width - width <= 0.1 {
current_line_width += span_width;
false
} else {
Expand Down Expand Up @@ -231,7 +231,6 @@ where
span.letter_spacing,
width - current_line_width,
);

if new_metrics.count() != 0 {
failed_with_no_acception = false;
}
Expand All @@ -255,17 +254,23 @@ where
// Add new_span to next line
let mut new_line = Line {
hard_break: false,
spans: vec![new_span],
spans: vec![],
};
// Check for swallowed leading space
if new_line.spans[0].metrics.value().starts_with(" ") {
new_line.spans[0].swallow_leading_space = true;
if new_span.metrics.count() != 0 {
new_line.spans.push(new_span);
}
for span in line.spans.into_iter().skip(1) {
new_line.spans.push(span);
}
lines.push_front(new_line);
current_line_width = 0.0;
if new_line.spans.is_empty() {
continue;
}
// Check for swallowed leading space
if new_line.spans[0].metrics.value().starts_with(" ") {
new_line.spans[0].swallow_leading_space = true;
}
lines.push_front(new_line);
}
}
if !current_line.spans.is_empty() {
Expand Down Expand Up @@ -460,7 +465,7 @@ impl TextMetrics {
// Textwrap cannot find a good break point, we directly drop chars
loop {
let span_width = self.width_until(font_size, letter_spacing, naive_break_index);
if span_width <= width || naive_break_index == 0 {
if span_width - width <= 0.1 || naive_break_index == 0 {
break;
}
naive_break_index -= 1;
Expand Down Expand Up @@ -563,14 +568,10 @@ impl TextMetrics {
drop(positions);
// Split here, create a new span
let mut new_metrics = self.clone();
if real_index == 0 {
new_metrics.positions = Arc::new(RwLock::new(vec![]));
} else {
new_metrics.positions = {
let mut p = self.positions.write().unwrap();
Arc::new(RwLock::new(p.split_off(real_index)))
};
}
new_metrics.positions = {
let mut p = self.positions.write().unwrap();
Arc::new(RwLock::new(p.split_off(real_index)))
};
new_metrics
}
}
36 changes: 34 additions & 2 deletions tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ pub fn test_search_font() -> Result<(), Error> {
pub fn test_text_wrap() -> Result<(), Error> {
let fontkit = FontKit::new();
fontkit.search_fonts_from_path("examples/AlimamaFangYuanTiVF.ttf")?;
let key = fontkit.font_keys().next().unwrap();
let mut key = FontKey::default();
key.family = "AlimamaFangYuanTiVF-Medium-Round".into();
let mut area = Area::<(), TextMetrics>::new();
let metrics = fontkit
.measure(&key, " 傲冬黑色真皮皮衣 穿着舒适显瘦")
Expand All @@ -69,6 +70,37 @@ pub fn test_text_wrap() -> Result<(), Error> {
});
area.unwrap_text();
area.wrap_text(576.0)?;
assert_eq!(area.width(), 549.12);
assert_eq!(area.width(), 553.608);
Ok(())
}

#[test]
pub fn test_complex_text_wrap() -> Result<(), Error> {
let fontkit = FontKit::new();
fontkit.search_fonts_from_path("examples/AlimamaFangYuanTiVF.ttf")?;
let mut key = FontKey::default();
key.family = "AlimamaFangYuanTiVF-Medium-Round".into();
let mut area = Area::<(), TextMetrics>::new();
let metrics = fontkit.measure(&key, "商家").unwrap();
let mut span = Span::default();
span.font_key = key.clone();
span.size = 32.0;
span.metrics = metrics;
let metrics = fontkit.measure(&key, "热卖12345678").unwrap();
let mut span_1 = Span::default();
span_1.font_key = key.clone();
span_1.size = 32.0;
span_1.metrics = metrics;
area.lines.push(Line {
spans: vec![span],
hard_break: true,
});
area.lines.push(Line {
spans: vec![span_1],
hard_break: true,
});
area.unwrap_text();
area.wrap_text(64.4)?;
assert_eq!(area.value_string(), "商家\n热卖\n1234\n567\n8");
Ok(())
}

0 comments on commit 7429630

Please sign in to comment.