1 #ifndef LH_TABLE_H
2 #define LH_TABLE_H
3 
4 namespace litehtml
5 {
6 	struct table_row
7 	{
8 		typedef std::vector<table_row>	vector;
9 
10 		int				height;
11 		int				border_top;
12 		int				border_bottom;
13 		element::ptr	el_row;
14 		int				top;
15 		int				bottom;
16 		css_length		css_height;
17 		int				min_height;
18 
table_rowtable_row19 		table_row()
20 		{
21 			min_height		= 0;
22 			top				= 0;
23 			bottom			= 0;
24 			border_bottom	= 0;
25 			border_top		= 0;
26 			height			= 0;
27 			el_row			= nullptr;
28 			css_height.predef(0);
29 		}
30 
table_rowtable_row31 		table_row(int h, element::ptr& row)
32 		{
33 			min_height		= 0;
34 			height			= h;
35 			el_row			= row;
36 			border_bottom	= 0;
37 			border_top		= 0;
38 			top				= 0;
39 			bottom			= 0;
40 			if (row)
41 			{
42 				css_height = row->get_css_height();
43 			}
44 		}
45 
table_rowtable_row46 		table_row(const table_row& val)
47 		{
48 			min_height = val.min_height;
49 			top = val.top;
50 			bottom = val.bottom;
51 			border_bottom = val.border_bottom;
52 			border_top = val.border_top;
53 			height = val.height;
54 			css_height = val.css_height;
55 			el_row = val.el_row;
56 		}
57 
table_rowtable_row58 		table_row(table_row&& val)
59 		{
60 			min_height = val.min_height;
61 			top = val.top;
62 			bottom = val.bottom;
63 			border_bottom = val.border_bottom;
64 			border_top = val.border_top;
65 			height = val.height;
66 			css_height = val.css_height;
67 			el_row = std::move(val.el_row);
68 		}
69 	};
70 
71 	struct table_column
72 	{
73 		typedef std::vector<table_column>	vector;
74 
75 		int			min_width;
76 		int			max_width;
77 		int			width;
78 		css_length	css_width;
79 		int			border_left;
80 		int			border_right;
81 		int			left;
82 		int			right;
83 
table_columntable_column84 		table_column()
85 		{
86 			left			= 0;
87 			right			= 0;
88 			border_left		= 0;
89 			border_right	= 0;
90 			min_width		= 0;
91 			max_width		= 0;
92 			width			= 0;
93 			css_width.predef(0);
94 		}
95 
table_columntable_column96 		table_column(int min_w, int max_w)
97 		{
98 			left			= 0;
99 			right			= 0;
100 			border_left		= 0;
101 			border_right	= 0;
102 			max_width		= max_w;
103 			min_width		= min_w;
104 			width			= 0;
105 			css_width.predef(0);
106 		}
107 
table_columntable_column108 		table_column(const table_column& val)
109 		{
110 			left			= val.left;
111 			right			= val.right;
112 			border_left		= val.border_left;
113 			border_right	= val.border_right;
114 			max_width		= val.max_width;
115 			min_width		= val.min_width;
116 			width			= val.width;
117 			css_width		= val.css_width;
118 		}
119 	};
120 
121 	class table_column_accessor
122 	{
123 	public:
124 		virtual int& get(table_column& col) = 0;
125 	};
126 
127 	class table_column_accessor_max_width : public table_column_accessor
128 	{
129 	public:
130 		virtual int& get(table_column& col);
131 	};
132 
133 	class table_column_accessor_min_width : public table_column_accessor
134 	{
135 	public:
136 		virtual int& get(table_column& col);
137 	};
138 
139 	class table_column_accessor_width : public table_column_accessor
140 	{
141 	public:
142 		virtual int& get(table_column& col);
143 	};
144 
145 	struct table_cell
146 	{
147 		element::ptr	el;
148 		int				colspan;
149 		int				rowspan;
150 		int				min_width;
151 		int				min_height;
152 		int				max_width;
153 		int				max_height;
154 		int				width;
155 		int				height;
156 		margins			borders;
157 
table_celltable_cell158 		table_cell()
159 		{
160 			min_width		= 0;
161 			min_height		= 0;
162 			max_width		= 0;
163 			max_height		= 0;
164 			width			= 0;
165 			height			= 0;
166 			colspan			= 1;
167 			rowspan			= 1;
168 			el				= nullptr;
169 		}
170 
table_celltable_cell171 		table_cell(const table_cell& val)
172 		{
173 			el				= val.el;
174 			colspan			= val.colspan;
175 			rowspan			= val.rowspan;
176 			width			= val.width;
177 			height			= val.height;
178 			min_width		= val.min_width;
179 			min_height		= val.min_height;
180 			max_width		= val.max_width;
181 			max_height		= val.max_height;
182 			borders			= val.borders;
183 		}
184 
table_celltable_cell185 		table_cell(const table_cell&& val)
186 		{
187 			el = std::move(val.el);
188 			colspan = val.colspan;
189 			rowspan = val.rowspan;
190 			width = val.width;
191 			height = val.height;
192 			min_width = val.min_width;
193 			min_height = val.min_height;
194 			max_width = val.max_width;
195 			max_height = val.max_height;
196 			borders = val.borders;
197 		}
198 	};
199 
200 	class table_grid
201 	{
202 	public:
203 		typedef std::vector< std::vector<table_cell> >	rows;
204 	private:
205 		int						m_rows_count;
206 		int						m_cols_count;
207 		rows					m_cells;
208 		table_column::vector	m_columns;
209 		table_row::vector		m_rows;
210 	public:
211 
table_grid()212 		table_grid()
213 		{
214 			m_rows_count	= 0;
215 			m_cols_count	= 0;
216 		}
217 
218 		void			clear();
219 		void			begin_row(element::ptr& row);
220 		void			add_cell(element::ptr& el);
221 		bool			is_rowspanned(int r, int c);
222 		void			finish();
223 		table_cell*		cell(int t_col, int t_row);
column(int c)224 		table_column&	column(int c)	{ return m_columns[c];	}
row(int r)225 		table_row&		row(int r)		{ return m_rows[r];		}
226 
rows_count()227 		int				rows_count()	{ return m_rows_count;	}
cols_count()228 		int				cols_count()	{ return m_cols_count;	}
229 
230 		void			distribute_max_width(int width, int start, int end);
231 		void			distribute_min_width(int width, int start, int end);
232 		void			distribute_width(int width, int start, int end);
233 		void			distribute_width(int width, int start, int end, table_column_accessor* acc);
234 		int				calc_table_width(int block_width, bool is_auto, int& min_table_width, int& max_table_width);
235 		void			calc_horizontal_positions(margins& table_borders, border_collapse bc, int bdr_space_x);
236 		void			calc_vertical_positions(margins& table_borders, border_collapse bc, int bdr_space_y);
237 		void			calc_rows_height(int blockHeight, int borderSpacingY);
238 	};
239 }
240 
241 #endif  // LH_TABLE_H
242