11#define RETROHTR_TREE_FLAG_GUI_ACTIVE 1
13#define RETROHTR_NODE_FLAG_DIRTY 2
15#ifndef RETROHTR_RENDER_NODES_INIT_SZ
16# define RETROHTR_RENDER_NODES_INIT_SZ 10
19#ifndef RETROHTR_TRACE_LVL
20# define RETROHTR_TRACE_LVL 0
23#define RETROHTR_EDGE_UNKNOWN 0
24#define RETROHTR_EDGE_LEFT 1
25#define RETROHTR_EDGE_TOP 2
26#define RETROHTR_EDGE_INSIDE 4
44#ifdef RETROGXC_PRESENT
56 struct RETROFLAT_BITMAP bitmap;
73#define retrohtr_node( tree, idx ) \
74 (0 <= (ssize_t)idx ? &((tree)->nodes[idx]) : NULL)
76#define retrohtr_node_parent( tree, idx ) \
77 (0 <= idx && 0 <= (tree)->nodes[idx].parent ? \
78 &((tree)->nodes[(tree)->nodes[idx].parent]) : NULL)
80#define retrohtr_tree_lock( tree ) \
81 if( NULL == (tree)->nodes ) { \
82 maug_mlock( (tree)->nodes_h, (tree)->nodes ); \
83 maug_cleanup_if_null_alloc( struct RETROHTR_RENDER_NODE*, (tree)->nodes ); \
86#define retrohtr_tree_unlock( tree ) \
87 if( NULL != (tree)->nodes ) { \
88 maug_munlock( (tree)->nodes_h, (tree)->nodes ); \
91#define retrohtr_tree_is_locked( tree ) (NULL != (tree)->nodes)
95#define retrohtr_node_screen_x( tree, node_idx ) \
96 ((tree)->nodes[node_idx].x)
98#define retrohtr_node_screen_y( tree, node_idx ) \
99 ((tree)->nodes[node_idx].y)
101void retrohtr_merge_prop(
103 const char* prop_name,
106 void* parent_prop, uint8_t* parent_prop_flags,
107 void* effect_prop, uint8_t* effect_prop_flags,
108 void* tag_prop, uint8_t* tag_prop_flags );
110void retrohtr_merge_styles(
111 struct MCSS_STYLE* effect_style,
112 struct MCSS_STYLE* parent_style,
113 struct MCSS_STYLE* tag_style,
120 ssize_t tag_idx, ssize_t node_idx,
size_t d );
135 struct MCSS_STYLE* parent_style,
struct MCSS_STYLE* effect_style,
140 struct MCSS_STYLE* prev_sibling_style,
141 struct MCSS_STYLE* parent_style, ssize_t node_idx,
size_t d );
145 struct MCSS_STYLE* prev_sibling_style,
146 struct MCSS_STYLE* parent_style, ssize_t node_idx,
size_t d );
150 ssize_t node_idx,
size_t d );
154 RETROFLAT_IN_KEY* input,
159 ssize_t iter,
size_t d );
167void retrohtr_merge_prop(
169 const char* prop_name,
172 void* parent_prop, uint8_t* parent_prop_flags,
173 void* effect_prop, uint8_t* effect_prop_flags,
174 void* tag_prop, uint8_t* tag_prop_flags
180 mcss_prop_is_heritable( p_id )
181 ) && (NULL != parent_prop && (
185 mcss_prop_is_active_flag( *parent_prop, IMPORTANT ) &&
187 !mcss_prop_is_important( *tag_prop ) &&
188 !mcss_prop_is_important( *effect_prop )
192 !mcss_prop_is_active( *tag_prop ) &&
193 !mcss_prop_is_active( *effect_prop )
197 !mcss_prop_is_active( *effect_prop )
202 if( MCSS_PROP_BACKGROUND_COLOR == p_id ) {
203#if RETROHTR_TRACE_LVL > 0
204 debug_printf( RETROHTR_TRACE_LVL,
"background color was %s",
208 }
else if( MCSS_PROP_COLOR == p_id ) {
209#if RETROHTR_TRACE_LVL > 0
210 debug_printf( RETROHTR_TRACE_LVL,
"color was %s",
215#if RETROHTR_TRACE_LVL > 0
216 debug_printf( RETROHTR_TRACE_LVL,
217 "%s using parent %s: " SSIZE_T_FMT,
218 gc_mhtml_tag_names[tag_type], prop_name, *(ssize_t*)parent_prop );
220 memcpy( effect_prop, parent_prop, prop_sz );
221 *effect_prop_flags = *parent_prop_flags;
222 if( MCSS_PROP_BACKGROUND_COLOR == p_id ) {
223#if RETROHTR_TRACE_LVL > 0
224 debug_printf( RETROHTR_TRACE_LVL,
"background color %s",
228 }
else if( MCSS_PROP_COLOR == p_id ) {
229#if RETROHTR_TRACE_LVL > 0
230 debug_printf( RETROHTR_TRACE_LVL,
"color %s",
237 mcss_prop_is_active( *tag_prop )
240#if RETROHTR_TRACE_LVL > 0
241 debug_printf( RETROHTR_TRACE_LVL,
"%s using style %s: " SSIZE_T_FMT,
242 gc_mhtml_tag_names[tag_type], prop_name,
243 *(ssize_t*)tag_prop );
244 if( MCSS_PROP_COLOR == p_id ) {
245 debug_printf( RETROHTR_TRACE_LVL,
"color %s",
250 memcpy( effect_prop, tag_prop, prop_sz );
251 *effect_prop_flags = *tag_prop_flags;
257void retrohtr_merge_styles(
258 struct MCSS_STYLE* effect_style,
259 struct MCSS_STYLE* parent_style,
260 struct MCSS_STYLE* tag_style,
268 MCSS_STYLE_FLAG_ACTIVE !=
269 (MCSS_STYLE_FLAG_ACTIVE & effect_style->flags)
271 mcss_style_init( effect_style );
276 #define MCSS_PROP_TABLE_MERGE( p_id, prop_n, prop_t, prop_p, def ) \
277 retrohtr_merge_prop( p_id, \
281 NULL != parent_style ? &(parent_style->prop_n) : NULL, \
282 NULL != parent_style ? &(parent_style->prop_n ## _flags) : 0, \
283 NULL != effect_style ? &(effect_style->prop_n) : NULL, \
284 NULL != effect_style ? &(effect_style->prop_n ## _flags) : 0, \
285 NULL != tag_style ? &(tag_style->prop_n) : NULL, \
286 NULL != tag_style ? &(tag_style->prop_n ## _flags) : 0 );
288 MCSS_PROP_TABLE( MCSS_PROP_TABLE_MERGE )
293 MCSS_PROP_FLAG_ACTIVE !=
294 (MCSS_PROP_FLAG_ACTIVE & effect_style->DISPLAY_flags)
298 #define MHTML_TAG_TABLE_DISP( tag_id, tag_name, fields, disp ) \
299 } else if( tag_id == tag_type ) { \
300 effect_style->DISPLAY = MCSS_DISPLAY_ ## disp; \
301 debug_printf( RETROHTR_TRACE_LVL, "%s defaulting to %s DISPLAY", \
302 gc_mhtml_tag_names[tag_type], \
303 gc_mcss_display_names[effect_style->DISPLAY] );
306 MHTML_TAG_TABLE( MHTML_TAG_TABLE_DISP )
318 uint8_t auto_unlocked = 0;
320 MAUG_MHANDLE new_nodes_h = (MAUG_MHANDLE)NULL;
322 if( NULL != tree->
nodes ) {
323#if RETROHTR_TRACE_LVL > 0
324 debug_printf( RETROHTR_TRACE_LVL,
"auto-unlocking nodes..." );
326 maug_munlock( tree->nodes_h, tree->
nodes );
331 assert( NULL == tree->
nodes );
332 assert( (MAUG_MHANDLE)NULL != tree->nodes_h );
335 maug_mrealloc_test( new_nodes_h, tree->nodes_h, tree->
nodes_sz_max * 2,
341 assert( NULL == tree->
nodes );
342 maug_mlock( tree->nodes_h, tree->
nodes );
343 if( NULL == tree->
nodes ) {
344 error_printf(
"unable to lock nodes!" );
349#if RETROHTR_TRACE_LVL > 0
350 debug_printf( RETROHTR_TRACE_LVL,
351 "zeroing node " SIZE_T_FMT
" (of " SIZE_T_FMT
")...",
360 maug_munlock( tree->nodes_h, tree->
nodes );
364 if( auto_unlocked ) {
365#if RETROHTR_TRACE_LVL > 0
366 debug_printf( RETROHTR_TRACE_LVL,
"auto-locking nodes..." );
368 maug_mlock( tree->nodes_h, tree->
nodes );
371 if( MERROR_OK != retval ) {
372 retidx = merror_retval_to_sz( retval );
380ssize_t retrohtr_add_node_child(
383 ssize_t node_new_idx = -1,
384 node_sibling_idx = -1;
386 node_new_idx = retrohtr_get_next_free_node( tree );
387 if( 0 > node_new_idx ) {
391#ifdef RETROGXC_PRESENT
392 retrohtr_node( tree, node_new_idx )->font_idx = -1;
394 retrohtr_node( tree, node_new_idx )->parent = node_parent_idx;
395 retrohtr_node( tree, node_new_idx )->first_child = -1;
396 retrohtr_node( tree, node_new_idx )->next_sibling = -1;
398 if( 0 > node_parent_idx ) {
400 1,
"adding root node under " SSIZE_T_FMT
"...", node_parent_idx );
404 1,
"adding node " SSIZE_T_FMT
" under " SSIZE_T_FMT,
405 node_new_idx, node_parent_idx );
409 if( 0 > retrohtr_node( tree, node_parent_idx )->first_child ) {
410#if RETROHTR_TRACE_LVL > 0
411 debug_printf( RETROHTR_TRACE_LVL,
"adding first child..." );
413 assert( -1 == retrohtr_node( tree, node_parent_idx )->first_child );
414 retrohtr_node( tree, node_parent_idx )->first_child = node_new_idx;
416 assert( NULL != retrohtr_node( tree, node_parent_idx ) );
417 node_sibling_idx = retrohtr_node( tree, node_parent_idx )->first_child;
418 assert( NULL != retrohtr_node( tree, node_sibling_idx ) );
419 while( 0 <= retrohtr_node( tree, node_sibling_idx )->next_sibling ) {
421 retrohtr_node( tree, node_sibling_idx )->next_sibling;
423 retrohtr_node( tree, node_sibling_idx )->next_sibling = node_new_idx;
437 ssize_t tag_idx, ssize_t node_idx,
size_t d
439 ssize_t node_new_idx = -1;
440 ssize_t tag_iter_idx = -1;
443 ssize_t tag_next_idx = 0;
445#if RETROHTR_TRACE_LVL > 0
446 debug_printf( RETROHTR_TRACE_LVL,
447 "creating render node for tag: " SSIZE_T_FMT, tag_idx );
455 p_tag_iter = mdata_vector_get( &(parser->tags), tag_idx,
union MHTML_TAG );
456 if( NULL == p_tag_iter ) {
462 assert( MHTML_TAG_TYPE_BODY == p_tag_iter->base.type );
464 node_new_idx = retrohtr_add_node_child( tree, node_idx );
465 if( 0 > node_new_idx ) {
468#if RETROHTR_TRACE_LVL > 0
469 debug_printf( RETROHTR_TRACE_LVL,
470 "created initial root node: " SIZE_T_FMT, node_new_idx );
473 node_idx = node_new_idx;
476 retrohtr_node( tree, node_idx )->tag = tag_idx;
478 retrohtr_node( tree, node_idx )->x = x;
479 retrohtr_node( tree, node_idx )->y = y;
480 retrohtr_node( tree, node_idx )->w = w;
481 retrohtr_node( tree, node_idx )->h = h;
484 tag_iter_idx = p_tag_iter->base.first_child;
485 while( 0 <= tag_iter_idx ) {
486 node_new_idx = retrohtr_add_node_child( tree, node_idx );
487 p_tag_iter = mdata_vector_get(
488 &(parser->tags), tag_iter_idx,
union MHTML_TAG );
489 assert( NULL != p_tag_iter );
490 if( 0 > node_new_idx ) {
494 retrohtr_node( tree, node_new_idx )->tag = tag_iter_idx;
496#if RETROHTR_TRACE_LVL > 0
497 debug_printf( RETROHTR_TRACE_LVL,
498 "rendering node " SSIZE_T_FMT
" (%s) under node " SSIZE_T_FMT,
500 gc_mhtml_tag_names[p_tag_iter->base.type],
505 if( MHTML_TAG_TYPE_IMG == p_tag_iter->base.type ) {
509 &(retrohtr_node( tree, node_new_idx )->bitmap),
511 if( MERROR_OK == retval ) {
512#if RETROHTR_TRACE_LVL > 0
513 debug_printf( RETROHTR_TRACE_LVL,
"loaded img: %s",
514 p_tag_iter->IMG.src );
517 error_printf(
"could not load img: %s", p_tag_iter->IMG.src );
521 tag_next_idx = p_tag_iter->base.next_sibling;
525 retval = retrohtr_tree_create( parser, tree, x, y, w, h,
526 tag_iter_idx, node_new_idx, d + 1 );
527 maug_cleanup_if_not_ok();
531 tag_iter_idx = tag_next_idx;
536 if( mdata_vector_is_locked( &(parser->tags) ) ) {
547 struct MCSS_STYLE* parent_style,
struct MCSS_STYLE* effect_style,
551 ssize_t tag_style_idx = -1;
554 struct MCSS_STYLE* style = NULL;
557#if RETROHTR_TRACE_LVL > 0
558 debug_printf( RETROHTR_TRACE_LVL,
559 "applying styles for tag: " SSIZE_T_FMT, tag_idx );
562 assert( !mdata_vector_is_locked( &(parser->tags) ) );
566 maug_mzero( effect_style,
sizeof(
struct MCSS_STYLE ) );
571 p_tag_iter = mdata_vector_get( &(parser->tags), tag_idx,
union MHTML_TAG );
572 if( NULL == p_tag_iter ) {
576 tag_type = p_tag_iter->base.type;
579 if( 0 < p_tag_iter->base.classes_sz ) {
581 style = mdata_vector_get(
582 &(parser->styler.styles), i,
struct MCSS_STYLE );
587 p_tag_iter->base.classes,
589 p_tag_iter->base.classes_sz
592#if RETROHTR_TRACE_LVL > 0
593 debug_printf( RETROHTR_TRACE_LVL,
"found style for tag class: %s",
597 retrohtr_merge_styles(
598 effect_style, parent_style, style, tag_type );
604 if( 0 < p_tag_iter->base.id_sz ) {
606 style = mdata_vector_get(
607 &(parser->styler.styles), i,
struct MCSS_STYLE );
614 p_tag_iter->base.id_sz
617#if RETROHTR_TRACE_LVL > 0
618 debug_printf( RETROHTR_TRACE_LVL,
"found style for tag ID: %s",
622 retrohtr_merge_styles(
623 effect_style, parent_style, style, tag_type );
629 tag_style_idx = p_tag_iter->base.style;
636 style = mdata_vector_get(
637 &(parser->styler.styles), tag_style_idx,
struct MCSS_STYLE );
640 retrohtr_merge_styles( effect_style, parent_style, style, tag_type );
651 struct MCSS_PARSER* styler,
652#ifdef RETROGXC_PRESENT
655 MAUG_MHANDLE* font_h_p,
657 struct MCSS_STYLE* effect_style
661#ifdef RETROGXC_PRESENT
662 if( 0 <= *font_idx_p ) {
663 error_printf(
"tried to load font but font already loaded, idx: "
664 SSIZE_T_FMT, *font_idx_p );
666 if( (MAUG_MHANDLE)NULL != *font_h_p ) {
667 error_printf(
"tried to load font but font already loaded, p: %p",
673 mdata_strpool_lock( &(styler->strpool) );
675#if RETROHTR_TRACE_LVL > 0
676 debug_printf( RETROHTR_TRACE_LVL,
677 "loading font: %s (" SSIZE_T_FMT
")",
679 effect_style->FONT_FAMILY );
682 if( MDATA_STRPOOL_IDX_ERROR == effect_style->FONT_FAMILY ) {
683 error_printf(
"style has no font associated!" );
690#ifdef RETROGXC_PRESENT
698 font_h_p, 0, 33, 93 );
703 mdata_strpool_unlock( &(styler->strpool) );
712 struct MCSS_STYLE* effect_style
718 RETROHTR_TREE_FLAG_GUI_ACTIVE ==
719 (RETROHTR_TREE_FLAG_GUI_ACTIVE & tree->flags)
721#if RETROHTR_TRACE_LVL > 0
722 debug_printf( RETROHTR_TRACE_LVL,
"tree GUI already active!" );
731 maug_cleanup_if_not_ok();
733 retval = retrohtr_load_font(
735#ifdef RETROGXC_PRESENT
736 &(tree->gui.font_idx),
741 maug_cleanup_if_not_ok();
743 tree->flags |= RETROHTR_TREE_FLAG_GUI_ACTIVE;
745#if RETROHTR_TRACE_LVL > 0
746 debug_printf( RETROHTR_TRACE_LVL,
"tree GUI initialized!" );
757 struct MCSS_STYLE* prev_sibling_style,
758 struct MCSS_STYLE* parent_style, ssize_t node_idx,
size_t d
760 struct MCSS_STYLE effect_style;
761 struct MCSS_STYLE child_prev_sibling_style;
762 struct MCSS_STYLE child_style;
763 ssize_t child_iter_idx = -1;
764 ssize_t tag_idx = -1;
765 ssize_t node_iter_idx = -1;
766 size_t this_line_w = 0;
767 size_t this_line_h = 0;
773 if( NULL == retrohtr_node( tree, node_idx ) ) {
777 tag_idx = retrohtr_node( tree, node_idx )->tag;
780 parser, tree, parent_style, &effect_style, tag_idx );
781 maug_cleanup_if_not_ok();
783 assert( !mdata_vector_is_locked( &(parser->tags) ) );
786 p_tag_iter = mdata_vector_get( &(parser->tags), tag_idx,
union MHTML_TAG );
787 assert( NULL != p_tag_iter );
791 if( mcss_prop_is_active( effect_style.POSITION ) ) {
792#if RETROHTR_TRACE_LVL > 0
793 debug_printf( RETROHTR_TRACE_LVL,
794 "node " SSIZE_T_FMT
": applying %s positioning",
795 node_idx, gc_mcss_position_names[effect_style.POSITION] );
804 retrohtr_node( tree, node_idx )->pos = effect_style.POSITION;
805 retrohtr_node( tree, node_idx )->pos_flags = effect_style.POSITION_flags;
813 if( mcss_prop_is_active_NOT_flag( effect_style.WIDTH, AUTO ) ) {
814 retrohtr_node( tree, node_idx )->w = effect_style.WIDTH;
817 if( mcss_prop_is_active_NOT_flag( effect_style.HEIGHT, AUTO ) ) {
818 retrohtr_node( tree, node_idx )->h = effect_style.HEIGHT;
824 retval = retrohtr_load_font(
826#ifdef RETROGXC_PRESENT
827 &(retrohtr_node( tree, node_idx )->font_idx),
829 &(retrohtr_node( tree, node_idx )->font_h),
832 maug_cleanup_if_not_ok();
834 if( 0 <= tag_idx && MHTML_TAG_TYPE_TEXT == p_tag_iter->base.type ) {
837 mdata_strpool_lock( &(parser->strpool) );
839#ifdef RETROGXC_PRESENT
846 p_tag_iter->TEXT.content_sz,
847#ifdef RETROGXC_PRESENT
848 retrohtr_node( tree, node_idx )->font_idx,
850 retrohtr_node( tree, node_idx )->font_h,
853 retrohtr_node_parent( tree, node_idx )->w,
854 retrohtr_node_parent( tree, node_idx )->h,
855 &(retrohtr_node( tree, node_idx )->w),
856 &(retrohtr_node( tree, node_idx )->h), 0 );
858#if RETROHTR_TRACE_LVL > 0
859 debug_printf( RETROHTR_TRACE_LVL,
"TEXT w: " SIZE_T_FMT,
860 retrohtr_node( tree, node_idx )->w );
863 mdata_strpool_unlock( &(parser->strpool) );
867 MHTML_TAG_TYPE_INPUT == p_tag_iter->base.type
871 retval = retrohtr_tree_gui( tree, &(parser->styler), &effect_style );
875 MERROR_OK != retrogui_init_ctl(
876 &ctl, RETROGUI_CTL_TYPE_BUTTON, node_idx )
878 error_printf(
"could not initialize control!" );
882 p_tag_node = mdata_vector_get(
884 retrohtr_node( tree, node_idx )->tag,
union MHTML_TAG );
886 ctl.base.x = retrohtr_node( tree, node_idx )->x;
887 ctl.base.y = retrohtr_node( tree, node_idx )->y;
890 ctl.BUTTON.label = p_tag_node->INPUT.value;
893 retrohtr_node( tree, node_idx )->w = ctl.base.w;
894 retrohtr_node( tree, node_idx )->h = ctl.base.h;
896#if RETROHTR_TRACE_LVL > 0
897 debug_printf( RETROHTR_TRACE_LVL,
"initialized control for INPUT..." );
900 retrogui_push_ctl( &(tree->gui), &ctl );
902 }
else if( 0 <= tag_idx && MHTML_TAG_TYPE_IMG == p_tag_iter->base.type ) {
904 if( retroflat_bitmap_ok( &(retrohtr_node( tree, node_idx )->bitmap) ) ) {
905 retrohtr_node( tree, node_idx )->w =
906 retroflat_bitmap_w( &(retrohtr_node( tree, node_idx )->bitmap) );
907 retrohtr_node( tree, node_idx )->h =
908 retroflat_bitmap_h( &(retrohtr_node( tree, node_idx )->bitmap) );
911#if RETROHTR_TRACE_LVL > 0
912 debug_printf( RETROHTR_TRACE_LVL,
"TEXT w: " SIZE_T_FMT,
913 retrohtr_node( tree, node_idx )->w );
919 maug_mzero( &child_prev_sibling_style,
sizeof(
struct MCSS_STYLE ) );
920 node_iter_idx = retrohtr_node( tree, node_idx )->first_child;
922 while( 0 <= node_iter_idx ) {
924 parser, tree, &child_prev_sibling_style, &effect_style,
925 node_iter_idx, d + 1 );
927 node_iter_idx = retrohtr_node( tree, node_iter_idx )->next_sibling;
931 if( mdata_vector_is_locked( &(parser->tags) ) ) {
936 if( 0 == retrohtr_node( tree, node_idx )->w ) {
938 MCSS_DISPLAY_BLOCK == effect_style.DISPLAY &&
939 0 <= retrohtr_node( tree, node_idx )->parent
943 retrohtr_node( tree, node_idx )->w =
944 retrohtr_node_parent( tree, node_idx )->w;
948 child_iter_idx = retrohtr_node( tree, node_idx )->first_child;
949 while( 0 <= child_iter_idx ) {
950 assert( !mdata_vector_is_locked( &(parser->tags) ) );
952 parser, tree, &effect_style, &child_style,
953 retrohtr_node( tree, child_iter_idx )->tag );
954 maug_cleanup_if_not_ok();
957 if( MCSS_POSITION_ABSOLUTE == child_style.POSITION ) {
959 retrohtr_node( tree, child_iter_idx )->next_sibling;
963 if( MCSS_DISPLAY_BLOCK == child_style.DISPLAY ) {
968 retrohtr_node( tree, child_iter_idx )->w >
969 retrohtr_node( tree, node_idx )->w
972 retrohtr_node( tree, node_idx )->w =
973 retrohtr_node( tree, child_iter_idx )->w;
977 this_line_w += retrohtr_node( tree, child_iter_idx )->w;
979 if( this_line_w > retrohtr_node( tree, node_idx )->w ) {
981 retrohtr_node( tree, node_idx )->w = this_line_w;
984 child_iter_idx = retrohtr_node( tree, child_iter_idx )->next_sibling;
989 if( 0 == retrohtr_node( tree, node_idx )->h ) {
991 child_iter_idx = retrohtr_node( tree, node_idx )->first_child;
992 while( 0 <= child_iter_idx ) {
993 assert( !mdata_vector_is_locked( &(parser->tags) ) );
995 parser, tree, &effect_style, &child_style,
996 retrohtr_node( tree, child_iter_idx )->tag );
999 if( MCSS_POSITION_ABSOLUTE == child_style.POSITION ) {
1000 child_iter_idx = retrohtr_node( tree, child_iter_idx )->next_sibling;
1004 if( MCSS_DISPLAY_BLOCK == child_style.DISPLAY ) {
1006 retrohtr_node( tree, node_idx )->h += this_line_h;
1009 this_line_h = retrohtr_node( tree, child_iter_idx )->h;
1012 if( this_line_h < retrohtr_node( tree, child_iter_idx )->h ) {
1013 this_line_h = retrohtr_node( tree, child_iter_idx )->h;
1017 child_iter_idx = retrohtr_node( tree, child_iter_idx )->next_sibling;
1021 retrohtr_node( tree, node_idx )->h += this_line_h;
1030 if( mcss_prop_is_active_NOT_flag( effect_style.PADDING_LEFT, AUTO ) ) {
1031 retrohtr_node( tree, node_idx )->w += effect_style.PADDING_LEFT;
1032 }
else if( mcss_prop_is_active_NOT_flag( effect_style.PADDING, AUTO ) ) {
1033 retrohtr_node( tree, node_idx )->w += effect_style.PADDING;
1037 if( mcss_prop_is_active_NOT_flag( effect_style.PADDING_RIGHT, AUTO ) ) {
1038 retrohtr_node( tree, node_idx )->w += effect_style.PADDING_RIGHT;
1039 }
else if( mcss_prop_is_active_NOT_flag( effect_style.PADDING, AUTO ) ) {
1040 retrohtr_node( tree, node_idx )->w += effect_style.PADDING;
1044 if( mcss_prop_is_active_NOT_flag( effect_style.PADDING_TOP, AUTO ) ) {
1045 retrohtr_node( tree, node_idx )->h += effect_style.PADDING_TOP;
1046 }
else if( mcss_prop_is_active_NOT_flag( effect_style.PADDING, AUTO ) ) {
1047 retrohtr_node( tree, node_idx )->h += effect_style.PADDING;
1051 if( mcss_prop_is_active_NOT_flag( effect_style.PADDING_BOTTOM, AUTO ) ) {
1052 retrohtr_node( tree, node_idx )->h += effect_style.PADDING_BOTTOM;
1053 }
else if( mcss_prop_is_active_NOT_flag( effect_style.PADDING, AUTO ) ) {
1054 retrohtr_node( tree, node_idx )->h += effect_style.PADDING;
1057#if RETROHTR_TRACE_LVL > 0
1058 debug_printf( RETROHTR_TRACE_LVL,
1059 "setting node " SIZE_T_FMT
" dirty...", node_idx );
1061 retrohtr_node( tree, node_idx )->flags |= RETROHTR_NODE_FLAG_DIRTY;
1065 if( mdata_vector_is_locked( &(parser->tags) ) ) {
1072 if( NULL != prev_sibling_style ) {
1074 prev_sibling_style, &effect_style,
1075 sizeof(
struct MCSS_STYLE ) );
1083#define retrohtr_break_on_active_pos( iter_idx ) \
1084 if( mcss_prop_is_active( retrohtr_node( tree, iter_idx )->pos ) ) { \
1088static ssize_t retrohtr_find_prev_sibling_in_box_model(
1092 ssize_t sibling_iter_idx = -1;
1093 ssize_t sibling_found_idx = -1;
1095 if( 0 > retrohtr_node( tree, node_idx )->parent ) {
1100 sibling_iter_idx = retrohtr_node_parent( tree, node_idx )->first_child;
1102 if( sibling_iter_idx == node_idx ) {
1107 while( 0 <= sibling_iter_idx && node_idx != sibling_iter_idx ) {
1110 MCSS_POSITION_ABSOLUTE != retrohtr_node( tree, sibling_iter_idx )->pos
1112 sibling_found_idx = sibling_iter_idx;
1117 sibling_iter_idx = retrohtr_node( tree, sibling_iter_idx )->next_sibling;
1121 return sibling_found_idx;
1128 ssize_t node_parent_idx
1130 ssize_t node_sibling_idx = -1;
1132 struct MCSS_STYLE effect_style;
1137 node_sibling_idx = retrohtr_node( tree, node_parent_idx )->first_child;
1138 while( 0 <= node_sibling_idx ) {
1139 maug_mzero( &effect_style,
sizeof(
struct MCSS_STYLE ) );
1141 parser, tree, NULL, &effect_style,
1142 retrohtr_node( tree, node_sibling_idx )->tag );
1144 if( MCSS_POSITION_ABSOLUTE == effect_style.POSITION ) {
1146 retrohtr_node( tree, node_sibling_idx )->edge |= RETROHTR_EDGE_INSIDE;
1148 }
else if( MCSS_DISPLAY_INLINE == effect_style.DISPLAY ) {
1150 if( 0 == col_idx ) {
1151 retrohtr_node( tree, node_sibling_idx )->edge |= RETROHTR_EDGE_LEFT;
1153 if( 0 == row_idx ) {
1154 retrohtr_node( tree, node_sibling_idx )->edge |= RETROHTR_EDGE_TOP;
1156 if( 0 < row_idx && 0 < col_idx ) {
1157 retrohtr_node( tree, node_sibling_idx )->edge |= RETROHTR_EDGE_INSIDE;
1169 if( 0 == row_idx ) {
1170 retrohtr_node( tree, node_sibling_idx )->edge |= RETROHTR_EDGE_TOP;
1174 retrohtr_node( tree, node_sibling_idx )->edge |= RETROHTR_EDGE_LEFT;
1177 assert( !mdata_vector_is_locked( &(parser->tags) ) );
1180 p_tag_iter = mdata_vector_get( &(parser->tags),
1181 retrohtr_node( tree, node_sibling_idx )->tag,
1183 assert( NULL != p_tag_iter );
1185 debug_printf( 1,
"marking node " SIZE_T_FMT
" (%s) edge: %u",
1187 gc_mhtml_tag_names[p_tag_iter->base.type],
1188 retrohtr_node( tree, node_sibling_idx )->edge );
1193 retrohtr_node( tree, node_sibling_idx )->next_sibling;
1198 if( mdata_vector_is_locked( &(parser->tags) ) ) {
1209 struct MCSS_STYLE* prev_sibling_style,
1210 struct MCSS_STYLE* parent_style, ssize_t node_idx,
size_t d
1212 struct MCSS_STYLE child_prev_sibling_style;
1213 struct MCSS_STYLE effect_style;
1214 ssize_t child_iter_idx = -1;
1215 ssize_t tag_idx = -1;
1216 ssize_t node_iter_idx = -1;
1217 ssize_t prev_sibling_idx = -1;
1221 if( NULL == retrohtr_node( tree, node_idx ) ) {
1225 tag_idx = retrohtr_node( tree, node_idx )->tag;
1228 parser, tree, parent_style, &effect_style, tag_idx );
1231 retrohtr_find_prev_sibling_in_box_model( tree, node_idx );
1235 if( MCSS_POSITION_ABSOLUTE == effect_style.POSITION ) {
1238 if( mcss_prop_is_active_NOT_flag( effect_style.LEFT, AUTO ) ) {
1240 child_iter_idx = retrohtr_node( tree, node_idx )->parent;
1241 while( 0 <= retrohtr_node( tree, child_iter_idx )->parent ) {
1242 retrohtr_break_on_active_pos( child_iter_idx );
1243 child_iter_idx = retrohtr_node( tree, child_iter_idx )->parent;
1247 retrohtr_node( tree, node_idx )->x =
1248 retrohtr_node( tree, child_iter_idx )->x + effect_style.LEFT;
1250 if( mcss_prop_is_active_NOT_flag( effect_style.RIGHT, AUTO ) ) {
1252 child_iter_idx = retrohtr_node( tree, node_idx )->parent;
1253 while( 0 <= retrohtr_node( tree, child_iter_idx )->parent ) {
1254 retrohtr_break_on_active_pos( child_iter_idx );
1255 child_iter_idx = retrohtr_node( tree, child_iter_idx )->parent;
1259 retrohtr_node( tree, node_idx )->x =
1260 retrohtr_node( tree, child_iter_idx )->w -
1261 retrohtr_node( tree, node_idx )->w -
1266 MCSS_DISPLAY_INLINE == effect_style.DISPLAY &&
1267 MCSS_DISPLAY_INLINE == prev_sibling_style->DISPLAY &&
1268 0 <= prev_sibling_idx
1271 retrohtr_node( tree, node_idx )->x =
1272 retrohtr_node( tree, prev_sibling_idx )->x +
1273 retrohtr_node( tree, prev_sibling_idx )->w;
1275 }
else if( 0 <= retrohtr_node( tree, node_idx )->parent ) {
1276 retrohtr_node( tree, node_idx )->x = retrohtr_node_parent( tree, node_idx )->x;
1283 if( MCSS_POSITION_ABSOLUTE == effect_style.POSITION ) {
1286 if( mcss_prop_is_active_NOT_flag( effect_style.TOP, AUTO ) ) {
1288 child_iter_idx = retrohtr_node( tree, node_idx )->parent;
1289 while( 0 <= retrohtr_node( tree, child_iter_idx )->parent ) {
1290 retrohtr_break_on_active_pos( child_iter_idx );
1291 child_iter_idx = retrohtr_node( tree, child_iter_idx )->parent;
1295 retrohtr_node( tree, node_idx )->y =
1296 retrohtr_node( tree, child_iter_idx )->y + effect_style.TOP;
1298 if( mcss_prop_is_active_NOT_flag( effect_style.BOTTOM, AUTO ) ) {
1300 child_iter_idx = retrohtr_node( tree, node_idx )->parent;
1301 while( 0 <= retrohtr_node( tree, child_iter_idx )->parent ) {
1302 retrohtr_break_on_active_pos( child_iter_idx );
1303 child_iter_idx = retrohtr_node( tree, child_iter_idx )->parent;
1307 retrohtr_node( tree, node_idx )->y =
1308 retrohtr_node( tree, child_iter_idx )->h -
1309 retrohtr_node( tree, node_idx )->h -
1310 effect_style.BOTTOM;
1314 MCSS_DISPLAY_INLINE == effect_style.DISPLAY &&
1315 MCSS_DISPLAY_INLINE == prev_sibling_style->DISPLAY &&
1316 0 <= prev_sibling_idx
1319 retrohtr_node( tree, node_idx )->y = retrohtr_node( tree, prev_sibling_idx )->y;
1321 }
else if( 0 <= prev_sibling_idx ) {
1328 retrohtr_node( tree, node_idx )->y =
1329 retrohtr_node( tree, prev_sibling_idx )->y +
1330 retrohtr_node( tree, prev_sibling_idx )->h;
1332 }
else if( 0 <= retrohtr_node( tree, node_idx )->parent ) {
1335 retrohtr_node( tree, node_idx )->y = retrohtr_node_parent( tree, node_idx )->y;
1341 MCSS_POSITION_ABSOLUTE != retrohtr_node( tree, node_idx )->pos &&
1342 0 <= retrohtr_node( tree, node_idx )->parent &&
1343 mcss_prop_is_active_flag( effect_style.MARGIN_LEFT, AUTO ) &&
1344 mcss_prop_is_active_flag( effect_style.MARGIN_RIGHT, AUTO )
1347 retrohtr_node( tree, node_idx )->x =
1348 retrohtr_node_parent( tree, node_idx )->x +
1349 (retrohtr_node_parent( tree, node_idx )->w >> 1) -
1350 (retrohtr_node( tree, node_idx )->w >> 1);
1353 0 <= retrohtr_node( tree, node_idx )->parent &&
1354 mcss_prop_is_active_flag( effect_style.MARGIN_LEFT, AUTO ) &&
1355 mcss_prop_is_active_NOT_flag( effect_style.MARGIN_RIGHT, AUTO )
1359 retrohtr_node( tree, node_idx )->x =
1360 retrohtr_node_parent( tree, node_idx )->w -
1361 retrohtr_node( tree, node_idx )->w;
1363 }
else if( mcss_prop_is_active( effect_style.MARGIN_LEFT ) ) {
1365 retrohtr_node( tree, node_idx )->x += effect_style.MARGIN_LEFT;
1374 debug_printf( 1,
"(d: " SIZE_T_FMT
") node " SIZE_T_FMT
" is on edge: %u",
1375 d, node_idx, retrohtr_node( tree, node_idx )->edge );
1379 RETROHTR_EDGE_UNKNOWN != retrohtr_node( tree, node_idx )->edge );
1382 RETROHTR_EDGE_LEFT ==
1383 (RETROHTR_EDGE_LEFT & retrohtr_node( tree, node_idx )->edge)
1386 if( mcss_prop_is_active_NOT_flag( parent_style->PADDING_LEFT, AUTO ) ) {
1387 retrohtr_node( tree, node_idx )->x += parent_style->PADDING_LEFT;
1388 }
else if( mcss_prop_is_active_NOT_flag( parent_style->PADDING, AUTO ) ) {
1389 retrohtr_node( tree, node_idx )->x += parent_style->PADDING;
1394 RETROHTR_EDGE_TOP ==
1395 (RETROHTR_EDGE_TOP & retrohtr_node( tree, node_idx )->edge) &&
1397 RETROHTR_EDGE_LEFT ==
1398 (RETROHTR_EDGE_LEFT & retrohtr_node( tree, node_idx )->edge)
1401 if( mcss_prop_is_active_NOT_flag( parent_style->PADDING_TOP, AUTO ) ) {
1402 retrohtr_node( tree, node_idx )->y += parent_style->PADDING_TOP;
1403 }
else if( mcss_prop_is_active_NOT_flag( parent_style->PADDING, AUTO ) ) {
1404 retrohtr_node( tree, node_idx )->y += parent_style->PADDING;
1410 if( mcss_prop_is_active( effect_style.COLOR ) ) {
1411 retrohtr_node( tree, node_idx )->fg = effect_style.COLOR;
1414 if( mcss_prop_is_active( effect_style.BACKGROUND_COLOR ) ) {
1415 retrohtr_node( tree, node_idx )->bg = effect_style.BACKGROUND_COLOR;
1420 retrohtr_mark_edge_child_nodes( parser, tree, node_idx );
1422 maug_mzero( &child_prev_sibling_style,
sizeof(
struct MCSS_STYLE ) );
1423 node_iter_idx = retrohtr_node( tree, node_idx )->first_child;
1424 while( 0 <= node_iter_idx ) {
1429 parser, tree, &child_prev_sibling_style, &effect_style,
1430 node_iter_idx, d + 1 );
1432 node_iter_idx = retrohtr_node( tree, node_iter_idx )->next_sibling;
1435 assert( !mdata_vector_is_locked( &(parser->tags) ) );
1437 p_tag_iter = mdata_vector_get( &(parser->tags), tag_idx,
union MHTML_TAG );
1438 assert( NULL != p_tag_iter );
1440 if( MHTML_TAG_TYPE_INPUT == p_tag_iter->base.type ) {
1442 retval = retrogui_pos_ctl( &(tree->gui), node_idx,
1443 retrohtr_node_screen_x( tree, node_idx ),
1444 retrohtr_node_screen_y( tree, node_idx ),
1445 retrohtr_node( tree, node_idx )->w,
1446 retrohtr_node( tree, node_idx )->h );
1447 maug_cleanup_if_not_ok();
1450#if RETROHTR_TRACE_LVL > 0
1451 debug_printf( RETROHTR_TRACE_LVL,
1452 "setting node " SIZE_T_FMT
" dirty...", node_idx );
1454 retrohtr_node( tree, node_idx )->flags |= RETROHTR_NODE_FLAG_DIRTY;
1458 if( mdata_vector_is_locked( &(parser->tags) ) ) {
1465 if( NULL != prev_sibling_style ) {
1467 prev_sibling_style, &effect_style,
1468 sizeof(
struct MCSS_STYLE ) );
1478 ssize_t node_idx,
size_t d
1484 node = retrohtr_node( tree, node_idx );
1486 if( NULL == node ) {
1492 if( 0 > node->tag ) {
1496 if( RETROHTR_NODE_FLAG_DIRTY != (RETROHTR_NODE_FLAG_DIRTY & node->flags) ) {
1500 assert( !mdata_vector_is_locked( &(parser->tags) ) );
1503 p_tag = mdata_vector_get( &(parser->tags), node->tag,
union MHTML_TAG );
1504 if( NULL == p_tag ) {
1509 if( MHTML_TAG_TYPE_TEXT == p_tag->base.type ) {
1512 MDATA_STRPOOL_IDX_ERROR == p_tag->TEXT.content_idx ||
1513#ifdef RETROGXC_PRESENT
1516 (MAUG_MHANDLE)NULL == node->font_h
1522 mdata_strpool_lock( &(parser->strpool) );
1524#ifdef RETROGXC_PRESENT
1531 p_tag->TEXT.content_sz,
1532#ifdef RETROGXC_PRESENT
1537 retrohtr_node_screen_x( tree, node_idx ),
1538 retrohtr_node_screen_y( tree, node_idx ),
1539 node->w, node->h, 0 );
1541 mdata_strpool_unlock( &(parser->strpool) );
1543 }
else if( MHTML_TAG_TYPE_BODY == p_tag->base.type ) {
1545#if RETROHTR_TRACE_LVL > 0
1547 RETROHTR_TRACE_LVL,
"drawing BODY node " SIZE_T_FMT
"...", node_idx );
1551 if( RETROFLAT_COLOR_NULL != node->bg ) {
1554 retrohtr_node_screen_x( tree, node_idx ),
1555 retrohtr_node_screen_y( tree, node_idx ),
1556 retrohtr_node( tree, node_idx )->w,
1557 retrohtr_node( tree, node_idx )->h,
1558 RETROFLAT_FLAGS_FILL );
1561 }
else if( MHTML_TAG_TYPE_IMG == p_tag->base.type ) {
1564 if( !retroflat_bitmap_ok( &(retrohtr_node( tree, node_idx )->bitmap) ) ) {
1568#
if RETROHTR_TRACE_LVL > 0
1570 RETROHTR_TRACE_LVL,
"drawing IMG node " SIZE_T_FMT
"...", node_idx );
1574 NULL, &(retrohtr_node( tree, node_idx )->bitmap),
1576 retrohtr_node_screen_x( tree, node_idx ),
1577 retrohtr_node_screen_y( tree, node_idx ),
1578 retroflat_bitmap_w( &(retrohtr_node( tree, node_idx )->bitmap) ),
1579 retroflat_bitmap_h( &(retrohtr_node( tree, node_idx )->bitmap) ),
1584 }
else if( MHTML_TAG_TYPE_INPUT == p_tag->base.type ) {
1586#if RETROHTR_TRACE_LVL > 0
1587 debug_printf( RETROHTR_TRACE_LVL,
"setting tree GUI dirty..." );
1593 if( RETROFLAT_COLOR_NULL == node->bg ) {
1597#if RETROHTR_TRACE_LVL > 0
1599 RETROHTR_TRACE_LVL,
"drawing xs node " SIZE_T_FMT
"...",
1607 retrohtr_node_screen_x( tree, node_idx ),
1608 retrohtr_node_screen_y( tree, node_idx ),
1613 node->flags &= ~RETROHTR_NODE_FLAG_DIRTY;
1617 if( mdata_vector_is_locked( &(parser->tags) ) ) {
1621 if( MERROR_OK != retval ) {
1622 error_printf(
"failed drawing node: " SIZE_T_FMT, node_idx );
1627 retrohtr_tree_draw( parser, tree, node->
first_child, d + 1 );
1629 retrohtr_tree_draw( parser, tree, node->
next_sibling, d );
1634 RETROHTR_TREE_FLAG_GUI_ACTIVE ==
1635 (tree->flags & RETROHTR_TREE_FLAG_GUI_ACTIVE)
1637 retrogui_redraw_ctls( &(tree->gui) );
1647 RETROFLAT_IN_KEY* input,
1653 assert( retrohtr_tree_is_locked( tree ) );
1656 RETROHTR_TREE_FLAG_GUI_ACTIVE !=
1657 (RETROHTR_TREE_FLAG_GUI_ACTIVE & tree->flags)
1666#if RETROHTR_TRACE_LVL > 0
1668 RETROHTR_TRACE_LVL,
"setting node " SIZE_T_FMT
" dirty...", idc );
1670 retrohtr_node( tree, idc )->flags |= RETROHTR_NODE_FLAG_DIRTY;
1673 if( MERROR_OK != retval ) {
1684 ssize_t node_idx,
size_t d
1691 if( 0 > node_idx ) {
1695 assert( !mdata_vector_is_locked( &(parser->tags) ) );
1698 p_tag_iter = mdata_vector_get(
1700 if( NULL == p_tag_iter ) {
1705 maug_mzero( indents, 30 );
1706 for( i = 0 ; d > i ; i++ ) {
1707 if( maug_strlen( indents ) >= 30 ) {
1710 strcat( indents,
" " );
1716 "%s" SSIZE_T_FMT
" (tag %s): x: " SSIZE_T_FMT
", y: " SSIZE_T_FMT
1717 " (" SSIZE_T_FMT
" x " SSIZE_T_FMT
") f: "
1718#ifdef RETROGXC_PRESENT
1724 0 <= tree->
nodes[node_idx].tag ?
1725 gc_mhtml_tag_names[p_tag_iter->base.type] :
"ROOT",
1726 tree->
nodes[node_idx].x, tree->
nodes[node_idx].y,
1727 tree->
nodes[node_idx].w, tree->
nodes[node_idx].h,
1728#ifdef RETROGXC_PRESENT
1729 tree->
nodes[node_idx].font_idx
1731 tree->
nodes[node_idx].font_h
1737 retval = retrohtr_tree_dump(
1739 maug_cleanup_if_not_ok();
1741 retval = retrohtr_tree_dump(
1743 maug_cleanup_if_not_ok();
1754#if RETROHTR_TRACE_LVL > 0
1755 debug_printf( RETROHTR_TRACE_LVL,
"freeing render nodes..." );
1764 RETROHTR_TREE_FLAG_GUI_ACTIVE ==
1765 (tree->flags & RETROHTR_TREE_FLAG_GUI_ACTIVE)
1771 retrohtr_tree_unlock( tree );
1773 if( (MAUG_MHANDLE)NULL != tree->nodes_h ) {
1774 maug_mfree( tree->nodes_h );
1787#if RETROHTR_TRACE_LVL > 0
1788 debug_printf( RETROHTR_TRACE_LVL,
1789 "allocating " SIZE_T_FMT
" nodes...", tree->
nodes_sz_max );
uint16_t MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition: merror.h:28
MERROR_RETVAL retroflat_load_bitmap(const char *filename, struct RETROFLAT_BITMAP *bmp_out, uint8_t flags)
Load a bitmap into the given ::RETROFLAT_BITMAP structure if it is available. Bitmaps are subject to ...
#define RETROFLAT_INSTANCE_NULL
Pass to retroflat_blit_bitmap() instance arg if this is not a sprite (i.e. if it is a background tile...
Definition: retroflt.h:570
MERROR_RETVAL retroflat_blit_bitmap(struct RETROFLAT_BITMAP *target, struct RETROFLAT_BITMAP *src, retroflat_pxxy_t s_x, retroflat_pxxy_t s_y, retroflat_pxxy_t d_x, retroflat_pxxy_t d_y, retroflat_pxxy_t w, retroflat_pxxy_t h, int16_t instance)
Blit the contents of a ::RETROFLAT_BITMAP onto another ::RETROFLAT_BITMAP.
int8_t RETROFLAT_COLOR
Defines an index in the platform-specific color-table.
Definition: retroflt.h:326
#define RETROFLAT_FLAGS_LITERAL_PATH
Flag for retroflat_load_bitmap() to not use assets path.
Definition: retroflt.h:385
#define RETROFLAT_FLAGS_BITMAP_SILENT
flag for retroflat_load_bitmap() to not show an error dialog if a bitmap fails to load (on supported ...
Definition: retroflt.h:391
void retroflat_rect(struct RETROFLAT_BITMAP *target, const RETROFLAT_COLOR color, retroflat_pxxy_t x, retroflat_pxxy_t y, retroflat_pxxy_t w, retroflat_pxxy_t h, uint8_t flags)
Draw a rectangle onto the target ::RETROFLAT_BITMAP.
#define RETROFLAT_FLAGS_FILL
Flag for retroflat_rect() or retroflat_ellipse(), indicating drawn shape should be filled.
Definition: retroflt.h:374
int16_t retroflat_pxxy_t
Type used for surface pixel coordinates.
Definition: retroflt.h:879
retrogui_idc_t retrogui_poll_ctls(struct RETROGUI *gui, RETROFLAT_IN_KEY *p_input, struct RETROFLAT_INPUT *input_evt)
Poll for the last clicked control and maintain listboxes and menus.
MERROR_RETVAL retrogui_destroy(struct RETROGUI *gui)
Free memory held by a RETROGUI controller internally and clean up any subordinate controls.
MERROR_RETVAL retrogui_init(struct RETROGUI *gui)
Prepare a RETROGUI controller for use.
int16_t retrogui_idc_t
Unique identifying constant number for controls.
Definition: retrogui.h:330
#define mdata_strpool_get(sp, idx)
Get a string by the index of its first character in the strpool.
Definition: mdata.h:334
MERROR_RETVAL retrofont_load(const char *font_name, MAUG_MHANDLE *p_font_h, uint8_t glyph_h, uint16_t first_glyph, uint16_t glyphs_count)
Load a font for drawing.
void retrofont_string(retroflat_blit_t *target, RETROFLAT_COLOR color, const char *str, size_t str_sz, MAUG_MHANDLE font_h, retroflat_pxxy_t x, retroflat_pxxy_t y, retroflat_pxxy_t max_w, retroflat_pxxy_t max_h, uint8_t flags)
Draw a string with the given font.
size_t nodes_sz_max
Current alloc'd number of nodes in RETROHTR_RENDER_NODE::nodes_h.
Definition: retrohtr.h:67
ssize_t parent
Index of container's render node in RETROHTR_RENDER_TREE.
Definition: retrohtr.h:51
ssize_t first_child
Index of first child's render node in RETROHTR_RENDER_TREE.
Definition: retrohtr.h:53
MERROR_RETVAL retrohtr_apply_styles(struct MHTML_PARSER *parser, struct RETROHTR_RENDER_TREE *tree, struct MCSS_STYLE *parent_style, struct MCSS_STYLE *effect_style, ssize_t tag_idx)
Create a style node that is a composite of a parent style and the styles applicable to the classes/ID...
ssize_t next_sibling
Index of next sibling's render node in RETROHTR_RENDER_TREE.
Definition: retrohtr.h:55
size_t nodes_sz
Current active number of nodes in RETROHTR_RENDER_NODE::nodes_h.
Definition: retrohtr.h:65
struct RETROHTR_RENDER_NODE * nodes
Locked pointer to nodes when locked with retrohtr_tree_lock().
Definition: retrohtr.h:63
#define mdata_vector_lock(v)
Lock the vector. This should be done when items from the vector are actively being referenced,...
Definition: mdata.h:372
#define mdata_vector_unlock(v)
Unlock the vector so items may be added and removed.
Definition: mdata.h:405
#define mdata_vector_ct(v)
Number of items of MDATA_VECTOR::item_sz bytes actively stored in this vector.
Definition: mdata.h:448
Definition: retrogui.h:468
#define RETROGUI_FLAGS_DIRTY
RETROGUI::flags indicating controls should be redrawn.
Definition: retrogui.h:263
MAUG_MHANDLE font_h
Font used to draw any attached RETROGUI_CTL.
Definition: retrogui.h:494
Definition: retrohtr.h:28
Definition: retrohtr.h:59
Definition: retrogui.h:450