diff options
author | George Hazan <george.hazan@gmail.com> | 2024-03-31 13:01:39 +0300 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2024-03-31 13:01:39 +0300 |
commit | 642682bda6c10dc1fbd06aa1b978608c0ba9a1f2 (patch) | |
tree | fa08de1b00ade14bc701fa7ab1bf5a80d9f7ae6d /plugins/NewStory/src | |
parent | 482709434f32ea4e476a477a534e5baa048f2886 (diff) |
since windows containers are not supported, all code moved inside NSWebPage
Diffstat (limited to 'plugins/NewStory/src')
-rw-r--r-- | plugins/NewStory/src/history_control.h | 80 | ||||
-rw-r--r-- | plugins/NewStory/src/stdafx.h | 3 | ||||
-rw-r--r-- | plugins/NewStory/src/webpage.cpp | 632 |
3 files changed, 689 insertions, 26 deletions
diff --git a/plugins/NewStory/src/history_control.h b/plugins/NewStory/src/history_control.h index 0579426b1d..038a3af366 100644 --- a/plugins/NewStory/src/history_control.h +++ b/plugins/NewStory/src/history_control.h @@ -5,28 +5,84 @@ struct NewstoryListData;
-class NSWebPage : public gdiplus_container
+class NSWebPage : public document_container
{
- typedef gdiplus_container CSuper;
+ typedef std::map<std::wstring, uint_ptr> images_map;
+
+ ULONG_PTR m_gdiplusToken;
+
+ mir_cs m_csImages;
+ images_map m_images;
+
+ position::vector m_clips;
+ HRGN m_hClipRgn;
+ std::set<std::wstring> m_installed_fonts;
+ HDC m_tmp_hdc;
NewstoryListData &ctrl;
- litehtml::string resolve_color(const litehtml::string &color) const;
+ std::string resolve_color(const string &color) const;
+ uint_ptr get_image(LPCWSTR url_or_path, bool redraw_on_ready);
+ void make_url(LPCWSTR url, LPCWSTR basepath, std::wstring &out);
- void get_client_rect(litehtml::position &client) const override;
- uint_ptr get_image(LPCWSTR url_or_path, bool redraw_on_ready) override;
- void import_css(litehtml::string &text, const litehtml::string &url, litehtml::string &baseurl) override;
- void make_url(LPCWSTR url, LPCWSTR basepath, std::wstring &out) override;
- void on_anchor_click(const char *url, const litehtml::element::ptr &el) override;
+ void get_client_rect(position &client) const override;
+ void import_css(string &text, const string &url, string &baseurl) override;
+ void on_anchor_click(const char *url, const 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;
+ void draw_image(uint_ptr hdc, const background_layer &layer, const std::string &url, const std::string &base_url) override;
+ void get_img_size(uint_ptr img, size &sz);
+ void free_image(uint_ptr img);
+
+ // document_container members
+ uint_ptr create_font(const char *faceName, int size, int weight, font_style italic, unsigned int decoration, font_metrics *fm) override;
+ void delete_font(uint_ptr hFont) override;
+ const char* get_default_font_name() const override;
+ int get_default_font_size() const override;
+
+ void draw_text(uint_ptr hdc, const char *text, uint_ptr hFont, web_color color, const position &pos) override;
+ int text_width(const char *text, uint_ptr hFont) override;
+ void transform_text(string &text, text_transform tt) override;
+
+ void draw_borders(uint_ptr hdc, const borders &borders, const position &draw_pos, bool root) override;
+ void draw_ellipse(HDC hdc, int x, int y, int width, int height, web_color color, int line_width);
+ void draw_list_marker(uint_ptr hdc, const list_marker &marker) override;
+ void draw_solid_fill(uint_ptr, const background_layer &, const web_color &) override;
+
+ void draw_linear_gradient(uint_ptr, const background_layer &, const background_layer::linear_gradient &) override;
+ void draw_radial_gradient(uint_ptr, const background_layer &, const background_layer::radial_gradient &) override;
+ void draw_conic_gradient(uint_ptr, const background_layer &, const background_layer::conic_gradient &) override;
+
+ void fill_ellipse(HDC hdc, int x, int y, int width, int height, web_color color);
+ void fill_rect(HDC hdc, int x, int y, int width, int height, web_color color);
+
+ int pt_to_px(int pt) const override;
+
+ void add_image(LPCWSTR url, uint_ptr img);
+ void load_image(const char *src, const char *baseurl, bool redraw_on_ready) override;
+ void get_image_size(const char *src, const char *baseurl, size &sz) override;
+
+ element::ptr create_element(const char *tag_name, const string_map &attributes, const document::ptr &doc) override;
+ void get_media_features(media_features &media) const override;
+ void get_language(string &language, string &culture) const override;
+ void link(const document::ptr &doc, const element::ptr &el) override;
+
+ void apply_clip(HDC hdc);
+ void del_clip() override;
+ void release_clip(HDC hdc);
+ void set_clip(const position &pos, const border_radiuses &bdr_radius) override;
+
+ void make_url_utf8(const char *url, const char *basepath, std::wstring &out);
+
+ void clear_images();
+
+ static int CALLBACK EnumFontsProc(const LOGFONT *lplf, const TEXTMETRIC *lptm, DWORD dwType, LPARAM lpData);
+
public:
- NSWebPage(NewstoryListData &_1) :
- ctrl(_1)
- {}
+ NSWebPage(NewstoryListData &_1);
+ ~NSWebPage();
COLORREF clText = -1, clBack = -1;
};
diff --git a/plugins/NewStory/src/stdafx.h b/plugins/NewStory/src/stdafx.h index f27c7602a1..f48693cc29 100644 --- a/plugins/NewStory/src/stdafx.h +++ b/plugins/NewStory/src/stdafx.h @@ -32,6 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include <malloc.h>
#include <map>
+#include <set>
//Miranda headers
#include <newpluginapi.h>
@@ -68,8 +69,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../../Libs/freeimage/src/FreeImage.h"
#include <../include/litehtml.h>
-#include <../containers/windows/gdiplus/gdiplus_container.h>
#include "dib.h"
+using namespace litehtml;
#include "resource.h"
#include "version.h"
diff --git a/plugins/NewStory/src/webpage.cpp b/plugins/NewStory/src/webpage.cpp index 1179348e7e..a2f6bf9043 100644 --- a/plugins/NewStory/src/webpage.cpp +++ b/plugins/NewStory/src/webpage.cpp @@ -21,10 +21,49 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #undef Translate #include <gdiplus.h> +#pragma comment(lib, "gdiplus.lib") +using namespace Gdiplus; + ///////////////////////////////////////////////////////////////////////////////////////// // Litehtml interface -litehtml::string NSWebPage::resolve_color(const litehtml::string &color) const +struct +{ + const char *name; + int color_index; +} +static colors[] = { + { "ActiveBorder", COLOR_ACTIVEBORDER }, + { "ActiveCaption", COLOR_ACTIVECAPTION }, + { "AppWorkspace", COLOR_APPWORKSPACE }, + { "Background", COLOR_BACKGROUND }, + { "ButtonFace", COLOR_BTNFACE }, + { "ButtonHighlight", COLOR_BTNHIGHLIGHT }, + { "ButtonShadow", COLOR_BTNSHADOW }, + { "ButtonText", COLOR_BTNTEXT }, + { "CaptionText", COLOR_CAPTIONTEXT }, + { "GrayText", COLOR_GRAYTEXT }, + { "Highlight", COLOR_HIGHLIGHT }, + { "HighlightText", COLOR_HIGHLIGHTTEXT }, + { "InactiveBorder", COLOR_INACTIVEBORDER }, + { "InactiveCaption", COLOR_INACTIVECAPTION }, + { "InactiveCaptionText", COLOR_INACTIVECAPTIONTEXT }, + { "InfoBackground", COLOR_INFOBK }, + { "InfoText", COLOR_INFOTEXT }, + { "Menu", COLOR_MENU }, + { "MenuText", COLOR_MENUTEXT }, + { "Scrollbar", COLOR_SCROLLBAR }, + { "ThreeDDarkShadow", COLOR_3DDKSHADOW }, + { "ThreeDFace", COLOR_3DFACE }, + { "ThreeDHighlight", COLOR_3DHILIGHT }, + { "ThreeDLightShadow", COLOR_3DLIGHT }, + { "ThreeDShadow", COLOR_3DSHADOW }, + { "Window", COLOR_WINDOW }, + { "WindowFrame", COLOR_WINDOWFRAME }, + { "WindowText", COLOR_WINDOWTEXT } +}; + +std::string NSWebPage::resolve_color(const std::string &color) const { char buf[20]; @@ -33,25 +72,596 @@ litehtml::string NSWebPage::resolve_color(const litehtml::string &color) const return buf; } - return CSuper::resolve_color(color); + for (auto &clr : colors) { + if (!t_strcasecmp(color.c_str(), clr.name)) { + char str_clr[20]; + DWORD rgb_color = GetSysColor(clr.color_index); + t_snprintf(str_clr, 20, "#%02X%02X%02X", GetRValue(rgb_color), GetGValue(rgb_color), GetBValue(rgb_color)); + return std::move(std::string(str_clr)); + } + } + return std::move(std::string()); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +NSWebPage::NSWebPage(NewstoryListData &_1) : + ctrl(_1) +{ + m_hClipRgn = NULL; + m_tmp_hdc = GetDC(NULL); + + GdiplusStartupInput gdiplusStartupInput; + GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL); + + EnumFonts(m_tmp_hdc, NULL, EnumFontsProc, (LPARAM)this); + m_installed_fonts.insert(L"monospace"); + m_installed_fonts.insert(L"serif"); + m_installed_fonts.insert(L"sans-serif"); + m_installed_fonts.insert(L"fantasy"); + m_installed_fonts.insert(L"cursive"); +} + +NSWebPage::~NSWebPage() +{ + clear_images(); + GdiplusShutdown(m_gdiplusToken); + + if (m_hClipRgn) { + DeleteObject(m_hClipRgn); + } + ReleaseDC(NULL, m_tmp_hdc); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// former win32_container + +int CALLBACK NSWebPage::EnumFontsProc(const LOGFONT *lplf, const TEXTMETRIC *, DWORD, LPARAM lpData) +{ + NSWebPage *container = (NSWebPage *)lpData; + container->m_installed_fonts.insert(lplf->lfFaceName); + return 1; +} + +static LPCWSTR get_exact_font_name(LPCWSTR facename) +{ + if (!lstrcmpi(facename, L"monospace")) return L"Courier New"; + else if (!lstrcmpi(facename, L"serif")) return L"Times New Roman"; + else if (!lstrcmpi(facename, L"sans-serif")) return L"Arial"; + else if (!lstrcmpi(facename, L"fantasy")) return L"Impact"; + else if (!lstrcmpi(facename, L"cursive")) return L"Comic Sans MS"; + else return facename; +} + +static void trim_quotes(std::string &str) +{ + if (str.front() == '"' || str.front() == '\'') + str.erase(0, 1); + + if (str.back() == '"' || str.back() == '\'') + str.erase(str.length() - 1, 1); +} + +uint_ptr NSWebPage::create_font(const char *font_list, int size, int weight, font_style italic, unsigned int decoration, font_metrics *fm) +{ + std::wstring font_name; + string_vector fonts; + split_string(font_list, fonts, ","); + bool found = false; + for (auto &name : fonts) { + trim(name); + trim_quotes(name); + Utf2T wname(name.c_str()); + if (m_installed_fonts.count(wname.get())) { + font_name = wname; + found = true; + break; + } + } + if (!found) font_name = Utf2T(get_default_font_name()); + font_name = get_exact_font_name(font_name.c_str()); + + LOGFONT lf = {}; + wcscpy_s(lf.lfFaceName, LF_FACESIZE, font_name.c_str()); + + lf.lfHeight = -size; + lf.lfWeight = weight; + lf.lfItalic = (italic == font_style_italic) ? TRUE : FALSE; + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfOutPrecision = OUT_DEFAULT_PRECIS; + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf.lfQuality = DEFAULT_QUALITY; + lf.lfStrikeOut = (decoration & font_decoration_linethrough) ? TRUE : FALSE; + lf.lfUnderline = (decoration & font_decoration_underline) ? TRUE : FALSE; + HFONT hFont = CreateFontIndirect(&lf); + + if (fm) { + SelectObject(m_tmp_hdc, hFont); + TEXTMETRIC tm = {}; + GetTextMetrics(m_tmp_hdc, &tm); + fm->ascent = tm.tmAscent; + fm->descent = tm.tmDescent; + fm->height = tm.tmHeight; + fm->x_height = tm.tmHeight / 2; // this is an estimate; call GetGlyphOutline to get the real value + fm->draw_spaces = italic || decoration; + } + + return (uint_ptr)hFont; } -//////////////////////////////////////////////////////////////////////////////// +void NSWebPage::delete_font(uint_ptr hFont) +{ + DeleteObject((HFONT)hFont); +} + +const char *NSWebPage::get_default_font_name() const +{ + return "Times New Roman"; +} + +int NSWebPage::get_default_font_size() const +{ + return 16; +} + +int NSWebPage::text_width(const char *text, uint_ptr hFont) +{ + SIZE size = {}; + SelectObject(m_tmp_hdc, (HFONT)hFont); + Utf2T wtext(text); + GetTextExtentPoint32(m_tmp_hdc, wtext, (int)mir_wstrlen(wtext), &size); + return size.cx; +} -litehtml::uint_ptr NSWebPage::get_image(LPCWSTR url_or_path, bool) +void NSWebPage::draw_text(uint_ptr hdc, const char *text, uint_ptr hFont, web_color color, const position &pos) +{ + apply_clip((HDC)hdc); + + HFONT oldFont = (HFONT)SelectObject((HDC)hdc, (HFONT)hFont); + + SetBkMode((HDC)hdc, TRANSPARENT); + + SetTextColor((HDC)hdc, RGB(color.red, color.green, color.blue)); + + RECT rcText = { pos.left(), pos.top(), pos.right(), pos.bottom() }; + DrawText((HDC)hdc, Utf2T(text), -1, &rcText, DT_SINGLELINE | DT_NOPREFIX | DT_BOTTOM | DT_NOCLIP); + + SelectObject((HDC)hdc, oldFont); + + release_clip((HDC)hdc); +} + +int NSWebPage::pt_to_px(int pt) const +{ + return MulDiv(pt, GetDeviceCaps(m_tmp_hdc, LOGPIXELSY), 72); +} + +void NSWebPage::draw_solid_fill(uint_ptr _hdc, const background_layer &bg, const web_color &color) +{ + HDC hdc = (HDC)_hdc; + apply_clip(hdc); + + fill_rect(hdc, bg.border_box.x, bg.border_box.y, bg.border_box.width, bg.border_box.height, color); + + release_clip(hdc); +} + +void NSWebPage::draw_linear_gradient(uint_ptr, const background_layer &, const background_layer::linear_gradient &) +{} + +void NSWebPage::draw_radial_gradient(uint_ptr, const background_layer &, const background_layer::radial_gradient &) +{} + +void NSWebPage::draw_conic_gradient(uint_ptr, const background_layer &, const background_layer::conic_gradient &) +{} + +void NSWebPage::draw_list_marker(uint_ptr hdc, const list_marker &marker) +{ + apply_clip((HDC)hdc); + + int top_margin = marker.pos.height / 3; + if (top_margin < 4) + top_margin = 0; + + int draw_x = marker.pos.x; + int draw_y = marker.pos.y + top_margin; + int draw_width = marker.pos.height - top_margin * 2; + int draw_height = marker.pos.height - top_margin * 2; + + switch (marker.marker_type) { + case list_style_type_circle: + { + draw_ellipse((HDC)hdc, draw_x, draw_y, draw_width, draw_height, marker.color, 1); + } + break; + case list_style_type_disc: + { + fill_ellipse((HDC)hdc, draw_x, draw_y, draw_width, draw_height, marker.color); + } + break; + case list_style_type_square: + { + fill_rect((HDC)hdc, draw_x, draw_y, draw_width, draw_height, marker.color); + } + break; + } + release_clip((HDC)hdc); +} + +void NSWebPage::make_url_utf8(const char *url, const char *basepath, std::wstring &out) +{ + make_url(Utf2T(url), Utf2T(basepath), out); +} + +void NSWebPage::load_image(const char *src, const char *baseurl, bool redraw_on_ready) +{ + std::wstring url; + make_url_utf8(src, baseurl, url); + + mir_cslockfull lck(m_csImages); + if (m_images.count(url) == 0) { + lck.unlock(); + + uint_ptr img = get_image(url.c_str(), redraw_on_ready); + add_image(url.c_str(), img); + } +} + +void NSWebPage::add_image(LPCWSTR url, uint_ptr img) +{ + mir_cslock lck(m_csImages); + m_images[url] = img; +} + +void NSWebPage::get_image_size(const char *src, const char *baseurl, size &sz) +{ + std::wstring url; + make_url_utf8(src, baseurl, url); + + sz.width = 0; + sz.height = 0; + + mir_cslock lck(m_csImages); + images_map::iterator img = m_images.find(url); + if (img != m_images.end() && img->second) { + get_img_size(img->second, sz); + } +} + +void NSWebPage::clear_images() +{ + mir_cslock lck(m_csImages); + for (auto &img : m_images) { + if (img.second) { + free_image(img.second); + } + } + m_images.clear(); +} + +void NSWebPage::set_clip(const position &pos, const border_radiuses &) +{ + m_clips.push_back(pos); +} + +void NSWebPage::del_clip() +{ + if (!m_clips.empty()) { + m_clips.pop_back(); + } +} + +void NSWebPage::apply_clip(HDC hdc) +{ + if (m_hClipRgn) { + DeleteObject(m_hClipRgn); + m_hClipRgn = NULL; + } + + if (!m_clips.empty()) { + POINT ptView = { 0, 0 }; + GetWindowOrgEx(hdc, &ptView); + + position clip_pos = m_clips.back(); + m_hClipRgn = CreateRectRgn(clip_pos.left() - ptView.x, clip_pos.top() - ptView.y, clip_pos.right() - ptView.x, clip_pos.bottom() - ptView.y); + SelectClipRgn(hdc, m_hClipRgn); + } +} + +void NSWebPage::release_clip(HDC hdc) +{ + SelectClipRgn(hdc, NULL); + + if (m_hClipRgn) { + DeleteObject(m_hClipRgn); + m_hClipRgn = NULL; + } +} + +element::ptr NSWebPage::create_element(const char *, const string_map &, const document::ptr &) +{ + return 0; +} + +void NSWebPage::get_media_features(media_features &media) const +{ + position client; + get_client_rect(client); + + media.type = media_type_screen; + media.width = client.width; + media.height = client.height; + media.color = 8; + media.monochrome = 0; + media.color_index = 256; + media.resolution = GetDeviceCaps(m_tmp_hdc, LOGPIXELSX); + media.device_width = GetDeviceCaps(m_tmp_hdc, HORZRES); + media.device_height = GetDeviceCaps(m_tmp_hdc, VERTRES); +} + +void NSWebPage::get_language(std::string &language, std::string &culture) const +{ + language = "en"; + culture = ""; +} + +void NSWebPage::transform_text(std::string &text, text_transform tt) +{ + if (text.empty()) return; + + LPWSTR txt = _wcsdup(Utf2T(text.c_str())); + switch (tt) { + case text_transform_capitalize: + CharUpperBuff(txt, 1); + break; + case text_transform_uppercase: + CharUpperBuff(txt, lstrlen(txt)); + break; + case text_transform_lowercase: + CharLowerBuff(txt, lstrlen(txt)); + break; + } + text = T2Utf(txt); + free(txt); +} + +void NSWebPage::link(const document::ptr &, const element::ptr &) +{} + +///////////////////////////////////////////////////////////////////////////////////////// +// GDI+ part (former gdiplus_container) + +static Color gdiplus_color(web_color color) +{ + return Color(color.alpha, color.red, color.green, color.blue); +} + +void NSWebPage::draw_ellipse(HDC hdc, int x, int y, int width, int height, web_color color, int) +{ + Graphics graphics(hdc); + + graphics.SetCompositingQuality(CompositingQualityHighQuality); + graphics.SetSmoothingMode(SmoothingModeAntiAlias); + + Pen pen(gdiplus_color(color)); + graphics.DrawEllipse(&pen, x, y, width, height); +} + +void NSWebPage::fill_ellipse(HDC hdc, int x, int y, int width, int height, web_color color) +{ + Graphics graphics(hdc); + + graphics.SetCompositingQuality(CompositingQualityHighQuality); + graphics.SetSmoothingMode(SmoothingModeAntiAlias); + + SolidBrush brush(gdiplus_color(color)); + graphics.FillEllipse(&brush, x, y, width, height); +} + +void NSWebPage::fill_rect(HDC hdc, int x, int y, int width, int height, web_color color) +{ + Graphics graphics(hdc); + + SolidBrush brush(gdiplus_color(color)); + graphics.FillRectangle(&brush, x, y, width, height); +} + +void NSWebPage::get_img_size(uint_ptr img, size &sz) +{ + Bitmap *bmp = (Bitmap *)img; + if (bmp) { + sz.width = bmp->GetWidth(); + sz.height = bmp->GetHeight(); + } +} + +void NSWebPage::free_image(uint_ptr img) +{ + Bitmap *bmp = (Bitmap *)img; + delete bmp; +} + +void NSWebPage::draw_image(uint_ptr _hdc, const background_layer &bg, const std::string &src, const std::string &base_url) +{ + if (src.empty() || (!bg.clip_box.width && !bg.clip_box.height)) + return; + + Bitmap *bgbmp; + std::wstring url; + make_url_utf8(src.c_str(), base_url.c_str(), url); + { + mir_cslock lck(m_csImages); + images_map::iterator img = m_images.find(url); + if (img != m_images.end() && img->second) + bgbmp = (Bitmap *)img->second; + else + return; + } + + Graphics graphics((HDC)_hdc); + graphics.SetInterpolationMode(Gdiplus::InterpolationModeNearestNeighbor); + graphics.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHalf); + + Region reg(Rect(bg.border_box.left(), bg.border_box.top(), bg.border_box.width, bg.border_box.height)); + graphics.SetClip(®); + + Bitmap *scaled_img = nullptr; + if (bg.origin_box.width != bgbmp->GetWidth() || bg.origin_box.height != bgbmp->GetHeight()) { + scaled_img = new Bitmap(bg.origin_box.width, bg.origin_box.height); + Graphics gr(scaled_img); + gr.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHighQuality); + gr.DrawImage(bgbmp, 0, 0, bg.origin_box.width, bg.origin_box.height); + bgbmp = scaled_img; + } + + switch (bg.repeat) { + case background_repeat_no_repeat: + { + graphics.DrawImage(bgbmp, bg.origin_box.x, bg.origin_box.y, bgbmp->GetWidth(), bgbmp->GetHeight()); + } + break; + case background_repeat_repeat_x: + { + CachedBitmap bmp(bgbmp, &graphics); + int x = bg.origin_box.x; + while (x > bg.clip_box.left()) x -= bgbmp->GetWidth(); + for (; x < bg.clip_box.right(); x += bgbmp->GetWidth()) { + graphics.DrawCachedBitmap(&bmp, x, bg.origin_box.y); + } + } + break; + case background_repeat_repeat_y: + { + CachedBitmap bmp(bgbmp, &graphics); + int y = bg.origin_box.y; + while (y > bg.clip_box.top()) y -= bgbmp->GetHeight(); + for (; y < bg.clip_box.bottom(); y += bgbmp->GetHeight()) { + graphics.DrawCachedBitmap(&bmp, bg.origin_box.x, y); + } + } + break; + case background_repeat_repeat: + { + CachedBitmap bmp(bgbmp, &graphics); + int x = bg.origin_box.x; + while (x > bg.clip_box.left()) x -= bgbmp->GetWidth(); + int y0 = bg.origin_box.y; + while (y0 > bg.clip_box.top()) y0 -= bgbmp->GetHeight(); + + for (; x < bg.clip_box.right(); x += bgbmp->GetWidth()) { + for (int y = y0; y < bg.clip_box.bottom(); y += bgbmp->GetHeight()) { + graphics.DrawCachedBitmap(&bmp, x, y); + } + } + } + break; + } + + delete scaled_img; +} + +// length of dash and space for "dashed" style, in multiples of pen width +const float dash = 3; +const float space = 2; + +static void draw_horz_border(Graphics &graphics, const border &border, int y, int left, int right) +{ + if (border.style != border_style_double || border.width < 3) { + if (border.width == 1) right--; // 1px-wide lines are longer by one pixel in GDI+ (the endpoint is also drawn) + Pen pen(gdiplus_color(border.color), (float)border.width); + if (border.style == border_style_dotted) { + float dashValues[2] = { 1, 1 }; + pen.SetDashPattern(dashValues, 2); + } + else if (border.style == border_style_dashed) { + float dashValues[2] = { dash, space }; + pen.SetDashPattern(dashValues, 2); + } + graphics.DrawLine(&pen, + Point(left, y + border.width / 2), + Point(right, y + border.width / 2)); + } + else { + int single_line_width = (int)round(border.width / 3.); + if (single_line_width == 1) right--; + Pen pen(gdiplus_color(border.color), (float)single_line_width); + graphics.DrawLine(&pen, + Point(left, y + single_line_width / 2), + Point(right, y + single_line_width / 2)); + graphics.DrawLine(&pen, + Point(left, y + border.width - 1 - single_line_width / 2), + Point(right, y + border.width - 1 - single_line_width / 2)); + } +} + +static void draw_vert_border(Graphics &graphics, const border &border, int x, int top, int bottom) +{ + if (border.style != border_style_double || border.width < 3) { + if (border.width == 1) bottom--; + Pen pen(gdiplus_color(border.color), (float)border.width); + if (border.style == border_style_dotted) { + float dashValues[2] = { 1, 1 }; + pen.SetDashPattern(dashValues, 2); + } + else if (border.style == border_style_dashed) { + float dashValues[2] = { dash, space }; + pen.SetDashPattern(dashValues, 2); + } + graphics.DrawLine(&pen, + Point(x + border.width / 2, top), + Point(x + border.width / 2, bottom)); + } + else { + int single_line_width = (int)round(border.width / 3.); + if (single_line_width == 1) bottom--; + Pen pen(gdiplus_color(border.color), (float)single_line_width); + graphics.DrawLine(&pen, + Point(x + single_line_width / 2, top), + Point(x + single_line_width / 2, bottom)); + graphics.DrawLine(&pen, + Point(x + border.width - 1 - single_line_width / 2, top), + Point(x + border.width - 1 - single_line_width / 2, bottom)); + } +} + +void NSWebPage::draw_borders(uint_ptr hdc, const borders &borders, const position &draw_pos, bool) +{ + apply_clip((HDC)hdc); + Graphics graphics((HDC)hdc); + + if (borders.left.width != 0) { + draw_vert_border(graphics, borders.left, draw_pos.left(), draw_pos.top(), draw_pos.bottom()); + } + if (borders.right.width != 0) { + draw_vert_border(graphics, borders.right, draw_pos.right() - borders.right.width, draw_pos.top(), draw_pos.bottom()); + } + if (borders.top.width != 0) { + draw_horz_border(graphics, borders.top, draw_pos.top(), draw_pos.left(), draw_pos.right()); + } + if (borders.bottom.width != 0) { + draw_horz_border(graphics, borders.bottom, draw_pos.bottom() - borders.bottom.width, draw_pos.left(), draw_pos.right()); + } + + release_clip((HDC)hdc); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// NSWebPage own functions + +uint_ptr NSWebPage::get_image(LPCWSTR url_or_path, bool) { if (!mir_wstrncmp(url_or_path, L"file://", 7)) url_or_path += 7; - return (litehtml::uint_ptr)new Gdiplus::Bitmap(url_or_path); + return (uint_ptr)new Gdiplus::Bitmap(url_or_path); } -void NSWebPage::get_client_rect(litehtml::position &pos) const +void NSWebPage::get_client_rect(position &pos) const { - pos = litehtml::size(ctrl.cachedWindowWidth, ctrl.cachedWindowHeight); + pos = size(ctrl.cachedWindowWidth, ctrl.cachedWindowHeight); } -void NSWebPage::import_css(litehtml::string &, const litehtml::string &, litehtml::string &) +void NSWebPage::import_css(std::string &, const std::string &, std::string &) { } @@ -60,7 +670,7 @@ void NSWebPage::make_url(LPCWSTR url, LPCWSTR, std::wstring &out) out = url; } -void NSWebPage::on_anchor_click(const char *pszUtl, const litehtml::element::ptr &) +void NSWebPage::on_anchor_click(const char *pszUtl, const element::ptr &) { Utils_OpenUrl(pszUtl); } @@ -73,10 +683,6 @@ void NSWebPage::set_caption(const char *) { } -void NSWebPage::set_clip(const litehtml::position &, const litehtml::border_radiuses &) -{ -} - void NSWebPage::set_cursor(const char *pszCursor) { if (!mir_strcmp(pszCursor, "pointer")) |