From bccf573b72c76597f6b1f1e99e8db4e1cc759843 Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Thu, 30 Mar 2017 14:10:32 -0400 Subject: Rename tto/fde_textout to cfde_textout This CL renames the textout file to cfde_textout to match the classname and moves up one directory to xfa/fde. Change-Id: I0b405961b8406818a2eb3cbb30f87620afa6ab7a Reviewed-on: https://pdfium-review.googlesource.com/3373 Reviewed-by: Tom Sepez Commit-Queue: dsinclair --- BUILD.gn | 4 +- xfa/fde/cfde_textout.cpp | 790 +++++++++++++++++++++++++++++++++ xfa/fde/cfde_textout.h | 175 ++++++++ xfa/fde/cfde_txtedtengine.cpp | 2 +- xfa/fde/tto/fde_textout.cpp | 790 --------------------------------- xfa/fde/tto/fde_textout.h | 175 -------- xfa/fwl/cfwl_checkbox.cpp | 2 +- xfa/fwl/cfwl_combobox.cpp | 2 +- xfa/fwl/cfwl_form.cpp | 2 +- xfa/fwl/cfwl_listbox.cpp | 2 +- xfa/fwl/cfwl_monthcalendar.cpp | 2 +- xfa/fwl/cfwl_pushbutton.cpp | 2 +- xfa/fwl/cfwl_widget.cpp | 2 +- xfa/fwl/theme/cfwl_checkboxtp.cpp | 2 +- xfa/fwl/theme/cfwl_monthcalendartp.cpp | 2 +- xfa/fwl/theme/cfwl_widgettp.cpp | 2 +- xfa/fxfa/app/xfa_ffwidgetacc.cpp | 2 +- xfa/fxfa/app/xfa_fwltheme.cpp | 2 +- xfa/fxfa/cxfa_widgetacc.cpp | 2 +- 19 files changed, 981 insertions(+), 981 deletions(-) create mode 100644 xfa/fde/cfde_textout.cpp create mode 100644 xfa/fde/cfde_textout.h delete mode 100644 xfa/fde/tto/fde_textout.cpp delete mode 100644 xfa/fde/tto/fde_textout.h diff --git a/BUILD.gn b/BUILD.gn index 6018890fa4..f695be9b70 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1318,6 +1318,8 @@ if (pdf_enable_xfa) { "xfa/fde/cfde_rendercontext.cpp", "xfa/fde/cfde_rendercontext.h", "xfa/fde/cfde_renderdevice.cpp", + "xfa/fde/cfde_textout.cpp", + "xfa/fde/cfde_textout.h", "xfa/fde/cfde_txtedtbuf.cpp", "xfa/fde/cfde_txtedtbuf.h", "xfa/fde/cfde_txtedtdorecord_deleterange.cpp", @@ -1376,8 +1378,6 @@ if (pdf_enable_xfa) { "xfa/fde/ifde_txtedtdorecord.h", "xfa/fde/ifde_txtedtengine.h", "xfa/fde/ifde_txtedtpage.h", - "xfa/fde/tto/fde_textout.cpp", - "xfa/fde/tto/fde_textout.h", "xfa/fde/xml/fde_xml.h", "xfa/fde/xml/fde_xml_imp.cpp", "xfa/fde/xml/fde_xml_imp.h", diff --git a/xfa/fde/cfde_textout.cpp b/xfa/fde/cfde_textout.cpp new file mode 100644 index 0000000000..b85bfef3f6 --- /dev/null +++ b/xfa/fde/cfde_textout.cpp @@ -0,0 +1,790 @@ +// 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_textout.h" + +#include + +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxcrt/fx_system.h" +#include "third_party/base/ptr_util.h" +#include "third_party/base/stl_util.h" +#include "xfa/fde/cfde_brush.h" +#include "xfa/fde/cfde_path.h" +#include "xfa/fde/cfde_pen.h" +#include "xfa/fde/cfde_renderdevice.h" +#include "xfa/fgas/layout/fgas_textbreak.h" + +FDE_TTOPIECE::FDE_TTOPIECE() = default; + +FDE_TTOPIECE::FDE_TTOPIECE(const FDE_TTOPIECE& that) = default; + +FDE_TTOPIECE::~FDE_TTOPIECE() = default; + +CFDE_TextOut::CFDE_TextOut() + : m_pTxtBreak(pdfium::MakeUnique()), + m_pFont(nullptr), + m_fFontSize(12.0f), + m_fLineSpace(m_fFontSize), + m_fLinePos(0.0f), + m_fTolerance(0.0f), + m_iAlignment(0), + m_iTxtBkAlignment(0), + m_wParagraphBkChar(L'\n'), + m_TxtColor(0xFF000000), + m_dwStyles(0), + m_dwTxtBkStyles(0), + m_bElliChanged(false), + m_iEllipsisWidth(0), + m_ttoLines(5), + m_iCurLine(0), + m_iCurPiece(0), + m_iTotalLines(0) { + m_Matrix.SetIdentity(); + m_rtClip.Reset(); + m_rtLogicClip.Reset(); +} + +CFDE_TextOut::~CFDE_TextOut() {} + +void CFDE_TextOut::SetFont(const CFX_RetainPtr& pFont) { + ASSERT(pFont); + m_pFont = pFont; + m_pTxtBreak->SetFont(pFont); +} + +void CFDE_TextOut::SetFontSize(float fFontSize) { + ASSERT(fFontSize > 0); + m_fFontSize = fFontSize; + m_pTxtBreak->SetFontSize(fFontSize); +} + +void CFDE_TextOut::SetTextColor(FX_ARGB color) { + m_TxtColor = color; +} + +void CFDE_TextOut::SetStyles(uint32_t dwStyles) { + m_dwStyles = dwStyles; + m_dwTxtBkStyles = 0; + if (dwStyles & FDE_TTOSTYLE_SingleLine) + m_dwTxtBkStyles |= FX_LAYOUTSTYLE_SingleLine; + + m_pTxtBreak->SetLayoutStyles(m_dwTxtBkStyles); +} + +void CFDE_TextOut::SetTabWidth(float fTabWidth) { + ASSERT(fTabWidth > 1.0f); + m_pTxtBreak->SetTabWidth(fTabWidth); +} + +void CFDE_TextOut::SetEllipsisString(const CFX_WideString& wsEllipsis) { + m_bElliChanged = true; + m_wsEllipsis = wsEllipsis; +} + +void CFDE_TextOut::SetParagraphBreakChar(wchar_t wch) { + m_wParagraphBkChar = wch; + m_pTxtBreak->SetParagraphBreakChar(wch); +} + +void CFDE_TextOut::SetAlignment(int32_t iAlignment) { + m_iAlignment = iAlignment; + switch (m_iAlignment) { + case FDE_TTOALIGNMENT_TopCenter: + case FDE_TTOALIGNMENT_Center: + case FDE_TTOALIGNMENT_BottomCenter: + m_iTxtBkAlignment = CFX_TxtLineAlignment_Center; + break; + case FDE_TTOALIGNMENT_TopRight: + case FDE_TTOALIGNMENT_CenterRight: + case FDE_TTOALIGNMENT_BottomRight: + m_iTxtBkAlignment = CFX_TxtLineAlignment_Right; + break; + default: + m_iTxtBkAlignment = CFX_TxtLineAlignment_Left; + break; + } + m_pTxtBreak->SetAlignment(m_iTxtBkAlignment); +} + +void CFDE_TextOut::SetLineSpace(float fLineSpace) { + ASSERT(fLineSpace > 1.0f); + m_fLineSpace = fLineSpace; +} + +void CFDE_TextOut::SetDIBitmap(const CFX_RetainPtr& pDIB) { + ASSERT(pDIB); + + m_pRenderDevice.reset(); + CFX_FxgeDevice* device = new CFX_FxgeDevice; + device->Attach(pDIB, false, nullptr, false); + m_pRenderDevice = pdfium::MakeUnique(device, false); +} + +void CFDE_TextOut::SetRenderDevice(CFX_RenderDevice* pDevice) { + ASSERT(pDevice); + m_pRenderDevice = pdfium::MakeUnique(pDevice, false); +} + +void CFDE_TextOut::SetClipRect(const CFX_Rect& rtClip) { + m_rtClip = rtClip.As(); +} + +void CFDE_TextOut::SetClipRect(const CFX_RectF& rtClip) { + m_rtClip = rtClip; +} + +void CFDE_TextOut::SetLogicClipRect(const CFX_RectF& rtClip) { + m_rtLogicClip = rtClip; +} + +void CFDE_TextOut::SetMatrix(const CFX_Matrix& matrix) { + m_Matrix = matrix; +} + +void CFDE_TextOut::SetLineBreakTolerance(float fTolerance) { + m_fTolerance = fTolerance; + m_pTxtBreak->SetLineBreakTolerance(m_fTolerance); +} + +int32_t CFDE_TextOut::GetTotalLines() { + return m_iTotalLines; +} + +void CFDE_TextOut::CalcLogicSize(const wchar_t* pwsStr, + int32_t iLength, + CFX_SizeF& size) { + CFX_RectF rtText(0.0f, 0.0f, size.width, size.height); + CalcLogicSize(pwsStr, iLength, rtText); + size = rtText.Size(); +} + +void CFDE_TextOut::CalcLogicSize(const wchar_t* pwsStr, + int32_t iLength, + CFX_RectF& rect) { + if (!pwsStr || iLength < 1) { + rect.width = 0.0f; + rect.height = 0.0f; + } else { + CalcTextSize(pwsStr, iLength, rect); + } +} + +void CFDE_TextOut::CalcTextSize(const wchar_t* pwsStr, + int32_t iLength, + CFX_RectF& rect) { + ASSERT(m_pFont && m_fFontSize >= 1.0f); + SetLineWidth(rect); + m_iTotalLines = 0; + const wchar_t* pStr = pwsStr; + bool bHotKey = !!(m_dwStyles & FDE_TTOSTYLE_HotKey); + float fWidth = 0.0f; + float fHeight = 0.0f; + float fStartPos = rect.right(); + CFX_BreakType dwBreakStatus = CFX_BreakType::None; + wchar_t wPreChar = 0; + wchar_t wch; + wchar_t wBreak = 0; + while (iLength-- > 0) { + wch = *pStr++; + if (wBreak == 0 && (wch == L'\n' || wch == L'\r')) { + wBreak = wch; + m_pTxtBreak->SetParagraphBreakChar(wch); + } + if (bHotKey && wch == L'&' && wPreChar != L'&') { + wPreChar = wch; + continue; + } + dwBreakStatus = m_pTxtBreak->AppendChar(wch); + if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) + RetrieveLineWidth(dwBreakStatus, fStartPos, fWidth, fHeight); + + wPreChar = 0; + } + dwBreakStatus = m_pTxtBreak->EndBreak(CFX_BreakType::Paragraph); + if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) + RetrieveLineWidth(dwBreakStatus, fStartPos, fWidth, fHeight); + + m_pTxtBreak->Reset(); + float fInc = rect.Height() - fHeight; + if (m_iAlignment >= FDE_TTOALIGNMENT_CenterLeft && + m_iAlignment < FDE_TTOALIGNMENT_BottomLeft) { + fInc /= 2.0f; + } else if (m_iAlignment < FDE_TTOALIGNMENT_CenterLeft) { + fInc = 0.0f; + } + rect.left += fStartPos; + rect.top += fInc; + rect.width = std::min(fWidth, rect.Width()); + rect.height = fHeight; + if (m_dwStyles & FDE_TTOSTYLE_LastLineHeight) + rect.height -= m_fLineSpace - m_fFontSize; +} + +void CFDE_TextOut::SetLineWidth(CFX_RectF& rect) { + if ((m_dwStyles & FDE_TTOSTYLE_SingleLine) == 0) { + float fLineWidth = 0.0f; + if (rect.Width() < 1.0f) + rect.width = m_fFontSize * 1000.0f; + + fLineWidth = rect.Width(); + m_pTxtBreak->SetLineWidth(fLineWidth); + } +} + +bool CFDE_TextOut::RetrieveLineWidth(CFX_BreakType dwBreakStatus, + float& fStartPos, + float& fWidth, + float& fHeight) { + if (CFX_BreakTypeNoneOrPiece(dwBreakStatus)) + return false; + + float fLineStep = (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize; + bool bLineWrap = !!(m_dwStyles & FDE_TTOSTYLE_LineWrap); + float fLineWidth = 0.0f; + int32_t iCount = m_pTxtBreak->CountBreakPieces(); + for (int32_t i = 0; i < iCount; i++) { + const CFX_BreakPiece* pPiece = m_pTxtBreak->GetBreakPieceUnstable(i); + fLineWidth += static_cast(pPiece->m_iWidth) / 20000.0f; + fStartPos = + std::min(fStartPos, static_cast(pPiece->m_iStartPos) / 20000.0f); + } + m_pTxtBreak->ClearBreakPieces(); + if (dwBreakStatus == CFX_BreakType::Paragraph) { + m_pTxtBreak->Reset(); + } + if (!bLineWrap && dwBreakStatus == CFX_BreakType::Line) { + fWidth += fLineWidth; + } else { + fWidth = std::max(fWidth, fLineWidth); + fHeight += fLineStep; + } + m_iTotalLines++; + return true; +} + +void CFDE_TextOut::DrawText(const wchar_t* pwsStr, + int32_t iLength, + int32_t x, + int32_t y) { + CFX_RectF rtText(static_cast(x), static_cast(y), + m_fFontSize * 1000.0f, m_fFontSize * 1000.0f); + DrawText(pwsStr, iLength, rtText); +} + +void CFDE_TextOut::DrawText(const wchar_t* pwsStr, + int32_t iLength, + float x, + float y) { + DrawText(pwsStr, iLength, + CFX_RectF(x, y, m_fFontSize * 1000.0f, m_fFontSize * 1000.0f)); +} + +void CFDE_TextOut::DrawText(const wchar_t* pwsStr, + int32_t iLength, + const CFX_Rect& rect) { + DrawText(pwsStr, iLength, rect.As()); +} + +void CFDE_TextOut::DrawText(const wchar_t* pwsStr, + int32_t iLength, + const CFX_RectF& rect) { + CFX_RectF rtText(rect.left, rect.top, rect.width, rect.height); + CFX_Matrix rm; + rm.SetReverse(m_Matrix); + rm.TransformRect(rtText); + DrawText(pwsStr, iLength, rtText, m_rtClip); +} + +void CFDE_TextOut::DrawLogicText(const wchar_t* pwsStr, + int32_t iLength, + float x, + float y) { + CFX_RectF rtText(x, y, m_fFontSize * 1000.0f, m_fFontSize * 1000.0f); + DrawLogicText(pwsStr, iLength, rtText); +} + +void CFDE_TextOut::DrawLogicText(const wchar_t* pwsStr, + int32_t iLength, + const CFX_RectF& rect) { + CFX_RectF rtClip(m_rtLogicClip.left, m_rtLogicClip.top, m_rtLogicClip.width, + m_rtLogicClip.height); + m_Matrix.TransformRect(rtClip); + DrawText(pwsStr, iLength, rect, rtClip); +} + +void CFDE_TextOut::DrawText(const wchar_t* pwsStr, + int32_t iLength, + const CFX_RectF& rect, + const CFX_RectF& rtClip) { + ASSERT(m_pFont && m_fFontSize >= 1.0f); + if (!pwsStr || iLength < 1) + return; + if (rect.width < m_fFontSize || rect.height < m_fFontSize) + return; + + float fLineWidth = rect.width; + m_pTxtBreak->SetLineWidth(fLineWidth); + m_ttoLines.clear(); + m_wsText.clear(); + LoadText(pwsStr, iLength, rect); + if (m_dwStyles & FDE_TTOSTYLE_Ellipsis) { + ReplaceWidthEllipsis(); + } + Reload(rect); + DoAlignment(rect); + OnDraw(rtClip); +} + +void CFDE_TextOut::ExpandBuffer(int32_t iSize, int32_t iType) { + ASSERT(iSize >= 0); + size_t size = iSize; + switch (iType) { + case 0: + if (m_CharWidths.size() < size) + m_CharWidths.resize(size, 0); + break; + case 1: + if (m_EllCharWidths.size() < size) + m_EllCharWidths.resize(size, 0); + break; + case 2: + if (m_CharPos.size() < size) + m_CharPos.resize(size, FXTEXT_CHARPOS()); + break; + } +} + +void CFDE_TextOut::LoadEllipsis() { + if (!m_bElliChanged) { + return; + } + m_bElliChanged = false; + m_iEllipsisWidth = 0; + int32_t iLength = m_wsEllipsis.GetLength(); + if (iLength < 1) { + return; + } + ExpandBuffer(iLength, 1); + const wchar_t* pStr = m_wsEllipsis.c_str(); + CFX_BreakType dwBreakStatus; + wchar_t wch; + while (iLength-- > 0) { + wch = *pStr++; + dwBreakStatus = m_pTxtBreak->AppendChar(wch); + if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) + RetrieveEllPieces(&m_EllCharWidths); + } + dwBreakStatus = m_pTxtBreak->EndBreak(CFX_BreakType::Paragraph); + if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) + RetrieveEllPieces(&m_EllCharWidths); + + m_pTxtBreak->Reset(); +} + +void CFDE_TextOut::RetrieveEllPieces(std::vector* pCharWidths) { + int32_t iCount = m_pTxtBreak->CountBreakPieces(); + int32_t iCharIndex = 0; + for (int32_t i = 0; i < iCount; i++) { + const CFX_BreakPiece* pPiece = m_pTxtBreak->GetBreakPieceUnstable(i); + int32_t iPieceChars = pPiece->GetLength(); + for (int32_t j = 0; j < iPieceChars; j++) { + (*pCharWidths)[iCharIndex] = + std::max(pPiece->GetChar(j)->m_iCharWidth, 0); + m_iEllipsisWidth += (*pCharWidths)[iCharIndex]; + iCharIndex++; + } + } + m_pTxtBreak->ClearBreakPieces(); +} + +void CFDE_TextOut::LoadText(const wchar_t* pwsStr, + int32_t iLength, + const CFX_RectF& rect) { + wchar_t* pStr = m_wsText.GetBuffer(iLength); + int32_t iTxtLength = iLength; + ExpandBuffer(iTxtLength, 0); + bool bHotKey = !!(m_dwStyles & FDE_TTOSTYLE_HotKey); + bool bLineWrap = !!(m_dwStyles & FDE_TTOSTYLE_LineWrap); + float fLineStep = (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize; + float fLineStop = rect.bottom(); + m_fLinePos = rect.top; + m_HotKeys.clear(); + int32_t iStartChar = 0; + int32_t iChars = 0; + int32_t iPieceWidths = 0; + CFX_BreakType dwBreakStatus; + wchar_t wch; + bool bRet = false; + while (iTxtLength-- > 0) { + wch = *pwsStr++; + if (bHotKey && wch == L'&' && *(pStr - 1) != L'&') { + if (iTxtLength > 0) + m_HotKeys.push_back(iChars); + continue; + } + *pStr++ = wch; + iChars++; + dwBreakStatus = m_pTxtBreak->AppendChar(wch); + if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) { + bool bEndofLine = + RetrievePieces(dwBreakStatus, iStartChar, iPieceWidths, false, rect); + if (bEndofLine && + (bLineWrap || dwBreakStatus == CFX_BreakType::Paragraph || + dwBreakStatus == CFX_BreakType::Page)) { + iPieceWidths = 0; + m_iCurLine++; + m_fLinePos += fLineStep; + } + if (m_fLinePos + fLineStep > fLineStop) { + int32_t iCurLine = bEndofLine ? m_iCurLine - 1 : m_iCurLine; + m_ttoLines[iCurLine].SetNewReload(true); + bRet = true; + break; + } + } + } + dwBreakStatus = m_pTxtBreak->EndBreak(CFX_BreakType::Paragraph); + if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus) && !bRet) + RetrievePieces(dwBreakStatus, iStartChar, iPieceWidths, false, rect); + + m_pTxtBreak->ClearBreakPieces(); + m_pTxtBreak->Reset(); + m_wsText.ReleaseBuffer(iLength); +} + +bool CFDE_TextOut::RetrievePieces(CFX_BreakType dwBreakStatus, + int32_t& iStartChar, + int32_t& iPieceWidths, + bool bReload, + const CFX_RectF& rect) { + bool bSingleLine = !!(m_dwStyles & FDE_TTOSTYLE_SingleLine); + bool bLineWrap = !!(m_dwStyles & FDE_TTOSTYLE_LineWrap); + float fLineStep = (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize; + bool bNeedReload = false; + float fLineWidth = 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_BreakPiece* pPiece = m_pTxtBreak->GetBreakPieceUnstable(i); + int32_t iPieceChars = pPiece->GetLength(); + int32_t iChar = iStartChar; + int32_t iWidth = 0; + int32_t j = 0; + for (; j < iPieceChars; j++) { + const CFX_Char* pTC = pPiece->GetChar(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) { + m_ttoLines[m_iCurLine].SetNewReload(true); + } else if (j > 0) { + CFX_RectF rtPiece; + rtPiece.left = rect.left + (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(); + return bSingleLine || bLineWrap || bNeedReload || + dwBreakStatus == CFX_BreakType::Paragraph; +} + +void CFDE_TextOut::AppendPiece(const FDE_TTOPIECE& ttoPiece, + bool bNeedReload, + bool bEnd) { + if (m_iCurLine >= pdfium::CollectionSize(m_ttoLines)) { + CFDE_TTOLine ttoLine; + ttoLine.SetNewReload(bNeedReload); + m_iCurPiece = ttoLine.AddPiece(m_iCurPiece, ttoPiece); + m_ttoLines.push_back(ttoLine); + m_iCurLine = pdfium::CollectionSize(m_ttoLines) - 1; + } else { + CFDE_TTOLine* pLine = &m_ttoLines[m_iCurLine]; + pLine->SetNewReload(bNeedReload); + m_iCurPiece = pLine->AddPiece(m_iCurPiece, ttoPiece); + if (bEnd) { + int32_t iPieces = pLine->GetSize(); + if (m_iCurPiece < iPieces) { + pLine->RemoveLast(iPieces - m_iCurPiece - 1); + } + } + } + if (!bEnd && bNeedReload) + m_iCurPiece = 0; +} + +void CFDE_TextOut::ReplaceWidthEllipsis() { + LoadEllipsis(); + int32_t iLength = m_wsEllipsis.GetLength(); + if (iLength < 1) + return; + + for (auto& line : m_ttoLines) { + if (!line.GetNewReload()) + continue; + + int32_t iEllipsisCharIndex = iLength - 1; + int32_t iCharWidth = 0; + int32_t iCharCount = 0; + int32_t iPiece = line.GetSize(); + while (iPiece-- > 0) { + FDE_TTOPIECE* pPiece = line.GetPtrAt(iPiece); + if (!pPiece) + break; + + for (int32_t j = pPiece->iChars - 1; j >= 0; j--) { + if (iEllipsisCharIndex < 0) + break; + + int32_t index = pPiece->iStartChar + j; + iCharWidth += m_CharWidths[index]; + iCharCount++; + if (iCharCount <= iLength) { + m_wsText.SetAt(index, m_wsEllipsis.GetAt(iEllipsisCharIndex)); + m_CharWidths[index] = m_EllCharWidths[iEllipsisCharIndex]; + } else if (iCharWidth <= m_iEllipsisWidth) { + m_wsText.SetAt(index, 0); + m_CharWidths[index] = 0; + } + iEllipsisCharIndex--; + } + if (iEllipsisCharIndex < 0) + break; + } + } +} + +void CFDE_TextOut::Reload(const CFX_RectF& rect) { + int i = 0; + for (auto& line : m_ttoLines) { + if (line.GetNewReload()) { + m_iCurLine = i; + m_iCurPiece = 0; + ReloadLinePiece(&line, rect); + } + ++i; + } +} + +void CFDE_TextOut::ReloadLinePiece(CFDE_TTOLine* pLine, const CFX_RectF& rect) { + const wchar_t* pwsStr = m_wsText.c_str(); + int32_t iPieceWidths = 0; + FDE_TTOPIECE* pPiece = pLine->GetPtrAt(0); + int32_t iStartChar = pPiece->iStartChar; + m_fLinePos = pPiece->rtPiece.top; + int32_t iPieceCount = pLine->GetSize(); + int32_t iPieceIndex = 0; + CFX_BreakType dwBreakStatus = CFX_BreakType::None; + wchar_t wch; + while (iPieceIndex < iPieceCount) { + int32_t iStar = iStartChar; + int32_t iEnd = pPiece->iChars + iStar; + while (iStar < iEnd) { + wch = *(pwsStr + iStar); + dwBreakStatus = m_pTxtBreak->AppendChar(wch); + if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) + RetrievePieces(dwBreakStatus, iStartChar, iPieceWidths, true, rect); + iStar++; + } + iPieceIndex++; + pPiece = pLine->GetPtrAt(iPieceIndex); + } + dwBreakStatus = m_pTxtBreak->EndBreak(CFX_BreakType::Paragraph); + if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) + RetrievePieces(dwBreakStatus, iStartChar, iPieceWidths, true, rect); + + m_pTxtBreak->Reset(); +} + +void CFDE_TextOut::DoAlignment(const CFX_RectF& rect) { + if (m_ttoLines.empty()) + return; + + float fLineStopS = rect.bottom(); + FDE_TTOPIECE* pFirstPiece = m_ttoLines.back().GetPtrAt(0); + if (!pFirstPiece) + return; + + float fLineStopD = pFirstPiece->rtPiece.bottom(); + float fInc = fLineStopS - fLineStopD; + if (m_iAlignment >= FDE_TTOALIGNMENT_CenterLeft && + m_iAlignment < FDE_TTOALIGNMENT_BottomLeft) { + fInc /= 2.0f; + } else if (m_iAlignment < FDE_TTOALIGNMENT_CenterLeft) { + fInc = 0.0f; + } + if (fInc < 1.0f) + return; + for (auto& line : m_ttoLines) { + int32_t iPieces = line.GetSize(); + for (int32_t j = 0; j < iPieces; j++) { + FDE_TTOPIECE* pPiece = line.GetPtrAt(j); + pPiece->rtPiece.top += fInc; + } + } +} + +void CFDE_TextOut::OnDraw(const CFX_RectF& rtClip) { + if (!m_pRenderDevice || m_ttoLines.empty()) + return; + + auto pBrush = pdfium::MakeUnique(); + pBrush->SetColor(m_TxtColor); + m_pRenderDevice->SaveState(); + if (rtClip.Width() > 0.0f && rtClip.Height() > 0.0f) + m_pRenderDevice->SetClipRect(rtClip); + + auto pPen = pdfium::MakeUnique(); + pPen->SetColor(m_TxtColor); + + for (auto& line : m_ttoLines) { + int32_t iPieces = line.GetSize(); + for (int32_t j = 0; j < iPieces; j++) { + FDE_TTOPIECE* pPiece = line.GetPtrAt(j); + if (!pPiece) + continue; + + int32_t iCount = GetDisplayPos(pPiece); + if (iCount > 0) { + m_pRenderDevice->DrawString(pBrush.get(), m_pFont, m_CharPos.data(), + iCount, m_fFontSize, &m_Matrix); + } + DrawLine(pPiece, pPen.get()); + } + } + m_pRenderDevice->RestoreState(); +} + +int32_t CFDE_TextOut::GetDisplayPos(FDE_TTOPIECE* pPiece) { + FX_TXTRUN tr = ToTextRun(pPiece); + ExpandBuffer(tr.iLength, 2); + return m_pTxtBreak->GetDisplayPos(&tr, m_CharPos.data()); +} + +int32_t CFDE_TextOut::GetCharRects(const FDE_TTOPIECE* pPiece) { + FX_TXTRUN tr = ToTextRun(pPiece); + m_rectArray = m_pTxtBreak->GetCharRects(&tr); + return pdfium::CollectionSize(m_rectArray); +} + +FX_TXTRUN CFDE_TextOut::ToTextRun(const FDE_TTOPIECE* pPiece) { + FX_TXTRUN tr; + tr.wsStr = m_wsText + pPiece->iStartChar; + tr.pWidths = &m_CharWidths[pPiece->iStartChar]; + tr.iLength = pPiece->iChars; + tr.pFont = m_pFont; + tr.fFontSize = m_fFontSize; + tr.dwStyles = m_dwTxtBkStyles; + tr.dwCharStyles = pPiece->dwCharStyles; + tr.wLineBreakChar = m_wParagraphBkChar; + tr.pRect = &pPiece->rtPiece; + return tr; +} + +void CFDE_TextOut::DrawLine(const FDE_TTOPIECE* pPiece, CFDE_Pen* pPen) { + bool bUnderLine = !!(m_dwStyles & FDE_TTOSTYLE_Underline); + bool bStrikeOut = !!(m_dwStyles & FDE_TTOSTYLE_Strikeout); + bool bHotKey = !!(m_dwStyles & FDE_TTOSTYLE_HotKey); + if (!bUnderLine && !bStrikeOut && !bHotKey) + return; + + auto pPath = pdfium::MakeUnique(); + int32_t iLineCount = 0; + CFX_RectF rtText = pPiece->rtPiece; + CFX_PointF pt1, pt2; + if (bUnderLine) { + pt1.x = rtText.left; + pt1.y = rtText.bottom(); + pt2.x = rtText.right(); + pt2.y = rtText.bottom(); + pPath->AddLine(pt1, pt2); + iLineCount++; + } + if (bStrikeOut) { + pt1.x = rtText.left; + pt1.y = rtText.bottom() - rtText.height * 2.0f / 5.0f; + pt2.x = rtText.right(); + pt2.y = pt1.y; + pPath->AddLine(pt1, pt2); + iLineCount++; + } + if (bHotKey) { + if (GetCharRects(pPiece) > 0) { + for (int32_t iCharIndex : m_HotKeys) { + if (iCharIndex >= pPiece->iStartChar && + iCharIndex < pPiece->iStartChar + pPiece->iChars) { + CFX_RectF rect = m_rectArray[iCharIndex - pPiece->iStartChar]; + pt1.x = rect.left; + pt1.y = rect.bottom(); + pt2.x = rect.right(); + pt2.y = rect.bottom(); + pPath->AddLine(pt1, pt2); + iLineCount++; + } + } + } + } + if (iLineCount > 0) + m_pRenderDevice->DrawPath(pPen, 1, pPath.get(), &m_Matrix); +} + +CFDE_TTOLine::CFDE_TTOLine() : m_bNewReload(false) {} + +CFDE_TTOLine::CFDE_TTOLine(const CFDE_TTOLine& ttoLine) : m_pieces(5) { + m_bNewReload = ttoLine.m_bNewReload; + m_pieces = ttoLine.m_pieces; +} + +CFDE_TTOLine::~CFDE_TTOLine() {} + +int32_t CFDE_TTOLine::AddPiece(int32_t index, const FDE_TTOPIECE& ttoPiece) { + if (index >= pdfium::CollectionSize(m_pieces)) { + m_pieces.push_back(ttoPiece); + return pdfium::CollectionSize(m_pieces); + } + m_pieces[index] = ttoPiece; + return index; +} + +int32_t CFDE_TTOLine::GetSize() const { + return pdfium::CollectionSize(m_pieces); +} + +FDE_TTOPIECE* CFDE_TTOLine::GetPtrAt(int32_t index) { + return pdfium::IndexInBounds(m_pieces, index) ? &m_pieces[index] : nullptr; +} + +void CFDE_TTOLine::RemoveLast(int32_t icount) { + if (icount < 0) + return; + icount = std::min(icount, pdfium::CollectionSize(m_pieces)); + m_pieces.erase(m_pieces.end() - icount, m_pieces.end()); +} + +void CFDE_TTOLine::RemoveAll() { + m_pieces.clear(); +} diff --git a/xfa/fde/cfde_textout.h b/xfa/fde/cfde_textout.h new file mode 100644 index 0000000000..c505c0737f --- /dev/null +++ b/xfa/fde/cfde_textout.h @@ -0,0 +1,175 @@ +// 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 + +#ifndef XFA_FDE_CFDE_TEXTOUT_H_ +#define XFA_FDE_CFDE_TEXTOUT_H_ + +#include +#include +#include + +#include "core/fxcrt/cfx_char.h" +#include "core/fxge/cfx_fxgedevice.h" +#include "core/fxge/cfx_renderdevice.h" +#include "core/fxge/fx_dib.h" +#include "xfa/fgas/font/cfgas_fontmgr.h" + +#define FDE_TTOSTYLE_Underline 0x0001 +#define FDE_TTOSTYLE_Strikeout 0x0002 +#define FDE_TTOSTYLE_SingleLine 0x0010 +#define FDE_TTOSTYLE_HotKey 0x0040 +#define FDE_TTOSTYLE_Ellipsis 0x0080 +#define FDE_TTOSTYLE_LineWrap 0x0100 +#define FDE_TTOSTYLE_LastLineHeight 0x1000 +#define FDE_TTOALIGNMENT_TopLeft 0 +#define FDE_TTOALIGNMENT_TopCenter 1 +#define FDE_TTOALIGNMENT_TopRight 2 +#define FDE_TTOALIGNMENT_TopAuto 3 +#define FDE_TTOALIGNMENT_CenterLeft 4 +#define FDE_TTOALIGNMENT_Center 5 +#define FDE_TTOALIGNMENT_CenterRight 6 +#define FDE_TTOALIGNMENT_CenterAuto 7 +#define FDE_TTOALIGNMENT_BottomLeft 8 +#define FDE_TTOALIGNMENT_BottomCenter 9 +#define FDE_TTOALIGNMENT_BottomRight 10 +#define FDE_TTOALIGNMENT_BottomAuto 11 + +class CFDE_Pen; +class CFDE_RenderDevice; +class CFX_RenderDevice; +class CFX_TxtBreak; +struct FX_TXTRUN; + +struct FDE_TTOPIECE { + FDE_TTOPIECE(); + FDE_TTOPIECE(const FDE_TTOPIECE& that); + ~FDE_TTOPIECE(); + + int32_t iStartChar; + int32_t iChars; + uint32_t dwCharStyles; + CFX_RectF rtPiece; +}; + +class CFDE_TTOLine { + public: + CFDE_TTOLine(); + CFDE_TTOLine(const CFDE_TTOLine& ttoLine); + ~CFDE_TTOLine(); + + bool GetNewReload() const { return m_bNewReload; } + void SetNewReload(bool reload) { m_bNewReload = reload; } + int32_t AddPiece(int32_t index, const FDE_TTOPIECE& ttoPiece); + int32_t GetSize() const; + FDE_TTOPIECE* GetPtrAt(int32_t index); + void RemoveLast(int32_t iCount); + void RemoveAll(); + + private: + bool m_bNewReload; + std::deque m_pieces; +}; + +class CFDE_TextOut { + public: + CFDE_TextOut(); + ~CFDE_TextOut(); + + void SetFont(const CFX_RetainPtr& pFont); + void SetFontSize(float fFontSize); + void SetTextColor(FX_ARGB color); + void SetStyles(uint32_t dwStyles); + void SetTabWidth(float fTabWidth); + void SetEllipsisString(const CFX_WideString& wsEllipsis); + void SetParagraphBreakChar(wchar_t wch); + void SetAlignment(int32_t iAlignment); + void SetLineSpace(float fLineSpace); + void SetDIBitmap(const CFX_RetainPtr& pDIB); + void SetRenderDevice(CFX_RenderDevice* pDevice); + void SetClipRect(const CFX_Rect& rtClip); + void SetClipRect(const CFX_RectF& rtClip); + void SetMatrix(const CFX_Matrix& matrix); + void SetLineBreakTolerance(float fTolerance); + + void DrawText(const wchar_t* pwsStr, int32_t iLength, int32_t x, int32_t y); + void DrawText(const wchar_t* pwsStr, int32_t iLength, float x, float y); + void DrawText(const wchar_t* pwsStr, int32_t iLength, const CFX_Rect& rect); + void DrawText(const wchar_t* pwsStr, int32_t iLength, const CFX_RectF& rect); + + void SetLogicClipRect(const CFX_RectF& rtClip); + void CalcLogicSize(const wchar_t* pwsStr, int32_t iLength, CFX_SizeF& size); + void CalcLogicSize(const wchar_t* pwsStr, int32_t iLength, CFX_RectF& rect); + void DrawLogicText(const wchar_t* pwsStr, int32_t iLength, float x, float y); + void DrawLogicText(const wchar_t* pwsStr, + int32_t iLength, + const CFX_RectF& rect); + int32_t GetTotalLines(); + + private: + void CalcTextSize(const wchar_t* pwsStr, int32_t iLength, CFX_RectF& rect); + bool RetrieveLineWidth(CFX_BreakType dwBreakStatus, + float& fStartPos, + float& fWidth, + float& fHeight); + void SetLineWidth(CFX_RectF& rect); + void DrawText(const wchar_t* pwsStr, + int32_t iLength, + const CFX_RectF& rect, + const CFX_RectF& rtClip); + void LoadText(const wchar_t* pwsStr, int32_t iLength, const CFX_RectF& rect); + void LoadEllipsis(); + void ExpandBuffer(int32_t iSize, int32_t iType); + void RetrieveEllPieces(std::vector* pCharWidths); + + void Reload(const CFX_RectF& rect); + void ReloadLinePiece(CFDE_TTOLine* pLine, const CFX_RectF& rect); + bool RetrievePieces(CFX_BreakType dwBreakStatus, + int32_t& iStartChar, + int32_t& iPieceWidths, + bool bReload, + const CFX_RectF& rect); + void AppendPiece(const FDE_TTOPIECE& ttoPiece, bool bNeedReload, bool bEnd); + void ReplaceWidthEllipsis(); + void DoAlignment(const CFX_RectF& rect); + void OnDraw(const CFX_RectF& rtClip); + int32_t GetDisplayPos(FDE_TTOPIECE* pPiece); + int32_t GetCharRects(const FDE_TTOPIECE* pPiece); + + FX_TXTRUN ToTextRun(const FDE_TTOPIECE* pPiece); + void DrawLine(const FDE_TTOPIECE* pPiece, CFDE_Pen* pPen); + + std::unique_ptr m_pTxtBreak; + CFX_RetainPtr m_pFont; + float m_fFontSize; + float m_fLineSpace; + float m_fLinePos; + float m_fTolerance; + int32_t m_iAlignment; + int32_t m_iTxtBkAlignment; + std::vector m_CharWidths; + std::vector m_EllCharWidths; + wchar_t m_wParagraphBkChar; + FX_ARGB m_TxtColor; + uint32_t m_dwStyles; + uint32_t m_dwTxtBkStyles; + CFX_WideString m_wsEllipsis; + bool m_bElliChanged; + int32_t m_iEllipsisWidth; + CFX_WideString m_wsText; + CFX_RectF m_rtClip; + CFX_RectF m_rtLogicClip; + CFX_Matrix m_Matrix; + std::deque m_ttoLines; + int32_t m_iCurLine; + int32_t m_iCurPiece; + int32_t m_iTotalLines; + std::vector m_CharPos; + std::unique_ptr m_pRenderDevice; + std::vector m_HotKeys; + std::vector m_rectArray; +}; + +#endif // XFA_FDE_CFDE_TEXTOUT_H_ diff --git a/xfa/fde/cfde_txtedtengine.cpp b/xfa/fde/cfde_txtedtengine.cpp index bdd36aa218..15edfc1c1c 100644 --- a/xfa/fde/cfde_txtedtengine.cpp +++ b/xfa/fde/cfde_txtedtengine.cpp @@ -11,12 +11,12 @@ #include "core/fxcrt/ifx_chariter.h" #include "third_party/base/ptr_util.h" +#include "xfa/fde/cfde_textout.h" #include "xfa/fde/cfde_txtedtbuf.h" #include "xfa/fde/cfde_txtedtdorecord_deleterange.h" #include "xfa/fde/cfde_txtedtdorecord_insert.h" #include "xfa/fde/cfde_txtedtpage.h" #include "xfa/fde/cfde_txtedtparag.h" -#include "xfa/fde/tto/fde_textout.h" #include "xfa/fgas/layout/fgas_textbreak.h" #include "xfa/fwl/cfwl_edit.h" diff --git a/xfa/fde/tto/fde_textout.cpp b/xfa/fde/tto/fde_textout.cpp deleted file mode 100644 index c036c77931..0000000000 --- a/xfa/fde/tto/fde_textout.cpp +++ /dev/null @@ -1,790 +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/tto/fde_textout.h" - -#include - -#include "core/fxcrt/fx_coordinates.h" -#include "core/fxcrt/fx_system.h" -#include "third_party/base/ptr_util.h" -#include "third_party/base/stl_util.h" -#include "xfa/fde/cfde_brush.h" -#include "xfa/fde/cfde_path.h" -#include "xfa/fde/cfde_pen.h" -#include "xfa/fde/cfde_renderdevice.h" -#include "xfa/fgas/layout/fgas_textbreak.h" - -FDE_TTOPIECE::FDE_TTOPIECE() = default; - -FDE_TTOPIECE::FDE_TTOPIECE(const FDE_TTOPIECE& that) = default; - -FDE_TTOPIECE::~FDE_TTOPIECE() = default; - -CFDE_TextOut::CFDE_TextOut() - : m_pTxtBreak(pdfium::MakeUnique()), - m_pFont(nullptr), - m_fFontSize(12.0f), - m_fLineSpace(m_fFontSize), - m_fLinePos(0.0f), - m_fTolerance(0.0f), - m_iAlignment(0), - m_iTxtBkAlignment(0), - m_wParagraphBkChar(L'\n'), - m_TxtColor(0xFF000000), - m_dwStyles(0), - m_dwTxtBkStyles(0), - m_bElliChanged(false), - m_iEllipsisWidth(0), - m_ttoLines(5), - m_iCurLine(0), - m_iCurPiece(0), - m_iTotalLines(0) { - m_Matrix.SetIdentity(); - m_rtClip.Reset(); - m_rtLogicClip.Reset(); -} - -CFDE_TextOut::~CFDE_TextOut() {} - -void CFDE_TextOut::SetFont(const CFX_RetainPtr& pFont) { - ASSERT(pFont); - m_pFont = pFont; - m_pTxtBreak->SetFont(pFont); -} - -void CFDE_TextOut::SetFontSize(float fFontSize) { - ASSERT(fFontSize > 0); - m_fFontSize = fFontSize; - m_pTxtBreak->SetFontSize(fFontSize); -} - -void CFDE_TextOut::SetTextColor(FX_ARGB color) { - m_TxtColor = color; -} - -void CFDE_TextOut::SetStyles(uint32_t dwStyles) { - m_dwStyles = dwStyles; - m_dwTxtBkStyles = 0; - if (dwStyles & FDE_TTOSTYLE_SingleLine) - m_dwTxtBkStyles |= FX_LAYOUTSTYLE_SingleLine; - - m_pTxtBreak->SetLayoutStyles(m_dwTxtBkStyles); -} - -void CFDE_TextOut::SetTabWidth(float fTabWidth) { - ASSERT(fTabWidth > 1.0f); - m_pTxtBreak->SetTabWidth(fTabWidth); -} - -void CFDE_TextOut::SetEllipsisString(const CFX_WideString& wsEllipsis) { - m_bElliChanged = true; - m_wsEllipsis = wsEllipsis; -} - -void CFDE_TextOut::SetParagraphBreakChar(wchar_t wch) { - m_wParagraphBkChar = wch; - m_pTxtBreak->SetParagraphBreakChar(wch); -} - -void CFDE_TextOut::SetAlignment(int32_t iAlignment) { - m_iAlignment = iAlignment; - switch (m_iAlignment) { - case FDE_TTOALIGNMENT_TopCenter: - case FDE_TTOALIGNMENT_Center: - case FDE_TTOALIGNMENT_BottomCenter: - m_iTxtBkAlignment = CFX_TxtLineAlignment_Center; - break; - case FDE_TTOALIGNMENT_TopRight: - case FDE_TTOALIGNMENT_CenterRight: - case FDE_TTOALIGNMENT_BottomRight: - m_iTxtBkAlignment = CFX_TxtLineAlignment_Right; - break; - default: - m_iTxtBkAlignment = CFX_TxtLineAlignment_Left; - break; - } - m_pTxtBreak->SetAlignment(m_iTxtBkAlignment); -} - -void CFDE_TextOut::SetLineSpace(float fLineSpace) { - ASSERT(fLineSpace > 1.0f); - m_fLineSpace = fLineSpace; -} - -void CFDE_TextOut::SetDIBitmap(const CFX_RetainPtr& pDIB) { - ASSERT(pDIB); - - m_pRenderDevice.reset(); - CFX_FxgeDevice* device = new CFX_FxgeDevice; - device->Attach(pDIB, false, nullptr, false); - m_pRenderDevice = pdfium::MakeUnique(device, false); -} - -void CFDE_TextOut::SetRenderDevice(CFX_RenderDevice* pDevice) { - ASSERT(pDevice); - m_pRenderDevice = pdfium::MakeUnique(pDevice, false); -} - -void CFDE_TextOut::SetClipRect(const CFX_Rect& rtClip) { - m_rtClip = rtClip.As(); -} - -void CFDE_TextOut::SetClipRect(const CFX_RectF& rtClip) { - m_rtClip = rtClip; -} - -void CFDE_TextOut::SetLogicClipRect(const CFX_RectF& rtClip) { - m_rtLogicClip = rtClip; -} - -void CFDE_TextOut::SetMatrix(const CFX_Matrix& matrix) { - m_Matrix = matrix; -} - -void CFDE_TextOut::SetLineBreakTolerance(float fTolerance) { - m_fTolerance = fTolerance; - m_pTxtBreak->SetLineBreakTolerance(m_fTolerance); -} - -int32_t CFDE_TextOut::GetTotalLines() { - return m_iTotalLines; -} - -void CFDE_TextOut::CalcLogicSize(const wchar_t* pwsStr, - int32_t iLength, - CFX_SizeF& size) { - CFX_RectF rtText(0.0f, 0.0f, size.width, size.height); - CalcLogicSize(pwsStr, iLength, rtText); - size = rtText.Size(); -} - -void CFDE_TextOut::CalcLogicSize(const wchar_t* pwsStr, - int32_t iLength, - CFX_RectF& rect) { - if (!pwsStr || iLength < 1) { - rect.width = 0.0f; - rect.height = 0.0f; - } else { - CalcTextSize(pwsStr, iLength, rect); - } -} - -void CFDE_TextOut::CalcTextSize(const wchar_t* pwsStr, - int32_t iLength, - CFX_RectF& rect) { - ASSERT(m_pFont && m_fFontSize >= 1.0f); - SetLineWidth(rect); - m_iTotalLines = 0; - const wchar_t* pStr = pwsStr; - bool bHotKey = !!(m_dwStyles & FDE_TTOSTYLE_HotKey); - float fWidth = 0.0f; - float fHeight = 0.0f; - float fStartPos = rect.right(); - CFX_BreakType dwBreakStatus = CFX_BreakType::None; - wchar_t wPreChar = 0; - wchar_t wch; - wchar_t wBreak = 0; - while (iLength-- > 0) { - wch = *pStr++; - if (wBreak == 0 && (wch == L'\n' || wch == L'\r')) { - wBreak = wch; - m_pTxtBreak->SetParagraphBreakChar(wch); - } - if (bHotKey && wch == L'&' && wPreChar != L'&') { - wPreChar = wch; - continue; - } - dwBreakStatus = m_pTxtBreak->AppendChar(wch); - if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) - RetrieveLineWidth(dwBreakStatus, fStartPos, fWidth, fHeight); - - wPreChar = 0; - } - dwBreakStatus = m_pTxtBreak->EndBreak(CFX_BreakType::Paragraph); - if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) - RetrieveLineWidth(dwBreakStatus, fStartPos, fWidth, fHeight); - - m_pTxtBreak->Reset(); - float fInc = rect.Height() - fHeight; - if (m_iAlignment >= FDE_TTOALIGNMENT_CenterLeft && - m_iAlignment < FDE_TTOALIGNMENT_BottomLeft) { - fInc /= 2.0f; - } else if (m_iAlignment < FDE_TTOALIGNMENT_CenterLeft) { - fInc = 0.0f; - } - rect.left += fStartPos; - rect.top += fInc; - rect.width = std::min(fWidth, rect.Width()); - rect.height = fHeight; - if (m_dwStyles & FDE_TTOSTYLE_LastLineHeight) - rect.height -= m_fLineSpace - m_fFontSize; -} - -void CFDE_TextOut::SetLineWidth(CFX_RectF& rect) { - if ((m_dwStyles & FDE_TTOSTYLE_SingleLine) == 0) { - float fLineWidth = 0.0f; - if (rect.Width() < 1.0f) - rect.width = m_fFontSize * 1000.0f; - - fLineWidth = rect.Width(); - m_pTxtBreak->SetLineWidth(fLineWidth); - } -} - -bool CFDE_TextOut::RetrieveLineWidth(CFX_BreakType dwBreakStatus, - float& fStartPos, - float& fWidth, - float& fHeight) { - if (CFX_BreakTypeNoneOrPiece(dwBreakStatus)) - return false; - - float fLineStep = (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize; - bool bLineWrap = !!(m_dwStyles & FDE_TTOSTYLE_LineWrap); - float fLineWidth = 0.0f; - int32_t iCount = m_pTxtBreak->CountBreakPieces(); - for (int32_t i = 0; i < iCount; i++) { - const CFX_BreakPiece* pPiece = m_pTxtBreak->GetBreakPieceUnstable(i); - fLineWidth += static_cast(pPiece->m_iWidth) / 20000.0f; - fStartPos = - std::min(fStartPos, static_cast(pPiece->m_iStartPos) / 20000.0f); - } - m_pTxtBreak->ClearBreakPieces(); - if (dwBreakStatus == CFX_BreakType::Paragraph) { - m_pTxtBreak->Reset(); - } - if (!bLineWrap && dwBreakStatus == CFX_BreakType::Line) { - fWidth += fLineWidth; - } else { - fWidth = std::max(fWidth, fLineWidth); - fHeight += fLineStep; - } - m_iTotalLines++; - return true; -} - -void CFDE_TextOut::DrawText(const wchar_t* pwsStr, - int32_t iLength, - int32_t x, - int32_t y) { - CFX_RectF rtText(static_cast(x), static_cast(y), - m_fFontSize * 1000.0f, m_fFontSize * 1000.0f); - DrawText(pwsStr, iLength, rtText); -} - -void CFDE_TextOut::DrawText(const wchar_t* pwsStr, - int32_t iLength, - float x, - float y) { - DrawText(pwsStr, iLength, - CFX_RectF(x, y, m_fFontSize * 1000.0f, m_fFontSize * 1000.0f)); -} - -void CFDE_TextOut::DrawText(const wchar_t* pwsStr, - int32_t iLength, - const CFX_Rect& rect) { - DrawText(pwsStr, iLength, rect.As()); -} - -void CFDE_TextOut::DrawText(const wchar_t* pwsStr, - int32_t iLength, - const CFX_RectF& rect) { - CFX_RectF rtText(rect.left, rect.top, rect.width, rect.height); - CFX_Matrix rm; - rm.SetReverse(m_Matrix); - rm.TransformRect(rtText); - DrawText(pwsStr, iLength, rtText, m_rtClip); -} - -void CFDE_TextOut::DrawLogicText(const wchar_t* pwsStr, - int32_t iLength, - float x, - float y) { - CFX_RectF rtText(x, y, m_fFontSize * 1000.0f, m_fFontSize * 1000.0f); - DrawLogicText(pwsStr, iLength, rtText); -} - -void CFDE_TextOut::DrawLogicText(const wchar_t* pwsStr, - int32_t iLength, - const CFX_RectF& rect) { - CFX_RectF rtClip(m_rtLogicClip.left, m_rtLogicClip.top, m_rtLogicClip.width, - m_rtLogicClip.height); - m_Matrix.TransformRect(rtClip); - DrawText(pwsStr, iLength, rect, rtClip); -} - -void CFDE_TextOut::DrawText(const wchar_t* pwsStr, - int32_t iLength, - const CFX_RectF& rect, - const CFX_RectF& rtClip) { - ASSERT(m_pFont && m_fFontSize >= 1.0f); - if (!pwsStr || iLength < 1) - return; - if (rect.width < m_fFontSize || rect.height < m_fFontSize) - return; - - float fLineWidth = rect.width; - m_pTxtBreak->SetLineWidth(fLineWidth); - m_ttoLines.clear(); - m_wsText.clear(); - LoadText(pwsStr, iLength, rect); - if (m_dwStyles & FDE_TTOSTYLE_Ellipsis) { - ReplaceWidthEllipsis(); - } - Reload(rect); - DoAlignment(rect); - OnDraw(rtClip); -} - -void CFDE_TextOut::ExpandBuffer(int32_t iSize, int32_t iType) { - ASSERT(iSize >= 0); - size_t size = iSize; - switch (iType) { - case 0: - if (m_CharWidths.size() < size) - m_CharWidths.resize(size, 0); - break; - case 1: - if (m_EllCharWidths.size() < size) - m_EllCharWidths.resize(size, 0); - break; - case 2: - if (m_CharPos.size() < size) - m_CharPos.resize(size, FXTEXT_CHARPOS()); - break; - } -} - -void CFDE_TextOut::LoadEllipsis() { - if (!m_bElliChanged) { - return; - } - m_bElliChanged = false; - m_iEllipsisWidth = 0; - int32_t iLength = m_wsEllipsis.GetLength(); - if (iLength < 1) { - return; - } - ExpandBuffer(iLength, 1); - const wchar_t* pStr = m_wsEllipsis.c_str(); - CFX_BreakType dwBreakStatus; - wchar_t wch; - while (iLength-- > 0) { - wch = *pStr++; - dwBreakStatus = m_pTxtBreak->AppendChar(wch); - if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) - RetrieveEllPieces(&m_EllCharWidths); - } - dwBreakStatus = m_pTxtBreak->EndBreak(CFX_BreakType::Paragraph); - if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) - RetrieveEllPieces(&m_EllCharWidths); - - m_pTxtBreak->Reset(); -} - -void CFDE_TextOut::RetrieveEllPieces(std::vector* pCharWidths) { - int32_t iCount = m_pTxtBreak->CountBreakPieces(); - int32_t iCharIndex = 0; - for (int32_t i = 0; i < iCount; i++) { - const CFX_BreakPiece* pPiece = m_pTxtBreak->GetBreakPieceUnstable(i); - int32_t iPieceChars = pPiece->GetLength(); - for (int32_t j = 0; j < iPieceChars; j++) { - (*pCharWidths)[iCharIndex] = - std::max(pPiece->GetChar(j)->m_iCharWidth, 0); - m_iEllipsisWidth += (*pCharWidths)[iCharIndex]; - iCharIndex++; - } - } - m_pTxtBreak->ClearBreakPieces(); -} - -void CFDE_TextOut::LoadText(const wchar_t* pwsStr, - int32_t iLength, - const CFX_RectF& rect) { - wchar_t* pStr = m_wsText.GetBuffer(iLength); - int32_t iTxtLength = iLength; - ExpandBuffer(iTxtLength, 0); - bool bHotKey = !!(m_dwStyles & FDE_TTOSTYLE_HotKey); - bool bLineWrap = !!(m_dwStyles & FDE_TTOSTYLE_LineWrap); - float fLineStep = (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize; - float fLineStop = rect.bottom(); - m_fLinePos = rect.top; - m_HotKeys.clear(); - int32_t iStartChar = 0; - int32_t iChars = 0; - int32_t iPieceWidths = 0; - CFX_BreakType dwBreakStatus; - wchar_t wch; - bool bRet = false; - while (iTxtLength-- > 0) { - wch = *pwsStr++; - if (bHotKey && wch == L'&' && *(pStr - 1) != L'&') { - if (iTxtLength > 0) - m_HotKeys.push_back(iChars); - continue; - } - *pStr++ = wch; - iChars++; - dwBreakStatus = m_pTxtBreak->AppendChar(wch); - if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) { - bool bEndofLine = - RetrievePieces(dwBreakStatus, iStartChar, iPieceWidths, false, rect); - if (bEndofLine && - (bLineWrap || dwBreakStatus == CFX_BreakType::Paragraph || - dwBreakStatus == CFX_BreakType::Page)) { - iPieceWidths = 0; - m_iCurLine++; - m_fLinePos += fLineStep; - } - if (m_fLinePos + fLineStep > fLineStop) { - int32_t iCurLine = bEndofLine ? m_iCurLine - 1 : m_iCurLine; - m_ttoLines[iCurLine].SetNewReload(true); - bRet = true; - break; - } - } - } - dwBreakStatus = m_pTxtBreak->EndBreak(CFX_BreakType::Paragraph); - if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus) && !bRet) - RetrievePieces(dwBreakStatus, iStartChar, iPieceWidths, false, rect); - - m_pTxtBreak->ClearBreakPieces(); - m_pTxtBreak->Reset(); - m_wsText.ReleaseBuffer(iLength); -} - -bool CFDE_TextOut::RetrievePieces(CFX_BreakType dwBreakStatus, - int32_t& iStartChar, - int32_t& iPieceWidths, - bool bReload, - const CFX_RectF& rect) { - bool bSingleLine = !!(m_dwStyles & FDE_TTOSTYLE_SingleLine); - bool bLineWrap = !!(m_dwStyles & FDE_TTOSTYLE_LineWrap); - float fLineStep = (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize; - bool bNeedReload = false; - float fLineWidth = 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_BreakPiece* pPiece = m_pTxtBreak->GetBreakPieceUnstable(i); - int32_t iPieceChars = pPiece->GetLength(); - int32_t iChar = iStartChar; - int32_t iWidth = 0; - int32_t j = 0; - for (; j < iPieceChars; j++) { - const CFX_Char* pTC = pPiece->GetChar(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) { - m_ttoLines[m_iCurLine].SetNewReload(true); - } else if (j > 0) { - CFX_RectF rtPiece; - rtPiece.left = rect.left + (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(); - return bSingleLine || bLineWrap || bNeedReload || - dwBreakStatus == CFX_BreakType::Paragraph; -} - -void CFDE_TextOut::AppendPiece(const FDE_TTOPIECE& ttoPiece, - bool bNeedReload, - bool bEnd) { - if (m_iCurLine >= pdfium::CollectionSize(m_ttoLines)) { - CFDE_TTOLine ttoLine; - ttoLine.SetNewReload(bNeedReload); - m_iCurPiece = ttoLine.AddPiece(m_iCurPiece, ttoPiece); - m_ttoLines.push_back(ttoLine); - m_iCurLine = pdfium::CollectionSize(m_ttoLines) - 1; - } else { - CFDE_TTOLine* pLine = &m_ttoLines[m_iCurLine]; - pLine->SetNewReload(bNeedReload); - m_iCurPiece = pLine->AddPiece(m_iCurPiece, ttoPiece); - if (bEnd) { - int32_t iPieces = pLine->GetSize(); - if (m_iCurPiece < iPieces) { - pLine->RemoveLast(iPieces - m_iCurPiece - 1); - } - } - } - if (!bEnd && bNeedReload) - m_iCurPiece = 0; -} - -void CFDE_TextOut::ReplaceWidthEllipsis() { - LoadEllipsis(); - int32_t iLength = m_wsEllipsis.GetLength(); - if (iLength < 1) - return; - - for (auto& line : m_ttoLines) { - if (!line.GetNewReload()) - continue; - - int32_t iEllipsisCharIndex = iLength - 1; - int32_t iCharWidth = 0; - int32_t iCharCount = 0; - int32_t iPiece = line.GetSize(); - while (iPiece-- > 0) { - FDE_TTOPIECE* pPiece = line.GetPtrAt(iPiece); - if (!pPiece) - break; - - for (int32_t j = pPiece->iChars - 1; j >= 0; j--) { - if (iEllipsisCharIndex < 0) - break; - - int32_t index = pPiece->iStartChar + j; - iCharWidth += m_CharWidths[index]; - iCharCount++; - if (iCharCount <= iLength) { - m_wsText.SetAt(index, m_wsEllipsis.GetAt(iEllipsisCharIndex)); - m_CharWidths[index] = m_EllCharWidths[iEllipsisCharIndex]; - } else if (iCharWidth <= m_iEllipsisWidth) { - m_wsText.SetAt(index, 0); - m_CharWidths[index] = 0; - } - iEllipsisCharIndex--; - } - if (iEllipsisCharIndex < 0) - break; - } - } -} - -void CFDE_TextOut::Reload(const CFX_RectF& rect) { - int i = 0; - for (auto& line : m_ttoLines) { - if (line.GetNewReload()) { - m_iCurLine = i; - m_iCurPiece = 0; - ReloadLinePiece(&line, rect); - } - ++i; - } -} - -void CFDE_TextOut::ReloadLinePiece(CFDE_TTOLine* pLine, const CFX_RectF& rect) { - const wchar_t* pwsStr = m_wsText.c_str(); - int32_t iPieceWidths = 0; - FDE_TTOPIECE* pPiece = pLine->GetPtrAt(0); - int32_t iStartChar = pPiece->iStartChar; - m_fLinePos = pPiece->rtPiece.top; - int32_t iPieceCount = pLine->GetSize(); - int32_t iPieceIndex = 0; - CFX_BreakType dwBreakStatus = CFX_BreakType::None; - wchar_t wch; - while (iPieceIndex < iPieceCount) { - int32_t iStar = iStartChar; - int32_t iEnd = pPiece->iChars + iStar; - while (iStar < iEnd) { - wch = *(pwsStr + iStar); - dwBreakStatus = m_pTxtBreak->AppendChar(wch); - if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) - RetrievePieces(dwBreakStatus, iStartChar, iPieceWidths, true, rect); - iStar++; - } - iPieceIndex++; - pPiece = pLine->GetPtrAt(iPieceIndex); - } - dwBreakStatus = m_pTxtBreak->EndBreak(CFX_BreakType::Paragraph); - if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) - RetrievePieces(dwBreakStatus, iStartChar, iPieceWidths, true, rect); - - m_pTxtBreak->Reset(); -} - -void CFDE_TextOut::DoAlignment(const CFX_RectF& rect) { - if (m_ttoLines.empty()) - return; - - float fLineStopS = rect.bottom(); - FDE_TTOPIECE* pFirstPiece = m_ttoLines.back().GetPtrAt(0); - if (!pFirstPiece) - return; - - float fLineStopD = pFirstPiece->rtPiece.bottom(); - float fInc = fLineStopS - fLineStopD; - if (m_iAlignment >= FDE_TTOALIGNMENT_CenterLeft && - m_iAlignment < FDE_TTOALIGNMENT_BottomLeft) { - fInc /= 2.0f; - } else if (m_iAlignment < FDE_TTOALIGNMENT_CenterLeft) { - fInc = 0.0f; - } - if (fInc < 1.0f) - return; - for (auto& line : m_ttoLines) { - int32_t iPieces = line.GetSize(); - for (int32_t j = 0; j < iPieces; j++) { - FDE_TTOPIECE* pPiece = line.GetPtrAt(j); - pPiece->rtPiece.top += fInc; - } - } -} - -void CFDE_TextOut::OnDraw(const CFX_RectF& rtClip) { - if (!m_pRenderDevice || m_ttoLines.empty()) - return; - - auto pBrush = pdfium::MakeUnique(); - pBrush->SetColor(m_TxtColor); - m_pRenderDevice->SaveState(); - if (rtClip.Width() > 0.0f && rtClip.Height() > 0.0f) - m_pRenderDevice->SetClipRect(rtClip); - - auto pPen = pdfium::MakeUnique(); - pPen->SetColor(m_TxtColor); - - for (auto& line : m_ttoLines) { - int32_t iPieces = line.GetSize(); - for (int32_t j = 0; j < iPieces; j++) { - FDE_TTOPIECE* pPiece = line.GetPtrAt(j); - if (!pPiece) - continue; - - int32_t iCount = GetDisplayPos(pPiece); - if (iCount > 0) { - m_pRenderDevice->DrawString(pBrush.get(), m_pFont, m_CharPos.data(), - iCount, m_fFontSize, &m_Matrix); - } - DrawLine(pPiece, pPen.get()); - } - } - m_pRenderDevice->RestoreState(); -} - -int32_t CFDE_TextOut::GetDisplayPos(FDE_TTOPIECE* pPiece) { - FX_TXTRUN tr = ToTextRun(pPiece); - ExpandBuffer(tr.iLength, 2); - return m_pTxtBreak->GetDisplayPos(&tr, m_CharPos.data()); -} - -int32_t CFDE_TextOut::GetCharRects(const FDE_TTOPIECE* pPiece) { - FX_TXTRUN tr = ToTextRun(pPiece); - m_rectArray = m_pTxtBreak->GetCharRects(&tr); - return pdfium::CollectionSize(m_rectArray); -} - -FX_TXTRUN CFDE_TextOut::ToTextRun(const FDE_TTOPIECE* pPiece) { - FX_TXTRUN tr; - tr.wsStr = m_wsText + pPiece->iStartChar; - tr.pWidths = &m_CharWidths[pPiece->iStartChar]; - tr.iLength = pPiece->iChars; - tr.pFont = m_pFont; - tr.fFontSize = m_fFontSize; - tr.dwStyles = m_dwTxtBkStyles; - tr.dwCharStyles = pPiece->dwCharStyles; - tr.wLineBreakChar = m_wParagraphBkChar; - tr.pRect = &pPiece->rtPiece; - return tr; -} - -void CFDE_TextOut::DrawLine(const FDE_TTOPIECE* pPiece, CFDE_Pen* pPen) { - bool bUnderLine = !!(m_dwStyles & FDE_TTOSTYLE_Underline); - bool bStrikeOut = !!(m_dwStyles & FDE_TTOSTYLE_Strikeout); - bool bHotKey = !!(m_dwStyles & FDE_TTOSTYLE_HotKey); - if (!bUnderLine && !bStrikeOut && !bHotKey) - return; - - auto pPath = pdfium::MakeUnique(); - int32_t iLineCount = 0; - CFX_RectF rtText = pPiece->rtPiece; - CFX_PointF pt1, pt2; - if (bUnderLine) { - pt1.x = rtText.left; - pt1.y = rtText.bottom(); - pt2.x = rtText.right(); - pt2.y = rtText.bottom(); - pPath->AddLine(pt1, pt2); - iLineCount++; - } - if (bStrikeOut) { - pt1.x = rtText.left; - pt1.y = rtText.bottom() - rtText.height * 2.0f / 5.0f; - pt2.x = rtText.right(); - pt2.y = pt1.y; - pPath->AddLine(pt1, pt2); - iLineCount++; - } - if (bHotKey) { - if (GetCharRects(pPiece) > 0) { - for (int32_t iCharIndex : m_HotKeys) { - if (iCharIndex >= pPiece->iStartChar && - iCharIndex < pPiece->iStartChar + pPiece->iChars) { - CFX_RectF rect = m_rectArray[iCharIndex - pPiece->iStartChar]; - pt1.x = rect.left; - pt1.y = rect.bottom(); - pt2.x = rect.right(); - pt2.y = rect.bottom(); - pPath->AddLine(pt1, pt2); - iLineCount++; - } - } - } - } - if (iLineCount > 0) - m_pRenderDevice->DrawPath(pPen, 1, pPath.get(), &m_Matrix); -} - -CFDE_TTOLine::CFDE_TTOLine() : m_bNewReload(false) {} - -CFDE_TTOLine::CFDE_TTOLine(const CFDE_TTOLine& ttoLine) : m_pieces(5) { - m_bNewReload = ttoLine.m_bNewReload; - m_pieces = ttoLine.m_pieces; -} - -CFDE_TTOLine::~CFDE_TTOLine() {} - -int32_t CFDE_TTOLine::AddPiece(int32_t index, const FDE_TTOPIECE& ttoPiece) { - if (index >= pdfium::CollectionSize(m_pieces)) { - m_pieces.push_back(ttoPiece); - return pdfium::CollectionSize(m_pieces); - } - m_pieces[index] = ttoPiece; - return index; -} - -int32_t CFDE_TTOLine::GetSize() const { - return pdfium::CollectionSize(m_pieces); -} - -FDE_TTOPIECE* CFDE_TTOLine::GetPtrAt(int32_t index) { - return pdfium::IndexInBounds(m_pieces, index) ? &m_pieces[index] : nullptr; -} - -void CFDE_TTOLine::RemoveLast(int32_t icount) { - if (icount < 0) - return; - icount = std::min(icount, pdfium::CollectionSize(m_pieces)); - m_pieces.erase(m_pieces.end() - icount, m_pieces.end()); -} - -void CFDE_TTOLine::RemoveAll() { - m_pieces.clear(); -} diff --git a/xfa/fde/tto/fde_textout.h b/xfa/fde/tto/fde_textout.h deleted file mode 100644 index 2ca77217a6..0000000000 --- a/xfa/fde/tto/fde_textout.h +++ /dev/null @@ -1,175 +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 - -#ifndef XFA_FDE_TTO_FDE_TEXTOUT_H_ -#define XFA_FDE_TTO_FDE_TEXTOUT_H_ - -#include -#include -#include - -#include "core/fxcrt/cfx_char.h" -#include "core/fxge/cfx_fxgedevice.h" -#include "core/fxge/cfx_renderdevice.h" -#include "core/fxge/fx_dib.h" -#include "xfa/fgas/font/cfgas_fontmgr.h" - -#define FDE_TTOSTYLE_Underline 0x0001 -#define FDE_TTOSTYLE_Strikeout 0x0002 -#define FDE_TTOSTYLE_SingleLine 0x0010 -#define FDE_TTOSTYLE_HotKey 0x0040 -#define FDE_TTOSTYLE_Ellipsis 0x0080 -#define FDE_TTOSTYLE_LineWrap 0x0100 -#define FDE_TTOSTYLE_LastLineHeight 0x1000 -#define FDE_TTOALIGNMENT_TopLeft 0 -#define FDE_TTOALIGNMENT_TopCenter 1 -#define FDE_TTOALIGNMENT_TopRight 2 -#define FDE_TTOALIGNMENT_TopAuto 3 -#define FDE_TTOALIGNMENT_CenterLeft 4 -#define FDE_TTOALIGNMENT_Center 5 -#define FDE_TTOALIGNMENT_CenterRight 6 -#define FDE_TTOALIGNMENT_CenterAuto 7 -#define FDE_TTOALIGNMENT_BottomLeft 8 -#define FDE_TTOALIGNMENT_BottomCenter 9 -#define FDE_TTOALIGNMENT_BottomRight 10 -#define FDE_TTOALIGNMENT_BottomAuto 11 - -class CFDE_Pen; -class CFDE_RenderDevice; -class CFX_RenderDevice; -class CFX_TxtBreak; -struct FX_TXTRUN; - -struct FDE_TTOPIECE { - FDE_TTOPIECE(); - FDE_TTOPIECE(const FDE_TTOPIECE& that); - ~FDE_TTOPIECE(); - - int32_t iStartChar; - int32_t iChars; - uint32_t dwCharStyles; - CFX_RectF rtPiece; -}; - -class CFDE_TTOLine { - public: - CFDE_TTOLine(); - CFDE_TTOLine(const CFDE_TTOLine& ttoLine); - ~CFDE_TTOLine(); - - bool GetNewReload() const { return m_bNewReload; } - void SetNewReload(bool reload) { m_bNewReload = reload; } - int32_t AddPiece(int32_t index, const FDE_TTOPIECE& ttoPiece); - int32_t GetSize() const; - FDE_TTOPIECE* GetPtrAt(int32_t index); - void RemoveLast(int32_t iCount); - void RemoveAll(); - - private: - bool m_bNewReload; - std::deque m_pieces; -}; - -class CFDE_TextOut { - public: - CFDE_TextOut(); - ~CFDE_TextOut(); - - void SetFont(const CFX_RetainPtr& pFont); - void SetFontSize(float fFontSize); - void SetTextColor(FX_ARGB color); - void SetStyles(uint32_t dwStyles); - void SetTabWidth(float fTabWidth); - void SetEllipsisString(const CFX_WideString& wsEllipsis); - void SetParagraphBreakChar(wchar_t wch); - void SetAlignment(int32_t iAlignment); - void SetLineSpace(float fLineSpace); - void SetDIBitmap(const CFX_RetainPtr& pDIB); - void SetRenderDevice(CFX_RenderDevice* pDevice); - void SetClipRect(const CFX_Rect& rtClip); - void SetClipRect(const CFX_RectF& rtClip); - void SetMatrix(const CFX_Matrix& matrix); - void SetLineBreakTolerance(float fTolerance); - - void DrawText(const wchar_t* pwsStr, int32_t iLength, int32_t x, int32_t y); - void DrawText(const wchar_t* pwsStr, int32_t iLength, float x, float y); - void DrawText(const wchar_t* pwsStr, int32_t iLength, const CFX_Rect& rect); - void DrawText(const wchar_t* pwsStr, int32_t iLength, const CFX_RectF& rect); - - void SetLogicClipRect(const CFX_RectF& rtClip); - void CalcLogicSize(const wchar_t* pwsStr, int32_t iLength, CFX_SizeF& size); - void CalcLogicSize(const wchar_t* pwsStr, int32_t iLength, CFX_RectF& rect); - void DrawLogicText(const wchar_t* pwsStr, int32_t iLength, float x, float y); - void DrawLogicText(const wchar_t* pwsStr, - int32_t iLength, - const CFX_RectF& rect); - int32_t GetTotalLines(); - - protected: - void CalcTextSize(const wchar_t* pwsStr, int32_t iLength, CFX_RectF& rect); - bool RetrieveLineWidth(CFX_BreakType dwBreakStatus, - float& fStartPos, - float& fWidth, - float& fHeight); - void SetLineWidth(CFX_RectF& rect); - void DrawText(const wchar_t* pwsStr, - int32_t iLength, - const CFX_RectF& rect, - const CFX_RectF& rtClip); - void LoadText(const wchar_t* pwsStr, int32_t iLength, const CFX_RectF& rect); - void LoadEllipsis(); - void ExpandBuffer(int32_t iSize, int32_t iType); - void RetrieveEllPieces(std::vector* pCharWidths); - - void Reload(const CFX_RectF& rect); - void ReloadLinePiece(CFDE_TTOLine* pLine, const CFX_RectF& rect); - bool RetrievePieces(CFX_BreakType dwBreakStatus, - int32_t& iStartChar, - int32_t& iPieceWidths, - bool bReload, - const CFX_RectF& rect); - void AppendPiece(const FDE_TTOPIECE& ttoPiece, bool bNeedReload, bool bEnd); - void ReplaceWidthEllipsis(); - void DoAlignment(const CFX_RectF& rect); - void OnDraw(const CFX_RectF& rtClip); - int32_t GetDisplayPos(FDE_TTOPIECE* pPiece); - int32_t GetCharRects(const FDE_TTOPIECE* pPiece); - - FX_TXTRUN ToTextRun(const FDE_TTOPIECE* pPiece); - void DrawLine(const FDE_TTOPIECE* pPiece, CFDE_Pen* pPen); - - std::unique_ptr m_pTxtBreak; - CFX_RetainPtr m_pFont; - float m_fFontSize; - float m_fLineSpace; - float m_fLinePos; - float m_fTolerance; - int32_t m_iAlignment; - int32_t m_iTxtBkAlignment; - std::vector m_CharWidths; - std::vector m_EllCharWidths; - wchar_t m_wParagraphBkChar; - FX_ARGB m_TxtColor; - uint32_t m_dwStyles; - uint32_t m_dwTxtBkStyles; - CFX_WideString m_wsEllipsis; - bool m_bElliChanged; - int32_t m_iEllipsisWidth; - CFX_WideString m_wsText; - CFX_RectF m_rtClip; - CFX_RectF m_rtLogicClip; - CFX_Matrix m_Matrix; - std::deque m_ttoLines; - int32_t m_iCurLine; - int32_t m_iCurPiece; - int32_t m_iTotalLines; - std::vector m_CharPos; - std::unique_ptr m_pRenderDevice; - std::vector m_HotKeys; - std::vector m_rectArray; -}; - -#endif // XFA_FDE_TTO_FDE_TEXTOUT_H_ diff --git a/xfa/fwl/cfwl_checkbox.cpp b/xfa/fwl/cfwl_checkbox.cpp index c1ca3296b9..5ec3504cae 100644 --- a/xfa/fwl/cfwl_checkbox.cpp +++ b/xfa/fwl/cfwl_checkbox.cpp @@ -12,7 +12,7 @@ #include #include "third_party/base/ptr_util.h" -#include "xfa/fde/tto/fde_textout.h" +#include "xfa/fde/cfde_textout.h" #include "xfa/fwl/cfwl_app.h" #include "xfa/fwl/cfwl_event.h" #include "xfa/fwl/cfwl_messagekey.h" diff --git a/xfa/fwl/cfwl_combobox.cpp b/xfa/fwl/cfwl_combobox.cpp index 61c363c95b..b5931d1c04 100644 --- a/xfa/fwl/cfwl_combobox.cpp +++ b/xfa/fwl/cfwl_combobox.cpp @@ -11,8 +11,8 @@ #include #include "third_party/base/ptr_util.h" +#include "xfa/fde/cfde_textout.h" #include "xfa/fde/cfde_txtedtengine.h" -#include "xfa/fde/tto/fde_textout.h" #include "xfa/fwl/cfwl_app.h" #include "xfa/fwl/cfwl_event.h" #include "xfa/fwl/cfwl_eventselectchanged.h" diff --git a/xfa/fwl/cfwl_form.cpp b/xfa/fwl/cfwl_form.cpp index 1b2d668e5a..3e606b3eb9 100644 --- a/xfa/fwl/cfwl_form.cpp +++ b/xfa/fwl/cfwl_form.cpp @@ -9,7 +9,7 @@ #include #include "third_party/base/ptr_util.h" -#include "xfa/fde/tto/fde_textout.h" +#include "xfa/fde/cfde_textout.h" #include "xfa/fwl/cfwl_app.h" #include "xfa/fwl/cfwl_event.h" #include "xfa/fwl/cfwl_formproxy.h" diff --git a/xfa/fwl/cfwl_listbox.cpp b/xfa/fwl/cfwl_listbox.cpp index c858063d07..9d9bf72f4c 100644 --- a/xfa/fwl/cfwl_listbox.cpp +++ b/xfa/fwl/cfwl_listbox.cpp @@ -12,7 +12,7 @@ #include "third_party/base/ptr_util.h" #include "third_party/base/stl_util.h" -#include "xfa/fde/tto/fde_textout.h" +#include "xfa/fde/cfde_textout.h" #include "xfa/fwl/cfwl_app.h" #include "xfa/fwl/cfwl_messagekey.h" #include "xfa/fwl/cfwl_messagemouse.h" diff --git a/xfa/fwl/cfwl_monthcalendar.cpp b/xfa/fwl/cfwl_monthcalendar.cpp index a973e75410..4ef0c694c5 100644 --- a/xfa/fwl/cfwl_monthcalendar.cpp +++ b/xfa/fwl/cfwl_monthcalendar.cpp @@ -12,7 +12,7 @@ #include "third_party/base/ptr_util.h" #include "third_party/base/stl_util.h" -#include "xfa/fde/tto/fde_textout.h" +#include "xfa/fde/cfde_textout.h" #include "xfa/fwl/cfwl_datetimepicker.h" #include "xfa/fwl/cfwl_formproxy.h" #include "xfa/fwl/cfwl_messagemouse.h" diff --git a/xfa/fwl/cfwl_pushbutton.cpp b/xfa/fwl/cfwl_pushbutton.cpp index fe4c3f621a..42925414f8 100644 --- a/xfa/fwl/cfwl_pushbutton.cpp +++ b/xfa/fwl/cfwl_pushbutton.cpp @@ -10,7 +10,7 @@ #include #include "third_party/base/ptr_util.h" -#include "xfa/fde/tto/fde_textout.h" +#include "xfa/fde/cfde_textout.h" #include "xfa/fwl/cfwl_event.h" #include "xfa/fwl/cfwl_eventmouse.h" #include "xfa/fwl/cfwl_messagekey.h" diff --git a/xfa/fwl/cfwl_widget.cpp b/xfa/fwl/cfwl_widget.cpp index f168ad127c..172014da62 100644 --- a/xfa/fwl/cfwl_widget.cpp +++ b/xfa/fwl/cfwl_widget.cpp @@ -11,7 +11,7 @@ #include #include "third_party/base/stl_util.h" -#include "xfa/fde/tto/fde_textout.h" +#include "xfa/fde/cfde_textout.h" #include "xfa/fwl/cfwl_app.h" #include "xfa/fwl/cfwl_combobox.h" #include "xfa/fwl/cfwl_event.h" diff --git a/xfa/fwl/theme/cfwl_checkboxtp.cpp b/xfa/fwl/theme/cfwl_checkboxtp.cpp index 76a20fe14a..0a3ae88a46 100644 --- a/xfa/fwl/theme/cfwl_checkboxtp.cpp +++ b/xfa/fwl/theme/cfwl_checkboxtp.cpp @@ -8,7 +8,7 @@ #include "core/fxge/cfx_pathdata.h" #include "third_party/base/ptr_util.h" -#include "xfa/fde/tto/fde_textout.h" +#include "xfa/fde/cfde_textout.h" #include "xfa/fwl/cfwl_checkbox.h" #include "xfa/fwl/cfwl_themebackground.h" #include "xfa/fwl/cfwl_themetext.h" diff --git a/xfa/fwl/theme/cfwl_monthcalendartp.cpp b/xfa/fwl/theme/cfwl_monthcalendartp.cpp index b14109d013..b9961af8b0 100644 --- a/xfa/fwl/theme/cfwl_monthcalendartp.cpp +++ b/xfa/fwl/theme/cfwl_monthcalendartp.cpp @@ -6,7 +6,7 @@ #include "xfa/fwl/theme/cfwl_monthcalendartp.h" -#include "xfa/fde/tto/fde_textout.h" +#include "xfa/fde/cfde_textout.h" #include "xfa/fwl/cfwl_monthcalendar.h" #include "xfa/fwl/cfwl_themebackground.h" #include "xfa/fwl/cfwl_themetext.h" diff --git a/xfa/fwl/theme/cfwl_widgettp.cpp b/xfa/fwl/theme/cfwl_widgettp.cpp index 6ce86fb269..a45716ad6b 100644 --- a/xfa/fwl/theme/cfwl_widgettp.cpp +++ b/xfa/fwl/theme/cfwl_widgettp.cpp @@ -10,7 +10,7 @@ #include #include "third_party/base/ptr_util.h" -#include "xfa/fde/tto/fde_textout.h" +#include "xfa/fde/cfde_textout.h" #include "xfa/fgas/font/cfgas_fontmgr.h" #include "xfa/fgas/font/cfgas_gefont.h" #include "xfa/fwl/cfwl_themebackground.h" diff --git a/xfa/fxfa/app/xfa_ffwidgetacc.cpp b/xfa/fxfa/app/xfa_ffwidgetacc.cpp index ada78921ef..b6d4decc42 100644 --- a/xfa/fxfa/app/xfa_ffwidgetacc.cpp +++ b/xfa/fxfa/app/xfa_ffwidgetacc.cpp @@ -13,7 +13,7 @@ #include "fxjs/cfxjse_value.h" #include "third_party/base/ptr_util.h" #include "third_party/base/stl_util.h" -#include "xfa/fde/tto/fde_textout.h" +#include "xfa/fde/cfde_textout.h" #include "xfa/fde/xml/fde_xml_imp.h" #include "xfa/fxfa/app/xfa_ffcheckbutton.h" #include "xfa/fxfa/app/xfa_ffchoicelist.h" diff --git a/xfa/fxfa/app/xfa_fwltheme.cpp b/xfa/fxfa/app/xfa_fwltheme.cpp index b7f23e3e9f..4d5b20e438 100644 --- a/xfa/fxfa/app/xfa_fwltheme.cpp +++ b/xfa/fxfa/app/xfa_fwltheme.cpp @@ -6,7 +6,7 @@ #include "xfa/fxfa/app/xfa_fwltheme.h" -#include "xfa/fde/tto/fde_textout.h" +#include "xfa/fde/cfde_textout.h" #include "xfa/fgas/crt/fgas_codepage.h" #include "xfa/fgas/font/cfgas_gefont.h" #include "xfa/fwl/cfwl_barcode.h" diff --git a/xfa/fxfa/cxfa_widgetacc.cpp b/xfa/fxfa/cxfa_widgetacc.cpp index 863ab83e73..9fee6bd238 100644 --- a/xfa/fxfa/cxfa_widgetacc.cpp +++ b/xfa/fxfa/cxfa_widgetacc.cpp @@ -10,7 +10,7 @@ #include #include "third_party/base/stl_util.h" -#include "xfa/fde/tto/fde_textout.h" +#include "xfa/fde/cfde_textout.h" #include "xfa/fde/xml/fde_xml_imp.h" #include "xfa/fxfa/app/cxfa_textlayout.h" #include "xfa/fxfa/app/xfa_ffwidgetacc.h" -- cgit v1.2.3