mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-04-25 07:28:48 +02:00
Bugfixing: correct handling of optional content
This commit is contained in:
parent
1fd01c14fd
commit
7ad4c46124
@ -516,7 +516,17 @@ PDFOptionalContentMembershipObject PDFOptionalContentMembershipObject::create(co
|
|||||||
{
|
{
|
||||||
// First, scan all optional content groups
|
// First, scan all optional content groups
|
||||||
PDFDocumentDataLoaderDecorator loader(document);
|
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())
|
if (!ocgs.empty())
|
||||||
{
|
{
|
||||||
|
@ -2741,29 +2741,29 @@ void PDFPageContentProcessor::operatorPaintXObject(PDFPageContentProcessor::PDFO
|
|||||||
|
|
||||||
if (m_xobjectDictionary)
|
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));
|
const PDFObject& object = m_document->getObject(m_xobjectDictionary->get(name.name));
|
||||||
if (object.isStream())
|
if (object.isStream())
|
||||||
{
|
{
|
||||||
const PDFStream* stream = object.getStream();
|
const PDFStream* stream = object.getStream();
|
||||||
const PDFDictionary* streamDictionary = stream->getDictionary();
|
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);
|
PDFDocumentDataLoaderDecorator loader(m_document);
|
||||||
QByteArray subtype = loader.readNameFromDictionary(streamDictionary, "Subtype");
|
QByteArray subtype = loader.readNameFromDictionary(streamDictionary, "Subtype");
|
||||||
if (subtype == "Image")
|
if (subtype == "Image")
|
||||||
|
@ -413,6 +413,27 @@ void PDFPrecompiledPageGenerator::performImagePainting(const QImage& image)
|
|||||||
return;
|
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);
|
m_precompiledPage->addImage(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,9 @@ protected:
|
|||||||
/// Returns, if feature is turned on
|
/// Returns, if feature is turned on
|
||||||
bool hasFeature(PDFRenderer::Feature feature) const { return m_features.testFlag(feature); }
|
bool hasFeature(PDFRenderer::Feature feature) const { return m_features.testFlag(feature); }
|
||||||
|
|
||||||
|
/// Is transparency group active?
|
||||||
|
bool isTransparencyGroupActive() const { return !m_transparencyGroupDataStack.empty(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Returns current pen (implementation)
|
/// Returns current pen (implementation)
|
||||||
QPen getCurrentPenImpl() const;
|
QPen getCurrentPenImpl() const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user