1 /* 2 * Copyright (c) 2014 Dmitry Kazakov <dimula73@gmail.com> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 */ 18 19 #ifndef __KIS_ACS_PIXEL_CACHE_RENDERER_H 20 #define __KIS_ACS_PIXEL_CACHE_RENDERER_H 21 22 #include "KoColorSpace.h" 23 #include "kis_paint_device.h" 24 #include "kis_iterator_ng.h" 25 #include "kis_display_color_converter.h" 26 27 28 namespace Acs { 29 30 class PixelCacheRenderer { 31 public: 32 /** 33 * \p Picker class must provide one method: 34 * - KoColor Picker::colorAt(float x, float y); 35 * 36 * How to handle High DPI: 37 * - pickRect - is in device independent pixels coordinates space 38 * (amount of space on the widget) 39 * - devicePixelRatioF - the amount of UI scaling 40 * - pixelCache and realPixelCache gets the size of 41 * pickRect.size()*devicePixelRatioF 42 * and sets the device pixel ratio, 43 * and color pickers need to take it into account. 44 * That way you can paint on the cache the same way you'd paint on a low dpi display 45 * and then just use painter->drawImage() and it works. 46 */ 47 template <class Picker> render(Picker * picker,const KisDisplayColorConverter * converter,const QRect & pickRect,KisPaintDeviceSP & realPixelCache,QImage & pixelCache,QPoint & pixelCacheOffset,qreal devicePixelRatioF)48 static void render(Picker *picker, 49 const KisDisplayColorConverter *converter, 50 const QRect &pickRect, 51 KisPaintDeviceSP &realPixelCache, 52 QImage &pixelCache, 53 QPoint &pixelCacheOffset, 54 qreal devicePixelRatioF) 55 { 56 const KoColorSpace *cacheColorSpace = converter->paintingColorSpace(); 57 const int pixelSize = cacheColorSpace->pixelSize(); 58 59 if (!realPixelCache || realPixelCache->colorSpace() != cacheColorSpace) { 60 realPixelCache = new KisPaintDevice(cacheColorSpace); 61 } 62 63 KoColor color; 64 65 QRect pickRectHighDPI = QRect(pickRect.topLeft(), pickRect.size()*devicePixelRatioF); 66 KisSequentialIterator it(realPixelCache, pickRectHighDPI); 67 68 while (it.nextPixel()) { 69 color = picker->colorAt(it.x()/devicePixelRatioF, it.y()/devicePixelRatioF); 70 memcpy(it.rawData(), color.data(), pixelSize); 71 } 72 73 74 // NOTE: toQImage() function of the converter copies exactBounds() only! 75 pixelCache = converter->toQImage(realPixelCache); 76 pixelCache.setDevicePixelRatio(devicePixelRatioF); 77 pixelCacheOffset = realPixelCache->exactBounds().topLeft()/devicePixelRatioF - pickRect.topLeft(); 78 } 79 }; 80 } 81 82 #endif /* __KIS_ACS_PIXEL_CACHE_RENDERER_H */ 83