mirror of
https://github.com/typst/typst
synced 2025-05-15 01:25:28 +08:00
Resolve lengths in math with scaled font size (#5168)
This commit is contained in:
parent
b060dd7f61
commit
250223c997
@ -86,6 +86,12 @@ impl Rel<Length> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert to a relative length with the absolute part resolved at the
|
||||||
|
/// given font size.
|
||||||
|
pub fn at(self, font_size: Abs) -> Rel<Abs> {
|
||||||
|
self.map(|abs| abs.at(font_size))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Numeric + Debug> Debug for Rel<T> {
|
impl<T: Numeric + Debug> Debug for Rel<T> {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
use crate::diag::{bail, SourceResult};
|
use crate::diag::{bail, SourceResult};
|
||||||
use crate::foundations::{
|
use crate::foundations::{
|
||||||
cast, elem, func, Content, NativeElement, Packed, Resolve, Smart, StyleChain, Value,
|
cast, elem, func, Content, NativeElement, Packed, Smart, StyleChain, Value,
|
||||||
};
|
};
|
||||||
use crate::layout::{Em, Frame, Length, Point, Rel, Size};
|
use crate::layout::{Em, Frame, Length, Point, Rel, Size};
|
||||||
use crate::math::{
|
use crate::math::{
|
||||||
style_cramped, FrameFragment, GlyphFragment, LayoutMath, MathContext, MathFragment,
|
scaled_font_size, style_cramped, FrameFragment, GlyphFragment, LayoutMath,
|
||||||
Scaled,
|
MathContext, MathFragment, Scaled,
|
||||||
};
|
};
|
||||||
use crate::text::TextElem;
|
use crate::text::TextElem;
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ impl LayoutMath for Packed<AccentElem> {
|
|||||||
let width = self
|
let width = self
|
||||||
.size(styles)
|
.size(styles)
|
||||||
.unwrap_or(Rel::one())
|
.unwrap_or(Rel::one())
|
||||||
.resolve(styles)
|
.at(scaled_font_size(ctx, styles))
|
||||||
.relative_to(base.width());
|
.relative_to(base.width());
|
||||||
|
|
||||||
// Forcing the accent to be at least as large as the base makes it too
|
// Forcing the accent to be at least as large as the base makes it too
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
use comemo::Track;
|
use comemo::Track;
|
||||||
|
|
||||||
use crate::diag::{At, SourceResult};
|
use crate::diag::{At, SourceResult};
|
||||||
use crate::foundations::{
|
use crate::foundations::{cast, elem, Content, Context, Func, Packed, Smart, StyleChain};
|
||||||
cast, elem, Content, Context, Func, Packed, Resolve, Smart, StyleChain,
|
|
||||||
};
|
|
||||||
use crate::layout::{
|
use crate::layout::{
|
||||||
Abs, Angle, Frame, FrameItem, Length, Point, Ratio, Rel, Size, Transform,
|
Abs, Angle, Frame, FrameItem, Length, Point, Ratio, Rel, Size, Transform,
|
||||||
};
|
};
|
||||||
use crate::math::{FrameFragment, LayoutMath, MathContext};
|
use crate::math::{scaled_font_size, FrameFragment, LayoutMath, MathContext};
|
||||||
use crate::syntax::Span;
|
use crate::syntax::Span;
|
||||||
use crate::text::TextElem;
|
use crate::text::TextElem;
|
||||||
use crate::visualize::{FixedStroke, Geometry, Stroke};
|
use crate::visualize::{FixedStroke, Geometry, Stroke};
|
||||||
@ -120,7 +118,7 @@ impl LayoutMath for Packed<CancelElem> {
|
|||||||
let mut body = body.into_frame();
|
let mut body = body.into_frame();
|
||||||
let body_size = body.size();
|
let body_size = body.size();
|
||||||
let span = self.span();
|
let span = self.span();
|
||||||
let length = self.length(styles).resolve(styles);
|
let length = self.length(styles).at(scaled_font_size(ctx, styles));
|
||||||
|
|
||||||
let stroke = self.stroke(styles).unwrap_or(FixedStroke {
|
let stroke = self.stroke(styles).unwrap_or(FixedStroke {
|
||||||
paint: TextElem::fill_in(styles).as_decoration(),
|
paint: TextElem::fill_in(styles).as_decoration(),
|
||||||
|
@ -11,7 +11,7 @@ use unicode_segmentation::UnicodeSegmentation;
|
|||||||
|
|
||||||
use crate::diag::SourceResult;
|
use crate::diag::SourceResult;
|
||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
use crate::foundations::{Content, Packed, Resolve, StyleChain, StyleVec};
|
use crate::foundations::{Content, Packed, StyleChain, StyleVec};
|
||||||
use crate::introspection::{SplitLocator, TagElem};
|
use crate::introspection::{SplitLocator, TagElem};
|
||||||
use crate::layout::{
|
use crate::layout::{
|
||||||
layout_frame, Abs, Axes, BoxElem, Em, Frame, HElem, PlaceElem, Region, Size, Spacing,
|
layout_frame, Abs, Axes, BoxElem, Em, Frame, HElem, PlaceElem, Region, Size, Spacing,
|
||||||
@ -220,7 +220,7 @@ impl MathContext<'_, '_, '_> {
|
|||||||
if let Spacing::Rel(rel) = elem.amount() {
|
if let Spacing::Rel(rel) = elem.amount() {
|
||||||
if rel.rel.is_zero() {
|
if rel.rel.is_zero() {
|
||||||
self.push(MathFragment::Spacing(
|
self.push(MathFragment::Spacing(
|
||||||
rel.abs.resolve(styles),
|
rel.abs.at(scaled_font_size(self, styles)),
|
||||||
elem.weak(styles),
|
elem.weak(styles),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,6 @@ pub struct VecElem {
|
|||||||
/// #set math.vec(gap: 1em)
|
/// #set math.vec(gap: 1em)
|
||||||
/// $ vec(1, 2) $
|
/// $ vec(1, 2) $
|
||||||
/// ```
|
/// ```
|
||||||
#[resolve]
|
|
||||||
#[default(DEFAULT_ROW_GAP.into())]
|
#[default(DEFAULT_ROW_GAP.into())]
|
||||||
pub gap: Rel<Length>,
|
pub gap: Rel<Length>,
|
||||||
|
|
||||||
@ -81,7 +80,7 @@ impl LayoutMath for Packed<VecElem> {
|
|||||||
styles,
|
styles,
|
||||||
self.children(),
|
self.children(),
|
||||||
self.align(styles),
|
self.align(styles),
|
||||||
self.gap(styles),
|
self.gap(styles).at(scaled_font_size(ctx, styles)),
|
||||||
LeftRightAlternator::Right,
|
LeftRightAlternator::Right,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -182,7 +181,6 @@ pub struct MatElem {
|
|||||||
/// #set math.mat(row-gap: 1em)
|
/// #set math.mat(row-gap: 1em)
|
||||||
/// $ mat(1, 2; 3, 4) $
|
/// $ mat(1, 2; 3, 4) $
|
||||||
/// ```
|
/// ```
|
||||||
#[resolve]
|
|
||||||
#[parse(
|
#[parse(
|
||||||
let gap = args.named("gap")?;
|
let gap = args.named("gap")?;
|
||||||
args.named("row-gap")?.or(gap)
|
args.named("row-gap")?.or(gap)
|
||||||
@ -196,7 +194,6 @@ pub struct MatElem {
|
|||||||
/// #set math.mat(column-gap: 1em)
|
/// #set math.mat(column-gap: 1em)
|
||||||
/// $ mat(1, 2; 3, 4) $
|
/// $ mat(1, 2; 3, 4) $
|
||||||
/// ```
|
/// ```
|
||||||
#[resolve]
|
|
||||||
#[parse(args.named("column-gap")?.or(gap))]
|
#[parse(args.named("column-gap")?.or(gap))]
|
||||||
#[default(DEFAULT_COL_GAP.into())]
|
#[default(DEFAULT_COL_GAP.into())]
|
||||||
pub column_gap: Rel<Length>,
|
pub column_gap: Rel<Length>,
|
||||||
@ -268,6 +265,9 @@ impl LayoutMath for Packed<MatElem> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let font_size = scaled_font_size(ctx, styles);
|
||||||
|
let column_gap = self.column_gap(styles).at(font_size);
|
||||||
|
let row_gap = self.row_gap(styles).at(font_size);
|
||||||
let delim = self.delim(styles);
|
let delim = self.delim(styles);
|
||||||
let frame = layout_mat_body(
|
let frame = layout_mat_body(
|
||||||
ctx,
|
ctx,
|
||||||
@ -275,7 +275,7 @@ impl LayoutMath for Packed<MatElem> {
|
|||||||
rows,
|
rows,
|
||||||
self.align(styles),
|
self.align(styles),
|
||||||
augment,
|
augment,
|
||||||
Axes::new(self.column_gap(styles), self.row_gap(styles)),
|
Axes::new(column_gap, row_gap),
|
||||||
self.span(),
|
self.span(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -322,7 +322,6 @@ pub struct CasesElem {
|
|||||||
/// #set math.cases(gap: 1em)
|
/// #set math.cases(gap: 1em)
|
||||||
/// $ x = cases(1, 2) $
|
/// $ x = cases(1, 2) $
|
||||||
/// ```
|
/// ```
|
||||||
#[resolve]
|
|
||||||
#[default(DEFAULT_ROW_GAP.into())]
|
#[default(DEFAULT_ROW_GAP.into())]
|
||||||
pub gap: Rel<Length>,
|
pub gap: Rel<Length>,
|
||||||
|
|
||||||
@ -340,7 +339,7 @@ impl LayoutMath for Packed<CasesElem> {
|
|||||||
styles,
|
styles,
|
||||||
self.children(),
|
self.children(),
|
||||||
FixedAlignment::Start,
|
FixedAlignment::Start,
|
||||||
self.gap(styles),
|
self.gap(styles).at(scaled_font_size(ctx, styles)),
|
||||||
LeftRightAlternator::None,
|
LeftRightAlternator::None,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -2,10 +2,11 @@ use ttf_parser::math::{GlyphAssembly, GlyphConstruction, GlyphPart};
|
|||||||
use ttf_parser::LazyArray16;
|
use ttf_parser::LazyArray16;
|
||||||
|
|
||||||
use crate::diag::SourceResult;
|
use crate::diag::SourceResult;
|
||||||
use crate::foundations::{elem, Content, Packed, Resolve, Smart, StyleChain};
|
use crate::foundations::{elem, Content, Packed, Smart, StyleChain};
|
||||||
use crate::layout::{Abs, Axis, Frame, Length, Point, Rel, Size, VAlignment};
|
use crate::layout::{Abs, Axis, Frame, Length, Point, Rel, Size, VAlignment};
|
||||||
use crate::math::{
|
use crate::math::{
|
||||||
GlyphFragment, LayoutMath, MathContext, MathFragment, Scaled, VariantFragment,
|
scaled_font_size, GlyphFragment, LayoutMath, MathContext, MathFragment, Scaled,
|
||||||
|
VariantFragment,
|
||||||
};
|
};
|
||||||
use crate::utils::Get;
|
use crate::utils::Get;
|
||||||
|
|
||||||
@ -91,7 +92,7 @@ pub(super) fn stretch_fragment(
|
|||||||
glyph,
|
glyph,
|
||||||
stretch
|
stretch
|
||||||
.unwrap_or(Rel::one())
|
.unwrap_or(Rel::one())
|
||||||
.resolve(styles)
|
.at(scaled_font_size(ctx, styles))
|
||||||
.relative_to(relative_to_size),
|
.relative_to(relative_to_size),
|
||||||
short_fall,
|
short_fall,
|
||||||
axis,
|
axis,
|
||||||
|
BIN
tests/ref/math-accent-sized-script.png
Normal file
BIN
tests/ref/math-accent-sized-script.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 331 B |
BIN
tests/ref/math-spacing-script.png
Normal file
BIN
tests/ref/math-spacing-script.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 346 B |
@ -31,3 +31,7 @@ $ tilde(integral), tilde(integral)_a^b, tilde(integral_a^b) $
|
|||||||
--- math-accent-sized ---
|
--- math-accent-sized ---
|
||||||
// Test accent size.
|
// Test accent size.
|
||||||
$tilde(sum), tilde(sum, size: #50%), accent(H, hat, size: #200%)$
|
$tilde(sum), tilde(sum, size: #50%), accent(H, hat, size: #200%)$
|
||||||
|
|
||||||
|
--- math-accent-sized-script ---
|
||||||
|
// Test accent size in script size.
|
||||||
|
$tilde(U, size: #1.1em), x^tilde(U, size: #1.1em), sscript(tilde(U, size: #1.1em))$
|
||||||
|
@ -49,6 +49,10 @@ $integral f(x) thin dif x$,
|
|||||||
// Both are weak, collide
|
// Both are weak, collide
|
||||||
$integral f(x) #h(0.166em, weak: true)dif x$
|
$integral f(x) #h(0.166em, weak: true)dif x$
|
||||||
|
|
||||||
|
--- math-spacing-script ---
|
||||||
|
// Test spacing in script size
|
||||||
|
$x^(a #h(1em) b) + x^x^(a #h(1em) b) + sscript(a #h(1em) b)$
|
||||||
|
|
||||||
--- math-spacing-ignorant ---
|
--- math-spacing-ignorant ---
|
||||||
// Test spacing with ignorant elements
|
// Test spacing with ignorant elements
|
||||||
$#metadata(none) "text"$ \
|
$#metadata(none) "text"$ \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user