mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-04-16 19:27:24 +02:00
Color management system - base classes + settings
This commit is contained in:
parent
aae6c56a5f
commit
0470c4bc1d
@ -39,6 +39,7 @@ SOURCES += \
|
|||||||
sources/pdfaction.cpp \
|
sources/pdfaction.cpp \
|
||||||
sources/pdfblendfunction.cpp \
|
sources/pdfblendfunction.cpp \
|
||||||
sources/pdfccittfaxdecoder.cpp \
|
sources/pdfccittfaxdecoder.cpp \
|
||||||
|
sources/pdfcms.cpp \
|
||||||
sources/pdfcompiler.cpp \
|
sources/pdfcompiler.cpp \
|
||||||
sources/pdffile.cpp \
|
sources/pdffile.cpp \
|
||||||
sources/pdfitemmodels.cpp \
|
sources/pdfitemmodels.cpp \
|
||||||
@ -77,6 +78,7 @@ HEADERS += \
|
|||||||
sources/pdfaction.h \
|
sources/pdfaction.h \
|
||||||
sources/pdfblendfunction.h \
|
sources/pdfblendfunction.h \
|
||||||
sources/pdfccittfaxdecoder.h \
|
sources/pdfccittfaxdecoder.h \
|
||||||
|
sources/pdfcms.h \
|
||||||
sources/pdfcompiler.h \
|
sources/pdfcompiler.h \
|
||||||
sources/pdffile.h \
|
sources/pdffile.h \
|
||||||
sources/pdfitemmodels.h \
|
sources/pdfitemmodels.h \
|
||||||
@ -174,6 +176,16 @@ zlib.files = $$PDFFORQT_DEPENDENCIES_PATH/zlib/bin/zlib.dll
|
|||||||
zlib.path = $$DESTDIR/install
|
zlib.path = $$DESTDIR/install
|
||||||
INSTALLS += zlib
|
INSTALLS += zlib
|
||||||
|
|
||||||
|
# Link lcms2
|
||||||
|
LIBS += -L$$PDFFORQT_DEPENDENCIES_PATH/lcms2/bin/ -llcms2
|
||||||
|
INCLUDEPATH += $$PDFFORQT_DEPENDENCIES_PATH/lcms2/include
|
||||||
|
DEPENDPATH += $$PDFFORQT_DEPENDENCIES_PATH/lcms2/include
|
||||||
|
|
||||||
|
# Add lcms2 to installations
|
||||||
|
lcms2.files = $$PDFFORQT_DEPENDENCIES_PATH/lcms2/bin/lcms2.dll
|
||||||
|
lcms2.path = $$DESTDIR/install
|
||||||
|
INSTALLS += lcms2
|
||||||
|
|
||||||
# ensure debug info even for RELEASE build
|
# ensure debug info even for RELEASE build
|
||||||
CONFIG += force_debug_info
|
CONFIG += force_debug_info
|
||||||
|
|
||||||
|
219
PdfForQtLib/sources/pdfcms.cpp
Normal file
219
PdfForQtLib/sources/pdfcms.cpp
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
|
#include "pdfcms.h"
|
||||||
|
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:5033)
|
||||||
|
#include <lcms2.h>
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
namespace pdf
|
||||||
|
{
|
||||||
|
|
||||||
|
bool PDFCMSGeneric::isCompatible(const PDFCMSSettings& settings) const
|
||||||
|
{
|
||||||
|
return settings.system == PDFCMSSettings::System::Generic;
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor PDFCMSGeneric::getColorFromDeviceGray(const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(color);
|
||||||
|
Q_UNUSED(intent);
|
||||||
|
Q_UNUSED(reporter);
|
||||||
|
return QColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor PDFCMSGeneric::getColorFromDeviceRGB(const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(color);
|
||||||
|
Q_UNUSED(intent);
|
||||||
|
Q_UNUSED(reporter);
|
||||||
|
return QColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor PDFCMSGeneric::getColorFromDeviceCMYK(const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(color);
|
||||||
|
Q_UNUSED(intent);
|
||||||
|
Q_UNUSED(reporter);
|
||||||
|
return QColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor PDFCMSGeneric::getColorFromXYZ(const PDFColor3& whitePoint, const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(color);
|
||||||
|
Q_UNUSED(intent);
|
||||||
|
Q_UNUSED(reporter);
|
||||||
|
Q_UNUSED(whitePoint);
|
||||||
|
return QColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFCMSManager::PDFCMSManager(QObject* parent) :
|
||||||
|
BaseClass(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const PDFColorSpaceIdentifiers& PDFCMSManager::getOutputProfiles() const
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&m_mutex);
|
||||||
|
return m_outputProfiles.get(this, &PDFCMSManager::getOutputProfilesImpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
const PDFColorSpaceIdentifiers& PDFCMSManager::getGrayProfiles() const
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&m_mutex);
|
||||||
|
return m_grayProfiles.get(this, &PDFCMSManager::getGrayProfilesImpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
const PDFColorSpaceIdentifiers& PDFCMSManager::getRGBProfiles() const
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&m_mutex);
|
||||||
|
return m_RGBProfiles.get(this, &PDFCMSManager::getRGBProfilesImpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
const PDFColorSpaceIdentifiers& PDFCMSManager::getCMYKProfiles() const
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&m_mutex);
|
||||||
|
return m_CMYKProfiles.get(this, &PDFCMSManager::getCMYKProfilesImpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFCMSSettings PDFCMSManager::getDefaultSettings() const
|
||||||
|
{
|
||||||
|
PDFCMSSettings settings;
|
||||||
|
|
||||||
|
auto getFirstProfileId = [](const PDFColorSpaceIdentifiers& identifiers)
|
||||||
|
{
|
||||||
|
if (!identifiers.empty())
|
||||||
|
{
|
||||||
|
return identifiers.front().id;
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
};
|
||||||
|
|
||||||
|
settings.system = PDFCMSSettings::System::LittleCMS2;
|
||||||
|
settings.outputCS = getFirstProfileId(getOutputProfiles());
|
||||||
|
settings.deviceGray = getFirstProfileId(getGrayProfiles());
|
||||||
|
settings.deviceRGB = getFirstProfileId(getRGBProfiles());
|
||||||
|
settings.deviceCMYK = getFirstProfileId(getCMYKProfiles());
|
||||||
|
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PDFCMSManager::getSystemName(PDFCMSSettings::System system)
|
||||||
|
{
|
||||||
|
switch (system)
|
||||||
|
{
|
||||||
|
case PDFCMSSettings::System::Generic:
|
||||||
|
return tr("Generic");
|
||||||
|
|
||||||
|
case PDFCMSSettings::System::LittleCMS2:
|
||||||
|
{
|
||||||
|
const int major = LCMS_VERSION / 1000;
|
||||||
|
const int minor = (LCMS_VERSION % 1000) / 10;
|
||||||
|
return tr("Little CMS %1.%2").arg(major).arg(minor);
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
Q_ASSERT(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFColorSpaceIdentifiers PDFCMSManager::getOutputProfilesImpl() const
|
||||||
|
{
|
||||||
|
// Currently, we only support sRGB output color profile.
|
||||||
|
return { PDFColorSpaceIdentifier::createSRGB() };
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFColorSpaceIdentifiers PDFCMSManager::getGrayProfilesImpl() const
|
||||||
|
{
|
||||||
|
// Jakub Melka: We create gray profiles for temperature 5000K, 6500K and 9300K.
|
||||||
|
// We also use linear gamma and gamma value 2.2.
|
||||||
|
return {
|
||||||
|
PDFColorSpaceIdentifier::createGray(tr("Gray D65, γ = 2.2"), "@GENERIC_Gray_D65_g22", 6500.0, 2.2),
|
||||||
|
PDFColorSpaceIdentifier::createGray(tr("Gray D50, γ = 2.2"), "@GENERIC_Gray_D50_g22", 5000.0, 2.2),
|
||||||
|
PDFColorSpaceIdentifier::createGray(tr("Gray D93, γ = 2.2"), "@GENERIC_Gray_D93_g22", 9300.0, 2.2),
|
||||||
|
PDFColorSpaceIdentifier::createGray(tr("Gray D65, γ = 1.0 (linear)"), "@GENERIC_Gray_D65_g10", 6500.0, 1.0),
|
||||||
|
PDFColorSpaceIdentifier::createGray(tr("Gray D50, γ = 1.0 (linear)"), "@GENERIC_Gray_D50_g10", 5000.0, 1.0),
|
||||||
|
PDFColorSpaceIdentifier::createGray(tr("Gray D93, γ = 1.0 (linear)"), "@GENERIC_Gray_D93_g10", 9300.0, 1.0)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFColorSpaceIdentifiers PDFCMSManager::getRGBProfilesImpl() const
|
||||||
|
{
|
||||||
|
// Jakub Melka: We create RGB profiles for common standars and also for
|
||||||
|
// default standard sRGB. See https://en.wikipedia.org/wiki/Color_spaces_with_RGB_primaries.
|
||||||
|
return {
|
||||||
|
PDFColorSpaceIdentifier::createSRGB(),
|
||||||
|
PDFColorSpaceIdentifier::createRGB(tr("HDTV (ITU-R BT.709)"), "@GENERIC_RGB_HDTV", 6500, QPointF(0.64, 0.33), QPointF(0.30, 0.60), QPointF(0.15, 0.06), 20.0 / 9.0),
|
||||||
|
PDFColorSpaceIdentifier::createRGB(tr("Adobe RGB 1998"), "@GENERIC_RGB_Adobe1998", 6500, QPointF(0.64, 0.33), QPointF(0.30, 0.60), QPointF(0.15, 0.06), 563.0 / 256.0),
|
||||||
|
PDFColorSpaceIdentifier::createRGB(tr("PAL / SECAM"), "@GENERIC_RGB_PalSecam", 6500, QPointF(0.64, 0.33), QPointF(0.29, 0.60), QPointF(0.15, 0.06), 14.0 / 5.0),
|
||||||
|
PDFColorSpaceIdentifier::createRGB(tr("NTSC"), "@GENERIC_RGB_NTSC", 6500, QPointF(0.64, 0.34), QPointF(0.31, 0.595), QPointF(0.155, 0.07), 20.0 / 9.0),
|
||||||
|
PDFColorSpaceIdentifier::createRGB(tr("Adobe Wide Gamut RGB"), "@GENERIC_RGB_AdobeWideGamut", 5000, QPointF(0.735, 0.265), QPointF(0.115, 0.826), QPointF(0.157, 0.018), 563.0 / 256.0),
|
||||||
|
PDFColorSpaceIdentifier::createRGB(tr("ProPhoto RGB"), "@GENERIC_RGB_ProPhoto", 5000, QPointF(0.7347, 0.2653), QPointF(0.1596, 0.8404), QPointF(0.0366, 0.0001), 9.0 / 5.0)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFColorSpaceIdentifiers PDFCMSManager::getCMYKProfilesImpl() const
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFColorSpaceIdentifier PDFColorSpaceIdentifier::createGray(QString name, QString id, PDFReal temperature, PDFReal gamma)
|
||||||
|
{
|
||||||
|
PDFColorSpaceIdentifier result;
|
||||||
|
result.type = Type::Gray;
|
||||||
|
result.name = qMove(name);
|
||||||
|
result.id = qMove(id);
|
||||||
|
result.temperature = temperature;
|
||||||
|
result.gamma = gamma;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFColorSpaceIdentifier PDFColorSpaceIdentifier::createSRGB()
|
||||||
|
{
|
||||||
|
PDFColorSpaceIdentifier result;
|
||||||
|
result.type = Type::sRGB;
|
||||||
|
result.name = PDFCMSManager::tr("sRGB");
|
||||||
|
result.id = "@GENERIC_sRGB";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFColorSpaceIdentifier PDFColorSpaceIdentifier::createRGB(QString name, QString id, PDFReal temperature, QPointF primaryR, QPointF primaryG, QPointF primaryB, PDFReal gamma)
|
||||||
|
{
|
||||||
|
PDFColorSpaceIdentifier result;
|
||||||
|
result.type = Type::RGB;
|
||||||
|
result.name = qMove(name);
|
||||||
|
result.id = qMove(id);
|
||||||
|
result.temperature = temperature;
|
||||||
|
result.primaryR = primaryR;
|
||||||
|
result.primaryG = primaryG;
|
||||||
|
result.primaryB = primaryB;
|
||||||
|
result.gamma = gamma;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace pdf
|
||||||
|
|
225
PdfForQtLib/sources/pdfcms.h
Normal file
225
PdfForQtLib/sources/pdfcms.h
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
// 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 PDFCMS_H
|
||||||
|
#define PDFCMS_H
|
||||||
|
|
||||||
|
#include "pdfglobal.h"
|
||||||
|
#include "pdfcolorspaces.h"
|
||||||
|
#include "pdfexception.h"
|
||||||
|
#include "pdfutils.h"
|
||||||
|
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
|
#include <compare>
|
||||||
|
|
||||||
|
namespace pdf
|
||||||
|
{
|
||||||
|
|
||||||
|
/// This simple structure stores settings for color management system, and what
|
||||||
|
/// color management system should be used. At default, two color management
|
||||||
|
/// system are available - generic (which uses default imprecise color management),
|
||||||
|
/// and CMS using engine LittleCMS2, which was written by Marti Maria, and is
|
||||||
|
/// linked as separate library.
|
||||||
|
struct PDFCMSSettings
|
||||||
|
{
|
||||||
|
/// Type of color management system
|
||||||
|
enum class System
|
||||||
|
{
|
||||||
|
Generic,
|
||||||
|
LittleCMS2
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Controls accuracy of the color transformations. High accuracy
|
||||||
|
/// could mean high memory consumption, but better color accuracy,
|
||||||
|
/// low accuracy means low memory consumption and low color accuracy.
|
||||||
|
enum class Accuracy
|
||||||
|
{
|
||||||
|
Low,
|
||||||
|
Medium,
|
||||||
|
High
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(const PDFCMSSettings&) const = default;
|
||||||
|
|
||||||
|
System system = System::Generic;
|
||||||
|
Accuracy accuracy = Accuracy::Medium;
|
||||||
|
RenderingIntent intent = RenderingIntent::Auto;
|
||||||
|
bool isBlackPointCompensationActive = true;
|
||||||
|
bool isWhitePaperColorTransformed = false;
|
||||||
|
QString outputCS; ///< Output (rendering) color space
|
||||||
|
QString deviceGray; ///< Identifiers for color space (device gray)
|
||||||
|
QString deviceRGB; ///< Identifiers for color space (device RGB)
|
||||||
|
QString deviceCMYK; ///< Identifiers for color space (device CMYK)
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Color management system base class. It contains functions to transform
|
||||||
|
/// colors from various color system to device color system. If color management
|
||||||
|
/// system can't handle color transform, it should return invalid color.
|
||||||
|
class PDFCMS
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit inline PDFCMS() = default;
|
||||||
|
virtual ~PDFCMS() = default;
|
||||||
|
|
||||||
|
/// This function should decide, if color management system is compatible with these
|
||||||
|
/// settings (so, it transforms colors according to this setting). If this
|
||||||
|
/// function returns false, then this color management system should be replaced
|
||||||
|
/// by newly created one, according these settings.
|
||||||
|
virtual bool isCompatible(const PDFCMSSettings& settings) const = 0;
|
||||||
|
|
||||||
|
/// Converts color in Device Gray color space to the target device
|
||||||
|
/// color space. If error occurs, then invalid color is returned.
|
||||||
|
/// Caller then should handle this - try to convert color as accurate
|
||||||
|
/// as possible.
|
||||||
|
/// \param color Single color channel value
|
||||||
|
/// \param intent Rendering intent
|
||||||
|
/// \param reporter Render error reporter (used, when color transform fails)
|
||||||
|
virtual QColor getColorFromDeviceGray(const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const = 0;
|
||||||
|
|
||||||
|
/// Converts color in Device RGB color space to the target device
|
||||||
|
/// color space. If error occurs, then invalid color is returned.
|
||||||
|
/// Caller then should handle this - try to convert color as accurate
|
||||||
|
/// as possible.
|
||||||
|
/// \param color Three color channel value (R,G,B channel)
|
||||||
|
/// \param intent Rendering intent
|
||||||
|
/// \param reporter Render error reporter (used, when color transform fails)
|
||||||
|
virtual QColor getColorFromDeviceRGB(const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const = 0;
|
||||||
|
|
||||||
|
/// Converts color in Device CMYK color space to the target device
|
||||||
|
/// color space. If error occurs, then invalid color is returned.
|
||||||
|
/// Caller then should handle this - try to convert color as accurate
|
||||||
|
/// as possible.
|
||||||
|
/// \param color Four color channel value (C,M,Y,K channel)
|
||||||
|
/// \param intent Rendering intent
|
||||||
|
/// \param reporter Render error reporter (used, when color transform fails)
|
||||||
|
virtual QColor getColorFromDeviceCMYK(const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const = 0;
|
||||||
|
|
||||||
|
/// Converts color in XYZ color space to the target device
|
||||||
|
/// color space. If error occurs, then invalid color is returned.
|
||||||
|
/// Caller then should handle this - try to convert color as accurate
|
||||||
|
/// as possible.
|
||||||
|
/// \param whitePoint White point of source XYZ color space
|
||||||
|
/// \param Three color channel value (X,Y,Z channel)
|
||||||
|
/// \param intent Rendering intent
|
||||||
|
/// \param reporter Render error reporter (used, when color transform fails)
|
||||||
|
virtual QColor getColorFromXYZ(const PDFColor3& whitePoint, const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PDFCMSGeneric : public PDFCMS
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit inline PDFCMSGeneric() = default;
|
||||||
|
|
||||||
|
virtual bool isCompatible(const PDFCMSSettings& settings) const override;
|
||||||
|
virtual QColor getColorFromDeviceGray(const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
||||||
|
virtual QColor getColorFromDeviceRGB(const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
||||||
|
virtual QColor getColorFromDeviceCMYK(const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
||||||
|
virtual QColor getColorFromXYZ(const PDFColor3& whitePoint, const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PDFColorSpaceIdentifier
|
||||||
|
{
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
Gray,
|
||||||
|
sRGB,
|
||||||
|
RGB,
|
||||||
|
CMYK
|
||||||
|
};
|
||||||
|
|
||||||
|
Type type = Type::sRGB;
|
||||||
|
QString name;
|
||||||
|
QString id;
|
||||||
|
PDFReal temperature = 6500.0;
|
||||||
|
QPointF primaryR;
|
||||||
|
QPointF primaryG;
|
||||||
|
QPointF primaryB;
|
||||||
|
PDFReal gamma = 1.0;
|
||||||
|
|
||||||
|
/// Creates gray color space identifier
|
||||||
|
/// \param name Name of color profile
|
||||||
|
/// \param id Identifier of color profile
|
||||||
|
/// \param temperature White point temperature
|
||||||
|
/// \param gamma Gamma correction
|
||||||
|
static PDFColorSpaceIdentifier createGray(QString name, QString id, PDFReal temperature, PDFReal gamma);
|
||||||
|
|
||||||
|
/// Creates sRGB color space identifier
|
||||||
|
static PDFColorSpaceIdentifier createSRGB();
|
||||||
|
|
||||||
|
/// Creates RGB color space identifier
|
||||||
|
/// \param name Name of color profile
|
||||||
|
/// \param id Identifier of color profile
|
||||||
|
/// \param temperature White point temperature
|
||||||
|
/// \param primaryR Primary red
|
||||||
|
/// \param primaryG Primary green
|
||||||
|
/// \param primaryB Primary blue
|
||||||
|
/// \param gamma Gamma correction
|
||||||
|
static PDFColorSpaceIdentifier createRGB(QString name, QString id, PDFReal temperature, QPointF primaryR, QPointF primaryG, QPointF primaryB, PDFReal gamma);
|
||||||
|
};
|
||||||
|
|
||||||
|
using PDFColorSpaceIdentifiers = std::vector<PDFColorSpaceIdentifier>;
|
||||||
|
|
||||||
|
/// Manager, that manages current color management system and also list
|
||||||
|
/// of usable input and output color profiles. It has color profiles
|
||||||
|
/// for outout device, and color profiles for input (gray/RGB/CMYK).
|
||||||
|
/// It also handles settings, and it's changes. Constant functions
|
||||||
|
/// is save to call from multiple threads, this also holds for some
|
||||||
|
/// non-constant functions - manager is protected by mutexes.
|
||||||
|
class PDFFORQTLIBSHARED_EXPORT PDFCMSManager : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
using BaseClass = QObject;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PDFCMSManager(QObject* parent);
|
||||||
|
|
||||||
|
const PDFColorSpaceIdentifiers& getOutputProfiles() const;
|
||||||
|
const PDFColorSpaceIdentifiers& getGrayProfiles() const;
|
||||||
|
const PDFColorSpaceIdentifiers& getRGBProfiles() const;
|
||||||
|
const PDFColorSpaceIdentifiers& getCMYKProfiles() const;
|
||||||
|
|
||||||
|
/// Returns default color management settings
|
||||||
|
PDFCMSSettings getDefaultSettings() const;
|
||||||
|
|
||||||
|
/// Get translated name for color management system
|
||||||
|
/// \param system System
|
||||||
|
static QString getSystemName(PDFCMSSettings::System system);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void colorManagementSystemChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
PDFColorSpaceIdentifiers getOutputProfilesImpl() const;
|
||||||
|
PDFColorSpaceIdentifiers getGrayProfilesImpl() const;
|
||||||
|
PDFColorSpaceIdentifiers getRGBProfilesImpl() const;
|
||||||
|
PDFColorSpaceIdentifiers getCMYKProfilesImpl() const;
|
||||||
|
|
||||||
|
PDFCMSSettings m_settings;
|
||||||
|
|
||||||
|
mutable QMutex m_mutex;
|
||||||
|
mutable PDFCachedItem<PDFColorSpaceIdentifiers> m_outputProfiles;
|
||||||
|
mutable PDFCachedItem<PDFColorSpaceIdentifiers> m_grayProfiles;
|
||||||
|
mutable PDFCachedItem<PDFColorSpaceIdentifiers> m_RGBProfiles;
|
||||||
|
mutable PDFCachedItem<PDFColorSpaceIdentifiers> m_CMYKProfiles;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace pdf
|
||||||
|
|
||||||
|
#endif // PDFCMS_H
|
@ -150,6 +150,7 @@ enum class RendererEngine
|
|||||||
|
|
||||||
enum class RenderingIntent
|
enum class RenderingIntent
|
||||||
{
|
{
|
||||||
|
Auto, ///< Rendering intent is automatically selected
|
||||||
Perceptual,
|
Perceptual,
|
||||||
AbsoluteColorimetric,
|
AbsoluteColorimetric,
|
||||||
RelativeColorimetric,
|
RelativeColorimetric,
|
||||||
|
@ -26,5 +26,6 @@
|
|||||||
<file>resources/shortcuts.svg</file>
|
<file>resources/shortcuts.svg</file>
|
||||||
<file>resources/info.svg</file>
|
<file>resources/info.svg</file>
|
||||||
<file>resources/send-mail.svg</file>
|
<file>resources/send-mail.svg</file>
|
||||||
|
<file>resources/cms.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@ -59,9 +59,10 @@
|
|||||||
namespace pdfviewer
|
namespace pdfviewer
|
||||||
{
|
{
|
||||||
|
|
||||||
PDFViewerMainWindow::PDFViewerMainWindow(QWidget *parent) :
|
PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) :
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
ui(new Ui::PDFViewerMainWindow),
|
ui(new Ui::PDFViewerMainWindow),
|
||||||
|
m_CMSManager(new pdf::PDFCMSManager(this)),
|
||||||
m_settings(new PDFViewerSettings(this)),
|
m_settings(new PDFViewerSettings(this)),
|
||||||
m_pdfWidget(nullptr),
|
m_pdfWidget(nullptr),
|
||||||
m_sidebarDockWidget(nullptr),
|
m_sidebarDockWidget(nullptr),
|
||||||
@ -544,8 +545,7 @@ void PDFViewerMainWindow::readSettings()
|
|||||||
restoreState(state);
|
restoreState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_settings->readSettings(settings);
|
m_settings->readSettings(settings, m_CMSManager->getDefaultSettings());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFViewerMainWindow::readActionSettings()
|
void PDFViewerMainWindow::readActionSettings()
|
||||||
@ -976,10 +976,11 @@ void PDFViewerMainWindow::on_actionRendering_Errors_triggered()
|
|||||||
|
|
||||||
void PDFViewerMainWindow::on_actionOptions_triggered()
|
void PDFViewerMainWindow::on_actionOptions_triggered()
|
||||||
{
|
{
|
||||||
PDFViewerSettingsDialog dialog(m_settings->getSettings(), getActions(), this);
|
PDFViewerSettingsDialog dialog(m_settings->getSettings(), m_settings->getColorManagementSystemSettings(), getActions(), m_CMSManager, this);
|
||||||
if (dialog.exec() == QDialog::Accepted)
|
if (dialog.exec() == QDialog::Accepted)
|
||||||
{
|
{
|
||||||
m_settings->setSettings(dialog.getSettings());
|
m_settings->setSettings(dialog.getSettings());
|
||||||
|
m_settings->setColorManagementSystemSettings(dialog.getCMSSettings());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,6 +139,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
Ui::PDFViewerMainWindow* ui;
|
Ui::PDFViewerMainWindow* ui;
|
||||||
|
pdf::PDFCMSManager* m_CMSManager;
|
||||||
PDFViewerSettings* m_settings;
|
PDFViewerSettings* m_settings;
|
||||||
pdf::PDFWidget* m_pdfWidget;
|
pdf::PDFWidget* m_pdfWidget;
|
||||||
QSharedPointer<pdf::PDFDocument> m_pdfDocument;
|
QSharedPointer<pdf::PDFDocument> m_pdfDocument;
|
||||||
|
@ -26,11 +26,14 @@ const int PIXMAP_CACHE_LIMIT = QPixmapCache::cacheLimit();
|
|||||||
|
|
||||||
void PDFViewerSettings::setSettings(const PDFViewerSettings::Settings& settings)
|
void PDFViewerSettings::setSettings(const PDFViewerSettings::Settings& settings)
|
||||||
{
|
{
|
||||||
|
if (m_settings != settings)
|
||||||
|
{
|
||||||
m_settings = settings;
|
m_settings = settings;
|
||||||
emit settingsChanged();
|
emit settingsChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFViewerSettings::readSettings(QSettings& settings)
|
void PDFViewerSettings::readSettings(QSettings& settings, const pdf::PDFCMSSettings& defaultCMSSettings)
|
||||||
{
|
{
|
||||||
Settings defaultSettings;
|
Settings defaultSettings;
|
||||||
|
|
||||||
@ -52,6 +55,18 @@ void PDFViewerSettings::readSettings(QSettings& settings)
|
|||||||
m_settings.m_allowLaunchURI = settings.value("allowLaunchURI", defaultSettings.m_allowLaunchURI).toBool();
|
m_settings.m_allowLaunchURI = settings.value("allowLaunchURI", defaultSettings.m_allowLaunchURI).toBool();
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("ColorManagementSystemSettings");
|
||||||
|
m_colorManagementSystemSettings.system = static_cast<pdf::PDFCMSSettings::System>(settings.value("system", int(defaultCMSSettings.system)).toInt());
|
||||||
|
m_colorManagementSystemSettings.accuracy = static_cast<pdf::PDFCMSSettings::Accuracy>(settings.value("accuracy", int(defaultCMSSettings.accuracy)).toInt());
|
||||||
|
m_colorManagementSystemSettings.intent = static_cast<pdf::RenderingIntent>(settings.value("intent", int(defaultCMSSettings.intent)).toInt());
|
||||||
|
m_colorManagementSystemSettings.isBlackPointCompensationActive = settings.value("isBlackPointCompensationActive", defaultCMSSettings.isBlackPointCompensationActive).toBool();
|
||||||
|
m_colorManagementSystemSettings.isWhitePaperColorTransformed = settings.value("isWhitePaperColorTransformed", defaultCMSSettings.isWhitePaperColorTransformed).toBool();
|
||||||
|
m_colorManagementSystemSettings.outputCS = settings.value("outputCS", defaultCMSSettings.outputCS).toString();
|
||||||
|
m_colorManagementSystemSettings.deviceGray = settings.value("deviceGray", defaultCMSSettings.deviceGray).toString();
|
||||||
|
m_colorManagementSystemSettings.deviceRGB = settings.value("deviceRGB", defaultCMSSettings.deviceRGB).toString();
|
||||||
|
m_colorManagementSystemSettings.deviceCMYK = settings.value("deviceCMYK", defaultCMSSettings.deviceCMYK).toString();
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
emit settingsChanged();
|
emit settingsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +89,18 @@ void PDFViewerSettings::writeSettings(QSettings& settings)
|
|||||||
settings.setValue("allowLaunchApplications", m_settings.m_allowLaunchApplications);
|
settings.setValue("allowLaunchApplications", m_settings.m_allowLaunchApplications);
|
||||||
settings.setValue("allowLaunchURI", m_settings.m_allowLaunchURI);
|
settings.setValue("allowLaunchURI", m_settings.m_allowLaunchURI);
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("ColorManagementSystemSettings");
|
||||||
|
settings.setValue("system", int(m_colorManagementSystemSettings.system));
|
||||||
|
settings.setValue("accuracy", int(m_colorManagementSystemSettings.accuracy));
|
||||||
|
settings.setValue("intent", int(m_colorManagementSystemSettings.intent));
|
||||||
|
settings.setValue("isBlackPointCompensationActive", m_colorManagementSystemSettings.isBlackPointCompensationActive);
|
||||||
|
settings.setValue("isWhitePaperColorTransformed", m_colorManagementSystemSettings.isWhitePaperColorTransformed);
|
||||||
|
settings.setValue("outputCS", m_colorManagementSystemSettings.outputCS);
|
||||||
|
settings.setValue("deviceGray", m_colorManagementSystemSettings.deviceGray);
|
||||||
|
settings.setValue("deviceRGB", m_colorManagementSystemSettings.deviceRGB);
|
||||||
|
settings.setValue("deviceCMYK", m_colorManagementSystemSettings.deviceCMYK);
|
||||||
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PDFViewerSettings::getDirectory() const
|
QString PDFViewerSettings::getDirectory() const
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#define PDFVIEWERSETTINGS_H
|
#define PDFVIEWERSETTINGS_H
|
||||||
|
|
||||||
#include "pdfrenderer.h"
|
#include "pdfrenderer.h"
|
||||||
|
#include "pdfcms.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
@ -40,6 +41,9 @@ public:
|
|||||||
{
|
{
|
||||||
Settings();
|
Settings();
|
||||||
|
|
||||||
|
bool operator==(const Settings&) const = default;
|
||||||
|
bool operator!=(const Settings&) const = default;
|
||||||
|
|
||||||
pdf::PDFRenderer::Features m_features;
|
pdf::PDFRenderer::Features m_features;
|
||||||
QString m_directory;
|
QString m_directory;
|
||||||
pdf::RendererEngine m_rendererEngine;
|
pdf::RendererEngine m_rendererEngine;
|
||||||
@ -62,7 +66,7 @@ public:
|
|||||||
const Settings& getSettings() const { return m_settings; }
|
const Settings& getSettings() const { return m_settings; }
|
||||||
void setSettings(const Settings& settings);
|
void setSettings(const Settings& settings);
|
||||||
|
|
||||||
void readSettings(QSettings& settings);
|
void readSettings(QSettings& settings, const pdf::PDFCMSSettings& defaultCMSSettings);
|
||||||
void writeSettings(QSettings& settings);
|
void writeSettings(QSettings& settings);
|
||||||
|
|
||||||
QString getDirectory() const;
|
QString getDirectory() const;
|
||||||
@ -94,14 +98,17 @@ public:
|
|||||||
int getFontCacheLimit() const { return m_settings.m_fontCacheLimit; }
|
int getFontCacheLimit() const { return m_settings.m_fontCacheLimit; }
|
||||||
int getInstancedFontCacheLimit() const { return m_settings.m_instancedFontCacheLimit; }
|
int getInstancedFontCacheLimit() const { return m_settings.m_instancedFontCacheLimit; }
|
||||||
|
|
||||||
|
const pdf::PDFCMSSettings& getColorManagementSystemSettings() const { return m_colorManagementSystemSettings; }
|
||||||
|
void setColorManagementSystemSettings(const pdf::PDFCMSSettings& settings) { m_colorManagementSystemSettings = settings; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void settingsChanged();
|
void settingsChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Settings m_settings;
|
Settings m_settings;
|
||||||
|
pdf::PDFCMSSettings m_colorManagementSystemSettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace pdfviewer
|
} // namespace pdfviewer
|
||||||
|
|
||||||
#endif // PDFVIEWERSETTINGS_H
|
#endif // PDFVIEWERSETTINGS_H
|
||||||
|
@ -29,10 +29,14 @@
|
|||||||
namespace pdfviewer
|
namespace pdfviewer
|
||||||
{
|
{
|
||||||
|
|
||||||
PDFViewerSettingsDialog::PDFViewerSettingsDialog(const PDFViewerSettings::Settings& settings, QList<QAction*> actions, QWidget *parent) :
|
PDFViewerSettingsDialog::PDFViewerSettingsDialog(const PDFViewerSettings::Settings& settings,
|
||||||
|
const pdf::PDFCMSSettings& cmsSettings,
|
||||||
|
QList<QAction*> actions,
|
||||||
|
pdf::PDFCMSManager* cmsManager, QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
ui(new Ui::PDFViewerSettingsDialog),
|
ui(new Ui::PDFViewerSettingsDialog),
|
||||||
m_settings(settings),
|
m_settings(settings),
|
||||||
|
m_cmsSettings(cmsSettings),
|
||||||
m_actions(),
|
m_actions(),
|
||||||
m_isLoadingData(false)
|
m_isLoadingData(false)
|
||||||
{
|
{
|
||||||
@ -43,6 +47,7 @@ PDFViewerSettingsDialog::PDFViewerSettingsDialog(const PDFViewerSettings::Settin
|
|||||||
new QListWidgetItem(QIcon(":/resources/shading.svg"), tr("Shading"), ui->optionsPagesWidget, ShadingSettings);
|
new QListWidgetItem(QIcon(":/resources/shading.svg"), tr("Shading"), ui->optionsPagesWidget, ShadingSettings);
|
||||||
new QListWidgetItem(QIcon(":/resources/cache.svg"), tr("Cache"), ui->optionsPagesWidget, CacheSettings);
|
new QListWidgetItem(QIcon(":/resources/cache.svg"), tr("Cache"), ui->optionsPagesWidget, CacheSettings);
|
||||||
new QListWidgetItem(QIcon(":/resources/shortcuts.svg"), tr("Shortcuts"), ui->optionsPagesWidget, ShortcutSettings);
|
new QListWidgetItem(QIcon(":/resources/shortcuts.svg"), tr("Shortcuts"), ui->optionsPagesWidget, ShortcutSettings);
|
||||||
|
new QListWidgetItem(QIcon(":/resources/cms.svg"), tr("Colors"), ui->optionsPagesWidget, ColorManagementSystemSettings);
|
||||||
new QListWidgetItem(QIcon(":/resources/security.svg"), tr("Security"), ui->optionsPagesWidget, SecuritySettings);
|
new QListWidgetItem(QIcon(":/resources/security.svg"), tr("Security"), ui->optionsPagesWidget, SecuritySettings);
|
||||||
|
|
||||||
ui->renderingEngineComboBox->addItem(tr("Software"), static_cast<int>(pdf::RendererEngine::Software));
|
ui->renderingEngineComboBox->addItem(tr("Software"), static_cast<int>(pdf::RendererEngine::Software));
|
||||||
@ -53,7 +58,33 @@ PDFViewerSettingsDialog::PDFViewerSettingsDialog(const PDFViewerSettings::Settin
|
|||||||
ui->multisampleAntialiasingSamplesCountComboBox->addItem(QString::number(i), i);
|
ui->multisampleAntialiasingSamplesCountComboBox->addItem(QString::number(i), i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (QWidget* widget : { ui->engineInfoLabel, ui->renderingInfoLabel, ui->securityInfoLabel })
|
// Load CMS data
|
||||||
|
ui->cmsTypeComboBox->addItem(pdf::PDFCMSManager::getSystemName(pdf::PDFCMSSettings::System::Generic), int(pdf::PDFCMSSettings::System::Generic));
|
||||||
|
ui->cmsTypeComboBox->addItem(pdf::PDFCMSManager::getSystemName(pdf::PDFCMSSettings::System::LittleCMS2), int(pdf::PDFCMSSettings::System::LittleCMS2));
|
||||||
|
|
||||||
|
ui->cmsRenderingIntentComboBox->addItem(tr("Auto"), int(pdf::RenderingIntent::Auto));
|
||||||
|
ui->cmsRenderingIntentComboBox->addItem(tr("Perceptual"), int(pdf::RenderingIntent::Perceptual));
|
||||||
|
ui->cmsRenderingIntentComboBox->addItem(tr("Relative colorimetric"), int(pdf::RenderingIntent::RelativeColorimetric));
|
||||||
|
ui->cmsRenderingIntentComboBox->addItem(tr("Absolute colorimetric"), int(pdf::RenderingIntent::AbsoluteColorimetric));
|
||||||
|
ui->cmsRenderingIntentComboBox->addItem(tr("Saturation"), int(pdf::RenderingIntent::Saturation));
|
||||||
|
|
||||||
|
ui->cmsAccuracyComboBox->addItem(tr("Low"), int(pdf::PDFCMSSettings::Accuracy::Low));
|
||||||
|
ui->cmsAccuracyComboBox->addItem(tr("Medium"), int(pdf::PDFCMSSettings::Accuracy::Medium));
|
||||||
|
ui->cmsAccuracyComboBox->addItem(tr("High"), int(pdf::PDFCMSSettings::Accuracy::High));
|
||||||
|
|
||||||
|
auto fillColorProfileList = [](QComboBox* comboBox, const pdf::PDFColorSpaceIdentifiers& identifiers)
|
||||||
|
{
|
||||||
|
for (const pdf::PDFColorSpaceIdentifier& identifier : identifiers)
|
||||||
|
{
|
||||||
|
comboBox->addItem(identifier.name, identifier.id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fillColorProfileList(ui->cmsOutputColorProfileComboBox, cmsManager->getOutputProfiles());
|
||||||
|
fillColorProfileList(ui->cmsDeviceGrayColorProfileComboBox, cmsManager->getGrayProfiles());
|
||||||
|
fillColorProfileList(ui->cmsDeviceRGBColorProfileComboBox, cmsManager->getRGBProfiles());
|
||||||
|
fillColorProfileList(ui->cmsDeviceCMYKColorProfileComboBox, cmsManager->getCMYKProfiles());
|
||||||
|
|
||||||
|
for (QWidget* widget : { ui->engineInfoLabel, ui->renderingInfoLabel, ui->securityInfoLabel, ui->cmsInfoLabel })
|
||||||
{
|
{
|
||||||
widget->setMinimumWidth(widget->sizeHint().width());
|
widget->setMinimumWidth(widget->sizeHint().width());
|
||||||
}
|
}
|
||||||
@ -120,6 +151,10 @@ void PDFViewerSettingsDialog::on_optionsPagesWidget_currentItemChanged(QListWidg
|
|||||||
ui->stackedWidget->setCurrentWidget(ui->shortcutsPage);
|
ui->stackedWidget->setCurrentWidget(ui->shortcutsPage);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ColorManagementSystemSettings:
|
||||||
|
ui->stackedWidget->setCurrentWidget(ui->cmsPage);
|
||||||
|
break;
|
||||||
|
|
||||||
case SecuritySettings:
|
case SecuritySettings:
|
||||||
ui->stackedWidget->setCurrentWidget(ui->securityPage);
|
ui->stackedWidget->setCurrentWidget(ui->securityPage);
|
||||||
break;
|
break;
|
||||||
@ -183,6 +218,47 @@ void PDFViewerSettingsDialog::loadData()
|
|||||||
// Security
|
// Security
|
||||||
ui->allowLaunchCheckBox->setChecked(m_settings.m_allowLaunchApplications);
|
ui->allowLaunchCheckBox->setChecked(m_settings.m_allowLaunchApplications);
|
||||||
ui->allowRunURICheckBox->setChecked(m_settings.m_allowLaunchURI);
|
ui->allowRunURICheckBox->setChecked(m_settings.m_allowLaunchURI);
|
||||||
|
|
||||||
|
// CMS
|
||||||
|
ui->cmsTypeComboBox->setCurrentIndex(ui->cmsTypeComboBox->findData(int(m_cmsSettings.system)));
|
||||||
|
if (m_cmsSettings.system != pdf::PDFCMSSettings::System::Generic)
|
||||||
|
{
|
||||||
|
ui->cmsRenderingIntentComboBox->setEnabled(true);
|
||||||
|
ui->cmsRenderingIntentComboBox->setCurrentIndex(ui->cmsRenderingIntentComboBox->findData(int(m_cmsSettings.intent)));
|
||||||
|
ui->cmsAccuracyComboBox->setEnabled(true);
|
||||||
|
ui->cmsAccuracyComboBox->setCurrentIndex(ui->cmsAccuracyComboBox->findData(int(m_cmsSettings.accuracy)));
|
||||||
|
ui->cmsIsBlackPointCompensationCheckBox->setEnabled(true);
|
||||||
|
ui->cmsIsBlackPointCompensationCheckBox->setChecked(m_cmsSettings.isBlackPointCompensationActive);
|
||||||
|
ui->cmsWhitePaperColorTransformedCheckBox->setEnabled(true);
|
||||||
|
ui->cmsWhitePaperColorTransformedCheckBox->setChecked(m_cmsSettings.isWhitePaperColorTransformed);
|
||||||
|
ui->cmsOutputColorProfileComboBox->setEnabled(true);
|
||||||
|
ui->cmsOutputColorProfileComboBox->setCurrentIndex(ui->cmsOutputColorProfileComboBox->findData(m_cmsSettings.outputCS));
|
||||||
|
ui->cmsDeviceGrayColorProfileComboBox->setEnabled(true);
|
||||||
|
ui->cmsDeviceGrayColorProfileComboBox->setCurrentIndex(ui->cmsDeviceGrayColorProfileComboBox->findData(m_cmsSettings.deviceGray));
|
||||||
|
ui->cmsDeviceRGBColorProfileComboBox->setEnabled(true);
|
||||||
|
ui->cmsDeviceRGBColorProfileComboBox->setCurrentIndex(ui->cmsDeviceRGBColorProfileComboBox->findData(m_cmsSettings.deviceRGB));
|
||||||
|
ui->cmsDeviceCMYKColorProfileComboBox->setEnabled(true);
|
||||||
|
ui->cmsDeviceCMYKColorProfileComboBox->setCurrentIndex(ui->cmsDeviceCMYKColorProfileComboBox->findData(m_cmsSettings.deviceCMYK));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->cmsRenderingIntentComboBox->setEnabled(false);
|
||||||
|
ui->cmsRenderingIntentComboBox->setCurrentIndex(-1);
|
||||||
|
ui->cmsAccuracyComboBox->setEnabled(false);
|
||||||
|
ui->cmsAccuracyComboBox->setCurrentIndex(-1);
|
||||||
|
ui->cmsIsBlackPointCompensationCheckBox->setEnabled(false);
|
||||||
|
ui->cmsIsBlackPointCompensationCheckBox->setChecked(false);
|
||||||
|
ui->cmsWhitePaperColorTransformedCheckBox->setEnabled(false);
|
||||||
|
ui->cmsWhitePaperColorTransformedCheckBox->setChecked(false);
|
||||||
|
ui->cmsOutputColorProfileComboBox->setEnabled(false);
|
||||||
|
ui->cmsOutputColorProfileComboBox->setCurrentIndex(-1);
|
||||||
|
ui->cmsDeviceGrayColorProfileComboBox->setEnabled(false);
|
||||||
|
ui->cmsDeviceGrayColorProfileComboBox->setCurrentIndex(-1);
|
||||||
|
ui->cmsDeviceRGBColorProfileComboBox->setEnabled(false);
|
||||||
|
ui->cmsDeviceRGBColorProfileComboBox->setCurrentIndex(-1);
|
||||||
|
ui->cmsDeviceCMYKColorProfileComboBox->setEnabled(false);
|
||||||
|
ui->cmsDeviceCMYKColorProfileComboBox->setCurrentIndex(-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFViewerSettingsDialog::saveData()
|
void PDFViewerSettingsDialog::saveData()
|
||||||
@ -270,6 +346,42 @@ void PDFViewerSettingsDialog::saveData()
|
|||||||
{
|
{
|
||||||
m_settings.m_instancedFontCacheLimit = ui->cachedInstancedFontLimitEdit->value();
|
m_settings.m_instancedFontCacheLimit = ui->cachedInstancedFontLimitEdit->value();
|
||||||
}
|
}
|
||||||
|
else if (sender == ui->cmsTypeComboBox)
|
||||||
|
{
|
||||||
|
m_cmsSettings.system = static_cast<pdf::PDFCMSSettings::System>(ui->cmsTypeComboBox->currentData().toInt());
|
||||||
|
}
|
||||||
|
else if (sender == ui->cmsRenderingIntentComboBox)
|
||||||
|
{
|
||||||
|
m_cmsSettings.intent = static_cast<pdf::RenderingIntent>(ui->cmsRenderingIntentComboBox->currentData().toInt());
|
||||||
|
}
|
||||||
|
else if (sender == ui->cmsAccuracyComboBox)
|
||||||
|
{
|
||||||
|
m_cmsSettings.accuracy = static_cast<pdf::PDFCMSSettings::Accuracy>(ui->cmsAccuracyComboBox->currentData().toInt());
|
||||||
|
}
|
||||||
|
else if (sender == ui->cmsIsBlackPointCompensationCheckBox)
|
||||||
|
{
|
||||||
|
m_cmsSettings.isBlackPointCompensationActive = ui->cmsIsBlackPointCompensationCheckBox->isChecked();
|
||||||
|
}
|
||||||
|
else if (sender == ui->cmsWhitePaperColorTransformedCheckBox)
|
||||||
|
{
|
||||||
|
m_cmsSettings.isWhitePaperColorTransformed = ui->cmsWhitePaperColorTransformedCheckBox->isChecked();
|
||||||
|
}
|
||||||
|
else if (sender == ui->cmsOutputColorProfileComboBox)
|
||||||
|
{
|
||||||
|
m_cmsSettings.outputCS = ui->cmsOutputColorProfileComboBox->currentData().toString();
|
||||||
|
}
|
||||||
|
else if (sender == ui->cmsDeviceGrayColorProfileComboBox)
|
||||||
|
{
|
||||||
|
m_cmsSettings.deviceGray = ui->cmsDeviceGrayColorProfileComboBox->currentData().toString();
|
||||||
|
}
|
||||||
|
else if (sender == ui->cmsDeviceRGBColorProfileComboBox)
|
||||||
|
{
|
||||||
|
m_cmsSettings.deviceRGB = ui->cmsDeviceRGBColorProfileComboBox->currentData().toString();
|
||||||
|
}
|
||||||
|
else if (sender == ui->cmsDeviceCMYKColorProfileComboBox)
|
||||||
|
{
|
||||||
|
m_cmsSettings.deviceCMYK = ui->cmsDeviceCMYKColorProfileComboBox->currentData().toString();
|
||||||
|
}
|
||||||
|
|
||||||
loadData();
|
loadData();
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,17 @@ class PDFViewerSettingsDialog : public QDialog
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PDFViewerSettingsDialog(const PDFViewerSettings::Settings& settings, QList<QAction*> actions, QWidget* parent);
|
/// Constructor
|
||||||
|
/// \param settings Viewer settings
|
||||||
|
/// \param cmsSettings Color management system settings
|
||||||
|
/// \param actions Actions
|
||||||
|
/// \param cmsManager CMS manager
|
||||||
|
/// \param parent Parent widget
|
||||||
|
explicit PDFViewerSettingsDialog(const PDFViewerSettings::Settings& settings,
|
||||||
|
const pdf::PDFCMSSettings& cmsSettings,
|
||||||
|
QList<QAction*> actions,
|
||||||
|
pdf::PDFCMSManager* cmsManager,
|
||||||
|
QWidget* parent);
|
||||||
virtual ~PDFViewerSettingsDialog() override;
|
virtual ~PDFViewerSettingsDialog() override;
|
||||||
|
|
||||||
virtual void accept() override;
|
virtual void accept() override;
|
||||||
@ -49,10 +59,12 @@ public:
|
|||||||
ShadingSettings,
|
ShadingSettings,
|
||||||
CacheSettings,
|
CacheSettings,
|
||||||
ShortcutSettings,
|
ShortcutSettings,
|
||||||
|
ColorManagementSystemSettings,
|
||||||
SecuritySettings
|
SecuritySettings
|
||||||
};
|
};
|
||||||
|
|
||||||
const PDFViewerSettings::Settings& getSettings() const { return m_settings; }
|
const PDFViewerSettings::Settings& getSettings() const { return m_settings; }
|
||||||
|
const pdf::PDFCMSSettings& getCMSSettings() const { return m_cmsSettings; }
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_optionsPagesWidget_currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous);
|
void on_optionsPagesWidget_currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous);
|
||||||
@ -66,6 +78,7 @@ private:
|
|||||||
|
|
||||||
Ui::PDFViewerSettingsDialog* ui;
|
Ui::PDFViewerSettingsDialog* ui;
|
||||||
PDFViewerSettings::Settings m_settings;
|
PDFViewerSettings::Settings m_settings;
|
||||||
|
pdf::PDFCMSSettings m_cmsSettings;
|
||||||
QList<QAction*> m_actions;
|
QList<QAction*> m_actions;
|
||||||
bool m_isLoadingData;
|
bool m_isLoadingData;
|
||||||
};
|
};
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>720</width>
|
<width>742</width>
|
||||||
<height>538</height>
|
<height>573</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -26,7 +26,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QStackedWidget" name="stackedWidget">
|
<widget class="QStackedWidget" name="stackedWidget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>4</number>
|
<number>5</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="enginePage">
|
<widget class="QWidget" name="enginePage">
|
||||||
<layout class="QVBoxLayout" name="enginePageLayout">
|
<layout class="QVBoxLayout" name="enginePageLayout">
|
||||||
@ -564,6 +564,144 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="cmsPage">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="cmsGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Color management system settings</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="cmsWidgetsLayout">
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="cmsTypeComboBox"/>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QCheckBox" name="cmsWhitePaperColorTransformedCheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enabled</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="cmsWhitePaperColorTransformedLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>White paper color transformed</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<widget class="QLabel" name="cmsDeviceRGBProfileLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Device RGB color profile</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="cmsOutputProfileLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Output color profile</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QCheckBox" name="cmsIsBlackPointCompensationCheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enabled</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QLabel" name="cmsDeviceGrayColorProfileLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Device gray color profile</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="cmsRenderingIntentComboBox"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="cmsRenderingIntentLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Rendering intent</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QComboBox" name="cmsAccuracyComboBox"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="cmsAccuracyLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Accuracy</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="cmsLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Color management system</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="cmsBlackPointCompensationLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Black point compensation</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="0">
|
||||||
|
<widget class="QLabel" name="cmsDeviceCMYKColorProfileLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Device CMYK color profile</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QComboBox" name="cmsOutputColorProfileComboBox"/>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="1">
|
||||||
|
<widget class="QComboBox" name="cmsDeviceGrayColorProfileComboBox"/>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<widget class="QComboBox" name="cmsDeviceRGBColorProfileComboBox"/>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="1">
|
||||||
|
<widget class="QComboBox" name="cmsDeviceCMYKColorProfileComboBox"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="cmsInfoLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string><html><head/><body><p><span style=" font-weight:600;">Color management system </span>manages input and output color profiles and color transformations. It enables to perceive real colors defined in PDF document. Select 'Generic' to disable this functionality for fast color transform. <span style=" font-weight:600;">Rendering intent</span> affects how colors are transformed. Rendering intents are usually defined in content streams in PDF document, but you can override them, if you select other intent, than 'Auto'. <span style=" font-weight:600;">Accuracy </span>affects how precise the color transformation would be, at the cost of more memory consumption. <span style=" font-weight:600;">Black point compensation</span> compensates black colors out of gamut. <span style=" font-weight:600;">White paper color transformed </span>affects color of the underlying white paper - it transforms pure white from device RGB profile to output profile, if enabled.</p><p><span style=" font-weight:600;">Output color profile</span> defines output (target) rendering profile. This profile should be color space, in which your screen is displaying colors. You can also define color spaces for <span style=" font-weight:600;">gray/RGB/CMYK</span> device color spaces, which are used to transform gray/RGB/CMYK colors to the output color profile.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="cmsVerticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>41</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
<widget class="QWidget" name="securityPage">
|
<widget class="QWidget" name="securityPage">
|
||||||
<layout class="QVBoxLayout" name="securityPageLayout">
|
<layout class="QVBoxLayout" name="securityPageLayout">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
|
110
PdfForQtViewer/resources/cms.svg
Normal file
110
PdfForQtViewer/resources/cms.svg
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="30mm"
|
||||||
|
height="30mm"
|
||||||
|
viewBox="0 0 30 30"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||||
|
sodipodi:docname="cms.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="spiro"
|
||||||
|
id="path-effect831"
|
||||||
|
is_visible="true" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="5.6"
|
||||||
|
inkscape:cx="164.25422"
|
||||||
|
inkscape:cy="113.44001"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2035"
|
||||||
|
inkscape:window-x="-13"
|
||||||
|
inkscape:window-y="-13"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
<cc:license
|
||||||
|
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
|
||||||
|
<dc:creator>
|
||||||
|
<cc:Agent>
|
||||||
|
<dc:title>Jakub Melka</dc:title>
|
||||||
|
</cc:Agent>
|
||||||
|
</dc:creator>
|
||||||
|
</cc:Work>
|
||||||
|
<cc:License
|
||||||
|
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Notice" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Attribution" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
|
||||||
|
</cc:License>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Vrstva 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-267)">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 11.646391,283.58184 v 0 0"
|
||||||
|
id="path837"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:#969696;fill-opacity:0.75294119;stroke:none;stroke-width:1.3012532;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path876"
|
||||||
|
cx="9.6383934"
|
||||||
|
cy="277.41611"
|
||||||
|
rx="7.7485123"
|
||||||
|
ry="7.9611235" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:#000000;fill-opacity:0.75294119;stroke:none;stroke-width:1.3012532;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path876-0"
|
||||||
|
cx="19.607515"
|
||||||
|
cy="278.33743"
|
||||||
|
rx="7.7485123"
|
||||||
|
ry="7.9611239" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:#e6e6e6;fill-opacity:0.75294119;stroke:none;stroke-width:1.3012532;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path876-06"
|
||||||
|
cx="13.512649"
|
||||||
|
cy="286.41666"
|
||||||
|
rx="7.7485123"
|
||||||
|
ry="7.9611239" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.7 KiB |
Loading…
x
Reference in New Issue
Block a user