1 #include "container_linux.h"
2 #define _USE_MATH_DEFINES
3 #include <math.h>
4
5 #ifndef M_PI
6 # define M_PI 3.14159265358979323846
7 #endif
8
container_linux(void)9 container_linux::container_linux(void)
10 {
11 m_temp_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 2, 2);
12 m_temp_cr = cairo_create(m_temp_surface);
13 }
14
~container_linux(void)15 container_linux::~container_linux(void)
16 {
17 clear_images();
18 cairo_surface_destroy(m_temp_surface);
19 cairo_destroy(m_temp_cr);
20 }
21
create_font(const litehtml::tchar_t * faceName,int size,int weight,litehtml::font_style italic,unsigned int decoration,litehtml::font_metrics * fm)22 litehtml::uint_ptr container_linux::create_font( const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm )
23 {
24 litehtml::string_vector fonts;
25 litehtml::split_string(faceName, fonts, ",");
26 litehtml::trim(fonts[0]);
27
28 cairo_font_face_t* fnt = 0;
29
30 FcPattern *pattern = FcPatternCreate();
31 bool found = false;
32 for(litehtml::string_vector::iterator i = fonts.begin(); i != fonts.end(); i++)
33 {
34 if(FcPatternAddString(pattern, FC_FAMILY, (unsigned char *) i->c_str()))
35 {
36 found = true;
37 break;
38 }
39 }
40 if(found)
41 {
42 if(italic == litehtml::fontStyleItalic )
43 {
44 FcPatternAddInteger (pattern, FC_SLANT, FC_SLANT_ITALIC);
45 } else
46 {
47 FcPatternAddInteger (pattern, FC_SLANT, FC_SLANT_ROMAN);
48 }
49
50 int fc_weight = FC_WEIGHT_NORMAL;
51 if(weight >= 0 && weight < 150) fc_weight = FC_WEIGHT_THIN;
52 else if(weight >= 150 && weight < 250) fc_weight = FC_WEIGHT_EXTRALIGHT;
53 else if(weight >= 250 && weight < 350) fc_weight = FC_WEIGHT_LIGHT;
54 else if(weight >= 350 && weight < 450) fc_weight = FC_WEIGHT_NORMAL;
55 else if(weight >= 450 && weight < 550) fc_weight = FC_WEIGHT_MEDIUM;
56 else if(weight >= 550 && weight < 650) fc_weight = FC_WEIGHT_SEMIBOLD;
57 else if(weight >= 650 && weight < 750) fc_weight = FC_WEIGHT_BOLD;
58 else if(weight >= 750 && weight < 850) fc_weight = FC_WEIGHT_EXTRABOLD;
59 else if(weight >= 950) fc_weight = FC_WEIGHT_BLACK;
60
61 FcPatternAddInteger (pattern, FC_WEIGHT, fc_weight);
62
63 fnt = cairo_ft_font_face_create_for_pattern(pattern);
64 }
65
66 FcPatternDestroy(pattern);
67
68 cairo_font* ret = 0;
69
70 if(fm && fnt)
71 {
72 cairo_save(m_temp_cr);
73
74 cairo_set_font_face(m_temp_cr, fnt);
75 cairo_set_font_size(m_temp_cr, size);
76 cairo_font_extents_t ext;
77 cairo_font_extents(m_temp_cr, &ext);
78
79 cairo_text_extents_t tex;
80 cairo_text_extents(m_temp_cr, "x", &tex);
81
82 fm->ascent = (int) ext.ascent;
83 fm->descent = (int) ext.descent;
84 fm->height = (int) (ext.ascent + ext.descent);
85 fm->x_height = (int) tex.height;
86
87 cairo_restore(m_temp_cr);
88
89 ret = new cairo_font;
90 ret->font = fnt;
91 ret->size = size;
92 ret->strikeout = (decoration & litehtml::font_decoration_linethrough) ? true : false;
93 ret->underline = (decoration & litehtml::font_decoration_underline) ? true : false;
94
95 }
96
97 return (litehtml::uint_ptr) ret;
98 }
99
delete_font(litehtml::uint_ptr hFont)100 void container_linux::delete_font( litehtml::uint_ptr hFont )
101 {
102 cairo_font* fnt = (cairo_font*) hFont;
103 if(fnt)
104 {
105 cairo_font_face_destroy(fnt->font);
106 delete fnt;
107 }
108 }
109
text_width(const litehtml::tchar_t * text,litehtml::uint_ptr hFont)110 int container_linux::text_width( const litehtml::tchar_t* text, litehtml::uint_ptr hFont )
111 {
112 cairo_font* fnt = (cairo_font*) hFont;
113
114 cairo_save(m_temp_cr);
115
116 cairo_set_font_size(m_temp_cr, fnt->size);
117 cairo_set_font_face(m_temp_cr, fnt->font);
118 cairo_text_extents_t ext;
119 cairo_text_extents(m_temp_cr, text, &ext);
120
121 cairo_restore(m_temp_cr);
122
123 return (int) ext.x_advance;
124 }
125
draw_text(litehtml::uint_ptr hdc,const litehtml::tchar_t * text,litehtml::uint_ptr hFont,litehtml::web_color color,const litehtml::position & pos)126 void container_linux::draw_text( litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos )
127 {
128 cairo_font* fnt = (cairo_font*) hFont;
129 cairo_t* cr = (cairo_t*) hdc;
130 cairo_save(cr);
131
132 apply_clip(cr);
133
134 cairo_set_font_face(cr, fnt->font);
135 cairo_set_font_size(cr, fnt->size);
136 cairo_font_extents_t ext;
137 cairo_font_extents(cr, &ext);
138
139 int x = pos.left();
140 int y = pos.bottom() - ext.descent;
141
142 set_color(cr, color);
143
144 cairo_move_to(cr, x, y);
145 cairo_show_text(cr, text);
146
147 int tw = 0;
148
149 if(fnt->underline || fnt->strikeout)
150 {
151 tw = text_width(text, hFont);
152 }
153
154 if(fnt->underline)
155 {
156 cairo_set_line_width(cr, 1);
157 cairo_move_to(cr, x, y + 1.5);
158 cairo_line_to(cr, x + tw, y + 1.5);
159 cairo_stroke(cr);
160 }
161 if(fnt->strikeout)
162 {
163 cairo_text_extents_t tex;
164 cairo_text_extents(cr, "x", &tex);
165
166 int ln_y = y - tex.height / 2.0;
167
168 cairo_set_line_width(cr, 1);
169 cairo_move_to(cr, x, (double) ln_y - 0.5);
170 cairo_line_to(cr, x + tw, (double) ln_y - 0.5);
171 cairo_stroke(cr);
172 }
173
174 cairo_restore(cr);
175 }
176
pt_to_px(int pt)177 int container_linux::pt_to_px( int pt )
178 {
179 GdkScreen* screen = gdk_screen_get_default();
180 double dpi = gdk_screen_get_resolution(screen);
181
182 return (int) ((double) pt * dpi / 72.0);
183 }
184
get_default_font_size() const185 int container_linux::get_default_font_size() const
186 {
187 return 16;
188 }
189
draw_list_marker(litehtml::uint_ptr hdc,const litehtml::list_marker & marker)190 void container_linux::draw_list_marker( litehtml::uint_ptr hdc, const litehtml::list_marker& marker )
191 {
192 if(!marker.image.empty())
193 {
194 /*litehtml::tstring url;
195 make_url(marker.image.c_str(), marker.baseurl, url);
196
197 lock_images_cache();
198 images_map::iterator img_i = m_images.find(url.c_str());
199 if(img_i != m_images.end())
200 {
201 if(img_i->second)
202 {
203 draw_txdib((cairo_t*) hdc, img_i->second, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height);
204 }
205 }
206 unlock_images_cache();*/
207 } else
208 {
209 switch(marker.marker_type)
210 {
211 case litehtml::list_style_type_circle:
212 {
213 draw_ellipse((cairo_t*) hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color, 0.5);
214 }
215 break;
216 case litehtml::list_style_type_disc:
217 {
218 fill_ellipse((cairo_t*) hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color);
219 }
220 break;
221 case litehtml::list_style_type_square:
222 if(hdc)
223 {
224 cairo_t* cr = (cairo_t*) hdc;
225 cairo_save(cr);
226
227 cairo_new_path(cr);
228 cairo_rectangle(cr, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height);
229
230 set_color(cr, marker.color);
231 cairo_fill(cr);
232 cairo_restore(cr);
233 }
234 break;
235 default:
236 /*do nothing*/
237 break;
238 }
239 }
240 }
241
load_image(const litehtml::tchar_t * src,const litehtml::tchar_t * baseurl,bool redraw_on_ready)242 void container_linux::load_image( const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready )
243 {
244 litehtml::tstring url;
245 make_url(src, baseurl, url);
246 if(m_images.find(url.c_str()) == m_images.end())
247 {
248 try
249 {
250 Glib::RefPtr<Gdk::Pixbuf> img = get_image(url.c_str(), true);
251 if(img)
252 {
253 m_images[url.c_str()] = img;
254 }
255 } catch(...)
256 {
257 int iii=0;
258 iii++;
259 }
260 }
261 }
262
get_image_size(const litehtml::tchar_t * src,const litehtml::tchar_t * baseurl,litehtml::size & sz)263 void container_linux::get_image_size( const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz )
264 {
265 litehtml::tstring url;
266 make_url(src, baseurl, url);
267
268 images_map::iterator img = m_images.find(url.c_str());
269 if(img != m_images.end())
270 {
271 sz.width = img->second->get_width();
272 sz.height = img->second->get_height();
273 } else
274 {
275 sz.width = 0;
276 sz.height = 0;
277 }
278 }
279
draw_background(litehtml::uint_ptr hdc,const litehtml::background_paint & bg)280 void container_linux::draw_background( litehtml::uint_ptr hdc, const litehtml::background_paint& bg )
281 {
282 cairo_t* cr = (cairo_t*) hdc;
283 cairo_save(cr);
284 apply_clip(cr);
285
286 rounded_rectangle(cr, bg.border_box, bg.border_radius);
287 cairo_clip(cr);
288
289 cairo_rectangle(cr, bg.clip_box.x, bg.clip_box.y, bg.clip_box.width, bg.clip_box.height);
290 cairo_clip(cr);
291
292 if(bg.color.alpha)
293 {
294 set_color(cr, bg.color);
295 cairo_paint(cr);
296 }
297
298 litehtml::tstring url;
299 make_url(bg.image.c_str(), bg.baseurl.c_str(), url);
300
301 //lock_images_cache();
302 images_map::iterator img_i = m_images.find(url.c_str());
303 if(img_i != m_images.end() && img_i->second)
304 {
305 Glib::RefPtr<Gdk::Pixbuf> bgbmp = img_i->second;
306
307 Glib::RefPtr<Gdk::Pixbuf> new_img;
308 if(bg.image_size.width != bgbmp->get_width() || bg.image_size.height != bgbmp->get_height())
309 {
310 new_img = bgbmp->scale_simple(bg.image_size.width, bg.image_size.height, Gdk::INTERP_BILINEAR);
311 bgbmp = new_img;
312 }
313
314 cairo_surface_t* img = surface_from_pixbuf(bgbmp);
315 cairo_pattern_t *pattern = cairo_pattern_create_for_surface(img);
316 cairo_matrix_t flib_m;
317 cairo_matrix_init_identity(&flib_m);
318 cairo_matrix_translate(&flib_m, -bg.position_x, -bg.position_y);
319 cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
320 cairo_pattern_set_matrix (pattern, &flib_m);
321
322 switch(bg.repeat)
323 {
324 case litehtml::background_repeat_no_repeat:
325 draw_pixbuf(cr, bgbmp, bg.position_x, bg.position_y, bgbmp->get_width(), bgbmp->get_height());
326 break;
327
328 case litehtml::background_repeat_repeat_x:
329 cairo_set_source(cr, pattern);
330 cairo_rectangle(cr, bg.clip_box.left(), bg.position_y, bg.clip_box.width, bgbmp->get_height());
331 cairo_fill(cr);
332 break;
333
334 case litehtml::background_repeat_repeat_y:
335 cairo_set_source(cr, pattern);
336 cairo_rectangle(cr, bg.position_x, bg.clip_box.top(), bgbmp->get_width(), bg.clip_box.height);
337 cairo_fill(cr);
338 break;
339
340 case litehtml::background_repeat_repeat:
341 cairo_set_source(cr, pattern);
342 cairo_rectangle(cr, bg.clip_box.left(), bg.clip_box.top(), bg.clip_box.width, bg.clip_box.height);
343 cairo_fill(cr);
344 break;
345 }
346
347 cairo_pattern_destroy(pattern);
348 cairo_surface_destroy(img);
349
350 }
351 // unlock_images_cache();
352 cairo_restore(cr);
353 }
354
make_url(const litehtml::tchar_t * url,const litehtml::tchar_t * basepath,litehtml::tstring & out)355 void container_linux::make_url(const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out)
356 {
357 out = url;
358 }
359
add_path_arc(cairo_t * cr,double x,double y,double rx,double ry,double a1,double a2,bool neg)360 void container_linux::add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg)
361 {
362 if(rx > 0 && ry > 0)
363 {
364
365 cairo_save(cr);
366
367 cairo_translate(cr, x, y);
368 cairo_scale(cr, 1, ry / rx);
369 cairo_translate(cr, -x, -y);
370
371 if(neg)
372 {
373 cairo_arc_negative(cr, x, y, rx, a1, a2);
374 } else
375 {
376 cairo_arc(cr, x, y, rx, a1, a2);
377 }
378
379 cairo_restore(cr);
380 } else
381 {
382 cairo_move_to(cr, x, y);
383 }
384 }
385
draw_borders(litehtml::uint_ptr hdc,const litehtml::borders & borders,const litehtml::position & draw_pos,bool root)386 void container_linux::draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root)
387 {
388 cairo_t* cr = (cairo_t*) hdc;
389 cairo_save(cr);
390 apply_clip(cr);
391
392 cairo_new_path(cr);
393
394 int bdr_top = 0;
395 int bdr_bottom = 0;
396 int bdr_left = 0;
397 int bdr_right = 0;
398
399 if(borders.top.width != 0 && borders.top.style > litehtml::border_style_hidden)
400 {
401 bdr_top = (int) borders.top.width;
402 }
403 if(borders.bottom.width != 0 && borders.bottom.style > litehtml::border_style_hidden)
404 {
405 bdr_bottom = (int) borders.bottom.width;
406 }
407 if(borders.left.width != 0 && borders.left.style > litehtml::border_style_hidden)
408 {
409 bdr_left = (int) borders.left.width;
410 }
411 if(borders.right.width != 0 && borders.right.style > litehtml::border_style_hidden)
412 {
413 bdr_right = (int) borders.right.width;
414 }
415
416 // draw right border
417 if(bdr_right)
418 {
419 set_color(cr, borders.right.color);
420
421 double r_top = borders.radius.top_right_x;
422 double r_bottom = borders.radius.bottom_right_x;
423
424 if(r_top)
425 {
426 double end_angle = 2 * M_PI;
427 double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_top / (double) bdr_right + 1);
428
429 add_path_arc(cr,
430 draw_pos.right() - r_top,
431 draw_pos.top() + r_top,
432 r_top - bdr_right,
433 r_top - bdr_right + (bdr_right - bdr_top),
434 end_angle,
435 start_angle, true);
436
437 add_path_arc(cr,
438 draw_pos.right() - r_top,
439 draw_pos.top() + r_top,
440 r_top,
441 r_top,
442 start_angle,
443 end_angle, false);
444 } else
445 {
446 cairo_move_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top);
447 cairo_line_to(cr, draw_pos.right(), draw_pos.top());
448 }
449
450 if(r_bottom)
451 {
452 cairo_line_to(cr, draw_pos.right(), draw_pos.bottom() - r_bottom);
453
454 double start_angle = 0;
455 double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_bottom / (double) bdr_right + 1);
456
457 add_path_arc(cr,
458 draw_pos.right() - r_bottom,
459 draw_pos.bottom() - r_bottom,
460 r_bottom,
461 r_bottom,
462 start_angle,
463 end_angle, false);
464
465 add_path_arc(cr,
466 draw_pos.right() - r_bottom,
467 draw_pos.bottom() - r_bottom,
468 r_bottom - bdr_right,
469 r_bottom - bdr_right + (bdr_right - bdr_bottom),
470 end_angle,
471 start_angle, true);
472 } else
473 {
474 cairo_line_to(cr, draw_pos.right(), draw_pos.bottom());
475 cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom);
476 }
477
478 cairo_fill(cr);
479 }
480
481 // draw bottom border
482 if(bdr_bottom)
483 {
484 set_color(cr, borders.bottom.color);
485
486 double r_left = borders.radius.bottom_left_x;
487 double r_right = borders.radius.bottom_right_x;
488
489 if(r_left)
490 {
491 double start_angle = M_PI / 2.0;
492 double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_left / (double) bdr_bottom + 1);
493
494 add_path_arc(cr,
495 draw_pos.left() + r_left,
496 draw_pos.bottom() - r_left,
497 r_left - bdr_bottom + (bdr_bottom - bdr_left),
498 r_left - bdr_bottom,
499 start_angle,
500 end_angle, false);
501
502 add_path_arc(cr,
503 draw_pos.left() + r_left,
504 draw_pos.bottom() - r_left,
505 r_left,
506 r_left,
507 end_angle,
508 start_angle, true);
509 } else
510 {
511 cairo_move_to(cr, draw_pos.left(), draw_pos.bottom());
512 cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom);
513 }
514
515 if(r_right)
516 {
517 cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.bottom());
518
519 double end_angle = M_PI / 2.0;
520 double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_right / (double) bdr_bottom + 1);
521
522 add_path_arc(cr,
523 draw_pos.right() - r_right,
524 draw_pos.bottom() - r_right,
525 r_right,
526 r_right,
527 end_angle,
528 start_angle, true);
529
530 add_path_arc(cr,
531 draw_pos.right() - r_right,
532 draw_pos.bottom() - r_right,
533 r_right - bdr_bottom + (bdr_bottom - bdr_right),
534 r_right - bdr_bottom,
535 start_angle,
536 end_angle, false);
537 } else
538 {
539 cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom);
540 cairo_line_to(cr, draw_pos.right(), draw_pos.bottom());
541 }
542
543 cairo_fill(cr);
544 }
545
546 // draw top border
547 if(bdr_top)
548 {
549 set_color(cr, borders.top.color);
550
551 double r_left = borders.radius.top_left_x;
552 double r_right = borders.radius.top_right_x;
553
554 if(r_left)
555 {
556 double end_angle = M_PI * 3.0 / 2.0;
557 double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_left / (double) bdr_top + 1);
558
559 add_path_arc(cr,
560 draw_pos.left() + r_left,
561 draw_pos.top() + r_left,
562 r_left,
563 r_left,
564 end_angle,
565 start_angle, true);
566
567 add_path_arc(cr,
568 draw_pos.left() + r_left,
569 draw_pos.top() + r_left,
570 r_left - bdr_top + (bdr_top - bdr_left),
571 r_left - bdr_top,
572 start_angle,
573 end_angle, false);
574 } else
575 {
576 cairo_move_to(cr, draw_pos.left(), draw_pos.top());
577 cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top);
578 }
579
580 if(r_right)
581 {
582 cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.top() + bdr_top);
583
584 double start_angle = M_PI * 3.0 / 2.0;
585 double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_right / (double) bdr_top + 1);
586
587 add_path_arc(cr,
588 draw_pos.right() - r_right,
589 draw_pos.top() + r_right,
590 r_right - bdr_top + (bdr_top - bdr_right),
591 r_right - bdr_top,
592 start_angle,
593 end_angle, false);
594
595 add_path_arc(cr,
596 draw_pos.right() - r_right,
597 draw_pos.top() + r_right,
598 r_right,
599 r_right,
600 end_angle,
601 start_angle, true);
602 } else
603 {
604 cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top);
605 cairo_line_to(cr, draw_pos.right(), draw_pos.top());
606 }
607
608 cairo_fill(cr);
609 }
610
611 // draw left border
612 if(bdr_left)
613 {
614 set_color(cr, borders.left.color);
615
616 double r_top = borders.radius.top_left_x;
617 double r_bottom = borders.radius.bottom_left_x;
618
619 if(r_top)
620 {
621 double start_angle = M_PI;
622 double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_top / (double) bdr_left + 1);
623
624 add_path_arc(cr,
625 draw_pos.left() + r_top,
626 draw_pos.top() + r_top,
627 r_top - bdr_left,
628 r_top - bdr_left + (bdr_left - bdr_top),
629 start_angle,
630 end_angle, false);
631
632 add_path_arc(cr,
633 draw_pos.left() + r_top,
634 draw_pos.top() + r_top,
635 r_top,
636 r_top,
637 end_angle,
638 start_angle, true);
639 } else
640 {
641 cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top);
642 cairo_line_to(cr, draw_pos.left(), draw_pos.top());
643 }
644
645 if(r_bottom)
646 {
647 cairo_line_to(cr, draw_pos.left(), draw_pos.bottom() - r_bottom);
648
649 double end_angle = M_PI;
650 double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_bottom / (double) bdr_left + 1);
651
652 add_path_arc(cr,
653 draw_pos.left() + r_bottom,
654 draw_pos.bottom() - r_bottom,
655 r_bottom,
656 r_bottom,
657 end_angle,
658 start_angle, true);
659
660 add_path_arc(cr,
661 draw_pos.left() + r_bottom,
662 draw_pos.bottom() - r_bottom,
663 r_bottom - bdr_left,
664 r_bottom - bdr_left + (bdr_left - bdr_bottom),
665 start_angle,
666 end_angle, false);
667 } else
668 {
669 cairo_line_to(cr, draw_pos.left(), draw_pos.bottom());
670 cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom);
671 }
672
673 cairo_fill(cr);
674 }
675 cairo_restore(cr);
676 }
677
transform_text(litehtml::tstring & text,litehtml::text_transform tt)678 void container_linux::transform_text(litehtml::tstring& text, litehtml::text_transform tt)
679 {
680
681 }
682
set_clip(const litehtml::position & pos,const litehtml::border_radiuses & bdr_radius,bool valid_x,bool valid_y)683 void container_linux::set_clip( const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y )
684 {
685 litehtml::position clip_pos = pos;
686 litehtml::position client_pos;
687 get_client_rect(client_pos);
688 if(!valid_x)
689 {
690 clip_pos.x = client_pos.x;
691 clip_pos.width = client_pos.width;
692 }
693 if(!valid_y)
694 {
695 clip_pos.y = client_pos.y;
696 clip_pos.height = client_pos.height;
697 }
698 m_clips.emplace_back(clip_pos, bdr_radius);
699 }
700
del_clip()701 void container_linux::del_clip()
702 {
703 if(!m_clips.empty())
704 {
705 m_clips.pop_back();
706 }
707 }
708
apply_clip(cairo_t * cr)709 void container_linux::apply_clip( cairo_t* cr )
710 {
711 for(const auto& clip_box : m_clips)
712 {
713 rounded_rectangle(cr, clip_box.box, clip_box.radius);
714 cairo_clip(cr);
715 }
716 }
717
draw_ellipse(cairo_t * cr,int x,int y,int width,int height,const litehtml::web_color & color,int line_width)718 void container_linux::draw_ellipse( cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, int line_width )
719 {
720 if(!cr) return;
721 cairo_save(cr);
722
723 apply_clip(cr);
724
725 cairo_new_path(cr);
726
727 cairo_translate (cr, x + width / 2.0, y + height / 2.0);
728 cairo_scale (cr, width / 2.0, height / 2.0);
729 cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI);
730
731 set_color(cr, color);
732 cairo_set_line_width(cr, line_width);
733 cairo_stroke(cr);
734
735 cairo_restore(cr);
736 }
737
fill_ellipse(cairo_t * cr,int x,int y,int width,int height,const litehtml::web_color & color)738 void container_linux::fill_ellipse( cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color )
739 {
740 if(!cr) return;
741 cairo_save(cr);
742
743 apply_clip(cr);
744
745 cairo_new_path(cr);
746
747 cairo_translate (cr, x + width / 2.0, y + height / 2.0);
748 cairo_scale (cr, width / 2.0, height / 2.0);
749 cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI);
750
751 set_color(cr, color);
752 cairo_fill(cr);
753
754 cairo_restore(cr);
755 }
756
clear_images()757 void container_linux::clear_images()
758 {
759 /* for(images_map::iterator i = m_images.begin(); i != m_images.end(); i++)
760 {
761 if(i->second)
762 {
763 delete i->second;
764 }
765 }
766 m_images.clear();
767 */
768 }
769
get_default_font_name() const770 const litehtml::tchar_t* container_linux::get_default_font_name() const
771 {
772 return "Times New Roman";
773 }
774
create_element(const litehtml::tchar_t * tag_name,const litehtml::string_map & attributes,const std::shared_ptr<litehtml::document> & doc)775 std::shared_ptr<litehtml::element> container_linux::create_element(const litehtml::tchar_t *tag_name,
776 const litehtml::string_map &attributes,
777 const std::shared_ptr<litehtml::document> &doc)
778 {
779 return 0;
780 }
781
rounded_rectangle(cairo_t * cr,const litehtml::position & pos,const litehtml::border_radiuses & radius)782 void container_linux::rounded_rectangle( cairo_t* cr, const litehtml::position &pos, const litehtml::border_radiuses &radius )
783 {
784 cairo_new_path(cr);
785 if(radius.top_left_x)
786 {
787 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);
788 } else
789 {
790 cairo_move_to(cr, pos.left(), pos.top());
791 }
792
793 cairo_line_to(cr, pos.right() - radius.top_right_x, pos.top());
794
795 if(radius.top_right_x)
796 {
797 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);
798 }
799
800 cairo_line_to(cr, pos.right(), pos.bottom() - radius.bottom_right_x);
801
802 if(radius.bottom_right_x)
803 {
804 cairo_arc(cr, pos.right() - radius.bottom_right_x, pos.bottom() - radius.bottom_right_x, radius.bottom_right_x, 0, M_PI / 2.0);
805 }
806
807 cairo_line_to(cr, pos.left() - radius.bottom_left_x, pos.bottom());
808
809 if(radius.bottom_left_x)
810 {
811 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);
812 }
813 }
814
draw_pixbuf(cairo_t * cr,const Glib::RefPtr<Gdk::Pixbuf> & bmp,int x,int y,int cx,int cy)815 void container_linux::draw_pixbuf(cairo_t* cr, const Glib::RefPtr<Gdk::Pixbuf>& bmp, int x, int y, int cx, int cy)
816 {
817 cairo_save(cr);
818
819 {
820 Cairo::RefPtr<Cairo::Context> crobj(new Cairo::Context(cr, false));
821
822 cairo_matrix_t flib_m;
823 cairo_matrix_init(&flib_m, 1, 0, 0, -1, 0, 0);
824
825 if(cx != bmp->get_width() || cy != bmp->get_height())
826 {
827 Glib::RefPtr<Gdk::Pixbuf> new_img = bmp->scale_simple(cx, cy, Gdk::INTERP_BILINEAR);;
828 Gdk::Cairo::set_source_pixbuf(crobj, new_img, x, y);
829 crobj->paint();
830 } else
831 {
832 Gdk::Cairo::set_source_pixbuf(crobj, bmp, x, y);
833 crobj->paint();
834 }
835 }
836
837 cairo_restore(cr);
838 }
839
surface_from_pixbuf(const Glib::RefPtr<Gdk::Pixbuf> & bmp)840 cairo_surface_t* container_linux::surface_from_pixbuf(const Glib::RefPtr<Gdk::Pixbuf>& bmp)
841 {
842 cairo_surface_t* ret = NULL;
843
844 if(bmp->get_has_alpha())
845 {
846 ret = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bmp->get_width(), bmp->get_height());
847 } else
848 {
849 ret = cairo_image_surface_create(CAIRO_FORMAT_RGB24, bmp->get_width(), bmp->get_height());
850 }
851
852 Cairo::RefPtr<Cairo::Surface> surface(new Cairo::Surface(ret, false));
853 Cairo::RefPtr<Cairo::Context> ctx = Cairo::Context::create(surface);
854 Gdk::Cairo::set_source_pixbuf(ctx, bmp, 0.0, 0.0);
855 ctx->paint();
856
857 return ret;
858 }
859
get_media_features(litehtml::media_features & media) const860 void container_linux::get_media_features(litehtml::media_features& media) const
861 {
862 litehtml::position client;
863 get_client_rect(client);
864 media.type = litehtml::media_type_screen;
865 media.width = client.width;
866 media.height = client.height;
867 media.device_width = Gdk::screen_width();
868 media.device_height = Gdk::screen_height();
869 media.color = 8;
870 media.monochrome = 0;
871 media.color_index = 256;
872 media.resolution = 96;
873 }
874
get_language(litehtml::tstring & language,litehtml::tstring & culture) const875 void container_linux::get_language(litehtml::tstring& language, litehtml::tstring& culture) const
876 {
877 language = _t("en");
878 culture = _t("");
879 }
880
link(const std::shared_ptr<litehtml::document> & ptr,const litehtml::element::ptr & el)881 void container_linux::link(const std::shared_ptr<litehtml::document> &ptr, const litehtml::element::ptr& el)
882 {
883
884 }
885