2 #include <kms++/kms++.h>
3 #include <kms++util/kms++util.h>
5 using namespace std;
7 namespace kms
8 {
9 void draw_rgb_pixel(IMappedFramebuffer& buf, unsigned x, unsigned y, RGB color)
10 {
11 switch (buf.format()) {
12 case PixelFormat::XRGB8888:
13 case PixelFormat::ARGB8888:
14 {
15 uint32_t *p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
16 *p = color.argb8888();
17 break;
18 }
19 case PixelFormat::XBGR8888:
20 case PixelFormat::ABGR8888:
21 {
22 uint32_t *p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
23 *p = color.abgr8888();
24 break;
25 }
26 case PixelFormat::RGB565:
27 {
28 uint16_t *p = (uint16_t*)(buf.map(0) + buf.stride(0) * y + x * 2);
29 *p = color.rgb565();
30 break;
31 }
32 default:
33 throw std::invalid_argument("invalid pixelformat");
34 }
35 }
37 void draw_yuv422_macropixel(IMappedFramebuffer& buf, unsigned x, unsigned y, YUV yuv1, YUV yuv2)
38 {
39 ASSERT((x & 1) == 0);
41 uint8_t *p = (uint8_t*)(buf.map(0) + buf.stride(0) * y + x * 2);
43 uint8_t y0 = yuv1.y;
44 uint8_t y1 = yuv2.y;
45 uint8_t u = (yuv1.u + yuv2.u) / 2;
46 uint8_t v = (yuv1.v + yuv2.v) / 2;
48 switch (buf.format()) {
49 case PixelFormat::UYVY:
50 p[0] = u;
51 p[1] = y0;
52 p[2] = v;
53 p[3] = y1;
54 break;
56 case PixelFormat::YUYV:
57 p[0] = y0;
58 p[1] = u;
59 p[2] = y1;
60 p[3] = v;
61 break;
63 case PixelFormat::YVYU:
64 p[0] = y0;
65 p[1] = v;
66 p[2] = y1;
67 p[3] = u;
68 break;
70 case PixelFormat::VYUY:
71 p[0] = v;
72 p[1] = y0;
73 p[2] = u;
74 p[3] = y1;
75 break;
77 default:
78 throw std::invalid_argument("invalid pixelformat");
79 }
80 }
82 void draw_yuv420_macropixel(IMappedFramebuffer& buf, unsigned x, unsigned y,
83 YUV yuv1, YUV yuv2, YUV yuv3, YUV yuv4)
84 {
85 ASSERT((x & 1) == 0);
86 ASSERT((y & 1) == 0);
88 uint8_t *py1 = (uint8_t*)(buf.map(0) + buf.stride(0) * (y + 0) + x);
89 uint8_t *py2 = (uint8_t*)(buf.map(0) + buf.stride(0) * (y + 1) + x);
91 uint8_t *puv = (uint8_t*)(buf.map(1) + buf.stride(1) * (y / 2) + x);
93 uint8_t y0 = yuv1.y;
94 uint8_t y1 = yuv2.y;
95 uint8_t y2 = yuv3.y;
96 uint8_t y3 = yuv4.y;
97 uint8_t u = (yuv1.u + yuv2.u + yuv3.u + yuv4.u) / 4;
98 uint8_t v = (yuv1.v + yuv2.v + yuv3.v + yuv4.v) / 4;
100 switch (buf.format()) {
101 case PixelFormat::NV12:
102 py1[0] = y0;
103 py1[1] = y1;
104 py2[0] = y2;
105 py2[1] = y3;
106 puv[0] = u;
107 puv[1] = v;
108 break;
110 case PixelFormat::NV21:
111 py1[0] = y0;
112 py1[1] = y1;
113 py2[0] = y2;
114 py2[1] = y3;
115 puv[0] = v;
116 puv[1] = u;
117 break;
119 default:
120 throw std::invalid_argument("invalid pixelformat");
121 }
122 }
124 void draw_rect(IMappedFramebuffer &fb, uint32_t x, uint32_t y, uint32_t w, uint32_t h, RGB color)
125 {
126 for (unsigned i = x; i < x + w; ++i) {
127 for (unsigned j = y; j < y + h; ++j) {
128 draw_rgb_pixel(fb, i, j, color);
129 }
130 }
131 }
133 static void draw_char(IMappedFramebuffer& buf, uint32_t xpos, uint32_t ypos, char c, RGB color)
134 {
135 #include "font_8x8.h"
137 for (uint32_t y = 0; y < 8; y++) {
138 uint8_t bits = fontdata_8x8[8 * c + y];
140 for (uint32_t x = 0; x < 8; x++) {
141 bool bit = (bits >> (7 - x)) & 1;
143 draw_rgb_pixel(buf, xpos + x, ypos + y, bit ? color : RGB());
144 }
145 }
146 }
148 void draw_text(IMappedFramebuffer& buf, uint32_t x, uint32_t y, const string& str, RGB color)
149 {
150 for(unsigned i = 0; i < str.size(); i++)
151 draw_char(buf, (x + 8 * i), y, str[i], color);
152 }
154 }