• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The PDFium Authors
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_CONTENTLAYOUTPROCESSOR_H_
8 #define XFA_FXFA_LAYOUT_CXFA_CONTENTLAYOUTPROCESSOR_H_
9 
10 #include <float.h>
11 
12 #include <array>
13 #include <list>
14 #include <map>
15 #include <optional>
16 #include <utility>
17 #include <vector>
18 
19 #include "core/fxcrt/fx_coordinates.h"
20 #include "core/fxcrt/unowned_ptr.h"
21 #include "fxjs/gc/heap.h"
22 #include "v8/include/cppgc/garbage-collected.h"
23 #include "v8/include/cppgc/macros.h"
24 #include "v8/include/cppgc/member.h"
25 #include "v8/include/cppgc/persistent.h"
26 #include "xfa/fxfa/fxfa_basic.h"
27 
28 constexpr float kXFALayoutPrecision = 0.0005f;
29 
30 class CXFA_ContentLayoutItem;
31 class CXFA_Node;
32 class CXFA_ViewLayoutItem;
33 class CXFA_ViewLayoutProcessor;
34 
35 class CXFA_ContentLayoutProcessor
36     : public cppgc::GarbageCollected<CXFA_ContentLayoutProcessor> {
37  public:
38   enum class Result : uint8_t {
39     kDone,
40     kPageFullBreak,
41     kRowFullBreak,
42     kManualBreak,
43   };
44 
45   enum class Stage : uint8_t {
46     kNone,
47     kBookendLeader,
48     kBreakBefore,
49     kKeep,
50     kContainer,
51     kBreakAfter,
52     kBookendTrailer,
53     kDone,
54   };
55 
56   CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
57   ~CXFA_ContentLayoutProcessor();
58 
59   void Trace(cppgc::Visitor* visitor) const;
GetHeap()60   cppgc::Heap* GetHeap() const { return m_pHeap; }
61 
62   Result DoLayout(bool bUseBreakControl, float fHeightLimit, float fRealHeight);
63   void DoLayoutPageArea(CXFA_ViewLayoutItem* pPageAreaLayoutItem);
64 
GetFormNode()65   CXFA_Node* GetFormNode() { return m_pFormNode; }
66   CXFA_ContentLayoutItem* ExtractLayoutItem();
67 
68  private:
69   class Context {
70     CPPGC_STACK_ALLOCATED();  // Allows Raw/Unowned pointers.
71 
72    public:
73     Context();
74     ~Context();
75 
76     std::optional<float> m_fCurColumnWidth;
77     UnownedPtr<std::vector<float>> m_prgSpecifiedColumnWidths;
78     UnownedPtr<CXFA_ContentLayoutProcessor> m_pOverflowProcessor;  // OK, stack
79     UnownedPtr<CXFA_Node> m_pOverflowNode;                         // Ok, stack
80   };
81 
82   using ContentLayoutItemVector =
83       std::vector<cppgc::Persistent<CXFA_ContentLayoutItem>>;
84 
85   CXFA_ContentLayoutProcessor(cppgc::Heap* pHeap,
86                               CXFA_Node* pNode,
87                               CXFA_ViewLayoutProcessor* pViewLayoutProcessor);
88 
89   Result DoLayoutInternal(bool bUseBreakControl,
90                           float fHeightLimit,
91                           float fRealHeight,
92                           Context* pContext);
93 
94   CFX_SizeF GetCurrentComponentSize();
HasLayoutItem()95   bool HasLayoutItem() const { return !!m_pLayoutItem; }
96   void SplitLayoutItem(float fSplitPos);
97   float FindSplitPos(float fProposedSplitPos);
98   bool ProcessKeepForSplit(CXFA_ContentLayoutProcessor* pChildProcessor,
99                            Result eRetValue,
100                            ContentLayoutItemVector& rgCurLineLayoutItem,
101                            float* fContentCurRowAvailWidth,
102                            float* fContentCurRowHeight,
103                            float* fContentCurRowY,
104                            bool* bAddedItemInRow,
105                            bool* bForceEndPage,
106                            Result* result);
107   void ProcessUnUseOverFlow(CXFA_Node* pLeaderNode,
108                             CXFA_Node* pTrailerNode,
109                             CXFA_ContentLayoutItem* pTrailerItem,
110                             CXFA_Node* pFormNode);
111   bool IsAddNewRowForTrailer(CXFA_ContentLayoutItem* pTrailerItem);
112   bool JudgeLeaderOrTrailerForOccur(CXFA_Node* pFormNode);
113 
114   // Object comes from GCed heap.
115   CXFA_ContentLayoutItem* CreateContentLayoutItem(CXFA_Node* pFormNode);
116 
117   void SetCurrentComponentPos(const CFX_PointF& pos);
118   void SetCurrentComponentSize(const CFX_SizeF& size);
119 
120   void SplitLayoutItem(CXFA_ContentLayoutItem* pLayoutItem,
121                        CXFA_ContentLayoutItem* pSecondParent,
122                        float fSplitPos);
123   float InsertKeepLayoutItems();
124   bool CalculateRowChildPosition(
125       std::array<ContentLayoutItemVector, 3>& rgCurLineLayoutItems,
126       XFA_AttributeValue eFlowStrategy,
127       bool bContainerHeightAutoSize,
128       bool bContainerWidthAutoSize,
129       float* fContentCalculatedWidth,
130       float* fContentCalculatedHeight,
131       float* fContentCurRowY,
132       float fContentCurRowHeight,
133       float fContentWidthLimit,
134       bool bRootForceTb);
135   void ProcessUnUseBinds(CXFA_Node* pFormNode);
136   bool JudgePutNextPage(CXFA_ContentLayoutItem* pParentLayoutItem,
137                         float fChildHeight,
138                         std::vector<CXFA_ContentLayoutItem*>* pKeepItems);
139 
140   void DoLayoutPositionedContainer(Context* pContext);
141   void DoLayoutTableContainer(CXFA_Node* pLayoutNode);
142   Result DoLayoutFlowedContainer(bool bUseBreakControl,
143                                  XFA_AttributeValue eFlowStrategy,
144                                  float fHeightLimit,
145                                  float fRealHeight,
146                                  Context* pContext,
147                                  bool bRootForceTb);
148   void DoLayoutField();
149 
150   void GotoNextContainerNodeSimple();
151 
152   // Return new stage and new action node.
153   std::pair<Stage, CXFA_Node*> GotoNextContainerNode(
154       Stage nCurStage,
155       CXFA_Node* pParentContainer,
156       CXFA_Node* pCurActionNode);
157 
158   std::optional<Stage> ProcessKeepNodesForCheckNext(CXFA_Node** pCurActionNode,
159                                                     CXFA_Node** pNextContainer,
160                                                     bool* pLastKeepNode);
161 
162   std::optional<Stage> ProcessKeepNodesForBreakBefore(
163       CXFA_Node** pCurActionNode,
164       CXFA_Node* pContainerNode);
165 
166   CXFA_Node* GetSubformSetParent(CXFA_Node* pSubformSet);
167 
168   void UpdatePendingItemLayout(CXFA_ContentLayoutItem* pLayoutItem);
169   void AddTrailerBeforeSplit(float fSplitPos,
170                              CXFA_ContentLayoutItem* pTrailerLayoutItem,
171                              bool bUseInherited);
172   void AddLeaderAfterSplit(CXFA_ContentLayoutItem* pLeaderLayoutItem);
173   void AddPendingNode(CXFA_Node* pPendingNode, bool bBreakPending);
174   float InsertPendingItems(CXFA_Node* pCurChildNode);
175   Result InsertFlowedItem(
176       CXFA_ContentLayoutProcessor* pProcessor,
177       bool bContainerWidthAutoSize,
178       bool bContainerHeightAutoSize,
179       float fContainerHeight,
180       XFA_AttributeValue eFlowStrategy,
181       uint8_t* uCurHAlignState,
182       std::array<ContentLayoutItemVector, 3>& rgCurLineLayoutItems,
183       bool bUseBreakControl,
184       float fAvailHeight,
185       float fRealHeight,
186       float fContentWidthLimit,
187       float* fContentCurRowY,
188       float* fContentCurRowAvailWidth,
189       float* fContentCurRowHeight,
190       bool* bAddedItemInRow,
191       bool* bForceEndPage,
192       Context* pLayoutContext,
193       bool bNewRow);
194 
195   std::optional<Stage> HandleKeep(CXFA_Node* pBreakAfterNode,
196                                   CXFA_Node** pCurActionNode);
197   std::optional<Stage> HandleBookendLeader(CXFA_Node* pParentContainer,
198                                            CXFA_Node** pCurActionNode);
199   std::optional<Stage> HandleBreakBefore(CXFA_Node* pChildContainer,
200                                          CXFA_Node** pCurActionNode);
201   std::optional<Stage> HandleBreakAfter(CXFA_Node* pChildContainer,
202                                         CXFA_Node** pCurActionNode);
203   std::optional<Stage> HandleCheckNextChildContainer(
204       CXFA_Node* pParentContainer,
205       CXFA_Node* pChildContainer,
206       CXFA_Node** pCurActionNode);
207   std::optional<Stage> HandleBookendTrailer(CXFA_Node* pParentContainer,
208                                             CXFA_Node** pCurActionNode);
209   void ProcessKeepNodesEnd();
210   void AdjustContainerSpecifiedSize(Context* pContext,
211                                     CFX_SizeF* pSize,
212                                     bool* pContainerWidthAutoSize,
213                                     bool* pContainerHeightAutoSize);
214   CXFA_ContentLayoutItem* FindLastContentLayoutItem(
215       XFA_AttributeValue eFlowStrategy);
216   CFX_SizeF CalculateLayoutItemSize(const CXFA_ContentLayoutItem* pLayoutChild);
217 
218   Stage m_nCurChildNodeStage = Stage::kNone;
219   Result m_ePreProcessRs = Result::kDone;
220   bool m_bBreakPending = true;
221   bool m_bUseInherited = false;
222   bool m_bKeepBreakFinish = false;
223   bool m_bIsProcessKeep = false;
224   bool m_bHasAvailHeight = true;
225   float m_fUsedSize = 0;
226   float m_fLastRowWidth = 0;
227   float m_fLastRowY = 0;
228   float m_fWidthLimit = 0;
229   UnownedPtr<cppgc::Heap> m_pHeap;
230   cppgc::Member<CXFA_Node> const m_pFormNode;
231   cppgc::Member<CXFA_Node> m_pCurChildNode;
232   cppgc::Member<CXFA_Node> m_pKeepHeadNode;
233   cppgc::Member<CXFA_Node> m_pKeepTailNode;
234   cppgc::Member<CXFA_ContentLayoutItem> m_pLayoutItem;
235   cppgc::Member<CXFA_ContentLayoutItem> m_pOldLayoutItem;
236   cppgc::Member<CXFA_ViewLayoutProcessor> m_pViewLayoutProcessor;
237   cppgc::Member<CXFA_ContentLayoutProcessor> m_pCurChildPreprocessor;
238   std::vector<float> m_rgSpecifiedColumnWidths;
239   std::vector<cppgc::Member<CXFA_ContentLayoutItem>> m_ArrayKeepItems;
240   std::list<cppgc::Member<CXFA_Node>> m_PendingNodes;
241   std::map<cppgc::Member<CXFA_Node>, int32_t> m_PendingNodesCount;
242 };
243 
244 #endif  // XFA_FXFA_LAYOUT_CXFA_CONTENTLAYOUTPROCESSOR_H_
245