Skip to content

Commit bc1c8e3

Browse files
authored
Merge pull request #262 from litehtml/block_render_fix
Block render fix
2 parents 866f47a + 819c20e commit bc1c8e3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+967
-500
lines changed

include/litehtml/background.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@ namespace litehtml
2222
int_vector m_repeat;
2323
int_vector m_clip;
2424
int_vector m_origin;
25+
26+
bool is_empty() const
27+
{
28+
if(m_color.alpha != 0) return false;
29+
if(m_image.empty()) return true;
30+
for(const auto& img : m_image)
31+
{
32+
if(!img.empty()) return false;
33+
}
34+
return true;
35+
}
2536
};
2637

2738
class background_paint

include/litehtml/document.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ namespace litehtml
6262
litehtml::css m_master_css;
6363
litehtml::css m_user_css;
6464
litehtml::size m_size;
65+
litehtml::size m_content_size;
6566
position::vector m_fixed_boxes;
6667
media_query_list::vector m_media_lists;
6768
element::ptr m_over_element;
@@ -83,6 +84,8 @@ namespace litehtml
8384
int to_pixels(const css_length& val, int fontSize, int size = 0) const;
8485
int width() const;
8586
int height() const;
87+
int content_width() const;
88+
int content_height() const;
8689
void add_stylesheet(const char* str, const char* baseurl, const char* media);
8790
bool on_mouse_over(int x, int y, int client_x, int client_y, position::vector& redraw_boxes);
8891
bool on_lbutton_down(int x, int y, int client_x, int client_y, position::vector& redraw_boxes);

include/litehtml/element.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ namespace litehtml
5050
bool is_float() const;
5151

5252
bool have_parent() const;
53+
bool is_root() const;
5354
element::ptr parent() const;
5455
void parent(const element::ptr& par);
5556
// returns true for elements inside a table (but outside cells) that don't participate in table rendering
@@ -158,9 +159,9 @@ namespace litehtml
158159
return false;
159160
}
160161

161-
inline bool litehtml::element::have_parent() const
162+
inline bool litehtml::element::is_root() const
162163
{
163-
return !m_parent.expired();
164+
return m_parent.expired();
164165
}
165166

166167
inline element::ptr litehtml::element::parent() const

include/litehtml/line_box.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ namespace litehtml
3939
};
4040
protected:
4141
std::shared_ptr<render_item> m_element;
42+
int m_rendered_min_width;
4243
public:
43-
explicit line_box_item(const std::shared_ptr<render_item>& element) : m_element(element) {}
44+
explicit line_box_item(const std::shared_ptr<render_item>& element) : m_element(element), m_rendered_min_width(0) {}
4445
line_box_item() = default;
4546
line_box_item(const line_box_item& el) = default;
4647
line_box_item(line_box_item&&) = default;
@@ -55,6 +56,8 @@ namespace litehtml
5556
virtual int right() const;
5657
virtual int left() const;
5758
virtual element_type get_type() const { return type_text_part; }
59+
virtual int get_rendered_min_width() const { return m_rendered_min_width; }
60+
virtual void set_rendered_min_width(int min_width) { m_rendered_min_width = min_width; }
5861
};
5962

6063
class lbi_start : public line_box_item
@@ -72,6 +75,7 @@ namespace litehtml
7275
int right() const override;
7376
int left() const override;
7477
element_type get_type() const override { return type_inline_start; }
78+
int get_rendered_min_width() const override { return width(); }
7579
};
7680

7781
class lbi_end : public lbi_start
@@ -151,7 +155,7 @@ namespace litehtml
151155
int top_margin() const;
152156
int bottom_margin() const;
153157
void y_shift(int shift);
154-
std::list< std::unique_ptr<line_box_item> > finish(bool last_box = false);
158+
std::list< std::unique_ptr<line_box_item> > finish(bool last_box, const containing_block_context &containing_block_size);
155159
std::list< std::unique_ptr<line_box_item> > new_width(int left, int right);
156160
std::shared_ptr<render_item> get_last_text_part() const;
157161
std::shared_ptr<render_item> get_first_text_part() const;

include/litehtml/master_css.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ namespace litehtml{ const char* const master_css = R"##(
55
66
html {
77
display: block;
8-
height:100%;
9-
width:100%;
108
position: relative;
119
}
1210
@@ -37,8 +35,6 @@ script {
3735
body {
3836
display:block;
3937
margin:8px;
40-
height:100%;
41-
width:100%;
4238
}
4339
4440
p {

include/litehtml/render_item.h

Lines changed: 68 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ namespace litehtml
2626
bool m_skip;
2727
std::vector<std::shared_ptr<render_item>> m_positioned;
2828

29-
virtual int _render(int x, int y, int max_width, bool second_pass) { return 0; }
29+
containing_block_context calculate_containing_block_context(const containing_block_context& cb_context);
30+
void calc_cb_length(const css_length& len, int percent_base, containing_block_context::typed_int& out_value) const;
3031

3132
public:
3233
explicit render_item(std::shared_ptr<element> src_el);
@@ -216,6 +217,36 @@ namespace litehtml
216217
return content_offset_top() + content_offset_bottom();
217218
}
218219

220+
int box_sizing_left() const
221+
{
222+
return m_padding.left + m_borders.left;
223+
}
224+
225+
int box_sizing_right() const
226+
{
227+
return m_padding.right + m_borders.right;
228+
}
229+
230+
int box_sizing_width() const
231+
{
232+
return box_sizing_left() + box_sizing_left();
233+
}
234+
235+
int box_sizing_top() const
236+
{
237+
return m_padding.top + m_borders.top;
238+
}
239+
240+
int box_sizing_bottom() const
241+
{
242+
return m_padding.bottom + m_borders.bottom;
243+
}
244+
245+
int box_sizing_height() const
246+
{
247+
return box_sizing_top() + box_sizing_bottom();
248+
}
249+
219250
void parent(const std::shared_ptr<render_item>& par)
220251
{
221252
m_parent = par;
@@ -237,15 +268,15 @@ namespace litehtml
237268
ri->parent(shared_from_this());
238269
}
239270

240-
int render(int x, int y, int max_width)
241-
{
242-
return _render(x, y, max_width, false);
243-
}
271+
virtual int render(int x, int y, const containing_block_context& containing_block_size, bool second_pass = false)
272+
{
273+
return 0;
274+
}
244275

245-
bool have_parent() const
246-
{
247-
return !m_parent.expired();
248-
}
276+
bool is_root() const
277+
{
278+
return m_parent.expired();
279+
}
249280

250281
bool collapse_top_margin() const
251282
{
@@ -254,7 +285,7 @@ namespace litehtml
254285
m_element->in_normal_flow() &&
255286
m_element->css().get_float() == float_none &&
256287
m_margins.top >= 0 &&
257-
have_parent();
288+
!is_root();
258289
}
259290

260291
bool collapse_bottom_margin() const
@@ -264,19 +295,19 @@ namespace litehtml
264295
m_element->in_normal_flow() &&
265296
m_element->css().get_float() == float_none &&
266297
m_margins.bottom >= 0 &&
267-
have_parent();
298+
!is_root();
268299
}
269300

270301
bool is_visible() const
271302
{
272303
return !(m_skip || src_el()->css().get_display() == display_none || src_el()->css().get_visibility() != visibility_visible);
273304
}
274305

275-
int calc_width(int defVal) const;
276-
bool get_predefined_height(int& p_height) const;
277-
void apply_relative_shift(int parent_width);
306+
int calc_width(int defVal, int containing_block_width) const;
307+
bool get_predefined_height(int& p_height, int containing_block_height) const;
308+
void apply_relative_shift(const containing_block_context &containing_block_size);
278309
void calc_outlines( int parent_width );
279-
void calc_auto_margins(int parent_width);
310+
int calc_auto_margins(int parent_width); // returns left margin
280311

281312
virtual std::shared_ptr<render_item> init();
282313
virtual void apply_vertical_align() {}
@@ -294,7 +325,7 @@ namespace litehtml
294325
void render_positioned(render_type rt = render_all);
295326
void add_positioned(const std::shared_ptr<litehtml::render_item> &el);
296327
void get_redraw_box(litehtml::position& pos, int x = 0, int y = 0);
297-
void calc_document_size( litehtml::size& sz, int x = 0, int y = 0 );
328+
void calc_document_size( litehtml::size& sz, litehtml::size& content_size, int x = 0, int y = 0 );
298329
virtual void get_inline_boxes( position::vector& boxes ) const {};
299330
virtual void set_inline_boxes( position::vector& boxes ) {};
300331
virtual void add_inline_box( const position& box ) {};
@@ -334,21 +365,20 @@ namespace litehtml
334365
int_int_cache m_cache_line_left;
335366
int_int_cache m_cache_line_right;
336367

337-
int _render(int x, int y, int max_width, bool second_pass) override;
338-
339368
/**
340369
* Render block content.
341370
*
342371
* @param x - horizontal position of the content
343372
* @param y - vertical position of the content
344-
* @param max_width - maximal width of the content
345373
* @param second_pass - true is this is the second pass.
346374
* @param ret_width - input minimal width.
375+
* @param self_size - defines calculated size of block
347376
* @return return value is the minimal width of the content in block. Must be greater or equal to ret_width parameter
348377
*/
349-
virtual int _render_content(int x, int y, int max_width, bool second_pass, int ret_width) {return ret_width;}
378+
virtual int _render_content(int x, int y, bool second_pass, int ret_width, const containing_block_context &self_size) {return ret_width;}
379+
int render(int x, int y, const containing_block_context &containing_block_size, bool second_pass) override;
350380

351-
int place_float(const std::shared_ptr<render_item> &el, int top, int max_width);
381+
int place_float(const std::shared_ptr<render_item> &el, int top, const containing_block_context &containing_block_size);
352382
int get_floats_height(element_float el_float = float_none) const override;
353383
int get_left_floats_height() const override;
354384
int get_right_floats_height() const override;
@@ -358,7 +388,9 @@ namespace litehtml
358388
void add_float(const std::shared_ptr<render_item> &el, int x, int y) override;
359389
int get_cleared_top(const std::shared_ptr<render_item> &el, int line_top) const;
360390
int find_next_line_top( int top, int width, int def_right ) override;
361-
virtual void fix_line_width( int max_width, element_float flt ) {}
391+
virtual void fix_line_width(element_float flt,
392+
const containing_block_context &containing_block_size)
393+
{}
362394
void update_floats(int dy, const std::shared_ptr<render_item> &_parent) override;
363395
public:
364396
explicit render_item_block(std::shared_ptr<element> src_el) : render_item(std::move(src_el))
@@ -379,7 +411,8 @@ namespace litehtml
379411
class render_item_block_context : public render_item_block
380412
{
381413
protected:
382-
int _render_content(int x, int y, int max_width, bool second_pass, int ret_width) override;
414+
int _render_content(int x, int y, bool second_pass, int ret_width,
415+
const containing_block_context &self_size) override;
383416

384417
public:
385418
explicit render_item_block_context(std::shared_ptr<element> src_el) : render_item_block(std::move(src_el))
@@ -417,12 +450,14 @@ namespace litehtml
417450
std::vector<std::unique_ptr<litehtml::line_box> > m_line_boxes;
418451
int m_max_line_width;
419452

420-
int _render_content(int x, int y, int max_width, bool second_pass, int ret_width) override;
421-
void fix_line_width( int max_width, element_float flt ) override;
453+
int _render_content(int x, int y, bool second_pass, int ret_width,
454+
const containing_block_context &self_size) override;
455+
void fix_line_width(element_float flt,
456+
const containing_block_context &self_size) override;
422457

423-
std::list<std::unique_ptr<line_box_item> > finish_last_box(bool end_of_render, int max_width);
424-
void place_inline(std::unique_ptr<line_box_item> item, int max_width);
425-
int new_box(const std::unique_ptr<line_box_item>& el, int max_width, line_context& line_ctx);
458+
std::list<std::unique_ptr<line_box_item> > finish_last_box(bool end_of_render, const containing_block_context &self_size);
459+
void place_inline(std::unique_ptr<line_box_item> item, const containing_block_context &self_size);
460+
int new_box(const std::unique_ptr<line_box_item>& el, line_context& line_ctx, const containing_block_context &self_size);
426461
void apply_vertical_align() override;
427462
public:
428463
explicit render_item_inline_context(std::shared_ptr<element> src_el) : render_item_block(std::move(src_el)), m_max_line_width(0)
@@ -444,15 +479,14 @@ namespace litehtml
444479
int m_border_spacing_x;
445480
int m_border_spacing_y;
446481

447-
int _render(int x, int y, int max_width, bool second_pass) override;
448-
449482
public:
450483
explicit render_item_table(std::shared_ptr<element> src_el);
451484

452485
std::shared_ptr<render_item> clone() override
453486
{
454487
return std::make_shared<render_item_table>(src_el());
455488
}
489+
int render(int x, int y, const containing_block_context &containing_block_size, bool second_pass) override;
456490
void draw_children(uint_ptr hdc, int x, int y, const position* clip, draw_flag flag, int zindex) override;
457491
int get_draw_vertical_offset() override;
458492
std::shared_ptr<render_item> init() override;
@@ -464,8 +498,6 @@ namespace litehtml
464498
explicit render_item_table_part(std::shared_ptr<element> src_el) : render_item(std::move(src_el))
465499
{}
466500

467-
int _render(int x, int y, int max_width, bool second_pass) override
468-
{return 0;}
469501
std::shared_ptr<render_item> clone() override
470502
{
471503
return std::make_shared<render_item_table_part>(src_el());
@@ -478,8 +510,6 @@ namespace litehtml
478510
explicit render_item_table_row(std::shared_ptr<element> src_el) : render_item(std::move(src_el))
479511
{}
480512

481-
int _render(int x, int y, int max_width, bool second_pass) override
482-
{return 0;}
483513
std::shared_ptr<render_item> clone() override
484514
{
485515
return std::make_shared<render_item_table_row>(src_el());
@@ -492,7 +522,6 @@ namespace litehtml
492522
protected:
493523
position::vector m_boxes;
494524

495-
int _render(int x, int y, int max_width, bool second_pass) override;
496525
public:
497526
explicit render_item_inline(std::shared_ptr<element> src_el) : render_item(std::move(src_el))
498527
{}
@@ -512,13 +541,13 @@ namespace litehtml
512541
class render_item_image : public render_item
513542
{
514543
protected:
515-
int _render(int x, int y, int max_width, bool second_pass) override;
516-
int calc_max_height(int image_height);
544+
int calc_max_height(int image_height, int containing_block_height);
517545

518546
public:
519547
explicit render_item_image(std::shared_ptr<element> src_el) : render_item(std::move(src_el))
520548
{}
521549

550+
int render(int x, int y, const containing_block_context &containing_block_size, bool second_pass) override;
522551
std::shared_ptr<render_item> clone() override
523552
{
524553
return std::make_shared<render_item_image>(src_el());
@@ -548,7 +577,8 @@ namespace litehtml
548577
protected:
549578
std::list<std::unique_ptr<flex_item>> m_flex_items;
550579

551-
int _render_content(int x, int y, int max_width, bool second_pass, int ret_width) override;
580+
int _render_content(int x, int y, bool second_pass, int ret_width,
581+
const containing_block_context &self_size) override;
552582

553583
public:
554584
explicit render_item_flex(std::shared_ptr<element> src_el) : render_item_block(std::move(src_el))

0 commit comments

Comments
 (0)