Example #1
0
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);
}
Example #2
0
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);
}
Example #3
0
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);
}
Example #4
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);
}
Example #5
0
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++;
    }
  }
}
Example #6
0
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++;
    }
  }
}
Example #7
0
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);
}
Example #8
0
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(&gtb->gtb_text_renderer)))
    glw_renderer_init_quad(&gtb->gtb_text_renderer);

  if(w->glw_class == &glw_text &&
     unlikely(!glw_renderer_initialized(&gtb->gtb_cursor_renderer)))
    glw_renderer_init_quad(&gtb->gtb_cursor_renderer);

  if(gtb->gtb_background_alpha > GLW_ALPHA_EPSILON &&
     unlikely(!glw_renderer_initialized(&gtb->gtb_cursor_renderer))) {
    glw_renderer_init_quad(&gtb->gtb_background_renderer);
    glw_renderer_vtx_pos(&gtb->gtb_background_renderer, 0, -1, -1, 0);
    glw_renderer_vtx_pos(&gtb->gtb_background_renderer, 1,  1, -1, 0);
    glw_renderer_vtx_pos(&gtb->gtb_background_renderer, 2,  1,  1, 0);
    glw_renderer_vtx_pos(&gtb->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, &gtb->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(&gtb->gtb_texture);
  const int tex_height = glw_tex_height(&gtb->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(&gtb->gtb_text_renderer, 0, 1,1,1,1+text_width/20);
	glw_renderer_vtx_col(&gtb->gtb_text_renderer, 1, 1,1,1,0);
	glw_renderer_vtx_col(&gtb->gtb_text_renderer, 2, 1,1,1,0);
	glw_renderer_vtx_col(&gtb->gtb_text_renderer, 3, 1,1,1,1+text_width/20);
      }
#endif
    } else {

      glw_renderer_vtx_col_reset(&gtb->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(&gtb->gtb_text_renderer, 0, x1, y1, 0.0);
    glw_renderer_vtx_st (&gtb->gtb_text_renderer, 0, 0, t);

    glw_renderer_vtx_pos(&gtb->gtb_text_renderer, 1, x2, y1, 0.0);
    glw_renderer_vtx_st (&gtb->gtb_text_renderer, 1, s, t);

    glw_renderer_vtx_pos(&gtb->gtb_text_renderer, 2, x2, y2, 0.0);
    glw_renderer_vtx_st (&gtb->gtb_text_renderer, 2, s, 0);

    glw_renderer_vtx_pos(&gtb->gtb_text_renderer, 3, x1, y2, 0.0);
    glw_renderer_vtx_st (&gtb->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(&gtb->gtb_cursor_renderer, 0, x1, y1, 0.0);
    glw_renderer_vtx_pos(&gtb->gtb_cursor_renderer, 1, x2, y1, 0.0);
    glw_renderer_vtx_pos(&gtb->gtb_cursor_renderer, 2, x2, y2, 0.0);
    glw_renderer_vtx_pos(&gtb->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);
}
Example #9
0
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]);
  }
}
Example #10
0
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);
  }

}
Example #11
0
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);
}
Example #12
0
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(&gtb->gtb_text_renderer))
    glw_renderer_init_quad(&gtb->gtb_text_renderer);

  if(w->glw_class == &glw_text &&
     !glw_renderer_initialized(&gtb->gtb_cursor_renderer))
    glw_renderer_init_quad(&gtb->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, &gtb->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(&gtb->gtb_text_renderer, 0, 1,1,1,1+text_width/20);
	glw_renderer_vtx_col(&gtb->gtb_text_renderer, 1, 1,1,1,0);
	glw_renderer_vtx_col(&gtb->gtb_text_renderer, 2, 1,1,1,0);
	glw_renderer_vtx_col(&gtb->gtb_text_renderer, 3, 1,1,1,1+text_width/20);
      }

    } else { 

      glw_renderer_vtx_col(&gtb->gtb_text_renderer, 0, 1,1,1,1);
      glw_renderer_vtx_col(&gtb->gtb_text_renderer, 1, 1,1,1,1);
      glw_renderer_vtx_col(&gtb->gtb_text_renderer, 2, 1,1,1,1);
      glw_renderer_vtx_col(&gtb->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(&gtb->gtb_text_renderer, 0, x1, y1, 0.0);
    glw_renderer_vtx_st (&gtb->gtb_text_renderer, 0, 0, t);

    glw_renderer_vtx_pos(&gtb->gtb_text_renderer, 1, x2, y1, 0.0);
    glw_renderer_vtx_st (&gtb->gtb_text_renderer, 1, s, t);

    glw_renderer_vtx_pos(&gtb->gtb_text_renderer, 2, x2, y2, 0.0);
    glw_renderer_vtx_st (&gtb->gtb_text_renderer, 2, s, 0);

    glw_renderer_vtx_pos(&gtb->gtb_text_renderer, 3, x1, y2, 0.0);
    glw_renderer_vtx_st (&gtb->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(&gtb->gtb_cursor_renderer, 0, x1, y1, 0.0);
    glw_renderer_vtx_pos(&gtb->gtb_cursor_renderer, 1, x2, y1, 0.0);
    glw_renderer_vtx_pos(&gtb->gtb_cursor_renderer, 2, x2, y2, 0.0);
    glw_renderer_vtx_pos(&gtb->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);
}
Example #13
0
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++;
    }
  }
}