summaryrefslogtreecommitdiff
path: root/src/export
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-09-19 17:44:40 +0200
committerLaurenz <laurmaedje@gmail.com>2022-09-19 17:44:40 +0200
commite29f55bb294cc298daad97accf6d8a76976b409c (patch)
treecc4db3b61fa23e13f781e992c63427d36e77ef8c /src/export
parent59f67b79c7ff50f0bc9a27373d0fa36d1523e08a (diff)
Remove font store
Diffstat (limited to 'src/export')
-rw-r--r--src/export/pdf/font.rs7
-rw-r--r--src/export/pdf/mod.rs19
-rw-r--r--src/export/pdf/page.rs30
-rw-r--r--src/export/render.rs39
4 files changed, 39 insertions, 56 deletions
diff --git a/src/export/pdf/font.rs b/src/export/pdf/font.rs
index b3481c43..446d36bc 100644
--- a/src/export/pdf/font.rs
+++ b/src/export/pdf/font.rs
@@ -9,7 +9,7 @@ use crate::util::SliceExt;
/// Embed all used fonts into the PDF.
pub fn write_fonts(ctx: &mut PdfContext) {
- for &font_id in ctx.font_map.items() {
+ for font in ctx.font_map.items() {
let type0_ref = ctx.alloc.bump();
let cid_ref = ctx.alloc.bump();
let descriptor_ref = ctx.alloc.bump();
@@ -17,8 +17,7 @@ pub fn write_fonts(ctx: &mut PdfContext) {
let data_ref = ctx.alloc.bump();
ctx.font_refs.push(type0_ref);
- let glyphs = &ctx.glyph_sets[&font_id];
- let font = ctx.fonts.get(font_id);
+ let glyphs = &ctx.glyph_sets[font];
let metrics = font.metrics();
let ttf = font.ttf();
@@ -161,7 +160,7 @@ pub fn write_fonts(ctx: &mut PdfContext) {
.filter(Filter::FlateDecode);
// Subset and write the font's bytes.
- let data = font.buffer();
+ let data = font.data();
let subsetted = {
let glyphs: Vec<_> = glyphs.iter().copied().collect();
let profile = subsetter::Profile::pdf(&glyphs);
diff --git a/src/export/pdf/mod.rs b/src/export/pdf/mod.rs
index 7468f7d7..a87f5c6b 100644
--- a/src/export/pdf/mod.rs
+++ b/src/export/pdf/mod.rs
@@ -14,12 +14,11 @@ use pdf_writer::{Finish, Name, PdfWriter, Ref, TextStr};
use self::outline::{Heading, HeadingNode};
use self::page::Page;
-use crate::font::{FontId, FontStore};
+use crate::font::Font;
use crate::frame::Frame;
use crate::geom::{Dir, Em, Length};
use crate::image::Image;
use crate::library::text::Lang;
-use crate::Context;
/// Export a collection of frames into a PDF file.
///
@@ -28,8 +27,8 @@ use crate::Context;
/// included in the PDF.
///
/// Returns the raw bytes making up the PDF file.
-pub fn pdf(ctx: &Context, frames: &[Frame]) -> Vec<u8> {
- let mut ctx = PdfContext::new(ctx);
+pub fn pdf(frames: &[Frame]) -> Vec<u8> {
+ let mut ctx = PdfContext::new();
page::construct_pages(&mut ctx, frames);
font::write_fonts(&mut ctx);
image::write_images(&mut ctx);
@@ -43,9 +42,8 @@ const SRGB: Name<'static> = Name(b"srgb");
const D65_GRAY: Name<'static> = Name(b"d65gray");
/// Context for exporting a whole PDF document.
-pub struct PdfContext<'a> {
+pub struct PdfContext {
writer: PdfWriter,
- fonts: &'a FontStore,
pages: Vec<Page>,
page_heights: Vec<f32>,
alloc: Ref,
@@ -53,20 +51,19 @@ pub struct PdfContext<'a> {
font_refs: Vec<Ref>,
image_refs: Vec<Ref>,
page_refs: Vec<Ref>,
- font_map: Remapper<FontId>,
+ font_map: Remapper<Font>,
image_map: Remapper<Image>,
- glyph_sets: HashMap<FontId, HashSet<u16>>,
+ glyph_sets: HashMap<Font, HashSet<u16>>,
languages: HashMap<Lang, usize>,
heading_tree: Vec<HeadingNode>,
}
-impl<'a> PdfContext<'a> {
- fn new(ctx: &'a Context) -> Self {
+impl PdfContext {
+ fn new() -> Self {
let mut alloc = Ref::new(1);
let page_tree_ref = alloc.bump();
Self {
writer: PdfWriter::new(),
- fonts: &ctx.fonts,
pages: vec![],
page_heights: vec![],
alloc,
diff --git a/src/export/pdf/page.rs b/src/export/pdf/page.rs
index 6df7531b..708eafad 100644
--- a/src/export/pdf/page.rs
+++ b/src/export/pdf/page.rs
@@ -5,7 +5,7 @@ use pdf_writer::{Content, Filter, Finish, Name, Rect, Ref, Str};
use super::{
deflate, EmExt, Heading, HeadingNode, LengthExt, PdfContext, RefExt, D65_GRAY, SRGB,
};
-use crate::font::FontId;
+use crate::font::Font;
use crate::frame::{Destination, Element, Frame, Group, Role, Text};
use crate::geom::{
self, Color, Em, Geometry, Length, Numeric, Paint, Point, Ratio, Shape, Size, Stroke,
@@ -154,8 +154,8 @@ pub struct Page {
}
/// An exporter for the contents of a single PDF page.
-struct PageContext<'a, 'b> {
- parent: &'a mut PdfContext<'b>,
+struct PageContext<'a> {
+ parent: &'a mut PdfContext,
page_ref: Ref,
content: Content,
state: State,
@@ -169,14 +169,14 @@ struct PageContext<'a, 'b> {
#[derive(Debug, Default, Clone)]
struct State {
transform: Transform,
- font: Option<(FontId, Length)>,
+ font: Option<(Font, Length)>,
fill: Option<Paint>,
fill_space: Option<Name<'static>>,
stroke: Option<Stroke>,
stroke_space: Option<Name<'static>>,
}
-impl<'a, 'b> PageContext<'a, 'b> {
+impl<'a> PageContext<'a> {
fn save_state(&mut self) {
self.saves.push(self.state.clone());
self.content.save_state();
@@ -200,12 +200,12 @@ impl<'a, 'b> PageContext<'a, 'b> {
]);
}
- fn set_font(&mut self, font_id: FontId, size: Length) {
- if self.state.font != Some((font_id, size)) {
- self.parent.font_map.insert(font_id);
- let name = format_eco!("F{}", self.parent.font_map.map(font_id));
+ fn set_font(&mut self, font: &Font, size: Length) {
+ if self.state.font.as_ref().map(|(f, s)| (f, *s)) != Some((font, size)) {
+ self.parent.font_map.insert(font.clone());
+ let name = format_eco!("F{}", self.parent.font_map.map(font.clone()));
self.content.set_font(Name(name.as_bytes()), size.to_f32());
- self.state.font = Some((font_id, size));
+ self.state.font = Some((font.clone(), size));
}
}
@@ -328,17 +328,15 @@ fn write_text(ctx: &mut PageContext, x: f32, y: f32, text: &Text) {
*ctx.parent.languages.entry(text.lang).or_insert(0) += text.glyphs.len();
ctx.parent
.glyph_sets
- .entry(text.font_id)
+ .entry(text.font.clone())
.or_default()
.extend(text.glyphs.iter().map(|g| g.id));
- let font = ctx.parent.fonts.get(text.font_id);
-
ctx.set_fill(text.fill);
- ctx.set_font(text.font_id, text.size);
+ ctx.set_font(&text.font, text.size);
ctx.content.begin_text();
- // Position the text.
+ // Positiosn the text.
ctx.content.set_text_matrix([1.0, 0.0, 0.0, -1.0, x, y]);
let mut positioned = ctx.content.show_positioned();
@@ -363,7 +361,7 @@ fn write_text(ctx: &mut PageContext, x: f32, y: f32, text: &Text) {
encoded.push((glyph.id >> 8) as u8);
encoded.push((glyph.id & 0xff) as u8);
- if let Some(advance) = font.advance(glyph.id) {
+ if let Some(advance) = text.font.advance(glyph.id) {
adjustment += glyph.x_advance - advance;
}
diff --git a/src/export/render.rs b/src/export/render.rs
index 688cf979..bf735ded 100644
--- a/src/export/render.rs
+++ b/src/export/render.rs
@@ -13,7 +13,6 @@ use crate::geom::{
self, Geometry, Length, Paint, PathElement, Shape, Size, Stroke, Transform,
};
use crate::image::{DecodedImage, Image};
-use crate::Context;
/// Export a frame into a rendered image.
///
@@ -22,7 +21,7 @@ use crate::Context;
///
/// In addition to the frame, you need to pass in the context used during
/// compilation so that fonts and images can be rendered.
-pub fn render(ctx: &Context, frame: &Frame, pixel_per_pt: f32) -> sk::Pixmap {
+pub fn render(frame: &Frame, pixel_per_pt: f32) -> sk::Pixmap {
let size = frame.size();
let pxw = (pixel_per_pt * size.x.to_f32()).round().max(1.0) as u32;
let pxh = (pixel_per_pt * size.y.to_f32()).round().max(1.0) as u32;
@@ -31,7 +30,7 @@ pub fn render(ctx: &Context, frame: &Frame, pixel_per_pt: f32) -> sk::Pixmap {
canvas.fill(sk::Color::WHITE);
let ts = sk::Transform::from_scale(pixel_per_pt, pixel_per_pt);
- render_frame(&mut canvas, ts, None, ctx, frame);
+ render_frame(&mut canvas, ts, None, frame);
canvas
}
@@ -41,7 +40,6 @@ fn render_frame(
canvas: &mut sk::Pixmap,
ts: sk::Transform,
mask: Option<&sk::ClipMask>,
- ctx: &Context,
frame: &Frame,
) {
for (pos, element) in frame.elements() {
@@ -51,10 +49,10 @@ fn render_frame(
match element {
Element::Group(group) => {
- render_group(canvas, ts, mask, ctx, group);
+ render_group(canvas, ts, mask, group);
}
Element::Text(text) => {
- render_text(canvas, ts, mask, ctx, text);
+ render_text(canvas, ts, mask, text);
}
Element::Shape(shape) => {
render_shape(canvas, ts, mask, shape);
@@ -72,7 +70,6 @@ fn render_group(
canvas: &mut sk::Pixmap,
ts: sk::Transform,
mask: Option<&sk::ClipMask>,
- ctx: &Context,
group: &Group,
) {
let ts = ts.pre_concat(group.transform.into());
@@ -107,7 +104,7 @@ fn render_group(
}
}
- render_frame(canvas, ts, mask, ctx, &group.frame);
+ render_frame(canvas, ts, mask, &group.frame);
}
/// Render a text run into the canvas.
@@ -115,7 +112,6 @@ fn render_text(
canvas: &mut sk::Pixmap,
ts: sk::Transform,
mask: Option<&sk::ClipMask>,
- ctx: &Context,
text: &Text,
) {
let mut x = 0.0;
@@ -124,9 +120,9 @@ fn render_text(
let offset = x + glyph.x_offset.at(text.size).to_f32();
let ts = ts.pre_translate(offset, 0.0);
- render_svg_glyph(canvas, ts, mask, ctx, text, id)
- .or_else(|| render_bitmap_glyph(canvas, ts, mask, ctx, text, id))
- .or_else(|| render_outline_glyph(canvas, ts, mask, ctx, text, id));
+ render_svg_glyph(canvas, ts, mask, text, id)
+ .or_else(|| render_bitmap_glyph(canvas, ts, mask, text, id))
+ .or_else(|| render_outline_glyph(canvas, ts, mask, text, id));
x += glyph.x_advance.at(text.size).to_f32();
}
@@ -137,12 +133,10 @@ fn render_svg_glyph(
canvas: &mut sk::Pixmap,
ts: sk::Transform,
_: Option<&sk::ClipMask>,
- ctx: &Context,
text: &Text,
id: GlyphId,
) -> Option<()> {
- let font = ctx.fonts.get(text.font_id);
- let mut data = font.ttf().glyph_svg_image(id)?;
+ let mut data = text.font.ttf().glyph_svg_image(id)?;
// Decompress SVGZ.
let mut decoded = vec![];
@@ -164,7 +158,7 @@ fn render_svg_glyph(
// If there's no viewbox defined, use the em square for our scale
// transformation ...
- let upem = font.units_per_em() as f32;
+ let upem = text.font.units_per_em() as f32;
let (mut width, mut height) = (upem, upem);
// ... but if there's a viewbox or width, use that.
@@ -188,14 +182,12 @@ fn render_bitmap_glyph(
canvas: &mut sk::Pixmap,
ts: sk::Transform,
mask: Option<&sk::ClipMask>,
- ctx: &Context,
text: &Text,
id: GlyphId,
) -> Option<()> {
let size = text.size.to_f32();
let ppem = size * ts.sy;
- let font = ctx.fonts.get(text.font_id);
- let raster = font.ttf().glyph_raster_image(id, ppem as u16)?;
+ let raster = text.font.ttf().glyph_raster_image(id, ppem as u16)?;
let ext = match raster.format {
ttf_parser::RasterImageFormat::PNG => "png",
};
@@ -217,7 +209,6 @@ fn render_outline_glyph(
canvas: &mut sk::Pixmap,
ts: sk::Transform,
mask: Option<&sk::ClipMask>,
- ctx: &Context,
text: &Text,
id: GlyphId,
) -> Option<()> {
@@ -227,10 +218,9 @@ fn render_outline_glyph(
// rasterization can't be used due to very large text size or weird
// scale/skewing transforms.
if ppem > 100.0 || ts.kx != 0.0 || ts.ky != 0.0 || ts.sx != ts.sy {
- let font = ctx.fonts.get(text.font_id);
let path = {
let mut builder = WrappedPathBuilder(sk::PathBuilder::new());
- font.ttf().outline_glyph(id, &mut builder)?;
+ text.font.ttf().outline_glyph(id, &mut builder)?;
builder.0.finish()?
};
@@ -239,7 +229,7 @@ fn render_outline_glyph(
// Flip vertically because font design coordinate
// system is Y-up.
- let scale = text.size.to_f32() / font.units_per_em() as f32;
+ let scale = text.size.to_f32() / text.font.units_per_em() as f32;
let ts = ts.pre_scale(scale, -scale);
canvas.fill_path(&path, &paint, rule, ts, mask)?;
return Some(());
@@ -248,9 +238,8 @@ fn render_outline_glyph(
// Rasterize the glyph with `pixglyph`.
// Try to retrieve a prepared glyph or prepare it from scratch if it
// doesn't exist, yet.
- let glyph = pixglyph::Glyph::load(ctx.fonts.get(text.font_id).ttf(), id)?;
+ let glyph = pixglyph::Glyph::load(text.font.ttf(), id)?;
let bitmap = glyph.rasterize(ts.tx, ts.ty, ppem);
-
let cw = canvas.width() as i32;
let ch = canvas.height() as i32;
let mw = bitmap.width as i32;