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