text: #pragma once
  
  namespace litehtml
  {
  	class html_tag;
  
  	enum box_type
  	{
  		box_block,
  		box_line
  	};
  
  	class box
  	{
  	public:
  		typedef std::unique_ptr<litehtml::box>	ptr;
  		typedef std::vector< box::ptr >			vector;
  	protected:
  		int		m_box_top;
  		int		m_box_left;
  		int		m_box_right;
  	public:
  		box(int top, int left, int right)
  		{
  			m_box_top	= top;
  			m_box_left	= left;
  			m_box_right	= right;
  		}
  
  		int		bottom()	{ return m_box_top + height();	}
  		int		top()		{ return m_box_top;				}
  		int		right()		{ return m_box_left + width();	}
  		int		left()		{ return m_box_left;			}
  
  		virtual ~box();
  		
  		virtual litehtml::box_type	get_type() = 0;
  		virtual int					height() = 0;
  		virtual int					width() = 0;
  		virtual void				add_element(const element::ptr &el) = 0;
  		virtual bool				can_hold(const element::ptr &el, white_space ws) = 0;
  		virtual void				finish(bool last_box = false) = 0;
  		virtual bool				is_empty() = 0;
  		virtual int					baseline() = 0;
  		virtual void				get_elements(elements_vector& els) = 0;
  		virtual int					top_margin() = 0;
  		virtual int					bottom_margin() = 0;
  		virtual void				y_shift(int shift) = 0;
  		virtual void				new_width(int left, int right, elements_vector& els) = 0;
  	};
  
  	//////////////////////////////////////////////////////////////////////////
  
  	class block_box : public box
  	{
  		element::ptr m_element;
  	public:
  		block_box(int top, int left, int right) : box(top, left, right)
  		{
  			m_element = 0;
  		}
  
  		virtual litehtml::box_type	get_type();
  		virtual int					height();
  		virtual int					width();
  		virtual void				add_element(const element::ptr &el);
  		virtual bool				can_hold(const element::ptr &el, white_space ws);
  		virtual void				finish(bool last_box = false);
  		virtual bool				is_empty();
  		virtual int					baseline();
  		virtual void				get_elements(elements_vector& els);
  		virtual int					top_margin();
  		virtual int					bottom_margin();
  		virtual void				y_shift(int shift);
  		virtual void				new_width(int left, int right, elements_vector& els);
  	};
  
  	//////////////////////////////////////////////////////////////////////////
  
  	class line_box : public box
  	{
  		elements_vector			m_items;
  		int						m_height;
  		int						m_width;
  		int						m_line_height;
  		font_metrics			m_font_metrics;
  		int						m_baseline;
  		text_align				m_text_align;
  	public:
  		line_box(int top, int left, int right, int line_height, font_metrics& fm, text_align align) : box(top, left, right)
  		{
  			m_height		= 0;
  			m_width			= 0;
  			m_font_metrics	= fm;
  			m_line_height	= line_height;
  			m_baseline		= 0;
  			m_text_align	= align;
  		}
  
  		virtual litehtml::box_type	get_type();
  		virtual int					height();
  		virtual int					width();
  		virtual void				add_element(const element::ptr &el);
  		virtual bool				can_hold(const element::ptr &el, white_space ws);
  		virtual void				finish(bool last_box = false);
  		virtual bool				is_empty();
  		virtual int					baseline();
  		virtual void				get_elements(elements_vector& els);
  		virtual int					top_margin();
  		virtual int					bottom_margin();
  		virtual void				y_shift(int shift);
  		virtual void				new_width(int left, int right, elements_vector& els);
  
  	private:
  		bool						have_last_space();
  		bool						is_break_only();
  	};
  }