blitz-pdf 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +266 -12
- package/THIRD_PARTY_NOTICES.md +4 -2
- package/dist/browser.d.ts +1 -1
- package/dist/browser.d.ts.map +1 -1
- package/dist/document-options.d.ts +36 -0
- package/dist/document-options.d.ts.map +1 -0
- package/dist/document-options.js +236 -0
- package/dist/document-options.js.map +1 -0
- package/dist/node.d.ts +1 -1
- package/dist/node.d.ts.map +1 -1
- package/dist/options.d.ts +35 -1
- package/dist/options.d.ts.map +1 -1
- package/dist/options.js +21 -14
- package/dist/options.js.map +1 -1
- package/dist/types.d.ts +71 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/validation.d.ts +2 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +7 -0
- package/dist/validation.js.map +1 -0
- package/examples/zugferd.mjs +41 -0
- package/licenses/RUST_DEPENDENCIES.txt +27 -0
- package/package.json +3 -2
- package/src/browser.ts +1 -1
- package/src/document-options.ts +218 -0
- package/src/node.ts +1 -1
- package/src/options.ts +18 -13
- package/src/types.ts +76 -1
- package/src/validation.ts +6 -0
- package/vendor/README.md +27 -2
- package/vendor/krilla/.cargo-ok +1 -0
- package/vendor/krilla/.cargo_vcs_info.json +6 -0
- package/vendor/krilla/Cargo.lock +1357 -0
- package/vendor/krilla/Cargo.toml +165 -0
- package/vendor/krilla/LICENSE_APACHE +202 -0
- package/vendor/krilla/LICENSE_MIT +21 -0
- package/vendor/krilla/README.md +156 -0
- package/vendor/krilla/examples/basic.rs +117 -0
- package/vendor/krilla/examples/empty_document.rs +25 -0
- package/vendor/krilla/examples/parley.rs +174 -0
- package/vendor/krilla/examples/simple_text.rs +118 -0
- package/vendor/krilla/examples/stream_builder.rs +93 -0
- package/vendor/krilla/icc/LICENSE +116 -0
- package/vendor/krilla/icc/README.md +1 -0
- package/vendor/krilla/icc/sGrey-v2-magic.icc +0 -0
- package/vendor/krilla/icc/sGrey-v4.icc +0 -0
- package/vendor/krilla/icc/sRGB-v2-magic.icc +0 -0
- package/vendor/krilla/icc/sRGB-v4.icc +0 -0
- package/vendor/krilla/src/chunk_container.rs +503 -0
- package/vendor/krilla/src/configure/PDF_A1.md +227 -0
- package/vendor/krilla/src/configure/PDF_A2.md +269 -0
- package/vendor/krilla/src/configure/PDF_A3.md +31 -0
- package/vendor/krilla/src/configure/PDF_A4.md +211 -0
- package/vendor/krilla/src/configure/PDF_UA1.md +202 -0
- package/vendor/krilla/src/configure/README.md +23 -0
- package/vendor/krilla/src/configure/mod.rs +197 -0
- package/vendor/krilla/src/configure/validate.rs +1244 -0
- package/vendor/krilla/src/configure/version.rs +134 -0
- package/vendor/krilla/src/content.rs +1352 -0
- package/vendor/krilla/src/data.rs +49 -0
- package/vendor/krilla/src/document.rs +156 -0
- package/vendor/krilla/src/error.rs +170 -0
- package/vendor/krilla/src/geom.rs +341 -0
- package/vendor/krilla/src/graphics/blend.rs +46 -0
- package/vendor/krilla/src/graphics/color.rs +552 -0
- package/vendor/krilla/src/graphics/graphic.rs +30 -0
- package/vendor/krilla/src/graphics/graphics_state.rs +251 -0
- package/vendor/krilla/src/graphics/icc.rs +218 -0
- package/vendor/krilla/src/graphics/image.rs +835 -0
- package/vendor/krilla/src/graphics/mask.rs +128 -0
- package/vendor/krilla/src/graphics/mod.rs +14 -0
- package/vendor/krilla/src/graphics/paint.rs +434 -0
- package/vendor/krilla/src/graphics/separation.rs +86 -0
- package/vendor/krilla/src/graphics/shading_function.rs +865 -0
- package/vendor/krilla/src/graphics/shading_pattern.rs +60 -0
- package/vendor/krilla/src/graphics/tiling_pattern.rs +119 -0
- package/vendor/krilla/src/graphics/xobject.rs +150 -0
- package/vendor/krilla/src/interactive/action.rs +68 -0
- package/vendor/krilla/src/interactive/annotation.rs +283 -0
- package/vendor/krilla/src/interactive/destination.rs +289 -0
- package/vendor/krilla/src/interactive/mod.rs +3 -0
- package/vendor/krilla/src/interchange/embed.rs +240 -0
- package/vendor/krilla/src/interchange/metadata.rs +564 -0
- package/vendor/krilla/src/interchange/mod.rs +4 -0
- package/vendor/krilla/src/interchange/outline.rs +263 -0
- package/vendor/krilla/src/interchange/tagging/fmt.rs +733 -0
- package/vendor/krilla/src/interchange/tagging/generate.toml +474 -0
- package/vendor/krilla/src/interchange/tagging/generated.rs +4754 -0
- package/vendor/krilla/src/interchange/tagging/mod.rs +1324 -0
- package/vendor/krilla/src/interchange/tagging/tag.rs +686 -0
- package/vendor/krilla/src/lib.rs +179 -0
- package/vendor/krilla/src/num.rs +26 -0
- package/vendor/krilla/src/page.rs +612 -0
- package/vendor/krilla/src/pdf.rs +313 -0
- package/vendor/krilla/src/resource.rs +436 -0
- package/vendor/krilla/src/serialize.rs +1101 -0
- package/vendor/krilla/src/stream.rs +368 -0
- package/vendor/krilla/src/surface.rs +664 -0
- package/vendor/krilla/src/text/cid.rs +488 -0
- package/vendor/krilla/src/text/font.rs +351 -0
- package/vendor/krilla/src/text/glyph/bitmap.rs +81 -0
- package/vendor/krilla/src/text/glyph/colr.rs +581 -0
- package/vendor/krilla/src/text/glyph/mod.rs +205 -0
- package/vendor/krilla/src/text/glyph/outline.rs +72 -0
- package/vendor/krilla/src/text/glyph/svg.rs +34 -0
- package/vendor/krilla/src/text/group.rs +463 -0
- package/vendor/krilla/src/text/mod.rs +232 -0
- package/vendor/krilla/src/text/shape.rs +102 -0
- package/vendor/krilla/src/text/type3.rs +514 -0
- package/vendor/krilla/src/util.rs +286 -0
- package/vendor/stylo/properties/longhands.toml +0 -1
- package/vendor/stylo/stylesheets/rule_parser.rs +1 -1
- package/wasm/blitz_pdf.js +10 -5
- package/wasm/blitz_pdf_bg.wasm +0 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
use std::ops::Range;
|
|
2
|
+
|
|
3
|
+
use crate::color::rgb;
|
|
4
|
+
use crate::geom::Transform;
|
|
5
|
+
use crate::surface::Surface;
|
|
6
|
+
use crate::text::Font;
|
|
7
|
+
|
|
8
|
+
#[cfg(feature = "raster-images")]
|
|
9
|
+
pub(crate) mod bitmap;
|
|
10
|
+
pub(crate) mod colr;
|
|
11
|
+
pub(crate) mod outline;
|
|
12
|
+
pub(crate) mod svg;
|
|
13
|
+
|
|
14
|
+
/// A glyph ID.
|
|
15
|
+
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
|
|
16
|
+
pub struct GlyphId(u32);
|
|
17
|
+
|
|
18
|
+
impl GlyphId {
|
|
19
|
+
/// Create a new glyph ID.
|
|
20
|
+
pub fn new(id: u32) -> Self {
|
|
21
|
+
Self(id)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/// Get the glyph ID as a u32.
|
|
25
|
+
pub fn to_u32(&self) -> u32 {
|
|
26
|
+
self.0
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
pub(crate) fn to_skrifa(self) -> skrifa::GlyphId {
|
|
30
|
+
skrifa::GlyphId::new(self.0)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/// Draw a color glyph to a surface.
|
|
35
|
+
pub(crate) fn draw_color_glyph(
|
|
36
|
+
font: Font,
|
|
37
|
+
context_color: rgb::Color,
|
|
38
|
+
glyph: GlyphId,
|
|
39
|
+
base_transform: Transform,
|
|
40
|
+
surface: &mut Surface,
|
|
41
|
+
) -> Option<()> {
|
|
42
|
+
surface.push_transform(&base_transform);
|
|
43
|
+
surface.push_transform(&Transform::from_scale(1.0, -1.0));
|
|
44
|
+
|
|
45
|
+
// Note: See the comment in krilla-svg in `render_svg_glyph` for why we prefer
|
|
46
|
+
// COLR over SVG. For Noto Color Emoji specifically, using SVG will be slow when
|
|
47
|
+
// rendering multiple glyphs.
|
|
48
|
+
let drawn = colr::draw_glyph(font.clone(), context_color, glyph, surface)
|
|
49
|
+
.or_else(|| svg::draw_glyph(font.clone(), context_color, glyph, surface))
|
|
50
|
+
.or_else(|| {
|
|
51
|
+
#[cfg(feature = "raster-images")]
|
|
52
|
+
let res = bitmap::draw_glyph(font.clone(), glyph, surface);
|
|
53
|
+
|
|
54
|
+
#[cfg(not(feature = "raster-images"))]
|
|
55
|
+
let res = None;
|
|
56
|
+
|
|
57
|
+
res
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
surface.pop();
|
|
61
|
+
surface.pop();
|
|
62
|
+
|
|
63
|
+
drawn
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
pub(crate) fn should_outline(font: &Font, glyph: GlyphId) -> bool {
|
|
67
|
+
let has_svg = svg::has_svg_data(font, glyph);
|
|
68
|
+
let has_colr = colr::has_colr_data(font, glyph);
|
|
69
|
+
#[cfg(feature = "raster-images")]
|
|
70
|
+
let has_bitmap = bitmap::has_bitmap_data(font, glyph);
|
|
71
|
+
#[cfg(not(feature = "raster-images"))]
|
|
72
|
+
let has_bitmap = false;
|
|
73
|
+
font.font_info().can_be_cid_font() && !has_svg && !has_colr && !has_bitmap
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/// Draw a color glyph or outline glyph to a surface.
|
|
77
|
+
pub(crate) fn draw_glyph(
|
|
78
|
+
font: Font,
|
|
79
|
+
context_color: rgb::Color,
|
|
80
|
+
glyph: GlyphId,
|
|
81
|
+
base_transform: Transform,
|
|
82
|
+
surface: &mut Surface,
|
|
83
|
+
) -> Option<()> {
|
|
84
|
+
draw_color_glyph(font.clone(), context_color, glyph, base_transform, surface)
|
|
85
|
+
.or_else(|| outline::draw_glyph(font, glyph, base_transform, surface))
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/// A glyph with certain properties.
|
|
89
|
+
pub trait Glyph {
|
|
90
|
+
/// The glyph ID of the glyph.
|
|
91
|
+
fn glyph_id(&self) -> GlyphId;
|
|
92
|
+
/// The range of bytes in the original text covered by the cluster that the glyph
|
|
93
|
+
/// belongs to.
|
|
94
|
+
fn text_range(&self) -> Range<usize>;
|
|
95
|
+
/// The advance in the x direction of the glyph, at the given font size.
|
|
96
|
+
fn x_advance(&self, size: f32) -> f32;
|
|
97
|
+
/// The offset in the x direction of the glyph, at the given font size.
|
|
98
|
+
fn x_offset(&self, size: f32) -> f32;
|
|
99
|
+
/// The offset in the y direction of the glyph, at the given font size.
|
|
100
|
+
fn y_offset(&self, size: f32) -> f32;
|
|
101
|
+
/// The advance in the y direction of the glyph, at the given font size.
|
|
102
|
+
fn y_advance(&self, size: f32) -> f32;
|
|
103
|
+
/// A location identifying the glyph. If set, `krilla` will automatically call
|
|
104
|
+
/// `set_location` before processing the glyph.
|
|
105
|
+
fn location(&self) -> Option<crate::surface::Location>;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/// A glyph type that implements `Glyph`.
|
|
109
|
+
///
|
|
110
|
+
/// You can use it if you don't have your own type of glyph that you want to use.
|
|
111
|
+
#[derive(Debug, Clone)]
|
|
112
|
+
pub struct KrillaGlyph {
|
|
113
|
+
/// The glyph ID of the glyph.
|
|
114
|
+
pub glyph_id: GlyphId,
|
|
115
|
+
/// The range in the original text that corresponds to the
|
|
116
|
+
/// cluster of the glyph.
|
|
117
|
+
pub text_range: Range<usize>,
|
|
118
|
+
/// The advance of the glyph.
|
|
119
|
+
pub x_advance: f32,
|
|
120
|
+
/// The x offset of the glyph.
|
|
121
|
+
pub x_offset: f32,
|
|
122
|
+
/// The y offset of the glyph.
|
|
123
|
+
pub y_offset: f32,
|
|
124
|
+
/// The y advance of the glyph.
|
|
125
|
+
pub y_advance: f32,
|
|
126
|
+
/// The location of the glyph.
|
|
127
|
+
pub location: Option<crate::surface::Location>,
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
impl Glyph for KrillaGlyph {
|
|
131
|
+
fn glyph_id(&self) -> GlyphId {
|
|
132
|
+
self.glyph_id
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
fn text_range(&self) -> Range<usize> {
|
|
136
|
+
self.text_range.clone()
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
fn x_advance(&self, size: f32) -> f32 {
|
|
140
|
+
self.x_advance * size
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
fn x_offset(&self, size: f32) -> f32 {
|
|
144
|
+
self.x_offset * size
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
fn y_offset(&self, size: f32) -> f32 {
|
|
148
|
+
self.y_offset * size
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
fn y_advance(&self, size: f32) -> f32 {
|
|
152
|
+
self.y_advance * size
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
fn location(&self) -> Option<crate::surface::Location> {
|
|
156
|
+
self.location
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
impl KrillaGlyph {
|
|
161
|
+
/// Create a new krilla glyph.
|
|
162
|
+
///
|
|
163
|
+
/// Important: `x_advance`, `x_offset`, `y_offset` and `y_advance`
|
|
164
|
+
/// need to be normalized, i.e. divided by the units per em!
|
|
165
|
+
pub fn new(
|
|
166
|
+
glyph_id: GlyphId,
|
|
167
|
+
x_advance: f32,
|
|
168
|
+
x_offset: f32,
|
|
169
|
+
y_offset: f32,
|
|
170
|
+
y_advance: f32,
|
|
171
|
+
range: Range<usize>,
|
|
172
|
+
location: Option<crate::surface::Location>,
|
|
173
|
+
) -> Self {
|
|
174
|
+
Self {
|
|
175
|
+
glyph_id,
|
|
176
|
+
x_advance,
|
|
177
|
+
x_offset,
|
|
178
|
+
y_offset,
|
|
179
|
+
y_advance,
|
|
180
|
+
text_range: range,
|
|
181
|
+
location,
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/// A glyph that belongs either to a CID font or a Type 3 font.
|
|
187
|
+
#[derive(Clone, Copy)]
|
|
188
|
+
pub(crate) enum PDFGlyph {
|
|
189
|
+
Type3(u8),
|
|
190
|
+
Cid(u16),
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
impl PDFGlyph {
|
|
194
|
+
/// Encode the glyph into a content stream.
|
|
195
|
+
#[inline(always)]
|
|
196
|
+
pub(crate) fn encode_into(&self, slice: &mut Vec<u8>) {
|
|
197
|
+
match self {
|
|
198
|
+
PDFGlyph::Type3(cg) => slice.push(*cg),
|
|
199
|
+
PDFGlyph::Cid(cid) => {
|
|
200
|
+
slice.push((cid >> 8) as u8);
|
|
201
|
+
slice.push((cid & 0xff) as u8);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
use skrifa::outline::{DrawSettings, OutlinePen};
|
|
2
|
+
|
|
3
|
+
use crate::geom::Path;
|
|
4
|
+
use crate::geom::Transform;
|
|
5
|
+
use crate::surface::Surface;
|
|
6
|
+
use crate::text::Font;
|
|
7
|
+
use crate::text::GlyphId;
|
|
8
|
+
|
|
9
|
+
pub(crate) fn glyph_path(font: Font, glyph: GlyphId) -> Option<tiny_skia_path::Path> {
|
|
10
|
+
let outline_glyphs = font.outline_glyphs();
|
|
11
|
+
let mut outline_builder = OutlineBuilder::new();
|
|
12
|
+
|
|
13
|
+
if let Some(outline_glyph) = outline_glyphs.get(glyph.to_skrifa()) {
|
|
14
|
+
outline_glyph
|
|
15
|
+
.draw(
|
|
16
|
+
DrawSettings::unhinted(skrifa::instance::Size::unscaled(), font.location_ref()),
|
|
17
|
+
&mut outline_builder,
|
|
18
|
+
)
|
|
19
|
+
.ok()?;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
outline_builder.finish()
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/// Draw an outline-based glyph on a surface.
|
|
26
|
+
pub(crate) fn draw_glyph(
|
|
27
|
+
font: Font,
|
|
28
|
+
glyph: GlyphId,
|
|
29
|
+
base_transform: Transform,
|
|
30
|
+
surface: &mut Surface,
|
|
31
|
+
) -> Option<()> {
|
|
32
|
+
let path = Path(glyph_path(font, glyph).and_then(|p| p.transform(base_transform.to_tsp()))?);
|
|
33
|
+
|
|
34
|
+
surface.draw_path(&path);
|
|
35
|
+
|
|
36
|
+
Some(())
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/// A wrapper struct for implementing the `OutlinePen` trait.
|
|
40
|
+
pub(crate) struct OutlineBuilder(tiny_skia_path::PathBuilder);
|
|
41
|
+
|
|
42
|
+
impl OutlineBuilder {
|
|
43
|
+
pub(crate) fn new() -> Self {
|
|
44
|
+
Self(tiny_skia_path::PathBuilder::new())
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
pub(crate) fn finish(self) -> Option<tiny_skia_path::Path> {
|
|
48
|
+
self.0.finish()
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
impl OutlinePen for OutlineBuilder {
|
|
53
|
+
fn move_to(&mut self, x: f32, y: f32) {
|
|
54
|
+
self.0.move_to(x, y);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
fn line_to(&mut self, x: f32, y: f32) {
|
|
58
|
+
self.0.line_to(x, y);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32) {
|
|
62
|
+
self.0.quad_to(cx0, cy0, x, y);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32) {
|
|
66
|
+
self.0.cubic_to(cx0, cy0, cx1, cy1, x, y);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
fn close(&mut self) {
|
|
70
|
+
self.0.close()
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
use skrifa::raw::TableProvider;
|
|
2
|
+
|
|
3
|
+
use crate::color::rgb;
|
|
4
|
+
use crate::surface::Surface;
|
|
5
|
+
use crate::text::Font;
|
|
6
|
+
use crate::text::GlyphId;
|
|
7
|
+
|
|
8
|
+
pub(crate) fn has_svg_data(font: &Font, glyph: GlyphId) -> bool {
|
|
9
|
+
font.font_ref()
|
|
10
|
+
.svg()
|
|
11
|
+
.map(|svg_table| svg_table.glyph_data(glyph.to_skrifa()).is_ok())
|
|
12
|
+
.is_ok()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/// Draw an SVG-based glyph on a surface.
|
|
16
|
+
pub(crate) fn draw_glyph(
|
|
17
|
+
font: Font,
|
|
18
|
+
context_color: rgb::Color,
|
|
19
|
+
glyph: GlyphId,
|
|
20
|
+
surface: &mut Surface,
|
|
21
|
+
) -> Option<()> {
|
|
22
|
+
let svg_data = font
|
|
23
|
+
.font_ref()
|
|
24
|
+
.svg()
|
|
25
|
+
.and_then(|svg_table| svg_table.glyph_data(glyph.to_skrifa()))
|
|
26
|
+
.ok()??;
|
|
27
|
+
|
|
28
|
+
let upem = font.units_per_em();
|
|
29
|
+
|
|
30
|
+
let fn_ = surface.sc.serialize_settings().render_svg_glyph_fn;
|
|
31
|
+
fn_(svg_data, context_color, glyph, (upem, upem), surface)?;
|
|
32
|
+
|
|
33
|
+
Some(())
|
|
34
|
+
}
|