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) 
  103   size_t x, 
size_t y, 
size_t w, 
size_t h,
 
  104   ssize_t tag_idx, ssize_t node_idx, 
size_t d );
 
  119   struct MCSS_STYLE* parent_style, 
struct MCSS_STYLE* effect_style,
 
  124   struct MCSS_STYLE* prev_sibling_style,
 
  125   struct MCSS_STYLE* parent_style, ssize_t node_idx, 
size_t d );
 
  129   struct MCSS_STYLE* prev_sibling_style,
 
  130   struct MCSS_STYLE* parent_style, ssize_t node_idx, 
size_t d );
 
  134   ssize_t node_idx, 
size_t d );
 
  138   RETROFLAT_IN_KEY* input,
 
  143   ssize_t iter, 
size_t d );
 
  152   uint8_t auto_unlocked = 0;
 
  154   MAUG_MHANDLE new_nodes_h = (MAUG_MHANDLE)NULL;
 
  156   if( NULL != tree->
nodes ) {
 
  157      debug_printf( RETROHTR_TRACE_LVL, 
"auto-unlocking nodes..." );
 
  158      maug_munlock( tree->nodes_h, tree->
nodes );
 
  163   assert( NULL == tree->
nodes );
 
  164   assert( (MAUG_MHANDLE)NULL != tree->nodes_h );
 
  168      new_nodes_h = maug_mrealloc( tree->nodes_h, tree->
nodes_sz_max * 2,
 
  170      if( (MAUG_MHANDLE)NULL == new_nodes_h ) {
 
  172            "unable to reallocate " SIZE_T_FMT 
" nodes!",
 
  176      tree->nodes_h = new_nodes_h;
 
  181   assert( NULL == tree->
nodes );
 
  182   maug_mlock( tree->nodes_h, tree->
nodes );
 
  183   if( NULL == tree->
nodes ) {
 
  184      error_printf( 
"unable to lock nodes!" );
 
  189   debug_printf( RETROHTR_TRACE_LVL,
 
  190      "zeroing node " SIZE_T_FMT 
" (of " SIZE_T_FMT 
")...",
 
  198   maug_munlock( tree->nodes_h, tree->
nodes );
 
  202   if( auto_unlocked ) {
 
  203      debug_printf( RETROHTR_TRACE_LVL, 
"auto-locking nodes..." );
 
  204      maug_mlock( tree->nodes_h, tree->
nodes );
 
  210ssize_t retrohtr_add_node_child(
 
  213   ssize_t node_new_idx = -1,
 
  214      node_sibling_idx = -1;
 
  216   node_new_idx = retrohtr_get_next_free_node( tree );
 
  217   if( 0 > node_new_idx ) {
 
  221#ifdef RETROGXC_PRESENT 
  222   retrohtr_node( tree, node_new_idx )->font_idx = -1;
 
  224   retrohtr_node( tree, node_new_idx )->parent = node_parent_idx;
 
  225   retrohtr_node( tree, node_new_idx )->first_child = -1;
 
  226   retrohtr_node( tree, node_new_idx )->next_sibling = -1;
 
  228   if( 0 > node_parent_idx ) {
 
  230         1, 
"adding root node under " SSIZE_T_FMT 
"...", node_parent_idx );
 
  234         1, 
"adding node " SSIZE_T_FMT 
" under " SSIZE_T_FMT,
 
  235         node_new_idx, node_parent_idx );
 
  239   if( 0 > retrohtr_node( tree, node_parent_idx )->first_child ) {
 
  240      debug_printf( RETROHTR_TRACE_LVL, 
"adding first child..." );
 
  241      assert( -1 == retrohtr_node( tree, node_parent_idx )->first_child );
 
  242      retrohtr_node( tree, node_parent_idx )->first_child = node_new_idx;
 
  244      assert( NULL != retrohtr_node( tree, node_parent_idx ) );
 
  245      node_sibling_idx = retrohtr_node( tree, node_parent_idx )->first_child;
 
  246      assert( NULL != retrohtr_node( tree, node_sibling_idx ) );
 
  247      while( 0 <= retrohtr_node( tree, node_sibling_idx )->next_sibling ) {
 
  249            retrohtr_node( tree, node_sibling_idx )->next_sibling;
 
  251      retrohtr_node( tree, node_sibling_idx )->next_sibling = node_new_idx;
 
  261   size_t x, 
size_t y, 
size_t w, 
size_t h,
 
  262   ssize_t tag_idx, ssize_t node_idx, 
size_t d
 
  264   ssize_t node_new_idx = -1;
 
  265   ssize_t tag_iter_idx = -1;
 
  268   ssize_t tag_next_idx = 0;
 
  270   debug_printf( RETROHTR_TRACE_LVL, 
 
  271      "creating render node for tag: " SSIZE_T_FMT, tag_idx );
 
  278   p_tag_iter = mdata_vector_get( &(parser->tags), tag_idx, 
union MHTML_TAG );
 
  279   if( NULL == p_tag_iter ) {
 
  285      assert( MHTML_TAG_TYPE_BODY == p_tag_iter->base.type );
 
  287      node_new_idx = retrohtr_add_node_child( tree, node_idx );
 
  288      if( 0 > node_new_idx ) {
 
  291      debug_printf( RETROHTR_TRACE_LVL,
 
  292         "created initial root node: " SIZE_T_FMT, node_new_idx );
 
  294      node_idx = node_new_idx;
 
  297      retrohtr_node( tree, node_idx )->tag = tag_idx;
 
  299      retrohtr_node( tree, node_idx )->x = x;
 
  300      retrohtr_node( tree, node_idx )->y = y;
 
  301      retrohtr_node( tree, node_idx )->w = w;
 
  302      retrohtr_node( tree, node_idx )->h = h;
 
  305   tag_iter_idx = p_tag_iter->base.first_child;
 
  306   while( 0 <= tag_iter_idx ) {
 
  307      node_new_idx = retrohtr_add_node_child( tree, node_idx );
 
  308      p_tag_iter = mdata_vector_get(
 
  309         &(parser->tags), tag_iter_idx, 
union MHTML_TAG );
 
  310      assert( NULL != p_tag_iter );
 
  311      if( 0 > node_new_idx ) {
 
  315      retrohtr_node( tree, node_new_idx )->tag = tag_iter_idx;
 
  317      debug_printf( RETROHTR_TRACE_LVL,
 
  318         "rendering node " SSIZE_T_FMT 
" (%s) under node " SSIZE_T_FMT,
 
  320         gc_mhtml_tag_names[p_tag_iter->base.type],
 
  324      if( MHTML_TAG_TYPE_IMG == p_tag_iter->base.type ) {
 
  328            &(retrohtr_node( tree, node_new_idx )->bitmap),
 
  330         if( MERROR_OK == retval ) {
 
  331            debug_printf( RETROHTR_TRACE_LVL, 
"loaded img: %s", 
 
  332               p_tag_iter->IMG.src );
 
  334            error_printf( 
"could not load img: %s", p_tag_iter->IMG.src );
 
  338      tag_next_idx = p_tag_iter->base.next_sibling;
 
  342      retval = retrohtr_tree_create( parser, tree, x, y, w, h,
 
  343         tag_iter_idx, node_new_idx, d + 1 );
 
  344      maug_cleanup_if_not_ok();
 
  348      tag_iter_idx = tag_next_idx;
 
  353   if( mdata_vector_is_locked( &(parser->tags) ) ) {
 
  362   struct MCSS_STYLE* parent_style, 
struct MCSS_STYLE* effect_style,
 
  366   ssize_t tag_style_idx = -1;
 
  369   struct MCSS_STYLE* style = NULL;
 
  372   debug_printf( RETROHTR_TRACE_LVL,
 
  373      "applying styles for tag: " SSIZE_T_FMT, tag_idx );
 
  375   assert( !mdata_vector_is_locked( &(parser->tags) ) );
 
  379   maug_mzero( effect_style, 
sizeof( 
struct MCSS_STYLE ) );
 
  384   p_tag_iter = mdata_vector_get( &(parser->tags), tag_idx, 
union MHTML_TAG );
 
  385   if( NULL == p_tag_iter ) {
 
  389   tag_type = p_tag_iter->base.type;
 
  392   if( 0 < p_tag_iter->base.classes_sz ) {
 
  394         style = mdata_vector_get(
 
  395            &(parser->styler.styles), i, 
struct MCSS_STYLE );
 
  400               p_tag_iter->base.classes,
 
  402               p_tag_iter->base.classes_sz
 
  405            debug_printf( RETROHTR_TRACE_LVL, 
"found style for tag class: %s",
 
  408            mcssmerge_styles( effect_style, parent_style, style, tag_type );
 
  414   if( 0 < p_tag_iter->base.id_sz ) {
 
  416         style = mdata_vector_get(
 
  417            &(parser->styler.styles), i, 
struct MCSS_STYLE );
 
  424               p_tag_iter->base.id_sz
 
  427            debug_printf( RETROHTR_TRACE_LVL, 
"found style for tag ID: %s",
 
  430            mcssmerge_styles( effect_style, parent_style, style, tag_type );
 
  436   tag_style_idx = p_tag_iter->base.style;
 
  443   style = mdata_vector_get(
 
  444      &(parser->styler.styles), tag_style_idx, 
struct MCSS_STYLE );
 
  447   mcssmerge_styles( effect_style, parent_style, style, tag_type );
 
  456   struct MCSS_PARSER* styler,
 
  457#ifdef RETROGXC_PRESENT
 
  460   MAUG_MHANDLE* font_h_p,
 
  462   struct MCSS_STYLE* effect_style
 
  466#ifdef RETROGXC_PRESENT 
  467   if( 0 <= *font_idx_p ) {
 
  468      error_printf( 
"tried to load font but font already loaded, idx: " 
  469         SSIZE_T_FMT, *font_idx_p );
 
  471   if( (MAUG_MHANDLE)NULL != *font_h_p ) {
 
  472      error_printf( 
"tried to load font but font already loaded, p: %p",
 
  478   mdata_strpool_lock( &(styler->strpool) );
 
  480   debug_printf( RETROHTR_TRACE_LVL,
 
  481      "loading font: %s (" SSIZE_T_FMT 
")",
 
  482      mdata_strpool_get( &(styler->strpool), effect_style->FONT_FAMILY ),
 
  483      effect_style->FONT_FAMILY );
 
  485   if( 0 >= effect_style->FONT_FAMILY ) {
 
  486      error_printf( 
"style has no font associated!" );
 
  493#ifdef RETROGXC_PRESENT 
  496         mdata_strpool_get( &(styler->strpool), effect_style->FONT_FAMILY ),
 
  500         mdata_strpool_get( &(styler->strpool), effect_style->FONT_FAMILY ),
 
  501         font_h_p, 0, 33, 93 );
 
  506   mdata_strpool_unlock( &(styler->strpool) );
 
  513   struct MCSS_STYLE* effect_style
 
  519      RETROHTR_TREE_FLAG_GUI_ACTIVE ==
 
  520         (RETROHTR_TREE_FLAG_GUI_ACTIVE & tree->flags)
 
  522      debug_printf( RETROHTR_TRACE_LVL, 
"tree GUI already active!" );
 
  530   maug_cleanup_if_not_ok();
 
  532   retval = retrohtr_load_font(
 
  534#ifdef RETROGXC_PRESENT
 
  535      &(tree->gui.font_idx),
 
  540   maug_cleanup_if_not_ok();
 
  542   tree->flags |= RETROHTR_TREE_FLAG_GUI_ACTIVE;
 
  544   debug_printf( RETROHTR_TRACE_LVL, 
"tree GUI initialized!" );
 
  552   struct MCSS_STYLE* prev_sibling_style,
 
  553   struct MCSS_STYLE* parent_style, ssize_t node_idx, 
size_t d
 
  555   struct MCSS_STYLE effect_style;
 
  556   struct MCSS_STYLE child_prev_sibling_style;
 
  557   struct MCSS_STYLE child_style;
 
  558   ssize_t child_iter_idx = -1;
 
  559   ssize_t tag_idx = -1;
 
  560   ssize_t node_iter_idx = -1;
 
  561   size_t this_line_w = 0;
 
  562   size_t this_line_h = 0;
 
  568   if( NULL == retrohtr_node( tree, node_idx ) ) {
 
  572   tag_idx = retrohtr_node( tree, node_idx )->tag;
 
  575      parser, tree, parent_style, &effect_style, tag_idx );
 
  576   maug_cleanup_if_not_ok();
 
  578   assert( !mdata_vector_is_locked( &(parser->tags) ) );
 
  581   p_tag_iter = mdata_vector_get( &(parser->tags), tag_idx, 
union MHTML_TAG );
 
  582   assert( NULL != p_tag_iter );
 
  586   if( mcss_prop_is_active( effect_style.POSITION ) ) {
 
  587      debug_printf( RETROHTR_TRACE_LVL,
 
  588         "node " SSIZE_T_FMT 
": applying %s positioning",
 
  589         node_idx, gc_mcss_position_names[effect_style.POSITION] );
 
  597      retrohtr_node( tree, node_idx )->pos = effect_style.POSITION;
 
  598      retrohtr_node( tree, node_idx )->pos_flags = effect_style.POSITION_flags;
 
  606   if( mcss_prop_is_active_NOT_flag( effect_style.WIDTH, AUTO ) ) {
 
  607      retrohtr_node( tree, node_idx )->w = effect_style.WIDTH;
 
  610   if( mcss_prop_is_active_NOT_flag( effect_style.HEIGHT, AUTO ) ) {
 
  611      retrohtr_node( tree, node_idx )->h = effect_style.HEIGHT;
 
  617   retval = retrohtr_load_font(
 
  619#ifdef RETROGXC_PRESENT
 
  620      &(retrohtr_node( tree, node_idx )->font_idx),
 
  622      &(retrohtr_node( tree, node_idx )->font_h),
 
  625   maug_cleanup_if_not_ok();
 
  627   if( 0 <= tag_idx && MHTML_TAG_TYPE_TEXT == p_tag_iter->base.type ) {
 
  630      mdata_strpool_lock( &(parser->strpool) );
 
  632#ifdef RETROGXC_PRESENT 
  638         mdata_strpool_get( &(parser->strpool), p_tag_iter->TEXT.content_idx ),
 
  639         p_tag_iter->TEXT.content_sz,
 
  640#ifdef RETROGXC_PRESENT
 
  641         retrohtr_node( tree, node_idx )->font_idx,
 
  643         retrohtr_node( tree, node_idx )->font_h,
 
  646         retrohtr_node_parent( tree, node_idx )->w,
 
  647         retrohtr_node_parent( tree, node_idx )->h,
 
  648         &(retrohtr_node( tree, node_idx )->w),
 
  649         &(retrohtr_node( tree, node_idx )->h), 0 );
 
  651      debug_printf( RETROHTR_TRACE_LVL, 
"TEXT w: " SIZE_T_FMT, 
 
  652         retrohtr_node( tree, node_idx )->w );
 
  654      mdata_strpool_unlock( &(parser->strpool) );
 
  658      MHTML_TAG_TYPE_INPUT == p_tag_iter->base.type
 
  662      retval = retrohtr_tree_gui( tree, &(parser->styler), &effect_style );
 
  666         MERROR_OK != retrogui_init_ctl(
 
  667            &ctl, RETROGUI_CTL_TYPE_BUTTON, node_idx )
 
  669         error_printf( 
"could not initialize control!" );
 
  673      p_tag_node = mdata_vector_get(
 
  675         retrohtr_node( tree, node_idx )->tag, 
union MHTML_TAG );
 
  677      ctl.base.x = retrohtr_node( tree, node_idx )->x;
 
  678      ctl.base.y = retrohtr_node( tree, node_idx )->y;
 
  681      ctl.BUTTON.label = p_tag_node->INPUT.value;
 
  684      retrohtr_node( tree, node_idx )->w = ctl.base.w;
 
  685      retrohtr_node( tree, node_idx )->h = ctl.base.h;
 
  687      debug_printf( RETROHTR_TRACE_LVL, 
"initialized control for INPUT..." );
 
  689      retrogui_push_ctl( &(tree->gui), &ctl );
 
  691   } 
else if( 0 <= tag_idx && MHTML_TAG_TYPE_IMG == p_tag_iter->base.type ) {
 
  693      if( retroflat_bitmap_ok( &(retrohtr_node( tree, node_idx )->bitmap) ) ) {
 
  694         retrohtr_node( tree, node_idx )->w =
 
  695            retroflat_bitmap_w( &(retrohtr_node( tree, node_idx )->bitmap) );
 
  696         retrohtr_node( tree, node_idx )->h =
 
  697            retroflat_bitmap_h( &(retrohtr_node( tree, node_idx )->bitmap) );
 
  700      debug_printf( RETROHTR_TRACE_LVL, 
"TEXT w: " SIZE_T_FMT, 
 
  701         retrohtr_node( tree, node_idx )->w );
 
  706      maug_mzero( &child_prev_sibling_style, 
sizeof( 
struct MCSS_STYLE ) );
 
  707      node_iter_idx = retrohtr_node( tree, node_idx )->first_child;
 
  709      while( 0 <= node_iter_idx ) {
 
  711            parser, tree, &child_prev_sibling_style, &effect_style,
 
  712            node_iter_idx, d + 1 );
 
  714         node_iter_idx = retrohtr_node( tree, node_iter_idx )->next_sibling;
 
  718   if( mdata_vector_is_locked( &(parser->tags) ) ) {
 
  723   if( 0 == retrohtr_node( tree, node_idx )->w ) {
 
  725         MCSS_DISPLAY_BLOCK == effect_style.DISPLAY &&
 
  726         0 <= retrohtr_node( tree, node_idx )->parent
 
  730         retrohtr_node( tree, node_idx )->w =
 
  731            retrohtr_node_parent( tree, node_idx )->w;
 
  735      child_iter_idx = retrohtr_node( tree, node_idx )->first_child;
 
  736      while( 0 <= child_iter_idx ) {
 
  737         assert( !mdata_vector_is_locked( &(parser->tags) ) );
 
  739            parser, tree, &effect_style, &child_style,
 
  740            retrohtr_node( tree, child_iter_idx )->tag );
 
  741         maug_cleanup_if_not_ok();
 
  744         if( MCSS_POSITION_ABSOLUTE == child_style.POSITION ) {
 
  746               retrohtr_node( tree, child_iter_idx )->next_sibling;
 
  750         if( MCSS_DISPLAY_BLOCK == child_style.DISPLAY ) {
 
  755               retrohtr_node( tree, child_iter_idx )->w >
 
  756                  retrohtr_node( tree, node_idx )->w
 
  759               retrohtr_node( tree, node_idx )->w =
 
  760                  retrohtr_node( tree, child_iter_idx )->w;
 
  764            this_line_w += retrohtr_node( tree, child_iter_idx )->w;
 
  766            if( this_line_w > retrohtr_node( tree, node_idx )->w ) {
 
  768               retrohtr_node( tree, node_idx )->w = this_line_w;
 
  771         child_iter_idx = retrohtr_node( tree, child_iter_idx )->next_sibling;
 
  776   if( 0 == retrohtr_node( tree, node_idx )->h ) {
 
  778      child_iter_idx = retrohtr_node( tree, node_idx )->first_child;
 
  779      while( 0 <= child_iter_idx ) {
 
  780         assert( !mdata_vector_is_locked( &(parser->tags) ) );
 
  782            parser, tree, &effect_style, &child_style,
 
  783            retrohtr_node( tree, child_iter_idx )->tag );
 
  786         if( MCSS_POSITION_ABSOLUTE == child_style.POSITION ) {
 
  787            child_iter_idx = retrohtr_node( tree, child_iter_idx )->next_sibling;
 
  791         if( MCSS_DISPLAY_BLOCK == child_style.DISPLAY ) {
 
  793            retrohtr_node( tree, node_idx )->h += this_line_h;
 
  796            this_line_h = retrohtr_node( tree, child_iter_idx )->h;
 
  799            if( this_line_h < retrohtr_node( tree, child_iter_idx )->h ) {
 
  800               this_line_h = retrohtr_node( tree, child_iter_idx )->h;
 
  804         child_iter_idx = retrohtr_node( tree, child_iter_idx )->next_sibling;
 
  808      retrohtr_node( tree, node_idx )->h += this_line_h;
 
  817   if( mcss_prop_is_active_NOT_flag( effect_style.PADDING_LEFT, AUTO ) ) {
 
  818      retrohtr_node( tree, node_idx )->w += effect_style.PADDING_LEFT;
 
  819   } 
else if( mcss_prop_is_active_NOT_flag( effect_style.PADDING, AUTO ) ) {
 
  820      retrohtr_node( tree, node_idx )->w += effect_style.PADDING;
 
  824   if( mcss_prop_is_active_NOT_flag( effect_style.PADDING_RIGHT, AUTO ) ) {
 
  825      retrohtr_node( tree, node_idx )->w += effect_style.PADDING_RIGHT;
 
  826   } 
else if( mcss_prop_is_active_NOT_flag( effect_style.PADDING, AUTO ) ) {
 
  827      retrohtr_node( tree, node_idx )->w += effect_style.PADDING;
 
  831   if( mcss_prop_is_active_NOT_flag( effect_style.PADDING_TOP, AUTO ) ) {
 
  832      retrohtr_node( tree, node_idx )->h += effect_style.PADDING_TOP;
 
  833   } 
else if( mcss_prop_is_active_NOT_flag( effect_style.PADDING, AUTO ) ) {
 
  834      retrohtr_node( tree, node_idx )->h += effect_style.PADDING;
 
  838   if( mcss_prop_is_active_NOT_flag( effect_style.PADDING_BOTTOM, AUTO ) ) {
 
  839      retrohtr_node( tree, node_idx )->h += effect_style.PADDING_BOTTOM;
 
  840   } 
else if( mcss_prop_is_active_NOT_flag( effect_style.PADDING, AUTO ) ) {
 
  841      retrohtr_node( tree, node_idx )->h += effect_style.PADDING;
 
  844   debug_printf( RETROHTR_TRACE_LVL,
 
  845      "setting node " SIZE_T_FMT 
" dirty...", node_idx );
 
  846   retrohtr_node( tree, node_idx )->flags |= RETROHTR_NODE_FLAG_DIRTY;
 
  850   if( mdata_vector_is_locked( &(parser->tags) ) ) {
 
  857   if( NULL != prev_sibling_style ) {
 
  859         prev_sibling_style, &effect_style,
 
  860         sizeof( 
struct MCSS_STYLE ) );
 
  868#define retrohtr_break_on_active_pos( iter_idx ) \ 
  869   if( mcss_prop_is_active( retrohtr_node( tree, iter_idx )->pos ) ) { \ 
  873static ssize_t retrohtr_find_prev_sibling_in_box_model(
 
  877   ssize_t sibling_iter_idx = -1;
 
  878   ssize_t sibling_found_idx = -1;
 
  880   if( 0 > retrohtr_node( tree, node_idx )->parent ) {
 
  885   sibling_iter_idx = retrohtr_node_parent( tree, node_idx )->first_child;
 
  887   if( sibling_iter_idx == node_idx ) {
 
  892   while( 0 <= sibling_iter_idx && node_idx != sibling_iter_idx ) {
 
  895         MCSS_POSITION_ABSOLUTE != retrohtr_node( tree, sibling_iter_idx )->pos
 
  897         sibling_found_idx = sibling_iter_idx;
 
  902      sibling_iter_idx = retrohtr_node( tree, sibling_iter_idx )->next_sibling;
 
  906   return sibling_found_idx;
 
  911   ssize_t node_parent_idx
 
  913   ssize_t node_sibling_idx = -1;
 
  915   struct MCSS_STYLE effect_style;
 
  920   node_sibling_idx = retrohtr_node( tree, node_parent_idx )->first_child;
 
  921   while( 0 <= node_sibling_idx ) {
 
  922      maug_mzero( &effect_style, 
sizeof( 
struct MCSS_STYLE ) );
 
  924         parser, tree, NULL, &effect_style,
 
  925         retrohtr_node( tree, node_sibling_idx )->tag );
 
  927      if( MCSS_POSITION_ABSOLUTE == effect_style.POSITION ) {
 
  929         retrohtr_node( tree, node_sibling_idx )->edge |= RETROHTR_EDGE_INSIDE;
 
  931      } 
else if( MCSS_DISPLAY_INLINE == effect_style.DISPLAY ) {
 
  934            retrohtr_node( tree, node_sibling_idx )->edge |= RETROHTR_EDGE_LEFT;
 
  937            retrohtr_node( tree, node_sibling_idx )->edge |= RETROHTR_EDGE_TOP;
 
  939         if( 0 < row_idx && 0 < col_idx ) {
 
  940            retrohtr_node( tree, node_sibling_idx )->edge |= RETROHTR_EDGE_INSIDE;
 
  953            retrohtr_node( tree, node_sibling_idx )->edge |= RETROHTR_EDGE_TOP;
 
  957         retrohtr_node( tree, node_sibling_idx )->edge |= RETROHTR_EDGE_LEFT;
 
  960      assert( !mdata_vector_is_locked( &(parser->tags) ) );
 
  963      p_tag_iter = mdata_vector_get( &(parser->tags),
 
  964         retrohtr_node( tree, node_sibling_idx )->tag,
 
  966      assert( NULL != p_tag_iter );
 
  968      debug_printf( 1, 
"marking node " SIZE_T_FMT 
" (%s) edge: %u",
 
  970         gc_mhtml_tag_names[p_tag_iter->base.type],
 
  971         retrohtr_node( tree, node_sibling_idx )->edge );
 
  976         retrohtr_node( tree, node_sibling_idx )->next_sibling;
 
  981   if( mdata_vector_is_locked( &(parser->tags) ) ) {
 
  990   struct MCSS_STYLE* prev_sibling_style,
 
  991   struct MCSS_STYLE* parent_style, ssize_t node_idx, 
size_t d
 
  993   struct MCSS_STYLE child_prev_sibling_style;
 
  994   struct MCSS_STYLE effect_style;
 
  995   ssize_t child_iter_idx = -1;
 
  996   ssize_t tag_idx = -1;
 
  997   ssize_t node_iter_idx = -1;
 
  998   ssize_t prev_sibling_idx = -1;
 
 1002   if( NULL == retrohtr_node( tree, node_idx ) ) {
 
 1006   tag_idx = retrohtr_node( tree, node_idx )->tag;
 
 1009      parser, tree, parent_style, &effect_style, tag_idx );
 
 1012      retrohtr_find_prev_sibling_in_box_model( tree, node_idx );
 
 1016   if( MCSS_POSITION_ABSOLUTE == effect_style.POSITION ) {
 
 1019      if( mcss_prop_is_active_NOT_flag( effect_style.LEFT, AUTO ) ) {
 
 1021         child_iter_idx = retrohtr_node( tree, node_idx )->parent;
 
 1022         while( 0 <= retrohtr_node( tree, child_iter_idx )->parent ) {
 
 1023            retrohtr_break_on_active_pos( child_iter_idx );
 
 1024            child_iter_idx = retrohtr_node( tree, child_iter_idx )->parent;
 
 1028         retrohtr_node( tree, node_idx )->x =
 
 1029            retrohtr_node( tree, child_iter_idx )->x + effect_style.LEFT;
 
 1031      if( mcss_prop_is_active_NOT_flag( effect_style.RIGHT, AUTO ) ) {
 
 1033         child_iter_idx = retrohtr_node( tree, node_idx )->parent;
 
 1034         while( 0 <= retrohtr_node( tree, child_iter_idx )->parent ) {
 
 1035            retrohtr_break_on_active_pos( child_iter_idx );
 
 1036            child_iter_idx = retrohtr_node( tree, child_iter_idx )->parent;
 
 1040         retrohtr_node( tree, node_idx )->x = 
 
 1041            retrohtr_node( tree, child_iter_idx )->w - 
 
 1042            retrohtr_node( tree, node_idx )->w - 
 
 1047      MCSS_DISPLAY_INLINE == effect_style.DISPLAY &&
 
 1048      MCSS_DISPLAY_INLINE == prev_sibling_style->DISPLAY &&
 
 1049      0 <= prev_sibling_idx
 
 1052      retrohtr_node( tree, node_idx )->x =
 
 1053         retrohtr_node( tree, prev_sibling_idx )->x +
 
 1054         retrohtr_node( tree, prev_sibling_idx )->w;
 
 1056   } 
else if( 0 <= retrohtr_node( tree, node_idx )->parent ) {
 
 1057      retrohtr_node( tree, node_idx )->x = retrohtr_node_parent( tree, node_idx )->x;
 
 1064   if( MCSS_POSITION_ABSOLUTE == effect_style.POSITION ) {
 
 1067      if( mcss_prop_is_active_NOT_flag( effect_style.TOP, AUTO ) ) {
 
 1069         child_iter_idx = retrohtr_node( tree, node_idx )->parent;
 
 1070         while( 0 <= retrohtr_node( tree, child_iter_idx )->parent ) {
 
 1071            retrohtr_break_on_active_pos( child_iter_idx );
 
 1072            child_iter_idx = retrohtr_node( tree, child_iter_idx )->parent;
 
 1076         retrohtr_node( tree, node_idx )->y = 
 
 1077            retrohtr_node( tree, child_iter_idx )->y + effect_style.TOP;
 
 1079      if( mcss_prop_is_active_NOT_flag( effect_style.BOTTOM, AUTO ) ) {
 
 1081         child_iter_idx = retrohtr_node( tree, node_idx )->parent;
 
 1082         while( 0 <= retrohtr_node( tree, child_iter_idx )->parent ) {
 
 1083            retrohtr_break_on_active_pos( child_iter_idx );
 
 1084            child_iter_idx = retrohtr_node( tree, child_iter_idx )->parent;
 
 1088         retrohtr_node( tree, node_idx )->y = 
 
 1089            retrohtr_node( tree, child_iter_idx )->h - 
 
 1090            retrohtr_node( tree, node_idx )->h - 
 
 1091            effect_style.BOTTOM;
 
 1095      MCSS_DISPLAY_INLINE == effect_style.DISPLAY &&
 
 1096      MCSS_DISPLAY_INLINE == prev_sibling_style->DISPLAY &&
 
 1097      0 <= prev_sibling_idx
 
 1100      retrohtr_node( tree, node_idx )->y = retrohtr_node( tree, prev_sibling_idx )->y;
 
 1102   } 
else if( 0 <= prev_sibling_idx ) {
 
 1109      retrohtr_node( tree, node_idx )->y =
 
 1110         retrohtr_node( tree, prev_sibling_idx )->y +
 
 1111         retrohtr_node( tree, prev_sibling_idx )->h;
 
 1113   } 
else if( 0 <= retrohtr_node( tree, node_idx )->parent ) {
 
 1116      retrohtr_node( tree, node_idx )->y = retrohtr_node_parent( tree, node_idx )->y;
 
 1122      MCSS_POSITION_ABSOLUTE != retrohtr_node( tree, node_idx )->pos &&
 
 1123      0 <= retrohtr_node( tree, node_idx )->parent &&
 
 1124      mcss_prop_is_active_flag( effect_style.MARGIN_LEFT, AUTO ) &&
 
 1125      mcss_prop_is_active_flag( effect_style.MARGIN_RIGHT, AUTO )
 
 1128      retrohtr_node( tree, node_idx )->x =
 
 1129         retrohtr_node_parent( tree, node_idx )->x +
 
 1130         (retrohtr_node_parent( tree, node_idx )->w >> 1) -
 
 1131         (retrohtr_node( tree, node_idx )->w >> 1);
 
 1134      0 <= retrohtr_node( tree, node_idx )->parent &&
 
 1135      mcss_prop_is_active_flag( effect_style.MARGIN_LEFT, AUTO ) &&
 
 1136      mcss_prop_is_active_NOT_flag( effect_style.MARGIN_RIGHT, AUTO )
 
 1140      retrohtr_node( tree, node_idx )->x = 
 
 1141         retrohtr_node_parent( tree, node_idx )->w -
 
 1142         retrohtr_node( tree, node_idx )->w;
 
 1144   } 
else if( mcss_prop_is_active( effect_style.MARGIN_LEFT ) ) {
 
 1146      retrohtr_node( tree, node_idx )->x += effect_style.MARGIN_LEFT;
 
 1155   debug_printf( 1, 
"(d: " SIZE_T_FMT 
") node " SIZE_T_FMT 
" is on edge: %u",
 
 1156      d, node_idx, retrohtr_node( tree, node_idx )->edge );
 
 1160      RETROHTR_EDGE_UNKNOWN != retrohtr_node( tree, node_idx )->edge );
 
 1163      RETROHTR_EDGE_LEFT ==
 
 1164         (RETROHTR_EDGE_LEFT & retrohtr_node( tree, node_idx )->edge)
 
 1167      if( mcss_prop_is_active_NOT_flag( parent_style->PADDING_LEFT, AUTO ) ) {
 
 1168         retrohtr_node( tree, node_idx )->x += parent_style->PADDING_LEFT;
 
 1169      } 
else if( mcss_prop_is_active_NOT_flag( parent_style->PADDING, AUTO ) ) {
 
 1170         retrohtr_node( tree, node_idx )->x += parent_style->PADDING;
 
 1175      RETROHTR_EDGE_TOP ==
 
 1176         (RETROHTR_EDGE_TOP & retrohtr_node( tree, node_idx )->edge) &&
 
 1178      RETROHTR_EDGE_LEFT ==
 
 1179         (RETROHTR_EDGE_LEFT & retrohtr_node( tree, node_idx )->edge)
 
 1182      if( mcss_prop_is_active_NOT_flag( parent_style->PADDING_TOP, AUTO ) ) {
 
 1183         retrohtr_node( tree, node_idx )->y += parent_style->PADDING_TOP;
 
 1184      } 
else if( mcss_prop_is_active_NOT_flag( parent_style->PADDING, AUTO ) ) {
 
 1185         retrohtr_node( tree, node_idx )->y += parent_style->PADDING;
 
 1191   if( mcss_prop_is_active( effect_style.COLOR ) ) {
 
 1192      retrohtr_node( tree, node_idx )->fg = effect_style.COLOR;
 
 1195   if( mcss_prop_is_active( effect_style.BACKGROUND_COLOR ) ) {
 
 1196      retrohtr_node( tree, node_idx )->bg = effect_style.BACKGROUND_COLOR;
 
 1201   retrohtr_mark_edge_child_nodes( parser, tree, node_idx );
 
 1203   maug_mzero( &child_prev_sibling_style, 
sizeof( 
struct MCSS_STYLE ) );
 
 1204   node_iter_idx = retrohtr_node( tree, node_idx )->first_child;
 
 1205   while( 0 <= node_iter_idx ) {
 
 1210         parser, tree, &child_prev_sibling_style, &effect_style,
 
 1211         node_iter_idx, d + 1 );
 
 1213      node_iter_idx = retrohtr_node( tree, node_iter_idx )->next_sibling;
 
 1216   assert( !mdata_vector_is_locked( &(parser->tags) ) );
 
 1218   p_tag_iter = mdata_vector_get( &(parser->tags), tag_idx, 
union MHTML_TAG );
 
 1219   assert( NULL != p_tag_iter );
 
 1221   if( MHTML_TAG_TYPE_INPUT == p_tag_iter->base.type ) {
 
 1223      retval = retrogui_pos_ctl( &(tree->gui), node_idx,
 
 1224         retrohtr_node_screen_x( tree, node_idx ),
 
 1225         retrohtr_node_screen_y( tree, node_idx ),
 
 1226         retrohtr_node( tree, node_idx )->w,
 
 1227         retrohtr_node( tree, node_idx )->h );
 
 1228      maug_cleanup_if_not_ok();
 
 1231   debug_printf( RETROHTR_TRACE_LVL,
 
 1232      "setting node " SIZE_T_FMT 
" dirty...", node_idx );
 
 1233   retrohtr_node( tree, node_idx )->flags |= RETROHTR_NODE_FLAG_DIRTY;
 
 1237   if( mdata_vector_is_locked( &(parser->tags) ) ) {
 
 1244   if( NULL != prev_sibling_style ) {
 
 1246         prev_sibling_style, &effect_style,
 
 1247         sizeof( 
struct MCSS_STYLE ) );
 
 1255   ssize_t node_idx, 
size_t d
 
 1261   node = retrohtr_node( tree, node_idx );
 
 1263   if( NULL == node ) {
 
 1269   if( 0 > node->tag ) {
 
 1273   if( RETROHTR_NODE_FLAG_DIRTY != (RETROHTR_NODE_FLAG_DIRTY & node->flags) ) {
 
 1277   assert( !mdata_vector_is_locked( &(parser->tags) ) );
 
 1280   p_tag = mdata_vector_get( &(parser->tags), node->tag, 
union MHTML_TAG );
 
 1281   if( NULL == p_tag ) {
 
 1286   if( MHTML_TAG_TYPE_TEXT == p_tag->base.type ) {
 
 1289         0 > p_tag->TEXT.content_idx ||
 
 1290#ifdef RETROGXC_PRESENT
 
 1293         (MAUG_MHANDLE)NULL == node->font_h
 
 1299      mdata_strpool_lock( &(parser->strpool) );
 
 1301#ifdef RETROGXC_PRESENT 
 1307         mdata_strpool_get( &(parser->strpool), p_tag->TEXT.content_idx ),
 
 1308         p_tag->TEXT.content_sz,
 
 1309#ifdef RETROGXC_PRESENT
 
 1314         retrohtr_node_screen_x( tree, node_idx ),
 
 1315         retrohtr_node_screen_y( tree, node_idx ),
 
 1316         node->w, node->h, 0 );
 
 1318      mdata_strpool_unlock( &(parser->strpool) );
 
 1320   } 
else if( MHTML_TAG_TYPE_BODY == p_tag->base.type ) {
 
 1323         RETROHTR_TRACE_LVL, 
"drawing BODY node " SIZE_T_FMT 
"...", node_idx );
 
 1326      if( RETROFLAT_COLOR_NULL != node->bg ) {
 
 1329            retrohtr_node_screen_x( tree, node_idx ),
 
 1330            retrohtr_node_screen_y( tree, node_idx ),
 
 1331            retrohtr_node( tree, node_idx )->w,
 
 1332            retrohtr_node( tree, node_idx )->h,
 
 1333            RETROFLAT_FLAGS_FILL );
 
 1336   } 
else if( MHTML_TAG_TYPE_IMG == p_tag->base.type ) {
 
 1339      if( !retroflat_bitmap_ok( &(retrohtr_node( tree, node_idx )->bitmap) ) ) {
 
 1344         RETROHTR_TRACE_LVL, 
"drawing IMG node " SIZE_T_FMT 
"...", node_idx );
 
 1347         NULL, &(retrohtr_node( tree, node_idx )->bitmap),
 
 1349         retrohtr_node_screen_x( tree, node_idx ),
 
 1350         retrohtr_node_screen_y( tree, node_idx ),
 
 1351         retroflat_bitmap_w( &(retrohtr_node( tree, node_idx )->bitmap) ),
 
 1352         retroflat_bitmap_h( &(retrohtr_node( tree, node_idx )->bitmap) ),
 
 1357   } 
else if( MHTML_TAG_TYPE_INPUT == p_tag->base.type ) {
 
 1360         RETROHTR_TRACE_LVL, 
"setting tree GUI dirty..." );
 
 1365      if( RETROFLAT_COLOR_NULL == node->bg ) {
 
 1370         RETROHTR_TRACE_LVL, 
"drawing xs node " SIZE_T_FMT 
"...",
 
 1377         retrohtr_node_screen_x( tree, node_idx ),
 
 1378         retrohtr_node_screen_y( tree, node_idx ),
 
 1383   node->flags &= ~RETROHTR_NODE_FLAG_DIRTY;
 
 1387   if( mdata_vector_is_locked( &(parser->tags) ) ) {
 
 1391   if( MERROR_OK != retval ) {
 
 1392      error_printf( 
"failed drawing node: " SIZE_T_FMT, node_idx );
 
 1397   retrohtr_tree_draw( parser, tree, node->
first_child, d + 1 );
 
 1399   retrohtr_tree_draw( parser, tree, node->
next_sibling, d );
 
 1404      RETROHTR_TREE_FLAG_GUI_ACTIVE ==
 
 1405         (tree->flags & RETROHTR_TREE_FLAG_GUI_ACTIVE)
 
 1407      retrogui_redraw_ctls( &(tree->gui) );
 
 1415   RETROFLAT_IN_KEY* input,
 
 1421   assert( retrohtr_tree_is_locked( tree ) );
 
 1424      RETROHTR_TREE_FLAG_GUI_ACTIVE !=
 
 1425         (RETROHTR_TREE_FLAG_GUI_ACTIVE & tree->flags)
 
 1435         RETROHTR_TRACE_LVL, 
"setting node " SIZE_T_FMT 
" dirty...", idc );
 
 1436      retrohtr_node( tree, idc )->flags |= RETROHTR_NODE_FLAG_DIRTY;
 
 1439   if( MERROR_OK != retval ) {
 
 1448   ssize_t node_idx, 
size_t d
 
 1455   if( 0 > node_idx ) {
 
 1459   assert( !mdata_vector_is_locked( &(parser->tags) ) );
 
 1462   p_tag_iter = mdata_vector_get(
 
 1464   if( NULL == p_tag_iter ) {
 
 1469   maug_mzero( indents, 30 );
 
 1470   for( i = 0 ; d > i ; i++ ) {
 
 1471      if( maug_strlen( indents ) >= 30 ) {
 
 1474      strcat( indents, 
"   " );
 
 1480      "%s" SSIZE_T_FMT 
" (tag %s): x: " SSIZE_T_FMT 
", y: " SSIZE_T_FMT
 
 1481      " (" SSIZE_T_FMT 
" x " SSIZE_T_FMT 
") f: " 
 1482#ifdef RETROGXC_PRESENT
 
 1488      0 <= tree->
nodes[node_idx].tag ?
 
 1489         gc_mhtml_tag_names[p_tag_iter->base.type] : 
"ROOT",
 
 1490      tree->
nodes[node_idx].x, tree->
nodes[node_idx].y,
 
 1491      tree->
nodes[node_idx].w, tree->
nodes[node_idx].h,
 
 1492#ifdef RETROGXC_PRESENT
 
 1493      tree->
nodes[node_idx].font_idx
 
 1495      tree->
nodes[node_idx].font_h
 
 1501   retval = retrohtr_tree_dump(
 
 1503   maug_cleanup_if_not_ok();
 
 1505   retval = retrohtr_tree_dump(
 
 1507   maug_cleanup_if_not_ok();
 
 1516   debug_printf( RETROHTR_TRACE_LVL, 
"freeing render nodes..." );
 
 1524      RETROHTR_TREE_FLAG_GUI_ACTIVE ==
 
 1525         (tree->flags & RETROHTR_TREE_FLAG_GUI_ACTIVE)
 
 1531   retrohtr_tree_unlock( tree );
 
 1533   if( (MAUG_MHANDLE)NULL != tree->nodes_h ) {
 
 1534      maug_mfree( tree->nodes_h );
 
 1545   debug_printf( RETROHTR_TRACE_LVL,
 
 1546      "allocating " SIZE_T_FMT 
" nodes...", tree->
nodes_sz_max );
 
 1547   tree->nodes_h = maug_malloc(
 
 1549   maug_cleanup_if_null_alloc( MAUG_MHANDLE, tree->nodes_h );
 
uint16_t MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition: merror.h:19
MERROR_RETVAL retroflat_blit_bitmap(struct RETROFLAT_BITMAP *target, struct RETROFLAT_BITMAP *src, size_t s_x, size_t s_y, int16_t d_x, int16_t d_y, size_t w, size_t h, int16_t instance)
Blit the contents of a ::RETROFLAT_BITMAP onto another ::RETROFLAT_BITMAP.
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:569
int8_t RETROFLAT_COLOR
Defines an index in the platform-specific color-table.
Definition: retroflt.h:325
#define RETROFLAT_FLAGS_LITERAL_PATH
Flag for retroflat_load_bitmap() to not use assets path.
Definition: retroflt.h:384
#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:390
void retroflat_rect(struct RETROFLAT_BITMAP *target, const RETROFLAT_COLOR color, int16_t x, int16_t y, int16_t w, int16_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:373
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:292
void retrofont_string(retroflat_blit_t *target, RETROFLAT_COLOR color, const char *str, size_t str_sz, MAUG_MHANDLE font_h, size_t x, size_t y, size_t max_w, size_t max_h, uint8_t flags)
Draw a string with the given font.
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.
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:320
#define mdata_vector_unlock(v)
Unlock the vector so items may be added and removed.
Definition: mdata.h:353
#define mdata_vector_ct(v)
Number of items of MDATA_VECTOR::item_sz bytes actively stored in this vector.
Definition: mdata.h:396
Definition: retrogui.h:430
#define RETROGUI_FLAGS_DIRTY
RETROGUI::flags indicating controls should be redrawn.
Definition: retrogui.h:248
MAUG_MHANDLE font_h
Font used to draw any attached RETROGUI_CTL.
Definition: retrogui.h:456
Definition: retrohtr.h:28
Definition: retrohtr.h:59
Definition: retrogui.h:412