Disable stack execution on plugins
[claws.git] / src / plugins / litehtml_viewer / litehtml / media_query.cpp
blob7cddb15a2452c7e6789960df7a14a4ea1c601359
1 #include "html.h"
2 #include "media_query.h"
3 #include "document.h"
6 litehtml::media_query::media_query()
8 m_media_type = media_type_all;
9 m_not = false;
12 litehtml::media_query::media_query( const media_query& val )
14 m_not = val.m_not;
15 m_expressions = val.m_expressions;
16 m_media_type = val.m_media_type;
19 litehtml::media_query::ptr litehtml::media_query::create_from_string(const string& str, const std::shared_ptr<document>& doc)
21 media_query::ptr query = std::make_shared<media_query>();
23 string_vector tokens;
24 split_string(str, tokens, " \t\r\n", "", "(");
26 for(auto & token : tokens)
28 if(token == "not")
30 query->m_not = true;
31 } else if(token.at(0) == '(')
33 token.erase(0, 1);
34 if(!token.empty() && token.at(token.length() - 1) == ')')
36 token.erase(token.length() - 1, 1);
38 media_query_expression expr;
39 string_vector expr_tokens;
40 split_string(token, expr_tokens, ":");
41 if(!expr_tokens.empty())
43 trim(expr_tokens[0]);
44 expr.feature = (media_feature) value_index(expr_tokens[0], media_feature_strings, media_feature_none);
45 if(expr.feature != media_feature_none)
47 if(expr_tokens.size() == 1)
49 expr.check_as_bool = true;
50 } else
52 trim(expr_tokens[1]);
53 expr.check_as_bool = false;
54 if(expr.feature == media_feature_orientation)
56 expr.val = value_index(expr_tokens[1], media_orientation_strings, media_orientation_landscape);
57 } else
59 string::size_type slash_pos = expr_tokens[1].find('/');
60 if( slash_pos != string::npos )
62 string val1 = expr_tokens[1].substr(0, slash_pos);
63 string val2 = expr_tokens[1].substr(slash_pos + 1);
64 trim(val1);
65 trim(val2);
66 expr.val = atoi(val1.c_str());
67 expr.val2 = atoi(val2.c_str());
68 } else
70 css_length length;
71 length.fromString(expr_tokens[1]);
72 if(length.units() == css_units_dpcm || length.units() == css_units_dpi)
74 expr.val = (int) (length.val() * 2.54);
75 } else
77 if(doc)
79 doc->cvt_units(length, doc->container()->get_default_font_size());
81 expr.val = (int) length.val();
86 query->m_expressions.push_back(expr);
89 } else
91 query->m_media_type = (media_type) value_index(token, media_type_strings, media_type_all);
96 return query;
99 bool litehtml::media_query::check( const media_features& features ) const
101 bool res = false;
102 if(m_media_type == media_type_all || m_media_type == features.type)
104 res = true;
105 for(auto expression : m_expressions)
107 if(!expression.check(features))
109 res = false;
110 break;
115 if(m_not)
117 res = !res;
120 return res;
123 //////////////////////////////////////////////////////////////////////////
125 litehtml::media_query_list::ptr litehtml::media_query_list::create_from_string(const string& str, const std::shared_ptr<document>& doc)
127 media_query_list::ptr list = std::make_shared<media_query_list>();
129 string_vector tokens;
130 split_string(str, tokens, ",");
132 for(auto & token : tokens)
134 trim(token);
135 lcase(token);
137 litehtml::media_query::ptr query = media_query::create_from_string(token, doc);
138 if(query)
140 list->m_queries.push_back(query);
143 if(list->m_queries.empty())
145 list = nullptr;
148 return list;
151 bool litehtml::media_query_list::apply_media_features( const media_features& features )
153 bool apply = false;
155 for(auto & query : m_queries)
157 if(query->check(features))
159 apply = true;
160 break;
164 bool ret = (apply != m_is_used);
165 m_is_used = apply;
166 return ret;
169 bool litehtml::media_query_expression::check( const media_features& features ) const
171 switch(feature)
173 case media_feature_width:
174 if(check_as_bool)
176 return (features.width != 0);
177 } else if(features.width == val)
179 return true;
181 break;
182 case media_feature_min_width:
183 if(features.width >= val)
185 return true;
187 break;
188 case media_feature_max_width:
189 if(features.width <= val)
191 return true;
193 break;
194 case media_feature_height:
195 if(check_as_bool)
197 return (features.height != 0);
198 } else if(features.height == val)
200 return true;
202 break;
203 case media_feature_min_height:
204 if(features.height >= val)
206 return true;
208 break;
209 case media_feature_max_height:
210 if(features.height <= val)
212 return true;
214 break;
216 case media_feature_device_width:
217 if(check_as_bool)
219 return (features.device_width != 0);
220 } else if(features.device_width == val)
222 return true;
224 break;
225 case media_feature_min_device_width:
226 if(features.device_width >= val)
228 return true;
230 break;
231 case media_feature_max_device_width:
232 if(features.device_width <= val)
234 return true;
236 break;
237 case media_feature_device_height:
238 if(check_as_bool)
240 return (features.device_height != 0);
241 } else if(features.device_height == val)
243 return true;
245 break;
246 case media_feature_min_device_height:
247 if(features.device_height >= val)
249 return true;
251 break;
252 case media_feature_max_device_height:
253 if(features.device_height <= val)
255 return true;
257 break;
259 case media_feature_orientation:
260 if(features.height >= features.width)
262 if(val == media_orientation_portrait)
264 return true;
266 } else
268 if(val == media_orientation_landscape)
270 return true;
273 break;
274 case media_feature_aspect_ratio:
275 if(features.height && val2)
277 int ratio_this = round_d( (double) val / (double) val2 * 100 );
278 int ratio_feat = round_d( (double) features.width / (double) features.height * 100.0 );
279 if(ratio_this == ratio_feat)
281 return true;
284 break;
285 case media_feature_min_aspect_ratio:
286 if(features.height && val2)
288 int ratio_this = round_d( (double) val / (double) val2 * 100 );
289 int ratio_feat = round_d( (double) features.width / (double) features.height * 100.0 );
290 if(ratio_feat >= ratio_this)
292 return true;
295 break;
296 case media_feature_max_aspect_ratio:
297 if(features.height && val2)
299 int ratio_this = round_d( (double) val / (double) val2 * 100 );
300 int ratio_feat = round_d( (double) features.width / (double) features.height * 100.0 );
301 if(ratio_feat <= ratio_this)
303 return true;
306 break;
308 case media_feature_device_aspect_ratio:
309 if(features.device_height && val2)
311 int ratio_this = round_d( (double) val / (double) val2 * 100 );
312 int ratio_feat = round_d( (double) features.device_width / (double) features.device_height * 100.0 );
313 if(ratio_feat == ratio_this)
315 return true;
318 break;
319 case media_feature_min_device_aspect_ratio:
320 if(features.device_height && val2)
322 int ratio_this = round_d( (double) val / (double) val2 * 100 );
323 int ratio_feat = round_d( (double) features.device_width / (double) features.device_height * 100.0 );
324 if(ratio_feat >= ratio_this)
326 return true;
329 break;
330 case media_feature_max_device_aspect_ratio:
331 if(features.device_height && val2)
333 int ratio_this = round_d( (double) val / (double) val2 * 100 );
334 int ratio_feat = round_d( (double) features.device_width / (double) features.device_height * 100.0 );
335 if(ratio_feat <= ratio_this)
337 return true;
340 break;
342 case media_feature_color:
343 if(check_as_bool)
345 return (features.color != 0);
346 } else if(features.color == val)
348 return true;
350 break;
351 case media_feature_min_color:
352 if(features.color >= val)
354 return true;
356 break;
357 case media_feature_max_color:
358 if(features.color <= val)
360 return true;
362 break;
364 case media_feature_color_index:
365 if(check_as_bool)
367 return (features.color_index != 0);
368 } else if(features.color_index == val)
370 return true;
372 break;
373 case media_feature_min_color_index:
374 if(features.color_index >= val)
376 return true;
378 break;
379 case media_feature_max_color_index:
380 if(features.color_index <= val)
382 return true;
384 break;
386 case media_feature_monochrome:
387 if(check_as_bool)
389 return (features.monochrome != 0);
390 } else if(features.monochrome == val)
392 return true;
394 break;
395 case media_feature_min_monochrome:
396 if(features.monochrome >= val)
398 return true;
400 break;
401 case media_feature_max_monochrome:
402 if(features.monochrome <= val)
404 return true;
406 break;
408 case media_feature_resolution:
409 if(features.resolution == val)
411 return true;
413 break;
414 case media_feature_min_resolution:
415 if(features.resolution >= val)
417 return true;
419 break;
420 case media_feature_max_resolution:
421 if(features.resolution <= val)
423 return true;
425 break;
426 default:
427 return false;
430 return false;