• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 #include "xfa/fde/cfde_txtedtparag.h"
8 
9 #include <memory>
10 
11 #include "xfa/fde/cfde_txtedtbuf.h"
12 #include "xfa/fde/cfde_txtedtengine.h"
13 #include "xfa/fde/ifde_txtedtengine.h"
14 #include "xfa/fde/ifx_chariter.h"
15 #include "xfa/fgas/layout/fgas_textbreak.h"
16 
CFDE_TxtEdtParag(CFDE_TxtEdtEngine * pEngine)17 CFDE_TxtEdtParag::CFDE_TxtEdtParag(CFDE_TxtEdtEngine* pEngine)
18     : m_nCharStart(0),
19       m_nCharCount(0),
20       m_nLineCount(0),
21       m_lpData(nullptr),
22       m_pEngine(pEngine) {
23   ASSERT(m_pEngine);
24 }
25 
~CFDE_TxtEdtParag()26 CFDE_TxtEdtParag::~CFDE_TxtEdtParag() {
27   if (m_lpData)
28     FX_Free(m_lpData);
29 }
30 
LoadParag()31 void CFDE_TxtEdtParag::LoadParag() {
32   if (m_lpData) {
33     m_lpData[0]++;
34     return;
35   }
36   CFX_TxtBreak* pTxtBreak = m_pEngine->GetTextBreak();
37   CFDE_TxtEdtBuf* pTxtBuf = m_pEngine->GetTextBuf();
38   const FDE_TXTEDTPARAMS* pParam = m_pEngine->GetEditParams();
39   FX_WCHAR wcAlias = 0;
40   if (pParam->dwMode & FDE_TEXTEDITMODE_Password) {
41     wcAlias = m_pEngine->GetAliasChar();
42   }
43   std::unique_ptr<IFX_CharIter> pIter(new CFDE_TxtEdtBuf::Iterator(
44       static_cast<CFDE_TxtEdtBuf*>(pTxtBuf), wcAlias));
45   pIter->SetAt(m_nCharStart);
46   int32_t nEndIndex = m_nCharStart + m_nCharCount;
47   CFX_ArrayTemplate<int32_t> LineBaseArr;
48   bool bReload = false;
49   uint32_t dwBreakStatus = FX_TXTBREAK_None;
50   do {
51     if (bReload) {
52       dwBreakStatus = pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
53     } else {
54       FX_WCHAR wAppend = pIter->GetChar();
55       dwBreakStatus = pTxtBreak->AppendChar(wAppend);
56     }
57     if (pIter->GetAt() + 1 == nEndIndex &&
58         dwBreakStatus < FX_TXTBREAK_LineBreak) {
59       dwBreakStatus = pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
60     }
61     if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
62       int32_t nCount = pTxtBreak->CountBreakPieces();
63       int32_t nTotal = 0;
64       for (int32_t j = 0; j < nCount; j++) {
65         const CFX_TxtPiece* Piece = pTxtBreak->GetBreakPiece(j);
66         nTotal += Piece->GetLength();
67       }
68       LineBaseArr.Add(nTotal);
69       pTxtBreak->ClearBreakPieces();
70     }
71     if ((pIter->GetAt() + 1 == nEndIndex) &&
72         (dwBreakStatus == FX_TXTBREAK_LineBreak)) {
73       bReload = true;
74       pIter->Next(true);
75     }
76   } while (pIter->Next(false) && (pIter->GetAt() < nEndIndex));
77   pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
78   pTxtBreak->ClearBreakPieces();
79   int32_t nLineCount = LineBaseArr.GetSize();
80   m_nLineCount = nLineCount;
81   if (m_lpData) {
82     m_lpData = FX_Realloc(int32_t, m_lpData, nLineCount + 1);
83   } else {
84     m_lpData = FX_Alloc(int32_t, nLineCount + 1);
85   }
86   int32_t* pIntArr = m_lpData;
87   pIntArr[0] = 1;
88   m_nLineCount = nLineCount;
89   pIntArr++;
90   for (int32_t j = 0; j < nLineCount; j++, pIntArr++) {
91     *pIntArr = LineBaseArr[j];
92   }
93   LineBaseArr.RemoveAll();
94 }
95 
UnloadParag()96 void CFDE_TxtEdtParag::UnloadParag() {
97   m_lpData[0]--;
98   ASSERT(m_lpData[0] >= 0);
99   if (m_lpData[0] == 0) {
100     FX_Free(m_lpData);
101     m_lpData = nullptr;
102   }
103 }
104 
CalcLines()105 void CFDE_TxtEdtParag::CalcLines() {
106   CFX_TxtBreak* pTxtBreak = m_pEngine->GetTextBreak();
107   CFDE_TxtEdtBuf* pTxtBuf = m_pEngine->GetTextBuf();
108   int32_t nCount = 0;
109   uint32_t dwBreakStatus = FX_TXTBREAK_None;
110   int32_t nEndIndex = m_nCharStart + m_nCharCount;
111   std::unique_ptr<IFX_CharIter> pIter(
112       new CFDE_TxtEdtBuf::Iterator(static_cast<CFDE_TxtEdtBuf*>(pTxtBuf)));
113   pIter->SetAt(m_nCharStart);
114   bool bReload = false;
115   do {
116     if (bReload) {
117       dwBreakStatus = pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
118     } else {
119       FX_WCHAR wAppend = pIter->GetChar();
120       dwBreakStatus = pTxtBreak->AppendChar(wAppend);
121     }
122     if (pIter->GetAt() + 1 == nEndIndex &&
123         dwBreakStatus < FX_TXTBREAK_LineBreak) {
124       dwBreakStatus = pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
125     }
126     if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
127       nCount++;
128       pTxtBreak->ClearBreakPieces();
129     }
130     if ((pIter->GetAt() + 1 == nEndIndex) &&
131         (dwBreakStatus == FX_TXTBREAK_LineBreak)) {
132       bReload = true;
133       pIter->Next(true);
134     }
135   } while (pIter->Next(false) && (pIter->GetAt() < nEndIndex));
136   pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
137   pTxtBreak->ClearBreakPieces();
138   m_nLineCount = nCount;
139 }
140 
GetLineRange(int32_t nLineIndex,int32_t & nStart,int32_t & nCount) const141 void CFDE_TxtEdtParag::GetLineRange(int32_t nLineIndex,
142                                     int32_t& nStart,
143                                     int32_t& nCount) const {
144   int32_t* pLineBaseArr = m_lpData;
145   ASSERT(nLineIndex < m_nLineCount);
146   nStart = m_nCharStart;
147   pLineBaseArr++;
148   for (int32_t i = 0; i < nLineIndex; i++) {
149     nStart += *pLineBaseArr;
150     pLineBaseArr++;
151   }
152   nCount = *pLineBaseArr;
153 }
154