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