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