1 #ifndef NK_RAW_WAYLAND_H_
2 #define NK_RAW_WAYLAND_H_
3 
4 #define WIDTH 800
5 #define HEIGHT 600
6 
7 #ifndef MIN
8 #define MIN(a,b) ((a) < (b) ? (a) : (b))
9 #endif
10 #ifndef MAX
11 #define MAX(a,b) ((a) < (b) ? (b) : (a))
12 #endif
13 
14 typedef enum wayland_pixel_layout {
15     PIXEL_LAYOUT_XRGB_8888,
16     PIXEL_LAYOUT_RGBX_8888,
17 } wayland_pl;
18 
19 struct wayland_img {
20     void *pixels;
21     int w, h, pitch;
22     wayland_pl pl;
23     enum nk_font_atlas_format format;
24 };
25 
26 struct nk_wayland{
27     /*wayland vars*/
28     struct wl_display *display;
29     struct wl_compositor *compositor;
30     struct xdg_wm_base *xdg_wm_base;
31     struct wl_shm *wl_shm;
32     struct wl_seat* seat;
33     struct wl_callback *frame_callback;
34     struct wl_surface *surface;
35 	struct xdg_surface *xdg_surface;
36 	struct xdg_toplevel *xdg_toplevel;
37 	struct wl_buffer *front_buffer;
38 
39 
40     /*nuklear vars*/
41     struct nk_context ctx;
42     struct nk_rect scissors;
43     struct nk_font_atlas atlas;
44     struct wayland_img font_tex;
45 	int32_t width, height;
46 	int32_t *data;
47     int mouse_pointer_x;
48     int mouse_pointer_y;
49     uint8_t tex_scratch[512 * 512];
50 
51 };
52 
nk_color_to_xrgb8888(struct nk_color col)53 static uint32_t nk_color_to_xrgb8888(struct nk_color col)
54 {
55     return (col.a << 24) + (col.r << 16) + (col.g << 8) + col.b;
56 }
57 
nk_wayland_int2color(const unsigned int i,wayland_pl pl)58 static struct nk_color nk_wayland_int2color(const unsigned int i, wayland_pl pl)
59 {
60     struct nk_color col = {0,0,0,0};
61 
62     switch (pl) {
63     case PIXEL_LAYOUT_RGBX_8888:
64         col.r = (i >> 24) & 0xff;
65         col.g = (i >> 16) & 0xff;
66         col.b = (i >> 8) & 0xff;
67         col.a = i & 0xff;
68         break;
69     case PIXEL_LAYOUT_XRGB_8888:
70         col.a = (i >> 24) & 0xff;
71         col.r = (i >> 16) & 0xff;
72         col.g = (i >> 8) & 0xff;
73         col.b = i & 0xff;
74         break;
75 
76     default:
77         perror("nk_rawfb_int2color(): Unsupported pixel layout.\n");
78         break;
79     }
80     return col;
81 }
82 
nk_wayland_color2int(const struct nk_color c,wayland_pl pl)83 static unsigned int nk_wayland_color2int(const struct nk_color c, wayland_pl pl)
84 {
85     unsigned int res = 0;
86 
87     switch (pl) {
88     case PIXEL_LAYOUT_RGBX_8888:
89         res |= c.r << 24;
90         res |= c.g << 16;
91         res |= c.b << 8;
92         res |= c.a;
93         break;
94 
95     case PIXEL_LAYOUT_XRGB_8888:
96         res |= c.a << 24;
97         res |= c.r << 16;
98         res |= c.g << 8;
99         res |= c.b;
100         break;
101 
102     default:
103         perror("nk_rawfb_color2int(): Unsupported pixel layout.\n");
104         break;
105     }
106     return (res);
107 }
108 
nk_wayland_ctx_setpixel(const struct nk_wayland * win,const short x0,const short y0,const struct nk_color col)109 static void nk_wayland_ctx_setpixel(const struct nk_wayland* win,
110     const short x0, const short y0, const struct nk_color col)
111 {
112     uint32_t c = nk_color_to_xrgb8888(col);
113     uint32_t *pixels = (uint32_t *)win->data;
114     unsigned int *ptr;
115 
116     pixels += (y0 * win->width);
117     ptr = (unsigned int *)pixels + x0;
118 
119     if (y0 < win->scissors.h && y0 >= win->scissors.y && x0 >= win->scissors.x && x0 < win->scissors.w){
120         *ptr = c;
121     }else {
122         printf("out of bound! \n");
123     }
124 }
125 
nk_wayland_fill_polygon(const struct nk_wayland * win,const struct nk_vec2i * pnts,int count,const struct nk_color col)126 static void nk_wayland_fill_polygon(const struct nk_wayland* win, const struct nk_vec2i *pnts, int count, const struct nk_color col)
127 {
128     int i = 0;
129     //#define MAX_POINTS 64
130     int left = 10000, top = 10000, bottom = 0, right = 0;
131     int nodes, nodeX[1024], pixelX, pixelY, j, swap ;
132 
133     if (count == 0) return;
134     if (count > 1024)
135         count = 1024;
136 
137     /* Get polygon dimensions */
138     for (i = 0; i < count; i++) {
139         if (left > pnts[i].x)
140             left = pnts[i].x;
141         if (right < pnts[i].x)
142             right = pnts[i].x;
143         if (top > pnts[i].y)
144             top = pnts[i].y;
145         if (bottom < pnts[i].y)
146             bottom = pnts[i].y;
147     } bottom++; right++;
148 
149     /* Polygon scanline algorithm released under public-domain by Darel Rex Finley, 2007 */
150     /*  Loop through the rows of the image. */
151     for (pixelY = top; pixelY < bottom; pixelY ++) {
152         nodes = 0; /*  Build a list of nodes. */
153         j = count - 1;
154         for (i = 0; i < count; i++) {
155             if (((pnts[i].y < pixelY) && (pnts[j].y >= pixelY)) ||
156                 ((pnts[j].y < pixelY) && (pnts[i].y >= pixelY))) {
157                 nodeX[nodes++]= (int)((float)pnts[i].x
158                      + ((float)pixelY - (float)pnts[i].y) / ((float)pnts[j].y - (float)pnts[i].y)
159                      * ((float)pnts[j].x - (float)pnts[i].x));
160             } j = i;
161         }
162 
163         /*  Sort the nodes, via a simple “Bubble” sort. */
164         i = 0;
165         while (i < nodes - 1) {
166             if (nodeX[i] > nodeX[i+1]) {
167                 swap = nodeX[i];
168                 nodeX[i] = nodeX[i+1];
169                 nodeX[i+1] = swap;
170                 if (i) i--;
171             } else i++;
172         }
173         /*  Fill the pixels between node pairs. */
174         for (i = 0; i < nodes; i += 2) {
175             if (nodeX[i+0] >= right) break;
176             if (nodeX[i+1] > left) {
177                 if (nodeX[i+0] < left) nodeX[i+0] = left ;
178                 if (nodeX[i+1] > right) nodeX[i+1] = right;
179                 for (pixelX = nodeX[i]; pixelX < nodeX[i + 1]; pixelX++)
180                     nk_wayland_ctx_setpixel(win, pixelX, pixelY, col);
181             }
182         }
183     }
184 }
185 
nk_wayland_fill_arc(const struct nk_wayland * win,short x0,short y0,short w,short h,const short s,const struct nk_color col)186 static void nk_wayland_fill_arc(const struct nk_wayland* win, short x0, short y0, short w, short h, const short s, const struct nk_color col)
187 {
188     /* Bresenham's ellipses - modified to fill one quarter */
189     const int a2 = (w * w) / 4;
190     const int b2 = (h * h) / 4;
191     const int fa2 = 4 * a2, fb2 = 4 * b2;
192     int x, y, sigma;
193     struct nk_vec2i pnts[3];
194     if (w < 1 || h < 1) return;
195     if (s != 0 && s != 90 && s != 180 && s != 270)
196         return;
197 
198     /* Convert upper left to center */
199     h = (h + 1) / 2;
200     w = (w + 1) / 2;
201     x0 += w;
202     y0 += h;
203 
204     pnts[0].x = x0;
205     pnts[0].y = y0;
206     pnts[2].x = x0;
207     pnts[2].y = y0;
208 
209     /* First half */
210     for (x = 0, y = h, sigma = 2*b2+a2*(1-2*h); b2*x <= a2*y; x++) {
211         if (s == 180) {
212             pnts[1].x = x0 + x; pnts[1].y = y0 + y;
213         } else if (s == 270) {
214             pnts[1].x = x0 - x; pnts[1].y = y0 + y;
215         } else if (s == 0) {
216             pnts[1].x = x0 + x; pnts[1].y = y0 - y;
217         } else if (s == 90) {
218             pnts[1].x = x0 - x; pnts[1].y = y0 - y;
219         }
220         nk_wayland_fill_polygon(win, pnts, 3, col);
221         pnts[2] = pnts[1];
222         if (sigma >= 0) {
223             sigma += fa2 * (1 - y);
224             y--;
225         } sigma += b2 * ((4 * x) + 6);
226     }
227 
228     /* Second half */
229     for (x = w, y = 0, sigma = 2*a2+b2*(1-2*w); a2*y <= b2*x; y++) {
230         if (s == 180) {
231             pnts[1].x = x0 + x; pnts[1].y = y0 + y;
232         } else if (s == 270) {
233             pnts[1].x = x0 - x; pnts[1].y = y0 + y;
234         } else if (s == 0) {
235             pnts[1].x = x0 + x; pnts[1].y = y0 - y;
236         } else if (s == 90) {
237             pnts[1].x = x0 - x; pnts[1].y = y0 - y;
238         }
239         nk_wayland_fill_polygon(win, pnts, 3, col);
240         pnts[2] = pnts[1];
241         if (sigma >= 0) {
242             sigma += fb2 * (1 - x);
243             x--;
244         } sigma += a2 * ((4 * y) + 6);
245     }
246 }
247 
nk_wayland_img_setpixel(const struct wayland_img * img,const int x0,const int y0,const struct nk_color col)248 static void nk_wayland_img_setpixel(const struct wayland_img *img, const int x0, const int y0, const struct nk_color col)
249 {
250     unsigned int c = nk_wayland_color2int(col, img->pl);
251     unsigned char *ptr;
252     unsigned int *pixel;
253     NK_ASSERT(img);
254     if (y0 < img->h && y0 >= 0 && x0 >= 0 && x0 < img->w) {
255         ptr = (unsigned char *)img->pixels + (img->pitch * y0);
256 	pixel = (unsigned int *)ptr;
257 
258         if (img->format == NK_FONT_ATLAS_ALPHA8) {
259             ptr[x0] = col.a;
260         } else {
261 	    pixel[x0] = c;
262         }
263     }
264 }
265 
nk_wayland_getpixel(const struct nk_wayland * win,const int x0,const int y0)266 static struct nk_color nk_wayland_getpixel(const struct nk_wayland* win, const int x0, const int y0)
267 {
268     struct nk_color col = {0, 0, 0, 0};
269     uint32_t *ptr;
270 
271     if (y0 < win->height && y0 >= 0 && x0 >= 0 && x0 < win->width) {
272         ptr = (uint32_t *)win->data + (y0 * win->width);
273 
274         col = nk_wayland_int2color(*ptr, PIXEL_LAYOUT_XRGB_8888);
275     }
276 
277     return col;
278 }
279 
nk_wayland_img_getpixel(const struct wayland_img * img,const int x0,const int y0)280 static struct nk_color nk_wayland_img_getpixel(const struct wayland_img *img, const int x0, const int y0)
281 {
282     struct nk_color col = {0, 0, 0, 0};
283     unsigned char *ptr;
284     unsigned int pixel;
285     NK_ASSERT(img);
286     if (y0 < img->h && y0 >= 0 && x0 >= 0 && x0 < img->w) {
287         ptr = (unsigned char *)img->pixels + (img->pitch * y0);
288 
289         if (img->format == NK_FONT_ATLAS_ALPHA8) {
290             col.a = ptr[x0];
291             col.b = col.g = col.r = 0xff;
292         } else {
293             pixel = ((unsigned int *)ptr)[x0];
294             col = nk_wayland_int2color(pixel, img->pl);
295         }
296     } return col;
297 }
298 
nk_wayland_blendpixel(const struct nk_wayland * win,const int x0,const int y0,struct nk_color col)299 static void nk_wayland_blendpixel(const struct nk_wayland* win, const int x0, const int y0, struct nk_color col)
300 {
301     struct nk_color col2;
302     unsigned char inv_a;
303     if (col.a == 0)
304         return;
305 
306     inv_a = 0xff - col.a;
307     col2 = nk_wayland_getpixel(win, x0, y0);
308     col.r = (col.r * col.a + col2.r * inv_a) >> 8;
309     col.g = (col.g * col.a + col2.g * inv_a) >> 8;
310     col.b = (col.b * col.a + col2.b * inv_a) >> 8;
311     nk_wayland_ctx_setpixel(win, x0, y0, col);
312 }
313 
nk_wayland_img_blendpixel(const struct wayland_img * img,const int x0,const int y0,struct nk_color col)314 static void nk_wayland_img_blendpixel(const struct wayland_img *img, const int x0, const int y0, struct nk_color col)
315 {
316     struct nk_color col2;
317     unsigned char inv_a;
318     if (col.a == 0)
319         return;
320 
321     inv_a = 0xff - col.a;
322     col2 = nk_wayland_img_getpixel(img, x0, y0);
323     col.r = (col.r * col.a + col2.r * inv_a) >> 8;
324     col.g = (col.g * col.a + col2.g * inv_a) >> 8;
325     col.b = (col.b * col.a + col2.b * inv_a) >> 8;
326     nk_wayland_img_setpixel(img, x0, y0, col);
327 }
328 
nk_wayland_line_horizontal(const struct nk_wayland * win,const short x0,const short y,const short x1,const struct nk_color col)329 static void nk_wayland_line_horizontal(const struct nk_wayland* win, const short x0, const short y, const short x1, const struct nk_color col)
330 {
331     /* This function is called the most. Try to optimize it a bit...
332      * It does not check for scissors or image borders.
333      * The caller has to make sure it does no exceed bounds. */
334     unsigned int i, n;
335     unsigned int c[16];
336     unsigned char *pixels = (uint8_t*)win->data;
337     unsigned int *ptr;
338 
339     pixels += (y * (win->width * 4));
340     ptr = (unsigned int *)pixels + x0;
341 
342     n = x1 - x0;
343     for (i = 0; i < sizeof(c) / sizeof(c[0]); i++)
344         c[i] = nk_color_to_xrgb8888(col);
345 
346     while (n > 16) {
347         memcpy((void *)ptr, c, sizeof(c));
348         n -= 16; ptr += 16;
349     } for (i = 0; i < n; i++)
350         ptr[i] = c[i];
351 }
352 
353 
nk_wayland_scissor(struct nk_wayland * win,const float x,const float y,const float w,const float h)354 static void nk_wayland_scissor(struct nk_wayland* win, const float x, const float y, const float w, const float h)
355 {
356     win->scissors.x = MIN(MAX(x, 0), WIDTH);
357     win->scissors.y = MIN(MAX(y, 0), HEIGHT);
358     win->scissors.w = MIN(MAX(w + x, 0), WIDTH);
359     win->scissors.h = MIN(MAX(h + y, 0), HEIGHT);
360 }
361 
nk_wayland_stroke_line(const struct nk_wayland * win,short x0,short y0,short x1,short y1,const unsigned int line_thickness,const struct nk_color col)362 static void nk_wayland_stroke_line(const struct nk_wayland* win, short x0, short y0, short x1, short y1, const unsigned int line_thickness, const struct nk_color col)
363 {
364     short tmp;
365     int dy, dx, stepx, stepy;
366 
367     NK_UNUSED(line_thickness);
368 
369     dy = y1 - y0;
370     dx = x1 - x0;
371 
372     //printf("\n\n\n\n");
373     // fast path
374     if (dy == 0) {
375         if (dx == 0 || y0 >= win->scissors.h || y0 < win->scissors.y){
376             return;
377         }
378 
379         if (dx < 0) {
380             // swap x0 and x1
381             tmp = x1;
382             x1 = x0;
383             x0 = tmp;
384         }
385         x1 = MIN(win->scissors.w, x1);
386         x0 = MIN(win->scissors.w, x0);
387         x1 = MAX(win->scissors.x, x1);
388         x0 = MAX(win->scissors.x, x0);
389         nk_wayland_line_horizontal(win, x0, y0, x1, col);
390         return;
391     }
392     if (dy < 0) {
393         dy = -dy;
394         stepy = -1;
395     } else stepy = 1;
396 
397     if (dx < 0) {
398         dx = -dx;
399         stepx = -1;
400     } else stepx = 1;
401 
402     dy <<= 1;
403     dx <<= 1;
404 
405     nk_wayland_ctx_setpixel(win, x0, y0, col);
406     if (dx > dy) {
407         int fraction = dy - (dx >> 1);
408         while (x0 != x1) {
409             if (fraction >= 0) {
410                 y0 += stepy;
411                 fraction -= dx;
412             }
413             x0 += stepx;
414             fraction += dy;
415             nk_wayland_ctx_setpixel(win, x0, y0, col);
416         }
417     } else {
418         int fraction = dx - (dy >> 1);
419         while (y0 != y1) {
420             if (fraction >= 0) {
421                 x0 += stepx;
422                 fraction -= dy;
423             }
424             y0 += stepy;
425             fraction += dx;
426             nk_wayland_ctx_setpixel(win, x0, y0, col);
427         }
428     }
429 }
430 
431 static void
nk_wayland_fill_rect(const struct nk_wayland * win,const short x,const short y,const short w,const short h,const short r,const struct nk_color col)432 nk_wayland_fill_rect(const struct nk_wayland* win,
433     const short x, const short y, const short w, const short h,
434     const short r, const struct nk_color col)
435 {
436     int i;
437     if (r == 0) {
438         for (i = 0; i < h; i++)
439             nk_wayland_stroke_line(win, x, y + i, x + w, y + i, 1, col);
440     } else {
441         const short xc = x + r;
442         const short yc = y + r;
443         const short wc = (short)(w - 2 * r);
444         const short hc = (short)(h - 2 * r);
445 
446         struct nk_vec2i pnts[12];
447         pnts[0].x = x;
448         pnts[0].y = yc;
449         pnts[1].x = xc;
450         pnts[1].y = yc;
451         pnts[2].x = xc;
452         pnts[2].y = y;
453 
454         pnts[3].x = xc + wc;
455         pnts[3].y = y;
456         pnts[4].x = xc + wc;
457         pnts[4].y = yc;
458         pnts[5].x = x + w;
459         pnts[5].y = yc;
460 
461         pnts[6].x = x + w;
462         pnts[6].y = yc + hc;
463         pnts[7].x = xc + wc;
464         pnts[7].y = yc + hc;
465         pnts[8].x = xc + wc;
466         pnts[8].y = y + h;
467 
468         pnts[9].x = xc;
469         pnts[9].y = y + h;
470         pnts[10].x = xc;
471         pnts[10].y = yc + hc;
472         pnts[11].x = x;
473         pnts[11].y = yc + hc;
474 
475         nk_wayland_fill_polygon(win, pnts, 12, col);
476 
477         nk_wayland_fill_arc(win, xc + wc - r, y,
478                 (unsigned)r*2, (unsigned)r*2, 0 , col);
479         nk_wayland_fill_arc(win, x, y,
480                 (unsigned)r*2, (unsigned)r*2, 90 , col);
481         nk_wayland_fill_arc(win, x, yc + hc - r,
482                 (unsigned)r*2, (unsigned)r*2, 270 , col);
483         nk_wayland_fill_arc(win, xc + wc - r, yc + hc - r,
484                 (unsigned)r*2, (unsigned)r*2, 180 , col);
485     }
486 }
487 
nk_wayland_stroke_arc(const struct nk_wayland * win,short x0,short y0,short w,short h,const short s,const short line_thickness,const struct nk_color col)488 static void nk_wayland_stroke_arc(const struct nk_wayland* win,
489     short x0, short y0, short w, short h, const short s,
490     const short line_thickness, const struct nk_color col)
491 {
492     /* Bresenham's ellipses - modified to draw one quarter */
493     const int a2 = (w * w) / 4;
494     const int b2 = (h * h) / 4;
495     const int fa2 = 4 * a2, fb2 = 4 * b2;
496     int x, y, sigma;
497 
498     NK_UNUSED(line_thickness);
499 
500     if (s != 0 && s != 90 && s != 180 && s != 270) return;
501     if (w < 1 || h < 1) return;
502 
503     /* Convert upper left to center */
504     h = (h + 1) / 2;
505     w = (w + 1) / 2;
506     x0 += w; y0 += h;
507 
508     /* First half */
509     for (x = 0, y = h, sigma = 2*b2+a2*(1-2*h); b2*x <= a2*y; x++) {
510         if (s == 180)
511             nk_wayland_ctx_setpixel(win, x0 + x, y0 + y, col);
512         else if (s == 270)
513             nk_wayland_ctx_setpixel(win, x0 - x, y0 + y, col);
514         else if (s == 0)
515             nk_wayland_ctx_setpixel(win, x0 + x, y0 - y, col);
516         else if (s == 90)
517             nk_wayland_ctx_setpixel(win, x0 - x, y0 - y, col);
518         if (sigma >= 0) {
519             sigma += fa2 * (1 - y);
520             y--;
521         } sigma += b2 * ((4 * x) + 6);
522     }
523 
524     /* Second half */
525     for (x = w, y = 0, sigma = 2*a2+b2*(1-2*w); a2*y <= b2*x; y++) {
526         if (s == 180)
527             nk_wayland_ctx_setpixel(win, x0 + x, y0 + y, col);
528         else if (s == 270)
529             nk_wayland_ctx_setpixel(win, x0 - x, y0 + y, col);
530         else if (s == 0)
531             nk_wayland_ctx_setpixel(win, x0 + x, y0 - y, col);
532         else if (s == 90)
533             nk_wayland_ctx_setpixel(win, x0 - x, y0 - y, col);
534         if (sigma >= 0) {
535             sigma += fb2 * (1 - x);
536             x--;
537         } sigma += a2 * ((4 * y) + 6);
538     }
539 }
540 
541 
542 
543 
nk_wayland_stroke_rect(const struct nk_wayland * win,const short x,const short y,const short w,const short h,const short r,const short line_thickness,const struct nk_color col)544 static void nk_wayland_stroke_rect(const struct nk_wayland* win,
545     const short x, const short y, const short w, const short h,
546     const short r, const short line_thickness, const struct nk_color col)
547 {
548     if (r == 0) {
549         nk_wayland_stroke_line(win, x, y, x + w, y, line_thickness, col);
550         nk_wayland_stroke_line(win, x, y + h, x + w, y + h, line_thickness, col);
551         nk_wayland_stroke_line(win, x, y, x, y + h, line_thickness, col);
552         nk_wayland_stroke_line(win, x + w, y, x + w, y + h, line_thickness, col);
553     } else {
554         const short xc = x + r;
555         const short yc = y + r;
556         const short wc = (short)(w - 2 * r);
557         const short hc = (short)(h - 2 * r);
558 
559         nk_wayland_stroke_line(win, xc, y, xc + wc, y, line_thickness, col);
560         nk_wayland_stroke_line(win, x + w, yc, x + w, yc + hc, line_thickness, col);
561         nk_wayland_stroke_line(win, xc, y + h, xc + wc, y + h, line_thickness, col);
562         nk_wayland_stroke_line(win, x, yc, x, yc + hc, line_thickness, col);
563 
564         nk_wayland_stroke_arc(win, xc + wc - r, y,
565                 (unsigned)r*2, (unsigned)r*2, 0 , line_thickness, col);
566         nk_wayland_stroke_arc(win, x, y,
567                 (unsigned)r*2, (unsigned)r*2, 90 , line_thickness, col);
568         nk_wayland_stroke_arc(win, x, yc + hc - r,
569                 (unsigned)r*2, (unsigned)r*2, 270 , line_thickness, col);
570         nk_wayland_stroke_arc(win, xc + wc - r, yc + hc - r,
571                 (unsigned)r*2, (unsigned)r*2, 180 , line_thickness, col);
572     }
573 }
574 
nk_wayland_fill_triangle(const struct nk_wayland * win,const short x0,const short y0,const short x1,const short y1,const short x2,const short y2,const struct nk_color col)575 static void nk_wayland_fill_triangle(const struct nk_wayland *win,
576     const short x0, const short y0, const short x1, const short y1,
577     const short x2, const short y2, const struct nk_color col)
578 {
579     struct nk_vec2i pnts[3];
580     pnts[0].x = x0;
581     pnts[0].y = y0;
582     pnts[1].x = x1;
583     pnts[1].y = y1;
584     pnts[2].x = x2;
585     pnts[2].y = y2;
586     nk_wayland_fill_polygon(win, pnts, 3, col);
587 }
588 
nk_wayland_clear(const struct nk_wayland * win,const struct nk_color col)589 static void nk_wayland_clear(const struct nk_wayland *win, const struct nk_color col)
590 {
591     nk_wayland_fill_rect(win, 0, 0, win->width, win->height, 0, col);
592 }
593 
nk_wayland_fill_circle(struct nk_wayland * win,short x0,short y0,short w,short h,const struct nk_color col)594 static void nk_wayland_fill_circle(struct nk_wayland* win, short x0, short y0, short w, short h, const struct nk_color col)
595 {
596     /* Bresenham's ellipses */
597     const int a2 = (w * w) / 4;
598     const int b2 = (h * h) / 4;
599     const int fa2 = 4 * a2, fb2 = 4 * b2;
600     int x, y, sigma;
601 
602     /* Convert upper left to center */
603     h = (h + 1) / 2;
604     w = (w + 1) / 2;
605     x0 += w;
606     y0 += h;
607 
608     /* First half */
609     for (x = 0, y = h, sigma = 2*b2+a2*(1-2*h); b2*x <= a2*y; x++) {
610         nk_wayland_stroke_line(win, x0 - x, y0 + y, x0 + x, y0 + y, 1, col);
611         nk_wayland_stroke_line(win, x0 - x, y0 - y, x0 + x, y0 - y, 1, col);
612         if (sigma >= 0) {
613             sigma += fa2 * (1 - y);
614             y--;
615         } sigma += b2 * ((4 * x) + 6);
616     }
617     /* Second half */
618     for (x = w, y = 0, sigma = 2*a2+b2*(1-2*w); a2*y <= b2*x; y++) {
619         nk_wayland_stroke_line(win, x0 - x, y0 + y, x0 + x, y0 + y, 1, col);
620         nk_wayland_stroke_line(win, x0 - x, y0 - y, x0 + x, y0 - y, 1, col);
621         if (sigma >= 0) {
622             sigma += fb2 * (1 - x);
623             x--;
624         } sigma += a2 * ((4 * y) + 6);
625     }
626 }
627 /**
628  * Copy wayland_img into nk_wayland with scissor & stretch
629  */
nk_wayland_copy_image(const struct nk_wayland * win,const struct wayland_img * src,const struct nk_rect * dst_rect,const struct nk_rect * src_rect,const struct nk_rect * dst_scissors,const struct nk_color * fg)630 static void nk_wayland_copy_image(const struct nk_wayland *win, const struct wayland_img *src,
631     const struct nk_rect *dst_rect,
632     const struct nk_rect *src_rect,
633     const struct nk_rect *dst_scissors,
634     const struct nk_color *fg)
635 {
636     short i, j;
637     struct nk_color col;
638     float xinc = src_rect->w / dst_rect->w;
639     float yinc = src_rect->h / dst_rect->h;
640     float xoff = src_rect->x, yoff = src_rect->y;
641 
642     // Simple nearest filtering rescaling
643     // TODO: use bilinear filter
644     for (j = 0; j < (short)dst_rect->h; j++) {
645         for (i = 0; i < (short)dst_rect->w; i++) {
646             if (dst_scissors) {
647                 if (i + (int)(dst_rect->x + 0.5f) < dst_scissors->x || i + (int)(dst_rect->x + 0.5f) >= dst_scissors->w)
648                     continue;
649                 if (j + (int)(dst_rect->y + 0.5f) < dst_scissors->y || j + (int)(dst_rect->y + 0.5f) >= dst_scissors->h)
650                     continue;
651             }
652             col = nk_wayland_img_getpixel(src, (int)xoff, (int) yoff);
653 	    if (col.r || col.g || col.b)
654 	    {
655 		col.r = fg->r;
656 		col.g = fg->g;
657 		col.b = fg->b;
658 	    }
659             nk_wayland_blendpixel(win, i + (int)(dst_rect->x + 0.5f), j + (int)(dst_rect->y + 0.5f), col);
660             xoff += xinc;
661         }
662         xoff = src_rect->x;
663         yoff += yinc;
664     }
665 }
666 
nk_wayland_font_query_font_glyph(nk_handle handle,const float height,struct nk_user_font_glyph * glyph,const nk_rune codepoint,const nk_rune next_codepoint)667 static void nk_wayland_font_query_font_glyph(nk_handle handle, const float height, struct nk_user_font_glyph *glyph, const nk_rune codepoint, const nk_rune next_codepoint)
668 {
669     float scale;
670     const struct nk_font_glyph *g;
671     struct nk_font *font;
672     NK_ASSERT(glyph);
673     NK_UNUSED(next_codepoint);
674 
675     font = (struct nk_font*)handle.ptr;
676     NK_ASSERT(font);
677     NK_ASSERT(font->glyphs);
678     if (!font || !glyph)
679         return;
680 
681     scale = height/font->info.height;
682     g = nk_font_find_glyph(font, codepoint);
683     glyph->width = (g->x1 - g->x0) * scale;
684     glyph->height = (g->y1 - g->y0) * scale;
685     glyph->offset = nk_vec2(g->x0 * scale, g->y0 * scale);
686     glyph->xadvance = (g->xadvance * scale);
687     glyph->uv[0] = nk_vec2(g->u0, g->v0);
688     glyph->uv[1] = nk_vec2(g->u1, g->v1);
689 }
690 
nk_wayland_draw_text(const struct nk_wayland * win,const struct nk_user_font * font,const struct nk_rect rect,const char * text,const int len,const float font_height,const struct nk_color fg)691 void nk_wayland_draw_text(const struct nk_wayland *win, const struct nk_user_font *font, const struct nk_rect rect, const char *text, const int len, const float font_height, const struct nk_color fg)
692 {
693     float x = 0;
694     int text_len = 0;
695     nk_rune unicode = 0;
696     nk_rune next = 0;
697     int glyph_len = 0;
698     int next_glyph_len = 0;
699     struct nk_user_font_glyph g;
700     if (!len || !text) return;
701 
702     x = 0;
703     glyph_len = nk_utf_decode(text, &unicode, len);
704     if (!glyph_len) return;
705 
706     // draw every glyph image
707     while (text_len < len && glyph_len) {
708         struct nk_rect src_rect;
709         struct nk_rect dst_rect;
710         float char_width = 0;
711         if (unicode == NK_UTF_INVALID) break;
712 
713         // query currently drawn glyph information
714         next_glyph_len = nk_utf_decode(text + text_len + glyph_len, &next, (int)len - text_len);
715         nk_wayland_font_query_font_glyph(font->userdata, font_height, &g, unicode,
716                     (next == NK_UTF_INVALID) ? '\0' : next);
717 
718         //calculate and draw glyph drawing rectangle and image
719         char_width = g.xadvance;
720         src_rect.x = g.uv[0].x * win->font_tex.w;
721         src_rect.y = g.uv[0].y * win->font_tex.h;
722         src_rect.w = g.uv[1].x * win->font_tex.w - g.uv[0].x * win->font_tex.w;
723         src_rect.h = g.uv[1].y * win->font_tex.h - g.uv[0].y * win->font_tex.h;
724 
725         dst_rect.x = x + g.offset.x + rect.x;
726         dst_rect.y = g.offset.y + rect.y;
727         dst_rect.w = ceilf(g.width);
728         dst_rect.h = ceilf(g.height);
729 
730         // Use software rescaling to blit glyph from font_text to framebuffer
731         nk_wayland_copy_image(win, &(win->font_tex), &dst_rect, &src_rect, &(win->scissors), &fg);
732 
733         // offset next glyph
734         text_len += glyph_len;
735         x += char_width;
736         glyph_len = next_glyph_len;
737         unicode = next;
738     }
739 }
740 
nk_wayland_render(struct nk_wayland * win,const struct nk_color clear,const unsigned char enable_clear)741 static void nk_wayland_render(struct nk_wayland *win, const struct nk_color clear, const unsigned char enable_clear)
742 {
743     const struct nk_command *cmd;
744     const struct nk_command_text *tx;
745     const struct nk_command_scissor *s;
746     const struct nk_command_rect_filled *rf;
747     const struct nk_command_rect *r;
748     const struct nk_command_circle_filled *c;
749     const struct nk_command_triangle_filled *t;
750     const struct nk_command_line *l;
751     const struct nk_command_polygon_filled *p;
752 
753     if (enable_clear)
754         nk_wayland_clear(win, clear);
755 
756     nk_foreach(cmd, (struct nk_context*)&(win->ctx)) {
757         switch (cmd->type) {
758         case NK_COMMAND_NOP:
759             //printf("NK_COMMAND_NOP \n");
760             break;
761 
762         case NK_COMMAND_SCISSOR:
763             s = (const struct nk_command_scissor*)cmd;
764             nk_wayland_scissor(win, s->x, s->y, s->w, s->h);
765             break;
766 
767         case NK_COMMAND_LINE:
768             l = (const struct nk_command_line *)cmd;
769             nk_wayland_stroke_line(win, l->begin.x, l->begin.y, l->end.x, l->end.y, l->line_thickness, l->color);
770             break;
771 
772         case NK_COMMAND_RECT:
773             r = (const struct nk_command_rect *)cmd;
774             nk_wayland_stroke_rect(win, r->x, r->y, r->w, r->h, (unsigned short)r->rounding, r->line_thickness, r->color);
775             break;
776 
777         case NK_COMMAND_RECT_FILLED:
778             rf = (const struct nk_command_rect_filled *)cmd;
779             nk_wayland_fill_rect(win, rf->x, rf->y, rf->w, rf->h, (unsigned short)rf->rounding, rf->color);
780             break;
781 
782         case NK_COMMAND_CIRCLE:
783           //  printf("NK_COMMAND_CIRCLE \n");
784             //const struct nk_command_circle *c = (const struct nk_command_circle *)cmd;
785             //nk_rawfb_stroke_circle(rawfb, c->x, c->y, c->w, c->h, c->line_thickness, c->color);
786             break;
787 
788         case NK_COMMAND_CIRCLE_FILLED:
789             c = (const struct nk_command_circle_filled *)cmd;
790             nk_wayland_fill_circle(win, c->x, c->y, c->w, c->h, c->color);
791 
792             //const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
793             //nk_rawfb_fill_circle(rawfb, c->x, c->y, c->w, c->h, c->color);
794             break;
795 
796         case NK_COMMAND_TRIANGLE:
797             //printf("NK_COMMAND_TRIANGLE \n");
798             //const struct nk_command_triangle*t = (const struct nk_command_triangle*)cmd;
799             //nk_rawfb_stroke_triangle(rawfb, t->a.x, t->a.y, t->b.x, t->b.y, t->c.x, t->c.y, t->line_thickness, t->color);
800             break;
801 
802         case NK_COMMAND_TRIANGLE_FILLED:
803             t = (const struct nk_command_triangle_filled *)cmd;
804             nk_wayland_fill_triangle(win, t->a.x, t->a.y, t->b.x, t->b.y, t->c.x, t->c.y, t->color);
805             break;
806 
807         case NK_COMMAND_POLYGON:
808           //  printf("NK_COMMAND_POLYGON \n");
809             //const struct nk_command_polygon *p =(const struct nk_command_polygon*)cmd;
810             //nk_rawfb_stroke_polygon(rawfb, p->points, p->point_count, p->line_thickness,p->color);
811             break;
812 
813         case NK_COMMAND_POLYGON_FILLED:
814            // printf("NK_COMMAND_POLYGON_FILLED \n");
815             p = (const struct nk_command_polygon_filled *)cmd;
816             nk_wayland_fill_polygon(win, p->points, p->point_count, p->color);
817             break;
818 
819         case NK_COMMAND_POLYLINE:
820            // printf("NK_COMMAND_POLYLINE \n");
821             //const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd;
822             //nk_rawfb_stroke_polyline(rawfb, p->points, p->point_count, p->line_thickness, p->color);
823             break;
824 
825         case NK_COMMAND_TEXT:
826             tx = (const struct nk_command_text*)cmd;
827             nk_wayland_draw_text(win, tx->font, nk_rect(tx->x, tx->y, tx->w, tx->h), tx->string, tx->length, tx->height, tx->foreground);
828             break;
829 
830         case NK_COMMAND_CURVE:
831          //    printf("NK_COMMAND_CURVE \n");
832             //const struct nk_command_curve *q = (const struct nk_command_curve *)cmd;
833             //nk_rawfb_stroke_curve(rawfb, q->begin, q->ctrl[0], q->ctrl[1], q->end, 22, q->line_thickness, q->color);
834             break;
835 
836         case NK_COMMAND_RECT_MULTI_COLOR:
837           //  printf("NK_COMMAND_RECT_MULTI_COLOR \n");
838             //const struct nk_command_rect_multi_color *q = (const struct nk_command_rect_multi_color *)cmd;
839             //nk_rawfb_draw_rect_multi_color(rawfb, q->x, q->y, q->w, q->h, q->left, q->top, q->right, q->bottom);
840             break;
841 
842         case NK_COMMAND_IMAGE:
843             //printf("NK_COMMAND_IMAGE \n");
844            // const struct nk_command_image *q = (const struct nk_command_image *)cmd;
845            // nk_rawfb_drawimage(rawfb, q->x, q->y, q->w, q->h, &q->img, &q->col);
846             break;
847 
848         case NK_COMMAND_ARC:
849             printf("NK_COMMAND_ARC \n");
850             assert(0 && "NK_COMMAND_ARC not implemented\n");
851             break;
852 
853         case NK_COMMAND_ARC_FILLED:
854             printf("NK_COMMAND_ARC \n");
855             assert(0 && "NK_COMMAND_ARC_FILLED not implemented\n");
856             break;
857 
858         default:
859             printf("unhandled OP: %d \n", cmd->type);
860             break;
861         }
862     } nk_clear(&(win->ctx));
863 }
864 
865 #endif
866