1 #include <stdlib.h>
2 #include <string.h>
3 
4 #define WIN32_MEAN_AND_LEAN
5 #include <windows.h>
6 #include "gdiplus.h"
7 
8 #include <ui/font.h>
9 
10 #include <nuklear.h>
11 
12 #include "canvas.h"
13 #include "display.h"
14 #include "font.h"
15 
16 extern struct ui_display display;
17 
18 struct ui_font *
ui_create_font(const char * name,int size,int flags)19 ui_create_font(const char *name, int size, int flags)
20 {
21 	struct ui_font *font;
22 	GpFontFamily *family;
23 	WCHAR *wname;
24 	int wlen;
25 	enum FontStyle style;
26 
27 	font = calloc(1, sizeof *font);
28 
29 	if (!font)
30 		return NULL;
31 
32 	wlen = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
33 	wname = (WCHAR *)_alloca((wlen + 1) * sizeof *wname);
34 	MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, wlen);
35 	wname[wlen] = 0;
36 
37 	if ((flags & (UI_FONT_BOLD | UI_FONT_ITALIC)) ==
38 		(UI_FONT_BOLD | UI_FONT_ITALIC)) {
39 		style = FontStyleBoldItalic;
40 	} else if (flags & UI_FONT_BOLD) {
41 		style = FontStyleBold;
42 	} else if (flags & UI_FONT_ITALIC) {
43 		style = FontStyleItalic;
44 	} else if (flags & UI_FONT_ULINE) {
45 		style = FontStyleUnderline;
46 	} else {
47 		style = FontStyleRegular;
48 	}
49 
50 	GdipCreateFontFamilyFromName(wname, NULL, &family);
51 	GdipCreateFont(family, (REAL)size, style, UnitPixel,
52 		&font->ft);
53 	GdipDeleteFontFamily(family);
54 
55 	font->handle.userdata = nk_handle_ptr(font);
56 	GdipGetFontSize(font->ft, &font->handle.height);
57 	font->handle.width = ui_get_text_width;
58 
59 	return font;
60 }
61 
62 void
ui_set_font(struct nk_context * ctx,struct ui_font * font)63 ui_set_font(struct nk_context *ctx, struct ui_font *font)
64 {
65 	struct ui_canvas *canvas = ctx->userdata.ptr;
66 
67 	font->canvas = canvas;
68 
69 	nk_style_set_font(ctx, &font->handle);
70 }
71 
72 float
ui_get_text_width(nk_handle handle,float height,const char * text,int len)73 ui_get_text_width(nk_handle handle, float height, const char *text, int len)
74 {
75 	struct ui_font *font = (struct ui_font *)handle.ptr;
76 	struct ui_canvas *canvas = font->canvas;
77 	RectF layout = { 0.0f, 0.0f, 65536.0f, 65536.0f };
78 	RectF bbox;
79 	WCHAR *wstr;
80 	int wlen;
81 
82 	if (!font || !text)
83 		return 0;
84 
85 	(void)height;
86 	wlen = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
87 	wstr = (WCHAR *)_alloca(wlen * sizeof *wstr);
88 	MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wlen);
89 
90 	GdipMeasureString(canvas->memory, wstr, wlen, font->ft, &layout,
91 		canvas->format, &bbox, NULL, NULL);
92 
93 	return bbox.Width;
94 }
95