File indexing completed on 2025-01-05 03:59:44
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2011-04-27 0007 * Description : image preview item for image editor. 0008 * 0009 * SPDX-FileCopyrightText: 2011-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "imagepreviewitem.h" 0016 0017 // Qt includes 0018 0019 #include <QStyleOptionGraphicsItem> 0020 #include <QApplication> 0021 #include <QPainter> 0022 #include <QPixmap> 0023 0024 // Local includes 0025 0026 #include "dimg.h" 0027 #include "exposurecontainer.h" 0028 #include "iccmanager.h" 0029 #include "iccsettingscontainer.h" 0030 #include "icctransform.h" 0031 #include "editorcore.h" 0032 #include "dimgitems_p.h" 0033 0034 namespace Digikam 0035 { 0036 0037 ImagePreviewItem::ImagePreviewItem() 0038 { 0039 Q_D(GraphicsDImgItem); 0040 d->init(this); 0041 } 0042 0043 ImagePreviewItem::~ImagePreviewItem() 0044 { 0045 } 0046 0047 void ImagePreviewItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) 0048 { 0049 Q_D(GraphicsDImgItem); 0050 0051 QRect drawRect = option->exposedRect.intersected(boundingRect()).toAlignedRect(); 0052 QRect pixSourceRect; 0053 QPixmap pix; 0054 QSize completeSize = boundingRect().size().toSize(); 0055 0056 /* 0057 * For high resolution ("retina") displays, Mac OS X / Qt 0058 * report only half of the physical resolution in terms of 0059 * pixels, i.e. every logical pixels corresponds to 2x2 0060 * physical pixels. However, UI elements and fonts are 0061 * nevertheless rendered at full resolution, and pixmaps 0062 * as well, provided their resolution is high enough (that 0063 * is, higher than the reported, logical resolution). 0064 * 0065 * To work around this, we render the photos not a logical 0066 * resolution, but with the photo's full resolution, but 0067 * at the screen's aspect ratio. When we later draw this 0068 * high resolution bitmap, it is up to Qt to scale the 0069 * photo to the true physical resolution. The ratio 0070 * computed below is the ratio between the photo and 0071 * screen resolutions, or equivalently the factor by which 0072 * we need to increase the pixel size of the rendered 0073 * pixmap. 0074 */ 0075 0076 qreal dpr = widget->devicePixelRatio(); 0077 0078 QRect scaledDrawRect = QRectF(dpr * drawRect.x(), 0079 dpr * drawRect.y(), 0080 dpr * drawRect.width(), 0081 dpr * drawRect.height()).toRect(); 0082 0083 // scale "as if" scaling to whole image, but clip output to our exposed region 0084 0085 QSize scaledCompleteSize = QSizeF(dpr * completeSize.width(), 0086 dpr * completeSize.height()).toSize(); 0087 DImg scaledImage = d->image.smoothScaleClipped(scaledCompleteSize.width(), 0088 scaledCompleteSize.height(), 0089 scaledDrawRect.x(), 0090 scaledDrawRect.y(), 0091 scaledDrawRect.width(), 0092 scaledDrawRect.height()); 0093 0094 if (d->cachedPixmaps.find(scaledDrawRect, &pix, &pixSourceRect)) 0095 { 0096 if (pixSourceRect.isNull()) 0097 { 0098 painter->drawPixmap(drawRect, pix); 0099 } 0100 else 0101 { 0102 painter->drawPixmap(drawRect, pix, pixSourceRect); 0103 } 0104 } 0105 else 0106 { 0107 // TODO: factoring ICC settings code using ImageIface/EditorCore methods. 0108 0109 // Apply CM settings. 0110 0111 bool doSoftProofing = EditorCore::defaultInstance()->softProofingEnabled(); 0112 ICCSettingsContainer iccSettings = EditorCore::defaultInstance()->getICCSettings(); 0113 0114 if (iccSettings.enableCM && (iccSettings.useManagedView || doSoftProofing)) 0115 { 0116 IccManager manager(scaledImage); 0117 IccTransform monitorICCtrans; 0118 0119 if (doSoftProofing) 0120 { 0121 monitorICCtrans = manager.displaySoftProofingTransform(IccProfile(iccSettings.defaultProofProfile), widget); 0122 } 0123 else 0124 { 0125 monitorICCtrans = manager.displayTransform(widget); 0126 } 0127 0128 pix = scaledImage.convertToPixmap(monitorICCtrans); 0129 } 0130 else 0131 { 0132 pix = scaledImage.convertToPixmap(); 0133 } 0134 0135 d->cachedPixmaps.insert(scaledDrawRect, pix); 0136 0137 painter->drawPixmap(drawRect, pix); 0138 } 0139 0140 // Show the Over/Under exposure pixels indicators 0141 0142 ExposureSettingsContainer* const expoSettings = EditorCore::defaultInstance()->getExposureSettings(); 0143 0144 if (expoSettings) 0145 { 0146 if (expoSettings->underExposureIndicator || expoSettings->overExposureIndicator) 0147 { 0148 QImage pureColorMask = scaledImage.pureColorMask(expoSettings); 0149 QPixmap pixMask = QPixmap::fromImage(pureColorMask); 0150 painter->drawPixmap(drawRect, pixMask); 0151 } 0152 } 0153 } 0154 0155 } // namespace Digikam 0156 0157 #include "moc_imagepreviewitem.cpp"