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