diff options
Diffstat (limited to 'libs/litehtml/src/css_properties.cpp')
-rw-r--r-- | libs/litehtml/src/css_properties.cpp | 126 |
1 files changed, 105 insertions, 21 deletions
diff --git a/libs/litehtml/src/css_properties.cpp b/libs/litehtml/src/css_properties.cpp index 9100a998e0..6014babb3b 100644 --- a/libs/litehtml/src/css_properties.cpp +++ b/libs/litehtml/src/css_properties.cpp @@ -1,13 +1,15 @@ #include "html.h" #include "css_properties.h" #include <cmath> +#include "document.h" +#include "html_tag.h" +#include "document_container.h" #define offset(member) ((uint_ptr)&this->member - (uint_ptr)this) +//#define offset(func) [](const css_properties& css) { return css.func; } void litehtml::css_properties::compute(const html_tag* el, const document::ptr& doc) { - compute_font(el, doc); - int font_size = get_font_size(); m_color = el->get_property<web_color>(_color_, true, web_color::black, offset(m_color)); m_el_position = (element_position) el->get_property<int>( _position_, false, element_position_static, offset(m_el_position)); @@ -15,6 +17,7 @@ void litehtml::css_properties::compute(const html_tag* el, const document::ptr& m_visibility = (visibility) el->get_property<int>( _visibility_, true, visibility_visible, offset(m_visibility)); m_float = (element_float) el->get_property<int>( _float_, false, float_none, offset(m_float)); m_clear = (element_clear) el->get_property<int>( _clear_, false, clear_none, offset(m_clear)); + m_appearance = (appearance) el->get_property<int>( _appearance_, false, appearance_none, offset(m_appearance)); m_box_sizing = (box_sizing) el->get_property<int>( _box_sizing_, false, box_sizing_content_box, offset(m_box_sizing)); m_overflow = (overflow) el->get_property<int>( _overflow_, false, overflow_visible, offset(m_overflow)); m_text_align = (text_align) el->get_property<int>( _text_align_, true, text_align_left, offset(m_text_align)); @@ -97,10 +100,16 @@ void litehtml::css_properties::compute(const html_tag* el, const document::ptr& { m_display = display_block; } + } else if(el->is_replaced() && m_display == display_inline) + { + m_display = display_inline_block; } } // 5. Otherwise, the remaining 'display' property values apply as specified. + compute_font(el, doc); + int font_size = get_font_size(); + const css_length _auto = css_length::predef_value(0); const css_length none = _auto, normal = _auto; @@ -217,17 +226,17 @@ void litehtml::css_properties::compute(const html_tag* el, const document::ptr& m_css_text_indent = el->get_property<css_length>(_text_indent_, true, 0, offset(m_css_text_indent)); doc->cvt_units(m_css_text_indent, m_font_metrics, 0); - m_css_line_height = el->get_property<css_length>(_line_height_, true, normal, offset(m_css_line_height)); - if(m_css_line_height.is_predefined()) + m_line_height.css_value = el->get_property<css_length>(_line_height_, true, normal, offset(m_line_height.css_value)); + if(m_line_height.css_value.is_predefined()) { - m_line_height = m_font_metrics.height; - } else if(m_css_line_height.units() == css_units_none) + m_line_height.computed_value = m_font_metrics.height; + } else if(m_line_height.css_value.units() == css_units_none) { - m_line_height = (int) std::nearbyint(m_css_line_height.val() * font_size); + m_line_height.computed_value = (int) std::nearbyint(m_line_height.css_value.val() * font_size); } else { - m_line_height = doc->to_pixels(m_css_line_height, m_font_metrics, m_font_metrics.font_size); - m_css_line_height = (float) m_line_height; + m_line_height.computed_value = doc->to_pixels(m_line_height.css_value, m_font_metrics, m_font_metrics.font_size); + m_line_height.css_value = (float) m_line_height.computed_value; } m_list_style_type = (list_style_type) el->get_property<int>(_list_style_type_, true, list_style_type_disc, offset(m_list_style_type)); @@ -281,7 +290,7 @@ void litehtml::css_properties::compute_font(const html_tag* el, const document:: { parent_sz = doc_font_size; } - + int font_size = parent_sz; if(sz.is_predefined()) @@ -347,22 +356,96 @@ void litehtml::css_properties::compute_font(const html_tag* el, const document:: font_size = doc->to_pixels(sz, fm, 0); } } - + m_font_size = (float)font_size; // initialize font m_font_family = el->get_property<string>( _font_family_, true, doc->container()->get_default_font_name(), offset(m_font_family)); m_font_weight = el->get_property<css_length>(_font_weight_, true, css_length::predef_value(font_weight_normal), offset(m_font_weight)); m_font_style = (font_style) el->get_property<int>( _font_style_, true, font_style_normal, offset(m_font_style)); - m_text_decoration = el->get_property<string>( _text_decoration_, true, "none", offset(m_text_decoration)); - - m_font = doc->get_font( - m_font_family.c_str(), - font_size, - m_font_weight.is_predefined() ? index_value(m_font_weight.predef(), font_weight_strings).c_str() : std::to_string(m_font_weight.val()).c_str(), - index_value(m_font_style, font_style_strings).c_str(), - m_text_decoration.c_str(), - &m_font_metrics); + bool propagate_decoration = !is_one_of(m_display, display_inline_block, display_inline_table, display_inline_flex) && + m_float == float_none && !is_one_of(m_el_position, element_position_absolute, element_position_fixed); + + m_text_decoration_line = el->get_property<int>(_text_decoration_line_, propagate_decoration, text_decoration_line_none, offset(m_text_decoration_line)); + + // Merge parent text decoration with child text decoration + if (propagate_decoration && el->parent()) + { + m_text_decoration_line |= el->parent()->css().get_text_decoration_line(); + } + + if(m_text_decoration_line) + { + m_text_decoration_thickness = el->get_property<css_length>(_text_decoration_thickness_, propagate_decoration, css_length::predef_value(text_decoration_thickness_auto), offset(m_text_decoration_thickness)); + m_text_decoration_style = (text_decoration_style) el->get_property<int>(_text_decoration_style_, propagate_decoration, text_decoration_style_solid, offset(m_text_decoration_style)); + m_text_decoration_color = get_color_property(el, _text_decoration_color_, propagate_decoration, web_color::current_color, offset(m_text_decoration_color)); + } else + { + m_text_decoration_thickness = css_length::predef_value(text_decoration_thickness_auto); + m_text_decoration_color = web_color::current_color; + } + + // text-emphasis + m_text_emphasis_style = el->get_property<string>(_text_emphasis_style_, true, "", offset(m_text_emphasis_style)); + m_text_emphasis_position = el->get_property<int>(_text_emphasis_position_, true, text_emphasis_position_over, offset(m_text_emphasis_position)); + m_text_emphasis_color = get_color_property(el, _text_emphasis_color_, true, web_color::current_color, offset(m_text_emphasis_color)); + + if(el->parent()) + { + if(m_text_emphasis_style.empty() || m_text_emphasis_style == "initial" || m_text_emphasis_style == "unset") + { + m_text_emphasis_style = el->parent()->css().get_text_emphasis_style(); + } + if(m_text_emphasis_color == web_color::current_color) + { + m_text_emphasis_color = el->parent()->css().get_text_emphasis_color(); + } + m_text_emphasis_position |= el->parent()->css().get_text_emphasis_position(); + } + + if(m_font_weight.is_predefined()) + { + switch(m_font_weight.predef()) + { + case font_weight_bold: + m_font_weight = 700; + break; + case font_weight_bolder: + { + const int inherited = (int) el->parent()->css().m_font_weight.val(); + if(inherited < 400) m_font_weight = 400; + else if(inherited >= 400 && inherited < 600) m_font_weight = 700; + else m_font_weight = 900; + } + break; + case font_weight_lighter: + { + const int inherited = (int) el->parent()->css().m_font_weight.val(); + if(inherited < 600) m_font_weight = 100; + else if(inherited >= 600 && inherited < 800) m_font_weight = 400; + else m_font_weight = 700; + } + break; + default: + m_font_weight = 400; + break; + } + } + + font_description descr; + descr.family = m_font_family; + descr.size = font_size; + descr.style = m_font_style; + descr.weight = (int) m_font_weight.val(); + descr.decoration_line = m_text_decoration_line; + descr.decoration_thickness = m_text_decoration_thickness; + descr.decoration_style = m_text_decoration_style; + descr.decoration_color = m_text_decoration_color; + descr.emphasis_style = m_text_emphasis_style; + descr.emphasis_color = m_text_emphasis_color; + descr.emphasis_position = m_text_emphasis_position; + + m_font = doc->get_font(descr, &m_font_metrics); } void litehtml::css_properties::compute_background(const html_tag* el, const document::ptr& doc) @@ -462,6 +545,7 @@ std::vector<std::tuple<litehtml::string, litehtml::string>> litehtml::css_proper ret.emplace_back("overflow", index_value(m_overflow, overflow_strings)); ret.emplace_back("white_space", index_value(m_white_space, white_space_strings)); ret.emplace_back("visibility", index_value(m_visibility, visibility_strings)); + ret.emplace_back("appearance", index_value(m_appearance, appearance_strings)); ret.emplace_back("box_sizing", index_value(m_box_sizing, box_sizing_strings)); ret.emplace_back("z_index", m_z_index.to_string()); ret.emplace_back("vertical_align", index_value(m_vertical_align, vertical_align_strings)); @@ -478,7 +562,7 @@ std::vector<std::tuple<litehtml::string, litehtml::string>> litehtml::css_proper ret.emplace_back("max_height", m_css_max_width.to_string()); ret.emplace_back("offsets", m_css_offsets.to_string()); ret.emplace_back("text_indent", m_css_text_indent.to_string()); - ret.emplace_back("line_height", std::to_string(m_line_height)); + ret.emplace_back("line_height", std::to_string(m_line_height.computed_value)); ret.emplace_back("list_style_type", index_value(m_list_style_type, list_style_type_strings)); ret.emplace_back("list_style_position", index_value(m_list_style_position, list_style_position_strings)); ret.emplace_back("border_spacing_x", m_css_border_spacing_x.to_string()); |