pax_global_header00006660000000000000000000000064142231255020014506gustar00rootroot0000000000000052 comment=43af58e8adad70c4f1a0a9235546a246754c1737 litehtml-0.6/000077500000000000000000000000001422312550200131755ustar00rootroot00000000000000litehtml-0.6/.github/000077500000000000000000000000001422312550200145355ustar00rootroot00000000000000litehtml-0.6/.github/workflows/000077500000000000000000000000001422312550200165725ustar00rootroot00000000000000litehtml-0.6/.github/workflows/cmake.yml000066400000000000000000000026441422312550200204030ustar00rootroot00000000000000name: CMake on: push: branches: [ master ] pull_request: branches: [ master ] env: # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) BUILD_TYPE: Release jobs: build: # The CMake configure and build commands are platform agnostic and should work equally # well on Windows or Mac. You can convert this to a matrix build if you need # cross-platform coverage. # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Configure CMake # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - name: Build # Build your program with the given configuration run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} - name: Test working-directory: ${{github.workspace}}/build # Execute tests defined by the CMake configuration. # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail run: ctest -C ${{env.BUILD_TYPE}} --rerun-failed --output-on-failure litehtml-0.6/.gitignore000066400000000000000000000050751422312550200151740ustar00rootroot00000000000000## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. # User-specific files *.suo *.user *.sln.docstates # Build results cmake-build-*/ [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ x64/ build/ bld/ [Bb]in/ [Oo]bj/ _build/ _build32/ _build64/ *.inc # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* [Tt]esting/ #NUNIT *.VisualState.xml TestResult.xml # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ dlldata.c *_i.c *_p.c *_i.h *.ilk *.meta *.obj *.pch *.pdb *.pgc *.pgd *.rsp *.sbr *.tlb *.tli *.tlh *.tmp *.tmp_proj *.log *.vspscc *.vssscc .builds *.pidb *.svclog *.scc # Chutzpah Test files _Chutzpah* # Visual C++ cache files ipch/ *.aps *.ncb *.opensdf *.sdf *.cachefile # Visual Studio profiler *.psess *.vsp *.vspx # TFS 2012 Local Workspace $tf/ # Guidance Automation Toolkit *.gpState # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user # JustCode is a .NET coding addin-in .JustCode # TeamCity is a build add-in _TeamCity* # DotCover is a Code Coverage Tool *.dotCover # NCrunch *.ncrunch* _NCrunch_* .*crunch*.local.xml # MightyMoose *.mm.* AutoTest.Net/ # Web workbench (sass) .sass-cache/ # Installshield output folder [Ee]xpress/ # DocProject is a documentation generator add-in DocProject/buildhelp/ DocProject/Help/*.HxT DocProject/Help/*.HxC DocProject/Help/*.hhc DocProject/Help/*.hhk DocProject/Help/*.hhp DocProject/Help/Html2 DocProject/Help/html # Click-Once directory publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml # NuGet Packages Directory packages/ ## TODO: If the tool you use requires repositories.config uncomment the next line #!packages/repositories.config # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented) !packages/build/ # Windows Azure Build Output csx/ *.build.csdef # Windows Store app package directory AppPackages/ # Others .idea/ .vs/ .vscode/ sql/ *.Cache ClientBin/ [Ss]tyle[Cc]op.* ~$* *~ *.dbmdl *.dbproj.schemaview *.pfx *.publishsettings node_modules/ # RIA/Silverlight projects Generated_Code/ # Backup & report files from converting an old project file to a newer # Visual Studio version. Backup files are not needed, because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm # SQL Server files *.mdf *.ldf # Business Intelligence projects *.rdl.data *.bim.layout *.bim_*.settings # Microsoft Fakes FakesAssemblies/ litehtml-0.6/CMakeLists.txt000066400000000000000000000155011422312550200157370ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.11) project(litehtml LANGUAGES C CXX) include(CTest) enable_testing() # Soname # MAJOR is incremented when symbols are removed or changed in an incompatible way # MINOR is incremented when new symbols are added set(PROJECT_MAJOR 0) set(PROJECT_MINOR 0) option(EXTERNAL_GUMBO "Link against external gumbo instead of shipping a bundled copy" OFF) if(NOT EXTERNAL_GUMBO) add_subdirectory(src/gumbo) endif() set(SOURCE_LITEHTML src/background.cpp src/box.cpp src/codepoint.cpp src/context.cpp src/css_length.cpp src/css_selector.cpp src/document.cpp src/el_anchor.cpp src/el_base.cpp src/el_before_after.cpp src/el_body.cpp src/el_break.cpp src/el_cdata.cpp src/el_comment.cpp src/el_div.cpp src/element.cpp src/el_font.cpp src/el_image.cpp src/el_link.cpp src/el_li.cpp src/el_para.cpp src/el_script.cpp src/el_space.cpp src/el_style.cpp src/el_table.cpp src/el_td.cpp src/el_text.cpp src/el_title.cpp src/el_tr.cpp src/html.cpp src/html_tag.cpp src/iterators.cpp src/media_query.cpp src/style.cpp src/stylesheet.cpp src/table.cpp src/tstring_view.cpp src/url.cpp src/url_path.cpp src/utf8_strings.cpp src/web_color.cpp src/num_cvt.cpp src/strtod.cpp ) set(HEADER_LITEHTML include/litehtml.h include/litehtml/attributes.h include/litehtml/background.h include/litehtml/borders.h include/litehtml/box.h include/litehtml/codepoint.h include/litehtml/context.h include/litehtml/css_length.h include/litehtml/css_margins.h include/litehtml/css_offsets.h include/litehtml/css_position.h include/litehtml/css_selector.h include/litehtml/document.h include/litehtml/el_anchor.h include/litehtml/el_base.h include/litehtml/el_before_after.h include/litehtml/el_body.h include/litehtml/el_break.h include/litehtml/el_cdata.h include/litehtml/el_comment.h include/litehtml/el_div.h include/litehtml/el_font.h include/litehtml/el_image.h include/litehtml/el_link.h include/litehtml/el_para.h include/litehtml/el_script.h include/litehtml/el_space.h include/litehtml/el_style.h include/litehtml/el_table.h include/litehtml/el_td.h include/litehtml/el_text.h include/litehtml/el_title.h include/litehtml/el_tr.h include/litehtml/element.h include/litehtml/html.h include/litehtml/html_tag.h include/litehtml/iterators.h include/litehtml/media_query.h include/litehtml/os_types.h include/litehtml/style.h include/litehtml/stylesheet.h include/litehtml/table.h include/litehtml/tstring_view.h include/litehtml/types.h include/litehtml/url.h include/litehtml/url_path.h include/litehtml/utf8_strings.h include/litehtml/web_color.h include/litehtml/num_cvt.h ) set(TEST_LITEHTML containers/test/container_test.cpp test/codepoint_test.cpp test/contextTest.cpp test/cssTest.cpp test/documentTest.cpp test/layoutGlobalTest.cpp test/mediaQueryTest.cpp test/tstring_view_test.cpp test/url_test.cpp test/url_path_test.cpp test/webColorTest.cpp ) set(PROJECT_LIB_VERSION ${PROJECT_MAJOR}.${PROJECT_MINOR}.0) set(PROJECT_SO_VERSION ${PROJECT_MAJOR}) add_library(${PROJECT_NAME} ${SOURCE_LITEHTML}) set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_LIB_VERSION} SOVERSION ${PROJECT_SO_VERSION}) set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 11 C_STANDARD 99 PUBLIC_HEADER "${HEADER_LITEHTML}" ) # Export litehtml includes. target_include_directories(${PROJECT_NAME} PUBLIC $ $ $) target_include_directories(${PROJECT_NAME} PRIVATE include/${PROJECT_NAME}) option(LITEHTML_UTF8 "Build litehtml with UTF-8 text conversion functions." OFF) if (LITEHTML_UTF8) target_compile_definitions(${PROJECT_NAME} PUBLIC LITEHTML_UTF8) endif() # Gumbo target_link_libraries(${PROJECT_NAME} PUBLIC gumbo) # install and export install(TARGETS ${PROJECT_NAME} EXPORT litehtmlTargets RUNTIME DESTINATION bin COMPONENT libraries ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT libraries LIBRARY DESTINATION lib${LIB_SUFFIX} COMPONENT libraries PUBLIC_HEADER DESTINATION include/litehtml ) install(FILES cmake/litehtmlConfig.cmake DESTINATION lib${LIB_SUFFIX}/cmake/litehtml) install(EXPORT litehtmlTargets FILE litehtmlTargets.cmake DESTINATION lib${LIB_SUFFIX}/cmake/litehtml) # Generate master.css.inc function(make_inc src dst) file(READ ${src} data) file(WRITE ${dst} "R\"##(\n${data})##\"") endfunction(make_inc) make_inc(include/master.css src/master.css.inc) set_source_files_properties(src/master.css.inc PROPERTIES GENERATED TRUE) # Tests if (BUILD_TESTING) include(FetchContent) FetchContent_Declare( googletest URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip ) # For Windows: Prevent overriding the parent project's compiler/linker settings set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) FetchContent_GetProperties(googletest) if(NOT googletest_POPULATED) FetchContent_Populate(googletest) add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR}) endif() enable_testing() set(TEST_NAME ${PROJECT_NAME}_tests) add_executable( ${TEST_NAME} ${TEST_LITEHTML} ${CMAKE_CURRENT_SOURCE_DIR}/src/master.css.inc ) set_target_properties(${TEST_NAME} PROPERTIES CXX_STANDARD 11 C_STANDARD 99 PUBLIC_HEADER "${HEADER_LITEHTML}" ) target_include_directories( ${TEST_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/containers ) target_link_libraries( ${TEST_NAME} ${PROJECT_NAME} gtest_main ) include(GoogleTest) gtest_discover_tests(${TEST_NAME}) endif() # set(TEST_NAME ${PROJECT_NAME}_tests) # add_executable(${TEST_NAME} ${TEST_LITEHTML} ${CMAKE_CURRENT_SOURCE_DIR}/src/master.css.inc) # set_target_properties(${TEST_NAME} PROPERTIES # CXX_STANDARD 11 # C_STANDARD 99 # PUBLIC_HEADER "${HEADER_LITEHTML}" # ) # target_include_directories(${TEST_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/containers) # target_link_libraries(${TEST_NAME} PRIVATE ${PROJECT_NAME}) # # tests # add_test(NAME contextTest COMMAND ${TEST_NAME} 1) # add_test(NAME cssTest COMMAND ${TEST_NAME} 2) # add_test(NAME documentTest COMMAND ${TEST_NAME} 3) # add_test(NAME layoutGlobalTest COMMAND ${TEST_NAME} 4) # add_test(NAME mediaQueryTest COMMAND ${TEST_NAME} 5) # add_test(NAME webColorTest COMMAND ${TEST_NAME} 6) # endif() litehtml-0.6/LICENSE000066400000000000000000000027431422312550200142100ustar00rootroot00000000000000Copyright (c) 2013, Yuri Kobets (tordex) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. litehtml-0.6/README.md000066400000000000000000000063241422312550200144610ustar00rootroot00000000000000# What is litehtml? **litehtml** is the lightweight HTML rendering engine with CSS2/CSS3 support. Note that **litehtml** itself does not draw any text, pictures or other graphics and that **litehtml** does not depend on any image/draw/font library. You are free to use any library to draw images, fonts and any other graphics. **litehtml** just parses HTML/CSS and places the HTML elements into the correct positions (renders HTML). To draw the HTML elements you have to implement the simple callback interface [document_container](https://github.com/litehtml/litehtml/wiki/document_container). This interface is really simple, check it out! The [document_container](https://github.com/litehtml/litehtml/wiki/document_container) implementation is required to render HTML correctly. # Where litehtml can be used **litehtml** can be used when you need to show HTML formatted text or even to create a mini-browser, but using it as a full-featured HTML engine is not recommended. Usually you don't need something like WebKit to show simple HTML tooltips or HTML-formatted text, **litehtml** is much better for these as it's more lightweight and easier to integrate into your application. ## HTML Parser **litehtml** uses the [gumbo-parser](https://github.com/google/gumbo-parser) to parse HTML. Gumbo is an implementation of the HTML5 parsing algorithm implemented as a pure C99 library with no outside dependencies. It's designed to serve as a building block for other tools and libraries such as linters, validators, templating languages, and refactoring and analysis tools. ## Compatibility **litehtml** is compatible with any platform suported by C++ and STL. For Windows MS Visual Studio 2013 is recommended. **litehtml** supports both UTF-8 and Unicode strings on Windows and UTF-8 strings on Linux and Haiku. ## Support for HTML and CSS standards Unfortunately **litehtml** is not fully compatible with HTML/CSS standards. There is lots of work to do to make **litehtml** work as well as modern browsers. But **litehtml** supports most HTML tags and CSS properties. You can find the list of supported CSS properties in [this table](https://docs.google.com/spreadsheet/ccc?key=0AvHXl5n24PuhdHdELUdhaUl4OGlncXhDcDJuM1JpMnc&usp=sharing). For most simple usecases the HTML/CSS features supported by **litehtml** are enough. Right now **litehtml** supports even some pages with very complex HTML/CSS designs. As an example the pages created with [bootstrap framework](http://getbootstrap.com/) are usually well formatted by **litehtml**. ## Testing litehtml You can [download the simple browser](http://www.litehtml.com/download.html) (**litebrowser**) to test the **litehtml** rendering engine. The litebrowser source codes are available on GitHub: * [For Windows](https://github.com/litehtml/litebrowser) * [For Linux](https://github.com/litehtml/litebrowser-linux) * [For Haiku](https://github.com/adamfowleruk/litebrowser-haiku) ## License **litehtml** is distributed under [New BSD License](https://opensource.org/licenses/BSD-3-Clause). The **gumbo-parser** is disributed under [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) ## Links * [source code](https://github.com/litehtml/litehtml) * [website](http://www.litehtml.com/) litehtml-0.6/cmake/000077500000000000000000000000001422312550200142555ustar00rootroot00000000000000litehtml-0.6/cmake/litehtmlConfig.cmake000066400000000000000000000001621422312550200202260ustar00rootroot00000000000000include(CMakeFindDependencyMacro) find_dependency(gumbo) include(${CMAKE_CURRENT_LIST_DIR}/litehtmlTargets.cmake) litehtml-0.6/containers/000077500000000000000000000000001422312550200153425ustar00rootroot00000000000000litehtml-0.6/containers/cairo/000077500000000000000000000000001422312550200164375ustar00rootroot00000000000000litehtml-0.6/containers/cairo/cairo_container.cpp000066400000000000000000000633521422312550200223130ustar00rootroot00000000000000#include "cairo_container.h" #define _USE_MATH_DEFINES #include #include "cairo_font.h" #include cairo_container::cairo_container(void) { m_temp_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 2, 2); m_temp_cr = cairo_create(m_temp_surface); m_font_link = NULL; CoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_ALL, IID_IMLangFontLink2, (void**) &m_font_link); InitializeCriticalSection(&m_img_sync); } cairo_container::~cairo_container(void) { clear_images(); if(m_font_link) { m_font_link->Release(); } cairo_surface_destroy(m_temp_surface); cairo_destroy(m_temp_cr); DeleteCriticalSection(&m_img_sync); } litehtml::uint_ptr cairo_container::create_font( const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm ) { std::wstring fnt_name = L"sans-serif"; litehtml::string_vector fonts; litehtml::split_string(faceName, fonts, _t(",")); if(!fonts.empty()) { litehtml::trim(fonts[0]); #ifdef LITEHTML_UTF8 wchar_t* f = cairo_font::utf8_to_wchar(fonts[0].c_str()); fnt_name = f; delete f; #else fnt_name = fonts[0]; if (fnt_name.front() == L'"' || fnt_name.front() == L'\'') { fnt_name.erase(0, 1); } if (fnt_name.back() == L'"' || fnt_name.back() == L'\'') { fnt_name.erase(fnt_name.length() - 1, 1); } #endif } cairo_font* fnt = new cairo_font( m_font_link, fnt_name.c_str(), size, weight, (italic == litehtml::fontStyleItalic) ? TRUE : FALSE, (decoration & litehtml::font_decoration_linethrough) ? TRUE : FALSE, (decoration & litehtml::font_decoration_underline) ? TRUE : FALSE); cairo_save(m_temp_cr); fnt->load_metrics(m_temp_cr); if(fm) { fm->ascent = fnt->metrics().ascent; fm->descent = fnt->metrics().descent; fm->height = fnt->metrics().height; fm->x_height = fnt->metrics().x_height; if(italic == litehtml::fontStyleItalic || decoration) { fm->draw_spaces = true; } else { fm->draw_spaces = false; } } cairo_restore(m_temp_cr); return (litehtml::uint_ptr) fnt; } void cairo_container::delete_font( litehtml::uint_ptr hFont ) { cairo_font* fnt = (cairo_font*) hFont; if(fnt) { delete fnt; } } int cairo_container::text_width( const litehtml::tchar_t* text, litehtml::uint_ptr hFont ) { cairo_font* fnt = (cairo_font*) hFont; cairo_save(m_temp_cr); int ret = fnt->text_width(m_temp_cr, text); cairo_restore(m_temp_cr); return ret; } void cairo_container::draw_text( litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos ) { if(hFont) { cairo_font* fnt = (cairo_font*) hFont; cairo_t* cr = (cairo_t*) hdc; cairo_save(cr); apply_clip(cr); int x = pos.left(); int y = pos.bottom() - fnt->metrics().descent; set_color(cr, color); fnt->show_text(cr, x, y, text); cairo_restore(cr); } } int cairo_container::pt_to_px( int pt ) const { HDC dc = GetDC(NULL); int ret = MulDiv(pt, GetDeviceCaps(dc, LOGPIXELSY), 72); ReleaseDC(NULL, dc); return ret; } int cairo_container::get_default_font_size() const { return 16; } void cairo_container::draw_list_marker( litehtml::uint_ptr hdc, const litehtml::list_marker& marker ) { if(!marker.image.empty()) { std::wstring url; t_make_url(marker.image.c_str(), marker.baseurl, url); lock_images_cache(); images_map::iterator img_i = m_images.find(url.c_str()); if(img_i != m_images.end()) { if(img_i->second) { draw_txdib((cairo_t*)hdc, img_i->second.get(), marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height); unlock_images_cache(); return; } } unlock_images_cache(); } switch(marker.marker_type) { case litehtml::list_style_type_circle: { draw_ellipse((cairo_t*) hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color, 0.5); } break; case litehtml::list_style_type_disc: { fill_ellipse((cairo_t*) hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color); } break; case litehtml::list_style_type_square: if(hdc) { cairo_t* cr = (cairo_t*) hdc; cairo_save(cr); cairo_new_path(cr); cairo_rectangle(cr, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height); set_color(cr, marker.color); cairo_fill(cr); cairo_restore(cr); } break; } } void cairo_container::load_image( const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready ) { std::wstring url; t_make_url(src, baseurl, url); lock_images_cache(); if(m_images.find(url.c_str()) == m_images.end()) { unlock_images_cache(); image_ptr img = get_image(url.c_str(), redraw_on_ready); lock_images_cache(); m_images[url] = img; unlock_images_cache(); } else { unlock_images_cache(); } } void cairo_container::get_image_size( const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz ) { std::wstring url; t_make_url(src, baseurl, url); sz.width = 0; sz.height = 0; lock_images_cache(); images_map::iterator img = m_images.find(url.c_str()); if(img != m_images.end()) { if(img->second) { sz.width = img->second->getWidth(); sz.height = img->second->getHeight(); } } unlock_images_cache(); } void cairo_container::draw_image( litehtml::uint_ptr hdc, const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, const litehtml::position& pos ) { cairo_t* cr = (cairo_t*) hdc; cairo_save(cr); apply_clip(cr); std::wstring url; t_make_url(src, baseurl, url); lock_images_cache(); images_map::iterator img = m_images.find(url.c_str()); if(img != m_images.end()) { if(img->second) { draw_txdib(cr, img->second.get(), pos.x, pos.y, pos.width, pos.height); } } unlock_images_cache(); cairo_restore(cr); } void cairo_container::draw_background( litehtml::uint_ptr hdc, const litehtml::background_paint& bg ) { cairo_t* cr = (cairo_t*) hdc; cairo_save(cr); apply_clip(cr); rounded_rectangle(cr, bg.border_box, bg.border_radius); cairo_clip(cr); cairo_rectangle(cr, bg.clip_box.x, bg.clip_box.y, bg.clip_box.width, bg.clip_box.height); cairo_clip(cr); if(bg.color.alpha) { set_color(cr, bg.color); cairo_paint(cr); } std::wstring url; t_make_url(bg.image.c_str(), bg.baseurl.c_str(), url); lock_images_cache(); images_map::iterator img_i = m_images.find(url.c_str()); if(img_i != m_images.end() && img_i->second) { image_ptr bgbmp = img_i->second; image_ptr new_img; if(bg.image_size.width != bgbmp->getWidth() || bg.image_size.height != bgbmp->getHeight()) { new_img = image_ptr(new CTxDIB); bgbmp->resample(bg.image_size.width, bg.image_size.height, new_img.get()); bgbmp = new_img; } cairo_surface_t* img = cairo_image_surface_create_for_data((unsigned char*) bgbmp->getBits(), CAIRO_FORMAT_ARGB32, bgbmp->getWidth(), bgbmp->getHeight(), bgbmp->getWidth() * 4); cairo_pattern_t *pattern = cairo_pattern_create_for_surface(img); cairo_matrix_t flib_m; cairo_matrix_init(&flib_m, 1, 0, 0, -1, 0, 0); cairo_matrix_translate(&flib_m, -bg.position_x, -bg.position_y); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); cairo_pattern_set_matrix (pattern, &flib_m); switch(bg.repeat) { case litehtml::background_repeat_no_repeat: draw_txdib(cr, bgbmp.get(), bg.position_x, bg.position_y, bgbmp->getWidth(), bgbmp->getHeight()); break; case litehtml::background_repeat_repeat_x: cairo_set_source(cr, pattern); cairo_rectangle(cr, bg.clip_box.left(), bg.position_y, bg.clip_box.width, bgbmp->getHeight()); cairo_fill(cr); break; case litehtml::background_repeat_repeat_y: cairo_set_source(cr, pattern); cairo_rectangle(cr, bg.position_x, bg.clip_box.top(), bgbmp->getWidth(), bg.clip_box.height); cairo_fill(cr); break; case litehtml::background_repeat_repeat: cairo_set_source(cr, pattern); cairo_rectangle(cr, bg.clip_box.left(), bg.clip_box.top(), bg.clip_box.width, bg.clip_box.height); cairo_fill(cr); break; } cairo_pattern_destroy(pattern); cairo_surface_destroy(img); } unlock_images_cache(); cairo_restore(cr); } bool cairo_container::add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg) { if(rx > 0 && ry > 0) { cairo_save(cr); cairo_translate(cr, x, y); cairo_scale(cr, 1, ry / rx); cairo_translate(cr, -x, -y); if(neg) { cairo_arc_negative(cr, x, y, rx, a1, a2); } else { cairo_arc(cr, x, y, rx, a1, a2); } cairo_restore(cr); return true; } return false; } void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root ) { cairo_t* cr = (cairo_t*) hdc; cairo_save(cr); apply_clip(cr); cairo_new_path(cr); int bdr_top = 0; int bdr_bottom = 0; int bdr_left = 0; int bdr_right = 0; if(borders.top.width != 0 && borders.top.style > litehtml::border_style_hidden) { bdr_top = (int) borders.top.width; } if(borders.bottom.width != 0 && borders.bottom.style > litehtml::border_style_hidden) { bdr_bottom = (int) borders.bottom.width; } if(borders.left.width != 0 && borders.left.style > litehtml::border_style_hidden) { bdr_left = (int) borders.left.width; } if(borders.right.width != 0 && borders.right.style > litehtml::border_style_hidden) { bdr_right = (int) borders.right.width; } // draw right border if (bdr_right) { set_color(cr, borders.right.color); double r_top = (double) borders.radius.top_right_x; double r_bottom = (double) borders.radius.bottom_right_x; if(r_top) { double end_angle = 2.0 * M_PI; double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_top / (double) bdr_right + 0.5); if (!add_path_arc(cr, draw_pos.right() - r_top, draw_pos.top() + r_top, r_top - bdr_right, r_top - bdr_right + (bdr_right - bdr_top), end_angle, start_angle, true)) { cairo_move_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); } if (!add_path_arc(cr, draw_pos.right() - r_top, draw_pos.top() + r_top, r_top, r_top, start_angle, end_angle, false)) { cairo_line_to(cr, draw_pos.right(), draw_pos.top()); } } else { cairo_move_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); cairo_line_to(cr, draw_pos.right(), draw_pos.top()); } if(r_bottom) { cairo_line_to(cr, draw_pos.right(), draw_pos.bottom() - r_bottom); double start_angle = 0; double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_bottom / (double) bdr_right + 0.5); if (!add_path_arc(cr, draw_pos.right() - r_bottom, draw_pos.bottom() - r_bottom, r_bottom, r_bottom, start_angle, end_angle, false)) { cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); } if (!add_path_arc(cr, draw_pos.right() - r_bottom, draw_pos.bottom() - r_bottom, r_bottom - bdr_right, r_bottom - bdr_right + (bdr_right - bdr_bottom), end_angle, start_angle, true)) { cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); } } else { cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); } cairo_fill(cr); } // draw bottom border if(bdr_bottom) { set_color(cr, borders.bottom.color); double r_left = borders.radius.bottom_left_x; double r_right = borders.radius.bottom_right_x; if(r_left) { double start_angle = M_PI / 2.0; double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_left / (double) bdr_bottom + 0.5); if (!add_path_arc(cr, draw_pos.left() + r_left, draw_pos.bottom() - r_left, r_left - bdr_bottom + (bdr_bottom - bdr_left), r_left - bdr_bottom, start_angle, end_angle, false)) { cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); } if (!add_path_arc(cr, draw_pos.left() + r_left, draw_pos.bottom() - r_left, r_left, r_left, end_angle, start_angle, true)) { cairo_line_to(cr, draw_pos.left(), draw_pos.bottom()); } } else { cairo_move_to(cr, draw_pos.left(), draw_pos.bottom()); cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); } if(r_right) { cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.bottom()); double end_angle = M_PI / 2.0; double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_right / (double) bdr_bottom + 0.5); if (!add_path_arc(cr, draw_pos.right() - r_right, draw_pos.bottom() - r_right, r_right, r_right, end_angle, start_angle, true)) { cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); } if (!add_path_arc(cr, draw_pos.right() - r_right, draw_pos.bottom() - r_right, r_right - bdr_bottom + (bdr_bottom - bdr_right), r_right - bdr_bottom, start_angle, end_angle, false)) { cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); } } else { cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); } cairo_fill(cr); } // draw top border if(bdr_top) { set_color(cr, borders.top.color); double r_left = borders.radius.top_left_x; double r_right = borders.radius.top_right_x; if(r_left) { double end_angle = M_PI * 3.0 / 2.0; double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_left / (double) bdr_top + 0.5); if (!add_path_arc(cr, draw_pos.left() + r_left, draw_pos.top() + r_left, r_left, r_left, end_angle, start_angle, true)) { cairo_move_to(cr, draw_pos.left(), draw_pos.top()); } if (!add_path_arc(cr, draw_pos.left() + r_left, draw_pos.top() + r_left, r_left - bdr_top + (bdr_top - bdr_left), r_left - bdr_top, start_angle, end_angle, false)) { cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); } } else { cairo_move_to(cr, draw_pos.left(), draw_pos.top()); cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); } if(r_right) { cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.top() + bdr_top); double start_angle = M_PI * 3.0 / 2.0; double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_right / (double) bdr_top + 0.5); if (!add_path_arc(cr, draw_pos.right() - r_right, draw_pos.top() + r_right, r_right - bdr_top + (bdr_top - bdr_right), r_right - bdr_top, start_angle, end_angle, false)) { cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); } if (!add_path_arc(cr, draw_pos.right() - r_right, draw_pos.top() + r_right, r_right, r_right, end_angle, start_angle, true)) { cairo_line_to(cr, draw_pos.right(), draw_pos.top()); } } else { cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); cairo_line_to(cr, draw_pos.right(), draw_pos.top()); } cairo_fill(cr); } // draw left border if (bdr_left) { set_color(cr, borders.left.color); double r_top = borders.radius.top_left_x; double r_bottom = borders.radius.bottom_left_x; if(r_top) { double start_angle = M_PI; double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_top / (double) bdr_left + 0.5); if (!add_path_arc(cr, draw_pos.left() + r_top, draw_pos.top() + r_top, r_top - bdr_left, r_top - bdr_left + (bdr_left - bdr_top), start_angle, end_angle, false)) { cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); } if (!add_path_arc(cr, draw_pos.left() + r_top, draw_pos.top() + r_top, r_top, r_top, end_angle, start_angle, true)) { cairo_line_to(cr, draw_pos.left(), draw_pos.top()); } } else { cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); cairo_line_to(cr, draw_pos.left(), draw_pos.top()); } if(r_bottom) { cairo_line_to(cr, draw_pos.left(), draw_pos.bottom() - r_bottom); double end_angle = M_PI; double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_bottom / (double) bdr_left + 0.5); if (!add_path_arc(cr, draw_pos.left() + r_bottom, draw_pos.bottom() - r_bottom, r_bottom, r_bottom, end_angle, start_angle, true)) { cairo_line_to(cr, draw_pos.left(), draw_pos.bottom()); } if (!add_path_arc(cr, draw_pos.left() + r_bottom, draw_pos.bottom() - r_bottom, r_bottom - bdr_left, r_bottom - bdr_left + (bdr_left - bdr_bottom), start_angle, end_angle, false)) { cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); } } else { cairo_line_to(cr, draw_pos.left(), draw_pos.bottom()); cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); } cairo_fill(cr); } cairo_restore(cr); } void cairo_container::set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) { litehtml::position clip_pos = pos; litehtml::position client_pos; get_client_rect(client_pos); if(!valid_x) { clip_pos.x = client_pos.x; clip_pos.width = client_pos.width; } if(!valid_y) { clip_pos.y = client_pos.y; clip_pos.height = client_pos.height; } m_clips.emplace_back(clip_pos, bdr_radius); } void cairo_container::del_clip() { if(!m_clips.empty()) { m_clips.pop_back(); } } void cairo_container::apply_clip( cairo_t* cr ) { for(const auto& clip_box : m_clips) { rounded_rectangle(cr, clip_box.box, clip_box.radius); cairo_clip(cr); } } void cairo_container::draw_ellipse( cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, double line_width ) { if(!cr) return; cairo_save(cr); apply_clip(cr); cairo_new_path(cr); cairo_translate (cr, x + width / 2.0, y + height / 2.0); cairo_scale (cr, width / 2.0, height / 2.0); cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI); set_color(cr, color); cairo_set_line_width(cr, line_width); cairo_stroke(cr); cairo_restore(cr); } void cairo_container::fill_ellipse( cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color ) { if(!cr) return; cairo_save(cr); apply_clip(cr); cairo_new_path(cr); cairo_translate (cr, x + width / 2.0, y + height / 2.0); cairo_scale (cr, width / 2.0, height / 2.0); cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI); set_color(cr, color); cairo_fill(cr); cairo_restore(cr); } void cairo_container::clear_images() { lock_images_cache(); m_images.clear(); unlock_images_cache(); } const litehtml::tchar_t* cairo_container::get_default_font_name() const { return _t("Times New Roman"); } void cairo_container::draw_txdib( cairo_t* cr, CTxDIB* bmp, int x, int y, int cx, int cy ) { cairo_save(cr); cairo_matrix_t flib_m; cairo_matrix_init(&flib_m, 1, 0, 0, -1, 0, 0); cairo_surface_t* img = NULL; CTxDIB rbmp; if(cx != bmp->getWidth() || cy != bmp->getHeight()) { bmp->resample(cx, cy, &rbmp); img = cairo_image_surface_create_for_data((unsigned char*) rbmp.getBits(), CAIRO_FORMAT_ARGB32, rbmp.getWidth(), rbmp.getHeight(), rbmp.getWidth() * 4); cairo_matrix_translate(&flib_m, 0, -rbmp.getHeight()); cairo_matrix_translate(&flib_m, x, -y); } else { img = cairo_image_surface_create_for_data((unsigned char*) bmp->getBits(), CAIRO_FORMAT_ARGB32, bmp->getWidth(), bmp->getHeight(), bmp->getWidth() * 4); cairo_matrix_translate(&flib_m, 0, -bmp->getHeight()); cairo_matrix_translate(&flib_m, x, -y); } cairo_transform(cr, &flib_m); cairo_set_source_surface(cr, img, 0, 0); cairo_paint(cr); cairo_restore(cr); cairo_surface_destroy(img); } void cairo_container::rounded_rectangle(cairo_t* cr, const litehtml::position& pos, const litehtml::border_radiuses& radius) { cairo_new_path(cr); if(radius.top_left_x) { cairo_arc(cr, pos.left() + radius.top_left_x, pos.top() + radius.top_left_x, radius.top_left_x, M_PI, M_PI * 3.0 / 2.0); } else { cairo_move_to(cr, pos.left(), pos.top()); } cairo_line_to(cr, pos.right() - radius.top_right_x, pos.top()); if(radius.top_right_x) { cairo_arc(cr, pos.right() - radius.top_right_x, pos.top() + radius.top_right_x, radius.top_right_x, M_PI * 3.0 / 2.0, 2.0 * M_PI); } cairo_line_to(cr, pos.right(), pos.bottom() - radius.bottom_right_x); if(radius.bottom_right_x) { cairo_arc(cr, pos.right() - radius.bottom_right_x, pos.bottom() - radius.bottom_right_x, radius.bottom_right_x, 0, M_PI / 2.0); } cairo_line_to(cr, pos.left() - radius.bottom_left_x, pos.bottom()); if(radius.bottom_left_x) { cairo_arc(cr, pos.left() + radius.bottom_left_x, pos.bottom() - radius.bottom_left_x, radius.bottom_left_x, M_PI / 2.0, M_PI); } } void cairo_container::remove_image( std::wstring& url ) { lock_images_cache(); images_map::iterator i = m_images.find(url); if(i != m_images.end()) { m_images.erase(i); } unlock_images_cache(); } void cairo_container::add_image(std::wstring& url, image_ptr& img) { lock_images_cache(); images_map::iterator i = m_images.find(url); if(i != m_images.end()) { if(img) { i->second = img; } else { m_images.erase(i); } } unlock_images_cache(); } void cairo_container::lock_images_cache() { EnterCriticalSection(&m_img_sync); } void cairo_container::unlock_images_cache() { LeaveCriticalSection(&m_img_sync); } std::shared_ptr cairo_container::create_element(const litehtml::tchar_t* tag_name, const litehtml::string_map& attributes, const std::shared_ptr& doc) { return 0; } void cairo_container::get_media_features(litehtml::media_features& media) const { litehtml::position client; get_client_rect(client); HDC hdc = GetDC(NULL); media.type = litehtml::media_type_screen; media.width = client.width; media.height = client.height; media.color = 8; media.monochrome = 0; media.color_index = 256; media.resolution = GetDeviceCaps(hdc, LOGPIXELSX); media.device_width = GetDeviceCaps(hdc, HORZRES); media.device_height = GetDeviceCaps(hdc, VERTRES); ReleaseDC(NULL, hdc); } void cairo_container::get_language(litehtml::tstring& language, litehtml::tstring & culture) const { language = _t("en"); culture = _t(""); } void cairo_container::make_url_utf8( const char* url, const char* basepath, std::wstring& out ) { wchar_t* urlW = cairo_font::utf8_to_wchar(url); wchar_t* basepathW = cairo_font::utf8_to_wchar(basepath); make_url(urlW, basepathW, out); if(urlW) delete urlW; if(basepathW) delete basepathW; } void cairo_container::transform_text( litehtml::tstring& text, litehtml::text_transform tt ) { if(text.empty()) return; #ifndef LITEHTML_UTF8 switch(tt) { case litehtml::text_transform_capitalize: if(!text.empty()) { text[0] = (WCHAR) CharUpper((LPWSTR) text[0]); } break; case litehtml::text_transform_uppercase: for(size_t i = 0; i < text.length(); i++) { text[i] = (WCHAR) CharUpper((LPWSTR) text[i]); } break; case litehtml::text_transform_lowercase: for(size_t i = 0; i < text.length(); i++) { text[i] = (WCHAR) CharLower((LPWSTR) text[i]); } break; } #else LPWSTR txt = cairo_font::utf8_to_wchar(text.c_str()); switch(tt) { case litehtml::text_transform_capitalize: CharUpperBuff(txt, 1); break; case litehtml::text_transform_uppercase: CharUpperBuff(txt, lstrlen(txt)); break; case litehtml::text_transform_lowercase: CharLowerBuff(txt, lstrlen(txt)); break; } LPSTR txtA = cairo_font::wchar_to_utf8(txt); text = txtA; delete txtA; delete txt; #endif } void cairo_container::link(const std::shared_ptr& doc, const litehtml::element::ptr& el) { } litehtml::tstring cairo_container::resolve_color(const litehtml::tstring& color) const { struct custom_color { litehtml::tchar_t* name; int color_index; }; static custom_color colors[] = { { _t("ActiveBorder"), COLOR_ACTIVEBORDER}, { _t("ActiveCaption"), COLOR_ACTIVECAPTION}, { _t("AppWorkspace"), COLOR_APPWORKSPACE }, { _t("Background"), COLOR_BACKGROUND }, { _t("ButtonFace"), COLOR_BTNFACE }, { _t("ButtonHighlight"), COLOR_BTNHIGHLIGHT }, { _t("ButtonShadow"), COLOR_BTNSHADOW }, { _t("ButtonText"), COLOR_BTNTEXT }, { _t("CaptionText"), COLOR_CAPTIONTEXT }, { _t("GrayText"), COLOR_GRAYTEXT }, { _t("Highlight"), COLOR_HIGHLIGHT }, { _t("HighlightText"), COLOR_HIGHLIGHTTEXT }, { _t("InactiveBorder"), COLOR_INACTIVEBORDER }, { _t("InactiveCaption"), COLOR_INACTIVECAPTION }, { _t("InactiveCaptionText"), COLOR_INACTIVECAPTIONTEXT }, { _t("InfoBackground"), COLOR_INFOBK }, { _t("InfoText"), COLOR_INFOTEXT }, { _t("Menu"), COLOR_MENU }, { _t("MenuText"), COLOR_MENUTEXT }, { _t("Scrollbar"), COLOR_SCROLLBAR }, { _t("ThreeDDarkShadow"), COLOR_3DDKSHADOW }, { _t("ThreeDFace"), COLOR_3DFACE }, { _t("ThreeDHighlight"), COLOR_3DHILIGHT }, { _t("ThreeDLightShadow"), COLOR_3DLIGHT }, { _t("ThreeDShadow"), COLOR_3DSHADOW }, { _t("Window"), COLOR_WINDOW }, { _t("WindowFrame"), COLOR_WINDOWFRAME }, { _t("WindowText"), COLOR_WINDOWTEXT } }; if (color == _t("Highlight")) { int iii = 0; iii++; } for (auto& clr : colors) { if (!litehtml::t_strcasecmp(clr.name, color.c_str())) { litehtml::tchar_t str_clr[20]; DWORD rgb_color = GetSysColor(clr.color_index); #ifdef LITEHTML_UTF8 StringCchPrintfA(str_clr, 20, "#%02X%02X%02X", GetRValue(rgb_color), GetGValue(rgb_color), GetBValue(rgb_color)); #else StringCchPrintf(str_clr, 20, L"#%02X%02X%02X", GetRValue(rgb_color), GetGValue(rgb_color), GetBValue(rgb_color)); #endif // LITEHTML_UTF8 return std::move(litehtml::tstring(str_clr)); } } return std::move(litehtml::tstring()); } litehtml-0.6/containers/cairo/cairo_container.h000066400000000000000000000115601422312550200217520ustar00rootroot00000000000000#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef LITEHTML_UTF8 #define t_make_url make_url_utf8 #else #define t_make_url make_url #endif struct cairo_clip_box { typedef std::vector vector; litehtml::position box; litehtml::border_radiuses radius; cairo_clip_box(const litehtml::position& vBox, litehtml::border_radiuses vRad) { box = vBox; radius = vRad; } cairo_clip_box(const cairo_clip_box& val) { box = val.box; radius = val.radius; } cairo_clip_box& operator=(const cairo_clip_box& val) { box = val.box; radius = val.radius; return *this; } }; class cairo_container : public litehtml::document_container { public: typedef std::shared_ptr image_ptr; typedef std::map images_map; protected: cairo_surface_t* m_temp_surface; cairo_t* m_temp_cr; images_map m_images; cairo_clip_box::vector m_clips; IMLangFontLink2* m_font_link; CRITICAL_SECTION m_img_sync; public: cairo_container(void); virtual ~cairo_container(void); virtual litehtml::uint_ptr create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) override; virtual void delete_font(litehtml::uint_ptr hFont) override; virtual int text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) override; virtual void draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) override; virtual int pt_to_px(int pt) const override; virtual int get_default_font_size() const override; virtual const litehtml::tchar_t* get_default_font_name() const override; virtual void draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) override; virtual void load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) override; virtual void get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) override; virtual void draw_image(litehtml::uint_ptr hdc, const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, const litehtml::position& pos); virtual void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) override; virtual void draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) override; virtual void transform_text(litehtml::tstring& text, litehtml::text_transform tt) override; virtual void set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) override; virtual void del_clip() override; virtual std::shared_ptr create_element(const litehtml::tchar_t* tag_name, const litehtml::string_map& attributes, const std::shared_ptr& doc) override; virtual void get_media_features(litehtml::media_features& media) const override; virtual void get_language(litehtml::tstring& language, litehtml::tstring & culture) const override; virtual void link(const std::shared_ptr& doc, const litehtml::element::ptr& el) override; virtual litehtml::tstring resolve_color(const litehtml::tstring& color) const override; virtual void make_url( LPCWSTR url, LPCWSTR basepath, std::wstring& out ) = 0; virtual image_ptr get_image(LPCWSTR url, bool redraw_on_ready) = 0; void clear_images(); void add_image(std::wstring& url, image_ptr& img); void remove_image(std::wstring& url); void make_url_utf8( const char* url, const char* basepath, std::wstring& out ); protected: virtual void draw_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, double line_width); virtual void fill_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color); virtual void rounded_rectangle( cairo_t* cr, const litehtml::position &pos, const litehtml::border_radiuses &radius ); void set_color(cairo_t* cr, litehtml::web_color color) { cairo_set_source_rgba(cr, color.red / 255.0, color.green / 255.0, color.blue / 255.0, color.alpha / 255.0); } private: simpledib::dib* get_dib(litehtml::uint_ptr hdc) { return (simpledib::dib*) hdc; } void apply_clip(cairo_t* cr); bool add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg); void draw_txdib(cairo_t* cr, CTxDIB* bmp, int x, int y, int cx, int cy); void lock_images_cache(); void unlock_images_cache(); }; litehtml-0.6/containers/cairo/cairo_font.cpp000066400000000000000000000172361422312550200212770ustar00rootroot00000000000000#include "cairo_font.h" cairo_font::cairo_font(IMLangFontLink2* fl, HFONT hFont, int size ) { init(); m_font_link = fl; if(m_font_link) { m_font_link->AddRef(); } m_size = size; set_font(hFont); } cairo_font::cairo_font(IMLangFontLink2* fl, LPCWSTR facename, int size, int weight, BOOL italic, BOOL strikeout, BOOL underline ) { init(); m_size = size; m_font_link = fl; if(m_font_link) { m_font_link->AddRef(); } LOGFONT lf; ZeroMemory(&lf, sizeof(lf)); if(!lstrcmpi(facename, L"monospace")) { wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Courier New"); } else if(!lstrcmpi(facename, L"serif")) { wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Times New Roman"); } else if(!lstrcmpi(facename, L"sans-serif")) { wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Arial"); } else if(!lstrcmpi(facename, L"fantasy")) { wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Impact"); } else if(!lstrcmpi(facename, L"cursive")) { wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Comic Sans MS"); } else { wcscpy_s(lf.lfFaceName, LF_FACESIZE, facename); } lf.lfHeight = -size; lf.lfWeight = weight; lf.lfItalic = italic; lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfStrikeOut = strikeout; lf.lfUnderline = underline; HFONT fnt = CreateFontIndirect(&lf); set_font(fnt); } cairo_font::~cairo_font() { if(m_font_face) { cairo_font_face_destroy(m_font_face); } for(size_t i = 0; i < m_linked_fonts.size(); i++) { if(m_linked_fonts[i]->hFont) { m_font_link->ReleaseFont(m_linked_fonts[i]->hFont); } if(m_linked_fonts[i]->font_face) { cairo_font_face_destroy(m_linked_fonts[i]->font_face); } } m_linked_fonts.clear(); if(m_font_link) { m_font_link->AddRef(); } if(m_hFont) { DeleteObject(m_hFont); } } void cairo_font::show_text( cairo_t* cr, int x, int y, const litehtml::tchar_t* str ) { lock(); text_chunk::vector chunks; split_text(str, chunks); cairo_set_font_size(cr, m_size); cairo_move_to(cr, x, y); for(size_t i = 0; i < chunks.size(); i++) { if(chunks[i]->font) { cairo_set_font_face(cr, chunks[i]->font->font_face); } else { cairo_set_font_face(cr, m_font_face); } cairo_show_text(cr, chunks[i]->text); } unlock(); if(m_bUnderline) { int tw = text_width(cr, chunks); lock(); cairo_set_line_width(cr, 1); cairo_move_to(cr, x, y + 1.5); cairo_line_to(cr, x + tw, y + 1.5); cairo_stroke(cr); unlock(); } if(m_bStrikeOut) { int tw = text_width(cr, chunks); cairo_font_metrics fm; get_metrics(cr, &fm); int ln_y = y - fm.x_height / 2; lock(); cairo_set_line_width(cr, 1); cairo_move_to(cr, x, (double) ln_y - 0.5); cairo_line_to(cr, x + tw, (double) ln_y - 0.5); cairo_stroke(cr); unlock(); } free_text_chunks(chunks); } void cairo_font::split_text( const litehtml::tchar_t* src, text_chunk::vector& chunks ) { wchar_t* str; #ifdef LITEHTML_UTF8 str = cairo_font::utf8_to_wchar(src); wchar_t* str_start = str; #else str = (wchar_t*) src; #endif int cch = lstrlen(str); HDC hdc = GetDC(NULL); SelectObject(hdc, m_hFont); HRESULT hr = S_OK; while(cch > 0) { DWORD dwActualCodePages; long cchActual; if(m_font_link) { hr = m_font_link->GetStrCodePages(str, cch, m_font_code_pages, &dwActualCodePages, &cchActual); } else { hr = S_FALSE; } if(hr != S_OK) { break; } text_chunk* chk = new text_chunk; int sz = WideCharToMultiByte(CP_UTF8, 0, str, cchActual, chk->text, 0, NULL, NULL) + 1; chk->text = new CHAR[sz]; sz = WideCharToMultiByte(CP_UTF8, 0, str, cchActual, chk->text, sz, NULL, NULL); chk->text[sz] = 0; chk->font = NULL; if(!(dwActualCodePages & m_font_code_pages)) { for(linked_font::vector::iterator i = m_linked_fonts.begin(); i != m_linked_fonts.end(); i++) { if((*i)->code_pages == dwActualCodePages) { chk->font = (*i); break; } } if(!chk->font) { linked_font* lkf = new linked_font; lkf->code_pages = dwActualCodePages; lkf->hFont = NULL; m_font_link->MapFont(hdc, dwActualCodePages, 0, &lkf->hFont); if (lkf->hFont) { lkf->font_face = create_font_face(lkf->hFont); m_linked_fonts.push_back(lkf); } else { delete lkf; lkf = NULL; } chk->font = lkf; } } chunks.push_back(chk); cch -= cchActual; str += cchActual; } if(hr != S_OK) { text_chunk* chk = new text_chunk; int sz = WideCharToMultiByte(CP_UTF8, 0, str, -1, chk->text, 0, NULL, NULL) + 1; chk->text = new CHAR[sz]; sz = WideCharToMultiByte(CP_UTF8, 0, str, -1, chk->text, sz, NULL, NULL); chk->text[sz] = 0; chk->font = NULL; chunks.push_back(chk); } ReleaseDC(NULL, hdc); #ifdef LITEHTML_UTF8 delete str_start; #endif } void cairo_font::free_text_chunks( text_chunk::vector& chunks ) { for(size_t i = 0; i < chunks.size(); i++) { delete chunks[i]; } chunks.clear(); } cairo_font_face_t* cairo_font::create_font_face( HFONT fnt ) { LOGFONT lf; GetObject(fnt, sizeof(LOGFONT), &lf); return cairo_win32_font_face_create_for_logfontw(&lf); } int cairo_font::text_width( cairo_t* cr, const litehtml::tchar_t* str ) { text_chunk::vector chunks; split_text(str, chunks); int ret = text_width(cr, chunks); free_text_chunks(chunks); return (int) ret; } int cairo_font::text_width( cairo_t* cr, text_chunk::vector& chunks ) { lock(); cairo_set_font_size(cr, m_size); double ret = 0; for(size_t i = 0; i < chunks.size(); i++) { if(chunks[i]->font) { cairo_set_font_face(cr, chunks[i]->font->font_face); } else { cairo_set_font_face(cr, m_font_face); } cairo_text_extents_t ext; cairo_text_extents(cr, chunks[i]->text, &ext); ret += ext.x_advance; } unlock(); return (int) ret; } void cairo_font::get_metrics(cairo_t* cr, cairo_font_metrics* fm ) { lock(); cairo_set_font_face(cr, m_font_face); cairo_set_font_size(cr, m_size); cairo_font_extents_t ext; cairo_font_extents(cr, &ext); cairo_text_extents_t tex; cairo_text_extents(cr, "x", &tex); fm->ascent = (int) ext.ascent; fm->descent = (int) ext.descent; fm->height = (int) (ext.ascent + ext.descent); fm->x_height = (int) tex.height; unlock(); } void cairo_font::set_font( HFONT hFont ) { clear(); m_hFont = hFont; m_font_face = create_font_face(m_hFont); m_font_code_pages = 0; if(m_font_link) { HDC hdc = GetDC(NULL); SelectObject(hdc, m_hFont); m_font_link->GetFontCodePages(hdc, m_hFont, &m_font_code_pages); ReleaseDC(NULL, hdc); } LOGFONT lf; GetObject(m_hFont, sizeof(LOGFONT), &lf); m_bUnderline = lf.lfUnderline; m_bStrikeOut = lf.lfStrikeOut; } void cairo_font::clear() { if(m_font_face) { cairo_font_face_destroy(m_font_face); m_font_face = NULL; } for(size_t i = 0; i < m_linked_fonts.size(); i++) { if(m_linked_fonts[i]->hFont && m_font_link) { m_font_link->ReleaseFont(m_linked_fonts[i]->hFont); } if(m_linked_fonts[i]->font_face) { cairo_font_face_destroy(m_linked_fonts[i]->font_face); } } m_linked_fonts.clear(); if(m_hFont) { DeleteObject(m_hFont); m_hFont = NULL; } } void cairo_font::init() { m_hFont = NULL; m_font_face = NULL; m_font_link = NULL; m_font_code_pages = 0; m_size = 0; m_bUnderline = FALSE; m_bStrikeOut = FALSE; } wchar_t* cairo_font::utf8_to_wchar( const char* src ) { if(!src) return NULL; int len = (int) strlen(src); wchar_t* ret = new wchar_t[len + 1]; MultiByteToWideChar(CP_UTF8, 0, src, -1, ret, len + 1); return ret; } char* cairo_font::wchar_to_utf8( const wchar_t* src ) { if(!src) return NULL; int len = WideCharToMultiByte(CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL); char* ret = new char[len]; WideCharToMultiByte(CP_UTF8, 0, src, -1, ret, len, NULL, NULL); return ret; }litehtml-0.6/containers/cairo/cairo_font.h000066400000000000000000000045461422312550200207440ustar00rootroot00000000000000#pragma once #include #include #include #include #include #include #include #include #include #include struct linked_font { typedef std::vector vector; DWORD code_pages; HFONT hFont; cairo_font_face_t* font_face; }; struct text_chunk { typedef std::vector vector; char* text; linked_font* font; ~text_chunk() { if(text) { delete text; } } }; struct cairo_font_metrics { int height; int ascent; int descent; int x_height; }; class cairo_font { HFONT m_hFont; cairo_font_face_t* m_font_face; IMLangFontLink2* m_font_link; DWORD m_font_code_pages; linked_font::vector m_linked_fonts; int m_size; BOOL m_bUnderline; BOOL m_bStrikeOut; cairo_font_metrics m_metrics; public: // fonts are not thread safe :( // you have to declare and initialize cairo_font::m_sync before the first using. static CRITICAL_SECTION m_sync; cairo_font(IMLangFontLink2* fl, HFONT hFont, int size); cairo_font(IMLangFontLink2* fl, LPCWSTR facename, int size, int weight, BOOL italic, BOOL strikeout, BOOL underline); void init(); ~cairo_font(); void show_text(cairo_t* cr, int x, int y, const litehtml::tchar_t*); int text_width(cairo_t* cr, const litehtml::tchar_t* str); void load_metrics(cairo_t* cr); cairo_font_metrics& metrics(); static wchar_t* utf8_to_wchar(const char* src); static char* wchar_to_utf8(const wchar_t* src); private: void split_text(const litehtml::tchar_t* str, text_chunk::vector& chunks); void free_text_chunks(text_chunk::vector& chunks); cairo_font_face_t* create_font_face(HFONT fnt); void set_font(HFONT hFont); void clear(); int text_width(cairo_t* cr, text_chunk::vector& chunks); void lock(); void unlock(); int round_d(double val); void get_metrics(cairo_t* cr, cairo_font_metrics* fm); }; inline void cairo_font::lock() { EnterCriticalSection(&m_sync); } inline void cairo_font::unlock() { LeaveCriticalSection(&m_sync); } inline int cairo_font::round_d(double val) { int int_val = (int) val; if(val - int_val >= 0.5) { int_val++; } return int_val; } inline cairo_font_metrics& cairo_font::metrics() { return m_metrics; } inline void cairo_font::load_metrics(cairo_t* cr) { get_metrics(cr, &m_metrics); } litehtml-0.6/containers/gdiplus/000077500000000000000000000000001422312550200170115ustar00rootroot00000000000000litehtml-0.6/containers/gdiplus/gdiplus_container.cpp000066400000000000000000000146041422312550200232330ustar00rootroot00000000000000#include "gdiplus_container.h" gdiplus_container::gdiplus_container(void) { } gdiplus_container::~gdiplus_container(void) { } void gdiplus_container::draw_ellipse( HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color, int line_width ) { Gdiplus::Graphics graphics(hdc); Gdiplus::LinearGradientBrush* brush = NULL; graphics.SetCompositingQuality(Gdiplus::CompositingQualityHighQuality); graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); Gdiplus::Pen pen( Gdiplus::Color(color.alpha, color.red, color.green, color.blue) ); graphics.DrawEllipse(&pen, x, y, width, height); } void gdiplus_container::fill_ellipse( HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color ) { Gdiplus::Graphics graphics(hdc); graphics.SetCompositingQuality(Gdiplus::CompositingQualityHighQuality); graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); Gdiplus::SolidBrush brush( Gdiplus::Color(color.alpha, color.red, color.green, color.blue) ); graphics.FillEllipse(&brush, x, y, width, height); } void gdiplus_container::fill_rect( HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color, const litehtml::css_border_radius& radius ) { Gdiplus::Graphics graphics(hdc); Gdiplus::SolidBrush brush( Gdiplus::Color(color.alpha, color.red, color.green, color.blue) ); graphics.FillRectangle(&brush, x, y, width, height); } void gdiplus_container::get_img_size( litehtml::uint_ptr img, litehtml::size& sz ) { Gdiplus::Bitmap* bmp = (Gdiplus::Bitmap*) img; if(bmp) { sz.width = bmp->GetWidth(); sz.height = bmp->GetHeight(); } } void gdiplus_container::draw_img(HDC hdc, litehtml::uint_ptr img, const litehtml::position& pos ) { Gdiplus::Bitmap* bmp = (Gdiplus::Bitmap*) img; if(bmp) { Gdiplus::Graphics graphics(hdc); graphics.SetInterpolationMode(Gdiplus::InterpolationModeNearestNeighbor); graphics.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHalf); graphics.DrawImage(bmp, pos.x, pos.y, pos.width, pos.height); } } void gdiplus_container::free_image( litehtml::uint_ptr img ) { Gdiplus::Bitmap* bmp = (Gdiplus::Bitmap*) img; if(bmp) { delete bmp; } } void gdiplus_container::draw_img_bg( HDC hdc, litehtml::uint_ptr img, const litehtml::position& draw_pos, const litehtml::position& pos, litehtml::background_repeat repeat, litehtml::background_attachment attachment ) { Gdiplus::Bitmap* bgbmp = (Gdiplus::Bitmap*) img; int img_width = bgbmp->GetWidth(); int img_height = bgbmp->GetHeight(); Gdiplus::Graphics graphics(hdc); graphics.SetInterpolationMode(Gdiplus::InterpolationModeNearestNeighbor); graphics.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHalf); Gdiplus::Region reg(Gdiplus::Rect(draw_pos.left(), draw_pos.top(), draw_pos.width, draw_pos.height)); graphics.SetClip(®); switch(repeat) { case litehtml::background_repeat_no_repeat: { graphics.DrawImage(bgbmp, pos.x, pos.y, bgbmp->GetWidth(), bgbmp->GetHeight()); } break; case litehtml::background_repeat_repeat_x: { Gdiplus::CachedBitmap bmp(bgbmp, &graphics); for(int x = pos.left(); x < pos.right(); x += bgbmp->GetWidth()) { graphics.DrawCachedBitmap(&bmp, x, pos.top()); } for(int x = pos.left() - bgbmp->GetWidth(); x + (int) bgbmp->GetWidth() > draw_pos.left(); x -= bgbmp->GetWidth()) { graphics.DrawCachedBitmap(&bmp, x, pos.top()); } } break; case litehtml::background_repeat_repeat_y: { Gdiplus::CachedBitmap bmp(bgbmp, &graphics); for(int y = pos.top(); y < pos.bottom(); y += bgbmp->GetHeight()) { graphics.DrawCachedBitmap(&bmp, pos.left(), y); } for(int y = pos.top() - bgbmp->GetHeight(); y + (int) bgbmp->GetHeight() > draw_pos.top(); y -= bgbmp->GetHeight()) { graphics.DrawCachedBitmap(&bmp, pos.left(), y); } } break; case litehtml::background_repeat_repeat: { Gdiplus::CachedBitmap bmp(bgbmp, &graphics); if(bgbmp->GetHeight() >= 0) { for(int x = pos.left(); x < pos.right(); x += bgbmp->GetWidth()) { for(int y = pos.top(); y < pos.bottom(); y += bgbmp->GetHeight()) { graphics.DrawCachedBitmap(&bmp, x, y); } } } } break; } } void gdiplus_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::css_borders& borders, const litehtml::position& draw_pos ) { apply_clip((HDC) hdc); // draw left border if(borders.left.width.val() != 0 && borders.left.style > litehtml::border_style_hidden) { HPEN pen = CreatePen(PS_SOLID, 1, RGB(borders.left.color.red, borders.left.color.green, borders.left.color.blue)); HPEN oldPen = (HPEN) SelectObject((HDC) hdc, pen); for(int x = 0; x < borders.left.width.val(); x++) { MoveToEx((HDC) hdc, draw_pos.left() + x, draw_pos.top(), NULL); LineTo((HDC) hdc, draw_pos.left() + x, draw_pos.bottom()); } SelectObject((HDC) hdc, oldPen); DeleteObject(pen); } // draw right border if(borders.right.width.val() != 0 && borders.right.style > litehtml::border_style_hidden) { HPEN pen = CreatePen(PS_SOLID, 1, RGB(borders.right.color.red, borders.right.color.green, borders.right.color.blue)); HPEN oldPen = (HPEN) SelectObject((HDC) hdc, pen); for(int x = 0; x < borders.right.width.val(); x++) { MoveToEx((HDC) hdc, draw_pos.right() - x - 1, draw_pos.top(), NULL); LineTo((HDC) hdc, draw_pos.right() - x - 1, draw_pos.bottom()); } SelectObject((HDC) hdc, oldPen); DeleteObject(pen); } // draw top border if(borders.top.width.val() != 0 && borders.top.style > litehtml::border_style_hidden) { HPEN pen = CreatePen(PS_SOLID, 1, RGB(borders.top.color.red, borders.top.color.green, borders.top.color.blue)); HPEN oldPen = (HPEN) SelectObject((HDC) hdc, pen); for(int y = 0; y < borders.top.width.val(); y++) { MoveToEx((HDC) hdc, draw_pos.left(), draw_pos.top() + y, NULL); LineTo((HDC) hdc, draw_pos.right(), draw_pos.top() + y); } SelectObject((HDC) hdc, oldPen); DeleteObject(pen); } // draw bottom border if(borders.bottom.width.val() != 0 && borders.bottom.style > litehtml::border_style_hidden) { HPEN pen = CreatePen(PS_SOLID, 1, RGB(borders.bottom.color.red, borders.bottom.color.green, borders.bottom.color.blue)); HPEN oldPen = (HPEN) SelectObject((HDC) hdc, pen); for(int y = 0; y < borders.bottom.width.val(); y++) { MoveToEx((HDC) hdc, draw_pos.left(), draw_pos.bottom() - y - 1, NULL); LineTo((HDC) hdc, draw_pos.right(), draw_pos.bottom() - y - 1); } SelectObject((HDC) hdc, oldPen); DeleteObject(pen); } release_clip((HDC) hdc); } litehtml-0.6/containers/gdiplus/gdiplus_container.h000066400000000000000000000024571422312550200227030ustar00rootroot00000000000000#pragma once #include #include #include #include #include #include #include #include #include #include #include "..\win32\win32_container.h" class gdiplus_container : public litehtml::win32_container { public: gdiplus_container(void); virtual ~gdiplus_container(void); protected: virtual void draw_ellipse(HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color, int line_width); virtual void fill_ellipse(HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color); virtual void fill_rect(HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color, const litehtml::css_border_radius& radius); virtual void get_img_size(litehtml::uint_ptr img, litehtml::size& sz); virtual void draw_img(HDC hdc, litehtml::uint_ptr img, const litehtml::position& pos); virtual void free_image(litehtml::uint_ptr img); virtual void draw_img_bg(HDC hdc, litehtml::uint_ptr img, const litehtml::position& draw_pos, const litehtml::position& pos, litehtml::background_repeat repeat, litehtml::background_attachment attachment); virtual void draw_borders(litehtml::uint_ptr hdc, const litehtml::css_borders& borders, const litehtml::position& draw_pos); }; litehtml-0.6/containers/haiku/000077500000000000000000000000001422312550200164435ustar00rootroot00000000000000litehtml-0.6/containers/haiku/container_haiku.cpp000066400000000000000000000342571422312550200223250ustar00rootroot00000000000000/* * Copyright 2019-2020 Haiku Inc. * All rights reserved. Distributed under the terms of the BSD 3-clause license. * Constributors * 2019-2020 Adam Fowler */ #include "container_haiku.h" #include #include #include #include #include #include #include #include #include #include LiteHtmlView::LiteHtmlView(BRect frame, const char *name) : BView(frame, name, B_FOLLOW_ALL, B_WILL_DRAW), fContext(NULL), m_html(NULL), m_images(), m_base_url(), m_url() { BRect bounds(Bounds()); BPoint topLeft = bounds.LeftTop(); std::cout << "Initial bounds: topLeft x: " << +topLeft.x << ", y: " << +topLeft.y << ", width: " << +bounds.Width() << ", height: " << +bounds.Height() << std::endl; SetDrawingMode(B_OP_OVER); SetFont(be_plain_font); //FillRect(bounds,B_SOLID_LOW); //SetLowColor(B_DOCUMENT_PANEL_COLOR); //FillRect(rect); } LiteHtmlView::~LiteHtmlView() { } void LiteHtmlView::SetContext(litehtml::context* ctx) { fContext = ctx; } void LiteHtmlView::RenderFile(const char* localFilePath) { std::cout << "RenderFile" << std::endl; //BUrlRequest req; // assume a local file for now, that is HTML std::ifstream t(localFilePath); std::string html((std::istreambuf_iterator(t)), std::istreambuf_iterator()); //std::cout << "HTML output:-" << std::endl << html << std::endl; // Get parent folder for the base url std::cout << "Loaded from file: " << localFilePath << std::endl; BPath htmlPath(localFilePath); BPath dirPath; htmlPath.GetParent(&dirPath); std::cout << "parent path: " << dirPath.Path() << std::endl; set_base_url(dirPath.Path()); //std::cout << " base url now:" << m_base_url << std::endl; RenderHTML(html); } void LiteHtmlView::RenderHTML(const std::string& htmlText) { std::cout << "RenderHTML" << std::endl; // now use this string m_html = litehtml::document::createFromString( htmlText.c_str(), this, fContext); if (m_html) { std::cout << "Successfully read html" << std::endl; // success // post-parse render operations, if required. Invalidate(); } else { std::cout << "Failed to read html" << std::endl; } // always fire the rendering complete message std::cout << "Sending html rendered message: " << M_HTML_RENDERED << std::endl; } void LiteHtmlView::Draw(BRect b) { std::cout << "DRAW CALLED" << std::endl; BRect bounds(Bounds()); FillRect(bounds,B_SOLID_LOW); // b only part of the window, but we need to draw the whole lot if (NULL != m_html) { BPoint leftTop = bounds.LeftTop(); litehtml::position clip(leftTop.x,leftTop.y, bounds.Width(),bounds.Height()); m_html->render(bounds.Width()); m_html->draw((litehtml::uint_ptr) this,0,0,&clip); } SendNotices(M_HTML_RENDERED,new BMessage(M_HTML_RENDERED)); } void LiteHtmlView::GetPreferredSize(float* width,float* height) { if (NULL == m_html) { BRect bounds(Bounds()); *width = bounds.Width(); *height = bounds.Height(); } else { *width = m_html->width(); *height = m_html->height(); } } litehtml::uint_ptr LiteHtmlView::create_font( const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm ) { //std::cout << "create_font" << std::endl; litehtml::string_vector fonts; litehtml::split_string(faceName, fonts, ","); litehtml::trim(fonts[0]); uint16 face = B_REGULAR_FACE; // default if (italic == litehtml::fontStyleItalic) { face |= B_ITALIC_FACE; } if (decoration & litehtml::font_decoration_underline) { face |= B_UNDERSCORE_FACE; } if (decoration & litehtml::font_decoration_linethrough) { face |= B_STRIKEOUT_FACE; } // Note: LIGHT, HEAVY, CONDENSED not supported in BeOS R5 #ifdef __HAIKU__ if(weight >= 0 && weight < 150) face |= B_LIGHT_FACE; else if(weight >= 150 && weight < 250) face |= B_LIGHT_FACE; else if(weight >= 250 && weight < 350) face |= B_LIGHT_FACE; //else if(weight >= 350 && weight < 450) face |= B_REGULAR_FACE; //else if(weight >= 450 && weight < 550) face |= B_REGULAR_FACE; else if(weight >= 550 && weight < 650) face |= B_CONDENSED_FACE; #else else if(weight >= 550 && weight < 650) face |= B_BOLD_FACE; #endif else if(weight >= 650 && weight < 750) face |= B_BOLD_FACE; #ifndef __HAIKU__ else if(weight >= 750 && weight < 850) face |= B_BOLD_FACE; else if(weight >= 950) face |= B_BOLD_FACE; #else else if(weight >= 750 && weight < 850) face |= B_HEAVY_FACE; else if(weight >= 950) face |= B_HEAVY_FACE; #endif BFont* tempFont = new BFont(); bool found = false; for(litehtml::string_vector::iterator i = fonts.begin(); i != fonts.end(); i++) { if (B_OK == tempFont->SetFamilyAndFace(i->c_str(),face)) { found = true; break; } } if (!found) { // default to the Be plain font tempFont = new BFont(be_plain_font); if (weight >= 550) { tempFont = new BFont(be_bold_font); } tempFont->SetFace(face); // chooses closest } tempFont->SetSize(size); font_height hgt; tempFont->GetHeight(&hgt); fm->ascent = hgt.ascent; fm->descent = hgt.descent; fm->height = (int) (hgt.ascent + hgt.descent); fm->x_height = (int) hgt.leading; return (litehtml::uint_ptr) tempFont; } void LiteHtmlView::delete_font( litehtml::uint_ptr hFont ) { std::cout << "delete_font" << std::endl; } int LiteHtmlView::text_width( const litehtml::tchar_t* text, litehtml::uint_ptr hFont ) { //std::cout << "text_width" << std::endl; BFont* fnt = (BFont*)hFont; int width = fnt->StringWidth(text); //std::cout << " Width: " << +width << std::endl; return width; } void LiteHtmlView::draw_text( litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos ) { //std::cout << "draw_text" << std::endl; if (!text) return; if (0 == strlen(text)) return; BFont* fnt = (BFont*)hFont; //std::cout << " left: " << +pos.left() << ", top: " << +pos.top() << std::endl; //std::cout << " RGBA: " << +color.red << "," << +color.green << "," << +color.blue << "," << +color.alpha << std::endl; //std::cout << " Font size: " << +fnt->Size() << std::endl; //std::cout << " Text: " << text << std::endl; BRect bounds(Bounds()); //FillRect(bounds,B_SOLID_LOW); BPoint leftTop = bounds.LeftTop(); //std::cout << " Bounds left: " << +leftTop.x << ", top: " << +leftTop.y << ", Width: " << +bounds.Width() << ", Height: " << +bounds.Height() << std::endl; font_height fh; fnt->GetHeight(&fh); int baseline = fh.ascent + fh.descent;// + 10; int leftbase = 0; //10; MovePenTo(pos.left() + leftbase,pos.top() + baseline);//leftTop.x,leftTop.y); SetFont(fnt); //SetFont(be_plain_font); rgb_color clr = ui_color(B_DOCUMENT_TEXT_COLOR); /* rgb_color clr; clr.blue = 40; clr.red = 40; clr.green = 40; */ clr.red = color.red; clr.green = color.green; clr.blue = color.blue; clr.alpha = color.alpha; //std::cout << " Final RGBA: " << +clr.red << "," << +clr.green << "," << +clr.blue << "," << +clr.alpha << std::endl; SetHighColor(clr); SetLowColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR)); BString mystr(""); //mystr << "text: "; mystr << text; DrawString(mystr); } int LiteHtmlView::pt_to_px( int pt ) { std::cout << "pt_to_px" << std::endl; return (int) ((double) pt * 1.3333333333); } int LiteHtmlView::get_default_font_size() const { //std::cout << "get_default_font_size" << std::endl; return 12; } const litehtml::tchar_t* LiteHtmlView::get_default_font_name() const { //std::cout << "get_default_font_name" << std::endl; font_family fam; font_style style; be_plain_font->GetFamilyAndStyle(&fam,&style); char* cp = strdup(fam); return (litehtml::tchar_t*)cp; } void LiteHtmlView::draw_list_marker( litehtml::uint_ptr hdc, const litehtml::list_marker& marker ) { std::cout << "draw_list_marker" << std::endl; if (!marker.image.empty()) { std::cout << " image marker" << std::endl; } } void LiteHtmlView::load_image( const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready ) { std::cout << "load_image" << std::endl; std::string url; make_url(src, baseurl, url); if(m_images.find(url.c_str()) == m_images.end()) { BEntry entry(url.c_str(), true); if (entry.Exists()) { std::cout << " Loading bitmap from file" << std::endl; BBitmap* img = BTranslationUtils::GetBitmap(url.c_str()); m_images[url] = img; } } } void LiteHtmlView::make_url(const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out) { std::cout << "make_url" << std::endl; std::cout << " url: " << url << std::endl; if(!basepath || (basepath && !basepath[0])) { if(!m_base_url.empty()) { //out = urljoin(m_base_url, std::string(url)); std::string ns(m_base_url); ns += "/"; ns += url; out = ns; } else { out = url; } } else { std::cout << " basepath: " << basepath << std::endl; //out = urljoin(std::string(basepath), std::string(url)); std::string ns(basepath); ns += "/"; ns += url; out = ns; } std::cout << " Output url: " << out << std::endl; } void LiteHtmlView::set_base_url(const litehtml::tchar_t* base_url) { std::cout << "set_base_url" << std::endl; /* if(base_url) { m_base_url = urljoin(m_url, std::string(base_url)); } else { */ m_base_url = base_url; std::cout << " base url set to: " << m_base_url << std::endl; //} } void LiteHtmlView::get_image_size( const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz ) { std::cout << "get_image_size" << std::endl; std::string url; make_url(src,NULL,url); const auto& miter(m_images.find(url.c_str())); if (m_images.end() != miter) { BBitmap* img = (BBitmap*)miter->second; BRect size = img->Bounds(); sz.width = size.Width(); sz.height = size.Height(); std::cout << " width: " << +sz.width << ", height: " << +sz.height << std::endl; } } void LiteHtmlView::draw_image( litehtml::uint_ptr hdc, const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, const litehtml::position& pos ) { std::string url; make_url(src, baseurl, url); const auto& img = m_images.find(url.c_str()); if(img != m_images.end()) { if(img->second) { DrawBitmap(img->second,BPoint(pos.x,pos.y)); // TODO support scaling //draw_txdib(cr, img->second.get(), pos.x, pos.y, pos.width, pos.height); } } } void LiteHtmlView::draw_background( litehtml::uint_ptr hdc, const litehtml::background_paint& bg ) { std::cout << "draw_background" << std::endl; if (0 < bg.image.length()) { std::cout << " background includes an image!" << std::endl; draw_image(hdc,bg.image.c_str(),m_base_url.c_str(),litehtml::position(bg.position_x,bg.position_y,bg.image_size.width,bg.image_size.height)); } } void LiteHtmlView::draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) { std::cout << "draw_borders" << std::endl; int bdr_top = 0; int bdr_bottom = 0; int bdr_left = 0; int bdr_right = 0; //std::cout << " uint ptr: " << +hdc << std::endl; //std::cout << " this ptr: " << +this << std::endl; if(borders.top.width != 0 && borders.top.style > litehtml::border_style_hidden) { bdr_top = (int) borders.top.width; std::cout << " Border top: " << bdr_right << std::endl; } if(borders.bottom.width != 0 && borders.bottom.style > litehtml::border_style_hidden) { bdr_bottom = (int) borders.bottom.width; std::cout << " Border bottom: " << bdr_right << std::endl; } if(borders.left.width != 0 && borders.left.style > litehtml::border_style_hidden) { bdr_left = (int) borders.left.width; std::cout << " Border left: " << bdr_right << std::endl; } if(borders.right.width != 0 && borders.right.style > litehtml::border_style_hidden) { bdr_right = (int) borders.right.width; std::cout << " Border right: " << bdr_right << std::endl; } if (bdr_bottom) { // draw rectangle for now - no check for radius StrokeRect( BRect( BPoint(draw_pos.left(), draw_pos.bottom()), BPoint(draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom) ) ); } } void LiteHtmlView::transform_text(litehtml::tstring& text, litehtml::text_transform tt) { std::cout << "transform_text" << std::endl; } void LiteHtmlView::set_clip( const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y ) { std::cout << "set_clip" << std::endl; } void LiteHtmlView::del_clip() { std::cout << "del_clip" << std::endl; } std::shared_ptr LiteHtmlView::create_element(const litehtml::tchar_t *tag_name, const litehtml::string_map &attributes, const std::shared_ptr &doc) { //std::cout << "create_element" << std::endl; return 0; } void LiteHtmlView::get_media_features(litehtml::media_features& media) const { std::cout << "get_media_features" << std::endl; litehtml::position client; get_client_rect(client); media.type = litehtml::media_type_screen; media.width = client.width; media.height = client.height; BRect bounds(Bounds()); media.device_width = bounds.Width(); media.device_height = bounds.Height(); media.color = 8; media.monochrome = 0; media.color_index = 256; media.resolution = 96; } void LiteHtmlView::link(const std::shared_ptr &ptr, const litehtml::element::ptr& el) { std::cout << "link" << std::endl; } void LiteHtmlView::set_caption(const char* caption) { std::cout << "set_caption" << std::endl; } void LiteHtmlView::get_client_rect(litehtml::position& client) const { //std::cout << "get_client_rect" << std::endl; BRect bounds(Bounds()); BPoint leftTop = bounds.LeftTop(); client.width = bounds.Width(); client.height = bounds.Height(); client.x = leftTop.x; client.y = leftTop.y; } void LiteHtmlView::on_anchor_click(const char* base, const litehtml::element::ptr& anchor) { std::cout << "on_anchor_click" << std::endl; } void LiteHtmlView::set_cursor(const char* cursor) { std::cout << "set_cursor" << std::endl; } void LiteHtmlView::import_css(litehtml::tstring& s1, const litehtml::tstring& s2, litehtml::tstring& s3) { std::cout << "import_css" << std::endl; } void LiteHtmlView::get_language(litehtml::tstring& s1, litehtml::tstring& s2) const { std::cout << "get_language" << std::endl; } litehtml-0.6/containers/haiku/container_haiku.h000066400000000000000000000100111422312550200217500ustar00rootroot00000000000000/* * Copyright 2019-2020 Haiku Inc. * All rights reserved. Distributed under the terms of the BSD 3-clause license. * Constributors * 2019-2020 Adam Fowler */ #ifndef LITEHTMLVIEW_H #define LITEHTMLVIEW_H #include "../../include/litehtml.h" #include #include #include class BBitmap; enum { M_HTML_RENDERED = 'hrnd' }; class LiteHtmlView : public BView, public litehtml::document_container { public: //LiteHtmlView(BMessage *archive); LiteHtmlView(BRect frame, const char *name); //LiteHtmlView(const char *name, uint32 flags, BLayout *layout=NULL); virtual ~LiteHtmlView(); void SetContext(litehtml::context* ctx); void RenderFile(const char* localFilePath); void RenderHTML(const std::string& htmlText); virtual litehtml::uint_ptr create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) override; virtual void delete_font(litehtml::uint_ptr hFont) override; virtual int text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) override; virtual void draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) override; virtual int pt_to_px(int pt) override; virtual int get_default_font_size() const override; virtual const litehtml::tchar_t* get_default_font_name() const override; virtual void load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) override; virtual void get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) override; virtual void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) override; virtual void draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) override; virtual void draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) override; virtual std::shared_ptr create_element(const litehtml::tchar_t *tag_name, const litehtml::string_map &attributes, const std::shared_ptr &doc) override; virtual void get_media_features(litehtml::media_features& media) const override; //virtual void get_language(litehtml::tstring& language, litehtml::tstring & culture) const override; virtual void link(const std::shared_ptr &ptr, const litehtml::element::ptr& el) override; virtual void transform_text(litehtml::tstring& text, litehtml::text_transform tt) override; virtual void set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) override; virtual void del_clip() override; // unimplemented virtual void set_caption(const char*); virtual void get_client_rect(litehtml::position& client) const; virtual void set_base_url(const char*); virtual void on_anchor_click(const char*, const litehtml::element::ptr&); virtual void set_cursor(const char*); virtual void import_css(litehtml::tstring&, const litehtml::tstring&, litehtml::tstring&); virtual void get_language(litehtml::tstring&, litehtml::tstring&) const; //BView virtual void Draw(BRect updateRect) override; virtual void GetPreferredSize(float* width, float* height) override; protected: void make_url(const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out); virtual void draw_image( litehtml::uint_ptr hdc, const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, const litehtml::position& pos ); private: litehtml::context* fContext; litehtml::document::ptr m_html; std::map m_images; litehtml::tstring m_base_url; litehtml::tstring m_url; }; #endif litehtml-0.6/containers/linux/000077500000000000000000000000001422312550200165015ustar00rootroot00000000000000litehtml-0.6/containers/linux/container_linux.cpp000066400000000000000000000562631422312550200224220ustar00rootroot00000000000000#include "container_linux.h" #include #ifndef M_PI # define M_PI 3.14159265358979323846 #endif container_linux::container_linux() { m_temp_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 2, 2); m_temp_cr = cairo_create(m_temp_surface); } container_linux::~container_linux() { clear_images(); cairo_surface_destroy(m_temp_surface); cairo_destroy(m_temp_cr); } litehtml::uint_ptr container_linux::create_font( const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm ) { PangoFontDescription *desc = pango_font_description_from_string (faceName); pango_font_description_set_absolute_size(desc, size * PANGO_SCALE); if(italic == litehtml::fontStyleItalic ) { pango_font_description_set_style(desc, PANGO_STYLE_ITALIC); } else { pango_font_description_set_style(desc, PANGO_STYLE_NORMAL); } PangoWeight fnt_weight; if(weight >= 0 && weight < 150) fnt_weight = PANGO_WEIGHT_THIN; else if(weight >= 150 && weight < 250) fnt_weight = PANGO_WEIGHT_ULTRALIGHT; else if(weight >= 250 && weight < 350) fnt_weight = PANGO_WEIGHT_LIGHT; else if(weight >= 350 && weight < 450) fnt_weight = PANGO_WEIGHT_NORMAL; else if(weight >= 450 && weight < 550) fnt_weight = PANGO_WEIGHT_MEDIUM; else if(weight >= 550 && weight < 650) fnt_weight = PANGO_WEIGHT_SEMIBOLD; else if(weight >= 650 && weight < 750) fnt_weight = PANGO_WEIGHT_BOLD; else if(weight >= 750 && weight < 850) fnt_weight = PANGO_WEIGHT_ULTRABOLD; else fnt_weight = PANGO_WEIGHT_HEAVY; pango_font_description_set_weight(desc, fnt_weight); cairo_font* ret = nullptr; if(fm) { cairo_save(m_temp_cr); PangoLayout *layout = pango_cairo_create_layout(m_temp_cr); PangoContext *context = pango_layout_get_context(layout); PangoLanguage *language = pango_language_get_default(); pango_layout_set_font_description(layout, desc); PangoFontMetrics *metrics = pango_context_get_metrics(context, desc, language); fm->ascent = PANGO_PIXELS((double)pango_font_metrics_get_ascent(metrics)); fm->descent = PANGO_PIXELS((double)pango_font_metrics_get_descent(metrics)); fm->height = fm->ascent + fm->descent; fm->x_height = fm->height; pango_layout_set_text(layout, "x", 1); int x_width, x_height; pango_layout_get_pixel_size(layout, &x_width, &x_height); fm->x_height = x_height; cairo_restore(m_temp_cr); g_object_unref(layout); pango_font_metrics_unref(metrics); ret = new cairo_font; ret->font = desc; ret->size = size; ret->strikeout = (decoration & litehtml::font_decoration_linethrough) != 0; ret->underline = (decoration & litehtml::font_decoration_underline) != 0; ret->ascent = fm->ascent; ret->descent = fm->descent; ret->underline_thickness = pango_font_metrics_get_underline_thickness(metrics); ret->underline_position = -pango_font_metrics_get_underline_position(metrics); pango_quantize_line_geometry(&ret->underline_thickness, &ret->underline_position); ret->underline_thickness = PANGO_PIXELS(ret->underline_thickness); ret->underline_position = -1;//PANGO_PIXELS(ret->underline_position); ret->strikethrough_thickness = pango_font_metrics_get_strikethrough_thickness(metrics); ret->strikethrough_position = pango_font_metrics_get_strikethrough_position(metrics); pango_quantize_line_geometry(&ret->strikethrough_thickness, &ret->strikethrough_position); ret->strikethrough_thickness = PANGO_PIXELS(ret->strikethrough_thickness); ret->strikethrough_position = PANGO_PIXELS(ret->strikethrough_position); } return (litehtml::uint_ptr) ret; } void container_linux::delete_font( litehtml::uint_ptr hFont ) { auto* fnt = (cairo_font*) hFont; if(fnt) { pango_font_description_free(fnt->font); delete fnt; } } int container_linux::text_width( const litehtml::tchar_t* text, litehtml::uint_ptr hFont ) { auto* fnt = (cairo_font*) hFont; cairo_save(m_temp_cr); PangoLayout *layout = pango_cairo_create_layout(m_temp_cr); pango_layout_set_font_description(layout, fnt->font); pango_layout_set_text(layout, text, -1); pango_cairo_update_layout (m_temp_cr, layout); int x_width, x_height; pango_layout_get_pixel_size(layout, &x_width, &x_height); cairo_restore(m_temp_cr); return (int) x_width; } void container_linux::draw_text( litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos ) { auto* fnt = (cairo_font*) hFont; auto* cr = (cairo_t*) hdc; cairo_save(cr); apply_clip(cr); set_color(cr, color); PangoLayout *layout = pango_cairo_create_layout(cr); pango_layout_set_font_description (layout, fnt->font); pango_layout_set_text (layout, text, -1); int baseline = PANGO_PIXELS(pango_layout_get_baseline(layout)); PangoRectangle ink_rect, logical_rect; pango_layout_get_pixel_extents(layout, &ink_rect, &logical_rect); int text_baseline = pos.height - fnt->descent; int x = pos.left() + logical_rect.x; int y = pos.top() + logical_rect.y + text_baseline - baseline; cairo_move_to(cr, x, y); pango_cairo_update_layout (cr, layout); pango_cairo_show_layout (cr, layout); int tw = 0; if(fnt->underline || fnt->strikeout) { tw = text_width(text, hFont); } if(fnt->underline) { cairo_set_line_width(cr, fnt->underline_thickness); cairo_move_to(cr, x, pos.top() + text_baseline - fnt->underline_position + 0.5); cairo_line_to(cr, x + tw, pos.top() + text_baseline - fnt->underline_position + 0.5); cairo_stroke(cr); } if(fnt->strikeout) { cairo_set_line_width(cr, fnt->strikethrough_thickness); cairo_move_to(cr, x, pos.top() + text_baseline - fnt->strikethrough_position - 0.5); cairo_line_to(cr, x + tw, pos.top() + text_baseline - fnt->strikethrough_position - 0.5); cairo_stroke(cr); } cairo_restore(cr); g_object_unref(layout); } int container_linux::pt_to_px( int pt ) const { GdkScreen* screen = gdk_screen_get_default(); double dpi = gdk_screen_get_resolution(screen); return (int) ((double) pt * dpi / 72.0); } int container_linux::get_default_font_size() const { return pt_to_px(12); } void container_linux::draw_list_marker( litehtml::uint_ptr hdc, const litehtml::list_marker& marker ) { if(!marker.image.empty()) { /*litehtml::tstring url; make_url(marker.image.c_str(), marker.baseurl, url); lock_images_cache(); images_map::iterator img_i = m_images.find(url.c_str()); if(img_i != m_images.end()) { if(img_i->second) { draw_txdib((cairo_t*) hdc, img_i->second, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height); } } unlock_images_cache();*/ } else { switch(marker.marker_type) { case litehtml::list_style_type_circle: { draw_ellipse((cairo_t*) hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color, 1); } break; case litehtml::list_style_type_disc: { fill_ellipse((cairo_t*) hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color); } break; case litehtml::list_style_type_square: if(hdc) { auto* cr = (cairo_t*) hdc; cairo_save(cr); cairo_new_path(cr); cairo_rectangle(cr, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height); set_color(cr, marker.color); cairo_fill(cr); cairo_restore(cr); } break; default: /*do nothing*/ break; } } } void container_linux::load_image( const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready ) { litehtml::tstring url; make_url(src, baseurl, url); if(m_images.find(url) == m_images.end()) { try { Glib::RefPtr img = get_image(url.c_str(), true); if(img) { m_images[url.c_str()] = img; } } catch(...) { m_images[url.c_str()] = Glib::RefPtr(nullptr); } } } void container_linux::get_image_size( const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz ) { litehtml::tstring url; make_url(src, baseurl, url); auto img = m_images.find(url); if(img != m_images.end()) { if(img->second) { sz.width = img->second->get_width(); sz.height = img->second->get_height(); } else { sz.width = 0; sz.height = 0; } } else { sz.width = 0; sz.height = 0; } } void container_linux::draw_background( litehtml::uint_ptr hdc, const litehtml::background_paint& bg ) { auto* cr = (cairo_t*) hdc; cairo_save(cr); apply_clip(cr); rounded_rectangle(cr, bg.border_box, bg.border_radius); cairo_clip(cr); cairo_rectangle(cr, bg.clip_box.x, bg.clip_box.y, bg.clip_box.width, bg.clip_box.height); cairo_clip(cr); if(bg.color.alpha) { set_color(cr, bg.color); cairo_paint(cr); } litehtml::tstring url; make_url(bg.image.c_str(), bg.baseurl.c_str(), url); //lock_images_cache(); auto img_i = m_images.find(url); if(img_i != m_images.end() && img_i->second) { Glib::RefPtr bgbmp = img_i->second; Glib::RefPtr new_img; if(bg.image_size.width != bgbmp->get_width() || bg.image_size.height != bgbmp->get_height()) { new_img = bgbmp->scale_simple(bg.image_size.width, bg.image_size.height, Gdk::INTERP_BILINEAR); bgbmp = new_img; } cairo_surface_t* img = surface_from_pixbuf(bgbmp); cairo_pattern_t *pattern = cairo_pattern_create_for_surface(img); cairo_matrix_t flib_m; cairo_matrix_init_identity(&flib_m); cairo_matrix_translate(&flib_m, -bg.position_x, -bg.position_y); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); cairo_pattern_set_matrix (pattern, &flib_m); switch(bg.repeat) { case litehtml::background_repeat_no_repeat: draw_pixbuf(cr, bgbmp, bg.position_x, bg.position_y, bgbmp->get_width(), bgbmp->get_height()); break; case litehtml::background_repeat_repeat_x: cairo_set_source(cr, pattern); cairo_rectangle(cr, bg.clip_box.left(), bg.position_y, bg.clip_box.width, bgbmp->get_height()); cairo_fill(cr); break; case litehtml::background_repeat_repeat_y: cairo_set_source(cr, pattern); cairo_rectangle(cr, bg.position_x, bg.clip_box.top(), bgbmp->get_width(), bg.clip_box.height); cairo_fill(cr); break; case litehtml::background_repeat_repeat: cairo_set_source(cr, pattern); cairo_rectangle(cr, bg.clip_box.left(), bg.clip_box.top(), bg.clip_box.width, bg.clip_box.height); cairo_fill(cr); break; } cairo_pattern_destroy(pattern); cairo_surface_destroy(img); } // unlock_images_cache(); cairo_restore(cr); } void container_linux::make_url(const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out) { out = url; } void container_linux::add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg) { if(rx > 0 && ry > 0) { cairo_save(cr); cairo_translate(cr, x, y); cairo_scale(cr, 1, ry / rx); cairo_translate(cr, -x, -y); if(neg) { cairo_arc_negative(cr, x, y, rx, a1, a2); } else { cairo_arc(cr, x, y, rx, a1, a2); } cairo_restore(cr); } else { cairo_move_to(cr, x, y); } } void container_linux::draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) { auto* cr = (cairo_t*) hdc; cairo_save(cr); apply_clip(cr); cairo_new_path(cr); int bdr_top = 0; int bdr_bottom = 0; int bdr_left = 0; int bdr_right = 0; if(borders.top.width != 0 && borders.top.style > litehtml::border_style_hidden) { bdr_top = (int) borders.top.width; } if(borders.bottom.width != 0 && borders.bottom.style > litehtml::border_style_hidden) { bdr_bottom = (int) borders.bottom.width; } if(borders.left.width != 0 && borders.left.style > litehtml::border_style_hidden) { bdr_left = (int) borders.left.width; } if(borders.right.width != 0 && borders.right.style > litehtml::border_style_hidden) { bdr_right = (int) borders.right.width; } // draw right border if(bdr_right) { set_color(cr, borders.right.color); double r_top = borders.radius.top_right_x; double r_bottom = borders.radius.bottom_right_x; if(r_top) { double end_angle = 2 * M_PI; double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_top / (double) bdr_right + 1); add_path_arc(cr, draw_pos.right() - r_top, draw_pos.top() + r_top, r_top - bdr_right, r_top - bdr_right + (bdr_right - bdr_top), end_angle, start_angle, true); add_path_arc(cr, draw_pos.right() - r_top, draw_pos.top() + r_top, r_top, r_top, start_angle, end_angle, false); } else { cairo_move_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); cairo_line_to(cr, draw_pos.right(), draw_pos.top()); } if(r_bottom) { cairo_line_to(cr, draw_pos.right(), draw_pos.bottom() - r_bottom); double start_angle = 0; double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_bottom / (double) bdr_right + 1); add_path_arc(cr, draw_pos.right() - r_bottom, draw_pos.bottom() - r_bottom, r_bottom, r_bottom, start_angle, end_angle, false); add_path_arc(cr, draw_pos.right() - r_bottom, draw_pos.bottom() - r_bottom, r_bottom - bdr_right, r_bottom - bdr_right + (bdr_right - bdr_bottom), end_angle, start_angle, true); } else { cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); } cairo_fill(cr); } // draw bottom border if(bdr_bottom) { set_color(cr, borders.bottom.color); double r_left = borders.radius.bottom_left_x; double r_right = borders.radius.bottom_right_x; if(r_left) { double start_angle = M_PI / 2.0; double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_left / (double) bdr_bottom + 1); add_path_arc(cr, draw_pos.left() + r_left, draw_pos.bottom() - r_left, r_left - bdr_bottom + (bdr_bottom - bdr_left), r_left - bdr_bottom, start_angle, end_angle, false); add_path_arc(cr, draw_pos.left() + r_left, draw_pos.bottom() - r_left, r_left, r_left, end_angle, start_angle, true); } else { cairo_move_to(cr, draw_pos.left(), draw_pos.bottom()); cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); } if(r_right) { cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.bottom()); double end_angle = M_PI / 2.0; double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_right / (double) bdr_bottom + 1); add_path_arc(cr, draw_pos.right() - r_right, draw_pos.bottom() - r_right, r_right, r_right, end_angle, start_angle, true); add_path_arc(cr, draw_pos.right() - r_right, draw_pos.bottom() - r_right, r_right - bdr_bottom + (bdr_bottom - bdr_right), r_right - bdr_bottom, start_angle, end_angle, false); } else { cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); } cairo_fill(cr); } // draw top border if(bdr_top) { set_color(cr, borders.top.color); double r_left = borders.radius.top_left_x; double r_right = borders.radius.top_right_x; if(r_left) { double end_angle = M_PI * 3.0 / 2.0; double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_left / (double) bdr_top + 1); add_path_arc(cr, draw_pos.left() + r_left, draw_pos.top() + r_left, r_left, r_left, end_angle, start_angle, true); add_path_arc(cr, draw_pos.left() + r_left, draw_pos.top() + r_left, r_left - bdr_top + (bdr_top - bdr_left), r_left - bdr_top, start_angle, end_angle, false); } else { cairo_move_to(cr, draw_pos.left(), draw_pos.top()); cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); } if(r_right) { cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.top() + bdr_top); double start_angle = M_PI * 3.0 / 2.0; double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_right / (double) bdr_top + 1); add_path_arc(cr, draw_pos.right() - r_right, draw_pos.top() + r_right, r_right - bdr_top + (bdr_top - bdr_right), r_right - bdr_top, start_angle, end_angle, false); add_path_arc(cr, draw_pos.right() - r_right, draw_pos.top() + r_right, r_right, r_right, end_angle, start_angle, true); } else { cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); cairo_line_to(cr, draw_pos.right(), draw_pos.top()); } cairo_fill(cr); } // draw left border if(bdr_left) { set_color(cr, borders.left.color); double r_top = borders.radius.top_left_x; double r_bottom = borders.radius.bottom_left_x; if(r_top) { double start_angle = M_PI; double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_top / (double) bdr_left + 1); add_path_arc(cr, draw_pos.left() + r_top, draw_pos.top() + r_top, r_top - bdr_left, r_top - bdr_left + (bdr_left - bdr_top), start_angle, end_angle, false); add_path_arc(cr, draw_pos.left() + r_top, draw_pos.top() + r_top, r_top, r_top, end_angle, start_angle, true); } else { cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); cairo_line_to(cr, draw_pos.left(), draw_pos.top()); } if(r_bottom) { cairo_line_to(cr, draw_pos.left(), draw_pos.bottom() - r_bottom); double end_angle = M_PI; double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_bottom / (double) bdr_left + 1); add_path_arc(cr, draw_pos.left() + r_bottom, draw_pos.bottom() - r_bottom, r_bottom, r_bottom, end_angle, start_angle, true); add_path_arc(cr, draw_pos.left() + r_bottom, draw_pos.bottom() - r_bottom, r_bottom - bdr_left, r_bottom - bdr_left + (bdr_left - bdr_bottom), start_angle, end_angle, false); } else { cairo_line_to(cr, draw_pos.left(), draw_pos.bottom()); cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); } cairo_fill(cr); } cairo_restore(cr); } void container_linux::transform_text(litehtml::tstring& text, litehtml::text_transform tt) { } void container_linux::set_clip( const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y ) { litehtml::position clip_pos = pos; litehtml::position client_pos; get_client_rect(client_pos); if(!valid_x) { clip_pos.x = client_pos.x; clip_pos.width = client_pos.width; } if(!valid_y) { clip_pos.y = client_pos.y; clip_pos.height = client_pos.height; } m_clips.emplace_back(clip_pos, bdr_radius); } void container_linux::del_clip() { if(!m_clips.empty()) { m_clips.pop_back(); } } void container_linux::apply_clip( cairo_t* cr ) { for(const auto& clip_box : m_clips) { rounded_rectangle(cr, clip_box.box, clip_box.radius); cairo_clip(cr); } } void container_linux::draw_ellipse( cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, int line_width ) { if(!cr || !width || !height) return; cairo_save(cr); apply_clip(cr); cairo_new_path(cr); cairo_translate (cr, x + width / 2.0, y + height / 2.0); cairo_scale (cr, width / 2.0, height / 2.0); cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI); set_color(cr, color); cairo_set_line_width(cr, line_width); cairo_stroke(cr); cairo_restore(cr); } void container_linux::fill_ellipse( cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color ) { if(!cr || !width || !height) return; cairo_save(cr); apply_clip(cr); cairo_new_path(cr); cairo_translate (cr, x + width / 2.0, y + height / 2.0); cairo_scale (cr, width / 2.0, height / 2.0); cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI); set_color(cr, color); cairo_fill(cr); cairo_restore(cr); } void container_linux::clear_images() { /* for(images_map::iterator i = m_images.begin(); i != m_images.end(); i++) { if(i->second) { delete i->second; } } m_images.clear(); */ } const litehtml::tchar_t* container_linux::get_default_font_name() const { return "Times New Roman"; } std::shared_ptr container_linux::create_element(const litehtml::tchar_t *tag_name, const litehtml::string_map &attributes, const std::shared_ptr &doc) { return nullptr; } void container_linux::rounded_rectangle( cairo_t* cr, const litehtml::position &pos, const litehtml::border_radiuses &radius ) { cairo_new_path(cr); if(radius.top_left_x) { cairo_arc(cr, pos.left() + radius.top_left_x, pos.top() + radius.top_left_x, radius.top_left_x, M_PI, M_PI * 3.0 / 2.0); } else { cairo_move_to(cr, pos.left(), pos.top()); } cairo_line_to(cr, pos.right() - radius.top_right_x, pos.top()); if(radius.top_right_x) { cairo_arc(cr, pos.right() - radius.top_right_x, pos.top() + radius.top_right_x, radius.top_right_x, M_PI * 3.0 / 2.0, 2.0 * M_PI); } cairo_line_to(cr, pos.right(), pos.bottom() - radius.bottom_right_x); if(radius.bottom_right_x) { cairo_arc(cr, pos.right() - radius.bottom_right_x, pos.bottom() - radius.bottom_right_x, radius.bottom_right_x, 0, M_PI / 2.0); } cairo_line_to(cr, pos.left() - radius.bottom_left_x, pos.bottom()); if(radius.bottom_left_x) { cairo_arc(cr, pos.left() + radius.bottom_left_x, pos.bottom() - radius.bottom_left_x, radius.bottom_left_x, M_PI / 2.0, M_PI); } } void container_linux::draw_pixbuf(cairo_t* cr, const Glib::RefPtr& bmp, int x, int y, int cx, int cy) { cairo_save(cr); { Cairo::RefPtr crobj(new Cairo::Context(cr, false)); cairo_matrix_t flib_m; cairo_matrix_init(&flib_m, 1, 0, 0, -1, 0, 0); if(cx != bmp->get_width() || cy != bmp->get_height()) { Glib::RefPtr new_img = bmp->scale_simple(cx, cy, Gdk::INTERP_BILINEAR); Gdk::Cairo::set_source_pixbuf(crobj, new_img, x, y); crobj->paint(); } else { Gdk::Cairo::set_source_pixbuf(crobj, bmp, x, y); crobj->paint(); } } cairo_restore(cr); } cairo_surface_t* container_linux::surface_from_pixbuf(const Glib::RefPtr& bmp) { cairo_surface_t* ret; if(bmp->get_has_alpha()) { ret = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bmp->get_width(), bmp->get_height()); } else { ret = cairo_image_surface_create(CAIRO_FORMAT_RGB24, bmp->get_width(), bmp->get_height()); } Cairo::RefPtr surface(new Cairo::Surface(ret, false)); Cairo::RefPtr ctx = Cairo::Context::create(surface); Gdk::Cairo::set_source_pixbuf(ctx, bmp, 0.0, 0.0); ctx->paint(); return ret; } void container_linux::get_media_features(litehtml::media_features& media) const { litehtml::position client; get_client_rect(client); media.type = litehtml::media_type_screen; media.width = client.width; media.height = client.height; media.device_width = Gdk::screen_width(); media.device_height = Gdk::screen_height(); media.color = 8; media.monochrome = 0; media.color_index = 256; media.resolution = 96; } void container_linux::get_language(litehtml::tstring& language, litehtml::tstring& culture) const { language = _t("en"); culture = _t(""); } void container_linux::link(const std::shared_ptr &ptr, const litehtml::element::ptr& el) { } litehtml-0.6/containers/linux/container_linux.h000066400000000000000000000102721422312550200220550ustar00rootroot00000000000000#ifndef LH_CONTAINER_LINUX_H #define LH_CONTAINER_LINUX_H #include "../../include/litehtml.h" #include #include #include struct cairo_clip_box { typedef std::vector vector; litehtml::position box; litehtml::border_radiuses radius; cairo_clip_box(const litehtml::position& vBox, const litehtml::border_radiuses& vRad) { box = vBox; radius = vRad; } cairo_clip_box(const cairo_clip_box& val) { box = val.box; radius = val.radius; } cairo_clip_box& operator=(const cairo_clip_box& val) { box = val.box; radius = val.radius; return *this; } }; struct cairo_font { PangoFontDescription* font; int size; bool underline; bool strikeout; int ascent; int descent; int underline_thickness; int underline_position; int strikethrough_thickness; int strikethrough_position; }; class container_linux : public litehtml::document_container { typedef std::map > images_map; protected: cairo_surface_t* m_temp_surface; cairo_t* m_temp_cr; images_map m_images; cairo_clip_box::vector m_clips; public: container_linux(); virtual ~container_linux(); litehtml::uint_ptr create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) override; void delete_font(litehtml::uint_ptr hFont) override; int text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) override; void draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) override; int pt_to_px(int pt) const override; int get_default_font_size() const override; const litehtml::tchar_t* get_default_font_name() const override; void load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) override; void get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) override; void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) override; void draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) override; void draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) override; std::shared_ptr create_element(const litehtml::tchar_t *tag_name, const litehtml::string_map &attributes, const std::shared_ptr &doc) override; void get_media_features(litehtml::media_features& media) const override; void get_language(litehtml::tstring& language, litehtml::tstring & culture) const override; void link(const std::shared_ptr &ptr, const litehtml::element::ptr& el) override; void transform_text(litehtml::tstring& text, litehtml::text_transform tt) override; void set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) override; void del_clip() override; virtual void make_url( const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out ); virtual Glib::RefPtr get_image(const litehtml::tchar_t* url, bool redraw_on_ready) = 0; void clear_images(); protected: virtual void draw_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, int line_width); virtual void fill_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color); virtual void rounded_rectangle( cairo_t* cr, const litehtml::position &pos, const litehtml::border_radiuses &radius ); private: void apply_clip(cairo_t* cr); static void add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg); static void set_color(cairo_t* cr, const litehtml::web_color& color) { cairo_set_source_rgba(cr, color.red / 255.0, color.green / 255.0, color.blue / 255.0, color.alpha / 255.0); } static cairo_surface_t* surface_from_pixbuf(const Glib::RefPtr& bmp); static void draw_pixbuf(cairo_t* cr, const Glib::RefPtr& bmp, int x, int y, int cx, int cy); }; #endif litehtml-0.6/containers/test/000077500000000000000000000000001422312550200163215ustar00rootroot00000000000000litehtml-0.6/containers/test/container_test.cpp000066400000000000000000000067171422312550200220610ustar00rootroot00000000000000#include "container_test.h" container_test::container_test() {} container_test::~container_test() {} litehtml::uint_ptr container_test::create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) { if (fm) { fm->ascent = 10; fm->descent = 5; fm->height = 10 + 5; fm->x_height = 3; } return (litehtml::uint_ptr)0; } void container_test::delete_font(litehtml::uint_ptr hFont) {} int container_test::text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) { return 0; } void container_test::draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) {} int container_test::pt_to_px(int pt) const { return (int)((double)pt * 96 / 72.0); } int container_test::get_default_font_size() const { return 16; } const litehtml::tchar_t* container_test::get_default_font_name() const { return _t("Times New Roman"); } void container_test::draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) {} void container_test::load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) {} void container_test::get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) {} void container_test::draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) {} void container_test::make_url(const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out) { out = url; } void container_test::draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) {} void container_test::set_caption(const litehtml::tchar_t* caption){}; //: set_caption void container_test::set_base_url(const litehtml::tchar_t* base_url){}; //: set_base_url void container_test::link(const std::shared_ptr& ptr, const litehtml::element::ptr& el) {} void container_test::on_anchor_click(const litehtml::tchar_t* url, const litehtml::element::ptr& el) {} //: on_anchor_click void container_test::set_cursor(const litehtml::tchar_t* cursor) {} //: set_cursor void container_test::transform_text(litehtml::tstring& text, litehtml::text_transform tt) {} void container_test::import_css(litehtml::tstring& text, const litehtml::tstring& url, litehtml::tstring& baseurl) {} //: import_css void container_test::set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) {} void container_test::del_clip() {} void container_test::get_client_rect(litehtml::position& client) const {} //: get_client_rect std::shared_ptr container_test::create_element(const litehtml::tchar_t* tag_name, const litehtml::string_map& attributes, const std::shared_ptr& doc) { return 0; } void container_test::get_media_features(litehtml::media_features& media) const { litehtml::position client; get_client_rect(client); media.type = litehtml::media_type_screen; media.width = client.width; media.height = client.height; media.device_width = 100; media.device_height = 100; media.color = 8; media.monochrome = 0; media.color_index = 256; media.resolution = 96; } void container_test::get_language(litehtml::tstring& language, litehtml::tstring& culture) const { language = _t("en"); culture = _t(""); } //: resolve_colorlitehtml-0.6/containers/test/container_test.h000066400000000000000000000056511422312550200215220ustar00rootroot00000000000000#pragma once #include "../../include/litehtml.h" class container_test : public litehtml::document_container { public: container_test(); virtual ~container_test(); virtual litehtml::uint_ptr create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) override; virtual void delete_font(litehtml::uint_ptr hFont) override; virtual int text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) override; virtual void draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) override; virtual int pt_to_px(int pt) const override; virtual int get_default_font_size() const override; virtual const litehtml::tchar_t* get_default_font_name() const override; virtual void load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) override; virtual void get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) override; virtual void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) override; virtual void draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) override; virtual void draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) override; virtual std::shared_ptr create_element(const litehtml::tchar_t *tag_name, const litehtml::string_map &attributes, const std::shared_ptr &doc) override; virtual void get_media_features(litehtml::media_features& media) const override; virtual void get_language(litehtml::tstring& language, litehtml::tstring & culture) const override; virtual void link(const std::shared_ptr &ptr, const litehtml::element::ptr& el) override; virtual void transform_text(litehtml::tstring& text, litehtml::text_transform tt) override; virtual void set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) override; virtual void del_clip() override; virtual void make_url( const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out ); virtual void set_caption(const litehtml::tchar_t* caption) override; virtual void set_base_url(const litehtml::tchar_t* base_url) override; virtual void on_anchor_click(const litehtml::tchar_t* url, const litehtml::element::ptr& el) override; virtual void set_cursor(const litehtml::tchar_t* cursor) override; virtual void import_css(litehtml::tstring& text, const litehtml::tstring& url, litehtml::tstring& baseurl) override; virtual void get_client_rect(litehtml::position& client) const override; }; litehtml-0.6/containers/win32/000077500000000000000000000000001422312550200163045ustar00rootroot00000000000000litehtml-0.6/containers/win32/win32_container.cpp000066400000000000000000000172661422312550200220300ustar00rootroot00000000000000#include #include "win32_container.h" litehtml::win32_container::win32_container() { m_hClipRgn = NULL; } litehtml::win32_container::~win32_container() { if(m_hClipRgn) { DeleteObject(m_hClipRgn); } } litehtml::uint_ptr litehtml::win32_container::create_font( const wchar_t* faceName, int size, int weight, font_style italic, unsigned int decoration ) { litehtml::string_vector fonts; tokenize(faceName, fonts, L","); litehtml::trim(fonts[0]); LOGFONT lf; ZeroMemory(&lf, sizeof(lf)); wcscpy_s(lf.lfFaceName, LF_FACESIZE, fonts[0].c_str()); lf.lfHeight = -size; lf.lfWeight = weight; lf.lfItalic = (italic == litehtml::fontStyleItalic) ? TRUE : FALSE; lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfStrikeOut = (decoration & litehtml::font_decoration_linethrough) ? TRUE : FALSE; lf.lfUnderline = (decoration & litehtml::font_decoration_underline) ? TRUE : FALSE; HFONT hFont = CreateFontIndirect(&lf); return (uint_ptr) hFont; } void litehtml::win32_container::delete_font( uint_ptr hFont ) { DeleteObject((HFONT) hFont); } int litehtml::win32_container::line_height( uint_ptr hdc, uint_ptr hFont ) { HFONT oldFont = (HFONT) SelectObject((HDC) hdc, (HFONT) hFont); TEXTMETRIC tm; GetTextMetrics((HDC) hdc, &tm); SelectObject((HDC) hdc, oldFont); return (int) tm.tmHeight; } int litehtml::win32_container::text_width( uint_ptr hdc, const wchar_t* text, uint_ptr hFont ) { HFONT oldFont = (HFONT) SelectObject((HDC) hdc, (HFONT) hFont); SIZE sz = {0, 0}; GetTextExtentPoint32((HDC) hdc, text, lstrlen(text), &sz); SelectObject((HDC) hdc, oldFont); return (int) sz.cx; } void litehtml::win32_container::draw_text( uint_ptr hdc, const wchar_t* text, uint_ptr hFont, litehtml::web_color color, const litehtml::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, text, -1, &rcText, DT_SINGLELINE | DT_NOPREFIX | DT_BOTTOM | DT_NOCLIP); SelectObject((HDC) hdc, oldFont); release_clip((HDC) hdc); } void litehtml::win32_container::fill_rect( uint_ptr hdc, const litehtml::position& pos, const litehtml::web_color color, const litehtml::css_border_radius& radius ) { apply_clip((HDC) hdc); fill_rect((HDC) hdc, pos.x, pos.y, pos.width, pos.height, color, radius); release_clip((HDC) hdc); } litehtml::uint_ptr litehtml::win32_container::get_temp_dc() { return (litehtml::uint_ptr) GetDC(NULL); } void litehtml::win32_container::release_temp_dc( uint_ptr hdc ) { ReleaseDC(NULL, (HDC) hdc); } int litehtml::win32_container::pt_to_px( int pt ) { HDC dc = GetDC(NULL); int ret = MulDiv(pt, GetDeviceCaps(dc, LOGPIXELSY), 72); ReleaseDC(NULL, dc); return ret; } int litehtml::win32_container::get_text_base_line( uint_ptr hdc, uint_ptr hFont ) { HDC dc = (HDC) hdc; if(!dc) { dc = GetDC(NULL); } HFONT oldFont = (HFONT) SelectObject(dc, (HFONT) hFont); TEXTMETRIC tm; GetTextMetrics(dc, &tm); SelectObject(dc, oldFont); if(!hdc) { ReleaseDC(NULL, dc); } return (int) tm.tmDescent; } void litehtml::win32_container::draw_list_marker(uint_ptr hdc, const litehtml::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, css_border_radius()); } break; } release_clip((HDC)hdc); } void litehtml::win32_container::load_image( const wchar_t* src, const wchar_t* baseurl, bool redraw_on_ready ) { std::wstring url; make_url(src, baseurl, url); if(m_images.find(url.c_str()) == m_images.end()) { uint_ptr img = get_image(url.c_str()); if(img) { m_images[url.c_str()] = img; } } } void litehtml::win32_container::get_image_size( const wchar_t* src, const wchar_t* baseurl, litehtml::size& sz ) { std::wstring url; make_url(src, baseurl, url); images_map::iterator img = m_images.find(url.c_str()); if(img != m_images.end()) { get_img_size(img->second, sz); } } void litehtml::win32_container::draw_image( uint_ptr hdc, const wchar_t* src, const wchar_t* baseurl, const litehtml::position& pos ) { apply_clip((HDC) hdc); std::wstring url; make_url(src, baseurl, url); images_map::iterator img = m_images.find(url.c_str()); if(img != m_images.end()) { draw_img((HDC) hdc, img->second, pos); } release_clip((HDC) hdc); } void litehtml::win32_container::clear_images() { for(images_map::iterator i = m_images.begin(); i != m_images.end(); i++) { if(i->second) { free_image(i->second); } } m_images.clear(); } int litehtml::win32_container::get_default_font_size() const { return 16; } 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 ) { apply_clip((HDC) hdc); std::wstring url; make_url(image, baseurl, url); images_map::iterator img = m_images.find(url.c_str()); if(img != m_images.end()) { litehtml::size img_sz; get_img_size(img->second, img_sz); litehtml::position pos = draw_pos; if(bg_pos.x.units() != css_units_percentage) { pos.x += (int) bg_pos.x.val(); } else { pos.x += (int) ((float) (draw_pos.width - img_sz.width) * bg_pos.x.val() / 100.0); } if(bg_pos.y.units() != css_units_percentage) { pos.y += (int) bg_pos.y.val(); } else { pos.y += (int) ( (float) (draw_pos.height - img_sz.height) * bg_pos.y.val() / 100.0); } draw_img_bg((HDC) hdc, img->second, draw_pos, pos, repeat, attachment); } release_clip((HDC) hdc); } wchar_t litehtml::win32_container::toupper( const wchar_t c ) { return (wchar_t) CharUpper((LPWSTR) c); } wchar_t litehtml::win32_container::tolower( const wchar_t c ) { return (wchar_t) CharLower((LPWSTR) c); } void litehtml::win32_container::set_clip( const litehtml::position& pos, bool valid_x, bool valid_y ) { litehtml::position clip_pos = pos; litehtml::position client_pos; get_client_rect(client_pos); if(!valid_x) { clip_pos.x = client_pos.x; clip_pos.width = client_pos.width; } if(!valid_y) { clip_pos.y = client_pos.y; clip_pos.height = client_pos.height; } m_clips.push_back(clip_pos); } void litehtml::win32_container::del_clip() { if(!m_clips.empty()) { m_clips.pop_back(); if(!m_clips.empty()) { litehtml::position clip_pos = m_clips.back(); } } } void litehtml::win32_container::apply_clip(HDC hdc) { if(m_hClipRgn) { DeleteObject(m_hClipRgn); m_hClipRgn = NULL; } if(!m_clips.empty()) { POINT ptView = {0, 0}; GetWindowOrgEx(hdc, &ptView); litehtml::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 litehtml::win32_container::release_clip(HDC hdc) { SelectClipRgn(hdc, NULL); if(m_hClipRgn) { DeleteObject(m_hClipRgn); m_hClipRgn = NULL; } } litehtml-0.6/containers/win32/win32_container.h000066400000000000000000000062331422312550200214650ustar00rootroot00000000000000#pragma once #include namespace litehtml { class win32_container : public document_container { public: typedef std::map images_map; protected: images_map m_images; litehtml::position::vector m_clips; HRGN m_hClipRgn; public: win32_container(); virtual ~win32_container(); // litehtml::document_container members virtual uint_ptr create_font(const wchar_t* faceName, int size, int weight, font_style italic, unsigned int decoration); virtual void delete_font(uint_ptr hFont); virtual int line_height(uint_ptr hdc, uint_ptr hFont); virtual int get_text_base_line(uint_ptr hdc, uint_ptr hFont); virtual int text_width(uint_ptr hdc, const wchar_t* text, uint_ptr hFont); virtual void draw_text(uint_ptr hdc, const wchar_t* text, uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos); virtual void fill_rect(uint_ptr hdc, const litehtml::position& pos, const litehtml::web_color color, const litehtml::css_border_radius& radius); virtual uint_ptr get_temp_dc(); virtual void release_temp_dc(uint_ptr hdc); virtual int pt_to_px(int pt); virtual void draw_list_marker(uint_ptr hdc, const litehtml::list_marker& marker); virtual void load_image(const wchar_t* src, const wchar_t* baseurl, bool redraw_on_ready); virtual void get_image_size(const wchar_t* src, const wchar_t* baseurl, litehtml::size& sz); virtual void draw_image(uint_ptr hdc, const wchar_t* src, const wchar_t* baseurl, const litehtml::position& pos); virtual void 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); virtual int get_default_font_size() const; virtual wchar_t toupper(const wchar_t c); virtual wchar_t tolower(const wchar_t c); virtual void set_clip(const litehtml::position& pos, bool valid_x, bool valid_y); virtual void del_clip(); protected: void apply_clip(HDC hdc); void release_clip(HDC hdc); void clear_images(); virtual void make_url( LPCWSTR url, LPCWSTR basepath, std::wstring& out ) = 0; virtual uint_ptr get_image(LPCWSTR url) = 0; virtual void free_image(uint_ptr img) = 0; virtual void get_client_rect(litehtml::position& client) = 0; virtual void draw_ellipse(HDC hdc, int x, int y, int width, int height, const web_color& color, int line_width) = 0; virtual void fill_ellipse(HDC hdc, int x, int y, int width, int height, const web_color& color) = 0; virtual void fill_rect(HDC hdc, int x, int y, int width, int height, const web_color& color, const litehtml::css_border_radius& radius) = 0; virtual void get_img_size(litehtml::uint_ptr img, litehtml::size& sz) = 0; virtual void draw_img(HDC hdc, litehtml::uint_ptr img, const litehtml::position& pos) = 0; virtual void draw_img_bg(HDC hdc, litehtml::uint_ptr img, const litehtml::position& draw_pos, const litehtml::position& pos, litehtml::background_repeat repeat, litehtml::background_attachment attachment) = 0; }; }litehtml-0.6/include/000077500000000000000000000000001422312550200146205ustar00rootroot00000000000000litehtml-0.6/include/litehtml.h000066400000000000000000000003261422312550200166140ustar00rootroot00000000000000#ifndef LITEHTML_H #define LITEHTML_H #include #include #include #include #include #endif // LITEHTML_H litehtml-0.6/include/litehtml/000077500000000000000000000000001422312550200164425ustar00rootroot00000000000000litehtml-0.6/include/litehtml/attributes.h000066400000000000000000000007421422312550200210040ustar00rootroot00000000000000#ifndef LH_ATTRIBUTES_H #define LH_ATTRIBUTES_H namespace litehtml { struct attr_color { unsigned char rgbBlue; unsigned char rgbGreen; unsigned char rgbRed; unsigned char rgbAlpha; attr_color() { rgbAlpha = 255; rgbBlue = 0; rgbGreen = 0; rgbRed = 0; } }; struct attr_border { style_border border; int width; attr_color color; attr_border() { border = borderNone; width = 0; } }; } #endif // LH_ATTRIBUTES_H litehtml-0.6/include/litehtml/background.h000066400000000000000000000022351422312550200207340ustar00rootroot00000000000000#ifndef LH_BACKGROUND_H #define LH_BACKGROUND_H #include "types.h" #include "attributes.h" #include "css_length.h" #include "css_position.h" #include "web_color.h" #include "borders.h" namespace litehtml { class background { public: tstring m_image; tstring m_baseurl; web_color m_color; background_attachment m_attachment; css_position m_position; background_repeat m_repeat; background_box m_clip; background_box m_origin; css_border_radius m_radius; public: background(); background(const background& val); ~background() = default; background& operator=(const background& val); }; class background_paint { public: tstring image; tstring baseurl; background_attachment attachment; background_repeat repeat; web_color color; position clip_box; position origin_box; position border_box; border_radiuses border_radius; size image_size; int position_x; int position_y; bool is_root; public: background_paint(); background_paint(const background_paint& val); background_paint& operator=(const background& val); }; } #endif // LH_BACKGROUND_H litehtml-0.6/include/litehtml/borders.h000066400000000000000000000143141422312550200202560ustar00rootroot00000000000000#ifndef LH_BORDERS_H #define LH_BORDERS_H #include "css_length.h" #include "types.h" namespace litehtml { struct css_border { css_length width; border_style style; web_color color; css_border() { style = border_style_none; } css_border(const css_border& val) { width = val.width; style = val.style; color = val.color; } css_border& operator=(const css_border& val) { width = val.width; style = val.style; color = val.color; return *this; } }; struct border { int width; border_style style; web_color color; border() { width = 0; } border(const border& val) { width = val.width; style = val.style; color = val.color; } border(const css_border& val) { width = (int) val.width.val(); style = val.style; color = val.color; } border& operator=(const border& val) { width = val.width; style = val.style; color = val.color; return *this; } border& operator=(const css_border& val) { width = (int) val.width.val(); style = val.style; color = val.color; return *this; } }; struct border_radiuses { int top_left_x; int top_left_y; int top_right_x; int top_right_y; int bottom_right_x; int bottom_right_y; int bottom_left_x; int bottom_left_y; border_radiuses() { top_left_x = 0; top_left_y = 0; top_right_x = 0; top_right_y = 0; bottom_right_x = 0; bottom_right_y = 0; bottom_left_x = 0; bottom_left_y = 0; } border_radiuses(const border_radiuses& val) { top_left_x = val.top_left_x; top_left_y = val.top_left_y; top_right_x = val.top_right_x; top_right_y = val.top_right_y; bottom_right_x = val.bottom_right_x; bottom_right_y = val.bottom_right_y; bottom_left_x = val.bottom_left_x; bottom_left_y = val.bottom_left_y; } border_radiuses& operator = (const border_radiuses& val) { top_left_x = val.top_left_x; top_left_y = val.top_left_y; top_right_x = val.top_right_x; top_right_y = val.top_right_y; bottom_right_x = val.bottom_right_x; bottom_right_y = val.bottom_right_y; bottom_left_x = val.bottom_left_x; bottom_left_y = val.bottom_left_y; return *this; } void operator += (const margins& mg) { top_left_x += mg.left; top_left_y += mg.top; top_right_x += mg.right; top_right_y += mg.top; bottom_right_x += mg.right; bottom_right_y += mg.bottom; bottom_left_x += mg.left; bottom_left_y += mg.bottom; fix_values(); } void operator -= (const margins& mg) { top_left_x -= mg.left; top_left_y -= mg.top; top_right_x -= mg.right; top_right_y -= mg.top; bottom_right_x -= mg.right; bottom_right_y -= mg.bottom; bottom_left_x -= mg.left; bottom_left_y -= mg.bottom; fix_values(); } void fix_values() { if (top_left_x < 0) top_left_x = 0; if (top_left_y < 0) top_left_y = 0; if (top_right_x < 0) top_right_x = 0; if (top_right_y < 0) top_right_y = 0; if (bottom_right_x < 0) bottom_right_x = 0; if (bottom_right_y < 0) bottom_right_y = 0; if (bottom_left_x < 0) bottom_left_x = 0; if (bottom_left_y < 0) bottom_left_y = 0; } }; struct css_border_radius { css_length top_left_x; css_length top_left_y; css_length top_right_x; css_length top_right_y; css_length bottom_right_x; css_length bottom_right_y; css_length bottom_left_x; css_length bottom_left_y; css_border_radius() { } css_border_radius(const css_border_radius& val) { top_left_x = val.top_left_x; top_left_y = val.top_left_y; top_right_x = val.top_right_x; top_right_y = val.top_right_y; bottom_left_x = val.bottom_left_x; bottom_left_y = val.bottom_left_y; bottom_right_x = val.bottom_right_x; bottom_right_y = val.bottom_right_y; } css_border_radius& operator=(const css_border_radius& val) { top_left_x = val.top_left_x; top_left_y = val.top_left_y; top_right_x = val.top_right_x; top_right_y = val.top_right_y; bottom_left_x = val.bottom_left_x; bottom_left_y = val.bottom_left_y; bottom_right_x = val.bottom_right_x; bottom_right_y = val.bottom_right_y; return *this; } border_radiuses calc_percents(int width, int height) { border_radiuses ret; ret.bottom_left_x = bottom_left_x.calc_percent(width); ret.bottom_left_y = bottom_left_y.calc_percent(height); ret.top_left_x = top_left_x.calc_percent(width); ret.top_left_y = top_left_y.calc_percent(height); ret.top_right_x = top_right_x.calc_percent(width); ret.top_right_y = top_right_y.calc_percent(height); ret.bottom_right_x = bottom_right_x.calc_percent(width); ret.bottom_right_y = bottom_right_y.calc_percent(height); return ret; } }; struct css_borders { css_border left; css_border top; css_border right; css_border bottom; css_border_radius radius; css_borders() = default; bool is_visible() const { return left.width.val() != 0 || right.width.val() != 0 || top.width.val() != 0 || bottom.width.val() != 0; } css_borders(const css_borders& val) { left = val.left; right = val.right; top = val.top; bottom = val.bottom; radius = val.radius; } css_borders& operator=(const css_borders& val) { left = val.left; right = val.right; top = val.top; bottom = val.bottom; radius = val.radius; return *this; } }; struct borders { border left; border top; border right; border bottom; border_radiuses radius; borders() = default; borders(const borders& val) { left = val.left; right = val.right; top = val.top; bottom = val.bottom; radius = val.radius; } borders(const css_borders& val) { left = val.left; right = val.right; top = val.top; bottom = val.bottom; } bool is_visible() const { return left.width != 0 || right.width != 0 || top.width != 0 || bottom.width != 0; } borders& operator=(const borders& val) { left = val.left; right = val.right; top = val.top; bottom = val.bottom; radius = val.radius; return *this; } borders& operator=(const css_borders& val) { left = val.left; right = val.right; top = val.top; bottom = val.bottom; return *this; } }; } #endif // LH_BORDERS_H litehtml-0.6/include/litehtml/box.h000066400000000000000000000066261422312550200174150ustar00rootroot00000000000000#ifndef LH_BOX_H #define LH_BOX_H namespace litehtml { class html_tag; enum box_type { box_block, box_line }; class box { public: typedef std::unique_ptr ptr; typedef std::vector< box::ptr > vector; protected: int m_box_top; int m_box_left; int m_box_right; public: box(int top, int left, int right) { m_box_top = top; m_box_left = left; m_box_right = right; } virtual ~box() = default; int bottom() const { return m_box_top + height(); } int top() const { return m_box_top; } int right() const { return m_box_left + width(); } int left() const { return m_box_left; } virtual litehtml::box_type get_type() const = 0; virtual int height() const = 0; virtual int width() const = 0; virtual void add_element(const element::ptr &el) = 0; virtual bool can_hold(const element::ptr &el, white_space ws) const = 0; virtual void finish(bool last_box = false) = 0; virtual bool is_empty() const = 0; virtual int baseline() const = 0; virtual void get_elements(elements_vector& els) = 0; virtual int top_margin() const = 0; virtual int bottom_margin() const = 0; virtual void y_shift(int shift) = 0; virtual void new_width(int left, int right, elements_vector& els) = 0; }; ////////////////////////////////////////////////////////////////////////// class block_box : public box { element::ptr m_element; public: block_box(int top, int left, int right) : box(top, left, right) { m_element = nullptr; } litehtml::box_type get_type() const override; int height() const override; int width() const override; void add_element(const element::ptr &el) override; bool can_hold(const element::ptr &el, white_space ws) const override; void finish(bool last_box = false) override; bool is_empty() const override; int baseline() const override; void get_elements(elements_vector& els) override; int top_margin() const override; int bottom_margin() const override; void y_shift(int shift) override; void new_width(int left, int right, elements_vector& els) override; }; ////////////////////////////////////////////////////////////////////////// class line_box : public box { elements_vector m_items; int m_height; int m_width; int m_line_height; font_metrics m_font_metrics; int m_baseline; text_align m_text_align; public: line_box(int top, int left, int right, int line_height, font_metrics& fm, text_align align) : box(top, left, right) { m_height = 0; m_width = 0; m_font_metrics = fm; m_line_height = line_height; m_baseline = 0; m_text_align = align; } litehtml::box_type get_type() const override; int height() const override; int width() const override; void add_element(const element::ptr &el) override; bool can_hold(const element::ptr &el, white_space ws) const override; void finish(bool last_box = false) override; bool is_empty() const override; int baseline() const override; void get_elements(elements_vector& els) override; int top_margin() const override; int bottom_margin() const override; void y_shift(int shift) override; void new_width(int left, int right, elements_vector& els) override; private: bool have_last_space() const; bool is_break_only() const; }; } #endif // LH_BOX_H litehtml-0.6/include/litehtml/codepoint.h000066400000000000000000000042061422312550200206010ustar00rootroot00000000000000// Copyright (C) 2020-2021 Primate Labs Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the names of the copyright holders nor the names of their // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef LITEHTML_CODEPOINT_H__ #define LITEHTML_CODEPOINT_H__ #include #include "litehtml/os_types.h" namespace litehtml { bool is_ascii_codepoint(litehtml::tchar_t c); // Returns true if the codepoint is a reserved codepoint for URLs. // https://datatracker.ietf.org/doc/html/rfc3986#section-2.2 bool is_url_reserved_codepoint(litehtml::tchar_t c); // Returns true if the codepoint is a scheme codepoint for URLs. // https://datatracker.ietf.org/doc/html/rfc3986#section-3.1 bool is_url_scheme_codepoint(litehtml::tchar_t c); } // namespace litehtml #endif // LITEHTML_CODEPOINT_H__ litehtml-0.6/include/litehtml/context.h000066400000000000000000000004441422312550200203010ustar00rootroot00000000000000#ifndef LH_CONTEXT_H #define LH_CONTEXT_H #include "stylesheet.h" namespace litehtml { class context { litehtml::css m_master_css; public: void load_master_stylesheet(const tchar_t* str); litehtml::css& master_css() { return m_master_css; } }; } #endif // LH_CONTEXT_H litehtml-0.6/include/litehtml/css_length.h000066400000000000000000000044611422312550200207510ustar00rootroot00000000000000#ifndef LH_CSS_LENGTH_H #define LH_CSS_LENGTH_H #include "types.h" namespace litehtml { class css_length { union { float m_value; int m_predef; }; css_units m_units; bool m_is_predefined; public: css_length(); css_length(const css_length& val); css_length& operator=(const css_length& val); css_length& operator=(float val); bool is_predefined() const; void predef(int val); int predef() const; void set_value(float val, css_units units); float val() const; css_units units() const; int calc_percent(int width) const; void fromString(const tstring& str, const tstring& predefs = _t(""), int defValue = 0); }; // css_length inlines inline css_length::css_length() { m_value = 0; m_predef = 0; m_units = css_units_none; m_is_predefined = false; } inline css_length::css_length(const css_length& val) { if(val.is_predefined()) { m_predef = val.m_predef; } else { m_value = val.m_value; } m_units = val.m_units; m_is_predefined = val.m_is_predefined; } inline css_length& css_length::operator=(const css_length& val) { if(val.is_predefined()) { m_predef = val.m_predef; } else { m_value = val.m_value; } m_units = val.m_units; m_is_predefined = val.m_is_predefined; return *this; } inline css_length& css_length::operator=(float val) { m_value = val; m_units = css_units_px; m_is_predefined = false; return *this; } inline bool css_length::is_predefined() const { return m_is_predefined; } inline void css_length::predef(int val) { m_predef = val; m_is_predefined = true; } inline int css_length::predef() const { if(m_is_predefined) { return m_predef; } return 0; } inline void css_length::set_value(float val, css_units units) { m_value = val; m_is_predefined = false; m_units = units; } inline float css_length::val() const { if(!m_is_predefined) { return m_value; } return 0; } inline css_units css_length::units() const { return m_units; } inline int css_length::calc_percent(int width) const { if(!is_predefined()) { if(units() == css_units_percentage) { return (int) ((double) width * (double) m_value / 100.0); } else { return (int) val(); } } return 0; } } #endif // LH_CSS_LENGTH_H litehtml-0.6/include/litehtml/css_margins.h000066400000000000000000000010511422312550200211200ustar00rootroot00000000000000#ifndef LH_CSS_MARGINS_H #define LH_CSS_MARGINS_H #include "css_length.h" namespace litehtml { struct css_margins { css_length left; css_length right; css_length top; css_length bottom; css_margins() = default; css_margins(const css_margins& val) { left = val.left; right = val.right; top = val.top; bottom = val.bottom; } css_margins& operator=(const css_margins& val) { left = val.left; right = val.right; top = val.top; bottom = val.bottom; return *this; } }; } #endif // LH_CSS_MARGINS_H litehtml-0.6/include/litehtml/css_offsets.h000066400000000000000000000010511422312550200211310ustar00rootroot00000000000000#ifndef LH_CSS_OFFSETS_H #define LH_CSS_OFFSETS_H #include "css_length.h" namespace litehtml { struct css_offsets { css_length left; css_length top; css_length right; css_length bottom; css_offsets() = default; css_offsets(const css_offsets& val) { left = val.left; top = val.top; right = val.right; bottom = val.bottom; } css_offsets& operator=(const css_offsets& val) { left = val.left; top = val.top; right = val.right; bottom = val.bottom; return *this; } }; } #endif // LH_CSS_OFFSETS_H litehtml-0.6/include/litehtml/css_position.h000066400000000000000000000010331422312550200213240ustar00rootroot00000000000000#ifndef LH_CSS_POSITION_H #define LH_CSS_POSITION_H #include "css_length.h" namespace litehtml { struct css_position { css_length x; css_length y; css_length width; css_length height; css_position() = default; css_position(const css_position& val) { x = val.x; y = val.y; width = val.width; height = val.height; } css_position& operator=(const css_position& val) { x = val.x; y = val.y; width = val.width; height = val.height; return *this; } }; } #endif // LH_CSS_POSITION_H litehtml-0.6/include/litehtml/css_selector.h000066400000000000000000000123411422312550200213040ustar00rootroot00000000000000#ifndef LH_CSS_SELECTOR_H #define LH_CSS_SELECTOR_H #include "style.h" #include "media_query.h" namespace litehtml { ////////////////////////////////////////////////////////////////////////// struct selector_specificity { int a; int b; int c; int d; explicit selector_specificity(int va = 0, int vb = 0, int vc = 0, int vd = 0) { a = va; b = vb; c = vc; d = vd; } void operator += (const selector_specificity& val) { a += val.a; b += val.b; c += val.c; d += val.d; } bool operator==(const selector_specificity& val) const { if(a == val.a && b == val.b && c == val.c && d == val.d) { return true; } return false; } bool operator!=(const selector_specificity& val) const { if(a != val.a || b != val.b || c != val.c || d != val.d) { return true; } return false; } bool operator > (const selector_specificity& val) const { if(a > val.a) { return true; } else if(a < val.a) { return false; } else { if(b > val.b) { return true; } else if(b < val.b) { return false; } else { if(c > val.c) { return true; } else if(c < val.c) { return false; } else { if(d > val.d) { return true; } else if(d < val.d) { return false; } } } } return false; } bool operator >= (const selector_specificity& val) const { if((*this) == val) return true; if((*this) > val) return true; return false; } bool operator <= (const selector_specificity& val) const { if((*this) > val) { return false; } return true; } bool operator < (const selector_specificity& val) const { if((*this) <= val && (*this) != val) { return true; } return false; } }; ////////////////////////////////////////////////////////////////////////// enum attr_select_condition { select_exists, select_equal, select_contain_str, select_start_str, select_end_str, select_pseudo_class, select_pseudo_element, }; ////////////////////////////////////////////////////////////////////////// struct css_attribute_selector { typedef std::vector vector; tstring attribute; tstring val; string_vector class_val; attr_select_condition condition; css_attribute_selector() { condition = select_exists; } }; ////////////////////////////////////////////////////////////////////////// class css_element_selector { public: tstring m_tag; css_attribute_selector::vector m_attrs; public: void parse(const tstring& txt); }; ////////////////////////////////////////////////////////////////////////// enum css_combinator { combinator_descendant, combinator_child, combinator_adjacent_sibling, combinator_general_sibling }; ////////////////////////////////////////////////////////////////////////// class css_selector { public: typedef std::shared_ptr ptr; typedef std::vector vector; public: selector_specificity m_specificity; css_element_selector m_right; css_selector::ptr m_left; css_combinator m_combinator; tstring m_style; int m_order; media_query_list::ptr m_media_query; tstring m_baseurl; public: explicit css_selector(const media_query_list::ptr& media, const tstring& baseurl) { m_media_query = media; m_baseurl = baseurl; m_combinator = combinator_descendant; m_order = 0; } ~css_selector() = default; css_selector(const css_selector& val) { m_right = val.m_right; if(val.m_left) { m_left = std::make_shared(*val.m_left); } else { m_left = nullptr; } m_combinator = val.m_combinator; m_specificity = val.m_specificity; m_order = val.m_order; m_media_query = val.m_media_query; } bool parse(const tstring& text); void calc_specificity(); bool is_media_valid() const; void add_media_to_doc(document* doc) const; }; inline bool css_selector::is_media_valid() const { if(!m_media_query) { return true; } return m_media_query->is_used(); } ////////////////////////////////////////////////////////////////////////// inline bool operator > (const css_selector& v1, const css_selector& v2) { if(v1.m_specificity == v2.m_specificity) { return (v1.m_order > v2.m_order); } return (v1.m_specificity > v2.m_specificity); } inline bool operator < (const css_selector& v1, const css_selector& v2) { if(v1.m_specificity == v2.m_specificity) { return (v1.m_order < v2.m_order); } return (v1.m_specificity < v2.m_specificity); } inline bool operator >(const css_selector::ptr& v1, const css_selector::ptr& v2) { return (*v1 > *v2); } inline bool operator < (const css_selector::ptr& v1, const css_selector::ptr& v2) { return (*v1 < *v2); } ////////////////////////////////////////////////////////////////////////// class used_selector { public: typedef std::unique_ptr ptr; typedef std::vector vector; css_selector::ptr m_selector; bool m_used; used_selector(const css_selector::ptr& selector, bool used) { m_used = used; m_selector = selector; } }; } #endif // LH_CSS_SELECTOR_H litehtml-0.6/include/litehtml/document.h000066400000000000000000000105361422312550200204360ustar00rootroot00000000000000#ifndef LH_DOCUMENT_H #define LH_DOCUMENT_H #include "style.h" #include "types.h" #include "context.h" namespace litehtml { struct css_text { typedef std::vector vector; tstring text; tstring baseurl; tstring media; css_text() = default; css_text(const tchar_t* txt, const tchar_t* url, const tchar_t* media_str) { text = txt ? txt : _t(""); baseurl = url ? url : _t(""); media = media_str ? media_str : _t(""); } css_text(const css_text& val) { text = val.text; baseurl = val.baseurl; media = val.media; } }; class html_tag; class document : public std::enable_shared_from_this { public: typedef std::shared_ptr ptr; typedef std::weak_ptr weak_ptr; private: std::shared_ptr m_root; document_container* m_container; fonts_map m_fonts; css_text::vector m_css; litehtml::css m_styles; litehtml::web_color m_def_color; litehtml::context* m_context; litehtml::size m_size; position::vector m_fixed_boxes; media_query_list::vector m_media_lists; element::ptr m_over_element; elements_vector m_tabular_elements; media_features m_media; tstring m_lang; tstring m_culture; public: document(litehtml::document_container* objContainer, litehtml::context* ctx); virtual ~document(); litehtml::document_container* container() { return m_container; } uint_ptr get_font(const tchar_t* name, int size, const tchar_t* weight, const tchar_t* style, const tchar_t* decoration, font_metrics* fm); int render(int max_width, render_type rt = render_all); void draw(uint_ptr hdc, int x, int y, const position* clip); web_color get_def_color() { return m_def_color; } int cvt_units(const tchar_t* str, int fontSize, bool* is_percent = nullptr) const; int cvt_units(css_length& val, int fontSize, int size = 0) const; int width() const; int height() const; void add_stylesheet(const tchar_t* str, const tchar_t* baseurl, const tchar_t* media); bool on_mouse_over(int x, int y, int client_x, int client_y, position::vector& redraw_boxes); bool on_lbutton_down(int x, int y, int client_x, int client_y, position::vector& redraw_boxes); bool on_lbutton_up(int x, int y, int client_x, int client_y, position::vector& redraw_boxes); bool on_mouse_leave(position::vector& redraw_boxes); litehtml::element::ptr create_element(const tchar_t* tag_name, const string_map& attributes); element::ptr root(); void get_fixed_boxes(position::vector& fixed_boxes); void add_fixed_box(const position& pos); void add_media_list(const media_query_list::ptr& list); bool media_changed(); bool lang_changed(); bool match_lang(const tstring & lang); void add_tabular(const element::ptr& el); element::const_ptr get_over_element() const { return m_over_element; } void append_children_from_string(element& parent, const tchar_t* str); void append_children_from_utf8(element& parent, const char* str); static litehtml::document::ptr createFromString(const tchar_t* str, litehtml::document_container* objPainter, litehtml::context* ctx, litehtml::css* user_styles = nullptr); static litehtml::document::ptr createFromUTF8(const char* str, litehtml::document_container* objPainter, litehtml::context* ctx, litehtml::css* user_styles = nullptr); private: litehtml::uint_ptr add_font(const tchar_t* name, int size, const tchar_t* weight, const tchar_t* style, const tchar_t* decoration, font_metrics* fm); void create_node(void* gnode, elements_vector& elements, bool parseTextNode); bool update_media_lists(const media_features& features); void fix_tables_layout(); void fix_table_children(element::ptr& el_ptr, style_display disp, const tchar_t* disp_str); void fix_table_parent(element::ptr& el_ptr, style_display disp, const tchar_t* disp_str); }; inline element::ptr document::root() { return m_root; } inline void document::add_tabular(const element::ptr& el) { m_tabular_elements.push_back(el); } inline bool document::match_lang(const tstring & lang) { return lang == m_lang || lang == m_culture; } } #endif // LH_DOCUMENT_H litehtml-0.6/include/litehtml/el_anchor.h000066400000000000000000000005211422312550200205430ustar00rootroot00000000000000#ifndef LH_EL_ANCHOR_H #define LH_EL_ANCHOR_H #include "html_tag.h" namespace litehtml { class el_anchor : public html_tag { public: explicit el_anchor(const std::shared_ptr& doc); void on_click() override; void apply_stylesheet(const litehtml::css& stylesheet) override; }; } #endif // LH_EL_ANCHOR_H litehtml-0.6/include/litehtml/el_base.h000066400000000000000000000004141422312550200202040ustar00rootroot00000000000000#ifndef LH_EL_BASE_H #define LH_EL_BASE_H #include "html_tag.h" namespace litehtml { class el_base : public html_tag { public: explicit el_base(const std::shared_ptr& doc); void parse_attributes() override; }; } #endif // LH_EL_BASE_H litehtml-0.6/include/litehtml/el_before_after.h000066400000000000000000000016551422312550200217250ustar00rootroot00000000000000#ifndef LH_EL_BEFORE_AFTER_H #define LH_EL_BEFORE_AFTER_H #include "html_tag.h" namespace litehtml { class el_before_after_base : public html_tag { public: el_before_after_base(const std::shared_ptr& doc, bool before); void add_style(const tstring& style, const tstring& baseurl) override; void apply_stylesheet(const litehtml::css& stylesheet) override; private: void add_text(const tstring& txt); void add_function(const tstring& fnc, const tstring& params); static tstring convert_escape(const tchar_t* txt); }; class el_before : public el_before_after_base { public: explicit el_before(const std::shared_ptr& doc) : el_before_after_base(doc, true) { } }; class el_after : public el_before_after_base { public: explicit el_after(const std::shared_ptr& doc) : el_before_after_base(doc, false) { } }; } #endif // LH_EL_BEFORE_AFTER_H litehtml-0.6/include/litehtml/el_body.h000066400000000000000000000004111422312550200202240ustar00rootroot00000000000000#ifndef LH_EL_BODY_H #define LH_EL_BODY_H #include "html_tag.h" namespace litehtml { class el_body : public html_tag { public: explicit el_body(const std::shared_ptr& doc); bool is_body() const override; }; } #endif // LH_EL_BODY_H litehtml-0.6/include/litehtml/el_break.h000066400000000000000000000004171422312550200203610ustar00rootroot00000000000000#ifndef LH_EL_BREAK_H #define LH_EL_BREAK_H #include "html_tag.h" namespace litehtml { class el_break : public html_tag { public: explicit el_break(const std::shared_ptr& doc); bool is_break() const override; }; } #endif // LH_EL_BREAK_H litehtml-0.6/include/litehtml/el_cdata.h000066400000000000000000000005261422312550200203520ustar00rootroot00000000000000#ifndef LH_EL_CDATA_H #define LH_EL_CDATA_H #include "html_tag.h" namespace litehtml { class el_cdata : public element { tstring m_text; public: explicit el_cdata(const std::shared_ptr& doc); void get_text(tstring& text) override; void set_data(const tchar_t* data) override; }; } #endif // LH_EL_CDATA_H litehtml-0.6/include/litehtml/el_comment.h000066400000000000000000000006041422312550200207350ustar00rootroot00000000000000#ifndef LH_EL_COMMENT_H #define LH_EL_COMMENT_H #include "html_tag.h" namespace litehtml { class el_comment : public element { tstring m_text; public: explicit el_comment(const std::shared_ptr& doc); bool is_comment() const override; void get_text(tstring& text) override; void set_data(const tchar_t* data) override; }; } #endif // LH_EL_COMMENT_H litehtml-0.6/include/litehtml/el_div.h000066400000000000000000000004071422312550200200560ustar00rootroot00000000000000#ifndef LH_EL_DIV_H #define LH_EL_DIV_H #include "html_tag.h" namespace litehtml { class el_div : public html_tag { public: explicit el_div(const std::shared_ptr& doc); void parse_attributes() override; }; } #endif // LH_EL_DIV_H litehtml-0.6/include/litehtml/el_font.h000066400000000000000000000004141422312550200202400ustar00rootroot00000000000000#ifndef LH_EL_FONT_H #define LH_EL_FONT_H #include "html_tag.h" namespace litehtml { class el_font : public html_tag { public: explicit el_font(const std::shared_ptr& doc); void parse_attributes() override; }; } #endif // LH_EL_FONT_H litehtml-0.6/include/litehtml/el_image.h000066400000000000000000000013631422312550200203600ustar00rootroot00000000000000#ifndef LH_EL_IMAGE_H #define LH_EL_IMAGE_H #include "html_tag.h" namespace litehtml { class el_image : public html_tag { tstring m_src; public: el_image(const std::shared_ptr& doc); virtual ~el_image(void); virtual int line_height() const override; virtual bool is_replaced() const override; virtual int render(int x, int y, int max_width, bool second_pass = false) override; virtual void parse_attributes() override; virtual void parse_styles(bool is_reparse = false) override; virtual void draw(uint_ptr hdc, int x, int y, const position* clip) override; virtual void get_content_size(size& sz, int max_width) override; private: int calc_max_height(int image_height); }; } #endif // LH_EL_IMAGE_H litehtml-0.6/include/litehtml/el_li.h000066400000000000000000000005331422312550200177000ustar00rootroot00000000000000#ifndef LH_EL_LI_H #define LH_EL_LI_H #include "html_tag.h" namespace litehtml { class el_li : public html_tag { public: explicit el_li(const std::shared_ptr& doc); int render(int x, int y, int max_width, bool second_pass = false) override; private: bool m_index_initialized = false; }; } #endif // LH_EL_LI_H litehtml-0.6/include/litehtml/el_link.h000066400000000000000000000004301422312550200202250ustar00rootroot00000000000000#ifndef LH_EL_LINK_H #define LH_EL_LINK_H #include "html_tag.h" namespace litehtml { class el_link : public html_tag { public: explicit el_link(const std::shared_ptr& doc); protected: void parse_attributes() override; }; } #endif // LH_EL_LINK_H litehtml-0.6/include/litehtml/el_para.h000066400000000000000000000004151422312550200202160ustar00rootroot00000000000000#ifndef LH_EL_PARA_H #define LH_EL_PARA_H #include "html_tag.h" namespace litehtml { class el_para : public html_tag { public: explicit el_para(const std::shared_ptr& doc); void parse_attributes() override; }; } #endif // LH_EL_PARA_H litehtml-0.6/include/litehtml/el_script.h000066400000000000000000000006021422312550200205750ustar00rootroot00000000000000#ifndef LH_EL_SCRIPT_H #define LH_EL_SCRIPT_H #include "html_tag.h" namespace litehtml { class el_script : public element { tstring m_text; public: explicit el_script(const std::shared_ptr& doc); void parse_attributes() override; bool appendChild(const ptr &el) override; const tchar_t* get_tagName() const override; }; } #endif // LH_EL_SCRIPT_H litehtml-0.6/include/litehtml/el_space.h000066400000000000000000000005771422312550200203770ustar00rootroot00000000000000#ifndef LH_EL_SPACE_H #define LH_EL_SPACE_H #include "html_tag.h" #include "el_text.h" namespace litehtml { class el_space : public el_text { public: el_space(const tchar_t* text, const std::shared_ptr& doc); bool is_white_space() const override; bool is_break() const override; bool is_space() const override; }; } #endif // LH_EL_SPACE_H litehtml-0.6/include/litehtml/el_style.h000066400000000000000000000006161422312550200204360ustar00rootroot00000000000000#ifndef LH_EL_STYLE_H #define LH_EL_STYLE_H #include "html_tag.h" namespace litehtml { class el_style : public element { elements_vector m_children; public: explicit el_style(const std::shared_ptr& doc); void parse_attributes() override; bool appendChild(const ptr &el) override; const tchar_t* get_tagName() const override; }; } #endif // LH_EL_STYLE_H litehtml-0.6/include/litehtml/el_table.h000066400000000000000000000006771422312550200203740ustar00rootroot00000000000000#ifndef LH_EL_TABLE_H #define LH_EL_TABLE_H #include "html_tag.h" namespace litehtml { struct col_info { int width; bool is_auto; }; class el_table : public html_tag { public: explicit el_table(const std::shared_ptr& doc); bool appendChild(const litehtml::element::ptr& el) override; void parse_styles(bool is_reparse = false) override; void parse_attributes() override; }; } #endif // LH_EL_TABLE_H litehtml-0.6/include/litehtml/el_td.h000066400000000000000000000004021422312550200176760ustar00rootroot00000000000000#ifndef LH_EL_TD_H #define LH_EL_TD_H #include "html_tag.h" namespace litehtml { class el_td : public html_tag { public: explicit el_td(const std::shared_ptr& doc); void parse_attributes() override; }; } #endif // LH_EL_TD_H litehtml-0.6/include/litehtml/el_text.h000066400000000000000000000021721422312550200202610ustar00rootroot00000000000000#ifndef LH_EL_TEXT_H #define LH_EL_TEXT_H #include "html_tag.h" namespace litehtml { class el_text : public element { protected: tstring m_text; tstring m_transformed_text; size m_size; text_transform m_text_transform; bool m_use_transformed; bool m_draw_spaces; public: el_text(const tchar_t* text, const std::shared_ptr& doc); void get_text(tstring& text) override; const tchar_t* get_style_property(const tchar_t* name, bool inherited, const tchar_t* def = nullptr) const override; void parse_styles(bool is_reparse) override; int get_base_line() override; void draw(uint_ptr hdc, int x, int y, const position* clip) override; int line_height() const override; uint_ptr get_font(font_metrics* fm = nullptr) override; style_display get_display() const override; white_space get_white_space() const override; element_position get_element_position(css_offsets* offsets = nullptr) const override; css_offsets get_css_offsets() const override; protected: void get_content_size(size& sz, int max_width) override; }; } #endif // LH_EL_TEXT_H litehtml-0.6/include/litehtml/el_title.h000066400000000000000000000004351422312550200204160ustar00rootroot00000000000000#ifndef LH_EL_TITLE_H #define LH_EL_TITLE_H #include "html_tag.h" namespace litehtml { class el_title : public html_tag { public: explicit el_title(const std::shared_ptr& doc); protected: void parse_attributes() override; }; } #endif // LH_EL_TITLE_H litehtml-0.6/include/litehtml/el_tr.h000066400000000000000000000004751422312550200177260ustar00rootroot00000000000000#ifndef LH_EL_TR_H #define LH_EL_TR_H #include "html_tag.h" namespace litehtml { class el_tr : public html_tag { public: explicit el_tr(const std::shared_ptr& doc); void parse_attributes() override; void get_inline_boxes(position::vector& boxes) override; }; } #endif // LH_EL_TR_H litehtml-0.6/include/litehtml/element.h000066400000000000000000000321041422312550200202440ustar00rootroot00000000000000#ifndef LH_ELEMENT_H #define LH_ELEMENT_H #include #include "stylesheet.h" #include "css_offsets.h" namespace litehtml { class box; class element : public std::enable_shared_from_this { friend class block_box; friend class line_box; friend class html_tag; friend class el_table; friend class document; public: typedef std::shared_ptr ptr; typedef std::shared_ptr const_ptr; typedef std::weak_ptr weak_ptr; protected: std::weak_ptr m_parent; std::weak_ptr m_doc; litehtml::box* m_box; elements_vector m_children; position m_pos; margins m_margins; margins m_padding; margins m_borders; bool m_skip; virtual void select_all(const css_selector& selector, elements_vector& res); public: explicit element(const std::shared_ptr& doc); virtual ~element() = default; // returns refer to m_pos member; position& get_position(); int left() const; int right() const; int top() const; int bottom() const; int height() const; int width() const; int content_margins_top() const; int content_margins_bottom() const; int content_margins_left() const; int content_margins_right() const; int content_margins_width() const; int content_margins_height() const; int margin_top() const; int margin_bottom() const; int margin_left() const; int margin_right() const; margins get_margins() const; int padding_top() const; int padding_bottom() const; int padding_left() const; int padding_right() const; margins get_paddings() const; int border_top() const; int border_bottom() const; int border_left() const; int border_right() const; margins get_borders() const; bool in_normal_flow() const; litehtml::web_color get_color(const tchar_t* prop_name, bool inherited, const litehtml::web_color& def_color = litehtml::web_color()); bool is_inline_box() const; position get_placement() const; bool collapse_top_margin() const; bool collapse_bottom_margin() const; bool is_positioned() const; bool skip() const; void skip(bool val); bool have_parent() const; element::ptr parent() const; void parent(const element::ptr& par); bool is_visible() const; int calc_width(int defVal) const; int get_inline_shift_left(); int get_inline_shift_right(); void apply_relative_shift(int parent_width); // returns true for elements inside a table (but outside cells) that don't participate in table rendering bool is_table_skip() const; std::shared_ptr get_document() const; virtual elements_vector select_all(const tstring& selector); virtual elements_vector select_all(const css_selector& selector); virtual element::ptr select_one(const tstring& selector); virtual element::ptr select_one(const css_selector& selector); virtual int render(int x, int y, int max_width, bool second_pass = false); virtual int render_inline(const ptr &container, int max_width); virtual int place_element(const ptr &el, int max_width); virtual void calc_outlines( int parent_width ); virtual void calc_auto_margins(int parent_width); virtual void apply_vertical_align(); virtual bool fetch_positioned(); virtual void render_positioned(render_type rt = render_all); virtual bool appendChild(const ptr &el); virtual bool removeChild(const ptr &el); virtual void clearRecursive(); virtual const tchar_t* get_tagName() const; virtual void set_tagName(const tchar_t* tag); virtual void set_data(const tchar_t* data); virtual element_float get_float() const; virtual vertical_align get_vertical_align() const; virtual element_clear get_clear() const; virtual size_t get_children_count() const; virtual element::ptr get_child(int idx) const; virtual overflow get_overflow() const; virtual css_length get_css_left() const; virtual css_length get_css_right() const; virtual css_length get_css_top() const; virtual css_length get_css_bottom() const; virtual css_offsets get_css_offsets() const; virtual css_length get_css_width() const; virtual void set_css_width(css_length& w); virtual css_length get_css_height() const; virtual void set_attr(const tchar_t* name, const tchar_t* val); virtual const tchar_t* get_attr(const tchar_t* name, const tchar_t* def = nullptr) const; virtual void apply_stylesheet(const litehtml::css& stylesheet); virtual void refresh_styles(); virtual bool is_white_space() const; virtual bool is_space() const; virtual bool is_comment() const; virtual bool is_body() const; virtual bool is_break() const; virtual int get_base_line(); virtual bool on_mouse_over(); virtual bool on_mouse_leave(); virtual bool on_lbutton_down(); virtual bool on_lbutton_up(); virtual void on_click(); virtual bool find_styles_changes(position::vector& redraw_boxes, int x, int y); virtual const tchar_t* get_cursor(); virtual void init_font(); virtual bool is_point_inside(int x, int y); virtual bool set_pseudo_class(const tchar_t* pclass, bool add); virtual bool set_class(const tchar_t* pclass, bool add); virtual bool is_replaced() const; virtual int line_height() const; virtual white_space get_white_space() const; virtual style_display get_display() const; virtual visibility get_visibility() const; virtual element_position get_element_position(css_offsets* offsets = nullptr) const; virtual void get_inline_boxes(position::vector& boxes); virtual void parse_styles(bool is_reparse = false); virtual void draw(uint_ptr hdc, int x, int y, const position* clip); virtual void draw_background( uint_ptr hdc, int x, int y, const position* clip ); virtual const tchar_t* get_style_property(const tchar_t* name, bool inherited, const tchar_t* def = nullptr) const; virtual uint_ptr get_font(font_metrics* fm = nullptr); virtual int get_font_size() const; virtual void get_text(tstring& text); virtual void parse_attributes(); virtual int select(const css_selector& selector, bool apply_pseudo = true); virtual int select(const css_element_selector& selector, bool apply_pseudo = true); virtual element::ptr find_ancestor(const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr); virtual bool is_ancestor(const ptr &el) const; virtual element::ptr find_adjacent_sibling(const element::ptr& el, const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr); virtual element::ptr find_sibling(const element::ptr& el, const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr); virtual bool is_first_child_inline(const element::ptr& el) const; virtual bool is_last_child_inline(const element::ptr& el); virtual bool have_inline_child() const; virtual void get_content_size(size& sz, int max_width); virtual void init(); virtual bool is_floats_holder() const; virtual int get_floats_height(element_float el_float = float_none) const; virtual int get_left_floats_height() const; virtual int get_right_floats_height() const; virtual int get_line_left(int y); virtual int get_line_right(int y, int def_right); virtual void get_line_left_right(int y, int def_right, int& ln_left, int& ln_right); virtual void add_float(const ptr &el, int x, int y); virtual void update_floats(int dy, const ptr &parent); virtual void add_positioned(const ptr &el); virtual int find_next_line_top(int top, int width, int def_right); virtual int get_zindex() const; virtual void draw_stacking_context(uint_ptr hdc, int x, int y, const position* clip, bool with_positioned); virtual void draw_children( uint_ptr hdc, int x, int y, const position* clip, draw_flag flag, int zindex ); virtual bool is_nth_child(const element::ptr& el, int num, int off, bool of_type) const; virtual bool is_nth_last_child(const element::ptr& el, int num, int off, bool of_type) const; virtual bool is_only_child(const element::ptr& el, bool of_type) const; virtual bool get_predefined_height(int& p_height) const; virtual void calc_document_size(litehtml::size& sz, int x = 0, int y = 0); virtual void get_redraw_box(litehtml::position& pos, int x = 0, int y = 0); virtual void add_style(const tstring& style, const tstring& baseurl); virtual element::ptr get_element_by_point(int x, int y, int client_x, int client_y); virtual element::ptr get_child_by_point(int x, int y, int client_x, int client_y, draw_flag flag, int zindex); virtual const background* get_background(bool own_only = false); }; ////////////////////////////////////////////////////////////////////////// // INLINE FUNCTIONS // ////////////////////////////////////////////////////////////////////////// inline int litehtml::element::right() const { return left() + width(); } inline int litehtml::element::left() const { return m_pos.left() - margin_left() - m_padding.left - m_borders.left; } inline int litehtml::element::top() const { return m_pos.top() - margin_top() - m_padding.top - m_borders.top; } inline int litehtml::element::bottom() const { return top() + height(); } inline int litehtml::element::height() const { return m_pos.height + margin_top() + margin_bottom() + m_padding.height() + m_borders.height(); } inline int litehtml::element::width() const { return m_pos.width + margin_left() + margin_right() + m_padding.width() + m_borders.width(); } inline int litehtml::element::content_margins_top() const { return margin_top() + m_padding.top + m_borders.top; } inline int litehtml::element::content_margins_bottom() const { return margin_bottom() + m_padding.bottom + m_borders.bottom; } inline int litehtml::element::content_margins_left() const { return margin_left() + m_padding.left + m_borders.left; } inline int litehtml::element::content_margins_right() const { return margin_right() + m_padding.right + m_borders.right; } inline int litehtml::element::content_margins_width() const { return content_margins_left() + content_margins_right(); } inline int litehtml::element::content_margins_height() const { return content_margins_top() + content_margins_bottom(); } inline litehtml::margins litehtml::element::get_paddings() const { return m_padding; } inline litehtml::margins litehtml::element::get_borders() const { return m_borders; } inline int litehtml::element::padding_top() const { return m_padding.top; } inline int litehtml::element::padding_bottom() const { return m_padding.bottom; } inline int litehtml::element::padding_left() const { return m_padding.left; } inline int litehtml::element::padding_right() const { return m_padding.right; } inline bool litehtml::element::in_normal_flow() const { if(get_element_position() != element_position_absolute && get_display() != display_none) { return true; } return false; } inline int litehtml::element::border_top() const { return m_borders.top; } inline int litehtml::element::border_bottom() const { return m_borders.bottom; } inline int litehtml::element::border_left() const { return m_borders.left; } inline int litehtml::element::border_right() const { return m_borders.right; } inline bool litehtml::element::skip() const { return m_skip; } inline void litehtml::element::skip(bool val) { m_skip = val; } inline bool litehtml::element::have_parent() const { return !m_parent.expired(); } inline element::ptr litehtml::element::parent() const { return m_parent.lock(); } inline void litehtml::element::parent(const element::ptr& par) { m_parent = par; } inline int litehtml::element::margin_top() const { return m_margins.top; } inline int litehtml::element::margin_bottom() const { return m_margins.bottom; } inline int litehtml::element::margin_left() const { return m_margins.left; } inline int litehtml::element::margin_right() const { return m_margins.right; } inline litehtml::margins litehtml::element::get_margins() const { margins ret; ret.left = margin_left(); ret.right = margin_right(); ret.top = margin_top(); ret.bottom = margin_bottom(); return ret; } inline bool litehtml::element::is_positioned() const { return (get_element_position() > element_position_static); } inline bool litehtml::element::is_visible() const { return !(m_skip || get_display() == display_none || get_visibility() != visibility_visible); } inline position& litehtml::element::get_position() { return m_pos; } inline std::shared_ptr element::get_document() const { return m_doc.lock(); } } #endif // LH_ELEMENT_H litehtml-0.6/include/litehtml/html.h000066400000000000000000000112671422312550200175660ustar00rootroot00000000000000#ifndef LH_HTML_H #define LH_HTML_H #include #include #include #include #include #include #include #include #include #include "os_types.h" #include "types.h" #include "background.h" #include "borders.h" #include "html_tag.h" #include "web_color.h" #include "media_query.h" namespace litehtml { struct list_marker { tstring image; const tchar_t* baseurl; list_style_type marker_type; web_color color; position pos; int index; uint_ptr font; }; // call back interface to draw text, images and other elements class document_container { public: virtual litehtml::uint_ptr create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) = 0; virtual void delete_font(litehtml::uint_ptr hFont) = 0; virtual int text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) = 0; virtual void draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) = 0; virtual int pt_to_px(int pt) const = 0; virtual int get_default_font_size() const = 0; virtual const litehtml::tchar_t* get_default_font_name() const = 0; virtual void draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) = 0; virtual void load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) = 0; virtual void get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) = 0; virtual void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) = 0; virtual void draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) = 0; virtual void set_caption(const litehtml::tchar_t* caption) = 0; virtual void set_base_url(const litehtml::tchar_t* base_url) = 0; virtual void link(const std::shared_ptr& doc, const litehtml::element::ptr& el) = 0; virtual void on_anchor_click(const litehtml::tchar_t* url, const litehtml::element::ptr& el) = 0; virtual void set_cursor(const litehtml::tchar_t* cursor) = 0; virtual void transform_text(litehtml::tstring& text, litehtml::text_transform tt) = 0; virtual void import_css(litehtml::tstring& text, const litehtml::tstring& url, litehtml::tstring& baseurl) = 0; virtual void set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) = 0; virtual void del_clip() = 0; virtual void get_client_rect(litehtml::position& client) const = 0; virtual std::shared_ptr create_element(const litehtml::tchar_t *tag_name, const litehtml::string_map &attributes, const std::shared_ptr &doc) = 0; virtual void get_media_features(litehtml::media_features& media) const = 0; virtual void get_language(litehtml::tstring& language, litehtml::tstring & culture) const = 0; virtual litehtml::tstring resolve_color(const litehtml::tstring& /*color*/) const { return litehtml::tstring(); } virtual void split_text(const char* text, const std::function& on_word, const std::function& on_space); protected: ~document_container() = default; }; void trim(tstring &s); void lcase(tstring &s); int value_index(const tstring& val, const tstring& strings, int defValue = -1, tchar_t delim = _t(';')); bool value_in_list(const tstring& val, const tstring& strings, tchar_t delim = _t(';')); tstring::size_type find_close_bracket(const tstring &s, tstring::size_type off, tchar_t open_b = _t('('), tchar_t close_b = _t(')')); void split_string(const tstring& str, string_vector& tokens, const tstring& delims, const tstring& delims_preserve = _t(""), const tstring& quote = _t("\"")); void join_string(tstring& str, const string_vector& tokens, const tstring& delims); double t_strtod(const tchar_t* string, tchar_t** endPtr); int t_strcasecmp(const tchar_t *s1, const tchar_t *s2); int t_strncasecmp(const tchar_t *s1, const tchar_t *s2, size_t n); inline int t_isdigit(int c) { return (c >= '0' && c <= '9'); } inline int t_tolower(int c) { return (c >= 'A' && c <= 'Z' ? c + 'a' - 'A' : c); } inline int round_f(float val) { int int_val = (int) val; if(val - int_val >= 0.5) { int_val++; } return int_val; } inline int round_d(double val) { int int_val = (int) val; if(val - int_val >= 0.5) { int_val++; } return int_val; } } #endif // LH_HTML_H litehtml-0.6/include/litehtml/html_tag.h000066400000000000000000000235371422312550200204240ustar00rootroot00000000000000#ifndef LH_HTML_TAG_H #define LH_HTML_TAG_H #include "element.h" #include "style.h" #include "background.h" #include "css_margins.h" #include "borders.h" #include "css_selector.h" #include "stylesheet.h" #include "box.h" #include "table.h" namespace litehtml { struct line_context { int calculatedTop; int top; int left; int right; int width() const { return right - left; } void fix_top() { calculatedTop = top; } }; class html_tag : public element { friend class elements_iterator; friend class el_table; friend class table_grid; friend class block_box; friend class line_box; public: typedef std::shared_ptr ptr; protected: box::vector m_boxes; string_vector m_class_values; tstring m_tag; litehtml::style m_style; string_map m_attrs; vertical_align m_vertical_align; text_align m_text_align; style_display m_display; list_style_type m_list_style_type; list_style_position m_list_style_position; white_space m_white_space; element_float m_float; element_clear m_clear; floated_box::vector m_floats_left; floated_box::vector m_floats_right; elements_vector m_positioned; background m_bg; element_position m_el_position; int m_line_height; bool m_lh_predefined; string_vector m_pseudo_classes; used_selector::vector m_used_styles; uint_ptr m_font; int m_font_size; font_metrics m_font_metrics; css_margins m_css_margins; css_margins m_css_padding; css_borders m_css_borders; css_length m_css_width; css_length m_css_height; css_length m_css_min_width; css_length m_css_min_height; css_length m_css_max_width; css_length m_css_max_height; css_offsets m_css_offsets; css_length m_css_text_indent; overflow m_overflow; visibility m_visibility; int m_z_index; box_sizing m_box_sizing; int_int_cache m_cache_line_left; int_int_cache m_cache_line_right; // data for table rendering std::unique_ptr m_grid; css_length m_css_border_spacing_x; css_length m_css_border_spacing_y; int m_border_spacing_x; int m_border_spacing_y; border_collapse m_border_collapse; void select_all(const css_selector& selector, elements_vector& res) override; public: explicit html_tag(const std::shared_ptr& doc); /* render functions */ int render(int x, int y, int max_width, bool second_pass = false) override; int render_inline(const element::ptr &container, int max_width) override; int place_element(const element::ptr &el, int max_width) override; bool fetch_positioned() override; void render_positioned(render_type rt = render_all) override; int new_box(const element::ptr &el, int max_width, line_context& line_ctx); int get_cleared_top(const element::ptr &el, int line_top) const; int finish_last_box(bool end_of_render = false); bool appendChild(const element::ptr &el) override; bool removeChild(const element::ptr &el) override; void clearRecursive() override; const tchar_t* get_tagName() const override; void set_tagName(const tchar_t* tag) override; void set_data(const tchar_t* data) override; element_float get_float() const override; vertical_align get_vertical_align() const override; css_length get_css_left() const override; css_length get_css_right() const override; css_length get_css_top() const override; css_length get_css_bottom() const override; css_length get_css_width() const override; css_offsets get_css_offsets() const override; void set_css_width(css_length& w) override; css_length get_css_height() const override; element_clear get_clear() const override; size_t get_children_count() const override; element::ptr get_child(int idx) const override; element_position get_element_position(css_offsets* offsets = nullptr) const override; overflow get_overflow() const override; void set_attr(const tchar_t* name, const tchar_t* val) override; const tchar_t* get_attr(const tchar_t* name, const tchar_t* def = nullptr) const override; void apply_stylesheet(const litehtml::css& stylesheet) override; void refresh_styles() override; bool is_white_space() const override; bool is_body() const override; bool is_break() const override; int get_base_line() override; bool on_mouse_over() override; bool on_mouse_leave() override; bool on_lbutton_down() override; bool on_lbutton_up() override; void on_click() override; bool find_styles_changes(position::vector& redraw_boxes, int x, int y) override; const tchar_t* get_cursor() override; void init_font() override; bool set_pseudo_class(const tchar_t* pclass, bool add) override; bool set_class(const tchar_t* pclass, bool add) override; bool is_replaced() const override; int line_height() const override; white_space get_white_space() const override; style_display get_display() const override; visibility get_visibility() const override; void parse_styles(bool is_reparse = false) override; void draw(uint_ptr hdc, int x, int y, const position* clip) override; void draw_background(uint_ptr hdc, int x, int y, const position* clip) override; const tchar_t* get_style_property(const tchar_t* name, bool inherited, const tchar_t* def = nullptr) const override; uint_ptr get_font(font_metrics* fm = nullptr) override; int get_font_size() const override; elements_vector& children(); void calc_outlines(int parent_width) override; void calc_auto_margins(int parent_width) override; int select(const css_selector& selector, bool apply_pseudo = true) override; int select(const css_element_selector& selector, bool apply_pseudo = true) override; elements_vector select_all(const tstring& selector) override; elements_vector select_all(const css_selector& selector) override; element::ptr select_one(const tstring& selector) override; element::ptr select_one(const css_selector& selector) override; element::ptr find_ancestor(const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr) override; element::ptr find_adjacent_sibling(const element::ptr& el, const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr) override; element::ptr find_sibling(const element::ptr& el, const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr) override; void get_text(tstring& text) override; void parse_attributes() override; bool is_first_child_inline(const element::ptr& el) const override; bool is_last_child_inline(const element::ptr& el) override; bool have_inline_child() const override; void get_content_size(size& sz, int max_width) override; void init() override; void get_inline_boxes(position::vector& boxes) override; bool is_floats_holder() const override; int get_floats_height(element_float el_float = float_none) const override; int get_left_floats_height() const override; int get_right_floats_height() const override; int get_line_left(int y) override; int get_line_right(int y, int def_right) override; void get_line_left_right(int y, int def_right, int& ln_left, int& ln_right) override; void add_float(const element::ptr &el, int x, int y) override; void update_floats(int dy, const element::ptr &parent) override; void add_positioned(const element::ptr &el) override; int find_next_line_top(int top, int width, int def_right) override; void apply_vertical_align() override; void draw_children(uint_ptr hdc, int x, int y, const position* clip, draw_flag flag, int zindex) override; int get_zindex() const override; void draw_stacking_context(uint_ptr hdc, int x, int y, const position* clip, bool with_positioned) override; void calc_document_size(litehtml::size& sz, int x = 0, int y = 0) override; void get_redraw_box(litehtml::position& pos, int x = 0, int y = 0) override; void add_style(const tstring& style, const tstring& baseurl) override; element::ptr get_element_by_point(int x, int y, int client_x, int client_y) override; element::ptr get_child_by_point(int x, int y, int client_x, int client_y, draw_flag flag, int zindex) override; bool is_nth_child(const element::ptr& el, int num, int off, bool of_type) const override; bool is_nth_last_child(const element::ptr& el, int num, int off, bool of_type) const override; bool is_only_child(const element::ptr& el, bool of_type) const override; const background* get_background(bool own_only = false) override; protected: void draw_children_box(uint_ptr hdc, int x, int y, const position* clip, draw_flag flag, int zindex); void draw_children_table(uint_ptr hdc, int x, int y, const position* clip, draw_flag flag, int zindex); int render_box(int x, int y, int max_width, bool second_pass = false); int render_table(int x, int y, int max_width, bool second_pass = false); int fix_line_width(int max_width, element_float flt); void parse_background(); void init_background_paint( position pos, background_paint &bg_paint, const background* bg ); void draw_list_marker( uint_ptr hdc, const position &pos ); tstring get_list_marker_text(int index); static void parse_nth_child_params( const tstring& param, int &num, int &off ); void remove_before_after(); litehtml::element::ptr get_element_before(); litehtml::element::ptr get_element_after(); }; /************************************************************************/ /* Inline Functions */ /************************************************************************/ inline elements_vector& litehtml::html_tag::children() { return m_children; } } #endif // LH_HTML_TAG_H litehtml-0.6/include/litehtml/iterators.h000066400000000000000000000030231422312550200206250ustar00rootroot00000000000000#ifndef LH_ITERATORS_H #define LH_ITERATORS_H #include "types.h" namespace litehtml { class element; class iterator_selector { public: virtual bool select(const element::ptr& el) = 0; protected: ~iterator_selector() = default; }; class elements_iterator { private: struct stack_item { int idx; element::ptr el; stack_item() : idx(0) { } stack_item(const stack_item& val) { idx = val.idx; el = val.el; } stack_item(stack_item&& val) { idx = val.idx; el = std::move(val.el); } }; std::vector m_stack; element::ptr m_el; int m_idx; iterator_selector* m_go_inside; iterator_selector* m_select; public: elements_iterator(const element::ptr& el, iterator_selector* go_inside, iterator_selector* select) { m_el = el; m_idx = -1; m_go_inside = go_inside; m_select = select; } ~elements_iterator() = default; element::ptr next(bool ret_parent = true); private: void next_idx(); }; class go_inside_inline final : public iterator_selector { public: bool select(const element::ptr& el) override; }; class go_inside_table final : public iterator_selector { public: bool select(const element::ptr& el) override; }; class table_rows_selector final : public iterator_selector { public: bool select(const element::ptr& el) override; }; class table_cells_selector final : public iterator_selector { public: bool select(const element::ptr& el) override; }; } #endif // LH_ITERATORS_H litehtml-0.6/include/litehtml/media_query.h000066400000000000000000000032731422312550200211240ustar00rootroot00000000000000#ifndef LH_MEDIA_QUERY_H #define LH_MEDIA_QUERY_H namespace litehtml { struct media_query_expression { typedef std::vector vector; media_feature feature; int val; int val2; bool check_as_bool; media_query_expression() { check_as_bool = false; feature = media_feature_none; val = 0; val2 = 0; } bool check(const media_features& features) const; }; class media_query { public: typedef std::shared_ptr ptr; typedef std::vector vector; private: media_query_expression::vector m_expressions; bool m_not; media_type m_media_type; public: media_query(); media_query(const media_query& val); static media_query::ptr create_from_string(const tstring& str, const std::shared_ptr& doc); bool check(const media_features& features) const; }; class media_query_list { public: typedef std::shared_ptr ptr; typedef std::vector vector; private: media_query::vector m_queries; bool m_is_used; public: media_query_list(); media_query_list(const media_query_list& val); static media_query_list::ptr create_from_string(const tstring& str, const std::shared_ptr& doc); bool is_used() const; bool apply_media_features(const media_features& features); // returns true if the m_is_used changed }; inline media_query_list::media_query_list(const media_query_list& val) { m_is_used = val.m_is_used; m_queries = val.m_queries; } inline media_query_list::media_query_list() { m_is_used = false; } inline bool media_query_list::is_used() const { return m_is_used; } } #endif // LH_MEDIA_QUERY_H litehtml-0.6/include/litehtml/num_cvt.h000066400000000000000000000005671422312550200202760ustar00rootroot00000000000000#ifndef NUM_CVT_H #define NUM_CVT_H #include #include "os_types.h" namespace litehtml { namespace num_cvt { litehtml::tstring to_latin_lower(int val); litehtml::tstring to_latin_upper(int val); litehtml::tstring to_greek_lower(int val); litehtml::tstring to_roman_lower(int value); litehtml::tstring to_roman_upper(int value); } } #endif // NUM_CVT_Hlitehtml-0.6/include/litehtml/os_types.h000066400000000000000000000035141422312550200204630ustar00rootroot00000000000000#ifndef LH_OS_TYPES_H #define LH_OS_TYPES_H #include #include namespace litehtml { #if defined( WIN32 ) || defined( _WIN32 ) || defined( WINCE ) // noexcept appeared since Visual Studio 2013 #if defined(_MSC_VER) && _MSC_VER < 1900 #define noexcept #endif #ifndef LITEHTML_UTF8 typedef std::wstring tstring; typedef wchar_t tchar_t; typedef std::wstringstream tstringstream; #define _t(quote) L##quote #define t_strlen wcslen #define t_strcmp wcscmp #define t_strncmp wcsncmp #define t_strtol wcstol #define t_atoi _wtoi #define t_itoa(value, buffer, size, radix) _itow_s(value, buffer, size, radix) #define t_strstr wcsstr #define t_isspace iswspace #define t_to_string(val) std::to_wstring(val) #else typedef std::string tstring; typedef char tchar_t; typedef std::stringstream tstringstream; #define _t(quote) quote #define t_strlen strlen #define t_strcmp strcmp #define t_strncmp strncmp #define t_strtol strtol #define t_atoi atoi #define t_itoa(value, buffer, size, radix) _itoa_s(value, buffer, size, radix) #define t_strstr strstr #define t_isspace isspace #define t_to_string(val) std::to_string(val) #endif #ifdef _WIN64 typedef unsigned __int64 uint_ptr; #else typedef unsigned int uint_ptr; #endif #else #define LITEHTML_UTF8 typedef std::string tstring; typedef char tchar_t; typedef std::uintptr_t uint_ptr; typedef std::stringstream tstringstream; #define _t(quote) quote #define t_strlen strlen #define t_strcmp strcmp #define t_strncmp strncmp #define t_itoa(value, buffer, size, radix) snprintf(buffer, size, "%d", value) #define t_strtol strtol #define t_atoi atoi #define t_strstr strstr #define t_isspace isspace #define t_to_string(val) std::to_string(val) #endif } #endif // LH_OS_TYPES_H litehtml-0.6/include/litehtml/style.h000066400000000000000000000042131422312550200177530ustar00rootroot00000000000000#ifndef LH_STYLE_H #define LH_STYLE_H #include "attributes.h" #include namespace litehtml { class property_value { public: tstring m_value; bool m_important; property_value() { m_important = false; } property_value(const tchar_t* val, bool imp) { m_important = imp; m_value = val; } property_value(const property_value& val) { m_value = val.m_value; m_important = val.m_important; } property_value& operator=(const property_value& val) { m_value = val.m_value; m_important = val.m_important; return *this; } }; typedef std::map props_map; class style { public: typedef std::shared_ptr