mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Ignore accent when positioning superscript
This commit is contained in:
parent
3f85d005bb
commit
255044e04e
@ -112,13 +112,14 @@ impl LayoutMath for AccentNode {
|
|||||||
let size = Size::new(base.width(), accent.height() + gap + base.height());
|
let size = Size::new(base.width(), accent.height() + gap + base.height());
|
||||||
let accent_pos = Point::with_x(base_attach - accent_attach);
|
let accent_pos = Point::with_x(base_attach - accent_attach);
|
||||||
let base_pos = Point::with_y(accent.height() + gap);
|
let base_pos = Point::with_y(accent.height() + gap);
|
||||||
|
let base_ascent = base.ascent();
|
||||||
let baseline = base_pos.y + base.ascent();
|
let baseline = base_pos.y + base.ascent();
|
||||||
|
|
||||||
let mut frame = Frame::new(size);
|
let mut frame = Frame::new(size);
|
||||||
frame.set_baseline(baseline);
|
frame.set_baseline(baseline);
|
||||||
frame.push_frame(accent_pos, accent);
|
frame.push_frame(accent_pos, accent);
|
||||||
frame.push_frame(base_pos, base.to_frame(ctx));
|
frame.push_frame(base_pos, base.to_frame(ctx));
|
||||||
ctx.push(FrameFragment::new(ctx, frame));
|
ctx.push(FrameFragment::new(ctx, frame).with_base_ascent(base_ascent));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -51,12 +51,15 @@ impl LayoutMath for AttachNode {
|
|||||||
let base = ctx.layout_fragment(&self.base)?;
|
let base = ctx.layout_fragment(&self.base)?;
|
||||||
|
|
||||||
ctx.style(ctx.style.for_subscript());
|
ctx.style(ctx.style.for_subscript());
|
||||||
let top = self.top.as_ref().map(|node| ctx.layout_frame(node)).transpose()?;
|
let top = self.top.as_ref().map(|node| ctx.layout_fragment(node)).transpose()?;
|
||||||
ctx.unstyle();
|
ctx.unstyle();
|
||||||
|
|
||||||
ctx.style(ctx.style.for_superscript());
|
ctx.style(ctx.style.for_superscript());
|
||||||
let bottom =
|
let bottom = self
|
||||||
self.bottom.as_ref().map(|node| ctx.layout_frame(node)).transpose()?;
|
.bottom
|
||||||
|
.as_ref()
|
||||||
|
.map(|node| ctx.layout_fragment(node))
|
||||||
|
.transpose()?;
|
||||||
ctx.unstyle();
|
ctx.unstyle();
|
||||||
|
|
||||||
let render_limits = self.base.is::<LimitsNode>()
|
let render_limits = self.base.is::<LimitsNode>()
|
||||||
@ -145,8 +148,8 @@ impl LayoutMath for LimitsNode {
|
|||||||
fn scripts(
|
fn scripts(
|
||||||
ctx: &mut MathContext,
|
ctx: &mut MathContext,
|
||||||
base: MathFragment,
|
base: MathFragment,
|
||||||
sup: Option<Frame>,
|
sup: Option<MathFragment>,
|
||||||
sub: Option<Frame>,
|
sub: Option<MathFragment>,
|
||||||
) -> SourceResult<()> {
|
) -> SourceResult<()> {
|
||||||
let sup_shift_up = if ctx.style.cramped {
|
let sup_shift_up = if ctx.style.cramped {
|
||||||
scaled!(ctx, superscript_shift_up_cramped)
|
scaled!(ctx, superscript_shift_up_cramped)
|
||||||
@ -166,8 +169,13 @@ fn scripts(
|
|||||||
let mut shift_down = Abs::zero();
|
let mut shift_down = Abs::zero();
|
||||||
|
|
||||||
if let Some(sup) = &sup {
|
if let Some(sup) = &sup {
|
||||||
|
let ascent = match &base {
|
||||||
|
MathFragment::Frame(frame) => frame.base_ascent,
|
||||||
|
_ => base.ascent(),
|
||||||
|
};
|
||||||
|
|
||||||
shift_up = sup_shift_up
|
shift_up = sup_shift_up
|
||||||
.max(base.ascent() - sup_drop_max)
|
.max(ascent - sup_drop_max)
|
||||||
.max(sup_bottom_min + sup.descent());
|
.max(sup_bottom_min + sup.descent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,13 +230,13 @@ fn scripts(
|
|||||||
if let Some(sup) = sup {
|
if let Some(sup) = sup {
|
||||||
let sup_pos =
|
let sup_pos =
|
||||||
Point::new(sup_delta + base_width, ascent - shift_up - sup.ascent());
|
Point::new(sup_delta + base_width, ascent - shift_up - sup.ascent());
|
||||||
frame.push_frame(sup_pos, sup);
|
frame.push_frame(sup_pos, sup.to_frame(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(sub) = sub {
|
if let Some(sub) = sub {
|
||||||
let sub_pos =
|
let sub_pos =
|
||||||
Point::new(sub_delta + base_width, ascent + shift_down - sub.ascent());
|
Point::new(sub_delta + base_width, ascent + shift_down - sub.ascent());
|
||||||
frame.push_frame(sub_pos, sub);
|
frame.push_frame(sub_pos, sub.to_frame(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.push(FrameFragment::new(ctx, frame).with_class(class));
|
ctx.push(FrameFragment::new(ctx, frame).with_class(class));
|
||||||
@ -240,8 +248,8 @@ fn scripts(
|
|||||||
fn limits(
|
fn limits(
|
||||||
ctx: &mut MathContext,
|
ctx: &mut MathContext,
|
||||||
base: MathFragment,
|
base: MathFragment,
|
||||||
top: Option<Frame>,
|
top: Option<MathFragment>,
|
||||||
bottom: Option<Frame>,
|
bottom: Option<MathFragment>,
|
||||||
) -> SourceResult<()> {
|
) -> SourceResult<()> {
|
||||||
let upper_gap_min = scaled!(ctx, upper_limit_gap_min);
|
let upper_gap_min = scaled!(ctx, upper_limit_gap_min);
|
||||||
let upper_rise_min = scaled!(ctx, upper_limit_baseline_rise_min);
|
let upper_rise_min = scaled!(ctx, upper_limit_baseline_rise_min);
|
||||||
@ -275,13 +283,13 @@ fn limits(
|
|||||||
|
|
||||||
if let Some(top) = top {
|
if let Some(top) = top {
|
||||||
let top_pos = Point::with_x((width - top.width()) / 2.0 + delta);
|
let top_pos = Point::with_x((width - top.width()) / 2.0 + delta);
|
||||||
frame.push_frame(top_pos, top);
|
frame.push_frame(top_pos, top.to_frame(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(bottom) = bottom {
|
if let Some(bottom) = bottom {
|
||||||
let bottom_pos =
|
let bottom_pos =
|
||||||
Point::new((width - bottom.width()) / 2.0 - delta, height - bottom.height());
|
Point::new((width - bottom.width()) / 2.0 - delta, height - bottom.height());
|
||||||
frame.push_frame(bottom_pos, bottom);
|
frame.push_frame(bottom_pos, bottom.to_frame(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.push(FrameFragment::new(ctx, frame).with_class(class));
|
ctx.push(FrameFragment::new(ctx, frame).with_class(class));
|
||||||
|
@ -218,7 +218,7 @@ impl GlyphFragment {
|
|||||||
glyphs: vec![Glyph {
|
glyphs: vec![Glyph {
|
||||||
id: self.id.0,
|
id: self.id.0,
|
||||||
c: self.c,
|
c: self.c,
|
||||||
x_advance: Em::from_length(self.width, ctx.size),
|
x_advance: Em::from_length(self.width, self.font_size),
|
||||||
x_offset: Em::zero(),
|
x_offset: Em::zero(),
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
@ -256,22 +256,25 @@ impl Debug for VariantFragment {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct FrameFragment {
|
pub struct FrameFragment {
|
||||||
pub frame: Frame,
|
pub frame: Frame,
|
||||||
pub limits: bool,
|
|
||||||
pub spaced: bool,
|
|
||||||
pub style: MathStyle,
|
pub style: MathStyle,
|
||||||
pub font_size: Abs,
|
pub font_size: Abs,
|
||||||
pub class: MathClass,
|
pub class: MathClass,
|
||||||
|
pub limits: bool,
|
||||||
|
pub spaced: bool,
|
||||||
|
pub base_ascent: Abs,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FrameFragment {
|
impl FrameFragment {
|
||||||
pub fn new(ctx: &MathContext, frame: Frame) -> Self {
|
pub fn new(ctx: &MathContext, frame: Frame) -> Self {
|
||||||
|
let base_ascent = frame.ascent();
|
||||||
Self {
|
Self {
|
||||||
frame,
|
frame,
|
||||||
limits: false,
|
|
||||||
spaced: false,
|
|
||||||
font_size: ctx.size,
|
font_size: ctx.size,
|
||||||
style: ctx.style,
|
style: ctx.style,
|
||||||
class: MathClass::Normal,
|
class: MathClass::Normal,
|
||||||
|
limits: false,
|
||||||
|
spaced: false,
|
||||||
|
base_ascent,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,6 +289,10 @@ impl FrameFragment {
|
|||||||
pub fn with_spaced(self, spaced: bool) -> Self {
|
pub fn with_spaced(self, spaced: bool) -> Self {
|
||||||
Self { spaced, ..self }
|
Self { spaced, ..self }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_base_ascent(self, base_ascent: Abs) -> Self {
|
||||||
|
Self { base_ascent, ..self }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Look up the italics correction for a glyph.
|
/// Look up the italics correction for a glyph.
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 6.5 KiB |
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
// Test function call.
|
// Test function call.
|
||||||
$grave(a), acute(b), hat(f), tilde(§), macron(ä), diaer(a), ä, \
|
$grave(a), acute(b), hat(f), tilde(§), macron(ä), diaer(a), ä \
|
||||||
breve(\&), dot(!), circle(a), caron(@), arrow(Z), arrow.l(Z)$
|
breve(\&), dot(!), circle(a), caron(@), arrow(Z), arrow.l(Z)$
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -17,6 +17,10 @@ $sqrt(tilde(T)) + hat(f)/hat(g)$
|
|||||||
// Test wide base.
|
// Test wide base.
|
||||||
$arrow("ABC" + d), tilde(sum)$
|
$arrow("ABC" + d), tilde(sum)$
|
||||||
|
|
||||||
|
---
|
||||||
|
// Test effect of accent on superscript.
|
||||||
|
$A^x != hat(A)^x != hat(hat(A))^x$
|
||||||
|
|
||||||
---
|
---
|
||||||
// Test high base.
|
// Test high base.
|
||||||
$ tilde(integral), tilde(integral)_a^b, tilde(integral_a^b) $
|
$ tilde(integral), tilde(integral)_a^b, tilde(integral_a^b) $
|
||||||
|
Loading…
x
Reference in New Issue
Block a user