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_ITEMLAYOUT_H_
8 #define _XFA_LAYOUT_ITEMLAYOUT_H_
9 #define XFA_LAYOUT_INVALIDNODE ((CXFA_Node*)(intptr_t)-1)
10 #define XFA_LAYOUT_FLOAT_PERCISION (0.0005f)
11 #include "float.h"
12 #define XFA_LAYOUT_FLOAT_MAX FLT_MAX
13 class CXFA_ItemLayoutProcessor;
14 class CXFA_LayoutPageMgr;
15 class CXFA_ContainerLayoutItem;
16 class CXFA_ContentLayoutItem;
17 enum XFA_ItemLayoutProcessorResult {
18   XFA_ItemLayoutProcessorResult_Done,
19   XFA_ItemLayoutProcessorResult_PageFullBreak,
20   XFA_ItemLayoutProcessorResult_RowFullBreak,
21   XFA_ItemLayoutProcessorResult_ManualBreak,
22 };
23 enum XFA_ItemLayoutProcessorStages {
24   XFA_ItemLayoutProcessorStages_None,
25   XFA_ItemLayoutProcessorStages_BookendLeader,
26   XFA_ItemLayoutProcessorStages_BreakBefore,
27   XFA_ItemLayoutProcessorStages_Keep,
28   XFA_ItemLayoutProcessorStages_Container,
29   XFA_ItemLayoutProcessorStages_BreakAfter,
30   XFA_ItemLayoutProcessorStages_BookendTrailer,
31   XFA_ItemLayoutProcessorStages_Done,
32 };
33 
34 class CXFA_LayoutContext {
35  public:
CXFA_LayoutContext()36   CXFA_LayoutContext()
37       : m_prgSpecifiedColumnWidths(NULL),
38         m_fCurColumnWidth(0),
39         m_bCurColumnWidthAvaiable(FALSE),
40         m_pOverflowProcessor(NULL),
41         m_pOverflowNode(NULL) {}
~CXFA_LayoutContext()42   ~CXFA_LayoutContext() { m_pOverflowProcessor = NULL; }
43   CFX_ArrayTemplate<FX_FLOAT>* m_prgSpecifiedColumnWidths;
44   FX_FLOAT m_fCurColumnWidth;
45   FX_BOOL m_bCurColumnWidthAvaiable;
46   CXFA_ItemLayoutProcessor* m_pOverflowProcessor;
47   CXFA_Node* m_pOverflowNode;
48 };
49 
50 class CXFA_ItemLayoutProcessor {
51  public:
52   CXFA_ItemLayoutProcessor(CXFA_Node* pNode, CXFA_LayoutPageMgr* pPageMgr);
53 
54   XFA_ItemLayoutProcessorResult DoLayout(
55       FX_BOOL bUseBreakControl,
56       FX_FLOAT fHeightLimit,
57       FX_FLOAT fRealHeight = XFA_LAYOUT_FLOAT_MAX,
58       CXFA_LayoutContext* pContext = NULL);
59 
60   void GetCurrentComponentPos(FX_FLOAT& fAbsoluteX, FX_FLOAT& fAbsoluteY);
61 
62   void GetCurrentComponentSize(FX_FLOAT& fWidth, FX_FLOAT& fHeight);
63 
64   void SetCurrentComponentPos(FX_FLOAT fAbsoluteX, FX_FLOAT fAbsoluteY);
65 
66   void SetCurrentComponentSize(FX_FLOAT fWidth, FX_FLOAT fHeight);
GetFormNode()67   inline CXFA_Node* GetFormNode() { return m_pFormNode; }
HasLayoutItem()68   inline FX_BOOL HasLayoutItem() { return m_pLayoutItem != NULL; }
69   CXFA_ContentLayoutItem* ExtractLayoutItem();
70 
71   static FX_BOOL IncrementRelayoutNode(CXFA_LayoutProcessor* pLayoutProcessor,
72                                        CXFA_Node* pNode,
73                                        CXFA_Node* pParentNode);
74   static void CalculatePositionedContainerPos(CXFA_Node* pNode,
75                                               FX_FLOAT fWidth,
76                                               FX_FLOAT fHeight,
77                                               FX_FLOAT& fAbsoluteX,
78                                               FX_FLOAT& fAbsoluteY);
79   static FX_BOOL FindLayoutItemSplitPos(CXFA_ContentLayoutItem* pLayoutItem,
80                                         FX_FLOAT fCurVerticalOffset,
81                                         FX_FLOAT& fProposedSplitPos,
82                                         FX_BOOL& bAppChange,
83                                         FX_BOOL bCalculateMargin = TRUE);
84   FX_FLOAT FindSplitPos(FX_FLOAT fProposedSplitPos);
85   void SplitLayoutItem(CXFA_ContentLayoutItem* pLayoutItem,
86                        CXFA_ContentLayoutItem* pSecondParent,
87                        FX_FLOAT fSplitPos);
88   void SplitLayoutItem(FX_FLOAT fSplitPos);
89   FX_BOOL JudgePutNextPage(
90       CXFA_ContentLayoutItem* pParentLayoutItem,
91       FX_FLOAT fChildHeight,
92       CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& pKeepItems);
93   FX_BOOL ProcessKeepForSplite(
94       CXFA_ItemLayoutProcessor* pParentProcessor,
95       CXFA_ItemLayoutProcessor* pChildProcessor,
96       XFA_ItemLayoutProcessorResult eRetValue,
97       CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& rgCurLineLayoutItem,
98       FX_FLOAT& fContentCurRowAvailWidth,
99       FX_FLOAT& fContentCurRowHeight,
100       FX_FLOAT& fContentCurRowY,
101       FX_BOOL& bAddedItemInRow,
102       FX_BOOL& bForceEndPage,
103       XFA_ItemLayoutProcessorResult& result);
104   FX_FLOAT InsertKeepLayoutItems();
105   void DoLayoutPageArea(CXFA_ContainerLayoutItem* pPageAreaLayoutItem);
106   FX_BOOL CalculateRowChildPosition(
107       CFX_ArrayTemplate<CXFA_ContentLayoutItem*>(&rgCurLineLayoutItems)[3],
108       XFA_ATTRIBUTEENUM eFlowStrategy,
109       FX_BOOL bContainerHeightAutoSize,
110       FX_BOOL bContainerWidthAutoSize,
111       FX_FLOAT& fContentCalculatedWidth,
112       FX_FLOAT& fContentCalculatedHeight,
113       FX_FLOAT& fContentCurRowY,
114       FX_FLOAT fContentCurRowHeight,
115       FX_FLOAT fContentWidthLimit,
116       FX_BOOL bRootForceTb = FALSE);
117 
118   void ProcessUnUseOverFlow(CXFA_Node* pLeaderNode,
119                             CXFA_Node* pTrailerNode,
120                             CXFA_ContentLayoutItem* pTrailerItem,
121                             CXFA_Node* pFormNode);
122   void ProcessUnUseBinds(CXFA_Node* pFormNode);
123   FX_BOOL IsAddNewRowForTrailer(CXFA_ContentLayoutItem* pTrailerItem);
124   FX_BOOL JudgeLeaderOrTrailerForOccur(CXFA_Node* pFormNode);
125   CXFA_ContentLayoutItem* CreateContentLayoutItem(CXFA_Node* pFormNode);
126 
127  protected:
128   void DoLayoutPositionedContainer(CXFA_LayoutContext* pContext = NULL);
129   void DoLayoutTableContainer(CXFA_Node* pLayoutNode);
130   XFA_ItemLayoutProcessorResult DoLayoutFlowedContainer(
131       FX_BOOL bUseBreakControl,
132       XFA_ATTRIBUTEENUM eFlowStrategy,
133       FX_FLOAT fHeightLimit,
134       FX_FLOAT fRealHeight,
135       CXFA_LayoutContext* pContext = NULL,
136       FX_BOOL bRootForceTb = FALSE);
137   void DoLayoutField();
138   void XFA_ItemLayoutProcessor_GotoNextContainerNode(
139       CXFA_Node*& pCurActionNode,
140       XFA_ItemLayoutProcessorStages& nCurStage,
141       CXFA_Node* pParentContainer,
142       FX_BOOL bUsePageBreak);
143 
144   FX_BOOL ProcessKeepNodesForCheckNext(CXFA_Node*& pCurActionNode,
145                                        XFA_ItemLayoutProcessorStages& nCurStage,
146                                        CXFA_Node*& pNextContainer,
147                                        FX_BOOL& bLastKeepNode);
148 
149   FX_BOOL ProcessKeepNodesForBreakBefore(
150       CXFA_Node*& pCurActionNode,
151       XFA_ItemLayoutProcessorStages& nCurStage,
152       CXFA_Node* pContainerNode);
153 
154   CXFA_Node* GetSubformSetParent(CXFA_Node* pSubformSet);
155 
156  public:
157   FX_BOOL m_bKeepBreakFinish;
158   FX_BOOL m_bIsProcessKeep;
159   CXFA_Node* m_pKeepHeadNode;
160   CXFA_Node* m_pKeepTailNode;
161   CXFA_Node* m_pFormNode;
162   CXFA_ContentLayoutItem* m_pLayoutItem;
163 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_
164   CXFA_ContentLayoutItem* m_pOldLayoutItem;
165 #else
166   CXFA_LayoutPageMgr* m_pPageMgrCreateItem;
167 #endif
168   CXFA_Node* m_pCurChildNode;
169   CXFA_ItemLayoutProcessor* m_pCurChildPreprocessor;
170   XFA_ItemLayoutProcessorStages m_nCurChildNodeStage;
171   FX_FLOAT m_fUsedSize;
172   CXFA_LayoutPageMgr* m_pPageMgr;
173   CFX_PtrList m_rgPendingNodes;
174   FX_BOOL m_bBreakPending;
175   CFX_ArrayTemplate<FX_FLOAT> m_rgSpecifiedColumnWidths;
176   CFX_ArrayTemplate<CXFA_ContentLayoutItem*> m_arrayKeepItems;
177   CFX_MapPtrToPtr m_PendingNodesCount;
178   FX_FLOAT m_fLastRowWidth;
179   FX_FLOAT m_fLastRowY;
180   FX_FLOAT m_fWidthLimite;
181   FX_BOOL m_bUseInheriated;
182   XFA_ItemLayoutProcessorResult m_ePreProcessRs;
183   FX_BOOL m_bHasAvailHeight;
184 };
185 FX_BOOL XFA_ItemLayoutProcessor_IsTakingSpace(CXFA_Node* pNode);
186 #endif
187