mirror of
				https://github.com/JakubMelka/PDF4QT.git
				synced 2025-06-05 21:59:17 +02:00 
			
		
		
		
	Refactoring - using of CMS
This commit is contained in:
		| @@ -113,3 +113,9 @@ void MainWindow::on_actionAdd_JBIG2_image_triggered() | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void MainWindow::reportRenderErrorOnce(pdf::RenderErrorType type, QString message) | ||||||
|  | { | ||||||
|  |     Q_UNUSED(type); | ||||||
|  |     QMessageBox::critical(this, tr("Error"), message); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -18,12 +18,11 @@ public: | |||||||
|     virtual ~MainWindow() override; |     virtual ~MainWindow() override; | ||||||
|  |  | ||||||
|     virtual void reportRenderError(pdf::RenderErrorType type, QString message) override; |     virtual void reportRenderError(pdf::RenderErrorType type, QString message) override; | ||||||
|  |     virtual void reportRenderErrorOnce(pdf::RenderErrorType type, QString message) override; | ||||||
|  |  | ||||||
| private slots: | private slots: | ||||||
|     void on_actionAddImage_triggered(); |     void on_actionAddImage_triggered(); | ||||||
|  |  | ||||||
|     void on_actionClear_triggered(); |     void on_actionClear_triggered(); | ||||||
|  |  | ||||||
|     void on_actionAdd_JBIG2_image_triggered(); |     void on_actionAdd_JBIG2_image_triggered(); | ||||||
|  |  | ||||||
| private: | private: | ||||||
|   | |||||||
| @@ -72,6 +72,11 @@ bool PDFCMSGeneric::isCompatible(const PDFCMSSettings& settings) const | |||||||
|     return settings.system == PDFCMSSettings::System::Generic; |     return settings.system == PDFCMSSettings::System::Generic; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | QColor PDFCMSGeneric::getPaperColor() const | ||||||
|  | { | ||||||
|  |     return QColor(Qt::white); | ||||||
|  | } | ||||||
|  |  | ||||||
| QColor PDFCMSGeneric::getColorFromDeviceGray(const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | QColor PDFCMSGeneric::getColorFromDeviceGray(const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     Q_UNUSED(color); |     Q_UNUSED(color); | ||||||
| @@ -96,7 +101,7 @@ QColor PDFCMSGeneric::getColorFromDeviceCMYK(const PDFColor& color, RenderingInt | |||||||
|     return QColor(); |     return QColor(); | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFCMSGeneric::getColorFromXYZ(const PDFColor3& whitePoint, const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | QColor PDFCMSGeneric::getColorFromXYZ(const PDFColor3& whitePoint, const PDFColor3& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     Q_UNUSED(color); |     Q_UNUSED(color); | ||||||
|     Q_UNUSED(intent); |     Q_UNUSED(intent); | ||||||
| @@ -111,6 +116,12 @@ PDFCMSManager::PDFCMSManager(QObject* parent) : | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | PDFCMSPointer PDFCMSManager::getCurrentCMS() const | ||||||
|  | { | ||||||
|  |     QMutexLocker lock(&m_mutex); | ||||||
|  |     return m_CMS.get(this, &PDFCMSManager::getCurrentCMSImpl); | ||||||
|  | } | ||||||
|  |  | ||||||
| void PDFCMSManager::setSettings(const PDFCMSSettings& settings) | void PDFCMSManager::setSettings(const PDFCMSSettings& settings) | ||||||
| { | { | ||||||
|     if (m_settings != settings) |     if (m_settings != settings) | ||||||
| @@ -120,6 +131,7 @@ void PDFCMSManager::setSettings(const PDFCMSSettings& settings) | |||||||
|         { |         { | ||||||
|             QMutexLocker lock(&m_mutex); |             QMutexLocker lock(&m_mutex); | ||||||
|             m_settings = settings; |             m_settings = settings; | ||||||
|  |             m_CMS.dirty(); | ||||||
|             m_outputProfiles.dirty(); |             m_outputProfiles.dirty(); | ||||||
|             m_grayProfiles.dirty(); |             m_grayProfiles.dirty(); | ||||||
|             m_RGBProfiles.dirty(); |             m_RGBProfiles.dirty(); | ||||||
| @@ -208,6 +220,11 @@ QString PDFCMSManager::getSystemName(PDFCMSSettings::System system) | |||||||
|     return QString(); |     return QString(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | PDFCMSPointer PDFCMSManager::getCurrentCMSImpl() const | ||||||
|  | { | ||||||
|  |     return PDFCMSPointer(new PDFCMSGeneric()); | ||||||
|  | } | ||||||
|  |  | ||||||
| PDFColorProfileIdentifiers PDFCMSManager::getOutputProfilesImpl() const | PDFColorProfileIdentifiers PDFCMSManager::getOutputProfilesImpl() const | ||||||
| { | { | ||||||
|     // Currently, we only support sRGB output color profile. |     // Currently, we only support sRGB output color profile. | ||||||
|   | |||||||
| @@ -24,6 +24,7 @@ | |||||||
| #include "pdfutils.h" | #include "pdfutils.h" | ||||||
|  |  | ||||||
| #include <QMutex> | #include <QMutex> | ||||||
|  | #include <QSharedPointer> | ||||||
|  |  | ||||||
| #include <compare> | #include <compare> | ||||||
|  |  | ||||||
| @@ -83,6 +84,9 @@ public: | |||||||
|     /// by newly created one, according these settings. |     /// by newly created one, according these settings. | ||||||
|     virtual bool isCompatible(const PDFCMSSettings& settings) const = 0; |     virtual bool isCompatible(const PDFCMSSettings& settings) const = 0; | ||||||
|  |  | ||||||
|  |     /// Returns color of the white paper | ||||||
|  |     virtual QColor getPaperColor() const = 0; | ||||||
|  |  | ||||||
|     /// Converts color in Device Gray color space to the target device |     /// Converts color in Device Gray color space to the target device | ||||||
|     /// color space. If error occurs, then invalid color is returned. |     /// color space. If error occurs, then invalid color is returned. | ||||||
|     /// Caller then should handle this - try to convert color as accurate |     /// Caller then should handle this - try to convert color as accurate | ||||||
| @@ -118,19 +122,22 @@ public: | |||||||
|     /// \param Three color channel value (X,Y,Z channel) |     /// \param Three color channel value (X,Y,Z channel) | ||||||
|     /// \param intent Rendering intent |     /// \param intent Rendering intent | ||||||
|     /// \param reporter Render error reporter (used, when color transform fails) |     /// \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; |     virtual QColor getColorFromXYZ(const PDFColor3& whitePoint, const PDFColor3& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const = 0; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | using PDFCMSPointer = QSharedPointer<PDFCMS>; | ||||||
|  |  | ||||||
| class PDFCMSGeneric : public PDFCMS | class PDFCMSGeneric : public PDFCMS | ||||||
| { | { | ||||||
| public: | public: | ||||||
|     explicit inline PDFCMSGeneric() = default; |     explicit inline PDFCMSGeneric() = default; | ||||||
|  |  | ||||||
|     virtual bool isCompatible(const PDFCMSSettings& settings) const override; |     virtual bool isCompatible(const PDFCMSSettings& settings) const override; | ||||||
|  |     virtual QColor getPaperColor() const override; | ||||||
|     virtual QColor getColorFromDeviceGray(const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) 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 getColorFromDeviceRGB(const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual QColor getColorFromDeviceCMYK(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; |     virtual QColor getColorFromXYZ(const PDFColor3& whitePoint, const PDFColor3& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct PDFColorProfileIdentifier | struct PDFColorProfileIdentifier | ||||||
| @@ -197,6 +204,10 @@ private: | |||||||
| public: | public: | ||||||
|     explicit PDFCMSManager(QObject* parent); |     explicit PDFCMSManager(QObject* parent); | ||||||
|  |  | ||||||
|  |     /// Returns current CMS. This function possibly creates CMS, | ||||||
|  |     /// of no CMS is found. | ||||||
|  |     PDFCMSPointer getCurrentCMS() const; | ||||||
|  |  | ||||||
|     const PDFCMSSettings& getSettings() const { return m_settings; } |     const PDFCMSSettings& getSettings() const { return m_settings; } | ||||||
|     void setSettings(const PDFCMSSettings& settings); |     void setSettings(const PDFCMSSettings& settings); | ||||||
|  |  | ||||||
| @@ -216,6 +227,9 @@ signals: | |||||||
|     void colorManagementSystemChanged(); |     void colorManagementSystemChanged(); | ||||||
|  |  | ||||||
| private: | private: | ||||||
|  |     /// Creates new CMS based on current settings | ||||||
|  |     PDFCMSPointer getCurrentCMSImpl() const; | ||||||
|  |  | ||||||
|     /// This function returns external profiles. It is not protected by mutex, |     /// This function returns external profiles. It is not protected by mutex, | ||||||
|     /// so it is not thread-safe. For this reason, it is not in public |     /// so it is not thread-safe. For this reason, it is not in public | ||||||
|     /// interface. |     /// interface. | ||||||
| @@ -239,6 +253,7 @@ private: | |||||||
|     PDFCMSSettings m_settings; |     PDFCMSSettings m_settings; | ||||||
|  |  | ||||||
|     mutable QMutex m_mutex; |     mutable QMutex m_mutex; | ||||||
|  |     mutable PDFCachedItem<PDFCMSPointer> m_CMS; | ||||||
|     mutable PDFCachedItem<PDFColorProfileIdentifiers> m_outputProfiles; |     mutable PDFCachedItem<PDFColorProfileIdentifiers> m_outputProfiles; | ||||||
|     mutable PDFCachedItem<PDFColorProfileIdentifiers> m_grayProfiles; |     mutable PDFCachedItem<PDFColorProfileIdentifiers> m_grayProfiles; | ||||||
|     mutable PDFCachedItem<PDFColorProfileIdentifiers> m_RGBProfiles; |     mutable PDFCachedItem<PDFColorProfileIdentifiers> m_RGBProfiles; | ||||||
|   | |||||||
| @@ -21,21 +21,31 @@ | |||||||
| #include "pdfexception.h" | #include "pdfexception.h" | ||||||
| #include "pdfutils.h" | #include "pdfutils.h" | ||||||
| #include "pdfpattern.h" | #include "pdfpattern.h" | ||||||
|  | #include "pdfcms.h" | ||||||
|  |  | ||||||
| namespace pdf | namespace pdf | ||||||
| { | { | ||||||
|  |  | ||||||
| QColor PDFDeviceGrayColorSpace::getDefaultColor() const | QColor PDFDeviceGrayColorSpace::getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     return QColor(Qt::black); |     return getColor(PDFColor(0.0f), cms, intent, reporter); | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFDeviceGrayColorSpace::getColor(const PDFColor& color) const | QColor PDFDeviceGrayColorSpace::getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|  |     Q_ASSERT(cms); | ||||||
|     Q_ASSERT(color.size() == getColorComponentCount()); |     Q_ASSERT(color.size() == getColorComponentCount()); | ||||||
|  |  | ||||||
|     PDFColorComponent component = clip01(color[0]); |     PDFColorComponent component = clip01(color[0]); | ||||||
|  |  | ||||||
|  |     // If color management system handles the color transformation, then use it, | ||||||
|  |     // otherwise fall back to the generic case. | ||||||
|  |     QColor cmsColor = cms->getColorFromDeviceGray(color, intent, reporter); | ||||||
|  |     if (cmsColor.isValid()) | ||||||
|  |     { | ||||||
|  |         return cmsColor; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     QColor result(QColor::Rgb); |     QColor result(QColor::Rgb); | ||||||
|     result.setRgbF(component, component, component, 1.0); |     result.setRgbF(component, component, component, 1.0); | ||||||
|     return result; |     return result; | ||||||
| @@ -46,16 +56,29 @@ size_t PDFDeviceGrayColorSpace::getColorComponentCount() const | |||||||
|     return 1; |     return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFDeviceRGBColorSpace::getDefaultColor() const | QColor PDFDeviceRGBColorSpace::getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     return QColor(Qt::black); |     return getColor(PDFColor(0.0f, 0.0f, 0.0f), cms, intent, reporter); | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFDeviceRGBColorSpace::getColor(const PDFColor& color) const | QColor PDFDeviceRGBColorSpace::getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     Q_ASSERT(color.size() == getColorComponentCount()); |     Q_ASSERT(color.size() == getColorComponentCount()); | ||||||
|  |  | ||||||
|     return fromRGB01({ color[0], color[1], color[2] }); |     PDFColorComponent r = clip01(color[0]); | ||||||
|  |     PDFColorComponent g = clip01(color[1]); | ||||||
|  |     PDFColorComponent b = clip01(color[2]); | ||||||
|  |  | ||||||
|  |     PDFColor clippedColor(r, g, b); | ||||||
|  |     QColor cmsColor = cms->getColorFromDeviceRGB(clippedColor, intent, reporter); | ||||||
|  |     if (cmsColor.isValid()) | ||||||
|  |     { | ||||||
|  |         return cmsColor; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     QColor result(QColor::Rgb); | ||||||
|  |     result.setRgbF(r, g, b, 1.0); | ||||||
|  |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| size_t PDFDeviceRGBColorSpace::getColorComponentCount() const | size_t PDFDeviceRGBColorSpace::getColorComponentCount() const | ||||||
| @@ -63,12 +86,12 @@ size_t PDFDeviceRGBColorSpace::getColorComponentCount() const | |||||||
|     return 3; |     return 3; | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFDeviceCMYKColorSpace::getDefaultColor() const | QColor PDFDeviceCMYKColorSpace::getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     return QColor(Qt::black); |     return getColor(PDFColor(0.0f, 0.0f, 0.0f, 1.0f), cms, intent, reporter); | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFDeviceCMYKColorSpace::getColor(const PDFColor& color) const | QColor PDFDeviceCMYKColorSpace::getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     Q_ASSERT(color.size() == getColorComponentCount()); |     Q_ASSERT(color.size() == getColorComponentCount()); | ||||||
|  |  | ||||||
| @@ -77,6 +100,13 @@ QColor PDFDeviceCMYKColorSpace::getColor(const PDFColor& color) const | |||||||
|     PDFColorComponent y = clip01(color[2]); |     PDFColorComponent y = clip01(color[2]); | ||||||
|     PDFColorComponent k = clip01(color[3]); |     PDFColorComponent k = clip01(color[3]); | ||||||
|  |  | ||||||
|  |     PDFColor clippedColor(c, m, y, k); | ||||||
|  |     QColor cmsColor = cms->getColorFromDeviceCMYK(clippedColor, intent, reporter); | ||||||
|  |     if (cmsColor.isValid()) | ||||||
|  |     { | ||||||
|  |         return cmsColor; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     QColor result(QColor::Cmyk); |     QColor result(QColor::Cmyk); | ||||||
|     result.setCmykF(c, m, y, k, 1.0); |     result.setCmykF(c, m, y, k, 1.0); | ||||||
|     return result; |     return result; | ||||||
| @@ -87,7 +117,11 @@ size_t PDFDeviceCMYKColorSpace::getColorComponentCount() const | |||||||
|     return 4; |     return 4; | ||||||
| } | } | ||||||
|  |  | ||||||
| QImage PDFAbstractColorSpace::getImage(const PDFImageData& imageData, const PDFImageData& softMask) const | QImage PDFAbstractColorSpace::getImage(const PDFImageData& imageData, | ||||||
|  |                                        const PDFImageData& softMask, | ||||||
|  |                                        const PDFCMS* cms, | ||||||
|  |                                        RenderingIntent intent, | ||||||
|  |                                        PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     if (imageData.isValid()) |     if (imageData.isValid()) | ||||||
|     { |     { | ||||||
| @@ -139,7 +173,7 @@ QImage PDFAbstractColorSpace::getImage(const PDFImageData& imageData, const PDFI | |||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
|                         QColor transformedColor = getColor(color); |                         QColor transformedColor = getColor(color, cms, intent, reporter); | ||||||
|                         QRgb rgb = transformedColor.rgb(); |                         QRgb rgb = transformedColor.rgb(); | ||||||
|  |  | ||||||
|                         *outputLine++ = qRed(rgb); |                         *outputLine++ = qRed(rgb); | ||||||
| @@ -206,7 +240,7 @@ QImage PDFAbstractColorSpace::getImage(const PDFImageData& imageData, const PDFI | |||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
|                         QColor transformedColor = getColor(color); |                         QColor transformedColor = getColor(color, cms, intent, reporter); | ||||||
|                         QRgb rgb = transformedColor.rgb(); |                         QRgb rgb = transformedColor.rgb(); | ||||||
|  |  | ||||||
|                         *outputLine++ = qRed(rgb); |                         *outputLine++ = qRed(rgb); | ||||||
| @@ -264,7 +298,7 @@ QImage PDFAbstractColorSpace::getImage(const PDFImageData& imageData, const PDFI | |||||||
|                         { |                         { | ||||||
|                             PDFBitReader::Value value = reader.read(); |                             PDFBitReader::Value value = reader.read(); | ||||||
|  |  | ||||||
|                             // Interpolate value, if it is not empty |                             // Interpolate value, if decode is not empty | ||||||
|                             if (!decode.empty()) |                             if (!decode.empty()) | ||||||
|                             { |                             { | ||||||
|                                 color[k] = interpolate(value, 0.0, max, decode[2 * k], decode[2 * k + 1]); |                                 color[k] = interpolate(value, 0.0, max, decode[2 * k], decode[2 * k + 1]); | ||||||
| @@ -282,7 +316,7 @@ QImage PDFAbstractColorSpace::getImage(const PDFImageData& imageData, const PDFI | |||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
|                         QColor transformedColor = getColor(color); |                         QColor transformedColor = getColor(color, cms, intent, reporter); | ||||||
|                         QRgb rgb = transformedColor.rgb(); |                         QRgb rgb = transformedColor.rgb(); | ||||||
|  |  | ||||||
|                         *outputLine++ = qRed(rgb); |                         *outputLine++ = qRed(rgb); | ||||||
| @@ -305,14 +339,14 @@ QImage PDFAbstractColorSpace::getImage(const PDFImageData& imageData, const PDFI | |||||||
|     return QImage(); |     return QImage(); | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFAbstractColorSpace::getCheckedColor(const PDFColor& color) const | QColor PDFAbstractColorSpace::getCheckedColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     if (getColorComponentCount() != color.size()) |     if (getColorComponentCount() != color.size()) | ||||||
|     { |     { | ||||||
|         throw PDFException(PDFTranslationContext::tr("Invalid number of color components. Expected number is %1, actual number is %2.").arg(static_cast<int>(getColorComponentCount())).arg(static_cast<int>(color.size()))); |         throw PDFException(PDFTranslationContext::tr("Invalid number of color components. Expected number is %1, actual number is %2.").arg(static_cast<int>(getColorComponentCount())).arg(static_cast<int>(color.size()))); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return getColor(color); |     return getColor(color, cms, intent, reporter); | ||||||
| } | } | ||||||
|  |  | ||||||
| QImage PDFAbstractColorSpace::createAlphaMask(const PDFImageData& softMask) | QImage PDFAbstractColorSpace::createAlphaMask(const PDFImageData& softMask) | ||||||
| @@ -609,7 +643,7 @@ PDFColor3 PDFAbstractColorSpace::convertXYZtoRGB(const PDFColor3& xyzColor) | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| QColor PDFXYZColorSpace::getDefaultColor() const | QColor PDFXYZColorSpace::getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     PDFColor color; |     PDFColor color; | ||||||
|     const size_t componentCount = getColorComponentCount(); |     const size_t componentCount = getColorComponentCount(); | ||||||
| @@ -617,7 +651,7 @@ QColor PDFXYZColorSpace::getDefaultColor() const | |||||||
|     { |     { | ||||||
|         color.push_back(0.0f); |         color.push_back(0.0f); | ||||||
|     } |     } | ||||||
|     return getColor(color); |     return getColor(color, cms, intent, reporter); | ||||||
| } | } | ||||||
|  |  | ||||||
| PDFXYZColorSpace::PDFXYZColorSpace(PDFColor3 whitePoint) : | PDFXYZColorSpace::PDFXYZColorSpace(PDFColor3 whitePoint) : | ||||||
| @@ -639,12 +673,20 @@ PDFCalGrayColorSpace::PDFCalGrayColorSpace(PDFColor3 whitePoint, PDFColor3 black | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFCalGrayColorSpace::getColor(const PDFColor& color) const | QColor PDFCalGrayColorSpace::getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     Q_ASSERT(color.size() == getColorComponentCount()); |     Q_ASSERT(color.size() == getColorComponentCount()); | ||||||
|  |  | ||||||
|     const PDFColorComponent A = clip01(color[0]); |     const PDFColorComponent A = clip01(color[0]); | ||||||
|     const PDFColorComponent xyzColor = std::powf(A, m_gamma); |     const PDFColorComponent xyzColor = std::powf(A, m_gamma); | ||||||
|  |  | ||||||
|  |     PDFColor3 xyzColorCMS = { xyzColor, xyzColor, xyzColor }; | ||||||
|  |     QColor cmsColor = cms->getColorFromXYZ(m_whitePoint, xyzColorCMS, intent, reporter); | ||||||
|  |     if (cmsColor.isValid()) | ||||||
|  |     { | ||||||
|  |         return cmsColor; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const PDFColor3 xyzColorMultipliedByWhitePoint = colorMultiplyByFactor(m_whitePoint, xyzColor); |     const PDFColor3 xyzColorMultipliedByWhitePoint = colorMultiplyByFactor(m_whitePoint, xyzColor); | ||||||
|     const PDFColor3 rgb = convertXYZtoRGB(xyzColorMultipliedByWhitePoint); |     const PDFColor3 rgb = convertXYZtoRGB(xyzColorMultipliedByWhitePoint); | ||||||
|     const PDFColor3 calibratedRGB = colorMultiplyByFactors(rgb, m_correctionCoefficients); |     const PDFColor3 calibratedRGB = colorMultiplyByFactors(rgb, m_correctionCoefficients); | ||||||
| @@ -680,13 +722,20 @@ PDFCalRGBColorSpace::PDFCalRGBColorSpace(PDFColor3 whitePoint, PDFColor3 blackPo | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFCalRGBColorSpace::getColor(const PDFColor& color) const | QColor PDFCalRGBColorSpace::getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     Q_ASSERT(color.size() == getColorComponentCount()); |     Q_ASSERT(color.size() == getColorComponentCount()); | ||||||
|  |  | ||||||
|     const PDFColor3 ABC = clip01(PDFColor3{ color[0], color[1], color[2] }); |     const PDFColor3 ABC = clip01(PDFColor3{ color[0], color[1], color[2] }); | ||||||
|     const PDFColor3 ABCwithGamma = colorPowerByFactors(ABC, m_gamma); |     const PDFColor3 ABCwithGamma = colorPowerByFactors(ABC, m_gamma); | ||||||
|     const PDFColor3 XYZ = m_matrix * ABCwithGamma; |     const PDFColor3 XYZ = m_matrix * ABCwithGamma; | ||||||
|  |  | ||||||
|  |     QColor cmsColor = cms->getColorFromXYZ(m_whitePoint, XYZ, intent, reporter); | ||||||
|  |     if (cmsColor.isValid()) | ||||||
|  |     { | ||||||
|  |         return cmsColor; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const PDFColor3 rgb = convertXYZtoRGB(XYZ); |     const PDFColor3 rgb = convertXYZtoRGB(XYZ); | ||||||
|     const PDFColor3 calibratedRGB = colorMultiplyByFactors(rgb, m_correctionCoefficients); |     const PDFColor3 calibratedRGB = colorMultiplyByFactors(rgb, m_correctionCoefficients); | ||||||
|     return fromRGB01(calibratedRGB); |     return fromRGB01(calibratedRGB); | ||||||
| @@ -732,7 +781,7 @@ PDFLabColorSpace::PDFLabColorSpace(PDFColor3 whitePoint, | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFLabColorSpace::getColor(const PDFColor& color) const | QColor PDFLabColorSpace::getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     Q_ASSERT(color.size() == getColorComponentCount()); |     Q_ASSERT(color.size() == getColorComponentCount()); | ||||||
|  |  | ||||||
| @@ -765,6 +814,12 @@ QColor PDFLabColorSpace::getColor(const PDFColor& color) const | |||||||
|     const PDFColorComponent gN = g(N); |     const PDFColorComponent gN = g(N); | ||||||
|     const PDFColor3 gLMN = { gL, gM, gN }; |     const PDFColor3 gLMN = { gL, gM, gN }; | ||||||
|  |  | ||||||
|  |     QColor cmsColor = cms->getColorFromXYZ(m_whitePoint, gLMN, intent, reporter); | ||||||
|  |     if (cmsColor.isValid()) | ||||||
|  |     { | ||||||
|  |         return cmsColor; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const PDFColor3 XYZ = colorMultiplyByFactors(m_whitePoint, gLMN); |     const PDFColor3 XYZ = colorMultiplyByFactors(m_whitePoint, gLMN); | ||||||
|     const PDFColor3 rgb = convertXYZtoRGB(XYZ); |     const PDFColor3 rgb = convertXYZtoRGB(XYZ); | ||||||
|     const PDFColor3 calibratedRGB = colorMultiplyByFactors(rgb, m_correctionCoefficients); |     const PDFColor3 calibratedRGB = colorMultiplyByFactors(rgb, m_correctionCoefficients); | ||||||
| @@ -802,7 +857,7 @@ PDFICCBasedColorSpace::PDFICCBasedColorSpace(PDFColorSpacePointer alternateColor | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFICCBasedColorSpace::getDefaultColor() const | QColor PDFICCBasedColorSpace::getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     PDFColor color; |     PDFColor color; | ||||||
|     const size_t componentCount = getColorComponentCount(); |     const size_t componentCount = getColorComponentCount(); | ||||||
| @@ -810,10 +865,10 @@ QColor PDFICCBasedColorSpace::getDefaultColor() const | |||||||
|     { |     { | ||||||
|         color.push_back(0.0f); |         color.push_back(0.0f); | ||||||
|     } |     } | ||||||
|     return getColor(color); |     return getColor(color, cms, intent, reporter); | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFICCBasedColorSpace::getColor(const PDFColor& color) const | QColor PDFICCBasedColorSpace::getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     Q_ASSERT(color.size() == getColorComponentCount()); |     Q_ASSERT(color.size() == getColorComponentCount()); | ||||||
|  |  | ||||||
| @@ -828,7 +883,7 @@ QColor PDFICCBasedColorSpace::getColor(const PDFColor& color) const | |||||||
|         clippedColor[i] = qBound(m_range[imin], clippedColor[i], m_range[imax]); |         clippedColor[i] = qBound(m_range[imin], clippedColor[i], m_range[imax]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return m_alternateColorSpace->getColor(clippedColor); |     return m_alternateColorSpace->getColor(clippedColor, cms, intent, reporter); | ||||||
| } | } | ||||||
|  |  | ||||||
| size_t PDFICCBasedColorSpace::getColorComponentCount() const | size_t PDFICCBasedColorSpace::getColorComponentCount() const | ||||||
| @@ -914,12 +969,12 @@ PDFIndexedColorSpace::PDFIndexedColorSpace(PDFColorSpacePointer baseColorSpace, | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFIndexedColorSpace::getDefaultColor() const | QColor PDFIndexedColorSpace::getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     return getColor(PDFColor(0.0f)); |     return getColor(PDFColor(0.0f), cms, intent, reporter); | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFIndexedColorSpace::getColor(const PDFColor& color) const | QColor PDFIndexedColorSpace::getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     // Indexed color space value must have exactly one component! |     // Indexed color space value must have exactly one component! | ||||||
|     Q_ASSERT(color.size() == 1); |     Q_ASSERT(color.size() == 1); | ||||||
| @@ -941,7 +996,7 @@ QColor PDFIndexedColorSpace::getColor(const PDFColor& color) const | |||||||
|         decodedColor.push_back(component); |         decodedColor.push_back(component); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return m_baseColorSpace->getColor(decodedColor); |     return m_baseColorSpace->getColor(decodedColor, cms, intent, reporter); | ||||||
| } | } | ||||||
|  |  | ||||||
| size_t PDFIndexedColorSpace::getColorComponentCount() const | size_t PDFIndexedColorSpace::getColorComponentCount() const | ||||||
| @@ -949,7 +1004,11 @@ size_t PDFIndexedColorSpace::getColorComponentCount() const | |||||||
|     return 1; |     return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| QImage PDFIndexedColorSpace::getImage(const PDFImageData& imageData, const PDFImageData& softMask) const | QImage PDFIndexedColorSpace::getImage(const PDFImageData& imageData, | ||||||
|  |                                       const PDFImageData& softMask, | ||||||
|  |                                       const PDFCMS* cms, | ||||||
|  |                                       RenderingIntent intent, | ||||||
|  |                                       PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     if (imageData.isValid()) |     if (imageData.isValid()) | ||||||
|     { |     { | ||||||
| @@ -983,7 +1042,7 @@ QImage PDFIndexedColorSpace::getImage(const PDFImageData& imageData, const PDFIm | |||||||
|                         PDFBitReader::Value index = reader.read(); |                         PDFBitReader::Value index = reader.read(); | ||||||
|                         color[0] = index; |                         color[0] = index; | ||||||
|  |  | ||||||
|                         QColor transformedColor = getColor(color); |                         QColor transformedColor = getColor(color, cms, intent, reporter); | ||||||
|                         QRgb rgb = transformedColor.rgb(); |                         QRgb rgb = transformedColor.rgb(); | ||||||
|  |  | ||||||
|                         *outputLine++ = qRed(rgb); |                         *outputLine++ = qRed(rgb); | ||||||
| @@ -1031,7 +1090,7 @@ QImage PDFIndexedColorSpace::getImage(const PDFImageData& imageData, const PDFIm | |||||||
|                         PDFBitReader::Value index = reader.read(); |                         PDFBitReader::Value index = reader.read(); | ||||||
|                         color[0] = index; |                         color[0] = index; | ||||||
|  |  | ||||||
|                         QColor transformedColor = getColor(color); |                         QColor transformedColor = getColor(color, cms, intent, reporter); | ||||||
|                         QRgb rgb = transformedColor.rgb(); |                         QRgb rgb = transformedColor.rgb(); | ||||||
|  |  | ||||||
|                         *outputLine++ = qRed(rgb); |                         *outputLine++ = qRed(rgb); | ||||||
| @@ -1104,12 +1163,12 @@ PDFSeparationColorSpace::PDFSeparationColorSpace(QByteArray&& colorName, PDFColo | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFSeparationColorSpace::getDefaultColor() const | QColor PDFSeparationColorSpace::getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     return getColor(PDFColor(0.0f)); |     return getColor(PDFColor(0.0f), cms, intent, reporter); | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFSeparationColorSpace::getColor(const PDFColor& color) const | QColor PDFSeparationColorSpace::getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     // Separation color space value must have exactly one component! |     // Separation color space value must have exactly one component! | ||||||
|     Q_ASSERT(color.size() == 1); |     Q_ASSERT(color.size() == 1); | ||||||
| @@ -1126,7 +1185,7 @@ QColor PDFSeparationColorSpace::getColor(const PDFColor& color) const | |||||||
|     { |     { | ||||||
|         PDFColor color; |         PDFColor color; | ||||||
|         std::for_each(outputColor.cbegin(), outputColor.cend(), [&color](double value) { color.push_back(static_cast<float>(value)); }); |         std::for_each(outputColor.cbegin(), outputColor.cend(), [&color](double value) { color.push_back(static_cast<float>(value)); }); | ||||||
|         return m_alternateColorSpace->getColor(color); |         return m_alternateColorSpace->getColor(color, cms, intent, reporter); | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
| @@ -1179,14 +1238,22 @@ const unsigned char* PDFImageData::getRow(unsigned int rowIndex) const | |||||||
|     return data + (rowIndex * m_stride); |     return data + (rowIndex * m_stride); | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFPatternColorSpace::getDefaultColor() const | QColor PDFPatternColorSpace::getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|  |     Q_UNUSED(cms); | ||||||
|  |     Q_UNUSED(intent); | ||||||
|  |     Q_UNUSED(reporter); | ||||||
|  |  | ||||||
|     return QColor(Qt::transparent); |     return QColor(Qt::transparent); | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFPatternColorSpace::getColor(const PDFColor& color) const | QColor PDFPatternColorSpace::getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     Q_UNUSED(color); |     Q_UNUSED(color); | ||||||
|  |     Q_UNUSED(cms); | ||||||
|  |     Q_UNUSED(intent); | ||||||
|  |     Q_UNUSED(reporter); | ||||||
|  |  | ||||||
|     throw PDFException(PDFTranslationContext::tr("Pattern doesn't have defined uniform color.")); |     throw PDFException(PDFTranslationContext::tr("Pattern doesn't have defined uniform color.")); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1213,14 +1280,14 @@ PDFDeviceNColorSpace::PDFDeviceNColorSpace(PDFDeviceNColorSpace::Type type, | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFDeviceNColorSpace::getDefaultColor() const | QColor PDFDeviceNColorSpace::getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     PDFColor color; |     PDFColor color; | ||||||
|     color.resize(getColorComponentCount()); |     color.resize(getColorComponentCount()); | ||||||
|     return getColor(color); |     return getColor(color, cms, intent, reporter); | ||||||
| } | } | ||||||
|  |  | ||||||
| QColor PDFDeviceNColorSpace::getColor(const PDFColor& color) const | QColor PDFDeviceNColorSpace::getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     // Input values |     // Input values | ||||||
|     std::vector<double> inputColor(color.size(), 0.0); |     std::vector<double> inputColor(color.size(), 0.0); | ||||||
| @@ -1238,7 +1305,7 @@ QColor PDFDeviceNColorSpace::getColor(const PDFColor& color) const | |||||||
|     { |     { | ||||||
|         PDFColor color; |         PDFColor color; | ||||||
|         std::for_each(outputColor.cbegin(), outputColor.cend(), [&color](double value) { color.push_back(static_cast<float>(value)); }); |         std::for_each(outputColor.cbegin(), outputColor.cend(), [&color](double value) { color.push_back(static_cast<float>(value)); }); | ||||||
|         return m_alternateColorSpace->getColor(color); |         return m_alternateColorSpace->getColor(color, cms, intent, reporter); | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -27,6 +27,7 @@ | |||||||
|  |  | ||||||
| namespace pdf | namespace pdf | ||||||
| { | { | ||||||
|  | class PDFCMS; | ||||||
| class PDFArray; | class PDFArray; | ||||||
| class PDFObject; | class PDFObject; | ||||||
| class PDFStream; | class PDFStream; | ||||||
| @@ -35,6 +36,7 @@ class PDFDocument; | |||||||
| class PDFDictionary; | class PDFDictionary; | ||||||
| class PDFAbstractColorSpace; | class PDFAbstractColorSpace; | ||||||
| class PDFPatternColorSpace; | class PDFPatternColorSpace; | ||||||
|  | class PDFRenderErrorReporter; | ||||||
|  |  | ||||||
| using PDFColorComponent = float; | using PDFColorComponent = float; | ||||||
| using PDFColor = PDFFlatArray<PDFColorComponent, 4>; | using PDFColor = PDFFlatArray<PDFColorComponent, 4>; | ||||||
| @@ -214,15 +216,45 @@ public: | |||||||
|     explicit PDFAbstractColorSpace() = default; |     explicit PDFAbstractColorSpace() = default; | ||||||
|     virtual ~PDFAbstractColorSpace() = default; |     virtual ~PDFAbstractColorSpace() = default; | ||||||
|  |  | ||||||
|     virtual QColor getDefaultColor() const = 0; |     /// Returns default color for the color space | ||||||
|     virtual QColor getColor(const PDFColor& color) const = 0; |     virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const = 0; | ||||||
|  |  | ||||||
|  |     /// Returns transformed color for given input color. Color is transformed using color | ||||||
|  |     /// management system (cms), if color management system fails, and returns invalid color, | ||||||
|  |     /// then generic solution for color transformation is used (which is often not valid). | ||||||
|  |     /// Caller can also specify rendering intent and error reporter, where color management | ||||||
|  |     /// system can write errors during color transformation. | ||||||
|  |     /// \param color Input color | ||||||
|  |     /// \param cms Color management system | ||||||
|  |     /// \param intent Rendering intent | ||||||
|  |     /// \param reporter Error reporter | ||||||
|  |     virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const = 0; | ||||||
|  |  | ||||||
|  |     /// Returns color component count | ||||||
|     virtual size_t getColorComponentCount() const = 0; |     virtual size_t getColorComponentCount() const = 0; | ||||||
|     virtual QImage getImage(const PDFImageData& imageData, const PDFImageData& softMask) const; |  | ||||||
|  |     /// Transforms image data to result image. | ||||||
|  |     /// \param imageData Image data | ||||||
|  |     /// \param softMask Soft mask (for alpha channel) | ||||||
|  |     /// \param cms Color management system | ||||||
|  |     /// \param intent Rendering intent | ||||||
|  |     /// \param reporter Error reporter | ||||||
|  |     virtual QImage getImage(const PDFImageData& imageData, | ||||||
|  |                             const PDFImageData& softMask, | ||||||
|  |                             const PDFCMS* cms, | ||||||
|  |                             RenderingIntent intent, | ||||||
|  |                             PDFRenderErrorReporter* reporter) const; | ||||||
|  |  | ||||||
|  |     /// If this class is pattern space, returns this, otherwise returns nullptr. | ||||||
|     virtual const PDFPatternColorSpace* asPatternColorSpace() const { return nullptr; } |     virtual const PDFPatternColorSpace* asPatternColorSpace() const { return nullptr; } | ||||||
|  |  | ||||||
|     /// Checks, if number of color components is OK, and if yes, converts them to the QColor value. |     /// Checks, if number of color components is OK, and if yes, converts them to the QColor value. | ||||||
|     /// If they are not OK, exception is thrown. |     /// If they are not OK, exception is thrown. \sa getColor | ||||||
|     QColor getCheckedColor(const PDFColor& color) const; |     /// \param color Input color | ||||||
|  |     /// \param cms Color management system | ||||||
|  |     /// \param intent Rendering intent | ||||||
|  |     /// \param reporter Error reporter | ||||||
|  |     QColor getCheckedColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const; | ||||||
|  |  | ||||||
|     /// Creates alpha mask from soft image data. Exception is thrown, if something fails. |     /// Creates alpha mask from soft image data. Exception is thrown, if something fails. | ||||||
|     /// \param softMask Soft mask |     /// \param softMask Soft mask | ||||||
| @@ -365,8 +397,8 @@ public: | |||||||
|     explicit PDFDeviceGrayColorSpace() = default; |     explicit PDFDeviceGrayColorSpace() = default; | ||||||
|     virtual ~PDFDeviceGrayColorSpace() = default; |     virtual ~PDFDeviceGrayColorSpace() = default; | ||||||
|  |  | ||||||
|     virtual QColor getDefaultColor() const override; |     virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual QColor getColor(const PDFColor& color) const override; |     virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual size_t getColorComponentCount() const override; |     virtual size_t getColorComponentCount() const override; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -376,8 +408,8 @@ public: | |||||||
|     explicit PDFDeviceRGBColorSpace() = default; |     explicit PDFDeviceRGBColorSpace() = default; | ||||||
|     virtual ~PDFDeviceRGBColorSpace() = default; |     virtual ~PDFDeviceRGBColorSpace() = default; | ||||||
|  |  | ||||||
|     virtual QColor getDefaultColor() const override; |     virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual QColor getColor(const PDFColor& color) const override; |     virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual size_t getColorComponentCount() const override; |     virtual size_t getColorComponentCount() const override; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -387,15 +419,15 @@ public: | |||||||
|     explicit PDFDeviceCMYKColorSpace() = default; |     explicit PDFDeviceCMYKColorSpace() = default; | ||||||
|     virtual ~PDFDeviceCMYKColorSpace() = default; |     virtual ~PDFDeviceCMYKColorSpace() = default; | ||||||
|  |  | ||||||
|     virtual QColor getDefaultColor() const override; |     virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual QColor getColor(const PDFColor& color) const override; |     virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual size_t getColorComponentCount() const override; |     virtual size_t getColorComponentCount() const override; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class PDFXYZColorSpace : public PDFAbstractColorSpace | class PDFXYZColorSpace : public PDFAbstractColorSpace | ||||||
| { | { | ||||||
| public: | public: | ||||||
|     virtual QColor getDefaultColor() const override; |     virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|  |  | ||||||
| protected: | protected: | ||||||
|     explicit PDFXYZColorSpace(PDFColor3 whitePoint); |     explicit PDFXYZColorSpace(PDFColor3 whitePoint); | ||||||
| @@ -416,7 +448,7 @@ public: | |||||||
|     explicit PDFCalGrayColorSpace(PDFColor3 whitePoint, PDFColor3 blackPoint, PDFColorComponent gamma); |     explicit PDFCalGrayColorSpace(PDFColor3 whitePoint, PDFColor3 blackPoint, PDFColorComponent gamma); | ||||||
|     virtual ~PDFCalGrayColorSpace() = default; |     virtual ~PDFCalGrayColorSpace() = default; | ||||||
|  |  | ||||||
|     virtual QColor getColor(const PDFColor& color) const override; |     virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual size_t getColorComponentCount() const override; |     virtual size_t getColorComponentCount() const override; | ||||||
|  |  | ||||||
|     /// Creates CalGray color space from provided values. |     /// Creates CalGray color space from provided values. | ||||||
| @@ -435,7 +467,7 @@ public: | |||||||
|     explicit PDFCalRGBColorSpace(PDFColor3 whitePoint, PDFColor3 blackPoint, PDFColor3 gamma, PDFColorComponentMatrix_3x3 matrix); |     explicit PDFCalRGBColorSpace(PDFColor3 whitePoint, PDFColor3 blackPoint, PDFColor3 gamma, PDFColorComponentMatrix_3x3 matrix); | ||||||
|     virtual ~PDFCalRGBColorSpace() = default; |     virtual ~PDFCalRGBColorSpace() = default; | ||||||
|  |  | ||||||
|     virtual QColor getColor(const PDFColor& color) const override; |     virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual size_t getColorComponentCount() const override; |     virtual size_t getColorComponentCount() const override; | ||||||
|  |  | ||||||
|     /// Creates CalRGB color space from provided values. |     /// Creates CalRGB color space from provided values. | ||||||
| @@ -455,7 +487,7 @@ public: | |||||||
|     explicit PDFLabColorSpace(PDFColor3 whitePoint, PDFColor3 blackPoint, PDFColorComponent aMin, PDFColorComponent aMax, PDFColorComponent bMin, PDFColorComponent bMax); |     explicit PDFLabColorSpace(PDFColor3 whitePoint, PDFColor3 blackPoint, PDFColorComponent aMin, PDFColorComponent aMax, PDFColorComponent bMin, PDFColorComponent bMax); | ||||||
|     virtual ~PDFLabColorSpace() = default; |     virtual ~PDFLabColorSpace() = default; | ||||||
|  |  | ||||||
|     virtual QColor getColor(const PDFColor& color) const override; |     virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual size_t getColorComponentCount() const override; |     virtual size_t getColorComponentCount() const override; | ||||||
|  |  | ||||||
|     /// Creates Lab color space from provided values. |     /// Creates Lab color space from provided values. | ||||||
| @@ -481,8 +513,8 @@ public: | |||||||
|     explicit PDFICCBasedColorSpace(PDFColorSpacePointer alternateColorSpace, Ranges range); |     explicit PDFICCBasedColorSpace(PDFColorSpacePointer alternateColorSpace, Ranges range); | ||||||
|     virtual ~PDFICCBasedColorSpace() = default; |     virtual ~PDFICCBasedColorSpace() = default; | ||||||
|  |  | ||||||
|     virtual QColor getDefaultColor() const override; |     virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual QColor getColor(const PDFColor& color) const override; |     virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual size_t getColorComponentCount() const override; |     virtual size_t getColorComponentCount() const override; | ||||||
|  |  | ||||||
|     /// Creates ICC based color space from provided values. |     /// Creates ICC based color space from provided values. | ||||||
| @@ -503,10 +535,14 @@ public: | |||||||
|     explicit PDFIndexedColorSpace(PDFColorSpacePointer baseColorSpace, QByteArray&& colors, int maxValue); |     explicit PDFIndexedColorSpace(PDFColorSpacePointer baseColorSpace, QByteArray&& colors, int maxValue); | ||||||
|     virtual ~PDFIndexedColorSpace() = default; |     virtual ~PDFIndexedColorSpace() = default; | ||||||
|  |  | ||||||
|     virtual QColor getDefaultColor() const override; |     virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual QColor getColor(const PDFColor& color) const override; |     virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual size_t getColorComponentCount() const override; |     virtual size_t getColorComponentCount() const override; | ||||||
|     virtual QImage getImage(const PDFImageData& imageData, const PDFImageData& softMask) const override; |     virtual QImage getImage(const PDFImageData& imageData, | ||||||
|  |                             const PDFImageData& softMask, | ||||||
|  |                             const PDFCMS* cms, | ||||||
|  |                             RenderingIntent intent, | ||||||
|  |                             PDFRenderErrorReporter* reporter) const override; | ||||||
|  |  | ||||||
|     /// Creates indexed color space from provided values. |     /// Creates indexed color space from provided values. | ||||||
|     /// \param colorSpaceDictionary Color space dictionary |     /// \param colorSpaceDictionary Color space dictionary | ||||||
| @@ -530,8 +566,8 @@ public: | |||||||
|     explicit PDFSeparationColorSpace(QByteArray&& colorName, PDFColorSpacePointer alternateColorSpace, PDFFunctionPtr tintTransform); |     explicit PDFSeparationColorSpace(QByteArray&& colorName, PDFColorSpacePointer alternateColorSpace, PDFFunctionPtr tintTransform); | ||||||
|     virtual ~PDFSeparationColorSpace() = default; |     virtual ~PDFSeparationColorSpace() = default; | ||||||
|  |  | ||||||
|     virtual QColor getDefaultColor() const override; |     virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual QColor getColor(const PDFColor& color) const override; |     virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual size_t getColorComponentCount() const override; |     virtual size_t getColorComponentCount() const override; | ||||||
|  |  | ||||||
|     /// Creates separation color space from provided values. |     /// Creates separation color space from provided values. | ||||||
| @@ -576,8 +612,8 @@ public: | |||||||
|                                   std::vector<QByteArray> processColorSpaceComponents); |                                   std::vector<QByteArray> processColorSpaceComponents); | ||||||
|     virtual ~PDFDeviceNColorSpace() = default; |     virtual ~PDFDeviceNColorSpace() = default; | ||||||
|  |  | ||||||
|     virtual QColor getDefaultColor() const override; |     virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual QColor getColor(const PDFColor& color) const override; |     virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual size_t getColorComponentCount() const override; |     virtual size_t getColorComponentCount() const override; | ||||||
|  |  | ||||||
|     /// Returns type of DeviceN color space |     /// Returns type of DeviceN color space | ||||||
| @@ -613,8 +649,8 @@ public: | |||||||
|  |  | ||||||
|     virtual ~PDFPatternColorSpace() override = default; |     virtual ~PDFPatternColorSpace() override = default; | ||||||
|  |  | ||||||
|     virtual QColor getDefaultColor() const override; |     virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual QColor getColor(const PDFColor& color) const override; |     virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|     virtual size_t getColorComponentCount() const override; |     virtual size_t getColorComponentCount() const override; | ||||||
|     virtual const PDFPatternColorSpace* asPatternColorSpace() const override { return this; } |     virtual const PDFPatternColorSpace* asPatternColorSpace() const override { return this; } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ | |||||||
| //    along with PDFForQt.  If not, see <https://www.gnu.org/licenses/>. | //    along with PDFForQt.  If not, see <https://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
| #include "pdfcompiler.h" | #include "pdfcompiler.h" | ||||||
|  | #include "pdfcms.h" | ||||||
| #include "pdfdrawspacecontroller.h" | #include "pdfdrawspacecontroller.h" | ||||||
|  |  | ||||||
| #include <QtConcurrent/QtConcurrent> | #include <QtConcurrent/QtConcurrent> | ||||||
| @@ -112,7 +113,8 @@ const PDFPrecompiledPage* PDFAsynchronousPageCompiler::getCompiledPage(PDFIntege | |||||||
|         auto compilePage = [this, pageIndex]() -> PDFPrecompiledPage |         auto compilePage = [this, pageIndex]() -> PDFPrecompiledPage | ||||||
|         { |         { | ||||||
|             PDFPrecompiledPage compiledPage; |             PDFPrecompiledPage compiledPage; | ||||||
|             PDFRenderer renderer(m_proxy->getDocument(), m_proxy->getFontCache(), m_proxy->getOptionalContentActivity(), m_proxy->getFeatures(), m_proxy->getMeshQualitySettings()); |             PDFCMSPointer cms = m_proxy->getCMSManager()->getCurrentCMS(); | ||||||
|  |             PDFRenderer renderer(m_proxy->getDocument(), m_proxy->getFontCache(), cms.data(), m_proxy->getOptionalContentActivity(), m_proxy->getFeatures(), m_proxy->getMeshQualitySettings()); | ||||||
|             renderer.compile(&compiledPage, pageIndex); |             renderer.compile(&compiledPage, pageIndex); | ||||||
|             return compiledPage; |             return compiledPage; | ||||||
|         }; |         }; | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ | |||||||
| #include "pdfpainter.h" | #include "pdfpainter.h" | ||||||
| #include "pdfcompiler.h" | #include "pdfcompiler.h" | ||||||
| #include "pdfconstants.h" | #include "pdfconstants.h" | ||||||
|  | #include "pdfcms.h" | ||||||
|  |  | ||||||
| #include <QPainter> | #include <QPainter> | ||||||
|  |  | ||||||
| @@ -429,6 +430,7 @@ void PDFDrawWidgetProxy::init(PDFWidget* widget) | |||||||
|     connect(m_horizontalScrollbar, &QScrollBar::valueChanged, this, &PDFDrawWidgetProxy::onHorizontalScrollbarValueChanged); |     connect(m_horizontalScrollbar, &QScrollBar::valueChanged, this, &PDFDrawWidgetProxy::onHorizontalScrollbarValueChanged); | ||||||
|     connect(m_verticalScrollbar, &QScrollBar::valueChanged, this, &PDFDrawWidgetProxy::onVerticalScrollbarValueChanged); |     connect(m_verticalScrollbar, &QScrollBar::valueChanged, this, &PDFDrawWidgetProxy::onVerticalScrollbarValueChanged); | ||||||
|     connect(this, &PDFDrawWidgetProxy::drawSpaceChanged, this, &PDFDrawWidgetProxy::repaintNeeded); |     connect(this, &PDFDrawWidgetProxy::drawSpaceChanged, this, &PDFDrawWidgetProxy::repaintNeeded); | ||||||
|  |     connect(getCMSManager(), &PDFCMSManager::colorManagementSystemChanged, this, &PDFDrawWidgetProxy::onColorManagementSystemChanged); | ||||||
|  |  | ||||||
|     // We must update the draw space - widget has been set |     // We must update the draw space - widget has been set | ||||||
|     update(); |     update(); | ||||||
| @@ -595,6 +597,9 @@ void PDFDrawWidgetProxy::draw(QPainter* painter, QRect rect) | |||||||
| { | { | ||||||
|     painter->fillRect(rect, Qt::lightGray); |     painter->fillRect(rect, Qt::lightGray); | ||||||
|  |  | ||||||
|  |     // Use current paper color (it can be a bit different from white) | ||||||
|  |     QColor paperColor = getCMSManager()->getCurrentCMS()->getPaperColor(); | ||||||
|  |  | ||||||
|     // Iterate trough pages and display them on the painter device |     // Iterate trough pages and display them on the painter device | ||||||
|     for (const LayoutItem& item : m_layout.items) |     for (const LayoutItem& item : m_layout.items) | ||||||
|     { |     { | ||||||
| @@ -604,8 +609,8 @@ void PDFDrawWidgetProxy::draw(QPainter* painter, QRect rect) | |||||||
|         QRect placedRect = item.pageRect.translated(m_horizontalOffset - m_layout.blockRect.left(), m_verticalOffset - m_layout.blockRect.top()); |         QRect placedRect = item.pageRect.translated(m_horizontalOffset - m_layout.blockRect.left(), m_verticalOffset - m_layout.blockRect.top()); | ||||||
|         if (placedRect.intersects(rect)) |         if (placedRect.intersects(rect)) | ||||||
|         { |         { | ||||||
|             // Clear the page space by white color |             // Clear the page space by paper color | ||||||
|             painter->fillRect(placedRect, Qt::white); |             painter->fillRect(placedRect, paperColor); | ||||||
|  |  | ||||||
|             const PDFPrecompiledPage* compiledPage = m_compiler->getCompiledPage(item.pageIndex, true); |             const PDFPrecompiledPage* compiledPage = m_compiler->getCompiledPage(item.pageIndex, true); | ||||||
|             if (compiledPage && compiledPage->isValid()) |             if (compiledPage && compiledPage->isValid()) | ||||||
| @@ -1072,6 +1077,11 @@ PDFRenderer::Features PDFDrawWidgetProxy::getFeatures() const | |||||||
|     return m_features; |     return m_features; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | const PDFCMSManager* PDFDrawWidgetProxy::getCMSManager() const | ||||||
|  | { | ||||||
|  |     return m_widget->getCMSManager(); | ||||||
|  | } | ||||||
|  |  | ||||||
| void PDFDrawWidgetProxy::setFeatures(PDFRenderer::Features features) | void PDFDrawWidgetProxy::setFeatures(PDFRenderer::Features features) | ||||||
| { | { | ||||||
|     if (m_features != features) |     if (m_features != features) | ||||||
| @@ -1116,4 +1126,10 @@ void PDFDrawWidgetProxy::setColorTolerance(PDFReal colorTolerance) | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void PDFDrawWidgetProxy::onColorManagementSystemChanged() | ||||||
|  | { | ||||||
|  |     m_compiler->reset(); | ||||||
|  |     emit pageImageChanged(true, { }); | ||||||
|  | } | ||||||
|  |  | ||||||
| }   // namespace pdf | }   // namespace pdf | ||||||
|   | |||||||
| @@ -34,6 +34,7 @@ namespace pdf | |||||||
| { | { | ||||||
| class PDFWidget; | class PDFWidget; | ||||||
| class IDrawWidget; | class IDrawWidget; | ||||||
|  | class PDFCMSManager; | ||||||
| class PDFAsynchronousPageCompiler; | class PDFAsynchronousPageCompiler; | ||||||
|  |  | ||||||
| /// This class controls draw space - page layout. Pages are divided into blocks | /// This class controls draw space - page layout. Pages are divided into blocks | ||||||
| @@ -272,6 +273,7 @@ public: | |||||||
|     PDFRenderer::Features getFeatures() const; |     PDFRenderer::Features getFeatures() const; | ||||||
|     const PDFMeshQualitySettings& getMeshQualitySettings() const { return m_meshQualitySettings; } |     const PDFMeshQualitySettings& getMeshQualitySettings() const { return m_meshQualitySettings; } | ||||||
|     PDFAsynchronousPageCompiler* getCompiler() const { return m_compiler; } |     PDFAsynchronousPageCompiler* getCompiler() const { return m_compiler; } | ||||||
|  |     const PDFCMSManager* getCMSManager() const; | ||||||
|  |  | ||||||
|     void setFeatures(PDFRenderer::Features features); |     void setFeatures(PDFRenderer::Features features); | ||||||
|     void setPreferredMeshResolutionRatio(PDFReal ratio); |     void setPreferredMeshResolutionRatio(PDFReal ratio); | ||||||
| @@ -324,6 +326,7 @@ private: | |||||||
|     /// Converts rectangle from device space to the pixel space |     /// Converts rectangle from device space to the pixel space | ||||||
|     QRectF fromDeviceSpace(const QRectF& rect) const; |     QRectF fromDeviceSpace(const QRectF& rect) const; | ||||||
|  |  | ||||||
|  |     void onColorManagementSystemChanged(); | ||||||
|     void onHorizontalScrollbarValueChanged(int value); |     void onHorizontalScrollbarValueChanged(int value); | ||||||
|     void onVerticalScrollbarValueChanged(int value); |     void onVerticalScrollbarValueChanged(int value); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -28,8 +28,9 @@ | |||||||
| namespace pdf | namespace pdf | ||||||
| { | { | ||||||
|  |  | ||||||
| PDFWidget::PDFWidget(RendererEngine engine, int samplesCount, QWidget* parent) : | PDFWidget::PDFWidget(const PDFCMSManager* cmsManager, RendererEngine engine, int samplesCount, QWidget* parent) : | ||||||
|     QWidget(parent), |     QWidget(parent), | ||||||
|  |     m_cmsManager(cmsManager), | ||||||
|     m_drawWidget(nullptr), |     m_drawWidget(nullptr), | ||||||
|     m_horizontalScrollBar(nullptr), |     m_horizontalScrollBar(nullptr), | ||||||
|     m_verticalScrollBar(nullptr), |     m_verticalScrollBar(nullptr), | ||||||
|   | |||||||
| @@ -28,6 +28,7 @@ | |||||||
| namespace pdf | namespace pdf | ||||||
| { | { | ||||||
| class PDFDocument; | class PDFDocument; | ||||||
|  | class PDFCMSManager; | ||||||
| class PDFDrawWidget; | class PDFDrawWidget; | ||||||
| class PDFDrawWidgetProxy; | class PDFDrawWidgetProxy; | ||||||
|  |  | ||||||
| @@ -48,9 +49,10 @@ class PDFFORQTLIBSHARED_EXPORT PDFWidget : public QWidget | |||||||
|  |  | ||||||
| public: | public: | ||||||
|     /// Constructs new PDFWidget. |     /// Constructs new PDFWidget. | ||||||
|  |     /// \param cmsManager Color management system manager | ||||||
|     /// \param engine Rendering engine type |     /// \param engine Rendering engine type | ||||||
|     /// \param samplesCount Samples count for rendering engine MSAA antialiasing |     /// \param samplesCount Samples count for rendering engine MSAA antialiasing | ||||||
|     explicit PDFWidget(RendererEngine engine, int samplesCount, QWidget* parent); |     explicit PDFWidget(const PDFCMSManager* cmsManager, RendererEngine engine, int samplesCount, QWidget* parent); | ||||||
|     virtual ~PDFWidget() override; |     virtual ~PDFWidget() override; | ||||||
|  |  | ||||||
|     using PageRenderingErrors = std::map<PDFInteger, QList<PDFRenderError>>; |     using PageRenderingErrors = std::map<PDFInteger, QList<PDFRenderError>>; | ||||||
| @@ -74,6 +76,7 @@ public: | |||||||
|     /// \param instancedFontCacheLimit Instanced font cache limit [-] |     /// \param instancedFontCacheLimit Instanced font cache limit [-] | ||||||
|     void updateCacheLimits(int compiledPageCacheLimit, int thumbnailsCacheLimit, int fontCacheLimit, int instancedFontCacheLimit); |     void updateCacheLimits(int compiledPageCacheLimit, int thumbnailsCacheLimit, int fontCacheLimit, int instancedFontCacheLimit); | ||||||
|  |  | ||||||
|  |     const PDFCMSManager* getCMSManager() const { return m_cmsManager; } | ||||||
|     IDrawWidget* getDrawWidget() const { return m_drawWidget; } |     IDrawWidget* getDrawWidget() const { return m_drawWidget; } | ||||||
|     QScrollBar* getHorizontalScrollbar() const { return m_horizontalScrollBar; } |     QScrollBar* getHorizontalScrollbar() const { return m_horizontalScrollBar; } | ||||||
|     QScrollBar* getVerticalScrollbar() const { return m_verticalScrollBar; } |     QScrollBar* getVerticalScrollbar() const { return m_verticalScrollBar; } | ||||||
| @@ -91,6 +94,7 @@ private: | |||||||
|  |  | ||||||
|     IDrawWidget* createDrawWidget(RendererEngine rendererEngine, int samplesCount); |     IDrawWidget* createDrawWidget(RendererEngine rendererEngine, int samplesCount); | ||||||
|  |  | ||||||
|  |     const PDFCMSManager* m_cmsManager; | ||||||
|     IDrawWidget* m_drawWidget; |     IDrawWidget* m_drawWidget; | ||||||
|     QScrollBar* m_horizontalScrollBar; |     QScrollBar* m_horizontalScrollBar; | ||||||
|     QScrollBar* m_verticalScrollBar; |     QScrollBar* m_verticalScrollBar; | ||||||
|   | |||||||
| @@ -87,6 +87,12 @@ public: | |||||||
|     /// \param type Error type |     /// \param type Error type | ||||||
|     /// \param message Error message |     /// \param message Error message | ||||||
|     virtual void reportRenderError(RenderErrorType type, QString message) = 0; |     virtual void reportRenderError(RenderErrorType type, QString message) = 0; | ||||||
|  |  | ||||||
|  |     /// Reports render error, but only once - if same error was already reported, | ||||||
|  |     /// then no new error is reported. | ||||||
|  |     /// \param type Error type | ||||||
|  |     /// \param message Error message | ||||||
|  |     virtual void reportRenderErrorOnce(RenderErrorType type, QString message) = 0; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }   // namespace pdf | }   // namespace pdf | ||||||
|   | |||||||
| @@ -725,12 +725,12 @@ PDFImage PDFImage::createImage(const PDFDocument* document, | |||||||
|     return image; |     return image; | ||||||
| } | } | ||||||
|  |  | ||||||
| QImage PDFImage::getImage() const | QImage PDFImage::getImage(const PDFCMS* cms, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     const bool isImageMask = m_imageData.getMaskingType() == PDFImageData::MaskingType::ImageMask; |     const bool isImageMask = m_imageData.getMaskingType() == PDFImageData::MaskingType::ImageMask; | ||||||
|     if (m_colorSpace && !isImageMask) |     if (m_colorSpace && !isImageMask) | ||||||
|     { |     { | ||||||
|         return m_colorSpace->getImage(m_imageData, m_softMask); |         return m_colorSpace->getImage(m_imageData, m_softMask, cms, m_renderingIntent, reporter); | ||||||
|     } |     } | ||||||
|     else if (isImageMask) |     else if (isImageMask) | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -49,7 +49,7 @@ public: | |||||||
|                                 PDFRenderErrorReporter* errorReporter); |                                 PDFRenderErrorReporter* errorReporter); | ||||||
|  |  | ||||||
|     /// Returns image transformed from image data and color space |     /// Returns image transformed from image data and color space | ||||||
|     QImage getImage() const; |     QImage getImage(const PDFCMS* cms, PDFRenderErrorReporter* reporter) const; | ||||||
|  |  | ||||||
|     /// Returns rendering intent of the image |     /// Returns rendering intent of the image | ||||||
|     RenderingIntent getRenderingIntent() const { return m_renderingIntent; } |     RenderingIntent getRenderingIntent() const { return m_renderingIntent; } | ||||||
|   | |||||||
| @@ -183,12 +183,14 @@ void PDFPageContentProcessor::initDictionaries(const PDFObject& resourcesObject) | |||||||
| PDFPageContentProcessor::PDFPageContentProcessor(const PDFPage* page, | PDFPageContentProcessor::PDFPageContentProcessor(const PDFPage* page, | ||||||
|                                                  const PDFDocument* document, |                                                  const PDFDocument* document, | ||||||
|                                                  const PDFFontCache* fontCache, |                                                  const PDFFontCache* fontCache, | ||||||
|  |                                                  const PDFCMS* CMS, | ||||||
|                                                  const PDFOptionalContentActivity* optionalContentActivity, |                                                  const PDFOptionalContentActivity* optionalContentActivity, | ||||||
|                                                  QMatrix pagePointToDevicePointMatrix, |                                                  QMatrix pagePointToDevicePointMatrix, | ||||||
|                                                  const PDFMeshQualitySettings& meshQualitySettings) : |                                                  const PDFMeshQualitySettings& meshQualitySettings) : | ||||||
|     m_page(page), |     m_page(page), | ||||||
|     m_document(document), |     m_document(document), | ||||||
|     m_fontCache(fontCache), |     m_fontCache(fontCache), | ||||||
|  |     m_CMS(CMS), | ||||||
|     m_optionalContentActivity(optionalContentActivity), |     m_optionalContentActivity(optionalContentActivity), | ||||||
|     m_colorSpaceDictionary(nullptr), |     m_colorSpaceDictionary(nullptr), | ||||||
|     m_fontDictionary(nullptr), |     m_fontDictionary(nullptr), | ||||||
| @@ -244,9 +246,9 @@ QList<PDFRenderError> PDFPageContentProcessor::processContents() | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     m_graphicState.setStrokeColorSpace(m_deviceGrayColorSpace); |     m_graphicState.setStrokeColorSpace(m_deviceGrayColorSpace); | ||||||
|     m_graphicState.setStrokeColor(m_deviceGrayColorSpace->getDefaultColor()); |     m_graphicState.setStrokeColor(m_deviceGrayColorSpace->getDefaultColor(m_CMS, m_graphicState.getRenderingIntent(), this)); | ||||||
|     m_graphicState.setFillColorSpace(m_deviceGrayColorSpace); |     m_graphicState.setFillColorSpace(m_deviceGrayColorSpace); | ||||||
|     m_graphicState.setFillColor(m_deviceGrayColorSpace->getDefaultColor()); |     m_graphicState.setFillColor(m_deviceGrayColorSpace->getDefaultColor(m_CMS, m_graphicState.getRenderingIntent(), this)); | ||||||
|     m_graphicState.setStateFlags(PDFPageContentProcessorState::StateAll); |     m_graphicState.setStateFlags(PDFPageContentProcessorState::StateAll); | ||||||
|     updateGraphicState(); |     updateGraphicState(); | ||||||
|  |  | ||||||
| @@ -674,7 +676,7 @@ void PDFPageContentProcessor::processPathPainting(const QPainterPath& path, bool | |||||||
|                     settings.userSpaceToDeviceSpaceMatrix = getPatternBaseMatrix(); |                     settings.userSpaceToDeviceSpaceMatrix = getPatternBaseMatrix(); | ||||||
|                     settings.initResolution(); |                     settings.initResolution(); | ||||||
|  |  | ||||||
|                     PDFMesh mesh = shadingPattern->createMesh(settings); |                     PDFMesh mesh = shadingPattern->createMesh(settings, m_CMS, m_graphicState.getRenderingIntent(), this); | ||||||
|  |  | ||||||
|                     // Now, merge the current path to the mesh clipping path |                     // Now, merge the current path to the mesh clipping path | ||||||
|                     QPainterPath boundingPath = mesh.getBoundingPath(); |                     QPainterPath boundingPath = mesh.getBoundingPath(); | ||||||
| @@ -763,7 +765,7 @@ void PDFPageContentProcessor::processPathPainting(const QPainterPath& path, bool | |||||||
|                     settings.userSpaceToDeviceSpaceMatrix = getPatternBaseMatrix(); |                     settings.userSpaceToDeviceSpaceMatrix = getPatternBaseMatrix(); | ||||||
|                     settings.initResolution(); |                     settings.initResolution(); | ||||||
|  |  | ||||||
|                     PDFMesh mesh = shadingPattern->createMesh(settings); |                     PDFMesh mesh = shadingPattern->createMesh(settings, m_CMS, m_graphicState.getRenderingIntent(), this); | ||||||
|  |  | ||||||
|                     // We must stroke the path. |                     // We must stroke the path. | ||||||
|                     QPainterPathStroker stroker; |                     QPainterPathStroker stroker; | ||||||
| @@ -856,7 +858,7 @@ void PDFPageContentProcessor::processTillingPatternPainting(const PDFTilingPatte | |||||||
|         m_graphicState.setStrokeColorSpace(uncoloredPatternColorSpace); |         m_graphicState.setStrokeColorSpace(uncoloredPatternColorSpace); | ||||||
|         m_graphicState.setFillColorSpace(uncoloredPatternColorSpace); |         m_graphicState.setFillColorSpace(uncoloredPatternColorSpace); | ||||||
|  |  | ||||||
|         QColor color = uncoloredPatternColorSpace->getCheckedColor(uncoloredPatternColor); |         QColor color = uncoloredPatternColorSpace->getCheckedColor(uncoloredPatternColor, m_CMS, m_graphicState.getRenderingIntent(), this); | ||||||
|         m_graphicState.setStrokeColor(color); |         m_graphicState.setStrokeColor(color); | ||||||
|         m_graphicState.setFillColor(color); |         m_graphicState.setFillColor(color); | ||||||
|     } |     } | ||||||
| @@ -866,7 +868,7 @@ void PDFPageContentProcessor::processTillingPatternPainting(const PDFTilingPatte | |||||||
|         m_graphicState.setStrokeColorSpace(m_deviceGrayColorSpace); |         m_graphicState.setStrokeColorSpace(m_deviceGrayColorSpace); | ||||||
|         m_graphicState.setFillColorSpace(m_deviceGrayColorSpace); |         m_graphicState.setFillColorSpace(m_deviceGrayColorSpace); | ||||||
|  |  | ||||||
|         QColor color = m_deviceGrayColorSpace->getDefaultColor(); |         QColor color = m_deviceGrayColorSpace->getDefaultColor(m_CMS, m_graphicState.getRenderingIntent(), this); | ||||||
|         m_graphicState.setStrokeColor(color); |         m_graphicState.setStrokeColor(color); | ||||||
|         m_graphicState.setFillColor(color); |         m_graphicState.setFillColor(color); | ||||||
|     } |     } | ||||||
| @@ -2085,7 +2087,7 @@ void PDFPageContentProcessor::operatorColorSetStrokingColorSpace(PDFPageContentP | |||||||
|     { |     { | ||||||
|         // We must also set default color (it can depend on the color space) |         // We must also set default color (it can depend on the color space) | ||||||
|         m_graphicState.setStrokeColorSpace(colorSpace); |         m_graphicState.setStrokeColorSpace(colorSpace); | ||||||
|         m_graphicState.setStrokeColor(colorSpace->getDefaultColor()); |         m_graphicState.setStrokeColor(colorSpace->getDefaultColor(m_CMS, m_graphicState.getRenderingIntent(), this)); | ||||||
|         updateGraphicState(); |         updateGraphicState(); | ||||||
|         checkStrokingColor(); |         checkStrokingColor(); | ||||||
|     } |     } | ||||||
| @@ -2108,7 +2110,7 @@ void PDFPageContentProcessor::operatorColorSetFillingColorSpace(PDFOperandName n | |||||||
|     { |     { | ||||||
|         // We must also set default color (it can depend on the color space) |         // We must also set default color (it can depend on the color space) | ||||||
|         m_graphicState.setFillColorSpace(colorSpace); |         m_graphicState.setFillColorSpace(colorSpace); | ||||||
|         m_graphicState.setFillColor(colorSpace->getDefaultColor()); |         m_graphicState.setFillColor(colorSpace->getDefaultColor(m_CMS, m_graphicState.getRenderingIntent(), this)); | ||||||
|         updateGraphicState(); |         updateGraphicState(); | ||||||
|         checkFillingColor(); |         checkFillingColor(); | ||||||
|     } |     } | ||||||
| @@ -2137,7 +2139,7 @@ void PDFPageContentProcessor::operatorColorSetStrokingColor() | |||||||
|         { |         { | ||||||
|             color.push_back(readOperand<PDFReal>(i)); |             color.push_back(readOperand<PDFReal>(i)); | ||||||
|         } |         } | ||||||
|         m_graphicState.setStrokeColor(colorSpace->getColor(color)); |         m_graphicState.setStrokeColor(colorSpace->getColor(color, m_CMS, m_graphicState.getRenderingIntent(), this)); | ||||||
|         updateGraphicState(); |         updateGraphicState(); | ||||||
|         checkStrokingColor(); |         checkStrokingColor(); | ||||||
|     } |     } | ||||||
| @@ -2177,7 +2179,7 @@ void PDFPageContentProcessor::operatorColorSetStrokingColorN() | |||||||
|             if (m_patternDictionary && m_patternDictionary->hasKey(name.name)) |             if (m_patternDictionary && m_patternDictionary->hasKey(name.name)) | ||||||
|             { |             { | ||||||
|                 // Create the pattern |                 // Create the pattern | ||||||
|                 PDFPatternPtr pattern = PDFPattern::createPattern(m_colorSpaceDictionary, m_document, m_patternDictionary->get(name.name)); |                 PDFPatternPtr pattern = PDFPattern::createPattern(m_colorSpaceDictionary, m_document, m_patternDictionary->get(name.name), m_CMS, m_graphicState.getRenderingIntent(), this); | ||||||
|                 m_graphicState.setStrokeColorSpace(PDFColorSpacePointer(new PDFPatternColorSpace(qMove(pattern), qMove(uncoloredColorSpace), qMove(uncoloredPatternColor)))); |                 m_graphicState.setStrokeColorSpace(PDFColorSpacePointer(new PDFPatternColorSpace(qMove(pattern), qMove(uncoloredColorSpace), qMove(uncoloredPatternColor)))); | ||||||
|                 updateGraphicState(); |                 updateGraphicState(); | ||||||
|                 return; |                 return; | ||||||
| @@ -2215,7 +2217,7 @@ void PDFPageContentProcessor::operatorColorSetFillingColor() | |||||||
|         { |         { | ||||||
|             color.push_back(readOperand<PDFReal>(i)); |             color.push_back(readOperand<PDFReal>(i)); | ||||||
|         } |         } | ||||||
|         m_graphicState.setFillColor(colorSpace->getColor(color)); |         m_graphicState.setFillColor(colorSpace->getColor(color, m_CMS, m_graphicState.getRenderingIntent(), this)); | ||||||
|         updateGraphicState(); |         updateGraphicState(); | ||||||
|         checkFillingColor(); |         checkFillingColor(); | ||||||
|     } |     } | ||||||
| @@ -2255,7 +2257,7 @@ void PDFPageContentProcessor::operatorColorSetFillingColorN() | |||||||
|             if (m_patternDictionary && m_patternDictionary->hasKey(name.name)) |             if (m_patternDictionary && m_patternDictionary->hasKey(name.name)) | ||||||
|             { |             { | ||||||
|                 // Create the pattern |                 // Create the pattern | ||||||
|                 PDFPatternPtr pattern = PDFPattern::createPattern(m_colorSpaceDictionary, m_document, m_patternDictionary->get(name.name)); |                 PDFPatternPtr pattern = PDFPattern::createPattern(m_colorSpaceDictionary, m_document, m_patternDictionary->get(name.name), m_CMS, m_graphicState.getRenderingIntent(), this); | ||||||
|                 m_graphicState.setFillColorSpace(QSharedPointer<PDFAbstractColorSpace>(new PDFPatternColorSpace(qMove(pattern), qMove(uncoloredColorSpace), qMove(uncoloredPatternColor)))); |                 m_graphicState.setFillColorSpace(QSharedPointer<PDFAbstractColorSpace>(new PDFPatternColorSpace(qMove(pattern), qMove(uncoloredColorSpace), qMove(uncoloredPatternColor)))); | ||||||
|                 updateGraphicState(); |                 updateGraphicState(); | ||||||
|                 return; |                 return; | ||||||
| @@ -2628,7 +2630,7 @@ void PDFPageContentProcessor::operatorShadingPaintShape(PDFPageContentProcessor: | |||||||
|         throw PDFRendererException(RenderErrorType::Error, PDFTranslationContext::tr("Shading '%1' not found.").arg(QString::fromLatin1(name.name))); |         throw PDFRendererException(RenderErrorType::Error, PDFTranslationContext::tr("Shading '%1' not found.").arg(QString::fromLatin1(name.name))); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     PDFPatternPtr pattern = PDFPattern::createShadingPattern(m_colorSpaceDictionary, m_document, m_shadingDictionary->get(name.name), QMatrix(), PDFObject(), true); |     PDFPatternPtr pattern = PDFPattern::createShadingPattern(m_colorSpaceDictionary, m_document, m_shadingDictionary->get(name.name), QMatrix(), PDFObject(), m_CMS, m_graphicState.getRenderingIntent(), this, true); | ||||||
|  |  | ||||||
|     // We will do a trick: we will set current fill color space, and then paint |     // We will do a trick: we will set current fill color space, and then paint | ||||||
|     // bounding rectangle in the color pattern. |     // bounding rectangle in the color pattern. | ||||||
| @@ -2664,7 +2666,7 @@ void PDFPageContentProcessor::paintXObjectImage(const PDFStream* stream) | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     PDFImage pdfImage = PDFImage::createImage(m_document, stream, qMove(colorSpace), false, m_graphicState.getRenderingIntent(), this); |     PDFImage pdfImage = PDFImage::createImage(m_document, stream, qMove(colorSpace), false, m_graphicState.getRenderingIntent(), this); | ||||||
|     QImage image = pdfImage.getImage(); |     QImage image = pdfImage.getImage(m_CMS, this); | ||||||
|  |  | ||||||
|     if (image.format() == QImage::Format_Alpha8) |     if (image.format() == QImage::Format_Alpha8) | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -36,6 +36,7 @@ | |||||||
|  |  | ||||||
| namespace pdf | namespace pdf | ||||||
| { | { | ||||||
|  | class PDFCMS; | ||||||
| class PDFMesh; | class PDFMesh; | ||||||
| class PDFTilingPattern; | class PDFTilingPattern; | ||||||
| class PDFOptionalContentActivity; | class PDFOptionalContentActivity; | ||||||
| @@ -49,6 +50,7 @@ public: | |||||||
|     explicit PDFPageContentProcessor(const PDFPage* page, |     explicit PDFPageContentProcessor(const PDFPage* page, | ||||||
|                                      const PDFDocument* document, |                                      const PDFDocument* document, | ||||||
|                                      const PDFFontCache* fontCache, |                                      const PDFFontCache* fontCache, | ||||||
|  |                                      const PDFCMS* CMS, | ||||||
|                                      const PDFOptionalContentActivity* optionalContentActivity, |                                      const PDFOptionalContentActivity* optionalContentActivity, | ||||||
|                                      QMatrix pagePointToDevicePointMatrix, |                                      QMatrix pagePointToDevicePointMatrix, | ||||||
|                                      const PDFMeshQualitySettings& meshQualitySettings); |                                      const PDFMeshQualitySettings& meshQualitySettings); | ||||||
| @@ -170,7 +172,7 @@ public: | |||||||
|  |  | ||||||
|     /// Reports render error, but only once - if same error was already reported, |     /// Reports render error, but only once - if same error was already reported, | ||||||
|     /// then no new error is reported. |     /// then no new error is reported. | ||||||
|     void reportRenderErrorOnce(RenderErrorType type, QString message); |     virtual void reportRenderErrorOnce(RenderErrorType type, QString message) override; | ||||||
|  |  | ||||||
| protected: | protected: | ||||||
|  |  | ||||||
| @@ -686,7 +688,7 @@ private: | |||||||
|         const size_t colorSpaceComponentCount = colorSpace->getColorComponentCount(); |         const size_t colorSpaceComponentCount = colorSpace->getColorComponentCount(); | ||||||
|         if (operandCount == colorSpaceComponentCount) |         if (operandCount == colorSpaceComponentCount) | ||||||
|         { |         { | ||||||
|             return colorSpace->getColor(PDFColor(static_cast<PDFColorComponent>(operands)...)); |             return colorSpace->getColor(PDFColor(static_cast<PDFColorComponent>(operands)...), m_CMS, m_graphicState.getRenderingIntent(), this); | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
| @@ -843,6 +845,7 @@ private: | |||||||
|     const PDFPage* m_page; |     const PDFPage* m_page; | ||||||
|     const PDFDocument* m_document; |     const PDFDocument* m_document; | ||||||
|     const PDFFontCache* m_fontCache; |     const PDFFontCache* m_fontCache; | ||||||
|  |     const PDFCMS* m_CMS; | ||||||
|     const PDFOptionalContentActivity* m_optionalContentActivity; |     const PDFOptionalContentActivity* m_optionalContentActivity; | ||||||
|     const PDFDictionary* m_colorSpaceDictionary; |     const PDFDictionary* m_colorSpaceDictionary; | ||||||
|     const PDFDictionary* m_fontDictionary; |     const PDFDictionary* m_fontDictionary; | ||||||
|   | |||||||
| @@ -27,10 +27,11 @@ PDFPainterBase::PDFPainterBase(PDFRenderer::Features features, | |||||||
|                                const PDFPage* page, |                                const PDFPage* page, | ||||||
|                                const PDFDocument* document, |                                const PDFDocument* document, | ||||||
|                                const PDFFontCache* fontCache, |                                const PDFFontCache* fontCache, | ||||||
|  |                                const PDFCMS* cms, | ||||||
|                                const PDFOptionalContentActivity* optionalContentActivity, |                                const PDFOptionalContentActivity* optionalContentActivity, | ||||||
|                                QMatrix pagePointToDevicePointMatrix, |                                QMatrix pagePointToDevicePointMatrix, | ||||||
|                                const PDFMeshQualitySettings& meshQualitySettings) : |                                const PDFMeshQualitySettings& meshQualitySettings) : | ||||||
|     BaseClass(page, document, fontCache, optionalContentActivity, pagePointToDevicePointMatrix, meshQualitySettings), |     BaseClass(page, document, fontCache, cms, optionalContentActivity, pagePointToDevicePointMatrix, meshQualitySettings), | ||||||
|     m_features(features) |     m_features(features) | ||||||
| { | { | ||||||
|  |  | ||||||
| @@ -233,9 +234,10 @@ PDFPainter::PDFPainter(QPainter* painter, | |||||||
|                        const PDFPage* page, |                        const PDFPage* page, | ||||||
|                        const PDFDocument* document, |                        const PDFDocument* document, | ||||||
|                        const PDFFontCache* fontCache, |                        const PDFFontCache* fontCache, | ||||||
|  |                        const PDFCMS* cms, | ||||||
|                        const PDFOptionalContentActivity* optionalContentActivity, |                        const PDFOptionalContentActivity* optionalContentActivity, | ||||||
|                        const PDFMeshQualitySettings& meshQualitySettings) : |                        const PDFMeshQualitySettings& meshQualitySettings) : | ||||||
|     BaseClass(features, page, document, fontCache, optionalContentActivity, pagePointToDevicePointMatrix, meshQualitySettings), |     BaseClass(features, page, document, fontCache, cms, optionalContentActivity, pagePointToDevicePointMatrix, meshQualitySettings), | ||||||
|     m_painter(painter) |     m_painter(painter) | ||||||
| { | { | ||||||
|     Q_ASSERT(painter); |     Q_ASSERT(painter); | ||||||
|   | |||||||
| @@ -40,6 +40,7 @@ public: | |||||||
|                             const PDFPage* page, |                             const PDFPage* page, | ||||||
|                             const PDFDocument* document, |                             const PDFDocument* document, | ||||||
|                             const PDFFontCache* fontCache, |                             const PDFFontCache* fontCache, | ||||||
|  |                             const PDFCMS* cms, | ||||||
|                             const PDFOptionalContentActivity* optionalContentActivity, |                             const PDFOptionalContentActivity* optionalContentActivity, | ||||||
|                             QMatrix pagePointToDevicePointMatrix, |                             QMatrix pagePointToDevicePointMatrix, | ||||||
|                             const PDFMeshQualitySettings& meshQualitySettings); |                             const PDFMeshQualitySettings& meshQualitySettings); | ||||||
| @@ -107,6 +108,7 @@ public: | |||||||
|     /// \param page Page, which will be drawn |     /// \param page Page, which will be drawn | ||||||
|     /// \param document Document owning the page |     /// \param document Document owning the page | ||||||
|     /// \param fontCache Font cache |     /// \param fontCache Font cache | ||||||
|  |     /// \param cms Color management system | ||||||
|     /// \param optionalContentActivity Activity of optional content |     /// \param optionalContentActivity Activity of optional content | ||||||
|     /// \param meshQualitySettings Mesh quality settings |     /// \param meshQualitySettings Mesh quality settings | ||||||
|     explicit PDFPainter(QPainter* painter, |     explicit PDFPainter(QPainter* painter, | ||||||
| @@ -115,6 +117,7 @@ public: | |||||||
|                         const PDFPage* page, |                         const PDFPage* page, | ||||||
|                         const PDFDocument* document, |                         const PDFDocument* document, | ||||||
|                         const PDFFontCache* fontCache, |                         const PDFFontCache* fontCache, | ||||||
|  |                         const PDFCMS* cms, | ||||||
|                         const PDFOptionalContentActivity* optionalContentActivity, |                         const PDFOptionalContentActivity* optionalContentActivity, | ||||||
|                         const PDFMeshQualitySettings& meshQualitySettings); |                         const PDFMeshQualitySettings& meshQualitySettings); | ||||||
|     virtual ~PDFPainter() override; |     virtual ~PDFPainter() override; | ||||||
| @@ -290,9 +293,10 @@ public: | |||||||
|                                                 const PDFPage* page, |                                                 const PDFPage* page, | ||||||
|                                                 const PDFDocument* document, |                                                 const PDFDocument* document, | ||||||
|                                                 const PDFFontCache* fontCache, |                                                 const PDFFontCache* fontCache, | ||||||
|  |                                                 const PDFCMS* cms, | ||||||
|                                                 const PDFOptionalContentActivity* optionalContentActivity, |                                                 const PDFOptionalContentActivity* optionalContentActivity, | ||||||
|                                                 const PDFMeshQualitySettings& meshQualitySettings) : |                                                 const PDFMeshQualitySettings& meshQualitySettings) : | ||||||
|         BaseClass(features, page, document, fontCache, optionalContentActivity, QMatrix(), meshQualitySettings), |         BaseClass(features, page, document, fontCache, cms, optionalContentActivity, QMatrix(), meshQualitySettings), | ||||||
|         m_precompiledPage(precompiledPage) |         m_precompiledPage(precompiledPage) | ||||||
|     { |     { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -43,7 +43,12 @@ ShadingType PDFAxialShading::getShadingType() const | |||||||
|     return ShadingType::Axial; |     return ShadingType::Axial; | ||||||
| } | } | ||||||
|  |  | ||||||
| PDFPatternPtr PDFPattern::createPattern(const PDFDictionary* colorSpaceDictionary, const PDFDocument* document, const PDFObject& object) | PDFPatternPtr PDFPattern::createPattern(const PDFDictionary* colorSpaceDictionary, | ||||||
|  |                                         const PDFDocument* document, | ||||||
|  |                                         const PDFObject& object, | ||||||
|  |                                         const PDFCMS* cms, | ||||||
|  |                                         RenderingIntent intent, | ||||||
|  |                                         PDFRenderErrorReporter* reporter) | ||||||
| { | { | ||||||
|     const PDFObject& dereferencedObject = document->getObject(object); |     const PDFObject& dereferencedObject = document->getObject(object); | ||||||
|     const PDFDictionary* patternDictionary = nullptr; |     const PDFDictionary* patternDictionary = nullptr; | ||||||
| @@ -112,7 +117,7 @@ PDFPatternPtr PDFPattern::createPattern(const PDFDictionary* colorSpaceDictionar | |||||||
|             { |             { | ||||||
|                 PDFObject patternGraphicState = document->getObject(patternDictionary->get("ExtGState")); |                 PDFObject patternGraphicState = document->getObject(patternDictionary->get("ExtGState")); | ||||||
|                 QMatrix matrix = loader.readMatrixFromDictionary(patternDictionary, "Matrix", QMatrix()); |                 QMatrix matrix = loader.readMatrixFromDictionary(patternDictionary, "Matrix", QMatrix()); | ||||||
|                 return createShadingPattern(colorSpaceDictionary, document, patternDictionary->get("Shading"), matrix, patternGraphicState, false); |                 return createShadingPattern(colorSpaceDictionary, document, patternDictionary->get("Shading"), matrix, patternGraphicState, cms, intent, reporter, false); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             default: |             default: | ||||||
| @@ -131,6 +136,9 @@ PDFPatternPtr PDFPattern::createShadingPattern(const PDFDictionary* colorSpaceDi | |||||||
|                                                const PDFObject& shadingObject, |                                                const PDFObject& shadingObject, | ||||||
|                                                const QMatrix& matrix, |                                                const QMatrix& matrix, | ||||||
|                                                const PDFObject& patternGraphicState, |                                                const PDFObject& patternGraphicState, | ||||||
|  |                                                const PDFCMS* cms, | ||||||
|  |                                                RenderingIntent intent, | ||||||
|  |                                                PDFRenderErrorReporter* reporter, | ||||||
|                                                bool ignoreBackgroundColor) |                                                bool ignoreBackgroundColor) | ||||||
| { | { | ||||||
|     const PDFObject& dereferencedShadingObject = document->getObject(shadingObject); |     const PDFObject& dereferencedShadingObject = document->getObject(shadingObject); | ||||||
| @@ -167,7 +175,7 @@ PDFPatternPtr PDFPattern::createShadingPattern(const PDFDictionary* colorSpaceDi | |||||||
|         std::vector<PDFReal> backgroundColorValues = loader.readNumberArrayFromDictionary(shadingDictionary, "Background"); |         std::vector<PDFReal> backgroundColorValues = loader.readNumberArrayFromDictionary(shadingDictionary, "Background"); | ||||||
|         if (!backgroundColorValues.empty()) |         if (!backgroundColorValues.empty()) | ||||||
|         { |         { | ||||||
|             backgroundColor = colorSpace->getCheckedColor(PDFAbstractColorSpace::convertToColor(backgroundColorValues)); |             backgroundColor = colorSpace->getCheckedColor(PDFAbstractColorSpace::convertToColor(backgroundColorValues), cms, intent, reporter); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     QRectF boundingBox = loader.readRectangle(shadingDictionary->get("BBox"), QRectF()); |     QRectF boundingBox = loader.readRectangle(shadingDictionary->get("BBox"), QRectF()); | ||||||
| @@ -474,7 +482,7 @@ ShadingType PDFFunctionShading::getShadingType() const | |||||||
|     return ShadingType::Function; |     return ShadingType::Function; | ||||||
| } | } | ||||||
|  |  | ||||||
| PDFMesh PDFFunctionShading::createMesh(const PDFMeshQualitySettings& settings) const | PDFMesh PDFFunctionShading::createMesh(const PDFMeshQualitySettings& settings, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     PDFMesh mesh; |     PDFMesh mesh; | ||||||
|  |  | ||||||
| @@ -724,7 +732,7 @@ PDFMesh PDFFunctionShading::createMesh(const PDFMeshQualitySettings& settings) c | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 return m_colorSpace->getColor(PDFAbstractColorSpace::convertToColor(colorBuffer)); |                 return m_colorSpace->getColor(PDFAbstractColorSpace::convertToColor(colorBuffer), cms, intent, reporter); | ||||||
|             }; |             }; | ||||||
|  |  | ||||||
|             PDFMesh::Triangle triangle1; |             PDFMesh::Triangle triangle1; | ||||||
| @@ -777,7 +785,7 @@ PDFMesh PDFFunctionShading::createMesh(const PDFMeshQualitySettings& settings) c | |||||||
|     return mesh; |     return mesh; | ||||||
| } | } | ||||||
|  |  | ||||||
| PDFMesh PDFAxialShading::createMesh(const PDFMeshQualitySettings& settings) const | PDFMesh PDFAxialShading::createMesh(const PDFMeshQualitySettings& settings, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     PDFMesh mesh; |     PDFMesh mesh; | ||||||
|  |  | ||||||
| @@ -957,7 +965,7 @@ PDFMesh PDFAxialShading::createMesh(const PDFMeshQualitySettings& settings) cons | |||||||
|             uint32_t bottomRight = mesh.addVertex(QPointF(item.first, yb)); |             uint32_t bottomRight = mesh.addVertex(QPointF(item.first, yb)); | ||||||
|  |  | ||||||
|             PDFColor mixedColor = PDFAbstractColorSpace::mixColors(previousColor, item.second, 0.5); |             PDFColor mixedColor = PDFAbstractColorSpace::mixColors(previousColor, item.second, 0.5); | ||||||
|             QColor color = m_colorSpace->getColor(mixedColor); |             QColor color = m_colorSpace->getColor(mixedColor, cms, intent, reporter); | ||||||
|             mesh.addQuad(topLeft, topRight, bottomRight, bottomLeft, color.rgb()); |             mesh.addQuad(topLeft, topRight, bottomRight, bottomLeft, color.rgb()); | ||||||
|  |  | ||||||
|             topLeft = topRight; |             topLeft = topRight; | ||||||
| @@ -1110,7 +1118,7 @@ ShadingType PDFRadialShading::getShadingType() const | |||||||
|     return ShadingType::Radial; |     return ShadingType::Radial; | ||||||
| } | } | ||||||
|  |  | ||||||
| PDFMesh PDFRadialShading::createMesh(const PDFMeshQualitySettings& settings) const | PDFMesh PDFRadialShading::createMesh(const PDFMeshQualitySettings& settings, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     PDFMesh mesh; |     PDFMesh mesh; | ||||||
|  |  | ||||||
| @@ -1373,7 +1381,7 @@ PDFMesh PDFRadialShading::createMesh(const PDFMeshQualitySettings& settings) con | |||||||
|                 uint32_t v3 = mesh.addVertex(p3); |                 uint32_t v3 = mesh.addVertex(p3); | ||||||
|                 uint32_t v4 = mesh.addVertex(p4); |                 uint32_t v4 = mesh.addVertex(p4); | ||||||
|  |  | ||||||
|                 QColor color = m_colorSpace->getColor(mixedColor); |                 QColor color = m_colorSpace->getColor(mixedColor, cms, intent, reporter); | ||||||
|                 mesh.addQuad(v1, v2, v3, v4, color.rgb()); |                 mesh.addQuad(v1, v2, v3, v4, color.rgb()); | ||||||
|  |  | ||||||
|                 angle0 = angle1; |                 angle0 = angle1; | ||||||
| @@ -1400,7 +1408,7 @@ ShadingType PDFFreeFormGouradTriangleShading::getShadingType() const | |||||||
|     return ShadingType::FreeFormGouradTriangle; |     return ShadingType::FreeFormGouradTriangle; | ||||||
| } | } | ||||||
|  |  | ||||||
| PDFMesh PDFFreeFormGouradTriangleShading::createMesh(const PDFMeshQualitySettings& settings) const | PDFMesh PDFFreeFormGouradTriangleShading::createMesh(const PDFMeshQualitySettings& settings, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     PDFMesh mesh; |     PDFMesh mesh; | ||||||
|  |  | ||||||
| @@ -1477,13 +1485,13 @@ PDFMesh PDFFreeFormGouradTriangleShading::createMesh(const PDFMeshQualitySetting | |||||||
|     const VertexData* vc = nullptr; |     const VertexData* vc = nullptr; | ||||||
|     const VertexData* vd = nullptr; |     const VertexData* vd = nullptr; | ||||||
|  |  | ||||||
|     auto addTriangle = [this, &settings, &mesh, &vertices](const VertexData* va, const VertexData* vb, const VertexData* vc) |     auto addTriangle = [this, &settings, &mesh, &vertices, cms, intent, reporter](const VertexData* va, const VertexData* vb, const VertexData* vc) | ||||||
|     { |     { | ||||||
|         const uint32_t via = va->index; |         const uint32_t via = va->index; | ||||||
|         const uint32_t vib = vb->index; |         const uint32_t vib = vb->index; | ||||||
|         const uint32_t vic = vc->index; |         const uint32_t vic = vc->index; | ||||||
|  |  | ||||||
|         addSubdividedTriangles(settings, mesh, via, vib, vic, va->color, vb->color, vc->color); |         addSubdividedTriangles(settings, mesh, via, vib, vic, va->color, vb->color, vc->color, cms, intent, reporter); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     for (size_t i = 0; i < vertexCount;) |     for (size_t i = 0; i < vertexCount;) | ||||||
| @@ -1549,7 +1557,7 @@ ShadingType PDFLatticeFormGouradTriangleShading::getShadingType() const | |||||||
|     return ShadingType::LatticeFormGouradTriangle; |     return ShadingType::LatticeFormGouradTriangle; | ||||||
| } | } | ||||||
|  |  | ||||||
| PDFMesh PDFLatticeFormGouradTriangleShading::createMesh(const PDFMeshQualitySettings& settings) const | PDFMesh PDFLatticeFormGouradTriangleShading::createMesh(const PDFMeshQualitySettings& settings, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     PDFMesh mesh; |     PDFMesh mesh; | ||||||
|  |  | ||||||
| @@ -1638,8 +1646,8 @@ PDFMesh PDFLatticeFormGouradTriangleShading::createMesh(const PDFMeshQualitySett | |||||||
|             const VertexData& vertexBottomRight = vertices[vBottomRight]; |             const VertexData& vertexBottomRight = vertices[vBottomRight]; | ||||||
|             const VertexData& vertexBottomLeft = vertices[vBottomLeft]; |             const VertexData& vertexBottomLeft = vertices[vBottomLeft]; | ||||||
|  |  | ||||||
|             addSubdividedTriangles(settings, mesh, vertexTopLeft.index, vertexTopRight.index, vertexBottomRight.index, vertexTopLeft.color, vertexTopRight.color, vertexBottomRight.color); |             addSubdividedTriangles(settings, mesh, vertexTopLeft.index, vertexTopRight.index, vertexBottomRight.index, vertexTopLeft.color, vertexTopRight.color, vertexBottomRight.color, cms, intent, reporter); | ||||||
|             addSubdividedTriangles(settings, mesh, vertexBottomRight.index, vertexBottomLeft.index, vertexTopLeft.index, vertexBottomRight.color, vertexBottomLeft.color, vertexTopLeft.color); |             addSubdividedTriangles(settings, mesh, vertexBottomRight.index, vertexBottomLeft.index, vertexTopLeft.index, vertexBottomRight.color, vertexBottomLeft.color, vertexTopLeft.color, cms, intent, reporter); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -1689,8 +1697,9 @@ PDFColor PDFType4567Shading::getColor(PDFColor colorOrFunctionParameter) const | |||||||
| } | } | ||||||
|  |  | ||||||
| void PDFType4567Shading::addSubdividedTriangles(const PDFMeshQualitySettings& settings, | void PDFType4567Shading::addSubdividedTriangles(const PDFMeshQualitySettings& settings, | ||||||
|                                                       PDFMesh& mesh, uint32_t v1, uint32_t v2, uint32_t v3, |                                                 PDFMesh& mesh, uint32_t v1, uint32_t v2, uint32_t v3, | ||||||
|                                                       PDFColor c1, PDFColor c2, PDFColor c3) const |                                                 PDFColor c1, PDFColor c2, PDFColor c3, | ||||||
|  |                                                 const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     // First, verify, if we can subdivide the triangle |     // First, verify, if we can subdivide the triangle | ||||||
|     QLineF v12(mesh.getVertex(v1), mesh.getVertex(v2)); |     QLineF v12(mesh.getVertex(v1), mesh.getVertex(v2)); | ||||||
| @@ -1718,8 +1727,8 @@ void PDFType4567Shading::addSubdividedTriangles(const PDFMeshQualitySettings& se | |||||||
|             PDFColor cx = PDFAbstractColorSpace::mixColors(c2, c3, 0.5); |             PDFColor cx = PDFAbstractColorSpace::mixColors(c2, c3, 0.5); | ||||||
|             const uint32_t vx = mesh.addVertex(x); |             const uint32_t vx = mesh.addVertex(x); | ||||||
|  |  | ||||||
|             addSubdividedTriangles(settings, mesh, v1, v2, vx, c1, c2, cx); |             addSubdividedTriangles(settings, mesh, v1, v2, vx, c1, c2, cx, cms, intent, reporter); | ||||||
|             addSubdividedTriangles(settings, mesh, v1, v3, vx, c1, c3, cx); |             addSubdividedTriangles(settings, mesh, v1, v3, vx, c1, c3, cx, cms, intent, reporter); | ||||||
|         } |         } | ||||||
|         else if (length13 == maxLength) |         else if (length13 == maxLength) | ||||||
|         { |         { | ||||||
| @@ -1729,8 +1738,8 @@ void PDFType4567Shading::addSubdividedTriangles(const PDFMeshQualitySettings& se | |||||||
|             PDFColor cx = PDFAbstractColorSpace::mixColors(c1, c3, 0.5); |             PDFColor cx = PDFAbstractColorSpace::mixColors(c1, c3, 0.5); | ||||||
|             const uint32_t vx = mesh.addVertex(x); |             const uint32_t vx = mesh.addVertex(x); | ||||||
|  |  | ||||||
|             addSubdividedTriangles(settings, mesh, v1, v2, vx, c1, c2, cx); |             addSubdividedTriangles(settings, mesh, v1, v2, vx, c1, c2, cx, cms, intent, reporter); | ||||||
|             addSubdividedTriangles(settings, mesh, v2, v3, vx, c2, c3, cx); |             addSubdividedTriangles(settings, mesh, v2, v3, vx, c2, c3, cx, cms, intent, reporter); | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
| @@ -1742,8 +1751,8 @@ void PDFType4567Shading::addSubdividedTriangles(const PDFMeshQualitySettings& se | |||||||
|             PDFColor cx = PDFAbstractColorSpace::mixColors(c1, c2, 0.5); |             PDFColor cx = PDFAbstractColorSpace::mixColors(c1, c2, 0.5); | ||||||
|             const uint32_t vx = mesh.addVertex(x); |             const uint32_t vx = mesh.addVertex(x); | ||||||
|  |  | ||||||
|             addSubdividedTriangles(settings, mesh, v1, v3, vx, c1, c3, cx); |             addSubdividedTriangles(settings, mesh, v1, v3, vx, c1, c3, cx, cms, intent, reporter); | ||||||
|             addSubdividedTriangles(settings, mesh, v2, v3, vx, c2, c3, cx); |             addSubdividedTriangles(settings, mesh, v2, v3, vx, c2, c3, cx, cms, intent, reporter); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
| @@ -1760,7 +1769,7 @@ void PDFType4567Shading::addSubdividedTriangles(const PDFMeshQualitySettings& se | |||||||
|             color[i] = (c1[i] + c2[i] + c3[i]) * coefficient; |             color[i] = (c1[i] + c2[i] + c3[i]) * coefficient; | ||||||
|         } |         } | ||||||
|         Q_ASSERT(colorComponents == m_colorSpace->getColorComponentCount()); |         Q_ASSERT(colorComponents == m_colorSpace->getColorComponentCount()); | ||||||
|         QColor transformedColor = m_colorSpace->getColor(color); |         QColor transformedColor = m_colorSpace->getColor(color, cms, intent, reporter); | ||||||
|  |  | ||||||
|         PDFMesh::Triangle triangle; |         PDFMesh::Triangle triangle; | ||||||
|         triangle.v1 = v1; |         triangle.v1 = v1; | ||||||
| @@ -1940,7 +1949,7 @@ ShadingType PDFTensorProductPatchShading::getShadingType() const | |||||||
|     return ShadingType::TensorProductPatchMesh; |     return ShadingType::TensorProductPatchMesh; | ||||||
| } | } | ||||||
|  |  | ||||||
| PDFMesh PDFTensorProductPatchShading::createMesh(const PDFMeshQualitySettings& settings) const | PDFMesh PDFTensorProductPatchShading::createMesh(const PDFMeshQualitySettings& settings, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     PDFMesh mesh; |     PDFMesh mesh; | ||||||
|  |  | ||||||
| @@ -2159,7 +2168,7 @@ PDFMesh PDFTensorProductPatchShading::createMesh(const PDFMeshQualitySettings& s | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fillMesh(mesh, patternSpaceToDeviceSpaceMatrix, settings, patches); |     fillMesh(mesh, patternSpaceToDeviceSpaceMatrix, settings, patches, cms, intent, reporter); | ||||||
|     return mesh; |     return mesh; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -2204,7 +2213,12 @@ struct PDFTensorProductPatchShadingBase::Triangle | |||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| void PDFTensorProductPatchShadingBase::fillMesh(PDFMesh& mesh, const PDFMeshQualitySettings& settings, const PDFTensorPatch& patch) const | void PDFTensorProductPatchShadingBase::fillMesh(PDFMesh& mesh, | ||||||
|  |                                                 const PDFMeshQualitySettings& settings, | ||||||
|  |                                                 const PDFTensorPatch& patch, | ||||||
|  |                                                 const PDFCMS* cms, | ||||||
|  |                                                 RenderingIntent intent, | ||||||
|  |                                                 PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     // We implement algorithm similar to Ruppert's algorithm (see https://en.wikipedia.org/wiki/Ruppert%27s_algorithm), but |     // We implement algorithm similar to Ruppert's algorithm (see https://en.wikipedia.org/wiki/Ruppert%27s_algorithm), but | ||||||
|     // we do not need a mesh for FEM calculation, so we do not care about quality of the triangles (we can have triangles with |     // we do not need a mesh for FEM calculation, so we do not care about quality of the triangles (we can have triangles with | ||||||
| @@ -2367,7 +2381,7 @@ void PDFTensorProductPatchShadingBase::fillMesh(PDFMesh& mesh, const PDFMeshQual | |||||||
|  |  | ||||||
|         QPointF center = triangle.getCenter(); |         QPointF center = triangle.getCenter(); | ||||||
|         PDFColor color = getColorForUV(center.x(), center.y()); |         PDFColor color = getColorForUV(center.x(), center.y()); | ||||||
|         QRgb rgbColor = m_colorSpace->getColor(color).rgb(); |         QRgb rgbColor = m_colorSpace->getColor(color, cms, intent, reporter).rgb(); | ||||||
|  |  | ||||||
|         PDFMesh::Triangle meshTriangle; |         PDFMesh::Triangle meshTriangle; | ||||||
|         meshTriangle.v1 = static_cast<uint32_t>(vertexIndex++); |         meshTriangle.v1 = static_cast<uint32_t>(vertexIndex++); | ||||||
| @@ -2383,11 +2397,14 @@ void PDFTensorProductPatchShadingBase::fillMesh(PDFMesh& mesh, const PDFMeshQual | |||||||
| void PDFTensorProductPatchShadingBase::fillMesh(PDFMesh& mesh, | void PDFTensorProductPatchShadingBase::fillMesh(PDFMesh& mesh, | ||||||
|                                                 const QMatrix& patternSpaceToDeviceSpaceMatrix, |                                                 const QMatrix& patternSpaceToDeviceSpaceMatrix, | ||||||
|                                                 const PDFMeshQualitySettings& settings, |                                                 const PDFMeshQualitySettings& settings, | ||||||
|                                                 const PDFTensorPatches& patches) const |                                                 const PDFTensorPatches& patches, | ||||||
|  |                                                 const PDFCMS* cms, | ||||||
|  |                                                 RenderingIntent intent, | ||||||
|  |                                                 PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     for (const auto& patch : patches) |     for (const auto& patch : patches) | ||||||
|     { |     { | ||||||
|         fillMesh(mesh, settings, patch); |         fillMesh(mesh, settings, patch, cms, intent, reporter); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Create bounding path |     // Create bounding path | ||||||
| @@ -2423,7 +2440,7 @@ ShadingType PDFCoonsPatchShading::getShadingType() const | |||||||
|     return ShadingType::CoonsPatchMesh; |     return ShadingType::CoonsPatchMesh; | ||||||
| } | } | ||||||
|  |  | ||||||
| PDFMesh PDFCoonsPatchShading::createMesh(const PDFMeshQualitySettings& settings) const | PDFMesh PDFCoonsPatchShading::createMesh(const PDFMeshQualitySettings& settings, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const | ||||||
| { | { | ||||||
|     PDFMesh mesh; |     PDFMesh mesh; | ||||||
|  |  | ||||||
| @@ -2617,7 +2634,7 @@ PDFMesh PDFCoonsPatchShading::createMesh(const PDFMeshQualitySettings& settings) | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fillMesh(mesh, patternSpaceToDeviceSpaceMatrix, settings, patches); |     fillMesh(mesh, patternSpaceToDeviceSpaceMatrix, settings, patches, cms, intent, reporter); | ||||||
|     return mesh; |     return mesh; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -174,7 +174,15 @@ public: | |||||||
|     /// \param colorSpaceDictionary Color space dictionary |     /// \param colorSpaceDictionary Color space dictionary | ||||||
|     /// \param document Document, owning the pdf object |     /// \param document Document, owning the pdf object | ||||||
|     /// \param object Object defining the pattern |     /// \param object Object defining the pattern | ||||||
|     static PDFPatternPtr createPattern(const PDFDictionary* colorSpaceDictionary, const PDFDocument* document, const PDFObject& object); |     /// \param cms Color management system | ||||||
|  |     /// \param intent Rendering intent | ||||||
|  |     /// \param reporter Error reporter | ||||||
|  |     static PDFPatternPtr createPattern(const PDFDictionary* colorSpaceDictionary, | ||||||
|  |                                        const PDFDocument* document, | ||||||
|  |                                        const PDFObject& object, | ||||||
|  |                                        const PDFCMS* cms, | ||||||
|  |                                        RenderingIntent intent, | ||||||
|  |                                        PDFRenderErrorReporter* reporter); | ||||||
|  |  | ||||||
|     /// Create shading pattern from the object. If error occurs, exception is thrown |     /// Create shading pattern from the object. If error occurs, exception is thrown | ||||||
|     /// \param colorSpaceDictionary Color space dictionary |     /// \param colorSpaceDictionary Color space dictionary | ||||||
| @@ -182,12 +190,18 @@ public: | |||||||
|     /// \param object Object defining the shading |     /// \param object Object defining the shading | ||||||
|     /// \param matrix Matrix converting reference coordinate system to the device coordinate system |     /// \param matrix Matrix converting reference coordinate system to the device coordinate system | ||||||
|     /// \param patternGraphicState Pattern graphic state |     /// \param patternGraphicState Pattern graphic state | ||||||
|  |     /// \param cms Color management system | ||||||
|  |     /// \param intent Rendering intent | ||||||
|  |     /// \param reporter Error reporter | ||||||
|     /// \param ignoreBackgroundColor If set, then ignores background color, even if it is present |     /// \param ignoreBackgroundColor If set, then ignores background color, even if it is present | ||||||
|     static PDFPatternPtr createShadingPattern(const PDFDictionary* colorSpaceDictionary, |     static PDFPatternPtr createShadingPattern(const PDFDictionary* colorSpaceDictionary, | ||||||
|                                               const PDFDocument* document, |                                               const PDFDocument* document, | ||||||
|                                               const PDFObject& shadingObject, |                                               const PDFObject& shadingObject, | ||||||
|                                               const QMatrix& matrix, |                                               const QMatrix& matrix, | ||||||
|                                               const PDFObject& patternGraphicState, |                                               const PDFObject& patternGraphicState, | ||||||
|  |                                               const PDFCMS* cms, | ||||||
|  |                                               RenderingIntent intent, | ||||||
|  |                                               PDFRenderErrorReporter* reporter, | ||||||
|                                               bool ignoreBackgroundColor); |                                               bool ignoreBackgroundColor); | ||||||
|  |  | ||||||
| protected: | protected: | ||||||
| @@ -262,7 +276,10 @@ public: | |||||||
|     /// coordinate system. You must transform the mesh, if you want to |     /// coordinate system. You must transform the mesh, if you want to | ||||||
|     /// use it in another coordinate system. |     /// use it in another coordinate system. | ||||||
|     /// \param settings Meshing settings |     /// \param settings Meshing settings | ||||||
|     virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings) const = 0; |     /// \param cms Color management system | ||||||
|  |     /// \param intent Rendering intent | ||||||
|  |     /// \param reporter Error reporter | ||||||
|  |     virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const = 0; | ||||||
|  |  | ||||||
|     /// Returns patterns graphic state. This state must be applied before |     /// Returns patterns graphic state. This state must be applied before | ||||||
|     /// the shading pattern is painted to the target device. |     /// the shading pattern is painted to the target device. | ||||||
| @@ -313,7 +330,7 @@ public: | |||||||
|     explicit PDFFunctionShading() = default; |     explicit PDFFunctionShading() = default; | ||||||
|  |  | ||||||
|     virtual ShadingType getShadingType() const override; |     virtual ShadingType getShadingType() const override; | ||||||
|     virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings) const override; |     virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     friend class PDFPattern; |     friend class PDFPattern; | ||||||
| @@ -329,7 +346,7 @@ public: | |||||||
|     explicit PDFAxialShading() = default; |     explicit PDFAxialShading() = default; | ||||||
|  |  | ||||||
|     virtual ShadingType getShadingType() const override; |     virtual ShadingType getShadingType() const override; | ||||||
|     virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings) const override; |     virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     friend class PDFPattern; |     friend class PDFPattern; | ||||||
| @@ -341,7 +358,7 @@ public: | |||||||
|     explicit PDFRadialShading() = default; |     explicit PDFRadialShading() = default; | ||||||
|  |  | ||||||
|     virtual ShadingType getShadingType() const override; |     virtual ShadingType getShadingType() const override; | ||||||
|     virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings) const override; |     virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     friend class PDFPattern; |     friend class PDFPattern; | ||||||
| @@ -361,7 +378,17 @@ protected: | |||||||
|     /// Returns color for given color or function parameter |     /// Returns color for given color or function parameter | ||||||
|     PDFColor getColor(PDFColor colorOrFunctionParameter) const; |     PDFColor getColor(PDFColor colorOrFunctionParameter) const; | ||||||
|  |  | ||||||
|     void addSubdividedTriangles(const PDFMeshQualitySettings& settings, PDFMesh& mesh, uint32_t v1, uint32_t v2, uint32_t v3, PDFColor c1, PDFColor c2, PDFColor c3) const; |     void addSubdividedTriangles(const PDFMeshQualitySettings& settings, | ||||||
|  |                                 PDFMesh& mesh, | ||||||
|  |                                 uint32_t v1, | ||||||
|  |                                 uint32_t v2, | ||||||
|  |                                 uint32_t v3, | ||||||
|  |                                 PDFColor c1, | ||||||
|  |                                 PDFColor c2, | ||||||
|  |                                 PDFColor c3, | ||||||
|  |                                 const PDFCMS* cms, | ||||||
|  |                                 RenderingIntent intent, | ||||||
|  |                                 PDFRenderErrorReporter* reporter) const; | ||||||
|  |  | ||||||
|     uint8_t m_bitsPerCoordinate = 0; |     uint8_t m_bitsPerCoordinate = 0; | ||||||
|     uint8_t m_bitsPerComponent = 0; |     uint8_t m_bitsPerComponent = 0; | ||||||
| @@ -387,7 +414,7 @@ public: | |||||||
|     explicit PDFFreeFormGouradTriangleShading() = default; |     explicit PDFFreeFormGouradTriangleShading() = default; | ||||||
|  |  | ||||||
|     virtual ShadingType getShadingType() const override; |     virtual ShadingType getShadingType() const override; | ||||||
|     virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings) const override; |     virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     friend class PDFPattern; |     friend class PDFPattern; | ||||||
| @@ -399,7 +426,7 @@ public: | |||||||
|     explicit PDFLatticeFormGouradTriangleShading() = default; |     explicit PDFLatticeFormGouradTriangleShading() = default; | ||||||
|  |  | ||||||
|     virtual ShadingType getShadingType() const override; |     virtual ShadingType getShadingType() const override; | ||||||
|     virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings) const override; |     virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     friend class PDFPattern; |     friend class PDFPattern; | ||||||
| @@ -531,8 +558,8 @@ public: | |||||||
| protected: | protected: | ||||||
|     struct Triangle; |     struct Triangle; | ||||||
|  |  | ||||||
|     void fillMesh(PDFMesh& mesh, const PDFMeshQualitySettings& settings, const PDFTensorPatch& patch) const; |     void fillMesh(PDFMesh& mesh, const PDFMeshQualitySettings& settings, const PDFTensorPatch& patch, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const; | ||||||
|     void fillMesh(PDFMesh& mesh, const QMatrix& patternSpaceToDeviceSpaceMatrix, const PDFMeshQualitySettings& settings, const PDFTensorPatches& patches) const; |     void fillMesh(PDFMesh& mesh, const QMatrix& patternSpaceToDeviceSpaceMatrix, const PDFMeshQualitySettings& settings, const PDFTensorPatches& patches, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const; | ||||||
|     static void addTriangle(std::vector<Triangle>& triangles, const PDFTensorPatch& patch, std::array<QPointF, 3> uvCoordinates); |     static void addTriangle(std::vector<Triangle>& triangles, const PDFTensorPatch& patch, std::array<QPointF, 3> uvCoordinates); | ||||||
|  |  | ||||||
| private: | private: | ||||||
| @@ -545,7 +572,7 @@ public: | |||||||
|     explicit PDFCoonsPatchShading() = default; |     explicit PDFCoonsPatchShading() = default; | ||||||
|  |  | ||||||
|     virtual ShadingType getShadingType() const override; |     virtual ShadingType getShadingType() const override; | ||||||
|     virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings) const override; |     virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     friend class PDFPattern; |     friend class PDFPattern; | ||||||
| @@ -557,7 +584,7 @@ public: | |||||||
|     explicit PDFTensorProductPatchShading() = default; |     explicit PDFTensorProductPatchShading() = default; | ||||||
|  |  | ||||||
|     virtual ShadingType getShadingType() const override; |     virtual ShadingType getShadingType() const override; | ||||||
|     virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings) const override; |     virtual PDFMesh createMesh(const PDFMeshQualitySettings& settings, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     friend class PDFPattern; |     friend class PDFPattern; | ||||||
|   | |||||||
| @@ -30,11 +30,13 @@ namespace pdf | |||||||
|  |  | ||||||
| PDFRenderer::PDFRenderer(const PDFDocument* document, | PDFRenderer::PDFRenderer(const PDFDocument* document, | ||||||
|                          const PDFFontCache* fontCache, |                          const PDFFontCache* fontCache, | ||||||
|  |                          const PDFCMS* cms, | ||||||
|                          const PDFOptionalContentActivity* optionalContentActivity, |                          const PDFOptionalContentActivity* optionalContentActivity, | ||||||
|                          Features features, |                          Features features, | ||||||
|                          const PDFMeshQualitySettings& meshQualitySettings) : |                          const PDFMeshQualitySettings& meshQualitySettings) : | ||||||
|     m_document(document), |     m_document(document), | ||||||
|     m_fontCache(fontCache), |     m_fontCache(fontCache), | ||||||
|  |     m_cms(cms), | ||||||
|     m_optionalContentActivity(optionalContentActivity), |     m_optionalContentActivity(optionalContentActivity), | ||||||
|     m_features(features), |     m_features(features), | ||||||
|     m_meshQualitySettings(meshQualitySettings) |     m_meshQualitySettings(meshQualitySettings) | ||||||
| @@ -104,7 +106,7 @@ QList<PDFRenderError> PDFRenderer::render(QPainter* painter, const QRectF& recta | |||||||
|  |  | ||||||
|     QMatrix matrix = createPagePointToDevicePointMatrix(page, rectangle); |     QMatrix matrix = createPagePointToDevicePointMatrix(page, rectangle); | ||||||
|  |  | ||||||
|     PDFPainter processor(painter, m_features, matrix, page, m_document, m_fontCache, m_optionalContentActivity, m_meshQualitySettings); |     PDFPainter processor(painter, m_features, matrix, page, m_document, m_fontCache, m_cms, m_optionalContentActivity, m_meshQualitySettings); | ||||||
|     return processor.processContents(); |     return processor.processContents(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -120,7 +122,7 @@ QList<PDFRenderError> PDFRenderer::render(QPainter* painter, const QMatrix& matr | |||||||
|     const PDFPage* page = catalog->getPage(pageIndex); |     const PDFPage* page = catalog->getPage(pageIndex); | ||||||
|     Q_ASSERT(page); |     Q_ASSERT(page); | ||||||
|  |  | ||||||
|     PDFPainter processor(painter, m_features, matrix, page, m_document, m_fontCache, m_optionalContentActivity, m_meshQualitySettings); |     PDFPainter processor(painter, m_features, matrix, page, m_document, m_fontCache, m_cms, m_optionalContentActivity, m_meshQualitySettings); | ||||||
|     return processor.processContents(); |     return processor.processContents(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -140,7 +142,7 @@ void PDFRenderer::compile(PDFPrecompiledPage* precompiledPage, size_t pageIndex) | |||||||
|     QElapsedTimer timer; |     QElapsedTimer timer; | ||||||
|     timer.start(); |     timer.start(); | ||||||
|  |  | ||||||
|     PDFPrecompiledPageGenerator generator(precompiledPage, m_features, page, m_document, m_fontCache, m_optionalContentActivity, m_meshQualitySettings); |     PDFPrecompiledPageGenerator generator(precompiledPage, m_features, page, m_document, m_fontCache, m_cms, m_optionalContentActivity, m_meshQualitySettings); | ||||||
|     QList<PDFRenderError> errors = generator.processContents(); |     QList<PDFRenderError> errors = generator.processContents(); | ||||||
|     precompiledPage->optimize(); |     precompiledPage->optimize(); | ||||||
|     precompiledPage->finalize(timer.nsecsElapsed(), qMove(errors)); |     precompiledPage->finalize(timer.nsecsElapsed(), qMove(errors)); | ||||||
|   | |||||||
| @@ -31,6 +31,7 @@ class QOpenGLFramebufferObject; | |||||||
|  |  | ||||||
| namespace pdf | namespace pdf | ||||||
| { | { | ||||||
|  | class PDFCMS; | ||||||
| class PDFFontCache; | class PDFFontCache; | ||||||
| class PDFPrecompiledPage; | class PDFPrecompiledPage; | ||||||
| class PDFOptionalContentActivity; | class PDFOptionalContentActivity; | ||||||
| @@ -52,7 +53,12 @@ public: | |||||||
|  |  | ||||||
|     Q_DECLARE_FLAGS(Features, Feature) |     Q_DECLARE_FLAGS(Features, Feature) | ||||||
|  |  | ||||||
|     explicit PDFRenderer(const PDFDocument* document, const PDFFontCache* fontCache, const PDFOptionalContentActivity* optionalContentActivity, Features features, const PDFMeshQualitySettings& meshQualitySettings); |     explicit PDFRenderer(const PDFDocument* document, | ||||||
|  |                          const PDFFontCache* fontCache, | ||||||
|  |                          const PDFCMS* cms, | ||||||
|  |                          const PDFOptionalContentActivity* optionalContentActivity, | ||||||
|  |                          Features features, | ||||||
|  |                          const PDFMeshQualitySettings& meshQualitySettings); | ||||||
|  |  | ||||||
|     /// Paints desired page onto the painter. Page is painted in the rectangle using best-fit method. |     /// 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 |     /// If the page doesn't exist, then error is returned. No exception is thrown. Rendering errors | ||||||
| @@ -86,6 +92,7 @@ public: | |||||||
| private: | private: | ||||||
|     const PDFDocument* m_document; |     const PDFDocument* m_document; | ||||||
|     const PDFFontCache* m_fontCache; |     const PDFFontCache* m_fontCache; | ||||||
|  |     const PDFCMS* m_cms; | ||||||
|     const PDFOptionalContentActivity* m_optionalContentActivity; |     const PDFOptionalContentActivity* m_optionalContentActivity; | ||||||
|     Features m_features; |     Features m_features; | ||||||
|     PDFMeshQualitySettings m_meshQualitySettings; |     PDFMeshQualitySettings m_meshQualitySettings; | ||||||
|   | |||||||
| @@ -155,7 +155,7 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) : | |||||||
|  |  | ||||||
|     readSettings(); |     readSettings(); | ||||||
|  |  | ||||||
|     m_pdfWidget = new pdf::PDFWidget(m_settings->getRendererEngine(), m_settings->isMultisampleAntialiasingEnabled() ? m_settings->getRendererSamples() : -1, this); |     m_pdfWidget = new pdf::PDFWidget(m_CMSManager, m_settings->getRendererEngine(), m_settings->isMultisampleAntialiasingEnabled() ? m_settings->getRendererSamples() : -1, this); | ||||||
|     setCentralWidget(m_pdfWidget); |     setCentralWidget(m_pdfWidget); | ||||||
|     setFocusProxy(m_pdfWidget); |     setFocusProxy(m_pdfWidget); | ||||||
|     m_pdfWidget->updateCacheLimits(m_settings->getCompiledPageCacheLimit() * 1024, m_settings->getThumbnailsCacheLimit(), m_settings->getFontCacheLimit(), m_settings->getInstancedFontCacheLimit()); |     m_pdfWidget->updateCacheLimits(m_settings->getCompiledPageCacheLimit() * 1024, m_settings->getThumbnailsCacheLimit(), m_settings->getFontCacheLimit(), m_settings->getInstancedFontCacheLimit()); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user