1 #include "html.h"
2 #include "el_image.h"
3 #include "document.h"
4 
el_image(const std::shared_ptr<litehtml::document> & doc)5 litehtml::el_image::el_image(const std::shared_ptr<litehtml::document>& doc) : html_tag(doc)
6 {
7 	m_display = display_inline_block;
8 }
9 
~el_image(void)10 litehtml::el_image::~el_image( void )
11 {
12 
13 }
14 
get_content_size(size & sz,int max_width)15 void litehtml::el_image::get_content_size( size& sz, int max_width )
16 {
17 	get_document()->container()->get_image_size(m_src.c_str(), 0, sz);
18 }
19 
line_height() const20 int litehtml::el_image::line_height() const
21 {
22 	return height();
23 }
24 
is_replaced() const25 bool litehtml::el_image::is_replaced() const
26 {
27 	return true;
28 }
29 
render(int x,int y,int max_width,bool second_pass)30 int litehtml::el_image::render( int x, int y, int max_width, bool second_pass )
31 {
32 	int parent_width = max_width;
33 
34 	calc_outlines(parent_width);
35 
36 	m_pos.move_to(x, y);
37 
38 	document::ptr doc = get_document();
39 
40 	litehtml::size sz;
41 	doc->container()->get_image_size(m_src.c_str(), 0, sz);
42 
43 	m_pos.width		= sz.width;
44 	m_pos.height	= sz.height;
45 
46 	if(m_css_height.is_predefined() && m_css_width.is_predefined())
47 	{
48 		m_pos.height	= sz.height;
49 		m_pos.width		= sz.width;
50 
51 		// check for max-height
52 		if(!m_css_max_width.is_predefined())
53 		{
54 			int max_width = doc->cvt_units(m_css_max_width, m_font_size, parent_width);
55 			if(m_pos.width > max_width)
56 			{
57 				m_pos.width = max_width;
58 			}
59 			if(sz.width)
60 			{
61 				m_pos.height = (int) ((float) m_pos.width * (float) sz.height / (float)sz.width);
62 			} else
63 			{
64 				m_pos.height = sz.height;
65 			}
66 		}
67 
68 		// check for max-height
69 		if(!m_css_max_height.is_predefined())
70 		{
71 			int max_height = doc->cvt_units(m_css_max_height, m_font_size);
72 			if(m_pos.height > max_height)
73 			{
74 				m_pos.height = max_height;
75 			}
76 			if(sz.height)
77 			{
78 				m_pos.width = (int) (m_pos.height * (float)sz.width / (float)sz.height);
79 			} else
80 			{
81 				m_pos.width = sz.width;
82 			}
83 		}
84 	} else if(!m_css_height.is_predefined() && m_css_width.is_predefined())
85 	{
86 		if (!get_predefined_height(m_pos.height))
87 		{
88 			m_pos.height = (int)m_css_height.val();
89 		}
90 
91 		// check for max-height
92 		if(!m_css_max_height.is_predefined())
93 		{
94 			int max_height = doc->cvt_units(m_css_max_height, m_font_size);
95 			if(m_pos.height > max_height)
96 			{
97 				m_pos.height = max_height;
98 			}
99 		}
100 
101 		if(sz.height)
102 		{
103 			m_pos.width = (int) (m_pos.height * (float)sz.width / (float)sz.height);
104 		} else
105 		{
106 			m_pos.width = sz.width;
107 		}
108 	} else if(m_css_height.is_predefined() && !m_css_width.is_predefined())
109 	{
110 		m_pos.width = (int) m_css_width.calc_percent(parent_width);
111 
112 		// check for max-width
113 		if(!m_css_max_width.is_predefined())
114 		{
115 			int max_width = doc->cvt_units(m_css_max_width, m_font_size, parent_width);
116 			if(m_pos.width > max_width)
117 			{
118 				m_pos.width = max_width;
119 			}
120 		}
121 
122 		if(sz.width)
123 		{
124 			m_pos.height = (int) ((float) m_pos.width * (float) sz.height / (float)sz.width);
125 		} else
126 		{
127 			m_pos.height = sz.height;
128 		}
129 	} else
130 	{
131 		m_pos.width		= (int) m_css_width.calc_percent(parent_width);
132 		m_pos.height	= 0;
133 		if (!get_predefined_height(m_pos.height))
134 		{
135 			m_pos.height = (int)m_css_height.val();
136 		}
137 
138 		// check for max-height
139 		if(!m_css_max_height.is_predefined())
140 		{
141 			int max_height = doc->cvt_units(m_css_max_height, m_font_size);
142 			if(m_pos.height > max_height)
143 			{
144 				m_pos.height = max_height;
145 			}
146 		}
147 
148 		// check for max-height
149 		if(!m_css_max_width.is_predefined())
150 		{
151 			int max_width = doc->cvt_units(m_css_max_width, m_font_size, parent_width);
152 			if(m_pos.width > max_width)
153 			{
154 				m_pos.width = max_width;
155 			}
156 		}
157 	}
158 
159 	calc_auto_margins(parent_width);
160 
161 	m_pos.x	+= content_margins_left();
162 	m_pos.y += content_margins_top();
163 
164 	return m_pos.width + content_margins_left() + content_margins_right();
165 }
166 
parse_attributes()167 void litehtml::el_image::parse_attributes()
168 {
169 	m_src = get_attr(_t("src"), _t(""));
170 
171 	const tchar_t* attr_height = get_attr(_t("height"));
172 	if(attr_height)
173 	{
174 		m_style.add_property(_t("height"), attr_height, 0, false);
175 	}
176 	const tchar_t* attr_width = get_attr(_t("width"));
177 	if(attr_width)
178 	{
179 		m_style.add_property(_t("width"), attr_width, 0, false);
180 	}
181 }
182 
draw(uint_ptr hdc,int x,int y,const position * clip)183 void litehtml::el_image::draw( uint_ptr hdc, int x, int y, const position* clip )
184 {
185 	position pos = m_pos;
186 	pos.x += x;
187 	pos.y += y;
188 
189 	position el_pos = pos;
190 	el_pos += m_padding;
191 	el_pos += m_borders;
192 
193 	// draw standard background here
194 	if (el_pos.does_intersect(clip))
195 	{
196 		const background* bg = get_background();
197 		if (bg)
198 		{
199 			background_paint bg_paint;
200 			init_background_paint(pos, bg_paint, bg);
201 
202 			get_document()->container()->draw_background(hdc, bg_paint);
203 		}
204 	}
205 
206 	// draw image as background
207 	if(pos.does_intersect(clip))
208 	{
209 		if (pos.width > 0 && pos.height > 0) {
210 			background_paint bg;
211 			bg.image				= m_src;
212 			bg.clip_box				= pos;
213 			bg.origin_box			= pos;
214 			bg.border_box			= pos;
215 			bg.border_box			+= m_padding;
216 			bg.border_box			+= m_borders;
217 			bg.repeat				= background_repeat_no_repeat;
218 			bg.image_size.width		= pos.width;
219 			bg.image_size.height	= pos.height;
220 			bg.border_radius		= m_css_borders.radius.calc_percents(bg.border_box.width, bg.border_box.height);
221 			bg.position_x			= pos.x;
222 			bg.position_y			= pos.y;
223 			get_document()->container()->draw_background(hdc, bg);
224 		}
225 	}
226 
227 	// draw borders
228 	if (el_pos.does_intersect(clip))
229 	{
230 		position border_box = pos;
231 		border_box += m_padding;
232 		border_box += m_borders;
233 
234 		borders bdr = m_css_borders;
235 		bdr.radius = m_css_borders.radius.calc_percents(border_box.width, border_box.height);
236 
237 		get_document()->container()->draw_borders(hdc, bdr, border_box, have_parent() ? false : true);
238 	}
239 }
240 
parse_styles(bool is_reparse)241 void litehtml::el_image::parse_styles( bool is_reparse /*= false*/ )
242 {
243 	html_tag::parse_styles(is_reparse);
244 
245 	if(!m_src.empty())
246 	{
247 		if(!m_css_height.is_predefined() && !m_css_width.is_predefined())
248 		{
249 			get_document()->container()->load_image(m_src.c_str(), 0, true);
250 		} else
251 		{
252 			get_document()->container()->load_image(m_src.c_str(), 0, false);
253 		}
254 	}
255 }
256