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