libwebsockets
Lightweight C library for HTML5 websockets
lws-dlo.h
Go to the documentation of this file.
1 /*
2  * lws abstract display
3  *
4  * Copyright (C) 2019 - 2022 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  *
24  * lws display_list and display_list objects (dlo)
25  */
26 
27 #include <stdint.h>
28 
30 struct lws_surface_info;
31 struct lws_display_state;
32 struct lws_display_font;
33 struct lws_dlo_text;
34 struct lws_display;
35 struct lws_dlo_text;
36 struct lws_dlo;
37 
38 #define LWSDC_RGBA(_r, _g, _b, _a) (((uint32_t)(_r) & 0xff) |
39  (((uint32_t)(_g) & 0xff) << 8) |
40  (((uint32_t)(_b) & 0xff) << 16) |
41  (((uint32_t)(_a) & 0xff) << 24))
42 
43 #define LWSDC_R(_c) ((_c) & 0xff)
44 #define LWSDC_G(_c) ((_c >> 8) & 0xff)
45 #define LWSDC_B(_c) ((_c >> 16) & 0xff)
46 #define LWSDC_ALPHA(_c) ((_c >> 24) & 0xff)
47 
48 #define RGB_TO_Y(_r, _g, _b) ((((_r) * 299) + ((_g) * 587) + ((_b) * 114)) / 1000)
49 /* stores Y in RGBY */
50 #define PALETTE_RGBY(_r, _g, _b) LWSDC_RGBA(_r, _g, _b, (RGB_TO_Y(_r, _g, _b)))
51 
52 typedef struct {
55 } lws_dlo_dim_t;
56 
57 /*
58  * When using RGBA to describe native greyscale, R is Y and A is A, GB is ignored
59  */
60 
61 /* composed at start of larger, font-specific glyph struct */
62 
63 typedef struct lws_font_glyph {
65 
70 
71  int8_t x; /* x offset inside the glyph */
72 
73 } lws_font_glyph_t;
74 
75 typedef lws_stateful_ret_t (*lws_dlo_renderer_t)(struct lws_display_render_state *rs);
76 typedef lws_font_glyph_t * (*lws_dlo_image_glyph_t)(
77  struct lws_dlo_text *text,
78  uint32_t unicode, char attach);
79 typedef void (*lws_dlo_destroy_t)(struct lws_dlo *dlo);
80 
81 typedef struct lws_display_id {
83 
84  char id[16];
85  lws_box_t box; /* taken from DLO after layout */
86 
87  void *priv_user;
88  void *priv_driver;
89 
90  char exists;
91  char iframe; /* 1 = render html as if partial
92  * is the origin, otherwise
93  * render html with surface
94  * (0,0) as origin and rs->box
95  * is a viewport on to that */
96 } lws_display_id_t;
97 
98 /*
99  * Common dlo object that joins the display list, composed into a subclass
100  * object like lws_dlo_rect_t etc
101  */
102 
103 typedef struct lws_dlo {
105 
106  lws_dll2_t col_list; /* lws_dlo_t: column-mates */
107  lws_dll2_t row_list; /* lws_dlo_t: row-mates */
108 
109  /* children are rendered "inside" the parent DLO box after allowing
110  * for parent padding */
112 
113  /* only used for dlo rect representing whole table */
114 
115  lws_dll2_owner_t table_cols; /* lhp_table_col_t */
116  lws_dll2_owner_t table_rows; /* lhp_table_row_t */
117 
118  /* may point to dlo whose width or height decides our x or y */
119 
120  struct lws_dlo *abut_x;
121  struct lws_dlo *abut_y;
122 
123  lws_dlo_destroy_t _destroy; /* dlo-type specific cb */
124  lws_dlo_renderer_t render; /* dlo-type specific cb */
125 
127  lws_fx_t padding[4]; /* child origin */
128 
129  lws_display_id_t *id; /* only valid until ids destroyed */
130 
133 
134  uint8_t flag_runon:1; /* continues same line */
135  uint8_t flag_done_align:1;
136  uint8_t flag_toplevel:1; /* don't scan up with me (different owner) */
137 
138  /* render-specific members ... */
139 } lws_dlo_t;
140 
141 typedef struct lws_circle {
143 
144  /* rasterization temps */
145  lws_fx_t orx; /* abs pixel x for centre */
146  lws_fx_t ory; /* abs pixel y for centre */
149 } lws_circle_t;
150 
151 typedef struct lws_dlo_rect {
152  lws_dlo_t dlo;
153  lws_circle_t c[4]; /* t-l, t-r, b-l, b-r */
154  lws_fx_t b[4]; /* border width on t/r/b/l */
155  lws_display_colour_t dcb; /* border colour */
156 
157  /* rasterization temps */
158 
162 
163  uint8_t init;
164  uint8_t alt;
165 } lws_dlo_rect_t;
166 
167 typedef struct lws_dlo_circle {
168  lws_dlo_t dlo;
169 } lws_dlo_circle_t;
170 
171 typedef struct lws_font_choice {
172  const char *family_name;
173  const char *generic_name;
174  uint16_t weight;
175  uint16_t style; /* normal, italic, oblique */
176  uint16_t fixed_height;
177 } lws_font_choice_t;
178 
179 typedef struct lws_display_font {
181 
182  lws_font_choice_t choice;
183 
184  const uint8_t *data; /* may be cast to imp struct */
185  uint8_t *priv; /* only used by implementation */
187  lws_dlo_renderer_t renderer;
188  lws_dlo_image_glyph_t image_glyph;
189 
190  lws_fx_t em; /* 1 em in pixels */
191  lws_fx_t ex; /* 1 ex in pixels */
192 } lws_display_font_t;
193 
194 typedef struct lws_dlo_filesystem {
196 
197  const char *name;
198  const void *data;
200 } lws_dlo_filesystem_t;
201 
202 #define LWSDLO_TEXT_FLAG_WRAP (1 << 0)
203 
204 typedef struct lws_dlo_text {
205  lws_dlo_t dlo;
206  const lws_display_font_t *font;
208  lws_box_t bounding_box; /* { 0, 0, w, h } relative
209  * to and subject to
210  * clipping by .dlo.box */
211 
212  /* referred to by glyphs */
213  const struct lws_surface_info *ic;
214  struct lwsac *ac_glyphs;
215  uint8_t *line;
216  uint16_t curr;
217 
218  char *text;
219  uint8_t *kern;
223 
225 
226  uint32_t flags;
228  int16_t font_height;
230 
231  int16_t group_height;
233 
235 } lws_dlo_text_t;
236 
237 typedef struct lws_dlo_rasterize {
238  lws_dll2_owner_t owner; /* lws_flow_t */
240  int lines;
241 } lws_dlo_rasterize_t;
242 
243 typedef struct lws_dlo_png {
244  lws_dlo_t dlo; /* ordering: first */
245  lws_flow_t flow; /* ordering: second */
247 } lws_dlo_png_t;
248 
249 typedef struct lws_dlo_jpeg {
250  lws_dlo_t dlo; /* ordering: first */
251  lws_flow_t flow; /* ordering: second */
253 } lws_dlo_jpeg_t;
254 
255 typedef enum {
259 } lws_dlo_image_type_t;
260 
261 typedef struct {
262  union {
263  lws_dlo_jpeg_t *dlo_jpeg;
264  lws_dlo_png_t *dlo_png;
265  } u;
266  lws_dlo_image_type_t type;
267  char failed;
268 } lws_dlo_image_t;
269 
271 
272 typedef struct lws_displaylist {
275 } lws_displaylist_t;
276 
277 typedef struct lws_dl_rend {
278  lws_displaylist_t *dl;
279  int w;
280  int h;
281 } lws_dl_rend_t;
282 
283 typedef struct lws_display_render_stack {
284  lws_dlo_t *dlo; /* position in dlo owner */
285  lws_box_t co; /* our origin as parent */
286 } lws_display_render_stack_t;
287 
288 typedef struct lws_display_render_state {
289  lws_sorted_usec_list_t sul; /* return to event loop statefully */
290  lws_display_state_t *lds; /* optional, if using lws_display */
291 
293 
294  const struct lws_surface_info *ic; /* display dimensions, palette */
295 
296  lws_display_render_stack_t st[12]; /* DLO child stack */
297  int sp; /* DLO child stack level */
298 
299  uint8_t *line; /* Y or RGB line comp buffer */
300 
301  lws_displaylist_t displaylist;
302 
305 
306  char html;
307 
308 } lws_display_render_state_t;
309 
310 
311 LWS_VISIBLE LWS_EXTERN void
312 lws_display_render_free_ids(lws_display_render_state_t *rs);
313 
314 LWS_VISIBLE LWS_EXTERN lws_display_id_t *
315 lws_display_render_add_id(lws_display_render_state_t *rs, const char *id, void *priv);
316 
317 LWS_VISIBLE LWS_EXTERN lws_display_id_t *
318 lws_display_render_get_id(lws_display_render_state_t *rs, const char *id);
319 
320 LWS_VISIBLE LWS_EXTERN void
321 lws_display_render_dump_ids(lws_dll2_owner_t *ids);
322 
323 LWS_VISIBLE LWS_EXTERN void
324 lws_dlo_contents(lws_dlo_t *parent, lws_dlo_dim_t *dim);
325 
326 LWS_VISIBLE LWS_EXTERN void
327 lws_display_dlo_adjust_dims(lws_dlo_t *dlo, lws_dlo_dim_t *dim);
328 
329 /**
330  * lws_display_dl_init() - init display list object
331  *
332  * \param dl: Pointer to the display list
333  * \param ds: Lws display state to bind the list to
334  *
335  * Initializes the display list \p dl and binds it to the display state \p ds.
336  */
337 LWS_VISIBLE LWS_EXTERN void
338 lws_display_dl_init(lws_displaylist_t *dl, struct lws_display_state *ds);
339 
340 //#if defined(_DEBUG)
341 LWS_VISIBLE LWS_EXTERN void
342 lws_display_dl_dump(lws_displaylist_t *dl);
343 //#endif
344 
345 /**
346  * lws_display_list_destroy() - destroys display list and objects on it
347  *
348  * \param dl: Pointer to the display list
349  *
350  * Destroys every DLO on the list.
351  */
352 LWS_VISIBLE LWS_EXTERN void
353 lws_display_list_destroy(lws_displaylist_t *dl);
354 
355 LWS_VISIBLE LWS_EXTERN void
356 lws_display_dlo_destroy(lws_dlo_t **r);
357 
358 LWS_VISIBLE LWS_EXTERN int
359 lws_display_dlo_add(lws_displaylist_t *dl, lws_dlo_t *dlo_parent, lws_dlo_t *dlo);
360 
361 LWS_VISIBLE LWS_EXTERN int
362 lws_dlo_ensure_err_diff(lws_dlo_t *dlo);
363 
364 /*
365  * lws_display_list_render_line() - render a single raster line of the list
366  *
367  * \param rs: prepared render state object
368  *
369  * Allocates a line pair buffer into ds->line if necessary, and renders the
370  * current line (set by ds->curr) of the display list rasterization into it
371  */
372 LWS_VISIBLE LWS_EXTERN lws_stateful_ret_t
373 lws_display_list_render_line(lws_display_render_state_t *rs);
374 
375 LWS_VISIBLE LWS_EXTERN lws_stateful_ret_t
376 lws_display_get_ids_boxes(lws_display_render_state_t *rs);
377 
378 /*
379  * rect
380  */
381 
382 LWS_VISIBLE LWS_EXTERN lws_dlo_rect_t *
383 lws_display_dlo_rect_new(lws_displaylist_t *dl, lws_dlo_t *dlo_parent,
384  lws_box_t *box, const lws_fx_t *radii,
385  lws_display_colour_t dc);
386 
387 LWS_VISIBLE LWS_EXTERN lws_stateful_ret_t
388 lws_display_render_rect(struct lws_display_render_state *rs);
389 
390 /*
391  * dlo text
392  */
393 
394 LWS_VISIBLE LWS_EXTERN lws_dlo_text_t *
395 lws_display_dlo_text_new(lws_displaylist_t *dl, lws_dlo_t *dlo_parent,
396  lws_box_t *box, const lws_display_font_t *font);
397 
398 LWS_VISIBLE LWS_EXTERN int
399 lws_display_dlo_text_update(lws_dlo_text_t *text, lws_display_colour_t dc,
400  lws_fx_t indent, const char *utf8, size_t text_len);
401 
402 LWS_VISIBLE LWS_EXTERN void
404 
405 /*
406  * PNG
407  */
408 
409 LWS_VISIBLE LWS_EXTERN lws_dlo_png_t *
410 lws_display_dlo_png_new(lws_displaylist_t *dl, lws_dlo_t *dlo_parent,
411  lws_box_t *box);
412 
413 LWS_VISIBLE LWS_EXTERN lws_stateful_ret_t
414 lws_display_render_png(struct lws_display_render_state *rs);
415 
416 LWS_VISIBLE LWS_EXTERN lws_stateful_ret_t
417 lws_display_dlo_png_metadata_scan(lws_dlo_png_t *dp);
418 
419 LWS_VISIBLE LWS_EXTERN void
421 
422 /*
423  * JPEG
424  */
425 
426 LWS_VISIBLE LWS_EXTERN lws_dlo_jpeg_t *
427 lws_display_dlo_jpeg_new(lws_displaylist_t *dl, lws_dlo_t *dlo_parent,
428  lws_box_t *box);
429 
430 LWS_VISIBLE LWS_EXTERN lws_stateful_ret_t
431 lws_display_render_jpeg(struct lws_display_render_state *rs);
432 
433 LWS_VISIBLE LWS_EXTERN lws_stateful_ret_t
434 lws_display_dlo_jpeg_metadata_scan(lws_dlo_jpeg_t *dj);
435 
436 LWS_VISIBLE LWS_EXTERN void
438 
439 /*
440  * SS / dlo images
441  */
442 
443 struct lhp_ctx;
444 
445 typedef struct {
446  struct lws_context *cx;
447  lws_displaylist_t *dl;
448  lws_dlo_t *dlo_parent;
452  const char *url;
453  struct lhp_ctx *lhp;
454  lws_dlo_image_t *u;
455  int32_t window;
456 
457  uint8_t type;
458 } lws_dlo_ss_create_info_t;
459 
460 LWS_VISIBLE LWS_EXTERN int
461 lws_dlo_ss_create(lws_dlo_ss_create_info_t *i, lws_dlo_t **pdlo);
462 
463 typedef struct lhp_ctx lhp_ctx_t;
464 
465 LWS_VISIBLE LWS_EXTERN int
466 lws_dlo_ss_find(struct lws_context *cx, const char *url, lws_dlo_image_t *u);
467 
468 LWS_VISIBLE LWS_EXTERN lws_stateful_ret_t
469 lhp_displaylist_layout(lhp_ctx_t *ctx, char reason);
470 
471 #define lws_dlo_image_width(_u) ((_u)->failed ? -1 :
472  ((_u)->type == LWSDLOSS_TYPE_JPEG ?
473  (int)lws_jpeg_get_width((_u)->u.dlo_jpeg->j) :
474  (int)lws_upng_get_width((_u)->u.dlo_png->png)))
475 #define lws_dlo_image_height(_u) ((_u)->failed ? -1 :
476  ((_u)->type == LWSDLOSS_TYPE_JPEG ?
477  (int)lws_jpeg_get_height((_u)->u.dlo_jpeg->j) :
478  (int)lws_upng_get_height((_u)->u.dlo_png->png)))
479 
480 #define lws_dlo_image_metadata_scan(_u) ((_u)->failed ? LWS_SRET_FATAL :
481  ((_u)->type == LWSDLOSS_TYPE_JPEG ?
482  lws_display_dlo_jpeg_metadata_scan((_u)->u.dlo_jpeg) :
483  lws_display_dlo_png_metadata_scan((_u)->u.dlo_png)))
484 
485 /*
486  * Font registry
487  *
488  * Register fonts (currently, psfu) to the lws_context, and select the closest
489  * matching. Used to pick fonts from whatever CSS information is available.
490  */
491 
492 LWS_VISIBLE LWS_EXTERN int
493 lws_font_register(struct lws_context *cx, const uint8_t *data, size_t data_len);
494 
495 LWS_VISIBLE LWS_EXTERN const lws_display_font_t *
496 lws_font_choose(struct lws_context *cx, const lws_font_choice_t *hints);
497 
498 LWS_VISIBLE LWS_EXTERN void
499 lws_fonts_destroy(struct lws_context *cx);
500 
501 /*
502  * Static blob registry (built-in, name-accessible blobs)
503  */
504 
505 LWS_VISIBLE LWS_EXTERN lws_dlo_filesystem_t *
506 lws_dlo_file_register(struct lws_context *cx, const lws_dlo_filesystem_t *f);
507 
508 /* only needed if f dynamically heap-allocated... doesn't free data; data
509  * is typically overallocated after the lws_dlo_filesystem_t and freed when
510  * that is freed by this. */
511 
512 LWS_VISIBLE LWS_EXTERN void
513 lws_dlo_file_unregister(lws_dlo_filesystem_t **f);
514 
515 LWS_VISIBLE LWS_EXTERN void
516 lws_dlo_file_unregister_by_name(struct lws_context *cx, const char *name);
517 
518 LWS_VISIBLE LWS_EXTERN const lws_dlo_filesystem_t *
519 lws_dlo_file_choose(struct lws_context *cx, const char *name);
520 
521 LWS_VISIBLE LWS_EXTERN void
522 lws_dlo_file_destroy(struct lws_context *cx);
523 
524 LWS_VISIBLE extern const struct lws_plat_file_ops lws_dlo_fops;