1// Copyright 2017 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7#ifndef XFA_FXFA_APP_CXFA_TEXTLAYOUT_H_
8#define XFA_FXFA_APP_CXFA_TEXTLAYOUT_H_
9
10#include <memory>
11#include <vector>
12
13#include "core/fxcrt/fx_basic.h"
14#include "core/fxcrt/fx_coordinates.h"
15#include "core/fxcrt/fx_string.h"
16#include "xfa/fde/css/fde_css.h"
17#include "xfa/fgas/layout/fgas_rtfbreak.h"
18#include "xfa/fxfa/app/cxfa_textparser.h"
19
20class CFDE_Brush;
21class CFDE_CSSComputedStyle;
22class CFDE_Pen;
23class CFDE_RenderDevice;
24class CFDE_XMLNode;
25class CFX_RTFBreak;
26class CXFA_LoaderContext;
27class CXFA_LinkUserData;
28class CXFA_Node;
29class CXFA_PieceLine;
30class CXFA_TextProvider;
31class CXFA_TextTabstopsContext;
32class XFA_TextPiece;
33
34class CXFA_TextLayout {
35 public:
36  explicit CXFA_TextLayout(CXFA_TextProvider* pTextProvider);
37  ~CXFA_TextLayout();
38
39  int32_t GetText(CFX_WideString& wsText);
40  FX_FLOAT GetLayoutHeight();
41  FX_FLOAT StartLayout(FX_FLOAT fWidth = -1);
42  bool DoLayout(int32_t iBlockIndex,
43                FX_FLOAT& fCalcHeight,
44                FX_FLOAT fContentAreaHeight = -1,
45                FX_FLOAT fTextHeight = -1);
46
47  bool CalcSize(const CFX_SizeF& minSize,
48                const CFX_SizeF& maxSize,
49                CFX_SizeF& defaultSize);
50  bool Layout(const CFX_SizeF& size, FX_FLOAT* fHeight = nullptr);
51  void ItemBlocks(const CFX_RectF& rtText, int32_t iBlockIndex);
52  bool DrawString(CFX_RenderDevice* pFxDevice,
53                  const CFX_Matrix& tmDoc2Device,
54                  const CFX_RectF& rtClip,
55                  int32_t iBlock = 0);
56  bool IsLoaded() const { return !m_pieceLines.empty(); }
57  void Unload();
58  const std::vector<std::unique_ptr<CXFA_PieceLine>>* GetPieceLines() const {
59    return &m_pieceLines;
60  }
61
62  bool m_bHasBlock;
63  CFX_ArrayTemplate<int32_t> m_Blocks;
64
65 private:
66  void GetTextDataNode();
67  CFDE_XMLNode* GetXMLContainerNode();
68  std::unique_ptr<CFX_RTFBreak> CreateBreak(bool bDefault);
69  void InitBreak(FX_FLOAT fLineWidth);
70  void InitBreak(CFDE_CSSComputedStyle* pStyle,
71                 FDE_CSSDisplay eDisplay,
72                 FX_FLOAT fLineWidth,
73                 CFDE_XMLNode* pXMLNode,
74                 CFDE_CSSComputedStyle* pParentStyle = nullptr);
75  bool Loader(const CFX_SizeF& szText,
76              FX_FLOAT& fLinePos,
77              bool bSavePieces = true);
78  void LoadText(CXFA_Node* pNode,
79                const CFX_SizeF& szText,
80                FX_FLOAT& fLinePos,
81                bool bSavePieces);
82  bool LoadRichText(CFDE_XMLNode* pXMLNode,
83                    const CFX_SizeF& szText,
84                    FX_FLOAT& fLinePos,
85                    const CFX_RetainPtr<CFDE_CSSComputedStyle>& pParentStyle,
86                    bool bSavePieces,
87                    CFX_RetainPtr<CXFA_LinkUserData> pLinkData,
88                    bool bEndBreak = true,
89                    bool bIsOl = false,
90                    int32_t iLiCount = 0);
91  bool AppendChar(const CFX_WideString& wsText,
92                  FX_FLOAT& fLinePos,
93                  FX_FLOAT fSpaceAbove,
94                  bool bSavePieces);
95  void AppendTextLine(CFX_RTFBreakType dwStatus,
96                      FX_FLOAT& fLinePos,
97                      bool bSavePieces,
98                      bool bEndBreak = false);
99  void EndBreak(CFX_RTFBreakType dwStatus, FX_FLOAT& fLinePos, bool bDefault);
100  bool IsEnd(bool bSavePieces);
101  void ProcessText(CFX_WideString& wsText);
102  void UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom);
103  void RenderString(CFDE_RenderDevice* pDevice,
104                    CFDE_Brush* pBrush,
105                    CXFA_PieceLine* pPieceLine,
106                    int32_t iPiece,
107                    FXTEXT_CHARPOS* pCharPos,
108                    const CFX_Matrix& tmDoc2Device);
109  void RenderPath(CFDE_RenderDevice* pDevice,
110                  CFDE_Pen* pPen,
111                  CXFA_PieceLine* pPieceLine,
112                  int32_t iPiece,
113                  FXTEXT_CHARPOS* pCharPos,
114                  const CFX_Matrix& tmDoc2Device);
115  int32_t GetDisplayPos(const XFA_TextPiece* pPiece,
116                        FXTEXT_CHARPOS* pCharPos,
117                        bool bCharCode = false);
118  bool ToRun(const XFA_TextPiece* pPiece, FX_RTFTEXTOBJ* tr);
119  void DoTabstops(CFDE_CSSComputedStyle* pStyle, CXFA_PieceLine* pPieceLine);
120  bool Layout(int32_t iBlock);
121  int32_t CountBlocks() const;
122
123  CXFA_TextProvider* m_pTextProvider;
124  CXFA_Node* m_pTextDataNode;
125  bool m_bRichText;
126  std::unique_ptr<CFX_RTFBreak> m_pBreak;
127  std::unique_ptr<CXFA_LoaderContext> m_pLoader;
128  int32_t m_iLines;
129  FX_FLOAT m_fMaxWidth;
130  CXFA_TextParser m_textParser;
131  std::vector<std::unique_ptr<CXFA_PieceLine>> m_pieceLines;
132  std::unique_ptr<CXFA_TextTabstopsContext> m_pTabstopContext;
133  bool m_bBlockContinue;
134};
135
136#endif  // XFA_FXFA_APP_CXFA_TEXTLAYOUT_H_
137