// Copyright 2014 PDFium Authors. All rights reserved. | |
// 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 | |
#include "xfa/src/foxitlib.h" | |
#include "xfa/src/fee/include/ifde_txtedtbuf.h" | |
#include "xfa/src/fee/include/ifde_txtedtengine.h" | |
#include "xfa/src/fee/include/fx_wordbreak.h" | |
#include "fde_txtedtparag.h" | |
#include "fde_txtedtengine.h" | |
#include "fde_txtedtbuf.h" | |
CFDE_TxtEdtParag::CFDE_TxtEdtParag(CFDE_TxtEdtEngine* pEngine) | |
: m_nCharStart(0), | |
m_nCharCount(0), | |
m_nLineCount(0), | |
m_lpData(NULL), | |
m_pEngine(pEngine) { | |
FXSYS_assert(m_pEngine); | |
} | |
CFDE_TxtEdtParag::~CFDE_TxtEdtParag() { | |
if (m_lpData != NULL) { | |
FX_Free(m_lpData); | |
} | |
} | |
void CFDE_TxtEdtParag::LoadParag() { | |
if (m_lpData != NULL) { | |
((int32_t*)m_lpData)[0]++; | |
return; | |
} | |
IFX_TxtBreak* pTxtBreak = m_pEngine->GetTextBreak(); | |
IFDE_TxtEdtBuf* pTxtBuf = m_pEngine->GetTextBuf(); | |
const FDE_TXTEDTPARAMS* pParam = m_pEngine->GetEditParams(); | |
FX_WCHAR wcAlias = 0; | |
if (pParam->dwMode & FDE_TEXTEDITMODE_Password) { | |
wcAlias = m_pEngine->GetAliasChar(); | |
} | |
IFX_CharIter* pIter = | |
new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)pTxtBuf, wcAlias); | |
pIter->SetAt(m_nCharStart); | |
int32_t nEndIndex = m_nCharStart + m_nCharCount; | |
CFX_ArrayTemplate<int32_t> LineBaseArr; | |
FX_BOOL bReload = FALSE; | |
FX_DWORD dwBreakStatus = FX_TXTBREAK_None; | |
do { | |
if (bReload) { | |
dwBreakStatus = pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak); | |
} else { | |
FX_WCHAR wAppend = pIter->GetChar(); | |
dwBreakStatus = pTxtBreak->AppendChar(wAppend); | |
} | |
if (pIter->GetAt() + 1 == nEndIndex && | |
dwBreakStatus < FX_TXTBREAK_LineBreak) { | |
dwBreakStatus = pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak); | |
} | |
if (dwBreakStatus > FX_TXTBREAK_PieceBreak) { | |
int32_t nCount = pTxtBreak->CountBreakPieces(); | |
int32_t nTotal = 0; | |
for (int32_t j = 0; j < nCount; j++) { | |
const CFX_TxtPiece* Piece = pTxtBreak->GetBreakPiece(j); | |
nTotal += Piece->GetLength(); | |
} | |
LineBaseArr.Add(nTotal); | |
pTxtBreak->ClearBreakPieces(); | |
} | |
if ((pIter->GetAt() + 1 == nEndIndex) && | |
(dwBreakStatus == FX_TXTBREAK_LineBreak)) { | |
bReload = TRUE; | |
pIter->Next(TRUE); | |
} | |
} while (pIter->Next(FALSE) && (pIter->GetAt() < nEndIndex)); | |
pIter->Release(); | |
pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak); | |
pTxtBreak->ClearBreakPieces(); | |
int32_t nLineCount = LineBaseArr.GetSize(); | |
m_nLineCount = nLineCount; | |
if (m_lpData == NULL) { | |
m_lpData = FX_Alloc(int32_t, nLineCount + 1); | |
} else { | |
m_lpData = FX_Realloc(int32_t, m_lpData, (nLineCount + 1)); | |
} | |
int32_t* pIntArr = (int32_t*)m_lpData; | |
pIntArr[0] = 1; | |
m_nLineCount = nLineCount; | |
pIntArr++; | |
for (int32_t j = 0; j < nLineCount; j++, pIntArr++) { | |
*pIntArr = LineBaseArr[j]; | |
} | |
LineBaseArr.RemoveAll(); | |
} | |
void CFDE_TxtEdtParag::UnloadParag() { | |
FXSYS_assert(m_lpData != NULL); | |
((int32_t*)m_lpData)[0]--; | |
FXSYS_assert(((int32_t*)m_lpData)[0] >= 0); | |
if (((int32_t*)m_lpData)[0] == 0) { | |
FX_Free(m_lpData); | |
m_lpData = NULL; | |
} | |
} | |
void CFDE_TxtEdtParag::CalcLines() { | |
IFX_TxtBreak* pTxtBreak = m_pEngine->GetTextBreak(); | |
IFDE_TxtEdtBuf* pTxtBuf = m_pEngine->GetTextBuf(); | |
IFX_CharIter* pIter = new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)pTxtBuf); | |
int32_t nCount = 0; | |
FX_DWORD dwBreakStatus = FX_TXTBREAK_None; | |
int32_t nEndIndex = m_nCharStart + m_nCharCount; | |
pIter->SetAt(m_nCharStart); | |
FX_BOOL bReload = FALSE; | |
do { | |
if (bReload) { | |
dwBreakStatus = pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak); | |
} else { | |
FX_WCHAR wAppend = pIter->GetChar(); | |
dwBreakStatus = pTxtBreak->AppendChar(wAppend); | |
} | |
if (pIter->GetAt() + 1 == nEndIndex && | |
dwBreakStatus < FX_TXTBREAK_LineBreak) { | |
dwBreakStatus = pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak); | |
} | |
if (dwBreakStatus > FX_TXTBREAK_PieceBreak) { | |
nCount++; | |
pTxtBreak->ClearBreakPieces(); | |
} | |
if ((pIter->GetAt() + 1 == nEndIndex) && | |
(dwBreakStatus == FX_TXTBREAK_LineBreak)) { | |
bReload = TRUE; | |
pIter->Next(TRUE); | |
} | |
} while (pIter->Next(FALSE) && (pIter->GetAt() < nEndIndex)); | |
pIter->Release(); | |
pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak); | |
pTxtBreak->ClearBreakPieces(); | |
m_nLineCount = nCount; | |
} | |
void CFDE_TxtEdtParag::GetLineRange(int32_t nLineIndex, | |
int32_t& nStart, | |
int32_t& nCount) const { | |
int32_t* pLineBaseArr = (int32_t*)m_lpData; | |
FXSYS_assert(nLineIndex < m_nLineCount); | |
nStart = m_nCharStart; | |
pLineBaseArr++; | |
for (int32_t i = 0; i < nLineIndex; i++) { | |
nStart += *pLineBaseArr; | |
pLineBaseArr++; | |
} | |
nCount = *pLineBaseArr; | |
} |