6 litehtml::box_type litehtml::block_box::get_type()
11 int litehtml::block_box::height()
13 return m_element->height();
16 int litehtml::block_box::width()
18 return m_element->width();
21 void litehtml::block_box::add_element(const element::ptr &el)
27 void litehtml::block_box::finish(bool last_box)
29 if(!m_element) return;
30 m_element->apply_relative_shift(m_box_right - m_box_left);
33 bool litehtml::block_box::can_hold(const element::ptr &el, white_space ws)
35 if(m_element || el->is_inline_box())
42 bool litehtml::block_box::is_empty()
51 int litehtml::block_box::baseline()
55 return m_element->get_base_line();
60 void litehtml::block_box::get_elements( elements_vector& els )
62 els.push_back(m_element);
65 int litehtml::block_box::top_margin()
67 if(m_element && m_element->collapse_top_margin())
69 return m_element->m_margins.top;
74 int litehtml::block_box::bottom_margin()
76 if(m_element && m_element->collapse_bottom_margin())
78 return m_element->m_margins.bottom;
83 void litehtml::block_box::y_shift( int shift )
88 m_element->m_pos.y += shift;
92 void litehtml::block_box::new_width( int left, int right, elements_vector& els )
97 //////////////////////////////////////////////////////////////////////////
99 litehtml::box_type litehtml::line_box::get_type()
104 int litehtml::line_box::height()
109 int litehtml::line_box::width()
114 void litehtml::line_box::add_element(const element::ptr &el)
119 if( (m_items.empty() && el->is_white_space()) || el->is_break() )
122 } else if(el->is_white_space())
124 if (have_last_space())
134 m_items.push_back(el);
138 int el_shift_left = el->get_inline_shift_left();
139 int el_shift_right = el->get_inline_shift_right();
141 el->m_pos.x = m_box_left + m_width + el_shift_left + el->content_margins_left();
142 el->m_pos.y = m_box_top + el->content_margins_top();
143 m_width += el->width() + el_shift_left + el_shift_right;
148 void litehtml::line_box::finish(bool last_box)
150 if( is_empty() || (!is_empty() && last_box && is_break_only()) )
156 for(auto i = m_items.rbegin(); i != m_items.rend(); i++)
158 if((*i)->is_white_space() || (*i)->is_break())
163 m_width -= (*i)->width();
171 int base_line = m_font_metrics.base_line();
172 int line_height = m_line_height;
177 case text_align_right:
178 if(m_width < (m_box_right - m_box_left))
180 add_x = (m_box_right - m_box_left) - m_width;
183 case text_align_center:
184 if(m_width < (m_box_right - m_box_left))
186 add_x = ((m_box_right - m_box_left) - m_width) / 2;
194 // find line box baseline and line-height
195 for(const auto& el : m_items)
197 if(el->get_display() == display_inline_text)
201 base_line = std::max(base_line, fm.base_line());
202 line_height = std::max(line_height, el->line_height());
203 m_height = std::max(m_height, fm.height);
205 el->m_pos.x += add_x;
210 base_line += (line_height - m_height) / 2;
213 m_height = line_height;
218 for (const auto& el : m_items)
220 if(el->get_display() == display_inline_text)
224 el->m_pos.y = m_height - base_line - fm.ascent;
227 switch(el->get_vertical_align())
232 el->m_pos.y = m_height - base_line - el->height() + el->get_base_line() + el->content_margins_top();
235 el->m_pos.y = y1 + el->content_margins_top();
238 el->m_pos.y = m_height - base_line - m_font_metrics.ascent + el->content_margins_top();
241 el->m_pos.y = m_height - base_line - m_font_metrics.x_height / 2 - el->height() / 2 + el->content_margins_top();
244 el->m_pos.y = y2 - el->height() + el->content_margins_top();
247 el->m_pos.y = m_height - base_line + m_font_metrics.descent - el->height() + el->content_margins_top();
250 y1 = std::min(y1, el->top());
251 y2 = std::max(y2, el->bottom());
257 for (const auto& el : m_items)
260 el->m_pos.y += m_box_top;
261 if(el->get_display() != display_inline_text)
263 switch(el->get_vertical_align())
266 el->m_pos.y = m_box_top + el->content_margins_top();
269 el->m_pos.y = m_box_top + (y2 - y1) - el->height() + el->content_margins_top();
272 //TODO: process vertical align "baseline"
275 //TODO: process vertical align "middle"
278 //TODO: process vertical align "sub"
281 //TODO: process vertical align "super"
284 //TODO: process vertical align "text-bottom"
287 //TODO: process vertical align "text-top"
292 el->apply_relative_shift(m_box_right - m_box_left);
295 m_baseline = (base_line - y1) - (m_height - line_height);
298 bool litehtml::line_box::can_hold(const element::ptr &el, white_space ws)
300 if(!el->is_inline_box()) return false;
307 if(ws == white_space_nowrap || ws == white_space_pre)
312 if(m_box_left + m_width + el->width() + el->get_inline_shift_left() + el->get_inline_shift_right() > m_box_right)
320 bool litehtml::line_box::have_last_space()
323 for (auto i = m_items.rbegin(); i != m_items.rend() && !ret; i++)
325 if((*i)->is_white_space() || (*i)->is_break())
336 bool litehtml::line_box::is_empty()
338 if(m_items.empty()) return true;
339 for (auto i = m_items.rbegin(); i != m_items.rend(); i++)
341 if(!(*i)->m_skip || (*i)->is_break())
349 int litehtml::line_box::baseline()
354 void litehtml::line_box::get_elements( elements_vector& els )
356 els.insert(els.begin(), m_items.begin(), m_items.end());
359 int litehtml::line_box::top_margin()
364 int litehtml::line_box::bottom_margin()
369 void litehtml::line_box::y_shift( int shift )
372 for (auto& el : m_items)
374 el->m_pos.y += shift;
378 bool litehtml::line_box::is_break_only()
380 if(m_items.empty()) return true;
382 if(m_items.front()->is_break())
384 for (auto& el : m_items)
396 void litehtml::line_box::new_width( int left, int right, elements_vector& els )
398 int add = left - m_box_left;
404 auto remove_begin = m_items.end();
405 for (auto i = m_items.begin() + 1; i != m_items.end(); i++)
407 element::ptr el = (*i);
411 if(m_box_left + m_width + el->width() + el->get_inline_shift_right() + el->get_inline_shift_left() > m_box_right)
418 m_width += el->width() + el->get_inline_shift_right() + el->get_inline_shift_left();
422 if(remove_begin != m_items.end())
424 els.insert(els.begin(), remove_begin, m_items.end());
425 m_items.erase(remove_begin, m_items.end());
427 for(const auto& el : els)