1 #ifndef LH_RENDER_ITEM_H
2 #define LH_RENDER_ITEM_H
11 #include "formatting_context.h"
17 class render_item
: public std::enable_shared_from_this
<render_item
>
20 std::shared_ptr
<element
> m_element
;
21 std::weak_ptr
<render_item
> m_parent
;
22 std::list
<std::shared_ptr
<render_item
>> m_children
;
28 std::vector
<std::shared_ptr
<render_item
>> m_positioned
;
30 containing_block_context
calculate_containing_block_context(const containing_block_context
& cb_context
);
31 void calc_cb_length(const css_length
& len
, int percent_base
, containing_block_context::typed_int
& out_value
) const;
32 virtual int _render(int x
, int y
, const containing_block_context
& containing_block_size
, formatting_context
* fmt_ctx
, bool second_pass
= false)
38 explicit render_item(std::shared_ptr
<element
> src_el
);
40 virtual ~render_item() = default;
42 std::list
<std::shared_ptr
<render_item
>>& children()
64 return left() + width();
69 return m_pos
.left() - m_margins
.left
- m_padding
.left
- m_borders
.left
;
74 return m_pos
.top() - m_margins
.top
- m_padding
.top
- m_borders
.top
;
79 return top() + height();
84 return m_pos
.height
+ m_margins
.height() + m_padding
.height() + m_borders
.height();
89 return m_pos
.width
+ m_margins
.width() + m_padding
.width() + m_borders
.width();
92 int padding_top() const
97 int padding_bottom() const
99 return m_padding
.bottom
;
102 int padding_left() const
104 return m_padding
.left
;
107 int padding_right() const
109 return m_padding
.right
;
112 int border_top() const
114 return m_borders
.top
;
117 int border_bottom() const
119 return m_borders
.bottom
;
122 int border_left() const
124 return m_borders
.left
;
127 int border_right() const
129 return m_borders
.right
;
132 int margin_top() const
134 return m_margins
.top
;
137 int margin_bottom() const
139 return m_margins
.bottom
;
142 int margin_left() const
144 return m_margins
.left
;
147 int margin_right() const
149 return m_margins
.right
;
152 std::shared_ptr
<render_item
> parent() const
154 return m_parent
.lock();
157 margins
& get_margins()
162 margins
& get_paddings()
167 void set_paddings(const margins
& val
)
172 margins
& get_borders()
178 * Top offset to the element content. Includes paddings, margins and borders.
180 int content_offset_top() const
182 return m_margins
.top
+ m_padding
.top
+ m_borders
.top
;
186 * Bottom offset to the element content. Includes paddings, margins and borders.
188 inline int content_offset_bottom() const
190 return m_margins
.bottom
+ m_padding
.bottom
+ m_borders
.bottom
;
194 * Left offset to the element content. Includes paddings, margins and borders.
196 int content_offset_left() const
198 return m_margins
.left
+ m_padding
.left
+ m_borders
.left
;
202 * Right offset to the element content. Includes paddings, margins and borders.
204 int content_offset_right() const
206 return m_margins
.right
+ m_padding
.right
+ m_borders
.right
;
210 * Sum of left and right offsets to the element content. Includes paddings, margins and borders.
212 int content_offset_width() const
214 return content_offset_left() + content_offset_right();
218 * Sum of top and bottom offsets to the element content. Includes paddings, margins and borders.
220 int content_offset_height() const
222 return content_offset_top() + content_offset_bottom();
225 int box_sizing_left() const
227 if(css().get_box_sizing() == box_sizing_border_box
)
229 return m_padding
.left
+ m_borders
.left
;
234 int box_sizing_right() const
236 if(css().get_box_sizing() == box_sizing_border_box
)
238 return m_padding
.right
+ m_borders
.right
;
243 int box_sizing_width() const
245 return box_sizing_left() + box_sizing_right();
248 int box_sizing_top() const
250 if(css().get_box_sizing() == box_sizing_border_box
)
252 return m_padding
.top
+ m_borders
.top
;
257 int box_sizing_bottom() const
259 if(css().get_box_sizing() == box_sizing_border_box
)
261 return m_padding
.bottom
+ m_borders
.bottom
;
266 int box_sizing_height() const
268 return box_sizing_top() + box_sizing_bottom();
271 void parent(const std::shared_ptr
<render_item
>& par
)
276 const std::shared_ptr
<element
>& src_el() const
281 const css_properties
& css() const
283 return m_element
->css();
286 void add_child(const std::shared_ptr
<render_item
>& ri
)
288 m_children
.push_back(ri
);
289 ri
->parent(shared_from_this());
294 return m_parent
.expired();
297 bool collapse_top_margin() const
299 return !m_borders
.top
&&
301 m_element
->in_normal_flow() &&
302 m_element
->css().get_float() == float_none
&&
303 m_margins
.top
>= 0 &&
308 bool collapse_bottom_margin() const
310 return !m_borders
.bottom
&&
312 m_element
->in_normal_flow() &&
313 m_element
->css().get_float() == float_none
&&
314 m_margins
.bottom
>= 0 &&
318 bool is_visible() const
320 return !(m_skip
|| src_el()->css().get_display() == display_none
|| src_el()->css().get_visibility() != visibility_visible
);
323 bool is_flex_item() const
326 if(par
&& (par
->css().get_display() == display_inline_flex
|| par
->css().get_display() == display_flex
))
333 int render(int x
, int y
, const containing_block_context
& containing_block_size
, formatting_context
* fmt_ctx
, bool second_pass
= false);
334 void apply_relative_shift(const containing_block_context
&containing_block_size
);
335 void calc_outlines( int parent_width
);
336 int calc_auto_margins(int parent_width
); // returns left margin
338 virtual std::shared_ptr
<render_item
> init();
339 virtual void apply_vertical_align() {}
341 * Get first baseline position. Default position is element bottom without bottom margin.
342 * @returns offset of the first baseline from element top
344 virtual int get_first_baseline() { return height() - margin_bottom(); }
346 * Get last baseline position. Default position is element bottom without bottom margin.
347 * @returns offset of the last baseline from element top
349 virtual int get_last_baseline() { return height() - margin_bottom(); }
351 virtual std::shared_ptr
<render_item
> clone()
353 return std::make_shared
<render_item
>(src_el());
356 std::shared_ptr
<litehtml::render_item
>,
357 std::shared_ptr
<litehtml::render_item
>,
358 std::shared_ptr
<litehtml::render_item
>
360 bool fetch_positioned();
361 void render_positioned(render_type rt
= render_all
);
362 void add_positioned(const std::shared_ptr
<litehtml::render_item
> &el
);
363 void get_redraw_box(litehtml::position
& pos
, int x
= 0, int y
= 0);
364 void calc_document_size( litehtml::size
& sz
, litehtml::size
& content_size
, int x
= 0, int y
= 0 );
365 virtual void get_inline_boxes( position::vector
& boxes
) const {};
366 virtual void set_inline_boxes( position::vector
& boxes
) {};
367 virtual void add_inline_box( const position
& box
) {};
368 virtual void clear_inline_boxes() {};
369 void draw_stacking_context( uint_ptr hdc
, int x
, int y
, const position
* clip
, bool with_positioned
);
370 virtual void draw_children( uint_ptr hdc
, int x
, int y
, const position
* clip
, draw_flag flag
, int zindex
);
371 virtual int get_draw_vertical_offset() { return 0; }
372 virtual std::shared_ptr
<element
> get_child_by_point(int x
, int y
, int client_x
, int client_y
, draw_flag flag
, int zindex
);
373 std::shared_ptr
<element
> get_element_by_point(int x
, int y
, int client_x
, int client_y
);
374 bool is_point_inside( int x
, int y
);
375 void dump(litehtml::dumper
& cout
);
376 position
get_placement() const;
378 * Returns the boxes of rendering element. All coordinates are absolute
380 * @param redraw_boxes [out] resulting rendering boxes
383 void get_rendering_boxes( position::vector
& redraw_boxes
);
387 #endif //LH_RENDER_ITEM_H