sdl2surface_rawfb.h 38 KB

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