mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
Add support for converting text in SVGs to paths (#5390)
This commit is contained in:
parent
468a60103d
commit
67ef6066f4
@ -55,6 +55,7 @@ pub fn layout_image(
|
||||
elem.alt(styles),
|
||||
engine.world,
|
||||
&families(styles).collect::<Vec<_>>(),
|
||||
elem.flatten_text(styles),
|
||||
)
|
||||
.at(span)?;
|
||||
|
||||
|
@ -94,6 +94,12 @@ pub struct ImageElem {
|
||||
/// ```
|
||||
#[default(ImageFit::Cover)]
|
||||
pub fit: ImageFit,
|
||||
|
||||
/// Whether text in SVG images should be converted into paths before
|
||||
/// embedding. This will result in the text becoming unselectable in
|
||||
/// the output.
|
||||
#[default(false)]
|
||||
pub flatten_text: bool,
|
||||
}
|
||||
|
||||
#[scope]
|
||||
@ -246,13 +252,14 @@ impl Image {
|
||||
alt: Option<EcoString>,
|
||||
world: Tracked<dyn World + '_>,
|
||||
families: &[&str],
|
||||
flatten_text: bool,
|
||||
) -> StrResult<Image> {
|
||||
let kind = match format {
|
||||
ImageFormat::Raster(format) => {
|
||||
ImageKind::Raster(RasterImage::new(data, format)?)
|
||||
}
|
||||
ImageFormat::Vector(VectorFormat::Svg) => {
|
||||
ImageKind::Svg(SvgImage::with_fonts(data, world, families)?)
|
||||
ImageKind::Svg(SvgImage::with_fonts(data, world, flatten_text, families)?)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -22,6 +22,7 @@ pub struct SvgImage(Arc<Repr>);
|
||||
struct Repr {
|
||||
data: Bytes,
|
||||
size: Axes<f64>,
|
||||
flatten_text: bool,
|
||||
font_hash: u128,
|
||||
tree: usvg::Tree,
|
||||
}
|
||||
@ -32,7 +33,13 @@ impl SvgImage {
|
||||
pub fn new(data: Bytes) -> StrResult<SvgImage> {
|
||||
let tree =
|
||||
usvg::Tree::from_data(&data, &base_options()).map_err(format_usvg_error)?;
|
||||
Ok(Self(Arc::new(Repr { data, size: tree_size(&tree), font_hash: 0, tree })))
|
||||
Ok(Self(Arc::new(Repr {
|
||||
data,
|
||||
size: tree_size(&tree),
|
||||
font_hash: 0,
|
||||
flatten_text: false,
|
||||
tree,
|
||||
})))
|
||||
}
|
||||
|
||||
/// Decode an SVG image with access to fonts.
|
||||
@ -40,6 +47,7 @@ impl SvgImage {
|
||||
pub fn with_fonts(
|
||||
data: Bytes,
|
||||
world: Tracked<dyn World + '_>,
|
||||
flatten_text: bool,
|
||||
families: &[&str],
|
||||
) -> StrResult<SvgImage> {
|
||||
let book = world.book();
|
||||
@ -60,7 +68,13 @@ impl SvgImage {
|
||||
)
|
||||
.map_err(format_usvg_error)?;
|
||||
let font_hash = resolver.into_inner().unwrap().finish();
|
||||
Ok(Self(Arc::new(Repr { data, size: tree_size(&tree), font_hash, tree })))
|
||||
Ok(Self(Arc::new(Repr {
|
||||
data,
|
||||
size: tree_size(&tree),
|
||||
font_hash,
|
||||
flatten_text,
|
||||
tree,
|
||||
})))
|
||||
}
|
||||
|
||||
/// The raw image data.
|
||||
@ -73,6 +87,11 @@ impl SvgImage {
|
||||
self.0.size.x
|
||||
}
|
||||
|
||||
/// Whether the SVG's text should be flattened.
|
||||
pub fn flatten_text(&self) -> bool {
|
||||
self.0.flatten_text
|
||||
}
|
||||
|
||||
/// The SVG's height in pixels.
|
||||
pub fn height(&self) -> f64 {
|
||||
self.0.size.y
|
||||
|
@ -208,7 +208,11 @@ fn encode_svg(
|
||||
) -> Result<(Chunk, Ref), svg2pdf::ConversionError> {
|
||||
svg2pdf::to_chunk(
|
||||
svg.tree(),
|
||||
svg2pdf::ConversionOptions { pdfa, ..Default::default() },
|
||||
svg2pdf::ConversionOptions {
|
||||
pdfa,
|
||||
embed_text: !svg.flatten_text(),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user