| // Copyright 2017 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_CXFA_TEXTLAYOUT_H_ | |
| #define XFA_FXFA_CXFA_TEXTLAYOUT_H_ | |
| #include <memory> | |
| #include <vector> | |
| #include "core/fxcrt/css/cfx_css.h" | |
| #include "core/fxcrt/fx_coordinates.h" | |
| #include "core/fxcrt/retain_ptr.h" | |
| #include "core/fxcrt/unowned_ptr.h" | |
| #include "core/fxcrt/widestring.h" | |
| #include "core/fxge/dib/fx_dib.h" | |
| #include "fxjs/gc/heap.h" | |
| #include "v8/include/cppgc/garbage-collected.h" | |
| #include "v8/include/cppgc/member.h" | |
| #include "v8/include/cppgc/visitor.h" | |
| #include "xfa/fgas/layout/cfgas_char.h" | |
| #include "xfa/fgas/layout/cfgas_textpiece.h" | |
| #include "xfa/fxfa/fxfa_basic.h" | |
| class CFGAS_LinkUserData; | |
| class CFGAS_RTFBreak; | |
| class CFX_CSSComputedStyle; | |
| class CFX_RenderDevice; | |
| class CFX_XMLNode; | |
| class CXFA_FFDoc; | |
| class CXFA_Node; | |
| class CXFA_TextParser; | |
| class CXFA_TextProvider; | |
| class CXFA_TextTabstopsContext; | |
| class TextCharPos; | |
| class CXFA_TextLayout final : public cppgc::GarbageCollected<CXFA_TextLayout> { | |
| public: | |
| CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED; | |
| ~CXFA_TextLayout(); | |
| void Trace(cppgc::Visitor* visitor) const; | |
| float GetLayoutHeight(); | |
| float StartLayout(float fWidth); | |
| float DoLayout(float fTextHeight); | |
| float DoSplitLayout(size_t szBlockIndex, | |
| float fCalcHeight, | |
| float fTextHeight); | |
| float Layout(const CFX_SizeF& size); | |
| CFX_SizeF CalcSize(const CFX_SizeF& minSize, const CFX_SizeF& maxSize); | |
| void ItemBlocks(const CFX_RectF& rtText, size_t szBlockIndex); | |
| bool DrawString(CFX_RenderDevice* pFxDevice, | |
| const CFX_Matrix& mtDoc2Device, | |
| const CFX_RectF& rtClip, | |
| size_t szBlockIndex); | |
| bool IsLoaded() const { return !m_pieceLines.empty(); } | |
| void Unload(); | |
| bool HasBlock() const { return m_bHasBlock; } | |
| void ClearBlocks() { m_Blocks.clear(); } | |
| void ResetHasBlock() { m_bHasBlock = false; } | |
| // Returns empty string when no link is present. | |
| WideString GetLinkURLAtPoint(const CFX_PointF& point); | |
| private: | |
| class TextPiece : public CFGAS_TextPiece { | |
| public: | |
| TextPiece(); | |
| ~TextPiece(); | |
| int32_t iUnderline = 0; | |
| int32_t iLineThrough = 0; | |
| XFA_AttributeValue iPeriod = XFA_AttributeValue::All; | |
| FX_ARGB dwColor = 0; | |
| RetainPtr<CFGAS_LinkUserData> pLinkData; | |
| }; | |
| class PieceLine { | |
| public: | |
| PieceLine(); | |
| ~PieceLine(); | |
| std::vector<std::unique_ptr<TextPiece>> m_textPieces; | |
| std::vector<size_t> m_charCounts; | |
| }; | |
| struct BlockData { | |
| size_t szIndex; | |
| size_t szLength; | |
| }; | |
| struct BlockHeight { | |
| size_t szBlockIndex; | |
| float fHeight; | |
| }; | |
| struct LoaderContext { | |
| LoaderContext(); | |
| ~LoaderContext(); | |
| void Trace(cppgc::Visitor* visitor) const; | |
| bool bSaveLineHeight = false; | |
| bool bFilterSpace = false; | |
| float fWidth = 0; | |
| float fHeight = 0; | |
| float fLastPos = 0; | |
| float fStartLineOffset = 0; | |
| size_t nCharIdx = 0; | |
| // TODO(thestig): Make this size_t? | |
| int32_t iTotalLines = -1; | |
| UnownedPtr<const CFX_XMLNode> pXMLNode; | |
| RetainPtr<CFX_CSSComputedStyle> pParentStyle; | |
| cppgc::Member<CXFA_Node> pNode; | |
| std::vector<float> lineHeights; | |
| std::vector<BlockHeight> blockHeights; | |
| }; | |
| CXFA_TextLayout(CXFA_FFDoc* doc, CXFA_TextProvider* pTextProvider); | |
| void GetTextDataNode(); | |
| CFX_XMLNode* GetXMLContainerNode(); | |
| std::unique_ptr<CFGAS_RTFBreak> CreateBreak(bool bDefault); | |
| void InitBreak(float fLineWidth); | |
| void InitBreak(CFX_CSSComputedStyle* pStyle, | |
| CFX_CSSDisplay eDisplay, | |
| float fLineWidth, | |
| const CFX_XMLNode* pXMLNode, | |
| CFX_CSSComputedStyle* pParentStyle); | |
| void Loader(float textWidth, float* pLinePos, bool bSavePieces); | |
| void LoadText(CXFA_Node* pNode, | |
| float textWidth, | |
| float* pLinePos, | |
| bool bSavePieces); | |
| bool LoadRichText(const CFX_XMLNode* pXMLNode, | |
| float textWidth, | |
| float* pLinePos, | |
| RetainPtr<CFX_CSSComputedStyle> pParentStyle, | |
| bool bSavePieces, | |
| RetainPtr<CFGAS_LinkUserData> pLinkData, | |
| bool bEndBreak, | |
| bool bIsOl, | |
| int32_t iLiCount); | |
| bool AppendChar(const WideString& wsText, | |
| float* pLinePos, | |
| float fSpaceAbove, | |
| bool bSavePieces); | |
| void AppendTextLine(CFGAS_Char::BreakType dwStatus, | |
| float* pLinePos, | |
| bool bSavePieces, | |
| bool bEndBreak); | |
| void EndBreak(CFGAS_Char::BreakType dwStatus, float* pLinePos, bool bDefault); | |
| bool IsEnd(bool bSavePieces); | |
| void UpdateAlign(float fHeight, float fBottom); | |
| void RenderString(CFX_RenderDevice* pDevice, | |
| PieceLine* pPieceLine, | |
| size_t szPiece, | |
| std::vector<TextCharPos>* pCharPos, | |
| const CFX_Matrix& mtDoc2Device); | |
| void RenderPath(CFX_RenderDevice* pDevice, | |
| const PieceLine* pPieceLine, | |
| size_t szPiece, | |
| std::vector<TextCharPos>* pCharPos, | |
| const CFX_Matrix& mtDoc2Device); | |
| size_t GetDisplayPos(const TextPiece* pPiece, | |
| std::vector<TextCharPos>* pCharPos); | |
| void DoTabstops(CFX_CSSComputedStyle* pStyle, PieceLine* pPieceLine); | |
| bool LayoutInternal(size_t szBlockIndex); | |
| size_t CountBlocks() const; | |
| size_t GetNextIndexFromLastBlockData() const; | |
| void UpdateLoaderHeight(float fTextHeight); | |
| bool m_bHasBlock = false; | |
| bool m_bRichText = false; | |
| int32_t m_iLines = 0; | |
| float m_fMaxWidth = 0; | |
| std::vector<BlockData> m_Blocks; | |
| cppgc::Member<CXFA_FFDoc> const m_pDoc; | |
| cppgc::Member<CXFA_TextProvider> const m_pTextProvider; | |
| cppgc::Member<CXFA_Node> m_pTextDataNode; | |
| cppgc::Member<CXFA_TextParser> m_pTextParser; | |
| std::unique_ptr<CFGAS_RTFBreak> m_pBreak; | |
| std::unique_ptr<LoaderContext> m_pLoader; | |
| std::vector<std::unique_ptr<PieceLine>> m_pieceLines; | |
| std::unique_ptr<CXFA_TextTabstopsContext> m_pTabstopContext; | |
| }; | |
| #endif // XFA_FXFA_CXFA_TEXTLAYOUT_H_ |