mirror of https://github.com/JakubMelka/PDF4QT.git
Mesh quality settings
This commit is contained in:
parent
9941438e99
commit
b09f9eff21
|
@ -65,6 +65,7 @@ SOURCES += \
|
|||
|
||||
HEADERS += \
|
||||
sources/pdfitemmodels.h \
|
||||
sources/pdfmeshqualitysettings.h \
|
||||
sources/pdfobject.h \
|
||||
sources/pdfoptionalcontent.h \
|
||||
sources/pdfparser.h \
|
||||
|
|
|
@ -552,7 +552,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(), m_features);
|
||||
PDFRenderer renderer(m_controller->getDocument(), m_controller->getFontCache(), m_controller->getOptionalContentActivity(), m_features, m_meshQualitySettings);
|
||||
QList<PDFRenderError> errors = renderer.render(painter, placedRect, item.pageIndex);
|
||||
|
||||
if (!errors.empty())
|
||||
|
@ -827,4 +827,31 @@ void PDFDrawWidgetProxy::setFeatures(PDFRenderer::Features features)
|
|||
}
|
||||
}
|
||||
|
||||
void PDFDrawWidgetProxy::setPreferredMeshResolutionRatio(PDFReal ratio)
|
||||
{
|
||||
if (m_meshQualitySettings.preferredMeshResolutionRatio != ratio)
|
||||
{
|
||||
m_meshQualitySettings.preferredMeshResolutionRatio = ratio;
|
||||
emit repaintNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFDrawWidgetProxy::setMinimalMeshResolutionRatio(PDFReal ratio)
|
||||
{
|
||||
if (m_meshQualitySettings.minimalMeshResolutionRatio != ratio)
|
||||
{
|
||||
m_meshQualitySettings.minimalMeshResolutionRatio = ratio;
|
||||
emit repaintNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFDrawWidgetProxy::setColorTolerance(PDFReal colorTolerance)
|
||||
{
|
||||
if (m_meshQualitySettings.tolerance != colorTolerance)
|
||||
{
|
||||
m_meshQualitySettings.tolerance = colorTolerance;
|
||||
emit repaintNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pdf
|
||||
|
|
|
@ -215,6 +215,9 @@ public:
|
|||
|
||||
PDFRenderer::Features getFeatures() const;
|
||||
void setFeatures(PDFRenderer::Features features);
|
||||
void setPreferredMeshResolutionRatio(PDFReal ratio);
|
||||
void setMinimalMeshResolutionRatio(PDFReal ratio);
|
||||
void setColorTolerance(PDFReal colorTolerance);
|
||||
|
||||
signals:
|
||||
void drawSpaceChanged();
|
||||
|
@ -332,6 +335,9 @@ private:
|
|||
|
||||
/// Renderer features
|
||||
PDFRenderer::Features m_features;
|
||||
|
||||
/// Mesh quality settings
|
||||
PDFMeshQualitySettings m_meshQualitySettings;
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
// Copyright (C) 2019 Jakub Melka
|
||||
//
|
||||
// This file is part of PdfForQt.
|
||||
//
|
||||
// PdfForQt 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
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// PdfForQt 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 PDFForQt. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef PDFMESHQUALITYSETTINGS_H
|
||||
#define PDFMESHQUALITYSETTINGS_H
|
||||
|
||||
#include "pdfglobal.h"
|
||||
|
||||
#include <QMatrix>
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
|
||||
struct PDFMeshQualitySettings
|
||||
{
|
||||
/// Initializes default resolution
|
||||
void initResolution();
|
||||
|
||||
/// Value used to compute minimal pxiel size resolution (it is multiplied by whole shading area size)
|
||||
PDFReal minimalMeshResolutionRatio = 0.005;
|
||||
|
||||
/// Value used to compute pixel size resolution (it is multiplied by whole shading area size)
|
||||
PDFReal preferredMeshResolutionRatio = 0.02;
|
||||
|
||||
/// Matrix, which transforms user space points (user space is target space of the shading)
|
||||
/// to the device space of the paint device.
|
||||
QMatrix userSpaceToDeviceSpaceMatrix;
|
||||
|
||||
/// Rectangle in device space coordinate system, onto which is area meshed.
|
||||
QRectF deviceSpaceMeshingArea;
|
||||
|
||||
/// Preferred mesh resolution in device space pixels. Mesh will be created in this
|
||||
/// resolution, if it is smooth enough (no jumps in colors occurs).
|
||||
PDFReal preferredMeshResolution = 1.0;
|
||||
|
||||
/// Minimal mesh resolution in device space pixels. If jumps in colors occurs (jump
|
||||
/// is two colors, that differ more than \p color tolerance), then mesh is meshed to
|
||||
/// minimal mesh resolution.
|
||||
PDFReal minimalMeshResolution = 1.0;
|
||||
|
||||
/// Color tolerance - 1% by default
|
||||
PDFReal tolerance = 0.01;
|
||||
|
||||
/// Test points to determine maximal curvature of the tensor product patch meshes
|
||||
PDFInteger patchTestPoints = 64;
|
||||
|
||||
/// Lower value of the surface curvature meshing resolution mapping. When ratio between
|
||||
/// current curvature at the center of meshed triangle and maximal curvature is below
|
||||
/// this value, then prefered mesh resolution is used. If ratio is higher than this value
|
||||
/// and lower than \p patchResolutionMappingRatioHigh, then target length is linearly mapped.
|
||||
/// If value is higher, than \p patchResolutionMappingRatioHigh, then minimal mesh resolution
|
||||
/// is used when generating triangles on the patch.
|
||||
PDFReal patchResolutionMappingRatioLow = 0.3;
|
||||
|
||||
/// Highter value of the surface curvature meshing resolution mapping. \sa patchResolutionMappingRatioLow
|
||||
PDFReal patchResolutionMappingRatioHigh = 0.9;
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
||||
#endif // PDFMESHQUALITYSETTINGS_H
|
|
@ -184,7 +184,8 @@ PDFPageContentProcessor::PDFPageContentProcessor(const PDFPage* page,
|
|||
const PDFDocument* document,
|
||||
const PDFFontCache* fontCache,
|
||||
const PDFOptionalContentActivity* optionalContentActivity,
|
||||
QMatrix pagePointToDevicePointMatrix) :
|
||||
QMatrix pagePointToDevicePointMatrix,
|
||||
const PDFMeshQualitySettings& meshQualitySettings) :
|
||||
m_page(page),
|
||||
m_document(document),
|
||||
m_fontCache(fontCache),
|
||||
|
@ -201,7 +202,8 @@ PDFPageContentProcessor::PDFPageContentProcessor(const PDFPage* page,
|
|||
m_drawingUncoloredTilingPatternState(0),
|
||||
m_isWarningColorOperatorsInUncoloredTilingPatternReported(false),
|
||||
m_patternBaseMatrix(pagePointToDevicePointMatrix),
|
||||
m_pagePointToDevicePointMatrix(pagePointToDevicePointMatrix)
|
||||
m_pagePointToDevicePointMatrix(pagePointToDevicePointMatrix),
|
||||
m_meshQualitySettings(meshQualitySettings)
|
||||
{
|
||||
Q_ASSERT(page);
|
||||
Q_ASSERT(document);
|
||||
|
@ -628,10 +630,10 @@ void PDFPageContentProcessor::processPathPainting(const QPainterPath& path, bool
|
|||
}
|
||||
|
||||
// We must create a mesh and then draw pattern
|
||||
PDFMeshQualitySettings settings;
|
||||
PDFMeshQualitySettings settings = m_meshQualitySettings;
|
||||
settings.deviceSpaceMeshingArea = getPageBoundingRectDeviceSpace();
|
||||
settings.userSpaceToDeviceSpaceMatrix = getPatternBaseMatrix();
|
||||
settings.initDefaultResolution();
|
||||
settings.initResolution();
|
||||
|
||||
PDFMesh mesh = shadingPattern->createMesh(settings);
|
||||
|
||||
|
@ -717,10 +719,10 @@ void PDFPageContentProcessor::processPathPainting(const QPainterPath& path, bool
|
|||
}
|
||||
|
||||
// We must create a mesh and then draw pattern
|
||||
PDFMeshQualitySettings settings;
|
||||
PDFMeshQualitySettings settings = m_meshQualitySettings;
|
||||
settings.deviceSpaceMeshingArea = getPageBoundingRectDeviceSpace();
|
||||
settings.userSpaceToDeviceSpaceMatrix = getPatternBaseMatrix();
|
||||
settings.initDefaultResolution();
|
||||
settings.initResolution();
|
||||
|
||||
PDFMesh mesh = shadingPattern->createMesh(settings);
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "pdfparser.h"
|
||||
#include "pdffont.h"
|
||||
#include "pdfutils.h"
|
||||
#include "pdfmeshqualitysettings.h"
|
||||
|
||||
#include <QMatrix>
|
||||
#include <QPainterPath>
|
||||
|
@ -48,7 +49,8 @@ public:
|
|||
const PDFDocument* document,
|
||||
const PDFFontCache* fontCache,
|
||||
const PDFOptionalContentActivity* optionalContentActivity,
|
||||
QMatrix pagePointToDevicePointMatrix);
|
||||
QMatrix pagePointToDevicePointMatrix,
|
||||
const PDFMeshQualitySettings& meshQualitySettings);
|
||||
virtual ~PDFPageContentProcessor();
|
||||
|
||||
enum class Operator
|
||||
|
@ -814,6 +816,9 @@ private:
|
|||
/// Bounding rectangle of pages media box in device space coordinates. If drawing rotation
|
||||
/// is zero, then it corresponds to the scaled media box of the page.
|
||||
QRectF m_pageBoundingRectDeviceSpace;
|
||||
|
||||
/// Mesh quality settings
|
||||
PDFMeshQualitySettings m_meshQualitySettings;
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
|
|
@ -29,8 +29,9 @@ PDFPainter::PDFPainter(QPainter* painter,
|
|||
const PDFPage* page,
|
||||
const PDFDocument* document,
|
||||
const PDFFontCache* fontCache,
|
||||
const PDFOptionalContentActivity* optionalContentActivity) :
|
||||
PDFPageContentProcessor(page, document, fontCache, optionalContentActivity, pagePointToDevicePointMatrix),
|
||||
const PDFOptionalContentActivity* optionalContentActivity,
|
||||
const PDFMeshQualitySettings& meshQualitySettings) :
|
||||
PDFPageContentProcessor(page, document, fontCache, optionalContentActivity, pagePointToDevicePointMatrix, meshQualitySettings),
|
||||
m_painter(painter),
|
||||
m_features(features)
|
||||
{
|
||||
|
|
|
@ -41,13 +41,15 @@ public:
|
|||
/// \param document Document owning the page
|
||||
/// \param fontCache Font cache
|
||||
/// \param optionalContentActivity Activity of optional content
|
||||
/// \param meshQualitySettings Mesh quality settings
|
||||
explicit PDFPainter(QPainter* painter,
|
||||
PDFRenderer::Features features,
|
||||
QMatrix pagePointToDevicePointMatrix,
|
||||
const PDFPage* page,
|
||||
const PDFDocument* document,
|
||||
const PDFFontCache* fontCache,
|
||||
const PDFOptionalContentActivity* optionalContentActivity);
|
||||
const PDFOptionalContentActivity* optionalContentActivity,
|
||||
const PDFMeshQualitySettings& meshQualitySettings);
|
||||
virtual ~PDFPainter() override;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -903,7 +903,7 @@ PDFMesh PDFAxialShading::createMesh(const PDFMeshQualitySettings& settings) cons
|
|||
{
|
||||
// We will skip this coordinate, if both of meshing criteria have been met:
|
||||
// 1) Color difference is small (lesser than tolerance)
|
||||
// 2) Distance from previous and next point is less than preffered meshing resolution OR colors are equal
|
||||
// 2) Distance from previous and next point is less than preferred meshing resolution OR colors are equal
|
||||
|
||||
if (it != coloredCoordinates.cbegin() && std::next(it) != coloredCoordinates.cend())
|
||||
{
|
||||
|
@ -1083,15 +1083,12 @@ QPointF PDFMesh::getTriangleCenter(const PDFMesh::Triangle& triangle) const
|
|||
return (m_vertices[triangle.v1] + m_vertices[triangle.v2] + m_vertices[triangle.v3]) / 3.0;
|
||||
}
|
||||
|
||||
void PDFMeshQualitySettings::initDefaultResolution()
|
||||
void PDFMeshQualitySettings::initResolution()
|
||||
{
|
||||
// We will take 0.5% percent of device space meshing area as minimal resolution (it is ~1.5 mm for
|
||||
// A4 page) and default resolution 4x number of that.
|
||||
|
||||
Q_ASSERT(deviceSpaceMeshingArea.isValid());
|
||||
PDFReal size = qMax(deviceSpaceMeshingArea.width(), deviceSpaceMeshingArea.height());
|
||||
minimalMeshResolution = size * 0.005;
|
||||
preferredMeshResolution = minimalMeshResolution * 4;
|
||||
minimalMeshResolution = size * minimalMeshResolutionRatio;
|
||||
preferredMeshResolution = size * qMax(preferredMeshResolutionRatio, minimalMeshResolutionRatio);
|
||||
}
|
||||
|
||||
ShadingType PDFRadialShading::getShadingType() const
|
||||
|
@ -1272,7 +1269,7 @@ PDFMesh PDFRadialShading::createMesh(const PDFMeshQualitySettings& settings) con
|
|||
{
|
||||
// We will skip this coordinate, if both of meshing criteria have been met:
|
||||
// 1) Color difference is small (lesser than tolerance)
|
||||
// 2) Distance from previous and next point is less than preffered meshing resolution OR colors are equal
|
||||
// 2) Distance from previous and next point is less than preferred meshing resolution OR colors are equal
|
||||
|
||||
if (it != coloredCoordinates.cbegin() && std::next(it) != coloredCoordinates.cend())
|
||||
{
|
||||
|
@ -2610,6 +2607,4 @@ PDFMesh PDFCoonsPatchShading::createMesh(const PDFMeshQualitySettings& settings)
|
|||
return mesh;
|
||||
}
|
||||
|
||||
// TODO: Implement settings of meshing in the settings dialog
|
||||
|
||||
} // namespace pdf
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "pdfobject.h"
|
||||
#include "pdffunction.h"
|
||||
#include "pdfcolorspaces.h"
|
||||
#include "pdfmeshqualitysettings.h"
|
||||
|
||||
#include <QMatrix>
|
||||
|
||||
|
@ -53,45 +54,6 @@ enum class ShadingType
|
|||
TensorProductPatchMesh = 7
|
||||
};
|
||||
|
||||
struct PDFMeshQualitySettings
|
||||
{
|
||||
/// Initializes default resolution
|
||||
void initDefaultResolution();
|
||||
|
||||
/// Matrix, which transforms user space points (user space is target space of the shading)
|
||||
/// to the device space of the paint device.
|
||||
QMatrix userSpaceToDeviceSpaceMatrix;
|
||||
|
||||
/// Rectangle in device space coordinate system, onto which is area meshed.
|
||||
QRectF deviceSpaceMeshingArea;
|
||||
|
||||
/// Preferred mesh resolution in device space pixels. Mesh will be created in this
|
||||
/// resolution, if it is smooth enough (no jumps in colors occurs).
|
||||
PDFReal preferredMeshResolution = 1.0;
|
||||
|
||||
/// Minimal mesh resolution in device space pixels. If jumps in colors occurs (jump
|
||||
/// is two colors, that differ more than \p color tolerance), then mesh is meshed to
|
||||
/// minimal mesh resolution.
|
||||
PDFReal minimalMeshResolution = 1.0;
|
||||
|
||||
/// Color tolerance - 1% by default
|
||||
PDFReal tolerance = 0.01;
|
||||
|
||||
/// Test points to determine maximal curvature of the tensor product patch meshes
|
||||
PDFInteger patchTestPoints = 64;
|
||||
|
||||
/// Lower value of the surface curvature meshing resolution mapping. When ratio between
|
||||
/// current curvature at the center of meshed triangle and maximal curvature is below
|
||||
/// this value, then prefered mesh resolution is used. If ratio is higher than this value
|
||||
/// and lower than \p patchResolutionMappingRatioHigh, then target length is linearly mapped.
|
||||
/// If value is higher, than \p patchResolutionMappingRatioHigh, then minimal mesh resolution
|
||||
/// is used when generating triangles on the patch.
|
||||
PDFReal patchResolutionMappingRatioLow = 0.3;
|
||||
|
||||
/// Highter value of the surface curvature meshing resolution mapping. \sa patchResolutionMappingRatioLow
|
||||
PDFReal patchResolutionMappingRatioHigh = 0.9;
|
||||
};
|
||||
|
||||
/// Mesh consisting of triangles
|
||||
class PDFMesh
|
||||
{
|
||||
|
|
|
@ -22,11 +22,16 @@
|
|||
namespace pdf
|
||||
{
|
||||
|
||||
PDFRenderer::PDFRenderer(const PDFDocument* document, const PDFFontCache* fontCache, const PDFOptionalContentActivity* optionalContentActivity, Features features) :
|
||||
PDFRenderer::PDFRenderer(const PDFDocument* document,
|
||||
const PDFFontCache* fontCache,
|
||||
const PDFOptionalContentActivity* optionalContentActivity,
|
||||
Features features,
|
||||
const PDFMeshQualitySettings& meshQualitySettings) :
|
||||
m_document(document),
|
||||
m_fontCache(fontCache),
|
||||
m_optionalContentActivity(optionalContentActivity),
|
||||
m_features(features)
|
||||
m_features(features),
|
||||
m_meshQualitySettings(meshQualitySettings)
|
||||
{
|
||||
Q_ASSERT(document);
|
||||
}
|
||||
|
@ -88,7 +93,7 @@ QList<PDFRenderError> PDFRenderer::render(QPainter* painter, const QRectF& recta
|
|||
}
|
||||
}
|
||||
|
||||
PDFPainter processor(painter, m_features, matrix, page, m_document, m_fontCache, m_optionalContentActivity);
|
||||
PDFPainter processor(painter, m_features, matrix, page, m_document, m_fontCache, m_optionalContentActivity, m_meshQualitySettings);
|
||||
return processor.processContents();
|
||||
}
|
||||
|
||||
|
@ -106,7 +111,7 @@ QList<PDFRenderError> PDFRenderer::render(QPainter* painter, const QMatrix& matr
|
|||
const PDFPage* page = catalog->getPage(pageIndex);
|
||||
Q_ASSERT(page);
|
||||
|
||||
PDFPainter processor(painter, m_features, matrix, page, m_document, m_fontCache, m_optionalContentActivity);
|
||||
PDFPainter processor(painter, m_features, matrix, page, m_document, m_fontCache, m_optionalContentActivity, m_meshQualitySettings);
|
||||
return processor.processContents();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "pdfpage.h"
|
||||
#include "pdfexception.h"
|
||||
#include "pdfmeshqualitysettings.h"
|
||||
|
||||
class QPainter;
|
||||
|
||||
|
@ -44,7 +45,7 @@ public:
|
|||
|
||||
Q_DECLARE_FLAGS(Features, Feature)
|
||||
|
||||
explicit PDFRenderer(const PDFDocument* document, const PDFFontCache* fontCache, const PDFOptionalContentActivity* optionalContentActivity, Features features);
|
||||
explicit PDFRenderer(const PDFDocument* document, const PDFFontCache* fontCache, const PDFOptionalContentActivity* optionalContentActivity, Features features, const PDFMeshQualitySettings& meshQualitySettings);
|
||||
|
||||
/// 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
|
||||
|
@ -67,6 +68,7 @@ private:
|
|||
const PDFFontCache* m_fontCache;
|
||||
const PDFOptionalContentActivity* m_optionalContentActivity;
|
||||
Features m_features;
|
||||
PDFMeshQualitySettings m_meshQualitySettings;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -255,6 +255,9 @@ void PDFViewerMainWindow::onViewerSettingsChanged()
|
|||
{
|
||||
m_pdfWidget->updateRenderer(m_settings->getRendererEngine(), m_settings->isMultisampleAntialiasingEnabled() ? m_settings->getRendererSamples() : -1);
|
||||
m_pdfWidget->getDrawWidgetProxy()->setFeatures(m_settings->getFeatures());
|
||||
m_pdfWidget->getDrawWidgetProxy()->setPreferredMeshResolutionRatio(m_settings->getPreferredMeshResolutionRatio());
|
||||
m_pdfWidget->getDrawWidgetProxy()->setMinimalMeshResolutionRatio(m_settings->getMinimalMeshResolutionRatio());
|
||||
m_pdfWidget->getDrawWidgetProxy()->setColorTolerance(m_settings->getColorTolerance());
|
||||
updateRenderingOptionActions();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,12 +11,17 @@ void PDFViewerSettings::setSettings(const PDFViewerSettings::Settings& settings)
|
|||
|
||||
void PDFViewerSettings::readSettings(QSettings& settings)
|
||||
{
|
||||
Settings defaultSettings;
|
||||
|
||||
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("rendererFeatures", 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", true).toBool();
|
||||
m_settings.m_rendererSamples = settings.value("rendererSamples", 16).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_preferredMeshResolutionRatio = settings.value("preferredMeshResolutionRatio", defaultSettings.m_preferredMeshResolutionRatio).toDouble();
|
||||
m_settings.m_minimalMeshResolutionRatio = settings.value("minimalMeshResolutionRatio", defaultSettings.m_minimalMeshResolutionRatio).toDouble();
|
||||
m_settings.m_colorTolerance = settings.value("colorTolerance", defaultSettings.m_colorTolerance).toDouble();
|
||||
settings.endGroup();
|
||||
|
||||
emit settingsChanged();
|
||||
|
@ -30,6 +35,9 @@ void PDFViewerSettings::writeSettings(QSettings& settings)
|
|||
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("preferredMeshResolutionRatio", m_settings.m_preferredMeshResolutionRatio);
|
||||
settings.setValue("minimalMeshResolutionRatio", m_settings.m_minimalMeshResolutionRatio);
|
||||
settings.setValue("colorTolerance", m_settings.m_colorTolerance);
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
|
@ -89,4 +97,31 @@ void PDFViewerSettings::setRendererSamples(int rendererSamples)
|
|||
}
|
||||
}
|
||||
|
||||
void PDFViewerSettings::setPreferredMeshResolutionRatio(pdf::PDFReal preferredMeshResolutionRatio)
|
||||
{
|
||||
if (m_settings.m_preferredMeshResolutionRatio != preferredMeshResolutionRatio)
|
||||
{
|
||||
m_settings.m_preferredMeshResolutionRatio = preferredMeshResolutionRatio;
|
||||
emit settingsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFViewerSettings::setMinimalMeshResolutionRatio(pdf::PDFReal minimalMeshResolutionRatio)
|
||||
{
|
||||
if (m_settings.m_minimalMeshResolutionRatio != minimalMeshResolutionRatio)
|
||||
{
|
||||
m_settings.m_minimalMeshResolutionRatio = minimalMeshResolutionRatio;
|
||||
emit settingsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFViewerSettings::setColorTolerance(pdf::PDFReal colorTolerance)
|
||||
{
|
||||
if (m_settings.m_colorTolerance != colorTolerance)
|
||||
{
|
||||
m_settings.m_colorTolerance = colorTolerance;
|
||||
emit settingsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pdfviewer
|
||||
|
|
|
@ -25,7 +25,10 @@ public:
|
|||
m_features(pdf::PDFRenderer::getDefaultFeatures()),
|
||||
m_rendererEngine(pdf::RendererEngine::OpenGL),
|
||||
m_multisampleAntialiasing(true),
|
||||
m_rendererSamples(16)
|
||||
m_rendererSamples(16),
|
||||
m_preferredMeshResolutionRatio(0.02),
|
||||
m_minimalMeshResolutionRatio(0.005),
|
||||
m_colorTolerance(0.01)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -35,6 +38,9 @@ public:
|
|||
pdf::RendererEngine m_rendererEngine;
|
||||
bool m_multisampleAntialiasing;
|
||||
int m_rendererSamples;
|
||||
pdf::PDFReal m_preferredMeshResolutionRatio;
|
||||
pdf::PDFReal m_minimalMeshResolutionRatio;
|
||||
pdf::PDFReal m_colorTolerance;
|
||||
};
|
||||
|
||||
const Settings& getSettings() const { return m_settings; }
|
||||
|
@ -57,6 +63,15 @@ public:
|
|||
|
||||
bool isMultisampleAntialiasingEnabled() const { return m_settings.m_multisampleAntialiasing; }
|
||||
|
||||
pdf::PDFReal getPreferredMeshResolutionRatio() const { return m_settings.m_preferredMeshResolutionRatio; }
|
||||
void setPreferredMeshResolutionRatio(pdf::PDFReal preferredMeshResolutionRatio);
|
||||
|
||||
pdf::PDFReal getMinimalMeshResolutionRatio() const { return m_settings.m_minimalMeshResolutionRatio; }
|
||||
void setMinimalMeshResolutionRatio(pdf::PDFReal minimalMeshResolutionRatio);
|
||||
|
||||
pdf::PDFReal getColorTolerance() const { return m_settings.m_colorTolerance; }
|
||||
void setColorTolerance(pdf::PDFReal colorTolerance);
|
||||
|
||||
signals:
|
||||
void settingsChanged();
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "pdfglobal.h"
|
||||
#include "pdfutils.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QListWidgetItem>
|
||||
|
||||
namespace pdfviewer
|
||||
|
@ -42,6 +43,10 @@ PDFViewerSettingsDialog::PDFViewerSettingsDialog(const PDFViewerSettings::Settin
|
|||
{
|
||||
connect(comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PDFViewerSettingsDialog::saveData);
|
||||
}
|
||||
for (QDoubleSpinBox* spinBox : { ui->preferredMeshResolutionEdit, ui->minimalMeshResolutionEdit, ui->colorToleranceEdit })
|
||||
{
|
||||
connect(spinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &PDFViewerSettingsDialog::saveData);
|
||||
}
|
||||
|
||||
ui->optionsPagesWidget->setCurrentRow(0);
|
||||
adjustSize();
|
||||
|
@ -82,6 +87,7 @@ void PDFViewerSettingsDialog::loadData()
|
|||
pdf::PDFTemporaryValueChange guard(&m_isLoadingData, true);
|
||||
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);
|
||||
|
@ -106,11 +112,17 @@ void PDFViewerSettingsDialog::loadData()
|
|||
ui->multisampleAntialiasingSamplesCountComboBox->setCurrentIndex(-1);
|
||||
}
|
||||
|
||||
// Rendering
|
||||
ui->antialiasingCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::Antialiasing));
|
||||
ui->textAntialiasingCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::TextAntialiasing));
|
||||
ui->smoothPicturesCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::SmoothImages));
|
||||
ui->ignoreOptionalContentCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::IgnoreOptionalContent));
|
||||
ui->clipToCropBoxCheckBox->setChecked(m_settings.m_features.testFlag(pdf::PDFRenderer::ClipToCropBox));
|
||||
|
||||
// Shading
|
||||
ui->preferredMeshResolutionEdit->setValue(m_settings.m_preferredMeshResolutionRatio);
|
||||
ui->minimalMeshResolutionEdit->setValue(m_settings.m_minimalMeshResolutionRatio);
|
||||
ui->colorToleranceEdit->setValue(m_settings.m_colorTolerance);
|
||||
}
|
||||
|
||||
void PDFViewerSettingsDialog::saveData()
|
||||
|
@ -154,6 +166,18 @@ void PDFViewerSettingsDialog::saveData()
|
|||
{
|
||||
m_settings.m_features.setFlag(pdf::PDFRenderer::ClipToCropBox, ui->clipToCropBoxCheckBox->isChecked());
|
||||
}
|
||||
else if (sender == ui->preferredMeshResolutionEdit)
|
||||
{
|
||||
m_settings.m_preferredMeshResolutionRatio = ui->preferredMeshResolutionEdit->value();
|
||||
}
|
||||
else if (sender == ui->minimalMeshResolutionEdit)
|
||||
{
|
||||
m_settings.m_minimalMeshResolutionRatio = ui->minimalMeshResolutionEdit->value();
|
||||
}
|
||||
else if (sender == ui->colorToleranceEdit)
|
||||
{
|
||||
m_settings.m_colorTolerance = ui->colorToleranceEdit->value();
|
||||
}
|
||||
|
||||
loadData();
|
||||
}
|
||||
|
|
|
@ -255,6 +255,113 @@
|
|||
<property name="title">
|
||||
<string>Shading Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="preferredMeshResolutionLabel">
|
||||
<property name="text">
|
||||
<string>Preferred mesh resolution ratio</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="colorToleranceLabel">
|
||||
<property name="text">
|
||||
<string>Color tolerance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="minimalMeshResolutionLabel">
|
||||
<property name="text">
|
||||
<string>Minimal mesh resolution ratio</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDoubleSpinBox" name="preferredMeshResolutionEdit">
|
||||
<property name="correctionMode">
|
||||
<enum>QAbstractSpinBox::CorrectToNearestValue</enum>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.001000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="minimalMeshResolutionEdit">
|
||||
<property name="correctionMode">
|
||||
<enum>QAbstractSpinBox::CorrectToNearestValue</enum>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.001000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="colorToleranceEdit">
|
||||
<property name="correctionMode">
|
||||
<enum>QAbstractSpinBox::CorrectToNearestValue</enum>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.001000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="shadingInfoLabel">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>Shading is meshed according the mesh quality criteria. It involves <span style=" font-weight:600;">color tolerance</span> and shape tolerance. If color of vertices of triangle in the mesh is too different (it differs more than color tolerance) then mesh is refined and triangle is subdivided. Some shadings are defined by patterns (such as <span style=" font-style:italic;">Coons patch shading </span>or <span style=" font-style:italic;">Tensor product patch shading</span>), which is also considered in meshing.</p><p><span style=" font-weight:600;">Preferred mesh resolution ratio</span> should be set to optimal balance between performance of mesh generation and quality of the mesh. Optimal triangle size will be computed in the following way: total meshing area (typically a page) will be multiplied with this ratio and that will determine the triangle size. So, if we have A4 page (210 mm x 297mm), and ratio is set to 0,01, then we will get optimal triangle size as 297 * 0.01 = ~3mm.</p><p><span style=" font-weight:600;">Minimal mesh resolution ratio</span> is ratio, which will determine triangle minimal size. At this bound, no triangles are subdivided, even if color is different or shape is not good. This should be set to a value, at which user barely can recognize patterns on the screen (for example, the size of triangle should be &lt; 1mm). But it also affect performance, because too much triangles can be generated.</p><p><span style=" font-weight:600;">Color tolerance</span> is threshold, at which is two colors recognized as different. The comparation is done component-wise, so if at least one of color components is greater than this parameter, then colors are treated as different.</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="shadingVerticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>91</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
Loading…
Reference in New Issue