diff options
Diffstat (limited to 'xfa/fee/fde_txtedtpage.cpp')
-rw-r--r-- | xfa/fee/fde_txtedtpage.cpp | 650 |
1 files changed, 650 insertions, 0 deletions
diff --git a/xfa/fee/fde_txtedtpage.cpp b/xfa/fee/fde_txtedtpage.cpp new file mode 100644 index 0000000000..5ecbceaf40 --- /dev/null +++ b/xfa/fee/fde_txtedtpage.cpp @@ -0,0 +1,650 @@ +// 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/fee/fde_txtedtpage.h" + +#include <algorithm> + +#include "xfa/fee/fde_txtedtbuf.h" +#include "xfa/fee/fde_txtedtengine.h" +#include "xfa/fee/fde_txtedtparag.h" +#include "xfa/fee/fx_wordbreak/fx_wordbreak.h" +#include "xfa/fee/ifde_txtedtbuf.h" +#include "xfa/fee/ifde_txtedtengine.h" +#include "xfa/fee/ifde_txtedtpage.h" + +#define FDE_TXTEDT_TOLERANCE 0.1f + +IFDE_TxtEdtPage* IFDE_TxtEdtPage::Create(IFDE_TxtEdtEngine* pEngine, + int32_t nIndex) { + return (IFDE_TxtEdtPage*)new CFDE_TxtEdtPage(pEngine, nIndex); +} +CFDE_TxtEdtTextSet::CFDE_TxtEdtTextSet(CFDE_TxtEdtPage* pPage) + : m_pPage(pPage) {} +CFDE_TxtEdtTextSet::~CFDE_TxtEdtTextSet() {} +FDE_VISUALOBJTYPE CFDE_TxtEdtTextSet::GetType() { + return FDE_VISUALOBJ_Text; +} +FX_BOOL CFDE_TxtEdtTextSet::GetBBox(FDE_HVISUALOBJ hVisualObj, + CFX_RectF& bbox) { + return FALSE; +} +FX_BOOL CFDE_TxtEdtTextSet::GetMatrix(FDE_HVISUALOBJ hVisualObj, + CFX_Matrix& matrix) { + return FALSE; +} +FX_BOOL CFDE_TxtEdtTextSet::GetRect(FDE_HVISUALOBJ hVisualObj, CFX_RectF& rt) { + rt = ((FDE_TEXTEDITPIECE*)(hVisualObj))->rtPiece; + return TRUE; +} +FX_BOOL CFDE_TxtEdtTextSet::GetClip(FDE_HVISUALOBJ hVisualObj, CFX_RectF& rt) { + return FALSE; +} +int32_t CFDE_TxtEdtTextSet::GetString(FDE_HVISUALOBJ hText, + CFX_WideString& wsText) { + FDE_TEXTEDITPIECE* pPiece = (FDE_TEXTEDITPIECE*)hText; + FX_WCHAR* pBuffer = wsText.GetBuffer(pPiece->nCount); + for (int32_t i = 0; i < pPiece->nCount; i++) { + pBuffer[i] = m_pPage->GetChar((void*)hText, i); + } + wsText.ReleaseBuffer(pPiece->nCount); + return pPiece->nCount; +} +IFX_Font* CFDE_TxtEdtTextSet::GetFont(FDE_HVISUALOBJ hText) { + return m_pPage->GetEngine()->GetEditParams()->pFont; +} +FX_FLOAT CFDE_TxtEdtTextSet::GetFontSize(FDE_HVISUALOBJ hText) { + return m_pPage->GetEngine()->GetEditParams()->fFontSize; +} +FX_ARGB CFDE_TxtEdtTextSet::GetFontColor(FDE_HVISUALOBJ hText) { + return m_pPage->GetEngine()->GetEditParams()->dwFontColor; +} +int32_t CFDE_TxtEdtTextSet::GetDisplayPos(FDE_HVISUALOBJ hText, + FXTEXT_CHARPOS* pCharPos, + FX_BOOL bCharCode, + CFX_WideString* pWSForms) { + if (hText == NULL) { + return 0; + } + FDE_TEXTEDITPIECE* pPiece = (FDE_TEXTEDITPIECE*)hText; + int32_t nLength = pPiece->nCount; + if (nLength < 1) { + return 0; + } + CFDE_TxtEdtEngine* pEngine = (CFDE_TxtEdtEngine*)(m_pPage->GetEngine()); + const FDE_TXTEDTPARAMS* pTextParams = pEngine->GetEditParams(); + IFX_TxtBreak* pBreak = pEngine->GetTextBreak(); + FX_DWORD dwLayoutStyle = pBreak->GetLayoutStyles(); + FX_TXTRUN tr; + tr.pAccess = m_pPage; + tr.pIdentity = (void*)hText; + tr.pStr = NULL; + tr.pWidths = NULL; + tr.iLength = nLength; + tr.pFont = pTextParams->pFont; + tr.fFontSize = pTextParams->fFontSize; + tr.dwStyles = dwLayoutStyle; + tr.iCharRotation = pTextParams->nCharRotation; + tr.dwCharStyles = pPiece->dwCharStyles; + tr.pRect = &(pPiece->rtPiece); + tr.wLineBreakChar = pTextParams->wLineBreakChar; + return pBreak->GetDisplayPos(&tr, pCharPos, bCharCode, pWSForms); +} +int32_t CFDE_TxtEdtTextSet::GetCharRects(FDE_HVISUALOBJ hText, + CFX_RectFArray& rtArray) { + return GetCharRects_Impl(hText, rtArray); +} +int32_t CFDE_TxtEdtTextSet::GetCharRects_Impl(FDE_HVISUALOBJ hText, + CFX_RectFArray& rtArray, + FX_BOOL bBBox) { + if (hText == NULL) { + return 0; + } + FDE_TEXTEDITPIECE* pPiece = (FDE_TEXTEDITPIECE*)hText; + CFDE_TxtEdtEngine* pEngine = (CFDE_TxtEdtEngine*)(m_pPage->GetEngine()); + int32_t nLength = pPiece->nCount; + if (nLength < 1) { + return 0; + } + const FDE_TXTEDTPARAMS* pTextParams = pEngine->GetEditParams(); + FX_DWORD dwLayoutStyle = pEngine->GetTextBreak()->GetLayoutStyles(); + FX_TXTRUN tr; + tr.pAccess = m_pPage; + tr.pIdentity = (void*)hText; + tr.pStr = NULL; + tr.pWidths = NULL; + tr.iLength = nLength; + tr.pFont = pTextParams->pFont; + tr.fFontSize = pTextParams->fFontSize; + tr.dwStyles = dwLayoutStyle; + tr.iCharRotation = pTextParams->nCharRotation; + tr.dwCharStyles = pPiece->dwCharStyles; + tr.pRect = &(pPiece->rtPiece); + tr.wLineBreakChar = pTextParams->wLineBreakChar; + return pEngine->GetTextBreak()->GetCharRects(&tr, rtArray, bBBox); +} +CFDE_TxtEdtPage::CFDE_TxtEdtPage(IFDE_TxtEdtEngine* pEngine, int32_t nPageIndex) + : m_pIter(nullptr), + m_pTextSet(nullptr), + m_pBgnParag(nullptr), + m_pEndParag(nullptr), + m_nRefCount(0), + m_nPageStart(-1), + m_nCharCount(0), + m_nPageIndex(nPageIndex), + m_bLoaded(FALSE), + m_pCharWidth(nullptr) { + FXSYS_memset(&m_rtPage, 0, sizeof(CFX_RectF)); + FXSYS_memset(&m_rtPageMargin, 0, sizeof(CFX_RectF)); + FXSYS_memset(&m_rtPageContents, 0, sizeof(CFX_RectF)); + FXSYS_memset(&m_rtPageCanvas, 0, sizeof(CFX_RectF)); + m_pEditEngine = (CFDE_TxtEdtEngine*)pEngine; +} +CFDE_TxtEdtPage::~CFDE_TxtEdtPage() { + m_PieceMassArr.RemoveAll(TRUE); + if (m_pTextSet) { + delete m_pTextSet; + m_pTextSet = NULL; + } + if (m_pCharWidth) { + delete[] m_pCharWidth; + m_pCharWidth = NULL; + } + if (m_pIter != NULL) { + m_pIter->Release(); + m_pIter = NULL; + } +} +void CFDE_TxtEdtPage::Release() { + delete this; +} +IFDE_TxtEdtEngine* CFDE_TxtEdtPage::GetEngine() const { + return (IFDE_TxtEdtEngine*)m_pEditEngine; +} +FDE_VISUALOBJTYPE CFDE_TxtEdtPage::GetType() { + return FDE_VISUALOBJ_Text; +} +FX_BOOL CFDE_TxtEdtPage::GetBBox(FDE_HVISUALOBJ hVisualObj, CFX_RectF& bbox) { + return FALSE; +} +FX_BOOL CFDE_TxtEdtPage::GetMatrix(FDE_HVISUALOBJ hVisualObj, + CFX_Matrix& matrix) { + return FALSE; +} +FX_BOOL CFDE_TxtEdtPage::GetRect(FDE_HVISUALOBJ hVisualObj, CFX_RectF& rt) { + return FALSE; +} +FX_BOOL CFDE_TxtEdtPage::GetClip(FDE_HVISUALOBJ hVisualObj, CFX_RectF& rt) { + return FALSE; +} +int32_t CFDE_TxtEdtPage::GetCharRect(int32_t nIndex, + CFX_RectF& rect, + FX_BOOL bBBox) const { + FXSYS_assert(m_nRefCount > 0); + FXSYS_assert(nIndex >= 0 && nIndex < m_nCharCount); + if (m_nRefCount < 1) { + return 0; + } + int32_t nCount = m_PieceMassArr.GetSize(); + for (int32_t i = 0; i < nCount; i++) { + const FDE_TEXTEDITPIECE* pPiece = m_PieceMassArr.GetPtrAt(i); + if (nIndex >= pPiece->nStart && + nIndex < (pPiece->nStart + pPiece->nCount)) { + CFX_RectFArray rectArr; + if (bBBox) { + m_pTextSet->GetCharRects_Impl((FDE_HVISUALOBJ)pPiece, rectArr, bBBox); + } else { + m_pTextSet->GetCharRects((FDE_HVISUALOBJ)pPiece, rectArr); + } + rect = rectArr[nIndex - pPiece->nStart]; + return pPiece->nBidiLevel; + } + } + FXSYS_assert(0); + return 0; +} +int32_t CFDE_TxtEdtPage::GetCharIndex(const CFX_PointF& fPoint, + FX_BOOL& bBefore) { + FX_BOOL bVertical = m_pEditEngine->GetEditParams()->dwLayoutStyles & + FDE_TEXTEDITLAYOUT_DocVertical; + CFX_PointF ptF = fPoint; + NormalizePt2Rect(ptF, m_rtPageContents, FDE_TXTEDT_TOLERANCE); + int32_t nCount = m_PieceMassArr.GetSize(); + CFX_RectF rtLine; + int32_t nBgn = 0; + int32_t nEnd = 0; + FX_BOOL bInLine = FALSE; + int32_t i = 0; + for (i = 0; i < nCount; i++) { + const FDE_TEXTEDITPIECE* pPiece = m_PieceMassArr.GetPtrAt(i); + if (!bInLine && (bVertical ? (pPiece->rtPiece.left <= ptF.x && + pPiece->rtPiece.right() > ptF.x) + : (pPiece->rtPiece.top <= ptF.y && + pPiece->rtPiece.bottom() > ptF.y))) { + nBgn = nEnd = i; + rtLine = pPiece->rtPiece; + bInLine = TRUE; + } else if (bInLine) { + if (bVertical ? (!(pPiece->rtPiece.left <= ptF.x && + pPiece->rtPiece.right() > ptF.x)) + : (pPiece->rtPiece.bottom() <= ptF.y || + pPiece->rtPiece.top > ptF.y)) { + nEnd = i - 1; + break; + } else { + rtLine.Union(pPiece->rtPiece); + } + } + } + NormalizePt2Rect(ptF, rtLine, FDE_TXTEDT_TOLERANCE); + int32_t nCaret = 0; + FDE_TEXTEDITPIECE* pPiece = NULL; + for (i = nBgn; i <= nEnd; i++) { + pPiece = m_PieceMassArr.GetPtrAt(i); + nCaret = m_nPageStart + pPiece->nStart; + if (pPiece->rtPiece.Contains(ptF)) { + CFX_RectFArray rectArr; + m_pTextSet->GetCharRects((FDE_HVISUALOBJ)pPiece, rectArr); + int32_t nRtCount = rectArr.GetSize(); + for (int32_t j = 0; j < nRtCount; j++) { + if (rectArr[j].Contains(ptF)) { + nCaret = m_nPageStart + pPiece->nStart + j; + if (nCaret >= m_pEditEngine->GetTextBufLength()) { + bBefore = TRUE; + return m_pEditEngine->GetTextBufLength(); + } + FX_WCHAR 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 (bVertical + ? (ptF.y > ((rectArr[j].top + rectArr[j].bottom()) / 2)) + : (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; +} +int32_t CFDE_TxtEdtPage::GetCharStart() const { + return m_nPageStart; +} +int32_t CFDE_TxtEdtPage::GetCharCount() const { + return m_nCharCount; +} +int32_t CFDE_TxtEdtPage::GetDisplayPos(const CFX_RectF& rtClip, + FXTEXT_CHARPOS*& pCharPos, + CFX_RectF* pBBox) const { + pCharPos = FX_Alloc(FXTEXT_CHARPOS, m_nCharCount); + int32_t nCharPosCount = 0; + FDE_HVISUALOBJ hVisualObj = NULL; + int32_t nVisualObjCount = m_PieceMassArr.GetSize(); + FXTEXT_CHARPOS* pos = pCharPos; + CFX_RectF rtObj; + for (int32_t i = 0; i < nVisualObjCount; i++) { + hVisualObj = (FDE_HVISUALOBJ)m_PieceMassArr.GetPtrAt(i); + m_pTextSet->GetRect(hVisualObj, rtObj); + if (!rtClip.IntersectWith(rtObj)) { + continue; + } + int32_t nCount = m_pTextSet->GetDisplayPos(hVisualObj, pos, FALSE); + nCharPosCount += nCount; + pos += nCount; + } + if ((nCharPosCount * 5) < (m_nCharCount << 2)) { + FXTEXT_CHARPOS* pTemp = FX_Alloc(FXTEXT_CHARPOS, nCharPosCount); + FXSYS_memcpy(pTemp, pCharPos, sizeof(FXTEXT_CHARPOS) * nCharPosCount); + FX_Free(pCharPos); + pCharPos = pTemp; + } + return nCharPosCount; +} +void CFDE_TxtEdtPage::CalcRangeRectArray(int32_t nStart, + int32_t nCount, + CFX_RectFArray& RectFArr) const { + int32_t nPieceCount = m_PieceMassArr.GetSize(); + int32_t nEnd = nStart + nCount - 1; + FX_BOOL bInRange = FALSE; + for (int32_t i = 0; i < nPieceCount; i++) { + FDE_TEXTEDITPIECE* piece = m_PieceMassArr.GetPtrAt(i); + if (!bInRange) { + if (nStart >= piece->nStart && nStart < (piece->nStart + piece->nCount)) { + int32_t nRangeEnd = piece->nCount - 1; + FX_BOOL bEnd = FALSE; + if (nEnd >= piece->nStart && nEnd < (piece->nStart + piece->nCount)) { + nRangeEnd = nEnd - piece->nStart; + bEnd = TRUE; + } + CFX_RectFArray rcArr; + m_pTextSet->GetCharRects((FDE_HVISUALOBJ)piece, rcArr); + CFX_RectF rectPiece = rcArr[nStart - piece->nStart]; + rectPiece.Union(rcArr[nRangeEnd]); + RectFArr.Add(rectPiece); + if (bEnd) { + return; + } + bInRange = TRUE; + } + } else { + if (nEnd >= piece->nStart && nEnd < (piece->nStart + piece->nCount)) { + CFX_RectFArray rcArr; + m_pTextSet->GetCharRects((FDE_HVISUALOBJ)piece, rcArr); + CFX_RectF rectPiece = rcArr[0]; + rectPiece.Union(rcArr[nEnd - piece->nStart]); + RectFArr.Add(rectPiece); + return; + } + RectFArr.Add(piece->rtPiece); + } + } +} + +int32_t CFDE_TxtEdtPage::SelectWord(const CFX_PointF& fPoint, int32_t& nCount) { + if (m_nRefCount < 0) { + return -1; + } + IFDE_TxtEdtBuf* pBuf = m_pEditEngine->GetTextBuf(); + FX_BOOL bBefore; + int32_t nIndex = GetCharIndex(fPoint, bBefore); + if (nIndex == m_pEditEngine->GetTextBufLength()) { + nIndex = m_pEditEngine->GetTextBufLength() - 1; + } + if (nIndex < 0) { + return -1; + } + IFX_WordBreak* pIter = FX_WordBreak_Create(); + pIter->Attach(new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)pBuf)); + pIter->SetAt(nIndex); + nCount = pIter->GetWordLength(); + int32_t nRet = pIter->GetWordPos(); + pIter->Release(); + return nRet; +} +FX_BOOL CFDE_TxtEdtPage::IsLoaded(const CFX_RectF* pClipBox) { + return m_bLoaded; +} +int32_t CFDE_TxtEdtPage::LoadPage(const CFX_RectF* pClipBox, + IFX_Pause* pPause) { + if (m_nRefCount > 0) { + m_nRefCount++; + return m_nRefCount; + } + IFDE_TxtEdtBuf* pBuf = m_pEditEngine->GetTextBuf(); + const FDE_TXTEDTPARAMS* pParams = m_pEditEngine->GetEditParams(); + if (m_pIter != NULL) { + m_pIter->Release(); + } + FX_WCHAR wcAlias = 0; + if (pParams->dwMode & FDE_TEXTEDITMODE_Password) { + wcAlias = m_pEditEngine->GetAliasChar(); + } + m_pIter = new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)pBuf, wcAlias); + IFX_TxtBreak* pBreak = m_pEditEngine->GetTextBreak(); + pBreak->EndBreak(FX_TXTBREAK_ParagraphBreak); + 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 = (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 = (CFDE_TxtEdtParag*)m_pEditEngine->GetParag(nEndParag); + m_pEndParag->LoadParag(); + m_pEndParag->GetLineRange(nEndLine - nEndLineInParag, nPageEnd, nTemp); + nPageEnd += (nTemp - 1); + FX_BOOL bVertial = pParams->dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical; + FX_BOOL bLineReserve = + pParams->dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve; + FX_FLOAT fLineStart = + bVertial + ? (bLineReserve ? (pParams->fPlateWidth - pParams->fLineSpace) : 0.0f) + : 0.0f; + FX_FLOAT fLineStep = + (bVertial && bLineReserve) ? (-pParams->fLineSpace) : pParams->fLineSpace; + FX_FLOAT fLinePos = fLineStart; + if (m_pTextSet == NULL) { + m_pTextSet = new CFDE_TxtEdtTextSet(this); + } + m_PieceMassArr.RemoveAll(TRUE); + FX_DWORD dwBreakStatus = FX_TXTBREAK_None; + int32_t nPieceStart = 0; + if (m_pCharWidth != NULL) { + delete[] m_pCharWidth; + } + m_pCharWidth = new int32_t[nPageEnd - nPageStart + 1]; + pBreak->EndBreak(FX_TXTBREAK_ParagraphBreak); + pBreak->ClearBreakPieces(); + m_nPageStart = nPageStart; + m_nCharCount = nPageEnd - nPageStart + 1; + FX_BOOL bReload = FALSE; + FX_FLOAT fDefCharWidth = 0; + IFX_CharIter* pIter = m_pIter->Clone(); + pIter->SetAt(nPageStart); + m_pIter->SetAt(nPageStart); + FX_BOOL bFirstPiece = TRUE; + do { + if (bReload) { + dwBreakStatus = pBreak->EndBreak(FX_TXTBREAK_ParagraphBreak); + } else { + FX_WCHAR wAppend = pIter->GetChar(); + dwBreakStatus = pBreak->AppendChar(wAppend); + } + if (pIter->GetAt() == nPageEnd && dwBreakStatus < FX_TXTBREAK_LineBreak) { + dwBreakStatus = pBreak->EndBreak(FX_TXTBREAK_ParagraphBreak); + } + if (dwBreakStatus > FX_TXTBREAK_PieceBreak) { + int32_t nPieceCount = pBreak->CountBreakPieces(); + for (int32_t j = 0; j < nPieceCount; j++) { + const CFX_TxtPiece* pPiece = pBreak->GetBreakPiece(j); + FDE_TEXTEDITPIECE TxtEdtPiece; + FXSYS_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; + } + FX_FLOAT fParaBreakWidth = 0.0f; + if (pPiece->m_dwStatus > FX_TXTBREAK_PieceBreak) { + FX_WCHAR wRtChar = pParams->wLineBreakChar; + if (TxtEdtPiece.nCount >= 2) { + FX_WCHAR wChar = pBuf->GetCharByIndex( + m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 1); + FX_WCHAR wCharPre = pBuf->GetCharByIndex( + m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 2); + if (wChar == wRtChar) { + fParaBreakWidth += fDefCharWidth; + } + if (wCharPre == wRtChar) { + fParaBreakWidth += fDefCharWidth; + } + } else if (TxtEdtPiece.nCount >= 1) { + FX_WCHAR wChar = pBuf->GetCharByIndex( + m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 1); + if (wChar == wRtChar) { + fParaBreakWidth += fDefCharWidth; + } + } + } + if (pParams->dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) { + TxtEdtPiece.rtPiece.left = fLinePos; + TxtEdtPiece.rtPiece.top = (FX_FLOAT)pPiece->m_iStartPos / 20000.0f; + TxtEdtPiece.rtPiece.width = pParams->fLineSpace; + TxtEdtPiece.rtPiece.height = + (FX_FLOAT)pPiece->m_iWidth / 20000.0f + fParaBreakWidth; + } else { + TxtEdtPiece.rtPiece.left = (FX_FLOAT)pPiece->m_iStartPos / 20000.0f; + TxtEdtPiece.rtPiece.top = fLinePos; + TxtEdtPiece.rtPiece.width = + (FX_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_PieceMassArr.Add(TxtEdtPiece); + for (int32_t k = 0; k < TxtEdtPiece.nCount; k++) { + CFX_Char* ptc = pPiece->GetCharPtr(k); + m_pCharWidth[TxtEdtPiece.nStart + k] = ptc->m_iCharWidth; + } + } + fLinePos += fLineStep; + pBreak->ClearBreakPieces(); + } + if (pIter->GetAt() == nPageEnd && dwBreakStatus == FX_TXTBREAK_LineBreak) { + bReload = TRUE; + pIter->Next(TRUE); + } + } while (pIter->Next(FALSE) && (pIter->GetAt() <= nPageEnd)); + if (m_rtPageContents.left != 0) { + FX_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->m_nLimit - nCount) / 2; + fDelta = (m_rtPageContents.width / nCount) * n; + } else { + fDelta = (pParams->fPlateWidth - m_rtPageContents.width) / 2; + } + } + } + FX_FLOAT fOffset = m_rtPageContents.left - fDelta; + int32_t nCount = m_PieceMassArr.GetSize(); + for (int32_t i = 0; i < nCount; i++) { + FDE_TEXTEDITPIECE* pPiece = m_PieceMassArr.GetPtrAt(i); + pPiece->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; + int32_t nCount = m_PieceMassArr.GetSize(); + FDE_TEXTEDITPIECE* pPiece = m_PieceMassArr.GetPtrAt(nCount - 1); + pPiece->rtPiece.height = pParams->fFontSize; + } + pIter->Release(); + m_nRefCount = 1; + m_bLoaded = TRUE; + return 0; +} +void CFDE_TxtEdtPage::UnloadPage(const CFX_RectF* pClipBox) { + FXSYS_assert(m_nRefCount > 0); + m_nRefCount--; + if (m_nRefCount == 0) { + m_PieceMassArr.RemoveAll(); + if (m_pTextSet) { + delete m_pTextSet; + m_pTextSet = NULL; + } + if (m_pCharWidth) { + delete[] m_pCharWidth; + m_pCharWidth = NULL; + } + if (m_pBgnParag) { + m_pBgnParag->UnloadParag(); + } + if (m_pEndParag) { + m_pEndParag->UnloadParag(); + } + if (m_pIter) { + m_pIter->Release(); + m_pIter = NULL; + } + m_pBgnParag = NULL; + m_pEndParag = NULL; + } +} + +const CFX_RectF& CFDE_TxtEdtPage::GetContentsBox() { + return m_rtPageContents; +} +FX_POSITION CFDE_TxtEdtPage::GetFirstPosition(FDE_HVISUALOBJ hCanvas) { + if (m_PieceMassArr.GetSize() < 1) { + return NULL; + } + return (FX_POSITION)1; +} +FDE_HVISUALOBJ CFDE_TxtEdtPage::GetNext(FDE_HVISUALOBJ hCanvas, + FX_POSITION& pos, + IFDE_VisualSet*& pVisualSet) { + if (m_pTextSet == NULL) { + pos = NULL; + return NULL; + } + int32_t nPos = (int32_t)(uintptr_t)pos; + pVisualSet = m_pTextSet; + if (nPos + 1 > m_PieceMassArr.GetSize()) { + pos = NULL; + } else { + pos = (FX_POSITION)(uintptr_t)(nPos + 1); + } + return (FDE_HVISUALOBJ)(m_PieceMassArr.GetPtrAt(nPos - 1)); +} +FDE_HVISUALOBJ CFDE_TxtEdtPage::GetParentCanvas(FDE_HVISUALOBJ hCanvas, + IFDE_VisualSet*& pVisualSet) { + return NULL; +} +FX_WCHAR CFDE_TxtEdtPage::GetChar(void* pIdentity, int32_t index) const { + int32_t nIndex = + m_nPageStart + ((FDE_TEXTEDITPIECE*)pIdentity)->nStart + index; + if (nIndex != m_pIter->GetAt()) { + m_pIter->SetAt(nIndex); + } + FX_WCHAR wChar = m_pIter->GetChar(); + m_pIter->Next(); + return wChar; +} +int32_t CFDE_TxtEdtPage::GetWidth(void* pIdentity, int32_t index) const { + int32_t nWidth = + m_pCharWidth[((FDE_TEXTEDITPIECE*)pIdentity)->nStart + index]; + return nWidth; +} +void CFDE_TxtEdtPage::NormalizePt2Rect(CFX_PointF& ptF, + const CFX_RectF& rtF, + FX_FLOAT fTolerance) const { + if (rtF.Contains(ptF.x, ptF.y)) { + 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; + } +} |