PDF Output: Fix background image + text not rendering correctly if the same background image is used with different text multiple times. Fixes #2035338 [conversion from epub to pdf - all chapter titles are the same as the first chapter](https://bugs.launchpad.net/calibre/+bug/2035338)

Chromium renders this as the background image with a soft mask. The
background image is duplicated, however calibre's image dedup
cannot work as the softmask is part of the image dictionary and dedup
works by replacing references to the image dictionary.

There is a similar breakage which will happen if there are duplicated
soft masks as the dedup code does not currently update the softmask
references.
This commit is contained in:
Kovid Goyal 2023-09-14 21:25:35 +05:30
parent f486e62714
commit 2c5490a061
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -13,9 +13,11 @@ class Image {
charbuff buf; charbuff buf;
int64_t width, height; int64_t width, height;
PdfReference ref; PdfReference ref;
PdfReference smask;
bool is_valid;
Image( const Image & ) ; Image( const Image & ) ;
Image & operator=( const Image & ) ; Image & operator=( const Image & ) ;
bool is_valid;
public: public:
Image(const PdfReference &reference, const PdfObject *o) : buf(), width(0), height(0), ref(reference) { Image(const PdfReference &reference, const PdfObject *o) : buf(), width(0), height(0), ref(reference) {
@ -30,18 +32,20 @@ class Image {
const PdfDictionary &dict = o->GetDictionary(); const PdfDictionary &dict = o->GetDictionary();
if (dict.HasKey("Width") && dict.GetKey("Width")->IsNumber()) width = dict.GetKey("Width")->GetNumber(); if (dict.HasKey("Width") && dict.GetKey("Width")->IsNumber()) width = dict.GetKey("Width")->GetNumber();
if (dict.HasKey("Height") && dict.GetKey("Height")->IsNumber()) height = dict.GetKey("Height")->GetNumber(); if (dict.HasKey("Height") && dict.GetKey("Height")->IsNumber()) height = dict.GetKey("Height")->GetNumber();
if (dict.HasKey("SMask") && dict.GetKey("SMask")->IsReference()) smask = dict.GetKey("SMask")->GetReference();
} }
Image(Image &&other) noexcept : Image(Image &&other) noexcept :
buf(std::move(other.buf)), width(other.width), height(other.height), ref(other.ref) { buf(std::move(other.buf)), width(other.width), height(other.height), ref(other.ref), smask(other.smask) {
other.buf = charbuff(); is_valid = other.is_valid; other.buf = charbuff(); is_valid = other.is_valid;
} }
Image& operator=(Image &&other) noexcept { Image& operator=(Image &&other) noexcept {
buf = std::move(other.buf); other.buf = charbuff(); ref = other.ref; buf = std::move(other.buf); other.buf = charbuff(); ref = other.ref;
width = other.width; height = other.height; is_valid = other.is_valid; width = other.width; height = other.height; is_valid = other.is_valid;
smask = other.smask;
return *this; return *this;
} }
bool operator==(const Image &other) const noexcept { bool operator==(const Image &other) const noexcept {
return other.width == width && is_valid && other.is_valid && other.height == height && other.buf == buf; return other.width == width && is_valid && other.is_valid && other.height == height && other.smask == smask && other.buf == buf;
} }
std::size_t hash() const noexcept { return buf.size(); } std::size_t hash() const noexcept { return buf.size(); }
const PdfReference& reference() const noexcept { return ref; } const PdfReference& reference() const noexcept { return ref; }