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