diff options
author | Dan Sinclair <dsinclair@chromium.org> | 2017-08-30 12:16:16 -0400 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-08-30 16:26:12 +0000 |
commit | 68eefa6a6f6bbab73000a29e2cac3e104be1cc81 (patch) | |
tree | b48dbf0932022bc551ae06e2400262c203856942 /xfa/fde/cfde_txtedtpage.cpp | |
parent | aa3a9cd82df9dff1ef136797259e606a39c18b75 (diff) | |
download | pdfium-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.cpp | 398 |
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; -} |