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 
     14 #include "xfa/fxfa/parser/xfa_layout_itemlayout.h"
     15 
     16 class CXFA_ContainerRecord;
     17 class CXFA_LayoutItem;
     18 
     19 class CXFA_LayoutPageMgr {
     20  public:
     21   explicit CXFA_LayoutPageMgr(CXFA_LayoutProcessor* pLayoutProcessor);
     22   ~CXFA_LayoutPageMgr();
     23 
     24   bool InitLayoutPage(CXFA_Node* pFormNode);
     25   bool PrepareFirstPage(CXFA_Node* pRootSubform);
     26   FX_FLOAT GetAvailHeight();
     27   bool GetNextAvailContentHeight(FX_FLOAT fChildHeight);
     28   void SubmitContentItem(CXFA_ContentLayoutItem* pContentLayoutItem,
     29                          XFA_ItemLayoutProcessorResult eStatus);
     30   void FinishPaginatedPageSets();
     31   void SyncLayoutData();
     32   int32_t GetPageCount() const;
     33   CXFA_ContainerLayoutItem* GetPage(int32_t index) const;
     34   int32_t GetPageIndex(const CXFA_ContainerLayoutItem* pPage) const;
     35   inline CXFA_ContainerLayoutItem* GetRootLayoutItem() const {
     36     return m_pPageSetLayoutItemRoot;
     37   }
     38   bool ProcessBreakBeforeOrAfter(CXFA_Node* pBreakNode,
     39                                  bool bBefore,
     40                                  CXFA_Node*& pBreakLeaderNode,
     41                                  CXFA_Node*& pBreakTrailerNode,
     42                                  bool& bCreatePage);
     43   bool ProcessOverflow(CXFA_Node* pFormNode,
     44                        CXFA_Node*& pLeaderNode,
     45                        CXFA_Node*& pTrailerNode,
     46                        bool bDataMerge = false,
     47                        bool bCreatePage = true);
     48   CXFA_Node* QueryOverflow(CXFA_Node* pFormNode,
     49                            CXFA_LayoutContext* pLayoutContext = nullptr);
     50   bool ProcessBookendLeaderOrTrailer(CXFA_Node* pBookendNode,
     51                                      bool bLeader,
     52                                      CXFA_Node*& pBookendAppendNode);
     53 
     54  protected:
     55   bool AppendNewPage(bool bFirstTemPage = false);
     56   void ReorderPendingLayoutRecordToTail(CXFA_ContainerRecord* pNewRecord,
     57                                         CXFA_ContainerRecord* pPrevRecord);
     58   void RemoveLayoutRecord(CXFA_ContainerRecord* pNewRecord,
     59                           CXFA_ContainerRecord* pPrevRecord);
     60   CXFA_ContainerRecord* GetCurrentContainerRecord() {
     61     return *m_CurrentContainerRecordIter;
     62   }
     63   std::list<CXFA_ContainerRecord*>::iterator GetTailPosition() {
     64     auto iter = m_ProposedContainerRecords.end();
     65     return !m_ProposedContainerRecords.empty() ? std::prev(iter) : iter;
     66   }
     67   CXFA_ContainerRecord* CreateContainerRecord(CXFA_Node* pPageNode = nullptr,
     68                                               bool bCreateNew = false);
     69   void AddPageAreaLayoutItem(CXFA_ContainerRecord* pNewRecord,
     70                              CXFA_Node* pNewPageArea);
     71   void AddContentAreaLayoutItem(CXFA_ContainerRecord* pNewRecord,
     72                                 CXFA_Node* pContentArea);
     73   bool RunBreak(XFA_Element eBreakType,
     74                 XFA_ATTRIBUTEENUM eTargetType,
     75                 CXFA_Node* pTarget,
     76                 bool bStartNew);
     77   CXFA_Node* BreakOverflow(CXFA_Node* pOverflowNode,
     78                            CXFA_Node*& pLeaderTemplate,
     79                            CXFA_Node*& pTrailerTemplate,
     80                            bool bCreatePage = true);
     81   bool ResolveBookendLeaderOrTrailer(CXFA_Node* pBookendNode,
     82                                      bool bLeader,
     83                                      CXFA_Node*& pBookendAppendTemplate);
     84   bool ExecuteBreakBeforeOrAfter(CXFA_Node* pCurNode,
     85                                  bool bBefore,
     86                                  CXFA_Node*& pBreakLeaderTemplate,
     87                                  CXFA_Node*& pBreakTrailerTemplate);
     88 
     89   int32_t CreateMinPageRecord(CXFA_Node* pPageArea,
     90                               bool bTargetPageArea,
     91                               bool bCreateLast = false);
     92   void CreateMinPageSetRecord(CXFA_Node* pPageSet, bool bCreateAll = false);
     93   void CreateNextMinRecord(CXFA_Node* pRecordNode);
     94   bool FindPageAreaFromPageSet(CXFA_Node* pPageSet,
     95                                CXFA_Node* pStartChild,
     96                                CXFA_Node* pTargetPageArea = nullptr,
     97                                CXFA_Node* pTargetContentArea = nullptr,
     98                                bool bNewPage = false,
     99                                bool bQuery = false);
    100   bool FindPageAreaFromPageSet_Ordered(CXFA_Node* pPageSet,
    101                                        CXFA_Node* pStartChild,
    102                                        CXFA_Node* pTargetPageArea = nullptr,
    103                                        CXFA_Node* pTargetContentArea = nullptr,
    104                                        bool bNewPage = false,
    105                                        bool bQuery = false);
    106   bool FindPageAreaFromPageSet_SimplexDuplex(
    107       CXFA_Node* pPageSet,
    108       CXFA_Node* pStartChild,
    109       CXFA_Node* pTargetPageArea = nullptr,
    110       CXFA_Node* pTargetContentArea = nullptr,
    111       bool bNewPage = false,
    112       bool bQuery = false,
    113       XFA_ATTRIBUTEENUM ePreferredPosition = XFA_ATTRIBUTEENUM_First);
    114   bool MatchPageAreaOddOrEven(CXFA_Node* pPageArea, bool bLastMatch);
    115   CXFA_Node* GetNextAvailPageArea(CXFA_Node* pTargetPageArea,
    116                                   CXFA_Node* pTargetContentArea = nullptr,
    117                                   bool bNewPage = false,
    118                                   bool bQuery = false);
    119   bool GetNextContentArea(CXFA_Node* pTargetContentArea);
    120   void InitPageSetMap();
    121   void ProcessLastPageSet();
    122   bool IsPageSetRootOrderedOccurrence() const {
    123     return m_ePageSetMode == XFA_ATTRIBUTEENUM_OrderedOccurrence;
    124   }
    125   void ClearData();
    126   void MergePageSetContents();
    127   void LayoutPageSetContents();
    128   void PrepareLayout();
    129   void SaveLayoutItem(CXFA_LayoutItem* pParentLayoutItem);
    130 
    131   CXFA_LayoutProcessor* m_pLayoutProcessor;
    132   CXFA_Node* m_pTemplatePageSetRoot;
    133   CXFA_ContainerLayoutItem* m_pPageSetLayoutItemRoot;
    134   CXFA_ContainerLayoutItem* m_pPageSetCurRoot;
    135   std::list<CXFA_ContainerRecord*> m_ProposedContainerRecords;
    136   std::list<CXFA_ContainerRecord*>::iterator m_CurrentContainerRecordIter;
    137   CXFA_Node* m_pCurPageArea;
    138   int32_t m_nAvailPages;
    139   int32_t m_nCurPageCount;
    140   XFA_ATTRIBUTEENUM m_ePageSetMode;
    141   bool m_bCreateOverFlowPage;
    142   std::map<CXFA_Node*, int32_t> m_pPageSetMap;
    143   CFX_ArrayTemplate<CXFA_ContainerLayoutItem*> m_PageArray;
    144 };
    145 
    146 #endif  // XFA_FXFA_PARSER_CXFA_LAYOUTPAGEMGR_H_
    147