mirror of
https://github.com/typst/typst
synced 2025-05-13 12:36:23 +08:00
Tidy up PDF crate 🧹
This commit is contained in:
parent
67281c4f46
commit
77e5299667
@ -1,9 +1,9 @@
|
|||||||
//! Font utility and subsetting.
|
//! Font utility and subsetting.
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::error;
|
use std::error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::{self, Cursor, Seek, SeekFrom};
|
use std::io::{self, Cursor, Seek, SeekFrom};
|
||||||
use std::collections::HashMap;
|
|
||||||
use byteorder::{BE, ReadBytesExt, WriteBytesExt};
|
use byteorder::{BE, ReadBytesExt, WriteBytesExt};
|
||||||
use opentype::{OpenTypeReader, Outlines, TableRecord, Tag};
|
use opentype::{OpenTypeReader, Outlines, TableRecord, Tag};
|
||||||
use opentype::tables::{Header, Name, NameEntry, CharMap, MaximumProfile, HorizontalMetrics, OS2};
|
use opentype::tables::{Header, Name, NameEntry, CharMap, MaximumProfile, HorizontalMetrics, OS2};
|
||||||
@ -49,11 +49,13 @@ impl Font {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Map a character to it's glyph index.
|
/// Map a character to it's glyph index.
|
||||||
|
#[inline]
|
||||||
pub fn map(&self, c: char) -> u16 {
|
pub fn map(&self, c: char) -> u16 {
|
||||||
self.mapping.get(&c).map(|&g| g).unwrap_or(self.default_glyph)
|
self.mapping.get(&c).map(|&g| g).unwrap_or(self.default_glyph)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encode the given text for our font (into glyph ids).
|
/// Encode the given text for our font (into glyph ids).
|
||||||
|
#[inline]
|
||||||
pub fn encode(&self, text: &str) -> Vec<u8> {
|
pub fn encode(&self, text: &str) -> Vec<u8> {
|
||||||
println!("encoding {} with {:?}", text, self.mapping);
|
println!("encoding {} with {:?}", text, self.mapping);
|
||||||
let mut bytes = Vec::with_capacity(2 * text.len());
|
let mut bytes = Vec::with_capacity(2 * text.len());
|
||||||
@ -457,7 +459,8 @@ impl<'p> Subsetter<'p> {
|
|||||||
Err(_) => return Err(SubsettingError::MissingTable(tag.to_string())),
|
Err(_) => return Err(SubsettingError::MissingTable(tag.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.font.program.get(record.offset as usize .. (record.offset + record.length) as usize)
|
self.font.program
|
||||||
|
.get(record.offset as usize .. (record.offset + record.length) as usize)
|
||||||
.take_bytes()
|
.take_bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -552,6 +555,7 @@ pub enum SubsettingError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl error::Error for SubsettingError {
|
impl error::Error for SubsettingError {
|
||||||
|
#[inline]
|
||||||
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
||||||
match self {
|
match self {
|
||||||
SubsettingError::Opentype(err) => Some(err),
|
SubsettingError::Opentype(err) => Some(err),
|
||||||
|
@ -87,6 +87,7 @@ enum TokensState<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for TokensState<'_> {
|
impl PartialEq for TokensState<'_> {
|
||||||
|
#[inline]
|
||||||
fn eq(&self, other: &TokensState) -> bool {
|
fn eq(&self, other: &TokensState) -> bool {
|
||||||
use TokensState as TS;
|
use TokensState as TS;
|
||||||
|
|
||||||
@ -262,6 +263,7 @@ pub struct SyntaxTree<'s> {
|
|||||||
|
|
||||||
impl<'s> SyntaxTree<'s> {
|
impl<'s> SyntaxTree<'s> {
|
||||||
/// Create an empty syntax tree.
|
/// Create an empty syntax tree.
|
||||||
|
#[inline]
|
||||||
pub fn new() -> SyntaxTree<'s> {
|
pub fn new() -> SyntaxTree<'s> {
|
||||||
SyntaxTree { nodes: vec![] }
|
SyntaxTree { nodes: vec![] }
|
||||||
}
|
}
|
||||||
|
39
src/pdf.rs
39
src/pdf.rs
@ -1,15 +1,12 @@
|
|||||||
//! Writing of documents in the _PDF_ format.
|
//! Writing of documents in the _PDF_ format.
|
||||||
|
|
||||||
|
use std::collections::HashSet;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::{self, Write, Cursor};
|
use std::io::{self, Write, Cursor};
|
||||||
use std::collections::HashSet;
|
use pdf::{PdfWriter, Reference, Rect, Version, Trailer};
|
||||||
use pdf::{PdfWriter, Id, Rect, Version, Trailer};
|
use pdf::{Catalog, PageTree, Page, Resource, Text, Content};
|
||||||
use pdf::doc::{Catalog, PageTree, Page, Resource, Content};
|
use pdf::font::{Type0Font, CMapEncoding, CIDFont, CIDFontType, CIDSystemInfo, WidthRecord,
|
||||||
use pdf::text::Text;
|
FontDescriptor, FontFlags, EmbeddedFont, GlyphUnit};
|
||||||
use pdf::font::{
|
|
||||||
Type0Font, CMapEncoding, CIDFont, CIDFontType, CIDSystemInfo,
|
|
||||||
WidthRecord, FontDescriptor, FontFlags, EmbeddedFont, GlyphUnit
|
|
||||||
};
|
|
||||||
use opentype::{OpenTypeReader, tables::{self, MacStyleFlags}};
|
use opentype::{OpenTypeReader, tables::{self, MacStyleFlags}};
|
||||||
use crate::doc::{self, Document, TextCommand};
|
use crate::doc::{self, Document, TextCommand};
|
||||||
use crate::font::Font;
|
use crate::font::Font;
|
||||||
@ -22,6 +19,7 @@ pub trait WritePdf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<W: Write> WritePdf for W {
|
impl<W: Write> WritePdf for W {
|
||||||
|
#[inline]
|
||||||
fn write_pdf(&mut self, doc: &Document) -> PdfResult<usize> {
|
fn write_pdf(&mut self, doc: &Document) -> PdfResult<usize> {
|
||||||
PdfCreator::new(self, doc)?.write()
|
PdfCreator::new(self, doc)?.write()
|
||||||
}
|
}
|
||||||
@ -38,26 +36,30 @@ pub struct PdfWritingError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<io::Error> for PdfWritingError {
|
impl From<io::Error> for PdfWritingError {
|
||||||
|
#[inline]
|
||||||
fn from(err: io::Error) -> PdfWritingError {
|
fn from(err: io::Error) -> PdfWritingError {
|
||||||
PdfWritingError { message: format!("io error: {}", err) }
|
PdfWritingError { message: format!("{}", err) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<opentype::Error> for PdfWritingError {
|
impl From<opentype::Error> for PdfWritingError {
|
||||||
|
#[inline]
|
||||||
fn from(err: opentype::Error) -> PdfWritingError {
|
fn from(err: opentype::Error) -> PdfWritingError {
|
||||||
PdfWritingError { message: format!("{}", err) }
|
PdfWritingError { message: format!("{}", err) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<crate::font::SubsettingError> for PdfWritingError {
|
impl From<crate::font::SubsettingError> for PdfWritingError {
|
||||||
|
#[inline]
|
||||||
fn from(err: crate::font::SubsettingError) -> PdfWritingError {
|
fn from(err: crate::font::SubsettingError) -> PdfWritingError {
|
||||||
PdfWritingError { message: format!("{}", err) }
|
PdfWritingError { message: format!("{}", err) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for PdfWritingError {
|
impl fmt::Display for PdfWritingError {
|
||||||
|
#[inline]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "pdf writing error: {}", self.message)
|
f.write_str(&self.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,11 +75,11 @@ struct PdfCreator<'a, W: Write> {
|
|||||||
|
|
||||||
/// Offsets for the various groups of ids.
|
/// Offsets for the various groups of ids.
|
||||||
struct Offsets {
|
struct Offsets {
|
||||||
catalog: Id,
|
catalog: Reference,
|
||||||
page_tree: Id,
|
page_tree: Reference,
|
||||||
pages: (Id, Id),
|
pages: (Reference, Reference),
|
||||||
contents: (Id, Id),
|
contents: (Reference, Reference),
|
||||||
fonts: (Id, Id),
|
fonts: (Reference, Reference),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, W: Write> PdfCreator<'a, W> {
|
impl<'a, W: Write> PdfCreator<'a, W> {
|
||||||
@ -86,10 +88,10 @@ impl<'a, W: Write> PdfCreator<'a, W> {
|
|||||||
// Calculate a unique id for all object to come
|
// Calculate a unique id for all object to come
|
||||||
let catalog = 1;
|
let catalog = 1;
|
||||||
let page_tree = catalog + 1;
|
let page_tree = catalog + 1;
|
||||||
let pages = (page_tree + 1, page_tree + doc.pages.len() as Id);
|
let pages = (page_tree + 1, page_tree + doc.pages.len() as Reference);
|
||||||
let content_count = doc.pages.iter().flat_map(|p| p.text.iter()).count() as Id;
|
let content_count = doc.pages.iter().flat_map(|p| p.text.iter()).count() as Reference;
|
||||||
let contents = (pages.1 + 1, pages.1 + content_count);
|
let contents = (pages.1 + 1, pages.1 + content_count);
|
||||||
let fonts = (contents.1 + 1, contents.1 + 4 * doc.fonts.len() as Id);
|
let fonts = (contents.1 + 1, contents.1 + 4 * doc.fonts.len() as Reference);
|
||||||
|
|
||||||
let offsets = Offsets {
|
let offsets = Offsets {
|
||||||
catalog,
|
catalog,
|
||||||
@ -338,6 +340,7 @@ impl PdfFont {
|
|||||||
impl std::ops::Deref for PdfFont {
|
impl std::ops::Deref for PdfFont {
|
||||||
type Target = Font;
|
type Target = Font;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn deref(&self) -> &Font {
|
fn deref(&self) -> &Font {
|
||||||
&self.font
|
&self.font
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Utility functionality.
|
//! Utility functionality.
|
||||||
|
|
||||||
use std::str::Split;
|
|
||||||
use std::iter::Peekable;
|
use std::iter::Peekable;
|
||||||
|
use std::str::Split;
|
||||||
use unicode_xid::UnicodeXID;
|
use unicode_xid::UnicodeXID;
|
||||||
|
|
||||||
|
|
||||||
@ -29,6 +29,7 @@ pub trait Splinor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Splinor for str {
|
impl Splinor for str {
|
||||||
|
#[inline]
|
||||||
fn spline<'s, T: Clone>(&'s self, pat: &'s str, splinor: T) -> Spline<'s, T> {
|
fn spline<'s, T: Clone>(&'s self, pat: &'s str, splinor: T) -> Spline<'s, T> {
|
||||||
Spline {
|
Spline {
|
||||||
splinor: Splined::Splinor(splinor),
|
splinor: Splined::Splinor(splinor),
|
||||||
@ -60,6 +61,7 @@ pub enum Splined<'s, T> {
|
|||||||
impl<'s, T: Clone> Iterator for Spline<'s, T> {
|
impl<'s, T: Clone> Iterator for Spline<'s, T> {
|
||||||
type Item = Splined<'s, T>;
|
type Item = Splined<'s, T>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn next(&mut self) -> Option<Splined<'s, T>> {
|
fn next(&mut self) -> Option<Splined<'s, T>> {
|
||||||
if self.next_splinor && self.split.peek().is_some() {
|
if self.next_splinor && self.split.peek().is_some() {
|
||||||
self.next_splinor = false;
|
self.next_splinor = false;
|
||||||
@ -87,6 +89,7 @@ impl StrExt for str {
|
|||||||
self.chars().all(|c| c.is_whitespace() && c != '\n')
|
self.chars().all(|c| c.is_whitespace() && c != '\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn is_identifier(&self) -> bool {
|
fn is_identifier(&self) -> bool {
|
||||||
let mut chars = self.chars();
|
let mut chars = self.chars();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user