Back to FOPProjectPages


Integrating Alt-Design FO Tree into Redesign

Bridging the 0.20.0 -> 0.20.5 gap

Cleaning up org.apache.fop.apps

The org.apache.fop.apps package, in particular requires upgrading to compatibility with 0.20.5. To work on alt.design, the apps code at the time of branching was mercilessy hacked to provide a minimal front-end for alt.design. Logging, for instance, is still performed by MessageHandler.

Checkstyle

Anyone with an interest in the integration, but cautious about approaching the code would do a great service by cleaning the alt.design codebase up with Checkstyle. I have recently been developing with Eclipse and the 3.1.1 Checkstyle plugin, so a basic environment for such a cleanup process now exists.

Issues in the alt.design code

Tidying existing structure

    public static final int 
                                    NO_PROPERTY = 0, 
            // Properties setting up environment for from-table-column(), 
            // e.g. font-size = from-table-column() 
                                  COLUMN_NUMBER = 1, 
                         NUMBER_COLUMNS_SPANNED = 2, 
            // Properties setting font-size first 
            // Shorthand first 
                                           FONT = 3, 
                                      FONT_SIZE = 4, 
            // Writing mode early for handling of corresponding values 
                                   WRITING_MODE = 5, 
            // All other shorthands 

            // Non-shorthand properties 
            // Within these, compounds precede their components 
            // and corresponding relative properties 
            // precede corresponding absolute properties 

                    // Handle corresponding properties here 

            /** The number of markers on this FO. */ 
            private int numMarkers = 0; 

            ... 
            while ((ev = xmlevents.expectStartElement 
                    (FObjectNames.MARKER, XMLEvent.DISCARD_W_SPACE)) 
                   != null) { 
                new FoMarker(getFOTree(), this, ev, stateFlags); 
                numMarkers++; 
                ev = xmlevents.getEndElement(xmlevents.DISCARD_EV, ev); 
                pool.surrenderEvent(ev); 

        case PropertyValue.FROM_PARENT: 
            pv = ((FromParent)value).resolve(foNode); 
            if (pv == value) return value;  // unable to resolve 
            // TODO: validate here 
            return pv; 
        case PropertyValue.FROM_NEAREST_SPECIFIED: 
            pv = ((FromNearestSpecified)value).resolve(foNode); 
            if (pv == value) return value;  // unable to resolve 
            // TODO: validate here 
            return pv; 
        case PropertyValue.INHERITED_VALUE: 
            pv = ((InheritedValue)value).resolve(foNode); 
            if (pv == value) return value;  // unable to resolve 
            // TODO: validate here 
            return pv; 

    public void validate(int testProperty, int type) 
        throws PropertyException 
    { 
        // N.B. PROPERTY_SPECIFIC inheritance may require more specialized 
        // checks.  Only line-height comes into this category. 
        if ((propertyConsts.getDataTypes(testProperty) & type) == 0) { 
            String pname = PropNames.getPropertyName(testProperty); 
            throw new PropertyException 
                    ("Datatype(s) " + 
                     Property.listDataTypes(type) + 
                     " not defined on " + pname); 
        } 
    } 

Accessing property values

No property objects

Only singleton property objects exist. The data in property objects is regarded as a set of constants. How are property values maintained? The property value objects (e.g. Numeric, Literal) are associated with Flow Objects. The property whose value these property value objects represents is maintained in the property value object itself as an integer property index. The list of these integers is maintained in  { { { .../fo/PropNames.java } } } .

The singletons are generated in the  { { { setupProperty(int) } } }  method of  { { { .../fo/PropertyConsts.java } } } .  { { { setupProperty() } } }  is called within all of the getters of  { { { PropertyConsts } } } .

Storage of property values

The set of property values applicable to an FO is kept, when the building of an subtrees of the FO is completed, in the array  { { { private PropertyValue[] sparsePropsSet; } } }  The property indices of properties in  { { { sparePropsSet } } }  are contained in property index order in  { { { private final int[] sparseIndices; } } }  Both of these arrays have only enough elements to contain the applicable properties for the FO. In order to map from a property index to the associated  { { { PropertyValue } } }  in  { { { sparsePropsSet } } } , the array  { { { private final int[] sparsePropsMap; } } }  is required. Indexed by property index, it contains the corresponding index into  { { { sparsePropsSet } } } .

For example, suppose that only three properties are applicable to a certain FO. The indices of those properties are 25, 200 and 201.  { { { sparsePropsSet } } }  and  { { { sparseIndices } } }  will both contain three values;  { { { sparsePropsSet } } }  the actual property values for properties 25, 200 and 201 in elements 0, 1 and 2 respectively, and  { { { sparseIndices } } }  the  int  values 25, 200 and 201 in elements 0, 1 and 2 respectively.  { { { sparsePropsMap } } }  contains  { { { PropNames.LAST_PROPERTY_INDEX + 1 } } }  elements, initialized to -1. Elements 25, 200, and 201 will be reset to contain the values 0, 1 and 2 respectively.

Given a property index  property , the property value associated with the the index can be obtained by  sparsePropsSet[ sparsePropsMap[property] ] 

The accessor for property values within  { { { .../fo/FONode.java } } }  and descendants is the method  public PropertyValue getPropertyValue(int property) 

Potential problem with static-content

Depending on the results of an enquiry now before the xsl-editors, the handling of properties within static-content may have to change slightly. The above minimal scheme of properties data, compressed to only those properties which are relevant to a particular FO, builds the  { { { sparsePropsSet } } }  after the FO subtree of all of its children has been built. The assumption here is that properties which are not actaull applicable to the FO in question are no longer required. Any reference to such a property from within the FO's subtree (e.g. via the  { { { FromNearestSpecifiedValue() } } }  function) will have been resolved.

This may not be the case when marker subtrees are conceptually subpended to a node within static-content during the resolution of markers. In this case, for FOs within static-content, some indication of properties specified on the node may need to be kept.

Extending current design

Add support for FOP extensions

Tighter Area Tree integration

FOPAltDesignIntegration (last edited 2009-09-20 23:52:37 by localhost)