| // Copyright 2014 PDFium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
| #ifndef XFA_FXFA_LAYOUT_CXFA_VIEWLAYOUTPROCESSOR_H_ | |
| #define XFA_FXFA_LAYOUT_CXFA_VIEWLAYOUTPROCESSOR_H_ | |
| #include <iterator> | |
| #include <list> | |
| #include <map> | |
| #include <memory> | |
| #include <vector> | |
| #include "core/fxcrt/retain_ptr.h" | |
| #include "third_party/base/optional.h" | |
| #include "xfa/fxfa/layout/cxfa_contentlayoutprocessor.h" | |
| class CXFA_LayoutItem; | |
| class CXFA_Node; | |
| class CXFA_ViewLayoutProcessor { | |
| public: | |
| struct BreakData { | |
| CXFA_Node* pLeader; | |
| CXFA_Node* pTrailer; | |
| bool bCreatePage; | |
| }; | |
| struct OverflowData { | |
| CXFA_Node* pLeader; | |
| CXFA_Node* pTrailer; | |
| }; | |
| explicit CXFA_ViewLayoutProcessor(CXFA_LayoutProcessor* pLayoutProcessor); | |
| ~CXFA_ViewLayoutProcessor(); | |
| bool InitLayoutPage(CXFA_Node* pFormNode); | |
| bool PrepareFirstPage(CXFA_Node* pRootSubform); | |
| float GetAvailHeight(); | |
| bool GetNextAvailContentHeight(float fChildHeight); | |
| void SubmitContentItem( | |
| const RetainPtr<CXFA_ContentLayoutItem>& pContentLayoutItem, | |
| CXFA_ContentLayoutProcessor::Result eStatus); | |
| void FinishPaginatedPageSets(); | |
| void SyncLayoutData(); | |
| int32_t GetPageCount() const; | |
| CXFA_ViewLayoutItem* GetPage(int32_t index) const; | |
| int32_t GetPageIndex(const CXFA_ViewLayoutItem* pPage) const; | |
| CXFA_ViewLayoutItem* GetRootLayoutItem() const { | |
| return m_pPageSetRootLayoutItem.Get(); | |
| } | |
| Optional<BreakData> ProcessBreakBefore(const CXFA_Node* pBreakNode); | |
| Optional<BreakData> ProcessBreakAfter(const CXFA_Node* pBreakNode); | |
| Optional<OverflowData> ProcessOverflow(CXFA_Node* pFormNode, | |
| bool bCreatePage); | |
| CXFA_Node* QueryOverflow(CXFA_Node* pFormNode); | |
| CXFA_Node* ProcessBookendLeader(const CXFA_Node* pBookendNode); | |
| CXFA_Node* ProcessBookendTrailer(const CXFA_Node* pBookendNode); | |
| private: | |
| struct CXFA_ViewRecord { | |
| CXFA_ViewRecord(); | |
| ~CXFA_ViewRecord(); | |
| RetainPtr<CXFA_ViewLayoutItem> pCurPageSet; | |
| RetainPtr<CXFA_ViewLayoutItem> pCurPageArea; | |
| RetainPtr<CXFA_ViewLayoutItem> pCurContentArea; | |
| }; | |
| using RecordList = std::list<std::unique_ptr<CXFA_ViewRecord>>; | |
| bool AppendNewPage(bool bFirstTemPage); | |
| void ReorderPendingLayoutRecordToTail(CXFA_ViewRecord* pNewRecord, | |
| CXFA_ViewRecord* pPrevRecord); | |
| void RemoveLayoutRecord(CXFA_ViewRecord* pNewRecord, | |
| CXFA_ViewRecord* pPrevRecord); | |
| bool HasCurrentViewRecord() const { | |
| return m_CurrentViewRecordIter != m_ProposedViewRecords.end(); | |
| } | |
| CXFA_ViewRecord* GetCurrentViewRecord() { | |
| return m_CurrentViewRecordIter->get(); | |
| } | |
| const CXFA_ViewRecord* GetCurrentViewRecord() const { | |
| return m_CurrentViewRecordIter->get(); | |
| } | |
| void ResetToFirstViewRecord() { | |
| m_CurrentViewRecordIter = m_ProposedViewRecords.begin(); | |
| } | |
| RecordList::iterator GetTailPosition() { | |
| auto iter = m_ProposedViewRecords.end(); | |
| return !m_ProposedViewRecords.empty() ? std::prev(iter) : iter; | |
| } | |
| CXFA_ViewRecord* AppendNewRecord(std::unique_ptr<CXFA_ViewRecord> pNewRecord); | |
| CXFA_ViewRecord* CreateViewRecord(CXFA_Node* pPageNode, bool bCreateNew); | |
| CXFA_ViewRecord* CreateViewRecordSimple(); | |
| void AddPageAreaLayoutItem(CXFA_ViewRecord* pNewRecord, | |
| CXFA_Node* pNewPageArea); | |
| void AddContentAreaLayoutItem(CXFA_ViewRecord* pNewRecord, | |
| CXFA_Node* pContentArea); | |
| bool RunBreak(XFA_Element eBreakType, | |
| XFA_AttributeValue eTargetType, | |
| CXFA_Node* pTarget, | |
| bool bStartNew); | |
| bool ShouldGetNextPageArea(CXFA_Node* pTarget, bool bStartNew) const; | |
| bool BreakOverflow(const CXFA_Node* pOverflowNode, | |
| bool bCreatePage, | |
| CXFA_Node** pLeaderTemplate, | |
| CXFA_Node** pTrailerTemplate); | |
| CXFA_Node* ProcessBookendLeaderOrTrailer(const CXFA_Node* pBookendNode, | |
| bool bLeader); | |
| CXFA_Node* ResolveBookendLeaderOrTrailer(const CXFA_Node* pBookendNode, | |
| bool bLeader); | |
| Optional<BreakData> ProcessBreakBeforeOrAfter(const CXFA_Node* pBreakNode, | |
| bool bBefore); | |
| BreakData ExecuteBreakBeforeOrAfter(const CXFA_Node* pCurNode, bool bBefore); | |
| int32_t CreateMinPageRecord(CXFA_Node* pPageArea, | |
| bool bTargetPageArea, | |
| bool bCreateLast); | |
| void CreateMinPageSetRecord(CXFA_Node* pPageSet, bool bCreateAll); | |
| void CreateNextMinRecord(CXFA_Node* pRecordNode); | |
| bool FindPageAreaFromPageSet(CXFA_Node* pPageSet, | |
| CXFA_Node* pStartChild, | |
| CXFA_Node* pTargetPageArea, | |
| CXFA_Node* pTargetContentArea, | |
| bool bNewPage, | |
| bool bQuery); | |
| bool FindPageAreaFromPageSet_Ordered(CXFA_Node* pPageSet, | |
| CXFA_Node* pStartChild, | |
| CXFA_Node* pTargetPageArea, | |
| CXFA_Node* pTargetContentArea, | |
| bool bNewPage, | |
| bool bQuery); | |
| bool FindPageAreaFromPageSet_SimplexDuplex( | |
| CXFA_Node* pPageSet, | |
| CXFA_Node* pStartChild, | |
| CXFA_Node* pTargetPageArea, | |
| CXFA_Node* pTargetContentArea, | |
| bool bNewPage, | |
| bool bQuery, | |
| XFA_AttributeValue ePreferredPosition); | |
| bool MatchPageAreaOddOrEven(CXFA_Node* pPageArea); | |
| CXFA_Node* GetNextAvailPageArea(CXFA_Node* pTargetPageArea, | |
| CXFA_Node* pTargetContentArea, | |
| bool bNewPage, | |
| bool bQuery); | |
| bool GetNextContentArea(CXFA_Node* pTargetContentArea); | |
| void InitPageSetMap(); | |
| void ProcessLastPageSet(); | |
| bool IsPageSetRootOrderedOccurrence() const { | |
| return m_ePageSetMode == XFA_AttributeValue::OrderedOccurrence; | |
| } | |
| void ClearData(); | |
| void MergePageSetContents(); | |
| void LayoutPageSetContents(); | |
| void PrepareLayout(); | |
| void SaveLayoutItemChildren(CXFA_LayoutItem* pParentLayoutItem); | |
| void ProcessSimplexOrDuplexPageSets(CXFA_ViewLayoutItem* pPageSetLayoutItem, | |
| bool bIsSimplex); | |
| CXFA_LayoutProcessor* m_pLayoutProcessor = nullptr; | |
| CXFA_Node* m_pPageSetNode = nullptr; | |
| RetainPtr<CXFA_ViewLayoutItem> m_pPageSetRootLayoutItem; | |
| RetainPtr<CXFA_ViewLayoutItem> m_pPageSetCurLayoutItem; | |
| RecordList m_ProposedViewRecords; | |
| RecordList::iterator m_CurrentViewRecordIter; | |
| CXFA_Node* m_pCurPageArea = nullptr; | |
| int32_t m_nAvailPages = 0; | |
| int32_t m_nCurPageCount = 0; | |
| XFA_AttributeValue m_ePageSetMode = XFA_AttributeValue::OrderedOccurrence; | |
| bool m_bCreateOverFlowPage = false; | |
| std::map<CXFA_Node*, int32_t> m_pPageSetMap; | |
| std::vector<RetainPtr<CXFA_ViewLayoutItem>> m_PageArray; | |
| }; | |
| #endif // XFA_FXFA_LAYOUT_CXFA_VIEWLAYOUTPROCESSOR_H_ |