Example #1
0
File: table.c Project: mity/mctrl
int
table_set_cell_data(table_t* table, WORD col, WORD row, MC_TABLECELL* cell_data, BOOL unicode)
{
    table_cell_t* cell;
    table_refresh_detail_t refresh_detail;

    TABLE_TRACE("table_set_cell_data(%p, %hd, %hd, %p, %s)",
                table, col, row, cell_data, (unicode ? "unicode" : "ansi"));

    cell = table_get_cell(table, col, row);
    if(MC_ERR(cell == NULL)) {
        MC_TRACE("table_set_cell_data: table_get_cell() failed.");
        return -1;
    }

    if(MC_ERR(cell_data->fMask & ~MC_TCMF_ALL)) {
        MC_TRACE("table_set_cell_data: Unsupported pCell->fMask 0x%x", cell_data->fMask);
        SetLastError(ERROR_INVALID_PARAMETER);
        return -1;
    }

    /* Set the cell */
    if(cell_data->fMask & MC_TCMF_TEXT) {
        TCHAR* str;

        if(cell_data->pszText == MC_LPSTR_TEXTCALLBACK) {
            str = MC_LPSTR_TEXTCALLBACK;
        } else if(cell_data->pszText != NULL) {
            str = mc_str(cell_data->pszText, (unicode ? MC_STRW : MC_STRA), MC_STRT);
            if(MC_ERR(str == NULL)) {
                MC_TRACE("table_set_cell_data: mc_str() failed.");
                return -1;
            }
        } else {
            str = NULL;
        }
        table_cell_clear(cell);
        cell->text = str;
    }

    if(cell_data->fMask & MC_TCMF_PARAM)
        cell->lp = cell_data->lParam;

    if(cell_data->fMask & MC_TCMF_FLAGS)
        cell->flags = cell_data->dwFlags;

    /* Refresh */
    refresh_detail.event = TABLE_CELL_CHANGED;
    refresh_detail.param[0] = col;
    refresh_detail.param[1] = row;
    table_refresh(table, &refresh_detail);

    return 0;
}
Example #2
0
File: table.c Project: mity/mctrl
int
table_get_cell_data(table_t* table, WORD col, WORD row, MC_TABLECELL* cell_data, BOOL unicode)
{
    table_cell_t* cell;

    TABLE_TRACE("table_get_cell_data(%p, %hd, %hd, %p, %s)",
                table, col, row, cell_data, (unicode ? "unicode" : "ansi"));

    cell = table_get_cell(table, col, row);
    if(MC_ERR(cell == NULL)) {
        MC_TRACE("table_set_cell_data: table_get_cell_data() failed.");
        return -1;
    }

    if(MC_ERR(cell_data->fMask & ~MC_TCMF_ALL)) {
        MC_TRACE("table_get_cell_data: Unsupported pCell->fMask 0x%x", cell_data->fMask);
        SetLastError(ERROR_INVALID_PARAMETER);
        return -1;
    }

    if(cell_data->fMask & MC_TCMF_TEXT) {
        if(cell->text == MC_LPSTR_TEXTCALLBACK) {
            MC_TRACE("table_get_cell_data: Table cell contains "
                     "MC_LPSTR_TEXTCALLBACK and that cannot be asked for.");
            SetLastError(ERROR_INVALID_PARAMETER);
            return -1;
        } else {
            mc_str_inbuf(cell->text, MC_STRT, cell_data->pszText,
                         (unicode ? MC_STRW : MC_STRA), cell_data->cchTextMax);
        }
    }

    if(cell_data->fMask & MC_TCMF_PARAM)
        cell_data->lParam = cell->lp;

    if(cell_data->fMask & MC_TCMF_FLAGS)
        cell_data->dwFlags = cell->flags;

    return 0;
}
Example #3
0
/* 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;
}