mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Remove Typesetter in favor of typeset function 🎯
This commit is contained in:
parent
262a8fa36a
commit
6672f8f7df
@ -3,10 +3,11 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
use criterion::{criterion_group, criterion_main, Criterion};
|
use criterion::{criterion_group, criterion_main, Criterion};
|
||||||
use fontdock::fs::{FsIndex, FsProvider};
|
use fontdock::fs::{FsIndex, FsProvider};
|
||||||
|
use futures_executor::block_on;
|
||||||
|
|
||||||
use typstc::font::FontLoader;
|
use typstc::font::FontLoader;
|
||||||
use typstc::parse::parse;
|
use typstc::parse::parse;
|
||||||
use typstc::Typesetter;
|
use typstc::typeset;
|
||||||
|
|
||||||
const FONT_DIR: &str = "fonts";
|
const FONT_DIR: &str = "fonts";
|
||||||
const COMA: &str = include_str!("../tests/coma.typ");
|
const COMA: &str = include_str!("../tests/coma.typ");
|
||||||
@ -23,9 +24,11 @@ fn typesetting_benchmark(c: &mut Criterion) {
|
|||||||
let provider = FsProvider::new(files);
|
let provider = FsProvider::new(files);
|
||||||
let loader = FontLoader::new(Box::new(provider), descriptors);
|
let loader = FontLoader::new(Box::new(provider), descriptors);
|
||||||
let loader = Rc::new(RefCell::new(loader));
|
let loader = Rc::new(RefCell::new(loader));
|
||||||
let typesetter = Typesetter::new(loader.clone());
|
|
||||||
|
let style = Default::default();
|
||||||
|
let scope = typstc::library::_std();
|
||||||
c.bench_function("typeset-coma", |b| {
|
c.bench_function("typeset-coma", |b| {
|
||||||
b.iter(|| futures_executor::block_on(typesetter.typeset(COMA)))
|
b.iter(|| block_on(typeset(COMA, &style, &scope, Rc::clone(&loader))))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ use futures_executor::block_on;
|
|||||||
use typstc::export::pdf;
|
use typstc::export::pdf;
|
||||||
use typstc::font::FontLoader;
|
use typstc::font::FontLoader;
|
||||||
use typstc::parse::LineMap;
|
use typstc::parse::LineMap;
|
||||||
use typstc::{Feedback, Pass, Typesetter};
|
use typstc::{typeset, Feedback, Pass};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Vec<_> = std::env::args().collect();
|
let args: Vec<_> = std::env::args().collect();
|
||||||
@ -41,11 +41,12 @@ fn main() {
|
|||||||
let loader = FontLoader::new(Box::new(provider), descriptors);
|
let loader = FontLoader::new(Box::new(provider), descriptors);
|
||||||
let loader = Rc::new(RefCell::new(loader));
|
let loader = Rc::new(RefCell::new(loader));
|
||||||
|
|
||||||
let typesetter = Typesetter::new(loader.clone());
|
let style = Default::default();
|
||||||
|
let scope = typstc::library::_std();
|
||||||
let Pass {
|
let Pass {
|
||||||
output: layouts,
|
output: layouts,
|
||||||
feedback: Feedback { mut diagnostics, .. },
|
feedback: Feedback { mut diagnostics, .. },
|
||||||
} = block_on(typesetter.typeset(&src));
|
} = block_on(typeset(&src, &style, &scope, Rc::clone(&loader)));
|
||||||
|
|
||||||
if !diagnostics.is_empty() {
|
if !diagnostics.is_empty() {
|
||||||
diagnostics.sort();
|
diagnostics.sort();
|
||||||
|
@ -14,8 +14,7 @@ use tide::{PdfWriter, Rect, Ref, Trailer, Version};
|
|||||||
use ttf_parser::{name_id, GlyphId};
|
use ttf_parser::{name_id, GlyphId};
|
||||||
|
|
||||||
use crate::font::FontLoader;
|
use crate::font::FontLoader;
|
||||||
use crate::layout::elements::LayoutElement;
|
use crate::layout::{BoxLayout, LayoutElement};
|
||||||
use crate::layout::BoxLayout;
|
|
||||||
use crate::length::Length;
|
use crate::length::Length;
|
||||||
|
|
||||||
/// Export a list of layouts into a _PDF_ document.
|
/// Export a list of layouts into a _PDF_ document.
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
//! Internally, the line layouter uses a stack layouter to stack the finished
|
//! Internally, the line layouter uses a stack layouter to stack the finished
|
||||||
//! lines on top of each.
|
//! lines on top of each.
|
||||||
|
|
||||||
use super::stack::{StackContext, StackLayouter};
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// Performs the line layouting.
|
/// Performs the line layouting.
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
//! Layouting of syntax trees into box layouts.
|
//! Layouting of syntax trees into box layouts.
|
||||||
|
|
||||||
pub mod elements;
|
|
||||||
pub mod line;
|
|
||||||
pub mod primitive;
|
pub mod primitive;
|
||||||
pub mod stack;
|
|
||||||
|
mod elements;
|
||||||
|
mod line;
|
||||||
|
mod stack;
|
||||||
mod tree;
|
mod tree;
|
||||||
|
|
||||||
|
pub use elements::*;
|
||||||
|
pub use line::*;
|
||||||
pub use primitive::*;
|
pub use primitive::*;
|
||||||
pub use tree::layout_tree as layout;
|
pub use stack::*;
|
||||||
|
pub use tree::*;
|
||||||
|
|
||||||
use crate::geom::{Insets, Point, Rect, RectExt, Sides, Size, SizeExt};
|
use crate::geom::{Insets, Point, Rect, RectExt, Sides, Size, SizeExt};
|
||||||
|
|
||||||
@ -15,8 +19,33 @@ use crate::eval::Scope;
|
|||||||
use crate::font::SharedFontLoader;
|
use crate::font::SharedFontLoader;
|
||||||
use crate::style::{LayoutStyle, PageStyle, TextStyle};
|
use crate::style::{LayoutStyle, PageStyle, TextStyle};
|
||||||
use crate::syntax::SynTree;
|
use crate::syntax::SynTree;
|
||||||
|
use crate::Pass;
|
||||||
|
|
||||||
use elements::LayoutElements;
|
/// Layout a syntax tree and return the produced layout.
|
||||||
|
pub async fn layout(
|
||||||
|
tree: &SynTree,
|
||||||
|
style: &LayoutStyle,
|
||||||
|
scope: &Scope,
|
||||||
|
loader: SharedFontLoader,
|
||||||
|
) -> Pass<MultiLayout> {
|
||||||
|
let space = LayoutSpace {
|
||||||
|
size: style.page.size,
|
||||||
|
insets: style.page.insets(),
|
||||||
|
expansion: LayoutExpansion::new(true, true),
|
||||||
|
};
|
||||||
|
tree::layout_tree(&tree, LayoutContext {
|
||||||
|
loader,
|
||||||
|
scope,
|
||||||
|
style,
|
||||||
|
base: space.usable(),
|
||||||
|
spaces: vec![space],
|
||||||
|
repeat: true,
|
||||||
|
sys: LayoutSystem::new(Dir::LTR, Dir::TTB),
|
||||||
|
align: LayoutAlign::new(GenAlign::Start, GenAlign::Start),
|
||||||
|
root: true,
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
/// A collection of layouts.
|
/// A collection of layouts.
|
||||||
pub type MultiLayout = Vec<BoxLayout>;
|
pub type MultiLayout = Vec<BoxLayout>;
|
||||||
@ -36,7 +65,7 @@ pub struct BoxLayout {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct LayoutContext<'a> {
|
pub struct LayoutContext<'a> {
|
||||||
/// The font loader to query fonts from when typesetting text.
|
/// The font loader to query fonts from when typesetting text.
|
||||||
pub loader: &'a SharedFontLoader,
|
pub loader: SharedFontLoader,
|
||||||
/// The function scope.
|
/// The function scope.
|
||||||
pub scope: &'a Scope,
|
pub scope: &'a Scope,
|
||||||
/// The style for pages and text.
|
/// The style for pages and text.
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! Layouting of syntax trees.
|
//! Layouting of syntax trees.
|
||||||
|
|
||||||
use super::line::{LineContext, LineLayouter};
|
use std::rc::Rc;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::shaping;
|
use crate::shaping;
|
||||||
use crate::style::LayoutStyle;
|
use crate::style::LayoutStyle;
|
||||||
@ -9,7 +10,7 @@ use crate::syntax::{
|
|||||||
};
|
};
|
||||||
use crate::{DynFuture, Feedback, Pass};
|
use crate::{DynFuture, Feedback, Pass};
|
||||||
|
|
||||||
/// Layout a syntax tree into a collection of boxes.
|
/// Layout a syntax tree in a given context.
|
||||||
pub async fn layout_tree(tree: &SynTree, ctx: LayoutContext<'_>) -> Pass<MultiLayout> {
|
pub async fn layout_tree(tree: &SynTree, ctx: LayoutContext<'_>) -> Pass<MultiLayout> {
|
||||||
let mut layouter = TreeLayouter::new(ctx);
|
let mut layouter = TreeLayouter::new(ctx);
|
||||||
layouter.layout_tree(tree).await;
|
layouter.layout_tree(tree).await;
|
||||||
@ -159,6 +160,7 @@ impl<'a> TreeLayouter<'a> {
|
|||||||
style: &self.style,
|
style: &self.style,
|
||||||
spaces: self.layouter.remaining(),
|
spaces: self.layouter.remaining(),
|
||||||
root: false,
|
root: false,
|
||||||
|
loader: Rc::clone(&self.ctx.loader),
|
||||||
..self.ctx
|
..self.ctx
|
||||||
};
|
};
|
||||||
|
|
||||||
|
79
src/lib.rs
79
src/lib.rs
@ -46,78 +46,21 @@ use std::pin::Pin;
|
|||||||
use crate::diagnostic::Diagnostic;
|
use crate::diagnostic::Diagnostic;
|
||||||
use crate::eval::{Scope, Value};
|
use crate::eval::{Scope, Value};
|
||||||
use crate::font::SharedFontLoader;
|
use crate::font::SharedFontLoader;
|
||||||
use crate::layout::{
|
use crate::layout::{Commands, MultiLayout};
|
||||||
layout, Commands, Dir, GenAlign, LayoutAlign, LayoutContext, LayoutExpansion,
|
use crate::style::LayoutStyle;
|
||||||
LayoutSpace, LayoutSystem, MultiLayout,
|
use crate::syntax::{Decoration, Offset, Pos, SpanVec};
|
||||||
};
|
|
||||||
use crate::style::{LayoutStyle, PageStyle, TextStyle};
|
|
||||||
use crate::syntax::{Decoration, Offset, Pos, SpanVec, SynTree};
|
|
||||||
|
|
||||||
/// Transforms source code into typesetted layouts.
|
/// Process source code directly into a collection of layouts.
|
||||||
///
|
pub async fn typeset(
|
||||||
/// A typesetter can be configured through various methods.
|
src: &str,
|
||||||
pub struct Typesetter {
|
style: &LayoutStyle,
|
||||||
/// The font loader shared by all typesetting processes.
|
scope: &Scope,
|
||||||
loader: SharedFontLoader,
|
loader: SharedFontLoader,
|
||||||
/// A scope that contains the standard library function definitions.
|
) -> Pass<MultiLayout> {
|
||||||
std: Scope,
|
let parsed = parse::parse(src);
|
||||||
/// The base layouting style.
|
let layouted = layout::layout(&parsed.output, style, scope, loader).await;
|
||||||
style: LayoutStyle,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Typesetter {
|
|
||||||
/// Create a new typesetter.
|
|
||||||
pub fn new(loader: SharedFontLoader) -> Self {
|
|
||||||
Self {
|
|
||||||
loader,
|
|
||||||
std: crate::library::_std(),
|
|
||||||
style: LayoutStyle::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the base text style.
|
|
||||||
pub fn set_text_style(&mut self, style: TextStyle) {
|
|
||||||
self.style.text = style;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the base page style.
|
|
||||||
pub fn set_page_style(&mut self, style: PageStyle) {
|
|
||||||
self.style.page = style;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parse source code into a syntax tree.
|
|
||||||
pub fn parse(&self, src: &str) -> Pass<SynTree> {
|
|
||||||
parse::parse(src)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Layout a syntax tree and return the produced layout.
|
|
||||||
pub async fn layout(&self, tree: &SynTree) -> Pass<MultiLayout> {
|
|
||||||
let space = LayoutSpace {
|
|
||||||
size: self.style.page.size,
|
|
||||||
insets: self.style.page.insets(),
|
|
||||||
expansion: LayoutExpansion::new(true, true),
|
|
||||||
};
|
|
||||||
layout(&tree, LayoutContext {
|
|
||||||
loader: &self.loader,
|
|
||||||
scope: &self.std,
|
|
||||||
style: &self.style,
|
|
||||||
base: space.usable(),
|
|
||||||
spaces: vec![space],
|
|
||||||
repeat: true,
|
|
||||||
sys: LayoutSystem::new(Dir::LTR, Dir::TTB),
|
|
||||||
align: LayoutAlign::new(GenAlign::Start, GenAlign::Start),
|
|
||||||
root: true,
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Process source code directly into a collection of layouts.
|
|
||||||
pub async fn typeset(&self, src: &str) -> Pass<MultiLayout> {
|
|
||||||
let parsed = self.parse(src);
|
|
||||||
let layouted = self.layout(&parsed.output).await;
|
|
||||||
let feedback = Feedback::merge(parsed.feedback, layouted.feedback);
|
let feedback = Feedback::merge(parsed.feedback, layouted.feedback);
|
||||||
Pass::new(layouted.output, feedback)
|
Pass::new(layouted.output, feedback)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A dynamic future type which allows recursive invocation of async functions
|
/// A dynamic future type which allows recursive invocation of async functions
|
||||||
|
@ -33,7 +33,7 @@ pub async fn boxed(
|
|||||||
ctx.spaces[0].expansion.vertical = true;
|
ctx.spaces[0].expansion.vertical = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let layouted = layout(&content, ctx).await;
|
let layouted = layout_tree(&content, ctx).await;
|
||||||
let layout = layouted.output.into_iter().next().unwrap();
|
let layout = layouted.output.into_iter().next().unwrap();
|
||||||
f.extend(layouted.feedback);
|
f.extend(layouted.feedback);
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
pub use crate::eval::{Dict, DictValue, Value};
|
pub use crate::eval::{Dict, DictValue, Value};
|
||||||
pub use crate::layout::primitive::*;
|
pub use crate::layout::primitive::*;
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
pub use crate::layout::{layout, Command, Commands, LayoutContext};
|
pub use crate::layout::{layout_tree, Command, Commands, LayoutContext};
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
pub use crate::syntax::{Span, Spanned, SynTree};
|
pub use crate::syntax::{Span, Spanned, SynTree};
|
||||||
pub use crate::{Feedback, Pass};
|
pub use crate::{Feedback, Pass};
|
||||||
|
@ -9,8 +9,7 @@ use ttf_parser::GlyphId;
|
|||||||
|
|
||||||
use crate::font::FontLoader;
|
use crate::font::FontLoader;
|
||||||
use crate::geom::{Point, Size};
|
use crate::geom::{Point, Size};
|
||||||
use crate::layout::elements::{LayoutElement, LayoutElements, Shaped};
|
use crate::layout::{BoxLayout, Dir, LayoutAlign, LayoutElement, LayoutElements, Shaped};
|
||||||
use crate::layout::{BoxLayout, Dir, LayoutAlign};
|
|
||||||
use crate::style::TextStyle;
|
use crate::style::TextStyle;
|
||||||
|
|
||||||
/// Shape text into a box.
|
/// Shape text into a box.
|
||||||
|
@ -13,14 +13,10 @@ use ttf_parser::OutlineBuilder;
|
|||||||
|
|
||||||
use typstc::export::pdf;
|
use typstc::export::pdf;
|
||||||
use typstc::font::{FontLoader, SharedFontLoader};
|
use typstc::font::{FontLoader, SharedFontLoader};
|
||||||
use typstc::geom::{Point, Sides, Size, Vec2};
|
use typstc::geom::{Point, Vec2};
|
||||||
use typstc::layout::elements::{LayoutElement, Shaped};
|
use typstc::layout::{LayoutElement, MultiLayout, Shaped};
|
||||||
use typstc::layout::MultiLayout;
|
|
||||||
use typstc::length::Length;
|
|
||||||
use typstc::paper::PaperClass;
|
|
||||||
use typstc::parse::LineMap;
|
use typstc::parse::LineMap;
|
||||||
use typstc::style::PageStyle;
|
use typstc::{typeset, Feedback, Pass};
|
||||||
use typstc::{Feedback, Pass, Typesetter};
|
|
||||||
|
|
||||||
const TEST_DIR: &str = "tests";
|
const TEST_DIR: &str = "tests";
|
||||||
const OUT_DIR: &str = "tests/out";
|
const OUT_DIR: &str = "tests/out";
|
||||||
@ -65,32 +61,20 @@ fn main() {
|
|||||||
let loader = FontLoader::new(Box::new(provider), descriptors);
|
let loader = FontLoader::new(Box::new(provider), descriptors);
|
||||||
let loader = Rc::new(RefCell::new(loader));
|
let loader = Rc::new(RefCell::new(loader));
|
||||||
|
|
||||||
let mut typesetter = Typesetter::new(loader.clone());
|
|
||||||
let edge = Length::pt(250.0).as_raw();
|
|
||||||
typesetter.set_page_style(PageStyle {
|
|
||||||
class: PaperClass::Custom,
|
|
||||||
size: Size::new(edge, edge),
|
|
||||||
margins: Sides::uniform(None),
|
|
||||||
});
|
|
||||||
|
|
||||||
for (name, path, src) in filtered {
|
for (name, path, src) in filtered {
|
||||||
test(&name, &src, &path, &mut typesetter, &loader)
|
test(&name, &src, &path, &loader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test(
|
fn test(name: &str, src: &str, src_path: &Path, loader: &SharedFontLoader) {
|
||||||
name: &str,
|
|
||||||
src: &str,
|
|
||||||
src_path: &Path,
|
|
||||||
typesetter: &mut Typesetter,
|
|
||||||
loader: &SharedFontLoader,
|
|
||||||
) {
|
|
||||||
println!("Testing {}.", name);
|
println!("Testing {}.", name);
|
||||||
|
|
||||||
|
let style = Default::default();
|
||||||
|
let scope = typstc::library::_std();
|
||||||
let Pass {
|
let Pass {
|
||||||
output: layouts,
|
output: layouts,
|
||||||
feedback: Feedback { mut diagnostics, .. },
|
feedback: Feedback { mut diagnostics, .. },
|
||||||
} = block_on(typesetter.typeset(&src));
|
} = block_on(typeset(&src, &style, &scope, Rc::clone(loader)));
|
||||||
|
|
||||||
if !diagnostics.is_empty() {
|
if !diagnostics.is_empty() {
|
||||||
diagnostics.sort();
|
diagnostics.sort();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user