mirror of
https://github.com/typst/typst
synced 2025-07-27 14:27:56 +08:00
Require the PdfEmbedding
feature
This commit is contained in:
parent
070a375f3e
commit
5ef332caa4
@ -15,7 +15,7 @@ use std::fmt::{self, Debug, Formatter};
|
||||
use std::sync::Arc;
|
||||
|
||||
use ecow::{eco_format, EcoString};
|
||||
use typst_library::World;
|
||||
use typst_library::{Feature, World};
|
||||
use typst_syntax::{Span, Spanned};
|
||||
use typst_utils::LazyHash;
|
||||
|
||||
@ -271,32 +271,42 @@ impl Packed<ImageElem> {
|
||||
.within(loaded)?,
|
||||
),
|
||||
ImageFormat::Vector(VectorFormat::Pdf) => {
|
||||
let document =
|
||||
PdfDocument::new(loaded.data.clone(), engine.world.clone())
|
||||
.within(loaded)?;
|
||||
let page_num = self.page.get(styles);
|
||||
if engine.world.library().features.is_enabled(Feature::PdfEmbedding) {
|
||||
let document =
|
||||
PdfDocument::new(loaded.data.clone(), engine.world.clone())
|
||||
.within(loaded)?;
|
||||
let page_num = self.page.get(styles);
|
||||
|
||||
if page_num == 0 {
|
||||
if page_num == 0 {
|
||||
bail!(
|
||||
span,
|
||||
"{page_num} is not a valid page number";
|
||||
hint: "page numbers for PDF start at 1"
|
||||
)
|
||||
};
|
||||
|
||||
// The user provides the page number start from 1, further down the pipeline,
|
||||
// page numbers are 0-based.
|
||||
let page_idx = page_num - 1;
|
||||
let num_pages = document.len();
|
||||
|
||||
let Some(pdf_image) = PdfImage::new(document, page_idx) else {
|
||||
bail!(
|
||||
span,
|
||||
"page {page_num} doesn't exist";
|
||||
hint: "the document only has {num_pages} pages"
|
||||
);
|
||||
};
|
||||
|
||||
ImageKind::Pdf(pdf_image)
|
||||
} else {
|
||||
bail!(
|
||||
span,
|
||||
"{page_num} is not a valid page number";
|
||||
hint: "page numbers start at 1"
|
||||
)
|
||||
};
|
||||
|
||||
let page_idx = page_num - 1;
|
||||
let num_pages = document.len();
|
||||
// The user provides the page number staring from 1, further down the pipeline they page
|
||||
// numbers are 0-based.
|
||||
let Some(pdf_image) = PdfImage::new(document, page_idx) else {
|
||||
bail!(
|
||||
span,
|
||||
"page {page_num} doesn't exist";
|
||||
hint: "the document only has {num_pages} pages"
|
||||
)
|
||||
};
|
||||
|
||||
ImageKind::Pdf(pdf_image)
|
||||
"embedding PDFs is currently an experimental, opt-in feature";
|
||||
hint: "enable the corresponding feature to try it out";
|
||||
hint: "convert your PDF to SVG instead"
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -116,9 +116,7 @@ fn build_pdf_texture(pdf: &PdfImage, w: u32, h: u32) -> Option<sk::Pixmap> {
|
||||
StandardFont::Helvetica => sf.helvetica.normal.clone(),
|
||||
StandardFont::HelveticaBold => sf.helvetica.bold.clone(),
|
||||
StandardFont::HelveticaOblique => sf.helvetica.italic.clone(),
|
||||
StandardFont::HelveticaBoldOblique => {
|
||||
sf.helvetica.bold_italic.clone()
|
||||
}
|
||||
StandardFont::HelveticaBoldOblique => sf.helvetica.bold_italic.clone(),
|
||||
StandardFont::Courier => sf.courier.normal.clone(),
|
||||
StandardFont::CourierBold => sf.courier.bold.clone(),
|
||||
StandardFont::CourierOblique => sf.courier.italic.clone(),
|
||||
@ -132,8 +130,7 @@ fn build_pdf_texture(pdf: &PdfImage, w: u32, h: u32) -> Option<sk::Pixmap> {
|
||||
};
|
||||
|
||||
bytes.map(|d| {
|
||||
let font_data: Arc<dyn AsRef<[u8]> + Send + Sync> =
|
||||
Arc::new(d.clone());
|
||||
let font_data: Arc<dyn AsRef<[u8]> + Send + Sync> = Arc::new(d.clone());
|
||||
|
||||
font_data
|
||||
})
|
||||
@ -142,9 +139,7 @@ fn build_pdf_texture(pdf: &PdfImage, w: u32, h: u32) -> Option<sk::Pixmap> {
|
||||
let interpreter_settings = InterpreterSettings {
|
||||
font_resolver: Arc::new(move |query| match query {
|
||||
FontQuery::Standard(s) => select_standard_font(*s),
|
||||
FontQuery::Fallback(f) => {
|
||||
select_standard_font(f.pick_standard_font())
|
||||
}
|
||||
FontQuery::Fallback(f) => select_standard_font(f.pick_standard_font()),
|
||||
}),
|
||||
warning_sink: Arc::new(|_| {}),
|
||||
};
|
||||
@ -156,7 +151,7 @@ fn build_pdf_texture(pdf: &PdfImage, w: u32, h: u32) -> Option<sk::Pixmap> {
|
||||
width: Some(w as u16),
|
||||
height: Some(h as u16),
|
||||
};
|
||||
|
||||
|
||||
let hayro_pix = hayro::render(page, &interpreter_settings, &render_settings);
|
||||
|
||||
sk::Pixmap::from_vec(hayro_pix.take_u8(), IntSize::from_wh(w, h)?)
|
||||
|
@ -1,12 +1,14 @@
|
||||
use std::borrow::Cow;
|
||||
use std::sync::Arc;
|
||||
use base64::Engine;
|
||||
use ecow::{eco_format, EcoString};
|
||||
use hayro::{FontData, FontQuery, InterpreterSettings, RenderSettings, StandardFont};
|
||||
use image::{codecs::png::PngEncoder, ImageEncoder};
|
||||
use std::borrow::Cow;
|
||||
use std::sync::Arc;
|
||||
use typst_library::foundations::Smart;
|
||||
use typst_library::layout::{Abs, Axes};
|
||||
use typst_library::visualize::{ExchangeFormat, Image, ImageKind, ImageScaling, PdfImage, RasterFormat};
|
||||
use typst_library::visualize::{
|
||||
ExchangeFormat, Image, ImageKind, ImageScaling, PdfImage, RasterFormat,
|
||||
};
|
||||
|
||||
use crate::SVGRenderer;
|
||||
|
||||
@ -73,20 +75,19 @@ pub fn convert_image_to_base64_url(image: &Image) -> EcoString {
|
||||
// doesn't exceed 3000 pixels.
|
||||
const MIN_WIDTH: f32 = 1000.0;
|
||||
const MAX_WIDTH: f32 = 3000.0;
|
||||
|
||||
|
||||
|
||||
let base_width = pdf.width();
|
||||
let w_scale = (MIN_WIDTH / base_width).max(MAX_WIDTH / base_width);
|
||||
let base_height = pdf.height();
|
||||
let h_scale = (MIN_WIDTH / base_height).min(MAX_WIDTH / base_height);
|
||||
|
||||
|
||||
let total_scale = w_scale.min(h_scale);
|
||||
|
||||
|
||||
let width = (base_width * total_scale).ceil() as u32;
|
||||
let height = (base_height * total_scale).ceil() as u32;
|
||||
|
||||
("png", Cow::Owned(pdf_to_png(pdf, width, height)))
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
let mut url = eco_format!("data:image/{format};base64,");
|
||||
@ -105,9 +106,7 @@ fn pdf_to_png(pdf: &PdfImage, w: u32, h: u32) -> Vec<u8> {
|
||||
StandardFont::Helvetica => sf.helvetica.normal.clone(),
|
||||
StandardFont::HelveticaBold => sf.helvetica.bold.clone(),
|
||||
StandardFont::HelveticaOblique => sf.helvetica.italic.clone(),
|
||||
StandardFont::HelveticaBoldOblique => {
|
||||
sf.helvetica.bold_italic.clone()
|
||||
}
|
||||
StandardFont::HelveticaBoldOblique => sf.helvetica.bold_italic.clone(),
|
||||
StandardFont::Courier => sf.courier.normal.clone(),
|
||||
StandardFont::CourierBold => sf.courier.bold.clone(),
|
||||
StandardFont::CourierOblique => sf.courier.italic.clone(),
|
||||
@ -121,8 +120,7 @@ fn pdf_to_png(pdf: &PdfImage, w: u32, h: u32) -> Vec<u8> {
|
||||
};
|
||||
|
||||
bytes.map(|d| {
|
||||
let font_data: Arc<dyn AsRef<[u8]> + Send + Sync> =
|
||||
Arc::new(d.clone());
|
||||
let font_data: Arc<dyn AsRef<[u8]> + Send + Sync> = Arc::new(d.clone());
|
||||
|
||||
font_data
|
||||
})
|
||||
@ -131,9 +129,7 @@ fn pdf_to_png(pdf: &PdfImage, w: u32, h: u32) -> Vec<u8> {
|
||||
let interpreter_settings = InterpreterSettings {
|
||||
font_resolver: Arc::new(move |query| match query {
|
||||
FontQuery::Standard(s) => select_standard_font(*s),
|
||||
FontQuery::Fallback(f) => {
|
||||
select_standard_font(f.pick_standard_font())
|
||||
}
|
||||
FontQuery::Fallback(f) => select_standard_font(f.pick_standard_font()),
|
||||
}),
|
||||
warning_sink: Arc::new(|_| {}),
|
||||
};
|
||||
@ -149,4 +145,4 @@ fn pdf_to_png(pdf: &PdfImage, w: u32, h: u32) -> Vec<u8> {
|
||||
let hayro_pix = hayro::render(page, &interpreter_settings, &render_settings);
|
||||
|
||||
hayro_pix.take_png()
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user