summaryrefslogtreecommitdiff
path: root/plugins/NewStory/src
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2024-03-31 13:01:39 +0300
committerGeorge Hazan <george.hazan@gmail.com>2024-03-31 13:01:39 +0300
commit642682bda6c10dc1fbd06aa1b978608c0ba9a1f2 (patch)
treefa08de1b00ade14bc701fa7ab1bf5a80d9f7ae6d /plugins/NewStory/src
parent482709434f32ea4e476a477a534e5baa048f2886 (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.h80
-rw-r--r--plugins/NewStory/src/stdafx.h3
-rw-r--r--plugins/NewStory/src/webpage.cpp632
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(&reg);
+
+ 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"))