// 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_XFA_LAYOUT_ITEMLAYOUT_H_ #define XFA_FXFA_PARSER_XFA_LAYOUT_ITEMLAYOUT_H_ #include <float.h> #include <list> #include <map> #include "core/fxcrt/include/fx_basic.h" #include "xfa/fxfa/parser/xfa_doclayout.h" #include "xfa/fxfa/parser/xfa_document_layout_imp.h" #define XFA_LAYOUT_INVALIDNODE ((CXFA_Node*)(intptr_t)-1) #define XFA_LAYOUT_FLOAT_PERCISION (0.0005f) #define XFA_LAYOUT_FLOAT_MAX FLT_MAX class CXFA_ContainerLayoutItem; class CXFA_ContentLayoutItem; class CXFA_ItemLayoutProcessor; class CXFA_LayoutPageMgr; class CXFA_Node; enum XFA_ItemLayoutProcessorResult { XFA_ItemLayoutProcessorResult_Done, XFA_ItemLayoutProcessorResult_PageFullBreak, XFA_ItemLayoutProcessorResult_RowFullBreak, XFA_ItemLayoutProcessorResult_ManualBreak, }; enum XFA_ItemLayoutProcessorStages { XFA_ItemLayoutProcessorStages_None, XFA_ItemLayoutProcessorStages_BookendLeader, XFA_ItemLayoutProcessorStages_BreakBefore, XFA_ItemLayoutProcessorStages_Keep, XFA_ItemLayoutProcessorStages_Container, XFA_ItemLayoutProcessorStages_BreakAfter, XFA_ItemLayoutProcessorStages_BookendTrailer, XFA_ItemLayoutProcessorStages_Done, }; class CXFA_LayoutContext { public: CXFA_LayoutContext() : m_prgSpecifiedColumnWidths(NULL), m_fCurColumnWidth(0), m_bCurColumnWidthAvaiable(FALSE), m_pOverflowProcessor(NULL), m_pOverflowNode(NULL) {} ~CXFA_LayoutContext() { m_pOverflowProcessor = NULL; } CFX_ArrayTemplate<FX_FLOAT>* m_prgSpecifiedColumnWidths; FX_FLOAT m_fCurColumnWidth; FX_BOOL m_bCurColumnWidthAvaiable; CXFA_ItemLayoutProcessor* m_pOverflowProcessor; CXFA_Node* m_pOverflowNode; }; class CXFA_ItemLayoutProcessor { public: CXFA_ItemLayoutProcessor(CXFA_Node* pNode, CXFA_LayoutPageMgr* pPageMgr); XFA_ItemLayoutProcessorResult DoLayout( FX_BOOL bUseBreakControl, FX_FLOAT fHeightLimit, FX_FLOAT fRealHeight = XFA_LAYOUT_FLOAT_MAX, CXFA_LayoutContext* pContext = NULL); void GetCurrentComponentPos(FX_FLOAT& fAbsoluteX, FX_FLOAT& fAbsoluteY); void GetCurrentComponentSize(FX_FLOAT& fWidth, FX_FLOAT& fHeight); void SetCurrentComponentPos(FX_FLOAT fAbsoluteX, FX_FLOAT fAbsoluteY); void SetCurrentComponentSize(FX_FLOAT fWidth, FX_FLOAT fHeight); inline CXFA_Node* GetFormNode() { return m_pFormNode; } inline FX_BOOL HasLayoutItem() { return m_pLayoutItem != NULL; } CXFA_ContentLayoutItem* ExtractLayoutItem(); static FX_BOOL IncrementRelayoutNode(CXFA_LayoutProcessor* pLayoutProcessor, CXFA_Node* pNode, CXFA_Node* pParentNode); static void CalculatePositionedContainerPos(CXFA_Node* pNode, FX_FLOAT fWidth, FX_FLOAT fHeight, FX_FLOAT& fAbsoluteX, FX_FLOAT& fAbsoluteY); static FX_BOOL FindLayoutItemSplitPos(CXFA_ContentLayoutItem* pLayoutItem, FX_FLOAT fCurVerticalOffset, FX_FLOAT& fProposedSplitPos, FX_BOOL& bAppChange, FX_BOOL bCalculateMargin = TRUE); FX_FLOAT FindSplitPos(FX_FLOAT fProposedSplitPos); void SplitLayoutItem(CXFA_ContentLayoutItem* pLayoutItem, CXFA_ContentLayoutItem* pSecondParent, FX_FLOAT fSplitPos); void SplitLayoutItem(FX_FLOAT fSplitPos); FX_BOOL JudgePutNextPage( CXFA_ContentLayoutItem* pParentLayoutItem, FX_FLOAT fChildHeight, CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& pKeepItems); FX_BOOL ProcessKeepForSplite( CXFA_ItemLayoutProcessor* pParentProcessor, CXFA_ItemLayoutProcessor* pChildProcessor, XFA_ItemLayoutProcessorResult eRetValue, CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& rgCurLineLayoutItem, FX_FLOAT& fContentCurRowAvailWidth, FX_FLOAT& fContentCurRowHeight, FX_FLOAT& fContentCurRowY, FX_BOOL& bAddedItemInRow, FX_BOOL& bForceEndPage, XFA_ItemLayoutProcessorResult& result); FX_FLOAT InsertKeepLayoutItems(); void DoLayoutPageArea(CXFA_ContainerLayoutItem* pPageAreaLayoutItem); FX_BOOL CalculateRowChildPosition( CFX_ArrayTemplate<CXFA_ContentLayoutItem*>(&rgCurLineLayoutItems)[3], XFA_ATTRIBUTEENUM eFlowStrategy, FX_BOOL bContainerHeightAutoSize, FX_BOOL bContainerWidthAutoSize, FX_FLOAT& fContentCalculatedWidth, FX_FLOAT& fContentCalculatedHeight, FX_FLOAT& fContentCurRowY, FX_FLOAT fContentCurRowHeight, FX_FLOAT fContentWidthLimit, FX_BOOL bRootForceTb = FALSE); void ProcessUnUseOverFlow(CXFA_Node* pLeaderNode, CXFA_Node* pTrailerNode, CXFA_ContentLayoutItem* pTrailerItem, CXFA_Node* pFormNode); void ProcessUnUseBinds(CXFA_Node* pFormNode); FX_BOOL IsAddNewRowForTrailer(CXFA_ContentLayoutItem* pTrailerItem); FX_BOOL JudgeLeaderOrTrailerForOccur(CXFA_Node* pFormNode); CXFA_ContentLayoutItem* CreateContentLayoutItem(CXFA_Node* pFormNode); protected: void DoLayoutPositionedContainer(CXFA_LayoutContext* pContext = NULL); void DoLayoutTableContainer(CXFA_Node* pLayoutNode); XFA_ItemLayoutProcessorResult DoLayoutFlowedContainer( FX_BOOL bUseBreakControl, XFA_ATTRIBUTEENUM eFlowStrategy, FX_FLOAT fHeightLimit, FX_FLOAT fRealHeight, CXFA_LayoutContext* pContext = NULL, FX_BOOL bRootForceTb = FALSE); void DoLayoutField(); void XFA_ItemLayoutProcessor_GotoNextContainerNode( CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, CXFA_Node* pParentContainer, FX_BOOL bUsePageBreak); FX_BOOL ProcessKeepNodesForCheckNext(CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, CXFA_Node*& pNextContainer, FX_BOOL& bLastKeepNode); FX_BOOL ProcessKeepNodesForBreakBefore( CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, CXFA_Node* pContainerNode); CXFA_Node* GetSubformSetParent(CXFA_Node* pSubformSet); public: FX_BOOL m_bKeepBreakFinish; FX_BOOL m_bIsProcessKeep; CXFA_Node* m_pKeepHeadNode; CXFA_Node* m_pKeepTailNode; CXFA_Node* m_pFormNode; CXFA_ContentLayoutItem* m_pLayoutItem; CXFA_ContentLayoutItem* m_pOldLayoutItem; CXFA_Node* m_pCurChildNode; CXFA_ItemLayoutProcessor* m_pCurChildPreprocessor; XFA_ItemLayoutProcessorStages m_nCurChildNodeStage; FX_FLOAT m_fUsedSize; CXFA_LayoutPageMgr* m_pPageMgr; std::list<CXFA_Node*> m_PendingNodes; FX_BOOL m_bBreakPending; CFX_ArrayTemplate<FX_FLOAT> m_rgSpecifiedColumnWidths; CFX_ArrayTemplate<CXFA_ContentLayoutItem*> m_arrayKeepItems; std::map<CXFA_Node*, int32_t> m_PendingNodesCount; FX_FLOAT m_fLastRowWidth; FX_FLOAT m_fLastRowY; FX_FLOAT m_fWidthLimite; FX_BOOL m_bUseInheriated; XFA_ItemLayoutProcessorResult m_ePreProcessRs; FX_BOOL m_bHasAvailHeight; }; FX_BOOL XFA_ItemLayoutProcessor_IsTakingSpace(CXFA_Node* pNode); #endif // XFA_FXFA_PARSER_XFA_LAYOUT_ITEMLAYOUT_H_