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_LAYOUT_CXFA_VIEWLAYOUTPROCESSOR_H_ 8 #define XFA_FXFA_LAYOUT_CXFA_VIEWLAYOUTPROCESSOR_H_ 9 10 #include <iterator> 11 #include <list> 12 #include <map> 13 #include <memory> 14 #include <vector> 15 16 #include "core/fxcrt/retain_ptr.h" 17 #include "third_party/base/optional.h" 18 #include "xfa/fxfa/layout/cxfa_contentlayoutprocessor.h" 19 20 class CXFA_LayoutItem; 21 class CXFA_Node; 22 23 class CXFA_ViewLayoutProcessor { 24 public: 25 struct BreakData { 26 CXFA_Node* pLeader; 27 CXFA_Node* pTrailer; 28 bool bCreatePage; 29 }; 30 31 struct OverflowData { 32 CXFA_Node* pLeader; 33 CXFA_Node* pTrailer; 34 }; 35 36 explicit CXFA_ViewLayoutProcessor(CXFA_LayoutProcessor* pLayoutProcessor); 37 ~CXFA_ViewLayoutProcessor(); 38 39 bool InitLayoutPage(CXFA_Node* pFormNode); 40 bool PrepareFirstPage(CXFA_Node* pRootSubform); 41 float GetAvailHeight(); 42 bool GetNextAvailContentHeight(float fChildHeight); 43 void SubmitContentItem( 44 const RetainPtr<CXFA_ContentLayoutItem>& pContentLayoutItem, 45 CXFA_ContentLayoutProcessor::Result eStatus); 46 void FinishPaginatedPageSets(); 47 void SyncLayoutData(); 48 int32_t GetPageCount() const; 49 CXFA_ViewLayoutItem* GetPage(int32_t index) const; 50 int32_t GetPageIndex(const CXFA_ViewLayoutItem* pPage) const; GetRootLayoutItem()51 CXFA_ViewLayoutItem* GetRootLayoutItem() const { 52 return m_pPageSetRootLayoutItem.Get(); 53 } 54 Optional<BreakData> ProcessBreakBefore(const CXFA_Node* pBreakNode); 55 Optional<BreakData> ProcessBreakAfter(const CXFA_Node* pBreakNode); 56 Optional<OverflowData> ProcessOverflow(CXFA_Node* pFormNode, 57 bool bCreatePage); 58 CXFA_Node* QueryOverflow(CXFA_Node* pFormNode); 59 CXFA_Node* ProcessBookendLeader(const CXFA_Node* pBookendNode); 60 CXFA_Node* ProcessBookendTrailer(const CXFA_Node* pBookendNode); 61 62 private: 63 struct CXFA_ViewRecord { 64 CXFA_ViewRecord(); 65 ~CXFA_ViewRecord(); 66 67 RetainPtr<CXFA_ViewLayoutItem> pCurPageSet; 68 RetainPtr<CXFA_ViewLayoutItem> pCurPageArea; 69 RetainPtr<CXFA_ViewLayoutItem> pCurContentArea; 70 }; 71 72 using RecordList = std::list<std::unique_ptr<CXFA_ViewRecord>>; 73 74 bool AppendNewPage(bool bFirstTemPage); 75 void ReorderPendingLayoutRecordToTail(CXFA_ViewRecord* pNewRecord, 76 CXFA_ViewRecord* pPrevRecord); 77 void RemoveLayoutRecord(CXFA_ViewRecord* pNewRecord, 78 CXFA_ViewRecord* pPrevRecord); HasCurrentViewRecord()79 bool HasCurrentViewRecord() const { 80 return m_CurrentViewRecordIter != m_ProposedViewRecords.end(); 81 } GetCurrentViewRecord()82 CXFA_ViewRecord* GetCurrentViewRecord() { 83 return m_CurrentViewRecordIter->get(); 84 } GetCurrentViewRecord()85 const CXFA_ViewRecord* GetCurrentViewRecord() const { 86 return m_CurrentViewRecordIter->get(); 87 } ResetToFirstViewRecord()88 void ResetToFirstViewRecord() { 89 m_CurrentViewRecordIter = m_ProposedViewRecords.begin(); 90 } GetTailPosition()91 RecordList::iterator GetTailPosition() { 92 auto iter = m_ProposedViewRecords.end(); 93 return !m_ProposedViewRecords.empty() ? std::prev(iter) : iter; 94 } 95 CXFA_ViewRecord* AppendNewRecord(std::unique_ptr<CXFA_ViewRecord> pNewRecord); 96 CXFA_ViewRecord* CreateViewRecord(CXFA_Node* pPageNode, bool bCreateNew); 97 CXFA_ViewRecord* CreateViewRecordSimple(); 98 void AddPageAreaLayoutItem(CXFA_ViewRecord* pNewRecord, 99 CXFA_Node* pNewPageArea); 100 void AddContentAreaLayoutItem(CXFA_ViewRecord* pNewRecord, 101 CXFA_Node* pContentArea); 102 bool RunBreak(XFA_Element eBreakType, 103 XFA_AttributeValue eTargetType, 104 CXFA_Node* pTarget, 105 bool bStartNew); 106 bool ShouldGetNextPageArea(CXFA_Node* pTarget, bool bStartNew) const; 107 bool BreakOverflow(const CXFA_Node* pOverflowNode, 108 bool bCreatePage, 109 CXFA_Node** pLeaderTemplate, 110 CXFA_Node** pTrailerTemplate); 111 CXFA_Node* ProcessBookendLeaderOrTrailer(const CXFA_Node* pBookendNode, 112 bool bLeader); 113 CXFA_Node* ResolveBookendLeaderOrTrailer(const CXFA_Node* pBookendNode, 114 bool bLeader); 115 Optional<BreakData> ProcessBreakBeforeOrAfter(const CXFA_Node* pBreakNode, 116 bool bBefore); 117 BreakData ExecuteBreakBeforeOrAfter(const CXFA_Node* pCurNode, bool bBefore); 118 119 int32_t CreateMinPageRecord(CXFA_Node* pPageArea, 120 bool bTargetPageArea, 121 bool bCreateLast); 122 void CreateMinPageSetRecord(CXFA_Node* pPageSet, bool bCreateAll); 123 void CreateNextMinRecord(CXFA_Node* pRecordNode); 124 bool FindPageAreaFromPageSet(CXFA_Node* pPageSet, 125 CXFA_Node* pStartChild, 126 CXFA_Node* pTargetPageArea, 127 CXFA_Node* pTargetContentArea, 128 bool bNewPage, 129 bool bQuery); 130 bool FindPageAreaFromPageSet_Ordered(CXFA_Node* pPageSet, 131 CXFA_Node* pStartChild, 132 CXFA_Node* pTargetPageArea, 133 CXFA_Node* pTargetContentArea, 134 bool bNewPage, 135 bool bQuery); 136 bool FindPageAreaFromPageSet_SimplexDuplex( 137 CXFA_Node* pPageSet, 138 CXFA_Node* pStartChild, 139 CXFA_Node* pTargetPageArea, 140 CXFA_Node* pTargetContentArea, 141 bool bNewPage, 142 bool bQuery, 143 XFA_AttributeValue ePreferredPosition); 144 bool MatchPageAreaOddOrEven(CXFA_Node* pPageArea); 145 CXFA_Node* GetNextAvailPageArea(CXFA_Node* pTargetPageArea, 146 CXFA_Node* pTargetContentArea, 147 bool bNewPage, 148 bool bQuery); 149 bool GetNextContentArea(CXFA_Node* pTargetContentArea); 150 void InitPageSetMap(); 151 void ProcessLastPageSet(); IsPageSetRootOrderedOccurrence()152 bool IsPageSetRootOrderedOccurrence() const { 153 return m_ePageSetMode == XFA_AttributeValue::OrderedOccurrence; 154 } 155 void ClearData(); 156 void MergePageSetContents(); 157 void LayoutPageSetContents(); 158 void PrepareLayout(); 159 void SaveLayoutItemChildren(CXFA_LayoutItem* pParentLayoutItem); 160 void ProcessSimplexOrDuplexPageSets(CXFA_ViewLayoutItem* pPageSetLayoutItem, 161 bool bIsSimplex); 162 163 CXFA_LayoutProcessor* m_pLayoutProcessor = nullptr; 164 CXFA_Node* m_pPageSetNode = nullptr; 165 RetainPtr<CXFA_ViewLayoutItem> m_pPageSetRootLayoutItem; 166 RetainPtr<CXFA_ViewLayoutItem> m_pPageSetCurLayoutItem; 167 RecordList m_ProposedViewRecords; 168 RecordList::iterator m_CurrentViewRecordIter; 169 CXFA_Node* m_pCurPageArea = nullptr; 170 int32_t m_nAvailPages = 0; 171 int32_t m_nCurPageCount = 0; 172 XFA_AttributeValue m_ePageSetMode = XFA_AttributeValue::OrderedOccurrence; 173 bool m_bCreateOverFlowPage = false; 174 std::map<CXFA_Node*, int32_t> m_pPageSetMap; 175 std::vector<RetainPtr<CXFA_ViewLayoutItem>> m_PageArray; 176 }; 177 178 #endif // XFA_FXFA_LAYOUT_CXFA_VIEWLAYOUTPROCESSOR_H_ 179