// 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_PARSER_CXFA_ITEMLAYOUTPROCESSOR_H_ #define XFA_FXFA_PARSER_CXFA_ITEMLAYOUTPROCESSOR_H_ #include #include #include #include #include #include "core/fxcrt/fx_coordinates.h" #include "xfa/fxfa/fxfa_basic.h" #define XFA_LAYOUT_INVALIDNODE ((CXFA_Node*)(intptr_t)-1) #define XFA_LAYOUT_FLOAT_PERCISION (0.0005f) class CXFA_ContainerLayoutItem; class CXFA_ContentLayoutItem; class CXFA_ItemLayoutProcessor; class CXFA_LayoutContext; class CXFA_LayoutPageMgr; class CXFA_LayoutProcessor; class CXFA_Node; enum class XFA_ItemLayoutProcessorResult { Done, PageFullBreak, RowFullBreak, ManualBreak, }; enum class XFA_ItemLayoutProcessorStages { None, BookendLeader, BreakBefore, Keep, Container, BreakAfter, BookendTrailer, Done, }; class CXFA_ItemLayoutProcessor { public: CXFA_ItemLayoutProcessor(CXFA_Node* pNode, CXFA_LayoutPageMgr* pPageMgr); ~CXFA_ItemLayoutProcessor(); XFA_ItemLayoutProcessorResult DoLayout(bool bUseBreakControl, float fHeightLimit, float fRealHeight, CXFA_LayoutContext* pContext); void DoLayoutPageArea(CXFA_ContainerLayoutItem* pPageAreaLayoutItem); CXFA_Node* GetFormNode() { return m_pFormNode; } CXFA_ContentLayoutItem* ExtractLayoutItem(); private: CFX_SizeF GetCurrentComponentSize(); bool HasLayoutItem() const { return !!m_pLayoutItem; } void SplitLayoutItem(float fSplitPos); float FindSplitPos(float fProposedSplitPos); bool ProcessKeepForSplit( CXFA_ItemLayoutProcessor* pChildProcessor, XFA_ItemLayoutProcessorResult eRetValue, std::vector* rgCurLineLayoutItem, float* fContentCurRowAvailWidth, float* fContentCurRowHeight, float* fContentCurRowY, bool* bAddedItemInRow, bool* bForceEndPage, XFA_ItemLayoutProcessorResult* result); void ProcessUnUseOverFlow(CXFA_Node* pLeaderNode, CXFA_Node* pTrailerNode, CXFA_ContentLayoutItem* pTrailerItem, CXFA_Node* pFormNode); bool IsAddNewRowForTrailer(CXFA_ContentLayoutItem* pTrailerItem); bool JudgeLeaderOrTrailerForOccur(CXFA_Node* pFormNode); CXFA_ContentLayoutItem* CreateContentLayoutItem(CXFA_Node* pFormNode); void SetCurrentComponentPos(const CFX_PointF& pos); void SetCurrentComponentSize(const CFX_SizeF& size); void SplitLayoutItem(CXFA_ContentLayoutItem* pLayoutItem, CXFA_ContentLayoutItem* pSecondParent, float fSplitPos); float InsertKeepLayoutItems(); bool CalculateRowChildPosition( std::vector (&rgCurLineLayoutItems)[3], XFA_AttributeEnum eFlowStrategy, bool bContainerHeightAutoSize, bool bContainerWidthAutoSize, float* fContentCalculatedWidth, float* fContentCalculatedHeight, float* fContentCurRowY, float fContentCurRowHeight, float fContentWidthLimit, bool bRootForceTb); void ProcessUnUseBinds(CXFA_Node* pFormNode); bool JudgePutNextPage(CXFA_ContentLayoutItem* pParentLayoutItem, float fChildHeight, std::vector* pKeepItems); void DoLayoutPositionedContainer(CXFA_LayoutContext* pContext); void DoLayoutTableContainer(CXFA_Node* pLayoutNode); XFA_ItemLayoutProcessorResult DoLayoutFlowedContainer( bool bUseBreakControl, XFA_AttributeEnum eFlowStrategy, float fHeightLimit, float fRealHeight, CXFA_LayoutContext* pContext, bool bRootForceTb); void DoLayoutField(); void GotoNextContainerNode(CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages* nCurStage, CXFA_Node* pParentContainer, bool bUsePageBreak); bool ProcessKeepNodesForCheckNext(CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages* nCurStage, CXFA_Node*& pNextContainer, bool& bLastKeepNode); bool ProcessKeepNodesForBreakBefore(CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages* nCurStage, CXFA_Node* pContainerNode); CXFA_Node* GetSubformSetParent(CXFA_Node* pSubformSet); void UpdatePendingItemLayout(CXFA_ContentLayoutItem* pLayoutItem); void AddTrailerBeforeSplit(float fSplitPos, CXFA_ContentLayoutItem* pTrailerLayoutItem, bool bUseInherited); void AddLeaderAfterSplit(CXFA_ContentLayoutItem* pLeaderLayoutItem); void AddPendingNode(CXFA_Node* pPendingNode, bool bBreakPending); float InsertPendingItems(CXFA_Node* pCurChildNode); XFA_ItemLayoutProcessorResult InsertFlowedItem( CXFA_ItemLayoutProcessor* pProcessor, bool bContainerWidthAutoSize, bool bContainerHeightAutoSize, float fContainerHeight, XFA_AttributeEnum eFlowStrategy, uint8_t* uCurHAlignState, std::vector (&rgCurLineLayoutItems)[3], bool bUseBreakControl, float fAvailHeight, float fRealHeight, float fContentWidthLimit, float* fContentCurRowY, float* fContentCurRowAvailWidth, float* fContentCurRowHeight, bool* bAddedItemInRow, bool* bForceEndPage, CXFA_LayoutContext* pLayoutContext, bool bNewRow); CXFA_Node* m_pFormNode; CXFA_ContentLayoutItem* m_pLayoutItem = nullptr; CXFA_Node* m_pCurChildNode = XFA_LAYOUT_INVALIDNODE; float m_fUsedSize = 0; CXFA_LayoutPageMgr* m_pPageMgr; std::list m_PendingNodes; bool m_bBreakPending = true; std::vector m_rgSpecifiedColumnWidths; std::vector m_arrayKeepItems; float m_fLastRowWidth = 0; float m_fLastRowY = 0; bool m_bUseInheriated = false; XFA_ItemLayoutProcessorResult m_ePreProcessRs = XFA_ItemLayoutProcessorResult::Done; bool m_bKeepBreakFinish = false; bool m_bIsProcessKeep = false; CXFA_Node* m_pKeepHeadNode = nullptr; CXFA_Node* m_pKeepTailNode = nullptr; CXFA_ContentLayoutItem* m_pOldLayoutItem = nullptr; CXFA_ItemLayoutProcessor* m_pCurChildPreprocessor = nullptr; XFA_ItemLayoutProcessorStages m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages::None; std::map m_PendingNodesCount; float m_fWidthLimite = 0; bool m_bHasAvailHeight = true; }; #endif // XFA_FXFA_PARSER_CXFA_ITEMLAYOUTPROCESSOR_H_