1
2 #include "RkCairoImageBackendCanvas.h"
3 #include "RkCanvasInfo.h"
4 #include "RkLog.h"
5
RkCairoImageBackendCanvas(const RkSize & size,RkImage::Format format,const unsigned char * data)6 RkCairoImageBackendCanvas::RkCairoImageBackendCanvas(const RkSize &size,
7 RkImage::Format format,
8 const unsigned char *data)
9 : canvasInfo{nullptr}
10 , imageSize{size}
11 {
12 #ifdef RK_OS_WIN
13 #elif RK_OS_MAC
14 #else // X11
15 auto cairoFormat = toCairoFormat(format);
16 if (cairoFormat != CAIRO_FORMAT_INVALID && imageSize.width() > 0 && imageSize.height() > 0) {
17 canvasInfo = std::make_unique<RkCanvasInfo>();
18 auto stride = cairo_format_stride_for_width(cairoFormat, imageSize.width());
19 if (data == nullptr)
20 imageData = std::vector<unsigned char>(imageSize.width() * imageSize.height() * pixelLength(format), 0);
21 else
22 imageData.assign(data, data + imageSize.width() * imageSize.height() * pixelLength(format));
23 canvasInfo->cairo_surface = cairo_image_surface_create_for_data(imageData.data(),
24 CAIRO_FORMAT_ARGB32,
25 imageSize.width(),
26 imageSize.height(),
27 stride);
28 }
29 #endif
30 }
31
~RkCairoImageBackendCanvas()32 RkCairoImageBackendCanvas::~RkCairoImageBackendCanvas()
33 {
34 if (canvasInfo)
35 cairo_surface_destroy(canvasInfo->cairo_surface);
36 }
37
toCairoFormat(RkImage::Format format) const38 cairo_format_t RkCairoImageBackendCanvas::toCairoFormat(RkImage::Format format) const
39 {
40 switch (format)
41 {
42 case RkImage::Format::ARGB32: return CAIRO_FORMAT_ARGB32;
43 case RkImage::Format::RGB32: return CAIRO_FORMAT_RGB24;
44 default: return CAIRO_FORMAT_INVALID;
45 }
46 }
47
pixelLength(RkImage::Format format) const48 int RkCairoImageBackendCanvas::pixelLength(RkImage::Format format) const
49 {
50 switch (format)
51 {
52 case RkImage::Format::ARGB32:
53 case RkImage::Format::RGB32: return 4;
54 default: return 1;
55 }
56 }
57
size() const58 const RkSize& RkCairoImageBackendCanvas::size() const
59 {
60 return imageSize;
61 }
62
isNull() const63 bool RkCairoImageBackendCanvas::isNull() const
64 {
65 return canvasInfo == nullptr;
66 }
67
data()68 unsigned char* RkCairoImageBackendCanvas::data()
69 {
70 return imageData.data();
71 }
72
dataCopy() const73 std::vector<unsigned char> RkCairoImageBackendCanvas::dataCopy() const
74 {
75 return imageData;
76 }
77
getCanvasInfo() const78 RkCanvasInfo* RkCairoImageBackendCanvas::getCanvasInfo() const
79 {
80 return canvasInfo.get();
81 }
82
fill(const RkColor & color)83 void RkCairoImageBackendCanvas::fill(const RkColor &color)
84 {
85 unsigned char *data = imageData.data();
86 for (decltype(imageData.size()) i = 0; i < imageData.size() - 4; i += 4) {
87 *(data + i) = color.red();
88 *(data + i + 1) = color.green();
89 *(data + i + 2) = color.blue();
90 *(data + i + 3) = color.alpha();
91 }
92 }
93