summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Biedert <github@ericbiedert.de>2023-12-28 14:30:32 +0100
committerGitHub <noreply@github.com>2023-12-28 13:30:32 +0000
commitf94708d202785922f9ffbc6b3beb50a5d636682b (patch)
tree018f59edd55a894b55baa1e10be97c0f9992faef
parent162b4e812db3027481b88fcaab02ba5c8337b041 (diff)
Make accent size adjustable (#3077)
-rw-r--r--crates/typst/src/eval/call.rs9
-rw-r--r--crates/typst/src/math/accent.rs15
-rw-r--r--tests/ref/math/accent.pngbin8128 -> 8869 bytes
-rw-r--r--tests/typ/math/accent.typ4
4 files changed, 22 insertions, 6 deletions
diff --git a/crates/typst/src/eval/call.rs b/crates/typst/src/eval/call.rs
index fd660e94..9e4a128f 100644
--- a/crates/typst/src/eval/call.rs
+++ b/crates/typst/src/eval/call.rs
@@ -122,10 +122,13 @@ impl Eval for ast::FuncCall<'_> {
let c = sym.get();
if let Some(accent) = Symbol::combining_accent(c) {
let base = args.expect("base")?;
+ let size = args.named("size")?;
args.finish()?;
- return Ok(Value::Content(
- AccentElem::new(base, Accent::new(accent)).pack(),
- ));
+ let mut accent = AccentElem::new(base, Accent::new(accent));
+ if let Some(size) = size {
+ accent = accent.with_size(size);
+ }
+ return Ok(Value::Content(accent.pack()));
}
}
let mut body = Content::empty();
diff --git a/crates/typst/src/math/accent.rs b/crates/typst/src/math/accent.rs
index 0480567c..ba030778 100644
--- a/crates/typst/src/math/accent.rs
+++ b/crates/typst/src/math/accent.rs
@@ -2,8 +2,8 @@ use ttf_parser::GlyphId;
use unicode_math_class::MathClass;
use crate::diag::{bail, SourceResult};
-use crate::foundations::{cast, elem, Content, NativeElement, Value};
-use crate::layout::{Abs, Em, Frame, Point, Size};
+use crate::foundations::{cast, elem, Content, NativeElement, Resolve, Smart, Value};
+use crate::layout::{Abs, Em, Frame, Length, Point, Rel, Size};
use crate::math::{
FrameFragment, GlyphFragment, LayoutMath, MathContext, MathFragment, Scaled,
};
@@ -56,6 +56,9 @@ pub struct AccentElem {
/// | Left arrow | `arrow.l`, `<-` | `←` |
#[required]
pub accent: Accent,
+
+ /// The size of the accent, relative to the width of the base.
+ pub size: Smart<Rel<Length>>,
}
impl LayoutMath for AccentElem {
@@ -74,12 +77,18 @@ impl LayoutMath for AccentElem {
_ => (base.width() + base.italics_correction()) / 2.0,
};
+ let width = self
+ .size(ctx.styles())
+ .unwrap_or(Rel::one())
+ .resolve(ctx.styles())
+ .relative_to(base.width());
+
// Forcing the accent to be at least as large as the base makes it too
// wide in many case.
let Accent(c) = self.accent();
let glyph = GlyphFragment::new(ctx, *c, self.span());
let short_fall = ACCENT_SHORT_FALL.scaled(ctx);
- let variant = glyph.stretch_horizontal(ctx, base.width(), short_fall);
+ let variant = glyph.stretch_horizontal(ctx, width, short_fall);
let accent = variant.frame;
let accent_attach = match variant.id {
Some(id) => attachment(ctx, id, variant.italics_correction),
diff --git a/tests/ref/math/accent.png b/tests/ref/math/accent.png
index 619a066c..b955b5ad 100644
--- a/tests/ref/math/accent.png
+++ b/tests/ref/math/accent.png
Binary files differ
diff --git a/tests/typ/math/accent.typ b/tests/typ/math/accent.typ
index cf1d3fa2..315e14b3 100644
--- a/tests/typ/math/accent.typ
+++ b/tests/typ/math/accent.typ
@@ -27,3 +27,7 @@ $A^x != hat(A)^x != hat(hat(A))^x$
---
// Test high base.
$ tilde(integral), tilde(integral)_a^b, tilde(integral_a^b) $
+
+---
+// Test accent size.
+$tilde(sum), tilde(sum, size: #50%), accent(H, hat, size: #200%)$