1 /*
2 * MIT License
3 *
4 * Copyright (c) 2016-2017 Patrick Rudolph <siro@das-labor.org>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24 /*
25 * ==============================================================
26 *
27 * API
28 *
29 * ===============================================================
30 */
31
32 /* Adapted from nulear_rawfb.h for use with SDL_Surface by Martijn Versteegh*/
33 #ifndef NK_SDLSURFACE_H_
34 #define NK_SDLSURFACE_H_
35
36 #include <SDL.h>
37 #include <SDL_surface.h>
38
39 struct sdlsurface_context *nk_sdlsurface_init(SDL_Surface *fb, float fontSize);
40 void nk_sdlsurface_render(const struct sdlsurface_context *sdlsurface, const struct nk_color clear, const unsigned char enable_clear);
41 void nk_sdlsurface_shutdown(struct sdlsurface_context *sdlsurface);
42
43 #endif
44 /*
45 * ==============================================================
46 *
47 * IMPLEMENTATION
48 *
49 * ===============================================================
50 */
51 #ifdef NK_SDLSURFACE_IMPLEMENTATION
52 struct sdlsurface_context {
53 struct nk_context ctx;
54 struct nk_rect scissors;
55 struct SDL_Surface *fb;
56 struct SDL_Surface *font_tex;
57 struct nk_font_atlas atlas;
58 };
59
60 #ifndef MIN
61 #define MIN(a,b) ((a) < (b) ? (a) : (b))
62 #endif
63 #ifndef MAX
64 #define MAX(a,b) ((a) < (b) ? (b) : (a))
65 #endif
66
67 static unsigned int
nk_sdlsurface_color2int(const struct nk_color c,SDL_PixelFormatEnum pl)68 nk_sdlsurface_color2int(const struct nk_color c, SDL_PixelFormatEnum pl)
69 {
70 unsigned int res = 0;
71
72 switch (pl) {
73 case SDL_PIXELFORMAT_RGBA8888:
74 res |= c.r << 24;
75 res |= c.g << 16;
76 res |= c.b << 8;
77 res |= c.a;
78 break;
79 case SDL_PIXELFORMAT_ARGB8888:
80 res |= c.a << 24;
81 res |= c.r << 16;
82 res |= c.g << 8;
83 res |= c.b;
84 break;
85
86 default:
87 perror("nk_sdlsurface_color2int(): Unsupported pixel layout.\n");
88 break;
89 }
90 return (res);
91 }
92
93 static struct nk_color
nk_sdlsurface_int2color(const unsigned int i,SDL_PixelFormatEnum pl)94 nk_sdlsurface_int2color(const unsigned int i, SDL_PixelFormatEnum pl)
95 {
96 struct nk_color col = {0,0,0,0};
97
98 switch (pl) {
99 case SDL_PIXELFORMAT_RGBA8888:
100 col.r = (i >> 24) & 0xff;
101 col.g = (i >> 16) & 0xff;
102 col.b = (i >> 8) & 0xff;
103 col.a = i & 0xff;
104 break;
105 case SDL_PIXELFORMAT_ARGB8888:
106 col.a = (i >> 24) & 0xff;
107 col.r = (i >> 16) & 0xff;
108 col.g = (i >> 8) & 0xff;
109 col.b = i & 0xff;
110 break;
111
112 default:
113 perror("nk_sdlsurface_int2color(): Unsupported pixel layout.\n");
114 break;
115 }
116 return col;
117 }
118
119 static void
nk_sdlsurface_ctx_setpixel(const struct sdlsurface_context * sdlsurface,const short x0,const short y0,const struct nk_color col)120 nk_sdlsurface_ctx_setpixel(const struct sdlsurface_context *sdlsurface,
121 const short x0, const short y0, const struct nk_color col)
122 {
123 unsigned int c = nk_sdlsurface_color2int(col, sdlsurface->fb->format->format);
124 unsigned char *pixels = sdlsurface->fb->pixels;
125 unsigned int *ptr;
126
127 pixels += y0 * sdlsurface->fb->pitch;
128 ptr = (unsigned int *)pixels + x0;
129
130 if (y0 < sdlsurface->scissors.h && y0 >= sdlsurface->scissors.y &&
131 x0 >= sdlsurface->scissors.x && x0 < sdlsurface->scissors.w)
132 *ptr = c;
133 }
134
135 static void
nk_sdlsurface_line_horizontal(const struct sdlsurface_context * sdlsurface,const short x0,const short y,const short x1,const struct nk_color col)136 nk_sdlsurface_line_horizontal(const struct sdlsurface_context *sdlsurface,
137 const short x0, const short y, const short x1, const struct nk_color col)
138 {
139 /* This function is called the most. Try to optimize it a bit...
140 * It does not check for scissors or image borders.
141 * The caller has to make sure it does no exceed bounds. */
142 unsigned int i, n;
143 unsigned int c[16];
144 unsigned char *pixels = sdlsurface->fb->pixels;
145 unsigned int *ptr;
146
147 pixels += y * sdlsurface->fb->pitch;
148 ptr = (unsigned int *)pixels + x0;
149
150 n = x1 - x0;
151 for (i = 0; i < sizeof(c) / sizeof(c[0]); i++)
152 c[i] = nk_sdlsurface_color2int(col, sdlsurface->fb->format->format);
153
154 while (n > 16) {
155 memcpy((void *)ptr, c, sizeof(c));
156 n -= 16; ptr += 16;
157 } for (i = 0; i < n; i++)
158 ptr[i] = c[i];
159 }
160
161 static void
nk_sdlsurface_img_setpixel(const struct SDL_Surface * img,const int x0,const int y0,const struct nk_color col)162 nk_sdlsurface_img_setpixel(const struct SDL_Surface *img,
163 const int x0, const int y0, const struct nk_color col)
164 {
165 unsigned int c = nk_sdlsurface_color2int(col, img->format->format);
166 unsigned char *ptr;
167 unsigned int *pixel;
168 NK_ASSERT(img);
169 if (y0 < img->h && y0 >= 0 && x0 >= 0 && x0 < img->w) {
170 ptr = (unsigned char *)img->pixels + (img->pitch * y0);
171 pixel = (unsigned int *)ptr;
172
173 if (img->format == NK_FONT_ATLAS_ALPHA8) {
174 ptr[x0] = col.a;
175 } else {
176 pixel[x0] = c;
177 }
178 }
179 }
180
181 static struct nk_color
nk_sdlsurface_img_getpixel(const struct SDL_Surface * img,const int x0,const int y0)182 nk_sdlsurface_img_getpixel(const struct SDL_Surface *img, const int x0, const int y0)
183 {
184 struct nk_color col = {0, 0, 0, 0};
185 unsigned char *ptr;
186 unsigned int pixel;
187 NK_ASSERT(img);
188 if (y0 < img->h && y0 >= 0 && x0 >= 0 && x0 < img->w) {
189 ptr = (unsigned char *)img->pixels + (img->pitch * y0);
190
191 if (img->format == NK_FONT_ATLAS_ALPHA8) {
192 col.a = ptr[x0];
193 col.b = col.g = col.r = 0xff;
194 } else {
195 pixel = ((unsigned int *)ptr)[x0];
196 col = nk_sdlsurface_int2color(pixel, img->format->format);
197 }
198 } return col;
199 }
200 static void
nk_sdlsurface_img_blendpixel(const struct SDL_Surface * img,const int x0,const int y0,struct nk_color col)201 nk_sdlsurface_img_blendpixel(const struct SDL_Surface *img,
202 const int x0, const int y0, struct nk_color col)
203 {
204 struct nk_color col2;
205 unsigned char inv_a;
206 if (col.a == 0)
207 return;
208
209 inv_a = 0xff - col.a;
210 col2 = nk_sdlsurface_img_getpixel(img, x0, y0);
211 col.r = (col.r * col.a + col2.r * inv_a) >> 8;
212 col.g = (col.g * col.a + col2.g * inv_a) >> 8;
213 col.b = (col.b * col.a + col2.b * inv_a) >> 8;
214 nk_sdlsurface_img_setpixel(img, x0, y0, col);
215 }
216
217 static void
nk_sdlsurface_scissor(struct sdlsurface_context * sdlsurface,const float x,const float y,const float w,const float h)218 nk_sdlsurface_scissor(struct sdlsurface_context *sdlsurface,
219 const float x,
220 const float y,
221 const float w,
222 const float h)
223 {
224 sdlsurface->scissors.x = MIN(MAX(x, 0), sdlsurface->fb->w);
225 sdlsurface->scissors.y = MIN(MAX(y, 0), sdlsurface->fb->h);
226 sdlsurface->scissors.w = MIN(MAX(w + x, 0), sdlsurface->fb->w);
227 sdlsurface->scissors.h = MIN(MAX(h + y, 0), sdlsurface->fb->h);
228 }
229
230 static void
nk_sdlsurface_stroke_line(const struct sdlsurface_context * sdlsurface,short x0,short y0,short x1,short y1,const unsigned int line_thickness,const struct nk_color col)231 nk_sdlsurface_stroke_line(const struct sdlsurface_context *sdlsurface,
232 short x0, short y0, short x1, short y1,
233 const unsigned int line_thickness, const struct nk_color col)
234 {
235 short tmp;
236 int dy, dx, stepx, stepy;
237
238 NK_UNUSED(line_thickness);
239
240 dy = y1 - y0;
241 dx = x1 - x0;
242
243 /* fast path */
244 if (dy == 0) {
245 if (dx == 0 || y0 >= sdlsurface->scissors.h || y0 < sdlsurface->scissors.y)
246 return;
247
248 if (dx < 0) {
249 /* swap x0 and x1 */
250 tmp = x1;
251 x1 = x0;
252 x0 = tmp;
253 }
254 x1 = MIN(sdlsurface->scissors.w, x1);
255 x0 = MIN(sdlsurface->scissors.w, x0);
256 x1 = MAX(sdlsurface->scissors.x, x1);
257 x0 = MAX(sdlsurface->scissors.x, x0);
258 nk_sdlsurface_line_horizontal(sdlsurface, x0, y0, x1, col);
259 return;
260 }
261 if (dy < 0) {
262 dy = -dy;
263 stepy = -1;
264 } else stepy = 1;
265
266 if (dx < 0) {
267 dx = -dx;
268 stepx = -1;
269 } else stepx = 1;
270
271 dy <<= 1;
272 dx <<= 1;
273
274 nk_sdlsurface_ctx_setpixel(sdlsurface, x0, y0, col);
275 if (dx > dy) {
276 int fraction = dy - (dx >> 1);
277 while (x0 != x1) {
278 if (fraction >= 0) {
279 y0 += stepy;
280 fraction -= dx;
281 }
282 x0 += stepx;
283 fraction += dy;
284 nk_sdlsurface_ctx_setpixel(sdlsurface, x0, y0, col);
285 }
286 } else {
287 int fraction = dx - (dy >> 1);
288 while (y0 != y1) {
289 if (fraction >= 0) {
290 x0 += stepx;
291 fraction -= dy;
292 }
293 y0 += stepy;
294 fraction += dx;
295 nk_sdlsurface_ctx_setpixel(sdlsurface, x0, y0, col);
296 }
297 }
298 }
299
300 static void
nk_sdlsurface_fill_polygon(const struct sdlsurface_context * sdlsurface,const struct nk_vec2i * pnts,int count,const struct nk_color col)301 nk_sdlsurface_fill_polygon(const struct sdlsurface_context *sdlsurface,
302 const struct nk_vec2i *pnts, int count, const struct nk_color col)
303 {
304 int i = 0;
305 #define MAX_POINTS 64
306 int left = 10000, top = 10000, bottom = 0, right = 0;
307 int nodes, nodeX[MAX_POINTS], pixelX, pixelY, j, swap ;
308
309 if (count == 0) return;
310 if (count > MAX_POINTS)
311 count = MAX_POINTS;
312
313 /* Get polygon dimensions */
314 for (i = 0; i < count; i++) {
315 if (left > pnts[i].x)
316 left = pnts[i].x;
317 if (right < pnts[i].x)
318 right = pnts[i].x;
319 if (top > pnts[i].y)
320 top = pnts[i].y;
321 if (bottom < pnts[i].y)
322 bottom = pnts[i].y;
323 } bottom++; right++;
324
325 /* Polygon scanline algorithm released under public-domain by Darel Rex Finley, 2007 */
326 /* Loop through the rows of the image. */
327 for (pixelY = top; pixelY < bottom; pixelY ++) {
328 nodes = 0; /* Build a list of nodes. */
329 j = count - 1;
330 for (i = 0; i < count; i++) {
331 if (((pnts[i].y < pixelY) && (pnts[j].y >= pixelY)) ||
332 ((pnts[j].y < pixelY) && (pnts[i].y >= pixelY))) {
333 nodeX[nodes++]= (int)((float)pnts[i].x
334 + ((float)pixelY - (float)pnts[i].y) / ((float)pnts[j].y - (float)pnts[i].y)
335 * ((float)pnts[j].x - (float)pnts[i].x));
336 } j = i;
337 }
338
339 /* Sort the nodes, via a simple “Bubble” sort. */
340 i = 0;
341 while (i < nodes - 1) {
342 if (nodeX[i] > nodeX[i+1]) {
343 swap = nodeX[i];
344 nodeX[i] = nodeX[i+1];
345 nodeX[i+1] = swap;
346 if (i) i--;
347 } else i++;
348 }
349 /* Fill the pixels between node pairs. */
350 for (i = 0; i < nodes; i += 2) {
351 if (nodeX[i+0] >= right) break;
352 if (nodeX[i+1] > left) {
353 if (nodeX[i+0] < left) nodeX[i+0] = left ;
354 if (nodeX[i+1] > right) nodeX[i+1] = right;
355 for (pixelX = nodeX[i]; pixelX < nodeX[i + 1]; pixelX++)
356 nk_sdlsurface_ctx_setpixel(sdlsurface, pixelX, pixelY, col);
357 }
358 }
359 }
360 #undef MAX_POINTS
361 }
362
363 static void
nk_sdlsurface_stroke_arc(const struct sdlsurface_context * sdlsurface,short x0,short y0,short w,short h,const short s,const short line_thickness,const struct nk_color col)364 nk_sdlsurface_stroke_arc(const struct sdlsurface_context *sdlsurface,
365 short x0, short y0, short w, short h, const short s,
366 const short line_thickness, const struct nk_color col)
367 {
368 /* Bresenham's ellipses - modified to draw one quarter */
369 const int a2 = (w * w) / 4;
370 const int b2 = (h * h) / 4;
371 const int fa2 = 4 * a2, fb2 = 4 * b2;
372 int x, y, sigma;
373
374 NK_UNUSED(line_thickness);
375
376 if (s != 0 && s != 90 && s != 180 && s != 270) return;
377 if (w < 1 || h < 1) return;
378
379 /* Convert upper left to center */
380 h = (h + 1) / 2;
381 w = (w + 1) / 2;
382 x0 += w; y0 += h;
383
384 /* First half */
385 for (x = 0, y = h, sigma = 2*b2+a2*(1-2*h); b2*x <= a2*y; x++) {
386 if (s == 180)
387 nk_sdlsurface_ctx_setpixel(sdlsurface, x0 + x, y0 + y, col);
388 else if (s == 270)
389 nk_sdlsurface_ctx_setpixel(sdlsurface, x0 - x, y0 + y, col);
390 else if (s == 0)
391 nk_sdlsurface_ctx_setpixel(sdlsurface, x0 + x, y0 - y, col);
392 else if (s == 90)
393 nk_sdlsurface_ctx_setpixel(sdlsurface, x0 - x, y0 - y, col);
394 if (sigma >= 0) {
395 sigma += fa2 * (1 - y);
396 y--;
397 } sigma += b2 * ((4 * x) + 6);
398 }
399
400 /* Second half */
401 for (x = w, y = 0, sigma = 2*a2+b2*(1-2*w); a2*y <= b2*x; y++) {
402 if (s == 180)
403 nk_sdlsurface_ctx_setpixel(sdlsurface, x0 + x, y0 + y, col);
404 else if (s == 270)
405 nk_sdlsurface_ctx_setpixel(sdlsurface, x0 - x, y0 + y, col);
406 else if (s == 0)
407 nk_sdlsurface_ctx_setpixel(sdlsurface, x0 + x, y0 - y, col);
408 else if (s == 90)
409 nk_sdlsurface_ctx_setpixel(sdlsurface, x0 - x, y0 - y, col);
410 if (sigma >= 0) {
411 sigma += fb2 * (1 - x);
412 x--;
413 } sigma += a2 * ((4 * y) + 6);
414 }
415 }
416
417 static void
nk_sdlsurface_fill_arc(const struct sdlsurface_context * sdlsurface,short x0,short y0,short w,short h,const short s,const struct nk_color col)418 nk_sdlsurface_fill_arc(const struct sdlsurface_context *sdlsurface, short x0, short y0,
419 short w, short h, const short s, const struct nk_color col)
420 {
421 /* Bresenham's ellipses - modified to fill one quarter */
422 const int a2 = (w * w) / 4;
423 const int b2 = (h * h) / 4;
424 const int fa2 = 4 * a2, fb2 = 4 * b2;
425 int x, y, sigma;
426 struct nk_vec2i pnts[3];
427 if (w < 1 || h < 1) return;
428 if (s != 0 && s != 90 && s != 180 && s != 270)
429 return;
430
431 /* Convert upper left to center */
432 h = (h + 1) / 2;
433 w = (w + 1) / 2;
434 x0 += w;
435 y0 += h;
436
437 pnts[0].x = x0;
438 pnts[0].y = y0;
439 pnts[2].x = x0;
440 pnts[2].y = y0;
441
442 /* First half */
443 for (x = 0, y = h, sigma = 2*b2+a2*(1-2*h); b2*x <= a2*y; x++) {
444 if (s == 180) {
445 pnts[1].x = x0 + x; pnts[1].y = y0 + y;
446 } else if (s == 270) {
447 pnts[1].x = x0 - x; pnts[1].y = y0 + y;
448 } else if (s == 0) {
449 pnts[1].x = x0 + x; pnts[1].y = y0 - y;
450 } else if (s == 90) {
451 pnts[1].x = x0 - x; pnts[1].y = y0 - y;
452 }
453 nk_sdlsurface_fill_polygon(sdlsurface, pnts, 3, col);
454 pnts[2] = pnts[1];
455 if (sigma >= 0) {
456 sigma += fa2 * (1 - y);
457 y--;
458 } sigma += b2 * ((4 * x) + 6);
459 }
460
461 /* Second half */
462 for (x = w, y = 0, sigma = 2*a2+b2*(1-2*w); a2*y <= b2*x; y++) {
463 if (s == 180) {
464 pnts[1].x = x0 + x; pnts[1].y = y0 + y;
465 } else if (s == 270) {
466 pnts[1].x = x0 - x; pnts[1].y = y0 + y;
467 } else if (s == 0) {
468 pnts[1].x = x0 + x; pnts[1].y = y0 - y;
469 } else if (s == 90) {
470 pnts[1].x = x0 - x; pnts[1].y = y0 - y;
471 }
472 nk_sdlsurface_fill_polygon(sdlsurface, pnts, 3, col);
473 pnts[2] = pnts[1];
474 if (sigma >= 0) {
475 sigma += fb2 * (1 - x);
476 x--;
477 } sigma += a2 * ((4 * y) + 6);
478 }
479 }
480
481 static void
nk_sdlsurface_stroke_rect(const struct sdlsurface_context * sdlsurface,const short x,const short y,const short w,const short h,const short r,const short line_thickness,const struct nk_color col)482 nk_sdlsurface_stroke_rect(const struct sdlsurface_context *sdlsurface,
483 const short x, const short y, const short w, const short h,
484 const short r, const short line_thickness, const struct nk_color col)
485 {
486 if (r == 0) {
487 nk_sdlsurface_stroke_line(sdlsurface, x, y, x + w, y, line_thickness, col);
488 nk_sdlsurface_stroke_line(sdlsurface, x, y + h, x + w, y + h, line_thickness, col);
489 nk_sdlsurface_stroke_line(sdlsurface, x, y, x, y + h, line_thickness, col);
490 nk_sdlsurface_stroke_line(sdlsurface, x + w, y, x + w, y + h, line_thickness, col);
491 } else {
492 const short xc = x + r;
493 const short yc = y + r;
494 const short wc = (short)(w - 2 * r);
495 const short hc = (short)(h - 2 * r);
496
497 nk_sdlsurface_stroke_line(sdlsurface, xc, y, xc + wc, y, line_thickness, col);
498 nk_sdlsurface_stroke_line(sdlsurface, x + w, yc, x + w, yc + hc, line_thickness, col);
499 nk_sdlsurface_stroke_line(sdlsurface, xc, y + h, xc + wc, y + h, line_thickness, col);
500 nk_sdlsurface_stroke_line(sdlsurface, x, yc, x, yc + hc, line_thickness, col);
501
502 nk_sdlsurface_stroke_arc(sdlsurface, xc + wc - r, y,
503 (unsigned)r*2, (unsigned)r*2, 0 , line_thickness, col);
504 nk_sdlsurface_stroke_arc(sdlsurface, x, y,
505 (unsigned)r*2, (unsigned)r*2, 90 , line_thickness, col);
506 nk_sdlsurface_stroke_arc(sdlsurface, x, yc + hc - r,
507 (unsigned)r*2, (unsigned)r*2, 270 , line_thickness, col);
508 nk_sdlsurface_stroke_arc(sdlsurface, xc + wc - r, yc + hc - r,
509 (unsigned)r*2, (unsigned)r*2, 180 , line_thickness, col);
510 }
511 }
512
513 static void
nk_sdlsurface_fill_rect(const struct sdlsurface_context * sdlsurface,const short x,const short y,const short w,const short h,const short r,const struct nk_color col)514 nk_sdlsurface_fill_rect(const struct sdlsurface_context *sdlsurface,
515 const short x, const short y, const short w, const short h,
516 const short r, const struct nk_color col)
517 {
518 int i;
519 if (r == 0) {
520 for (i = 0; i < h; i++)
521 nk_sdlsurface_stroke_line(sdlsurface, x, y + i, x + w, y + i, 1, col);
522 } else {
523 const short xc = x + r;
524 const short yc = y + r;
525 const short wc = (short)(w - 2 * r);
526 const short hc = (short)(h - 2 * r);
527
528 struct nk_vec2i pnts[12];
529 pnts[0].x = x;
530 pnts[0].y = yc;
531 pnts[1].x = xc;
532 pnts[1].y = yc;
533 pnts[2].x = xc;
534 pnts[2].y = y;
535
536 pnts[3].x = xc + wc;
537 pnts[3].y = y;
538 pnts[4].x = xc + wc;
539 pnts[4].y = yc;
540 pnts[5].x = x + w;
541 pnts[5].y = yc;
542
543 pnts[6].x = x + w;
544 pnts[6].y = yc + hc;
545 pnts[7].x = xc + wc;
546 pnts[7].y = yc + hc;
547 pnts[8].x = xc + wc;
548 pnts[8].y = y + h;
549
550 pnts[9].x = xc;
551 pnts[9].y = y + h;
552 pnts[10].x = xc;
553 pnts[10].y = yc + hc;
554 pnts[11].x = x;
555 pnts[11].y = yc + hc;
556
557 nk_sdlsurface_fill_polygon(sdlsurface, pnts, 12, col);
558
559 nk_sdlsurface_fill_arc(sdlsurface, xc + wc - r, y,
560 (unsigned)r*2, (unsigned)r*2, 0 , col);
561 nk_sdlsurface_fill_arc(sdlsurface, x, y,
562 (unsigned)r*2, (unsigned)r*2, 90 , col);
563 nk_sdlsurface_fill_arc(sdlsurface, x, yc + hc - r,
564 (unsigned)r*2, (unsigned)r*2, 270 , col);
565 nk_sdlsurface_fill_arc(sdlsurface, xc + wc - r, yc + hc - r,
566 (unsigned)r*2, (unsigned)r*2, 180 , col);
567 }
568 }
569
570 NK_API void
nk_sdlsurface_draw_rect_multi_color(const struct sdlsurface_context * sdlsurface,const short x,const short y,const short w,const short h,struct nk_color tl,struct nk_color tr,struct nk_color br,struct nk_color bl)571 nk_sdlsurface_draw_rect_multi_color(const struct sdlsurface_context *sdlsurface,
572 const short x, const short y, const short w, const short h, struct nk_color tl,
573 struct nk_color tr, struct nk_color br, struct nk_color bl)
574 {
575 int i, j;
576 struct nk_color *edge_buf;
577 struct nk_color *edge_t;
578 struct nk_color *edge_b;
579 struct nk_color *edge_l;
580 struct nk_color *edge_r;
581 struct nk_color pixel;
582
583 edge_buf = malloc(((2*w) + (2*h)) * sizeof(struct nk_color));
584 if (edge_buf == NULL)
585 return;
586
587 edge_t = edge_buf;
588 edge_b = edge_buf + w;
589 edge_l = edge_buf + (w*2);
590 edge_r = edge_buf + (w*2) + h;
591
592 /* Top and bottom edge gradients */
593 for (i=0; i<w; i++)
594 {
595 edge_t[i].r = (((((float)tr.r - tl.r)/(w-1))*i) + 0.5) + tl.r;
596 edge_t[i].g = (((((float)tr.g - tl.g)/(w-1))*i) + 0.5) + tl.g;
597 edge_t[i].b = (((((float)tr.b - tl.b)/(w-1))*i) + 0.5) + tl.b;
598 edge_t[i].a = (((((float)tr.a - tl.a)/(w-1))*i) + 0.5) + tl.a;
599
600 edge_b[i].r = (((((float)br.r - bl.r)/(w-1))*i) + 0.5) + bl.r;
601 edge_b[i].g = (((((float)br.g - bl.g)/(w-1))*i) + 0.5) + bl.g;
602 edge_b[i].b = (((((float)br.b - bl.b)/(w-1))*i) + 0.5) + bl.b;
603 edge_b[i].a = (((((float)br.a - bl.a)/(w-1))*i) + 0.5) + bl.a;
604 }
605
606 /* Left and right edge gradients */
607 for (i=0; i<h; i++)
608 {
609 edge_l[i].r = (((((float)bl.r - tl.r)/(h-1))*i) + 0.5) + tl.r;
610 edge_l[i].g = (((((float)bl.g - tl.g)/(h-1))*i) + 0.5) + tl.g;
611 edge_l[i].b = (((((float)bl.b - tl.b)/(h-1))*i) + 0.5) + tl.b;
612 edge_l[i].a = (((((float)bl.a - tl.a)/(h-1))*i) + 0.5) + tl.a;
613
614 edge_r[i].r = (((((float)br.r - tr.r)/(h-1))*i) + 0.5) + tr.r;
615 edge_r[i].g = (((((float)br.g - tr.g)/(h-1))*i) + 0.5) + tr.g;
616 edge_r[i].b = (((((float)br.b - tr.b)/(h-1))*i) + 0.5) + tr.b;
617 edge_r[i].a = (((((float)br.a - tr.a)/(h-1))*i) + 0.5) + tr.a;
618 }
619
620 for (i=0; i<h; i++) {
621 for (j=0; j<w; j++) {
622 if (i==0) {
623 nk_sdlsurface_img_blendpixel(sdlsurface->fb, x+j, y+i, edge_t[j]);
624 } else if (i==h-1) {
625 nk_sdlsurface_img_blendpixel(sdlsurface->fb, x+j, y+i, edge_b[j]);
626 } else {
627 if (j==0) {
628 nk_sdlsurface_img_blendpixel(sdlsurface->fb, x+j, y+i, edge_l[i]);
629 } else if (j==w-1) {
630 nk_sdlsurface_img_blendpixel(sdlsurface->fb, x+j, y+i, edge_r[i]);
631 } else {
632 pixel.r = (((((float)edge_r[i].r - edge_l[i].r)/(w-1))*j) + 0.5) + edge_l[i].r;
633 pixel.g = (((((float)edge_r[i].g - edge_l[i].g)/(w-1))*j) + 0.5) + edge_l[i].g;
634 pixel.b = (((((float)edge_r[i].b - edge_l[i].b)/(w-1))*j) + 0.5) + edge_l[i].b;
635 pixel.a = (((((float)edge_r[i].a - edge_l[i].a)/(w-1))*j) + 0.5) + edge_l[i].a;
636 nk_sdlsurface_img_blendpixel(sdlsurface->fb, x+j, y+i, pixel);
637 }
638 }
639 }
640 }
641
642 free(edge_buf);
643 }
644
645 static void
nk_sdlsurface_fill_triangle(const struct sdlsurface_context * sdlsurface,const short x0,const short y0,const short x1,const short y1,const short x2,const short y2,const struct nk_color col)646 nk_sdlsurface_fill_triangle(const struct sdlsurface_context *sdlsurface,
647 const short x0, const short y0, const short x1, const short y1,
648 const short x2, const short y2, const struct nk_color col)
649 {
650 struct nk_vec2i pnts[3];
651 pnts[0].x = x0;
652 pnts[0].y = y0;
653 pnts[1].x = x1;
654 pnts[1].y = y1;
655 pnts[2].x = x2;
656 pnts[2].y = y2;
657 nk_sdlsurface_fill_polygon(sdlsurface, pnts, 3, col);
658 }
659
660 static void
nk_sdlsurface_stroke_triangle(const struct sdlsurface_context * sdlsurface,const short x0,const short y0,const short x1,const short y1,const short x2,const short y2,const unsigned short line_thickness,const struct nk_color col)661 nk_sdlsurface_stroke_triangle(const struct sdlsurface_context *sdlsurface,
662 const short x0, const short y0, const short x1, const short y1,
663 const short x2, const short y2, const unsigned short line_thickness,
664 const struct nk_color col)
665 {
666 nk_sdlsurface_stroke_line(sdlsurface, x0, y0, x1, y1, line_thickness, col);
667 nk_sdlsurface_stroke_line(sdlsurface, x1, y1, x2, y2, line_thickness, col);
668 nk_sdlsurface_stroke_line(sdlsurface, x2, y2, x0, y0, line_thickness, col);
669 }
670
671 static void
nk_sdlsurface_stroke_polygon(const struct sdlsurface_context * sdlsurface,const struct nk_vec2i * pnts,const int count,const unsigned short line_thickness,const struct nk_color col)672 nk_sdlsurface_stroke_polygon(const struct sdlsurface_context *sdlsurface,
673 const struct nk_vec2i *pnts, const int count,
674 const unsigned short line_thickness, const struct nk_color col)
675 {
676 int i;
677 for (i = 1; i < count; ++i)
678 nk_sdlsurface_stroke_line(sdlsurface, pnts[i-1].x, pnts[i-1].y, pnts[i].x,
679 pnts[i].y, line_thickness, col);
680 nk_sdlsurface_stroke_line(sdlsurface, pnts[count-1].x, pnts[count-1].y,
681 pnts[0].x, pnts[0].y, line_thickness, col);
682 }
683
684 static void
nk_sdlsurface_stroke_polyline(const struct sdlsurface_context * sdlsurface,const struct nk_vec2i * pnts,const int count,const unsigned short line_thickness,const struct nk_color col)685 nk_sdlsurface_stroke_polyline(const struct sdlsurface_context *sdlsurface,
686 const struct nk_vec2i *pnts, const int count,
687 const unsigned short line_thickness, const struct nk_color col)
688 {
689 int i;
690 for (i = 0; i < count-1; ++i)
691 nk_sdlsurface_stroke_line(sdlsurface, pnts[i].x, pnts[i].y,
692 pnts[i+1].x, pnts[i+1].y, line_thickness, col);
693 }
694
695 static void
nk_sdlsurface_fill_circle(const struct sdlsurface_context * sdlsurface,short x0,short y0,short w,short h,const struct nk_color col)696 nk_sdlsurface_fill_circle(const struct sdlsurface_context *sdlsurface,
697 short x0, short y0, short w, short h, const struct nk_color col)
698 {
699 /* Bresenham's ellipses */
700 const int a2 = (w * w) / 4;
701 const int b2 = (h * h) / 4;
702 const int fa2 = 4 * a2, fb2 = 4 * b2;
703 int x, y, sigma;
704
705 /* Convert upper left to center */
706 h = (h + 1) / 2;
707 w = (w + 1) / 2;
708 x0 += w;
709 y0 += h;
710
711 /* First half */
712 for (x = 0, y = h, sigma = 2*b2+a2*(1-2*h); b2*x <= a2*y; x++) {
713 nk_sdlsurface_stroke_line(sdlsurface, x0 - x, y0 + y, x0 + x, y0 + y, 1, col);
714 nk_sdlsurface_stroke_line(sdlsurface, x0 - x, y0 - y, x0 + x, y0 - y, 1, col);
715 if (sigma >= 0) {
716 sigma += fa2 * (1 - y);
717 y--;
718 } sigma += b2 * ((4 * x) + 6);
719 }
720 /* Second half */
721 for (x = w, y = 0, sigma = 2*a2+b2*(1-2*w); a2*y <= b2*x; y++) {
722 nk_sdlsurface_stroke_line(sdlsurface, x0 - x, y0 + y, x0 + x, y0 + y, 1, col);
723 nk_sdlsurface_stroke_line(sdlsurface, x0 - x, y0 - y, x0 + x, y0 - y, 1, col);
724 if (sigma >= 0) {
725 sigma += fb2 * (1 - x);
726 x--;
727 } sigma += a2 * ((4 * y) + 6);
728 }
729 }
730
731 static void
nk_sdlsurface_stroke_circle(const struct sdlsurface_context * sdlsurface,short x0,short y0,short w,short h,const short line_thickness,const struct nk_color col)732 nk_sdlsurface_stroke_circle(const struct sdlsurface_context *sdlsurface,
733 short x0, short y0, short w, short h, const short line_thickness,
734 const struct nk_color col)
735 {
736 /* Bresenham's ellipses */
737 const int a2 = (w * w) / 4;
738 const int b2 = (h * h) / 4;
739 const int fa2 = 4 * a2, fb2 = 4 * b2;
740 int x, y, sigma;
741
742 NK_UNUSED(line_thickness);
743
744 /* Convert upper left to center */
745 h = (h + 1) / 2;
746 w = (w + 1) / 2;
747 x0 += w;
748 y0 += h;
749
750 /* First half */
751 for (x = 0, y = h, sigma = 2*b2+a2*(1-2*h); b2*x <= a2*y; x++) {
752 nk_sdlsurface_ctx_setpixel(sdlsurface, x0 + x, y0 + y, col);
753 nk_sdlsurface_ctx_setpixel(sdlsurface, x0 - x, y0 + y, col);
754 nk_sdlsurface_ctx_setpixel(sdlsurface, x0 + x, y0 - y, col);
755 nk_sdlsurface_ctx_setpixel(sdlsurface, x0 - x, y0 - y, col);
756 if (sigma >= 0) {
757 sigma += fa2 * (1 - y);
758 y--;
759 } sigma += b2 * ((4 * x) + 6);
760 }
761 /* Second half */
762 for (x = w, y = 0, sigma = 2*a2+b2*(1-2*w); a2*y <= b2*x; y++) {
763 nk_sdlsurface_ctx_setpixel(sdlsurface, x0 + x, y0 + y, col);
764 nk_sdlsurface_ctx_setpixel(sdlsurface, x0 - x, y0 + y, col);
765 nk_sdlsurface_ctx_setpixel(sdlsurface, x0 + x, y0 - y, col);
766 nk_sdlsurface_ctx_setpixel(sdlsurface, x0 - x, y0 - y, col);
767 if (sigma >= 0) {
768 sigma += fb2 * (1 - x);
769 x--;
770 } sigma += a2 * ((4 * y) + 6);
771 }
772 }
773
774 static void
nk_sdlsurface_stroke_curve(const struct sdlsurface_context * sdlsurface,const struct nk_vec2i p1,const struct nk_vec2i p2,const struct nk_vec2i p3,const struct nk_vec2i p4,const unsigned int num_segments,const unsigned short line_thickness,const struct nk_color col)775 nk_sdlsurface_stroke_curve(const struct sdlsurface_context *sdlsurface,
776 const struct nk_vec2i p1, const struct nk_vec2i p2,
777 const struct nk_vec2i p3, const struct nk_vec2i p4,
778 const unsigned int num_segments, const unsigned short line_thickness,
779 const struct nk_color col)
780 {
781 unsigned int i_step, segments;
782 float t_step;
783 struct nk_vec2i last = p1;
784
785 segments = MAX(num_segments, 1);
786 t_step = 1.0f/(float)segments;
787 for (i_step = 1; i_step <= segments; ++i_step) {
788 float t = t_step * (float)i_step;
789 float u = 1.0f - t;
790 float w1 = u*u*u;
791 float w2 = 3*u*u*t;
792 float w3 = 3*u*t*t;
793 float w4 = t * t *t;
794 float x = w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x;
795 float y = w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y;
796 nk_sdlsurface_stroke_line(sdlsurface, last.x, last.y,
797 (short)x, (short)y, line_thickness,col);
798 last.x = (short)x; last.y = (short)y;
799 }
800 }
801
802 static void
nk_sdlsurface_clear(const struct sdlsurface_context * sdlsurface,const struct nk_color col)803 nk_sdlsurface_clear(const struct sdlsurface_context *sdlsurface, const struct nk_color col)
804 {
805 nk_sdlsurface_fill_rect(sdlsurface, 0, 0, sdlsurface->fb->w, sdlsurface->fb->h, 0, col);
806 }
807
808 struct sdlsurface_context*
nk_sdlsurface_init(SDL_Surface * fb,float fontSize)809 nk_sdlsurface_init(SDL_Surface *fb, float fontSize)
810 {
811 const void *tex;
812 int texh, texw;
813 struct sdlsurface_context *sdlsurface;
814
815 assert((fb->format->format == SDL_PIXELFORMAT_ARGB8888)
816 || (fb->format->format == SDL_PIXELFORMAT_RGBA8888));
817
818 sdlsurface = malloc(sizeof(struct sdlsurface_context));
819 if (!sdlsurface)
820 return NULL;
821
822 memset(sdlsurface, 0, sizeof(struct sdlsurface_context));
823
824 sdlsurface->fb = fb;
825
826 if (0 == nk_init_default(&sdlsurface->ctx, 0)) {
827 free(sdlsurface);
828 return NULL;
829 }
830
831 nk_font_atlas_init_default(&sdlsurface->atlas);
832 nk_font_atlas_begin(&sdlsurface->atlas);
833 sdlsurface->atlas.default_font = nk_font_atlas_add_default(&sdlsurface->atlas, fontSize, 0);
834 tex = nk_font_atlas_bake(&sdlsurface->atlas, &texw, &texh, NK_FONT_ATLAS_RGBA32);
835 if (!tex) {
836 free(sdlsurface);
837 return NULL;
838 }
839
840 sdlsurface->font_tex = SDL_CreateRGBSurfaceWithFormat(0, texw, texh, 32, fb->format->format);
841
842 memcpy(sdlsurface->font_tex->pixels, tex, texw * texh * 4);
843
844 nk_font_atlas_end(&sdlsurface->atlas, nk_handle_ptr(NULL), NULL);
845 if (sdlsurface->atlas.default_font)
846 nk_style_set_font(&sdlsurface->ctx, &sdlsurface->atlas.default_font->handle);
847 nk_style_load_all_cursors(&sdlsurface->ctx, sdlsurface->atlas.cursors);
848 nk_sdlsurface_scissor(sdlsurface, 0, 0, sdlsurface->fb->w, sdlsurface->fb->h);
849
850 if (fb->format->format == SDL_PIXELFORMAT_RGBA8888)
851 {
852 uint32_t *fontPixels = (uint32_t *)sdlsurface->font_tex->pixels;
853 int i;
854 assert(sdlsurface->font_tex->pitch == sdlsurface->font_tex->w * 4);
855 for (i = 0; i < sdlsurface->font_tex->w * sdlsurface->font_tex->h; i++)
856 {
857 uint32_t col = fontPixels[i];
858 fontPixels[i] &= 0xFFFF00;
859 fontPixels[i] |= ((col & 0xFF000000) >> 24);
860 fontPixels[i] |= ((col & 0xFF) << 24);
861 }
862 }
863
864 return sdlsurface;
865 }
866
867 static void
nk_sdlsurface_stretch_image(const struct SDL_Surface * dst,const struct SDL_Surface * src,const struct nk_rect * dst_rect,const struct nk_rect * src_rect,const struct nk_rect * dst_scissors,const struct nk_color * fg)868 nk_sdlsurface_stretch_image(const struct SDL_Surface *dst,
869 const struct SDL_Surface *src, const struct nk_rect *dst_rect,
870 const struct nk_rect *src_rect, const struct nk_rect *dst_scissors,
871 const struct nk_color *fg)
872 {
873 short i, j;
874 struct nk_color col;
875 float xinc = src_rect->w / dst_rect->w;
876 float yinc = src_rect->h / dst_rect->h;
877 float xoff = src_rect->x, yoff = src_rect->y;
878
879 /* Simple nearest filtering rescaling */
880 /* TODO: use bilinear filter */
881 for (j = 0; j < (short)dst_rect->h; j++) {
882 for (i = 0; i < (short)dst_rect->w; i++) {
883 if (dst_scissors) {
884 if (i + (int)(dst_rect->x + 0.5f) < dst_scissors->x || i + (int)(dst_rect->x + 0.5f) >= dst_scissors->w)
885 continue;
886 if (j + (int)(dst_rect->y + 0.5f) < dst_scissors->y || j + (int)(dst_rect->y + 0.5f) >= dst_scissors->h)
887 continue;
888 }
889 col = nk_sdlsurface_img_getpixel(src, (int)xoff, (int) yoff);
890 if (col.r || col.g || col.b)
891 {
892 col.r = fg->r;
893 col.g = fg->g;
894 col.b = fg->b;
895 }
896 nk_sdlsurface_img_blendpixel(dst, i + (int)(dst_rect->x + 0.5f), j + (int)(dst_rect->y + 0.5f), col);
897 xoff += xinc;
898 }
899 xoff = src_rect->x;
900 yoff += yinc;
901 }
902 }
903
904 static void
nk_sdlsurface_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)905 nk_sdlsurface_font_query_font_glyph(nk_handle handle, const float height,
906 struct nk_user_font_glyph *glyph, const nk_rune codepoint,
907 const nk_rune next_codepoint)
908 {
909 float scale;
910 const struct nk_font_glyph *g;
911 struct nk_font *font;
912 NK_ASSERT(glyph);
913 NK_UNUSED(next_codepoint);
914
915 font = (struct nk_font*)handle.ptr;
916 NK_ASSERT(font);
917 NK_ASSERT(font->glyphs);
918 if (!font || !glyph)
919 return;
920
921 scale = height/font->info.height;
922 g = nk_font_find_glyph(font, codepoint);
923 glyph->width = (g->x1 - g->x0) * scale;
924 glyph->height = (g->y1 - g->y0) * scale;
925 glyph->offset = nk_vec2(g->x0 * scale, g->y0 * scale);
926 glyph->xadvance = (g->xadvance * scale);
927 glyph->uv[0] = nk_vec2(g->u0, g->v0);
928 glyph->uv[1] = nk_vec2(g->u1, g->v1);
929 }
930
931 NK_API void
nk_sdlsurface_draw_text(const struct sdlsurface_context * sdlsurface,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)932 nk_sdlsurface_draw_text(const struct sdlsurface_context *sdlsurface,
933 const struct nk_user_font *font, const struct nk_rect rect,
934 const char *text, const int len, const float font_height,
935 const struct nk_color fg)
936 {
937 float x = 0;
938 int text_len = 0;
939 nk_rune unicode = 0;
940 nk_rune next = 0;
941 int glyph_len = 0;
942 int next_glyph_len = 0;
943 struct nk_user_font_glyph g;
944 if (!len || !text) return;
945
946 x = 0;
947 glyph_len = nk_utf_decode(text, &unicode, len);
948 if (!glyph_len) return;
949
950 /* draw every glyph image */
951 while (text_len < len && glyph_len) {
952 struct nk_rect src_rect;
953 struct nk_rect dst_rect;
954 float char_width = 0;
955 if (unicode == NK_UTF_INVALID) break;
956
957 /* query currently drawn glyph information */
958 next_glyph_len = nk_utf_decode(text + text_len + glyph_len, &next, (int)len - text_len);
959 nk_sdlsurface_font_query_font_glyph(font->userdata, font_height, &g, unicode,
960 (next == NK_UTF_INVALID) ? '\0' : next);
961
962 /* calculate and draw glyph drawing rectangle and image */
963 char_width = g.xadvance;
964 src_rect.x = g.uv[0].x * sdlsurface->font_tex->w;
965 src_rect.y = g.uv[0].y * sdlsurface->font_tex->h;
966 src_rect.w = g.uv[1].x * sdlsurface->font_tex->w - g.uv[0].x * sdlsurface->font_tex->w;
967 src_rect.h = g.uv[1].y * sdlsurface->font_tex->h - g.uv[0].y * sdlsurface->font_tex->h;
968
969 dst_rect.x = x + g.offset.x + rect.x;
970 dst_rect.y = g.offset.y + rect.y;
971 dst_rect.w = ceil(g.width);
972 dst_rect.h = ceil(g.height);
973
974 /* Use software rescaling to blit glyph from font_text to framebuffer */
975 nk_sdlsurface_stretch_image(sdlsurface->fb, sdlsurface->font_tex, &dst_rect, &src_rect, &sdlsurface->scissors, &fg);
976
977 /* offset next glyph */
978 text_len += glyph_len;
979 x += char_width;
980 glyph_len = next_glyph_len;
981 unicode = next;
982 }
983 }
984
985 NK_API void
nk_sdlsurface_drawimage(const struct sdlsurface_context * sdlsurface,const int x,const int y,const int w,const int h,const struct nk_image * img,const struct nk_color * col)986 nk_sdlsurface_drawimage(const struct sdlsurface_context *sdlsurface,
987 const int x, const int y, const int w, const int h,
988 const struct nk_image *img, const struct nk_color *col)
989 {
990 struct nk_rect src_rect;
991 struct nk_rect dst_rect;
992
993 src_rect.x = img->region[0];
994 src_rect.y = img->region[1];
995 src_rect.w = img->region[2];
996 src_rect.h = img->region[3];
997
998 dst_rect.x = x;
999 dst_rect.y = y;
1000 dst_rect.w = w;
1001 dst_rect.h = h;
1002 nk_sdlsurface_stretch_image(sdlsurface->fb, sdlsurface->font_tex, &dst_rect, &src_rect, &sdlsurface->scissors, col);
1003 }
1004
1005 NK_API void
nk_sdlsurface_shutdown(struct sdlsurface_context * sdlsurface)1006 nk_sdlsurface_shutdown(struct sdlsurface_context *sdlsurface)
1007 {
1008 if (sdlsurface) {
1009 SDL_FreeSurface(sdlsurface->font_tex);
1010 nk_free(&sdlsurface->ctx);
1011 memset(sdlsurface, 0, sizeof(struct sdlsurface_context));
1012 free(sdlsurface);
1013 }
1014 }
1015
1016
1017 NK_API void
nk_sdlsurface_render(const struct sdlsurface_context * sdlsurface,const struct nk_color clear,const unsigned char enable_clear)1018 nk_sdlsurface_render(const struct sdlsurface_context *sdlsurface,
1019 const struct nk_color clear,
1020 const unsigned char enable_clear)
1021 {
1022 const struct nk_command *cmd;
1023 if (enable_clear)
1024 nk_sdlsurface_clear(sdlsurface, clear);
1025
1026 nk_foreach(cmd, (struct nk_context*)&sdlsurface->ctx) {
1027 switch (cmd->type) {
1028 case NK_COMMAND_NOP: break;
1029 case NK_COMMAND_SCISSOR: {
1030 const struct nk_command_scissor *s =(const struct nk_command_scissor*)cmd;
1031 nk_sdlsurface_scissor((struct sdlsurface_context *)sdlsurface, s->x, s->y, s->w, s->h);
1032 } break;
1033 case NK_COMMAND_LINE: {
1034 const struct nk_command_line *l = (const struct nk_command_line *)cmd;
1035 nk_sdlsurface_stroke_line(sdlsurface, l->begin.x, l->begin.y, l->end.x,
1036 l->end.y, l->line_thickness, l->color);
1037 } break;
1038 case NK_COMMAND_RECT: {
1039 const struct nk_command_rect *r = (const struct nk_command_rect *)cmd;
1040 nk_sdlsurface_stroke_rect(sdlsurface, r->x, r->y, r->w, r->h,
1041 (unsigned short)r->rounding, r->line_thickness, r->color);
1042 } break;
1043 case NK_COMMAND_RECT_FILLED: {
1044 const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled *)cmd;
1045 nk_sdlsurface_fill_rect(sdlsurface, r->x, r->y, r->w, r->h,
1046 (unsigned short)r->rounding, r->color);
1047 } break;
1048 case NK_COMMAND_CIRCLE: {
1049 const struct nk_command_circle *c = (const struct nk_command_circle *)cmd;
1050 nk_sdlsurface_stroke_circle(sdlsurface, c->x, c->y, c->w, c->h, c->line_thickness, c->color);
1051 } break;
1052 case NK_COMMAND_CIRCLE_FILLED: {
1053 const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
1054 nk_sdlsurface_fill_circle(sdlsurface, c->x, c->y, c->w, c->h, c->color);
1055 } break;
1056 case NK_COMMAND_TRIANGLE: {
1057 const struct nk_command_triangle*t = (const struct nk_command_triangle*)cmd;
1058 nk_sdlsurface_stroke_triangle(sdlsurface, t->a.x, t->a.y, t->b.x, t->b.y,
1059 t->c.x, t->c.y, t->line_thickness, t->color);
1060 } break;
1061 case NK_COMMAND_TRIANGLE_FILLED: {
1062 const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled *)cmd;
1063 nk_sdlsurface_fill_triangle(sdlsurface, t->a.x, t->a.y, t->b.x, t->b.y,
1064 t->c.x, t->c.y, t->color);
1065 } break;
1066 case NK_COMMAND_POLYGON: {
1067 const struct nk_command_polygon *p =(const struct nk_command_polygon*)cmd;
1068 nk_sdlsurface_stroke_polygon(sdlsurface, p->points, p->point_count, p->line_thickness,p->color);
1069 } break;
1070 case NK_COMMAND_POLYGON_FILLED: {
1071 const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled *)cmd;
1072 nk_sdlsurface_fill_polygon(sdlsurface, p->points, p->point_count, p->color);
1073 } break;
1074 case NK_COMMAND_POLYLINE: {
1075 const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd;
1076 nk_sdlsurface_stroke_polyline(sdlsurface, p->points, p->point_count, p->line_thickness, p->color);
1077 } break;
1078 case NK_COMMAND_TEXT: {
1079 const struct nk_command_text *t = (const struct nk_command_text*)cmd;
1080 nk_sdlsurface_draw_text(sdlsurface, t->font, nk_rect(t->x, t->y, t->w, t->h),
1081 t->string, t->length, t->height, t->foreground);
1082 } break;
1083 case NK_COMMAND_CURVE: {
1084 const struct nk_command_curve *q = (const struct nk_command_curve *)cmd;
1085 nk_sdlsurface_stroke_curve(sdlsurface, q->begin, q->ctrl[0], q->ctrl[1],
1086 q->end, 22, q->line_thickness, q->color);
1087 } break;
1088 case NK_COMMAND_RECT_MULTI_COLOR: {
1089 const struct nk_command_rect_multi_color *q = (const struct nk_command_rect_multi_color *)cmd;
1090 nk_sdlsurface_draw_rect_multi_color(sdlsurface, q->x, q->y, q->w, q->h, q->left, q->top, q->right, q->bottom);
1091 } break;
1092 case NK_COMMAND_IMAGE: {
1093 const struct nk_command_image *q = (const struct nk_command_image *)cmd;
1094 nk_sdlsurface_drawimage(sdlsurface, q->x, q->y, q->w, q->h, &q->img, &q->col);
1095 } break;
1096 case NK_COMMAND_ARC: {
1097 assert(0 && "NK_COMMAND_ARC not implemented\n");
1098 } break;
1099 case NK_COMMAND_ARC_FILLED: {
1100 assert(0 && "NK_COMMAND_ARC_FILLED not implemented\n");
1101 } break;
1102 default: break;
1103 }
1104 }
1105 nk_clear((struct nk_context*)&sdlsurface->ctx);
1106 }
1107 #endif
1108
1109