diff --git a/crates/typst-library/src/text/raw.rs b/crates/typst-library/src/text/raw.rs index cf4a0b6b6..8c121fa83 100644 --- a/crates/typst-library/src/text/raw.rs +++ b/crates/typst-library/src/text/raw.rs @@ -290,11 +290,7 @@ impl Show for RawElem { let theme = theme.as_deref().unwrap_or(&THEME); - let foreground = theme - .settings - .foreground - .map(to_typst) - .map_or(Color::BLACK, Color::from); + let foreground = theme.settings.foreground.unwrap_or(synt::Color::BLACK); let mut realized = if matches!(lang.as_deref(), Some("typ" | "typst" | "typc")) { let root = match lang.as_deref() { @@ -309,7 +305,7 @@ impl Show for RawElem { vec![], &highlighter, &mut |node, style| { - seq.push(styled(&text[node.range()], foreground.into(), style)); + seq.push(styled(&text[node.range()], foreground, style)); }, ); @@ -334,7 +330,7 @@ impl Show for RawElem { for (style, piece) in highlighter.highlight_line(line, syntax_set).into_iter().flatten() { - seq.push(styled(piece, foreground.into(), style)); + seq.push(styled(piece, foreground, style)); } } @@ -432,12 +428,11 @@ fn highlight_themed( } /// Style a piece of text with a syntect style. -fn styled(piece: &str, foreground: Paint, style: synt::Style) -> Content { +fn styled(piece: &str, foreground: synt::Color, style: synt::Style) -> Content { let mut body = TextElem::packed(piece); - let paint = to_typst(style.foreground).into(); - if paint != foreground { - body = body.styled(TextElem::set_fill(paint)); + if style.foreground != foreground { + body = body.styled(TextElem::set_fill(to_typst(style.foreground).into())); } if style.font_style.contains(synt::FontStyle::BOLD) { diff --git a/crates/typst/src/export/pdf/color.rs b/crates/typst/src/export/pdf/color.rs index 1ca0c3f79..4263993e3 100644 --- a/crates/typst/src/export/pdf/color.rs +++ b/crates/typst/src/export/pdf/color.rs @@ -199,20 +199,13 @@ impl ColorSpaces { writer .icc_profile(srgb, &profile) .n(3) - .range([0.0, 1.0, 0.0, 1.0, 0.0, 1.0]) - .alternate() - .srgb(); + .range([0.0, 1.0, 0.0, 1.0, 0.0, 1.0]); } // Write the gray color space if let Some(gray) = self.d65_gray { let profile = gray_icc(); - writer - .icc_profile(gray, &profile) - .n(1) - .range([0.0, 1.0]) - .alternate() - .d65_gray(); + writer.icc_profile(gray, &profile).n(1).range([0.0, 1.0]); } } } diff --git a/crates/typst/src/export/pdf/image.rs b/crates/typst/src/export/pdf/image.rs index d8064e3c1..5205c6f63 100644 --- a/crates/typst/src/export/pdf/image.rs +++ b/crates/typst/src/export/pdf/image.rs @@ -5,7 +5,10 @@ use image::{DynamicImage, GenericImageView, Rgba}; use pdf_writer::{Filter, Finish}; use super::{deflate, PdfContext, RefExt}; -use crate::image::{ImageKind, RasterFormat, RasterImage}; +use crate::{ + geom::ColorSpace, + image::{ImageKind, RasterFormat, RasterImage}, +}; /// Embed all used images into the PDF. #[tracing::instrument(skip_all)] @@ -33,9 +36,9 @@ pub fn write_images(ctx: &mut PdfContext) { if raster.icc().is_some() { space.icc_based(icc_ref); } else if has_color { - space.device_rgb(); + ctx.colors.write(ColorSpace::Srgb, space, &mut ctx.alloc); } else { - space.device_gray(); + ctx.colors.write(ColorSpace::D65Gray, space, &mut ctx.alloc); } // Add a second gray-scale image containing the alpha values if diff --git a/crates/typst/src/geom/color.rs b/crates/typst/src/geom/color.rs index aec0c5cd0..b99ba83d1 100644 --- a/crates/typst/src/geom/color.rs +++ b/crates/typst/src/geom/color.rs @@ -907,8 +907,9 @@ impl Color { } } + /// Returns the color's RGB(A) representation as an array of 8-bit values. pub fn to_vec4_u8(&self) -> [u8; 4] { - self.to_vec4().map(|x| (x * 255.0).round() as u8) + self.to_rgba().to_vec4().map(|x| (x * 255.0).round() as u8) } pub fn to_space(self, space: ColorSpace) -> Self { @@ -1113,7 +1114,9 @@ impl PartialEq for Color { // Lower precision for comparison to avoid rounding errors. // Keeps backward compatibility with previous versions of Typst. (Self::Rgba(_), Self::Rgba(_)) => self.to_vec4_u8() == other.to_vec4_u8(), - (Self::Luma(a), Self::Luma(b)) => a == b, + (Self::Luma(a), Self::Luma(b)) => { + (a.luma * 255.0).round() as u8 == (b.luma * 255.0).round() as u8 + } (Self::Oklab(a), Self::Oklab(b)) => a == b, (Self::LinearRgb(a), Self::LinearRgb(b)) => a == b, (Self::Cmyk(a), Self::Cmyk(b)) => a == b, diff --git a/tests/ref/bugs/raw-color-overwrite.png b/tests/ref/bugs/raw-color-overwrite.png new file mode 100644 index 000000000..b01d86a49 Binary files /dev/null and b/tests/ref/bugs/raw-color-overwrite.png differ diff --git a/tests/typ/bugs/raw-color-overwrite.typ b/tests/typ/bugs/raw-color-overwrite.typ new file mode 100644 index 000000000..ec306ef1a --- /dev/null +++ b/tests/typ/bugs/raw-color-overwrite.typ @@ -0,0 +1,13 @@ +// Test that the color of a raw block is not overwritten + +--- + +#show raw: set text(fill: blue) + +`Hello, World!` + +```rs +fn main() { + println!("Hello, World!"); +} +``` \ No newline at end of file