mirror of
				https://github.com/JakubMelka/PDF4QT.git
				synced 2025-06-05 21:59:17 +02:00 
			
		
		
		
	Bugfixing: correct handling of optional content
This commit is contained in:
		@@ -516,7 +516,17 @@ PDFOptionalContentMembershipObject PDFOptionalContentMembershipObject::create(co
 | 
			
		||||
        {
 | 
			
		||||
            // First, scan all optional content groups
 | 
			
		||||
            PDFDocumentDataLoaderDecorator loader(document);
 | 
			
		||||
            std::vector<PDFObjectReference> ocgs = loader.readReferenceArrayFromDictionary(dictionary, "OCGs");
 | 
			
		||||
            std::vector<PDFObjectReference> ocgs;
 | 
			
		||||
 | 
			
		||||
            PDFObject singleOCG = dictionary->get("OCGs");
 | 
			
		||||
            if (singleOCG.isReference())
 | 
			
		||||
            {
 | 
			
		||||
                ocgs = { singleOCG.getReference() };
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                ocgs = loader.readReferenceArrayFromDictionary(dictionary, "OCGs");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!ocgs.empty())
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
@@ -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")
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user