Compare commits

...

5 Commits

Author SHA1 Message Date
Max
aee99408e1
Apply short fall consistently in math when stretching (#6377) 2025-06-04 10:14:24 +00:00
Linus Unnebäck
1de2095f67
Add support for WebP images (#6311) 2025-06-04 09:54:03 +00:00
Max
5f776c7372
Bump New CM fonts to version 7.0.2 (#6376) 2025-06-04 09:41:08 +00:00
Max
128c40d839
Apply script-style to numbers consistently in math (#6320) 2025-06-04 08:20:54 +00:00
Nazar Serhiichuk
4a8367e90a
Fix Ukrainian secondary smart quotes (#6372) 2025-06-04 08:13:39 +00:00
62 changed files with 44 additions and 42 deletions

3
Cargo.lock generated
View File

@ -1215,6 +1215,7 @@ dependencies = [
"byteorder-lite", "byteorder-lite",
"color_quant", "color_quant",
"gif", "gif",
"image-webp",
"num-traits", "num-traits",
"png", "png",
"zune-core", "zune-core",
@ -2863,7 +2864,7 @@ dependencies = [
[[package]] [[package]]
name = "typst-assets" name = "typst-assets"
version = "0.13.1" version = "0.13.1"
source = "git+https://github.com/typst/typst-assets?rev=ab1295f#ab1295ff896444e51902e03c2669955e1d73604a" source = "git+https://github.com/typst/typst-assets?rev=c74e539#c74e539b090070a0c66fd007c550f5b6d3b724bd"
[[package]] [[package]]
name = "typst-cli" name = "typst-cli"

View File

@ -32,7 +32,7 @@ typst-svg = { path = "crates/typst-svg", version = "0.13.1" }
typst-syntax = { path = "crates/typst-syntax", version = "0.13.1" } typst-syntax = { path = "crates/typst-syntax", version = "0.13.1" }
typst-timing = { path = "crates/typst-timing", version = "0.13.1" } typst-timing = { path = "crates/typst-timing", version = "0.13.1" }
typst-utils = { path = "crates/typst-utils", version = "0.13.1" } typst-utils = { path = "crates/typst-utils", version = "0.13.1" }
typst-assets = { git = "https://github.com/typst/typst-assets", rev = "ab1295f" } typst-assets = { git = "https://github.com/typst/typst-assets", rev = "c74e539" }
typst-dev-assets = { git = "https://github.com/typst/typst-dev-assets", rev = "fddbf8b" } typst-dev-assets = { git = "https://github.com/typst/typst-dev-assets", rev = "fddbf8b" }
arrayvec = "0.7.4" arrayvec = "0.7.4"
az = "1.2" az = "1.2"
@ -69,7 +69,7 @@ icu_provider_adapters = "1.4"
icu_provider_blob = "1.4" icu_provider_blob = "1.4"
icu_segmenter = { version = "1.4", features = ["serde"] } icu_segmenter = { version = "1.4", features = ["serde"] }
if_chain = "1" if_chain = "1"
image = { version = "0.25.5", default-features = false, features = ["png", "jpeg", "gif"] } image = { version = "0.25.5", default-features = false, features = ["png", "jpeg", "gif", "webp"] }
indexmap = { version = "2", features = ["serde"] } indexmap = { version = "2", features = ["serde"] }
infer = { version = "0.19.0", default-features = false } infer = { version = "0.19.0", default-features = false }
kamadak-exif = "0.6" kamadak-exif = "0.6"

View File

@ -841,7 +841,9 @@ fn param_value_completions<'a>(
/// Returns which file extensions to complete for the given parameter if any. /// Returns which file extensions to complete for the given parameter if any.
fn path_completion(func: &Func, param: &ParamInfo) -> Option<&'static [&'static str]> { fn path_completion(func: &Func, param: &ParamInfo) -> Option<&'static [&'static str]> {
Some(match (func.name(), param.name) { Some(match (func.name(), param.name) {
(Some("image"), "source") => &["png", "jpg", "jpeg", "gif", "svg", "svgz"], (Some("image"), "source") => {
&["png", "jpg", "jpeg", "gif", "svg", "svgz", "webp"]
}
(Some("csv"), "source") => &["csv"], (Some("csv"), "source") => &["csv"],
(Some("plugin"), "source") => &["wasm"], (Some("plugin"), "source") => &["wasm"],
(Some("cbor"), "source") => &["cbor"], (Some("cbor"), "source") => &["cbor"],

View File

@ -147,6 +147,7 @@ fn determine_format(source: &DataSource, data: &Bytes) -> StrResult<ImageFormat>
"jpg" | "jpeg" => return Ok(ExchangeFormat::Jpg.into()), "jpg" | "jpeg" => return Ok(ExchangeFormat::Jpg.into()),
"gif" => return Ok(ExchangeFormat::Gif.into()), "gif" => return Ok(ExchangeFormat::Gif.into()),
"svg" | "svgz" => return Ok(VectorFormat::Svg.into()), "svg" | "svgz" => return Ok(VectorFormat::Svg.into()),
"webp" => return Ok(ExchangeFormat::Webp.into()),
_ => {} _ => {}
} }
} }

View File

@ -46,7 +46,7 @@ pub fn layout_accent(
// wide in many case. // wide in many case.
let width = elem.size(styles).relative_to(base.width()); let width = elem.size(styles).relative_to(base.width());
let short_fall = ACCENT_SHORT_FALL.at(glyph.font_size); let short_fall = ACCENT_SHORT_FALL.at(glyph.font_size);
let variant = glyph.stretch_horizontal(ctx, width, short_fall); let variant = glyph.stretch_horizontal(ctx, width - short_fall);
let accent = variant.frame; let accent = variant.frame;
let accent_attach = variant.accent_attach.0; let accent_attach = variant.accent_attach.0;

View File

@ -110,12 +110,12 @@ fn layout_frac_like(
if binom { if binom {
let mut left = GlyphFragment::new(ctx, styles, '(', span) let mut left = GlyphFragment::new(ctx, styles, '(', span)
.stretch_vertical(ctx, height, short_fall); .stretch_vertical(ctx, height - short_fall);
left.center_on_axis(ctx); left.center_on_axis(ctx);
ctx.push(left); ctx.push(left);
ctx.push(FrameFragment::new(styles, frame)); ctx.push(FrameFragment::new(styles, frame));
let mut right = GlyphFragment::new(ctx, styles, ')', span) let mut right = GlyphFragment::new(ctx, styles, ')', span)
.stretch_vertical(ctx, height, short_fall); .stretch_vertical(ctx, height - short_fall);
right.center_on_axis(ctx); right.center_on_axis(ctx);
ctx.push(right); ctx.push(right);
} else { } else {

View File

@ -435,13 +435,8 @@ impl GlyphFragment {
} }
/// Try to stretch a glyph to a desired height. /// Try to stretch a glyph to a desired height.
pub fn stretch_vertical( pub fn stretch_vertical(self, ctx: &mut MathContext, height: Abs) -> VariantFragment {
self, stretch_glyph(ctx, self, height, Axis::Y)
ctx: &mut MathContext,
height: Abs,
short_fall: Abs,
) -> VariantFragment {
stretch_glyph(ctx, self, height, short_fall, Axis::Y)
} }
/// Try to stretch a glyph to a desired width. /// Try to stretch a glyph to a desired width.
@ -449,9 +444,8 @@ impl GlyphFragment {
self, self,
ctx: &mut MathContext, ctx: &mut MathContext,
width: Abs, width: Abs,
short_fall: Abs,
) -> VariantFragment { ) -> VariantFragment {
stretch_glyph(ctx, self, width, short_fall, Axis::X) stretch_glyph(ctx, self, width, Axis::X)
} }
} }

View File

@ -314,7 +314,7 @@ fn layout_delimiters(
if let Some(left) = left { if let Some(left) = left {
let mut left = GlyphFragment::new(ctx, styles, left, span) let mut left = GlyphFragment::new(ctx, styles, left, span)
.stretch_vertical(ctx, target, short_fall); .stretch_vertical(ctx, target - short_fall);
left.align_on_axis(ctx, delimiter_alignment(left.c)); left.align_on_axis(ctx, delimiter_alignment(left.c));
ctx.push(left); ctx.push(left);
} }
@ -323,7 +323,7 @@ fn layout_delimiters(
if let Some(right) = right { if let Some(right) = right {
let mut right = GlyphFragment::new(ctx, styles, right, span) let mut right = GlyphFragment::new(ctx, styles, right, span)
.stretch_vertical(ctx, target, short_fall); .stretch_vertical(ctx, target - short_fall);
right.align_on_axis(ctx, delimiter_alignment(right.c)); right.align_on_axis(ctx, delimiter_alignment(right.c));
ctx.push(right); ctx.push(right);
} }

View File

@ -50,7 +50,7 @@ pub fn layout_root(
// Layout root symbol. // Layout root symbol.
let target = radicand.height() + thickness + gap; let target = radicand.height() + thickness + gap;
let sqrt = GlyphFragment::new(ctx, styles, '√', span) let sqrt = GlyphFragment::new(ctx, styles, '√', span)
.stretch_vertical(ctx, target, Abs::zero()) .stretch_vertical(ctx, target)
.frame; .frame;
// Layout the index. // Layout the index.

View File

@ -67,8 +67,7 @@ pub fn stretch_fragment(
let mut variant = stretch_glyph( let mut variant = stretch_glyph(
ctx, ctx,
glyph, glyph,
stretch.relative_to(relative_to_size), stretch.relative_to(relative_to_size) - short_fall,
short_fall,
axis, axis,
); );
@ -120,7 +119,6 @@ pub fn stretch_glyph(
ctx: &mut MathContext, ctx: &mut MathContext,
mut base: GlyphFragment, mut base: GlyphFragment,
target: Abs, target: Abs,
short_fall: Abs,
axis: Axis, axis: Axis,
) -> VariantFragment { ) -> VariantFragment {
// If the base glyph is good enough, use it. // If the base glyph is good enough, use it.
@ -128,8 +126,7 @@ pub fn stretch_glyph(
Axis::X => base.width, Axis::X => base.width,
Axis::Y => base.height(), Axis::Y => base.height(),
}; };
let short_target = target - short_fall; if target <= advance {
if short_target <= advance {
return base.into_variant(); return base.into_variant();
} }
@ -153,13 +150,13 @@ pub fn stretch_glyph(
for variant in construction.variants { for variant in construction.variants {
best_id = variant.variant_glyph; best_id = variant.variant_glyph;
best_advance = base.font.to_em(variant.advance_measurement).at(base.font_size); best_advance = base.font.to_em(variant.advance_measurement).at(base.font_size);
if short_target <= best_advance { if target <= best_advance {
break; break;
} }
} }
// This is either good or the best we've got. // This is either good or the best we've got.
if short_target <= best_advance || construction.assembly.is_none() { if target <= best_advance || construction.assembly.is_none() {
base.set_id(ctx, best_id); base.set_id(ctx, best_id);
return base.into_variant(); return base.into_variant();
} }

View File

@ -65,18 +65,13 @@ fn layout_inline_text(
// Small optimization for numbers. Note that this lays out slightly // Small optimization for numbers. Note that this lays out slightly
// differently to normal text and is worth re-evaluating in the future. // differently to normal text and is worth re-evaluating in the future.
let mut fragments = vec![]; let mut fragments = vec![];
let is_single = text.chars().count() == 1;
for unstyled_c in text.chars() { for unstyled_c in text.chars() {
let c = styled_char(styles, unstyled_c, false); let c = styled_char(styles, unstyled_c, false);
let mut glyph = GlyphFragment::new(ctx, styles, c, span); let mut glyph = GlyphFragment::new(ctx, styles, c, span);
if is_single { match EquationElem::size_in(styles) {
// Duplicate what `layout_glyph` does exactly even if it's MathSize::Script => glyph.make_script_size(ctx),
// probably incorrect here. MathSize::ScriptScript => glyph.make_script_script_size(ctx),
match EquationElem::size_in(styles) { _ => {}
MathSize::Script => glyph.make_script_size(ctx),
MathSize::ScriptScript => glyph.make_script_script_size(ctx),
_ => {}
}
} }
fragments.push(glyph.into()); fragments.push(glyph.into());
} }
@ -164,7 +159,7 @@ fn layout_glyph(
let mut variant = if math_size == MathSize::Display { let mut variant = if math_size == MathSize::Display {
let height = scaled!(ctx, styles, display_operator_min_height) let height = scaled!(ctx, styles, display_operator_min_height)
.max(SQRT_2 * glyph.height()); .max(SQRT_2 * glyph.height());
glyph.stretch_vertical(ctx, height, Abs::zero()) glyph.stretch_vertical(ctx, height)
} else { } else {
glyph.into_variant() glyph.into_variant()
}; };

View File

@ -286,7 +286,7 @@ fn layout_underoverspreader(
let body_class = body.class(); let body_class = body.class();
let body = body.into_fragment(styles); let body = body.into_fragment(styles);
let glyph = GlyphFragment::new(ctx, styles, c, span); let glyph = GlyphFragment::new(ctx, styles, c, span);
let stretched = glyph.stretch_horizontal(ctx, body.width(), Abs::zero()); let stretched = glyph.stretch_horizontal(ctx, body.width());
let mut rows = vec![]; let mut rows = vec![];
let baseline = match position { let baseline = match position {

View File

@ -247,8 +247,9 @@ impl<'s> SmartQuotes<'s> {
"es" if matches!(region, Some("ES") | None) => ("", "", "«", "»"), "es" if matches!(region, Some("ES") | None) => ("", "", "«", "»"),
"hu" | "pl" | "ro" => ("", "", "", ""), "hu" | "pl" | "ro" => ("", "", "", ""),
"no" | "nb" | "nn" if alternative => low_high, "no" | "nb" | "nn" if alternative => low_high,
"no" | "nb" | "nn" | "uk" => ("", "", "«", "»"), "no" | "nb" | "nn" => ("", "", "«", "»"),
"ru" => ("", "", "«", "»"), "ru" => ("", "", "«", "»"),
"uk" => ("", "", "«", "»"),
"el" => ("", "", "«", "»"), "el" => ("", "", "«", "»"),
"he" => ("", "", "", ""), "he" => ("", "", "", ""),
"hr" => ("", "", "", ""), "hr" => ("", "", "", ""),

View File

@ -77,8 +77,8 @@ pub struct ImageElem {
/// [`source`]($image.source) (even then, Typst will try to figure out the /// [`source`]($image.source) (even then, Typst will try to figure out the
/// format automatically, but that's not always possible). /// format automatically, but that's not always possible).
/// ///
/// Supported formats are `{"png"}`, `{"jpg"}`, `{"gif"}`, `{"svg"}` as well /// Supported formats are `{"png"}`, `{"jpg"}`, `{"gif"}`, `{"svg"}`,
/// as raw pixel data. Embedding PDFs as images is /// `{"webp"}` as well as raw pixel data. Embedding PDFs as images is
/// [not currently supported](https://github.com/typst/typst/issues/145). /// [not currently supported](https://github.com/typst/typst/issues/145).
/// ///
/// When providing raw pixel data as the `source`, you must specify a /// When providing raw pixel data as the `source`, you must specify a

View File

@ -9,6 +9,7 @@ use ecow::{eco_format, EcoString};
use image::codecs::gif::GifDecoder; use image::codecs::gif::GifDecoder;
use image::codecs::jpeg::JpegDecoder; use image::codecs::jpeg::JpegDecoder;
use image::codecs::png::PngDecoder; use image::codecs::png::PngDecoder;
use image::codecs::webp::WebPDecoder;
use image::{ use image::{
guess_format, DynamicImage, ImageBuffer, ImageDecoder, ImageResult, Limits, Pixel, guess_format, DynamicImage, ImageBuffer, ImageDecoder, ImageResult, Limits, Pixel,
}; };
@ -77,6 +78,7 @@ impl RasterImage {
ExchangeFormat::Jpg => decode(JpegDecoder::new(cursor), icc), ExchangeFormat::Jpg => decode(JpegDecoder::new(cursor), icc),
ExchangeFormat::Png => decode(PngDecoder::new(cursor), icc), ExchangeFormat::Png => decode(PngDecoder::new(cursor), icc),
ExchangeFormat::Gif => decode(GifDecoder::new(cursor), icc), ExchangeFormat::Gif => decode(GifDecoder::new(cursor), icc),
ExchangeFormat::Webp => decode(WebPDecoder::new(cursor), icc),
} }
.map_err(format_image_error)?; .map_err(format_image_error)?;
@ -242,6 +244,8 @@ pub enum ExchangeFormat {
/// Raster format that is typically used for short animated clips. Typst can /// Raster format that is typically used for short animated clips. Typst can
/// load GIFs, but they will become static. /// load GIFs, but they will become static.
Gif, Gif,
/// Raster format that supports both lossy and lossless compression.
Webp,
} }
impl ExchangeFormat { impl ExchangeFormat {
@ -257,6 +261,7 @@ impl From<ExchangeFormat> for image::ImageFormat {
ExchangeFormat::Png => image::ImageFormat::Png, ExchangeFormat::Png => image::ImageFormat::Png,
ExchangeFormat::Jpg => image::ImageFormat::Jpeg, ExchangeFormat::Jpg => image::ImageFormat::Jpeg,
ExchangeFormat::Gif => image::ImageFormat::Gif, ExchangeFormat::Gif => image::ImageFormat::Gif,
ExchangeFormat::Webp => image::ImageFormat::WebP,
} }
} }
} }
@ -269,6 +274,7 @@ impl TryFrom<image::ImageFormat> for ExchangeFormat {
image::ImageFormat::Png => ExchangeFormat::Png, image::ImageFormat::Png => ExchangeFormat::Png,
image::ImageFormat::Jpeg => ExchangeFormat::Jpg, image::ImageFormat::Jpeg => ExchangeFormat::Jpg,
image::ImageFormat::Gif => ExchangeFormat::Gif, image::ImageFormat::Gif => ExchangeFormat::Gif,
image::ImageFormat::WebP => ExchangeFormat::Webp,
_ => bail!("format not yet supported"), _ => bail!("format not yet supported"),
}) })
} }

View File

@ -45,6 +45,7 @@ pub fn convert_image_to_base64_url(image: &Image) -> EcoString {
ExchangeFormat::Png => "png", ExchangeFormat::Png => "png",
ExchangeFormat::Jpg => "jpeg", ExchangeFormat::Jpg => "jpeg",
ExchangeFormat::Gif => "gif", ExchangeFormat::Gif => "gif",
ExchangeFormat::Webp => "webp",
}, },
raster.data(), raster.data(),
), ),

View File

@ -69,7 +69,7 @@ the first item of the list above by indenting it.
## Adding a figure { #figure } ## Adding a figure { #figure }
You think that your report would benefit from a figure. Let's add one. Typst You think that your report would benefit from a figure. Let's add one. Typst
supports images in the formats PNG, JPEG, GIF, and SVG. To add an image file to supports images in the formats PNG, JPEG, GIF, SVG, and WebP. To add an image file to
your project, first open the _file panel_ by clicking the box icon in the left your project, first open the _file panel_ by clicking the box icon in the left
sidebar. Here, you can see a list of all files in your project. Currently, there sidebar. Here, you can see a list of all files in your project. Currently, there
is only one: The main Typst file you are writing in. To upload another file, is only one: The main Typst file you are writing in. To upload another file,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 465 B

After

Width:  |  Height:  |  Size: 461 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 644 B

After

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 572 B

After

Width:  |  Height:  |  Size: 567 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 351 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 510 B

After

Width:  |  Height:  |  Size: 506 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 670 B

After

Width:  |  Height:  |  Size: 687 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 340 B

After

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 506 B

After

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 927 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 989 B

After

Width:  |  Height:  |  Size: 903 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 976 B

After

Width:  |  Height:  |  Size: 875 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 954 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 818 B

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 496 B

After

Width:  |  Height:  |  Size: 526 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 651 B

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 882 B

After

Width:  |  Height:  |  Size: 956 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 902 B

After

Width:  |  Height:  |  Size: 897 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 648 B

After

Width:  |  Height:  |  Size: 640 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 927 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 420 B

After

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 651 B

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 620 B

After

Width:  |  Height:  |  Size: 630 B

BIN
tests/ref/smartquote-uk.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -46,6 +46,10 @@
#set text(lang: "ru") #set text(lang: "ru")
"Лошадь не ест салат из огурцов" - это была первая фраза, сказанная по 'телефону'. "Лошадь не ест салат из огурцов" - это была первая фраза, сказанная по 'телефону'.
--- smartquote-uk ---
#set text(lang: "uk")
"Кінь не їсть огірковий салат" перше речення, коли-небудь вимовлене по 'телефону'.
--- smartquote-it --- --- smartquote-it ---
#set text(lang: "it") #set text(lang: "it")
"Il cavallo non mangia insalata di cetrioli" è stata la prima frase pronunciata al 'telefono'. "Il cavallo non mangia insalata di cetrioli" è stata la prima frase pronunciata al 'telefono'.

View File

@ -243,7 +243,7 @@ A #box(image("/assets/images/tiger.jpg", height: 1cm, width: 80%)) B
--- image-png-but-pixmap-format --- --- image-png-but-pixmap-format ---
#image( #image(
read("/assets/images/tiger.jpg", encoding: none), read("/assets/images/tiger.jpg", encoding: none),
// Error: 11-18 expected "png", "jpg", "gif", dictionary, "svg", or auto // Error: 11-18 expected "png", "jpg", "gif", "webp", dictionary, "svg", or auto
format: "rgba8", format: "rgba8",
) )