From 210010f8ec3aaa180d29937ca22119fba5ecaeed Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 20 Mar 2024 17:15:58 +0300 Subject: NewStory: first html-based version which looks more or less like RTF version --- plugins/NewStory/NewStory.vcxproj | 30 ++- plugins/NewStory/NewStory.vcxproj.filters | 23 +++ plugins/NewStory/src/dib.cpp | 176 +++++++++++++++++ plugins/NewStory/src/dib.h | 40 ++++ plugins/NewStory/src/history_array.cpp | 118 +++++------- plugins/NewStory/src/history_array.h | 17 +- plugins/NewStory/src/history_control.cpp | 309 ++++++++++++++---------------- plugins/NewStory/src/history_control.h | 30 ++- plugins/NewStory/src/main.cpp | 2 +- plugins/NewStory/src/options.cpp | 13 +- plugins/NewStory/src/stdafx.cxx | 4 +- plugins/NewStory/src/stdafx.h | 18 +- plugins/NewStory/src/templates.cpp | 146 +++++++++++--- plugins/NewStory/src/webpage.cpp | 63 ++++++ 14 files changed, 686 insertions(+), 303 deletions(-) create mode 100644 plugins/NewStory/src/dib.cpp create mode 100644 plugins/NewStory/src/dib.h create mode 100644 plugins/NewStory/src/webpage.cpp (limited to 'plugins') diff --git a/plugins/NewStory/NewStory.vcxproj b/plugins/NewStory/NewStory.vcxproj index cfb8c75c47..9df881d8b1 100644 --- a/plugins/NewStory/NewStory.vcxproj +++ b/plugins/NewStory/NewStory.vcxproj @@ -18,11 +18,6 @@ x64 - - - {e26d2311-c164-48cf-ba24-5ceda873d1b2} - - NewStory {A7FAD273-8C71-4D72-A84F-2D160F2DC589} @@ -30,8 +25,27 @@ + + + .\src;../../libs/litehtml/include;%(AdditionalIncludeDirectories) + 4458;%(DisableSpecificWarnings) + + + + NotUsing + + + NotUsing + + + NotUsing + + + NotUsing + + @@ -39,6 +53,7 @@ + @@ -62,4 +77,9 @@ + + + {51db004a-e160-47c7-b017-bec90fdc442d} + + \ No newline at end of file diff --git a/plugins/NewStory/NewStory.vcxproj.filters b/plugins/NewStory/NewStory.vcxproj.filters index 72e30edc11..83fc3b22e0 100644 --- a/plugins/NewStory/NewStory.vcxproj.filters +++ b/plugins/NewStory/NewStory.vcxproj.filters @@ -41,6 +41,24 @@ Source Files + + Source Files\Litehtml + + + Source Files\Litehtml + + + Source Files\Litehtml + + + Source Files\Litehtml + + + Source Files\Litehtml + + + Source Files\Litehtml + @@ -85,4 +103,9 @@ Resource Files + + + {b1a3b930-2ec1-4ee0-8a76-0d65fecddd00} + + \ No newline at end of file diff --git a/plugins/NewStory/src/dib.cpp b/plugins/NewStory/src/dib.cpp new file mode 100644 index 0000000000..c54ef944fa --- /dev/null +++ b/plugins/NewStory/src/dib.cpp @@ -0,0 +1,176 @@ +#include "stdafx.h" + +simpledib::dib::dib() +{ + memset(this, 0, sizeof(*this)); +} + +simpledib::dib::~dib() +{ + destroy(); +} + +void simpledib::dib::destroy(bool del_bmp) +{ + if (m_hdc && m_ownData) { + SelectObject(m_hdc, m_oldBmp); + if (del_bmp) + DeleteObject(m_bmp); + DeleteDC(m_hdc); + } + else if (m_restore_view_port && m_hdc) { + ::SetWindowOrgEx(m_hdc, m_oldViewPort.x, m_oldViewPort.y, NULL); + } + + memset(this, 0, sizeof(*this)); +} + +bool simpledib::dib::create(int width, int height, bool topdowndib) +{ + destroy(); + + BITMAPINFO bmp_info; + bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmp_info.bmiHeader.biWidth = width; + bmp_info.bmiHeader.biHeight = height * (topdowndib ? -1 : 1); + bmp_info.bmiHeader.biPlanes = 1; + bmp_info.bmiHeader.biBitCount = 32; + bmp_info.bmiHeader.biCompression = BI_RGB; + bmp_info.bmiHeader.biSizeImage = 0; + bmp_info.bmiHeader.biXPelsPerMeter = 0; + bmp_info.bmiHeader.biYPelsPerMeter = 0; + bmp_info.bmiHeader.biClrUsed = 0; + bmp_info.bmiHeader.biClrImportant = 0; + + m_hdc = CreateCompatibleDC(NULL); + + m_bmp = ::CreateDIBSection(m_hdc, &bmp_info, DIB_RGB_COLORS, (LPVOID *)&m_bits, 0, 0); + if (m_bits && m_bmp) { + m_oldBmp = (HBITMAP)::SelectObject(m_hdc, m_bmp); + } + else { + DeleteDC(m_hdc); + m_hdc = nullptr; + } + + if (!m_hdc) + return false; + + m_width = width; + m_height = height; + m_ownData = true; + return true; +} + +/* +bool simpledib::dib::create( HDC hdc, HBITMAP bmp, LPRGBQUAD bits, int width, int height, int shift_x, int shift_y ) +{ + destroy(); + + m_bmp = bmp; + m_hdc = hdc; + m_bits = bits; + m_width = width; + m_height = height; + m_ownData = FALSE; + + SetWindowOrgEx(m_hdc, -shift_x, -shift_y, &m_oldViewPort); + m_restore_view_port = TRUE; + return true; +} + +*/ +bool simpledib::dib::create(HDC hdc, HBITMAP bmp, LPRGBQUAD bits, int width, int height) +{ + destroy(); + + m_bmp = bmp; + m_hdc = hdc; + m_bits = bits; + m_width = width; + m_height = height; + m_ownData = m_restore_view_port = false; + return true; +} + +void simpledib::dib::clear() +{ + if (m_bits) + memset(m_bits, 0, m_width * m_height * 4); +} + +void simpledib::dib::draw(HDC hdc, int x, int y) +{ + BLENDFUNCTION bf; + bf.BlendOp = AC_SRC_OVER; + bf.BlendFlags = 0; + bf.AlphaFormat = AC_SRC_ALPHA; + bf.SourceConstantAlpha = 255; + + AlphaBlend(hdc, x, y, m_width, m_height, m_hdc, 0, 0, m_width, m_height, bf); +} + +void simpledib::dib::draw(HDC hdc, LPRECT rcDraw) +{ + BLENDFUNCTION bf; + bf.BlendOp = AC_SRC_OVER; + bf.BlendFlags = 0; + bf.AlphaFormat = AC_SRC_ALPHA; + bf.SourceConstantAlpha = 255; + + AlphaBlend(hdc, + rcDraw->left, rcDraw->top, + rcDraw->right - rcDraw->left, + rcDraw->bottom - rcDraw->top, m_hdc, + + rcDraw->left, rcDraw->top, + rcDraw->right - rcDraw->left, + rcDraw->bottom - rcDraw->top, + bf); +} + +HDC simpledib::dib::beginPaint(HDC hdc, LPRECT rcDraw) +{ + if (!create(rcDraw->right - rcDraw->left, rcDraw->bottom - rcDraw->top, true)) + return nullptr; + + m_hTargetDC = hdc; + m_rcTarget = *rcDraw; + SetWindowOrgEx(m_hdc, rcDraw->left, rcDraw->top, &m_oldViewPort); + return m_hdc; +} + +void simpledib::dib::endPaint(bool copy) +{ + SetWindowOrgEx(m_hdc, m_oldViewPort.x, m_oldViewPort.y, NULL); + + if (!copy) { + BLENDFUNCTION bf = {}; + bf.BlendOp = AC_SRC_OVER; + bf.AlphaFormat = AC_SRC_ALPHA; + bf.SourceConstantAlpha = 255; + + AlphaBlend(m_hTargetDC, m_rcTarget.left, m_rcTarget.top, + m_rcTarget.right - m_rcTarget.left, + m_rcTarget.bottom - m_rcTarget.top, m_hdc, + 0, 0, + m_rcTarget.right - m_rcTarget.left, + m_rcTarget.bottom - m_rcTarget.top, + bf); + } + else { + BitBlt(m_hTargetDC, m_rcTarget.left, m_rcTarget.top, + m_rcTarget.right - m_rcTarget.left, + m_rcTarget.bottom - m_rcTarget.top, m_hdc, 0, 0, SRCCOPY); + } + + m_hTargetDC = NULL; + destroy(); +} + +HBITMAP simpledib::dib::detach_bitmap() +{ + HBITMAP bmp = m_bmp; + destroy(false); + return bmp; +} diff --git a/plugins/NewStory/src/dib.h b/plugins/NewStory/src/dib.h new file mode 100644 index 0000000000..62e6051d9e --- /dev/null +++ b/plugins/NewStory/src/dib.h @@ -0,0 +1,40 @@ +#pragma once + +namespace simpledib +{ + class dib + { + HBITMAP m_bmp; + HBITMAP m_oldBmp; + HDC m_hdc; + LPRGBQUAD m_bits; + int m_width, m_height; + + HDC m_hTargetDC; + POINT m_oldViewPort; + bool m_restore_view_port = false, m_ownData = false; + RECT m_rcTarget; + + public: + dib(); + ~dib(); + + __forceinline int width() const { return m_width; } + __forceinline int height() const { return m_height; } + __forceinline HDC hdc() const { return m_hdc; } + __forceinline HBITMAP bmp() const { return m_bmp; } + __forceinline LPRGBQUAD bits() const { return m_bits; } + __forceinline operator HDC() { return m_hdc; } + + bool create(int width, int height, bool topdowndib = false); + bool create(HDC hdc, HBITMAP bmp, LPRGBQUAD bits, int width, int height); + + void clear(); + void destroy(bool del_bmp = true); + void draw(HDC hdc, int x, int y); + void draw(HDC hdc, LPRECT rcDraw); + HDC beginPaint(HDC hdc, LPRECT rcDraw); + void endPaint(bool copy = false); + HBITMAP detach_bitmap(); + }; +} diff --git a/plugins/NewStory/src/history_array.cpp b/plugins/NewStory/src/history_array.cpp index 8fbcee0ed9..a22708743e 100644 --- a/plugins/NewStory/src/history_array.cpp +++ b/plugins/NewStory/src/history_array.cpp @@ -18,8 +18,6 @@ along with this program. If not, see . #include "stdafx.h" -extern HANDLE htuLog; - ///////////////////////////////////////////////////////////////////////////////////////// // Filters @@ -82,8 +80,6 @@ ItemData::~ItemData() mir_free(wtext); if (dbe.szReplyId) mir_free((char*)dbe.szReplyId); - if (data) - MTextDestroy(data); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -101,7 +97,7 @@ static bool isEqual(const ItemData *p1, const ItemData *p2) return true; } -ItemData* ItemData::checkPrev(ItemData *pPrev, HWND hwnd) +ItemData* ItemData::checkPrev(ItemData *pPrev) { m_grouping = GROUPING_NONE; if (!pPrev || !g_plugin.bMsgGrouping) @@ -118,7 +114,7 @@ ItemData* ItemData::checkPrev(ItemData *pPrev, HWND hwnd) if (pPrev->m_grouping == GROUPING_NONE) { pPrev->m_grouping = GROUPING_HEAD; if (pPrev->m_bLoaded) - pPrev->setText(hwnd); + pPrev->setText(); } m_grouping = GROUPING_ITEM; } @@ -127,7 +123,7 @@ ItemData* ItemData::checkPrev(ItemData *pPrev, HWND hwnd) ///////////////////////////////////////////////////////////////////////////////////////// -ItemData* ItemData::checkNext(ItemData *pPrev, HWND hwnd) +ItemData* ItemData::checkNext(ItemData *pPrev) { m_grouping = GROUPING_NONE; if (!pPrev || !g_plugin.bMsgGrouping) @@ -145,11 +141,11 @@ ItemData* ItemData::checkNext(ItemData *pPrev, HWND hwnd) if (pPrev->m_grouping == GROUPING_NONE) { pPrev->m_grouping = GROUPING_HEAD; if (pPrev->m_bLoaded) - pPrev->setText(hwnd); + pPrev->setText(); } m_grouping = GROUPING_ITEM; if (m_bLoaded) - setText(hwnd); + setText(); } return this; } @@ -172,7 +168,7 @@ static bool isEqualGC(const ItemData *p1, const ItemData *p2) return true; } -ItemData* ItemData::checkPrevGC(ItemData *pPrev, HWND hwnd) +ItemData* ItemData::checkPrevGC(ItemData *pPrev) { m_grouping = GROUPING_NONE; if (!pPrev || !g_plugin.bMsgGrouping) @@ -185,7 +181,7 @@ ItemData* ItemData::checkPrevGC(ItemData *pPrev, HWND hwnd) if (pPrev->m_grouping == GROUPING_NONE) { pPrev->m_grouping = GROUPING_HEAD; if (pPrev->m_bLoaded) - pPrev->setText(hwnd); + pPrev->setText(); } m_grouping = GROUPING_ITEM; } @@ -194,61 +190,44 @@ ItemData* ItemData::checkPrevGC(ItemData *pPrev, HWND hwnd) ///////////////////////////////////////////////////////////////////////////////////////// -void ItemData::checkCreate(HWND hwnd) +int ItemData::calcHeight(int top, int width, POINT *pPos) { - if (data == nullptr) { - setText(hwnd); - MTextSetParent(data, hwnd); - MTextActivate(data, true); - } -} + checkCreate(); -bool ItemData::isLink(HWND hwnd, POINT pt, CMStringW *pwszUrl) const -{ - int cp = MTextSendMessage(0, data, EM_CHARFROMPOS, 0, LPARAM(&pt)); - if (cp == -1) - return false; + SIZE sz; + sz.cx = width - 2; - if (!isLinkChar(hwnd, cp)) - return false; + POINT pos; + pos.x = 2; + pos.y = top + 2; - if (pwszUrl) { - CHARRANGE sel = { cp, cp }; - while (isLinkChar(hwnd, sel.cpMin-1)) - sel.cpMin--; - - while (isLinkChar(hwnd, sel.cpMax)) - sel.cpMax++; - - if (sel.cpMax > sel.cpMin) { - pwszUrl->Truncate(sel.cpMax - sel.cpMin + 1); - - TEXTRANGE tr = { 0 }; - tr.chrg = sel; - tr.lpstrText = pwszUrl->GetBuffer(); - int iRes = MTextSendMessage(0, data, EM_GETTEXTRANGE, 0, (LPARAM)&tr); - if (iRes > 0) - pwszUrl->Trim(); - else - pwszUrl->Empty(); - } + if (g_plugin.bShowType) // Message type icon + pos.x += 18; + + if (g_plugin.bShowDirection) // Message direction icon + pos.x += 18; + + if (dbe.flags & DBEF_BOOKMARK) // Bookmark icon + pos.x += 18; + + sz.cx -= pos.x; + if (m_bOfflineDownloaded != 0) // Download completed icon + sz.cx -= 18; + + if (savedHeight == -1) { + m_doc->render(sz.cx); + savedHeight = m_doc->height(); } - return true; + + if (pPos) + *pPos = pos; + return savedHeight + 5; } -bool ItemData::isLinkChar(HWND hwnd, int idx) const +void ItemData::checkCreate() { - if (idx < 0) - return false; - - CHARRANGE sel = { idx, idx + 1 }; - MTextSendMessage(hwnd, data, EM_EXSETSEL, 0, LPARAM(&sel)); - - CHARFORMAT2 cf = {}; - cf.cbSize = sizeof(cf); - cf.dwMask = CFM_LINK; - uint32_t res = MTextSendMessage(hwnd, data, EM_GETCHARFORMAT, SCF_SELECTION, LPARAM(&cf)); - return ((res & CFM_LINK) && (cf.dwEffects & CFE_LINK)) || ((res & CFM_REVISED) && (cf.dwEffects & CFE_REVISED)); + if (m_doc == nullptr) + setText(); } bool ItemData::fetch(void) @@ -475,14 +454,11 @@ void ItemData::load(bool bLoadAlways) dbe.unload(); } -void ItemData::setText(HWND hwnd) +void ItemData::setText() { - if (data) - MTextDestroy(data); - - data = MTextCreateEx2(hwnd, htuLog, formatRtf().GetBuffer(), MTEXT_FLG_RTF); - MTextSetProto(data, hContact); - savedHeight = -1; + m_doc = litehtml::document::createFromString(formatHtml(), &pOwner->webPage); + m_doc->render(pOwner->cachedWindowWidth); + savedHeight = m_doc->height(); } // Array @@ -559,7 +535,7 @@ void HistoryArray::addChatEvent(NewstoryListData *pOwner, SESSION_INFO *si, cons if (lin->ptszNick) { addNick(p, lin->ptszNick); - p.checkPrevGC((numItems == 0) ? nullptr : get(numItems - 1), hwndOwner); + p.checkPrevGC((numItems == 0) ? nullptr : get(numItems - 1)); } } @@ -582,9 +558,9 @@ bool HistoryArray::addEvent(NewstoryListData *pOwner, MCONTACT hContact, MEVENT p.dbe = hEvent; if (si) { checkGC(p, si); - pPrev = p.checkPrevGC(pPrev, hwndOwner); + pPrev = p.checkPrevGC(pPrev); } - else pPrev = p.checkPrev(pPrev, hwndOwner); + else pPrev = p.checkPrev(pPrev); } else { DB::ECPTR pCursor(DB::Events(hContact, hEvent)); @@ -599,9 +575,9 @@ bool HistoryArray::addEvent(NewstoryListData *pOwner, MCONTACT hContact, MEVENT p.dbe = hEvent; if (si) { checkGC(p, si); - pPrev = p.checkPrevGC(pPrev, hwndOwner); + pPrev = p.checkPrevGC(pPrev); } - else pPrev = p.checkPrev(pPrev, hwndOwner); + else pPrev = p.checkPrev(pPrev); } } @@ -628,7 +604,7 @@ void HistoryArray::addResults(NewstoryListData *pOwner, const OBJLISThContact; p.dbe = it->hEvent; p.m_bIsResult = true; - pPrev = p.checkPrev(pPrev, hwndOwner); + pPrev = p.checkPrev(pPrev); } } diff --git a/plugins/NewStory/src/history_array.h b/plugins/NewStory/src/history_array.h index 00482f76c2..f5a39ba5bd 100644 --- a/plugins/NewStory/src/history_array.h +++ b/plugins/NewStory/src/history_array.h @@ -26,29 +26,28 @@ struct ItemData wchar_t *wszNick; struct NewstoryListData *pOwner; - HText data; + litehtml::document::ptr m_doc; ItemData(); ~ItemData(); - ItemData* checkNext(ItemData *pPrev, HWND hwnd); - ItemData* checkPrev(ItemData *pPrev, HWND hwnd); - ItemData* checkPrevGC(ItemData *pPrev, HWND hwnd); - void checkCreate(HWND hwnd); - void setText(HWND hwnd); + ItemData* checkNext(ItemData *pPrev); + ItemData* checkPrev(ItemData *pPrev); + ItemData* checkPrevGC(ItemData *pPrev); + void checkCreate(); + int calcHeight(int top, int width, POINT *pPos = nullptr); bool completed() const { return m_bOfflineDownloaded == 100; } bool fetch(void); void fill(int tmpl); void load(bool bLoad = false); - bool isLink(HWND, POINT pt, CMStringW *url = nullptr) const; - bool isLinkChar(HWND, int idx) const; + void setText(); int getTemplate() const; int getCopyTemplate() const; void getFontColor(int &fontId, int &colorId) const; - CMStringA formatRtf(const wchar_t *pwszStr = 0); + CMStringA formatHtml(const wchar_t *pwszStr = 0); CMStringW formatString() { return TplFormatString(getTemplate(), hContact, this); } CMStringW formatStringEx(wchar_t *sztpl); diff --git a/plugins/NewStory/src/history_control.cpp b/plugins/NewStory/src/history_control.cpp index 2aafa3e58c..ee714e2771 100644 --- a/plugins/NewStory/src/history_control.cpp +++ b/plugins/NewStory/src/history_control.cpp @@ -20,8 +20,6 @@ along with this program. If not, see . #define AVERAGE_ITEM_HEIGHT 100 -HANDLE htuLog = 0; - void InitHotkeys() { HOTKEYDESC hkd = {}; @@ -57,6 +55,7 @@ void InitHotkeys() NewstoryListData::NewstoryListData(HWND _1) : m_hwnd(_1), + webPage(*this), redrawTimer(Miranda_GetSystemWindow(), LPARAM(this)) { items.setOwner(_1); @@ -89,6 +88,11 @@ void NewstoryListData::OnContextMenu(int index, POINT pt) void NewstoryListData::OnResize(int newWidth, int newHeight) { + if (dib.width() < newWidth || dib.height() < newHeight) { + dib.destroy(); + dib.create(newWidth, newHeight, true); + } + bool bDraw = false; if (newWidth != cachedWindowWidth) { cachedWindowWidth = newWidth; @@ -137,8 +141,8 @@ void NewstoryListData::AddResults(const OBJLIST &results) void NewstoryListData::AddSelection(int iFirst, int iLast) { - int start = min(totalCount - 1, iFirst); - int end = min(totalCount - 1, max(0, iLast)); + int start = std::min(totalCount - 1, iFirst); + int end = std::min(totalCount - 1, std::max(0, iLast)); if (start > end) std::swap(start, end); @@ -247,7 +251,7 @@ void NewstoryListData::BeginEditItem() if (itemHeight > height) dwStyle |= WS_VSCROLL; - hwndEditBox = CreateWindow(L"EDIT", wszText, dwStyle, 0, top, width, min(height, itemHeight), m_hwnd, NULL, g_plugin.getInst(), NULL); + hwndEditBox = CreateWindow(L"EDIT", wszText, dwStyle, 0, top, width, std::min(height, itemHeight), m_hwnd, NULL, g_plugin.getInst(), NULL); mir_subclassWindow(hwndEditBox, HistoryEditWndProc); SendMessage(hwndEditBox, WM_SETFONT, (WPARAM)g_fontTable[fontid].hfnt, 0); SendMessage(hwndEditBox, EM_SETMARGINS, EC_RIGHTMARGIN, 100); @@ -276,7 +280,7 @@ void NewstoryListData::Clear() void NewstoryListData::ClearSelection(int iFirst, int iLast) { - int start = min(0, iFirst); + int start = std::min(0, iFirst); int end = (iLast <= 0) ? totalCount - 1 : iLast; if (start > end) std::swap(start, end); @@ -436,9 +440,9 @@ void NewstoryListData::EndEditItem(bool bAccept) db_event_edit(pItem->dbe.getEvent(), &dbei); } - MTextDestroy(pItem->data); pItem->data = 0; + pItem->m_doc = 0; pItem->savedHeight = -1; - pItem->checkCreate(m_hwnd); + pItem->checkCreate(); } } @@ -581,11 +585,8 @@ int NewstoryListData::GetItemHeight(int index) int NewstoryListData::GetItemHeight(ItemData *pItem) { - if (pItem->savedHeight == -1) { - HDC hdc = GetDC(m_hwnd); - pItem->savedHeight = PaintItem(hdc, pItem, 0, cachedWindowWidth, false); - ReleaseDC(m_hwnd, hdc); - } + if (pItem->savedHeight == -1) + pItem->savedHeight = pItem->calcHeight(0, cachedWindowWidth); return pItem->savedHeight; } @@ -648,130 +649,142 @@ void NewstoryListData::OpenFolder() } } -int NewstoryListData::PaintItem(HDC hdc, ItemData *pItem, int top, int width, bool bDraw) +///////////////////////////////////////////////////////////////////////////////////////// +// Painting + +void NewstoryListData::Paint(simpledib::dib &dib, RECT *rcDraw) { - // remove any selections that might be created by the BBCodes parser - MTextSendMessage(m_hwnd, pItem->data, EM_SETSEL, 0, 0); + cairo_surface_t *surface = cairo_image_surface_create_for_data((unsigned char *)dib.bits(), CAIRO_FORMAT_ARGB32, dib.width(), dib.height(), dib.width() * 4); + cairo_t *cr = cairo_create(surface); - // LOGFONT lfText; - COLORREF clText, clBack, clLine; - int fontid, colorid; - pItem->getFontColor(fontid, colorid); + cairo_rectangle(cr, rcDraw->left, rcDraw->top, rcDraw->right - rcDraw->left, rcDraw->bottom - rcDraw->top); + cairo_clip(cr); - clText = g_fontTable[fontid].cl; - if (pItem->m_bHighlighted) { - clText = g_fontTable[FONT_HIGHLIGHT].cl; - clBack = g_colorTable[COLOR_HIGHLIGHT_BACK].cl; - clLine = g_colorTable[COLOR_FRAME].cl; - } - else if (pItem->m_bSelected) { - clText = g_colorTable[COLOR_SELTEXT].cl; - clBack = g_colorTable[COLOR_SELBACK].cl; - clLine = g_colorTable[COLOR_SELFRAME].cl; - } - else { - clLine = g_colorTable[COLOR_FRAME].cl; - clBack = g_colorTable[colorid].cl; - } + cairo_set_source_rgb(cr, 1, 1, 1); + cairo_paint(cr); - pItem->checkCreate(m_hwnd); + int top = scrollTopPixel; - SIZE sz; - sz.cx = width - 2; + int idx; + for (idx = scrollTopItem; top < cachedWindowHeight && idx < totalCount; idx++) { + if (hwndEditBox && caret == idx) + continue; - POINT pos; - pos.x = 2; - pos.y = top + 2; + auto *pItem = LoadItem(idx); - if (g_plugin.bShowType) // Message type icon - pos.x += 18; + POINT pos; + int height = pItem->calcHeight(top, cachedWindowWidth, &pos); - if (g_plugin.bShowDirecction) // Message direction icon - pos.x += 18; + COLORREF clText, clBack, clLine; + int fontid, colorid; + pItem->getFontColor(fontid, colorid); - if (pItem->dbe.flags & DBEF_BOOKMARK) // Bookmark icon - pos.x += 18; + if (pItem->m_bHighlighted) { + clText = g_fontTable[FONT_HIGHLIGHT].cl; + clBack = g_colorTable[COLOR_HIGHLIGHT_BACK].cl; + clLine = g_colorTable[COLOR_FRAME].cl; + } + else if (pItem->m_bSelected) { + clText = g_colorTable[COLOR_SELTEXT].cl; + clBack = g_colorTable[COLOR_SELBACK].cl; + clLine = g_colorTable[COLOR_SELFRAME].cl; + } + else { + clText = g_fontTable[fontid].cl; + clLine = g_colorTable[COLOR_FRAME].cl; + clBack = g_colorTable[colorid].cl; + } - sz.cx -= pos.x; - if (pItem->m_bOfflineDownloaded != 0) // Download completed icon - sz.cx -= 18; + HBRUSH hbr = CreateSolidBrush(clBack); + RECT rc = { 0, top, cachedWindowWidth, top + height }; + FillRect(dib, &rc, hbr); + DeleteObject(hbr); - HFONT hfnt = (HFONT)SelectObject(hdc, g_fontTable[fontid].hfnt); - MTextMeasure(hdc, &sz, pItem->data); - SelectObject(hdc, hfnt); + SetTextColor(dib, clText); + SetBkMode(dib, TRANSPARENT); - int height = sz.cy + 5; - if (!bDraw) - return height; + pos.x = 2; + HICON hIcon; - HBRUSH hbr = CreateSolidBrush(clBack); - RECT rc = { 0, top, width, top + height }; - FillRect(hdc, &rc, hbr); - DeleteObject(hbr); + // Message type icon + if (g_plugin.bShowType) { + switch (pItem->dbe.eventType) { + case EVENTTYPE_MESSAGE: + hIcon = g_plugin.getIcon(IDI_SENDMSG); + break; + case EVENTTYPE_FILE: + hIcon = Skin_LoadIcon(SKINICON_EVENT_FILE); + break; + case EVENTTYPE_STATUSCHANGE: + hIcon = g_plugin.getIcon(IDI_SIGNIN); + break; + default: + hIcon = g_plugin.getIcon(IDI_UNKNOWN); + break; + } + DrawIconEx(dib, pos.x, pos.y, hIcon, 16, 16, 0, 0, DI_NORMAL); + pos.x += 18; + } - SetTextColor(hdc, clText); - SetBkMode(hdc, TRANSPARENT); + // Direction icon + if (g_plugin.bShowDirection) { + if (pItem->dbe.flags & DBEF_SENT) + hIcon = g_plugin.getIcon(IDI_MSGOUT); + else + hIcon = g_plugin.getIcon(IDI_MSGIN); + DrawIconEx(dib, pos.x, pos.y, hIcon, 16, 16, 0, 0, DI_NORMAL); + pos.x += 18; + } - pos.x = 2; - HICON hIcon; - - // Message type icon - if (g_plugin.bShowType) { - switch (pItem->dbe.eventType) { - case EVENTTYPE_MESSAGE: - hIcon = g_plugin.getIcon(IDI_SENDMSG); - break; - case EVENTTYPE_FILE: - hIcon = Skin_LoadIcon(SKINICON_EVENT_FILE); - break; - case EVENTTYPE_STATUSCHANGE: - hIcon = g_plugin.getIcon(IDI_SIGNIN); - break; - default: - hIcon = g_plugin.getIcon(IDI_UNKNOWN); - break; + // Bookmark icon + if (pItem->dbe.flags & DBEF_BOOKMARK) { + DrawIconEx(dib, pos.x, pos.y, g_plugin.getIcon(IDI_BOOKMARK), 16, 16, 0, 0, DI_NORMAL); + pos.x += 18; } - DrawIconEx(hdc, pos.x, pos.y, hIcon, 16, 16, 0, 0, DI_NORMAL); - pos.x += 18; - } - // Direction icon - if (g_plugin.bShowDirecction) { - if (pItem->dbe.flags & DBEF_SENT) - hIcon = g_plugin.getIcon(IDI_MSGOUT); - else - hIcon = g_plugin.getIcon(IDI_MSGIN); - DrawIconEx(hdc, pos.x, pos.y, hIcon, 16, 16, 0, 0, DI_NORMAL); - pos.x += 18; - } + // Finished icon + if (pItem->m_bOfflineDownloaded != 0) { + if (pItem->completed()) + DrawIconEx(dib, cachedWindowWidth - 20, pos.y, g_plugin.getIcon(IDI_OK), 16, 16, 0, 0, DI_NORMAL); + else { + HPEN hpn = (HPEN)SelectObject(dib, CreatePen(PS_SOLID, 4, g_colorTable[COLOR_PROGRESS].cl)); + MoveToEx(dib, rc.left, rc.bottom - 4, 0); + LineTo(dib, rc.left + (rc.right - rc.left) * int(pItem->m_bOfflineDownloaded) / 100, rc.bottom - 4); + DeleteObject(SelectObject(dib, hpn)); + } + } - // Bookmark icon - if (pItem->dbe.flags & DBEF_BOOKMARK) { - DrawIconEx(hdc, pos.x, pos.y, g_plugin.getIcon(IDI_BOOKMARK), 16, 16, 0, 0, DI_NORMAL); - pos.x += 18; - } + HFONT hfnt = (HFONT)SelectObject(dib, g_fontTable[fontid].hfnt); + litehtml::position clip(pos.x, pos.y, cachedWindowWidth - pos.x, height); + pItem->m_doc->draw((UINT_PTR)cr, pos.x, pos.y, &clip); + SelectObject(dib, hfnt); - // Finished icon - if (pItem->m_bOfflineDownloaded != 0) { - if (pItem->completed()) - DrawIconEx(hdc, width - 20, pos.y, g_plugin.getIcon(IDI_OK), 16, 16, 0, 0, DI_NORMAL); - else { - HPEN hpn = (HPEN)SelectObject(hdc, CreatePen(PS_SOLID, 4, g_colorTable[COLOR_PROGRESS].cl)); - MoveToEx(hdc, rc.left, rc.bottom - 4, 0); - LineTo(hdc, rc.left + (rc.right - rc.left) * int(pItem->m_bOfflineDownloaded) / 100, rc.bottom - 4); - DeleteObject(SelectObject(hdc, hpn)); - } + HPEN hpn = (HPEN)SelectObject(dib, CreatePen(PS_SOLID, 1, clLine)); + MoveToEx(dib, rc.left, rc.bottom - 1, 0); + LineTo(dib, rc.right, rc.bottom - 1); + DeleteObject(SelectObject(dib, hpn)); + + top += height; } - hfnt = (HFONT)SelectObject(hdc, g_fontTable[fontid].hfnt); - MTextDisplay(hdc, pos, sz, pItem->data); - SelectObject(hdc, hfnt); + cachedMaxDrawnItem = idx; + + if (top <= cachedWindowHeight) { + RECT rc2; + SetRect(&rc2, 0, top, cachedWindowWidth, cachedWindowHeight); + + HBRUSH hbr = CreateSolidBrush(g_colorTable[COLOR_BACK].cl); + FillRect(dib, &rc2, hbr); + DeleteObject(hbr); + } - HPEN hpn = (HPEN)SelectObject(hdc, CreatePen(PS_SOLID, 1, clLine)); - MoveToEx(hdc, rc.left, rc.bottom - 1, 0); - LineTo(hdc, rc.right, rc.bottom - 1); - DeleteObject(SelectObject(hdc, hpn)); - return height; + if (g_plugin.bOptVScroll) + RecalcScrollBar(); + + if (g_plugin.bDrawEdge) { + RECT rc = { 0, 0, cachedWindowWidth, cachedWindowHeight }; + DrawEdge(dib, &rc, BDR_SUNKENOUTER, BF_RECT); + } } void NewstoryListData::RecalcScrollBar() @@ -868,8 +881,8 @@ void NewstoryListData::SetPos(int pos) void NewstoryListData::SetSelection(int iFirst, int iLast) { - int start = min(totalCount - 1, iFirst); - int end = min(totalCount - 1, max(0, iLast)); + int start = std::min(totalCount - 1, iFirst); + int end = std::min(totalCount - 1, std::max(0, iLast)); if (start > end) std::swap(start, end); @@ -899,7 +912,7 @@ void NewstoryListData::ToggleBookmark() p->dbe.flags |= DBEF_BOOKMARK; db_event_edit(p->dbe.getEvent(), &p->dbe); - p->setText(m_hwnd); + p->setText(); } InvalidateRect(m_hwnd, 0, FALSE); @@ -907,8 +920,8 @@ void NewstoryListData::ToggleBookmark() void NewstoryListData::ToggleSelection(int iFirst, int iLast) { - int start = min(totalCount - 1, iFirst); - int end = min(totalCount - 1, max(0, iLast)); + int start = std::min(totalCount - 1, iFirst); + int end = std::min(totalCount - 1, std::max(0, iLast)); if (start > end) std::swap(start, end); @@ -946,7 +959,7 @@ void NewstoryListData::TryUp(int iCount) ItemData *pPrev = nullptr; for (int j = 0; j < i + 1; j++) { auto *pItem = GetItem(j); - pPrev = pItem->checkNext(pPrev, m_hwnd); + pPrev = pItem->checkNext(pPrev); } caret = 0; @@ -1174,7 +1187,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM if (idx != -1) { auto *p = data->GetItem(idx); p->load(true); - p->setText(data->m_hwnd); + p->setText(); InvalidateRect(hwnd, 0, FALSE); } break; @@ -1207,40 +1220,14 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM we'll just ignore them */ if (IsWindowVisible(hwnd)) { PAINTSTRUCT ps; - HDC hdcWindow = BeginPaint(hwnd, &ps); - - RECT rc; - GetClientRect(hwnd, &rc); - - HDC hdc = CreateCompatibleDC(hdcWindow); - HBITMAP hbmSave = (HBITMAP)SelectObject(hdc, CreateCompatibleBitmap(hdcWindow, rc.right - rc.left, rc.bottom - rc.top)); - - int height = rc.bottom - rc.top; - int width = rc.right - rc.left; - int top = data->scrollTopPixel; - - for (idx = data->scrollTopItem; top < height && idx < data->totalCount; idx++) - top += data->PaintItem(hdc, data->LoadItem(idx), top, width, !data->hwndEditBox || data->caret != idx); - - data->cachedMaxDrawnItem = idx; - - if (top <= height) { - RECT rc2; - SetRect(&rc2, 0, top, width, height); + HDC hdc = BeginPaint(hwnd, &ps); - HBRUSH hbr = CreateSolidBrush(g_colorTable[COLOR_BACK].cl); - FillRect(hdc, &rc2, hbr); - DeleteObject(hbr); - } + data->Paint(data->dib, &ps.rcPaint); - if (g_plugin.bOptVScroll) - data->RecalcScrollBar(); - if (g_plugin.bDrawEdge) - DrawEdge(hdc, &rc, BDR_SUNKENOUTER, BF_RECT); + BitBlt(hdc, ps.rcPaint.left, ps.rcPaint.top, + ps.rcPaint.right - ps.rcPaint.left, + ps.rcPaint.bottom - ps.rcPaint.top, data->dib, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY); - BitBlt(hdcWindow, 0, 0, rc.right, rc.bottom, hdc, 0, 0, SRCCOPY); - DeleteObject(SelectObject(hdc, hbmSave)); - DeleteDC(hdc); EndPaint(hwnd, &ps); } break; @@ -1391,12 +1378,6 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM else { pt.y -= pItem->savedTop; - CMStringW wszUrl; - if (pItem->isLink(hwnd, pt, &wszUrl)) { - Utils_OpenUrlW(wszUrl); - return 0; - } - data->selStart = idx; data->SetSelection(idx, idx); data->SetCaret(idx); @@ -1440,14 +1421,6 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; idx = data->GetItemFromPixel(pt.y); if (idx >= 0) { - auto *pItem = data->LoadItem(idx); - MTextSendMessage(hwnd, pItem->data, msg, wParam, lParam); - - HCURSOR hOldCursor = GetCursor(); - HCURSOR hNewCursor = LoadCursor(0, (pItem->isLink(hwnd, pt) || pItem->m_bOfflineFile) ? IDC_HAND : IDC_ARROW); - if (hOldCursor != hNewCursor) - SetCursor(hNewCursor); - if (data->selStart != -1) { data->SetSelection(data->selStart, idx); InvalidateRect(hwnd, 0, FALSE); @@ -1541,7 +1514,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM void InitNewstoryControl() { - htuLog = MTextRegister("Newstory", MTEXT_FANCY_DEFAULT | MTEXT_SYSTEM_HICONS | MTEXT_FANCY_SMILEYS); + InitializeCriticalSection(&cairo_font::m_sync); WNDCLASS wndclass = {}; wndclass.style = /*CS_HREDRAW | CS_VREDRAW | */CS_DBLCLKS | CS_GLOBALCLASS; diff --git a/plugins/NewStory/src/history_control.h b/plugins/NewStory/src/history_control.h index 95cfc44dc7..188e39f037 100644 --- a/plugins/NewStory/src/history_control.h +++ b/plugins/NewStory/src/history_control.h @@ -3,6 +3,31 @@ #define NEWSTORYLIST_CLASS "NewstoryList" +struct NewstoryListData; + +class NSWebPage : public windows_container +{ + NewstoryListData &ctrl; + + cairo_surface_t *get_image(const std::string &url) override; + + void get_client_rect(litehtml::position &client) const override; + void import_css(litehtml::string &text, const litehtml::string &url, litehtml::string &baseurl) override; + void load_image(const char *src, const char *baseurl, bool redraw_on_ready) override; + void on_anchor_click(const char *url, const litehtml::element::ptr &el) override; + void set_base_url(const char *base_url) override; + void set_caption(const char *caption) override; + void set_clip(const litehtml::position &pos, const litehtml::border_radiuses &bdr_radius) override; + void set_cursor(const char *cursor) override; + +public: + NSWebPage(NewstoryListData &_1) : + ctrl(_1) + {} + + litehtml::uint_ptr getRC() const { return (litehtml::uint_ptr)m_temp_cr; } +}; + struct NewstoryListData : public MZeroedObject { NewstoryListData(HWND); @@ -32,6 +57,9 @@ struct NewstoryListData : public MZeroedObject CTimer redrawTimer; CSrmmBaseDialog *pMsgDlg = nullptr; + NSWebPage webPage; + simpledib::dib dib; + void OnContextMenu(int index, POINT pt); void OnResize(int newWidth, int newHeight); @@ -76,7 +104,7 @@ struct NewstoryListData : public MZeroedObject void OpenFolder(); void PageUp(); void PageDown(); - int PaintItem(HDC hdc, ItemData* pItem, int top, int width, bool bDraw); + void Paint(simpledib::dib &dib, RECT *rcDraw); void Quote(); void RecalcScrollBar(); void Reply(); diff --git a/plugins/NewStory/src/main.cpp b/plugins/NewStory/src/main.cpp index c45312d809..6ce6d2134c 100644 --- a/plugins/NewStory/src/main.cpp +++ b/plugins/NewStory/src/main.cpp @@ -158,7 +158,7 @@ void CMPlugin::LoadOptions() bDrawEdge = g_bOptDrawEdge; bHppCompat = g_bOptHppCompat; bMsgGrouping = g_bOptGrouping; - bShowDirecction = g_bShowDirection; + bShowDirection = g_bShowDirection; clCustom[0] = g_clCustom0; clCustom[1] = g_clCustom1; diff --git a/plugins/NewStory/src/options.cpp b/plugins/NewStory/src/options.cpp index 7decb0d967..b83ff73fb5 100644 --- a/plugins/NewStory/src/options.cpp +++ b/plugins/NewStory/src/options.cpp @@ -93,16 +93,6 @@ class CTemplateOptsDlg : public CBaseOptsDlg CCtrlMButton btnDiscard, bthVarHelp, btnReset; CCtrlTreeView m_tree; - UI_MESSAGE_MAP(CTemplateOptsDlg, CBaseOptsDlg); - UI_MESSAGE(UM_REDRAWLISTH, OnColorChanged); - UI_MESSAGE_MAP_END(); - - LRESULT OnColorChanged(UINT, WPARAM, LPARAM) - { - gpreview.SendMsg(MTM_SETBKCOLOR, g_colorTable[COLOR_BACK].cl, 0); - return 0; - } - public: CTemplateOptsDlg() : CBaseOptsDlg(IDD_OPT_TEMPLATES), @@ -186,7 +176,6 @@ public: m_tree.EnsureVisible(hFirst); WindowList_Add(g_hNewstoryWindows, m_hwnd); - OnColorChanged(0, 0, 0); return true; } @@ -278,7 +267,7 @@ public: CMStringW wszText(m_tempItem.formatStringEx(m_curr->tmpValue)); preview.SetText(wszText); - gpreview.SendMsg(MTM_UPDATEEX, MTEXT_FLG_RTF, LPARAM(m_tempItem.formatRtf(wszText).c_str())); + // gpreview.SendMsg(MTM_UPDATEEX, MTEXT_FLG_RTF, LPARAM(m_tempItem.formatRtf(wszText).c_str())); } void onSelChanged(CCtrlTreeView::TEventInfo *) diff --git a/plugins/NewStory/src/stdafx.cxx b/plugins/NewStory/src/stdafx.cxx index b5e6ba190b..d714e70110 100644 --- a/plugins/NewStory/src/stdafx.cxx +++ b/plugins/NewStory/src/stdafx.cxx @@ -16,4 +16,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "stdafx.h" \ No newline at end of file +#include "stdafx.h" + +#pragma comment(lib, "cairo.lib") diff --git a/plugins/NewStory/src/stdafx.h b/plugins/NewStory/src/stdafx.h index f1750a365b..dbdc97963e 100644 --- a/plugins/NewStory/src/stdafx.h +++ b/plugins/NewStory/src/stdafx.h @@ -17,8 +17,11 @@ along with this program. If not, see . */ #pragma once +#pragma warning(disable: 4458) -//Windows headers +#define NOMINMAX + +// Windows headers #include #include #include @@ -53,7 +56,6 @@ along with this program. If not, see . #include #include #include -#include #include #include #include @@ -62,10 +64,12 @@ along with this program. If not, see . #include "m_NewStory.h" #include "m_PluginUpdater.h" #include "m_smileyadd.h" -#ifndef MTEXT_NOHELPERS -#define MTEXT_NOHELPERS -#endif // MTEXT_NOHELPERS -#include "m_text.h" + +#include "../../Libs/litehtml/include/cairo.h" +#include "../../Libs/litehtml/include/litehtml.h" +#include "../../Libs/litehtml/containers/windows/cairo/cairo_font.h" +#include "../../Libs/litehtml/containers/windows/cairo/windows_container.h" +#include "dib.h" #include "resource.h" #include "version.h" @@ -102,7 +106,7 @@ struct CMPlugin : public PLUGIN // thesw options are a copy of static CMOption to keep performance high bool bMsgGrouping, bDrawEdge, bHppCompat, bDisableDelete = false; - bool bShowType, bShowDirecction; + bool bShowType, bShowDirection; COLORREF clCustom[5]; diff --git a/plugins/NewStory/src/templates.cpp b/plugins/NewStory/src/templates.cpp index 8006d2db4d..a5fe44bd72 100644 --- a/plugins/NewStory/src/templates.cpp +++ b/plugins/NewStory/src/templates.cpp @@ -28,6 +28,124 @@ wchar_t *months[12] = LPGENW("July"), LPGENW("August"), LPGENW("September"), LPGENW("October"), LPGENW("November"), LPGENW("December") }; +/////////////////////////////////////////////////////////////////////////////// +// HTML generator + +static uint32_t color2html(COLORREF clr) +{ + return (((clr & 0xFF) << 16) | (clr & 0xFF00) | ((clr & 0xFF0000) >> 16)); +} + +static char* font2html(LOGFONTA &lf, char *dest) +{ + mir_snprintf(dest, 100, "font-family: %s; font-size: %dpt; font-weight: %s; %s", + lf.lfFaceName, abs((signed char)lf.lfHeight) * 74 / g_iPixelY, + lf.lfWeight >= FW_BOLD ? "bold" : "normal", + lf.lfItalic ? "font-style: italic;" : ""); + return dest; +} + +static void AppendString(CMStringA &buf, const char *p) +{ + bool wasSpace = false; + + for (; *p; p++) { + if (*p == ' ') { + if (wasSpace) + buf.Append(" "); + else { + buf.AppendChar(' '); + wasSpace = true; + } + continue; + } + + wasSpace = false; + if (*p == '\r' && p[1] == '\n') { + buf.Append("
"); + p++; + } + else if (*p == '\n') buf.Append("
"); + else if (*p == '&') buf.Append("&"); + else if (*p == '>') buf.Append(">"); + else if (*p == '<') buf.Append("<"); + else if (*p == '&') buf.Append("""); + else if (*p == '[') { + p++; + if (*p == 'c') { + int colorId = -1; + if (p[2] == ']') { + colorId = atoi(p + 1); + p += 2; + } + else if (p[3] == ']') { + colorId = atoi(p + 1); + p += 3; + } + + switch (colorId) { + case 0: buf.Append(""); continue; + case 1: buf.Append(""); continue; + case 2: case 3: case 4: case 5: case 6: + buf.AppendFormat("", color2html(g_plugin.clCustom[colorId-2])); + continue; + } + } + + char *pEnd = ""; + if (*p == '/') { + pEnd = "/"; + p++; + } + if (*p == 'b' && p[1] == ']') { + buf.AppendFormat("<%sb>", pEnd); + p++; + } + else if (*p == 'i' && p[1] == ']') { + buf.AppendFormat("<%si>", pEnd); + p++; + } + else if (*p == 'u' && p[1] == ']') { + buf.AppendFormat("<%su>", pEnd); + p++; + } + else if (*p == 's' && p[1] == ']') { + buf.AppendFormat("<%ss>", pEnd); + p++; + } + else { + buf.AppendChar('['); + if (*pEnd == '/') + p--; + p--; + } + } + else buf.AppendChar(*p); + } +} + +CMStringA ItemData::formatHtml(const wchar_t *pwszStr) +{ + CMStringA str; + str.Append(""); + str.Append("\n"); + AppendString(str, T2Utf((pwszStr) ? pwszStr : formatString())); + + str.Append(""); + // Netlib_Logf(0, str); + return str; +} + /////////////////////////////////////////////////////////////////////////////// // RTF generator @@ -100,34 +218,6 @@ static void AppendUnicodeToBuffer(CMStringA &buf, const wchar_t *p) } } -CMStringA ItemData::formatRtf(const wchar_t *pwszStr) -{ - CMStringA buf; - buf.Append("{\\rtf1\\ansi\\deff0"); - - int fontID, colorID; - getFontColor(fontID, colorID); - auto &F = g_fontTable[fontID]; - buf.AppendFormat("{\\fonttbl{\\f0\\fnil\\fcharset0 %s;}}", F.lf.lfFaceName); - - COLORREF cr = F.cl; - buf.AppendFormat("{\\colortbl \\red%u\\green%u\\blue%u;", GetRValue(cr), GetGValue(cr), GetBValue(cr)); - cr = g_colorTable[(dbe.flags & DBEF_SENT) ? COLOR_OUTNICK : COLOR_INNICK].cl; - buf.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(cr), GetGValue(cr), GetBValue(cr)); - - for (auto cl : g_plugin.clCustom) { - cr = (cl == -1) ? 0 : cl; - buf.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(cr), GetGValue(cr), GetBValue(cr)); - } - - buf.AppendFormat("}\\uc1\\pard \\cf0\\f0\\b0\\i0\\fs%d ", GetFontHeight(F.lf)); - AppendUnicodeToBuffer(buf, (pwszStr) ? pwszStr : formatString()); - - buf.Append("}"); - // Netlib_Logf(0, buf); - return buf; -} - CMStringA NewstoryListData::GatherSelectedRtf() { CMStringA buf; diff --git a/plugins/NewStory/src/webpage.cpp b/plugins/NewStory/src/webpage.cpp new file mode 100644 index 0000000000..b3f2b70b0a --- /dev/null +++ b/plugins/NewStory/src/webpage.cpp @@ -0,0 +1,63 @@ +/* +Copyright (c) 2005 Victor Pavlychko (nullbyte@sotline.net.ua) +Copyright (C) 2012-24 Miranda NG team (https://miranda-ng.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "stdafx.h" + +///////////////////////////////////////////////////////////////////////////////////////// +// Litehtml interface + +CRITICAL_SECTION cairo_font::m_sync; + +cairo_surface_t* NSWebPage::get_image(const std::string &) +{ + return 0; +} + +void NSWebPage::get_client_rect(litehtml::position &pos) const +{ + pos = litehtml::size(ctrl.cachedWindowWidth, ctrl.cachedWindowHeight); + +} + +void NSWebPage::import_css(litehtml::string &, const litehtml::string &, litehtml::string &) +{ +} + +void NSWebPage::load_image(const char *, const char *, bool) +{ +} + +void NSWebPage::on_anchor_click(const char *, const litehtml::element::ptr &) +{ +} + +void NSWebPage::set_base_url(const char *) +{ +} + +void NSWebPage::set_caption(const char *) +{ +} + +void NSWebPage::set_clip(const litehtml::position &, const litehtml::border_radiuses &) +{ +} + +void NSWebPage::set_cursor(const char *) +{ +} -- cgit v1.2.3