mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Pattern shading refactoring
This commit is contained in:
@ -210,6 +210,7 @@ public:
|
|||||||
virtual QColor getColor(const PDFColor& color) const = 0;
|
virtual QColor getColor(const PDFColor& color) const = 0;
|
||||||
virtual size_t getColorComponentCount() const = 0;
|
virtual size_t getColorComponentCount() const = 0;
|
||||||
virtual QImage getImage(const PDFImageData& imageData) const;
|
virtual QImage getImage(const PDFImageData& imageData) const;
|
||||||
|
virtual const PDFPattern* getPattern() const { return nullptr; }
|
||||||
|
|
||||||
/// Checks, if number of color components is OK, and if yes, converts them to the QColor value.
|
/// Checks, if number of color components is OK, and if yes, converts them to the QColor value.
|
||||||
/// If they are not OK, exception is thrown.
|
/// If they are not OK, exception is thrown.
|
||||||
@ -544,7 +545,7 @@ public:
|
|||||||
virtual QColor getColor(const PDFColor& color) const override;
|
virtual QColor getColor(const PDFColor& color) const override;
|
||||||
virtual size_t getColorComponentCount() const override;
|
virtual size_t getColorComponentCount() const override;
|
||||||
|
|
||||||
const PDFPattern* getPattern() const { return m_pattern.get(); }
|
virtual const PDFPattern* getPattern() const override { return m_pattern.get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<PDFPattern> m_pattern;
|
std::shared_ptr<PDFPattern> m_pattern;
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
#include "pdfimage.h"
|
#include "pdfimage.h"
|
||||||
#include "pdfpattern.h"
|
#include "pdfpattern.h"
|
||||||
|
|
||||||
|
#include <QPainterPathStroker>
|
||||||
|
|
||||||
namespace pdf
|
namespace pdf
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -309,6 +311,11 @@ void PDFPageContentProcessor::performImagePainting(const QImage& image)
|
|||||||
Q_UNUSED(image);
|
Q_UNUSED(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFPageContentProcessor::performMeshPainting(const PDFMesh& mesh)
|
||||||
|
{
|
||||||
|
Q_UNUSED(mesh);
|
||||||
|
}
|
||||||
|
|
||||||
void PDFPageContentProcessor::performUpdateGraphicsState(const PDFPageContentProcessorState& state)
|
void PDFPageContentProcessor::performUpdateGraphicsState(const PDFPageContentProcessorState& state)
|
||||||
{
|
{
|
||||||
if (state.getStateFlags().testFlag(PDFPageContentProcessorState::StateTextFont) ||
|
if (state.getStateFlags().testFlag(PDFPageContentProcessorState::StateTextFont) ||
|
||||||
@ -569,6 +576,104 @@ void PDFPageContentProcessor::processForm(const QMatrix& matrix, const QRectF& b
|
|||||||
processContent(content);
|
processContent(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFPageContentProcessor::processPathPainting(const QPainterPath& path, bool stroke, bool fill, bool text, Qt::FillRule fillRule)
|
||||||
|
{
|
||||||
|
if (isContentSuppressed())
|
||||||
|
{
|
||||||
|
// Content is suppressed, do not paint anything
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!stroke && !fill) || path.isEmpty())
|
||||||
|
{
|
||||||
|
// No operation requested - either path is empty, or neither stroking or filling
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fill)
|
||||||
|
{
|
||||||
|
const PDFPattern* pattern = getGraphicState()->getFillColorSpace()->getPattern();
|
||||||
|
if (pattern)
|
||||||
|
{
|
||||||
|
if (const PDFShadingPattern* shadingPatern = pattern->getShadingPattern())
|
||||||
|
{
|
||||||
|
// We must create a mesh and then draw pattern
|
||||||
|
PDFMeshQualitySettings settings;
|
||||||
|
settings.deviceSpaceMeshingArea = getPageBoundingRectDeviceSpace();
|
||||||
|
settings.userSpaceToDeviceSpaceMatrix = getPatternBaseMatrix();
|
||||||
|
settings.initDefaultResolution();
|
||||||
|
|
||||||
|
PDFMesh mesh = shadingPatern->createMesh(settings);
|
||||||
|
|
||||||
|
// Now, merge the current path to the mesh clipping path
|
||||||
|
QPainterPath boundingPath = mesh.getBoundingPath();
|
||||||
|
boundingPath.addPath(getCurrentWorldMatrix().map(path));
|
||||||
|
mesh.setBoundingPath(boundingPath);
|
||||||
|
|
||||||
|
performMeshPainting(mesh);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: Implement tiling pattern
|
||||||
|
Q_ASSERT(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
fill = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stroke)
|
||||||
|
{
|
||||||
|
const PDFPattern* pattern = getGraphicState()->getStrokeColorSpace()->getPattern();
|
||||||
|
if (pattern)
|
||||||
|
{
|
||||||
|
if (const PDFShadingPattern* shadingPatern = pattern->getShadingPattern())
|
||||||
|
{
|
||||||
|
// We must create a mesh and then draw pattern
|
||||||
|
PDFMeshQualitySettings settings;
|
||||||
|
settings.deviceSpaceMeshingArea = getPageBoundingRectDeviceSpace();
|
||||||
|
settings.userSpaceToDeviceSpaceMatrix = getPatternBaseMatrix();
|
||||||
|
settings.initDefaultResolution();
|
||||||
|
|
||||||
|
PDFMesh mesh = shadingPatern->createMesh(settings);
|
||||||
|
|
||||||
|
// We must stroke the path.
|
||||||
|
QPainterPathStroker stroker;
|
||||||
|
stroker.setCapStyle(m_graphicState.getLineCapStyle());
|
||||||
|
stroker.setWidth(m_graphicState.getLineWidth());
|
||||||
|
stroker.setMiterLimit(m_graphicState.getMitterLimit());
|
||||||
|
stroker.setJoinStyle(m_graphicState.getLineJoinStyle());
|
||||||
|
|
||||||
|
const PDFLineDashPattern& lineDashPattern = m_graphicState.getLineDashPattern();
|
||||||
|
if (!lineDashPattern.isSolid())
|
||||||
|
{
|
||||||
|
stroker.setDashPattern(QVector<PDFReal>::fromStdVector(lineDashPattern.getDashArray()));
|
||||||
|
stroker.setDashOffset(lineDashPattern.getDashOffset());
|
||||||
|
}
|
||||||
|
QPainterPath strokedPath = stroker.createStroke(path);
|
||||||
|
|
||||||
|
QPainterPath boundingPath = mesh.getBoundingPath();
|
||||||
|
boundingPath.addPath(getCurrentWorldMatrix().map(strokedPath));
|
||||||
|
mesh.setBoundingPath(boundingPath);
|
||||||
|
|
||||||
|
performMeshPainting(mesh);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: Implement tiling pattern
|
||||||
|
Q_ASSERT(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
stroke = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stroke || fill)
|
||||||
|
{
|
||||||
|
performPathPainting(path, stroke, fill, text, fillRule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PDFPageContentProcessor::processCommand(const QByteArray& command)
|
void PDFPageContentProcessor::processCommand(const QByteArray& command)
|
||||||
{
|
{
|
||||||
Operator op = Operator::Invalid;
|
Operator op = Operator::Invalid;
|
||||||
@ -1529,7 +1634,7 @@ void PDFPageContentProcessor::operatorPathStroke()
|
|||||||
if (!m_currentPath.isEmpty())
|
if (!m_currentPath.isEmpty())
|
||||||
{
|
{
|
||||||
m_currentPath.setFillRule(Qt::WindingFill);
|
m_currentPath.setFillRule(Qt::WindingFill);
|
||||||
performPathPainting(m_currentPath, true, false, false, Qt::WindingFill);
|
processPathPainting(m_currentPath, true, false, false, Qt::WindingFill);
|
||||||
m_currentPath = QPainterPath();
|
m_currentPath = QPainterPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1541,7 +1646,7 @@ void PDFPageContentProcessor::operatorPathCloseStroke()
|
|||||||
{
|
{
|
||||||
m_currentPath.closeSubpath();
|
m_currentPath.closeSubpath();
|
||||||
m_currentPath.setFillRule(Qt::WindingFill);
|
m_currentPath.setFillRule(Qt::WindingFill);
|
||||||
performPathPainting(m_currentPath, true, false, false, Qt::WindingFill);
|
processPathPainting(m_currentPath, true, false, false, Qt::WindingFill);
|
||||||
m_currentPath = QPainterPath();
|
m_currentPath = QPainterPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1551,7 +1656,7 @@ void PDFPageContentProcessor::operatorPathFillWinding()
|
|||||||
if (!m_currentPath.isEmpty())
|
if (!m_currentPath.isEmpty())
|
||||||
{
|
{
|
||||||
m_currentPath.setFillRule(Qt::WindingFill);
|
m_currentPath.setFillRule(Qt::WindingFill);
|
||||||
performPathPainting(m_currentPath, false, true, false, Qt::WindingFill);
|
processPathPainting(m_currentPath, false, true, false, Qt::WindingFill);
|
||||||
m_currentPath = QPainterPath();
|
m_currentPath = QPainterPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1561,7 +1666,7 @@ void PDFPageContentProcessor::operatorPathFillEvenOdd()
|
|||||||
if (!m_currentPath.isEmpty())
|
if (!m_currentPath.isEmpty())
|
||||||
{
|
{
|
||||||
m_currentPath.setFillRule(Qt::OddEvenFill);
|
m_currentPath.setFillRule(Qt::OddEvenFill);
|
||||||
performPathPainting(m_currentPath, false, true, false, Qt::OddEvenFill);
|
processPathPainting(m_currentPath, false, true, false, Qt::OddEvenFill);
|
||||||
m_currentPath = QPainterPath();
|
m_currentPath = QPainterPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1571,7 +1676,7 @@ void PDFPageContentProcessor::operatorPathFillStrokeWinding()
|
|||||||
if (!m_currentPath.isEmpty())
|
if (!m_currentPath.isEmpty())
|
||||||
{
|
{
|
||||||
m_currentPath.setFillRule(Qt::WindingFill);
|
m_currentPath.setFillRule(Qt::WindingFill);
|
||||||
performPathPainting(m_currentPath, true, true, false, Qt::WindingFill);
|
processPathPainting(m_currentPath, true, true, false, Qt::WindingFill);
|
||||||
m_currentPath = QPainterPath();
|
m_currentPath = QPainterPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1581,7 +1686,7 @@ void PDFPageContentProcessor::operatorPathFillStrokeEvenOdd()
|
|||||||
if (!m_currentPath.isEmpty())
|
if (!m_currentPath.isEmpty())
|
||||||
{
|
{
|
||||||
m_currentPath.setFillRule(Qt::OddEvenFill);
|
m_currentPath.setFillRule(Qt::OddEvenFill);
|
||||||
performPathPainting(m_currentPath, true, true, false, Qt::OddEvenFill);
|
processPathPainting(m_currentPath, true, true, false, Qt::OddEvenFill);
|
||||||
m_currentPath = QPainterPath();
|
m_currentPath = QPainterPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1592,7 +1697,7 @@ void PDFPageContentProcessor::operatorPathCloseFillStrokeWinding()
|
|||||||
{
|
{
|
||||||
m_currentPath.closeSubpath();
|
m_currentPath.closeSubpath();
|
||||||
m_currentPath.setFillRule(Qt::WindingFill);
|
m_currentPath.setFillRule(Qt::WindingFill);
|
||||||
performPathPainting(m_currentPath, true, true, false, Qt::WindingFill);
|
processPathPainting(m_currentPath, true, true, false, Qt::WindingFill);
|
||||||
m_currentPath = QPainterPath();
|
m_currentPath = QPainterPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1603,7 +1708,7 @@ void PDFPageContentProcessor::operatorPathCloseFillStrokeEvenOdd()
|
|||||||
{
|
{
|
||||||
m_currentPath.closeSubpath();
|
m_currentPath.closeSubpath();
|
||||||
m_currentPath.setFillRule(Qt::OddEvenFill);
|
m_currentPath.setFillRule(Qt::OddEvenFill);
|
||||||
performPathPainting(m_currentPath, true, true, false, Qt::OddEvenFill);
|
processPathPainting(m_currentPath, true, true, false, Qt::OddEvenFill);
|
||||||
m_currentPath = QPainterPath();
|
m_currentPath = QPainterPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2069,7 +2174,7 @@ void PDFPageContentProcessor::operatorShadingPaintShape(PDFPageContentProcessor:
|
|||||||
deviceBoundingRectPath.addRect(m_pageBoundingRectDeviceSpace);
|
deviceBoundingRectPath.addRect(m_pageBoundingRectDeviceSpace);
|
||||||
QPainterPath boundingRectPath = inverted.map(deviceBoundingRectPath);
|
QPainterPath boundingRectPath = inverted.map(deviceBoundingRectPath);
|
||||||
|
|
||||||
performPathPainting(boundingRectPath, false, true, false, boundingRectPath.fillRule());
|
processPathPainting(boundingRectPath, false, true, false, boundingRectPath.fillRule());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFPageContentProcessor::paintXObjectImage(const PDFStream* stream)
|
void PDFPageContentProcessor::paintXObjectImage(const PDFStream* stream)
|
||||||
@ -2311,7 +2416,7 @@ void PDFPageContentProcessor::drawText(const TextSequence& textSequence)
|
|||||||
{
|
{
|
||||||
QMatrix textRenderingMatrix = adjustMatrix * textMatrix;
|
QMatrix textRenderingMatrix = adjustMatrix * textMatrix;
|
||||||
QPainterPath transformedGlyph = textRenderingMatrix.map(glyphPath);
|
QPainterPath transformedGlyph = textRenderingMatrix.map(glyphPath);
|
||||||
performPathPainting(transformedGlyph, stroke, fill, true, transformedGlyph.fillRule());
|
processPathPainting(transformedGlyph, stroke, fill, true, transformedGlyph.fillRule());
|
||||||
|
|
||||||
if (clipped)
|
if (clipped)
|
||||||
{
|
{
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
namespace pdf
|
namespace pdf
|
||||||
{
|
{
|
||||||
|
class PDFMesh;
|
||||||
class PDFOptionalContentActivity;
|
class PDFOptionalContentActivity;
|
||||||
|
|
||||||
static constexpr const char* PDF_RESOURCE_EXTGSTATE = "ExtGState";
|
static constexpr const char* PDF_RESOURCE_EXTGSTATE = "ExtGState";
|
||||||
@ -366,6 +367,12 @@ protected:
|
|||||||
/// \param image Image to be painted
|
/// \param image Image to be painted
|
||||||
virtual void performImagePainting(const QImage& image);
|
virtual void performImagePainting(const QImage& image);
|
||||||
|
|
||||||
|
/// This function has to be implemented in the client drawing implementation, it should
|
||||||
|
/// draw the mesh. Mesh is in device space coordinates (so world transformation matrix
|
||||||
|
/// is identity matrix).
|
||||||
|
/// \param mesh Mesh to be drawn
|
||||||
|
virtual void performMeshPainting(const PDFMesh& mesh);
|
||||||
|
|
||||||
/// This function has to be implemented in the client drawing implementation, it should
|
/// This function has to be implemented in the client drawing implementation, it should
|
||||||
/// update the device according to the graphic state change. The flags are set when
|
/// update the device according to the graphic state change. The flags are set when
|
||||||
/// the value differs from the previous graphic state.
|
/// the value differs from the previous graphic state.
|
||||||
@ -449,6 +456,14 @@ private:
|
|||||||
/// \param content Content stream of the form
|
/// \param content Content stream of the form
|
||||||
void processForm(const QMatrix& matrix, const QRectF& boundingBox, const PDFObject& resources, const QByteArray& content);
|
void processForm(const QMatrix& matrix, const QRectF& boundingBox, const PDFObject& resources, const QByteArray& content);
|
||||||
|
|
||||||
|
/// Performs path painting
|
||||||
|
/// \param path Path, which should be drawn (can be emtpy - in that case nothing happens)
|
||||||
|
/// \param stroke Stroke the path
|
||||||
|
/// \param fill Fill the path using given rule
|
||||||
|
/// \param text Is text being drawn?
|
||||||
|
/// \param fillRule Fill rule used in the fill mode
|
||||||
|
void processPathPainting(const QPainterPath& path, bool stroke, bool fill, bool text, Qt::FillRule fillRule);
|
||||||
|
|
||||||
enum class MarkedContentKind
|
enum class MarkedContentKind
|
||||||
{
|
{
|
||||||
OptionalContent,
|
OptionalContent,
|
||||||
|
@ -47,36 +47,7 @@ PDFPainter::~PDFPainter()
|
|||||||
|
|
||||||
void PDFPainter::performPathPainting(const QPainterPath& path, bool stroke, bool fill, bool text, Qt::FillRule fillRule)
|
void PDFPainter::performPathPainting(const QPainterPath& path, bool stroke, bool fill, bool text, Qt::FillRule fillRule)
|
||||||
{
|
{
|
||||||
// TODO: Implement Pattern features (shading/tiling)
|
Q_ASSERT(stroke || fill);
|
||||||
if (isContentSuppressed())
|
|
||||||
{
|
|
||||||
// Content is suppressed, do not paint anything
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!stroke && !fill) || path.isEmpty())
|
|
||||||
{
|
|
||||||
// No operation requested - either path is empty, or neither stroking or filling
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Temporary
|
|
||||||
if (const PDFPatternColorSpace* ps = dynamic_cast<const PDFPatternColorSpace*>(getGraphicState()->getFillColorSpace()))
|
|
||||||
{
|
|
||||||
m_painter->save();
|
|
||||||
const PDFAxialShading* pattern = (PDFAxialShading*)ps->getPattern();
|
|
||||||
m_painter->setClipPath(path, Qt::IntersectClip);
|
|
||||||
|
|
||||||
PDFMeshQualitySettings settings;
|
|
||||||
settings.deviceSpaceMeshingArea = getPageBoundingRectDeviceSpace();
|
|
||||||
settings.userSpaceToDeviceSpaceMatrix = getPatternBaseMatrix();
|
|
||||||
settings.initDefaultResolution();
|
|
||||||
|
|
||||||
PDFMesh mesh = pattern->createMesh(settings);
|
|
||||||
mesh.paint(m_painter);
|
|
||||||
m_painter->restore();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set antialiasing
|
// Set antialiasing
|
||||||
const bool antialiasing = (text && m_features.testFlag(PDFRenderer::TextAntialiasing)) || (!text && m_features.testFlag(PDFRenderer::Antialiasing));
|
const bool antialiasing = (text && m_features.testFlag(PDFRenderer::TextAntialiasing)) || (!text && m_features.testFlag(PDFRenderer::Antialiasing));
|
||||||
@ -164,6 +135,14 @@ void PDFPainter::performImagePainting(const QImage& image)
|
|||||||
m_painter->restore();
|
m_painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFPainter::performMeshPainting(const PDFMesh& mesh)
|
||||||
|
{
|
||||||
|
m_painter->save();
|
||||||
|
m_painter->setWorldMatrix(QMatrix());
|
||||||
|
mesh.paint(m_painter);
|
||||||
|
m_painter->restore();
|
||||||
|
}
|
||||||
|
|
||||||
void PDFPainter::performUpdateGraphicsState(const PDFPageContentProcessorState& state)
|
void PDFPainter::performUpdateGraphicsState(const PDFPageContentProcessorState& state)
|
||||||
{
|
{
|
||||||
const PDFPageContentProcessorState::StateFlags flags = state.getStateFlags();
|
const PDFPageContentProcessorState::StateFlags flags = state.getStateFlags();
|
||||||
|
@ -53,7 +53,8 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
virtual void performPathPainting(const QPainterPath& path, bool stroke, bool fill, bool text, Qt::FillRule fillRule) override;
|
virtual void performPathPainting(const QPainterPath& path, bool stroke, bool fill, bool text, Qt::FillRule fillRule) override;
|
||||||
virtual void performClipping(const QPainterPath& path, Qt::FillRule fillRule) override;
|
virtual void performClipping(const QPainterPath& path, Qt::FillRule fillRule) override;
|
||||||
virtual void performImagePainting(const QImage& image);
|
virtual void performImagePainting(const QImage& image) override;
|
||||||
|
virtual void performMeshPainting(const PDFMesh& mesh) override;
|
||||||
virtual void performUpdateGraphicsState(const PDFPageContentProcessorState& state) override;
|
virtual void performUpdateGraphicsState(const PDFPageContentProcessorState& state) override;
|
||||||
virtual void performSaveGraphicState(ProcessOrder order) override;
|
virtual void performSaveGraphicState(ProcessOrder order) override;
|
||||||
virtual void performRestoreGraphicState(ProcessOrder order) override;
|
virtual void performRestoreGraphicState(ProcessOrder order) override;
|
||||||
|
@ -370,20 +370,16 @@ PDFMesh PDFAxialShading::createMesh(const PDFMeshQualitySettings& settings) cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create background color triangles
|
// Create background color triangles
|
||||||
|
// TODO: Create background color for axial shading
|
||||||
|
|
||||||
// Transform mesh to the device space coordinates
|
// Transform mesh to the device space coordinates
|
||||||
mesh.transform(p1p2LCS);
|
mesh.transform(p1p2LCS);
|
||||||
|
|
||||||
// Transform mesh from the device space coordinates to user space coordinates
|
|
||||||
Q_ASSERT(settings.userSpaceToDeviceSpaceMatrix.isInvertible());
|
|
||||||
QMatrix deviceSpaceToUserSpaceMatrix = settings.userSpaceToDeviceSpaceMatrix.inverted();
|
|
||||||
mesh.transform(deviceSpaceToUserSpaceMatrix);
|
|
||||||
|
|
||||||
// Create bounding path
|
// Create bounding path
|
||||||
if (m_boundingBox.isValid())
|
if (m_boundingBox.isValid())
|
||||||
{
|
{
|
||||||
QPainterPath boundingPath;
|
QPainterPath boundingPath;
|
||||||
boundingPath.addRect(m_boundingBox);
|
boundingPath.addPolygon(settings.userSpaceToDeviceSpaceMatrix.map(m_boundingBox));
|
||||||
mesh.setBoundingPath(boundingPath);
|
mesh.setBoundingPath(boundingPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
namespace pdf
|
namespace pdf
|
||||||
{
|
{
|
||||||
class PDFPattern;
|
class PDFPattern;
|
||||||
|
class PDFShadingPattern;
|
||||||
|
|
||||||
using PDFPatternPtr = std::shared_ptr<PDFPattern>;
|
using PDFPatternPtr = std::shared_ptr<PDFPattern>;
|
||||||
|
|
||||||
@ -140,6 +141,7 @@ public:
|
|||||||
virtual ~PDFPattern() = default;
|
virtual ~PDFPattern() = default;
|
||||||
|
|
||||||
virtual PatternType getType() const = 0;
|
virtual PatternType getType() const = 0;
|
||||||
|
virtual const PDFShadingPattern* getShadingPattern() const = 0;
|
||||||
|
|
||||||
/// Returns bounding box in the shadings target coordinate system (not in
|
/// Returns bounding box in the shadings target coordinate system (not in
|
||||||
/// pattern coordinate system).
|
/// pattern coordinate system).
|
||||||
@ -182,8 +184,11 @@ public:
|
|||||||
|
|
||||||
virtual PatternType getType() const override;
|
virtual PatternType getType() const override;
|
||||||
virtual ShadingType getShadingType() const = 0;
|
virtual ShadingType getShadingType() const = 0;
|
||||||
|
virtual const PDFShadingPattern* getShadingPattern() const override { return this; }
|
||||||
|
|
||||||
/// Creates a colored mesh using settings
|
/// Creates a colored mesh using settings. Mesh is generated in device space
|
||||||
|
/// coordinate system. You must transform the mesh, if you want to
|
||||||
|
/// use it in another coordiante system.
|
||||||
/// \param settings Meshing settings
|
/// \param settings Meshing settings
|
||||||
virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings) const = 0;
|
virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings) const = 0;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user