mirror of
https://github.com/typst/typst
synced 2025-07-30 07:47:55 +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 std::sync::Arc;
|
||||||
|
|
||||||
use ecow::{eco_format, EcoString};
|
use ecow::{eco_format, EcoString};
|
||||||
use typst_library::World;
|
use typst_library::{Feature, World};
|
||||||
use typst_syntax::{Span, Spanned};
|
use typst_syntax::{Span, Spanned};
|
||||||
use typst_utils::LazyHash;
|
use typst_utils::LazyHash;
|
||||||
|
|
||||||
@ -271,32 +271,42 @@ impl Packed<ImageElem> {
|
|||||||
.within(loaded)?,
|
.within(loaded)?,
|
||||||
),
|
),
|
||||||
ImageFormat::Vector(VectorFormat::Pdf) => {
|
ImageFormat::Vector(VectorFormat::Pdf) => {
|
||||||
let document =
|
if engine.world.library().features.is_enabled(Feature::PdfEmbedding) {
|
||||||
PdfDocument::new(loaded.data.clone(), engine.world.clone())
|
let document =
|
||||||
.within(loaded)?;
|
PdfDocument::new(loaded.data.clone(), engine.world.clone())
|
||||||
let page_num = self.page.get(styles);
|
.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!(
|
bail!(
|
||||||
span,
|
span,
|
||||||
"{page_num} is not a valid page number";
|
"embedding PDFs is currently an experimental, opt-in feature";
|
||||||
hint: "page numbers start at 1"
|
hint: "enable the corresponding feature to try it out";
|
||||||
)
|
hint: "convert your PDF to SVG instead"
|
||||||
};
|
);
|
||||||
|
}
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -116,9 +116,7 @@ fn build_pdf_texture(pdf: &PdfImage, w: u32, h: u32) -> Option<sk::Pixmap> {
|
|||||||
StandardFont::Helvetica => sf.helvetica.normal.clone(),
|
StandardFont::Helvetica => sf.helvetica.normal.clone(),
|
||||||
StandardFont::HelveticaBold => sf.helvetica.bold.clone(),
|
StandardFont::HelveticaBold => sf.helvetica.bold.clone(),
|
||||||
StandardFont::HelveticaOblique => sf.helvetica.italic.clone(),
|
StandardFont::HelveticaOblique => sf.helvetica.italic.clone(),
|
||||||
StandardFont::HelveticaBoldOblique => {
|
StandardFont::HelveticaBoldOblique => sf.helvetica.bold_italic.clone(),
|
||||||
sf.helvetica.bold_italic.clone()
|
|
||||||
}
|
|
||||||
StandardFont::Courier => sf.courier.normal.clone(),
|
StandardFont::Courier => sf.courier.normal.clone(),
|
||||||
StandardFont::CourierBold => sf.courier.bold.clone(),
|
StandardFont::CourierBold => sf.courier.bold.clone(),
|
||||||
StandardFont::CourierOblique => sf.courier.italic.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| {
|
bytes.map(|d| {
|
||||||
let font_data: Arc<dyn AsRef<[u8]> + Send + Sync> =
|
let font_data: Arc<dyn AsRef<[u8]> + Send + Sync> = Arc::new(d.clone());
|
||||||
Arc::new(d.clone());
|
|
||||||
|
|
||||||
font_data
|
font_data
|
||||||
})
|
})
|
||||||
@ -142,9 +139,7 @@ fn build_pdf_texture(pdf: &PdfImage, w: u32, h: u32) -> Option<sk::Pixmap> {
|
|||||||
let interpreter_settings = InterpreterSettings {
|
let interpreter_settings = InterpreterSettings {
|
||||||
font_resolver: Arc::new(move |query| match query {
|
font_resolver: Arc::new(move |query| match query {
|
||||||
FontQuery::Standard(s) => select_standard_font(*s),
|
FontQuery::Standard(s) => select_standard_font(*s),
|
||||||
FontQuery::Fallback(f) => {
|
FontQuery::Fallback(f) => select_standard_font(f.pick_standard_font()),
|
||||||
select_standard_font(f.pick_standard_font())
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
warning_sink: Arc::new(|_| {}),
|
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),
|
width: Some(w as u16),
|
||||||
height: Some(h as u16),
|
height: Some(h as u16),
|
||||||
};
|
};
|
||||||
|
|
||||||
let hayro_pix = hayro::render(page, &interpreter_settings, &render_settings);
|
let hayro_pix = hayro::render(page, &interpreter_settings, &render_settings);
|
||||||
|
|
||||||
sk::Pixmap::from_vec(hayro_pix.take_u8(), IntSize::from_wh(w, h)?)
|
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 base64::Engine;
|
||||||
use ecow::{eco_format, EcoString};
|
use ecow::{eco_format, EcoString};
|
||||||
use hayro::{FontData, FontQuery, InterpreterSettings, RenderSettings, StandardFont};
|
use hayro::{FontData, FontQuery, InterpreterSettings, RenderSettings, StandardFont};
|
||||||
use image::{codecs::png::PngEncoder, ImageEncoder};
|
use image::{codecs::png::PngEncoder, ImageEncoder};
|
||||||
|
use std::borrow::Cow;
|
||||||
|
use std::sync::Arc;
|
||||||
use typst_library::foundations::Smart;
|
use typst_library::foundations::Smart;
|
||||||
use typst_library::layout::{Abs, Axes};
|
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;
|
use crate::SVGRenderer;
|
||||||
|
|
||||||
@ -73,20 +75,19 @@ pub fn convert_image_to_base64_url(image: &Image) -> EcoString {
|
|||||||
// doesn't exceed 3000 pixels.
|
// doesn't exceed 3000 pixels.
|
||||||
const MIN_WIDTH: f32 = 1000.0;
|
const MIN_WIDTH: f32 = 1000.0;
|
||||||
const MAX_WIDTH: f32 = 3000.0;
|
const MAX_WIDTH: f32 = 3000.0;
|
||||||
|
|
||||||
|
|
||||||
let base_width = pdf.width();
|
let base_width = pdf.width();
|
||||||
let w_scale = (MIN_WIDTH / base_width).max(MAX_WIDTH / base_width);
|
let w_scale = (MIN_WIDTH / base_width).max(MAX_WIDTH / base_width);
|
||||||
let base_height = pdf.height();
|
let base_height = pdf.height();
|
||||||
let h_scale = (MIN_WIDTH / base_height).min(MAX_WIDTH / base_height);
|
let h_scale = (MIN_WIDTH / base_height).min(MAX_WIDTH / base_height);
|
||||||
|
|
||||||
let total_scale = w_scale.min(h_scale);
|
let total_scale = w_scale.min(h_scale);
|
||||||
|
|
||||||
let width = (base_width * total_scale).ceil() as u32;
|
let width = (base_width * total_scale).ceil() as u32;
|
||||||
let height = (base_height * total_scale).ceil() as u32;
|
let height = (base_height * total_scale).ceil() as u32;
|
||||||
|
|
||||||
("png", Cow::Owned(pdf_to_png(pdf, width, height)))
|
("png", Cow::Owned(pdf_to_png(pdf, width, height)))
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut url = eco_format!("data:image/{format};base64,");
|
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::Helvetica => sf.helvetica.normal.clone(),
|
||||||
StandardFont::HelveticaBold => sf.helvetica.bold.clone(),
|
StandardFont::HelveticaBold => sf.helvetica.bold.clone(),
|
||||||
StandardFont::HelveticaOblique => sf.helvetica.italic.clone(),
|
StandardFont::HelveticaOblique => sf.helvetica.italic.clone(),
|
||||||
StandardFont::HelveticaBoldOblique => {
|
StandardFont::HelveticaBoldOblique => sf.helvetica.bold_italic.clone(),
|
||||||
sf.helvetica.bold_italic.clone()
|
|
||||||
}
|
|
||||||
StandardFont::Courier => sf.courier.normal.clone(),
|
StandardFont::Courier => sf.courier.normal.clone(),
|
||||||
StandardFont::CourierBold => sf.courier.bold.clone(),
|
StandardFont::CourierBold => sf.courier.bold.clone(),
|
||||||
StandardFont::CourierOblique => sf.courier.italic.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| {
|
bytes.map(|d| {
|
||||||
let font_data: Arc<dyn AsRef<[u8]> + Send + Sync> =
|
let font_data: Arc<dyn AsRef<[u8]> + Send + Sync> = Arc::new(d.clone());
|
||||||
Arc::new(d.clone());
|
|
||||||
|
|
||||||
font_data
|
font_data
|
||||||
})
|
})
|
||||||
@ -131,9 +129,7 @@ fn pdf_to_png(pdf: &PdfImage, w: u32, h: u32) -> Vec<u8> {
|
|||||||
let interpreter_settings = InterpreterSettings {
|
let interpreter_settings = InterpreterSettings {
|
||||||
font_resolver: Arc::new(move |query| match query {
|
font_resolver: Arc::new(move |query| match query {
|
||||||
FontQuery::Standard(s) => select_standard_font(*s),
|
FontQuery::Standard(s) => select_standard_font(*s),
|
||||||
FontQuery::Fallback(f) => {
|
FontQuery::Fallback(f) => select_standard_font(f.pick_standard_font()),
|
||||||
select_standard_font(f.pick_standard_font())
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
warning_sink: Arc::new(|_| {}),
|
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);
|
let hayro_pix = hayro::render(page, &interpreter_settings, &render_settings);
|
||||||
|
|
||||||
hayro_pix.take_png()
|
hayro_pix.take_png()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user