File indexing completed on 2025-01-05 03:53:12
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2002-12-09 0007 * Description : a tool to print images 0008 * 0009 * SPDX-FileCopyrightText: 2002-2003 by Todd Shoemaker <todd at theshoemakers dot net> 0010 * SPDX-FileCopyrightText: 2007-2012 by Angelo Naselli <anaselli at linux dot it> 0011 * SPDX-FileCopyrightText: 2006-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0012 * 0013 * SPDX-License-Identifier: GPL-2.0-or-later 0014 * 0015 * ============================================================ */ 0016 0017 #include "advprintphoto.h" 0018 0019 // Qt includes 0020 0021 #include <QFileInfo> 0022 #include <QPolygon> 0023 0024 // KDE includes 0025 0026 #include <klocalizedstring.h> 0027 0028 // Local includes 0029 0030 #include "digikam_debug.h" 0031 #include "previewloadthread.h" 0032 #include "advprintwizard.h" 0033 0034 namespace DigikamGenericPrintCreatorPlugin 0035 { 0036 0037 AdvPrintPhotoSize::AdvPrintPhotoSize() 0038 : m_label (i18n("Unsupported Paper Size")), 0039 m_dpi (0), 0040 m_autoRotate(false) 0041 { 0042 } 0043 0044 AdvPrintPhotoSize::AdvPrintPhotoSize(const AdvPrintPhotoSize& other) 0045 : m_label (other.m_label), 0046 m_dpi (other.m_dpi), 0047 m_autoRotate(other.m_autoRotate), 0048 m_layouts (other.m_layouts), 0049 m_icon (other.m_icon) 0050 0051 { 0052 } 0053 0054 AdvPrintPhotoSize::~AdvPrintPhotoSize() 0055 { 0056 } 0057 0058 // ----------------------------- 0059 0060 AdvPrintAdditionalInfo::AdvPrintAdditionalInfo() 0061 : m_unit (0), 0062 m_printPosition (0), 0063 m_scaleMode (0), 0064 m_keepRatio (true), 0065 m_autoRotate (true), 0066 m_printWidth (0.0), 0067 m_printHeight (0.0), 0068 m_enlargeSmallerImages(false) 0069 { 0070 } 0071 0072 AdvPrintAdditionalInfo::AdvPrintAdditionalInfo(const AdvPrintAdditionalInfo& other) 0073 : m_unit (other.m_unit), 0074 m_printPosition (other.m_printPosition), 0075 m_scaleMode (other.m_scaleMode), 0076 m_keepRatio (other.m_keepRatio), 0077 m_autoRotate (other.m_autoRotate), 0078 m_printWidth (other.m_printWidth), 0079 m_printHeight (other.m_printHeight), 0080 m_enlargeSmallerImages(other.m_enlargeSmallerImages) 0081 { 0082 } 0083 0084 AdvPrintAdditionalInfo::~AdvPrintAdditionalInfo() 0085 { 0086 } 0087 0088 // ----------------------------- 0089 0090 AdvPrintCaptionInfo::AdvPrintCaptionInfo() 0091 : m_captionType (AdvPrintSettings::NONE), 0092 m_captionFont (QLatin1String("Sans Serif")), 0093 m_captionColor(Qt::yellow), 0094 m_captionSize (2), 0095 m_captionText (QLatin1String("")) 0096 { 0097 } 0098 0099 AdvPrintCaptionInfo::AdvPrintCaptionInfo(const AdvPrintCaptionInfo& other) 0100 : m_captionType (other.m_captionType), 0101 m_captionFont (other.m_captionFont), 0102 m_captionColor(other.m_captionColor), 0103 m_captionSize (other.m_captionSize), 0104 m_captionText (other.m_captionText) 0105 { 0106 } 0107 0108 AdvPrintCaptionInfo::~AdvPrintCaptionInfo() 0109 { 0110 } 0111 0112 // ----------------------------- 0113 0114 AdvPrintPhoto::AdvPrintPhoto(int thumbnailSize, DInfoInterface* const iface) 0115 : m_url (QUrl()), 0116 m_thumbnailSize (thumbnailSize), 0117 m_cropRegion (QRect(-1, -1, -1, -1)), 0118 m_first (false), 0119 m_copies (1), 0120 m_rotation (0), 0121 m_pAddInfo (nullptr), 0122 m_pAdvPrintCaptionInfo(nullptr), 0123 m_iface (iface), 0124 m_thumbnail (nullptr), 0125 m_size (nullptr) 0126 { 0127 } 0128 0129 AdvPrintPhoto::AdvPrintPhoto(const AdvPrintPhoto& other) 0130 : m_url (other.m_url), 0131 m_thumbnailSize (other.m_thumbnailSize), 0132 m_cropRegion (other.m_cropRegion), 0133 m_first (other.m_first), 0134 m_copies (other.m_copies), 0135 m_rotation (other.m_rotation), 0136 m_pAddInfo (nullptr), 0137 m_pAdvPrintCaptionInfo(nullptr), 0138 m_iface (other.m_iface), 0139 m_thumbnail (nullptr), 0140 m_size (nullptr) 0141 { 0142 if (other.m_pAddInfo) 0143 { 0144 m_pAddInfo = new AdvPrintAdditionalInfo(*other.m_pAddInfo); 0145 } 0146 0147 if (other.m_pAdvPrintCaptionInfo) 0148 { 0149 m_pAdvPrintCaptionInfo = new AdvPrintCaptionInfo(*other.m_pAdvPrintCaptionInfo); 0150 } 0151 } 0152 0153 AdvPrintPhoto::~AdvPrintPhoto() 0154 { 0155 delete m_thumbnail; 0156 delete m_size; 0157 delete m_pAddInfo; 0158 delete m_pAdvPrintCaptionInfo; 0159 } 0160 0161 void AdvPrintPhoto::loadInCache() 0162 { 0163 // Load the thumbnail and size only once. 0164 0165 delete m_thumbnail; 0166 DImg photo = loadPhoto(); 0167 m_thumbnail = new DImg(photo.smoothScale(m_thumbnailSize, m_thumbnailSize, Qt::KeepAspectRatio)); 0168 0169 delete m_size; 0170 m_size = new QSize(photo.width(), photo.height()); 0171 } 0172 0173 DImg& AdvPrintPhoto::thumbnail() 0174 { 0175 if (!m_thumbnail) 0176 { 0177 loadInCache(); 0178 } 0179 0180 return *m_thumbnail; 0181 } 0182 0183 DImg AdvPrintPhoto::loadPhoto() 0184 { 0185 return PreviewLoadThread::loadHighQualitySynchronously(m_url.toLocalFile()); 0186 } 0187 0188 QSize& AdvPrintPhoto::size() 0189 { 0190 if (m_size == nullptr) 0191 { 0192 loadInCache(); 0193 } 0194 0195 return *m_size; 0196 } 0197 0198 int AdvPrintPhoto::width() 0199 { 0200 return size().width(); 0201 } 0202 0203 int AdvPrintPhoto::height() 0204 { 0205 return size().height(); 0206 } 0207 0208 double AdvPrintPhoto::scaleWidth(double unitToInches) 0209 { 0210 Q_ASSERT(m_pAddInfo != nullptr); 0211 0212 m_cropRegion = QRect(0, 0, 0213 (int)(m_pAddInfo->m_printWidth * unitToInches), 0214 (int)(m_pAddInfo->m_printHeight * unitToInches)); 0215 0216 return (m_pAddInfo->m_printWidth * unitToInches); 0217 } 0218 0219 double AdvPrintPhoto::scaleHeight(double unitToInches) 0220 { 0221 Q_ASSERT(m_pAddInfo != nullptr); 0222 0223 m_cropRegion = QRect(0, 0, 0224 (int)(m_pAddInfo->m_printWidth * unitToInches), 0225 (int)(m_pAddInfo->m_printHeight * unitToInches)); 0226 0227 return (m_pAddInfo->m_printHeight * unitToInches); 0228 } 0229 0230 QTransform AdvPrintPhoto::updateCropRegion(int woutlay, int houtlay, bool autoRotate) 0231 { 0232 QSize thmSize = thumbnail().size(); 0233 QRect imgRect = QRect(0, 0, size().width(), size().height()); 0234 bool resetCropRegion = (m_cropRegion == QRect(-1, -1, -1, -1)); 0235 0236 if (resetCropRegion) 0237 { 0238 // First, let's see if we should rotate 0239 0240 if (autoRotate) 0241 { 0242 if ((m_rotation == 0) && 0243 (((woutlay > houtlay) && (thmSize.height() > thmSize.width())) || 0244 ((houtlay > woutlay) && (thmSize.width() > thmSize.height())))) 0245 { 0246 // We will perform a rotation 0247 0248 m_rotation = 90; 0249 } 0250 } 0251 } 0252 else 0253 { 0254 // Does the crop region need updating (but the image shouldn't be rotated)? 0255 0256 resetCropRegion = (m_cropRegion == QRect(-2, -2, -2, -2)); 0257 } 0258 0259 // Rotate the image rectangle. 0260 0261 QTransform matrix; 0262 matrix.rotate(m_rotation); 0263 imgRect = matrix.mapToPolygon(imgRect).boundingRect(); 0264 imgRect.translate((-1)*imgRect.x(), (-1)*imgRect.y()); 0265 0266 // Size the rectangle based on the minimum image dimension. 0267 0268 int w = imgRect.width(); 0269 int h = imgRect.height(); 0270 0271 if (w < h) 0272 { 0273 h = AdvPrintWizard::normalizedInt((double)w * ((double)houtlay / (double)woutlay)); 0274 0275 if (h > imgRect.height()) 0276 { 0277 h = imgRect.height(); 0278 w = AdvPrintWizard::normalizedInt((double)h * ((double)woutlay / (double)houtlay)); 0279 } 0280 } 0281 else 0282 { 0283 w = AdvPrintWizard::normalizedInt((double)h * ((double)woutlay / (double)houtlay)); 0284 0285 if (w > imgRect.width()) 0286 { 0287 w = imgRect.width(); 0288 h = AdvPrintWizard::normalizedInt((double)w * ((double)houtlay / (double)woutlay)); 0289 } 0290 } 0291 0292 if (resetCropRegion) 0293 { 0294 m_cropRegion = QRect((imgRect.width() / 2) - (w / 2), 0295 (imgRect.height() / 2) - (h / 2), 0296 w, h); 0297 } 0298 0299 return matrix; 0300 } 0301 0302 } // Namespace Digikam