LibPDF: Add support for image masks
An image mask is a 1-bit-per-pixel bitmap that's black where the current color should be painted, and white where it should be transparent (think: like ink). load_image() already converts images like this into 8-bit-per-pixel images that have 0xff, 0xff, 0xff in rgb for opaque (originally 0 bit) pixels and 0, 0, 0 in rgb for transparent pixels. So we just move copy the image mask's image data into the alpha channel and replace rgb with the current color, and then draw it like a regular bitmap.
This commit is contained in:
parent
675b242e84
commit
4fd5d450be
Notes:
sideshowbarker
2024-07-17 18:06:52 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/4fd5d450be Pull-request: https://github.com/SerenityOS/serenity/pull/22676
1 changed files with 13 additions and 3 deletions
|
@ -1207,10 +1207,20 @@ PDFErrorOr<void> Renderer::show_image(NonnullRefPtr<StreamObject> image)
|
|||
return {};
|
||||
}
|
||||
auto image_bitmap = TRY(load_image(image));
|
||||
if (image_bitmap.is_image_mask)
|
||||
return Error(Error::Type::RenderingUnsupported, "Image masks");
|
||||
if (image_bitmap.is_image_mask) {
|
||||
// PDF 1.7 spec, 4.8.5 Masked Images, Stencil Masking:
|
||||
// "An image mask (an image XObject whose ImageMask entry is true) [...] is treated as a stencil mask [...].
|
||||
// Sample values [...] designate places on the page that should either be marked with the current color or masked out (not marked at all)."
|
||||
if (!state().paint_style.has<Gfx::Color>())
|
||||
return Error(Error::Type::RenderingUnsupported, "Image masks with pattern fill not yet implemented");
|
||||
|
||||
if (image_dict->contains(CommonNames::SMask)) {
|
||||
// Move mask to alpha channel, and put current color in RGB.
|
||||
auto current_color = state().paint_style.get<Gfx::Color>();
|
||||
for (auto& pixel : *image_bitmap.bitmap) {
|
||||
u8 mask_alpha = Color::from_argb(pixel).luminosity();
|
||||
pixel = current_color.with_alpha(mask_alpha).value();
|
||||
}
|
||||
} else if (image_dict->contains(CommonNames::SMask)) {
|
||||
auto smask_bitmap = TRY(load_image(TRY(image_dict->get_stream(m_document, CommonNames::SMask))));
|
||||
TRY(apply_alpha_channel(image_bitmap.bitmap, smask_bitmap.bitmap));
|
||||
} else if (image_dict->contains(CommonNames::Mask)) {
|
||||
|
|
Loading…
Add table
Reference in a new issue