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