win32_container.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. #include <litehtml.h>
  2. #include "win32_container.h"
  3. litehtml::win32_container::win32_container()
  4. {
  5. m_hClipRgn = NULL;
  6. }
  7. litehtml::win32_container::~win32_container()
  8. {
  9. if(m_hClipRgn)
  10. {
  11. DeleteObject(m_hClipRgn);
  12. }
  13. }
  14. litehtml::uint_ptr litehtml::win32_container::create_font( const wchar_t* faceName, int size, int weight, font_style italic, unsigned int decoration )
  15. {
  16. litehtml::string_vector fonts;
  17. tokenize(faceName, fonts, L",");
  18. litehtml::trim(fonts[0]);
  19. LOGFONT lf;
  20. ZeroMemory(&lf, sizeof(lf));
  21. wcscpy_s(lf.lfFaceName, LF_FACESIZE, fonts[0].c_str());
  22. lf.lfHeight = -size;
  23. lf.lfWeight = weight;
  24. lf.lfItalic = (italic == litehtml::fontStyleItalic) ? TRUE : FALSE;
  25. lf.lfCharSet = DEFAULT_CHARSET;
  26. lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
  27. lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  28. lf.lfQuality = DEFAULT_QUALITY;
  29. lf.lfStrikeOut = (decoration & litehtml::font_decoration_linethrough) ? TRUE : FALSE;
  30. lf.lfUnderline = (decoration & litehtml::font_decoration_underline) ? TRUE : FALSE;
  31. HFONT hFont = CreateFontIndirect(&lf);
  32. return (uint_ptr) hFont;
  33. }
  34. void litehtml::win32_container::delete_font( uint_ptr hFont )
  35. {
  36. DeleteObject((HFONT) hFont);
  37. }
  38. int litehtml::win32_container::line_height( uint_ptr hdc, uint_ptr hFont )
  39. {
  40. HFONT oldFont = (HFONT) SelectObject((HDC) hdc, (HFONT) hFont);
  41. TEXTMETRIC tm;
  42. GetTextMetrics((HDC) hdc, &tm);
  43. SelectObject((HDC) hdc, oldFont);
  44. return (int) tm.tmHeight;
  45. }
  46. int litehtml::win32_container::text_width( uint_ptr hdc, const wchar_t* text, uint_ptr hFont )
  47. {
  48. HFONT oldFont = (HFONT) SelectObject((HDC) hdc, (HFONT) hFont);
  49. SIZE sz = {0, 0};
  50. GetTextExtentPoint32((HDC) hdc, text, lstrlen(text), &sz);
  51. SelectObject((HDC) hdc, oldFont);
  52. return (int) sz.cx;
  53. }
  54. void litehtml::win32_container::draw_text( uint_ptr hdc, const wchar_t* text, uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos )
  55. {
  56. apply_clip((HDC) hdc);
  57. HFONT oldFont = (HFONT) SelectObject((HDC) hdc, (HFONT) hFont);
  58. SetBkMode((HDC) hdc, TRANSPARENT);
  59. SetTextColor((HDC) hdc, RGB(color.red, color.green, color.blue));
  60. RECT rcText = { pos.left(), pos.top(), pos.right(), pos.bottom() };
  61. DrawText((HDC) hdc, text, -1, &rcText, DT_SINGLELINE | DT_NOPREFIX | DT_BOTTOM | DT_NOCLIP);
  62. SelectObject((HDC) hdc, oldFont);
  63. release_clip((HDC) hdc);
  64. }
  65. void litehtml::win32_container::fill_rect( uint_ptr hdc, const litehtml::position& pos, const litehtml::web_color color, const litehtml::css_border_radius& radius )
  66. {
  67. apply_clip((HDC) hdc);
  68. fill_rect((HDC) hdc, pos.x, pos.y, pos.width, pos.height, color, radius);
  69. release_clip((HDC) hdc);
  70. }
  71. litehtml::uint_ptr litehtml::win32_container::get_temp_dc()
  72. {
  73. return (litehtml::uint_ptr) GetDC(NULL);
  74. }
  75. void litehtml::win32_container::release_temp_dc( uint_ptr hdc )
  76. {
  77. ReleaseDC(NULL, (HDC) hdc);
  78. }
  79. int litehtml::win32_container::pt_to_px( int pt )
  80. {
  81. HDC dc = GetDC(NULL);
  82. int ret = MulDiv(pt, GetDeviceCaps(dc, LOGPIXELSY), 72);
  83. ReleaseDC(NULL, dc);
  84. return ret;
  85. }
  86. int litehtml::win32_container::get_text_base_line( uint_ptr hdc, uint_ptr hFont )
  87. {
  88. HDC dc = (HDC) hdc;
  89. if(!dc)
  90. {
  91. dc = GetDC(NULL);
  92. }
  93. HFONT oldFont = (HFONT) SelectObject(dc, (HFONT) hFont);
  94. TEXTMETRIC tm;
  95. GetTextMetrics(dc, &tm);
  96. SelectObject(dc, oldFont);
  97. if(!hdc)
  98. {
  99. ReleaseDC(NULL, dc);
  100. }
  101. return (int) tm.tmDescent;
  102. }
  103. void litehtml::win32_container::draw_list_marker(uint_ptr hdc, const litehtml::list_marker& marker)
  104. {
  105. apply_clip((HDC)hdc);
  106. int top_margin = marker.pos.height / 3;
  107. if (top_margin < 4)
  108. top_margin = 0;
  109. int draw_x = marker.pos.x;
  110. int draw_y = marker.pos.y + top_margin;
  111. int draw_width = marker.pos.height - top_margin * 2;
  112. int draw_height = marker.pos.height - top_margin * 2;
  113. switch (marker.marker_type)
  114. {
  115. case list_style_type_circle:
  116. {
  117. draw_ellipse((HDC)hdc, draw_x, draw_y, draw_width, draw_height, marker.color, 1);
  118. }
  119. break;
  120. case list_style_type_disc:
  121. {
  122. fill_ellipse((HDC)hdc, draw_x, draw_y, draw_width, draw_height, marker.color);
  123. }
  124. break;
  125. case list_style_type_square:
  126. {
  127. fill_rect((HDC)hdc, draw_x, draw_y, draw_width, draw_height, marker.color, css_border_radius());
  128. }
  129. break;
  130. }
  131. release_clip((HDC)hdc);
  132. }
  133. void litehtml::win32_container::load_image( const wchar_t* src, const wchar_t* baseurl, bool redraw_on_ready )
  134. {
  135. std::wstring url;
  136. make_url(src, baseurl, url);
  137. if(m_images.find(url.c_str()) == m_images.end())
  138. {
  139. uint_ptr img = get_image(url.c_str());
  140. if(img)
  141. {
  142. m_images[url.c_str()] = img;
  143. }
  144. }
  145. }
  146. void litehtml::win32_container::get_image_size( const wchar_t* src, const wchar_t* baseurl, litehtml::size& sz )
  147. {
  148. std::wstring url;
  149. make_url(src, baseurl, url);
  150. images_map::iterator img = m_images.find(url.c_str());
  151. if(img != m_images.end())
  152. {
  153. get_img_size(img->second, sz);
  154. }
  155. }
  156. void litehtml::win32_container::draw_image( uint_ptr hdc, const wchar_t* src, const wchar_t* baseurl, const litehtml::position& pos )
  157. {
  158. apply_clip((HDC) hdc);
  159. std::wstring url;
  160. make_url(src, baseurl, url);
  161. images_map::iterator img = m_images.find(url.c_str());
  162. if(img != m_images.end())
  163. {
  164. draw_img((HDC) hdc, img->second, pos);
  165. }
  166. release_clip((HDC) hdc);
  167. }
  168. void litehtml::win32_container::clear_images()
  169. {
  170. for(images_map::iterator i = m_images.begin(); i != m_images.end(); i++)
  171. {
  172. if(i->second)
  173. {
  174. free_image(i->second);
  175. }
  176. }
  177. m_images.clear();
  178. }
  179. int litehtml::win32_container::get_default_font_size() const
  180. {
  181. return 16;
  182. }
  183. void litehtml::win32_container::draw_background( uint_ptr hdc, const wchar_t* image, const wchar_t* baseurl, const litehtml::position& draw_pos, const litehtml::css_position& bg_pos, litehtml::background_repeat repeat, litehtml::background_attachment attachment )
  184. {
  185. apply_clip((HDC) hdc);
  186. std::wstring url;
  187. make_url(image, baseurl, url);
  188. images_map::iterator img = m_images.find(url.c_str());
  189. if(img != m_images.end())
  190. {
  191. litehtml::size img_sz;
  192. get_img_size(img->second, img_sz);
  193. litehtml::position pos = draw_pos;
  194. if(bg_pos.x.units() != css_units_percentage)
  195. {
  196. pos.x += (int) bg_pos.x.val();
  197. } else
  198. {
  199. pos.x += (int) ((float) (draw_pos.width - img_sz.width) * bg_pos.x.val() / 100.0);
  200. }
  201. if(bg_pos.y.units() != css_units_percentage)
  202. {
  203. pos.y += (int) bg_pos.y.val();
  204. } else
  205. {
  206. pos.y += (int) ( (float) (draw_pos.height - img_sz.height) * bg_pos.y.val() / 100.0);
  207. }
  208. draw_img_bg((HDC) hdc, img->second, draw_pos, pos, repeat, attachment);
  209. }
  210. release_clip((HDC) hdc);
  211. }
  212. wchar_t litehtml::win32_container::toupper( const wchar_t c )
  213. {
  214. return (wchar_t) CharUpper((LPWSTR) c);
  215. }
  216. wchar_t litehtml::win32_container::tolower( const wchar_t c )
  217. {
  218. return (wchar_t) CharLower((LPWSTR) c);
  219. }
  220. void litehtml::win32_container::set_clip( const litehtml::position& pos, bool valid_x, bool valid_y )
  221. {
  222. litehtml::position clip_pos = pos;
  223. litehtml::position client_pos;
  224. get_client_rect(client_pos);
  225. if(!valid_x)
  226. {
  227. clip_pos.x = client_pos.x;
  228. clip_pos.width = client_pos.width;
  229. }
  230. if(!valid_y)
  231. {
  232. clip_pos.y = client_pos.y;
  233. clip_pos.height = client_pos.height;
  234. }
  235. m_clips.push_back(clip_pos);
  236. }
  237. void litehtml::win32_container::del_clip()
  238. {
  239. if(!m_clips.empty())
  240. {
  241. m_clips.pop_back();
  242. if(!m_clips.empty())
  243. {
  244. litehtml::position clip_pos = m_clips.back();
  245. }
  246. }
  247. }
  248. void litehtml::win32_container::apply_clip(HDC hdc)
  249. {
  250. if(m_hClipRgn)
  251. {
  252. DeleteObject(m_hClipRgn);
  253. m_hClipRgn = NULL;
  254. }
  255. if(!m_clips.empty())
  256. {
  257. POINT ptView = {0, 0};
  258. GetWindowOrgEx(hdc, &ptView);
  259. litehtml::position clip_pos = m_clips.back();
  260. m_hClipRgn = CreateRectRgn(clip_pos.left() - ptView.x, clip_pos.top() - ptView.y, clip_pos.right() - ptView.x, clip_pos.bottom() - ptView.y);
  261. SelectClipRgn(hdc, m_hClipRgn);
  262. }
  263. }
  264. void litehtml::win32_container::release_clip(HDC hdc)
  265. {
  266. SelectClipRgn(hdc, NULL);
  267. if(m_hClipRgn)
  268. {
  269. DeleteObject(m_hClipRgn);
  270. m_hClipRgn = NULL;
  271. }
  272. }