Home | History | Annotate | Download | only in parser
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #ifndef XFA_FXFA_PARSER_CXFA_LAYOUTPAGEMGR_H_
      8 #define XFA_FXFA_PARSER_CXFA_LAYOUTPAGEMGR_H_
      9 
     10 #include <iterator>
     11 #include <list>
     12 #include <map>
     13 #include <vector>
     14 
     15 #include "xfa/fxfa/parser/cxfa_itemlayoutprocessor.h"
     16 
     17 class CXFA_ContainerRecord;
     18 class CXFA_LayoutItem;
     19 class CXFA_Node;
     20 
     21 class CXFA_LayoutPageMgr {
     22  public:
     23   explicit CXFA_LayoutPageMgr(CXFA_LayoutProcessor* pLayoutProcessor);
     24   ~CXFA_LayoutPageMgr();
     25 
     26   bool InitLayoutPage(CXFA_Node* pFormNode);
     27   bool PrepareFirstPage(CXFA_Node* pRootSubform);
     28   float GetAvailHeight();
     29   bool GetNextAvailContentHeight(float fChildHeight);
     30   void SubmitContentItem(CXFA_ContentLayoutItem* pContentLayoutItem,
     31                          XFA_ItemLayoutProcessorResult eStatus);
     32   void FinishPaginatedPageSets();
     33   void SyncLayoutData();
     34   int32_t GetPageCount() const;
     35   CXFA_ContainerLayoutItem* GetPage(int32_t index) const;
     36   int32_t GetPageIndex(const CXFA_ContainerLayoutItem* pPage) const;
     37   inline CXFA_ContainerLayoutItem* GetRootLayoutItem() const {
     38     return m_pPageSetLayoutItemRoot;
     39   }
     40   bool ProcessBreakBeforeOrAfter(CXFA_Node* pBreakNode,
     41                                  bool bBefore,
     42                                  CXFA_Node*& pBreakLeaderNode,
     43                                  CXFA_Node*& pBreakTrailerNode,
     44                                  bool& bCreatePage);
     45   bool ProcessOverflow(CXFA_Node* pFormNode,
     46                        CXFA_Node*& pLeaderNode,
     47                        CXFA_Node*& pTrailerNode,
     48                        bool bDataMerge = false,
     49                        bool bCreatePage = true);
     50   CXFA_Node* QueryOverflow(CXFA_Node* pFormNode);
     51   bool ProcessBookendLeaderOrTrailer(CXFA_Node* pBookendNode,
     52                                      bool bLeader,
     53                                      CXFA_Node*& pBookendAppendNode);
     54 
     55  private:
     56   bool AppendNewPage(bool bFirstTemPage = false);
     57   void ReorderPendingLayoutRecordToTail(CXFA_ContainerRecord* pNewRecord,
     58                                         CXFA_ContainerRecord* pPrevRecord);
     59   void RemoveLayoutRecord(CXFA_ContainerRecord* pNewRecord,
     60                           CXFA_ContainerRecord* pPrevRecord);
     61   CXFA_ContainerRecord* GetCurrentContainerRecord() {
     62     return *m_CurrentContainerRecordIter;
     63   }
     64   std::list<CXFA_ContainerRecord*>::iterator GetTailPosition() {
     65     auto iter = m_ProposedContainerRecords.end();
     66     return !m_ProposedContainerRecords.empty() ? std::prev(iter) : iter;
     67   }
     68   CXFA_ContainerRecord* CreateContainerRecord(CXFA_Node* pPageNode = nullptr,
     69                                               bool bCreateNew = false);
     70   void AddPageAreaLayoutItem(CXFA_ContainerRecord* pNewRecord,
     71                              CXFA_Node* pNewPageArea);
     72   void AddContentAreaLayoutItem(CXFA_ContainerRecord* pNewRecord,
     73                                 CXFA_Node* pContentArea);
     74   bool RunBreak(XFA_Element eBreakType,
     75                 XFA_AttributeEnum eTargetType,
     76                 CXFA_Node* pTarget,
     77                 bool bStartNew);
     78   CXFA_Node* BreakOverflow(CXFA_Node* pOverflowNode,
     79                            CXFA_Node*& pLeaderTemplate,
     80                            CXFA_Node*& pTrailerTemplate,
     81                            bool bCreatePage = true);
     82   bool ResolveBookendLeaderOrTrailer(CXFA_Node* pBookendNode,
     83                                      bool bLeader,
     84                                      CXFA_Node*& pBookendAppendTemplate);
     85   bool ExecuteBreakBeforeOrAfter(CXFA_Node* pCurNode,
     86                                  bool bBefore,
     87                                  CXFA_Node*& pBreakLeaderTemplate,
     88                                  CXFA_Node*& pBreakTrailerTemplate);
     89 
     90   int32_t CreateMinPageRecord(CXFA_Node* pPageArea,
     91                               bool bTargetPageArea,
     92                               bool bCreateLast = false);
     93   void CreateMinPageSetRecord(CXFA_Node* pPageSet, bool bCreateAll = false);
     94   void CreateNextMinRecord(CXFA_Node* pRecordNode);
     95   bool FindPageAreaFromPageSet(CXFA_Node* pPageSet,
     96                                CXFA_Node* pStartChild,
     97                                CXFA_Node* pTargetPageArea = nullptr,
     98                                CXFA_Node* pTargetContentArea = nullptr,
     99                                bool bNewPage = false,
    100                                bool bQuery = false);
    101   bool FindPageAreaFromPageSet_Ordered(CXFA_Node* pPageSet,
    102                                        CXFA_Node* pStartChild,
    103                                        CXFA_Node* pTargetPageArea = nullptr,
    104                                        CXFA_Node* pTargetContentArea = nullptr,
    105                                        bool bNewPage = false,
    106                                        bool bQuery = false);
    107   bool FindPageAreaFromPageSet_SimplexDuplex(
    108       CXFA_Node* pPageSet,
    109       CXFA_Node* pStartChild,
    110       CXFA_Node* pTargetPageArea = nullptr,
    111       CXFA_Node* pTargetContentArea = nullptr,
    112       bool bNewPage = false,
    113       bool bQuery = false,
    114       XFA_AttributeEnum ePreferredPosition = XFA_AttributeEnum::First);
    115   bool MatchPageAreaOddOrEven(CXFA_Node* pPageArea);
    116   CXFA_Node* GetNextAvailPageArea(CXFA_Node* pTargetPageArea,
    117                                   CXFA_Node* pTargetContentArea = nullptr,
    118                                   bool bNewPage = false,
    119                                   bool bQuery = false);
    120   bool GetNextContentArea(CXFA_Node* pTargetContentArea);
    121   void InitPageSetMap();
    122   void ProcessLastPageSet();
    123   bool IsPageSetRootOrderedOccurrence() const {
    124     return m_ePageSetMode == XFA_AttributeEnum::OrderedOccurrence;
    125   }
    126   void ClearData();
    127   void MergePageSetContents();
    128   void LayoutPageSetContents();
    129   void PrepareLayout();
    130   void SaveLayoutItem(CXFA_LayoutItem* pParentLayoutItem);
    131 
    132   CXFA_LayoutProcessor* m_pLayoutProcessor;
    133   CXFA_Node* m_pTemplatePageSetRoot;
    134   CXFA_ContainerLayoutItem* m_pPageSetLayoutItemRoot;
    135   CXFA_ContainerLayoutItem* m_pPageSetCurRoot;
    136   std::list<CXFA_ContainerRecord*> m_ProposedContainerRecords;
    137   std::list<CXFA_ContainerRecord*>::iterator m_CurrentContainerRecordIter;
    138   CXFA_Node* m_pCurPageArea;
    139   int32_t m_nAvailPages;
    140   int32_t m_nCurPageCount;
    141   XFA_AttributeEnum m_ePageSetMode;
    142   bool m_bCreateOverFlowPage;
    143   std::map<CXFA_Node*, int32_t> m_pPageSetMap;
    144   std::vector<CXFA_ContainerLayoutItem*> m_PageArray;
    145 };
    146 
    147 #endif  // XFA_FXFA_PARSER_CXFA_LAYOUTPAGEMGR_H_
    148