mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
Fix text fill within clip: true
blocks in PNG export (#5502)
This commit is contained in:
parent
cda94ab405
commit
884c02872c
@ -164,30 +164,42 @@ fn write_bitmap<S: PaintSampler>(
|
||||
// If we have a clip mask we first render to a pixmap that we then blend
|
||||
// with our canvas
|
||||
if state.mask.is_some() {
|
||||
let cw = canvas.width() as i32;
|
||||
let ch = canvas.height() as i32;
|
||||
let mw = bitmap.width;
|
||||
let mh = bitmap.height;
|
||||
|
||||
let left = bitmap.left;
|
||||
let top = bitmap.top;
|
||||
|
||||
// Pad the pixmap with 1 pixel in each dimension so that we do
|
||||
// not get any problem with floating point errors along their border
|
||||
let mut pixmap = sk::Pixmap::new(mw + 2, mh + 2)?;
|
||||
let pixels = bytemuck::cast_slice_mut::<u8, u32>(pixmap.data_mut());
|
||||
for x in 0..mw {
|
||||
for y in 0..mh {
|
||||
let alpha = bitmap.coverage[(y * mw + x) as usize];
|
||||
let color = sampler.sample((x, y));
|
||||
pixmap.pixels_mut()[((y + 1) * (mw + 2) + (x + 1)) as usize] =
|
||||
sk::ColorU8::from_rgba(
|
||||
color.red(),
|
||||
color.green(),
|
||||
color.blue(),
|
||||
alpha,
|
||||
)
|
||||
.premultiply();
|
||||
|
||||
// To sample at the correct position, we need to convert each
|
||||
// pixel's position in the bitmap (x and y) to its final
|
||||
// expected position in the canvas. Due to padding, this
|
||||
// pixel's position in the pixmap will be (x + 1, y + 1).
|
||||
// Then, when drawing the pixmap to the canvas, we place its
|
||||
// top-left corner at position (left - 1, top - 1). Therefore,
|
||||
// the final position of this pixel in the canvas is given by
|
||||
// (left - 1 + x + 1, top - 1 + y + 1) = (left + x, top + y).
|
||||
let sample_pos = (
|
||||
(left + x as i32).clamp(0, cw) as u32,
|
||||
(top + y as i32).clamp(0, ch) as u32,
|
||||
);
|
||||
let color = sampler.sample(sample_pos);
|
||||
let color = bytemuck::cast(color);
|
||||
|
||||
let applied = alpha_mul(color, alpha as u32);
|
||||
pixels[((y + 1) * (mw + 2) + (x + 1)) as usize] = applied;
|
||||
}
|
||||
}
|
||||
|
||||
let left = bitmap.left;
|
||||
let top = bitmap.top;
|
||||
|
||||
canvas.draw_pixmap(
|
||||
left - 1,
|
||||
top - 1,
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 908 B |
Binary file not shown.
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
tests/ref/issue-5499-text-fill-in-clip-block.png
Normal file
BIN
tests/ref/issue-5499-text-fill-in-clip-block.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
@ -81,3 +81,34 @@ I
|
||||
// Warning: 17-34 Typst's default font has changed from Linux Libertine to its successor Libertinus Serif
|
||||
// Hint: 17-34 please set the font to `"Libertinus Serif"` instead
|
||||
#set text(font: "Linux Libertine")
|
||||
|
||||
--- issue-5499-text-fill-in-clip-block ---
|
||||
|
||||
#let pat = pattern(
|
||||
size: (30pt, 30pt),
|
||||
relative: "parent",
|
||||
square(
|
||||
size: 30pt,
|
||||
fill: gradient
|
||||
.conic(..color.map.rainbow),
|
||||
)
|
||||
)
|
||||
|
||||
#block(clip: false, height: 2em, {
|
||||
text(fill: blue, "Hello")
|
||||
[ ]
|
||||
text(fill: blue.darken(20%).transparentize(50%), "Hello")
|
||||
[ ]
|
||||
text(fill: gradient.linear(..color.map.rainbow), "Hello")
|
||||
[ ]
|
||||
text(fill: pat, "Hello")
|
||||
})
|
||||
#block(clip: true, height: 2em, {
|
||||
text(fill: blue, "Hello")
|
||||
[ ]
|
||||
text(fill: blue.darken(20%).transparentize(50%), "Hello")
|
||||
[ ]
|
||||
text(fill: gradient.linear(..color.map.rainbow), "Hello")
|
||||
[ ]
|
||||
text(fill: pat, "Hello")
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user