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::env::{Env, FsIndexExt, ResourceLoader};
use typst::eval::eval; use typst::eval::eval;
use typst::exec::{exec, State}; use typst::exec::{exec, State};
use typst::export::pdf;
use typst::layout::layout; use typst::layout::layout;
use typst::library; use typst::library;
use typst::parse::parse; use typst::parse::parse;
use typst::pdf;
use typst::typeset; use typst::typeset;
const FONT_DIR: &str = "../fonts"; 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. /// An owned font face.
pub struct FaceBuf { pub struct FaceBuf {
data: Box<[u8]>, data: Box<[u8]>,
index: u32,
ttf: ttf_parser::Face<'static>, ttf: ttf_parser::Face<'static>,
buzz: rustybuzz::Face<'static>, buzz: rustybuzz::Face<'static>,
} }
@ -17,6 +18,11 @@ impl FaceBuf {
&self.data &self.data
} }
/// The collection index.
pub fn index(&self) -> u32 {
self.index
}
/// Get a reference to the underlying ttf-parser face. /// Get a reference to the underlying ttf-parser face.
pub fn ttf(&self) -> &ttf_parser::Face<'_> { pub fn ttf(&self) -> &ttf_parser::Face<'_> {
// We can't implement Deref because that would leak the internal 'static // We can't implement Deref because that would leak the internal 'static
@ -33,7 +39,7 @@ impl FaceBuf {
} }
impl FaceFromVec for 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(); let data = vec.into_boxed_slice();
// SAFETY: The slices's location is stable in memory since we don't // SAFETY: The slices's location is stable in memory since we don't
@ -43,8 +49,9 @@ impl FaceFromVec for FaceBuf {
Some(Self { Some(Self {
data, data,
ttf: ttf_parser::Face::from_slice(slice, i).ok()?, index,
buzz: rustybuzz::Face::from_slice(slice, i)?, 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 super::{Element, Frame, ShapedText};
use crate::env::FontLoader; use crate::env::FontLoader;
use crate::exec::FontProps; 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 { pub fn shape(text: &str, loader: &mut FontLoader, props: &FontProps) -> Frame {
let mut frame = Frame::new(Size::new(Length::ZERO, Length::ZERO)); let mut frame = Frame::new(Size::ZERO);
shape_segment(&mut frame, text, props.families.iter(), None, loader, props); shape_segment(&mut frame, text, loader, props, props.families.iter(), None);
frame frame
} }
@ -18,10 +18,10 @@ pub fn shape(text: &str, loader: &mut FontLoader, props: &FontProps) -> Frame {
fn shape_segment<'a>( fn shape_segment<'a>(
frame: &mut Frame, frame: &mut Frame,
text: &str, text: &str,
mut families: impl Iterator<Item = &'a str> + Clone,
mut first: Option<FaceId>,
loader: &mut FontLoader, loader: &mut FontLoader,
props: &FontProps, props: &FontProps,
mut families: impl Iterator<Item = &'a str> + Clone,
mut first: Option<FaceId>,
) { ) {
// Select the font family. // Select the font family.
let (id, fallback) = loop { let (id, fallback) = loop {
@ -41,12 +41,12 @@ fn shape_segment<'a>(
}; };
// Register that this is the first available font. // Register that this is the first available font.
let face = loader.face(id);
if first.is_none() { if first.is_none() {
first = Some(id); first = Some(id);
} }
// Find out some metrics and prepare the shaped text container. // Find out some metrics and prepare the shaped text container.
let face = loader.face(id);
let ttf = face.ttf(); let ttf = face.ttf();
let units_per_em = f64::from(ttf.units_per_em().unwrap_or(1000)); let units_per_em = f64::from(ttf.units_per_em().unwrap_or(1000));
let convert = |units| f64::from(units) / units_per_em * props.size; let convert = |units| f64::from(units) / units_per_em * props.size;
@ -104,7 +104,7 @@ fn shape_segment<'a>(
let range = start .. end + offset; let range = start .. end + offset;
// Recursively shape the tofu sequence with the next family. // 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 { } else {
// Add the glyph to the shaped output. // Add the glyph to the shaped output.
// TODO: Don't ignore y_advance and y_offset. // 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 //! typeset document. The output of this is a collection of [`Frame`]s (one
//! per page), ready for exporting. //! per page), ready for exporting.
//! - **Exporting:** The finished layout can be exported into a supported //! - **Exporting:** The finished layout can be exported into a supported
//! format. Submodules for these formats are located in the [export] module. //! format. Currently, the only supported output format is [PDF].
//! Currently, the only supported output format is [_PDF_].
//! //!
//! [tokens]: parse::Tokens //! [tokens]: parse::Tokens
//! [parsed]: parse::parse //! [parsed]: parse::parse
@ -27,7 +26,7 @@
//! [execute]: exec::exec //! [execute]: exec::exec
//! [layout tree]: layout::Tree //! [layout tree]: layout::Tree
//! [layouted]: layout::layout //! [layouted]: layout::layout
//! [_PDF_]: export::pdf //! [PDF]: pdf
#[macro_use] #[macro_use]
pub mod diag; pub mod diag;
@ -36,13 +35,13 @@ pub mod eval;
pub mod color; pub mod color;
pub mod env; pub mod env;
pub mod exec; pub mod exec;
pub mod export;
pub mod font; pub mod font;
pub mod geom; pub mod geom;
pub mod layout; pub mod layout;
pub mod library; pub mod library;
pub mod paper; pub mod paper;
pub mod parse; pub mod parse;
pub mod pdf;
pub mod pretty; pub mod pretty;
pub mod syntax; pub mod syntax;
@ -52,7 +51,7 @@ use crate::eval::Scope;
use crate::exec::State; use crate::exec::State;
use crate::layout::Frame; 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( pub fn typeset(
env: &mut Env, env: &mut Env,
src: &str, src: &str,

View File

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

View File

@ -1,4 +1,4 @@
//! Exporting into _PDF_ documents. //! Exporting into PDF documents.
use std::cmp::Eq; use std::cmp::Eq;
use std::collections::HashMap; use std::collections::HashMap;
@ -18,13 +18,13 @@ use crate::env::{Env, ImageResource, ResourceId};
use crate::geom::{self, Length, Size}; use crate::geom::{self, Length, Size};
use crate::layout::{Element, Fill, Frame, Image, Shape}; 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 /// 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 /// 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> { pub fn export(env: &Env, frames: &[Frame]) -> Vec<u8> {
PdfExporter::new(env, frames).write() 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::env::{Env, FsIndexExt, ImageResource, ResourceLoader};
use typst::eval::{EvalContext, FuncArgs, FuncValue, Scope, Value}; use typst::eval::{EvalContext, FuncArgs, FuncValue, Scope, Value};
use typst::exec::State; use typst::exec::State;
use typst::export::pdf;
use typst::geom::{self, Length, Point, Sides, Size}; use typst::geom::{self, Length, Point, Sides, Size};
use typst::layout::{Element, Fill, Frame, Geometry, Image, Shape, ShapedText}; use typst::layout::{Element, Fill, Frame, Geometry, Image, Shape, ShapedText};
use typst::library; use typst::library;
use typst::parse::{LineMap, Scanner}; use typst::parse::{LineMap, Scanner};
use typst::pdf;
use typst::pretty::pretty; use typst::pretty::pretty;
use typst::syntax::{Location, Pos}; use typst::syntax::{Location, Pos};
use typst::typeset; use typst::typeset;