mirror of
https://github.com/typst/typst
synced 2025-06-28 16:22:53 +08:00
Fix bug in line layouter ✔
This commit is contained in:
parent
ef410f6877
commit
985fe28166
101
src/geom.rs
101
src/geom.rs
@ -6,18 +6,60 @@ pub use kurbo::*;
|
||||
use std::fmt::{self, Debug, Formatter};
|
||||
use std::ops::*;
|
||||
|
||||
use crate::layout::primitive::{Dir, Gen2, GenAlign, Side, SpecAxis};
|
||||
use crate::layout::primitive::{Dir, Gen2, GenAlign, Get, Side, SpecAxis};
|
||||
|
||||
macro_rules! impl_get_2d {
|
||||
($t:ty, $x:ident, $y:ident) => {
|
||||
impl Get<SpecAxis> for $t {
|
||||
type Component = f64;
|
||||
|
||||
fn get(self, axis: SpecAxis) -> f64 {
|
||||
match axis {
|
||||
SpecAxis::Horizontal => self.$x,
|
||||
SpecAxis::Vertical => self.$y,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mut(&mut self, axis: SpecAxis) -> &mut f64 {
|
||||
match axis {
|
||||
SpecAxis::Horizontal => &mut self.$x,
|
||||
SpecAxis::Vertical => &mut self.$y,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_get_2d!(Point, x, y);
|
||||
impl_get_2d!(Vec2, x, y);
|
||||
impl_get_2d!(Size, width, height);
|
||||
|
||||
impl Get<Side> for Rect {
|
||||
type Component = f64;
|
||||
|
||||
fn get(self, side: Side) -> f64 {
|
||||
match side {
|
||||
Side::Left => self.x0,
|
||||
Side::Top => self.y0,
|
||||
Side::Right => self.x1,
|
||||
Side::Bottom => self.y1,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mut(&mut self, side: Side) -> &mut f64 {
|
||||
match side {
|
||||
Side::Left => &mut self.x0,
|
||||
Side::Top => &mut self.y0,
|
||||
Side::Right => &mut self.x1,
|
||||
Side::Bottom => &mut self.y1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Additional methods for [sizes].
|
||||
///
|
||||
/// [sizes]: ../../kurbo/struct.Size.html
|
||||
pub trait SizeExt {
|
||||
/// Return the component for the specified axis.
|
||||
fn get(self, axis: SpecAxis) -> f64;
|
||||
|
||||
/// Borrow the component for the specified axis mutably.
|
||||
fn get_mut(&mut self, axis: SpecAxis) -> &mut f64;
|
||||
|
||||
/// Returns the generalized version of a `Size` based on the current
|
||||
/// directions.
|
||||
///
|
||||
@ -43,20 +85,6 @@ pub trait SizeExt {
|
||||
}
|
||||
|
||||
impl SizeExt for Size {
|
||||
fn get(self, axis: SpecAxis) -> f64 {
|
||||
match axis {
|
||||
SpecAxis::Horizontal => self.width,
|
||||
SpecAxis::Vertical => self.height,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mut(&mut self, axis: SpecAxis) -> &mut f64 {
|
||||
match axis {
|
||||
SpecAxis::Horizontal => &mut self.width,
|
||||
SpecAxis::Vertical => &mut self.height,
|
||||
}
|
||||
}
|
||||
|
||||
fn generalized(self, dirs: Gen2<Dir>) -> Self {
|
||||
match dirs.main.axis() {
|
||||
SpecAxis::Horizontal => Self::new(self.height, self.width),
|
||||
@ -90,37 +118,6 @@ impl SizeExt for Size {
|
||||
}
|
||||
}
|
||||
|
||||
/// Additional methods for [rectangles].
|
||||
///
|
||||
/// [rectangles]: ../../kurbo/struct.Rect.html
|
||||
pub trait RectExt {
|
||||
/// Return the value for the given side.
|
||||
fn get(self, side: Side) -> f64;
|
||||
|
||||
/// Borrow the value for the given side mutably.
|
||||
fn get_mut(&mut self, side: Side) -> &mut f64;
|
||||
}
|
||||
|
||||
impl RectExt for Rect {
|
||||
fn get(self, side: Side) -> f64 {
|
||||
match side {
|
||||
Side::Left => self.x0,
|
||||
Side::Top => self.y0,
|
||||
Side::Right => self.x1,
|
||||
Side::Bottom => self.y1,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mut(&mut self, side: Side) -> &mut f64 {
|
||||
match side {
|
||||
Side::Left => &mut self.x0,
|
||||
Side::Top => &mut self.y0,
|
||||
Side::Right => &mut self.x1,
|
||||
Side::Bottom => &mut self.y1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A function that depends linearly on one value.
|
||||
///
|
||||
/// This represents a function `f(x) = rel * x + abs`.
|
||||
|
@ -198,19 +198,17 @@ impl LineLayouter {
|
||||
pub fn finish_line(&mut self) {
|
||||
let mut layout = BoxLayout::new(self.run.size.specialized(self.ctx.dirs));
|
||||
let aligns = self.run.aligns.unwrap_or_default();
|
||||
let cross = self.ctx.dirs.cross;
|
||||
|
||||
let layouts = std::mem::take(&mut self.run.layouts);
|
||||
for (offset, child) in layouts {
|
||||
let x = match self.ctx.dirs.cross.is_positive() {
|
||||
true => offset,
|
||||
false => {
|
||||
self.run.size.width
|
||||
- offset
|
||||
- child.size.get(self.ctx.dirs.cross.axis())
|
||||
}
|
||||
let mut pos = Point::ZERO;
|
||||
*pos.get_mut(cross.axis()) = if cross.is_positive() {
|
||||
offset
|
||||
} else {
|
||||
self.run.size.width - offset - child.size.get(cross.axis())
|
||||
};
|
||||
|
||||
let pos = Point::new(x, 0.0);
|
||||
layout.push_layout(pos, child);
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ pub use tree::*;
|
||||
use crate::diag::Diag;
|
||||
use crate::eval::{PageState, State, TextState};
|
||||
use crate::font::SharedFontLoader;
|
||||
use crate::geom::{Insets, Point, Rect, RectExt, Size, SizeExt};
|
||||
use crate::geom::{Insets, Point, Rect, Size, SizeExt};
|
||||
use crate::shaping::Shaped;
|
||||
use crate::syntax::{Deco, Spanned, SynTree};
|
||||
use crate::{Feedback, Pass};
|
||||
|
@ -2,6 +2,50 @@
|
||||
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
|
||||
/// Generic access to a structure's components.
|
||||
pub trait Get<Index> {
|
||||
/// The structure's component type.
|
||||
type Component;
|
||||
|
||||
/// Return the component for the specified index.
|
||||
fn get(self, index: Index) -> Self::Component;
|
||||
|
||||
/// Borrow the component for the specified index mutably.
|
||||
fn get_mut(&mut self, index: Index) -> &mut Self::Component;
|
||||
}
|
||||
|
||||
/// Convert a type into its generic representation.
|
||||
///
|
||||
/// The generic representation deals with main and cross axes while the specific
|
||||
/// representation deals with horizontal and vertical axes.
|
||||
///
|
||||
/// See also [`ToSpec`] for the inverse conversion.
|
||||
///
|
||||
/// [`ToSpec`]: trait.ToSpec.html
|
||||
pub trait ToGen {
|
||||
/// The generic version of this type.
|
||||
type Output;
|
||||
|
||||
/// The generic version of this type based on the current directions.
|
||||
fn to_gen(self, dirs: Gen2<Dir>) -> Self::Output;
|
||||
}
|
||||
|
||||
/// Convert a type into its specific representation.
|
||||
///
|
||||
/// The specific representation deals with horizontal and vertical axes while
|
||||
/// the generic representation deals with main and cross axes.
|
||||
///
|
||||
/// See also [`ToGen`] for the inverse conversion.
|
||||
///
|
||||
/// [`ToGen`]: trait.ToGen.html
|
||||
pub trait ToSpec {
|
||||
/// The specific version of this type.
|
||||
type Output;
|
||||
|
||||
/// The specific version of this type based on the current directions.
|
||||
fn to_spec(self, dirs: Gen2<Dir>) -> Self::Output;
|
||||
}
|
||||
|
||||
/// The four directions into which content can be laid out.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum Dir {
|
||||
@ -81,38 +125,6 @@ impl Display for Dir {
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a type into its generic representation.
|
||||
///
|
||||
/// The generic representation deals with main and cross axes while the specific
|
||||
/// representation deals with horizontal and vertical axes.
|
||||
///
|
||||
/// See also [`ToSpec`] for the inverse conversion.
|
||||
///
|
||||
/// [`ToSpec`]: trait.ToSpec.html
|
||||
pub trait ToGen {
|
||||
/// The generic version of this type.
|
||||
type Output;
|
||||
|
||||
/// The generic version of this type based on the current directions.
|
||||
fn to_gen(self, dirs: Gen2<Dir>) -> Self::Output;
|
||||
}
|
||||
|
||||
/// Convert a type into its specific representation.
|
||||
///
|
||||
/// The specific representation deals with horizontal and vertical axes while
|
||||
/// the generic representation deals with main and cross axes.
|
||||
///
|
||||
/// See also [`ToGen`] for the inverse conversion.
|
||||
///
|
||||
/// [`ToGen`]: trait.ToGen.html
|
||||
pub trait ToSpec {
|
||||
/// The specific version of this type.
|
||||
type Output;
|
||||
|
||||
/// The specific version of this type based on the current directions.
|
||||
fn to_spec(self, dirs: Gen2<Dir>) -> Self::Output;
|
||||
}
|
||||
|
||||
/// A generic container with two components for the two generic axes.
|
||||
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
|
||||
pub struct Gen2<T> {
|
||||
@ -127,17 +139,19 @@ impl<T> Gen2<T> {
|
||||
pub fn new(main: T, cross: T) -> Self {
|
||||
Self { main, cross }
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the component for the specified generic axis.
|
||||
pub fn get(self, axis: GenAxis) -> T {
|
||||
impl<T> Get<GenAxis> for Gen2<T> {
|
||||
type Component = T;
|
||||
|
||||
fn get(self, axis: GenAxis) -> T {
|
||||
match axis {
|
||||
GenAxis::Main => self.main,
|
||||
GenAxis::Cross => self.cross,
|
||||
}
|
||||
}
|
||||
|
||||
/// Borrow the component for the specified generic axis mutably.
|
||||
pub fn get_mut(&mut self, axis: GenAxis) -> &mut T {
|
||||
fn get_mut(&mut self, axis: GenAxis) -> &mut T {
|
||||
match axis {
|
||||
GenAxis::Main => &mut self.main,
|
||||
GenAxis::Cross => &mut self.cross,
|
||||
@ -170,17 +184,19 @@ impl<T> Spec2<T> {
|
||||
pub fn new(horizontal: T, vertical: T) -> Self {
|
||||
Self { horizontal, vertical }
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the component for the given specific axis.
|
||||
pub fn get(self, axis: SpecAxis) -> T {
|
||||
impl<T> Get<SpecAxis> for Spec2<T> {
|
||||
type Component = T;
|
||||
|
||||
fn get(self, axis: SpecAxis) -> T {
|
||||
match axis {
|
||||
SpecAxis::Horizontal => self.horizontal,
|
||||
SpecAxis::Vertical => self.vertical,
|
||||
}
|
||||
}
|
||||
|
||||
/// Borrow the component for the given specific axis mutably.
|
||||
pub fn get_mut(&mut self, axis: SpecAxis) -> &mut T {
|
||||
fn get_mut(&mut self, axis: SpecAxis) -> &mut T {
|
||||
match axis {
|
||||
SpecAxis::Horizontal => &mut self.horizontal,
|
||||
SpecAxis::Vertical => &mut self.vertical,
|
||||
@ -416,9 +432,12 @@ impl<T> Sides<T> {
|
||||
bottom: value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the component for the given side.
|
||||
pub fn get(self, side: Side) -> T {
|
||||
impl<T> Get<Side> for Sides<T> {
|
||||
type Component = T;
|
||||
|
||||
fn get(self, side: Side) -> T {
|
||||
match side {
|
||||
Side::Left => self.left,
|
||||
Side::Top => self.top,
|
||||
@ -427,8 +446,7 @@ impl<T> Sides<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Borrow the component for the given side mutably.
|
||||
pub fn get_mut(&mut self, side: Side) -> &mut T {
|
||||
fn get_mut(&mut self, side: Side) -> &mut T {
|
||||
match side {
|
||||
Side::Left => &mut self.left,
|
||||
Side::Top => &mut self.top,
|
||||
|
Loading…
x
Reference in New Issue
Block a user