From 4283465f23806ae4b8ad7344949f55698c16a203 Mon Sep 17 00:00:00 2001 From: watcherhd Date: Thu, 21 Apr 2011 20:19:47 +0000 Subject: MTextControl - text render API for different plugins git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@12 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- mTextControl/src/fancy_rtf.cpp | 179 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 mTextControl/src/fancy_rtf.cpp (limited to 'mTextControl/src/fancy_rtf.cpp') diff --git a/mTextControl/src/fancy_rtf.cpp b/mTextControl/src/fancy_rtf.cpp new file mode 100644 index 0000000..01ad6bc --- /dev/null +++ b/mTextControl/src/fancy_rtf.cpp @@ -0,0 +1,179 @@ +#include "headers.h" + +struct BBCodeInfo +{ + TCHAR *start; + TCHAR *end; + bool (* func)(IFormattedTextDraw *ftd, CHARRANGE range, TCHAR *txt, DWORD cookie); + DWORD cookie; +}; + +enum { BBS_BOLD_S, BBS_BOLD_E, BBS_ITALIC_S, BBS_ITALIC_E, BBS_UNDERLINE_S, BBS_UNDERLINE_E, + BBS_STRIKEOUT_S, BBS_STRIKEOUT_E, BBS_COLOR_S, BBS_COLOR_E, BBS_URL1, BBS_URL2, + BBS_IMG1, BBS_IMG2 }; + +static bool bbCodeSimpleFunc(IFormattedTextDraw *ftd, CHARRANGE range, TCHAR *txt, DWORD cookie) +{ + CHARFORMAT cf = {0}; + cf.cbSize = sizeof(cf); + switch (cookie) + { + case BBS_BOLD_S: + cf.dwMask = CFM_BOLD; + cf.dwEffects = CFE_BOLD; + break; + case BBS_BOLD_E: + cf.dwMask = CFM_BOLD; + break; + case BBS_ITALIC_S: + cf.dwMask = CFM_ITALIC; + cf.dwEffects = CFE_ITALIC; + break; + case BBS_ITALIC_E: + cf.dwMask = CFM_ITALIC; + break; + case BBS_UNDERLINE_S: + cf.dwMask = CFM_UNDERLINE; + cf.dwEffects = CFE_UNDERLINE; + break; + case BBS_UNDERLINE_E: + cf.dwMask = CFM_UNDERLINE; + break; + case BBS_STRIKEOUT_S: + cf.dwMask = CFM_STRIKEOUT; + cf.dwEffects = CFE_STRIKEOUT; + break; + case BBS_STRIKEOUT_E: + cf.dwMask = CFM_STRIKEOUT; + break; + } + + ITextServices *ts = ftd->getTextService(); + + LRESULT lResult; + ts->TxSendMessage(EM_SETSEL, range.cpMin, -1, &lResult); + ts->TxSendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf, &lResult); + ts->TxSendMessage(EM_SETSEL, range.cpMin, range.cpMax, &lResult); + ts->TxSendMessage(EM_REPLACESEL, FALSE, (LPARAM)_T(""), &lResult); + + return true; +} + +static bool bbCodeImageFunc(IFormattedTextDraw *ftd, CHARRANGE range, TCHAR *txt, DWORD cookie) +{ + ITextServices *ts = ftd->getTextService(); + ITextDocument *td = ftd->getTextDocument(); + + long cnt; + LRESULT lResult; +/* + TEXTRANGE trg; + trg.chrg = range; + trg.lpstrText = new TCHAR[trg.chrg.cpMax - trg.chrg.cpMin + 1]; + ts->TxSendMessage(EM_GETTEXTRANGE, 0, (LPARAM)&trg, &lResult); + MessageBox(0, txt, trg.lpstrText, MB_OK); +*/ + ts->TxSendMessage(EM_SETSEL, range.cpMin, range.cpMax, &lResult); + IRichEditOle* RichEditOle; + ts->TxSendMessage(EM_GETOLEINTERFACE, 0, (LPARAM)&RichEditOle, &lResult); + td->Freeze(&cnt); +// HDC emfdc = CreateEnhMetaFile(NULL, NULL, NULL, _T("icon")); +// DrawIconEx(emfdc, 0, 0, (HICON)_ttol(txt), 16, 16, 0, NULL, DI_NORMAL); +// InsertBitmap(RichEditOle, CloseEnhMetaFile(emfdc)); +#ifdef _WIN64 + bool res = InsertBitmap(RichEditOle, CacheIconToEmf((HICON)_tstoi64(txt))); +#else + bool res = InsertBitmap(RichEditOle, CacheIconToEmf((HICON)_ttoi(txt))); +#endif + + td->Unfreeze(&cnt); + RichEditOle->Release(); + return res; +} + +static BBCodeInfo bbCodes[] = +{ + { _T("[b]"), 0, bbCodeSimpleFunc, BBS_BOLD_S }, + { _T("[/b]"), 0, bbCodeSimpleFunc, BBS_BOLD_E }, + { _T("[i]"), 0, bbCodeSimpleFunc, BBS_ITALIC_S }, + { _T("[/i]"), 0, bbCodeSimpleFunc, BBS_ITALIC_E }, + { _T("[u]"), 0, bbCodeSimpleFunc, BBS_UNDERLINE_S }, + { _T("[/u]"), 0, bbCodeSimpleFunc, BBS_UNDERLINE_E }, + { _T("[s]"), 0, bbCodeSimpleFunc, BBS_STRIKEOUT_S }, + { _T("[/s]"), 0, bbCodeSimpleFunc, BBS_STRIKEOUT_E }, + +// { _T("[color="), _T("]"), bbCodeSimpleFunc, BBS_COLOR_S }, +// { _T("[/color]"), 0, bbCodeSimpleFunc, BBS_COLOR_E } + + { _T("[$hicon="), _T("$]"), bbCodeImageFunc, 0 } + +// { _T("[url]"), _T("[/url]"), bbCodeSimpleFunc, BBS_URL1 }, +// { _T("[url="), _T("]"), bbCodeSimpleFunc, BBS_URL2 }, +// { _T("[url]"), _T("[/url]"), bbCodeSimpleFunc, BBS_IMG1 }, +// { _T("[url="), _T("]"), bbCodeSimpleFunc, BBS_IMG2 }, +}; +static int bbCodeCount = sizeof(bbCodes) / sizeof(*bbCodes); + +void bbCodeParse(IFormattedTextDraw *ftd) +{ + ITextServices *ts = ftd->getTextService(); + LRESULT lResult; + + int pos = 0; + for (bool found = true; found; ) + { + found = false; + CHARRANGE fRange; fRange.cpMin = -1; + TCHAR *fText = 0; + BBCodeInfo *fBBCode; + + for (int i = 0; i < bbCodeCount; i++) + { + CHARRANGE range; + + FINDTEXTEX fte; + fte.chrg.cpMin = pos; + fte.chrg.cpMax = -1; + + fte.lpstrText = bbCodes[i].start; + ts->TxSendMessage(EM_FINDTEXTEX, (WPARAM)FR_DOWN, (LPARAM)&fte, &lResult); + if (lResult == -1) + continue; + range = fte.chrgText; + + if (bbCodes[i].end) + { + fte.chrg.cpMin = fte.chrgText.cpMax; + fte.lpstrText = bbCodes[i].end; + ts->TxSendMessage(EM_FINDTEXTEX, (WPARAM)FR_DOWN, (LPARAM)&fte, &lResult); + if (lResult == -1) + continue; + range.cpMax = fte.chrgText.cpMax; + } + + if ((fRange.cpMin == -1) || (fRange.cpMin > range.cpMin)) + { + fRange = range; + fBBCode = bbCodes+i; + found = true; + + if (fText) delete [] fText; + if (bbCodes[i].end) + { + TEXTRANGE trg; + trg.chrg.cpMin = fte.chrg.cpMin; + trg.chrg.cpMax = fte.chrgText.cpMin; + trg.lpstrText = new TCHAR[trg.chrg.cpMax - trg.chrg.cpMin + 1]; + ts->TxSendMessage(EM_GETTEXTRANGE, 0, (LPARAM)&trg, &lResult); + fText = trg.lpstrText; + } + } + } + + if (found) + { + found = fBBCode->func(ftd, fRange, fText, fBBCode->cookie); + if (fText) delete [] fText; + } + } +} -- cgit v1.2.3