litehtml/containers/linux/container_linux.cpp

896 lines
23 KiB
C++

#include "container_linux.h"
#include <cmath>
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
container_linux::container_linux()
{
m_temp_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 2, 2);
m_temp_cr = cairo_create(m_temp_surface);
}
container_linux::~container_linux()
{
clear_images();
cairo_surface_destroy(m_temp_surface);
cairo_destroy(m_temp_cr);
}
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 )
{
PangoFontDescription *desc = pango_font_description_from_string (faceName);
pango_font_description_set_absolute_size(desc, size * PANGO_SCALE);
if(italic == litehtml::fontStyleItalic )
{
pango_font_description_set_style(desc, PANGO_STYLE_ITALIC);
} else
{
pango_font_description_set_style(desc, PANGO_STYLE_NORMAL);
}
PangoWeight fnt_weight;
if(weight >= 0 && weight < 150) fnt_weight = PANGO_WEIGHT_THIN;
else if(weight >= 150 && weight < 250) fnt_weight = PANGO_WEIGHT_ULTRALIGHT;
else if(weight >= 250 && weight < 350) fnt_weight = PANGO_WEIGHT_LIGHT;
else if(weight >= 350 && weight < 450) fnt_weight = PANGO_WEIGHT_NORMAL;
else if(weight >= 450 && weight < 550) fnt_weight = PANGO_WEIGHT_MEDIUM;
else if(weight >= 550 && weight < 650) fnt_weight = PANGO_WEIGHT_SEMIBOLD;
else if(weight >= 650 && weight < 750) fnt_weight = PANGO_WEIGHT_BOLD;
else if(weight >= 750 && weight < 850) fnt_weight = PANGO_WEIGHT_ULTRABOLD;
else fnt_weight = PANGO_WEIGHT_HEAVY;
pango_font_description_set_weight(desc, fnt_weight);
cairo_font* ret = nullptr;
if(fm)
{
cairo_save(m_temp_cr);
PangoLayout *layout = pango_cairo_create_layout(m_temp_cr);
PangoContext *context = pango_layout_get_context(layout);
PangoLanguage *language = pango_language_get_default();
pango_layout_set_font_description(layout, desc);
PangoFontMetrics *metrics = pango_context_get_metrics(context, desc, language);
fm->ascent = PANGO_PIXELS((double)pango_font_metrics_get_ascent(metrics));
fm->descent = PANGO_PIXELS((double)pango_font_metrics_get_descent(metrics));
fm->height = fm->ascent + fm->descent;
fm->x_height = fm->height;
pango_layout_set_text(layout, "x", 1);
int x_width, x_height;
pango_layout_get_pixel_size(layout, &x_width, &x_height);
fm->x_height = x_height;
cairo_restore(m_temp_cr);
g_object_unref(layout);
pango_font_metrics_unref(metrics);
ret = new cairo_font;
ret->font = desc;
ret->size = size;
ret->strikeout = (decoration & litehtml::font_decoration_linethrough) != 0;
ret->underline = (decoration & litehtml::font_decoration_underline) != 0;
ret->ascent = fm->ascent;
ret->descent = fm->descent;
ret->underline_thickness = pango_font_metrics_get_underline_thickness(metrics);
ret->underline_position = -pango_font_metrics_get_underline_position(metrics);
pango_quantize_line_geometry(&ret->underline_thickness, &ret->underline_position);
ret->underline_thickness = PANGO_PIXELS(ret->underline_thickness);
ret->underline_position = -1;//PANGO_PIXELS(ret->underline_position);
ret->strikethrough_thickness = pango_font_metrics_get_strikethrough_thickness(metrics);
ret->strikethrough_position = pango_font_metrics_get_strikethrough_position(metrics);
pango_quantize_line_geometry(&ret->strikethrough_thickness, &ret->strikethrough_position);
ret->strikethrough_thickness = PANGO_PIXELS(ret->strikethrough_thickness);
ret->strikethrough_position = PANGO_PIXELS(ret->strikethrough_position);
}
return (litehtml::uint_ptr) ret;
}
void container_linux::delete_font( litehtml::uint_ptr hFont )
{
auto* fnt = (cairo_font*) hFont;
if(fnt)
{
pango_font_description_free(fnt->font);
delete fnt;
}
}
int container_linux::text_width( const litehtml::tchar_t* text, litehtml::uint_ptr hFont )
{
auto* fnt = (cairo_font*) hFont;
cairo_save(m_temp_cr);
PangoLayout *layout = pango_cairo_create_layout(m_temp_cr);
pango_layout_set_font_description(layout, fnt->font);
pango_layout_set_text(layout, text, -1);
pango_cairo_update_layout (m_temp_cr, layout);
int x_width, x_height;
pango_layout_get_pixel_size(layout, &x_width, &x_height);
cairo_restore(m_temp_cr);
return (int) x_width;
}
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 )
{
auto* fnt = (cairo_font*) hFont;
auto* cr = (cairo_t*) hdc;
cairo_save(cr);
apply_clip(cr);
set_color(cr, color);
PangoLayout *layout = pango_cairo_create_layout(cr);
pango_layout_set_font_description (layout, fnt->font);
pango_layout_set_text (layout, text, -1);
int baseline = PANGO_PIXELS(pango_layout_get_baseline(layout));
PangoRectangle ink_rect, logical_rect;
pango_layout_get_pixel_extents(layout, &ink_rect, &logical_rect);
int text_baseline = pos.height - fnt->descent;
int x = pos.left() + logical_rect.x;
int y = pos.top() + logical_rect.y + text_baseline - baseline;
cairo_move_to(cr, x, y);
pango_cairo_update_layout (cr, layout);
pango_cairo_show_layout (cr, layout);
int tw = 0;
if(fnt->underline || fnt->strikeout)
{
tw = text_width(text, hFont);
}
if(fnt->underline)
{
cairo_set_line_width(cr, fnt->underline_thickness);
cairo_move_to(cr, x, pos.top() + text_baseline - fnt->underline_position + 0.5);
cairo_line_to(cr, x + tw, pos.top() + text_baseline - fnt->underline_position + 0.5);
cairo_stroke(cr);
}
if(fnt->strikeout)
{
cairo_set_line_width(cr, fnt->strikethrough_thickness);
cairo_move_to(cr, x, pos.top() + text_baseline - fnt->strikethrough_position - 0.5);
cairo_line_to(cr, x + tw, pos.top() + text_baseline - fnt->strikethrough_position - 0.5);
cairo_stroke(cr);
}
cairo_restore(cr);
g_object_unref(layout);
}
int container_linux::pt_to_px( int pt ) const
{
GdkScreen* screen = gdk_screen_get_default();
double dpi = gdk_screen_get_resolution(screen);
return (int) ((double) pt * dpi / 72.0);
}
int container_linux::get_default_font_size() const
{
return pt_to_px(12);
}
void container_linux::draw_list_marker( litehtml::uint_ptr hdc, const litehtml::list_marker& marker )
{
if(!marker.image.empty())
{
/*litehtml::tstring url;
make_url(marker.image.c_str(), marker.baseurl, url);
lock_images_cache();
images_map::iterator img_i = m_images.find(url.c_str());
if(img_i != m_images.end())
{
if(img_i->second)
{
draw_txdib((cairo_t*) hdc, img_i->second, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height);
}
}
unlock_images_cache();*/
} else
{
switch(marker.marker_type)
{
case litehtml::list_style_type_circle:
{
draw_ellipse((cairo_t*) hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color, 1);
}
break;
case litehtml::list_style_type_disc:
{
fill_ellipse((cairo_t*) hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color);
}
break;
case litehtml::list_style_type_square:
if(hdc)
{
auto* cr = (cairo_t*) hdc;
cairo_save(cr);
cairo_new_path(cr);
cairo_rectangle(cr, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height);
set_color(cr, marker.color);
cairo_fill(cr);
cairo_restore(cr);
}
break;
default:
/*do nothing*/
break;
}
}
}
void container_linux::load_image( const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready )
{
litehtml::tstring url;
make_url(src, baseurl, url);
if(m_images.find(url) == m_images.end())
{
try
{
Glib::RefPtr<Gdk::Pixbuf> img = get_image(url.c_str(), true);
if(img)
{
m_images[url.c_str()] = img;
}
} catch(...)
{
m_images[url.c_str()] = Glib::RefPtr<Gdk::Pixbuf>(nullptr);
}
}
}
void container_linux::get_image_size( const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz )
{
litehtml::tstring url;
make_url(src, baseurl, url);
auto img = m_images.find(url);
if(img != m_images.end())
{
if(img->second)
{
sz.width = img->second->get_width();
sz.height = img->second->get_height();
} else
{
sz.width = 0;
sz.height = 0;
}
} else
{
sz.width = 0;
sz.height = 0;
}
}
void container_linux::draw_background( litehtml::uint_ptr hdc, const litehtml::background_paint& bg )
{
auto* cr = (cairo_t*) hdc;
cairo_save(cr);
apply_clip(cr);
rounded_rectangle(cr, bg.border_box, bg.border_radius);
cairo_clip(cr);
cairo_rectangle(cr, bg.clip_box.x, bg.clip_box.y, bg.clip_box.width, bg.clip_box.height);
cairo_clip(cr);
if(bg.color.alpha)
{
set_color(cr, bg.color);
cairo_paint(cr);
}
litehtml::tstring url;
make_url(bg.image.c_str(), bg.baseurl.c_str(), url);
//lock_images_cache();
auto img_i = m_images.find(url);
if(img_i != m_images.end() && img_i->second)
{
Glib::RefPtr<Gdk::Pixbuf> bgbmp = img_i->second;
Glib::RefPtr<Gdk::Pixbuf> new_img;
if(bg.image_size.width != bgbmp->get_width() || bg.image_size.height != bgbmp->get_height())
{
new_img = bgbmp->scale_simple(bg.image_size.width, bg.image_size.height, Gdk::INTERP_BILINEAR);
bgbmp = new_img;
}
cairo_surface_t* img = surface_from_pixbuf(bgbmp);
cairo_pattern_t *pattern = cairo_pattern_create_for_surface(img);
cairo_matrix_t flib_m;
cairo_matrix_init_identity(&flib_m);
cairo_matrix_translate(&flib_m, -bg.position_x, -bg.position_y);
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
cairo_pattern_set_matrix (pattern, &flib_m);
switch(bg.repeat)
{
case litehtml::background_repeat_no_repeat:
draw_pixbuf(cr, bgbmp, bg.position_x, bg.position_y, bgbmp->get_width(), bgbmp->get_height());
break;
case litehtml::background_repeat_repeat_x:
cairo_set_source(cr, pattern);
cairo_rectangle(cr, bg.clip_box.left(), bg.position_y, bg.clip_box.width, bgbmp->get_height());
cairo_fill(cr);
break;
case litehtml::background_repeat_repeat_y:
cairo_set_source(cr, pattern);
cairo_rectangle(cr, bg.position_x, bg.clip_box.top(), bgbmp->get_width(), bg.clip_box.height);
cairo_fill(cr);
break;
case litehtml::background_repeat_repeat:
cairo_set_source(cr, pattern);
cairo_rectangle(cr, bg.clip_box.left(), bg.clip_box.top(), bg.clip_box.width, bg.clip_box.height);
cairo_fill(cr);
break;
}
cairo_pattern_destroy(pattern);
cairo_surface_destroy(img);
}
// unlock_images_cache();
cairo_restore(cr);
}
void container_linux::make_url(const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out)
{
out = url;
}
void container_linux::add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg)
{
if(rx > 0 && ry > 0)
{
cairo_save(cr);
cairo_translate(cr, x, y);
cairo_scale(cr, 1, ry / rx);
cairo_translate(cr, -x, -y);
if(neg)
{
cairo_arc_negative(cr, x, y, rx, a1, a2);
} else
{
cairo_arc(cr, x, y, rx, a1, a2);
}
cairo_restore(cr);
} else
{
cairo_move_to(cr, x, y);
}
}
void container_linux::draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root)
{
auto* cr = (cairo_t*) hdc;
cairo_save(cr);
apply_clip(cr);
cairo_new_path(cr);
int bdr_top = 0;
int bdr_bottom = 0;
int bdr_left = 0;
int bdr_right = 0;
if(borders.top.width != 0 && borders.top.style > litehtml::border_style_hidden)
{
bdr_top = (int) borders.top.width;
}
if(borders.bottom.width != 0 && borders.bottom.style > litehtml::border_style_hidden)
{
bdr_bottom = (int) borders.bottom.width;
}
if(borders.left.width != 0 && borders.left.style > litehtml::border_style_hidden)
{
bdr_left = (int) borders.left.width;
}
if(borders.right.width != 0 && borders.right.style > litehtml::border_style_hidden)
{
bdr_right = (int) borders.right.width;
}
// draw right border
if(bdr_right)
{
set_color(cr, borders.right.color);
double r_top = borders.radius.top_right_x;
double r_bottom = borders.radius.bottom_right_x;
if(r_top)
{
double end_angle = 2 * M_PI;
double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_top / (double) bdr_right + 1);
add_path_arc(cr,
draw_pos.right() - r_top,
draw_pos.top() + r_top,
r_top - bdr_right,
r_top - bdr_right + (bdr_right - bdr_top),
end_angle,
start_angle, true);
add_path_arc(cr,
draw_pos.right() - r_top,
draw_pos.top() + r_top,
r_top,
r_top,
start_angle,
end_angle, false);
} else
{
cairo_move_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top);
cairo_line_to(cr, draw_pos.right(), draw_pos.top());
}
if(r_bottom)
{
cairo_line_to(cr, draw_pos.right(), draw_pos.bottom() - r_bottom);
double start_angle = 0;
double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_bottom / (double) bdr_right + 1);
add_path_arc(cr,
draw_pos.right() - r_bottom,
draw_pos.bottom() - r_bottom,
r_bottom,
r_bottom,
start_angle,
end_angle, false);
add_path_arc(cr,
draw_pos.right() - r_bottom,
draw_pos.bottom() - r_bottom,
r_bottom - bdr_right,
r_bottom - bdr_right + (bdr_right - bdr_bottom),
end_angle,
start_angle, true);
} else
{
cairo_line_to(cr, draw_pos.right(), draw_pos.bottom());
cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom);
}
cairo_fill(cr);
}
// draw bottom border
if(bdr_bottom)
{
set_color(cr, borders.bottom.color);
double r_left = borders.radius.bottom_left_x;
double r_right = borders.radius.bottom_right_x;
if(r_left)
{
double start_angle = M_PI / 2.0;
double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_left / (double) bdr_bottom + 1);
add_path_arc(cr,
draw_pos.left() + r_left,
draw_pos.bottom() - r_left,
r_left - bdr_bottom + (bdr_bottom - bdr_left),
r_left - bdr_bottom,
start_angle,
end_angle, false);
add_path_arc(cr,
draw_pos.left() + r_left,
draw_pos.bottom() - r_left,
r_left,
r_left,
end_angle,
start_angle, true);
} else
{
cairo_move_to(cr, draw_pos.left(), draw_pos.bottom());
cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom);
}
if(r_right)
{
cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.bottom());
double end_angle = M_PI / 2.0;
double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_right / (double) bdr_bottom + 1);
add_path_arc(cr,
draw_pos.right() - r_right,
draw_pos.bottom() - r_right,
r_right,
r_right,
end_angle,
start_angle, true);
add_path_arc(cr,
draw_pos.right() - r_right,
draw_pos.bottom() - r_right,
r_right - bdr_bottom + (bdr_bottom - bdr_right),
r_right - bdr_bottom,
start_angle,
end_angle, false);
} else
{
cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom);
cairo_line_to(cr, draw_pos.right(), draw_pos.bottom());
}
cairo_fill(cr);
}
// draw top border
if(bdr_top)
{
set_color(cr, borders.top.color);
double r_left = borders.radius.top_left_x;
double r_right = borders.radius.top_right_x;
if(r_left)
{
double end_angle = M_PI * 3.0 / 2.0;
double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_left / (double) bdr_top + 1);
add_path_arc(cr,
draw_pos.left() + r_left,
draw_pos.top() + r_left,
r_left,
r_left,
end_angle,
start_angle, true);
add_path_arc(cr,
draw_pos.left() + r_left,
draw_pos.top() + r_left,
r_left - bdr_top + (bdr_top - bdr_left),
r_left - bdr_top,
start_angle,
end_angle, false);
} else
{
cairo_move_to(cr, draw_pos.left(), draw_pos.top());
cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top);
}
if(r_right)
{
cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.top() + bdr_top);
double start_angle = M_PI * 3.0 / 2.0;
double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_right / (double) bdr_top + 1);
add_path_arc(cr,
draw_pos.right() - r_right,
draw_pos.top() + r_right,
r_right - bdr_top + (bdr_top - bdr_right),
r_right - bdr_top,
start_angle,
end_angle, false);
add_path_arc(cr,
draw_pos.right() - r_right,
draw_pos.top() + r_right,
r_right,
r_right,
end_angle,
start_angle, true);
} else
{
cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top);
cairo_line_to(cr, draw_pos.right(), draw_pos.top());
}
cairo_fill(cr);
}
// draw left border
if(bdr_left)
{
set_color(cr, borders.left.color);
double r_top = borders.radius.top_left_x;
double r_bottom = borders.radius.bottom_left_x;
if(r_top)
{
double start_angle = M_PI;
double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_top / (double) bdr_left + 1);
add_path_arc(cr,
draw_pos.left() + r_top,
draw_pos.top() + r_top,
r_top - bdr_left,
r_top - bdr_left + (bdr_left - bdr_top),
start_angle,
end_angle, false);
add_path_arc(cr,
draw_pos.left() + r_top,
draw_pos.top() + r_top,
r_top,
r_top,
end_angle,
start_angle, true);
} else
{
cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top);
cairo_line_to(cr, draw_pos.left(), draw_pos.top());
}
if(r_bottom)
{
cairo_line_to(cr, draw_pos.left(), draw_pos.bottom() - r_bottom);
double end_angle = M_PI;
double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_bottom / (double) bdr_left + 1);
add_path_arc(cr,
draw_pos.left() + r_bottom,
draw_pos.bottom() - r_bottom,
r_bottom,
r_bottom,
end_angle,
start_angle, true);
add_path_arc(cr,
draw_pos.left() + r_bottom,
draw_pos.bottom() - r_bottom,
r_bottom - bdr_left,
r_bottom - bdr_left + (bdr_left - bdr_bottom),
start_angle,
end_angle, false);
} else
{
cairo_line_to(cr, draw_pos.left(), draw_pos.bottom());
cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom);
}
cairo_fill(cr);
}
cairo_restore(cr);
}
void container_linux::transform_text(litehtml::tstring& text, litehtml::text_transform tt)
{
}
void container_linux::set_clip( const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y )
{
litehtml::position clip_pos = pos;
litehtml::position client_pos;
get_client_rect(client_pos);
if(!valid_x)
{
clip_pos.x = client_pos.x;
clip_pos.width = client_pos.width;
}
if(!valid_y)
{
clip_pos.y = client_pos.y;
clip_pos.height = client_pos.height;
}
m_clips.emplace_back(clip_pos, bdr_radius);
}
void container_linux::del_clip()
{
if(!m_clips.empty())
{
m_clips.pop_back();
}
}
void container_linux::apply_clip( cairo_t* cr )
{
for(const auto& clip_box : m_clips)
{
rounded_rectangle(cr, clip_box.box, clip_box.radius);
cairo_clip(cr);
}
}
void container_linux::draw_ellipse( cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, int line_width )
{
if(!cr || !width || !height) return;
cairo_save(cr);
apply_clip(cr);
cairo_new_path(cr);
cairo_translate (cr, x + width / 2.0, y + height / 2.0);
cairo_scale (cr, width / 2.0, height / 2.0);
cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI);
set_color(cr, color);
cairo_set_line_width(cr, line_width);
cairo_stroke(cr);
cairo_restore(cr);
}
void container_linux::fill_ellipse( cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color )
{
if(!cr || !width || !height) return;
cairo_save(cr);
apply_clip(cr);
cairo_new_path(cr);
cairo_translate (cr, x + width / 2.0, y + height / 2.0);
cairo_scale (cr, width / 2.0, height / 2.0);
cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI);
set_color(cr, color);
cairo_fill(cr);
cairo_restore(cr);
}
void container_linux::clear_images()
{
/* for(images_map::iterator i = m_images.begin(); i != m_images.end(); i++)
{
if(i->second)
{
delete i->second;
}
}
m_images.clear();
*/
}
const litehtml::tchar_t* container_linux::get_default_font_name() const
{
return "Times New Roman";
}
std::shared_ptr<litehtml::element> container_linux::create_element(const litehtml::tchar_t *tag_name,
const litehtml::string_map &attributes,
const std::shared_ptr<litehtml::document> &doc)
{
return nullptr;
}
void container_linux::rounded_rectangle( cairo_t* cr, const litehtml::position &pos, const litehtml::border_radiuses &radius )
{
cairo_new_path(cr);
if(radius.top_left_x)
{
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);
} else
{
cairo_move_to(cr, pos.left(), pos.top());
}
cairo_line_to(cr, pos.right() - radius.top_right_x, pos.top());
if(radius.top_right_x)
{
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);
}
cairo_line_to(cr, pos.right(), pos.bottom() - radius.bottom_right_x);
if(radius.bottom_right_x)
{
cairo_arc(cr, pos.right() - radius.bottom_right_x, pos.bottom() - radius.bottom_right_x, radius.bottom_right_x, 0, M_PI / 2.0);
}
cairo_line_to(cr, pos.left() - radius.bottom_left_x, pos.bottom());
if(radius.bottom_left_x)
{
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);
}
}
void container_linux::draw_pixbuf(cairo_t* cr, const Glib::RefPtr<Gdk::Pixbuf>& bmp, int x, int y, int cx, int cy)
{
cairo_save(cr);
{
Cairo::RefPtr<Cairo::Context> crobj(new Cairo::Context(cr, false));
cairo_matrix_t flib_m;
cairo_matrix_init(&flib_m, 1, 0, 0, -1, 0, 0);
if(cx != bmp->get_width() || cy != bmp->get_height())
{
Glib::RefPtr<Gdk::Pixbuf> new_img = bmp->scale_simple(cx, cy, Gdk::INTERP_BILINEAR);
Gdk::Cairo::set_source_pixbuf(crobj, new_img, x, y);
crobj->paint();
} else
{
Gdk::Cairo::set_source_pixbuf(crobj, bmp, x, y);
crobj->paint();
}
}
cairo_restore(cr);
}
cairo_surface_t* container_linux::surface_from_pixbuf(const Glib::RefPtr<Gdk::Pixbuf>& bmp)
{
cairo_surface_t* ret;
if(bmp->get_has_alpha())
{
ret = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bmp->get_width(), bmp->get_height());
} else
{
ret = cairo_image_surface_create(CAIRO_FORMAT_RGB24, bmp->get_width(), bmp->get_height());
}
Cairo::RefPtr<Cairo::Surface> surface(new Cairo::Surface(ret, false));
Cairo::RefPtr<Cairo::Context> ctx = Cairo::Context::create(surface);
Gdk::Cairo::set_source_pixbuf(ctx, bmp, 0.0, 0.0);
ctx->paint();
return ret;
}
void container_linux::get_media_features(litehtml::media_features& media) const
{
litehtml::position client;
get_client_rect(client);
media.type = litehtml::media_type_screen;
media.width = client.width;
media.height = client.height;
media.device_width = Gdk::screen_width();
media.device_height = Gdk::screen_height();
media.color = 8;
media.monochrome = 0;
media.color_index = 256;
media.resolution = 96;
}
void container_linux::get_language(litehtml::tstring& language, litehtml::tstring& culture) const
{
language = _t("en");
culture = _t("");
}
void container_linux::link(const std::shared_ptr<litehtml::document> &ptr, const litehtml::element::ptr& el)
{
}