mirror of
				https://github.com/JakubMelka/PDF4QT.git
				synced 2025-06-05 21:59:17 +02:00 
			
		
		
		
	Rendering options
This commit is contained in:
		@@ -347,7 +347,8 @@ PDFDrawWidgetProxy::PDFDrawWidgetProxy(QObject* parent) :
 | 
			
		||||
    m_controller(nullptr),
 | 
			
		||||
    m_widget(nullptr),
 | 
			
		||||
    m_horizontalScrollbar(nullptr),
 | 
			
		||||
    m_verticalScrollbar(nullptr)
 | 
			
		||||
    m_verticalScrollbar(nullptr),
 | 
			
		||||
    m_features(PDFRenderer::Antialiasing | PDFRenderer::TextAntialiasing)
 | 
			
		||||
{
 | 
			
		||||
    m_controller = new PDFDrawSpaceController(this);
 | 
			
		||||
    connect(m_controller, &PDFDrawSpaceController::drawSpaceChanged, this, &PDFDrawWidgetProxy::update);
 | 
			
		||||
@@ -549,7 +550,7 @@ void PDFDrawWidgetProxy::draw(QPainter* painter, QRect rect)
 | 
			
		||||
            // Clear the page space by white color
 | 
			
		||||
            painter->fillRect(placedRect, Qt::white);
 | 
			
		||||
 | 
			
		||||
            PDFRenderer renderer(m_controller->getDocument(), m_controller->getFontCache(), m_controller->getOptionalContentActivity());
 | 
			
		||||
            PDFRenderer renderer(m_controller->getDocument(), m_controller->getFontCache(), m_controller->getOptionalContentActivity(), m_features);
 | 
			
		||||
            QList<PDFRenderError> errors = renderer.render(painter, placedRect, item.pageIndex);
 | 
			
		||||
 | 
			
		||||
            if (!errors.empty())
 | 
			
		||||
@@ -810,4 +811,18 @@ void PDFDrawWidgetProxy::updateVerticalScrollbarFromOffset()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PDFRenderer::Features PDFDrawWidgetProxy::getFeatures() const
 | 
			
		||||
{
 | 
			
		||||
    return m_features;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PDFDrawWidgetProxy::setFeatures(PDFRenderer::Features features)
 | 
			
		||||
{
 | 
			
		||||
    if (m_features != features)
 | 
			
		||||
    {
 | 
			
		||||
        m_features = features;
 | 
			
		||||
        emit repaintNeeded();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}   // namespace pdf
 | 
			
		||||
 
 | 
			
		||||
@@ -213,6 +213,9 @@ public:
 | 
			
		||||
 | 
			
		||||
    static constexpr PDFReal ZOOM_STEP = 1.2;
 | 
			
		||||
 | 
			
		||||
    PDFRenderer::Features getFeatures() const;
 | 
			
		||||
    void setFeatures(PDFRenderer::Features features);
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
    void drawSpaceChanged();
 | 
			
		||||
    void pageLayoutChanged();
 | 
			
		||||
@@ -326,6 +329,9 @@ private:
 | 
			
		||||
 | 
			
		||||
    /// Current page layout
 | 
			
		||||
    Layout m_layout;
 | 
			
		||||
 | 
			
		||||
    /// Renderer features
 | 
			
		||||
    PDFRenderer::Features m_features;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}   // namespace pdf
 | 
			
		||||
 
 | 
			
		||||
@@ -1866,6 +1866,23 @@ 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())
 | 
			
		||||
        {
 | 
			
		||||
@@ -1969,8 +1986,6 @@ void PDFPageContentProcessor::operatorMarkedContentBegin(PDFOperandName name)
 | 
			
		||||
 | 
			
		||||
void PDFPageContentProcessor::operatorMarkedContentBeginWithProperties(PDFOperandName name, PDFObject properties)
 | 
			
		||||
{
 | 
			
		||||
    // TODO: Handle optional content of images/forms
 | 
			
		||||
 | 
			
		||||
    // Handle the optional content
 | 
			
		||||
    if (name.name == "OC")
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -406,6 +406,10 @@ protected:
 | 
			
		||||
    /// Returns true, if graphic content is suppressed
 | 
			
		||||
    bool isContentSuppressed() const;
 | 
			
		||||
 | 
			
		||||
    /// Computes visibility of OCG/OCMD - returns false, if it is not suppressed,
 | 
			
		||||
    /// or true, if it is suppressed.
 | 
			
		||||
    virtual bool isContentSuppressedByOC(PDFObjectReference ocgOrOcmd);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    /// Initializes the resources dictionaries
 | 
			
		||||
    void initDictionaries(const PDFObject& resourcesObject);
 | 
			
		||||
@@ -665,10 +669,6 @@ private:
 | 
			
		||||
    /// Read object from operand stack
 | 
			
		||||
    PDFObject readObjectFromOperandStack(size_t startPosition) const;
 | 
			
		||||
 | 
			
		||||
    /// Computes visibility of OCG/OCMD - returns false, if it is not suppressed,
 | 
			
		||||
    /// or true, if it is suppressed.
 | 
			
		||||
    bool isContentSuppressedByOC(PDFObjectReference ocgOrOcmd);
 | 
			
		||||
 | 
			
		||||
    const PDFPage* m_page;
 | 
			
		||||
    const PDFDocument* m_document;
 | 
			
		||||
    const PDFFontCache* m_fontCache;
 | 
			
		||||
 
 | 
			
		||||
@@ -81,8 +81,6 @@ void PDFPainter::performPathPainting(const QPainterPath& path, bool stroke, bool
 | 
			
		||||
        m_painter->setBrush(Qt::NoBrush);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_painter->setRenderHint(QPainter::Antialiasing, m_features.testFlag(PDFRenderer::Antialiasing));
 | 
			
		||||
 | 
			
		||||
    Q_ASSERT(path.fillRule() == fillRule);
 | 
			
		||||
    m_painter->drawPath(path);
 | 
			
		||||
}
 | 
			
		||||
@@ -162,6 +160,16 @@ void PDFPainter::performRestoreGraphicState(ProcessOrder order)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool PDFPainter::isContentSuppressedByOC(PDFObjectReference ocgOrOcmd)
 | 
			
		||||
{
 | 
			
		||||
    if (m_features.testFlag(PDFRenderer::IgnoreOptionalContent))
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return PDFPageContentProcessor::isContentSuppressedByOC(ocgOrOcmd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QPen PDFPainter::getCurrentPenImpl() const
 | 
			
		||||
{
 | 
			
		||||
    const PDFPageContentProcessorState* graphicState = getGraphicState();
 | 
			
		||||
 
 | 
			
		||||
@@ -57,6 +57,7 @@ protected:
 | 
			
		||||
    virtual void performUpdateGraphicsState(const PDFPageContentProcessorState& state) override;
 | 
			
		||||
    virtual void performSaveGraphicState(ProcessOrder order) override;
 | 
			
		||||
    virtual void performRestoreGraphicState(ProcessOrder order) override;
 | 
			
		||||
    virtual bool isContentSuppressedByOC(PDFObjectReference ocgOrOcmd) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    /// Returns current pen
 | 
			
		||||
 
 | 
			
		||||
@@ -22,11 +22,11 @@
 | 
			
		||||
namespace pdf
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
PDFRenderer::PDFRenderer(const PDFDocument* document, const PDFFontCache* fontCache, const PDFOptionalContentActivity* optionalContentActivity) :
 | 
			
		||||
PDFRenderer::PDFRenderer(const PDFDocument* document, const PDFFontCache* fontCache, const PDFOptionalContentActivity* optionalContentActivity, Features features) :
 | 
			
		||||
    m_document(document),
 | 
			
		||||
    m_fontCache(fontCache),
 | 
			
		||||
    m_optionalContentActivity(optionalContentActivity),
 | 
			
		||||
    m_features(Antialiasing | TextAntialiasing)
 | 
			
		||||
    m_features(features)
 | 
			
		||||
{
 | 
			
		||||
    Q_ASSERT(document);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -32,17 +32,19 @@ class PDFOptionalContentActivity;
 | 
			
		||||
class PDFRenderer
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    explicit PDFRenderer(const PDFDocument* document, const PDFFontCache* fontCache, const PDFOptionalContentActivity* optionalContentActivity);
 | 
			
		||||
 | 
			
		||||
    enum Feature
 | 
			
		||||
    {
 | 
			
		||||
        Antialiasing        = 0x0001,   ///< Antialiasing for lines, shapes, etc.
 | 
			
		||||
        TextAntialiasing    = 0x0002,   ///< Antialiasing for drawing text
 | 
			
		||||
        SmoothImages        = 0x0004    ///< Adjust images to the device space using smooth transformation (slower, but better performance quality)
 | 
			
		||||
        Antialiasing            = 0x0001,   ///< Antialiasing for lines, shapes, etc.
 | 
			
		||||
        TextAntialiasing        = 0x0002,   ///< Antialiasing for drawing text
 | 
			
		||||
        SmoothImages            = 0x0004,   ///< Adjust images to the device space using smooth transformation (slower, but better image quality)
 | 
			
		||||
        IgnoreOptionalContent   = 0x0008,   ///< Ignore optional content (so all is drawn ignoring settings of optional content)
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Q_DECLARE_FLAGS(Features, Feature)
 | 
			
		||||
 | 
			
		||||
    explicit PDFRenderer(const PDFDocument* document, const PDFFontCache* fontCache, const PDFOptionalContentActivity* optionalContentActivity, Features features);
 | 
			
		||||
 | 
			
		||||
    /// Paints desired page onto the painter. Page is painted in the rectangle using best-fit method.
 | 
			
		||||
    /// If the page doesn't exist, then error is returned. No exception is thrown. Rendering errors
 | 
			
		||||
    /// are reported and returned in the error list. If no error occured, empty list is returned.
 | 
			
		||||
@@ -56,6 +58,9 @@ public:
 | 
			
		||||
    /// Rendering errors are reported and returned in the error list. If no error occured, empty list is returned.
 | 
			
		||||
    QList<PDFRenderError> render(QPainter* painter, const QMatrix& matrix, size_t pageIndex) const;
 | 
			
		||||
 | 
			
		||||
    /// Returns default renderer features
 | 
			
		||||
    static constexpr Features getDefaultFeatures() { return Antialiasing | TextAntialiasing; }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    const PDFDocument* m_document;
 | 
			
		||||
    const PDFFontCache* m_fontCache;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user