4a455696fbceddceccbfe3ac74148be38d6069ea
[claws.git] / src / plugins / litehtml_viewer / container_linux.cpp
1 /*
2  * Claws Mail -- A GTK+ based, lightweight, and fast e-mail client
3  * Copyright(C) 2019 the Claws Mail Team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write tothe Free Software
15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16  */
17
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #include "claws-features.h"
21 #endif
22
23 #include "container_linux.h"
24
25 #include <cairo-ft.h>
26
27 #define _USE_MATH_DEFINES
28 #include <math.h>
29
30 #ifndef M_PI
31 #       define M_PI    3.14159265358979323846
32 #endif
33
34 container_linux::container_linux(void)
35 {
36         m_temp_surface  = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 2, 2);
37         m_temp_cr               = cairo_create(m_temp_surface);
38         g_rec_mutex_init(&m_images_lock);
39 }
40
41 container_linux::~container_linux(void)
42 {
43         clear_images();
44         cairo_surface_destroy(m_temp_surface);
45         cairo_destroy(m_temp_cr);
46         g_rec_mutex_clear(&m_images_lock);
47 }
48
49 int container_linux::pt_to_px( int pt )
50 {
51         GdkScreen* screen = gdk_screen_get_default();
52         double dpi = gdk_screen_get_resolution(screen);
53
54         return (int) ((double) pt * dpi / 72.0);
55 }
56
57 void container_linux::draw_list_marker( litehtml::uint_ptr hdc, const litehtml::list_marker& marker )
58 {
59         if(!marker.image.empty())
60         {
61                 /*litehtml::tstring url;
62                 make_url(marker.image.c_str(), marker.baseurl, url);
63
64                 lock_images_cache();
65                 images_map::iterator img_i = m_images.find(url.c_str());
66                 if(img_i != m_images.end())
67                 {
68                         if(img_i->second)
69                         {
70                                 draw_txdib((cairo_t*) hdc, img_i->second, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height);
71                         }
72                 }
73                 unlock_images_cache();*/
74         } else
75         {
76                 switch(marker.marker_type)
77                 {
78                 case litehtml::list_style_type_circle:
79                         {
80                                 draw_ellipse((cairo_t*) hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color, 0.5);
81                         }
82                         break;
83                 case litehtml::list_style_type_disc:
84                         {
85                                 fill_ellipse((cairo_t*) hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color);
86                         }
87                         break;
88                 case litehtml::list_style_type_square:
89                         if(hdc)
90                         {
91                                 cairo_t* cr = (cairo_t*) hdc;
92                                 cairo_save(cr);
93
94                                 cairo_new_path(cr);
95                                 cairo_rectangle(cr, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height);
96
97                                 set_color(cr, marker.color);
98                                 cairo_fill(cr);
99                                 cairo_restore(cr);
100                         }
101                         break;
102                 default:
103                         /*do nothing*/
104                         break;
105                 }
106         }
107 }
108
109 void container_linux::draw_background( litehtml::uint_ptr hdc, const litehtml::background_paint& bg )
110 {
111         cairo_t* cr = (cairo_t*) hdc;
112         cairo_save(cr);
113         apply_clip(cr);
114
115         rounded_rectangle(cr, bg.border_box, bg.border_radius);
116         cairo_clip(cr);
117
118         cairo_rectangle(cr, bg.clip_box.x, bg.clip_box.y, bg.clip_box.width, bg.clip_box.height);
119         cairo_clip(cr);
120
121         if(bg.color.alpha)
122         {
123                 set_color(cr, bg.color);
124                 cairo_paint(cr);
125         }
126
127         litehtml::tstring url;
128         make_url(bg.image.c_str(), bg.baseurl.c_str(), url);
129
130         lock_images_cache();
131
132         auto i = m_images.find(url);
133         if(i != m_images.end() && i->second.first)
134         {
135                 GdkPixbuf *bgbmp = i->second.first;
136
137                 GdkPixbuf *new_img;
138                 if(bg.image_size.width != gdk_pixbuf_get_width(bgbmp) || bg.image_size.height != gdk_pixbuf_get_height(bgbmp))
139                 {
140                         new_img = gdk_pixbuf_scale_simple(bgbmp, bg.image_size.width, bg.image_size.height, GDK_INTERP_BILINEAR);
141                         bgbmp = new_img;
142                 }
143
144                 cairo_surface_t* img = surface_from_pixbuf(bgbmp);
145                 cairo_pattern_t *pattern = cairo_pattern_create_for_surface(img);
146                 cairo_matrix_t flib_m;
147                 cairo_matrix_init_identity(&flib_m);
148                 cairo_matrix_translate(&flib_m, -bg.position_x, -bg.position_y);
149                 cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
150                 cairo_pattern_set_matrix (pattern, &flib_m);
151
152                 switch(bg.repeat)
153                 {
154                 case litehtml::background_repeat_no_repeat:
155                         draw_pixbuf(cr, bgbmp, bg.position_x, bg.position_y, gdk_pixbuf_get_width(bgbmp), gdk_pixbuf_get_height(bgbmp));
156                         break;
157
158                 case litehtml::background_repeat_repeat_x:
159                         cairo_set_source(cr, pattern);
160                         cairo_rectangle(cr, bg.clip_box.left(), bg.position_y, bg.clip_box.width, gdk_pixbuf_get_height(bgbmp));
161                         cairo_fill(cr);
162                         break;
163
164                 case litehtml::background_repeat_repeat_y:
165                         cairo_set_source(cr, pattern);
166                         cairo_rectangle(cr, bg.position_x, bg.clip_box.top(), gdk_pixbuf_get_width(bgbmp), bg.clip_box.height);
167                         cairo_fill(cr);
168                         break;
169
170                 case litehtml::background_repeat_repeat:
171                         cairo_set_source(cr, pattern);
172                         cairo_rectangle(cr, bg.clip_box.left(), bg.clip_box.top(), bg.clip_box.width, bg.clip_box.height);
173                         cairo_fill(cr);
174                         break;
175                 }
176
177                 cairo_pattern_destroy(pattern);
178                 cairo_surface_destroy(img);
179
180         }
181
182         unlock_images_cache();
183         cairo_restore(cr);
184 }
185
186 void container_linux::make_url(const litehtml::tchar_t* url,    const litehtml::tchar_t* basepath, litehtml::tstring& out)
187 {
188         out = url;
189 }
190
191 void container_linux::add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg)
192 {
193         if(rx > 0 && ry > 0)
194         {
195
196                 cairo_save(cr);
197
198                 cairo_translate(cr, x, y);
199                 cairo_scale(cr, 1, ry / rx);
200                 cairo_translate(cr, -x, -y);
201
202                 if(neg)
203                 {
204                         cairo_arc_negative(cr, x, y, rx, a1, a2);
205                 } else
206                 {
207                         cairo_arc(cr, x, y, rx, a1, a2);
208                 }
209
210                 cairo_restore(cr);
211         } else
212         {
213                 cairo_move_to(cr, x, y);
214         }
215 }
216
217 void container_linux::draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root)
218 {
219         cairo_t* cr = (cairo_t*) hdc;
220         cairo_save(cr);
221         apply_clip(cr);
222
223         cairo_new_path(cr);
224
225         int bdr_top             = 0;
226         int bdr_bottom  = 0;
227         int bdr_left    = 0;
228         int bdr_right   = 0;
229
230         if(borders.top.width != 0 && borders.top.style > litehtml::border_style_hidden)
231         {
232                 bdr_top = (int) borders.top.width;
233         }
234         if(borders.bottom.width != 0 && borders.bottom.style > litehtml::border_style_hidden)
235         {
236                 bdr_bottom = (int) borders.bottom.width;
237         }
238         if(borders.left.width != 0 && borders.left.style > litehtml::border_style_hidden)
239         {
240                 bdr_left = (int) borders.left.width;
241         }
242         if(borders.right.width != 0 && borders.right.style > litehtml::border_style_hidden)
243         {
244                 bdr_right = (int) borders.right.width;
245         }
246
247         // draw right border
248         if(bdr_right)
249         {
250                 set_color(cr, borders.right.color);
251
252                 double r_top    = borders.radius.top_right_x;
253                 double r_bottom = borders.radius.bottom_right_x;
254
255                 if(r_top)
256                 {
257                         double end_angle        = 2 * M_PI;
258                         double start_angle      = end_angle - M_PI / 2.0  / ((double) bdr_top / (double) bdr_right + 1);
259
260                         add_path_arc(cr,
261                                 draw_pos.right() - r_top,
262                                 draw_pos.top() + r_top,
263                                 r_top - bdr_right,
264                                 r_top - bdr_right + (bdr_right - bdr_top),
265                                 end_angle,
266                                 start_angle, true);
267
268                         add_path_arc(cr,
269                                 draw_pos.right() - r_top,
270                                 draw_pos.top() + r_top,
271                                 r_top,
272                                 r_top,
273                                 start_angle,
274                                 end_angle, false);
275                 } else
276                 {
277                         cairo_move_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top);
278                         cairo_line_to(cr, draw_pos.right(), draw_pos.top());
279                 }
280
281                 if(r_bottom)
282                 {
283                         cairo_line_to(cr, draw_pos.right(),     draw_pos.bottom() - r_bottom);
284
285                         double start_angle      = 0;
286                         double end_angle        = start_angle + M_PI / 2.0  / ((double) bdr_bottom / (double) bdr_right + 1);
287
288                         add_path_arc(cr,
289                                 draw_pos.right() - r_bottom,
290                                 draw_pos.bottom() - r_bottom,
291                                 r_bottom,
292                                 r_bottom,
293                                 start_angle,
294                                 end_angle, false);
295
296                         add_path_arc(cr,
297                                 draw_pos.right() - r_bottom,
298                                 draw_pos.bottom() - r_bottom,
299                                 r_bottom - bdr_right,
300                                 r_bottom - bdr_right + (bdr_right - bdr_bottom),
301                                 end_angle,
302                                 start_angle, true);
303                 } else
304                 {
305                         cairo_line_to(cr, draw_pos.right(),     draw_pos.bottom());
306                         cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom);
307                 }
308
309                 cairo_fill(cr);
310         }
311
312         // draw bottom border
313         if(bdr_bottom)
314         {
315                 set_color(cr, borders.bottom.color);
316
317                 double r_left   = borders.radius.bottom_left_x;
318                 double r_right  = borders.radius.bottom_right_x;
319
320                 if(r_left)
321                 {
322                         double start_angle      = M_PI / 2.0;
323                         double end_angle        = start_angle + M_PI / 2.0  / ((double) bdr_left / (double) bdr_bottom + 1);
324
325                         add_path_arc(cr,
326                                 draw_pos.left() + r_left,
327                                 draw_pos.bottom() - r_left,
328                                 r_left - bdr_bottom + (bdr_bottom - bdr_left),
329                                 r_left - bdr_bottom,
330                                 start_angle,
331                                 end_angle, false);
332
333                         add_path_arc(cr,
334                                 draw_pos.left() + r_left,
335                                 draw_pos.bottom() - r_left,
336                                 r_left,
337                                 r_left,
338                                 end_angle,
339                                 start_angle, true);
340                 } else
341                 {
342                         cairo_move_to(cr, draw_pos.left(), draw_pos.bottom());
343                         cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom);
344                 }
345
346                 if(r_right)
347                 {
348                         cairo_line_to(cr, draw_pos.right() - r_right,   draw_pos.bottom());
349
350                         double end_angle        = M_PI / 2.0;
351                         double start_angle      = end_angle - M_PI / 2.0  / ((double) bdr_right / (double) bdr_bottom + 1);
352
353                         add_path_arc(cr,
354                                 draw_pos.right() - r_right,
355                                 draw_pos.bottom() - r_right,
356                                 r_right,
357                                 r_right,
358                                 end_angle,
359                                 start_angle, true);
360
361                         add_path_arc(cr,
362                                 draw_pos.right() - r_right,
363                                 draw_pos.bottom() - r_right,
364                                 r_right - bdr_bottom + (bdr_bottom - bdr_right),
365                                 r_right - bdr_bottom,
366                                 start_angle,
367                                 end_angle, false);
368                 } else
369                 {
370                         cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom);
371                         cairo_line_to(cr, draw_pos.right(),     draw_pos.bottom());
372                 }
373
374                 cairo_fill(cr);
375         }
376
377         // draw top border
378         if(bdr_top)
379         {
380                 set_color(cr, borders.top.color);
381
382                 double r_left   = borders.radius.top_left_x;
383                 double r_right  = borders.radius.top_right_x;
384
385                 if(r_left)
386                 {
387                         double end_angle        = M_PI * 3.0 / 2.0;
388                         double start_angle      = end_angle - M_PI / 2.0  / ((double) bdr_left / (double) bdr_top + 1);
389
390                         add_path_arc(cr,
391                                 draw_pos.left() + r_left,
392                                 draw_pos.top() + r_left,
393                                 r_left,
394                                 r_left,
395                                 end_angle,
396                                 start_angle, true);
397
398                         add_path_arc(cr,
399                                 draw_pos.left() + r_left,
400                                 draw_pos.top() + r_left,
401                                 r_left - bdr_top + (bdr_top - bdr_left),
402                                 r_left - bdr_top,
403                                 start_angle,
404                                 end_angle, false);
405                 } else
406                 {
407                         cairo_move_to(cr, draw_pos.left(), draw_pos.top());
408                         cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top);
409                 }
410
411                 if(r_right)
412                 {
413                         cairo_line_to(cr, draw_pos.right() - r_right,   draw_pos.top() + bdr_top);
414
415                         double start_angle      = M_PI * 3.0 / 2.0;
416                         double end_angle        = start_angle + M_PI / 2.0  / ((double) bdr_right / (double) bdr_top + 1);
417
418                         add_path_arc(cr,
419                                 draw_pos.right() - r_right,
420                                 draw_pos.top() + r_right,
421                                 r_right - bdr_top + (bdr_top - bdr_right),
422                                 r_right - bdr_top,
423                                 start_angle,
424                                 end_angle, false);
425
426                         add_path_arc(cr,
427                                 draw_pos.right() - r_right,
428                                 draw_pos.top() + r_right,
429                                 r_right,
430                                 r_right,
431                                 end_angle,
432                                 start_angle, true);
433                 } else
434                 {
435                         cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top);
436                         cairo_line_to(cr, draw_pos.right(),     draw_pos.top());
437                 }
438
439                 cairo_fill(cr);
440         }
441
442         // draw left border
443         if(bdr_left)
444         {
445                 set_color(cr, borders.left.color);
446
447                 double r_top    = borders.radius.top_left_x;
448                 double r_bottom = borders.radius.bottom_left_x;
449
450                 if(r_top)
451                 {
452                         double start_angle      = M_PI;
453                         double end_angle        = start_angle + M_PI / 2.0  / ((double) bdr_top / (double) bdr_left + 1);
454
455                         add_path_arc(cr,
456                                 draw_pos.left() + r_top,
457                                 draw_pos.top() + r_top,
458                                 r_top - bdr_left,
459                                 r_top - bdr_left + (bdr_left - bdr_top),
460                                 start_angle,
461                                 end_angle, false);
462
463                         add_path_arc(cr,
464                                 draw_pos.left() + r_top,
465                                 draw_pos.top() + r_top,
466                                 r_top,
467                                 r_top,
468                                 end_angle,
469                                 start_angle, true);
470                 } else
471                 {
472                         cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top);
473                         cairo_line_to(cr, draw_pos.left(), draw_pos.top());
474                 }
475
476                 if(r_bottom)
477                 {
478                         cairo_line_to(cr, draw_pos.left(),      draw_pos.bottom() - r_bottom);
479
480                         double end_angle        = M_PI;
481                         double start_angle      = end_angle - M_PI / 2.0  / ((double) bdr_bottom / (double) bdr_left + 1);
482
483                         add_path_arc(cr,
484                                 draw_pos.left() + r_bottom,
485                                 draw_pos.bottom() - r_bottom,
486                                 r_bottom,
487                                 r_bottom,
488                                 end_angle,
489                                 start_angle, true);
490
491                         add_path_arc(cr,
492                                 draw_pos.left() + r_bottom,
493                                 draw_pos.bottom() - r_bottom,
494                                 r_bottom - bdr_left,
495                                 r_bottom - bdr_left + (bdr_left - bdr_bottom),
496                                 start_angle,
497                                 end_angle, false);
498                 } else
499                 {
500                         cairo_line_to(cr, draw_pos.left(),      draw_pos.bottom());
501                         cairo_line_to(cr, draw_pos.left() + bdr_left,   draw_pos.bottom() - bdr_bottom);
502                 }
503
504                 cairo_fill(cr);
505         }
506         cairo_restore(cr);
507 }
508
509 void container_linux::transform_text(litehtml::tstring& text, litehtml::text_transform tt)
510 {
511
512 }
513
514 void container_linux::set_clip( const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y )
515 {
516         litehtml::position clip_pos = pos;
517         litehtml::position client_pos;
518         get_client_rect(client_pos);
519         if(!valid_x)
520         {
521                 clip_pos.x              = client_pos.x;
522                 clip_pos.width  = client_pos.width;
523         }
524         if(!valid_y)
525         {
526                 clip_pos.y              = client_pos.y;
527                 clip_pos.height = client_pos.height;
528         }
529         m_clips.emplace_back(clip_pos, bdr_radius);
530 }
531
532 void container_linux::del_clip()
533 {
534         if(!m_clips.empty())
535         {
536                 m_clips.pop_back();
537         }
538 }
539
540 void container_linux::apply_clip( cairo_t* cr )
541 {
542         for(const auto& clip_box : m_clips)
543         {
544                 rounded_rectangle(cr, clip_box.box, clip_box.radius);
545                 cairo_clip(cr);
546         }
547 }
548
549 void container_linux::draw_ellipse( cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, int line_width )
550 {
551         if(!cr) return;
552         cairo_save(cr);
553
554         apply_clip(cr);
555
556         cairo_new_path(cr);
557
558         cairo_translate (cr, x + width / 2.0, y + height / 2.0);
559         cairo_scale (cr, width / 2.0, height / 2.0);
560         cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI);
561
562         set_color(cr, color);
563         cairo_set_line_width(cr, line_width);
564         cairo_stroke(cr);
565
566         cairo_restore(cr);
567 }
568
569 void container_linux::fill_ellipse( cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color )
570 {
571         if(!cr) return;
572         cairo_save(cr);
573
574         apply_clip(cr);
575
576         cairo_new_path(cr);
577
578         cairo_translate (cr, x + width / 2.0, y + height / 2.0);
579         cairo_scale (cr, width / 2.0, height / 2.0);
580         cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI);
581
582         set_color(cr, color);
583         cairo_fill(cr);
584
585         cairo_restore(cr);
586 }
587
588 std::shared_ptr<litehtml::element>      container_linux::create_element(const litehtml::tchar_t *tag_name,
589                                                                                                                                           const litehtml::string_map &attributes,
590                                                                                                                                           const std::shared_ptr<litehtml::document> &doc)
591 {
592         return 0;
593 }
594
595 void container_linux::rounded_rectangle( cairo_t* cr, const litehtml::position &pos, const litehtml::border_radiuses &radius )
596 {
597         cairo_new_path(cr);
598         if(radius.top_left_x)
599         {
600                 cairo_arc(cr, pos.left() + radius.top_left_x, pos.top() + radius.top_left_x, radius.top_left_x, M_PI, M_PI * 3.0 / 2.0);
601         } else
602         {
603                 cairo_move_to(cr, pos.left(), pos.top());
604         }
605
606         cairo_line_to(cr, pos.right() - radius.top_right_x, pos.top());
607
608         if(radius.top_right_x)
609         {
610                 cairo_arc(cr, pos.right() - radius.top_right_x, pos.top() + radius.top_right_x, radius.top_right_x, M_PI * 3.0 / 2.0, 2.0 * M_PI);
611         }
612
613         cairo_line_to(cr, pos.right(), pos.bottom() - radius.bottom_right_x);
614
615         if(radius.bottom_right_x)
616         {
617                 cairo_arc(cr, pos.right() - radius.bottom_right_x, pos.bottom() - radius.bottom_right_x, radius.bottom_right_x, 0, M_PI / 2.0);
618         }
619
620         cairo_line_to(cr, pos.left() - radius.bottom_left_x, pos.bottom());
621
622         if(radius.bottom_left_x)
623         {
624                 cairo_arc(cr, pos.left() + radius.bottom_left_x, pos.bottom() - radius.bottom_left_x, radius.bottom_left_x, M_PI / 2.0, M_PI);
625         }
626 }
627
628 void container_linux::draw_pixbuf(cairo_t* cr, const GdkPixbuf *bmp, int x,     int y, int cx, int cy)
629 {
630         cairo_save(cr);
631
632         {
633                 cairo_matrix_t flib_m;
634                 cairo_matrix_init(&flib_m, 1, 0, 0, -1, 0, 0);
635
636                 if(cx != gdk_pixbuf_get_width(bmp) || cy != gdk_pixbuf_get_height(bmp))
637                 {
638                         GdkPixbuf *new_img = gdk_pixbuf_scale_simple(bmp, cx, cy, GDK_INTERP_BILINEAR);
639                         gdk_cairo_set_source_pixbuf(cr, new_img, x, y);
640                         cairo_paint(cr);
641                 } else
642                 {
643                         gdk_cairo_set_source_pixbuf(cr, bmp, x, y);
644                         cairo_paint(cr);
645                 }
646         }
647
648         cairo_restore(cr);
649 }
650
651 cairo_surface_t* container_linux::surface_from_pixbuf(const GdkPixbuf *bmp)
652 {
653         cairo_surface_t* ret = NULL;
654
655         if(gdk_pixbuf_get_has_alpha(bmp))
656         {
657                 ret = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, gdk_pixbuf_get_width(bmp), gdk_pixbuf_get_height(bmp));
658         } else
659         {
660                 ret = cairo_image_surface_create(CAIRO_FORMAT_RGB24, gdk_pixbuf_get_width(bmp), gdk_pixbuf_get_height(bmp));
661         }
662
663 //      Cairo::RefPtr<Cairo::Surface> surface(new Cairo::Surface(ret, false));
664 //      Cairo::RefPtr<Cairo::Context> ctx = Cairo::Context::create(surface);
665 //      Gdk::Cairo::set_source_pixbuf(ctx, bmp, 0.0, 0.0);
666         cairo_t *ctx = cairo_create(ret);
667         cairo_paint(ctx);
668         cairo_destroy(ctx);
669
670         return ret;
671 }
672
673 void container_linux::get_media_features(litehtml::media_features& media) const
674 {
675         litehtml::position client;
676     get_client_rect(client);
677         media.type                      = litehtml::media_type_screen;
678         media.width                     = client.width;
679         media.height            = client.height;
680         media.device_width      = gdk_screen_width();
681         media.device_height     = gdk_screen_height();
682         media.color                     = 8;
683         media.monochrome        = 0;
684         media.color_index       = 256;
685         media.resolution        = 96;
686 }
687
688 void container_linux::get_language(litehtml::tstring& language, litehtml::tstring& culture) const
689 {
690         language = _t("en");
691         culture = _t("");
692 }
693
694 void container_linux::link(const std::shared_ptr<litehtml::document> &ptr, const litehtml::element::ptr& el)
695 {
696
697 }