summaryrefslogtreecommitdiff
path: root/libs/mTextControl
diff options
context:
space:
mode:
Diffstat (limited to 'libs/mTextControl')
-rw-r--r--libs/mTextControl/src/FormattedTextDraw.cpp196
-rw-r--r--libs/mTextControl/src/FormattedTextDraw.h8
-rw-r--r--libs/mTextControl/src/services.cpp5
3 files changed, 115 insertions, 94 deletions
diff --git a/libs/mTextControl/src/FormattedTextDraw.cpp b/libs/mTextControl/src/FormattedTextDraw.cpp
index f18833bd25..8a074430fc 100644
--- a/libs/mTextControl/src/FormattedTextDraw.cpp
+++ b/libs/mTextControl/src/FormattedTextDraw.cpp
@@ -22,43 +22,6 @@ const IID IID_ITextDocument = {
};
/////////////////////////////////////////////////////////////////////////////
-// CallBack functions
-
-struct STREAMDATA
-{
- bool isUnicode;
- union
- {
- char *ansi;
- wchar_t *unicode;
- };
- size_t cbSize, cbCount;
-};
-
-static DWORD CALLBACK EditStreamInCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
-{
- STREAMDATA *pCookie = (STREAMDATA *)dwCookie;
- if (pCookie->isUnicode) {
- if ((pCookie->cbSize - pCookie->cbCount) * sizeof(wchar_t) < (size_t)cb)
- *pcb = LONG(pCookie->cbSize - pCookie->cbCount) * sizeof(wchar_t);
- else
- *pcb = cb & ~1UL;
- memcpy(pbBuff, pCookie->unicode + pCookie->cbCount, *pcb);
- pCookie->cbCount += *pcb / sizeof(wchar_t);
- }
- else {
- if (pCookie->cbSize - pCookie->cbCount < (uint32_t)cb)
- *pcb = LONG(pCookie->cbSize - pCookie->cbCount);
- else
- *pcb = cb;
- memcpy(pbBuff, pCookie->ansi + pCookie->cbCount, *pcb);
- pCookie->cbCount += *pcb;
- }
-
- return 0; // callback succeeded - no errors
-}
-
-/////////////////////////////////////////////////////////////////////////////
// CFormattedTextDraw
CFormattedTextDraw::CFormattedTextDraw()
@@ -73,16 +36,12 @@ CFormattedTextDraw::CFormattedTextDraw()
SetRectEmpty(&m_rcClient);
SetRectEmpty(&m_rcViewInset);
- m_pCF = (CHARFORMAT2W *)malloc(sizeof(CHARFORMAT2W));
-
InitDefaultCharFormat();
InitDefaultParaFormat();
m_spTextServices = nullptr;
m_spTextDocument = nullptr;
m_dwPropertyBits = TXTBIT_RICHTEXT | TXTBIT_MULTILINE | TXTBIT_WORDWRAP | TXTBIT_USECURRENTBKG;
- m_dwScrollbar = 0;
- m_dwMaxLength = INFINITE;
IUnknown *spUnk;
HRESULT hr = MyCreateTextServices(nullptr, static_cast<ITextHost *>(this), &spUnk);
@@ -95,51 +54,46 @@ CFormattedTextDraw::CFormattedTextDraw()
CFormattedTextDraw::~CFormattedTextDraw()
{
- free(m_pCF);
if (m_spTextServices != nullptr)
m_spTextServices->Release();
if (m_spTextDocument != nullptr)
m_spTextDocument->Release();
}
-HRESULT CFormattedTextDraw::putRTFTextA(char *newVal)
-{
- if (!m_spTextServices)
- return S_FALSE;
-
- STREAMDATA streamData = {};
- streamData.isUnicode = false;
- streamData.ansi = newVal;
- streamData.cbSize = mir_strlen(newVal);
-
- EDITSTREAM editStream;
- editStream.dwCookie = (DWORD_PTR)&streamData;
- editStream.dwError = 0;
- editStream.pfnCallback = (EDITSTREAMCALLBACK)EditStreamInCallback;
-
- LRESULT lResult = 0;
- m_spTextServices->TxSendMessage(EM_STREAMIN, SF_RTF, (LPARAM)&editStream, &lResult);
- return S_OK;
-}
+/////////////////////////////////////////////////////////////////////////////////////////
-HRESULT CFormattedTextDraw::putRTFTextW(wchar_t *newVal)
+struct STREAMDATATEXT
{
- if (!m_spTextServices)
- return S_FALSE;
-
- STREAMDATA streamData = {};
- streamData.isUnicode = true;
- streamData.unicode = newVal;
- streamData.cbSize = mir_wstrlen(newVal);
+ bool isUnicode;
+ union
+ {
+ char *ansi;
+ wchar_t *unicode;
+ };
+ size_t cbSize, cbCount;
+};
- EDITSTREAM editStream;
- editStream.dwCookie = (DWORD_PTR)&streamData;
- editStream.dwError = 0;
- editStream.pfnCallback = (EDITSTREAMCALLBACK)EditStreamInCallback;
+static DWORD CALLBACK EditStreamTextInCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
+{
+ auto *pCookie = (STREAMDATATEXT *)dwCookie;
+ if (pCookie->isUnicode) {
+ if ((pCookie->cbSize - pCookie->cbCount) * sizeof(wchar_t) < (size_t)cb)
+ *pcb = LONG(pCookie->cbSize - pCookie->cbCount) * sizeof(wchar_t);
+ else
+ *pcb = cb & ~1UL;
+ memcpy(pbBuff, pCookie->unicode + pCookie->cbCount, *pcb);
+ pCookie->cbCount += *pcb / sizeof(wchar_t);
+ }
+ else {
+ if (pCookie->cbSize - pCookie->cbCount < (uint32_t)cb)
+ *pcb = LONG(pCookie->cbSize - pCookie->cbCount);
+ else
+ *pcb = cb;
+ memcpy(pbBuff, pCookie->ansi + pCookie->cbCount, *pcb);
+ pCookie->cbCount += *pcb;
+ }
- LRESULT lResult = 0;
- m_spTextServices->TxSendMessage(EM_STREAMIN, SF_RTF | SF_UNICODE, (LPARAM)&editStream, &lResult);
- return S_OK;
+ return 0; // callback succeeded - no errors
}
HRESULT CFormattedTextDraw::putTextA(char *newVal)
@@ -147,7 +101,7 @@ HRESULT CFormattedTextDraw::putTextA(char *newVal)
if (!m_spTextServices)
return S_FALSE;
- STREAMDATA streamData = {};
+ STREAMDATATEXT streamData = {};
streamData.isUnicode = false;
streamData.ansi = newVal;
streamData.cbSize = mir_strlen(newVal);
@@ -155,7 +109,7 @@ HRESULT CFormattedTextDraw::putTextA(char *newVal)
EDITSTREAM editStream;
editStream.dwCookie = (DWORD_PTR)&streamData;
editStream.dwError = 0;
- editStream.pfnCallback = (EDITSTREAMCALLBACK)EditStreamInCallback;
+ editStream.pfnCallback = EditStreamTextInCallback;
LRESULT lResult = 0;
m_spTextServices->TxSendMessage(EM_STREAMIN, SF_TEXT, (LPARAM)&editStream, &lResult);
@@ -175,7 +129,7 @@ HRESULT CFormattedTextDraw::putTextW(wchar_t *newVal)
if (!m_spTextServices)
return S_FALSE;
- STREAMDATA streamData = {};
+ STREAMDATATEXT streamData = {};
streamData.isUnicode = true;
streamData.unicode = newVal;
streamData.cbSize = mir_wstrlen(newVal);
@@ -183,7 +137,7 @@ HRESULT CFormattedTextDraw::putTextW(wchar_t *newVal)
EDITSTREAM editStream;
editStream.dwCookie = (DWORD_PTR)&streamData;
editStream.dwError = 0;
- editStream.pfnCallback = (EDITSTREAMCALLBACK)EditStreamInCallback;
+ editStream.pfnCallback = EditStreamTextInCallback;
LRESULT lResult = 0;
m_spTextServices->TxSendMessage(EM_STREAMIN, SF_TEXT | SF_UNICODE, (LPARAM)&editStream, &lResult);
@@ -197,6 +151,78 @@ HRESULT CFormattedTextDraw::putTextW(wchar_t *newVal)
return S_OK;
}
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#define STREAMSTAGE_HEADER 0
+#define STREAMSTAGE_EVENTS 1
+#define STREAMSTAGE_TAIL 2
+#define STREAMSTAGE_STOP 3
+
+struct STREAMDATA
+{
+ CMStringA buf;
+ int iStage = STREAMSTAGE_HEADER;
+ MRtfProvider *pProv;
+};
+
+static DWORD CALLBACK EditStreamInCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
+{
+ auto *dat = (STREAMDATA *)dwCookie;
+
+ if (dat->buf.IsEmpty()) {
+ switch (dat->iStage) {
+ case STREAMSTAGE_HEADER:
+ dat->buf = dat->pProv->CreateRtfHeader();
+ dat->iStage = STREAMSTAGE_EVENTS;
+ break;
+
+ case STREAMSTAGE_EVENTS:
+ dat->buf = dat->pProv->CreateRtfBody();
+ dat->iStage = STREAMSTAGE_TAIL;
+ break;
+
+ case STREAMSTAGE_TAIL:
+ dat->buf = dat->pProv->CreateRtfFooter();
+ dat->iStage = STREAMSTAGE_STOP;
+ break;
+
+ case STREAMSTAGE_STOP:
+ *pcb = 0;
+ return 0;
+ }
+ }
+
+ *pcb = min(cb, dat->buf.GetLength());
+ memcpy(pbBuff, dat->buf.GetBuffer(), *pcb);
+ if (dat->buf.GetLength() == *pcb)
+ dat->buf.Empty();
+ else
+ dat->buf.Delete(0, *pcb);
+
+ return 0; // callback succeeded - no errors
+}
+
+HRESULT CFormattedTextDraw::putRTFText(MRtfProvider *pProv)
+{
+ if (!m_spTextServices)
+ return S_FALSE;
+
+ STREAMDATA streamData = {};
+ streamData.pProv = pProv;
+
+ EDITSTREAM editStream;
+ editStream.dwCookie = (DWORD_PTR)&streamData;
+ editStream.dwError = 0;
+ editStream.pfnCallback = EditStreamInCallback;
+
+ LRESULT lResult = 0;
+ m_spTextServices->TxSendMessage(EM_STREAMIN, SF_RTF, (LPARAM)&editStream, &lResult);
+ return S_OK;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Other methods
+
HRESULT CFormattedTextDraw::Draw(HDC hdcDraw, RECT *prc)
{
LOGFONT lf;
@@ -395,7 +421,7 @@ HRESULT CFormattedTextDraw::TxGetViewInset(LPRECT prc)
HRESULT CFormattedTextDraw::TxGetCharFormat(const CHARFORMATW **ppCF)
{
- *ppCF = m_pCF;
+ *ppCF = &m_CF;
return S_OK;
}
@@ -418,13 +444,13 @@ HRESULT CFormattedTextDraw::TxGetBackStyle(TXTBACKSTYLE *pstyle)
HRESULT CFormattedTextDraw::TxGetMaxLength(DWORD *plength)
{
- *plength = m_dwMaxLength;
+ *plength = INFINITE;
return S_OK;
}
HRESULT CFormattedTextDraw::TxGetScrollBars(DWORD *pdwScrollBar)
{
- *pdwScrollBar = m_dwScrollbar;
+ *pdwScrollBar = 0;
return S_OK;
}
@@ -446,7 +472,7 @@ HRESULT CFormattedTextDraw::TxGetExtent(LPSIZEL)
HRESULT CFormattedTextDraw::OnTxCharFormatChange(const CHARFORMATW *pcf)
{
- memcpy(m_pCF, pcf, pcf->cbSize);
+ memcpy(&m_CF, pcf, pcf->cbSize);
return S_OK;
}
@@ -536,7 +562,7 @@ HRESULT CFormattedTextDraw::CharFormatFromHFONT(CHARFORMAT2W *pCF, HFONT hFont)
HRESULT CFormattedTextDraw::InitDefaultCharFormat()
{
- return CharFormatFromHFONT(m_pCF, nullptr);
+ return CharFormatFromHFONT(&m_CF, nullptr);
}
HRESULT CFormattedTextDraw::InitDefaultParaFormat()
diff --git a/libs/mTextControl/src/FormattedTextDraw.h b/libs/mTextControl/src/FormattedTextDraw.h
index cd902e2cae..3ec7a7412e 100644
--- a/libs/mTextControl/src/FormattedTextDraw.h
+++ b/libs/mTextControl/src/FormattedTextDraw.h
@@ -24,11 +24,10 @@ class CFormattedTextDraw : public ITextHost, public MZeroedObject
int nPixelsPerInchX; // Pixels per logical inch along width
int nPixelsPerInchY; // Pixels per logical inch along height
- CHARFORMAT2W *m_pCF;
+ CHARFORMAT2W m_CF;
PARAFORMAT2 m_PF;
- uint32_t m_dwScrollbar; // Scroll bar style
+
uint32_t m_dwPropertyBits; // Property bits
- uint32_t m_dwMaxLength;
ITextServices *m_spTextServices;
ITextDocument *m_spTextDocument;
@@ -39,8 +38,7 @@ public:
HRESULT get_NaturalSize(HDC hdcDraw, long *Width, long *pVal);
HRESULT Draw(HDC hdcDraw, RECT *prc);
- HRESULT putRTFTextA(char *newVal);
- HRESULT putRTFTextW(wchar_t *newVal);
+ HRESULT putRTFText(MRtfProvider *pProv);
HRESULT putTextA(char *newVal);
HRESULT putTextW(wchar_t *newVal);
diff --git a/libs/mTextControl/src/services.cpp b/libs/mTextControl/src/services.cpp
index 4eebeeab22..317646dcbb 100644
--- a/libs/mTextControl/src/services.cpp
+++ b/libs/mTextControl/src/services.cpp
@@ -92,10 +92,7 @@ MTEXTCONTROL_DLL(TextObject *) MTextCreateEx(HANDLE userHandle, void *text, uint
MText_InitFormatting0(result->ftd, result->options);
if (flags & MTEXT_FLG_RTF) {
- if (flags & MTEXT_FLG_WCHAR)
- result->ftd->putRTFTextW((wchar_t *)text);
- else
- result->ftd->putRTFTextA((char *)text);
+ result->ftd->putRTFText((MRtfProvider *)text);
}
else {
if (flags & MTEXT_FLG_WCHAR)