nuklear_gdip.h 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233
  1. /*
  2. * Nuklear - 1.40.8 - public domain
  3. * no warrenty implied; use at your own risk.
  4. * authored from 2015-2017 by Micha Mettke
  5. */
  6. /*
  7. * ==============================================================
  8. *
  9. * API
  10. *
  11. * ===============================================================
  12. */
  13. #ifndef NK_GDIP_H_
  14. #define NK_GDIP_H_
  15. #define WIN32_LEAN_AND_MEAN
  16. #include <windows.h>
  17. #include <shlwapi.h>
  18. /* font */
  19. typedef struct GdipFont GdipFont;
  20. NK_API GdipFont* nk_gdipfont_create(const char *name, int size);
  21. NK_API GdipFont* nk_gdipfont_create_from_file(const WCHAR* filename, int size);
  22. NK_API GdipFont* nk_gdipfont_create_from_memory(const void* membuf, int membufSize, int size);
  23. NK_API void nk_gdipfont_del(GdipFont *font);
  24. NK_API struct nk_context* nk_gdip_init(HWND hwnd, unsigned int width, unsigned int height);
  25. NK_API void nk_gdip_set_font(GdipFont *font);
  26. NK_API int nk_gdip_handle_event(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
  27. NK_API void nk_gdip_render(enum nk_anti_aliasing AA, struct nk_color clear);
  28. NK_API void nk_gdip_shutdown(void);
  29. /* image */
  30. NK_API struct nk_image nk_gdip_load_image_from_file(const WCHAR* filename);
  31. NK_API struct nk_image nk_gdip_load_image_from_memory(const void* membuf, nk_uint membufSize);
  32. NK_API void nk_gdip_image_free(struct nk_image image);
  33. #endif
  34. /*
  35. * ==============================================================
  36. *
  37. * IMPLEMENTATION
  38. *
  39. * ===============================================================
  40. */
  41. #ifdef NK_GDIP_IMPLEMENTATION
  42. #include <stdlib.h>
  43. #include <malloc.h>
  44. #define _USE_MATH_DEFINES
  45. #include <math.h>
  46. /* manually declare everything GDI+ needs, because
  47. GDI+ headers are not usable from C */
  48. #define WINGDIPAPI __stdcall
  49. #define GDIPCONST const
  50. typedef struct GpGraphics GpGraphics;
  51. typedef struct GpImage GpImage;
  52. typedef struct GpPen GpPen;
  53. typedef struct GpBrush GpBrush;
  54. typedef struct GpStringFormat GpStringFormat;
  55. typedef struct GpFont GpFont;
  56. typedef struct GpFontFamily GpFontFamily;
  57. typedef struct GpFontCollection GpFontCollection;
  58. typedef GpImage GpBitmap;
  59. typedef GpBrush GpSolidFill;
  60. typedef int Status;
  61. typedef Status GpStatus;
  62. typedef float REAL;
  63. typedef DWORD ARGB;
  64. typedef POINT GpPoint;
  65. typedef enum {
  66. TextRenderingHintSystemDefault = 0,
  67. TextRenderingHintSingleBitPerPixelGridFit = 1,
  68. TextRenderingHintSingleBitPerPixel = 2,
  69. TextRenderingHintAntiAliasGridFit = 3,
  70. TextRenderingHintAntiAlias = 4,
  71. TextRenderingHintClearTypeGridFit = 5
  72. } TextRenderingHint;
  73. typedef enum {
  74. StringFormatFlagsDirectionRightToLeft = 0x00000001,
  75. StringFormatFlagsDirectionVertical = 0x00000002,
  76. StringFormatFlagsNoFitBlackBox = 0x00000004,
  77. StringFormatFlagsDisplayFormatControl = 0x00000020,
  78. StringFormatFlagsNoFontFallback = 0x00000400,
  79. StringFormatFlagsMeasureTrailingSpaces = 0x00000800,
  80. StringFormatFlagsNoWrap = 0x00001000,
  81. StringFormatFlagsLineLimit = 0x00002000,
  82. StringFormatFlagsNoClip = 0x00004000
  83. } StringFormatFlags;
  84. typedef enum
  85. {
  86. QualityModeInvalid = -1,
  87. QualityModeDefault = 0,
  88. QualityModeLow = 1,
  89. QualityModeHigh = 2
  90. } QualityMode;
  91. typedef enum
  92. {
  93. SmoothingModeInvalid = QualityModeInvalid,
  94. SmoothingModeDefault = QualityModeDefault,
  95. SmoothingModeHighSpeed = QualityModeLow,
  96. SmoothingModeHighQuality = QualityModeHigh,
  97. SmoothingModeNone,
  98. SmoothingModeAntiAlias,
  99. SmoothingModeAntiAlias8x4 = SmoothingModeAntiAlias,
  100. SmoothingModeAntiAlias8x8
  101. } SmoothingMode;
  102. typedef enum
  103. {
  104. FontStyleRegular = 0,
  105. FontStyleBold = 1,
  106. FontStyleItalic = 2,
  107. FontStyleBoldItalic = 3,
  108. FontStyleUnderline = 4,
  109. FontStyleStrikeout = 8
  110. } FontStyle;
  111. typedef enum {
  112. FillModeAlternate,
  113. FillModeWinding
  114. } FillMode;
  115. typedef enum {
  116. CombineModeReplace,
  117. CombineModeIntersect,
  118. CombineModeUnion,
  119. CombineModeXor,
  120. CombineModeExclude,
  121. CombineModeComplement
  122. } CombineMode;
  123. typedef enum {
  124. UnitWorld,
  125. UnitDisplay,
  126. UnitPixel,
  127. UnitPoint,
  128. UnitInch,
  129. UnitDocument,
  130. UnitMillimeter
  131. } Unit;
  132. typedef struct {
  133. FLOAT X;
  134. FLOAT Y;
  135. FLOAT Width;
  136. FLOAT Height;
  137. } RectF;
  138. typedef enum {
  139. DebugEventLevelFatal,
  140. DebugEventLevelWarning
  141. } DebugEventLevel;
  142. typedef VOID (WINAPI *DebugEventProc)(DebugEventLevel level, CHAR *message);
  143. typedef struct {
  144. UINT32 GdiplusVersion;
  145. DebugEventProc DebugEventCallback;
  146. BOOL SuppressBackgroundThread;
  147. BOOL SuppressExternalCodecs;
  148. } GdiplusStartupInput;
  149. typedef Status (WINAPI *NotificationHookProc)(OUT ULONG_PTR *token);
  150. typedef VOID (WINAPI *NotificationUnhookProc)(ULONG_PTR token);
  151. typedef struct {
  152. NotificationHookProc NotificationHook;
  153. NotificationUnhookProc NotificationUnhook;
  154. } GdiplusStartupOutput;
  155. /* startup & shutdown */
  156. Status WINAPI GdiplusStartup(
  157. OUT ULONG_PTR *token,
  158. const GdiplusStartupInput *input,
  159. OUT GdiplusStartupOutput *output);
  160. VOID WINAPI GdiplusShutdown(ULONG_PTR token);
  161. /* image */
  162. GpStatus WINGDIPAPI
  163. GdipCreateBitmapFromGraphics(INT width,
  164. INT height,
  165. GpGraphics* target,
  166. GpBitmap** bitmap);
  167. GpStatus WINGDIPAPI
  168. GdipDisposeImage(GpImage *image);
  169. GpStatus WINGDIPAPI
  170. GdipGetImageGraphicsContext(GpImage *image, GpGraphics **graphics);
  171. GpStatus WINGDIPAPI
  172. GdipGetImageWidth(GpImage *image, UINT *width);
  173. GpStatus WINGDIPAPI
  174. GdipGetImageHeight(GpImage *image, UINT *height);
  175. GpStatus WINGDIPAPI
  176. GdipLoadImageFromFile(GDIPCONST WCHAR* filename, GpImage **image);
  177. GpStatus WINGDIPAPI
  178. GdipLoadImageFromStream(IStream* stream, GpImage **image);
  179. /* pen */
  180. GpStatus WINGDIPAPI
  181. GdipCreatePen1(ARGB color, REAL width, Unit unit, GpPen **pen);
  182. GpStatus WINGDIPAPI
  183. GdipDeletePen(GpPen *pen);
  184. GpStatus WINGDIPAPI
  185. GdipSetPenWidth(GpPen *pen, REAL width);
  186. GpStatus WINGDIPAPI
  187. GdipSetPenColor(GpPen *pen, ARGB argb);
  188. /* brush */
  189. GpStatus WINGDIPAPI
  190. GdipCreateSolidFill(ARGB color, GpSolidFill **brush);
  191. GpStatus WINGDIPAPI
  192. GdipDeleteBrush(GpBrush *brush);
  193. GpStatus WINGDIPAPI
  194. GdipSetSolidFillColor(GpSolidFill *brush, ARGB color);
  195. /* font */
  196. GpStatus WINGDIPAPI
  197. GdipCreateFont(
  198. GDIPCONST GpFontFamily *fontFamily,
  199. REAL emSize,
  200. INT style,
  201. Unit unit,
  202. GpFont **font
  203. );
  204. GpStatus WINGDIPAPI
  205. GdipDeleteFont(GpFont* font);
  206. GpStatus WINGDIPAPI
  207. GdipGetFontSize(GpFont *font, REAL *size);
  208. GpStatus WINGDIPAPI
  209. GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name,
  210. GpFontCollection *fontCollection,
  211. GpFontFamily **fontFamily);
  212. GpStatus WINGDIPAPI
  213. GdipDeleteFontFamily(GpFontFamily *fontFamily);
  214. GpStatus WINGDIPAPI
  215. GdipStringFormatGetGenericTypographic(GpStringFormat **format);
  216. GpStatus WINGDIPAPI
  217. GdipSetStringFormatFlags(GpStringFormat *format, INT flags);
  218. GpStatus WINGDIPAPI
  219. GdipDeleteStringFormat(GpStringFormat *format);
  220. GpStatus WINGDIPAPI
  221. GdipPrivateAddMemoryFont(GpFontCollection* fontCollection,
  222. GDIPCONST void* memory, INT length);
  223. GpStatus WINGDIPAPI
  224. GdipPrivateAddFontFile(GpFontCollection* fontCollection,
  225. GDIPCONST WCHAR* filename);
  226. GpStatus WINGDIPAPI
  227. GdipNewPrivateFontCollection(GpFontCollection** fontCollection);
  228. GpStatus WINGDIPAPI
  229. GdipDeletePrivateFontCollection(GpFontCollection** fontCollection);
  230. GpStatus WINGDIPAPI
  231. GdipGetFontCollectionFamilyList(GpFontCollection* fontCollection,
  232. INT numSought, GpFontFamily* gpfamilies[], INT* numFound);
  233. GpStatus WINGDIPAPI
  234. GdipGetFontCollectionFamilyCount(GpFontCollection* fontCollection, INT* numFound);
  235. /* graphics */
  236. GpStatus WINGDIPAPI
  237. GdipCreateFromHWND(HWND hwnd, GpGraphics **graphics);
  238. GpStatus WINGDIPAPI
  239. GdipCreateFromHDC(HDC hdc, GpGraphics **graphics);
  240. GpStatus WINGDIPAPI
  241. GdipDeleteGraphics(GpGraphics *graphics);
  242. GpStatus WINGDIPAPI
  243. GdipSetSmoothingMode(GpGraphics *graphics, SmoothingMode smoothingMode);
  244. GpStatus WINGDIPAPI
  245. GdipSetClipRectI(GpGraphics *graphics, INT x, INT y,
  246. INT width, INT height, CombineMode combineMode);
  247. GpStatus WINGDIPAPI
  248. GdipDrawLineI(GpGraphics *graphics, GpPen *pen, INT x1, INT y1,
  249. INT x2, INT y2);
  250. GpStatus WINGDIPAPI
  251. GdipDrawArcI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
  252. INT width, INT height, REAL startAngle, REAL sweepAngle);
  253. GpStatus WINGDIPAPI
  254. GdipDrawPieI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
  255. INT width, INT height, REAL startAngle, REAL sweepAngle);
  256. GpStatus WINGDIPAPI
  257. GdipFillPieI(GpGraphics *graphics, GpBrush *brush, INT x, INT y,
  258. INT width, INT height, REAL startAngle, REAL sweepAngle);
  259. GpStatus WINGDIPAPI
  260. GdipDrawRectangleI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
  261. INT width, INT height);
  262. GpStatus WINGDIPAPI
  263. GdipFillRectangleI(GpGraphics *graphics, GpBrush *brush, INT x, INT y,
  264. INT width, INT height);
  265. GpStatus WINGDIPAPI
  266. GdipFillPolygonI(GpGraphics *graphics, GpBrush *brush,
  267. GDIPCONST GpPoint *points, INT count, FillMode fillMode);
  268. GpStatus WINGDIPAPI
  269. GdipDrawPolygonI(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points,
  270. INT count);
  271. GpStatus WINGDIPAPI
  272. GdipFillEllipseI(GpGraphics *graphics, GpBrush *brush, INT x, INT y,
  273. INT width, INT height);
  274. GpStatus WINGDIPAPI
  275. GdipDrawEllipseI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
  276. INT width, INT height);
  277. GpStatus WINGDIPAPI
  278. GdipDrawBezierI(GpGraphics *graphics, GpPen *pen, INT x1, INT y1,
  279. INT x2, INT y2, INT x3, INT y3, INT x4, INT y4);
  280. GpStatus WINGDIPAPI
  281. GdipDrawString(
  282. GpGraphics *graphics,
  283. GDIPCONST WCHAR *string,
  284. INT length,
  285. GDIPCONST GpFont *font,
  286. GDIPCONST RectF *layoutRect,
  287. GDIPCONST GpStringFormat *stringFormat,
  288. GDIPCONST GpBrush *brush
  289. );
  290. GpStatus WINGDIPAPI
  291. GdipGraphicsClear(GpGraphics *graphics, ARGB color);
  292. GpStatus WINGDIPAPI
  293. GdipDrawImageI(GpGraphics *graphics, GpImage *image, INT x, INT y);
  294. GpStatus WINGDIPAPI
  295. GdipDrawImageRectI(GpGraphics *graphics, GpImage *image, INT x, INT y,
  296. INT width, INT height);
  297. GpStatus WINGDIPAPI
  298. GdipMeasureString(
  299. GpGraphics *graphics,
  300. GDIPCONST WCHAR *string,
  301. INT length,
  302. GDIPCONST GpFont *font,
  303. GDIPCONST RectF *layoutRect,
  304. GDIPCONST GpStringFormat *stringFormat,
  305. RectF *boundingBox,
  306. INT *codepointsFitted,
  307. INT *linesFilled
  308. );
  309. GpStatus WINGDIPAPI
  310. GdipSetTextRenderingHint(GpGraphics *graphics, TextRenderingHint mode);
  311. LWSTDAPI_(IStream *) SHCreateMemStream(const BYTE *pInit, _In_ UINT cbInit);
  312. struct GdipFont
  313. {
  314. struct nk_user_font nk;
  315. GpFont* handle;
  316. };
  317. static struct {
  318. ULONG_PTR token;
  319. GpGraphics *window;
  320. GpGraphics *memory;
  321. GpImage *bitmap;
  322. GpPen *pen;
  323. GpSolidFill *brush;
  324. GpStringFormat *format;
  325. GpFontCollection *fontCollection[10];
  326. INT curFontCollection;
  327. struct nk_context ctx;
  328. } gdip;
  329. static ARGB convert_color(struct nk_color c)
  330. {
  331. return (c.a << 24) | (c.r << 16) | (c.g << 8) | c.b;
  332. }
  333. static void
  334. nk_gdip_scissor(float x, float y, float w, float h)
  335. {
  336. GdipSetClipRectI(gdip.memory, (INT)x, (INT)y, (INT)(w + 1), (INT)(h + 1), CombineModeReplace);
  337. }
  338. static void
  339. nk_gdip_stroke_line(short x0, short y0, short x1,
  340. short y1, unsigned int line_thickness, struct nk_color col)
  341. {
  342. GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
  343. GdipSetPenColor(gdip.pen, convert_color(col));
  344. GdipDrawLineI(gdip.memory, gdip.pen, x0, y0, x1, y1);
  345. }
  346. static void
  347. nk_gdip_stroke_rect(short x, short y, unsigned short w,
  348. unsigned short h, unsigned short r, unsigned short line_thickness, struct nk_color col)
  349. {
  350. GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
  351. GdipSetPenColor(gdip.pen, convert_color(col));
  352. if (r == 0) {
  353. GdipDrawRectangleI(gdip.memory, gdip.pen, x, y, w, h);
  354. } else {
  355. INT d = 2 * r;
  356. GdipDrawArcI(gdip.memory, gdip.pen, x, y, d, d, 180, 90);
  357. GdipDrawLineI(gdip.memory, gdip.pen, x + r, y, x + w - r, y);
  358. GdipDrawArcI(gdip.memory, gdip.pen, x + w - d, y, d, d, 270, 90);
  359. GdipDrawLineI(gdip.memory, gdip.pen, x + w, y + r, x + w, y + h - r);
  360. GdipDrawArcI(gdip.memory, gdip.pen, x + w - d, y + h - d, d, d, 0, 90);
  361. GdipDrawLineI(gdip.memory, gdip.pen, x, y + r, x, y + h - r);
  362. GdipDrawArcI(gdip.memory, gdip.pen, x, y + h - d, d, d, 90, 90);
  363. GdipDrawLineI(gdip.memory, gdip.pen, x + r, y + h, x + w - r, y + h);
  364. }
  365. }
  366. static void
  367. nk_gdip_fill_rect(short x, short y, unsigned short w,
  368. unsigned short h, unsigned short r, struct nk_color col)
  369. {
  370. GdipSetSolidFillColor(gdip.brush, convert_color(col));
  371. if (r == 0) {
  372. GdipFillRectangleI(gdip.memory, gdip.brush, x, y, w, h);
  373. } else {
  374. INT d = 2 * r;
  375. GdipFillRectangleI(gdip.memory, gdip.brush, x + r, y, w - d, h);
  376. GdipFillRectangleI(gdip.memory, gdip.brush, x, y + r, r, h - d);
  377. GdipFillRectangleI(gdip.memory, gdip.brush, x + w - r, y + r, r, h - d);
  378. GdipFillPieI(gdip.memory, gdip.brush, x, y, d, d, 180, 90);
  379. GdipFillPieI(gdip.memory, gdip.brush, x + w - d, y, d, d, 270, 90);
  380. GdipFillPieI(gdip.memory, gdip.brush, x + w - d, y + h - d, d, d, 0, 90);
  381. GdipFillPieI(gdip.memory, gdip.brush, x, y + h - d, d, d, 90, 90);
  382. }
  383. }
  384. static BOOL
  385. SetPoint(POINT *p, LONG x, LONG y)
  386. {
  387. if (!p)
  388. return FALSE;
  389. p->x = x;
  390. p->y = y;
  391. return TRUE;
  392. }
  393. static void
  394. nk_gdip_fill_triangle(short x0, short y0, short x1,
  395. short y1, short x2, short y2, struct nk_color col)
  396. {
  397. POINT points[3];
  398. SetPoint(&points[0], x0, y0);
  399. SetPoint(&points[1], x1, y1);
  400. SetPoint(&points[2], x2, y2);
  401. GdipSetSolidFillColor(gdip.brush, convert_color(col));
  402. GdipFillPolygonI(gdip.memory, gdip.brush, points, 3, FillModeAlternate);
  403. }
  404. static void
  405. nk_gdip_stroke_triangle(short x0, short y0, short x1,
  406. short y1, short x2, short y2, unsigned short line_thickness, struct nk_color col)
  407. {
  408. POINT points[4];
  409. SetPoint(&points[0], x0, y0);
  410. SetPoint(&points[1], x1, y1);
  411. SetPoint(&points[2], x2, y2);
  412. SetPoint(&points[3], x0, y0);
  413. GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
  414. GdipSetPenColor(gdip.pen, convert_color(col));
  415. GdipDrawPolygonI(gdip.memory, gdip.pen, points, 4);
  416. }
  417. static void
  418. nk_gdip_fill_polygon(const struct nk_vec2i *pnts, int count, struct nk_color col)
  419. {
  420. int i = 0;
  421. #define MAX_POINTS 64
  422. POINT points[MAX_POINTS];
  423. GdipSetSolidFillColor(gdip.brush, convert_color(col));
  424. for (i = 0; i < count && i < MAX_POINTS; ++i) {
  425. points[i].x = pnts[i].x;
  426. points[i].y = pnts[i].y;
  427. }
  428. GdipFillPolygonI(gdip.memory, gdip.brush, points, i, FillModeAlternate);
  429. #undef MAX_POINTS
  430. }
  431. static void
  432. nk_gdip_stroke_polygon(const struct nk_vec2i *pnts, int count,
  433. unsigned short line_thickness, struct nk_color col)
  434. {
  435. GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
  436. GdipSetPenColor(gdip.pen, convert_color(col));
  437. if (count > 0) {
  438. int i;
  439. for (i = 1; i < count; ++i)
  440. GdipDrawLineI(gdip.memory, gdip.pen, pnts[i-1].x, pnts[i-1].y, pnts[i].x, pnts[i].y);
  441. GdipDrawLineI(gdip.memory, gdip.pen, pnts[count-1].x, pnts[count-1].y, pnts[0].x, pnts[0].y);
  442. }
  443. }
  444. static void
  445. nk_gdip_stroke_polyline(const struct nk_vec2i *pnts,
  446. int count, unsigned short line_thickness, struct nk_color col)
  447. {
  448. GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
  449. GdipSetPenColor(gdip.pen, convert_color(col));
  450. if (count > 0) {
  451. int i;
  452. for (i = 1; i < count; ++i)
  453. GdipDrawLineI(gdip.memory, gdip.pen, pnts[i-1].x, pnts[i-1].y, pnts[i].x, pnts[i].y);
  454. }
  455. }
  456. static void
  457. nk_gdip_fill_circle(short x, short y, unsigned short w,
  458. unsigned short h, struct nk_color col)
  459. {
  460. GdipSetSolidFillColor(gdip.brush, convert_color(col));
  461. GdipFillEllipseI(gdip.memory, gdip.brush, x, y, w, h);
  462. }
  463. static void
  464. nk_gdip_stroke_circle(short x, short y, unsigned short w,
  465. unsigned short h, unsigned short line_thickness, struct nk_color col)
  466. {
  467. GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
  468. GdipSetPenColor(gdip.pen, convert_color(col));
  469. GdipDrawEllipseI(gdip.memory, gdip.pen, x, y, w, h);
  470. }
  471. static void
  472. nk_gdip_stroke_curve(struct nk_vec2i p1,
  473. struct nk_vec2i p2, struct nk_vec2i p3, struct nk_vec2i p4,
  474. unsigned short line_thickness, struct nk_color col)
  475. {
  476. GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
  477. GdipSetPenColor(gdip.pen, convert_color(col));
  478. GdipDrawBezierI(gdip.memory, gdip.pen, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);
  479. }
  480. static void
  481. nk_gdip_fill_arc(short cx, short cy, unsigned short r, float amin, float adelta, struct nk_color col)
  482. {
  483. GdipSetSolidFillColor(gdip.brush, convert_color(col));
  484. GdipFillPieI(gdip.memory, gdip.brush, cx - r, cy - r, r * 2, r * 2, amin * (180/M_PI), adelta * (180/M_PI));
  485. }
  486. static void
  487. nk_gdip_stroke_arc(short cx, short cy, unsigned short r, float amin, float adelta, unsigned short line_thickness, struct nk_color col)
  488. {
  489. GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
  490. GdipSetPenColor(gdip.pen, convert_color(col));
  491. GdipDrawPieI(gdip.memory, gdip.pen, cx - r, cy - r, r * 2, r * 2, amin * (180/M_PI), adelta * (180/M_PI));
  492. }
  493. static void
  494. nk_gdip_draw_text(short x, short y, unsigned short w, unsigned short h,
  495. const char *text, int len, GdipFont *font, struct nk_color cbg, struct nk_color cfg)
  496. {
  497. int wsize;
  498. WCHAR* wstr;
  499. RectF layout;
  500. layout.X = x;
  501. layout.Y = y;
  502. layout.Width = w;
  503. layout.Height = h;
  504. if(!text || !font || !len) return;
  505. wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
  506. wstr = (WCHAR*)_alloca(wsize * sizeof(wchar_t));
  507. MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize);
  508. GdipSetSolidFillColor(gdip.brush, convert_color(cfg));
  509. GdipDrawString(gdip.memory, wstr, wsize, font->handle, &layout, gdip.format, gdip.brush);
  510. }
  511. static void
  512. nk_gdip_draw_image(short x, short y, unsigned short w, unsigned short h,
  513. struct nk_image img, struct nk_color col)
  514. {
  515. GpImage *image = img.handle.ptr;
  516. GdipDrawImageRectI(gdip.memory, image, x, y, w, h);
  517. }
  518. static void
  519. nk_gdip_clear(struct nk_color col)
  520. {
  521. GdipGraphicsClear(gdip.memory, convert_color(col));
  522. }
  523. static void
  524. nk_gdip_blit(GpGraphics *graphics)
  525. {
  526. GdipDrawImageI(graphics, gdip.bitmap, 0, 0);
  527. }
  528. static struct nk_image
  529. nk_gdip_image_to_nk(GpImage *image) {
  530. struct nk_image img;
  531. UINT uwidth, uheight;
  532. img = nk_image_ptr( (void*)image );
  533. GdipGetImageHeight(image, &uheight);
  534. GdipGetImageWidth(image, &uwidth);
  535. img.h = uheight;
  536. img.w = uwidth;
  537. return img;
  538. }
  539. struct nk_image
  540. nk_gdip_load_image_from_file(const WCHAR *filename)
  541. {
  542. GpImage *image;
  543. if (GdipLoadImageFromFile(filename, &image))
  544. return nk_image_id(0);
  545. return nk_gdip_image_to_nk(image);
  546. }
  547. struct nk_image
  548. nk_gdip_load_image_from_memory(const void *membuf, nk_uint membufSize)
  549. {
  550. GpImage* image;
  551. GpStatus status;
  552. IStream *stream = SHCreateMemStream((const BYTE*)membuf, membufSize);
  553. if (!stream)
  554. return nk_image_id(0);
  555. status = GdipLoadImageFromStream(stream, &image);
  556. stream->lpVtbl->Release(stream);
  557. if (status)
  558. return nk_image_id(0);
  559. return nk_gdip_image_to_nk(image);
  560. }
  561. void
  562. nk_gdip_image_free(struct nk_image image)
  563. {
  564. if (!image.handle.ptr)
  565. return;
  566. GdipDisposeImage(image.handle.ptr);
  567. }
  568. GdipFont*
  569. nk_gdipfont_create(const char *name, int size)
  570. {
  571. GdipFont *font = (GdipFont*)calloc(1, sizeof(GdipFont));
  572. GpFontFamily *family;
  573. int wsize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
  574. WCHAR* wname = (WCHAR*)_alloca((wsize + 1) * sizeof(wchar_t));
  575. MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, wsize);
  576. wname[wsize] = 0;
  577. GdipCreateFontFamilyFromName(wname, NULL, &family);
  578. GdipCreateFont(family, (REAL)size, FontStyleRegular, UnitPixel, &font->handle);
  579. GdipDeleteFontFamily(family);
  580. return font;
  581. }
  582. GpFontCollection*
  583. nk_gdip_getCurFontCollection(){
  584. return gdip.fontCollection[gdip.curFontCollection];
  585. }
  586. GdipFont*
  587. nk_gdipfont_create_from_collection(int size){
  588. GpFontFamily **families;
  589. INT count;
  590. GdipFont *font = (GdipFont*)calloc(1, sizeof(GdipFont));
  591. if( GdipGetFontCollectionFamilyCount(nk_gdip_getCurFontCollection(), &count) ) return NULL;
  592. families = (GpFontFamily**)calloc(1, sizeof(GpFontFamily*));
  593. if( !families ) return NULL;
  594. if( GdipGetFontCollectionFamilyList(nk_gdip_getCurFontCollection(), count, families, &count) ) return NULL;
  595. if( count < 1 ) return NULL;
  596. if( GdipCreateFont(families[count-1], (REAL)size, FontStyleRegular, UnitPixel, &font->handle) ) return NULL;
  597. free(families);
  598. gdip.curFontCollection++;
  599. return font;
  600. }
  601. GdipFont*
  602. nk_gdipfont_create_from_memory(const void* membuf, int membufSize, int size)
  603. {
  604. if( !nk_gdip_getCurFontCollection() )
  605. if( GdipNewPrivateFontCollection(&gdip.fontCollection[gdip.curFontCollection]) ) return NULL;
  606. if( GdipPrivateAddMemoryFont(nk_gdip_getCurFontCollection(), membuf, membufSize) ) return NULL;
  607. return nk_gdipfont_create_from_collection(size);
  608. }
  609. GdipFont*
  610. nk_gdipfont_create_from_file(const WCHAR* filename, int size)
  611. {
  612. if( !nk_gdip_getCurFontCollection() )
  613. if( GdipNewPrivateFontCollection(&gdip.fontCollection[gdip.curFontCollection]) ) return NULL;
  614. if( GdipPrivateAddFontFile(nk_gdip_getCurFontCollection(), filename) ) return NULL;
  615. return nk_gdipfont_create_from_collection(size);
  616. }
  617. static float
  618. nk_gdipfont_get_text_width(nk_handle handle, float height, const char *text, int len)
  619. {
  620. GdipFont *font = (GdipFont *)handle.ptr;
  621. RectF layout = { 0.0f, 0.0f, 65536.0f, 65536.0f };
  622. RectF bbox;
  623. int wsize;
  624. WCHAR* wstr;
  625. if (!font || !text)
  626. return 0;
  627. (void)height;
  628. wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
  629. wstr = (WCHAR*)_malloca(wsize * sizeof(wchar_t));
  630. MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize);
  631. GdipMeasureString(gdip.memory, wstr, wsize, font->handle, &layout, gdip.format, &bbox, NULL, NULL);
  632. return bbox.Width;
  633. }
  634. void
  635. nk_gdipfont_del(GdipFont *font)
  636. {
  637. if(!font) return;
  638. GdipDeleteFont(font->handle);
  639. free(font);
  640. }
  641. static void
  642. nk_gdip_clipboard_paste(nk_handle usr, struct nk_text_edit* edit)
  643. {
  644. (void)usr;
  645. if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL))
  646. {
  647. HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
  648. if (mem)
  649. {
  650. SIZE_T size = GlobalSize(mem) - 1;
  651. if (size)
  652. {
  653. LPCWSTR wstr = (LPCWSTR)GlobalLock(mem);
  654. if (wstr)
  655. {
  656. int utf8size = WideCharToMultiByte(CP_UTF8, 0, wstr, (int)(size / sizeof(wchar_t)), NULL, 0, NULL, NULL);
  657. if (utf8size)
  658. {
  659. char* utf8 = (char*)malloc(utf8size);
  660. if (utf8)
  661. {
  662. WideCharToMultiByte(CP_UTF8, 0, wstr, (int)(size / sizeof(wchar_t)), utf8, utf8size, NULL, NULL);
  663. nk_textedit_paste(edit, utf8, utf8size);
  664. free(utf8);
  665. }
  666. }
  667. GlobalUnlock(mem);
  668. }
  669. }
  670. }
  671. CloseClipboard();
  672. }
  673. }
  674. static void
  675. nk_gdip_clipboard_copy(nk_handle usr, const char* text, int len)
  676. {
  677. if (OpenClipboard(NULL))
  678. {
  679. int wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
  680. if (wsize)
  681. {
  682. HGLOBAL mem = (HGLOBAL)GlobalAlloc(GMEM_MOVEABLE, (wsize + 1) * sizeof(wchar_t));
  683. if (mem)
  684. {
  685. wchar_t* wstr = (wchar_t*)GlobalLock(mem);
  686. if (wstr)
  687. {
  688. MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize);
  689. wstr[wsize] = 0;
  690. GlobalUnlock(mem);
  691. SetClipboardData(CF_UNICODETEXT, mem);
  692. }
  693. }
  694. }
  695. CloseClipboard();
  696. }
  697. }
  698. NK_API struct nk_context*
  699. nk_gdip_init(HWND hwnd, unsigned int width, unsigned int height)
  700. {
  701. int i;
  702. GdiplusStartupInput startup = { 1, NULL, FALSE, TRUE };
  703. GdiplusStartup(&gdip.token, &startup, NULL);
  704. GdipCreateFromHWND(hwnd, &gdip.window);
  705. GdipCreateBitmapFromGraphics(width, height, gdip.window, &gdip.bitmap);
  706. GdipGetImageGraphicsContext(gdip.bitmap, &gdip.memory);
  707. GdipCreatePen1(0, 1.0f, UnitPixel, &gdip.pen);
  708. GdipCreateSolidFill(0, &gdip.brush);
  709. GdipStringFormatGetGenericTypographic(&gdip.format);
  710. GdipSetStringFormatFlags(gdip.format, StringFormatFlagsNoFitBlackBox |
  711. StringFormatFlagsMeasureTrailingSpaces | StringFormatFlagsNoWrap |
  712. StringFormatFlagsNoClip);
  713. for(i=0; i< sizeof(gdip.fontCollection)/sizeof(gdip.fontCollection[0]); i++)
  714. gdip.fontCollection[i] = NULL;
  715. nk_init_default(&gdip.ctx, NULL);
  716. gdip.ctx.clip.copy = nk_gdip_clipboard_copy;
  717. gdip.ctx.clip.paste = nk_gdip_clipboard_paste;
  718. gdip.curFontCollection = 0;
  719. return &gdip.ctx;
  720. }
  721. NK_API void
  722. nk_gdip_set_font(GdipFont *gdipfont)
  723. {
  724. struct nk_user_font *font = &gdipfont->nk;
  725. font->userdata = nk_handle_ptr(gdipfont);
  726. GdipGetFontSize(gdipfont->handle, &font->height);
  727. font->width = nk_gdipfont_get_text_width;
  728. nk_style_set_font(&gdip.ctx, font);
  729. }
  730. NK_API int
  731. nk_gdip_handle_event(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
  732. {
  733. static int insert_toggle = 0;
  734. switch (msg)
  735. {
  736. case WM_SIZE:
  737. if (gdip.window)
  738. {
  739. unsigned int width = LOWORD(lparam);
  740. unsigned int height = HIWORD(lparam);
  741. GdipDeleteGraphics(gdip.window);
  742. GdipDeleteGraphics(gdip.memory);
  743. GdipDisposeImage(gdip.bitmap);
  744. GdipCreateFromHWND(wnd, &gdip.window);
  745. GdipCreateBitmapFromGraphics(width, height, gdip.window, &gdip.bitmap);
  746. GdipGetImageGraphicsContext(gdip.bitmap, &gdip.memory);
  747. }
  748. break;
  749. case WM_PAINT:
  750. {
  751. PAINTSTRUCT paint;
  752. HDC dc = BeginPaint(wnd, &paint);
  753. GpGraphics *graphics;
  754. GdipCreateFromHDC(dc, &graphics);
  755. nk_gdip_blit(graphics);
  756. GdipDeleteGraphics(graphics);
  757. EndPaint(wnd, &paint);
  758. return 1;
  759. }
  760. case WM_KEYDOWN:
  761. case WM_KEYUP:
  762. case WM_SYSKEYDOWN:
  763. case WM_SYSKEYUP:
  764. {
  765. int down = !((lparam >> 31) & 1);
  766. int ctrl = GetKeyState(VK_CONTROL) & (1 << 15);
  767. switch (wparam)
  768. {
  769. case VK_SHIFT:
  770. case VK_LSHIFT:
  771. case VK_RSHIFT:
  772. nk_input_key(&gdip.ctx, NK_KEY_SHIFT, down);
  773. return 1;
  774. case VK_DELETE:
  775. nk_input_key(&gdip.ctx, NK_KEY_DEL, down);
  776. return 1;
  777. case VK_RETURN:
  778. case VK_SEPARATOR:
  779. nk_input_key(&gdip.ctx, NK_KEY_ENTER, down);
  780. return 1;
  781. case VK_TAB:
  782. nk_input_key(&gdip.ctx, NK_KEY_TAB, down);
  783. return 1;
  784. case VK_LEFT:
  785. if (ctrl)
  786. nk_input_key(&gdip.ctx, NK_KEY_TEXT_WORD_LEFT, down);
  787. else
  788. nk_input_key(&gdip.ctx, NK_KEY_LEFT, down);
  789. return 1;
  790. case VK_RIGHT:
  791. if (ctrl)
  792. nk_input_key(&gdip.ctx, NK_KEY_TEXT_WORD_RIGHT, down);
  793. else
  794. nk_input_key(&gdip.ctx, NK_KEY_RIGHT, down);
  795. return 1;
  796. case VK_BACK:
  797. nk_input_key(&gdip.ctx, NK_KEY_BACKSPACE, down);
  798. return 1;
  799. case VK_HOME:
  800. nk_input_key(&gdip.ctx, NK_KEY_TEXT_START, down);
  801. nk_input_key(&gdip.ctx, NK_KEY_SCROLL_START, down);
  802. return 1;
  803. case VK_END:
  804. nk_input_key(&gdip.ctx, NK_KEY_TEXT_END, down);
  805. nk_input_key(&gdip.ctx, NK_KEY_SCROLL_END, down);
  806. return 1;
  807. case VK_NEXT:
  808. nk_input_key(&gdip.ctx, NK_KEY_SCROLL_DOWN, down);
  809. return 1;
  810. case VK_PRIOR:
  811. nk_input_key(&gdip.ctx, NK_KEY_SCROLL_UP, down);
  812. return 1;
  813. case VK_ESCAPE:
  814. nk_input_key(&gdip.ctx, NK_KEY_TEXT_RESET_MODE, down);
  815. return 1;
  816. case VK_INSERT:
  817. /* Only switch on release to avoid repeat issues
  818. * kind of confusing since we have to negate it but we're already
  819. * hacking it since Nuklear treats them as two separate keys rather
  820. * than a single toggle state */
  821. if (!down) {
  822. insert_toggle = !insert_toggle;
  823. if (insert_toggle) {
  824. nk_input_key(&gdip.ctx, NK_KEY_TEXT_INSERT_MODE, !down);
  825. /* nk_input_key(&gdip.ctx, NK_KEY_TEXT_REPLACE_MODE, down); */
  826. } else {
  827. nk_input_key(&gdip.ctx, NK_KEY_TEXT_REPLACE_MODE, !down);
  828. /* nk_input_key(&gdip.ctx, NK_KEY_TEXT_INSERT_MODE, down); */
  829. }
  830. }
  831. return 1;
  832. case 'A':
  833. if (ctrl) {
  834. nk_input_key(&gdip.ctx, NK_KEY_TEXT_SELECT_ALL, down);
  835. return 1;
  836. }
  837. break;
  838. case 'B':
  839. if (ctrl) {
  840. nk_input_key(&gdip.ctx, NK_KEY_TEXT_LINE_START, down);
  841. return 1;
  842. }
  843. break;
  844. case 'E':
  845. if (ctrl) {
  846. nk_input_key(&gdip.ctx, NK_KEY_TEXT_LINE_END, down);
  847. return 1;
  848. }
  849. break;
  850. case 'C':
  851. if (ctrl) {
  852. nk_input_key(&gdip.ctx, NK_KEY_COPY, down);
  853. return 1;
  854. }
  855. break;
  856. case 'V':
  857. if (ctrl) {
  858. nk_input_key(&gdip.ctx, NK_KEY_PASTE, down);
  859. return 1;
  860. }
  861. break;
  862. case 'X':
  863. if (ctrl) {
  864. nk_input_key(&gdip.ctx, NK_KEY_CUT, down);
  865. return 1;
  866. }
  867. break;
  868. case 'Z':
  869. if (ctrl) {
  870. nk_input_key(&gdip.ctx, NK_KEY_TEXT_UNDO, down);
  871. return 1;
  872. }
  873. break;
  874. case 'R':
  875. if (ctrl) {
  876. nk_input_key(&gdip.ctx, NK_KEY_TEXT_REDO, down);
  877. return 1;
  878. }
  879. break;
  880. }
  881. return 0;
  882. }
  883. case WM_CHAR:
  884. if (wparam >= 32)
  885. {
  886. nk_input_unicode(&gdip.ctx, (nk_rune)wparam);
  887. return 1;
  888. }
  889. break;
  890. case WM_LBUTTONDOWN:
  891. nk_input_button(&gdip.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
  892. SetCapture(wnd);
  893. return 1;
  894. case WM_LBUTTONUP:
  895. nk_input_button(&gdip.ctx, NK_BUTTON_DOUBLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
  896. nk_input_button(&gdip.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
  897. ReleaseCapture();
  898. return 1;
  899. case WM_RBUTTONDOWN:
  900. nk_input_button(&gdip.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
  901. SetCapture(wnd);
  902. return 1;
  903. case WM_RBUTTONUP:
  904. nk_input_button(&gdip.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
  905. ReleaseCapture();
  906. return 1;
  907. case WM_MBUTTONDOWN:
  908. nk_input_button(&gdip.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
  909. SetCapture(wnd);
  910. return 1;
  911. case WM_MBUTTONUP:
  912. nk_input_button(&gdip.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
  913. ReleaseCapture();
  914. return 1;
  915. case WM_MOUSEWHEEL:
  916. nk_input_scroll(&gdip.ctx, nk_vec2(0,(float)(short)HIWORD(wparam) / WHEEL_DELTA));
  917. return 1;
  918. case WM_MOUSEMOVE:
  919. nk_input_motion(&gdip.ctx, (short)LOWORD(lparam), (short)HIWORD(lparam));
  920. return 1;
  921. case WM_LBUTTONDBLCLK:
  922. nk_input_button(&gdip.ctx, NK_BUTTON_DOUBLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
  923. return 1;
  924. }
  925. return 0;
  926. }
  927. NK_API void
  928. nk_gdip_shutdown(void)
  929. {
  930. int i;
  931. for(i=0; i< gdip.curFontCollection; i++)
  932. GdipDeletePrivateFontCollection( &gdip.fontCollection[i] );
  933. GdipDeleteGraphics(gdip.window);
  934. GdipDeleteGraphics(gdip.memory);
  935. GdipDisposeImage(gdip.bitmap);
  936. GdipDeletePen(gdip.pen);
  937. GdipDeleteBrush(gdip.brush);
  938. GdipDeleteStringFormat(gdip.format);
  939. GdiplusShutdown(gdip.token);
  940. nk_free(&gdip.ctx);
  941. }
  942. NK_API void
  943. nk_gdip_prerender_gui(enum nk_anti_aliasing AA)
  944. {
  945. const struct nk_command *cmd;
  946. GdipSetTextRenderingHint(gdip.memory, AA != NK_ANTI_ALIASING_OFF ?
  947. TextRenderingHintClearTypeGridFit : TextRenderingHintSingleBitPerPixelGridFit);
  948. GdipSetSmoothingMode(gdip.memory, AA != NK_ANTI_ALIASING_OFF ?
  949. SmoothingModeHighQuality : SmoothingModeNone);
  950. nk_foreach(cmd, &gdip.ctx)
  951. {
  952. switch (cmd->type) {
  953. case NK_COMMAND_NOP: break;
  954. case NK_COMMAND_SCISSOR: {
  955. const struct nk_command_scissor *s =(const struct nk_command_scissor*)cmd;
  956. nk_gdip_scissor(s->x, s->y, s->w, s->h);
  957. } break;
  958. case NK_COMMAND_LINE: {
  959. const struct nk_command_line *l = (const struct nk_command_line *)cmd;
  960. nk_gdip_stroke_line(l->begin.x, l->begin.y, l->end.x,
  961. l->end.y, l->line_thickness, l->color);
  962. } break;
  963. case NK_COMMAND_RECT: {
  964. const struct nk_command_rect *r = (const struct nk_command_rect *)cmd;
  965. nk_gdip_stroke_rect(r->x, r->y, r->w, r->h,
  966. (unsigned short)r->rounding, r->line_thickness, r->color);
  967. } break;
  968. case NK_COMMAND_RECT_FILLED: {
  969. const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled *)cmd;
  970. nk_gdip_fill_rect(r->x, r->y, r->w, r->h,
  971. (unsigned short)r->rounding, r->color);
  972. } break;
  973. case NK_COMMAND_CIRCLE: {
  974. const struct nk_command_circle *c = (const struct nk_command_circle *)cmd;
  975. nk_gdip_stroke_circle(c->x, c->y, c->w, c->h, c->line_thickness, c->color);
  976. } break;
  977. case NK_COMMAND_CIRCLE_FILLED: {
  978. const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
  979. nk_gdip_fill_circle(c->x, c->y, c->w, c->h, c->color);
  980. } break;
  981. case NK_COMMAND_TRIANGLE: {
  982. const struct nk_command_triangle*t = (const struct nk_command_triangle*)cmd;
  983. nk_gdip_stroke_triangle(t->a.x, t->a.y, t->b.x, t->b.y,
  984. t->c.x, t->c.y, t->line_thickness, t->color);
  985. } break;
  986. case NK_COMMAND_TRIANGLE_FILLED: {
  987. const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled *)cmd;
  988. nk_gdip_fill_triangle(t->a.x, t->a.y, t->b.x, t->b.y,
  989. t->c.x, t->c.y, t->color);
  990. } break;
  991. case NK_COMMAND_POLYGON: {
  992. const struct nk_command_polygon *p =(const struct nk_command_polygon*)cmd;
  993. nk_gdip_stroke_polygon(p->points, p->point_count, p->line_thickness,p->color);
  994. } break;
  995. case NK_COMMAND_POLYGON_FILLED: {
  996. const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled *)cmd;
  997. nk_gdip_fill_polygon(p->points, p->point_count, p->color);
  998. } break;
  999. case NK_COMMAND_POLYLINE: {
  1000. const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd;
  1001. nk_gdip_stroke_polyline(p->points, p->point_count, p->line_thickness, p->color);
  1002. } break;
  1003. case NK_COMMAND_TEXT: {
  1004. const struct nk_command_text *t = (const struct nk_command_text*)cmd;
  1005. nk_gdip_draw_text(t->x, t->y, t->w, t->h,
  1006. (const char*)t->string, t->length,
  1007. (GdipFont*)t->font->userdata.ptr,
  1008. t->background, t->foreground);
  1009. } break;
  1010. case NK_COMMAND_CURVE: {
  1011. const struct nk_command_curve *q = (const struct nk_command_curve *)cmd;
  1012. nk_gdip_stroke_curve(q->begin, q->ctrl[0], q->ctrl[1],
  1013. q->end, q->line_thickness, q->color);
  1014. } break;
  1015. case NK_COMMAND_IMAGE: {
  1016. const struct nk_command_image *i = (const struct nk_command_image *)cmd;
  1017. nk_gdip_draw_image(i->x, i->y, i->w, i->h, i->img, i->col);
  1018. } break;
  1019. case NK_COMMAND_ARC: {
  1020. const struct nk_command_arc *i = (const struct nk_command_arc *)cmd;
  1021. nk_gdip_stroke_arc(i->cx, i->cy, i->r, i->a[0], i->a[1], i->line_thickness, i->color);
  1022. } break;
  1023. case NK_COMMAND_ARC_FILLED: {
  1024. const struct nk_command_arc_filled *i = (const struct nk_command_arc_filled *)cmd;
  1025. nk_gdip_fill_arc(i->cx, i->cy, i->r, i->a[0], i->a[1], i->color);
  1026. } break;
  1027. case NK_COMMAND_RECT_MULTI_COLOR:
  1028. default: break;
  1029. }
  1030. }
  1031. }
  1032. NK_API void
  1033. nk_gdip_render_gui(enum nk_anti_aliasing AA)
  1034. {
  1035. nk_gdip_prerender_gui(AA);
  1036. nk_gdip_blit(gdip.window);
  1037. nk_clear(&gdip.ctx);
  1038. }
  1039. NK_API void
  1040. nk_gdip_render(enum nk_anti_aliasing AA, struct nk_color clear)
  1041. {
  1042. nk_gdip_clear(clear);
  1043. nk_gdip_render_gui(AA);
  1044. }
  1045. #endif