Make pdf module top-level 🧱

This commit is contained in:
Laurenz 2021-03-24 21:48:25 +01:00
parent 73615f7e3c
commit e8057a5385
8 changed files with 29 additions and 26 deletions

View File

@ -4,10 +4,10 @@ use fontdock::FsIndex;
use typst::env::{Env, FsIndexExt, ResourceLoader};
use typst::eval::eval;
use typst::exec::{exec, State};
use typst::export::pdf;
use typst::layout::layout;
use typst::library;
use typst::parse::parse;
use typst::pdf;
use typst::typeset;
const FONT_DIR: &str = "../fonts";

View File

@ -1,3 +0,0 @@
//! Exporting into external formats.
pub mod pdf;

View File

@ -7,6 +7,7 @@ use fontdock::FaceFromVec;
/// An owned font face.
pub struct FaceBuf {
data: Box<[u8]>,
index: u32,
ttf: ttf_parser::Face<'static>,
buzz: rustybuzz::Face<'static>,
}
@ -17,6 +18,11 @@ impl FaceBuf {
&self.data
}
/// The collection index.
pub fn index(&self) -> u32 {
self.index
}
/// Get a reference to the underlying ttf-parser face.
pub fn ttf(&self) -> &ttf_parser::Face<'_> {
// We can't implement Deref because that would leak the internal 'static
@ -33,7 +39,7 @@ impl FaceBuf {
}
impl FaceFromVec for FaceBuf {
fn from_vec(vec: Vec<u8>, i: u32) -> Option<Self> {
fn from_vec(vec: Vec<u8>, index: u32) -> Option<Self> {
let data = vec.into_boxed_slice();
// SAFETY: The slices's location is stable in memory since we don't
@ -43,8 +49,9 @@ impl FaceFromVec for FaceBuf {
Some(Self {
data,
ttf: ttf_parser::Face::from_slice(slice, i).ok()?,
buzz: rustybuzz::Face::from_slice(slice, i)?,
index,
ttf: ttf_parser::Face::from_slice(slice, index).ok()?,
buzz: rustybuzz::Face::from_slice(slice, index)?,
})
}
}

View File

@ -5,12 +5,12 @@ use ttf_parser::GlyphId;
use super::{Element, Frame, ShapedText};
use crate::env::FontLoader;
use crate::exec::FontProps;
use crate::geom::{Length, Point, Size};
use crate::geom::{Point, Size};
/// Shape text into a frame containing shaped [`ShapedText`] runs.
/// Shape text into a frame containing [`ShapedText`] runs.
pub fn shape(text: &str, loader: &mut FontLoader, props: &FontProps) -> Frame {
let mut frame = Frame::new(Size::new(Length::ZERO, Length::ZERO));
shape_segment(&mut frame, text, props.families.iter(), None, loader, props);
let mut frame = Frame::new(Size::ZERO);
shape_segment(&mut frame, text, loader, props, props.families.iter(), None);
frame
}
@ -18,10 +18,10 @@ pub fn shape(text: &str, loader: &mut FontLoader, props: &FontProps) -> Frame {
fn shape_segment<'a>(
frame: &mut Frame,
text: &str,
mut families: impl Iterator<Item = &'a str> + Clone,
mut first: Option<FaceId>,
loader: &mut FontLoader,
props: &FontProps,
mut families: impl Iterator<Item = &'a str> + Clone,
mut first: Option<FaceId>,
) {
// Select the font family.
let (id, fallback) = loop {
@ -41,12 +41,12 @@ fn shape_segment<'a>(
};
// Register that this is the first available font.
let face = loader.face(id);
if first.is_none() {
first = Some(id);
}
// Find out some metrics and prepare the shaped text container.
let face = loader.face(id);
let ttf = face.ttf();
let units_per_em = f64::from(ttf.units_per_em().unwrap_or(1000));
let convert = |units| f64::from(units) / units_per_em * props.size;
@ -104,7 +104,7 @@ fn shape_segment<'a>(
let range = start .. end + offset;
// Recursively shape the tofu sequence with the next family.
shape_segment(frame, &text[range], families.clone(), first, loader, props);
shape_segment(frame, &text[range], loader, props, families.clone(), first);
} else {
// Add the glyph to the shaped output.
// TODO: Don't ignore y_advance and y_offset.

View File

@ -17,8 +17,7 @@
//! typeset document. The output of this is a collection of [`Frame`]s (one
//! per page), ready for exporting.
//! - **Exporting:** The finished layout can be exported into a supported
//! format. Submodules for these formats are located in the [export] module.
//! Currently, the only supported output format is [_PDF_].
//! format. Currently, the only supported output format is [PDF].
//!
//! [tokens]: parse::Tokens
//! [parsed]: parse::parse
@ -27,7 +26,7 @@
//! [execute]: exec::exec
//! [layout tree]: layout::Tree
//! [layouted]: layout::layout
//! [_PDF_]: export::pdf
//! [PDF]: pdf
#[macro_use]
pub mod diag;
@ -36,13 +35,13 @@ pub mod eval;
pub mod color;
pub mod env;
pub mod exec;
pub mod export;
pub mod font;
pub mod geom;
pub mod layout;
pub mod library;
pub mod paper;
pub mod parse;
pub mod pdf;
pub mod pretty;
pub mod syntax;
@ -52,7 +51,7 @@ use crate::eval::Scope;
use crate::exec::State;
use crate::layout::Frame;
/// Process _Typst_ source code directly into a collection of frames.
/// Process source code directly into a collection of frames.
pub fn typeset(
env: &mut Env,
src: &str,

View File

@ -7,9 +7,9 @@ use fontdock::FsIndex;
use typst::diag::Pass;
use typst::env::{Env, FsIndexExt, ResourceLoader};
use typst::exec::State;
use typst::export::pdf;
use typst::library;
use typst::parse::LineMap;
use typst::pdf;
use typst::typeset;
fn main() -> anyhow::Result<()> {

View File

@ -1,4 +1,4 @@
//! Exporting into _PDF_ documents.
//! Exporting into PDF documents.
use std::cmp::Eq;
use std::collections::HashMap;
@ -18,13 +18,13 @@ use crate::env::{Env, ImageResource, ResourceId};
use crate::geom::{self, Length, Size};
use crate::layout::{Element, Fill, Frame, Image, Shape};
/// Export a collection of frames into a _PDF_ document.
/// Export a collection of frames into a PDF document.
///
/// This creates one page per frame. In addition to the frames, you need to pass
/// in the environment used for typesetting such that things like fonts and
/// images can be included in the _PDF_.
/// images can be included in the PDF.
///
/// Returns the raw bytes making up the _PDF_ document.
/// Returns the raw bytes making up the PDF document.
pub fn export(env: &Env, frames: &[Frame]) -> Vec<u8> {
PdfExporter::new(env, frames).write()
}

View File

@ -19,11 +19,11 @@ use typst::diag::{Diag, DiagSet, Level, Pass};
use typst::env::{Env, FsIndexExt, ImageResource, ResourceLoader};
use typst::eval::{EvalContext, FuncArgs, FuncValue, Scope, Value};
use typst::exec::State;
use typst::export::pdf;
use typst::geom::{self, Length, Point, Sides, Size};
use typst::layout::{Element, Fill, Frame, Geometry, Image, Shape, ShapedText};
use typst::library;
use typst::parse::{LineMap, Scanner};
use typst::pdf;
use typst::pretty::pretty;
use typst::syntax::{Location, Pos};
use typst::typeset;