-
Notifications
You must be signed in to change notification settings - Fork 1
/
FastCairoPaintedItem.cpp
70 lines (51 loc) · 1.45 KB
/
FastCairoPaintedItem.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include "cairo/cairo.h"
#include <QPainter>
#include <execution>
#include "shuffler.hpp"
#include "CairoPaintedItem.hpp"
//////////////////////////////////////////////////////////////////////////////
CairoPaintedItem::~CairoPaintedItem() { cairo_destroy(cr_); }
//////////////////////////////////////////////////////////////////////////////
void CairoPaintedItem::init(cairo_t* const cr, int, int)
{
cairo_set_line_width(cr, 1.);
cairo_translate(cr, .5, .5);
}
//////////////////////////////////////////////////////////////////////////////
void CairoPaintedItem::paint(QPainter* const p)
{
auto cr(cr_);
int const w(width()), h(height());
auto& img(*static_cast<QImage*>(p->device()));
auto const d(img.bits());
if ((w != w_) || (h != h_) || (d != d_))
{
w_ = w; h_ = h; d_ = d;
//
cairo_destroy(cr);
auto const srf(
cairo_image_surface_create_for_data(
d,
CAIRO_FORMAT_ARGB32,
w,
h,
img.bytesPerLine()
)
);
cr_ = cr = cairo_create(srf);
cairo_surface_destroy(srf);
init(cr, w, h);
}
//
cairo_save(cr);
draw(cr, w, h);
cairo_restore(cr);
//
if (QImage::Format_RGBA8888_Premultiplied == img.format())
{
// img.rgbSwap(); // but the shuffler is faster
auto const src(reinterpret_cast<quint32*>(d));
std::transform(std::execution::unseq, src, src + img.sizeInBytes() / 4,
src, (quint32(&)(quint32))(shuffler::shuffle<2, 1, 0, 3>));
}
}