diff --git a/PdfForQtLib/sources/pdfoptionalcontent.cpp b/PdfForQtLib/sources/pdfoptionalcontent.cpp index 0803e37..0d32374 100644 --- a/PdfForQtLib/sources/pdfoptionalcontent.cpp +++ b/PdfForQtLib/sources/pdfoptionalcontent.cpp @@ -516,7 +516,17 @@ PDFOptionalContentMembershipObject PDFOptionalContentMembershipObject::create(co { // First, scan all optional content groups PDFDocumentDataLoaderDecorator loader(document); - std::vector ocgs = loader.readReferenceArrayFromDictionary(dictionary, "OCGs"); + std::vector ocgs; + + PDFObject singleOCG = dictionary->get("OCGs"); + if (singleOCG.isReference()) + { + ocgs = { singleOCG.getReference() }; + } + else + { + ocgs = loader.readReferenceArrayFromDictionary(dictionary, "OCGs"); + } if (!ocgs.empty()) { diff --git a/PdfForQtLib/sources/pdfpagecontentprocessor.cpp b/PdfForQtLib/sources/pdfpagecontentprocessor.cpp index c9aa8b3..4c24173 100644 --- a/PdfForQtLib/sources/pdfpagecontentprocessor.cpp +++ b/PdfForQtLib/sources/pdfpagecontentprocessor.cpp @@ -2741,29 +2741,29 @@ void PDFPageContentProcessor::operatorPaintXObject(PDFPageContentProcessor::PDFO if (m_xobjectDictionary) { - // According to the specification, XObjects are skipped entirely, as no operator was invoked. - if (m_xobjectDictionary->hasKey("OC")) - { - const PDFObject& object = m_xobjectDictionary->get("OC"); - if (object.isReference()) - { - if (isContentSuppressedByOC(object.getReference())) - { - return; - } - } - else - { - throw PDFRendererException(RenderErrorType::Error, PDFTranslationContext::tr("Reference to optional content expected.")); - } - } - const PDFObject& object = m_document->getObject(m_xobjectDictionary->get(name.name)); if (object.isStream()) { const PDFStream* stream = object.getStream(); const PDFDictionary* streamDictionary = stream->getDictionary(); + // According to the specification, XObjects are skipped entirely, as no operator was invoked. + if (streamDictionary->hasKey("OC")) + { + const PDFObject& object = streamDictionary->get("OC"); + if (object.isReference()) + { + if (isContentSuppressedByOC(object.getReference())) + { + return; + } + } + else + { + throw PDFRendererException(RenderErrorType::Error, PDFTranslationContext::tr("Reference to optional content expected.")); + } + } + PDFDocumentDataLoaderDecorator loader(m_document); QByteArray subtype = loader.readNameFromDictionary(streamDictionary, "Subtype"); if (subtype == "Image") diff --git a/PdfForQtLib/sources/pdfpainter.cpp b/PdfForQtLib/sources/pdfpainter.cpp index 53916f6..67b06b7 100644 --- a/PdfForQtLib/sources/pdfpainter.cpp +++ b/PdfForQtLib/sources/pdfpainter.cpp @@ -413,6 +413,27 @@ void PDFPrecompiledPageGenerator::performImagePainting(const QImage& image) return; } + if (isTransparencyGroupActive()) + { + PDFReal alpha = getEffectiveFillingAlpha(); + if (alpha != 1.0) + { + // Try to approximate transparency group using alpha channel + QImage imageWithAlpha = image; + QImage alphaChannel = imageWithAlpha.convertToFormat(QImage::Format_Alpha8); + uchar* bits = alphaChannel.bits(); + + for (qsizetype i = 0, sizeInBytes = alphaChannel.sizeInBytes(); i < sizeInBytes; ++i) + { + bits[i] *= alpha; + } + + imageWithAlpha.setAlphaChannel(alphaChannel); + m_precompiledPage->addImage(imageWithAlpha); + return; + } + } + m_precompiledPage->addImage(image); } diff --git a/PdfForQtLib/sources/pdfpainter.h b/PdfForQtLib/sources/pdfpainter.h index 0278963..d007de4 100644 --- a/PdfForQtLib/sources/pdfpainter.h +++ b/PdfForQtLib/sources/pdfpainter.h @@ -72,6 +72,9 @@ protected: /// Returns, if feature is turned on bool hasFeature(PDFRenderer::Feature feature) const { return m_features.testFlag(feature); } + /// Is transparency group active? + bool isTransparencyGroupActive() const { return !m_transparencyGroupDataStack.empty(); } + private: /// Returns current pen (implementation) QPen getCurrentPenImpl() const;