File indexing completed on 2024-05-12 15:56:55
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef __KIS_ACS_PIXEL_CACHE_RENDERER_H 0008 #define __KIS_ACS_PIXEL_CACHE_RENDERER_H 0009 0010 #include "KoColorSpace.h" 0011 #include "kis_paint_device.h" 0012 #include "kis_iterator_ng.h" 0013 #include "kis_display_color_converter.h" 0014 0015 0016 namespace Acs { 0017 0018 class PixelCacheRenderer { 0019 public: 0020 /** 0021 * \p Sampler class must provide one method: 0022 * - KoColor Sampler::colorAt(float x, float y); 0023 * 0024 * How to handle High DPI: 0025 * - sampleRect - is in device independent pixels coordinates space 0026 * (amount of space on the widget) 0027 * - devicePixelRatioF - the amount of UI scaling 0028 * - pixelCache and realPixelCache gets the size of 0029 * sampleRect.size()*devicePixelRatioF 0030 * and sets the device pixel ratio, 0031 * and color samplers need to take it into account. 0032 * That way you can paint on the cache the same way you'd paint on a low dpi display 0033 * and then just use painter->drawImage() and it works. 0034 */ 0035 template <class Sampler> 0036 static void render(Sampler *sampler, 0037 const KisDisplayColorConverter *converter, 0038 const QRect &sampleRect, 0039 KisPaintDeviceSP &realPixelCache, 0040 QImage &pixelCache, 0041 QPoint &pixelCacheOffset, 0042 qreal devicePixelRatioF) 0043 { 0044 const KoColorSpace *cacheColorSpace = converter->paintingColorSpace(); 0045 const int pixelSize = cacheColorSpace->pixelSize(); 0046 0047 if (!realPixelCache || realPixelCache->colorSpace() != cacheColorSpace) { 0048 realPixelCache = new KisPaintDevice(cacheColorSpace); 0049 } 0050 0051 KoColor color; 0052 0053 QRect sampleRectHighDPI = QRect(sampleRect.topLeft(), sampleRect.size()*devicePixelRatioF); 0054 KisSequentialIterator it(realPixelCache, sampleRectHighDPI); 0055 0056 while (it.nextPixel()) { 0057 color = sampler->colorAt(it.x()/devicePixelRatioF, it.y()/devicePixelRatioF); 0058 memcpy(it.rawData(), color.data(), pixelSize); 0059 } 0060 0061 0062 // NOTE: toQImage() function of the converter copies exactBounds() only! 0063 pixelCache = converter->toQImage(realPixelCache); 0064 pixelCache.setDevicePixelRatio(devicePixelRatioF); 0065 pixelCacheOffset = realPixelCache->exactBounds().topLeft()/devicePixelRatioF - sampleRect.topLeft(); 0066 } 0067 }; 0068 } 0069 0070 #endif /* __KIS_ACS_PIXEL_CACHE_RENDERER_H */