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; GetRootLayoutItem()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); GetCurrentContainerRecord()61 CXFA_ContainerRecord* GetCurrentContainerRecord() { 62 return *m_CurrentContainerRecordIter; 63 } GetTailPosition()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(); IsPageSetRootOrderedOccurrence()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