Files
msime-windows/experiments/tsf-edit-control/src/TextLayout.h
T
2026-06-11 15:55:59 +08:00

156 lines
3.8 KiB
C++

#pragma once
#include <Windows.h>
#include <d2d1.h>
#include <dwrite.h>
#include <msctf.h>
typedef struct
{
UINT nStart;
UINT nEnd;
TF_DISPLAYATTRIBUTE da;
} COMPOSITIONRENDERINFO;
//----------------------------------------------------------------
//
//
//
//----------------------------------------------------------------
struct CHARINFO
{
D2D1_RECT_F rc;
FLOAT GetWidth()
{
return rc.right - rc.left;
}
};
//----------------------------------------------------------------
//
//
//
//----------------------------------------------------------------
typedef struct
{
UINT nPos;
UINT nCnt;
CHARINFO *prgCharInfo;
} LINEINFO;
//----------------------------------------------------------------
//
//
//
//----------------------------------------------------------------
class CTextLayout
{
public:
CTextLayout()
{
_pDWriteFactory = NULL;
_pTextFormat = NULL;
_pTextLayout = NULL;
_prgLines = NULL;
_nLineCnt = 0;
_fInterimCaret = FALSE;
_fCaretVisible = TRUE;
_layoutWidth = 0.0f;
_nLineHeight = 0;
_lineHeightDips = 0.0f;
_dpiX = 96.0f;
_dpiY = 96.0f;
_paddingLeftDips = 0.0f;
_paddingTopDips = 0.0f;
_paddingRightDips = 0.0f;
_paddingBottomDips = 0.0f;
_rcCaret = D2D1::RectF();
}
~CTextLayout()
{
Clear();
if (_pTextFormat)
{
_pTextFormat->Release();
}
if (_pDWriteFactory)
{
_pDWriteFactory->Release();
}
}
BOOL Initialize(IDWriteFactory *pDWriteFactory);
BOOL Layout(const WCHAR *psz, UINT nCnt, const LOGFONT *plf, FLOAT layoutWidthPixels, FLOAT dpiX, FLOAT dpiY);
BOOL Render(ID2D1HwndRenderTarget *pRenderTarget, const WCHAR *psz, UINT nCnt, UINT nSelStart, UINT nSelEnd,
const COMPOSITIONRENDERINFO *pCompositionRenderInfo, UINT nCompositionRenderInfo);
BOOL RectFromCharPos(UINT nPos, RECT *prc);
UINT CharPosFromPoint(POINT pt);
UINT ExactCharPosFromPoint(POINT pt);
UINT FineFirstEndCharPosInLine(UINT uCurPos, BOOL bFirst);
void ToggleCaretBlink();
void ResetCaretBlink();
void SetInterimCaret(BOOL fSet, UINT uPos);
BOOL IsInterimCaret()
{
return _fInterimCaret;
}
LONG GetPaddingLeftPixels() const
{
return DipsToPixelsX(_paddingLeftDips);
}
LONG GetPaddingTopPixels() const
{
return DipsToPixelsY(_paddingTopDips);
}
LONG GetPaddingRightPixels() const
{
return DipsToPixelsX(_paddingRightDips);
}
LONG GetPaddingBottomPixels() const
{
return DipsToPixelsY(_paddingBottomDips);
}
int GetLineHeight()
{
return _nLineHeight;
}
private:
BOOL EnsureTextFormat(const LOGFONT *plf, FLOAT dpiY);
BOOL RectFromCharPosDips(UINT nPos, D2D1_RECT_F *prc);
FLOAT PixelsToDipsX(FLOAT value) const;
FLOAT PixelsToDipsY(FLOAT value) const;
LONG DipsToPixelsX(FLOAT value) const;
LONG DipsToPixelsY(FLOAT value) const;
void DrawUnderline(ID2D1HwndRenderTarget *pRenderTarget, const TF_DISPLAYATTRIBUTE *pda, const D2D1_RECT_F &rc,
BOOL bClause);
D2D1_COLOR_F GetAttributeColor(const TF_DA_COLOR *pdac, COLORREF fallbackColor);
D2D1_COLOR_F ToColorF(COLORREF color);
void Clear();
IDWriteFactory *_pDWriteFactory;
IDWriteTextFormat *_pTextFormat;
IDWriteTextLayout *_pTextLayout;
int _nLineHeight;
FLOAT _lineHeightDips;
FLOAT _layoutWidth;
FLOAT _dpiX;
FLOAT _dpiY;
FLOAT _paddingLeftDips;
FLOAT _paddingTopDips;
FLOAT _paddingRightDips;
FLOAT _paddingBottomDips;
LINEINFO *_prgLines;
UINT _nLineCnt;
BOOL _fInterimCaret;
BOOL _fCaretVisible;
D2D1_RECT_F _rcCaret;
};