mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +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 fontdock::fs::{FsIndex, FsProvider};
|
||||
use futures_executor::block_on;
|
||||
|
||||
use typstc::font::FontLoader;
|
||||
use typstc::parse::parse;
|
||||
use typstc::Typesetter;
|
||||
use typstc::typeset;
|
||||
|
||||
const FONT_DIR: &str = "fonts";
|
||||
const COMA: &str = include_str!("../tests/coma.typ");
|
||||
@ -23,9 +24,11 @@ fn typesetting_benchmark(c: &mut Criterion) {
|
||||
let provider = FsProvider::new(files);
|
||||
let loader = FontLoader::new(Box::new(provider), descriptors);
|
||||
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| {
|
||||
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::font::FontLoader;
|
||||
use typstc::parse::LineMap;
|
||||
use typstc::{Feedback, Pass, Typesetter};
|
||||
use typstc::{typeset, Feedback, Pass};
|
||||
|
||||
fn main() {
|
||||
let args: Vec<_> = std::env::args().collect();
|
||||
@ -41,11 +41,12 @@ fn main() {
|
||||
let loader = FontLoader::new(Box::new(provider), descriptors);
|
||||
let loader = Rc::new(RefCell::new(loader));
|
||||
|
||||
let typesetter = Typesetter::new(loader.clone());
|
||||
let style = Default::default();
|
||||
let scope = typstc::library::_std();
|
||||
let Pass {
|
||||
output: layouts,
|
||||
feedback: Feedback { mut diagnostics, .. },
|
||||
} = block_on(typesetter.typeset(&src));
|
||||
} = block_on(typeset(&src, &style, &scope, Rc::clone(&loader)));
|
||||
|
||||
if !diagnostics.is_empty() {
|
||||
diagnostics.sort();
|
||||
|
@ -14,8 +14,7 @@ use tide::{PdfWriter, Rect, Ref, Trailer, Version};
|
||||
use ttf_parser::{name_id, GlyphId};
|
||||
|
||||
use crate::font::FontLoader;
|
||||
use crate::layout::elements::LayoutElement;
|
||||
use crate::layout::BoxLayout;
|
||||
use crate::layout::{BoxLayout, LayoutElement};
|
||||
use crate::length::Length;
|
||||
|
||||
/// 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
|
||||
//! lines on top of each.
|
||||
|
||||
use super::stack::{StackContext, StackLayouter};
|
||||
use super::*;
|
||||
|
||||
/// Performs the line layouting.
|
||||
|
@ -1,13 +1,17 @@
|
||||
//! Layouting of syntax trees into box layouts.
|
||||
|
||||
pub mod elements;
|
||||
pub mod line;
|
||||
pub mod primitive;
|
||||
pub mod stack;
|
||||
|
||||
mod elements;
|
||||
mod line;
|
||||
mod stack;
|
||||
mod tree;
|
||||
|
||||
pub use elements::*;
|
||||
pub use line::*;
|
||||
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};
|
||||
|
||||
@ -15,8 +19,33 @@ use crate::eval::Scope;
|
||||
use crate::font::SharedFontLoader;
|
||||
use crate::style::{LayoutStyle, PageStyle, TextStyle};
|
||||
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.
|
||||
pub type MultiLayout = Vec<BoxLayout>;
|
||||
@ -36,7 +65,7 @@ pub struct BoxLayout {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LayoutContext<'a> {
|
||||
/// The font loader to query fonts from when typesetting text.
|
||||
pub loader: &'a SharedFontLoader,
|
||||
pub loader: SharedFontLoader,
|
||||
/// The function scope.
|
||||
pub scope: &'a Scope,
|
||||
/// The style for pages and text.
|
||||
|
@ -1,6 +1,7 @@
|
||||
//! Layouting of syntax trees.
|
||||
|
||||
use super::line::{LineContext, LineLayouter};
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::*;
|
||||
use crate::shaping;
|
||||
use crate::style::LayoutStyle;
|
||||
@ -9,7 +10,7 @@ use crate::syntax::{
|
||||
};
|
||||
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> {
|
||||
let mut layouter = TreeLayouter::new(ctx);
|
||||
layouter.layout_tree(tree).await;
|
||||
@ -159,6 +160,7 @@ impl<'a> TreeLayouter<'a> {
|
||||
style: &self.style,
|
||||
spaces: self.layouter.remaining(),
|
||||
root: false,
|
||||
loader: Rc::clone(&self.ctx.loader),
|
||||
..self.ctx
|
||||
};
|
||||
|
||||
|
83
src/lib.rs
83
src/lib.rs
@ -46,78 +46,21 @@ use std::pin::Pin;
|
||||
use crate::diagnostic::Diagnostic;
|
||||
use crate::eval::{Scope, Value};
|
||||
use crate::font::SharedFontLoader;
|
||||
use crate::layout::{
|
||||
layout, Commands, Dir, GenAlign, LayoutAlign, LayoutContext, LayoutExpansion,
|
||||
LayoutSpace, LayoutSystem, MultiLayout,
|
||||
};
|
||||
use crate::style::{LayoutStyle, PageStyle, TextStyle};
|
||||
use crate::syntax::{Decoration, Offset, Pos, SpanVec, SynTree};
|
||||
use crate::layout::{Commands, MultiLayout};
|
||||
use crate::style::LayoutStyle;
|
||||
use crate::syntax::{Decoration, Offset, Pos, SpanVec};
|
||||
|
||||
/// Transforms source code into typesetted layouts.
|
||||
///
|
||||
/// A typesetter can be configured through various methods.
|
||||
pub struct Typesetter {
|
||||
/// The font loader shared by all typesetting processes.
|
||||
/// Process source code directly into a collection of layouts.
|
||||
pub async fn typeset(
|
||||
src: &str,
|
||||
style: &LayoutStyle,
|
||||
scope: &Scope,
|
||||
loader: SharedFontLoader,
|
||||
/// A scope that contains the standard library function definitions.
|
||||
std: Scope,
|
||||
/// The base layouting style.
|
||||
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);
|
||||
Pass::new(layouted.output, feedback)
|
||||
}
|
||||
) -> Pass<MultiLayout> {
|
||||
let parsed = parse::parse(src);
|
||||
let layouted = layout::layout(&parsed.output, style, scope, loader).await;
|
||||
let feedback = Feedback::merge(parsed.feedback, layouted.feedback);
|
||||
Pass::new(layouted.output, feedback)
|
||||
}
|
||||
|
||||
/// 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;
|
||||
}
|
||||
|
||||
let layouted = layout(&content, ctx).await;
|
||||
let layouted = layout_tree(&content, ctx).await;
|
||||
let layout = layouted.output.into_iter().next().unwrap();
|
||||
f.extend(layouted.feedback);
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
pub use crate::eval::{Dict, DictValue, Value};
|
||||
pub use crate::layout::primitive::*;
|
||||
#[doc(no_inline)]
|
||||
pub use crate::layout::{layout, Command, Commands, LayoutContext};
|
||||
pub use crate::layout::{layout_tree, Command, Commands, LayoutContext};
|
||||
#[doc(no_inline)]
|
||||
pub use crate::syntax::{Span, Spanned, SynTree};
|
||||
pub use crate::{Feedback, Pass};
|
||||
|
@ -9,8 +9,7 @@ use ttf_parser::GlyphId;
|
||||
|
||||
use crate::font::FontLoader;
|
||||
use crate::geom::{Point, Size};
|
||||
use crate::layout::elements::{LayoutElement, LayoutElements, Shaped};
|
||||
use crate::layout::{BoxLayout, Dir, LayoutAlign};
|
||||
use crate::layout::{BoxLayout, Dir, LayoutAlign, LayoutElement, LayoutElements, Shaped};
|
||||
use crate::style::TextStyle;
|
||||
|
||||
/// Shape text into a box.
|
||||
|
@ -13,14 +13,10 @@ use ttf_parser::OutlineBuilder;
|
||||
|
||||
use typstc::export::pdf;
|
||||
use typstc::font::{FontLoader, SharedFontLoader};
|
||||
use typstc::geom::{Point, Sides, Size, Vec2};
|
||||
use typstc::layout::elements::{LayoutElement, Shaped};
|
||||
use typstc::layout::MultiLayout;
|
||||
use typstc::length::Length;
|
||||
use typstc::paper::PaperClass;
|
||||
use typstc::geom::{Point, Vec2};
|
||||
use typstc::layout::{LayoutElement, MultiLayout, Shaped};
|
||||
use typstc::parse::LineMap;
|
||||
use typstc::style::PageStyle;
|
||||
use typstc::{Feedback, Pass, Typesetter};
|
||||
use typstc::{typeset, Feedback, Pass};
|
||||
|
||||
const TEST_DIR: &str = "tests";
|
||||
const OUT_DIR: &str = "tests/out";
|
||||
@ -65,32 +61,20 @@ fn main() {
|
||||
let loader = FontLoader::new(Box::new(provider), descriptors);
|
||||
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 {
|
||||
test(&name, &src, &path, &mut typesetter, &loader)
|
||||
test(&name, &src, &path, &loader)
|
||||
}
|
||||
}
|
||||
|
||||
fn test(
|
||||
name: &str,
|
||||
src: &str,
|
||||
src_path: &Path,
|
||||
typesetter: &mut Typesetter,
|
||||
loader: &SharedFontLoader,
|
||||
) {
|
||||
fn test(name: &str, src: &str, src_path: &Path, loader: &SharedFontLoader) {
|
||||
println!("Testing {}.", name);
|
||||
|
||||
let style = Default::default();
|
||||
let scope = typstc::library::_std();
|
||||
let Pass {
|
||||
output: layouts,
|
||||
feedback: Feedback { mut diagnostics, .. },
|
||||
} = block_on(typesetter.typeset(&src));
|
||||
} = block_on(typeset(&src, &style, &scope, Rc::clone(loader)));
|
||||
|
||||
if !diagnostics.is_empty() {
|
||||
diagnostics.sort();
|
||||
|
Loading…
x
Reference in New Issue
Block a user