Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fee / src / fee / fde_txtedtparag.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../../../foxitlib.h"\r
8 #include "../../include/ifde_txtedtbuf.h"\r
9 #include "../../include/ifde_txtedtengine.h"\r
10 #include "../../include/fx_wordbreak.h"\r
11 #include "fde_txtedtparag.h"\r
12 #include "fde_txtedtengine.h"\r
13 #include "fde_txtedtbuf.h"\r
14 CFDE_TxtEdtParag::CFDE_TxtEdtParag(CFDE_TxtEdtEngine * pEngine)\r
15     : m_nLineCount(0)\r
16     , m_nCharStart(0)\r
17     , m_nCharCount(0)\r
18     , m_lpData(NULL)\r
19     , m_pEngine(pEngine)\r
20 {\r
21     FXSYS_assert(m_pEngine);\r
22 }\r
23 CFDE_TxtEdtParag::~CFDE_TxtEdtParag()\r
24 {\r
25     if (m_lpData != NULL) {\r
26         FX_Free(m_lpData);\r
27     }\r
28 }\r
29 void CFDE_TxtEdtParag::LoadParag()\r
30 {\r
31     if (m_lpData != NULL) {\r
32         ((FX_INT32*)m_lpData)[0]++;\r
33         return;\r
34     }\r
35     IFX_TxtBreak * pTxtBreak    = m_pEngine->GetTextBreak();\r
36     IFDE_TxtEdtBuf * pTxtBuf    = m_pEngine->GetTextBuf();\r
37     const FDE_TXTEDTPARAMS *pParam      = m_pEngine->GetEditParams();\r
38     FX_WCHAR wcAlias = 0;\r
39     if (pParam->dwMode & FDE_TEXTEDITMODE_Password) {\r
40         wcAlias = m_pEngine->GetAliasChar();\r
41     }\r
42     IFX_CharIter * pIter        = FX_NEW CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)pTxtBuf, wcAlias);\r
43     pIter->SetAt(m_nCharStart);\r
44     FX_INT32 nEndIndex = m_nCharStart + m_nCharCount;\r
45     CFX_ArrayTemplate<FX_INT32> LineBaseArr;\r
46     FX_BOOL             bReload                 = FALSE;\r
47     FX_DWORD    dwBreakStatus   = FX_TXTBREAK_None;\r
48     FX_INT32 nTextEnd = m_pEngine->GetTextBufLength();\r
49     do  {\r
50         if (bReload) {\r
51             dwBreakStatus = pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);\r
52         } else {\r
53             FX_WCHAR wAppend = pIter->GetChar();\r
54             dwBreakStatus = pTxtBreak->AppendChar(wAppend);\r
55         }\r
56         if (pIter->GetAt() + 1 == nEndIndex && dwBreakStatus < FX_TXTBREAK_LineBreak) {\r
57             dwBreakStatus = pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);\r
58         }\r
59         if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {\r
60             FX_INT32 nCount = pTxtBreak->CountBreakPieces();\r
61             FX_INT32 nTotal = 0;\r
62             for (FX_INT32 j = 0; j < nCount; j ++) {\r
63                 const CFX_TxtPiece * Piece = pTxtBreak->GetBreakPiece(j);\r
64                 nTotal += Piece->GetLength();\r
65             }\r
66             LineBaseArr.Add(nTotal);\r
67             pTxtBreak->ClearBreakPieces();\r
68         }\r
69         if ((pIter->GetAt() + 1 == nEndIndex) && (dwBreakStatus == FX_TXTBREAK_LineBreak)) {\r
70             bReload = TRUE;\r
71             pIter->Next(TRUE);\r
72         }\r
73     } while (pIter->Next(FALSE) && (pIter->GetAt() < nEndIndex));\r
74     pIter->Release();\r
75     pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);\r
76     pTxtBreak->ClearBreakPieces();\r
77     FX_INT32 nLineCount = LineBaseArr.GetSize();\r
78     m_nLineCount = nLineCount;\r
79     if (m_lpData == NULL) {\r
80         m_lpData = FX_Alloc(FX_INT32, nLineCount + 1);\r
81     } else {\r
82         m_lpData = FX_Realloc(FX_INT32, m_lpData, (nLineCount + 1));\r
83     }\r
84     FX_INT32 * pIntArr = (FX_INT32*)m_lpData;\r
85     pIntArr[0] = 1;\r
86     m_nLineCount = nLineCount;\r
87     pIntArr ++;\r
88     for (FX_INT32 j = 0; j < nLineCount; j ++, pIntArr ++) {\r
89         *pIntArr = LineBaseArr[j];\r
90     }\r
91     LineBaseArr.RemoveAll();\r
92 }\r
93 void CFDE_TxtEdtParag::UnloadParag()\r
94 {\r
95     FXSYS_assert(m_lpData != NULL);\r
96     ((FX_INT32*)m_lpData)[0]--;\r
97     FXSYS_assert(((FX_INT32*)m_lpData)[0] >= 0);\r
98     if (((FX_INT32*)m_lpData)[0] == 0) {\r
99         FX_Free(m_lpData);\r
100         m_lpData = NULL;\r
101     }\r
102 }\r
103 void CFDE_TxtEdtParag::CalcLines()\r
104 {\r
105     IFX_TxtBreak * pTxtBreak    = m_pEngine->GetTextBreak();\r
106     IFDE_TxtEdtBuf * pTxtBuf    = m_pEngine->GetTextBuf();\r
107     IFX_CharIter * pIter        = FX_NEW CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)pTxtBuf);\r
108     FX_INT32 nCount = 0;\r
109     FX_DWORD dwBreakStatus = FX_TXTBREAK_None;\r
110     FX_INT32 nEndIndex = m_nCharStart + m_nCharCount;\r
111     pIter->SetAt(m_nCharStart);\r
112     FX_BOOL bReload = FALSE;\r
113     FX_INT32 nTextEnd = m_pEngine->GetTextBufLength();\r
114     do {\r
115         if (bReload) {\r
116             dwBreakStatus = pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);\r
117         } else {\r
118             FX_WCHAR wAppend = pIter->GetChar();\r
119             dwBreakStatus = pTxtBreak->AppendChar(wAppend);\r
120         }\r
121         if (pIter->GetAt() + 1 == nEndIndex && dwBreakStatus < FX_TXTBREAK_LineBreak) {\r
122             dwBreakStatus = pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);\r
123         }\r
124         if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {\r
125             nCount ++;\r
126             pTxtBreak->ClearBreakPieces();\r
127         }\r
128         if ((pIter->GetAt() + 1 == nEndIndex) && (dwBreakStatus == FX_TXTBREAK_LineBreak)) {\r
129             bReload = TRUE;\r
130             pIter->Next(TRUE);\r
131         }\r
132     } while (pIter->Next(FALSE) && (pIter->GetAt() < nEndIndex));\r
133     pIter->Release();\r
134     pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);\r
135     pTxtBreak->ClearBreakPieces();\r
136     m_nLineCount = nCount;\r
137 }\r
138 void CFDE_TxtEdtParag::GetLineRange(FX_INT32 nLineIndex, FX_INT32& nStart, FX_INT32& nCount) const\r
139 {\r
140     FX_INT32 * pLineBaseArr = (FX_INT32*)m_lpData;\r
141     FXSYS_assert(nLineIndex < m_nLineCount);\r
142     nStart = m_nCharStart;\r
143     pLineBaseArr ++;\r
144     for (FX_INT32 i = 0; i < nLineIndex; i ++) {\r
145         nStart += *pLineBaseArr;\r
146         pLineBaseArr ++;\r
147     }\r
148     nCount = *pLineBaseArr;\r
149 }\r