File indexing completed on 2025-07-06 04:48:05
0001 /* 0002 SPDX-FileCopyrightText: 2019 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include "kitinerary_export.h" 0010 0011 #include <QExplicitlySharedDataPointer> 0012 #include <QMetaType> 0013 0014 #include <functional> 0015 0016 class QImage; 0017 class QTransform; 0018 0019 namespace KItinerary { 0020 class PdfImagePrivate; 0021 class PdfImageRef; 0022 } 0023 0024 namespace std { 0025 template<> 0026 struct hash<KItinerary::PdfImageRef> 0027 { 0028 inline std::size_t operator()(const KItinerary::PdfImageRef &ref) const noexcept; 0029 }; 0030 } 0031 0032 namespace KItinerary { 0033 0034 /** PDF image element type. */ 0035 enum class PdfImageType { 0036 Image, 0037 Mask, 0038 SMask 0039 }; 0040 0041 /** PDF object reference for an image, with the ability to address attached masks as well. */ 0042 class PdfImageRef 0043 { 0044 public: 0045 constexpr PdfImageRef() = default; 0046 constexpr inline PdfImageRef(int num, int gen, PdfImageType type = PdfImageType::Image) 0047 : m_refNum(num) 0048 , m_refGen(gen) 0049 , m_type(type) 0050 {} 0051 0052 constexpr inline bool isNull() const 0053 { 0054 return m_refNum < 0; 0055 } 0056 0057 constexpr inline bool operator==(const PdfImageRef &other) const 0058 { 0059 return m_refNum == other.m_refNum && m_refGen == other.m_refGen && m_type == other.m_type; 0060 } 0061 0062 private: 0063 int m_refNum = -1; 0064 int m_refGen = -1; 0065 PdfImageType m_type = PdfImageType::Image; 0066 friend class PdfImagePrivate; 0067 friend std::size_t std::hash<PdfImageRef>::operator ()(const PdfImageRef&) const noexcept; 0068 }; 0069 0070 /** An image in a PDF document. 0071 */ 0072 class KITINERARY_EXPORT PdfImage 0073 { 0074 Q_GADGET 0075 Q_PROPERTY(int width READ width) 0076 Q_PROPERTY(int height READ height) 0077 public: 0078 PdfImage(); 0079 PdfImage(const PdfImage&); 0080 ~PdfImage(); 0081 PdfImage& operator=(const PdfImage&); 0082 0083 /** Width of the image in PDF 1/72 dpi coordinates. */ 0084 int width() const; 0085 /** Height of the image in PDF 1/72 dpi coordinates. */ 0086 int height() const; 0087 0088 /** Height of the source image. */ 0089 int sourceHeight() const; 0090 /** Width of the source image. */ 0091 int sourceWidth() const; 0092 0093 /** Transformation from source image to final size/position on the page. 0094 * Values are 1/72 inch. 0095 */ 0096 QTransform transform() const; 0097 0098 /** Hints for loading image data. */ 0099 enum LoadingHint { 0100 NoHint = 0, ///< Load image data as-is. The default. 0101 AbortOnColorHint = 1, ///< Abort loading when encountering a non black/white pixel, as a shortcut for barcode detection. 0102 ConvertToGrayscaleHint = 2, ///< Convert to QImage::Format_Grayscale8 during loading. More efficient than converting later if all you need is grayscale. 0103 }; 0104 Q_DECLARE_FLAGS(LoadingHints, LoadingHint) 0105 0106 /** Sets image loading hints. */ 0107 void setLoadingHints(LoadingHints hints); 0108 0109 /** The source image without display transformations applied. */ 0110 QImage image() const; 0111 0112 /** Returns whether this image has an object id. 0113 * Vector graphic "images" don't have that. 0114 */ 0115 bool hasObjectId() const; 0116 0117 /** PDF-internal unique identifier of this image. 0118 * Use this to detect multiple occurrences of the same image in different 0119 * places, if that reduces e.g. computation cost. 0120 */ 0121 PdfImageRef objectId() const; 0122 0123 /** Returns whether this is a raster or vector image. */ 0124 bool isVectorImage() const; 0125 0126 /** If this is a vector image, this returns the number 0127 * of vector path elemets. 0128 */ 0129 int pathElementsCount() const; 0130 0131 /** Returns @c true if this image has an aspect-ratio changing transform. 0132 * That might need to be applied before doing barcode decoding for example. 0133 */ 0134 [[nodiscard]] bool hasAspectRatioTransform() const; 0135 0136 /** Applies the aspect ratio changing part of the transform 0137 * to the given image (which typically should be the one returned 0138 * by image()). 0139 */ 0140 [[nodiscard]] QImage applyAspectRatioTransform(const QImage &image) const; 0141 0142 private: 0143 friend class PdfExtractorOutputDevice; 0144 friend class PdfPagePrivate; 0145 friend class PdfPage; 0146 QExplicitlySharedDataPointer<PdfImagePrivate> d; 0147 }; 0148 0149 Q_DECLARE_OPERATORS_FOR_FLAGS(PdfImage::LoadingHints) 0150 0151 } 0152 0153 std::size_t std::hash<KItinerary::PdfImageRef>::operator()(const KItinerary::PdfImageRef &ref) const noexcept 0154 { 0155 // first part is how poppler hashes its Ref type 0156 return std::hash<int>{}(ref.m_refNum) ^ (std::hash<int>{}(ref.m_refGen) << 1) ^ std::hash<int>{}((int)ref.m_type); 0157 }