mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2024-12-27 08:42:48 +01:00
Function shading sampler
This commit is contained in:
parent
fec4f7630b
commit
301c07a23e
@ -502,6 +502,101 @@ PDFPatternPtr PDFPattern::createShadingPattern(const PDFDictionary* colorSpaceDi
|
||||
return PDFPatternPtr();
|
||||
}
|
||||
|
||||
class PDFFunctionShadingSampler : public PDFShadingSampler
|
||||
{
|
||||
public:
|
||||
PDFFunctionShadingSampler(const PDFFunctionShading* functionShadingPattern, QMatrix userSpaceToDeviceSpaceMatrix) :
|
||||
PDFShadingSampler(functionShadingPattern),
|
||||
m_functionShadingPattern(functionShadingPattern),
|
||||
m_domain(functionShadingPattern->getDomain())
|
||||
{
|
||||
QMatrix patternSpaceToDeviceSpaceMatrix = functionShadingPattern->getMatrix() * userSpaceToDeviceSpaceMatrix;
|
||||
QMatrix domainToDeviceSpaceMatrix = functionShadingPattern->getDomainToTargetTransform() * patternSpaceToDeviceSpaceMatrix;
|
||||
|
||||
if (domainToDeviceSpaceMatrix.isInvertible())
|
||||
{
|
||||
m_deviceSpaceToDomainMatrix = domainToDeviceSpaceMatrix.inverted();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_deviceSpaceToDomainMatrix = QMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool sample(const QPointF& devicePoint, PDFColorBuffer outputBuffer, int limit) const override
|
||||
{
|
||||
Q_UNUSED(limit);
|
||||
|
||||
if (!m_pattern->getColorSpace() || m_pattern->getColorSpace()->getColorComponentCount() != outputBuffer.size())
|
||||
{
|
||||
// Invalid color space, or invalid color buffer
|
||||
return false;
|
||||
}
|
||||
|
||||
QPointF domainPoint = m_deviceSpaceToDomainMatrix.map(devicePoint);
|
||||
|
||||
if (!m_domain.contains(domainPoint))
|
||||
{
|
||||
return fillBackgroundColor(outputBuffer);
|
||||
}
|
||||
|
||||
const auto& functions = m_functionShadingPattern->getFunctions();
|
||||
std::array<PDFReal, PDF_MAX_COLOR_COMPONENTS> colorBuffer = { };
|
||||
|
||||
if (colorBuffer.size() < outputBuffer.size())
|
||||
{
|
||||
// Jakub Melka: Too much colors - we cant process it
|
||||
return false;
|
||||
}
|
||||
|
||||
std::array<PDFReal, 2> input = { domainPoint.x(), domainPoint.y() };
|
||||
|
||||
if (functions.size() == 1)
|
||||
{
|
||||
Q_ASSERT(outputBuffer.size() <= colorBuffer.size());
|
||||
PDFFunction::FunctionResult result = functions.front()->apply(input.data(), input.data() + input.size(), colorBuffer.data(), colorBuffer.data() + outputBuffer.size());
|
||||
|
||||
if (!result)
|
||||
{
|
||||
// Function call failed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (functions.size() != outputBuffer.size())
|
||||
{
|
||||
// Invalid number of functions
|
||||
return false;
|
||||
}
|
||||
|
||||
Q_ASSERT(outputBuffer.size() <= colorBuffer.size());
|
||||
for (size_t i = 0, count = outputBuffer.size(); i < count; ++i)
|
||||
{
|
||||
PDFFunction::FunctionResult result = functions[i]->apply(input.data(), input.data() + input.size(), colorBuffer.data() + i, colorBuffer.data() + i + 1);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
// Function call failed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0, count = outputBuffer.size(); i < count; ++i)
|
||||
{
|
||||
outputBuffer[i] = colorBuffer[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
const PDFFunctionShading* m_functionShadingPattern;
|
||||
QRectF m_domain;
|
||||
QMatrix m_deviceSpaceToDomainMatrix;
|
||||
};
|
||||
|
||||
ShadingType PDFFunctionShading::getShadingType() const
|
||||
{
|
||||
return ShadingType::Function;
|
||||
@ -810,6 +905,11 @@ PDFMesh PDFFunctionShading::createMesh(const PDFMeshQualitySettings& settings, c
|
||||
return mesh;
|
||||
}
|
||||
|
||||
PDFShadingSampler* PDFFunctionShading::createSampler(QMatrix userSpaceToDeviceSpaceMatrix) const
|
||||
{
|
||||
return new PDFFunctionShadingSampler(this, userSpaceToDeviceSpaceMatrix);
|
||||
}
|
||||
|
||||
PDFMesh PDFAxialShading::createMesh(const PDFMeshQualitySettings& settings, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const
|
||||
{
|
||||
PDFMesh mesh;
|
||||
|
@ -383,6 +383,11 @@ public:
|
||||
|
||||
virtual ShadingType getShadingType() const override;
|
||||
virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
||||
virtual PDFShadingSampler* createSampler(QMatrix userSpaceToDeviceSpaceMatrix) const override;
|
||||
|
||||
const QRectF& getDomain() const { return m_domain; }
|
||||
const QMatrix& getDomainToTargetTransform() const { return m_domainToTargetTransform; }
|
||||
const std::vector<PDFFunctionPtr>& getFunctions() const { return m_functions; }
|
||||
|
||||
private:
|
||||
friend class PDFPattern;
|
||||
|
Loading…
Reference in New Issue
Block a user