Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork265
How to use litehtml
To use litehtml you need some easy steps:
- Implementlitehtml::document_container class.
- Prepare and load the master CSS.
- Call some functions fromlitehtml::document to parse, render and draw HTML text.
The first step to integrate litehtml into your application is implementing abstract classlitehtml::document_container. This class draw the HTML elements and perform some actions depended of the platform.
First you have to createlitehtml::context object and load master CSS withlitehtml::context::load_master_stylesheet function. Master CSS must contain the default styles for all HTML elements. See the master.css and example.
litehtml have 3 functions to render HTML document:
static litehtml::document::ptrcreateFromString(constchar* str, litehtml::document_container* objPainter, litehtml::context* ctx, litehtml::css* user_styles =nullptr);
createFromString - creates litehtml::document from string (null terminated). Note string must be in UTF-8 encoding.
str - HTML code
objPainter - your implementation oflitehtml::document_container
ctx - HTML context with master CSS
user_styles - optional user CSS (applied after all other styles)
createFromString returns the litehtml::document pointer. Calllitehtml::document::render(max_width) to render HTML elements:
m_doc->render(max_width);The parametermax_width usually the browser window width. Alsorender returns the optimal width for HTML text. You can use the returned value to render elements into the optimal width. This can be useful for tooltips.
Useheight andwidth litehtml::document functions to find the width and height of the rendered document:
m_doc->height()m_doc->width()Now calldraw function:
m_doc->draw(hdc, m_left, m_top, &clip);draw accepts 4 parameters:
- uint_ptr hdc - usually device context or something where to draw. For example HDC in windows. This parameter will be passed into all draw functions oflitehtml::document_container.
- int x, int y - position where to draw HTML.
- const position* clip - clipping area. litehtml does not draw the elements that don't intersect the clipping rectangle. But note, you have to set your own clipping if you want to clip HTML content.
That's all! Your HTML page is painted!
If you don't have the fixed size window to draw HTML, you need to get the HTMLbest width. It is very easy:document::render returns the best width for you.
So the example looks like this:
int best_width = m_doc->render(max_width);if(best_width < max_width){m_doc->render(best_width);}
First you render document with the maximum possible width anddocument::render returns the best width for HTML. If the best width is less then maximum width, you have to render your document with the returnedbest width. Now you can usedocument::width to get the actual document width.
You can use this technique to show HTML tooltips in your application or to create the HTML widgets.
Scrolling of html document is released via x,y parameters of the document::draw function. For example, if you want to scroll document on 50px horizontally and 100px vertically:
m_doc->draw(hdc, -50, -100, litehtml::position(50,100, window_width, window_height));
Note, thex andy parameters are screen relative. Theclip parameter is always document relative. Also note, definingclip parameter indraw does not guarantee the valid clipping. Some elements can be drawn out off the clipping area. litehtml just checks if the element's bounding rectangle is intersected with clipping rectangle to draw elements. So you must implement your own clipping.
If you want to handle the mouse you have call some functions fromlitehtml::document:
bool litehtml::document::on_mouse_over( int x, int y, int client_x, int client_y, position::vector& redraw_boxes );bool litehtml::document::on_mouse_leave( position::vector& redraw_boxes );bool litehtml::document::on_lbutton_down( int x, int y, int client_x, int client_y, position::vector& redraw_boxes );bool litehtml::document::on_lbutton_up( int x, int y, int client_x, int client_y, position::vector& redraw_boxes );All functions returns thebool to indicate that you have to redraw the rectangles fromredraw_boxes vector. Also note thex andy are relative to the HTML layout. So0,0 is the top-left corner.The parametersclient_x andclient_y are the mouse position in the client area (draw area). These parameters are used to handle the elements withfixed position.
If you process the mouse, the clicking on anchor tag will calls the functiondocument_container::on_anchor_click. This function gets the url of the anchor as parameter and pointer to litehtml::element. You can open the new document at this point.
NOTE: Don't delete the document insidedocument_container::on_anchor_click, this will cause the crash. Thedocument_container::on_anchor_click is generated bydocument::on_lbutton_up, so it is safe to delete old document and show new one afterdocument::on_lbutton_up is finished.
litehtml does not have the special handling of the named anchors. But it is easy to process the named anchors manually. You get the url with the anchor name intodocument_container::on_anchor_click. Just find the hash char (#) and extract the name. In the example below, the variableanchor_name contains the anchor name:
if(!anchor_name.empty()){if(m_doc){WCHAR selector[255];StringCchPrintf(selector,255,L"#%s", anchor_name.c_str());element::ptr el = m_doc->root()->select_one(selector);if(!el){StringCchPrintf(selector,255,L"[name=%s]", anchor_name.c_str());el = m_doc->root()->select_one(selector);}if(el){litehtml::position pos = el->get_placement();m_top = pos.y;}}}
The functionelement::select_one returns the first element for the CSS selector. Soselect_one("#name") return the element with attributeid="name".el->get_placement() returns the absolute position of the element (document relative coordinates).
So, you have the position of the named anchor and now you can scroll your document into this position.
litehtml does not cache the images. So if you want to increase the performance, you have to create your own images cache. Also you can implement the delayed images loading. Start image downloading in [#load_image load_image] function. If the image is not loaded return fake sizes and draw placeholder. When the image is loaded calllitehtml::document::render, and redraw page.
litehtml support CSS @media at-rule as well aremedia attribute in the <link> and <style> html tags. To make CSS media support you need:
- Implementdocument_container::get_media_features function and fill themedia parameter with valid media features (like width, height etc.).
- Calldocument::media_changed function when any media feature is changed (for example user is changed the window size).