summaryrefslogtreecommitdiff
path: root/xfa/fde/cfde_txtedtpage.cpp
diff options
context:
space:
mode:
authorDan Sinclair <dsinclair@chromium.org>2017-08-30 12:16:16 -0400
committerChromium commit bot <commit-bot@chromium.org>2017-08-30 16:26:12 +0000
commit68eefa6a6f6bbab73000a29e2cac3e104be1cc81 (patch)
treeb48dbf0932022bc551ae06e2400262c203856942 /xfa/fde/cfde_txtedtpage.cpp
parentaa3a9cd82df9dff1ef136797259e606a39c18b75 (diff)
downloadpdfium-68eefa6a6f6bbab73000a29e2cac3e104be1cc81.tar.xz
Rebuild CFDE_TextEditEngine.
This CL rebuilds the text edit engine in a simpler fashion. Instead of depending on multiple pages, paragraphs and buffer fields there is a single text edit engine which contains a gap buffer. This makes the code easier to understand and follow. Change-Id: I10fe85603fa9ed15a647eaac2d931f113cd0c7b0 Reviewed-on: https://pdfium-review.googlesource.com/11990 Commit-Queue: dsinclair <dsinclair@chromium.org> Reviewed-by: Henrique Nakashima <hnakashima@chromium.org> Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Diffstat (limited to 'xfa/fde/cfde_txtedtpage.cpp')
-rw-r--r--xfa/fde/cfde_txtedtpage.cpp398
1 files changed, 0 insertions, 398 deletions
diff --git a/xfa/fde/cfde_txtedtpage.cpp b/xfa/fde/cfde_txtedtpage.cpp
deleted file mode 100644
index 3020882c7e..0000000000
--- a/xfa/fde/cfde_txtedtpage.cpp
+++ /dev/null
@@ -1,398 +0,0 @@
-// 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/fde/cfde_txtedtpage.h"
-
-#include <algorithm>
-
-#include "core/fxcrt/cfx_wordbreak.h"
-#include "third_party/base/ptr_util.h"
-#include "third_party/base/stl_util.h"
-#include "xfa/fde/cfde_txtedtbuf.h"
-#include "xfa/fde/cfde_txtedtengine.h"
-#include "xfa/fde/cfde_txtedtparag.h"
-#include "xfa/fde/cfde_txtedttextset.h"
-#include "xfa/fgas/layout/cfx_txtbreak.h"
-
-namespace {
-
-const double kTolerance = 0.1f;
-
-} // namespace
-
-CFDE_TxtEdtPage::CFDE_TxtEdtPage(CFDE_TxtEdtEngine* pEngine, int32_t nPageIndex)
- : m_pEditEngine(pEngine),
- m_pBgnParag(nullptr),
- m_pEndParag(nullptr),
- m_nRefCount(0),
- m_nPageStart(-1),
- m_nCharCount(0),
- m_nPageIndex(nPageIndex),
- m_bLoaded(false) {
-}
-
-CFDE_TxtEdtPage::~CFDE_TxtEdtPage() {}
-
-int32_t CFDE_TxtEdtPage::GetCharRect(int32_t nIndex,
- CFX_RectF& rect,
- bool bBBox) const {
- ASSERT(m_nRefCount > 0);
- ASSERT(nIndex >= 0 && nIndex < m_nCharCount);
- if (m_nRefCount < 1)
- return 0;
-
- for (const auto& piece : m_Pieces) {
- if (nIndex >= piece.nStart && nIndex < piece.nStart + piece.nCount) {
- std::vector<CFX_RectF> rectArr = m_pTextSet->GetCharRects(&piece, bBBox);
- rect = rectArr[nIndex - piece.nStart];
- return piece.nBidiLevel;
- }
- }
- ASSERT(0);
- return 0;
-}
-
-int32_t CFDE_TxtEdtPage::GetCharIndex(const CFX_PointF& fPoint, bool& bBefore) {
- CFX_PointF ptF = fPoint;
- NormalizePt2Rect(ptF, m_rtPageContents, kTolerance);
- int32_t nCount = pdfium::CollectionSize<int32_t>(m_Pieces);
- CFX_RectF rtLine;
- int32_t nBgn = 0;
- int32_t nEnd = 0;
- bool bInLine = false;
- int32_t i = 0;
- for (i = 0; i < nCount; i++) {
- const FDE_TEXTEDITPIECE* pPiece = &m_Pieces[i];
- if (!bInLine &&
- (pPiece->rtPiece.top <= ptF.y && pPiece->rtPiece.bottom() > ptF.y)) {
- nBgn = nEnd = i;
- rtLine = pPiece->rtPiece;
- bInLine = true;
- } else if (bInLine) {
- if (pPiece->rtPiece.bottom() <= ptF.y || pPiece->rtPiece.top > ptF.y) {
- nEnd = i - 1;
- break;
- } else {
- rtLine.Union(pPiece->rtPiece);
- }
- }
- }
- NormalizePt2Rect(ptF, rtLine, kTolerance);
- int32_t nCaret = 0;
- FDE_TEXTEDITPIECE* pPiece = nullptr;
- for (i = nBgn; i <= nEnd; i++) {
- pPiece = &m_Pieces[i];
- nCaret = m_nPageStart + pPiece->nStart;
- if (pPiece->rtPiece.Contains(ptF)) {
- std::vector<CFX_RectF> rectArr = m_pTextSet->GetCharRects(pPiece, false);
- int32_t nRtCount = pdfium::CollectionSize<int32_t>(rectArr);
- for (int32_t j = 0; j < nRtCount; j++) {
- if (rectArr[j].Contains(ptF)) {
- nCaret = m_nPageStart + pPiece->nStart + j;
- if (nCaret >= m_pEditEngine->GetTextLength()) {
- bBefore = true;
- return m_pEditEngine->GetTextLength();
- }
- wchar_t wChar = m_pEditEngine->GetTextBuf()->GetCharByIndex(nCaret);
- if (wChar == L'\n' || wChar == L'\r') {
- if (wChar == L'\n') {
- if (m_pEditEngine->GetTextBuf()->GetCharByIndex(nCaret - 1) ==
- L'\r') {
- nCaret--;
- }
- }
- bBefore = true;
- return nCaret;
- }
- if (ptF.x > ((rectArr[j].left + rectArr[j].right()) / 2)) {
- bBefore = FX_IsOdd(pPiece->nBidiLevel);
- } else {
- bBefore = !FX_IsOdd(pPiece->nBidiLevel);
- }
- return nCaret;
- }
- }
- }
- }
- bBefore = true;
- return nCaret;
-}
-
-void CFDE_TxtEdtPage::CalcRangeRectArray(
- int32_t nStart,
- int32_t nCount,
- std::vector<CFX_RectF>* pRectFArr) const {
- int32_t nEnd = nStart + nCount - 1;
- bool bInRange = false;
- for (const auto& piece : m_Pieces) {
- if (!bInRange) {
- if (nStart >= piece.nStart && nStart < piece.nStart + piece.nCount) {
- int32_t nRangeEnd = piece.nCount - 1;
- bool bEnd = false;
- if (nEnd >= piece.nStart && nEnd < piece.nStart + piece.nCount) {
- nRangeEnd = nEnd - piece.nStart;
- bEnd = true;
- }
- std::vector<CFX_RectF> rcArr = m_pTextSet->GetCharRects(&piece, false);
- CFX_RectF rectPiece = rcArr[nStart - piece.nStart];
- rectPiece.Union(rcArr[nRangeEnd]);
- pRectFArr->push_back(rectPiece);
- if (bEnd)
- return;
-
- bInRange = true;
- }
- } else {
- if (nEnd >= piece.nStart && nEnd < piece.nStart + piece.nCount) {
- std::vector<CFX_RectF> rcArr = m_pTextSet->GetCharRects(&piece, false);
- CFX_RectF rectPiece = rcArr[0];
- rectPiece.Union(rcArr[nEnd - piece.nStart]);
- pRectFArr->push_back(rectPiece);
- return;
- }
- pRectFArr->push_back(piece.rtPiece);
- }
- }
-}
-
-int32_t CFDE_TxtEdtPage::SelectWord(const CFX_PointF& fPoint, int32_t& nCount) {
- if (m_nRefCount < 0) {
- return -1;
- }
- CFDE_TxtEdtBuf* pBuf = m_pEditEngine->GetTextBuf();
- bool bBefore;
- int32_t nIndex = GetCharIndex(fPoint, bBefore);
- if (nIndex == m_pEditEngine->GetTextLength()) {
- nIndex = m_pEditEngine->GetTextLength() - 1;
- }
- if (nIndex < 0) {
- return -1;
- }
- auto pIter = pdfium::MakeUnique<CFX_WordBreak>();
- pIter->Attach(new CFDE_TxtEdtBuf::Iterator(pBuf, 0));
- pIter->SetAt(nIndex);
- nCount = pIter->GetWordLength();
- return pIter->GetWordPos();
-}
-
-int32_t CFDE_TxtEdtPage::LoadPage() {
- if (m_nRefCount > 0) {
- m_nRefCount++;
- return m_nRefCount;
- }
-
- CFDE_TxtEdtBuf* pBuf = m_pEditEngine->GetTextBuf();
- const FDE_TXTEDTPARAMS* pParams = m_pEditEngine->GetEditParams();
- wchar_t wcAlias = 0;
- if (pParams->dwMode & FDE_TEXTEDITMODE_Password)
- wcAlias = m_pEditEngine->GetAliasChar();
-
- m_pIter = pdfium::MakeUnique<CFDE_TxtEdtBuf::Iterator>(
- static_cast<CFDE_TxtEdtBuf*>(pBuf), wcAlias);
- CFX_TxtBreak* pBreak = m_pEditEngine->GetTextBreak();
- pBreak->EndBreak(CFX_BreakType::Paragraph);
- pBreak->ClearBreakPieces();
- int32_t nPageLineCount = m_pEditEngine->GetPageLineCount();
- int32_t nStartLine = nPageLineCount * m_nPageIndex;
- int32_t nEndLine = std::min((nStartLine + nPageLineCount - 1),
- (m_pEditEngine->GetLineCount() - 1));
- int32_t nPageStart, nPageEnd, nTemp, nBgnParag, nStartLineInParag, nEndParag,
- nEndLineInParag;
- nBgnParag = m_pEditEngine->Line2Parag(0, 0, nStartLine, nStartLineInParag);
- m_pBgnParag =
- static_cast<CFDE_TxtEdtParag*>(m_pEditEngine->GetParag(nBgnParag));
- m_pBgnParag->LoadParag();
- m_pBgnParag->GetLineRange(nStartLine - nStartLineInParag, nPageStart, nTemp);
- nEndParag = m_pEditEngine->Line2Parag(nBgnParag, nStartLineInParag, nEndLine,
- nEndLineInParag);
- m_pEndParag =
- static_cast<CFDE_TxtEdtParag*>(m_pEditEngine->GetParag(nEndParag));
- m_pEndParag->LoadParag();
- m_pEndParag->GetLineRange(nEndLine - nEndLineInParag, nPageEnd, nTemp);
- nPageEnd += (nTemp - 1);
-
- float fLineStart = 0.0f;
- float fLineStep = pParams->fLineSpace;
- float fLinePos = fLineStart;
- if (!m_pTextSet)
- m_pTextSet = pdfium::MakeUnique<CFDE_TxtEdtTextSet>(this);
-
- m_Pieces.clear();
- CFX_BreakType dwBreakStatus = CFX_BreakType::None;
- int32_t nPieceStart = 0;
-
- m_CharWidths.resize(nPageEnd - nPageStart + 1, 0);
- pBreak->EndBreak(CFX_BreakType::Paragraph);
- pBreak->ClearBreakPieces();
- m_nPageStart = nPageStart;
- m_nCharCount = nPageEnd - nPageStart + 1;
- bool bReload = false;
- float fDefCharWidth = 0;
- std::unique_ptr<IFX_CharIter> pIter = m_pIter->Clone();
- pIter->SetAt(nPageStart);
- m_pIter->SetAt(nPageStart);
- bool bFirstPiece = true;
- do {
- if (bReload) {
- dwBreakStatus = pBreak->EndBreak(CFX_BreakType::Paragraph);
- } else {
- wchar_t wAppend = pIter->GetChar();
- dwBreakStatus = pBreak->AppendChar(wAppend);
- }
- if (pIter->GetAt() == nPageEnd && CFX_BreakTypeNoneOrPiece(dwBreakStatus))
- dwBreakStatus = pBreak->EndBreak(CFX_BreakType::Paragraph);
-
- if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) {
- int32_t nPieceCount = pBreak->CountBreakPieces();
- for (int32_t j = 0; j < nPieceCount; j++) {
- const CFX_BreakPiece* pPiece = pBreak->GetBreakPieceUnstable(j);
- FDE_TEXTEDITPIECE TxtEdtPiece;
- memset(&TxtEdtPiece, 0, sizeof(FDE_TEXTEDITPIECE));
- TxtEdtPiece.nBidiLevel = pPiece->m_iBidiLevel;
- TxtEdtPiece.nCount = pPiece->GetLength();
- TxtEdtPiece.nStart = nPieceStart;
- TxtEdtPiece.dwCharStyles = pPiece->m_dwCharStyles;
- if (FX_IsOdd(pPiece->m_iBidiLevel))
- TxtEdtPiece.dwCharStyles |= FX_TXTCHARSTYLE_OddBidiLevel;
-
- float fParaBreakWidth = 0.0f;
- if (!CFX_BreakTypeNoneOrPiece(pPiece->m_dwStatus)) {
- if (TxtEdtPiece.nCount >= 2) {
- wchar_t wChar = pBuf->GetCharByIndex(
- m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 1);
- wchar_t wCharPre = pBuf->GetCharByIndex(
- m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 2);
- if (wChar == L'\n') {
- fParaBreakWidth += fDefCharWidth;
- }
- if (wCharPre == L'\n') {
- fParaBreakWidth += fDefCharWidth;
- }
- } else if (TxtEdtPiece.nCount >= 1) {
- wchar_t wChar = pBuf->GetCharByIndex(
- m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 1);
- if (wChar == L'\n') {
- fParaBreakWidth += fDefCharWidth;
- }
- }
- }
-
- TxtEdtPiece.rtPiece.left = (float)pPiece->m_iStartPos / 20000.0f;
- TxtEdtPiece.rtPiece.top = fLinePos;
- TxtEdtPiece.rtPiece.width =
- (float)pPiece->m_iWidth / 20000.0f + fParaBreakWidth;
- TxtEdtPiece.rtPiece.height = pParams->fLineSpace;
-
- if (bFirstPiece) {
- m_rtPageContents = TxtEdtPiece.rtPiece;
- bFirstPiece = false;
- } else {
- m_rtPageContents.Union(TxtEdtPiece.rtPiece);
- }
- nPieceStart += TxtEdtPiece.nCount;
- m_Pieces.push_back(TxtEdtPiece);
- for (int32_t k = 0; k < TxtEdtPiece.nCount; k++) {
- m_CharWidths[TxtEdtPiece.nStart + k] =
- pPiece->GetChar(k)->m_iCharWidth;
- }
- }
- fLinePos += fLineStep;
- pBreak->ClearBreakPieces();
- }
- if (pIter->GetAt() == nPageEnd && dwBreakStatus == CFX_BreakType::Line) {
- bReload = true;
- pIter->Next(true);
- }
- } while (pIter->Next(false) && (pIter->GetAt() <= nPageEnd));
- if (m_rtPageContents.left != 0) {
- float fDelta = 0.0f;
- if (m_rtPageContents.width < pParams->fPlateWidth) {
- if (pParams->dwAlignment & FDE_TEXTEDITALIGN_Right) {
- fDelta = pParams->fPlateWidth - m_rtPageContents.width;
- } else if (pParams->dwAlignment & FDE_TEXTEDITALIGN_Center) {
- if ((pParams->dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText) &&
- m_nCharCount > 1) {
- int32_t nCount = m_nCharCount - 1;
- int32_t n = (m_pEditEngine->GetLimit() - nCount) / 2;
- fDelta = (m_rtPageContents.width / nCount) * n;
- } else {
- fDelta = (pParams->fPlateWidth - m_rtPageContents.width) / 2;
- }
- }
- }
- float fOffset = m_rtPageContents.left - fDelta;
- for (auto& piece : m_Pieces)
- piece.rtPiece.Offset(-fOffset, 0.0f);
-
- m_rtPageContents.Offset(-fOffset, 0.0f);
- }
- if (m_pEditEngine->GetEditParams()->dwLayoutStyles &
- FDE_TEXTEDITLAYOUT_LastLineHeight) {
- m_rtPageContents.height -= pParams->fLineSpace - pParams->fFontSize;
- m_Pieces.back().rtPiece.height = pParams->fFontSize;
- }
- m_nRefCount = 1;
- m_bLoaded = true;
- return 0;
-}
-
-void CFDE_TxtEdtPage::UnloadPage() {
- ASSERT(m_nRefCount > 0);
- m_nRefCount--;
- if (m_nRefCount != 0)
- return;
-
- m_Pieces.clear();
- m_pTextSet.reset();
- m_CharWidths.clear();
- if (m_pBgnParag) {
- m_pBgnParag->UnloadParag();
- m_pBgnParag = nullptr;
- }
- if (m_pEndParag) {
- m_pEndParag->UnloadParag();
- m_pEndParag = nullptr;
- }
- m_pIter.reset();
-}
-
-const FDE_TEXTEDITPIECE& CFDE_TxtEdtPage::GetTextPiece(size_t pos) const {
- ASSERT(pos < m_Pieces.size());
- return m_Pieces[pos];
-}
-
-wchar_t CFDE_TxtEdtPage::GetChar(const FDE_TEXTEDITPIECE* pIdentity,
- int32_t index) const {
- int32_t nIndex = m_nPageStart + pIdentity->nStart + index;
- if (nIndex != m_pIter->GetAt())
- m_pIter->SetAt(nIndex);
-
- wchar_t wChar = m_pIter->GetChar();
- m_pIter->Next();
- return wChar;
-}
-
-int32_t CFDE_TxtEdtPage::GetWidth(const FDE_TEXTEDITPIECE* pIdentity,
- int32_t index) const {
- int32_t nWidth = m_CharWidths[pIdentity->nStart + index];
- return nWidth;
-}
-
-void CFDE_TxtEdtPage::NormalizePt2Rect(CFX_PointF& ptF,
- const CFX_RectF& rtF,
- float fTolerance) const {
- if (rtF.Contains(ptF))
- return;
- if (ptF.x < rtF.left)
- ptF.x = rtF.left;
- else if (ptF.x >= rtF.right())
- ptF.x = rtF.right() - fTolerance;
-
- if (ptF.y < rtF.top)
- ptF.y = rtF.top;
- else if (ptF.y >= rtF.bottom())
- ptF.y = rtF.bottom() - fTolerance;
-}