示例#1
0
文件: grid.c 项目: UIKit0/mctrl
static int
grid_set_table(grid_t* grid, table_t* table)
{
    if(table != NULL && table == grid->table)
        return 0;

    if(MC_ERR(table != NULL  &&  (grid->style & MC_GS_OWNERDATA))) {
        MC_TRACE("grid_set_table: Cannot install table while having style "
                 "MC_GS_OWNERDATA");
        SetLastError(ERROR_INVALID_STATE);
        return -1;
    }

    if(table != NULL) {
        table_ref(table);
    } else if(!(grid->style & (MC_GS_NOTABLECREATE | MC_GS_OWNERDATA))) {
        table = table_create(0, 0);
        if(MC_ERR(table == NULL)) {
            MC_TRACE("grid_set_table: table_create() failed.");
            return -1;
        }
    }

    if(table != NULL) {
        if(MC_ERR(table_install_view(table, grid, grid_refresh)) != 0) {
            MC_TRACE("grid_set_table: table_install_view() failed.");
            table_unref(table);
            return -1;
        }
    }

    if(grid->table != NULL) {
        table_uninstall_view(grid->table, grid);
        table_unref(grid->table);
    }

    grid->table = table;

    if(table != NULL) {
        grid->col_count = table->col_count;
        grid->row_count = table->row_count;
    } else {
        grid->col_count = 0;
        grid->row_count = 0;
    }

    grid->cache_hint[0] = 0;
    grid->cache_hint[1] = 0;
    grid->cache_hint[2] = 0;
    grid->cache_hint[3] = 0;

    if(grid->col_widths != NULL) {
        free(grid->col_widths);
        grid->col_widths = NULL;
    }

    if(grid->row_heights != NULL) {
        free(grid->row_heights);
        grid->row_heights = NULL;
    }

    if(!grid->no_redraw) {
        InvalidateRect(grid->win, NULL, TRUE);
        grid_setup_scrollbars(grid, TRUE);
    }
    return 0;
}
示例#2
0
文件: table.c 项目: mity/mctrl
void MCTRL_API
mcTable_AddRef(MC_HTABLE hTable)
{
    if(hTable)
        table_ref((table_t*) hTable);
}
示例#3
0
文件: render.c 项目: RobertDash/pspp
/* Creates and returns a new render_page for rendering TABLE on a device
   described by PARAMS.

   The new render_page will be suitable for rendering on a device whose page
   size is PARAMS->size, but the caller is responsible for actually breaking it
   up to fit on such a device, using the render_break abstraction.  */
struct render_page *
render_page_create (const struct render_params *params,
                    const struct table *table_)
{
  struct render_page *page;
  struct table *table;
  enum { MIN, MAX };
  struct render_row *columns[2];
  struct render_row *rows;
  int table_widths[2];
  int *rules[TABLE_N_AXES];
  int nr, nc;
  int x, y;
  int i;
  enum table_axis axis;

  table = table_ref (table_);
  nc = table_nc (table);
  nr = table_nr (table);

  /* Figure out rule widths. */
  for (axis = 0; axis < TABLE_N_AXES; axis++)
    {
      int n = table->n[axis] + 1;
      int z;

      rules[axis] = xnmalloc (n, sizeof *rules);
      for (z = 0; z < n; z++)
        rules[axis][z] = measure_rule (params, table, axis, z);
    }

  /* Calculate minimum and maximum widths of cells that do not
     span multiple columns. */
  for (i = 0; i < 2; i++)
    columns[i] = xzalloc (nc * sizeof *columns[i]);
  for (y = 0; y < nr; y++)
    for (x = 0; x < nc; )
      {
        struct table_cell cell;

        table_get_cell (table, x, y, &cell);
        if (y == cell.d[V][0] && table_cell_colspan (&cell) == 1)
          {
            int w[2];
            int i;

            params->measure_cell_width (params->aux, &cell, &w[MIN], &w[MAX]);
            for (i = 0; i < 2; i++)
              if (columns[i][x].unspanned < w[i])
                columns[i][x].unspanned = w[i];
          }
        x = cell.d[H][1];
        table_cell_free (&cell);
      }

  /* Distribute widths of spanned columns. */
  for (i = 0; i < 2; i++)
    for (x = 0; x < nc; x++)
      columns[i][x].width = columns[i][x].unspanned;
  for (y = 0; y < nr; y++)
    for (x = 0; x < nc; )
      {
        struct table_cell cell;

        table_get_cell (table, x, y, &cell);
        if (y == cell.d[V][0] && table_cell_colspan (&cell) > 1)
          {
            int w[2];

            params->measure_cell_width (params->aux, &cell, &w[MIN], &w[MAX]);
            for (i = 0; i < 2; i++)
              distribute_spanned_width (w[i], &columns[i][cell.d[H][0]],
                                        rules[H], table_cell_colspan (&cell));
          }
        x = cell.d[H][1];
        table_cell_free (&cell);
      }

  /* Decide final column widths. */
  for (i = 0; i < 2; i++)
    table_widths[i] = calculate_table_width (table_nc (table),
                                             columns[i], rules[H]);
  if (table_widths[MAX] <= params->size[H])
    {
      /* Fits even with maximum widths.  Use them. */
      page = create_page_with_exact_widths (params, table, columns[MAX],
                                            rules[H]);
    }
  else if (table_widths[MIN] <= params->size[H])
    {
      /* Fits with minimum widths, so distribute the leftover space. */
      page = create_page_with_interpolated_widths (
        params, table, columns[MIN], columns[MAX],
        table_widths[MIN], table_widths[MAX], rules[H]);
    }
  else
    {
      /* Doesn't fit even with minimum widths.  Assign minimums for now, and
         later we can break it horizontally into multiple pages. */
      page = create_page_with_exact_widths (params, table, columns[MIN],
                                            rules[H]);
    }

  /* Calculate heights of cells that do not span multiple rows. */
  rows = xzalloc (nr * sizeof *rows);
  for (y = 0; y < nr; y++)
    {
      for (x = 0; x < nc; )
        {
          struct render_row *r = &rows[y];
          struct table_cell cell;

          table_get_cell (table, x, y, &cell);
          if (y == cell.d[V][0])
            {
              if (table_cell_rowspan (&cell) == 1)
                {
                  int w = joined_width (page, H, cell.d[H][0], cell.d[H][1]);
                  int h = params->measure_cell_height (params->aux, &cell, w);
                  if (h > r->unspanned)
                    r->unspanned = r->width = h;
                }
              else
                set_join_crossings (page, V, &cell, rules[V]);

              if (table_cell_colspan (&cell) > 1)
                set_join_crossings (page, H, &cell, rules[H]);
            }
          x = cell.d[H][1];
          table_cell_free (&cell);
        }
    }
  for (i = 0; i < 2; i++)
    free (columns[i]);

  /* Distribute heights of spanned rows. */
  for (y = 0; y < nr; y++)
    for (x = 0; x < nc; )
      {
        struct table_cell cell;

        table_get_cell (table, x, y, &cell);
        if (y == cell.d[V][0] && table_cell_rowspan (&cell) > 1)
          {
            int w = joined_width (page, H, cell.d[H][0], cell.d[H][1]);
            int h = params->measure_cell_height (params->aux, &cell, w);
            distribute_spanned_width (h, &rows[cell.d[V][0]], rules[V],
                                      table_cell_rowspan (&cell));
          }
        x = cell.d[H][1];
        table_cell_free (&cell);
      }

  /* Decide final row heights. */
  accumulate_row_widths (page, V, rows, rules[V]);
  free (rows);

  /* Measure headers.  If they are "too big", get rid of them.  */
  for (axis = 0; axis < TABLE_N_AXES; axis++)
    {
      int hw = headers_width (page, axis);
      if (hw * 2 >= page->params->size[axis]
          || hw + max_cell_width (page, axis) > page->params->size[axis])
        {
          page->table = table_unshare (page->table);
          page->table->h[axis][0] = page->table->h[axis][1] = 0;
          page->h[axis][0] = page->h[axis][1] = 0;
        }
    }

  free (rules[H]);
  free (rules[V]);

  return page;
}