kis_acs_pixel_cache_renderer.h 2.7 KB
Newer Older
1
/*
2
 *  SPDX-FileCopyrightText: 2014 Dmitry Kazakov <dimula73@gmail.com>
3
 *
Samuel Gaist's avatar
Samuel Gaist committed
4
 *  SPDX-License-Identifier: GPL-2.0-or-later
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 */

#ifndef __KIS_ACS_PIXEL_CACHE_RENDERER_H
#define __KIS_ACS_PIXEL_CACHE_RENDERER_H

#include "KoColorSpace.h"
#include "kis_paint_device.h"
#include "kis_iterator_ng.h"
#include "kis_display_color_converter.h"


namespace Acs {

    class PixelCacheRenderer {
    public:
        /**
21 22
         * \p Sampler class must provide one method:
         *     - KoColor Sampler::colorAt(float x, float y);
23 24
         *
         * How to handle High DPI:
25
         *  - sampleRect - is in device independent pixels coordinates space
26 27 28
         *     (amount of space on the widget)
         *  - devicePixelRatioF - the amount of UI scaling
         *  - pixelCache and realPixelCache gets the size of
29
         *     sampleRect.size()*devicePixelRatioF
30
         *     and sets the device pixel ratio,
31
         *     and color samplers need to take it into account.
32 33
         *  That way you can paint on the cache the same way you'd paint on a low dpi display
         *    and then just use painter->drawImage() and it works.
34
         */
35 36
        template <class Sampler>
        static void render(Sampler *sampler,
37
                           const KisDisplayColorConverter *converter,
38
                           const QRect &sampleRect,
39 40
                           KisPaintDeviceSP &realPixelCache,
                           QImage &pixelCache,
41 42
                           QPoint &pixelCacheOffset,
                           qreal devicePixelRatioF)
43 44 45
            {
                const KoColorSpace *cacheColorSpace = converter->paintingColorSpace();
                const int pixelSize = cacheColorSpace->pixelSize();
46 47 48 49

                if (!realPixelCache || realPixelCache->colorSpace() != cacheColorSpace) {
                    realPixelCache = new KisPaintDevice(cacheColorSpace);
                }
50 51 52

                KoColor color;

53 54
                QRect sampleRectHighDPI = QRect(sampleRect.topLeft(), sampleRect.size()*devicePixelRatioF);
                KisSequentialIterator it(realPixelCache, sampleRectHighDPI);
55

56
                while (it.nextPixel()) {
57
                    color = sampler->colorAt(it.x()/devicePixelRatioF, it.y()/devicePixelRatioF);
58
                    memcpy(it.rawData(), color.data(), pixelSize);
59
                }
60 61 62 63


                // NOTE: toQImage() function of the converter copies exactBounds() only!
                pixelCache = converter->toQImage(realPixelCache);
64
                pixelCache.setDevicePixelRatio(devicePixelRatioF);
65
                pixelCacheOffset = realPixelCache->exactBounds().topLeft()/devicePixelRatioF - sampleRect.topLeft();
66
        }
67 68 69 70
    };
}

#endif /* __KIS_ACS_PIXEL_CACHE_RENDERER_H */