mirror of
https://github.com/storytold/deckcraft.git
synced 2026-11-03 17:12:52 -06:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a553966498 |
@@ -76,16 +76,12 @@ fn tokens(l: &TextLayout, chars: bool) -> (Vec<Token>, Vec<(usize, usize)>) {
|
||||
|
||||
/// For each token of `b`, the token of `a` with the same text, in reading order, each used once.
|
||||
fn matches(a: &[Token], b: &[Token]) -> Vec<Option<usize>> {
|
||||
let mut used = vec![false; a.len()];
|
||||
b.iter()
|
||||
.map(|tb| {
|
||||
let i = a.iter().enumerate().position(|(i, ta)| !used.get(i).copied().unwrap_or(true) && ta.key == tb.key)?;
|
||||
if let Some(u) = used.get_mut(i) {
|
||||
*u = true;
|
||||
}
|
||||
Some(i)
|
||||
})
|
||||
.collect()
|
||||
// Unused tokens of `a` by text, in reading order, so each lookup is a pop rather than a scan.
|
||||
let mut free: std::collections::HashMap<&str, std::collections::VecDeque<usize>> = std::collections::HashMap::new();
|
||||
for (i, ta) in a.iter().enumerate() {
|
||||
free.entry(ta.key.as_str()).or_default().push_back(i);
|
||||
}
|
||||
b.iter().map(|tb| free.get_mut(tb.key.as_str())?.pop_front()).collect()
|
||||
}
|
||||
|
||||
fn layout(ctx: &Ctx, s: &Shape, x: Xfrm, fields: &dyn Fields) -> Option<TextLayout> {
|
||||
@@ -228,3 +224,19 @@ pub(crate) fn draw(
|
||||
pub(crate) fn token_keys(l: &TextLayout, chars: bool) -> Vec<String> {
|
||||
tokens(l, chars).0.into_iter().map(|t| t.key).collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod match_tests {
|
||||
use super::*;
|
||||
|
||||
fn tok(k: &str) -> Token {
|
||||
Token { key: k.into(), glyphs: Vec::new(), origin: Point::ZERO, run: 0 }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn each_source_token_is_used_once_in_reading_order() {
|
||||
let a: Vec<Token> = ["a", "b", "a"].map(tok).into();
|
||||
let b: Vec<Token> = ["a", "a", "a", "b", "c"].map(tok).into();
|
||||
assert_eq!(matches(&a, &b), vec![Some(0), Some(2), None, Some(1), None]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ pub struct GlyphRun {
|
||||
pub link: bool,
|
||||
/// Opacity of the fill on top of `color`'s own alpha (0 for no fill).
|
||||
pub alpha: f64,
|
||||
pub gradient: Option<deckcraft_model::style::Gradient>,
|
||||
pub gradient: Option<std::sync::Arc<deckcraft_model::style::Gradient>>,
|
||||
/// Shadow and glow behind the glyphs (`a:rPr/a:effectLst`).
|
||||
pub effects: Option<RunEffects>,
|
||||
/// East Asian vertical text (`eaVert`): each glyph stands upright, turned a quarter turn
|
||||
|
||||
@@ -46,7 +46,7 @@ pub(crate) struct Style {
|
||||
pub(crate) highlight: Option<Rgba>,
|
||||
pub(crate) outline: Option<(Rgba, f64)>,
|
||||
pub(crate) link: bool,
|
||||
pub(crate) gradient: Option<deckcraft_model::style::Gradient>,
|
||||
pub(crate) gradient: Option<std::sync::Arc<deckcraft_model::style::Gradient>>,
|
||||
pub(crate) effects: Option<RunEffects>,
|
||||
/// "Regular", "Bold"… for the slot and fallback faces.
|
||||
pub(crate) style_name: &'static str,
|
||||
@@ -136,7 +136,7 @@ pub(crate) fn make_style(ctx: &Ctx, r: &RunProps, scale: f64, prompt: Option<Rgb
|
||||
for s in &mut g.stops {
|
||||
s.color = deckcraft_model::ColorRef::rgb(ctx.color(&s.color, None));
|
||||
}
|
||||
(g.stops.first().map(|s| ctx.color(&s.color, None)).unwrap_or(Rgba::BLACK), 1.0, Some(g))
|
||||
(g.stops.first().map(|s| ctx.color(&s.color, None)).unwrap_or(Rgba::BLACK), 1.0, Some(std::sync::Arc::new(g)))
|
||||
}
|
||||
Some(Fill::None) => (Rgba::TRANSPARENT, 0.0, None),
|
||||
_ => (resolve::text_color(ctx, r), 1.0, None),
|
||||
|
||||
Reference in New Issue
Block a user