| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233 |
- /*
- * Nuklear - 1.40.8 - public domain
- * no warrenty implied; use at your own risk.
- * authored from 2015-2017 by Micha Mettke
- */
- /*
- * ==============================================================
- *
- * API
- *
- * ===============================================================
- */
- #ifndef NK_GDIP_H_
- #define NK_GDIP_H_
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <shlwapi.h>
- /* font */
- typedef struct GdipFont GdipFont;
- NK_API GdipFont* nk_gdipfont_create(const char *name, int size);
- NK_API GdipFont* nk_gdipfont_create_from_file(const WCHAR* filename, int size);
- NK_API GdipFont* nk_gdipfont_create_from_memory(const void* membuf, int membufSize, int size);
- NK_API void nk_gdipfont_del(GdipFont *font);
- NK_API struct nk_context* nk_gdip_init(HWND hwnd, unsigned int width, unsigned int height);
- NK_API void nk_gdip_set_font(GdipFont *font);
- NK_API int nk_gdip_handle_event(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
- NK_API void nk_gdip_render(enum nk_anti_aliasing AA, struct nk_color clear);
- NK_API void nk_gdip_shutdown(void);
- /* image */
- NK_API struct nk_image nk_gdip_load_image_from_file(const WCHAR* filename);
- NK_API struct nk_image nk_gdip_load_image_from_memory(const void* membuf, nk_uint membufSize);
- NK_API void nk_gdip_image_free(struct nk_image image);
- #endif
- /*
- * ==============================================================
- *
- * IMPLEMENTATION
- *
- * ===============================================================
- */
- #ifdef NK_GDIP_IMPLEMENTATION
- #include <stdlib.h>
- #include <malloc.h>
- #define _USE_MATH_DEFINES
- #include <math.h>
- /* manually declare everything GDI+ needs, because
- GDI+ headers are not usable from C */
- #define WINGDIPAPI __stdcall
- #define GDIPCONST const
- typedef struct GpGraphics GpGraphics;
- typedef struct GpImage GpImage;
- typedef struct GpPen GpPen;
- typedef struct GpBrush GpBrush;
- typedef struct GpStringFormat GpStringFormat;
- typedef struct GpFont GpFont;
- typedef struct GpFontFamily GpFontFamily;
- typedef struct GpFontCollection GpFontCollection;
- typedef GpImage GpBitmap;
- typedef GpBrush GpSolidFill;
- typedef int Status;
- typedef Status GpStatus;
- typedef float REAL;
- typedef DWORD ARGB;
- typedef POINT GpPoint;
- typedef enum {
- TextRenderingHintSystemDefault = 0,
- TextRenderingHintSingleBitPerPixelGridFit = 1,
- TextRenderingHintSingleBitPerPixel = 2,
- TextRenderingHintAntiAliasGridFit = 3,
- TextRenderingHintAntiAlias = 4,
- TextRenderingHintClearTypeGridFit = 5
- } TextRenderingHint;
- typedef enum {
- StringFormatFlagsDirectionRightToLeft = 0x00000001,
- StringFormatFlagsDirectionVertical = 0x00000002,
- StringFormatFlagsNoFitBlackBox = 0x00000004,
- StringFormatFlagsDisplayFormatControl = 0x00000020,
- StringFormatFlagsNoFontFallback = 0x00000400,
- StringFormatFlagsMeasureTrailingSpaces = 0x00000800,
- StringFormatFlagsNoWrap = 0x00001000,
- StringFormatFlagsLineLimit = 0x00002000,
- StringFormatFlagsNoClip = 0x00004000
- } StringFormatFlags;
- typedef enum
- {
- QualityModeInvalid = -1,
- QualityModeDefault = 0,
- QualityModeLow = 1,
- QualityModeHigh = 2
- } QualityMode;
- typedef enum
- {
- SmoothingModeInvalid = QualityModeInvalid,
- SmoothingModeDefault = QualityModeDefault,
- SmoothingModeHighSpeed = QualityModeLow,
- SmoothingModeHighQuality = QualityModeHigh,
- SmoothingModeNone,
- SmoothingModeAntiAlias,
- SmoothingModeAntiAlias8x4 = SmoothingModeAntiAlias,
- SmoothingModeAntiAlias8x8
- } SmoothingMode;
- typedef enum
- {
- FontStyleRegular = 0,
- FontStyleBold = 1,
- FontStyleItalic = 2,
- FontStyleBoldItalic = 3,
- FontStyleUnderline = 4,
- FontStyleStrikeout = 8
- } FontStyle;
- typedef enum {
- FillModeAlternate,
- FillModeWinding
- } FillMode;
- typedef enum {
- CombineModeReplace,
- CombineModeIntersect,
- CombineModeUnion,
- CombineModeXor,
- CombineModeExclude,
- CombineModeComplement
- } CombineMode;
- typedef enum {
- UnitWorld,
- UnitDisplay,
- UnitPixel,
- UnitPoint,
- UnitInch,
- UnitDocument,
- UnitMillimeter
- } Unit;
- typedef struct {
- FLOAT X;
- FLOAT Y;
- FLOAT Width;
- FLOAT Height;
- } RectF;
- typedef enum {
- DebugEventLevelFatal,
- DebugEventLevelWarning
- } DebugEventLevel;
- typedef VOID (WINAPI *DebugEventProc)(DebugEventLevel level, CHAR *message);
- typedef struct {
- UINT32 GdiplusVersion;
- DebugEventProc DebugEventCallback;
- BOOL SuppressBackgroundThread;
- BOOL SuppressExternalCodecs;
- } GdiplusStartupInput;
- typedef Status (WINAPI *NotificationHookProc)(OUT ULONG_PTR *token);
- typedef VOID (WINAPI *NotificationUnhookProc)(ULONG_PTR token);
- typedef struct {
- NotificationHookProc NotificationHook;
- NotificationUnhookProc NotificationUnhook;
- } GdiplusStartupOutput;
- /* startup & shutdown */
- Status WINAPI GdiplusStartup(
- OUT ULONG_PTR *token,
- const GdiplusStartupInput *input,
- OUT GdiplusStartupOutput *output);
- VOID WINAPI GdiplusShutdown(ULONG_PTR token);
- /* image */
- GpStatus WINGDIPAPI
- GdipCreateBitmapFromGraphics(INT width,
- INT height,
- GpGraphics* target,
- GpBitmap** bitmap);
- GpStatus WINGDIPAPI
- GdipDisposeImage(GpImage *image);
- GpStatus WINGDIPAPI
- GdipGetImageGraphicsContext(GpImage *image, GpGraphics **graphics);
- GpStatus WINGDIPAPI
- GdipGetImageWidth(GpImage *image, UINT *width);
- GpStatus WINGDIPAPI
- GdipGetImageHeight(GpImage *image, UINT *height);
- GpStatus WINGDIPAPI
- GdipLoadImageFromFile(GDIPCONST WCHAR* filename, GpImage **image);
- GpStatus WINGDIPAPI
- GdipLoadImageFromStream(IStream* stream, GpImage **image);
- /* pen */
- GpStatus WINGDIPAPI
- GdipCreatePen1(ARGB color, REAL width, Unit unit, GpPen **pen);
- GpStatus WINGDIPAPI
- GdipDeletePen(GpPen *pen);
- GpStatus WINGDIPAPI
- GdipSetPenWidth(GpPen *pen, REAL width);
- GpStatus WINGDIPAPI
- GdipSetPenColor(GpPen *pen, ARGB argb);
- /* brush */
- GpStatus WINGDIPAPI
- GdipCreateSolidFill(ARGB color, GpSolidFill **brush);
- GpStatus WINGDIPAPI
- GdipDeleteBrush(GpBrush *brush);
- GpStatus WINGDIPAPI
- GdipSetSolidFillColor(GpSolidFill *brush, ARGB color);
- /* font */
- GpStatus WINGDIPAPI
- GdipCreateFont(
- GDIPCONST GpFontFamily *fontFamily,
- REAL emSize,
- INT style,
- Unit unit,
- GpFont **font
- );
- GpStatus WINGDIPAPI
- GdipDeleteFont(GpFont* font);
- GpStatus WINGDIPAPI
- GdipGetFontSize(GpFont *font, REAL *size);
- GpStatus WINGDIPAPI
- GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name,
- GpFontCollection *fontCollection,
- GpFontFamily **fontFamily);
- GpStatus WINGDIPAPI
- GdipDeleteFontFamily(GpFontFamily *fontFamily);
- GpStatus WINGDIPAPI
- GdipStringFormatGetGenericTypographic(GpStringFormat **format);
- GpStatus WINGDIPAPI
- GdipSetStringFormatFlags(GpStringFormat *format, INT flags);
- GpStatus WINGDIPAPI
- GdipDeleteStringFormat(GpStringFormat *format);
- GpStatus WINGDIPAPI
- GdipPrivateAddMemoryFont(GpFontCollection* fontCollection,
- GDIPCONST void* memory, INT length);
- GpStatus WINGDIPAPI
- GdipPrivateAddFontFile(GpFontCollection* fontCollection,
- GDIPCONST WCHAR* filename);
- GpStatus WINGDIPAPI
- GdipNewPrivateFontCollection(GpFontCollection** fontCollection);
- GpStatus WINGDIPAPI
- GdipDeletePrivateFontCollection(GpFontCollection** fontCollection);
- GpStatus WINGDIPAPI
- GdipGetFontCollectionFamilyList(GpFontCollection* fontCollection,
- INT numSought, GpFontFamily* gpfamilies[], INT* numFound);
- GpStatus WINGDIPAPI
- GdipGetFontCollectionFamilyCount(GpFontCollection* fontCollection, INT* numFound);
- /* graphics */
- GpStatus WINGDIPAPI
- GdipCreateFromHWND(HWND hwnd, GpGraphics **graphics);
- GpStatus WINGDIPAPI
- GdipCreateFromHDC(HDC hdc, GpGraphics **graphics);
- GpStatus WINGDIPAPI
- GdipDeleteGraphics(GpGraphics *graphics);
- GpStatus WINGDIPAPI
- GdipSetSmoothingMode(GpGraphics *graphics, SmoothingMode smoothingMode);
- GpStatus WINGDIPAPI
- GdipSetClipRectI(GpGraphics *graphics, INT x, INT y,
- INT width, INT height, CombineMode combineMode);
- GpStatus WINGDIPAPI
- GdipDrawLineI(GpGraphics *graphics, GpPen *pen, INT x1, INT y1,
- INT x2, INT y2);
- GpStatus WINGDIPAPI
- GdipDrawArcI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
- INT width, INT height, REAL startAngle, REAL sweepAngle);
- GpStatus WINGDIPAPI
- GdipDrawPieI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
- INT width, INT height, REAL startAngle, REAL sweepAngle);
- GpStatus WINGDIPAPI
- GdipFillPieI(GpGraphics *graphics, GpBrush *brush, INT x, INT y,
- INT width, INT height, REAL startAngle, REAL sweepAngle);
- GpStatus WINGDIPAPI
- GdipDrawRectangleI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
- INT width, INT height);
- GpStatus WINGDIPAPI
- GdipFillRectangleI(GpGraphics *graphics, GpBrush *brush, INT x, INT y,
- INT width, INT height);
- GpStatus WINGDIPAPI
- GdipFillPolygonI(GpGraphics *graphics, GpBrush *brush,
- GDIPCONST GpPoint *points, INT count, FillMode fillMode);
- GpStatus WINGDIPAPI
- GdipDrawPolygonI(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points,
- INT count);
- GpStatus WINGDIPAPI
- GdipFillEllipseI(GpGraphics *graphics, GpBrush *brush, INT x, INT y,
- INT width, INT height);
- GpStatus WINGDIPAPI
- GdipDrawEllipseI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
- INT width, INT height);
- GpStatus WINGDIPAPI
- GdipDrawBezierI(GpGraphics *graphics, GpPen *pen, INT x1, INT y1,
- INT x2, INT y2, INT x3, INT y3, INT x4, INT y4);
- GpStatus WINGDIPAPI
- GdipDrawString(
- GpGraphics *graphics,
- GDIPCONST WCHAR *string,
- INT length,
- GDIPCONST GpFont *font,
- GDIPCONST RectF *layoutRect,
- GDIPCONST GpStringFormat *stringFormat,
- GDIPCONST GpBrush *brush
- );
- GpStatus WINGDIPAPI
- GdipGraphicsClear(GpGraphics *graphics, ARGB color);
- GpStatus WINGDIPAPI
- GdipDrawImageI(GpGraphics *graphics, GpImage *image, INT x, INT y);
- GpStatus WINGDIPAPI
- GdipDrawImageRectI(GpGraphics *graphics, GpImage *image, INT x, INT y,
- INT width, INT height);
- GpStatus WINGDIPAPI
- GdipMeasureString(
- GpGraphics *graphics,
- GDIPCONST WCHAR *string,
- INT length,
- GDIPCONST GpFont *font,
- GDIPCONST RectF *layoutRect,
- GDIPCONST GpStringFormat *stringFormat,
- RectF *boundingBox,
- INT *codepointsFitted,
- INT *linesFilled
- );
- GpStatus WINGDIPAPI
- GdipSetTextRenderingHint(GpGraphics *graphics, TextRenderingHint mode);
- LWSTDAPI_(IStream *) SHCreateMemStream(const BYTE *pInit, _In_ UINT cbInit);
- struct GdipFont
- {
- struct nk_user_font nk;
- GpFont* handle;
- };
- static struct {
- ULONG_PTR token;
- GpGraphics *window;
- GpGraphics *memory;
- GpImage *bitmap;
- GpPen *pen;
- GpSolidFill *brush;
- GpStringFormat *format;
- GpFontCollection *fontCollection[10];
- INT curFontCollection;
- struct nk_context ctx;
- } gdip;
- static ARGB convert_color(struct nk_color c)
- {
- return (c.a << 24) | (c.r << 16) | (c.g << 8) | c.b;
- }
- static void
- nk_gdip_scissor(float x, float y, float w, float h)
- {
- GdipSetClipRectI(gdip.memory, (INT)x, (INT)y, (INT)(w + 1), (INT)(h + 1), CombineModeReplace);
- }
- static void
- nk_gdip_stroke_line(short x0, short y0, short x1,
- short y1, unsigned int line_thickness, struct nk_color col)
- {
- GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
- GdipSetPenColor(gdip.pen, convert_color(col));
- GdipDrawLineI(gdip.memory, gdip.pen, x0, y0, x1, y1);
- }
- 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)
- {
- GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
- GdipSetPenColor(gdip.pen, convert_color(col));
- if (r == 0) {
- GdipDrawRectangleI(gdip.memory, gdip.pen, x, y, w, h);
- } else {
- INT d = 2 * r;
- GdipDrawArcI(gdip.memory, gdip.pen, x, y, d, d, 180, 90);
- GdipDrawLineI(gdip.memory, gdip.pen, x + r, y, x + w - r, y);
- GdipDrawArcI(gdip.memory, gdip.pen, x + w - d, y, d, d, 270, 90);
- GdipDrawLineI(gdip.memory, gdip.pen, x + w, y + r, x + w, y + h - r);
- GdipDrawArcI(gdip.memory, gdip.pen, x + w - d, y + h - d, d, d, 0, 90);
- GdipDrawLineI(gdip.memory, gdip.pen, x, y + r, x, y + h - r);
- GdipDrawArcI(gdip.memory, gdip.pen, x, y + h - d, d, d, 90, 90);
- GdipDrawLineI(gdip.memory, gdip.pen, x + r, y + h, x + w - r, y + h);
- }
- }
- static void
- nk_gdip_fill_rect(short x, short y, unsigned short w,
- unsigned short h, unsigned short r, struct nk_color col)
- {
- GdipSetSolidFillColor(gdip.brush, convert_color(col));
- if (r == 0) {
- GdipFillRectangleI(gdip.memory, gdip.brush, x, y, w, h);
- } else {
- INT d = 2 * r;
- GdipFillRectangleI(gdip.memory, gdip.brush, x + r, y, w - d, h);
- GdipFillRectangleI(gdip.memory, gdip.brush, x, y + r, r, h - d);
- GdipFillRectangleI(gdip.memory, gdip.brush, x + w - r, y + r, r, h - d);
- GdipFillPieI(gdip.memory, gdip.brush, x, y, d, d, 180, 90);
- GdipFillPieI(gdip.memory, gdip.brush, x + w - d, y, d, d, 270, 90);
- GdipFillPieI(gdip.memory, gdip.brush, x + w - d, y + h - d, d, d, 0, 90);
- GdipFillPieI(gdip.memory, gdip.brush, x, y + h - d, d, d, 90, 90);
- }
- }
- static BOOL
- SetPoint(POINT *p, LONG x, LONG y)
- {
- if (!p)
- return FALSE;
- p->x = x;
- p->y = y;
- return TRUE;
- }
- static void
- nk_gdip_fill_triangle(short x0, short y0, short x1,
- short y1, short x2, short y2, struct nk_color col)
- {
- POINT points[3];
- SetPoint(&points[0], x0, y0);
- SetPoint(&points[1], x1, y1);
- SetPoint(&points[2], x2, y2);
- GdipSetSolidFillColor(gdip.brush, convert_color(col));
- GdipFillPolygonI(gdip.memory, gdip.brush, points, 3, FillModeAlternate);
- }
- 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)
- {
- POINT points[4];
- SetPoint(&points[0], x0, y0);
- SetPoint(&points[1], x1, y1);
- SetPoint(&points[2], x2, y2);
- SetPoint(&points[3], x0, y0);
- GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
- GdipSetPenColor(gdip.pen, convert_color(col));
- GdipDrawPolygonI(gdip.memory, gdip.pen, points, 4);
- }
- static void
- nk_gdip_fill_polygon(const struct nk_vec2i *pnts, int count, struct nk_color col)
- {
- int i = 0;
- #define MAX_POINTS 64
- POINT points[MAX_POINTS];
- GdipSetSolidFillColor(gdip.brush, convert_color(col));
- for (i = 0; i < count && i < MAX_POINTS; ++i) {
- points[i].x = pnts[i].x;
- points[i].y = pnts[i].y;
- }
- GdipFillPolygonI(gdip.memory, gdip.brush, points, i, FillModeAlternate);
- #undef MAX_POINTS
- }
- static void
- nk_gdip_stroke_polygon(const struct nk_vec2i *pnts, int count,
- unsigned short line_thickness, struct nk_color col)
- {
- GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
- GdipSetPenColor(gdip.pen, convert_color(col));
- if (count > 0) {
- int i;
- for (i = 1; i < count; ++i)
- GdipDrawLineI(gdip.memory, gdip.pen, pnts[i-1].x, pnts[i-1].y, pnts[i].x, pnts[i].y);
- GdipDrawLineI(gdip.memory, gdip.pen, pnts[count-1].x, pnts[count-1].y, pnts[0].x, pnts[0].y);
- }
- }
- static void
- nk_gdip_stroke_polyline(const struct nk_vec2i *pnts,
- int count, unsigned short line_thickness, struct nk_color col)
- {
- GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
- GdipSetPenColor(gdip.pen, convert_color(col));
- if (count > 0) {
- int i;
- for (i = 1; i < count; ++i)
- GdipDrawLineI(gdip.memory, gdip.pen, pnts[i-1].x, pnts[i-1].y, pnts[i].x, pnts[i].y);
- }
- }
- static void
- nk_gdip_fill_circle(short x, short y, unsigned short w,
- unsigned short h, struct nk_color col)
- {
- GdipSetSolidFillColor(gdip.brush, convert_color(col));
- GdipFillEllipseI(gdip.memory, gdip.brush, x, y, w, h);
- }
- static void
- nk_gdip_stroke_circle(short x, short y, unsigned short w,
- unsigned short h, unsigned short line_thickness, struct nk_color col)
- {
- GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
- GdipSetPenColor(gdip.pen, convert_color(col));
- GdipDrawEllipseI(gdip.memory, gdip.pen, x, y, w, h);
- }
- 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)
- {
- GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
- GdipSetPenColor(gdip.pen, convert_color(col));
- GdipDrawBezierI(gdip.memory, gdip.pen, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);
- }
- static void
- nk_gdip_fill_arc(short cx, short cy, unsigned short r, float amin, float adelta, struct nk_color col)
- {
- GdipSetSolidFillColor(gdip.brush, convert_color(col));
- GdipFillPieI(gdip.memory, gdip.brush, cx - r, cy - r, r * 2, r * 2, amin * (180/M_PI), adelta * (180/M_PI));
- }
- static void
- nk_gdip_stroke_arc(short cx, short cy, unsigned short r, float amin, float adelta, unsigned short line_thickness, struct nk_color col)
- {
- GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
- GdipSetPenColor(gdip.pen, convert_color(col));
- GdipDrawPieI(gdip.memory, gdip.pen, cx - r, cy - r, r * 2, r * 2, amin * (180/M_PI), adelta * (180/M_PI));
- }
- 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)
- {
- int wsize;
- WCHAR* wstr;
- RectF layout;
- layout.X = x;
- layout.Y = y;
- layout.Width = w;
- layout.Height = h;
- if(!text || !font || !len) return;
- wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
- wstr = (WCHAR*)_alloca(wsize * sizeof(wchar_t));
- MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize);
- GdipSetSolidFillColor(gdip.brush, convert_color(cfg));
- GdipDrawString(gdip.memory, wstr, wsize, font->handle, &layout, gdip.format, gdip.brush);
- }
- static void
- nk_gdip_draw_image(short x, short y, unsigned short w, unsigned short h,
- struct nk_image img, struct nk_color col)
- {
- GpImage *image = img.handle.ptr;
- GdipDrawImageRectI(gdip.memory, image, x, y, w, h);
- }
- static void
- nk_gdip_clear(struct nk_color col)
- {
- GdipGraphicsClear(gdip.memory, convert_color(col));
- }
- static void
- nk_gdip_blit(GpGraphics *graphics)
- {
- GdipDrawImageI(graphics, gdip.bitmap, 0, 0);
- }
- static struct nk_image
- nk_gdip_image_to_nk(GpImage *image) {
- struct nk_image img;
- UINT uwidth, uheight;
- img = nk_image_ptr( (void*)image );
- GdipGetImageHeight(image, &uheight);
- GdipGetImageWidth(image, &uwidth);
- img.h = uheight;
- img.w = uwidth;
- return img;
- }
- struct nk_image
- nk_gdip_load_image_from_file(const WCHAR *filename)
- {
- GpImage *image;
- if (GdipLoadImageFromFile(filename, &image))
- return nk_image_id(0);
- return nk_gdip_image_to_nk(image);
- }
- struct nk_image
- nk_gdip_load_image_from_memory(const void *membuf, nk_uint membufSize)
- {
- GpImage* image;
- GpStatus status;
- IStream *stream = SHCreateMemStream((const BYTE*)membuf, membufSize);
- if (!stream)
- return nk_image_id(0);
- status = GdipLoadImageFromStream(stream, &image);
- stream->lpVtbl->Release(stream);
- if (status)
- return nk_image_id(0);
- return nk_gdip_image_to_nk(image);
- }
- void
- nk_gdip_image_free(struct nk_image image)
- {
- if (!image.handle.ptr)
- return;
- GdipDisposeImage(image.handle.ptr);
- }
- GdipFont*
- nk_gdipfont_create(const char *name, int size)
- {
- GdipFont *font = (GdipFont*)calloc(1, sizeof(GdipFont));
- GpFontFamily *family;
- int wsize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
- WCHAR* wname = (WCHAR*)_alloca((wsize + 1) * sizeof(wchar_t));
- MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, wsize);
- wname[wsize] = 0;
- GdipCreateFontFamilyFromName(wname, NULL, &family);
- GdipCreateFont(family, (REAL)size, FontStyleRegular, UnitPixel, &font->handle);
- GdipDeleteFontFamily(family);
- return font;
- }
- GpFontCollection*
- nk_gdip_getCurFontCollection(){
- return gdip.fontCollection[gdip.curFontCollection];
- }
- GdipFont*
- nk_gdipfont_create_from_collection(int size){
- GpFontFamily **families;
- INT count;
- GdipFont *font = (GdipFont*)calloc(1, sizeof(GdipFont));
- if( GdipGetFontCollectionFamilyCount(nk_gdip_getCurFontCollection(), &count) ) return NULL;
- families = (GpFontFamily**)calloc(1, sizeof(GpFontFamily*));
- if( !families ) return NULL;
- if( GdipGetFontCollectionFamilyList(nk_gdip_getCurFontCollection(), count, families, &count) ) return NULL;
- if( count < 1 ) return NULL;
- if( GdipCreateFont(families[count-1], (REAL)size, FontStyleRegular, UnitPixel, &font->handle) ) return NULL;
- free(families);
- gdip.curFontCollection++;
- return font;
- }
- GdipFont*
- nk_gdipfont_create_from_memory(const void* membuf, int membufSize, int size)
- {
- if( !nk_gdip_getCurFontCollection() )
- if( GdipNewPrivateFontCollection(&gdip.fontCollection[gdip.curFontCollection]) ) return NULL;
- if( GdipPrivateAddMemoryFont(nk_gdip_getCurFontCollection(), membuf, membufSize) ) return NULL;
- return nk_gdipfont_create_from_collection(size);
- }
- GdipFont*
- nk_gdipfont_create_from_file(const WCHAR* filename, int size)
- {
- if( !nk_gdip_getCurFontCollection() )
- if( GdipNewPrivateFontCollection(&gdip.fontCollection[gdip.curFontCollection]) ) return NULL;
- if( GdipPrivateAddFontFile(nk_gdip_getCurFontCollection(), filename) ) return NULL;
- return nk_gdipfont_create_from_collection(size);
- }
- static float
- nk_gdipfont_get_text_width(nk_handle handle, float height, const char *text, int len)
- {
- GdipFont *font = (GdipFont *)handle.ptr;
- RectF layout = { 0.0f, 0.0f, 65536.0f, 65536.0f };
- RectF bbox;
- int wsize;
- WCHAR* wstr;
- if (!font || !text)
- return 0;
- (void)height;
- wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
- wstr = (WCHAR*)_malloca(wsize * sizeof(wchar_t));
- MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize);
- GdipMeasureString(gdip.memory, wstr, wsize, font->handle, &layout, gdip.format, &bbox, NULL, NULL);
- return bbox.Width;
- }
- void
- nk_gdipfont_del(GdipFont *font)
- {
- if(!font) return;
- GdipDeleteFont(font->handle);
- free(font);
- }
- static void
- nk_gdip_clipboard_paste(nk_handle usr, struct nk_text_edit* edit)
- {
- (void)usr;
- if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL))
- {
- HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
- if (mem)
- {
- SIZE_T size = GlobalSize(mem) - 1;
- if (size)
- {
- LPCWSTR wstr = (LPCWSTR)GlobalLock(mem);
- if (wstr)
- {
- int utf8size = WideCharToMultiByte(CP_UTF8, 0, wstr, (int)(size / sizeof(wchar_t)), NULL, 0, NULL, NULL);
- if (utf8size)
- {
- char* utf8 = (char*)malloc(utf8size);
- if (utf8)
- {
- WideCharToMultiByte(CP_UTF8, 0, wstr, (int)(size / sizeof(wchar_t)), utf8, utf8size, NULL, NULL);
- nk_textedit_paste(edit, utf8, utf8size);
- free(utf8);
- }
- }
- GlobalUnlock(mem);
- }
- }
- }
- CloseClipboard();
- }
- }
- static void
- nk_gdip_clipboard_copy(nk_handle usr, const char* text, int len)
- {
- if (OpenClipboard(NULL))
- {
- int wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
- if (wsize)
- {
- HGLOBAL mem = (HGLOBAL)GlobalAlloc(GMEM_MOVEABLE, (wsize + 1) * sizeof(wchar_t));
- if (mem)
- {
- wchar_t* wstr = (wchar_t*)GlobalLock(mem);
- if (wstr)
- {
- MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize);
- wstr[wsize] = 0;
- GlobalUnlock(mem);
- SetClipboardData(CF_UNICODETEXT, mem);
- }
- }
- }
- CloseClipboard();
- }
- }
- NK_API struct nk_context*
- nk_gdip_init(HWND hwnd, unsigned int width, unsigned int height)
- {
- int i;
- GdiplusStartupInput startup = { 1, NULL, FALSE, TRUE };
- GdiplusStartup(&gdip.token, &startup, NULL);
- GdipCreateFromHWND(hwnd, &gdip.window);
- GdipCreateBitmapFromGraphics(width, height, gdip.window, &gdip.bitmap);
- GdipGetImageGraphicsContext(gdip.bitmap, &gdip.memory);
- GdipCreatePen1(0, 1.0f, UnitPixel, &gdip.pen);
- GdipCreateSolidFill(0, &gdip.brush);
- GdipStringFormatGetGenericTypographic(&gdip.format);
- GdipSetStringFormatFlags(gdip.format, StringFormatFlagsNoFitBlackBox |
- StringFormatFlagsMeasureTrailingSpaces | StringFormatFlagsNoWrap |
- StringFormatFlagsNoClip);
- for(i=0; i< sizeof(gdip.fontCollection)/sizeof(gdip.fontCollection[0]); i++)
- gdip.fontCollection[i] = NULL;
- nk_init_default(&gdip.ctx, NULL);
- gdip.ctx.clip.copy = nk_gdip_clipboard_copy;
- gdip.ctx.clip.paste = nk_gdip_clipboard_paste;
- gdip.curFontCollection = 0;
- return &gdip.ctx;
- }
- NK_API void
- nk_gdip_set_font(GdipFont *gdipfont)
- {
- struct nk_user_font *font = &gdipfont->nk;
- font->userdata = nk_handle_ptr(gdipfont);
- GdipGetFontSize(gdipfont->handle, &font->height);
- font->width = nk_gdipfont_get_text_width;
- nk_style_set_font(&gdip.ctx, font);
- }
- NK_API int
- nk_gdip_handle_event(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
- {
- static int insert_toggle = 0;
- switch (msg)
- {
- case WM_SIZE:
- if (gdip.window)
- {
- unsigned int width = LOWORD(lparam);
- unsigned int height = HIWORD(lparam);
- GdipDeleteGraphics(gdip.window);
- GdipDeleteGraphics(gdip.memory);
- GdipDisposeImage(gdip.bitmap);
- GdipCreateFromHWND(wnd, &gdip.window);
- GdipCreateBitmapFromGraphics(width, height, gdip.window, &gdip.bitmap);
- GdipGetImageGraphicsContext(gdip.bitmap, &gdip.memory);
- }
- break;
- case WM_PAINT:
- {
- PAINTSTRUCT paint;
- HDC dc = BeginPaint(wnd, &paint);
- GpGraphics *graphics;
- GdipCreateFromHDC(dc, &graphics);
- nk_gdip_blit(graphics);
- GdipDeleteGraphics(graphics);
- EndPaint(wnd, &paint);
- return 1;
- }
- case WM_KEYDOWN:
- case WM_KEYUP:
- case WM_SYSKEYDOWN:
- case WM_SYSKEYUP:
- {
- int down = !((lparam >> 31) & 1);
- int ctrl = GetKeyState(VK_CONTROL) & (1 << 15);
- switch (wparam)
- {
- case VK_SHIFT:
- case VK_LSHIFT:
- case VK_RSHIFT:
- nk_input_key(&gdip.ctx, NK_KEY_SHIFT, down);
- return 1;
- case VK_DELETE:
- nk_input_key(&gdip.ctx, NK_KEY_DEL, down);
- return 1;
- case VK_RETURN:
- case VK_SEPARATOR:
- nk_input_key(&gdip.ctx, NK_KEY_ENTER, down);
- return 1;
- case VK_TAB:
- nk_input_key(&gdip.ctx, NK_KEY_TAB, down);
- return 1;
- case VK_LEFT:
- if (ctrl)
- nk_input_key(&gdip.ctx, NK_KEY_TEXT_WORD_LEFT, down);
- else
- nk_input_key(&gdip.ctx, NK_KEY_LEFT, down);
- return 1;
- case VK_RIGHT:
- if (ctrl)
- nk_input_key(&gdip.ctx, NK_KEY_TEXT_WORD_RIGHT, down);
- else
- nk_input_key(&gdip.ctx, NK_KEY_RIGHT, down);
- return 1;
- case VK_BACK:
- nk_input_key(&gdip.ctx, NK_KEY_BACKSPACE, down);
- return 1;
- case VK_HOME:
- nk_input_key(&gdip.ctx, NK_KEY_TEXT_START, down);
- nk_input_key(&gdip.ctx, NK_KEY_SCROLL_START, down);
- return 1;
- case VK_END:
- nk_input_key(&gdip.ctx, NK_KEY_TEXT_END, down);
- nk_input_key(&gdip.ctx, NK_KEY_SCROLL_END, down);
- return 1;
- case VK_NEXT:
- nk_input_key(&gdip.ctx, NK_KEY_SCROLL_DOWN, down);
- return 1;
- case VK_PRIOR:
- nk_input_key(&gdip.ctx, NK_KEY_SCROLL_UP, down);
- return 1;
- case VK_ESCAPE:
- nk_input_key(&gdip.ctx, NK_KEY_TEXT_RESET_MODE, down);
- return 1;
- case VK_INSERT:
- /* Only switch on release to avoid repeat issues
- * kind of confusing since we have to negate it but we're already
- * hacking it since Nuklear treats them as two separate keys rather
- * than a single toggle state */
- if (!down) {
- insert_toggle = !insert_toggle;
- if (insert_toggle) {
- nk_input_key(&gdip.ctx, NK_KEY_TEXT_INSERT_MODE, !down);
- /* nk_input_key(&gdip.ctx, NK_KEY_TEXT_REPLACE_MODE, down); */
- } else {
- nk_input_key(&gdip.ctx, NK_KEY_TEXT_REPLACE_MODE, !down);
- /* nk_input_key(&gdip.ctx, NK_KEY_TEXT_INSERT_MODE, down); */
- }
- }
- return 1;
- case 'A':
- if (ctrl) {
- nk_input_key(&gdip.ctx, NK_KEY_TEXT_SELECT_ALL, down);
- return 1;
- }
- break;
- case 'B':
- if (ctrl) {
- nk_input_key(&gdip.ctx, NK_KEY_TEXT_LINE_START, down);
- return 1;
- }
- break;
- case 'E':
- if (ctrl) {
- nk_input_key(&gdip.ctx, NK_KEY_TEXT_LINE_END, down);
- return 1;
- }
- break;
- case 'C':
- if (ctrl) {
- nk_input_key(&gdip.ctx, NK_KEY_COPY, down);
- return 1;
- }
- break;
- case 'V':
- if (ctrl) {
- nk_input_key(&gdip.ctx, NK_KEY_PASTE, down);
- return 1;
- }
- break;
- case 'X':
- if (ctrl) {
- nk_input_key(&gdip.ctx, NK_KEY_CUT, down);
- return 1;
- }
- break;
- case 'Z':
- if (ctrl) {
- nk_input_key(&gdip.ctx, NK_KEY_TEXT_UNDO, down);
- return 1;
- }
- break;
- case 'R':
- if (ctrl) {
- nk_input_key(&gdip.ctx, NK_KEY_TEXT_REDO, down);
- return 1;
- }
- break;
- }
- return 0;
- }
- case WM_CHAR:
- if (wparam >= 32)
- {
- nk_input_unicode(&gdip.ctx, (nk_rune)wparam);
- return 1;
- }
- break;
- case WM_LBUTTONDOWN:
- nk_input_button(&gdip.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
- SetCapture(wnd);
- return 1;
- case WM_LBUTTONUP:
- nk_input_button(&gdip.ctx, NK_BUTTON_DOUBLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
- nk_input_button(&gdip.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
- ReleaseCapture();
- return 1;
- case WM_RBUTTONDOWN:
- nk_input_button(&gdip.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
- SetCapture(wnd);
- return 1;
- case WM_RBUTTONUP:
- nk_input_button(&gdip.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
- ReleaseCapture();
- return 1;
- case WM_MBUTTONDOWN:
- nk_input_button(&gdip.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
- SetCapture(wnd);
- return 1;
- case WM_MBUTTONUP:
- nk_input_button(&gdip.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
- ReleaseCapture();
- return 1;
- case WM_MOUSEWHEEL:
- nk_input_scroll(&gdip.ctx, nk_vec2(0,(float)(short)HIWORD(wparam) / WHEEL_DELTA));
- return 1;
- case WM_MOUSEMOVE:
- nk_input_motion(&gdip.ctx, (short)LOWORD(lparam), (short)HIWORD(lparam));
- return 1;
- case WM_LBUTTONDBLCLK:
- nk_input_button(&gdip.ctx, NK_BUTTON_DOUBLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
- return 1;
- }
- return 0;
- }
- NK_API void
- nk_gdip_shutdown(void)
- {
- int i;
- for(i=0; i< gdip.curFontCollection; i++)
- GdipDeletePrivateFontCollection( &gdip.fontCollection[i] );
- GdipDeleteGraphics(gdip.window);
- GdipDeleteGraphics(gdip.memory);
- GdipDisposeImage(gdip.bitmap);
- GdipDeletePen(gdip.pen);
- GdipDeleteBrush(gdip.brush);
- GdipDeleteStringFormat(gdip.format);
- GdiplusShutdown(gdip.token);
- nk_free(&gdip.ctx);
- }
- NK_API void
- nk_gdip_prerender_gui(enum nk_anti_aliasing AA)
- {
- const struct nk_command *cmd;
- GdipSetTextRenderingHint(gdip.memory, AA != NK_ANTI_ALIASING_OFF ?
- TextRenderingHintClearTypeGridFit : TextRenderingHintSingleBitPerPixelGridFit);
- GdipSetSmoothingMode(gdip.memory, AA != NK_ANTI_ALIASING_OFF ?
- SmoothingModeHighQuality : SmoothingModeNone);
- nk_foreach(cmd, &gdip.ctx)
- {
- switch (cmd->type) {
- case NK_COMMAND_NOP: break;
- case NK_COMMAND_SCISSOR: {
- const struct nk_command_scissor *s =(const struct nk_command_scissor*)cmd;
- nk_gdip_scissor(s->x, s->y, s->w, s->h);
- } break;
- case NK_COMMAND_LINE: {
- const struct nk_command_line *l = (const struct nk_command_line *)cmd;
- nk_gdip_stroke_line(l->begin.x, l->begin.y, l->end.x,
- l->end.y, l->line_thickness, l->color);
- } break;
- case NK_COMMAND_RECT: {
- const struct nk_command_rect *r = (const struct nk_command_rect *)cmd;
- nk_gdip_stroke_rect(r->x, r->y, r->w, r->h,
- (unsigned short)r->rounding, r->line_thickness, r->color);
- } break;
- case NK_COMMAND_RECT_FILLED: {
- const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled *)cmd;
- nk_gdip_fill_rect(r->x, r->y, r->w, r->h,
- (unsigned short)r->rounding, r->color);
- } break;
- case NK_COMMAND_CIRCLE: {
- const struct nk_command_circle *c = (const struct nk_command_circle *)cmd;
- nk_gdip_stroke_circle(c->x, c->y, c->w, c->h, c->line_thickness, c->color);
- } break;
- case NK_COMMAND_CIRCLE_FILLED: {
- const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
- nk_gdip_fill_circle(c->x, c->y, c->w, c->h, c->color);
- } break;
- case NK_COMMAND_TRIANGLE: {
- const struct nk_command_triangle*t = (const struct nk_command_triangle*)cmd;
- nk_gdip_stroke_triangle(t->a.x, t->a.y, t->b.x, t->b.y,
- t->c.x, t->c.y, t->line_thickness, t->color);
- } break;
- case NK_COMMAND_TRIANGLE_FILLED: {
- const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled *)cmd;
- nk_gdip_fill_triangle(t->a.x, t->a.y, t->b.x, t->b.y,
- t->c.x, t->c.y, t->color);
- } break;
- case NK_COMMAND_POLYGON: {
- const struct nk_command_polygon *p =(const struct nk_command_polygon*)cmd;
- nk_gdip_stroke_polygon(p->points, p->point_count, p->line_thickness,p->color);
- } break;
- case NK_COMMAND_POLYGON_FILLED: {
- const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled *)cmd;
- nk_gdip_fill_polygon(p->points, p->point_count, p->color);
- } break;
- case NK_COMMAND_POLYLINE: {
- const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd;
- nk_gdip_stroke_polyline(p->points, p->point_count, p->line_thickness, p->color);
- } break;
- case NK_COMMAND_TEXT: {
- const struct nk_command_text *t = (const struct nk_command_text*)cmd;
- nk_gdip_draw_text(t->x, t->y, t->w, t->h,
- (const char*)t->string, t->length,
- (GdipFont*)t->font->userdata.ptr,
- t->background, t->foreground);
- } break;
- case NK_COMMAND_CURVE: {
- const struct nk_command_curve *q = (const struct nk_command_curve *)cmd;
- nk_gdip_stroke_curve(q->begin, q->ctrl[0], q->ctrl[1],
- q->end, q->line_thickness, q->color);
- } break;
- case NK_COMMAND_IMAGE: {
- const struct nk_command_image *i = (const struct nk_command_image *)cmd;
- nk_gdip_draw_image(i->x, i->y, i->w, i->h, i->img, i->col);
- } break;
- case NK_COMMAND_ARC: {
- const struct nk_command_arc *i = (const struct nk_command_arc *)cmd;
- nk_gdip_stroke_arc(i->cx, i->cy, i->r, i->a[0], i->a[1], i->line_thickness, i->color);
- } break;
- case NK_COMMAND_ARC_FILLED: {
- const struct nk_command_arc_filled *i = (const struct nk_command_arc_filled *)cmd;
- nk_gdip_fill_arc(i->cx, i->cy, i->r, i->a[0], i->a[1], i->color);
- } break;
- case NK_COMMAND_RECT_MULTI_COLOR:
- default: break;
- }
- }
- }
- NK_API void
- nk_gdip_render_gui(enum nk_anti_aliasing AA)
- {
- nk_gdip_prerender_gui(AA);
- nk_gdip_blit(gdip.window);
- nk_clear(&gdip.ctx);
- }
- NK_API void
- nk_gdip_render(enum nk_anti_aliasing AA, struct nk_color clear)
- {
- nk_gdip_clear(clear);
- nk_gdip_render_gui(AA);
- }
- #endif
|