Scryber has a strong and deep structure.
This helps to keep the code clean and free from defects, but also to improves reuse and readability.
Full Size Image
The main PDFComponent hierarchy (including the PDFDocument) can be built either by hand cracking some code, or by writing the more concise XML and parsing this into a hierarchy.
Initialization and Loading
Once the processing starts (using ProcessDocument) then the initialisation and loading methods will be called for the entire component hierarchy and events will be raised in turn. It is possible to hook into these events to provide custom processing as required.
If greater control is needed than the overarching ProcessDocument method, then to manually invoke this stage use the InitAndLoad() method on the document class. This will ensure that the full process and lifecycle will continue to be followed and all components are initialized..
If the document AutoBind flag is set to true or an explicit call is made to DataBind(), then the entire document will be data bound bound. The PDFXMLParser hooks to the binding events of the components to dynamically build inner content at runtime using the binding templates. These will generate any required components based on data-sources and other actions.
It is easy to attach a handler to the data bind events of any component in the hierarchy just using standard .NET event handlers.
NOTE: We are still using the PDFComponent hierarchy. All the components, once generated with the data binding, are fully qualified members of the family.
Layout and Rendering
These 2 operations cannot be called separately as they are intrinsically linked
The layout operation converts the strongly typed, hard structure that has been built in the PDFComponent hierarchy into a looser and more generic PDFLayoutDocument. This is done through the use of layout engines. The engines are instantiated by the component and are then allowed to build some or all of the layout document as required.
As the layout is built up so page headers and other layout template components are dynamically generated and explicitly laid out, and the engine is also at liberty to use the styling information associated with each visual component.
The layout document is a much simpler structure with a hierarchy Pages, Blocks, Regions, Lines, and Runs, but the layout document also holds references to any resources (Fonts, Images, Patterns) and artefacts (Outlines, Link Destinations, Names) that are required to output the final document.
Once the whole document has been laid out and all artefacts registered then the layout document can render itself. Rather than writing directly to the underlying output stream, all rendering information (including document meta data and structure) is output using an instance of the PDFWriter.
The writer provides a higher level option for output, and supports the file structure of a PDF Document.
The PDFGraphics instance provides standard drawing and colouring capabilities and generates the correct op codes or object dictionaries required by the PDF reader to describe the requested graphical intent. Supplementary to this are the brushes, pens, and fonts that all set up the graphical and textual context for the operations to occur within.
The output from the PDFWriter is collected in indirect object instances (with up to 2 inner streams - object stream and data stream). Only once the Writer is closed does the data get written in the correct order with the appropriate structure to the underlying stream.