Remove Typesetter in favor of typeset function 🎯

This commit is contained in:
Laurenz 2020-10-04 18:18:55 +02:00
parent 262a8fa36a
commit 6672f8f7df
11 changed files with 74 additions and 115 deletions

View File

@ -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))))
});
}

View File

@ -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();

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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
};

View File

@ -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

View File

@ -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);

View File

@ -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};

View File

@ -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.

View File

@ -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();