Esempio n. 1
0
static void 
glw_image_layout(glw_t *w, glw_rctx_t *rc)
{
  glw_image_t *gi = (void *)w;
  glw_root_t *gr = w->glw_root;
  glw_loadable_texture_t *glt;
  glw_rctx_t rc0;
  glw_t *c;
  int hq = (w->glw_class == &glw_icon || w->glw_class == &glw_image);

  if(gi->gi_pending_url != NULL) {
    // Request to load
    int xs = -1, ys = -1;
    int flags = 0;
    gi->gi_loading_new_url = 1;

    if(gi->gi_pending != NULL) {
      glw_tex_deref(w->glw_root, gi->gi_pending);
      gi->gi_pending = NULL;
    }

    if(rstr_get(gi->gi_pending_url)[0] == 0) {
      // Empty string, unload all

      if(gi->gi_current != NULL) {
	glw_tex_deref(w->glw_root, gi->gi_current);
	gi->gi_current = NULL;
      }
	
      gi->gi_update = 1;

    } else {
    
      if(w->glw_class == &glw_repeatedimage)
	flags |= GLW_TEX_REPEAT;
	
      if(hq) {
	if(rc->rc_width < rc->rc_height) {
	  xs = rc->rc_width;
	} else {
	  ys = rc->rc_height;
	}
      }

      if(xs && ys) {

	if(w->glw_flags & GLW_DEBUG)
	  TRACE(TRACE_DEBUG, "IMG", "Loading texture: %s",
		rstr_get(gi->gi_pending_url));

	gi->gi_pending = glw_tex_create(w->glw_root,
					gi->gi_pending_url,
					flags, xs, ys);
	  
	rstr_release(gi->gi_pending_url);
	gi->gi_pending_url = NULL;
      }
    }
  }
  
  if((glt = gi->gi_pending) != NULL) {
    glw_tex_layout(gr, glt);

    if(glw_is_tex_inited(&glt->glt_texture) ||
       glt->glt_state == GLT_STATE_ERROR) {
      // Pending texture completed, ok or error: transfer to current

      if(gi->gi_current != NULL)
	glw_tex_deref(w->glw_root, gi->gi_current);

      gi->gi_current = gi->gi_pending;
      gi->gi_pending = NULL;
      gi->gi_update = 1;
      gi->gi_loading_new_url = 0;
    }
  }

  if((glt = gi->gi_current) == NULL)
    return;

  if(gi->gi_loading_new_url) {
    gi->gi_autofade = GLW_LP(8, gi->gi_autofade, 0);
  } else {
    gi->gi_autofade = GLW_LP(8, gi->gi_autofade, 1);
  }

  glw_tex_layout(gr, glt);

  if(glt->glt_state == GLT_STATE_ERROR) {
    if(!gi->gi_is_ready) {
      gi->gi_is_ready = 1;
      glw_signal0(w, GLW_SIGNAL_READINESS, NULL);
    }
  } else if(glw_is_tex_inited(&glt->glt_texture)) {

    int r = !gi->gi_loading_new_url;

    if(gi->gi_is_ready != r) {
      gi->gi_is_ready = r;
      glw_signal0(w, GLW_SIGNAL_READINESS, NULL);
    }

    if(gi->gi_update) {
      gi->gi_update = 0;

      glw_renderer_free(&gi->gi_gr);

      switch(gi->gi_mode) {
	
      case GI_MODE_NORMAL:
	glw_renderer_init_quad(&gi->gi_gr);
	glw_image_layout_normal(gr, rc, gi, glt);
	break;
      case GI_MODE_BORDER_SCALING:
	glw_renderer_init(&gi->gi_gr, 16, 18, borderobject);
	glw_image_layout_tesselated(gr, rc, gi, glt);
	break;
      case GI_MODE_REPEATED_TEXTURE:
	glw_renderer_init_quad(&gi->gi_gr);
	glw_image_layout_repeated(gr, rc, gi, glt);
	break;
      case GI_MODE_ALPHA_EDGES:
	glw_renderer_init(&gi->gi_gr, 16, 18, borderobject);
	glw_image_layout_alpha_edges(gr, rc, gi, glt);
	break;
      case GI_MODE_BORDER_ONLY_SCALING:
	glw_renderer_init(&gi->gi_gr, 16, 16, borderonlyobject);
	glw_image_layout_tesselated(gr, rc, gi, glt);
	break;
      default:
	abort();
      }


    } else if(gi->gi_last_width  != rc->rc_width ||
	      gi->gi_last_height != rc->rc_height) {

      gi->gi_last_width  = rc->rc_width;
      gi->gi_last_height = rc->rc_height;

      switch(gi->gi_mode) {
	
      case GI_MODE_NORMAL:
	break;
      case GI_MODE_BORDER_SCALING:
      case GI_MODE_BORDER_ONLY_SCALING:
	glw_image_layout_tesselated(gr, rc, gi, glt);
	break;
      case GI_MODE_REPEATED_TEXTURE:
	glw_image_layout_repeated(gr, rc, gi, glt);
	break;
      case GI_MODE_ALPHA_EDGES:
	glw_image_layout_alpha_edges(gr, rc, gi, glt);
	break;
      }
      gi->gi_need_reload = hq;
    }


    if(gi->gi_need_reload && gi->gi_pending == NULL &&
       gi->gi_pending_url == NULL && rc->rc_width && rc->rc_height) {

      gi->gi_need_reload = 0;
	
      int xs = -1, ys = -1, rescale;
	
      if(rc->rc_width < rc->rc_height) {
	rescale = rc->rc_width != glt->glt_xs;
	xs = rc->rc_width;
      } else {
	rescale = rc->rc_height != glt->glt_ys;
	ys = rc->rc_height;
      }
      
      if(rescale) {
	int flags = 0;
	if(w->glw_class == &glw_repeatedimage)
	  flags |= GLW_TEX_REPEAT;
	
	gi->gi_pending = glw_tex_create(w->glw_root, glt->glt_url,
					flags, xs, ys);
      }
    }
  } else {
    if(gi->gi_is_ready) {
      gi->gi_is_ready = 0;
      glw_signal0(w, GLW_SIGNAL_READINESS, NULL);
    }

  }

  glw_image_update_constraints(gi);

  if((c = TAILQ_FIRST(&w->glw_childs)) != NULL) {
    rc0 = *rc;
    
    rc0.rc_width  -= gi->gi_box_left + gi->gi_box_right;
    rc0.rc_height -= gi->gi_box_top  + gi->gi_box_bottom;

    if(rc0.rc_height >= 0 && rc0.rc_width >= 0)
      glw_layout0(c, &rc0);
  }
}
Esempio n. 2
0
static void 
glw_image_layout(glw_t *w, glw_rctx_t *rc)
{
  glw_image_t *gi = (void *)w;
  glw_root_t *gr = w->glw_root;
  glw_loadable_texture_t *glt;
  glw_rctx_t rc0;
  glw_t *c;

  if(gi->gi_pending_filename != NULL) {
    // Request to load
    int xs = -1, ys = -1;
    int flags = 0;
    
    if(gi->gi_pending != NULL)
      glw_tex_deref(w->glw_root, gi->gi_pending);
    
    if(gi->gi_pending_filename[0] == 0) {
      gi->gi_pending = NULL;

      if(gi->gi_current != NULL) {
	glw_tex_deref(w->glw_root, gi->gi_current);
	gi->gi_current = NULL;
      }

      gi->gi_update = 1;

    } else {

    
      if(w->glw_class == &glw_repeatedimage)
	flags |= GLW_TEX_REPEAT;


      if(gi->gi_bitmap_flags & GLW_IMAGE_HQ_SCALING) {

	if(rc->rc_width < rc->rc_height) {
	  xs = rc->rc_width;
	} else {
	  ys = rc->rc_height;
	}
      }

      if(xs && ys) {

	gi->gi_pending = glw_tex_create(w->glw_root, gi->gi_pending_filename,
					flags, xs, ys);

	free(gi->gi_pending_filename);
	gi->gi_pending_filename = NULL;
      } else {
	gi->gi_pending = NULL;
      }
    }
  }

  if((glt = gi->gi_pending) != NULL) {
    glw_tex_layout(gr, glt);

    if(glt->glt_state == GLT_STATE_VALID || 
       glt->glt_state == GLT_STATE_ERROR) {
      // Pending texture completed, ok or error: transfer to current

      if(gi->gi_current != NULL)
	glw_tex_deref(w->glw_root, gi->gi_current);

      gi->gi_current = gi->gi_pending;
      gi->gi_pending = NULL;
      gi->gi_update = 1;
    }
  }

  if((glt = gi->gi_current) == NULL)
    return;

  glw_tex_layout(gr, glt);

  if(glt->glt_state == GLT_STATE_ERROR) {
    if(!gi->gi_was_valid) {
      glw_signal0(w, GLW_SIGNAL_READY, NULL);
      gi->gi_was_valid = 1;
    }
  } else if(glt->glt_state == GLT_STATE_VALID) {

    if(!gi->gi_was_valid) {
      glw_signal0(w, GLW_SIGNAL_READY, NULL);
      gi->gi_was_valid = 1;
    }

    if(gi->gi_update) {
      gi->gi_update = 0;

      glw_renderer_free(&gi->gi_gr);

      switch(gi->gi_mode) {
	
      case GI_MODE_NORMAL:
	glw_renderer_init_quad(&gi->gi_gr);
	glw_image_layout_normal(gr, rc, gi, glt);
	break;
      case GI_MODE_BORDER_SCALING:
	glw_renderer_init(&gi->gi_gr, 16, 18, borderobject);
	glw_image_layout_tesselated(gr, rc, gi, glt);
	break;
      case GI_MODE_REPEATED_TEXTURE:
	glw_renderer_init_quad(&gi->gi_gr);
	glw_image_layout_repeated(gr, rc, gi, glt);
	break;
      case GI_MODE_ALPHA_EDGES:
	glw_renderer_init(&gi->gi_gr, 16, 18, borderobject);
	glw_image_layout_alpha_edges(gr, rc, gi, glt);
	break;
      case GI_MODE_BORDER_ONLY_SCALING:
	glw_renderer_init(&gi->gi_gr, 16, 16, borderonlyobject);
	glw_image_layout_tesselated(gr, rc, gi, glt);
	break;
      default:
	abort();
      }


    } else if(gi->gi_last_width  != rc->rc_width ||
	      gi->gi_last_height != rc->rc_height) {

      gi->gi_last_width  = rc->rc_width;
      gi->gi_last_height = rc->rc_height;

      switch(gi->gi_mode) {
	
      case GI_MODE_NORMAL:
	break;
      case GI_MODE_BORDER_SCALING:
      case GI_MODE_BORDER_ONLY_SCALING:
	glw_image_layout_tesselated(gr, rc, gi, glt);
	break;
      case GI_MODE_REPEATED_TEXTURE:
	glw_image_layout_repeated(gr, rc, gi, glt);
	break;
      case GI_MODE_ALPHA_EDGES:
	glw_image_layout_alpha_edges(gr, rc, gi, glt);
	break;
      }

      if(gi->gi_bitmap_flags & GLW_IMAGE_HQ_SCALING && gi->gi_pending == NULL &&
	 gi->gi_pending_filename == NULL && rc->rc_width && rc->rc_height) {

	int xs = -1, ys = -1, rescale;
	
	if(rc->rc_width < rc->rc_height) {
	  rescale = abs(rc->rc_width - glt->glt_xs) > glt->glt_xs / 10;
	  xs = rc->rc_width;
	} else {
	  rescale = abs(rc->rc_height - glt->glt_ys) > glt->glt_ys / 10;
	  ys = rc->rc_height;
	}
	
	if(rescale) {
	  int flags = 0;
	  if(w->glw_class == &glw_repeatedimage)
	    flags |= GLW_TEX_REPEAT;

	  gi->gi_pending = glw_tex_create(w->glw_root, glt->glt_filename,
					  flags, xs, ys);
	}
      }
    }
  }

  glw_image_update_constraints(gi);

  if((c = TAILQ_FIRST(&w->glw_childs)) != NULL) {
    rc0 = *rc;
    
    rc0.rc_width  -= gi->gi_box_left + gi->gi_box_right;
    rc0.rc_height -= gi->gi_box_top  + gi->gi_box_bottom;

    if(rc0.rc_height >= 0 && rc0.rc_width >= 0)
      glw_layout0(c, &rc0);
  }
}