Refactor font providing ⚙
This commit is contained in:
parent
db96ecae94
commit
e6e5aad7ce
@ -5,7 +5,7 @@ use crate::engine::Size;
|
||||
|
||||
|
||||
/// A complete typesetted document, which can be exported.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Document {
|
||||
/// The pages of the document.
|
||||
pub pages: Vec<Page>,
|
||||
@ -14,7 +14,7 @@ pub struct Document {
|
||||
}
|
||||
|
||||
/// A page with text contents in a document.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Page {
|
||||
/// The width of the page.
|
||||
pub width: Size,
|
||||
@ -25,14 +25,14 @@ pub struct Page {
|
||||
}
|
||||
|
||||
/// A series of text command, that can be written on to a page.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Text {
|
||||
/// The text commands.
|
||||
pub commands: Vec<TextCommand>,
|
||||
}
|
||||
|
||||
/// Different commands for rendering text.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum TextCommand {
|
||||
/// Writing of the text.
|
||||
Text(String),
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use crate::syntax::{SyntaxTree, Node};
|
||||
use crate::doc::{Document, Page, Text, TextCommand};
|
||||
use crate::font::{Font, FontFamily, FontConfig, FontError};
|
||||
use crate::font::{Font, FontFamily, FontFilter, FontError};
|
||||
use crate::Context;
|
||||
|
||||
mod size;
|
||||
@ -41,13 +41,18 @@ impl<'a> Engine<'a> {
|
||||
pub fn typeset(mut self) -> TypeResult<Document> {
|
||||
// Load font defined by style
|
||||
let mut font = None;
|
||||
let config = FontConfig::new(self.ctx.style.font_families.clone());
|
||||
let filter = FontFilter::new(&self.ctx.style.font_families);
|
||||
for provider in &self.ctx.font_providers {
|
||||
if let Some(mut source) = provider.provide(&config) {
|
||||
let mut program = Vec::new();
|
||||
source.read_to_end(&mut program)?;
|
||||
font = Some(Font::new(program)?);
|
||||
break;
|
||||
let available = provider.available();
|
||||
for info in available {
|
||||
if filter.matches(info) {
|
||||
if let Some(mut source) = provider.get(info) {
|
||||
let mut program = Vec::new();
|
||||
source.read_to_end(&mut program)?;
|
||||
font = Some(Font::new(program)?);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,7 +146,7 @@ impl<'a> Engine<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Default styles for a document.
|
||||
/// Default styles for typesetting.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Style {
|
||||
/// The width of the paper.
|
||||
|
@ -4,7 +4,7 @@ use std::iter::Sum;
|
||||
use std::ops::*;
|
||||
|
||||
|
||||
/// A general distance type that can convert between units.
|
||||
/// A general size (unit of length) type.
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub struct Size {
|
||||
/// The size in typographic points (1/72 inches).
|
||||
|
@ -240,8 +240,8 @@ impl PdfFont {
|
||||
// Subset the font using the selected characters
|
||||
let subsetted = font.subsetted(
|
||||
chars.iter().cloned(),
|
||||
&["head", "hhea", "maxp", "hmtx", "loca", "glyf"],
|
||||
&["cvt ", "prep", "fpgm", /* "OS/2", "cmap", "name", "post" */],
|
||||
&["head", "hhea", "maxp", "hmtx", "loca", "glyf"][..],
|
||||
&["cvt ", "prep", "fpgm"][..],
|
||||
)?;
|
||||
|
||||
// Specify flags for the font
|
||||
|
372
src/font.rs
372
src/font.rs
@ -1,7 +1,18 @@
|
||||
//! Font loading and transforming.
|
||||
//!
|
||||
//! # Font handling
|
||||
//! To do the typesetting, the compiler needs font data. To be highly portable the compiler assumes
|
||||
//! nothing about the environment. To still work with fonts, the consumer of this library has to
|
||||
//! add _font providers_ to their compiler instance. These can be queried for font data given
|
||||
//! flexible font filters specifying required font families and styles. A font provider is a type
|
||||
//! implementing the [`FontProvider`](crate::font::FontProvider) trait.
|
||||
//!
|
||||
//! There is one [included font provider](crate::font::FileSystemFontProvider) that serves
|
||||
//! fonts from a folder on the file system.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::fs::File;
|
||||
use std::path::PathBuf;
|
||||
use std::io::{self, Cursor, Read, Seek, SeekFrom};
|
||||
use byteorder::{BE, ReadBytesExt, WriteBytesExt};
|
||||
use opentype::{Error as OpentypeError, OpenTypeReader, Outlines, TableRecord, Tag};
|
||||
@ -10,8 +21,8 @@ use opentype::global::{MacStyleFlags, NameEntry};
|
||||
use crate::engine::Size;
|
||||
|
||||
|
||||
/// An font wrapper which allows to subset a font.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
/// A loaded font, containing relevant information for typesetting.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Font {
|
||||
/// The base name of the font.
|
||||
pub name: String,
|
||||
@ -27,27 +38,6 @@ pub struct Font {
|
||||
pub metrics: FontMetrics,
|
||||
}
|
||||
|
||||
/// Font metrics relevant to the typesetting engine.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct FontMetrics {
|
||||
/// Whether the font is italic.
|
||||
pub is_italic: bool,
|
||||
/// Whether font is fixed pitch.
|
||||
pub is_fixed_pitch: bool,
|
||||
/// The angle of italics.
|
||||
pub italic_angle: f32,
|
||||
/// The glyph bounding box: [x_min, y_min, x_max, y_max],
|
||||
pub bounding_box: [Size; 4],
|
||||
/// The typographics ascender relevant for line spacing.
|
||||
pub ascender: Size,
|
||||
/// The typographics descender relevant for line spacing.
|
||||
pub descender: Size,
|
||||
/// The approximate height of capital letters.
|
||||
pub cap_height: Size,
|
||||
/// The weight class of the font.
|
||||
pub weight_class: u16,
|
||||
}
|
||||
|
||||
impl Font {
|
||||
/// Create a new font from a font program.
|
||||
pub fn new(program: Vec<u8>) -> FontResult<Font> {
|
||||
@ -125,16 +115,16 @@ impl Font {
|
||||
/// All needed tables will be included (returning an error if a table was not present
|
||||
/// in the source font) and optional tables will be included if there were present
|
||||
/// in the source font. All other tables will be dropped.
|
||||
pub fn subsetted<C, I1, S1, I2, S2>(
|
||||
pub fn subsetted<C, I, S>(
|
||||
&self,
|
||||
chars: C,
|
||||
needed_tables: I1,
|
||||
optional_tables: I2
|
||||
needed_tables: I,
|
||||
optional_tables: I,
|
||||
) -> Result<Font, FontError>
|
||||
where
|
||||
C: IntoIterator<Item=char>,
|
||||
I1: IntoIterator<Item=S1>, S1: AsRef<str>,
|
||||
I2: IntoIterator<Item=S2>, S2: AsRef<str>
|
||||
I: IntoIterator<Item=S>,
|
||||
S: AsRef<str>,
|
||||
{
|
||||
let mut chars: Vec<char> = chars.into_iter().collect();
|
||||
chars.sort();
|
||||
@ -143,7 +133,7 @@ impl Font {
|
||||
let outlines = reader.outlines()?;
|
||||
let tables = reader.tables()?.to_vec();
|
||||
|
||||
Subsetter {
|
||||
let subsetter = Subsetter {
|
||||
font: &self,
|
||||
reader,
|
||||
outlines,
|
||||
@ -155,7 +145,192 @@ impl Font {
|
||||
chars,
|
||||
records: Vec::new(),
|
||||
body: Vec::new(),
|
||||
}.subset(needed_tables, optional_tables)
|
||||
};
|
||||
|
||||
subsetter.subset(needed_tables, optional_tables)
|
||||
}
|
||||
}
|
||||
|
||||
/// Font metrics relevant to the typesetting engine.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct FontMetrics {
|
||||
/// Whether the font is italic.
|
||||
pub is_italic: bool,
|
||||
/// Whether font is fixed pitch.
|
||||
pub is_fixed_pitch: bool,
|
||||
/// The angle of italics.
|
||||
pub italic_angle: f32,
|
||||
/// The glyph bounding box: [x_min, y_min, x_max, y_max],
|
||||
pub bounding_box: [Size; 4],
|
||||
/// The typographics ascender relevant for line spacing.
|
||||
pub ascender: Size,
|
||||
/// The typographics descender relevant for line spacing.
|
||||
pub descender: Size,
|
||||
/// The approximate height of capital letters.
|
||||
pub cap_height: Size,
|
||||
/// The weight class of the font.
|
||||
pub weight_class: u16,
|
||||
}
|
||||
|
||||
/// A type that provides fonts matching given criteria.
|
||||
pub trait FontProvider {
|
||||
/// Returns the font with the given info if this provider has it.
|
||||
fn get(&self, info: &FontInfo) -> Option<Box<dyn FontData>>;
|
||||
|
||||
/// The available fonts this provider can serve. While these should generally be retrievable
|
||||
/// through the `get` method, it is not guaranteed that a font info that is contained here
|
||||
/// yields a `Some` value when passed into `get`.
|
||||
fn available<'a>(&'a self) -> &'a [FontInfo];
|
||||
}
|
||||
|
||||
/// A wrapper trait around `Read + Seek`.
|
||||
///
|
||||
/// This type is needed because currently you can't make a trait object
|
||||
/// with two traits, like `Box<dyn Read + Seek>`.
|
||||
/// Automatically implemented for all types that are [`Read`] and [`Seek`].
|
||||
pub trait FontData: Read + Seek {}
|
||||
impl<T> FontData for T where T: Read + Seek {}
|
||||
|
||||
/// Describes a font.
|
||||
///
|
||||
/// Can be constructed conventiently with the [`font_info`] macro.
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct FontInfo {
|
||||
/// The font families this font is part of.
|
||||
pub families: Vec<FontFamily>,
|
||||
/// Whether the font is in italics.
|
||||
pub italic: bool,
|
||||
/// Whether the font is bold.
|
||||
pub bold: bool,
|
||||
}
|
||||
|
||||
/// A macro to create [FontInfos](crate::font::FontInfo) easily.
|
||||
///
|
||||
/// ```
|
||||
/// # use typeset::font_info;
|
||||
/// font_info!(
|
||||
/// "NotoSans", // Font family name
|
||||
/// [SansSerif], // Generic families
|
||||
/// false, false // Bold & Italic
|
||||
/// );
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! font_info {
|
||||
($family:expr, [$($generic:ident),*], $bold:expr, $italic:expr) => {{
|
||||
let mut families = vec![$crate::font::FontFamily::Named($family.to_string())];
|
||||
families.extend([$($crate::font::FontFamily::$generic),*].iter().cloned());
|
||||
$crate::font::FontInfo {
|
||||
families,
|
||||
italic: $italic,
|
||||
bold: $bold,
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
/// Criteria to filter fonts.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct FontFilter<'a> {
|
||||
/// A fallback list of font families we accept. The first family in this list, that also
|
||||
/// satisfies the other conditions shall be returned.
|
||||
pub families: &'a [FontFamily],
|
||||
/// If some, matches only italic/non-italic fonts, otherwise any.
|
||||
pub italic: Option<bool>,
|
||||
/// If some, matches only bold/non-bold fonts, otherwise any.
|
||||
pub bold: Option<bool>,
|
||||
}
|
||||
|
||||
impl<'a> FontFilter<'a> {
|
||||
/// Create a new font config with the given families.
|
||||
///
|
||||
/// All other fields are set to [`None`] and match anything.
|
||||
pub fn new(families: &'a [FontFamily]) -> FontFilter<'a> {
|
||||
FontFilter {
|
||||
families,
|
||||
italic: None,
|
||||
bold: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether this filter matches the given info.
|
||||
pub fn matches(&self, info: &FontInfo) -> bool {
|
||||
self.italic.map(|i| i == info.italic).unwrap_or(true)
|
||||
&& self.bold.map(|i| i == info.bold).unwrap_or(true)
|
||||
&& self.families.iter().any(|family| info.families.contains(family))
|
||||
}
|
||||
|
||||
/// Set the italic value to something.
|
||||
pub fn italic(&mut self, italic: bool) -> &mut Self {
|
||||
self.italic = Some(italic); self
|
||||
}
|
||||
|
||||
/// Set the bold value to something.
|
||||
pub fn bold(&mut self, bold: bool) -> &mut Self {
|
||||
self.bold = Some(bold); self
|
||||
}
|
||||
}
|
||||
|
||||
/// A family of fonts (either generic or named).
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub enum FontFamily {
|
||||
SansSerif,
|
||||
Serif,
|
||||
Monospace,
|
||||
Named(String),
|
||||
}
|
||||
|
||||
/// A font provider serving fonts from a folder on the local file system.
|
||||
pub struct FileSystemFontProvider {
|
||||
base: PathBuf,
|
||||
paths: Vec<PathBuf>,
|
||||
infos: Vec<FontInfo>,
|
||||
}
|
||||
|
||||
impl FileSystemFontProvider {
|
||||
/// Create a new provider from a folder and an iterator of pairs of
|
||||
/// font paths and font infos.
|
||||
///
|
||||
/// # Example
|
||||
/// Serve the two fonts `NotoSans-Regular` and `NotoSans-Italic` from the local
|
||||
/// folder `../fonts`.
|
||||
/// ```
|
||||
/// # use typeset::{font::FileSystemFontProvider, font_info};
|
||||
/// FileSystemFontProvider::new("../fonts", vec![
|
||||
/// ("NotoSans-Regular.ttf", font_info!("NotoSans", [SansSerif], false, false)),
|
||||
/// ("NotoSans-Italic.ttf", font_info!("NotoSans", [SansSerif], false, true)),
|
||||
/// ]);
|
||||
/// ```
|
||||
pub fn new<B, I, P>(base: B, infos: I) -> FileSystemFontProvider
|
||||
where
|
||||
B: Into<PathBuf>,
|
||||
I: IntoIterator<Item = (P, FontInfo)>,
|
||||
P: Into<PathBuf>,
|
||||
{
|
||||
let mut paths = Vec::new();
|
||||
let mut font_infos = Vec::new();
|
||||
|
||||
for (path, info) in infos.into_iter() {
|
||||
paths.push(path.into());
|
||||
font_infos.push(info);
|
||||
}
|
||||
|
||||
FileSystemFontProvider {
|
||||
base: base.into(),
|
||||
paths,
|
||||
infos: font_infos,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FontProvider for FileSystemFontProvider {
|
||||
fn get(&self, info: &FontInfo) -> Option<Box<dyn FontData>> {
|
||||
let index = self.infos.iter().position(|i| i == info)?;
|
||||
let path = &self.paths[index];
|
||||
let file = File::open(self.base.join(path)).ok()?;
|
||||
Some(Box::new(file) as Box<FontData>)
|
||||
}
|
||||
|
||||
fn available<'a>(&'a self) -> &'a [FontInfo] {
|
||||
&self.infos
|
||||
}
|
||||
}
|
||||
|
||||
@ -584,141 +759,6 @@ impl<T> TakeInvalid<T> for Option<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A type that provides fonts matching given criteria.
|
||||
pub trait FontProvider {
|
||||
/// Returns a font matching the configuration
|
||||
/// if this provider has a matching font.
|
||||
fn provide(&self, config: &FontConfig) -> Option<Box<dyn FontSource>>;
|
||||
}
|
||||
|
||||
/// A wrapper trait around `Read + Seek` to allow for making a trait object.
|
||||
///
|
||||
/// Automatically implemented for all types that are [`Read`] and [`Seek`].
|
||||
pub trait FontSource: Read + Seek {}
|
||||
|
||||
impl<T> FontSource for T where T: Read + Seek {}
|
||||
|
||||
/// A family of fonts (either generic or named).
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub enum FontFamily {
|
||||
SansSerif,
|
||||
Serif,
|
||||
Monospace,
|
||||
Named(String),
|
||||
}
|
||||
|
||||
/// Criteria to filter fonts.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct FontConfig {
|
||||
/// The font families we are looking for.
|
||||
pub families: Vec<FontFamily>,
|
||||
/// If some, matches only italic/non-italic fonts, otherwise any.
|
||||
pub italic: Option<bool>,
|
||||
/// If some, matches only bold/non-bold fonts, otherwise any.
|
||||
pub bold: Option<bool>,
|
||||
}
|
||||
|
||||
impl FontConfig {
|
||||
/// Create a new font config with the given families.
|
||||
///
|
||||
/// All other fields are set to [`None`] and match anything.
|
||||
pub fn new(families: Vec<FontFamily>) -> FontConfig {
|
||||
FontConfig {
|
||||
families,
|
||||
italic: None,
|
||||
bold: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the italic value to something.
|
||||
pub fn italic(&mut self, italic: bool) -> &mut Self {
|
||||
self.italic = Some(italic);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the bold value to something.
|
||||
pub fn bold(&mut self, bold: bool) -> &mut Self {
|
||||
self.bold = Some(bold);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// A font provider that works on font files on the local file system.
|
||||
pub struct FileFontProvider<'a> {
|
||||
root: PathBuf,
|
||||
specs: Vec<FileFontDescriptor<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> FileFontProvider<'a> {
|
||||
/// Create a new file font provider. The folder relative to which the `specs`
|
||||
/// contains the file paths, is given as `root`.
|
||||
pub fn new<P: 'a, I>(root: P, specs: I) -> FileFontProvider<'a>
|
||||
where
|
||||
I: IntoIterator<Item=FileFontDescriptor<'a>>,
|
||||
P: Into<PathBuf>
|
||||
{
|
||||
FileFontProvider {
|
||||
root: root.into(),
|
||||
specs: specs.into_iter().collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A type describing a font on the file system.
|
||||
///
|
||||
/// Can be constructed conventiently with the [`file_font`] macro.
|
||||
pub struct FileFontDescriptor<'a> {
|
||||
/// The path to the font relative to the root.
|
||||
pub path: &'a Path,
|
||||
/// The font families this font is part of.
|
||||
pub families: Vec<FontFamily>,
|
||||
/// Whether the font is in italics.
|
||||
pub italic: bool,
|
||||
/// Whether the font is bold.
|
||||
pub bold: bool,
|
||||
}
|
||||
|
||||
impl FileFontDescriptor<'_> {
|
||||
fn matches(&self, config: &FontConfig) -> bool {
|
||||
config.italic.map(|i| i == self.italic).unwrap_or(true)
|
||||
&& config.bold.map(|i| i == self.bold).unwrap_or(true)
|
||||
&& config.families.iter().any(|family| self.families.contains(family))
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper macro to create [file font descriptors](crate::font::FileFontDescriptor).
|
||||
///
|
||||
/// ```
|
||||
/// # use typeset::file_font;
|
||||
/// file_font!(
|
||||
/// "NotoSans", // Font family name
|
||||
/// [SansSerif], // Generic families
|
||||
/// "NotoSans-Regular.ttf", // Font file
|
||||
/// false, false // Bold & Italic
|
||||
/// );
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! file_font {
|
||||
($family:expr, [$($generic:ident),*], $path:expr, $bold:expr, $italic:expr) => {{
|
||||
let mut families = vec![$crate::font::FontFamily::Named($family.to_string())];
|
||||
families.extend([$($crate::font::FontFamily::$generic),*].iter().cloned());
|
||||
$crate::font::FileFontDescriptor {
|
||||
path: std::path::Path::new($path),
|
||||
families,
|
||||
italic: $italic, bold: $bold,
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
impl FontProvider for FileFontProvider<'_> {
|
||||
fn provide(&self, config: &FontConfig) -> Option<Box<dyn FontSource>> {
|
||||
self.specs.iter().find(|spec| spec.matches(&config)).map(|spec| {
|
||||
let file = std::fs::File::open(self.root.join(spec.path)).unwrap();
|
||||
Box::new(file) as Box<FontSource>
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// The error type for font operations.
|
||||
pub enum FontError {
|
||||
/// The font file is incorrect.
|
||||
|
25
src/lib.rs
25
src/lib.rs
@ -15,7 +15,7 @@
|
||||
//! ```
|
||||
//! use std::fs::File;
|
||||
//! use typeset::Compiler;
|
||||
//! use typeset::{font::FileFontProvider, file_font};
|
||||
//! use typeset::{font::FileSystemFontProvider, font_info};
|
||||
//! use typeset::export::pdf::PdfExporter;
|
||||
//!
|
||||
//! // Simple example source code.
|
||||
@ -24,9 +24,9 @@
|
||||
//! // Create a compiler with a font provider that provides three fonts
|
||||
//! // (the default sans-serif fonts and a fallback for the emoji).
|
||||
//! let mut compiler = Compiler::new();
|
||||
//! compiler.add_font_provider(FileFontProvider::new("../fonts", vec![
|
||||
//! compiler.add_font_provider(FileSystemFontProvider::new("../fonts", vec![
|
||||
//! // Font family name, generic families, file, bold, italic
|
||||
//! file_font!("NotoSans", [SansSerif], "NotoSans-Regular.ttf", false, false),
|
||||
//! ("NotoSans-Regular.ttf", font_info!("NotoSans", [SansSerif], false, false)),
|
||||
//! ]));
|
||||
//!
|
||||
//! // Compile the source code with the compiler.
|
||||
@ -145,21 +145,20 @@ mod test {
|
||||
use std::fs::File;
|
||||
use crate::Compiler;
|
||||
use crate::export::pdf::PdfExporter;
|
||||
use crate::font::FileFontProvider;
|
||||
use crate::font::FileSystemFontProvider;
|
||||
|
||||
/// Create a pdf with a name from the source code.
|
||||
fn test(name: &str, src: &str) {
|
||||
// Create compiler
|
||||
let mut compiler = Compiler::new();
|
||||
compiler.add_font_provider(FileFontProvider::new("../fonts", vec![
|
||||
// Font family name, generic families, file, bold, italic
|
||||
file_font!("NotoSans", [SansSerif], "NotoSans-Regular.ttf", false, false),
|
||||
file_font!("NotoSans", [SansSerif], "NotoSans-Bold.ttf", true, false),
|
||||
file_font!("NotoSans", [SansSerif], "NotoSans-Italic.ttf", false, true),
|
||||
file_font!("NotoSans", [SansSerif], "NotoSans-BoldItalic.ttf", true, true),
|
||||
file_font!("NotoSansMath", [SansSerif], "NotoSansMath-Regular.ttf", false, false),
|
||||
file_font!("NotoEmoji", [SansSerif, Serif, Monospace],
|
||||
"NotoEmoji-Regular.ttf", false, false),
|
||||
compiler.add_font_provider(FileSystemFontProvider::new("../fonts", vec![
|
||||
("NotoSans-Regular.ttf", font_info!("NotoSans", [SansSerif], false, false)),
|
||||
("NotoSans-Bold.ttf", font_info!("NotoSans", [SansSerif], true, false)),
|
||||
("NotoSans-Italic.ttf", font_info!("NotoSans", [SansSerif], false, true)),
|
||||
("NotoSans-BoldItalic.ttf", font_info!("NotoSans", [SansSerif], true, true)),
|
||||
("NotoSansMath-Regular.ttf", font_info!("NotoSansMath", [SansSerif], false, false)),
|
||||
("NotoEmoji-Regular.ttf",
|
||||
font_info!("NotoEmoji", [SansSerif, Serif, Monospace], false, false)),
|
||||
]));
|
||||
|
||||
// Compile into document
|
||||
|
Loading…
Reference in New Issue
Block a user