diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/css_properties.cpp | 5 | ||||
-rw-r--r-- | src/render_block.cpp | 21 | ||||
-rw-r--r-- | src/render_block_context.cpp | 5 | ||||
-rw-r--r-- | src/render_flex.cpp | 44 | ||||
-rw-r--r-- | src/render_image.cpp | 17 | ||||
-rw-r--r-- | src/render_item.cpp | 51 | ||||
-rw-r--r-- | src/render_table.cpp | 8 |
7 files changed, 118 insertions, 33 deletions
diff --git a/src/css_properties.cpp b/src/css_properties.cpp index 1dc16dab..9df08e35 100644 --- a/src/css_properties.cpp +++ b/src/css_properties.cpp @@ -409,6 +409,11 @@ void litehtml::css_properties::compute_flex(const element* el, const document::p m_flex_shrink = el->get_number_property(_flex_shrink_, false, 1, offset(m_flex_shrink)); m_flex_align_self = (flex_align_items) el->get_enum_property(_align_self_, false, flex_align_items_auto, offset(m_flex_align_self)); m_flex_basis = el->get_length_property(_flex_basis_, false, css_length::predef_value(flex_basis_auto), offset(m_flex_basis)); + if(!m_flex_basis.is_predefined() && m_flex_basis.units() == css_units_none) + { + // flex-basis property must contain units + m_flex_basis.predef(flex_basis_auto); + } doc->cvt_units(m_flex_basis, get_font_size()); if(m_display == display_inline || m_display == display_inline_block) { diff --git a/src/render_block.cpp b/src/render_block.cpp index d653f311..4eb8462b 100644 --- a/src/render_block.cpp +++ b/src/render_block.cpp @@ -208,15 +208,24 @@ int litehtml::render_item_block::_render(int x, int y, const containing_block_co bool requires_rerender = false; // when true, the second pass for content rendering is required // Set block width - if(self_size.width.type == containing_block_context::cbc_value_type_absolute) + if(!self_size.width_is_flex_basis) { - ret_width = m_pos.width = self_size.render_width; - } else if(self_size.width.type == containing_block_context::cbc_value_type_percentage) - { - m_pos.width = self_size.render_width; + if(self_size.width.type == containing_block_context::cbc_value_type_absolute) + { + ret_width = m_pos.width = self_size.render_width; + } else + { + m_pos.width = self_size.render_width; + } } else { - m_pos.width = self_size.render_width; + if(ret_width > self_size.render_width) + { + m_pos.width = ret_width; + } else + { + m_pos.width = self_size.render_width; + } } // Fix width with min-width attribute diff --git a/src/render_block_context.cpp b/src/render_block_context.cpp index df2f5057..c94bc566 100644 --- a/src/render_block_context.cpp +++ b/src/render_block_context.cpp @@ -110,10 +110,9 @@ int litehtml::render_item_block_context::_render_content(int x, int y, bool seco } } - int block_height = 0; - if (get_predefined_height(block_height, self_size.height)) + if (self_size.height.type != containing_block_context::cbc_value_type_auto && self_size.height > 0) { - m_pos.height = block_height; + m_pos.height = self_size.height; } else { m_pos.height = child_top; diff --git a/src/render_flex.cpp b/src/render_flex.cpp index d97dc62f..7614d240 100644 --- a/src/render_flex.cpp +++ b/src/render_flex.cpp @@ -263,7 +263,7 @@ int litehtml::render_item_flex::_render_content(int x, int y, bool second_pass, item.el->render(el_x, el_y, - self_size.new_width(item.main_size), fmt_ctx, false); + self_size.new_width(item.main_size - item.el->content_offset_width(), containing_block_context::cbc_size_mode_exact_width), fmt_ctx, false); ln.cross_size = std::max(ln.cross_size, item.el->height()); el_x += item.el->width(); } @@ -280,7 +280,11 @@ int litehtml::render_item_flex::_render_content(int x, int y, bool second_pass, self_size, fmt_ctx, false); item.el->render(el_x, el_y, - self_size.new_width(el_ret_width), fmt_ctx, false); + self_size.new_width_height(el_ret_width - item.el->content_offset_width(), + item.main_size - item.el->content_offset_height(), + containing_block_context::cbc_size_mode_exact_width | + containing_block_context::cbc_size_mode_exact_height), + fmt_ctx, false); ln.cross_size = std::max(ln.cross_size, item.el->width()); el_y += item.el->height(); } @@ -290,6 +294,7 @@ int litehtml::render_item_flex::_render_content(int x, int y, bool second_pass, } int free_cross_size = 0; + int cross_end = 0; if (is_row_direction) { if (self_size.height.type != containing_block_context::cbc_value_type_auto) @@ -300,11 +305,16 @@ int litehtml::render_item_flex::_render_content(int x, int y, bool second_pass, height -= box_sizing_height(); } free_cross_size = height - sum_cross_size; + cross_end = std::max(sum_cross_size, height); + } else + { + cross_end = sum_cross_size; } } else { free_cross_size = self_size.render_width - sum_cross_size; ret_width = sum_cross_size; + cross_end = std::max(sum_cross_size, (int) self_size.render_width); } // Find line cross size and align items @@ -317,10 +327,10 @@ int litehtml::render_item_flex::_render_content(int x, int y, bool second_pass, { if(is_row_direction) { - el_y = sum_cross_size - lines_spread.start(); + el_y = cross_end - lines_spread.start(); } else { - el_x = sum_cross_size - lines_spread.start(); + el_x = cross_end - lines_spread.start(); } } else { @@ -390,6 +400,9 @@ int litehtml::render_item_flex::_render_content(int x, int y, bool second_pass, { // TODO: must be rendered into the specified height item.el->pos().height = ln.cross_size - item.el->content_offset_height(); + } else if(is_wrap_reverse) + { + item.el->pos().y = el_y + ln.cross_size - item.el->height() + item.el->content_offset_top(); } break; } @@ -467,13 +480,24 @@ int litehtml::render_item_flex::_render_content(int x, int y, bool second_pass, break; default: item.el->pos().x = el_x + item.el->content_offset_left(); - item.el->render(el_x, - item.el->pos().y - item.el->content_offset_top(), - self_size.new_width(ln.cross_size), fmt_ctx, false); - if(item.el->css().get_width().is_predefined()) + if(!item.el->css().get_width().is_predefined()) { - // TODO: must be rendered into the specified height - item.el->pos().height = item.main_size - item.el->content_offset_height(); + item.el->render(el_x, + item.el->pos().y - item.el->content_offset_top(), + self_size.new_width(ln.cross_size), fmt_ctx, false); + } else + { + item.el->render(el_x, + item.el->pos().y - item.el->content_offset_top(), + self_size.new_width_height(ln.cross_size - item.el->content_offset_width(), + item.main_size - item.el->content_offset_height(), + containing_block_context::cbc_size_mode_exact_width | + containing_block_context::cbc_size_mode_exact_height), + fmt_ctx, false); + } + if(!item.el->css().get_width().is_predefined() && is_wrap_reverse) + { + item.el->pos().x = el_x + ln.cross_size - item.el->width() + item.el->content_offset_left(); } break; } diff --git a/src/render_image.cpp b/src/render_image.cpp index 63e622d7..1ff4574b 100644 --- a/src/render_image.cpp +++ b/src/render_image.cpp @@ -5,6 +5,7 @@ int litehtml::render_item_image::_render(int x, int y, const containing_block_context &containing_block_size, formatting_context* fmt_ctx, bool second_pass) { int parent_width = containing_block_size.width; + containing_block_context self_size = calculate_containing_block_context(containing_block_size); calc_outlines(parent_width); @@ -60,10 +61,10 @@ int litehtml::render_item_image::_render(int x, int y, const containing_block_co } } else if(!src_el()->css().get_height().is_predefined() && src_el()->css().get_width().is_predefined()) { - if (!get_predefined_height(m_pos.height, containing_block_size.height)) - { - m_pos.height = (int)src_el()->css().get_height().val(); - } + if(self_size.height.type != containing_block_context::cbc_value_type_auto && self_size.height > 0) + { + m_pos.height = self_size.height; + } // check for max-height if(!src_el()->css().get_max_height().is_predefined()) @@ -107,10 +108,10 @@ int litehtml::render_item_image::_render(int x, int y, const containing_block_co { m_pos.width = (int) src_el()->css().get_width().calc_percent(parent_width); m_pos.height = 0; - if (!get_predefined_height(m_pos.height, containing_block_size.height)) - { - m_pos.height = (int)src_el()->css().get_height().val(); - } + if(self_size.height.type != containing_block_context::cbc_value_type_auto && self_size.height > 0) + { + m_pos.height = self_size.height; + } // check for max-height if(!src_el()->css().get_max_height().is_predefined()) diff --git a/src/render_item.cpp b/src/render_item.cpp index 6e153d32..999d9689 100644 --- a/src/render_item.cpp +++ b/src/render_item.cpp @@ -1039,8 +1039,55 @@ litehtml::containing_block_context litehtml::render_item::calculate_containing_b // We have to use aut value for display_table_cell also. if (src_el()->css().get_display() != display_table_cell) { - calc_cb_length(src_el()->css().get_width(), cb_context.width, ret.width); - calc_cb_length(src_el()->css().get_height(), cb_context.height, ret.height); + auto par = parent(); + if(cb_context.size_mode & containing_block_context::cbc_size_mode_exact_width) + { + ret.width.value = cb_context.width; + ret.width.type = containing_block_context::cbc_value_type_absolute; + } else + { + auto *width = &css().get_width(); + if(par && (par->css().get_display() == display_flex || par->css().get_display() == display_inline_flex)) + { + if(!css().get_flex_basis().is_predefined() && css().get_flex_basis().val() >= 0) + { + if(par->css().get_flex_direction() == flex_direction_row || par->css().get_flex_direction() == flex_direction_row_reverse) + { + ret.width.type = containing_block_context::cbc_value_type_auto; + ret.width.value = 0; + width = nullptr; + } + } + } + if(width) + { + calc_cb_length(*width, cb_context.width, ret.width); + } + } + if(cb_context.size_mode & containing_block_context::cbc_size_mode_exact_height) + { + ret.height.value = cb_context.height; + ret.height.type = containing_block_context::cbc_value_type_absolute; + } else + { + auto *height = &css().get_height(); + if(par && (par->css().get_display() == display_flex || par->css().get_display() == display_inline_flex)) + { + if(!css().get_flex_basis().is_predefined() && css().get_flex_basis().val() >= 0) + { + if(par->css().get_flex_direction() == flex_direction_column || par->css().get_flex_direction() == flex_direction_column_reverse) + { + ret.height.type = containing_block_context::cbc_value_type_auto; + ret.height.value = 0; + height = nullptr; + } + } + } + if(height) + { + calc_cb_length(*height, cb_context.height, ret.height); + } + } if (ret.width.type != containing_block_context::cbc_value_type_auto && (src_el()->css().get_display() == display_table || src_el()->is_root())) { ret.width.value -= content_offset_width(); diff --git a/src/render_table.cpp b/src/render_table.cpp index 1a385964..fdff1f82 100644 --- a/src/render_table.cpp +++ b/src/render_table.cpp @@ -261,10 +261,10 @@ int litehtml::render_item_table::_render(int x, int y, const containing_block_co // calculate block height int block_height = 0; - if (get_predefined_height(block_height, containing_block_size.height)) - { - block_height -= m_padding.height() + m_borders.height(); - } + if(self_size.height.type != containing_block_context::cbc_value_type_auto && self_size.height > 0) + { + block_height = self_size.height - (m_padding.height() + m_borders.height()); + } // calculate minimum height from m_css.get_min_height() int min_height = 0; |