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); } }
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); } }