summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfrozolotl <44589151+frozolotl@users.noreply.github.com>2024-02-20 14:03:25 +0100
committerGitHub <noreply@github.com>2024-02-20 13:03:25 +0000
commitee2128d115f640a72f658540262e1028038a9381 (patch)
treec241ee7d75031bd4ff3ff7f96c76b4ec90fcb417
parentd8aba7c4ff10f8f5c3bab0adb46405cc221637bd (diff)
Fix transparent text in PNG export (#3444)
-rw-r--r--crates/typst-render/src/lib.rs29
-rw-r--r--tests/ref/text/font.pngbin18319 -> 20573 bytes
-rw-r--r--tests/typ/text/font.typ6
3 files changed, 13 insertions, 22 deletions
diff --git a/crates/typst-render/src/lib.rs b/crates/typst-render/src/lib.rs
index 8c519795..fa4a9bf1 100644
--- a/crates/typst-render/src/lib.rs
+++ b/crates/typst-render/src/lib.rs
@@ -465,12 +465,7 @@ fn render_outline_glyph(
write_bitmap(canvas, &bitmap, &state, sampler)?;
}
Paint::Solid(color) => {
- write_bitmap(
- canvas,
- &bitmap,
- &state,
- to_sk_color_u8_without_alpha(*color).premultiply(),
- )?;
+ write_bitmap(canvas, &bitmap, &state, to_sk_color_u8(*color).premultiply())?;
}
Paint::Pattern(pattern) => {
let pixmap = render_pattern_frame(&state, pattern);
@@ -548,7 +543,8 @@ fn write_bitmap<S: PaintSampler>(
let color = sampler.sample((x as _, y as _));
let color = bytemuck::cast(color);
let pi = (y * cw + x) as usize;
- if cov == 255 {
+ // Fast path if color is opaque.
+ if cov == u8::MAX && color & 0xFF == 0xFF {
pixels[pi] = color;
continue;
}
@@ -771,17 +767,6 @@ fn scaled_texture(image: &Image, w: u32, h: u32) -> Option<Arc<sk::Pixmap>> {
trait PaintSampler: Copy {
/// Sample the color at the `pos` in the pixmap.
fn sample(self, pos: (u32, u32)) -> sk::PremultipliedColorU8;
-
- /// Write the sampler to a pixmap.
- fn write_to_pixmap(self, canvas: &mut sk::Pixmap) {
- let width = canvas.width();
- for x in 0..canvas.width() {
- for y in 0..canvas.height() {
- let color = self.sample((x, y));
- canvas.pixels_mut()[(y * width + x) as usize] = color;
- }
- }
- }
}
impl PaintSampler for sk::PremultipliedColorU8 {
@@ -835,7 +820,7 @@ impl PaintSampler for GradientSampler<'_> {
self.transform_to_parent.map_point(&mut point);
// Sample the gradient
- to_sk_color_u8_without_alpha(self.gradient.sample_at(
+ to_sk_color_u8(self.gradient.sample_at(
(point.x, point.y),
(self.container_size.x.to_f32(), self.container_size.y.to_f32()),
))
@@ -1027,9 +1012,9 @@ fn to_sk_color(color: Color) -> sk::Color {
sk::Color::from_rgba8(r, g, b, a)
}
-fn to_sk_color_u8_without_alpha(color: Color) -> sk::ColorU8 {
- let [r, g, b, _] = color.to_rgb().to_vec4_u8();
- sk::ColorU8::from_rgba(r, g, b, 255)
+fn to_sk_color_u8(color: Color) -> sk::ColorU8 {
+ let [r, g, b, a] = color.to_rgb().to_vec4_u8();
+ sk::ColorU8::from_rgba(r, g, b, a)
}
fn to_sk_line_cap(cap: LineCap) -> sk::LineCap {
diff --git a/tests/ref/text/font.png b/tests/ref/text/font.png
index d3893ce8..39c8a951 100644
--- a/tests/ref/text/font.png
+++ b/tests/ref/text/font.png
Binary files differ
diff --git a/tests/typ/text/font.typ b/tests/typ/text/font.typ
index 07d00d14..736ded41 100644
--- a/tests/typ/text/font.typ
+++ b/tests/typ/text/font.typ
@@ -30,6 +30,12 @@ Emoji: 🐪, 🌋, 🏞
This is #text(rgb("FA644B"))[way more] colorful.
]
+// Transparency.
+#block(fill: green)[
+ #set text(fill: rgb("FF000080"))
+ This text is transparent.
+]
+
// Disable font fallback beyond the user-specified list.
// Without disabling, New Computer Modern Math would come to the rescue.
#set text(font: ("PT Sans", "Twitter Color Emoji"), fallback: false)