Transferring a chunk of style definitions and a tree of inline styles into an explict style set that should be used for rendering a component is a complex process.
All the information required to define the full styles are created as the document is laid out. Rendering and output will use the same full style so changes between these stages will not be reflected in the final output.
When the document starts the layout process it creates an empty stack of styles.
The document instance then creates a full default style using the virtual (overridable) CreateDefaultStyle() with a black fill, A4 portrait page and 24pt Helvetica font, and pushes this onto the stack. This is the root style, so the stack should never be empty from now on and there is a standard visual appearance.
The main layout methods are then called to traverse the hierarchy of the component tree, laying out each in turn.
Building the applied style.
As a component is laid out it must first get the ‘applied’ style. This is all the style items and values that are appropriate to be included on that component.
Again this can be broken down into a number of actions.
- Get the base style for the component - The PDFComponent returns an empty style instance that will ultimately be the complete applied style. PDFPanel overrides the base implementation and adds the PositionMode of Block. All components that override the GetBaseStyle method should only call the base method to get the instance, modify as required, and return this instance.
- The component then calls the overloaded GetAppliedStyle() with itself and the base style. This method is virtual, but the default implementation simply calls the same method on it"s parent until the parent is null and will then return the base style.
- The PDFDocument overrides the GetAppliedStyle() to ask its PDFStyleCollection to merge it"s appropriate style items into the base style. The style collection enumerates over it"s child styles asking each one in turn to merge into the base style.
- Each style in the collection could be an individual style definition, or a parsed reference of other style definitions in a PDFStylesDocument, all that matters is that they inherit from PDFStyleBase and therefore implement the MergeInto method that the PDFStyleCollection calls.
- It is up to the style instance to decide if and what should be merged. The PDFStyleDefn uses its AppliedID, AppliedClass and AppliedType property values to decide if it is an appropriate style for the passed component. If it is, then each of the style items within the definition are merged into the passed style.
- Ultimately all the appropriate style items will be included in the applied style and will then be run back up the call stack to the originating component as it"s base style.
Building the full style.
This is half the complete picture. We have a style that would be applied to a component, but there are also other styles built up on the style stack, and some of the items in these styles are inherited by each component below - like font or fill.
- With the components applied style - it is pushed onto the top of the stack (PDFStyleStack) by the layout engine.
- The layout engine then asks the style stack for a full style. This is a complete merge of all appropriate style items in each of the styles in the stack.
- The style stack enumerates from the first to the penultimate added and merges all style items that are inherited - MergeInherited(). The inheritance of an item is a flag on the style item instance, which is set at initialization.
- The last item in the stack (added after building the applied style) is then merged completely - MergeInto().
- The full style is then flattened into a distinct collection of style items and values then returned to the engine.
This is the final full style that will be used when laying out and rendering the component. Because of the complexity in generating a full style, the component will hold a reference to this full style. Any changes to the component style or document style definitions after this stage will not be used in the final rendering.