# CPdf

CPdf class is main pdf document class. It maintains document content using `XRefWriter` field, document catalog PDF dictionary and provides other specialized highlevel objects such as CPage (see ) and `COutline`.

Main responsibility is to keep all objects (it provides) synchronized with data which are used for them. As an example, it has to keep CPage instances synchronized with current state of page tree.

In design terminology, CPdf provides ; to manipulate with file in document scope of view. All internal objects used for particular purposes are hidden from class user and CPdf provides interface for manipulation with it (as an example, CPdf uses `XRefWriter` (see ) which enables making changes to document, but exports only `CXref` (see ) which enables just objects fetching - almost same interface as Xpdf `XRef` class).

## Instance life cycle

Instance of CPdf can be create only by `getInstance` factory method (see ) which returns instanstance wraped by shared_ptr which controls the life cycle. Instance is deallocated when the last reference to it is droped. CPdf instance is one purpose object which maintains exactly one document during its lifetime (between creation and close).

## CPdf modes

Each document may be opened in one of several modes. Each controls set of activities which can be done. ReadOnly mode guaranties that no change can be done to document. ReadWrite mode enables making changes but with some restriction (see programming documentation for more information). Finaly Advanced mode brigns full control upon document.

## Properties changing and revision handling

All changes to the document are done using `XRefWriter` as described in . Additional logic and responsibility of CPdf in this direction is to make adpater from `IProperty` interface of property to xpdf Object required by `XRefWriter`. Even more it also provides interface to get indirect objects in IProperty form. This means that it obscures low level information about who is doing parsing and storing and what data types are used. Also guaranties that all indirect properties are represented by same instance of IProperty to enable their reasonable usage.

To enable proper smart pointer implementation, CPdf holds weak_ptr to itself (called _this) initialized from shared_ptr returned by getInstance factory method. This is in turn used for initialization of all properties. The trick is that weak_ptr are valid only until original shared_ptr is valid. In the moment when the last reference is droped, all weak_ptr are no more valid and code which tries to use them can detect that without any problems (weak_ptr::lock method will simply fail and code can handle that).

To enable also inter document data exchange (in form of properties), it provides functionality for adding of indirect properties. When property is from other CPdf (this may mean other document), it'll do all neccesary handling for this situation (e. g. all other indirect objects which are refered from added one are added too).

Revision handling is done similar way but in this case without any special logic. Revision changing and geting current revision or cloning is directly delegated to `XRefWriter`. If document save is required, just checks whether mode is not read only and delegates the rest to `XRefWriter`

## Provided high level objects

CPdf provides high level objects maintaining some specialized part of document . These objects brings logic on properties with special meaning in pdf document. E. g. Pdf describes page as dictionary which contains all neccessary information for page (page attributes), its position in page tree (reference to parent tree node) and its content stored in . `CPage` then uses this dictionary for its initialization and provides logic for this dictionary.

CPdf facade scheme