// 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_LAYOUT_CXFA_CONTENTLAYOUTPROCESSOR_H_ #define XFA_FXFA_LAYOUT_CXFA_CONTENTLAYOUTPROCESSOR_H_ #include #include #include #include #include #include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/retain_ptr.h" #include "core/fxcrt/unowned_ptr.h" #include "third_party/base/optional.h" #include "xfa/fxfa/fxfa_basic.h" constexpr float kXFALayoutPrecision = 0.0005f; class CXFA_ContentLayoutItem; class CXFA_ContentLayoutProcessor; class CXFA_LayoutProcessor; class CXFA_Node; class CXFA_ViewLayoutItem; class CXFA_ViewLayoutProcessor; class CXFA_ContentLayoutProcessor { public: enum class Result : uint8_t { kDone, kPageFullBreak, kRowFullBreak, kManualBreak, }; enum class Stage : uint8_t { kNone, kBookendLeader, kBreakBefore, kKeep, kContainer, kBreakAfter, kBookendTrailer, kDone, }; CXFA_ContentLayoutProcessor(CXFA_Node* pNode, CXFA_ViewLayoutProcessor* pViewLayoutProcessor); ~CXFA_ContentLayoutProcessor(); Result DoLayout(bool bUseBreakControl, float fHeightLimit, float fRealHeight); void DoLayoutPageArea(CXFA_ViewLayoutItem* pPageAreaLayoutItem); CXFA_Node* GetFormNode() { return m_pFormNode; } RetainPtr ExtractLayoutItem(); private: class Context { public: Context(); ~Context(); Optional m_fCurColumnWidth; UnownedPtr> m_prgSpecifiedColumnWidths; UnownedPtr m_pOverflowProcessor; UnownedPtr m_pOverflowNode; }; Result DoLayoutInternal(bool bUseBreakControl, float fHeightLimit, float fRealHeight, Context* pContext); CFX_SizeF GetCurrentComponentSize(); bool HasLayoutItem() const { return !!m_pLayoutItem; } void SplitLayoutItem(float fSplitPos); float FindSplitPos(float fProposedSplitPos); bool ProcessKeepForSplit( CXFA_ContentLayoutProcessor* pChildProcessor, Result eRetValue, std::vector>* rgCurLineLayoutItem, float* fContentCurRowAvailWidth, float* fContentCurRowHeight, float* fContentCurRowY, bool* bAddedItemInRow, bool* bForceEndPage, Result* result); void ProcessUnUseOverFlow( CXFA_Node* pLeaderNode, CXFA_Node* pTrailerNode, const RetainPtr& pTrailerItem, CXFA_Node* pFormNode); bool IsAddNewRowForTrailer(CXFA_ContentLayoutItem* pTrailerItem); bool JudgeLeaderOrTrailerForOccur(CXFA_Node* pFormNode); RetainPtr 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_AttributeValue 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(Context* pContext); void DoLayoutTableContainer(CXFA_Node* pLayoutNode); Result DoLayoutFlowedContainer(bool bUseBreakControl, XFA_AttributeValue eFlowStrategy, float fHeightLimit, float fRealHeight, Context* pContext, bool bRootForceTb); void DoLayoutField(); void GotoNextContainerNodeSimple(bool bUsePageBreak); Stage GotoNextContainerNode(Stage nCurStage, bool bUsePageBreak, CXFA_Node* pParentContainer, CXFA_Node** pCurActionNode); Optional ProcessKeepNodesForCheckNext(CXFA_Node** pCurActionNode, CXFA_Node** pNextContainer, bool* pLastKeepNode); Optional ProcessKeepNodesForBreakBefore(CXFA_Node** pCurActionNode, CXFA_Node* pContainerNode); CXFA_Node* GetSubformSetParent(CXFA_Node* pSubformSet); void UpdatePendingItemLayout( const RetainPtr& pLayoutItem); void AddTrailerBeforeSplit( float fSplitPos, const RetainPtr& pTrailerLayoutItem, bool bUseInherited); void AddLeaderAfterSplit( const RetainPtr& pLeaderLayoutItem); void AddPendingNode(CXFA_Node* pPendingNode, bool bBreakPending); float InsertPendingItems(CXFA_Node* pCurChildNode); Result InsertFlowedItem( CXFA_ContentLayoutProcessor* pProcessor, bool bContainerWidthAutoSize, bool bContainerHeightAutoSize, float fContainerHeight, XFA_AttributeValue 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, Context* pLayoutContext, bool bNewRow); Optional HandleKeep(CXFA_Node* pBreakAfterNode, CXFA_Node** pCurActionNode); Optional HandleBookendLeader(CXFA_Node* pParentContainer, CXFA_Node** pCurActionNode); Optional HandleBreakBefore(CXFA_Node* pChildContainer, CXFA_Node** pCurActionNode); Optional HandleBreakAfter(CXFA_Node* pChildContainer, CXFA_Node** pCurActionNode); Optional HandleCheckNextChildContainer(CXFA_Node* pParentContainer, CXFA_Node* pChildContainer, CXFA_Node** pCurActionNode); Optional HandleBookendTrailer(CXFA_Node* pParentContainer, CXFA_Node** pCurActionNode); void ProcessKeepNodesEnd(); void AdjustContainerSpecifiedSize(Context* pContext, CFX_SizeF* pSize, bool* pContainerWidthAutoSize, bool* pContainerHeightAutoSize); CXFA_ContentLayoutItem* FindLastContentLayoutItem( XFA_AttributeValue eFlowStrategy); CFX_SizeF CalculateLayoutItemSize(const CXFA_ContentLayoutItem* pLayoutChild); Stage m_nCurChildNodeStage = Stage::kNone; Result m_ePreProcessRs = Result::kDone; bool m_bBreakPending = true; bool m_bUseInherited = false; bool m_bKeepBreakFinish = false; bool m_bIsProcessKeep = false; bool m_bHasAvailHeight = true; float m_fUsedSize = 0; float m_fLastRowWidth = 0; float m_fLastRowY = 0; float m_fWidthLimit = 0; CXFA_Node* const m_pFormNode; CXFA_Node* m_pCurChildNode = nullptr; CXFA_Node* m_pKeepHeadNode = nullptr; CXFA_Node* m_pKeepTailNode = nullptr; RetainPtr m_pLayoutItem; RetainPtr m_pOldLayoutItem; UnownedPtr m_pViewLayoutProcessor; std::vector m_rgSpecifiedColumnWidths; std::vector> m_ArrayKeepItems; std::list m_PendingNodes; std::map m_PendingNodesCount; std::unique_ptr m_pCurChildPreprocessor; }; #endif // XFA_FXFA_LAYOUT_CXFA_CONTENTLAYOUTPROCESSOR_H_