mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Bugfixing for patterns
This commit is contained in:
@ -350,12 +350,11 @@ PDFColorSpacePointer PDFAbstractColorSpace::createColorSpaceImpl(const PDFDictio
|
|||||||
{
|
{
|
||||||
stream = colorSpaceSettings.getStream();
|
stream = colorSpaceSettings.getStream();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (name == COLOR_SPACE_NAME_PATTERN)
|
if (name == COLOR_SPACE_NAME_PATTERN)
|
||||||
{
|
{
|
||||||
PDFPatternPtr pattern = PDFPattern::createPattern(colorSpaceDictionary, document, array->getItem(1));
|
return PDFColorSpacePointer(new PDFPatternColorSpace(std::make_shared<PDFInvalidPattern>()));
|
||||||
return PDFColorSpacePointer(new PDFPatternColorSpace(qMove(pattern)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dictionary)
|
if (dictionary)
|
||||||
@ -414,6 +413,11 @@ PDFColorSpacePointer PDFAbstractColorSpace::createDeviceColorSpaceByNameImpl(con
|
|||||||
throw PDFParserException(PDFTranslationContext::tr("Can't load color space, because color space structure is too complex."));
|
throw PDFParserException(PDFTranslationContext::tr("Can't load color space, because color space structure is too complex."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name == COLOR_SPACE_NAME_PATTERN)
|
||||||
|
{
|
||||||
|
return PDFColorSpacePointer(new PDFPatternColorSpace(std::make_shared<PDFInvalidPattern>()));
|
||||||
|
}
|
||||||
|
|
||||||
if (name == COLOR_SPACE_NAME_DEVICE_GRAY || name == COLOR_SPACE_NAME_ABBREVIATION_DEVICE_GRAY)
|
if (name == COLOR_SPACE_NAME_DEVICE_GRAY || name == COLOR_SPACE_NAME_ABBREVIATION_DEVICE_GRAY)
|
||||||
{
|
{
|
||||||
if (colorSpaceDictionary && colorSpaceDictionary->hasKey(COLOR_SPACE_NAME_DEFAULT_GRAY))
|
if (colorSpaceDictionary && colorSpaceDictionary->hasKey(COLOR_SPACE_NAME_DEFAULT_GRAY))
|
||||||
@ -985,7 +989,7 @@ const unsigned char* PDFImageData::getRow(unsigned int rowIndex) const
|
|||||||
|
|
||||||
QColor PDFPatternColorSpace::getDefaultColor() const
|
QColor PDFPatternColorSpace::getDefaultColor() const
|
||||||
{
|
{
|
||||||
throw PDFParserException(PDFTranslationContext::tr("Pattern doesn't have default color."));
|
return QColor(Qt::transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor PDFPatternColorSpace::getColor(const PDFColor& color) const
|
QColor PDFPatternColorSpace::getColor(const PDFColor& color) const
|
||||||
|
@ -177,6 +177,7 @@ void PDFPageContentProcessor::initDictionaries(const PDFObject& resourcesObject)
|
|||||||
m_extendedGraphicStateDictionary = getDictionary(PDF_RESOURCE_EXTGSTATE);
|
m_extendedGraphicStateDictionary = getDictionary(PDF_RESOURCE_EXTGSTATE);
|
||||||
m_propertiesDictionary = getDictionary("Properties");
|
m_propertiesDictionary = getDictionary("Properties");
|
||||||
m_shadingDictionary = getDictionary("Shading");
|
m_shadingDictionary = getDictionary("Shading");
|
||||||
|
m_patternDictionary = getDictionary("Pattern");
|
||||||
}
|
}
|
||||||
|
|
||||||
PDFPageContentProcessor::PDFPageContentProcessor(const PDFPage* page,
|
PDFPageContentProcessor::PDFPageContentProcessor(const PDFPage* page,
|
||||||
@ -194,6 +195,7 @@ PDFPageContentProcessor::PDFPageContentProcessor(const PDFPage* page,
|
|||||||
m_extendedGraphicStateDictionary(nullptr),
|
m_extendedGraphicStateDictionary(nullptr),
|
||||||
m_propertiesDictionary(nullptr),
|
m_propertiesDictionary(nullptr),
|
||||||
m_shadingDictionary(nullptr),
|
m_shadingDictionary(nullptr),
|
||||||
|
m_patternDictionary(nullptr),
|
||||||
m_textBeginEndState(0),
|
m_textBeginEndState(0),
|
||||||
m_compatibilityBeginEndState(0),
|
m_compatibilityBeginEndState(0),
|
||||||
m_patternBaseMatrix(pagePointToDevicePointMatrix),
|
m_patternBaseMatrix(pagePointToDevicePointMatrix),
|
||||||
@ -595,8 +597,19 @@ void PDFPageContentProcessor::processPathPainting(const QPainterPath& path, bool
|
|||||||
const PDFPattern* pattern = getGraphicState()->getFillColorSpace()->getPattern();
|
const PDFPattern* pattern = getGraphicState()->getFillColorSpace()->getPattern();
|
||||||
if (pattern)
|
if (pattern)
|
||||||
{
|
{
|
||||||
if (const PDFShadingPattern* shadingPatern = pattern->getShadingPattern())
|
switch (pattern->getType())
|
||||||
{
|
{
|
||||||
|
case PatternType::Tiling:
|
||||||
|
{
|
||||||
|
// TODO: Implement tiling pattern
|
||||||
|
throw PDFParserException(PDFTranslationContext::tr("Tiling pattern not implemented."));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PatternType::Shading:
|
||||||
|
{
|
||||||
|
const PDFShadingPattern* shadingPatern = pattern->getShadingPattern();
|
||||||
|
|
||||||
// We must create a mesh and then draw pattern
|
// We must create a mesh and then draw pattern
|
||||||
PDFMeshQualitySettings settings;
|
PDFMeshQualitySettings settings;
|
||||||
settings.deviceSpaceMeshingArea = getPageBoundingRectDeviceSpace();
|
settings.deviceSpaceMeshingArea = getPageBoundingRectDeviceSpace();
|
||||||
@ -611,11 +624,20 @@ void PDFPageContentProcessor::processPathPainting(const QPainterPath& path, bool
|
|||||||
mesh.setBoundingPath(boundingPath);
|
mesh.setBoundingPath(boundingPath);
|
||||||
|
|
||||||
performMeshPainting(mesh);
|
performMeshPainting(mesh);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
case PatternType::Invalid:
|
||||||
|
{
|
||||||
|
throw PDFParserException(PDFTranslationContext::tr("Invalid pattern."));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
{
|
{
|
||||||
// TODO: Implement tiling pattern
|
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fill = false;
|
fill = false;
|
||||||
@ -627,8 +649,19 @@ void PDFPageContentProcessor::processPathPainting(const QPainterPath& path, bool
|
|||||||
const PDFPattern* pattern = getGraphicState()->getStrokeColorSpace()->getPattern();
|
const PDFPattern* pattern = getGraphicState()->getStrokeColorSpace()->getPattern();
|
||||||
if (pattern)
|
if (pattern)
|
||||||
{
|
{
|
||||||
if (const PDFShadingPattern* shadingPatern = pattern->getShadingPattern())
|
switch (pattern->getType())
|
||||||
{
|
{
|
||||||
|
case PatternType::Tiling:
|
||||||
|
{
|
||||||
|
// TODO: Implement tiling pattern
|
||||||
|
throw PDFParserException(PDFTranslationContext::tr("Tiling pattern not implemented."));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PatternType::Shading:
|
||||||
|
{
|
||||||
|
const PDFShadingPattern* shadingPatern = pattern->getShadingPattern();
|
||||||
|
|
||||||
// We must create a mesh and then draw pattern
|
// We must create a mesh and then draw pattern
|
||||||
PDFMeshQualitySettings settings;
|
PDFMeshQualitySettings settings;
|
||||||
settings.deviceSpaceMeshingArea = getPageBoundingRectDeviceSpace();
|
settings.deviceSpaceMeshingArea = getPageBoundingRectDeviceSpace();
|
||||||
@ -657,11 +690,20 @@ void PDFPageContentProcessor::processPathPainting(const QPainterPath& path, bool
|
|||||||
mesh.setBoundingPath(boundingPath);
|
mesh.setBoundingPath(boundingPath);
|
||||||
|
|
||||||
performMeshPainting(mesh);
|
performMeshPainting(mesh);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
case PatternType::Invalid:
|
||||||
|
{
|
||||||
|
throw PDFParserException(PDFTranslationContext::tr("Invalid pattern."));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
{
|
{
|
||||||
// TODO: Implement tiling pattern
|
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stroke = false;
|
stroke = false;
|
||||||
@ -1807,8 +1849,35 @@ void PDFPageContentProcessor::operatorColorSetStrokingColorN()
|
|||||||
{
|
{
|
||||||
// In our implementation, operator 'SC' can also set color using all color spaces
|
// In our implementation, operator 'SC' can also set color using all color spaces
|
||||||
// PDF reference 1.7 allows here Pattern, Separation, DeviceN and ICCBased color spaces here,
|
// PDF reference 1.7 allows here Pattern, Separation, DeviceN and ICCBased color spaces here,
|
||||||
// but default operator can use them (with exception of Pattern color space).
|
// but default operator can use them (with exception of Pattern color space). For pattern color space,
|
||||||
|
// we treat this differently.
|
||||||
|
const PDFAbstractColorSpace* colorSpace = m_graphicState.getStrokeColorSpace();
|
||||||
|
if (colorSpace->getPattern())
|
||||||
|
{
|
||||||
|
if (m_operands.size() > 0)
|
||||||
|
{
|
||||||
|
// TODO: Implement tiling pattern colors
|
||||||
|
PDFOperandName name = readOperand<PDFOperandName>(m_operands.size() - 1);
|
||||||
|
if (m_patternDictionary && m_patternDictionary->hasKey(name.name))
|
||||||
|
{
|
||||||
|
// Create the pattern
|
||||||
|
PDFPatternPtr pattern = PDFPattern::createPattern(m_colorSpaceDictionary, m_document, m_patternDictionary->get(name.name));
|
||||||
|
m_graphicState.setStrokeColorSpace(QSharedPointer<PDFAbstractColorSpace>(new PDFPatternColorSpace(qMove(pattern))));
|
||||||
|
updateGraphicState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw PDFRendererException(RenderErrorType::Error, PDFTranslationContext::tr("Invalid pattern for Pattern color space."));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw PDFRendererException(RenderErrorType::Error, PDFTranslationContext::tr("Invalid pattern for Pattern color space."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
operatorColorSetStrokingColor();
|
operatorColorSetStrokingColor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFPageContentProcessor::operatorColorSetFillingColor()
|
void PDFPageContentProcessor::operatorColorSetFillingColor()
|
||||||
@ -1838,8 +1907,35 @@ void PDFPageContentProcessor::operatorColorSetFillingColorN()
|
|||||||
{
|
{
|
||||||
// In our implementation, operator 'sc' can also set color using all color spaces
|
// In our implementation, operator 'sc' can also set color using all color spaces
|
||||||
// PDF reference 1.7 allows here Pattern, Separation, DeviceN and ICCBased color spaces here,
|
// PDF reference 1.7 allows here Pattern, Separation, DeviceN and ICCBased color spaces here,
|
||||||
// but default operator can use them (with exception of Pattern color space).
|
// but default operator can use them (with exception of Pattern color space). For pattern color space,
|
||||||
|
// we treat this differently.
|
||||||
|
const PDFAbstractColorSpace* colorSpace = m_graphicState.getFillColorSpace();
|
||||||
|
if (colorSpace->getPattern())
|
||||||
|
{
|
||||||
|
if (m_operands.size() > 0)
|
||||||
|
{
|
||||||
|
// TODO: Implement tiling pattern colors
|
||||||
|
PDFOperandName name = readOperand<PDFOperandName>(m_operands.size() - 1);
|
||||||
|
if (m_patternDictionary && m_patternDictionary->hasKey(name.name))
|
||||||
|
{
|
||||||
|
// Create the pattern
|
||||||
|
PDFPatternPtr pattern = PDFPattern::createPattern(m_colorSpaceDictionary, m_document, m_patternDictionary->get(name.name));
|
||||||
|
m_graphicState.setFillColorSpace(QSharedPointer<PDFAbstractColorSpace>(new PDFPatternColorSpace(qMove(pattern))));
|
||||||
|
updateGraphicState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw PDFRendererException(RenderErrorType::Error, PDFTranslationContext::tr("Invalid pattern for Pattern color space."));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw PDFRendererException(RenderErrorType::Error, PDFTranslationContext::tr("Invalid pattern for Pattern color space."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
operatorColorSetFillingColor();
|
operatorColorSetFillingColor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFPageContentProcessor::operatorColorSetDeviceGrayStroking(PDFReal gray)
|
void PDFPageContentProcessor::operatorColorSetDeviceGrayStroking(PDFReal gray)
|
||||||
@ -2864,7 +2960,8 @@ PDFPageContentProcessor::PDFPageContentProcessorStateGuard::PDFPageContentProces
|
|||||||
m_xobjectDictionary(processor->m_xobjectDictionary),
|
m_xobjectDictionary(processor->m_xobjectDictionary),
|
||||||
m_extendedGraphicStateDictionary(processor->m_extendedGraphicStateDictionary),
|
m_extendedGraphicStateDictionary(processor->m_extendedGraphicStateDictionary),
|
||||||
m_propertiesDictionary(processor->m_propertiesDictionary),
|
m_propertiesDictionary(processor->m_propertiesDictionary),
|
||||||
m_shadingDictionary(processor->m_shadingDictionary)
|
m_shadingDictionary(processor->m_shadingDictionary),
|
||||||
|
m_patternDictionary(processor->m_patternDictionary)
|
||||||
{
|
{
|
||||||
m_processor->operatorSaveGraphicState();
|
m_processor->operatorSaveGraphicState();
|
||||||
}
|
}
|
||||||
@ -2878,6 +2975,7 @@ PDFPageContentProcessor::PDFPageContentProcessorStateGuard::~PDFPageContentProce
|
|||||||
m_processor->m_extendedGraphicStateDictionary = m_extendedGraphicStateDictionary;
|
m_processor->m_extendedGraphicStateDictionary = m_extendedGraphicStateDictionary;
|
||||||
m_processor->m_propertiesDictionary = m_propertiesDictionary;
|
m_processor->m_propertiesDictionary = m_propertiesDictionary;
|
||||||
m_processor->m_shadingDictionary = m_shadingDictionary;
|
m_processor->m_shadingDictionary = m_shadingDictionary;
|
||||||
|
m_processor->m_patternDictionary = m_patternDictionary;
|
||||||
|
|
||||||
m_processor->operatorRestoreGraphicState();
|
m_processor->operatorRestoreGraphicState();
|
||||||
}
|
}
|
||||||
|
@ -502,6 +502,7 @@ private:
|
|||||||
const PDFDictionary* m_extendedGraphicStateDictionary;
|
const PDFDictionary* m_extendedGraphicStateDictionary;
|
||||||
const PDFDictionary* m_propertiesDictionary;
|
const PDFDictionary* m_propertiesDictionary;
|
||||||
const PDFDictionary* m_shadingDictionary;
|
const PDFDictionary* m_shadingDictionary;
|
||||||
|
const PDFDictionary* m_patternDictionary;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Wrapper for PDF Name
|
/// Wrapper for PDF Name
|
||||||
@ -724,6 +725,7 @@ private:
|
|||||||
const PDFDictionary* m_extendedGraphicStateDictionary;
|
const PDFDictionary* m_extendedGraphicStateDictionary;
|
||||||
const PDFDictionary* m_propertiesDictionary;
|
const PDFDictionary* m_propertiesDictionary;
|
||||||
const PDFDictionary* m_shadingDictionary;
|
const PDFDictionary* m_shadingDictionary;
|
||||||
|
const PDFDictionary* m_patternDictionary;
|
||||||
|
|
||||||
// Default color spaces
|
// Default color spaces
|
||||||
PDFColorSpacePointer m_deviceGrayColorSpace;
|
PDFColorSpacePointer m_deviceGrayColorSpace;
|
||||||
|
@ -48,11 +48,6 @@ PDFPatternPtr PDFPattern::createPattern(const PDFDictionary* colorSpaceDictionar
|
|||||||
const PDFDictionary* patternDictionary = dereferencedObject.getDictionary();
|
const PDFDictionary* patternDictionary = dereferencedObject.getDictionary();
|
||||||
PDFDocumentDataLoaderDecorator loader(document);
|
PDFDocumentDataLoaderDecorator loader(document);
|
||||||
|
|
||||||
if (loader.readNameFromDictionary(patternDictionary, "Type") != "Pattern")
|
|
||||||
{
|
|
||||||
throw PDFParserException(PDFTranslationContext::tr("Invalid pattern."));
|
|
||||||
}
|
|
||||||
|
|
||||||
const PatternType patternType = static_cast<PatternType>(loader.readIntegerFromDictionary(patternDictionary, "PatternType", static_cast<PDFInteger>(PatternType::Invalid)));
|
const PatternType patternType = static_cast<PatternType>(loader.readIntegerFromDictionary(patternDictionary, "PatternType", static_cast<PDFInteger>(PatternType::Invalid)));
|
||||||
switch (patternType)
|
switch (patternType)
|
||||||
{
|
{
|
||||||
@ -89,16 +84,27 @@ PDFPatternPtr PDFPattern::createShadingPattern(const PDFDictionary* colorSpaceDi
|
|||||||
bool ignoreBackgroundColor)
|
bool ignoreBackgroundColor)
|
||||||
{
|
{
|
||||||
const PDFObject& dereferencedShadingObject = document->getObject(shadingObject);
|
const PDFObject& dereferencedShadingObject = document->getObject(shadingObject);
|
||||||
if (!dereferencedShadingObject.isDictionary())
|
if (!dereferencedShadingObject.isDictionary() && !dereferencedShadingObject.isStream())
|
||||||
{
|
{
|
||||||
throw PDFParserException(PDFTranslationContext::tr("Invalid shading."));
|
throw PDFParserException(PDFTranslationContext::tr("Invalid shading."));
|
||||||
}
|
}
|
||||||
|
|
||||||
PDFDocumentDataLoaderDecorator loader(document);
|
PDFDocumentDataLoaderDecorator loader(document);
|
||||||
const PDFDictionary* shadingDictionary = dereferencedShadingObject.getDictionary();
|
const PDFDictionary* shadingDictionary = nullptr;
|
||||||
|
const PDFStream* stream = nullptr;
|
||||||
|
|
||||||
|
if (dereferencedShadingObject.isDictionary())
|
||||||
|
{
|
||||||
|
shadingDictionary = dereferencedShadingObject.getDictionary();
|
||||||
|
}
|
||||||
|
else if (dereferencedShadingObject.isStream())
|
||||||
|
{
|
||||||
|
stream = dereferencedShadingObject.getStream();
|
||||||
|
shadingDictionary = stream->getDictionary();
|
||||||
|
}
|
||||||
|
|
||||||
// Parse common data for all shadings
|
// Parse common data for all shadings
|
||||||
PDFColorSpacePointer colorSpace = PDFAbstractColorSpace::createColorSpace(colorSpaceDictionary, document, shadingDictionary->get("ColorSpace"));
|
PDFColorSpacePointer colorSpace = PDFAbstractColorSpace::createColorSpace(colorSpaceDictionary, document, document->getObject(shadingDictionary->get("ColorSpace")));
|
||||||
|
|
||||||
if (colorSpace->getPattern())
|
if (colorSpace->getPattern())
|
||||||
{
|
{
|
||||||
@ -1183,5 +1189,6 @@ PDFMesh PDFRadialShading::createMesh(const PDFMeshQualitySettings& settings) con
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Apply graphic state of the pattern
|
// TODO: Apply graphic state of the pattern
|
||||||
|
// TODO: Implement settings of meshing in the settings dialog
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
@ -204,6 +204,15 @@ protected:
|
|||||||
QMatrix m_matrix;
|
QMatrix m_matrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PDFInvalidPattern : public PDFPattern
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit PDFInvalidPattern() = default;
|
||||||
|
|
||||||
|
virtual PatternType getType() const { return PatternType::Invalid; }
|
||||||
|
virtual const PDFShadingPattern* getShadingPattern() const { return nullptr; }
|
||||||
|
};
|
||||||
|
|
||||||
/// Shading pattern - smooth color distribution along the pattern's space
|
/// Shading pattern - smooth color distribution along the pattern's space
|
||||||
class PDFShadingPattern : public PDFPattern
|
class PDFShadingPattern : public PDFPattern
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user