mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-02-15 19:20:42 +01:00
Merge remote-tracking branch 'remotes/origin/branches/issue123'
This commit is contained in:
commit
6c5b8b08a5
2
.github/workflows/LinuxInstall.yml
vendored
2
.github/workflows/LinuxInstall.yml
vendored
@ -48,7 +48,7 @@ jobs:
|
||||
|
||||
- name: 'VCPKG: Install project dependencies'
|
||||
run: |
|
||||
./vcpkg install tbb openssl lcms zlib openjpeg freetype ijg-libjpeg libpng
|
||||
./vcpkg install tbb openssl lcms zlib openjpeg freetype ijg-libjpeg libpng blend2d
|
||||
working-directory: vcpkg
|
||||
|
||||
- name: Install Qt
|
||||
|
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -36,7 +36,7 @@ jobs:
|
||||
|
||||
- name: 'VCPKG: Install project dependencies'
|
||||
run: |
|
||||
./vcpkg install tbb openssl lcms zlib openjpeg freetype ijg-libjpeg libpng
|
||||
./vcpkg install tbb openssl lcms zlib openjpeg freetype ijg-libjpeg libpng blend2d
|
||||
working-directory: vcpkg
|
||||
|
||||
- name: Install Qt
|
||||
@ -101,7 +101,7 @@ jobs:
|
||||
|
||||
- name: 'VCPKG: Install project dependencies'
|
||||
run: |
|
||||
.\vcpkg install tbb openssl lcms zlib openjpeg freetype ijg-libjpeg libpng --triplet x64-windows
|
||||
.\vcpkg install tbb openssl lcms zlib openjpeg freetype ijg-libjpeg libpng blend2d --triplet x64-windows
|
||||
working-directory: vcpkg
|
||||
|
||||
- name: Install Qt
|
||||
|
@ -33,7 +33,6 @@ if(WIN32 AND MSVC)
|
||||
option(PDF4QT_INSTALL_PREPARE_WIX_INSTALLER "Prepare Wix installer for Windows" ON)
|
||||
endif()
|
||||
|
||||
option(PDF4QT_ENABLE_OPENGL "Enable OpenGL" ON)
|
||||
option(PDF4QT_BUILD_ONLY_CORE_LIBRARY "Build only core library" OFF)
|
||||
|
||||
set(PDF4QT_QT_ROOT "" CACHE PATH "Qt root directory")
|
||||
@ -49,18 +48,8 @@ include(GNUInstallDirs)
|
||||
|
||||
if(PDF4QT_BUILD_ONLY_CORE_LIBRARY)
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Svg Xml)
|
||||
|
||||
if(PDF4QT_ENABLE_OPENGL)
|
||||
add_compile_definitions(PDF4QT_ENABLE_OPENGL)
|
||||
find_package(Qt6 REQUIRED COMPONENTS OpenGL)
|
||||
endif()
|
||||
else()
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Svg Xml PrintSupport TextToSpeech Test)
|
||||
|
||||
if(PDF4QT_ENABLE_OPENGL)
|
||||
add_compile_definitions(PDF4QT_ENABLE_OPENGL)
|
||||
find_package(Qt6 REQUIRED COMPONENTS OpenGL OpenGLWidgets)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
qt_standard_project_setup()
|
||||
@ -72,6 +61,7 @@ find_package(Freetype REQUIRED)
|
||||
find_package(OpenJPEG CONFIG REQUIRED)
|
||||
find_package(JPEG REQUIRED)
|
||||
find_package(PNG REQUIRED)
|
||||
find_package(blend2d CONFIG REQUIRED)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
@ -178,7 +168,7 @@ if(PDF4QT_INSTALL_DEPENDENCIES AND NOT PDF4QT_BUILD_ONLY_CORE_LIBRARY)
|
||||
install(DIRECTORY ${PDF4QT_QT_ROOT}/bin/
|
||||
RUNTIME DESTINATION ${PDF4QT_INSTALL_LIB_DIR}/
|
||||
FILES_MATCHING
|
||||
REGEX "(Qt6Core|Qt6Gui|Qt6PrintSupport|Qt6Svg|Qt6TextToSpeech|Qt6Widgets|Qt6Xml|Qt6OpenGL|Qt6OpenGLWidgets|Qt6Multimedia|Qt6Network)\\..*"
|
||||
REGEX "(Qt6Core|Qt6Gui|Qt6PrintSupport|Qt6Svg|Qt6TextToSpeech|Qt6Widgets|Qt6Xml|Qt6Multimedia|Qt6Network)\\..*"
|
||||
PATTERN "Debug" EXCLUDE
|
||||
)
|
||||
|
||||
|
@ -35,10 +35,6 @@ add_executable(Pdf4QtDocDiff
|
||||
icon.rc
|
||||
)
|
||||
|
||||
if(PDF4QT_ENABLE_OPENGL)
|
||||
target_link_libraries(Pdf4QtDocDiff PRIVATE Qt6::OpenGLWidgets)
|
||||
endif()
|
||||
|
||||
target_link_libraries(Pdf4QtDocDiff PRIVATE Pdf4QtLibCore Pdf4QtLibWidgets Qt6::Core Qt6::Gui Qt6::Widgets)
|
||||
|
||||
set_target_properties(Pdf4QtDocDiff PROPERTIES
|
||||
|
@ -24,7 +24,6 @@
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents, true);
|
||||
QApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity, true);
|
||||
QApplication application(argc, argv);
|
||||
|
||||
QCoreApplication::setOrganizationName("MelkaJ");
|
||||
|
@ -82,7 +82,7 @@ MainWindow::MainWindow(QWidget* parent) :
|
||||
ui->documentFrame->setLayout(new QVBoxLayout);
|
||||
|
||||
m_cmsManager = new pdf::PDFCMSManager(this);
|
||||
m_pdfWidget = new pdf::PDFWidget(m_cmsManager, pdf::RendererEngine::Software, 1, ui->documentFrame);
|
||||
m_pdfWidget = new pdf::PDFWidget(m_cmsManager, pdf::RendererEngine::QPainter, ui->documentFrame);
|
||||
m_pdfWidget->getDrawWidgetProxy()->setProgress(m_progress);
|
||||
ui->documentFrame->layout()->addWidget(m_pdfWidget);
|
||||
m_pdfWidget->getDrawWidgetProxy()->registerDrawInterface(&m_drawInterface);
|
||||
|
@ -24,7 +24,6 @@
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents, true);
|
||||
QApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity, true);
|
||||
QApplication application(argc, argv);
|
||||
|
||||
QCoreApplication::setOrganizationName("MelkaJ");
|
||||
|
@ -35,9 +35,7 @@ PageItemDelegate::PageItemDelegate(PageItemModel* model, QObject* parent) :
|
||||
m_rasterizer(nullptr)
|
||||
{
|
||||
m_rasterizer = new pdf::PDFRasterizer(this);
|
||||
QSurfaceFormat format;
|
||||
format.setSamples(16);
|
||||
m_rasterizer->reset(false, format);
|
||||
m_rasterizer->reset(pdf::RendererEngine::Blend2D_SingleThread);
|
||||
}
|
||||
|
||||
PageItemDelegate::~PageItemDelegate()
|
||||
|
@ -146,6 +146,8 @@ add_library(Pdf4QtLibCore SHARED
|
||||
cmaps.qrc
|
||||
sources/pdfcertificatestore.h
|
||||
sources/pdfcertificatestore.cpp
|
||||
sources/pdfblpainter.h
|
||||
sources/pdfblpainter.cpp
|
||||
)
|
||||
|
||||
include(GenerateExportHeader)
|
||||
@ -163,10 +165,6 @@ target_link_libraries(Pdf4QtLibCore PRIVATE Freetype::Freetype)
|
||||
target_link_libraries(Pdf4QtLibCore PRIVATE openjp2)
|
||||
target_link_libraries(Pdf4QtLibCore PRIVATE JPEG::JPEG)
|
||||
|
||||
if(PDF4QT_ENABLE_OPENGL)
|
||||
target_link_libraries(Pdf4QtLibCore PRIVATE Qt6::OpenGL)
|
||||
endif()
|
||||
|
||||
if(LINUX_GCC)
|
||||
target_link_libraries(Pdf4QtLibCore PUBLIC TBB::tbb)
|
||||
endif()
|
||||
@ -178,6 +176,8 @@ endif()
|
||||
target_include_directories(Pdf4QtLibCore INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/sources)
|
||||
target_include_directories(Pdf4QtLibCore PUBLIC ${CMAKE_BINARY_DIR}/${INSTALL_INCLUDEDIR})
|
||||
|
||||
target_link_libraries(Pdf4QtLibCore PRIVATE blend2d::blend2d)
|
||||
|
||||
set_target_properties(Pdf4QtLibCore PROPERTIES
|
||||
VERSION ${PDF4QT_VERSION}
|
||||
SOVERSION ${PDF4QT_VERSION}
|
||||
|
1324
Pdf4QtLibCore/sources/pdfblpainter.cpp
Normal file
1324
Pdf4QtLibCore/sources/pdfblpainter.cpp
Normal file
File diff suppressed because it is too large
Load Diff
51
Pdf4QtLibCore/sources/pdfblpainter.h
Normal file
51
Pdf4QtLibCore/sources/pdfblpainter.h
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright (C) 2024 Jakub Melka
|
||||
//
|
||||
// This file is part of PDF4QT.
|
||||
//
|
||||
// PDF4QT is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// with the written consent of the copyright owner, any later version.
|
||||
//
|
||||
// PDF4QT is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef PDFBLPAINTER_H
|
||||
#define PDFBLPAINTER_H
|
||||
|
||||
#include "pdfglobal.h"
|
||||
|
||||
#include <QImage>
|
||||
#include <QPaintDevice>
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
class PDFBLPaintEngine;
|
||||
|
||||
class PDF4QTLIBCORESHARED_EXPORT PDFBLPaintDevice : public QPaintDevice
|
||||
{
|
||||
public:
|
||||
PDFBLPaintDevice(QImage& offscreenBuffer, bool isMultithreaded);
|
||||
virtual ~PDFBLPaintDevice() override;
|
||||
|
||||
virtual int devType() const override;
|
||||
virtual QPaintEngine* paintEngine() const override;
|
||||
|
||||
static uint32_t getVersion();
|
||||
|
||||
protected:
|
||||
virtual int metric(PaintDeviceMetric metric) const override;
|
||||
|
||||
private:
|
||||
QImage& m_offscreenBuffer;
|
||||
PDFBLPaintEngine* m_paintEngine;
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
||||
#endif // PDFBLPAINTER_H
|
@ -2685,4 +2685,16 @@ CharacterInfos PDFRealizedType3FontImpl::getCharacterInfos() const
|
||||
return result;
|
||||
}
|
||||
|
||||
QByteArray PDFSystemFont::getFontData(const QByteArray& fontName)
|
||||
{
|
||||
const PDFSystemFontInfoStorage* storage = PDFSystemFontInfoStorage::getInstance();
|
||||
|
||||
CIDSystemInfo systemInfo;
|
||||
PDFRenderErrorReporterDummy reporter;
|
||||
FontDescriptor descriptor;
|
||||
descriptor.fontName = fontName;
|
||||
|
||||
return storage->loadFont(&systemInfo, &descriptor, StandardFontType::Invalid, &reporter);
|
||||
}
|
||||
|
||||
} // namespace pdf
|
||||
|
@ -698,6 +698,12 @@ private:
|
||||
std::map<QByteArray, QByteArray> m_cmaps;
|
||||
};
|
||||
|
||||
class PDF4QTLIBCORESHARED_EXPORT PDFSystemFont
|
||||
{
|
||||
public:
|
||||
static QByteArray getFontData(const QByteArray& fontName);
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
||||
#endif // PDFFONT_H
|
||||
|
@ -187,8 +187,9 @@ private:
|
||||
|
||||
enum class RendererEngine
|
||||
{
|
||||
Software,
|
||||
OpenGL
|
||||
Blend2D_MultiThread,
|
||||
Blend2D_SingleThread,
|
||||
QPainter,
|
||||
};
|
||||
|
||||
enum class RenderingIntent
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "pdfpainter.h"
|
||||
#include "pdfpattern.h"
|
||||
#include "pdfcms.h"
|
||||
#include "pdfpainterutils.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QCryptographicHash>
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2021-2022 Jakub Melka
|
||||
// Copyright (C) 2021-2024 Jakub Melka
|
||||
//
|
||||
// This file is part of PDF4QT.
|
||||
//
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
#include "pdfpainterutils.h"
|
||||
|
||||
#include <QPainterPath>
|
||||
#include <QFontMetrics>
|
||||
|
||||
#include "pdfdbgheap.h"
|
||||
@ -63,4 +64,5 @@ QRect PDFPainterHelper::drawBubble(QPainter* painter, QPoint point, QColor color
|
||||
return rectangle;
|
||||
}
|
||||
|
||||
|
||||
} // namespace pdf
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "pdfcolorspaces.h"
|
||||
#include "pdfexecutionpolicy.h"
|
||||
#include "pdfconstants.h"
|
||||
#include "pdfpainterutils.h"
|
||||
|
||||
#include <QMutex>
|
||||
#include <QPainter>
|
||||
|
@ -21,19 +21,12 @@
|
||||
#include "pdfexecutionpolicy.h"
|
||||
#include "pdfprogress.h"
|
||||
#include "pdfannotation.h"
|
||||
#include "pdfblpainter.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QElapsedTimer>
|
||||
#include <QtMath>
|
||||
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
#include <QOpenGLContext>
|
||||
#include <QOffscreenSurface>
|
||||
#include <QOpenGLPaintDevice>
|
||||
#include <QOpenGLFramebufferObject>
|
||||
#include <QOpenGLFunctions>
|
||||
#endif
|
||||
|
||||
#include "pdfdbgheap.h"
|
||||
|
||||
namespace pdf
|
||||
@ -227,54 +220,19 @@ void PDFRenderer::compile(PDFPrecompiledPage* precompiledPage, size_t pageIndex)
|
||||
|
||||
PDFRasterizer::PDFRasterizer(QObject* parent) :
|
||||
BaseClass(parent),
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
m_features(),
|
||||
m_surfaceFormat(),
|
||||
m_surface(nullptr),
|
||||
m_context(nullptr),
|
||||
m_fbo(nullptr)
|
||||
#else
|
||||
m_features()
|
||||
#endif
|
||||
m_rendererEngine(RendererEngine::Blend2D_SingleThread)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PDFRasterizer::~PDFRasterizer()
|
||||
{
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
releaseOpenGL();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void PDFRasterizer::reset(bool useOpenGL, const QSurfaceFormat& surfaceFormat)
|
||||
void PDFRasterizer::reset(RendererEngine rendererEngine)
|
||||
{
|
||||
if (!PDFRendererInfo::isHardwareAccelerationSupported())
|
||||
{
|
||||
m_features.setFlag(FailedOpenGL, true);
|
||||
m_features.setFlag(ValidOpenGL, false);
|
||||
}
|
||||
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
if (useOpenGL != m_features.testFlag(UseOpenGL) || surfaceFormat != m_surfaceFormat)
|
||||
{
|
||||
// In either case, we must reset OpenGL
|
||||
releaseOpenGL();
|
||||
|
||||
m_features.setFlag(UseOpenGL, useOpenGL);
|
||||
m_surfaceFormat = surfaceFormat;
|
||||
|
||||
// We create new OpenGL renderer, but only if it hasn't failed (we do not try
|
||||
// again to create new OpenGL renderer.
|
||||
if (m_features.testFlag(UseOpenGL) && !m_features.testFlag(FailedOpenGL))
|
||||
{
|
||||
initializeOpenGL();
|
||||
}
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(surfaceFormat);
|
||||
m_features.setFlag(UseOpenGL, useOpenGL);
|
||||
#endif
|
||||
m_rendererEngine = rendererEngine;
|
||||
}
|
||||
|
||||
QImage PDFRasterizer::render(PDFInteger pageIndex,
|
||||
@ -285,70 +243,28 @@ QImage PDFRasterizer::render(PDFInteger pageIndex,
|
||||
const PDFAnnotationManager* annotationManager,
|
||||
PageRotation extraRotation)
|
||||
{
|
||||
QImage image;
|
||||
QImage image(size, QImage::Format_ARGB32_Premultiplied);
|
||||
|
||||
QTransform matrix = PDFRenderer::createPagePointToDevicePointMatrix(page, QRect(QPoint(0, 0), size), extraRotation);
|
||||
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
if (m_features.testFlag(UseOpenGL) && m_features.testFlag(ValidOpenGL))
|
||||
if (m_rendererEngine == RendererEngine::Blend2D_MultiThread ||
|
||||
m_rendererEngine == RendererEngine::Blend2D_SingleThread)
|
||||
{
|
||||
// We have valid OpenGL context, try to select it and possibly create framebuffer object
|
||||
// for target image (to paint it using paint device).
|
||||
Q_ASSERT(m_surface && m_context);
|
||||
if (m_context->makeCurrent(m_surface))
|
||||
PDFBLPaintDevice blPaintDevice(image, false);
|
||||
|
||||
QPainter painter(&blPaintDevice);
|
||||
compiledPage->draw(&painter, page->getCropBox(), matrix, features, 1.0);
|
||||
|
||||
if (annotationManager)
|
||||
{
|
||||
if (!m_fbo || m_fbo->width() != size.width() || m_fbo->height() != size.height())
|
||||
{
|
||||
// Delete old framebuffer object
|
||||
delete m_fbo;
|
||||
|
||||
// Create a new framebuffer object
|
||||
QOpenGLFramebufferObjectFormat format;
|
||||
format.setSamples(m_surfaceFormat.samples());
|
||||
m_fbo = new QOpenGLFramebufferObject(size.width(), size.height(), format);
|
||||
}
|
||||
|
||||
Q_ASSERT(m_fbo);
|
||||
if (m_fbo->isValid() && m_fbo->bind())
|
||||
{
|
||||
// Now, we have bind the buffer. Due to bug in Qt's OpenGL drawing subsystem,
|
||||
// we must render it two times, otherwise painter paths will be sometimes
|
||||
// replaced by filled rectangles.
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
QOpenGLPaintDevice device(size);
|
||||
QPainter painter(&device);
|
||||
painter.fillRect(QRect(QPoint(0, 0), size), compiledPage->getPaperColor());
|
||||
compiledPage->draw(&painter, page->getCropBox(), matrix, features, 1.0);
|
||||
|
||||
if (annotationManager)
|
||||
{
|
||||
QList<PDFRenderError> errors;
|
||||
PDFTextLayoutGetter textLayoutGetter(nullptr, pageIndex);
|
||||
annotationManager->drawPage(&painter, pageIndex, compiledPage, textLayoutGetter, matrix, errors);
|
||||
}
|
||||
}
|
||||
|
||||
m_fbo->release();
|
||||
|
||||
image = m_fbo->toImage();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_features.setFlag(FailedOpenGL, true);
|
||||
m_features.setFlag(ValidOpenGL, false);
|
||||
}
|
||||
|
||||
m_context->doneCurrent();
|
||||
QList<PDFRenderError> errors;
|
||||
PDFTextLayoutGetter textLayoutGetter(nullptr, pageIndex);
|
||||
annotationManager->drawPage(&painter, pageIndex, compiledPage, textLayoutGetter, matrix, errors);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (image.isNull())
|
||||
else
|
||||
{
|
||||
// If we can't use OpenGL, or user doesn't want to use OpenGL, then fallback
|
||||
// to standard software rasterizer.
|
||||
image = QImage(size, QImage::Format_ARGB32_Premultiplied);
|
||||
// Use standard software rasterizer.
|
||||
image.fill(Qt::white);
|
||||
|
||||
QPainter painter(&image);
|
||||
@ -362,13 +278,6 @@ QImage PDFRasterizer::render(PDFInteger pageIndex,
|
||||
}
|
||||
}
|
||||
|
||||
// Jakub Melka: Convert the image into format Format_ARGB32_Premultiplied for fast drawing.
|
||||
// If this format is used, then no image conversion is performed while drawing.
|
||||
if (image.format() != QImage::Format_ARGB32_Premultiplied)
|
||||
{
|
||||
image.convertTo(QImage::Format_ARGB32_Premultiplied);
|
||||
}
|
||||
|
||||
// Calculate image DPI
|
||||
QSizeF rotatedSizeInMeters = page->getRotatedMediaBoxMM().size() / 1000.0;
|
||||
QSizeF rotatedSizeInPixels = image.size();
|
||||
@ -380,87 +289,6 @@ QImage PDFRasterizer::render(PDFInteger pageIndex,
|
||||
return image;
|
||||
}
|
||||
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
void PDFRasterizer::initializeOpenGL()
|
||||
{
|
||||
Q_ASSERT(!m_surface);
|
||||
Q_ASSERT(!m_context);
|
||||
Q_ASSERT(!m_fbo);
|
||||
|
||||
m_features.setFlag(ValidOpenGL, false);
|
||||
m_features.setFlag(FailedOpenGL, false);
|
||||
|
||||
// Create context
|
||||
m_context = new QOpenGLContext(this);
|
||||
m_context->setFormat(m_surfaceFormat);
|
||||
if (!m_context->create())
|
||||
{
|
||||
m_features.setFlag(FailedOpenGL, true);
|
||||
|
||||
delete m_context;
|
||||
m_context = nullptr;
|
||||
}
|
||||
|
||||
// Create surface
|
||||
m_surface = new QOffscreenSurface(nullptr, this);
|
||||
m_surface->setFormat(m_surfaceFormat);
|
||||
m_surface->create();
|
||||
if (!m_surface->isValid())
|
||||
{
|
||||
m_features.setFlag(FailedOpenGL, true);
|
||||
|
||||
delete m_context;
|
||||
delete m_surface;
|
||||
|
||||
m_context = nullptr;
|
||||
m_surface = nullptr;
|
||||
}
|
||||
|
||||
// Check, if we can make it current
|
||||
if (m_context->makeCurrent(m_surface))
|
||||
{
|
||||
m_features.setFlag(ValidOpenGL, true);
|
||||
m_context->doneCurrent();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_features.setFlag(FailedOpenGL, true);
|
||||
releaseOpenGL();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
void PDFRasterizer::releaseOpenGL()
|
||||
{
|
||||
if (m_surface)
|
||||
{
|
||||
Q_ASSERT(m_context);
|
||||
|
||||
// Delete framebuffer
|
||||
if (m_fbo)
|
||||
{
|
||||
m_context->makeCurrent(m_surface);
|
||||
delete m_fbo;
|
||||
m_fbo = nullptr;
|
||||
m_context->doneCurrent();
|
||||
}
|
||||
|
||||
// Delete OpenGL context
|
||||
delete m_context;
|
||||
m_context = nullptr;
|
||||
|
||||
// Delete surface
|
||||
m_surface->destroy();
|
||||
delete m_surface;
|
||||
m_surface = nullptr;
|
||||
|
||||
// Set flag, that we do not have valid OpenGL
|
||||
m_features.setFlag(ValidOpenGL, false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PDFRasterizer* PDFRasterizerPool::acquire()
|
||||
{
|
||||
m_semaphore.acquire();
|
||||
@ -978,8 +806,7 @@ PDFRasterizerPool::PDFRasterizerPool(const PDFDocument* document,
|
||||
PDFRenderer::Features features,
|
||||
const PDFMeshQualitySettings& meshQualitySettings,
|
||||
int rasterizerCount,
|
||||
bool useOpenGL,
|
||||
const QSurfaceFormat& surfaceFormat,
|
||||
RendererEngine rendererEngine,
|
||||
QObject* parent) :
|
||||
BaseClass(parent),
|
||||
m_document(document),
|
||||
@ -994,96 +821,8 @@ PDFRasterizerPool::PDFRasterizerPool(const PDFDocument* document,
|
||||
for (int i = 0; i < rasterizerCount; ++i)
|
||||
{
|
||||
m_rasterizers.push_back(new PDFRasterizer(this));
|
||||
m_rasterizers.back()->reset(useOpenGL, surfaceFormat);
|
||||
m_rasterizers.back()->reset(rendererEngine);
|
||||
}
|
||||
}
|
||||
|
||||
PDFCachedItem<PDFRendererInfo::Info> PDFRendererInfo::s_info;
|
||||
|
||||
const PDFRendererInfo::Info& PDFRendererInfo::getHardwareAccelerationSupportedInfo()
|
||||
{
|
||||
auto getInfo = []()
|
||||
{
|
||||
Info info;
|
||||
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
QOffscreenSurface surface;
|
||||
surface.create();
|
||||
|
||||
if (!surface.isValid())
|
||||
{
|
||||
info.renderer = PDFTranslationContext::tr("GDI Generic");
|
||||
info.version = PDFTranslationContext::tr("1.1");
|
||||
info.vendor = PDFTranslationContext::tr("System");
|
||||
return info;
|
||||
}
|
||||
|
||||
QOpenGLContext context;
|
||||
|
||||
if (!context.create())
|
||||
{
|
||||
info.renderer = PDFTranslationContext::tr("GDI Generic");
|
||||
info.version = PDFTranslationContext::tr("1.1");
|
||||
info.vendor = PDFTranslationContext::tr("System");
|
||||
surface.destroy();
|
||||
return info;
|
||||
}
|
||||
|
||||
if (!context.makeCurrent(&surface))
|
||||
{
|
||||
info.renderer = PDFTranslationContext::tr("GDI Generic");
|
||||
info.version = PDFTranslationContext::tr("1.1");
|
||||
info.vendor = PDFTranslationContext::tr("System");
|
||||
surface.destroy();
|
||||
return info;
|
||||
}
|
||||
|
||||
const char* versionStr = reinterpret_cast<const char*>(context.functions()->glGetString(GL_VERSION));
|
||||
const char* vendorStr = reinterpret_cast<const char*>(context.functions()->glGetString(GL_VENDOR));
|
||||
const char* rendererStr = reinterpret_cast<const char*>(context.functions()->glGetString(GL_RENDERER));
|
||||
|
||||
QString versionString = QString::fromLocal8Bit(versionStr, std::strlen(versionStr));
|
||||
QString vendorString = QString::fromLocal8Bit(vendorStr, std::strlen(vendorStr));
|
||||
QString rendererString = QString::fromLocal8Bit(rendererStr, std::strlen(rendererStr));
|
||||
|
||||
context.doneCurrent();
|
||||
surface.destroy();
|
||||
|
||||
versionString = versionString.trimmed();
|
||||
|
||||
int spaceIndex = versionString.indexOf(QChar(QChar::Space));
|
||||
if (spaceIndex != -1)
|
||||
{
|
||||
versionString = versionString.left(spaceIndex);
|
||||
}
|
||||
|
||||
info.vendor = vendorString;
|
||||
info.renderer = rendererString;
|
||||
info.version = versionString;
|
||||
|
||||
QStringList versionStrSplitted = versionString.split('.', Qt::KeepEmptyParts);
|
||||
|
||||
if (versionStrSplitted.size() >= 2)
|
||||
{
|
||||
info.majorOpenGLVersion = versionStrSplitted[0].toInt();
|
||||
info.minorOpenGLVersion = versionStrSplitted[1].toInt();
|
||||
}
|
||||
#endif
|
||||
|
||||
return info;
|
||||
};
|
||||
|
||||
return s_info.get(getInfo);
|
||||
}
|
||||
|
||||
bool PDFRendererInfo::isHardwareAccelerationSupported()
|
||||
{
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
const Info& info = getHardwareAccelerationSupportedInfo();
|
||||
return std::make_pair(info.majorOpenGLVersion, info.minorOpenGLVersion) >= std::make_pair(REQUIRED_OPENGL_MAJOR_VERSION, REQUIRED_OPENGL_MINOR_VERSION);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace pdf
|
||||
|
@ -28,13 +28,9 @@
|
||||
#include <QMutex>
|
||||
#include <QSemaphore>
|
||||
#include <QImageWriter>
|
||||
#include <QSurfaceFormat>
|
||||
#include <QImage>
|
||||
|
||||
class QPainter;
|
||||
class QOpenGLContext;
|
||||
class QOffscreenSurface;
|
||||
class QOpenGLFramebufferObject;
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
@ -46,30 +42,6 @@ class PDFPrecompiledPage;
|
||||
class PDFAnnotationManager;
|
||||
class PDFOptionalContentActivity;
|
||||
|
||||
class PDF4QTLIBCORESHARED_EXPORT PDFRendererInfo
|
||||
{
|
||||
public:
|
||||
PDFRendererInfo() = delete;
|
||||
|
||||
struct Info
|
||||
{
|
||||
QString vendor;
|
||||
QString renderer;
|
||||
QString version;
|
||||
int majorOpenGLVersion = 0;
|
||||
int minorOpenGLVersion = 0;
|
||||
};
|
||||
|
||||
static const Info& getHardwareAccelerationSupportedInfo();
|
||||
static bool isHardwareAccelerationSupported();
|
||||
|
||||
static constexpr int REQUIRED_OPENGL_MAJOR_VERSION = 3;
|
||||
static constexpr int REQUIRED_OPENGL_MINOR_VERSION = 2;
|
||||
|
||||
private:
|
||||
static PDFCachedItem<Info> s_info;
|
||||
};
|
||||
|
||||
/// Renders the PDF page on the painter, or onto an image.
|
||||
class PDF4QTLIBCORESHARED_EXPORT PDFRenderer
|
||||
{
|
||||
@ -165,9 +137,7 @@ private:
|
||||
PDFMeshQualitySettings m_meshQualitySettings;
|
||||
};
|
||||
|
||||
/// Renders PDF pages to bitmap images (QImage). It can use OpenGL for painting,
|
||||
/// if it is enabled, if this is the case, offscreen rendering to framebuffer
|
||||
/// is used.
|
||||
/// Renders PDF pages to bitmap images (QImage).
|
||||
/// \note Construct this object only in main GUI thread
|
||||
class PDF4QTLIBCORESHARED_EXPORT PDFRasterizer : public QObject
|
||||
{
|
||||
@ -180,22 +150,9 @@ public:
|
||||
explicit PDFRasterizer(QObject* parent);
|
||||
virtual ~PDFRasterizer() override;
|
||||
|
||||
/// Resets the renderer. This function must be called from main GUI thread,
|
||||
/// it cannot be called from deferred threads, because it can create hidden
|
||||
/// window (offscreen surface). If hardware renderer is required, and
|
||||
/// none is available, then software renderer is used.
|
||||
/// \param useOpenGL Use OpenGL for rendering (ignored if not available)
|
||||
/// \param surfaceFormat Surface format to render
|
||||
void reset(bool useOpenGL, const QSurfaceFormat& surfaceFormat);
|
||||
|
||||
enum Feature
|
||||
{
|
||||
UseOpenGL = 0x0001, ///< Use OpenGL for rendering
|
||||
ValidOpenGL = 0x0002, ///< OpenGL is initialized and valid
|
||||
FailedOpenGL = 0x0004, ///< OpenGL creation has failed
|
||||
};
|
||||
|
||||
Q_DECLARE_FLAGS(Features, Feature)
|
||||
/// Resets the renderer.
|
||||
/// \param rendererEngine Renderer engine type
|
||||
void reset(RendererEngine rendererEngine);
|
||||
|
||||
/// Renders page to the image of given size. If some error occurs, then
|
||||
/// empty image is returned. Warning: this function can modify this object,
|
||||
@ -217,18 +174,7 @@ public:
|
||||
PageRotation extraRotation);
|
||||
|
||||
private:
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
void initializeOpenGL();
|
||||
void releaseOpenGL();
|
||||
#endif
|
||||
|
||||
Features m_features;
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
QSurfaceFormat m_surfaceFormat;
|
||||
QOffscreenSurface* m_surface;
|
||||
QOpenGLContext* m_context;
|
||||
QOpenGLFramebufferObject* m_fbo;
|
||||
#endif
|
||||
RendererEngine m_rendererEngine;
|
||||
};
|
||||
|
||||
/// Simple structure for storing rendered page images
|
||||
@ -267,8 +213,7 @@ public:
|
||||
/// \param features Renderer features
|
||||
/// \param meshQualitySettings Mesh quality settings
|
||||
/// \param rasterizerCount Number of rasterizers
|
||||
/// \param useOpenGL Use OpenGL for rendering?
|
||||
/// \param surfaceFormat Surface format
|
||||
/// \param rendererEngine Renderer engine
|
||||
/// \param parent Parent object
|
||||
explicit PDFRasterizerPool(const PDFDocument* document,
|
||||
PDFFontCache* fontCache,
|
||||
@ -277,8 +222,7 @@ public:
|
||||
PDFRenderer::Features features,
|
||||
const PDFMeshQualitySettings& meshQualitySettings,
|
||||
int rasterizerCount,
|
||||
bool useOpenGL,
|
||||
const QSurfaceFormat& surfaceFormat,
|
||||
RendererEngine rendererEngine,
|
||||
QObject* parent);
|
||||
|
||||
/// Acquire rasterizer. This function is thread safe.
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "pdfutils.h"
|
||||
#include "pdfexception.h"
|
||||
#include "pdfblpainter.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QtMath>
|
||||
@ -315,6 +316,18 @@ std::vector<PDFDependentLibraryInfo> PDFDependentLibraryInfo::getLibraryInfo()
|
||||
zlibInfo.url = tr("https://zlib.net/");
|
||||
result.emplace_back(qMove(zlibInfo));
|
||||
|
||||
// blend2d
|
||||
const uint32_t blend2dVersion = PDFBLPaintDevice::getVersion();
|
||||
const int blend2dMajor = (blend2dVersion >> 16) & 0xFF;
|
||||
const int blend2dMinor = (blend2dVersion >> 8) & 0xFF;
|
||||
const int blend2dPatch = (blend2dVersion) & 0xFF;
|
||||
PDFDependentLibraryInfo blend2dInfo;
|
||||
blend2dInfo.library = tr("Blend2D");
|
||||
blend2dInfo.license = tr("zlib specific");
|
||||
blend2dInfo.version = QString("%1.%2.%3").arg(blend2dMajor).arg(blend2dMinor).arg(blend2dPatch);
|
||||
blend2dInfo.url = tr("https://blend2d.com/");
|
||||
result.emplace_back(qMove(blend2dInfo));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -74,10 +74,6 @@ GENERATE_EXPORT_HEADER(Pdf4QtLibWidgets
|
||||
PDF4QTLIBWIDGETSSHARED_EXPORT
|
||||
EXPORT_FILE_NAME "${CMAKE_BINARY_DIR}/${INSTALL_INCLUDEDIR}/pdf4qtlibwidgets_export.h")
|
||||
|
||||
if(PDF4QT_ENABLE_OPENGL)
|
||||
target_link_libraries(Pdf4QtLibWidgets PRIVATE Qt6::OpenGLWidgets)
|
||||
endif()
|
||||
|
||||
target_link_libraries(Pdf4QtLibWidgets PRIVATE Pdf4QtLibCore Qt6::Core Qt6::Gui Qt6::Xml Qt6::Svg Qt6::Widgets)
|
||||
|
||||
if(LINUX_GCC)
|
||||
@ -88,6 +84,8 @@ if(MINGW)
|
||||
target_link_libraries(Pdf4QtLibWidgets PRIVATE Secur32 Mscms Gdi32 User32 crypt32)
|
||||
endif()
|
||||
|
||||
target_link_libraries(Pdf4QtLibWidgets PRIVATE blend2d::blend2d)
|
||||
|
||||
target_include_directories(Pdf4QtLibWidgets INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/sources)
|
||||
target_include_directories(Pdf4QtLibWidgets PUBLIC ${CMAKE_BINARY_DIR}/${INSTALL_INCLUDEDIR})
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "pdfannotation.h"
|
||||
#include "pdfdrawwidget.h"
|
||||
#include "pdfwidgetannotation.h"
|
||||
#include "pdfpainterutils.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QPainter>
|
||||
@ -469,7 +470,7 @@ PDFDrawWidgetProxy::PDFDrawWidgetProxy(QObject* parent) :
|
||||
m_rasterizer(new PDFRasterizer(this)),
|
||||
m_progress(nullptr),
|
||||
m_cacheClearTimer(new QTimer(this)),
|
||||
m_useOpenGL(false)
|
||||
m_rendererEngine(RendererEngine::Blend2D_MultiThread)
|
||||
{
|
||||
m_controller = new PDFDrawSpaceController(this);
|
||||
connect(m_controller, &PDFDrawSpaceController::drawSpaceChanged, this, &PDFDrawWidgetProxy::update);
|
||||
@ -1403,11 +1404,10 @@ bool PDFDrawWidgetProxy::isBlockMode() const
|
||||
return false;
|
||||
}
|
||||
|
||||
void PDFDrawWidgetProxy::updateRenderer(bool useOpenGL, const QSurfaceFormat& surfaceFormat)
|
||||
void PDFDrawWidgetProxy::updateRenderer(RendererEngine rendererEngine)
|
||||
{
|
||||
m_useOpenGL = useOpenGL;
|
||||
m_surfaceFormat = surfaceFormat;
|
||||
m_rasterizer->reset(useOpenGL && ENABLE_OPENGL_FOR_THUMBNAILS, surfaceFormat);
|
||||
m_rendererEngine = rendererEngine;
|
||||
m_rasterizer->reset(m_rendererEngine);
|
||||
}
|
||||
|
||||
void PDFDrawWidgetProxy::prefetchPages(PDFInteger pageIndex)
|
||||
|
@ -317,9 +317,8 @@ public:
|
||||
|
||||
/// Updates renderer (in current implementation, renderer for page thumbnails)
|
||||
/// using given parameters.
|
||||
/// \param useOpenGL Use OpenGL for rendering?
|
||||
/// \param surfaceFormat Surface format for OpenGL rendering
|
||||
void updateRenderer(bool useOpenGL, const QSurfaceFormat& surfaceFormat);
|
||||
/// \param rendererEngine Renderer engine
|
||||
void updateRenderer(RendererEngine rendererEngine);
|
||||
|
||||
/// Prefetches (prerenders) pages after page with pageIndex, i.e., prepares
|
||||
/// for non-flickering scroll operation.
|
||||
@ -338,8 +337,7 @@ public:
|
||||
void setProgress(PDFProgress* progress) { m_progress = progress; }
|
||||
PDFAsynchronousTextLayoutCompiler* getTextLayoutCompiler() const { return m_textLayoutCompiler; }
|
||||
PDFWidget* getWidget() const { return m_widget; }
|
||||
bool isUsingOpenGL() const { return m_useOpenGL; }
|
||||
const QSurfaceFormat& getSurfaceFormat() const { return m_surfaceFormat; }
|
||||
RendererEngine getRendererEngine() const { return m_rendererEngine; }
|
||||
PageRotation getPageRotation() const { return m_controller->getPageRotation(); }
|
||||
|
||||
void setFeatures(PDFRenderer::Features features);
|
||||
@ -461,8 +459,6 @@ private:
|
||||
constexpr inline T bound(T value) { return qBound(min, value, max); }
|
||||
};
|
||||
|
||||
static constexpr bool ENABLE_OPENGL_FOR_THUMBNAILS = false;
|
||||
|
||||
/// Flag, disables the update
|
||||
bool m_updateDisabled;
|
||||
|
||||
@ -536,11 +532,8 @@ private:
|
||||
/// Additional drawing interfaces
|
||||
std::set<IDocumentDrawInterface*> m_drawInterfaces;
|
||||
|
||||
/// Use OpenGL for rendering?
|
||||
bool m_useOpenGL;
|
||||
|
||||
/// Surface format for OpenGL
|
||||
QSurfaceFormat m_surfaceFormat;
|
||||
/// Renderer engine
|
||||
RendererEngine m_rendererEngine;
|
||||
|
||||
/// Page group info for rendering. Group of pages
|
||||
/// can be rendered with transparency or without paper
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "pdfannotation.h"
|
||||
#include "pdfwidgetannotation.h"
|
||||
#include "pdfwidgetformmanager.h"
|
||||
#include "pdfblpainter.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QGridLayout>
|
||||
@ -35,7 +36,7 @@
|
||||
namespace pdf
|
||||
{
|
||||
|
||||
PDFWidget::PDFWidget(const PDFCMSManager* cmsManager, RendererEngine engine, int samplesCount, QWidget* parent) :
|
||||
PDFWidget::PDFWidget(const PDFCMSManager* cmsManager, RendererEngine engine, QWidget* parent) :
|
||||
QWidget(parent),
|
||||
m_cmsManager(cmsManager),
|
||||
m_toolManager(nullptr),
|
||||
@ -44,9 +45,10 @@ PDFWidget::PDFWidget(const PDFCMSManager* cmsManager, RendererEngine engine, int
|
||||
m_drawWidget(nullptr),
|
||||
m_horizontalScrollBar(nullptr),
|
||||
m_verticalScrollBar(nullptr),
|
||||
m_proxy(nullptr)
|
||||
m_proxy(nullptr),
|
||||
m_rendererEngine(engine)
|
||||
{
|
||||
m_drawWidget = createDrawWidget(getEffectiveRenderer(engine), samplesCount);
|
||||
m_drawWidget = new PDFDrawWidget(this, this);
|
||||
m_horizontalScrollBar = new QScrollBar(Qt::Horizontal, this);
|
||||
m_verticalScrollBar = new QScrollBar(Qt::Vertical, this);
|
||||
|
||||
@ -62,10 +64,10 @@ PDFWidget::PDFWidget(const PDFCMSManager* cmsManager, RendererEngine engine, int
|
||||
|
||||
m_proxy = new PDFDrawWidgetProxy(this);
|
||||
m_proxy->init(this);
|
||||
m_proxy->updateRenderer(m_rendererEngine);
|
||||
connect(m_proxy, &PDFDrawWidgetProxy::renderingError, this, &PDFWidget::onRenderingError);
|
||||
connect(m_proxy, &PDFDrawWidgetProxy::repaintNeeded, m_drawWidget->getWidget(), QOverload<>::of(&QWidget::update));
|
||||
connect(m_proxy, &PDFDrawWidgetProxy::pageImageChanged, this, &PDFWidget::onPageImageChanged);
|
||||
updateRendererImpl();
|
||||
}
|
||||
|
||||
PDFWidget::~PDFWidget()
|
||||
@ -90,39 +92,10 @@ void PDFWidget::setDocument(const PDFModifiedDocument& document)
|
||||
m_drawWidget->getWidget()->update();
|
||||
}
|
||||
|
||||
void PDFWidget::updateRenderer(RendererEngine engine, int samplesCount)
|
||||
void PDFWidget::updateRenderer(RendererEngine engine)
|
||||
{
|
||||
engine = getEffectiveRenderer(engine);
|
||||
|
||||
PDFOpenGLDrawWidget* openglDrawWidget = qobject_cast<PDFOpenGLDrawWidget*>(m_drawWidget->getWidget());
|
||||
PDFDrawWidget* softwareDrawWidget = qobject_cast<PDFDrawWidget*>(m_drawWidget->getWidget());
|
||||
|
||||
// Do we need to change renderer?
|
||||
if ((openglDrawWidget && engine != RendererEngine::OpenGL) || (softwareDrawWidget && engine != RendererEngine::Software))
|
||||
{
|
||||
QGridLayout* layout = qobject_cast<QGridLayout*>(this->layout());
|
||||
layout->removeWidget(m_drawWidget->getWidget());
|
||||
delete m_drawWidget->getWidget();
|
||||
|
||||
m_drawWidget = createDrawWidget(engine, samplesCount);
|
||||
layout->addWidget(m_drawWidget->getWidget(), 0, 0);
|
||||
setFocusProxy(m_drawWidget->getWidget());
|
||||
connect(m_proxy, &PDFDrawWidgetProxy::repaintNeeded, m_drawWidget->getWidget(), QOverload<>::of(&QWidget::update));
|
||||
}
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
else if (openglDrawWidget)
|
||||
{
|
||||
// Just check the samples count
|
||||
QSurfaceFormat format = openglDrawWidget->format();
|
||||
if (format.samples() != samplesCount)
|
||||
{
|
||||
format.setSamples(samplesCount);
|
||||
openglDrawWidget->setFormat(format);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
updateRendererImpl();
|
||||
m_rendererEngine = engine;
|
||||
m_proxy->updateRenderer(m_rendererEngine);
|
||||
}
|
||||
|
||||
void PDFWidget::updateCacheLimits(int compiledPageCacheLimit, int thumbnailsCacheLimit, int fontCacheLimit, int instancedFontCacheLimit)
|
||||
@ -142,16 +115,6 @@ int PDFWidget::getPageRenderingErrorCount() const
|
||||
return count;
|
||||
}
|
||||
|
||||
void PDFWidget::updateRendererImpl()
|
||||
{
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
PDFOpenGLDrawWidget* openglDrawWidget = qobject_cast<PDFOpenGLDrawWidget*>(m_drawWidget->getWidget());
|
||||
m_proxy->updateRenderer(openglDrawWidget != nullptr, openglDrawWidget ? openglDrawWidget->format() : QSurfaceFormat::defaultFormat());
|
||||
#else
|
||||
m_proxy->updateRenderer(false, QSurfaceFormat::defaultFormat());
|
||||
#endif
|
||||
}
|
||||
|
||||
void PDFWidget::onRenderingError(PDFInteger pageIndex, const QList<PDFRenderError>& errors)
|
||||
{
|
||||
// Empty list of error should not be reported!
|
||||
@ -182,29 +145,6 @@ void PDFWidget::onPageImageChanged(bool all, const std::vector<PDFInteger>& page
|
||||
}
|
||||
}
|
||||
|
||||
IDrawWidget* PDFWidget::createDrawWidget(RendererEngine rendererEngine, int samplesCount)
|
||||
{
|
||||
switch (rendererEngine)
|
||||
{
|
||||
case RendererEngine::Software:
|
||||
return new PDFDrawWidget(this, this);
|
||||
|
||||
case RendererEngine::OpenGL:
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
return new PDFOpenGLDrawWidget(this, samplesCount, this);
|
||||
#else
|
||||
Q_UNUSED(samplesCount);
|
||||
return new PDFDrawWidget(this, this);
|
||||
#endif
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void PDFWidget::removeInputInterface(IDrawWidgetInputInterface* inputInterface)
|
||||
{
|
||||
auto it = std::find(m_inputInterfaces.begin(), m_inputInterfaces.end(), inputInterface);
|
||||
@ -223,16 +163,6 @@ void PDFWidget::addInputInterface(IDrawWidgetInputInterface* inputInterface)
|
||||
}
|
||||
}
|
||||
|
||||
RendererEngine PDFWidget::getEffectiveRenderer(RendererEngine rendererEngine)
|
||||
{
|
||||
if (rendererEngine == RendererEngine::OpenGL && !pdf::PDFRendererInfo::isHardwareAccelerationSupported())
|
||||
{
|
||||
return RendererEngine::Software;
|
||||
}
|
||||
|
||||
return rendererEngine;
|
||||
}
|
||||
|
||||
PDFWidgetFormManager* PDFWidget::getFormManager() const
|
||||
{
|
||||
return m_formManager;
|
||||
@ -259,43 +189,38 @@ void PDFWidget::setAnnotationManager(PDFWidgetAnnotationManager* annotationManag
|
||||
addInputInterface(m_annotationManager);
|
||||
}
|
||||
|
||||
template<typename BaseWidget>
|
||||
PDFDrawWidgetBase<BaseWidget>::PDFDrawWidgetBase(PDFWidget* widget, QWidget* parent) :
|
||||
BaseWidget(parent),
|
||||
PDFDrawWidget::PDFDrawWidget(PDFWidget* widget, QWidget* parent) :
|
||||
BaseClass(parent),
|
||||
m_widget(widget),
|
||||
m_mouseOperation(MouseOperation::None)
|
||||
{
|
||||
this->setFocusPolicy(Qt::StrongFocus);
|
||||
this->setMouseTracking(true);
|
||||
|
||||
QObject::connect(&m_autoScrollTimer, &QTimer::timeout, this, &PDFDrawWidgetBase::onAutoScrollTimeout);
|
||||
QObject::connect(&m_autoScrollTimer, &QTimer::timeout, this, &PDFDrawWidget::onAutoScrollTimeout);
|
||||
}
|
||||
|
||||
template<typename BaseWidget>
|
||||
std::vector<PDFInteger> PDFDrawWidgetBase<BaseWidget>::getCurrentPages() const
|
||||
std::vector<PDFInteger> PDFDrawWidget::getCurrentPages() const
|
||||
{
|
||||
return this->m_widget->getDrawWidgetProxy()->getPagesIntersectingRect(this->rect());
|
||||
}
|
||||
|
||||
template<typename BaseWidget>
|
||||
QSize PDFDrawWidgetBase<BaseWidget>::minimumSizeHint() const
|
||||
QSize PDFDrawWidget::minimumSizeHint() const
|
||||
{
|
||||
return QSize(200, 200);
|
||||
}
|
||||
|
||||
template<typename BaseWidget>
|
||||
bool PDFDrawWidgetBase<BaseWidget>::event(QEvent* event)
|
||||
bool PDFDrawWidget::event(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::ShortcutOverride)
|
||||
{
|
||||
return processEvent<QKeyEvent, &IDrawWidgetInputInterface::shortcutOverrideEvent>(static_cast<QKeyEvent*>(event));
|
||||
}
|
||||
|
||||
return BaseWidget::event(event);
|
||||
return BaseClass::event(event);
|
||||
}
|
||||
|
||||
template<typename BaseWidget>
|
||||
void PDFDrawWidgetBase<BaseWidget>::performMouseOperation(QPoint currentMousePosition)
|
||||
void PDFDrawWidget::performMouseOperation(QPoint currentMousePosition)
|
||||
{
|
||||
switch (m_mouseOperation)
|
||||
{
|
||||
@ -323,9 +248,8 @@ void PDFDrawWidgetBase<BaseWidget>::performMouseOperation(QPoint currentMousePos
|
||||
}
|
||||
}
|
||||
|
||||
template<typename BaseWidget>
|
||||
template<typename Event, void (IDrawWidgetInputInterface::* Function)(QWidget*, Event*)>
|
||||
bool PDFDrawWidgetBase<BaseWidget>::processEvent(Event* event)
|
||||
bool PDFDrawWidget::processEvent(Event* event)
|
||||
{
|
||||
QString tooltip;
|
||||
for (IDrawWidgetInputInterface* inputInterface : m_widget->getInputInterfaces())
|
||||
@ -351,8 +275,7 @@ bool PDFDrawWidgetBase<BaseWidget>::processEvent(Event* event)
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename BaseWidget>
|
||||
void PDFDrawWidgetBase<BaseWidget>::keyPressEvent(QKeyEvent* event)
|
||||
void PDFDrawWidget::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
event->ignore();
|
||||
|
||||
@ -388,8 +311,7 @@ void PDFDrawWidgetBase<BaseWidget>::keyPressEvent(QKeyEvent* event)
|
||||
updateCursor();
|
||||
}
|
||||
|
||||
template<typename BaseWidget>
|
||||
void PDFDrawWidgetBase<BaseWidget>::keyReleaseEvent(QKeyEvent* event)
|
||||
void PDFDrawWidget::keyReleaseEvent(QKeyEvent* event)
|
||||
{
|
||||
event->ignore();
|
||||
|
||||
@ -401,8 +323,7 @@ void PDFDrawWidgetBase<BaseWidget>::keyReleaseEvent(QKeyEvent* event)
|
||||
event->accept();
|
||||
}
|
||||
|
||||
template<typename BaseWidget>
|
||||
void PDFDrawWidgetBase<BaseWidget>::mousePressEvent(QMouseEvent* event)
|
||||
void PDFDrawWidget::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
event->ignore();
|
||||
|
||||
@ -442,8 +363,7 @@ void PDFDrawWidgetBase<BaseWidget>::mousePressEvent(QMouseEvent* event)
|
||||
event->accept();
|
||||
}
|
||||
|
||||
template<typename BaseWidget>
|
||||
void PDFDrawWidgetBase<BaseWidget>::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
void PDFDrawWidget::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
{
|
||||
event->ignore();
|
||||
|
||||
@ -453,8 +373,7 @@ void PDFDrawWidgetBase<BaseWidget>::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
template<typename BaseWidget>
|
||||
void PDFDrawWidgetBase<BaseWidget>::mouseReleaseEvent(QMouseEvent* event)
|
||||
void PDFDrawWidget::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
event->ignore();
|
||||
|
||||
@ -491,8 +410,7 @@ void PDFDrawWidgetBase<BaseWidget>::mouseReleaseEvent(QMouseEvent* event)
|
||||
event->accept();
|
||||
}
|
||||
|
||||
template<typename BaseWidget>
|
||||
void PDFDrawWidgetBase<BaseWidget>::mouseMoveEvent(QMouseEvent* event)
|
||||
void PDFDrawWidget::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
event->ignore();
|
||||
|
||||
@ -506,8 +424,7 @@ void PDFDrawWidgetBase<BaseWidget>::mouseMoveEvent(QMouseEvent* event)
|
||||
event->accept();
|
||||
}
|
||||
|
||||
template<typename BaseWidget>
|
||||
void PDFDrawWidgetBase<BaseWidget>::updateCursor()
|
||||
void PDFDrawWidget::updateCursor()
|
||||
{
|
||||
std::optional<QCursor> cursor;
|
||||
|
||||
@ -554,8 +471,7 @@ void PDFDrawWidgetBase<BaseWidget>::updateCursor()
|
||||
}
|
||||
}
|
||||
|
||||
template<typename BaseWidget>
|
||||
void PDFDrawWidgetBase<BaseWidget>::onAutoScrollTimeout()
|
||||
void PDFDrawWidget::onAutoScrollTimeout()
|
||||
{
|
||||
if (m_mouseOperation != MouseOperation::AutoScroll)
|
||||
{
|
||||
@ -579,8 +495,7 @@ void PDFDrawWidgetBase<BaseWidget>::onAutoScrollTimeout()
|
||||
proxy->scrollByPixels(QPoint(scrollX, scrollY));
|
||||
}
|
||||
|
||||
template<typename BaseWidget>
|
||||
void PDFDrawWidgetBase<BaseWidget>::wheelEvent(QWheelEvent* event)
|
||||
void PDFDrawWidget::wheelEvent(QWheelEvent* event)
|
||||
{
|
||||
event->ignore();
|
||||
|
||||
@ -659,62 +574,59 @@ void PDFDrawWidgetBase<BaseWidget>::wheelEvent(QWheelEvent* event)
|
||||
event->accept();
|
||||
}
|
||||
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
PDFOpenGLDrawWidget::PDFOpenGLDrawWidget(PDFWidget* widget, int samplesCount, QWidget* parent) :
|
||||
BaseClass(widget, parent)
|
||||
{
|
||||
QSurfaceFormat format = this->format();
|
||||
format.setProfile(QSurfaceFormat::CoreProfile);
|
||||
format.setSamples(samplesCount);
|
||||
format.setColorSpace(QColorSpace(QColorSpace::SRgb));
|
||||
format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
|
||||
setFormat(format);
|
||||
}
|
||||
|
||||
PDFOpenGLDrawWidget::~PDFOpenGLDrawWidget()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PDFOpenGLDrawWidget::resizeGL(int w, int h)
|
||||
{
|
||||
QOpenGLWidget::resizeGL(w, h);
|
||||
|
||||
getPDFWidget()->getDrawWidgetProxy()->update();
|
||||
}
|
||||
|
||||
void PDFOpenGLDrawWidget::initializeGL()
|
||||
{
|
||||
QOpenGLWidget::initializeGL();
|
||||
}
|
||||
|
||||
void PDFOpenGLDrawWidget::paintGL()
|
||||
{
|
||||
if (this->isValid())
|
||||
{
|
||||
QPainter painter(this);
|
||||
getPDFWidget()->getDrawWidgetProxy()->draw(&painter, this->rect());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PDFDrawWidget::PDFDrawWidget(PDFWidget* widget, QWidget* parent) :
|
||||
BaseClass(widget, parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PDFDrawWidget::~PDFDrawWidget()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PDFDrawWidget::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
QPainter painter(this);
|
||||
getPDFWidget()->getDrawWidgetProxy()->draw(&painter, this->rect());
|
||||
RendererEngine rendererEngine = getPDFWidget()->getDrawWidgetProxy()->getRendererEngine();
|
||||
switch (rendererEngine)
|
||||
{
|
||||
case RendererEngine::Blend2D_MultiThread:
|
||||
case RendererEngine::Blend2D_SingleThread:
|
||||
{
|
||||
QRect rect = this->rect();
|
||||
|
||||
qreal devicePixelRatio = devicePixelRatioF();
|
||||
m_blend2DframeBuffer.setDevicePixelRatio(devicePixelRatio);
|
||||
|
||||
qreal dpmX = logicalDpiX() / 0.0254;
|
||||
qreal dpmY = logicalDpiY() / 0.0254;
|
||||
m_blend2DframeBuffer.setDotsPerMeterX(qCeil(dpmX));
|
||||
m_blend2DframeBuffer.setDotsPerMeterY(qCeil(dpmY));
|
||||
|
||||
QSize requiredSize = rect.size() * devicePixelRatio;
|
||||
if (m_blend2DframeBuffer.size() != requiredSize)
|
||||
{
|
||||
m_blend2DframeBuffer = QImage(requiredSize, QImage::Format_ARGB32_Premultiplied);
|
||||
}
|
||||
|
||||
const bool multithreaded = rendererEngine == RendererEngine::Blend2D_MultiThread;
|
||||
PDFBLPaintDevice blPaintDevice(m_blend2DframeBuffer, multithreaded);
|
||||
QPainter blPainter;
|
||||
|
||||
if (blPainter.begin(&blPaintDevice))
|
||||
{
|
||||
getPDFWidget()->getDrawWidgetProxy()->draw(&blPainter, rect);
|
||||
blPainter.end();
|
||||
}
|
||||
|
||||
QPainter painter(this);
|
||||
painter.drawImage(QPoint(0, 0), m_blend2DframeBuffer);
|
||||
break;
|
||||
}
|
||||
|
||||
case RendererEngine::QPainter:
|
||||
{
|
||||
QPainter painter(this);
|
||||
getPDFWidget()->getDrawWidgetProxy()->draw(&painter, this->rect());
|
||||
m_blend2DframeBuffer = QImage();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PDFDrawWidget::resizeEvent(QResizeEvent* event)
|
||||
@ -724,9 +636,4 @@ void PDFDrawWidget::resizeEvent(QResizeEvent* event)
|
||||
getPDFWidget()->getDrawWidgetProxy()->update();
|
||||
}
|
||||
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
template class PDFDrawWidgetBase<QOpenGLWidget>;
|
||||
#endif
|
||||
template class PDFDrawWidgetBase<QWidget>;
|
||||
|
||||
} // namespace pdf
|
||||
|
@ -27,10 +27,6 @@
|
||||
#include <QTimer>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
#include <QOpenGLWidget>
|
||||
#endif
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
class PDFDocument;
|
||||
@ -65,8 +61,7 @@ public:
|
||||
/// Constructs new PDFWidget.
|
||||
/// \param cmsManager Color management system manager
|
||||
/// \param engine Rendering engine type
|
||||
/// \param samplesCount Samples count for rendering engine MSAA antialiasing
|
||||
explicit PDFWidget(const PDFCMSManager* cmsManager, RendererEngine engine, int samplesCount, QWidget* parent);
|
||||
explicit PDFWidget(const PDFCMSManager* cmsManager, RendererEngine engine, QWidget* parent);
|
||||
virtual ~PDFWidget() override;
|
||||
|
||||
virtual bool focusNextPrevChild(bool next) override;
|
||||
@ -81,8 +76,7 @@ public:
|
||||
|
||||
/// Update rendering engine according the settings
|
||||
/// \param engine Engine type
|
||||
/// \param samplesCount Samples count for rendering engine MSAA antialiasing
|
||||
void updateRenderer(RendererEngine engine, int samplesCount);
|
||||
void updateRenderer(RendererEngine engine);
|
||||
|
||||
/// Updates cache limits
|
||||
/// \param compiledPageCacheLimit Compiled page cache limit [bytes]
|
||||
@ -115,14 +109,9 @@ signals:
|
||||
void pageRenderingErrorsChanged(pdf::PDFInteger pageIndex, int errorsCount);
|
||||
|
||||
private:
|
||||
RendererEngine getEffectiveRenderer(RendererEngine rendererEngine);
|
||||
|
||||
void updateRendererImpl();
|
||||
void onRenderingError(PDFInteger pageIndex, const QList<PDFRenderError>& errors);
|
||||
void onPageImageChanged(bool all, const std::vector<PDFInteger>& pages);
|
||||
|
||||
IDrawWidget* createDrawWidget(RendererEngine rendererEngine, int samplesCount);
|
||||
|
||||
const PDFCMSManager* m_cmsManager;
|
||||
PDFToolManager* m_toolManager;
|
||||
PDFWidgetAnnotationManager* m_annotationManager;
|
||||
@ -133,14 +122,19 @@ private:
|
||||
PDFDrawWidgetProxy* m_proxy;
|
||||
PageRenderingErrors m_pageRenderingErrors;
|
||||
std::vector<IDrawWidgetInputInterface*> m_inputInterfaces;
|
||||
RendererEngine m_rendererEngine;
|
||||
};
|
||||
|
||||
template<typename BaseWidget>
|
||||
class PDFDrawWidgetBase : public BaseWidget, public IDrawWidget
|
||||
class PDFDrawWidget : public QWidget, public IDrawWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
using BaseClass = QWidget;
|
||||
|
||||
public:
|
||||
explicit PDFDrawWidgetBase(PDFWidget* widget, QWidget* parent);
|
||||
virtual ~PDFDrawWidgetBase() override = default;
|
||||
explicit PDFDrawWidget(PDFWidget* widget, QWidget* parent);
|
||||
virtual ~PDFDrawWidget() override = default;
|
||||
|
||||
/// Returns page indices, which are currently displayed in the widget
|
||||
virtual std::vector<PDFInteger> getCurrentPages() const override;
|
||||
@ -158,6 +152,8 @@ protected:
|
||||
virtual void mouseReleaseEvent(QMouseEvent* event) override;
|
||||
virtual void mouseMoveEvent(QMouseEvent* event) override;
|
||||
virtual void wheelEvent(QWheelEvent* event) override;
|
||||
virtual void paintEvent(QPaintEvent* event) override;
|
||||
virtual void resizeEvent(QResizeEvent* event) override;
|
||||
|
||||
PDFWidget* getPDFWidget() const { return m_widget; }
|
||||
|
||||
@ -186,50 +182,9 @@ private:
|
||||
QTimer m_autoScrollTimer;
|
||||
QPointF m_autoScrollOffset;
|
||||
QElapsedTimer m_autoScrollLastElapsedTimer;
|
||||
QImage m_blend2DframeBuffer;
|
||||
};
|
||||
|
||||
class PDFDrawWidget : public PDFDrawWidgetBase<QWidget>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
using BaseClass = PDFDrawWidgetBase<QWidget>;
|
||||
|
||||
public:
|
||||
explicit PDFDrawWidget(PDFWidget* widget, QWidget* parent);
|
||||
virtual ~PDFDrawWidget() override;
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent* event) override;
|
||||
virtual void resizeEvent(QResizeEvent* event) override;
|
||||
};
|
||||
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
class PDFOpenGLDrawWidget : public PDFDrawWidgetBase<QOpenGLWidget>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
using BaseClass = PDFDrawWidgetBase<QOpenGLWidget>;
|
||||
|
||||
public:
|
||||
explicit PDFOpenGLDrawWidget(PDFWidget* widget, int samplesCount, QWidget* parent);
|
||||
virtual ~PDFOpenGLDrawWidget() override;
|
||||
|
||||
protected:
|
||||
virtual void resizeGL(int w, int h) override;
|
||||
virtual void initializeGL() override;
|
||||
virtual void paintGL() override;
|
||||
};
|
||||
#else
|
||||
using PDFOpenGLDrawWidget = PDFDrawWidget;
|
||||
#endif
|
||||
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
extern template class PDFDrawWidgetBase<QOpenGLWidget>;
|
||||
#endif
|
||||
extern template class PDFDrawWidgetBase<QWidget>;
|
||||
|
||||
} // namespace pdf
|
||||
|
||||
#endif // PDFDRAWWIDGET_H
|
||||
|
@ -1197,7 +1197,7 @@ void PDFMagnifierTool::mouseMoveEvent(QWidget* widget, QMouseEvent* event)
|
||||
if (m_mousePos != mousePos)
|
||||
{
|
||||
m_mousePos = mousePos;
|
||||
getProxy()->repaintNeeded();
|
||||
Q_EMIT getProxy()->repaintNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,10 +86,6 @@ GENERATE_EXPORT_HEADER(Pdf4QtViewer
|
||||
PDF4QTVIEWERLIBSHARED_EXPORT
|
||||
EXPORT_FILE_NAME "${CMAKE_BINARY_DIR}/${INSTALL_INCLUDEDIR}/pdf4qtviewer_export.h")
|
||||
|
||||
if(PDF4QT_ENABLE_OPENGL)
|
||||
target_link_libraries(Pdf4QtViewer PRIVATE Qt6::OpenGLWidgets)
|
||||
endif()
|
||||
|
||||
target_link_libraries(Pdf4QtViewer PRIVATE Pdf4QtLibCore Pdf4QtLibWidgets Qt6::Core Qt6::Gui Qt6::Widgets Qt6::PrintSupport Qt6::TextToSpeech Qt6::Xml Qt6::Svg)
|
||||
target_include_directories(Pdf4QtViewer INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_include_directories(Pdf4QtViewer PUBLIC ${CMAKE_BINARY_DIR}/${INSTALL_INCLUDEDIR})
|
||||
|
@ -150,6 +150,7 @@ std::vector<QAction*> PDFActionManager::getRenderingOptionActions() const
|
||||
RenderOptionTextAntialiasing,
|
||||
RenderOptionSmoothPictures,
|
||||
RenderOptionIgnoreOptionalContentSettings,
|
||||
RenderOptionDisplayRenderTimes,
|
||||
RenderOptionDisplayAnnotations,
|
||||
RenderOptionInvertColors,
|
||||
RenderOptionGrayscale,
|
||||
@ -157,8 +158,7 @@ std::vector<QAction*> PDFActionManager::getRenderingOptionActions() const
|
||||
RenderOptionHighContrast,
|
||||
RenderOptionCustomColors,
|
||||
RenderOptionShowTextBlocks,
|
||||
RenderOptionShowTextLines
|
||||
});
|
||||
RenderOptionShowTextLines});
|
||||
}
|
||||
|
||||
std::vector<QAction*> PDFActionManager::getActions() const
|
||||
@ -266,6 +266,7 @@ void PDFActionManager::initActions(QSize iconSize, bool initializeStampActions)
|
||||
setUserData(RenderOptionTextAntialiasing, pdf::PDFRenderer::TextAntialiasing);
|
||||
setUserData(RenderOptionSmoothPictures, pdf::PDFRenderer::SmoothImages);
|
||||
setUserData(RenderOptionIgnoreOptionalContentSettings, pdf::PDFRenderer::IgnoreOptionalContent);
|
||||
setUserData(RenderOptionDisplayRenderTimes, pdf::PDFRenderer::DisplayTimes);
|
||||
setUserData(RenderOptionDisplayAnnotations, pdf::PDFRenderer::DisplayAnnotations);
|
||||
setUserData(RenderOptionInvertColors, pdf::PDFRenderer::ColorAdjust_Invert);
|
||||
setUserData(RenderOptionGrayscale, pdf::PDFRenderer::ColorAdjust_Grayscale);
|
||||
@ -624,7 +625,7 @@ void PDFProgramController::initialize(Features features,
|
||||
|
||||
readSettings(Settings(GeneralSettings | PluginsSettings | RecentFileSettings | CertificateSettings));
|
||||
|
||||
m_pdfWidget = new pdf::PDFWidget(m_CMSManager, m_settings->getRendererEngine(), m_settings->isMultisampleAntialiasingEnabled() ? m_settings->getRendererSamples() : -1, m_mainWindow);
|
||||
m_pdfWidget = new pdf::PDFWidget(m_CMSManager, m_settings->getRendererEngine(), m_mainWindow);
|
||||
m_pdfWidget->setObjectName("pdfWidget");
|
||||
m_pdfWidget->updateCacheLimits(m_settings->getCompiledPageCacheLimit() * 1024, m_settings->getThumbnailsCacheLimit(), m_settings->getFontCacheLimit(), m_settings->getInstancedFontCacheLimit());
|
||||
m_pdfWidget->getDrawWidgetProxy()->setProgress(m_progress);
|
||||
@ -1697,7 +1698,7 @@ void PDFProgramController::updateActionsAvailability()
|
||||
|
||||
void PDFProgramController::onViewerSettingsChanged()
|
||||
{
|
||||
m_pdfWidget->updateRenderer(m_settings->getRendererEngine(), m_settings->isMultisampleAntialiasingEnabled() ? m_settings->getRendererSamples() : -1);
|
||||
m_pdfWidget->updateRenderer(m_settings->getRendererEngine());
|
||||
m_pdfWidget->updateCacheLimits(m_settings->getCompiledPageCacheLimit() * 1024, m_settings->getThumbnailsCacheLimit(), m_settings->getFontCacheLimit(), m_settings->getInstancedFontCacheLimit());
|
||||
m_pdfWidget->getDrawWidgetProxy()->setFeatures(m_settings->getFeatures());
|
||||
m_pdfWidget->getDrawWidgetProxy()->setPreferredMeshResolutionRatio(m_settings->getPreferredMeshResolutionRatio());
|
||||
@ -2298,24 +2299,6 @@ void PDFProgramController::resetSettings()
|
||||
}
|
||||
}
|
||||
|
||||
void PDFProgramController::checkHardwareOpenGLAvailability()
|
||||
{
|
||||
if (m_settings->getRendererEngine() == pdf::RendererEngine::OpenGL &&
|
||||
!pdf::PDFRendererInfo::isHardwareAccelerationSupported())
|
||||
{
|
||||
#ifdef PDF4QT_ENABLE_OPENGL
|
||||
pdf::PDFRendererInfo::Info info = pdf::PDFRendererInfo::getHardwareAccelerationSupportedInfo();
|
||||
QMessageBox::warning(m_mainWindow, tr("Warning"),
|
||||
tr("Hardware acceleration is not supported on this device. "
|
||||
"OpenGL version at least 3.2 is required. Software rendering is used instead. "
|
||||
"Available OpenGL is %1 using %2. You can turn off hardware acceleration "
|
||||
"in 'Tools' menu using 'Options' item to stop displaying this message.").arg(info.version, info.renderer));
|
||||
#else
|
||||
QMessageBox::warning(m_mainWindow, tr("Warning"), tr("Hardware acceleration is not enabled in this build."));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void PDFProgramController::onActionOptionsTriggered()
|
||||
{
|
||||
PDFViewerSettingsDialog::OtherSettings otherSettings;
|
||||
|
@ -161,6 +161,7 @@ public:
|
||||
RenderOptionTextAntialiasing,
|
||||
RenderOptionSmoothPictures,
|
||||
RenderOptionIgnoreOptionalContentSettings,
|
||||
RenderOptionDisplayRenderTimes,
|
||||
RenderOptionDisplayAnnotations,
|
||||
RenderOptionInvertColors,
|
||||
RenderOptionGrayscale,
|
||||
@ -297,8 +298,6 @@ public:
|
||||
void writeSettings();
|
||||
void resetSettings();
|
||||
|
||||
void checkHardwareOpenGLAvailability();
|
||||
|
||||
void performPrint();
|
||||
void performSave();
|
||||
void performSaveAs();
|
||||
|
@ -299,7 +299,7 @@ void PDFRenderToImagesDialog::on_buttonBox_clicked(QAbstractButton* button)
|
||||
m_cms = m_proxy->getCMSManager()->getCurrentCMS();
|
||||
m_rasterizerPool = new pdf::PDFRasterizerPool(m_document, m_proxy->getFontCache(), m_proxy->getCMSManager(),
|
||||
m_optionalContentActivity, m_proxy->getFeatures(), m_proxy->getMeshQualitySettings(),
|
||||
pdf::PDFRasterizerPool::getDefaultRasterizerCount(), m_proxy->isUsingOpenGL(), m_proxy->getSurfaceFormat(), this);
|
||||
pdf::PDFRasterizerPool::getDefaultRasterizerCount(), m_proxy->getRendererEngine(), this);
|
||||
connect(m_rasterizerPool, &pdf::PDFRasterizerPool::renderError, this, &PDFRenderToImagesDialog::onRenderError);
|
||||
|
||||
auto process = [this]()
|
||||
|
@ -160,6 +160,7 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) :
|
||||
m_actionManager->setAction(PDFActionManager::RenderOptionTextAntialiasing, ui->actionRenderOptionTextAntialiasing);
|
||||
m_actionManager->setAction(PDFActionManager::RenderOptionSmoothPictures, ui->actionRenderOptionSmoothPictures);
|
||||
m_actionManager->setAction(PDFActionManager::RenderOptionIgnoreOptionalContentSettings, ui->actionRenderOptionIgnoreOptionalContentSettings);
|
||||
m_actionManager->setAction(PDFActionManager::RenderOptionDisplayRenderTimes, ui->actionRenderOptionDisplayRenderTimes);
|
||||
m_actionManager->setAction(PDFActionManager::RenderOptionDisplayAnnotations, ui->actionRenderOptionDisplayAnnotations);
|
||||
m_actionManager->setAction(PDFActionManager::RenderOptionInvertColors, ui->actionColorInvert);
|
||||
m_actionManager->setAction(PDFActionManager::RenderOptionGrayscale, ui->actionColorGrayscale);
|
||||
@ -543,7 +544,6 @@ void PDFViewerMainWindow::showEvent(QShowEvent* event)
|
||||
{
|
||||
QMainWindow::showEvent(event);
|
||||
m_progressTaskbarIndicator->setWindow(windowHandle());
|
||||
QTimer::singleShot(0, this, [this] { m_programController->checkHardwareOpenGLAvailability(); });
|
||||
}
|
||||
|
||||
void PDFViewerMainWindow::dragEnterEvent(QDragEnterEvent* event)
|
||||
|
@ -90,6 +90,7 @@
|
||||
<addaction name="actionRenderOptionSmoothPictures"/>
|
||||
<addaction name="actionRenderOptionIgnoreOptionalContentSettings"/>
|
||||
<addaction name="actionRenderOptionDisplayAnnotations"/>
|
||||
<addaction name="actionRenderOptionDisplayRenderTimes"/>
|
||||
</widget>
|
||||
<addaction name="menuPage_Layout"/>
|
||||
<addaction name="menuRendering_Options"/>
|
||||
@ -1153,6 +1154,17 @@
|
||||
<string>If checked, bookmarks for main document chapters are generated automatically.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRenderOptionDisplayRenderTimes">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Display Render Times</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources>
|
||||
|
@ -130,6 +130,7 @@ PDFViewerMainWindowLite::PDFViewerMainWindowLite(QWidget* parent) :
|
||||
m_actionManager->setAction(PDFActionManager::RenderOptionTextAntialiasing, ui->actionRenderOptionTextAntialiasing);
|
||||
m_actionManager->setAction(PDFActionManager::RenderOptionSmoothPictures, ui->actionRenderOptionSmoothPictures);
|
||||
m_actionManager->setAction(PDFActionManager::RenderOptionIgnoreOptionalContentSettings, ui->actionRenderOptionIgnoreOptionalContentSettings);
|
||||
m_actionManager->setAction(PDFActionManager::RenderOptionDisplayRenderTimes, ui->actionRenderOptionDisplayRenderTimes);
|
||||
m_actionManager->setAction(PDFActionManager::RenderOptionDisplayAnnotations, ui->actionRenderOptionDisplayAnnotations);
|
||||
m_actionManager->setAction(PDFActionManager::RenderOptionInvertColors, ui->actionColorInvert);
|
||||
m_actionManager->setAction(PDFActionManager::RenderOptionGrayscale, ui->actionColorGrayscale);
|
||||
@ -432,7 +433,6 @@ void PDFViewerMainWindowLite::showEvent(QShowEvent* event)
|
||||
{
|
||||
QMainWindow::showEvent(event);
|
||||
m_progressTaskbarIndicator->setWindow(windowHandle());
|
||||
QTimer::singleShot(0, this, [this] { m_programController->checkHardwareOpenGLAvailability(); });
|
||||
}
|
||||
|
||||
void PDFViewerMainWindowLite::dragEnterEvent(QDragEnterEvent* event)
|
||||
|
@ -42,7 +42,7 @@
|
||||
<property name="title">
|
||||
<string>Go To</string>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuBookmarkSettings">
|
||||
<widget class="QMenu" name="menuBookmarkSettings">
|
||||
<property name="title">
|
||||
<string>Bookmark Settings</string>
|
||||
</property>
|
||||
@ -56,7 +56,6 @@
|
||||
<addaction name="actionGoToNextPage"/>
|
||||
<addaction name="actionGoToPreviousLine"/>
|
||||
<addaction name="actionGoToNextLine"/>
|
||||
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionBookmarkPage"/>
|
||||
<addaction name="actionGotoPreviousBookmark"/>
|
||||
@ -87,6 +86,7 @@
|
||||
<addaction name="actionRenderOptionSmoothPictures"/>
|
||||
<addaction name="actionRenderOptionIgnoreOptionalContentSettings"/>
|
||||
<addaction name="actionRenderOptionDisplayAnnotations"/>
|
||||
<addaction name="actionRenderOptionDisplayRenderTimes"/>
|
||||
</widget>
|
||||
<addaction name="menuPage_Layout"/>
|
||||
<addaction name="menuRendering_Options"/>
|
||||
@ -368,65 +368,65 @@
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionColorInvert">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="pdf4qtviewer.qrc">
|
||||
<normaloff>:/resources/invert-colors.svg</normaloff>:/resources/invert-colors.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Color | Inverted</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionColorGrayscale">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="pdf4qtviewer.qrc">
|
||||
<normaloff>:/resources/invert-colors.svg</normaloff>:/resources/invert-colors.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Color | Grayscale</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionColorHighContrast">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="pdf4qtviewer.qrc">
|
||||
<normaloff>:/resources/invert-colors.svg</normaloff>:/resources/invert-colors.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Color | High Contrast</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionColorBitonal">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="pdf4qtviewer.qrc">
|
||||
<normaloff>:/resources/invert-colors.svg</normaloff>:/resources/invert-colors.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Color | Monochromatic</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionColorCustom">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="pdf4qtviewer.qrc">
|
||||
<normaloff>:/resources/invert-colors.svg</normaloff>:/resources/invert-colors.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Color | Custom</string>
|
||||
</property>
|
||||
</action>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="pdf4qtviewer.qrc">
|
||||
<normaloff>:/resources/invert-colors.svg</normaloff>:/resources/invert-colors.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Color | Inverted</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionColorGrayscale">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="pdf4qtviewer.qrc">
|
||||
<normaloff>:/resources/invert-colors.svg</normaloff>:/resources/invert-colors.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Color | Grayscale</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionColorHighContrast">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="pdf4qtviewer.qrc">
|
||||
<normaloff>:/resources/invert-colors.svg</normaloff>:/resources/invert-colors.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Color | High Contrast</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionColorBitonal">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="pdf4qtviewer.qrc">
|
||||
<normaloff>:/resources/invert-colors.svg</normaloff>:/resources/invert-colors.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Color | Monochromatic</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionColorCustom">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="pdf4qtviewer.qrc">
|
||||
<normaloff>:/resources/invert-colors.svg</normaloff>:/resources/invert-colors.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Color | Custom</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRotateRight">
|
||||
<property name="icon">
|
||||
<iconset resource="pdf4qtviewer.qrc">
|
||||
@ -557,7 +557,6 @@
|
||||
<string>Become a Sponsor</string>
|
||||
</property>
|
||||
</action>
|
||||
|
||||
<action name="actionBookmarkPage">
|
||||
<property name="icon">
|
||||
<iconset resource="pdf4qtviewer.qrc">
|
||||
@ -651,6 +650,17 @@
|
||||
<string>If checked, bookmarks for main document chapters are generated automatically.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRenderOptionDisplayRenderTimes">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Display Render Times</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources>
|
||||
|
@ -43,9 +43,7 @@ void PDFViewerSettings::readSettings(QSettings& settings, const pdf::PDFCMSSetti
|
||||
settings.beginGroup("ViewerSettings");
|
||||
m_settings.m_directory = settings.value("defaultDirectory", QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)).toString();
|
||||
m_settings.m_features = static_cast<pdf::PDFRenderer::Features>(settings.value("rendererFeaturesv2", static_cast<int>(pdf::PDFRenderer::getDefaultFeatures())).toInt());
|
||||
m_settings.m_rendererEngine = static_cast<pdf::RendererEngine>(settings.value("renderingEngine", static_cast<int>(pdf::RendererEngine::OpenGL)).toInt());
|
||||
m_settings.m_multisampleAntialiasing = settings.value("msaa", defaultSettings.m_multisampleAntialiasing).toBool();
|
||||
m_settings.m_rendererSamples = settings.value("rendererSamples", defaultSettings.m_rendererSamples).toInt();
|
||||
m_settings.m_rendererEngine = static_cast<pdf::RendererEngine>(settings.value("renderingEngine", static_cast<int>(pdf::RendererEngine::Blend2D_MultiThread)).toInt());
|
||||
m_settings.m_prefetchPages = settings.value("prefetchPages", defaultSettings.m_prefetchPages).toBool();
|
||||
m_settings.m_preferredMeshResolutionRatio = settings.value("preferredMeshResolutionRatio", defaultSettings.m_preferredMeshResolutionRatio).toDouble();
|
||||
m_settings.m_minimalMeshResolutionRatio = settings.value("minimalMeshResolutionRatio", defaultSettings.m_minimalMeshResolutionRatio).toDouble();
|
||||
@ -119,8 +117,6 @@ void PDFViewerSettings::writeSettings(QSettings& settings)
|
||||
settings.setValue("defaultDirectory", m_settings.m_directory);
|
||||
settings.setValue("rendererFeaturesv2", static_cast<int>(m_settings.m_features));
|
||||
settings.setValue("renderingEngine", static_cast<int>(m_settings.m_rendererEngine));
|
||||
settings.setValue("msaa", m_settings.m_multisampleAntialiasing);
|
||||
settings.setValue("rendererSamples", m_settings.m_rendererSamples);
|
||||
settings.setValue("prefetchPages", m_settings.m_prefetchPages);
|
||||
settings.setValue("preferredMeshResolutionRatio", m_settings.m_preferredMeshResolutionRatio);
|
||||
settings.setValue("minimalMeshResolutionRatio", m_settings.m_minimalMeshResolutionRatio);
|
||||
@ -228,20 +224,6 @@ void PDFViewerSettings::setRendererEngine(pdf::RendererEngine rendererEngine)
|
||||
}
|
||||
}
|
||||
|
||||
int PDFViewerSettings::getRendererSamples() const
|
||||
{
|
||||
return m_settings.m_rendererSamples;
|
||||
}
|
||||
|
||||
void PDFViewerSettings::setRendererSamples(int rendererSamples)
|
||||
{
|
||||
if (m_settings.m_rendererSamples != rendererSamples)
|
||||
{
|
||||
m_settings.m_rendererSamples = rendererSamples;
|
||||
Q_EMIT settingsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFViewerSettings::setPreferredMeshResolutionRatio(pdf::PDFReal preferredMeshResolutionRatio)
|
||||
{
|
||||
if (m_settings.m_preferredMeshResolutionRatio != preferredMeshResolutionRatio)
|
||||
@ -271,9 +253,7 @@ void PDFViewerSettings::setColorTolerance(pdf::PDFReal colorTolerance)
|
||||
|
||||
PDFViewerSettings::Settings::Settings() :
|
||||
m_features(pdf::PDFRenderer::getDefaultFeatures()),
|
||||
m_rendererEngine(pdf::RendererEngine::OpenGL),
|
||||
m_multisampleAntialiasing(true),
|
||||
m_rendererSamples(16),
|
||||
m_rendererEngine(pdf::RendererEngine::Blend2D_MultiThread),
|
||||
m_prefetchPages(true),
|
||||
m_preferredMeshResolutionRatio(0.02),
|
||||
m_minimalMeshResolutionRatio(0.005),
|
||||
|
@ -52,8 +52,6 @@ public:
|
||||
pdf::PDFRenderer::Features m_features;
|
||||
QString m_directory;
|
||||
pdf::RendererEngine m_rendererEngine;
|
||||
bool m_multisampleAntialiasing;
|
||||
int m_rendererSamples;
|
||||
bool m_prefetchPages;
|
||||
pdf::PDFReal m_preferredMeshResolutionRatio;
|
||||
pdf::PDFReal m_minimalMeshResolutionRatio;
|
||||
@ -113,11 +111,7 @@ public:
|
||||
pdf::RendererEngine getRendererEngine() const;
|
||||
void setRendererEngine(pdf::RendererEngine rendererEngine);
|
||||
|
||||
int getRendererSamples() const;
|
||||
void setRendererSamples(int rendererSamples);
|
||||
|
||||
bool isPagePrefetchingEnabled() const { return m_settings.m_prefetchPages; }
|
||||
bool isMultisampleAntialiasingEnabled() const { return m_settings.m_multisampleAntialiasing; }
|
||||
|
||||
pdf::PDFReal getPreferredMeshResolutionRatio() const { return m_settings.m_preferredMeshResolutionRatio; }
|
||||
void setPreferredMeshResolutionRatio(pdf::PDFReal preferredMeshResolutionRatio);
|
||||
|
@ -102,13 +102,9 @@ PDFViewerSettingsDialog::PDFViewerSettingsDialog(const PDFViewerSettings::Settin
|
||||
font.setPointSize(font.pointSize() * 1.5);
|
||||
ui->optionsPagesWidget->setFont(font);
|
||||
|
||||
ui->renderingEngineComboBox->addItem(tr("Software"), static_cast<int>(pdf::RendererEngine::Software));
|
||||
ui->renderingEngineComboBox->addItem(tr("Hardware accelerated (OpenGL)"), static_cast<int>(pdf::RendererEngine::OpenGL));
|
||||
|
||||
for (int i : { 1, 2, 4, 8, 16 })
|
||||
{
|
||||
ui->multisampleAntialiasingSamplesCountComboBox->addItem(QString::number(i), i);
|
||||
}
|
||||
ui->renderingEngineComboBox->addItem(tr("Software | QPainter"), static_cast<int>(pdf::RendererEngine::QPainter));
|
||||
ui->renderingEngineComboBox->addItem(tr("Software | Blend2D | Parallel"), static_cast<int>(pdf::RendererEngine::Blend2D_MultiThread));
|
||||
ui->renderingEngineComboBox->addItem(tr("Software | Blend2D | Sequential"), static_cast<int>(pdf::RendererEngine::Blend2D_SingleThread));
|
||||
|
||||
ui->multithreadingComboBox->addItem(tr("Single thread"), static_cast<int>(pdf::PDFExecutionPolicy::Strategy::SingleThreaded));
|
||||
ui->multithreadingComboBox->addItem(tr("Multithreading (load balanced)"), static_cast<int>(pdf::PDFExecutionPolicy::Strategy::PageMultithreaded));
|
||||
@ -279,29 +275,6 @@ void PDFViewerSettingsDialog::loadData()
|
||||
ui->renderingEngineComboBox->setCurrentIndex(ui->renderingEngineComboBox->findData(static_cast<int>(m_settings.m_rendererEngine)));
|
||||
|
||||
// Engine
|
||||
if (m_settings.m_rendererEngine == pdf::RendererEngine::OpenGL)
|
||||
{
|
||||
ui->multisampleAntialiasingCheckBox->setEnabled(true);
|
||||
ui->multisampleAntialiasingCheckBox->setChecked(m_settings.m_multisampleAntialiasing);
|
||||
|
||||
if (m_settings.m_multisampleAntialiasing)
|
||||
{
|
||||
ui->multisampleAntialiasingSamplesCountComboBox->setEnabled(true);
|
||||
ui->multisampleAntialiasingSamplesCountComboBox->setCurrentIndex(ui->multisampleAntialiasingSamplesCountComboBox->findData(m_settings.m_rendererSamples));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->multisampleAntialiasingSamplesCountComboBox->setEnabled(false);
|
||||
ui->multisampleAntialiasingSamplesCountComboBox->setCurrentIndex(-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->multisampleAntialiasingCheckBox->setEnabled(false);
|
||||
ui->multisampleAntialiasingCheckBox->setChecked(false);
|
||||
ui->multisampleAntialiasingSamplesCountComboBox->setEnabled(false);
|
||||
ui->multisampleAntialiasingSamplesCountComboBox->setCurrentIndex(-1);
|
||||
}
|
||||
ui->prefetchPagesCheckBox->setChecked(m_settings.m_prefetchPages);
|
||||
ui->multithreadingComboBox->setCurrentIndex(ui->multithreadingComboBox->findData(static_cast<int>(m_settings.m_multithreadingStrategy)));
|
||||
|
||||
@ -432,14 +405,6 @@ void PDFViewerSettingsDialog::saveData()
|
||||
{
|
||||
m_settings.m_rendererEngine = static_cast<pdf::RendererEngine>(ui->renderingEngineComboBox->currentData().toInt());
|
||||
}
|
||||
else if (sender == ui->multisampleAntialiasingCheckBox)
|
||||
{
|
||||
m_settings.m_multisampleAntialiasing = ui->multisampleAntialiasingCheckBox->isChecked();
|
||||
}
|
||||
else if (sender == ui->multisampleAntialiasingSamplesCountComboBox)
|
||||
{
|
||||
m_settings.m_rendererSamples = ui->multisampleAntialiasingSamplesCountComboBox->currentData().toInt();
|
||||
}
|
||||
else if (sender == ui->prefetchPagesCheckBox)
|
||||
{
|
||||
m_settings.m_prefetchPages = ui->prefetchPagesCheckBox->isChecked();
|
||||
|
@ -35,7 +35,7 @@
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>6</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="enginePage">
|
||||
<layout class="QVBoxLayout" name="enginePageLayout">
|
||||
@ -59,47 +59,16 @@
|
||||
<layout class="QVBoxLayout" name="engineSettingsGroupBoxLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="engineSettingsGridLayout">
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="multisampleAntialiasingCheckBox">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="multithreadingLabel">
|
||||
<property name="text">
|
||||
<string>Enable</string>
|
||||
<string>Multithreading strategy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="renderingEngineComboBox"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="multisampleAntialiasingLabel">
|
||||
<property name="text">
|
||||
<string>Multisample antialiasing (MSAA)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="multisampleAntialiasingSamplesCountComboBox"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="prefetchPagesLabel">
|
||||
<property name="text">
|
||||
<string>Prefetch pages</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="multisampleAntiailasingSamplesLabel">
|
||||
<property name="text">
|
||||
<string>MSAA Samples count</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="prefetchPagesCheckBox">
|
||||
<property name="text">
|
||||
<string>Enable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="renderingEngineLabel">
|
||||
<property name="text">
|
||||
@ -107,22 +76,29 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="multithreadingLabel">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="prefetchPagesLabel">
|
||||
<property name="text">
|
||||
<string>Multithreading strategy</string>
|
||||
<string>Prefetch pages</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="multithreadingComboBox"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="prefetchPagesCheckBox">
|
||||
<property name="text">
|
||||
<string>Enable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="engineInfoLabel">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>Choose a rendering method based on your needs. Although <span style=" font-weight:600;">Software Rendering</span> is slower than the hardware-accelerated <span style=" font-weight:600;">OpenGL Rendering</span>, it can be utilized when OpenGL is not available on your platform. The default (and recommended) method is OpenGL Rendering. </p><p>OpenGL rendering employs <span style=" font-weight:600;">Multisample Antialiasing (MSAA)</span>, ensuring high-quality image rendering. You have the option to enable or disable this feature. However, disabling it might lead to inferior image quality. The Samples Count sets the number of samples per pixel used to determine pixel color. It can be set to 1, 2, 4, 8, or 16. Most modern GPUs support at least a value of 8. If your GPU doesn't support the desired sample count, lower this value. </p><p>The <span style=" font-weight:600;">Prefetch Pages</span> feature pre-renders pages adjacent to the currently viewed pages, minimizing flickering during scrolling. Prefetched pages are stored in the page cache. </p><p>The <span style=" font-weight:600;">Multithreading Strategy</span> determines how the program will utilize CPU cores. With the <span style=" font-weight:600;">Single Thread</span> strategy, only one CPU core is used for rendering a page. This results in longer processing times, but each page is independently compiled/drawn in its own thread. Alternatively, there are two multithreading strategies: Load Balanced and Maximum Threads. Load Balanced only parallelizes pages without processing individual page content. In contrast, the Maximum Threads strategy spawns as many threads as possible for operations to achieve optimal performance. </p></body></html></string>
|
||||
<string><html><head/><body><p>Select a rendering method tailored to your application's requirements. Software Rendering, utilizing QPainter, is a versatile choice that guarantees compatibility across all platforms. It's particularly useful in scenarios where direct access to hardware acceleration isn't crucial. QPainter, part of the Qt framework, excels in rendering 2D graphics with support for various painting styles, image processing, and intricate graphical transformations, making it an excellent tool for applications that require detailed and sophisticated 2D graphics without relying on hardware acceleration.</p><p>On the other hand, for applications that demand high-performance rendering, leveraging the Blend2D library offers a compelling alternative. Blend2D is a high-performance 2D vector graphics engine that utilizes multi-threading to accelerate the rendering process. It does not rely on QPainter or hardware acceleration but instead offers a software-based rendering solution optimized for speed and quality. Blend2D's advanced anti-aliasing techniques ensure crisp and clear image quality, making it suitable for applications where rendering performance and image quality are paramount.</p><p>The Prefetch Pages feature is a strategy that can be applied regardless of the rendering method chosen. By pre-rendering pages adjacent to the currently viewed content, this approach minimizes flickering and enhances the smoothness of transitions during scrolling, improving the overall user experience.</p><p>When it comes to optimizing the rendering process, the choice of multithreading strategy plays a crucial role. A Single Thread strategy, where rendering tasks are executed sequentially on a single CPU core, might be preferable in environments where simplicity and predictability are key. For more demanding applications, employing a Multi-threading strategy can significantly improve rendering times. Strategies like Load Balanced distribute the workload evenly across CPU cores without delving into content-specific processing, offering a good performance boost. The Maximum Threads strategy takes full advantage of available CPU resources by allocating as many threads as possible to the rendering tasks, achieving optimal performance and minimizing rendering times.</p><p>This delineation between using QPainter for software rendering and Blend2D for high-performance, multi-threaded rendering allows developers to choose the most appropriate rendering pathway based on their specific performance requirements and the graphical complexity of their application.</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
|
@ -24,7 +24,6 @@
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents, true);
|
||||
QApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity, true);
|
||||
QApplication application(argc, argv);
|
||||
|
||||
QCoreApplication::setOrganizationName("MelkaJ");
|
||||
|
@ -23,10 +23,6 @@ add_library(AudioBookPlugin SHARED
|
||||
icons.qrc
|
||||
)
|
||||
|
||||
if(PDF4QT_ENABLE_OPENGL)
|
||||
target_link_libraries(AudioBookPlugin PRIVATE Qt6::OpenGLWidgets)
|
||||
endif()
|
||||
|
||||
target_link_libraries(AudioBookPlugin PRIVATE Pdf4QtLibCore Pdf4QtLibWidgets Qt6::Core Qt6::Gui Qt6::Widgets)
|
||||
|
||||
if(MINGW)
|
||||
|
@ -23,10 +23,6 @@ add_library(DimensionsPlugin SHARED
|
||||
icons.qrc
|
||||
)
|
||||
|
||||
if(PDF4QT_ENABLE_OPENGL)
|
||||
target_link_libraries(DimensionsPlugin PRIVATE Qt6::OpenGLWidgets)
|
||||
endif()
|
||||
|
||||
target_link_libraries(DimensionsPlugin PRIVATE Pdf4QtLibCore Pdf4QtLibWidgets Qt6::Core Qt6::Gui Qt6::Widgets)
|
||||
|
||||
set_target_properties(DimensionsPlugin PROPERTIES
|
||||
|
@ -29,10 +29,6 @@ add_library(ObjectInspectorPlugin SHARED
|
||||
icons.qrc
|
||||
)
|
||||
|
||||
if(PDF4QT_ENABLE_OPENGL)
|
||||
target_link_libraries(ObjectInspectorPlugin PRIVATE Qt6::OpenGLWidgets)
|
||||
endif()
|
||||
|
||||
target_link_libraries(ObjectInspectorPlugin PRIVATE Pdf4QtLibCore Pdf4QtLibWidgets Qt6::Core Qt6::Gui Qt6::Widgets)
|
||||
|
||||
set_target_properties(ObjectInspectorPlugin PROPERTIES
|
||||
|
@ -25,10 +25,6 @@ add_library(OutputPreviewPlugin SHARED
|
||||
icons.qrc
|
||||
)
|
||||
|
||||
if(PDF4QT_ENABLE_OPENGL)
|
||||
target_link_libraries(OutputPreviewPlugin PRIVATE Qt6::OpenGLWidgets)
|
||||
endif()
|
||||
|
||||
target_link_libraries(OutputPreviewPlugin PRIVATE Pdf4QtLibCore Pdf4QtLibWidgets Qt6::Core Qt6::Gui Qt6::Widgets)
|
||||
|
||||
set_target_properties(OutputPreviewPlugin PROPERTIES
|
||||
|
@ -22,10 +22,6 @@ add_library(RedactPlugin SHARED
|
||||
icons.qrc
|
||||
)
|
||||
|
||||
if(PDF4QT_ENABLE_OPENGL)
|
||||
target_link_libraries(RedactPlugin PRIVATE Qt6::OpenGLWidgets)
|
||||
endif()
|
||||
|
||||
target_link_libraries(RedactPlugin PRIVATE Pdf4QtLibCore Pdf4QtLibWidgets Qt6::Core Qt6::Gui Qt6::Widgets)
|
||||
|
||||
set_target_properties(RedactPlugin PROPERTIES
|
||||
|
@ -22,10 +22,6 @@ add_library(SignaturePlugin SHARED
|
||||
icons.qrc
|
||||
)
|
||||
|
||||
if(PDF4QT_ENABLE_OPENGL)
|
||||
target_link_libraries(SignaturePlugin PRIVATE Qt6::OpenGLWidgets)
|
||||
endif()
|
||||
|
||||
target_link_libraries(SignaturePlugin PRIVATE Pdf4QtLibCore Pdf4QtLibWidgets Qt6::Core Qt6::Gui Qt6::Widgets)
|
||||
target_link_libraries(SignaturePlugin PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
||||
|
||||
|
@ -22,10 +22,6 @@ add_library(SoftProofingPlugin SHARED
|
||||
icons.qrc
|
||||
)
|
||||
|
||||
if(PDF4QT_ENABLE_OPENGL)
|
||||
target_link_libraries(SoftProofingPlugin PRIVATE Qt6::OpenGLWidgets)
|
||||
endif()
|
||||
|
||||
target_link_libraries(SoftProofingPlugin PRIVATE Pdf4QtLibCore Pdf4QtLibWidgets Qt6::Core Qt6::Gui Qt6::Widgets)
|
||||
|
||||
set_target_properties(SoftProofingPlugin PROPERTIES
|
||||
|
@ -30,7 +30,6 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
|
||||
QApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents, true);
|
||||
QApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity, true);
|
||||
QApplication application(argc, argv);
|
||||
|
||||
QCoreApplication::setOrganizationName("MelkaJ");
|
||||
|
@ -24,7 +24,6 @@
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QGuiApplication a(argc, argv);
|
||||
QGuiApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity, true);
|
||||
QCoreApplication::setOrganizationName("MelkaJ");
|
||||
QCoreApplication::setApplicationName("PdfTool");
|
||||
QCoreApplication::setApplicationVersion(pdf::PDF_LIBRARY_VERSION);
|
||||
|
@ -847,12 +847,12 @@ PDFToolOptions PDFToolAbstractApplication::getOptions(QCommandLineParser* parser
|
||||
}
|
||||
}
|
||||
|
||||
QString textValue = parser->value("render-hw-accel");
|
||||
QString textValue = parser->value("render-software");
|
||||
bool ok = false;
|
||||
bool value = textValue.toInt(&ok);
|
||||
if (ok)
|
||||
{
|
||||
options.renderUseHardwareRendering = value;
|
||||
options.renderUseSoftwareRendering = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -135,7 +135,7 @@ struct PDFToolOptions
|
||||
|
||||
// For option 'RenderFlags'
|
||||
pdf::PDFRenderer::Features renderFeatures = pdf::PDFRenderer::getDefaultFeatures();
|
||||
bool renderUseHardwareRendering = true;
|
||||
bool renderUseSoftwareRendering = true;
|
||||
bool renderShowPageStatistics = false;
|
||||
int renderMSAAsamples = 4;
|
||||
int renderRasterizerCount = pdf::PDFRasterizerPool::getDefaultRasterizerCount();
|
||||
|
@ -180,21 +180,11 @@ int PDFToolRenderBase::execute(const PDFToolOptions& options)
|
||||
fontCache.setDocument(md);
|
||||
fontCache.setCacheShrinkEnabled(nullptr, false);
|
||||
|
||||
QSurfaceFormat surfaceFormat;
|
||||
if (options.renderUseHardwareRendering)
|
||||
{
|
||||
surfaceFormat = QSurfaceFormat::defaultFormat();
|
||||
surfaceFormat.setProfile(QSurfaceFormat::CoreProfile);
|
||||
surfaceFormat.setSamples(options.renderMSAAsamples);
|
||||
surfaceFormat.setColorSpace(QColorSpace(QColorSpace::SRgb));
|
||||
surfaceFormat.setSwapBehavior(QSurfaceFormat::DefaultSwapBehavior);
|
||||
}
|
||||
|
||||
m_pageInfo.resize(document.getCatalog()->getPageCount());
|
||||
pdf::PDFRasterizerPool rasterizerPool(&document, &fontCache, &cmsManager,
|
||||
&optionalContentActivity, options.renderFeatures, meshQualitySettings,
|
||||
pdf::PDFRasterizerPool::getCorrectedRasterizerCount(options.renderRasterizerCount),
|
||||
options.renderUseHardwareRendering, surfaceFormat, nullptr);
|
||||
options.renderUseSoftwareRendering ? pdf::RendererEngine::QPainter : pdf::RendererEngine::Blend2D_SingleThread, nullptr);
|
||||
|
||||
auto onRenderError = [this](pdf::PDFInteger pageIndex, pdf::PDFRenderError error)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "pdf4qt",
|
||||
"version-string": "1.3.6",
|
||||
"dependencies": [ "tbb", "openssl", "lcms", "zlib", "openjpeg", "freetype", "ijg-libjpeg", "libpng" ]
|
||||
"version-string": "1.3.7",
|
||||
"dependencies": [ "tbb", "openssl", "lcms", "zlib", "openjpeg", "freetype", "ijg-libjpeg", "libpng", "blend2d" ]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user