245 lines
9.0 KiB
C++
245 lines
9.0 KiB
C++
// Copyright 2014 The PDFium Authors
|
|
// 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 <float.h>
|
|
|
|
#include <list>
|
|
#include <map>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "core/fxcrt/fx_coordinates.h"
|
|
#include "core/fxcrt/unowned_ptr.h"
|
|
#include "fxjs/gc/heap.h"
|
|
#include "third_party/abseil-cpp/absl/types/optional.h"
|
|
#include "v8/include/cppgc/garbage-collected.h"
|
|
#include "v8/include/cppgc/macros.h"
|
|
#include "v8/include/cppgc/member.h"
|
|
#include "v8/include/cppgc/persistent.h"
|
|
#include "xfa/fxfa/fxfa_basic.h"
|
|
|
|
constexpr float kXFALayoutPrecision = 0.0005f;
|
|
|
|
class CXFA_ContentLayoutItem;
|
|
class CXFA_Node;
|
|
class CXFA_ViewLayoutItem;
|
|
class CXFA_ViewLayoutProcessor;
|
|
|
|
class CXFA_ContentLayoutProcessor
|
|
: public cppgc::GarbageCollected<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,
|
|
};
|
|
|
|
CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
|
|
~CXFA_ContentLayoutProcessor();
|
|
|
|
void Trace(cppgc::Visitor* visitor) const;
|
|
cppgc::Heap* GetHeap() const { return m_pHeap; }
|
|
|
|
Result DoLayout(bool bUseBreakControl, float fHeightLimit, float fRealHeight);
|
|
void DoLayoutPageArea(CXFA_ViewLayoutItem* pPageAreaLayoutItem);
|
|
|
|
CXFA_Node* GetFormNode() { return m_pFormNode; }
|
|
CXFA_ContentLayoutItem* ExtractLayoutItem();
|
|
|
|
private:
|
|
class Context {
|
|
CPPGC_STACK_ALLOCATED(); // Allows Raw/Unowned pointers.
|
|
|
|
public:
|
|
Context();
|
|
~Context();
|
|
|
|
absl::optional<float> m_fCurColumnWidth;
|
|
UnownedPtr<std::vector<float>> m_prgSpecifiedColumnWidths;
|
|
UnownedPtr<CXFA_ContentLayoutProcessor> m_pOverflowProcessor; // OK, stack
|
|
UnownedPtr<CXFA_Node> m_pOverflowNode; // Ok, stack
|
|
};
|
|
|
|
CXFA_ContentLayoutProcessor(cppgc::Heap* pHeap,
|
|
CXFA_Node* pNode,
|
|
CXFA_ViewLayoutProcessor* pViewLayoutProcessor);
|
|
|
|
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<cppgc::Persistent<CXFA_ContentLayoutItem>>*
|
|
rgCurLineLayoutItem,
|
|
float* fContentCurRowAvailWidth,
|
|
float* fContentCurRowHeight,
|
|
float* fContentCurRowY,
|
|
bool* bAddedItemInRow,
|
|
bool* bForceEndPage,
|
|
Result* 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);
|
|
|
|
// Object comes from GCed heap.
|
|
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<cppgc::Persistent<CXFA_ContentLayoutItem>> (
|
|
&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<CXFA_ContentLayoutItem*>* 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();
|
|
|
|
// Return new stage and new action node.
|
|
std::pair<Stage, CXFA_Node*> GotoNextContainerNode(
|
|
Stage nCurStage,
|
|
CXFA_Node* pParentContainer,
|
|
CXFA_Node* pCurActionNode);
|
|
|
|
absl::optional<Stage> ProcessKeepNodesForCheckNext(CXFA_Node** pCurActionNode,
|
|
CXFA_Node** pNextContainer,
|
|
bool* pLastKeepNode);
|
|
|
|
absl::optional<Stage> ProcessKeepNodesForBreakBefore(
|
|
CXFA_Node** pCurActionNode,
|
|
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);
|
|
Result InsertFlowedItem(
|
|
CXFA_ContentLayoutProcessor* pProcessor,
|
|
bool bContainerWidthAutoSize,
|
|
bool bContainerHeightAutoSize,
|
|
float fContainerHeight,
|
|
XFA_AttributeValue eFlowStrategy,
|
|
uint8_t* uCurHAlignState,
|
|
std::vector<cppgc::Persistent<CXFA_ContentLayoutItem>> (
|
|
&rgCurLineLayoutItems)[3],
|
|
bool bUseBreakControl,
|
|
float fAvailHeight,
|
|
float fRealHeight,
|
|
float fContentWidthLimit,
|
|
float* fContentCurRowY,
|
|
float* fContentCurRowAvailWidth,
|
|
float* fContentCurRowHeight,
|
|
bool* bAddedItemInRow,
|
|
bool* bForceEndPage,
|
|
Context* pLayoutContext,
|
|
bool bNewRow);
|
|
|
|
absl::optional<Stage> HandleKeep(CXFA_Node* pBreakAfterNode,
|
|
CXFA_Node** pCurActionNode);
|
|
absl::optional<Stage> HandleBookendLeader(CXFA_Node* pParentContainer,
|
|
CXFA_Node** pCurActionNode);
|
|
absl::optional<Stage> HandleBreakBefore(CXFA_Node* pChildContainer,
|
|
CXFA_Node** pCurActionNode);
|
|
absl::optional<Stage> HandleBreakAfter(CXFA_Node* pChildContainer,
|
|
CXFA_Node** pCurActionNode);
|
|
absl::optional<Stage> HandleCheckNextChildContainer(
|
|
CXFA_Node* pParentContainer,
|
|
CXFA_Node* pChildContainer,
|
|
CXFA_Node** pCurActionNode);
|
|
absl::optional<Stage> 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;
|
|
UnownedPtr<cppgc::Heap> m_pHeap;
|
|
cppgc::Member<CXFA_Node> const m_pFormNode;
|
|
cppgc::Member<CXFA_Node> m_pCurChildNode;
|
|
cppgc::Member<CXFA_Node> m_pKeepHeadNode;
|
|
cppgc::Member<CXFA_Node> m_pKeepTailNode;
|
|
cppgc::Member<CXFA_ContentLayoutItem> m_pLayoutItem;
|
|
cppgc::Member<CXFA_ContentLayoutItem> m_pOldLayoutItem;
|
|
cppgc::Member<CXFA_ViewLayoutProcessor> m_pViewLayoutProcessor;
|
|
std::vector<float> m_rgSpecifiedColumnWidths;
|
|
std::vector<cppgc::Member<CXFA_ContentLayoutItem>> m_ArrayKeepItems;
|
|
std::list<cppgc::Member<CXFA_Node>> m_PendingNodes;
|
|
std::map<cppgc::Member<CXFA_Node>, int32_t> m_PendingNodesCount;
|
|
cppgc::Member<CXFA_ContentLayoutProcessor> m_pCurChildPreprocessor;
|
|
};
|
|
|
|
#endif // XFA_FXFA_LAYOUT_CXFA_CONTENTLAYOUTPROCESSOR_H_
|