예제 #1
0
void CFDE_TxtEdtEngine::GetCaretRect(CFX_RectF& rtCaret,
                                     int32_t nPageIndex,
                                     int32_t nCaret,
                                     FX_BOOL bBefore) {
  IFDE_TxtEdtPage* pPage = m_PagePtrArray[m_nCaretPage];
  m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
  FX_BOOL bCombText = m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText;
  int32_t nIndexInpage = nCaret - pPage->GetCharStart();
  if (bBefore && bCombText && nIndexInpage > 0) {
    nIndexInpage--;
    bBefore = FALSE;
  }
  int32_t nBIDILevel = pPage->GetCharRect(nIndexInpage, rtCaret, bCombText);
  if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
    if ((!FX_IsOdd(nBIDILevel) && !bBefore) ||
        (FX_IsOdd(nBIDILevel) && bBefore)) {
      rtCaret.Offset(0, rtCaret.height - 1.0f);
    }
    if (rtCaret.height == 0 && rtCaret.top > 1.0f)
      rtCaret.top -= 1.0f;

    rtCaret.height = 1.0f;
  } else {
    if ((!FX_IsOdd(nBIDILevel) && !bBefore) ||
        (FX_IsOdd(nBIDILevel) && bBefore)) {
      rtCaret.Offset(rtCaret.width - 1.0f, 0);
    }
    if (rtCaret.width == 0 && rtCaret.left > 1.0f)
      rtCaret.left -= 1.0f;

    rtCaret.width = 1.0f;
  }
  m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
}
예제 #2
0
int32_t CFDE_TxtEdtPage::LoadPage(const CFX_RectF* pClipBox,
                                  IFX_Pause* pPause) {
    if (m_nRefCount > 0) {
        m_nRefCount++;
        return m_nRefCount;
    }
    CFDE_TxtEdtBuf* pBuf = m_pEditEngine->GetTextBuf();
    const FDE_TXTEDTPARAMS* pParams = m_pEditEngine->GetEditParams();
    FX_WCHAR wcAlias = 0;
    if (pParams->dwMode & FDE_TEXTEDITMODE_Password) {
        wcAlias = m_pEditEngine->GetAliasChar();
    }
    m_pIter.reset(
        new CFDE_TxtEdtBufIter(static_cast<CFDE_TxtEdtBuf*>(pBuf), wcAlias));
    CFX_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 =
        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);
    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)
        m_pTextSet = new CFDE_TxtEdtTextSet(this);

    m_PieceMassArr.RemoveAll(TRUE);
    uint32_t dwBreakStatus = FX_TXTBREAK_None;
    int32_t nPieceStart = 0;
    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;
    std::unique_ptr<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;
    }
    m_nRefCount = 1;
    m_bLoaded = TRUE;
    return 0;
}
예제 #3
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, kTolerance);
    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, kTolerance);
    int32_t nCaret = 0;
    FDE_TEXTEDITPIECE* pPiece = nullptr;
    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(pPiece, rectArr, FALSE);
            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;
}
예제 #4
0
FX_BOOL CFDE_TextOut::RetriecePieces(uint32_t dwBreakStatus,
                                     int32_t& iStartChar,
                                     int32_t& iPieceWidths,
                                     FX_BOOL bReload,
                                     const CFX_RectF& rect) {
  FX_BOOL bSingleLine = !!(m_dwStyles & FDE_TTOSTYLE_SingleLine);
  FX_BOOL bLineWrap = !!(m_dwStyles & FDE_TTOSTYLE_LineWrap);
  FX_BOOL bVertical = !!(m_dwStyles & FDE_TTOSTYLE_VerticalLayout);
  FX_FLOAT fLineStep =
      (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize;
  if (bVertical) {
    fLineStep = -fLineStep;
  }
  CFX_Char* pTC = nullptr;
  FX_BOOL bNeedReload = FALSE;
  FX_FLOAT fLineWidth = bVertical ? rect.Height() : rect.Width();
  int32_t iLineWidth = FXSYS_round(fLineWidth * 20000.0f);
  int32_t iCount = m_pTxtBreak->CountBreakPieces();
  for (int32_t i = 0; i < iCount; i++) {
    const CFX_TxtPiece* pPiece = m_pTxtBreak->GetBreakPiece(i);
    int32_t iPieceChars = pPiece->GetLength();
    int32_t iChar = iStartChar;
    int32_t iWidth = 0;
    int32_t j = 0;
    for (; j < iPieceChars; j++) {
      pTC = pPiece->GetCharPtr(j);
      int32_t iCurCharWidth = pTC->m_iCharWidth > 0 ? pTC->m_iCharWidth : 0;
      if (bSingleLine || !bLineWrap) {
        if (iLineWidth - iPieceWidths - iWidth < iCurCharWidth) {
          bNeedReload = TRUE;
          break;
        }
      }
      iWidth += iCurCharWidth;
      m_CharWidths[iChar++] = iCurCharWidth;
    }
    if (j == 0 && !bReload) {
      CFDE_TTOLine* pLine = m_ttoLines.GetPtrAt(m_iCurLine);
      pLine->m_bNewReload = TRUE;
    } else if (j > 0) {
      CFX_RectF rtPiece;
      if (bVertical) {
        rtPiece.left = m_fLinePos;
        rtPiece.top = rect.top + (FX_FLOAT)pPiece->m_iStartPos / 20000.0f;
        rtPiece.width = fLineStep;
        rtPiece.height = iWidth / 20000.0f;
      } else {
        rtPiece.left = rect.left + (FX_FLOAT)pPiece->m_iStartPos / 20000.0f;
        rtPiece.top = m_fLinePos;
        rtPiece.width = iWidth / 20000.0f;
        rtPiece.height = fLineStep;
      }
      FDE_TTOPIECE ttoPiece;
      ttoPiece.iStartChar = iStartChar;
      ttoPiece.iChars = j;
      ttoPiece.rtPiece = rtPiece;
      ttoPiece.dwCharStyles = pPiece->m_dwCharStyles;
      if (FX_IsOdd(pPiece->m_iBidiLevel)) {
        ttoPiece.dwCharStyles |= FX_TXTCHARSTYLE_OddBidiLevel;
      }
      AppendPiece(ttoPiece, bNeedReload, (bReload && i == iCount - 1));
    }
    iStartChar += iPieceChars;
    iPieceWidths += iWidth;
  }
  m_pTxtBreak->ClearBreakPieces();
  FX_BOOL bRet = bSingleLine || bLineWrap || (!bLineWrap && bNeedReload) ||
                 dwBreakStatus == FX_TXTBREAK_ParagraphBreak;
  return bRet;
}