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