# Anatomy of a Formatting Object area source code file

## FO -area.c File

Abstract

Anatomy of a Formatting Object area source code file

These files are not autogenerated.

Some, but not all, formatting objects generate areas. Those that do generate areas and are implemented in xmlroff have an -area.c and area.h file.

The -area.[ch] files exist to implement fo_fo_area_new2() for the GObject class for the formatting object (or, for formatting objects implemented early and not yet brought up to date, to implement fo_fo_area_new()).

The _area_new2() or _area_new() function creates an area of the type appropriate for the formatting object and adds it to the formatting object tree.

The differences between the _area_new2() and _area_new() functions are really just in their interface: the _area_new2() functions get most of their inputs in a FoFoAreaNew2Context structure rather than as individual arguments. The _area_new2() functions also have a GError argument for error reporting.

The least straightforward -area.c file is fo-block-area.c, since that's where FoText and inline formatting objects are made into Pango layouts. The rest are mostly straightforward.

### Initial comment

    /* Fo
     * fo-table-body-area.c: Generate area for 'table-body' formatting object
     *
     * Copyright (C) 2001 Sun Microsystems
     *
     * $Id: fo-area-c-file.xml,v 1.1 2006/03/14 19:42:57 tonygraham Exp $
     *
     * See Copying for the status of this software.
     */

### #includes

    #include <fo-area-table-body.h>

The public interface for the type of area generated by this formatting object.

    #include <fo-table-body-private.h>

The private interface of this formatting object type.

### FoFo _area_new2()

Add the area generated by the formatting object to the area tree.

     /**
     * fo_table_body_area_new2:
     * @fo:      #FoTableBody
     * @context: #FoFoAreaNew2Context
     * @error:   #GError
     *
     * Create a new area for @fo and add it to the parent area.
     *
     * A pointer to the parent area is in @context.
     **/
    void
    fo_table_body_area_new2 (FoFo                *fo,
                             FoFoAreaNew2Context *context,
                             GError             **error)
    {
     FoTableBody *table_body = (FoTableBody *) fo;
     FoArea *use_parent_area;
     FoArea *new_area;

     g_return_if_fail (table_body != NULL);
     g_return_if_fail (FO_IS_TABLE_BODY (table_body));
     g_return_if_fail (context != NULL);
     g_return_if_fail (error == NULL || *error == NULL);

     new_area = fo_area_table_body_new ();
     use_parent_area = context->parent_area;

    #if defined(LIBFO_DEBUG) && 0
     g_warning ("*** table-body parent before new area:");
     fo_object_debug_dump (parent_area, 0);
     g_warning ("*** end table-body parent");
     #endif

    FO_AREA (new_area)->generated_by = fo;

Areas keep track of which FO generated them so they can get some property values, e.g., colors, from the FO rather than loading the area objects with duplicates of all the applicable formatting object property values.

     FO_FO (fo)->areas = g_list_append (FO_FO (fo)->areas, new_area);

FOs keep track of which areas they've generated

     fo_area_add_child (use_parent_area, new_area);

Attach the new area to the area tree.

     new_area = fo_area_size_request (new_area);

The new area asks its parent to allocate space for it. Anything could happen at this point: the area might not fit in the space remaining for it on the current page, so the new area, the parent area, and all containing areas up the page area may need to be split so one part of the new area is on the current page and the rest on the next page (or on multiple pages if it is big enough).

Consequently, the area returned by fo_area_size_request() might not be the same area that was passed to it. The return value is the last area resulting from the original new_area.

     fo_area_area_set_width (new_area, fo_area_get_available_width (new_area));

    #if defined(LIBFO_DEBUG) && 0
     g_warning ("*** table-body parent after new area:");
     fo_object_debug_dump (parent_area, 0);
     g_warning ("*** end table-body parent");
    #endif

     *(context->new_area) = new_area;

'Return' the new area so there's somewhere to hang the areas generated by the children of the current formatting object.

    }