/** * @file XTPSyntaxEditDrawTextProcessor.h * * @copyright * (c) 1998-2025 Codejock Software, All Rights Reserved. * * This source file is the property of Codejock Software and must not be * redistributed by any means without the explicit written permission of * Codejock Software. * * The use of this source code is governed by the terms and conditions specified * in the Toolkit Pro license agreement. Codejock Software grants you, as a * single software developer, the limited right to use this software on one * computer only. * * Contact Information: * support@codejock.com * http://www.codejock.com * */ /** @cond */ #if !defined(__XTPSYNTAXEDITDRAWTEXTPROCESSOR_H__) # define __XTPSYNTAXEDITDRAWTEXTPROCESSOR_H__ /** @endcond */ # if _MSC_VER > 1000 # pragma once # endif // _MSC_VER > 1000 # include "Common/Base/Diagnostic/XTPDisableNoisyWarnings.h" /** @cond */ template class CXTPReserveArray : protected CArray { typedef CArray Parent; protected: int m_nDataSize; public: CXTPReserveArray() { m_nDataSize = 0; } int GetDataSize() const { return m_nDataSize; } void SetDataSize(int nDataSize, int nReservedSize = -1, int nGrowBy = -1) { _ASSERTE(nReservedSize == -1 || nReservedSize >= nDataSize); nReservedSize = max(nReservedSize, nDataSize); m_nDataSize = nDataSize; CArray::SetSize(nReservedSize, nGrowBy); } void AddData(ARG_TYPE newElement) { CArray::SetAtGrow(m_nDataSize, newElement); m_nDataSize++; } void RemoveAll() { m_nDataSize = 0; } TYPE operator[](int nIndex) const { _ASSERTE(nIndex >= 0 && nIndex < GetDataSize()); return CArray::GetAt(nIndex); } TYPE& operator[](int nIndex) { _ASSERTE(nIndex >= 0 && nIndex < GetDataSize()); return CArray::ElementAt(nIndex); } // Direct Access to the element data (may return NULL) const TYPE* GetData() const { return CArray::GetData(); } TYPE* GetData() { return CArray::GetData(); } }; /** @endcond */ /** * @brief * This helper class is used by CXTPSyntaxEditCtrl as the Draw Text Processor. * It is responsible for both drawing chars and remembering each char position * and other text properties. */ class _XTP_EXT_CLASS CXTPSyntaxEditDrawTextProcessor { public: /** * @brief * Default object constructor. */ CXTPSyntaxEditDrawTextProcessor(); /** * @brief * Gets the text rectangle. * @return * The text rectangle. * @see * SetTextRect */ CRect GetTextRect() const; /** * @brief * Sets the text rectangle. * @param rcRect [in] Rectangle to be set. * @see * GetTextRect */ void SetTextRect(const CRect& rcRect); /** * @brief * Gets the height of a single row. * @return * The height of a single row. * @see * RecalcRowHeight */ int GetRowHeight() const; /** * @brief * Recalculates the height of a single row. * @param pDC [in] Pointer to the device context. * @param pFont [in] Pointer to the font to calculate. * @return * The height of a single row. * @see * GetRowHeight */ int RecalcRowHeight(CDC* pDC, CFont* pFont); /** * @brief * Gets the number of visible rows for the text rectangle. * @param bWithPartlyVisible TRUE to count both partly and fully visible rows, * FALSE to only count fully visible rows. * @return * The number of visible rows for the text rectangle. * @see * SetTextRect */ int GetRowsCount(BOOL bWithPartlyVisible) const; /** * @brief * Gets the tab size. * @return * The tab size. * @see * SetTabSize */ int GetTabSize() const; /** * @brief * Sets the tab size. * @param nTabSize [in] Tab size to be set. * @details * Size is measured in space characters and should be between 2 to 10. * @see * GetTabSize */ void SetTabSize(int nTabSize); /** * @brief * Gets the scroll offset for the x- coordinate. * @return * The scroll offset for the x- coordinate. * @see * SetScrollXOffset */ int GetScrollXOffset() const; /** * @brief * Sets the scroll offset for the x- coordinate. * @param nOffsetX [in] Scroll offset to be set. * @see * GetScrollXOffset */ void SetScrollXOffset(int nOffsetX); /** * @brief * Gets the current text metrics. * @return * A reference to the current text metrics. * @see * RecalcRowHeight */ const TEXTMETRIC& GetTextMetrics() const; /** * @brief * Gets the space character width, in pixels. * @return * The space character width, in pixels. * @see * RecalcRowHeight */ int GetSpaceWidth() const; /** * @brief * Aligns a specified column index to tab borders. * @param nRow Zero-based row index. * @param nCol Zero-based column index. * @param bVirtualSpace TRUE if virtual space is enabled, otherwise FALSE. * @return * The aligned column index. * @see * SetTabSize, GetTabSize */ int AlignColIdxToTabs(int nRow, int nCol, BOOL bVirtualSpace = FALSE); /** * @brief * Gets the starting x- position of a specified column. * @param nRow [in] Zero-based row index. * @param nCol [in] Zero-based column index. * @param pnCharWidth [out] Pointer to an integer to receive the * character width of the column (in pixels). * The value of this parameter may be NULL. * @param bVirtualSpace [in] TRUE if virtual space is enabled, otherwise FALSE. * @return * The starting x-position (in pixels) of the specified column. * @see * ColFromXPos */ int GetColPosX(int nRow, int nCol, int* pnCharWidth = NULL, BOOL bVirtualSpace = FALSE) const; /** * @brief * Gets the column at a specified x- position. * @param nRow [in] Zero-based row index. * @param nX [in] x- position (in pixels). * @param rnCol [out] Reference to an integer to receive the * index of the column at the specified x- position. * @param bVirtualSpace [in] TRUE if virtual space is enabled, otherwise FALSE. * @return * TRUE if successful, otherwise FALSE. * @see * GetColPosX, AlignColIdxToTabs */ BOOL ColFromXPos(int nRow, int nX, int& rnCol, BOOL bVirtualSpace = FALSE) const; /** * @brief * Retrieves the width (in pixels) of a specified row. * @param nRow Zero-based index of the row with the width to retrieve. * @return * The width (in pixels) of the specified row. * @see * GetRowsMaxWidth */ int GetRowWidth(int nRow) const; /** * @brief * Gets the maximum width (in pixels) of all visible rows. * @return * The maximum width (in pixels) of all visible rows. * @see * GetRowsWidth */ int GetRowsMaxWidth() const; /** * @brief * Gets the row and column, if any, at a specified point. * @param pt [in] Point to be tested. * @param rnRow [out] Reference to an integer to receive * the index of the row at the specified point. * @param rnCol [out] Reference to an integer to receive * the index of the column at the specified point. * @param bVirtualSpace [in] TRUE if virtual space is enabled, otherwise FALSE. * @return * TRUE if successful, otherwise FALSE. * @see * GetColPosX, HitTestRow. */ BOOL HitTest(const CPoint& pt, int& rnRow, int& rnCol, BOOL bVirtualSpace = FALSE) const; /** * @brief * Gets the row, if any, at a specified y- position. * @param nY [in] y- position (in pixels). * @param rnRow [out] Reference to an integer to receive * the index of the row at the specified y- position. * @return * TRUE if successful, otherwise FALSE. * @see * GetColPosX, HitTest. */ BOOL HitTestRow(int nY, int& rnRow) const; /** * @brief * Clears the cached row information of a specified row. * @param nRow Zero-based row index. * @see * DrawRowPart, PrintRowPart. */ void ResetRowInfo(int nRow); /** * @brief * Draws the row part and stores character positions. * @param pDC [in] Pointer to a valid device context. * @param nRow [in] Zero-based row index (or a value of -1 to * switch to finishing the current row drawing). * @param pcszText [in] String to draw. * @param nchCount [in] Character count to draw. * @return * The x- offset of the next row part. * @see * PrintRowPart */ int DrawRowPart(CDC* pDC, int nRow, LPCTSTR pcszText, int nchCount = -1); /** * @brief * Use this member function to draw row part and store characters positions. * @param pDC [in] Pointer to a valid device context. * @param nRow [in] Zero-based row index (or a value of -1 to * switch to finishing the current row drawing). * @param nPosY [in] y- offset to print the specified row. * @param nFlags [in] Additional printing options. * The following values are supported: * DT_CALCRECT, DT_SINGLELINE, DT_WORDBREAK * @param pcszText [in] String to draw. * @param nchCount [in] Character count to draw. * @param pnPrintedTextLen [out] Pointer to an integer to receive * the printed text length. * @return * The printed row height. * @see * DrawRowPart */ int PrintRowPart(CDC* pDC, int nRow, int nPosY, UINT nFlags, LPCTSTR pcszText, int nchCount = -1, int* pnPrintedTextLen = NULL); /** * @brief * Expands the character set by putting spaces in the position of tabs. * @param pszChars [in] Text to be processed. * @param strBuffer [out] Buffer for text to be created after expansion. * @param nDispPos [in] Start display position. * @param bEnableWhiteSpace [in] TRUE to show white space, FALSE otherwise. * @return * The end display position after expansion. */ int ExpandChars(LPCTSTR pszChars, CString& strBuffer, int nDispPos = 0, BOOL bEnableWhiteSpace = FALSE); /** * @brief * Sets the tab positions for a specified row. * @param nRow [in] Zero-based row index. * @param pcszOrigRowText [in] Row text (not expanded). */ void SetRowTabPositions(int nRow, LPCTSTR pcszOrigRowText); /** * @brief * Converts display position to string position. * @param nRow Zero-based row index. * @param nDispPos Zero-based display column index. * @param bVirtualSpace TRUE if virtual space is enabled, otherwise FALSE. * @return * The converted string position. */ int DispPosToStrPos(int nRow, int nDispPos, BOOL bVirtualSpace) const; /** * @brief * Converts string position to display position. * @param nRow Zero-based row index. * @param nStrPos Zero-based string position. * @param bVirtualSpace TRUE if virtual space is enabled, otherwise FALSE. * @return * The converted display position. */ int StrPosToDispPos(int nRow, int nStrPos, BOOL bVirtualSpace = FALSE) const; /** * @brief * Sets the caret position. * @param pWnd [in] Pointer to the caret owner window. * @param szSize [in] Reference to the caret size. * @param nRow [in] Zero-based row index. * @param rnCol [in, out] Reference to the zero-based column index. * @param bHideCaret [in] TRUE to hide the caret, FALSE to show the caret. * @param bVirtualSpace [in] TRUE if virtual space is enabled, otherwise FALSE. * @details * The [in, out] parameters rnCol and rnRow may be adjusted to valid values. * @return * The point of the caret position. */ CPoint SetCaretPos(CWnd* pWnd, const CSize& szSize, int nRow, int& rnCol, BOOL bHideCaret = FALSE, BOOL bVirtualSpace = FALSE); /** * @brief * Sets the caret position. * @param pWnd [in] Pointer to the caret owner window. * @param pt [in] Reference to the point to set the caret. * @param szSize [in] Reference to the caret size. * @param rnRow [in, out] Reference to the zero-based row index. * @param rnCol [in, out] Reference to the zero-based column index. * @param bVirtualSpace [in] TRUE if virtual space is enabled, otherwise FALSE. * @details * The [in, out] parameters rnCol and rnRow may be adjusted to valid values. * @return * The point of the caret position. */ CPoint SetCaretByPoint(CWnd* pWnd, const CPoint& pt, const CSize& szSize, int& rnRow, int& rnCol, BOOL bVirtualSpace = FALSE); public: /** @cond */ class _XTP_EXT_CLASS CXTPRowInfo : public CXTPCmdTarget { public: CXTPRowInfo() { nMaxWidth = 0; const int cnReservedSize = 4096; arCharsEnds.SetDataSize(0, cnReservedSize, cnReservedSize); arTabs.SetDataSize(0, cnReservedSize, cnReservedSize); arDispCol2StrPos.SetDataSize(0, cnReservedSize, cnReservedSize); arStrPos2DispCol.SetDataSize(0, cnReservedSize, cnReservedSize); } void Reset() { nMaxWidth = 0; arCharsEnds.RemoveAll(); } int nMaxWidth; CXTPReserveArray arCharsEnds; CXTPReserveArray arTabs; CXTPReserveArray arDispCol2StrPos; CXTPReserveArray arStrPos2DispCol; }; CXTPRowInfo* GetRowInfo(int nRow) const; /** @endcond */ private: void DrawTextOfSize(CDC* pDC, int nX, int nY, const SIZE& textSize, const RECT& rcText, LPCTSTR pcszText, int nchCount) const; protected: int m_nTabSize; /**< Tab size. */ TEXTMETRIC m_tmText; /**< Text metrics. */ int m_nSpaceWidth; /**< Space character width. */ CRect m_rcTextRect; /**< Text rectangle. */ int m_nRowHeight; /**< Row height. */ int m_nScrollXOffset; /**< Scroll offset for the x- coordinate. */ int m_nDrawingRow; /**< Currently drawing row. */ int m_nNextRowPosX; /**< x- offset to draw the next row part. */ int m_nPrintingRow; /**< Currently printing row. */ CPoint m_ptNextPrintPos; /**< x- and y- offset to print the next row part. */ BOOL m_bUseOutputDC; /**< TRUE to use the output DC for calculations. */ /** @cond */ typedef CXTPInternalCollectionT CXTPRowsInfoArray; /**< */ mutable CXTPRowsInfoArray m_arRows; /** @endcond */ protected: /** @cond */ // temporary buffers CArray m_arBuf_aDx; CXTPReserveArray m_arExpandCharsBuffer; /** @endcond */ }; AFX_INLINE const TEXTMETRIC& CXTPSyntaxEditDrawTextProcessor::GetTextMetrics() const { return m_tmText; } AFX_INLINE CRect CXTPSyntaxEditDrawTextProcessor::GetTextRect() const { return m_rcTextRect; } AFX_INLINE void CXTPSyntaxEditDrawTextProcessor::SetTextRect(const CRect& rcRect) { m_rcTextRect = rcRect; } AFX_INLINE int CXTPSyntaxEditDrawTextProcessor::GetRowHeight() const { return m_nRowHeight; } AFX_INLINE int CXTPSyntaxEditDrawTextProcessor::GetTabSize() const { return m_nTabSize; } AFX_INLINE void CXTPSyntaxEditDrawTextProcessor::SetTabSize(int nTabSize) { m_nTabSize = nTabSize; } AFX_INLINE int CXTPSyntaxEditDrawTextProcessor::GetScrollXOffset() const { return m_nScrollXOffset; } AFX_INLINE int CXTPSyntaxEditDrawTextProcessor::GetRowsCount(BOOL bWithPartlyVisible) const { int nHeight = m_rcTextRect.Height(); int nRowH = max(1, m_nRowHeight); int nPartly = bWithPartlyVisible ? 1 : 0; return nHeight / nRowH + ((nHeight % nRowH) ? nPartly : 0); } AFX_INLINE int CXTPSyntaxEditDrawTextProcessor::GetSpaceWidth() const { return m_nSpaceWidth; } # include "Common/Base/Diagnostic/XTPEnableNoisyWarnings.h" /** @cond */ #endif // !defined(__XTPSYNTAXEDITDRAWTEXTPROCESSOR_H__) /** @endcond */