/**
 * clutter_actor_get_allocation_geometry:
 * @self: A #ClutterActor
 * @geom: (out): allocation geometry in pixels
 *
 * Gets the layout box an actor has been assigned.  The allocation can
 * only be assumed valid inside a paint() method; anywhere else, it
 * may be out-of-date.
 *
 * An allocation does not incorporate the actor's scale or anchor point;
 * those transformations do not affect layout, only rendering.
 *
 * The returned rectangle is in pixels.
 *
 * Since: 0.8
 *
 * Deprecated: 1.12: Use clutter_actor_get_allocation_box() instead.
 */
void
clutter_actor_get_allocation_geometry (ClutterActor    *self,
                                       ClutterGeometry *geom)
{
  ClutterActorBox box;

  g_return_if_fail (CLUTTER_IS_ACTOR (self));
  g_return_if_fail (geom != NULL);

  clutter_actor_get_allocation_box (self, &box);

  geom->x = CLUTTER_NEARBYINT (clutter_actor_box_get_x (&box));
  geom->y = CLUTTER_NEARBYINT (clutter_actor_box_get_y (&box));
  geom->width = CLUTTER_NEARBYINT (clutter_actor_box_get_width (&box));
  geom->height = CLUTTER_NEARBYINT (clutter_actor_box_get_height (&box));
}
static void
clutter_table_layout_allocate (ClutterLayoutManager   *layout,
                               ClutterContainer       *container,
                               const ClutterActorBox  *box,
                               ClutterAllocationFlags  flags)
{
  ClutterTableLayout *self = CLUTTER_TABLE_LAYOUT (layout);
  ClutterTableLayoutPrivate *priv = self->priv;
  ClutterActor *actor, *child;
  gint row_spacing, col_spacing;
  gint i;
  DimensionData *rows, *columns;

  update_row_col (self, container);
  if (priv->n_cols < 1 || priv->n_rows < 1)
    return;

  actor = CLUTTER_ACTOR (container);

  if (clutter_actor_get_n_children (actor) == 0)
    return;

  col_spacing = (priv->col_spacing);
  row_spacing = (priv->row_spacing);

  calculate_table_dimensions (self, container,
                              box->x2 - box->x1,
                              box->y2 - box->y1);

  rows = (DimensionData *) (void *) priv->rows->data;
  columns = (DimensionData *) (void *) priv->columns->data;

  for (child = clutter_actor_get_first_child (actor);
       child != NULL;
       child = clutter_actor_get_next_sibling (child))
    {
      gint row, col, row_span, col_span;
      gint col_width, row_height;
      ClutterTableChild *meta;
      ClutterActorBox childbox;
      gint child_x, child_y;

      if (!CLUTTER_ACTOR_IS_VISIBLE (child))
        continue;

      meta =
        CLUTTER_TABLE_CHILD (clutter_layout_manager_get_child_meta (layout,
                                                                    container,
                                                                    child));

      /* get child properties */
      col = meta->col;
      row = meta->row;
      row_span = meta->row_span;
      col_span = meta->col_span;

      /* initialise the width and height */
      col_width = columns[col].final_size;
      row_height = rows[row].final_size;

      /* Add the widths of the spanned columns:
       *
       * First check that we have a non-zero span. Then we loop over each of
       * the columns that we're spanning but we stop short if we go past the
       * number of columns in the table. This is necessary to avoid accessing
       * uninitialised memory. We add the spacing in here too since we only
       * want to add as much spacing as times we successfully span.
       */
      if (col + col_span > priv->n_cols)
        g_warning (G_STRLOC ": column-span exceeds number of columns");
      if (row + row_span > priv->n_rows)
        g_warning (G_STRLOC ": row-span exceeds number of rows");

      if (col_span > 1)
        {
          for (i = col + 1; i < col + col_span && i < priv->n_cols; i++)
            {
              col_width += columns[i].final_size;
              col_width += col_spacing;
            }
        }

      /* add the height of the spanned rows */
      if (row_span > 1)
        {
          for (i = row + 1; i < row + row_span && i < priv->n_rows; i++)
            {
              row_height += rows[i].final_size;
              row_height += row_spacing;
            }
        }

      /* calculate child x */
      child_x = clutter_actor_box_get_x (box);
      for (i = 0; i < col; i++)
        {
          if (columns[i].visible)
            {
              child_x += columns[i].final_size;
              child_x += col_spacing;
            }
        }

      /* calculate child y */
      child_y = clutter_actor_box_get_y (box);
      for (i = 0; i < row; i++)
        {
          if (rows[i].visible)
            {
              child_y += rows[i].final_size;
              child_y += row_spacing;
            }
        }

      /* set up childbox */
      childbox.x1 = (float) child_x;
      childbox.x2 = (float) MAX (0, child_x + col_width);

      childbox.y1 = (float) child_y;
      childbox.y2 = (float) MAX (0, child_y + row_height);

      clutter_actor_allocate (child, &childbox, flags);
    }
}