static void glw_image_layout_normal(glw_root_t *gr, glw_rctx_t *rc, glw_image_t *gi, glw_loadable_texture_t *glt) { float xs = gr->gr_normalized_texture_coords ? glt->glt_s : glt->glt_xs; float ys = gr->gr_normalized_texture_coords ? glt->glt_t : glt->glt_ys; uint8_t tex[8]; int o = glt->glt_orientation < 9 ? glt->glt_orientation : 0; memcpy(tex, texcords[o], 8); glw_renderer_vtx_pos(&gi->gi_gr, 0, -1.0, -1.0, 0.0); glw_renderer_vtx_st (&gi->gi_gr, 0, tex[0] * xs , tex[1] * ys); glw_renderer_vtx_pos(&gi->gi_gr, 1, 1.0, -1.0, 0.0); glw_renderer_vtx_st (&gi->gi_gr, 1, tex[2] * xs , tex[3] * ys); glw_renderer_vtx_pos(&gi->gi_gr, 2, 1.0, 1.0, 0.0); glw_renderer_vtx_st (&gi->gi_gr, 2, tex[4] * xs , tex[5] * ys); glw_renderer_vtx_pos(&gi->gi_gr, 3, -1.0, 1.0, 0.0); glw_renderer_vtx_st (&gi->gi_gr, 3, tex[6] * xs , tex[7] * ys); }
static void gvv_render(glw_video_t *gv, glw_rctx_t *rc) { glw_video_surface_t *sa = gv->gv_sa; glw_video_surface_t *sb = gv->gv_sb; glw_program_t *gp; glw_backend_root_t *gbr = &gv->w.glw_root->gr_be; if(sa == NULL) return; gv->gv_width = sa->gvs_width[0]; gv->gv_height = sa->gvs_height[0]; upload_texture(gv, sa); const float yshift_a = (-0.5 * sa->gvs_yshift) / (float)sa->gvs_height[0]; glw_renderer_vtx_st(&gv->gv_quad, 0, 0, 1 + yshift_a); glw_renderer_vtx_st(&gv->gv_quad, 1, 1, 1 + yshift_a); glw_renderer_vtx_st(&gv->gv_quad, 2, 1, 0 + yshift_a); glw_renderer_vtx_st(&gv->gv_quad, 3, 0, 0 + yshift_a); if(sb != NULL) { // Two pictures that should be mixed upload_texture(gv, sb); gp = gbr->gbr_rgb2rgb_2f; const float yshift_b = (-0.5 * sb->gvs_yshift) / (float)sb->gvs_height[0]; glw_renderer_vtx_st2(&gv->gv_quad, 0, 0, 1 + yshift_b); glw_renderer_vtx_st2(&gv->gv_quad, 1, 1, 1 + yshift_b); glw_renderer_vtx_st2(&gv->gv_quad, 2, 1, 0 + yshift_b); glw_renderer_vtx_st2(&gv->gv_quad, 3, 0, 0 + yshift_b); } else { gp = gbr->gbr_rgb2rgb_1f; } gv->gv_gpa.gpa_prog = gp; glw_renderer_draw(&gv->gv_quad, gv->w.glw_root, rc, &sa->gvs_texture, sb != NULL ? &sb->gvs_texture : NULL, NULL, NULL, rc->rc_alpha * gv->w.glw_alpha, 0, &gv->gv_gpa); }
static void glw_image_layout_repeated(glw_root_t *gr, glw_rctx_t *rc, glw_image_t *gi, glw_loadable_texture_t *glt) { float xs = gr->gr_normalized_texture_coords ? glt->glt_s : glt->glt_xs; float ys = gr->gr_normalized_texture_coords ? glt->glt_t : glt->glt_ys; glw_renderer_vtx_pos(&gi->gi_gr, 0, -1.0, -1.0, 0.0); glw_renderer_vtx_st (&gi->gi_gr, 0, 0, ys); glw_renderer_vtx_pos(&gi->gi_gr, 1, 1.0, -1.0, 0.0); glw_renderer_vtx_st (&gi->gi_gr, 1, xs, ys); glw_renderer_vtx_pos(&gi->gi_gr, 2, 1.0, 1.0, 0.0); glw_renderer_vtx_st (&gi->gi_gr, 2, xs, 0); glw_renderer_vtx_pos(&gi->gi_gr, 3, -1.0, 1.0, 0.0); glw_renderer_vtx_st (&gi->gi_gr, 3, 0, 0); }
static void glw_raster_render(glw_t *w, const glw_rctx_t *rc) { glw_raster_t *q = (void *)w; #if 0 printf("RASTER W=%d H=%d\n", rc->rc_width, rc->rc_height); int i; for(i = 0; i < 16; i++) { printf("%f%c", rc->rc_be.gbr_mtx[i], "\t\t\t\n"[i&3]); } #endif if(!glw_is_tex_inited(&q->tex)) glw_tex_upload(w->glw_root, &q->tex, rastermap, GLW_TEXTURE_FORMAT_RGB, RASTER_TILE_SIZE, RASTER_TILE_SIZE, GLW_TEX_REPEAT); if(!glw_renderer_initialized(&q->r)) glw_renderer_init_quad(&q->r); if(q->width != rc->rc_width || q->height != rc->rc_height) { q->width = rc->rc_width; q->height = rc->rc_height; glw_renderer_vtx_pos(&q->r, 0, -1, -1, 0); glw_renderer_vtx_st (&q->r, 0, 0, rc->rc_height / (float)RASTER_TILE_SIZE); glw_renderer_vtx_pos(&q->r, 1, 1, -1, 0); glw_renderer_vtx_st (&q->r, 1, rc->rc_width / (float)RASTER_TILE_SIZE, rc->rc_height / (float)RASTER_TILE_SIZE); glw_renderer_vtx_pos(&q->r, 2, 1, 1, 0); glw_renderer_vtx_st (&q->r, 2, rc->rc_width / (float)RASTER_TILE_SIZE, 0); glw_renderer_vtx_pos(&q->r, 3, -1, 1, 0); glw_renderer_vtx_st (&q->r, 3, 0, 0); } glw_renderer_draw(&q->r, w->glw_root, rc, &q->tex, &q->color, NULL, rc->rc_alpha * w->glw_alpha, 0, NULL); }
static void glw_image_layout_tesselated(glw_root_t *gr, glw_rctx_t *rc, glw_image_t *gi, glw_loadable_texture_t *glt) { float tex[4][2]; float vex[4][2]; int x, y, i = 0; if(gr->gr_normalized_texture_coords) { tex[1][0] = 0.0f + (float)gi->gi_border_left / glt->glt_xs; tex[2][0] = glt->glt_s - (float)gi->gi_border_right / glt->glt_xs; tex[0][0] = gi->gi_bitmap_flags & GLW_IMAGE_BORDER_LEFT ? 0.0f : tex[1][0]; tex[3][0] = gi->gi_bitmap_flags & GLW_IMAGE_BORDER_RIGHT ? glt->glt_s : tex[2][0]; tex[0][1] = 0.0f; tex[1][1] = 0.0f + (float)gi->gi_border_top / glt->glt_ys; tex[2][1] = glt->glt_t - (float)gi->gi_border_bottom / glt->glt_ys; tex[3][1] = glt->glt_t; } else { tex[1][0] = gi->gi_border_left; tex[2][0] = glt->glt_xs - gi->gi_border_right; tex[0][0] = gi->gi_bitmap_flags & GLW_IMAGE_BORDER_LEFT ? 0.0f : tex[1][0]; tex[3][0] = gi->gi_bitmap_flags & GLW_IMAGE_BORDER_RIGHT ? glt->glt_xs : tex[2][0]; tex[0][1] = 0.0f; tex[1][1] = gi->gi_border_top; tex[2][1] = glt->glt_ys - gi->gi_border_bottom; tex[3][1] = glt->glt_ys; } vex[0][0] = GLW_MIN(-1.0f + 2.0f * (gi->gi_margin_left) / rc->rc_width, 0.0f); vex[1][0] = GLW_MIN(-1.0f + 2.0f * (gi->gi_border_left + gi->gi_margin_left) / rc->rc_width, 0.0f); vex[2][0] = GLW_MAX( 1.0f - 2.0f * (gi->gi_border_right + gi->gi_margin_right) / rc->rc_width, 0.0f); vex[3][0] = GLW_MAX( 1.0f - 2.0f * (gi->gi_margin_right) / rc->rc_width, 0.0f); vex[0][1] = GLW_MAX( 1.0f - 2.0f * (gi->gi_margin_top) / rc->rc_height, 0.0f); vex[1][1] = GLW_MAX( 1.0f - 2.0f * (gi->gi_border_top + gi->gi_margin_top) / rc->rc_height, 0.0f); vex[2][1] = GLW_MIN(-1.0f + 2.0f * (gi->gi_border_bottom + gi->gi_margin_bottom) / rc->rc_height, 0.0f); vex[3][1] = GLW_MIN(-1.0f + 2.0f * (gi->gi_margin_bottom) / rc->rc_height, 0.0f); for(y = 0; y < 4; y++) { for(x = 0; x < 4; x++) { glw_renderer_vtx_pos(&gi->gi_gr, i, vex[x][0], vex[y][1], 0.0f); glw_renderer_vtx_st (&gi->gi_gr, i, tex[x][0], tex[y][1]); i++; } } }
static void glw_image_layout_alpha_edges(glw_root_t *gr, glw_rctx_t *rc, glw_image_t *gi, glw_loadable_texture_t *glt) { float tex[4][2]; float vex[4][2]; int x, y, i = 0; if(gr->gr_normalized_texture_coords) { tex[0][0] = 0.0f; tex[1][0] = 0.0f + (float)gi->gi_alpha_edge / glt->glt_xs; tex[2][0] = glt->glt_s - (float)gi->gi_alpha_edge / glt->glt_xs; tex[3][0] = glt->glt_s; tex[0][1] = 0.0f; tex[1][1] = 0.0f + (float)gi->gi_alpha_edge / glt->glt_ys; tex[2][1] = glt->glt_t - (float)gi->gi_alpha_edge / glt->glt_ys; tex[3][1] = glt->glt_t; } else { tex[0][0] = 0.0f; tex[1][0] = gi->gi_alpha_edge; tex[2][0] = glt->glt_xs - gi->gi_alpha_edge; tex[3][0] = glt->glt_xs; tex[0][1] = 0.0f; tex[1][1] = gi->gi_alpha_edge; tex[2][1] = glt->glt_ys - gi->gi_alpha_edge; tex[3][1] = glt->glt_ys; } vex[0][0] = -1.0f; vex[1][0] = GLW_MIN(-1.0f + 2.0f * gi->gi_alpha_edge / rc->rc_width, 0.0f); vex[2][0] = GLW_MAX( 1.0f - 2.0f * gi->gi_alpha_edge / rc->rc_width, 0.0f); vex[3][0] = 1.0f; vex[0][1] = 1.0f; vex[1][1] = GLW_MAX( 1.0f - 2.0f * gi->gi_alpha_edge / rc->rc_height, 0.0f); vex[2][1] = GLW_MIN(-1.0f + 2.0f * gi->gi_alpha_edge / rc->rc_height, 0.0f); vex[3][1] = -1.0f; for(y = 0; y < 4; y++) { for(x = 0; x < 4; x++) { glw_renderer_vtx_pos(&gi->gi_gr, i, vex[x][0], vex[y][1], 0.0f); glw_renderer_vtx_st (&gi->gi_gr, i, tex[x][0], tex[y][1]); glw_renderer_vtx_col(&gi->gi_gr, i, 1, 1, 1, alphaborder[x][y]); i++; } } }
static void settexcoord(glw_renderer_t *gr, int c, float s0, float t0, const glw_root_t *root, const glw_loadable_texture_t *glt) { const int8_t *m = glt->glt_orientation < 9 ? tex_transform[glt->glt_orientation] : tex_transform[0]; s0 = s0 * 2 - 1; t0 = t0 * 2 - 1; float s = s0 * m[0] + t0 * m[1]; float t = s0 * m[2] + t0 * m[3]; if(root->gr_normalized_texture_coords) { s = (s + 1.0) * 0.5; t = (t + 1.0) * 0.5; } else { s = (s + 1.0) * 0.5 * glt->glt_xs; t = (t + 1.0) * 0.5 * glt->glt_ys; } glw_renderer_vtx_st(gr, c, s, t); }
static void glw_text_bitmap_layout(glw_t *w, const glw_rctx_t *rc) { glw_text_bitmap_t *gtb = (void *)w; glw_root_t *gr = w->glw_root; gr->gr_can_externalize = 0; // Initialize renderers if(unlikely(!glw_renderer_initialized(>b->gtb_text_renderer))) glw_renderer_init_quad(>b->gtb_text_renderer); if(w->glw_class == &glw_text && unlikely(!glw_renderer_initialized(>b->gtb_cursor_renderer))) glw_renderer_init_quad(>b->gtb_cursor_renderer); if(gtb->gtb_background_alpha > GLW_ALPHA_EPSILON && unlikely(!glw_renderer_initialized(>b->gtb_cursor_renderer))) { glw_renderer_init_quad(>b->gtb_background_renderer); glw_renderer_vtx_pos(>b->gtb_background_renderer, 0, -1, -1, 0); glw_renderer_vtx_pos(>b->gtb_background_renderer, 1, 1, -1, 0); glw_renderer_vtx_pos(>b->gtb_background_renderer, 2, 1, 1, 0); glw_renderer_vtx_pos(>b->gtb_background_renderer, 3, -1, 1, 0); } // Upload texture image_component_t *ic = image_find_component(gtb->gtb_image, IMAGE_PIXMAP); if(ic != NULL) { glw_tex_upload(gr, >b->gtb_texture, ic->pm, 0); gtb->gtb_margin = ic->pm->pm_margin; image_clear_component(ic); gtb->gtb_need_layout = 1; } const int tex_width = glw_tex_width(>b->gtb_texture); const int tex_height = glw_tex_height(>b->gtb_texture); ic = image_find_component(gtb->gtb_image, IMAGE_TEXT_INFO); image_component_text_info_t *ti = ic ? &ic->text_info : NULL; // Check if we need to repaint if(gtb->gtb_saved_width != rc->rc_width || gtb->gtb_saved_height != rc->rc_height) { if(ti != NULL && gtb->gtb_state == GTB_VALID) { if(ti->ti_flags & IMAGE_TEXT_WRAPPED) gtb->gtb_state = GTB_NEED_RENDER; if(rc->rc_width > gtb->gtb_saved_width && ti->ti_flags & IMAGE_TEXT_TRUNCATED) gtb->gtb_state = GTB_NEED_RENDER; if(gtb->gtb_flags & GTB_ELLIPSIZE) { if(ti->ti_flags & IMAGE_TEXT_TRUNCATED) { gtb->gtb_state = GTB_NEED_RENDER; } else { if(rc->rc_width - gtb->gtb_padding[2] - gtb->gtb_padding[0] < tex_width - gtb->gtb_margin * 2) gtb->gtb_state = GTB_NEED_RENDER; if(rc->rc_height - gtb->gtb_padding[1] - gtb->gtb_padding[3] < tex_height - gtb->gtb_margin * 2) gtb->gtb_state = GTB_NEED_RENDER; } } } gtb->gtb_saved_width = rc->rc_width; gtb->gtb_saved_height = rc->rc_height; gtb->gtb_update_cursor = 1; gtb->gtb_need_layout = 1; if(gtb->w.glw_flags2 & GLW2_DEBUG) printf(" textbitmap: Parent widget gives us :%d x %d ti=%p\n", rc->rc_width, rc->rc_height, ti); } if(ti != NULL && gtb->gtb_need_layout) { const int margin = gtb->gtb_margin; int left = gtb->gtb_padding[0] - margin; int top = rc->rc_height - gtb->gtb_padding[1] + margin; int right = rc->rc_width - gtb->gtb_padding[2] + margin; int bottom = gtb->gtb_padding[3] - margin; int text_width = tex_width; int text_height = tex_height; float x1, y1, x2, y2; if(gtb->w.glw_flags2 & GLW2_DEBUG) printf(" textbitmap: text_width:%d left:%d right:%d margin:%d\n", text_width, left, right, margin); // Vertical if(text_height > top - bottom) { // Oversized, must cut text_height = top - bottom; } else { switch(w->glw_alignment) { case LAYOUT_ALIGN_CENTER: case LAYOUT_ALIGN_LEFT: case LAYOUT_ALIGN_RIGHT: bottom = (bottom + top - text_height) / 2; top = bottom + text_height; break; case LAYOUT_ALIGN_TOP_LEFT: case LAYOUT_ALIGN_TOP_RIGHT: case LAYOUT_ALIGN_TOP: case LAYOUT_ALIGN_JUSTIFIED: bottom = top - tex_height; break; case LAYOUT_ALIGN_BOTTOM: case LAYOUT_ALIGN_BOTTOM_LEFT: case LAYOUT_ALIGN_BOTTOM_RIGHT: top = bottom + tex_height; break; } } y1 = -1.0f + 2.0f * bottom / (float)rc->rc_height; y2 = -1.0f + 2.0f * top / (float)rc->rc_height; // Horizontal if(text_width > right - left || ti->ti_flags & IMAGE_TEXT_TRUNCATED) { // Oversized, must cut text_width = right - left; if(gtb->w.glw_flags2 & GLW2_DEBUG) printf(" textbitmap: Oversized, must cut. Width is now %d\n", text_width); #if 0 if(!(gtb->gtb_flags & GTB_ELLIPSIZE)) { glw_renderer_vtx_col(>b->gtb_text_renderer, 0, 1,1,1,1+text_width/20); glw_renderer_vtx_col(>b->gtb_text_renderer, 1, 1,1,1,0); glw_renderer_vtx_col(>b->gtb_text_renderer, 2, 1,1,1,0); glw_renderer_vtx_col(>b->gtb_text_renderer, 3, 1,1,1,1+text_width/20); } #endif } else { glw_renderer_vtx_col_reset(>b->gtb_text_renderer); switch(w->glw_alignment) { case LAYOUT_ALIGN_JUSTIFIED: case LAYOUT_ALIGN_CENTER: case LAYOUT_ALIGN_BOTTOM: case LAYOUT_ALIGN_TOP: left = (left + right - text_width) / 2; right = left + text_width; break; case LAYOUT_ALIGN_LEFT: case LAYOUT_ALIGN_TOP_LEFT: case LAYOUT_ALIGN_BOTTOM_LEFT: right = left + tex_width; break; case LAYOUT_ALIGN_RIGHT: case LAYOUT_ALIGN_TOP_RIGHT: case LAYOUT_ALIGN_BOTTOM_RIGHT: left = right - tex_width; break; } } x1 = -1.0f + 2.0f * left / (float)rc->rc_width; x2 = -1.0f + 2.0f * right / (float)rc->rc_width; const float s = text_width / (float)tex_width; const float t = text_height / (float)tex_height; if(gtb->w.glw_flags2 & GLW2_DEBUG) printf(" s=%f t=%f\n", s, t); glw_renderer_vtx_pos(>b->gtb_text_renderer, 0, x1, y1, 0.0); glw_renderer_vtx_st (>b->gtb_text_renderer, 0, 0, t); glw_renderer_vtx_pos(>b->gtb_text_renderer, 1, x2, y1, 0.0); glw_renderer_vtx_st (>b->gtb_text_renderer, 1, s, t); glw_renderer_vtx_pos(>b->gtb_text_renderer, 2, x2, y2, 0.0); glw_renderer_vtx_st (>b->gtb_text_renderer, 2, s, 0); glw_renderer_vtx_pos(>b->gtb_text_renderer, 3, x1, y2, 0.0); glw_renderer_vtx_st (>b->gtb_text_renderer, 3, 0, 0); } if(w->glw_class == &glw_text && gtb->gtb_update_cursor && gtb->gtb_state == GTB_VALID) { int i = gtb->gtb_edit_ptr; int left; float x1, y1, x2, y2; if(ti != NULL && ti->ti_charpos != NULL) { if(i < ti->ti_charposlen) { left = ti->ti_charpos[i*2 ]; } else { left = ti->ti_charpos[2 * ti->ti_charposlen - 1]; } } else { left = 0; } left += gtb->gtb_padding[0]; x1 = -1.0f + 2.0f * (left - 1) / (float)rc->rc_width; x2 = -1.0f + 2.0f * (left ) / (float)rc->rc_width; y1 = -1.0f + 2.0f * gtb->gtb_padding[3] / (float)rc->rc_height; y2 = 1.0f - 2.0f * gtb->gtb_padding[1] / (float)rc->rc_height; glw_renderer_vtx_pos(>b->gtb_cursor_renderer, 0, x1, y1, 0.0); glw_renderer_vtx_pos(>b->gtb_cursor_renderer, 1, x2, y1, 0.0); glw_renderer_vtx_pos(>b->gtb_cursor_renderer, 2, x2, y2, 0.0); glw_renderer_vtx_pos(>b->gtb_cursor_renderer, 3, x1, y2, 0.0); if(w->glw_flags2 & GLW2_DEBUG) { printf("Cursor updated %f %f %f %f rect:%d,%d\n", x1, y1, x2, y2, rc->rc_width, rc->rc_height); } gtb->gtb_update_cursor = 0; } gtb->gtb_paint_cursor = gtb->gtb_flags & GTB_PERMANENT_CURSOR || (w->glw_class == &glw_text && glw_is_focused(w)); if(gtb->gtb_paint_cursor && rc->rc_alpha > GLW_ALPHA_EPSILON) glw_need_refresh(gr, 0); gtb->gtb_need_layout = 0; if(gtb->gtb_state == GTB_VALID && gtb->gtb_deferred_realize) { gtb->gtb_deferred_realize = 0; gtb_realize(gtb); } if(gtb->gtb_state != GTB_NEED_RENDER) return; TAILQ_INSERT_TAIL(&gr->gr_gtb_render_queue, gtb, gtb_workq_link); gtb->gtb_state = GTB_QUEUED_FOR_RENDERING; hts_cond_signal(&gr->gr_gtb_work_cond); }
static void glw_bloom_layout(glw_t *w, glw_rctx_t *rc) { glw_bloom_t *b = (void *)w; glw_root_t *gr = w->glw_root; glw_rctx_t rc0; glw_t *c; int x, y, i, sizx, sizy; TAILQ_FOREACH(c, &w->glw_childs, glw_parent_link) glw_layout0(c, rc); if(b->b_glow < 0.01) { if(b->b_width || b->b_height) bloom_destroy_rtt(gr, b); return; } sizx = rc->rc_width + EDGE_SIZE; sizy = rc->rc_height + EDGE_SIZE; if(b->b_width != sizx || b->b_height != sizy) { if(b->b_width || b->b_height) bloom_destroy_rtt(gr, b); b->b_width = sizx; b->b_height = sizy; if(b->b_width || b->b_height) { for(i = 0; i < BLOOM_COUNT; i++) { x = b->b_width / (2 << i); y = b->b_height / (2 << i); glw_rtt_init(gr, &b->b_rtt[i], x, y, 1); } } } // Initialize output texture if(!b->b_render_initialized) { float xs = gr->gr_normalized_texture_coords ? 1.0 : b->b_width; float ys = gr->gr_normalized_texture_coords ? 1.0 : b->b_height; glw_renderer_init_quad(&b->b_render); glw_renderer_vtx_pos(&b->b_render, 0, -1.0, -1.0, 0.0); glw_renderer_vtx_st (&b->b_render, 0, 0.0, 0); glw_renderer_vtx_pos(&b->b_render, 1, 1.0, -1.0, 0.0); glw_renderer_vtx_st (&b->b_render, 1, xs, 0); glw_renderer_vtx_pos(&b->b_render, 2, 1.0, 1.0, 0.0); glw_renderer_vtx_st (&b->b_render, 2, xs, ys); glw_renderer_vtx_pos(&b->b_render, 3, -1.0, 1.0, 0.0); glw_renderer_vtx_st (&b->b_render, 3, 0.0, ys); } memset(&rc0, 0, sizeof(glw_rctx_t)); rc0.rc_alpha = 1; rc0.rc_width = b->b_width - EDGE_SIZE; rc0.rc_height = b->b_height - EDGE_SIZE; rc0.rc_inhibit_shadows = 1; if(!b->b_need_render) return; for(i = 0; i < BLOOM_COUNT; i++) { glw_rtt_enter(gr, &b->b_rtt[i], &rc0); rc0.rc_width = b->b_width - EDGE_SIZE; rc0.rc_height = b->b_height - EDGE_SIZE; glw_Scalef(&rc0, 1.0 - EDGE_SIZE / b->b_width, 1.0 - EDGE_SIZE / b->b_height, 1.0); TAILQ_FOREACH(c, &w->glw_childs, glw_parent_link) glw_render0(c, &rc0); glw_rtt_restore(gr, &b->b_rtt[i]); } }
static void glw_gradient_layout(glw_t *W, glw_rctx_t *rc) { glw_gradient_t *gg = (void *)W; glw_root_t *gr = W->glw_root; int w, h, i, tiles; w = rc->rc_width; h = rc->rc_height; tiles = gg->gg_image_flags & (GLW_IMAGE_BEVEL_LEFT | GLW_IMAGE_BEVEL_RIGHT) ? 3 : 1; for(i = gg->gg_tiles; i < tiles; i++) { glw_renderer_init_quad(&gg->gg_gr[i]); gg->gg_gr_initialized = tiles; } if(gg->gg_width != w || gg->gg_height != h || gg->gg_tiles != tiles) { gg->gg_width = w; gg->gg_height = h; gg->gg_tiles = tiles; gg->gg_height2 = glw_can_tnpo2(gr) ? h : 1 << (av_log2(h)); float xs = gr->gr_normalized_texture_coords ? 1.0 : TILEWIDTH; float ys = gr->gr_normalized_texture_coords ? 1.0 : gg->gg_height2; glw_renderer_t *r; if(tiles == 1) { r = &gg->gg_gr[0]; float u = xs * rc->rc_width / TILEWIDTH; glw_renderer_vtx_pos(r, 0, -1.0, -1.0, 0.0); glw_renderer_vtx_st (r, 0, 0.0, ys); glw_renderer_vtx_pos(r, 1, 1.0, -1.0, 0.0); glw_renderer_vtx_st (r, 1, u, ys); glw_renderer_vtx_pos(r, 2, 1.0, 1.0, 0.0); glw_renderer_vtx_st (r, 2, u, 0.0); glw_renderer_vtx_pos(r, 3, -1.0, 1.0, 0.0); glw_renderer_vtx_st (r, 3, 0.0, 0.0); } else { r = &gg->gg_gr[0]; float u = xs * (rc->rc_width - TILEWIDTH * 2) / TILEWIDTH; float x1 = -1.0 + 2.0 * TILEWIDTH / gg->gg_width; float x2 = -1.0 + 2.0 * (gg->gg_width - TILEWIDTH) / gg->gg_width; glw_renderer_vtx_pos(r, 0, x1, -1.0, 0.0); glw_renderer_vtx_st (r, 0, 0.0, ys); glw_renderer_vtx_pos(r, 1, x2, -1.0, 0.0); glw_renderer_vtx_st (r, 1, u, ys); glw_renderer_vtx_pos(r, 2, x2, 1.0, 0.0); glw_renderer_vtx_st (r, 2, u, 0.0); glw_renderer_vtx_pos(r, 3, x1, 1.0, 0.0); glw_renderer_vtx_st (r, 3, 0.0, 0.0); r = &gg->gg_gr[1]; glw_renderer_vtx_pos(r, 0, -1.0, -1.0, 0.0); glw_renderer_vtx_st (r, 0, 0.0, ys); glw_renderer_vtx_pos(r, 1, x1, -1.0, 0.0); glw_renderer_vtx_st (r, 1, xs, ys); glw_renderer_vtx_pos(r, 2, x1, 1.0, 0.0); glw_renderer_vtx_st (r, 2, xs, 0.0); glw_renderer_vtx_pos(r, 3, -1.0, 1.0, 0.0); glw_renderer_vtx_st (r, 3, 0.0, 0.0); r = &gg->gg_gr[2]; glw_renderer_vtx_pos(r, 0, x2, -1.0, 0.0); glw_renderer_vtx_st (r, 0, 0.0, ys); glw_renderer_vtx_pos(r, 1, 1.0, -1.0, 0.0); glw_renderer_vtx_st (r, 1, xs, ys); glw_renderer_vtx_pos(r, 2, 1.0, 1.0, 0.0); glw_renderer_vtx_st (r, 2, xs, 0.0); glw_renderer_vtx_pos(r, 3, x2, 1.0, 0.0); glw_renderer_vtx_st (r, 3, 0.0, 0.0); } gg->gg_repaint = 1; } if(gg->gg_repaint) { gg->gg_repaint = 0; repaint(gg, gr, i, TILEWIDTH, gg->gg_height2, gg->gg_tiles); } }
static void glw_fx_texrot_layout(glw_t *w, glw_rctx_t *rc) { glw_fx_texrot_t *fx = (void *)w; glw_loadable_texture_t *glt = fx->fx_tex; glw_root_t *gr = w->glw_root; glw_rctx_t rc0; int width = 512; int height = 512; width = 256; height = 256; if(glt == NULL) return; // Layout the source texture glw_tex_layout(w->glw_root, glt); if(!glw_renderer_initialized(&fx->fx_render)) { float xs = gr->gr_normalized_texture_coords ? 1.0 : glt->glt_xs; float ys = gr->gr_normalized_texture_coords ? 1.0 : glt->glt_ys; glw_renderer_init_quad(&fx->fx_source_render); glw_renderer_vtx_pos(&fx->fx_source_render, 0, -1.0, -1.0, 0.0); glw_renderer_vtx_st (&fx->fx_source_render, 0, 0.0, ys); glw_renderer_vtx_pos(&fx->fx_source_render, 1, 1.0, -1.0, 0.0); glw_renderer_vtx_st (&fx->fx_source_render, 1, xs, ys); glw_renderer_vtx_pos(&fx->fx_source_render, 2, 1.0, 1.0, 0.0); glw_renderer_vtx_st (&fx->fx_source_render, 2, xs, 0.0); glw_renderer_vtx_pos(&fx->fx_source_render, 3, -1.0, 1.0, 0.0); glw_renderer_vtx_st (&fx->fx_source_render, 3, 0.0, 0.0); } // Init render to texture object if(!fx->fx_rtt_initialized) { fx->fx_rtt_initialized = 1; glw_rtt_init(gr, &fx->fx_rtt, width, height, 0); } // Initialize output texture if(!fx->fx_render_initialized) { float xs = gr->gr_normalized_texture_coords ? 1.0 : width; float ys = gr->gr_normalized_texture_coords ? 1.0 : height; glw_renderer_init_quad(&fx->fx_render); glw_renderer_vtx_pos(&fx->fx_render, 0, -1.0, -1.0, 0.0); glw_renderer_vtx_st (&fx->fx_render, 0, 0.0, ys); glw_renderer_vtx_pos(&fx->fx_render, 1, 1.0, -1.0, 0.0); glw_renderer_vtx_st (&fx->fx_render, 1, xs, ys); glw_renderer_vtx_pos(&fx->fx_render, 2, 1.0, 1.0, 0.0); glw_renderer_vtx_st (&fx->fx_render, 2, xs, 0.0); glw_renderer_vtx_pos(&fx->fx_render, 3, -1.0, 1.0, 0.0); glw_renderer_vtx_st (&fx->fx_render, 3, 0.0, 0.0); } if(!fx->fx_need_render) return; // Enter render-to-texture mode glw_rtt_enter(gr, &fx->fx_rtt, &rc0); // Render the gradients glw_fx_texrot_render_internal(gr, &rc0, fx, glt); // Leave render-to-texture mode glw_rtt_restore(gr, &fx->fx_rtt); }
static void glw_text_bitmap_layout(glw_t *w, glw_rctx_t *rc) { glw_text_bitmap_t *gtb = (void *)w; glw_root_t *gr = w->glw_root; pixmap_t *pm = gtb->gtb_pixmap; // Initialize renderers if(!glw_renderer_initialized(>b->gtb_text_renderer)) glw_renderer_init_quad(>b->gtb_text_renderer); if(w->glw_class == &glw_text && !glw_renderer_initialized(>b->gtb_cursor_renderer)) glw_renderer_init_quad(>b->gtb_cursor_renderer); // Upload texture if(pm != NULL && pm->pm_pixels != NULL) { int fmt; fmt = pm->pm_type == PIXMAP_IA ? GLW_TEXTURE_FORMAT_I8A8 : GLW_TEXTURE_FORMAT_BGR32; glw_tex_upload(gr, >b->gtb_texture, pm->pm_pixels, fmt, pm->pm_width, pm->pm_height, 0); free(pm->pm_pixels); pm->pm_pixels = NULL; gtb->gtb_need_layout = 1; } // Check if we need to repaint if((gtb->gtb_saved_width != rc->rc_width || gtb->gtb_saved_height != rc->rc_height)) { if(pm != NULL && gtb->gtb_state == GTB_VALID) { if(pm->pm_flags & PIXMAP_TEXT_WRAPPED) gtb->gtb_state = GTB_NEED_RENDER; if(rc->rc_width > gtb->gtb_saved_width && pm->pm_flags & PIXMAP_TEXT_TRUNCATED) gtb->gtb_state = GTB_NEED_RENDER; if(gtb->gtb_flags & GTB_ELLIPSIZE) { if(pm->pm_flags & PIXMAP_TEXT_TRUNCATED) { gtb->gtb_state = GTB_NEED_RENDER; } else { if(rc->rc_width - gtb->gtb_padding_right - gtb->gtb_padding_left < pm->pm_width - pm->pm_margin * 2) gtb->gtb_state = GTB_NEED_RENDER; if(rc->rc_height - gtb->gtb_padding_top - gtb->gtb_padding_bottom < pm->pm_height - pm->pm_margin * 2) gtb->gtb_state = GTB_NEED_RENDER; } } } gtb->gtb_saved_width = rc->rc_width; gtb->gtb_saved_height = rc->rc_height; gtb->gtb_need_layout = 1; if(gtb->w.glw_flags & GLW_DEBUG) printf(" parent widget gives us :%d x %d\n", rc->rc_width, rc->rc_height); } if(pm != NULL && gtb->gtb_need_layout) { int left = gtb->gtb_padding_left - pm->pm_margin; int top = rc->rc_height - gtb->gtb_padding_top + pm->pm_margin; int right = rc->rc_width - gtb->gtb_padding_right + pm->pm_margin; int bottom = gtb->gtb_padding_bottom - pm->pm_margin; int text_width = pm->pm_width; int text_height = pm->pm_height; float x1, y1, x2, y2; // Horizontal if(text_width > right - left) { // Oversized, must cut text_width = right - left; if(!(gtb->gtb_flags & GTB_ELLIPSIZE)) { glw_renderer_vtx_col(>b->gtb_text_renderer, 0, 1,1,1,1+text_width/20); glw_renderer_vtx_col(>b->gtb_text_renderer, 1, 1,1,1,0); glw_renderer_vtx_col(>b->gtb_text_renderer, 2, 1,1,1,0); glw_renderer_vtx_col(>b->gtb_text_renderer, 3, 1,1,1,1+text_width/20); } } else { glw_renderer_vtx_col(>b->gtb_text_renderer, 0, 1,1,1,1); glw_renderer_vtx_col(>b->gtb_text_renderer, 1, 1,1,1,1); glw_renderer_vtx_col(>b->gtb_text_renderer, 2, 1,1,1,1); glw_renderer_vtx_col(>b->gtb_text_renderer, 3, 1,1,1,1); switch(w->glw_alignment) { case LAYOUT_ALIGN_JUSTIFIED: case LAYOUT_ALIGN_CENTER: case LAYOUT_ALIGN_BOTTOM: case LAYOUT_ALIGN_TOP: left = (left + right - text_width) / 2; right = left + text_width; break; case LAYOUT_ALIGN_LEFT: case LAYOUT_ALIGN_TOP_LEFT: case LAYOUT_ALIGN_BOTTOM_LEFT: right = left + pm->pm_width; break; case LAYOUT_ALIGN_RIGHT: case LAYOUT_ALIGN_TOP_RIGHT: case LAYOUT_ALIGN_BOTTOM_RIGHT: left = right - pm->pm_width; break; } } // Vertical if(text_height > top - bottom) { // Oversized, must cut text_height = top - bottom; } else { switch(w->glw_alignment) { case LAYOUT_ALIGN_CENTER: case LAYOUT_ALIGN_LEFT: case LAYOUT_ALIGN_RIGHT: bottom = (bottom + top - text_height) / 2; top = bottom + text_height; break; case LAYOUT_ALIGN_TOP_LEFT: case LAYOUT_ALIGN_TOP_RIGHT: case LAYOUT_ALIGN_TOP: case LAYOUT_ALIGN_JUSTIFIED: bottom = top - pm->pm_height; break; case LAYOUT_ALIGN_BOTTOM: case LAYOUT_ALIGN_BOTTOM_LEFT: case LAYOUT_ALIGN_BOTTOM_RIGHT: top = bottom + pm->pm_height; break; } } x1 = -1.0f + 2.0f * left / (float)rc->rc_width; y1 = -1.0f + 2.0f * bottom / (float)rc->rc_height; x2 = -1.0f + 2.0f * right / (float)rc->rc_width; y2 = -1.0f + 2.0f * top / (float)rc->rc_height; float s, t; if(gr->gr_normalized_texture_coords) { s = text_width / (float)pm->pm_width; t = text_height / (float)pm->pm_height; } else { s = text_width; t = text_height; } glw_renderer_vtx_pos(>b->gtb_text_renderer, 0, x1, y1, 0.0); glw_renderer_vtx_st (>b->gtb_text_renderer, 0, 0, t); glw_renderer_vtx_pos(>b->gtb_text_renderer, 1, x2, y1, 0.0); glw_renderer_vtx_st (>b->gtb_text_renderer, 1, s, t); glw_renderer_vtx_pos(>b->gtb_text_renderer, 2, x2, y2, 0.0); glw_renderer_vtx_st (>b->gtb_text_renderer, 2, s, 0); glw_renderer_vtx_pos(>b->gtb_text_renderer, 3, x1, y2, 0.0); glw_renderer_vtx_st (>b->gtb_text_renderer, 3, 0, 0); } if(w->glw_class == &glw_text && gtb->gtb_update_cursor && gtb->gtb_state == GTB_VALID) { int i = gtb->gtb_edit_ptr; int left, right; float x1, y1, x2, y2; if(pm != NULL && pm->pm_charpos != NULL) { if(i < pm->pm_charposlen) { left = pm->pm_charpos[i*2 ]; right = pm->pm_charpos[i*2+1]; } else { left = pm->pm_charpos[2*pm->pm_charposlen - 1]; right = left + 10; } left += gtb->gtb_padding_left; right += gtb->gtb_padding_left; } else { left = 0; right = 10; } x1 = -1.0f + 2.0f * left / (float)rc->rc_width; x2 = -1.0f + 2.0f * right / (float)rc->rc_width; y1 = -0.9f; y2 = 0.9f; glw_renderer_vtx_pos(>b->gtb_cursor_renderer, 0, x1, y1, 0.0); glw_renderer_vtx_pos(>b->gtb_cursor_renderer, 1, x2, y1, 0.0); glw_renderer_vtx_pos(>b->gtb_cursor_renderer, 2, x2, y2, 0.0); glw_renderer_vtx_pos(>b->gtb_cursor_renderer, 3, x1, y2, 0.0); gtb->gtb_update_cursor = 0; } gtb->gtb_paint_cursor = w->glw_class == &glw_text && glw_is_focused(w); gtb->gtb_need_layout = 0; if(gtb->gtb_state == GTB_VALID && gtb->gtb_deferred_realize) { gtb->gtb_deferred_realize = 0; gtb_realize(gtb); } if(gtb->gtb_state != GTB_NEED_RENDER) return; TAILQ_INSERT_TAIL(&gr->gr_gtb_render_queue, gtb, gtb_workq_link); gtb->gtb_state = GTB_QUEUED_FOR_RENDERING; hts_cond_signal(&gr->gr_gtb_work_cond); }
static void glw_image_layout_tesselated(glw_root_t *gr, glw_rctx_t *rc, glw_image_t *gi, glw_loadable_texture_t *glt) { float tex[4][2]; float vex[4][2]; int x, y, i = 0, BL, BR; if(gi->w.glw_flags2 & GLW2_AUTOMARGIN) { gi->gi_automargin_left = 0; gi->gi_automargin_top = 0; gi->gi_automargin_right = 0; gi->gi_automargin_bottom = 0; glw_t *c = TAILQ_FIRST(&gi->w.glw_childs); if(c != NULL && (c->glw_flags & (GLW_CONSTRAINT_X | GLW_CONSTRAINT_Y)) == (GLW_CONSTRAINT_X | GLW_CONSTRAINT_Y)) { int hspill = rc->rc_width - c->glw_req_size_x - gi->gi_box_left - gi->gi_box_right; if(hspill > 0) { gi->gi_automargin_left = hspill / 2 + (hspill & 1); gi->gi_automargin_right = hspill / 2; } int vspill = rc->rc_height - c->glw_req_size_y - gi->gi_box_top - gi->gi_box_bottom; if(vspill > 0) { gi->gi_automargin_top = vspill / 2 + (vspill & 1); gi->gi_automargin_bottom = vspill / 2; } } else if(c != NULL && c->glw_flags & GLW_CONSTRAINT_W && c->glw_req_weight < 0) { float aspect = -c->glw_req_weight; float cw = rc->rc_width - gi->gi_box_left - gi->gi_box_right; float ch = rc->rc_height - gi->gi_box_top - gi->gi_box_bottom; float myaspect = cw / ch; if(myaspect > aspect) { // We are wider than our child wants int cwidth = ch * aspect; int hspill = cw - cwidth; if(hspill > 0) { gi->gi_automargin_left = hspill / 2 + (hspill & 1); gi->gi_automargin_right = hspill / 2; } } else { int cheight = cw / aspect; int vspill = ch - cheight; if(vspill > 0) { gi->gi_automargin_top = vspill / 2 + (vspill & 1); gi->gi_automargin_bottom = vspill / 2; } } } else if(gi->gi_child_aspect > 0) { int px = rc->rc_height * gi->gi_child_aspect; int hspill = rc->rc_width - px - gi->gi_box_left - gi->gi_box_right; if(hspill > 0) { gi->gi_automargin_left = hspill / 2 + (hspill & 1); gi->gi_automargin_right = hspill / 2; } } if(gi->w.glw_flags & GLW_DEBUG) printf("Automargin %d,%d,%d,%d\n", gi->gi_automargin_left, gi->gi_automargin_top, gi->gi_automargin_right, gi->gi_automargin_bottom); update_box(gi); } if(gr->gr_normalized_texture_coords) { tex[1][0] = 0.0f + (float)gi->gi_border_left / glt->glt_xs; tex[2][0] = glt->glt_s - (float)gi->gi_border_right / glt->glt_xs; tex[0][0] = gi->gi_bitmap_flags & GLW_IMAGE_BORDER_LEFT ? 0.0f : tex[1][0]; tex[3][0] = gi->gi_bitmap_flags & GLW_IMAGE_BORDER_RIGHT ? glt->glt_s : tex[2][0]; tex[0][1] = 0.0f; tex[1][1] = 0.0f + (float)gi->gi_border_top / glt->glt_ys; tex[2][1] = glt->glt_t - (float)gi->gi_border_bottom / glt->glt_ys; tex[3][1] = glt->glt_t; } else { tex[1][0] = gi->gi_border_left; tex[2][0] = glt->glt_xs - gi->gi_border_right; tex[0][0] = gi->gi_bitmap_flags & GLW_IMAGE_BORDER_LEFT ? 0.0f : tex[1][0]; tex[3][0] = gi->gi_bitmap_flags & GLW_IMAGE_BORDER_RIGHT ? glt->glt_xs : tex[2][0]; tex[0][1] = 0.0f; tex[1][1] = gi->gi_border_top; tex[2][1] = glt->glt_ys - gi->gi_border_bottom; tex[3][1] = glt->glt_ys; } if(gi->gi_bitmap_flags & GLW_IMAGE_ASPECT_FIXED_BORDERS) { BL = rc->rc_height * gi->gi_border_left / glt->glt_ys; BR = rc->rc_height * gi->gi_border_right / glt->glt_ys; gi->gi_border_left_afix = BL; gi->gi_border_right_afix = BR; update_box(gi); } else { BL = gi->gi_border_left; BR = gi->gi_border_right; } vex[0][0] = GLW_MIN(-1.0f + 2.0f * (gi->gi_margin_left + gi->gi_automargin_left) / rc->rc_width, 0.0f); vex[1][0] = GLW_MIN(-1.0f + 2.0f * (BL + gi->gi_margin_left + gi->gi_automargin_left) / rc->rc_width, 0.0f); vex[2][0] = GLW_MAX( 1.0f - 2.0f * (BR + gi->gi_margin_right + gi->gi_automargin_right) / rc->rc_width, 0.0f); vex[3][0] = GLW_MAX( 1.0f - 2.0f * (gi->gi_margin_right + gi->gi_automargin_right) / rc->rc_width, 0.0f); vex[0][1] = GLW_MAX( 1.0f - 2.0f * (gi->gi_margin_top + gi->gi_automargin_top) / rc->rc_height, 0.0f); vex[1][1] = GLW_MAX( 1.0f - 2.0f * (gi->gi_border_top + gi->gi_margin_top + gi->gi_automargin_top) / rc->rc_height, 0.0f); vex[2][1] = GLW_MIN(-1.0f + 2.0f * (gi->gi_border_bottom + gi->gi_margin_bottom + gi->gi_automargin_bottom) / rc->rc_height, 0.0f); vex[3][1] = GLW_MIN(-1.0f + 2.0f * (gi->gi_margin_bottom + gi->gi_automargin_bottom) / rc->rc_height, 0.0f); for(y = 0; y < 4; y++) { for(x = 0; x < 4; x++) { glw_renderer_vtx_pos(&gi->gi_gr, i, vex[x][0], vex[y][1], 0.0f); glw_renderer_vtx_st (&gi->gi_gr, i, tex[x][0], tex[y][1]); i++; } } }