1 /*
2  * Copyright (c) 2018-2019 Hanspeter Portner (dev@open-music-kontrollers.ch)
3  *
4  * This is free software: you can redistribute it and/or modify
5  * it under the terms of the Artistic License 2.0 as published by
6  * The Perl Foundation.
7  *
8  * This source is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * Artistic License 2.0 for more details.
12  *
13  * You should have received a copy of the Artistic License 2.0
14  * along the source as a COPYING file. If not, obtain it from
15  * http://www.perlfoundation.org/artistic_license_2_0.
16  */
17 
18 #ifndef _D2TK_CORE_H
19 #define _D2TK_CORE_H
20 
21 #include <stdint.h>
22 #include <stdbool.h>
23 #include <stdlib.h>
24 
25 #include "config.h"
26 #include <d2tk/d2tk.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 typedef int32_t d2tk_coord_t;
33 typedef struct _d2tk_rect_t d2tk_rect_t;
34 typedef struct _d2tk_widget_t d2tk_widget_t;
35 typedef struct _d2tk_point_t d2tk_point_t;
36 typedef struct _d2tk_core_t d2tk_core_t;
37 typedef struct _d2tk_core_driver_t d2tk_core_driver_t;
38 typedef void (*d2tk_core_custom_t)(void *ctx, const d2tk_rect_t *rect,
39 	const void *data);
40 
41 typedef enum _d2tk_align_t {
42 	D2TK_ALIGN_NONE 				= 0,
43 	D2TK_ALIGN_LEFT					= (1 << 0),
44 	D2TK_ALIGN_CENTER				= (1 << 1),
45 	D2TK_ALIGN_RIGHT				= (1 << 2),
46 	D2TK_ALIGN_TOP					= (1 << 3),
47 	D2TK_ALIGN_MIDDLE				= (1 << 4),
48 	D2TK_ALIGN_BOTTOM				= (1 << 5)
49 } d2tk_align_t;
50 
51 #define D2TK_ALIGN_CENTERED (D2TK_ALIGN_CENTER | D2TK_ALIGN_MIDDLE)
52 
53 struct _d2tk_rect_t {
54 	d2tk_coord_t x;
55 	d2tk_coord_t y;
56 	d2tk_coord_t w;
57 	d2tk_coord_t h;
58 };
59 
60 struct _d2tk_point_t {
61 	d2tk_coord_t x;
62 	d2tk_coord_t y;
63 };
64 
65 #define D2TK_RECT(X, Y, W, H) \
66 	((d2tk_rect_t){ .x = (X), .y = (Y), .w = (W), .h = (H) })
67 
68 #define D2TK_POINT(X, Y) \
69 	((d2tk_point_t){ .x = (X), .y = (Y) })
70 
71 extern const size_t d2tk_widget_sz;
72 
73 D2TK_API void
74 d2tk_rect_shrink_x(d2tk_rect_t *dst, const d2tk_rect_t *src,
75 	d2tk_coord_t brd);
76 
77 D2TK_API void
78 d2tk_rect_shrink_y(d2tk_rect_t *dst, const d2tk_rect_t *src,
79 	d2tk_coord_t brd);
80 
81 D2TK_API void
82 d2tk_rect_shrink(d2tk_rect_t *dst, const d2tk_rect_t *src,
83 	d2tk_coord_t brd);
84 
85 D2TK_API void
86 d2tk_core_move_to(d2tk_core_t *core, d2tk_coord_t x, d2tk_coord_t y);
87 
88 D2TK_API void
89 d2tk_core_line_to(d2tk_core_t *core, d2tk_coord_t x, d2tk_coord_t y);
90 
91 D2TK_API void
92 d2tk_core_rect(d2tk_core_t *core, const d2tk_rect_t *rect);
93 
94 D2TK_API void
95 d2tk_core_rounded_rect(d2tk_core_t *core, const d2tk_rect_t *rect,
96 	d2tk_coord_t r);
97 
98 D2TK_API void
99 d2tk_core_arc(d2tk_core_t *core, d2tk_coord_t x, d2tk_coord_t y, d2tk_coord_t r,
100 	d2tk_coord_t a, d2tk_coord_t b, bool cw);
101 
102 D2TK_API void
103 d2tk_core_curve_to(d2tk_core_t *core, d2tk_coord_t x1, d2tk_coord_t y1,
104 	d2tk_coord_t x2, d2tk_coord_t y2, d2tk_coord_t x3, d2tk_coord_t y3);
105 
106 D2TK_API void
107 d2tk_core_color(d2tk_core_t *core, uint32_t rgba);
108 
109 D2TK_API void
110 d2tk_core_linear_gradient(d2tk_core_t *core, const d2tk_point_t point [2],
111 	const uint32_t rgba [2]);
112 
113 D2TK_API void
114 d2tk_core_stroke(d2tk_core_t *core);
115 
116 D2TK_API void
117 d2tk_core_fill(d2tk_core_t *core);
118 
119 D2TK_API void
120 d2tk_core_save(d2tk_core_t *core);
121 
122 D2TK_API void
123 d2tk_core_restore(d2tk_core_t *core);
124 
125 D2TK_API void
126 d2tk_core_rotate(d2tk_core_t *core, d2tk_coord_t deg);
127 
128 D2TK_API d2tk_widget_t *
129 d2tk_core_widget_begin(d2tk_core_t *core, uint64_t hash, d2tk_widget_t *widget);
130 
131 D2TK_API bool
132 d2tk_core_widget_not_end(d2tk_core_t *core, d2tk_widget_t *widget);
133 
134 D2TK_API d2tk_widget_t *
135 d2tk_core_widget_next(d2tk_core_t *core, d2tk_widget_t *widget);
136 
137 #define D2TK_CORE_WIDGET(CORE, HASH, WIDGET) \
138 	for(d2tk_widget_t *(WIDGET) = d2tk_core_widget_begin((CORE), (HASH), \
139 			alloca(d2tk_widget_sz)); \
140 		d2tk_core_widget_not_end((CORE), (WIDGET)); \
141 		(WIDGET) = d2tk_core_widget_next((CORE), (WIDGET)))
142 
143 D2TK_API ssize_t
144 d2tk_core_bbox_push(d2tk_core_t *core, bool cached, const d2tk_rect_t *rect);
145 
146 D2TK_API ssize_t
147 d2tk_core_bbox_container_push(d2tk_core_t *core, bool cached,
148 	const d2tk_rect_t *rect);
149 
150 D2TK_API void
151 d2tk_core_bbox_pop(d2tk_core_t *core, ssize_t ref);
152 
153 D2TK_API void
154 d2tk_core_begin_path(d2tk_core_t *core);
155 
156 D2TK_API void
157 d2tk_core_close_path(d2tk_core_t *core);
158 
159 D2TK_API void
160 d2tk_core_scissor(d2tk_core_t *core, const d2tk_rect_t *rect);
161 
162 D2TK_API void
163 d2tk_core_reset_scissor(d2tk_core_t *core);
164 
165 D2TK_API void
166 d2tk_core_font_size(d2tk_core_t *core, d2tk_coord_t size);
167 
168 D2TK_API void
169 d2tk_core_font_face(d2tk_core_t *core, size_t sz, const char *face);
170 
171 D2TK_API void
172 d2tk_core_text(d2tk_core_t *core, const d2tk_rect_t *rect, size_t sz,
173 	const char *text, d2tk_align_t align);
174 
175 D2TK_API void
176 d2tk_core_image(d2tk_core_t *core, const d2tk_rect_t *rect, size_t sz,
177 	const char *path, d2tk_align_t align);
178 
179 D2TK_API void
180 d2tk_core_bitmap(d2tk_core_t *core, const d2tk_rect_t *rect, uint32_t w,
181 	uint32_t h, uint32_t stride, const uint32_t *argb, uint64_t rev,
182 	d2tk_align_t align);
183 
184 D2TK_API void
185 d2tk_core_custom(d2tk_core_t *core, const d2tk_rect_t *rect, uint64_t dhash,
186 	const void *data, d2tk_core_custom_t custom);
187 
188 D2TK_API void
189 d2tk_core_stroke_width(d2tk_core_t *core, d2tk_coord_t width);
190 
191 D2TK_API int
192 d2tk_core_pre(d2tk_core_t *core, void *pctx);
193 
194 D2TK_API void
195 d2tk_core_post(d2tk_core_t *core);
196 
197 D2TK_API d2tk_core_t *
198 d2tk_core_new(const d2tk_core_driver_t *driver, void *data);
199 
200 D2TK_API void
201 d2tk_core_set_ttls(d2tk_core_t *core, uint32_t sprites, uint32_t memcaches);
202 
203 D2TK_API void
204 d2tk_core_free(d2tk_core_t *core);
205 
206 D2TK_API void
207 d2tk_core_set_dimensions(d2tk_core_t *core, d2tk_coord_t w, d2tk_coord_t h);
208 
209 D2TK_API void
210 d2tk_core_get_dimensions(d2tk_core_t *core, d2tk_coord_t *w, d2tk_coord_t *h);
211 
212 D2TK_API void
213 d2tk_core_set_full_refresh(d2tk_core_t *core);
214 
215 D2TK_API int
216 d2tk_core_text_extent(d2tk_core_t *core, size_t len, const char *buf,
217 	d2tk_coord_t h);
218 
219 #ifdef __cplusplus
220 }
221 #endif
222 
223 #endif // _D2TK_CORE_H
224