aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/css_properties.cpp5
-rw-r--r--src/render_block.cpp21
-rw-r--r--src/render_block_context.cpp5
-rw-r--r--src/render_flex.cpp44
-rw-r--r--src/render_image.cpp17
-rw-r--r--src/render_item.cpp51
-rw-r--r--src/render_table.cpp8
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;