|
1 | 1 | use crate::render::path; |
2 | 2 | use crate::util::allocate::RefAllocator; |
3 | | -use crate::util::context::{Context, Font}; |
| 3 | +use crate::util::context::Context; |
4 | 4 | use crate::util::helper::{deflate, TransformExt}; |
5 | 5 | use crate::util::resources::ResourceContainer; |
6 | 6 | use pdf_writer::types::{ |
7 | 7 | CidFontType, FontFlags, SystemInfo, TextRenderingMode, UnicodeCmap, |
8 | 8 | }; |
9 | | -use pdf_writer::{Chunk, Content, Filter, Finish, Name, Str}; |
| 9 | +use pdf_writer::{Chunk, Content, Filter, Finish, Name, Ref, Str}; |
10 | 10 | use siphasher::sip128::{Hasher128, SipHasher13}; |
11 | 11 | use std::collections::{BTreeMap, HashMap}; |
12 | 12 | use std::hash::Hash; |
13 | 13 | use ttf_parser::{name_id, Face, GlyphId, PlatformId, Tag}; |
14 | 14 | use unicode_properties::{GeneralCategory, UnicodeGeneralCategory}; |
15 | | -use usvg::{Fill, PaintOrder, Stroke, Transform, Visibility}; |
| 15 | +use usvg::{Fill, Group, ImageKind, Node, PaintOrder, Stroke, Transform, Visibility}; |
16 | 16 |
|
17 | 17 | const CFF: Tag = Tag::from_bytes(b"CFF "); |
18 | 18 | const CFF2: Tag = Tag::from_bytes(b"CFF2"); |
@@ -473,3 +473,63 @@ where |
473 | 473 | Some((key, head)) |
474 | 474 | } |
475 | 475 | } |
| 476 | + |
| 477 | +#[derive(Clone)] |
| 478 | +pub struct Font { |
| 479 | + pub glyph_set: BTreeMap<u16, String>, |
| 480 | + pub reference: Ref, |
| 481 | + pub face_data: Vec<u8>, |
| 482 | + pub units_per_em: u16, |
| 483 | + pub face_index: u32, |
| 484 | +} |
| 485 | + |
| 486 | +pub fn fill_fonts(group: &Group, ctx: &mut Context, fontdb: &fontdb::Database) { |
| 487 | + for child in group.children() { |
| 488 | + match child { |
| 489 | + Node::Text(t) => { |
| 490 | + let allocator = &mut ctx.ref_allocator; |
| 491 | + for span in t.layouted() { |
| 492 | + for g in &span.positioned_glyphs { |
| 493 | + let font = ctx.fonts.entry(g.font).or_insert_with(|| { |
| 494 | + fontdb |
| 495 | + .with_face_data(g.font, |data, face_index| { |
| 496 | + // TODO: Currently, we are parsing each font twice, once here |
| 497 | + // and once again when writing the fonts. We should probably |
| 498 | + // improve on that... |
| 499 | + if let Ok(ttf) = |
| 500 | + ttf_parser::Face::parse(data, face_index) |
| 501 | + { |
| 502 | + let reference = allocator.alloc_ref(); |
| 503 | + let glyph_set = BTreeMap::new(); |
| 504 | + return Some(Font { |
| 505 | + reference, |
| 506 | + face_data: Vec::from(data), |
| 507 | + units_per_em: ttf.units_per_em(), |
| 508 | + glyph_set, |
| 509 | + face_index, |
| 510 | + }); |
| 511 | + } |
| 512 | + |
| 513 | + None |
| 514 | + }) |
| 515 | + .flatten() |
| 516 | + }); |
| 517 | + |
| 518 | + if let Some(ref mut font) = font { |
| 519 | + font.glyph_set.insert(g.glyph_id.0, g.text.clone()); |
| 520 | + } |
| 521 | + } |
| 522 | + } |
| 523 | + } |
| 524 | + Node::Group(group) => fill_fonts(group, ctx, fontdb), |
| 525 | + Node::Image(image) => { |
| 526 | + if let ImageKind::SVG(svg) = image.kind() { |
| 527 | + fill_fonts(svg.root(), ctx, fontdb); |
| 528 | + } |
| 529 | + } |
| 530 | + _ => {} |
| 531 | + } |
| 532 | + |
| 533 | + child.subroots(|subroot| fill_fonts(subroot, ctx, fontdb)); |
| 534 | + } |
| 535 | +} |
0 commit comments