diff options
-rw-r--r-- | containers/linux/container_linux.cpp | 270 | ||||
-rw-r--r-- | include/litehtml/borders.h | 30 |
2 files changed, 171 insertions, 129 deletions
diff --git a/containers/linux/container_linux.cpp b/containers/linux/container_linux.cpp index 5c17d424..b5d984d4 100644 --- a/containers/linux/container_linux.cpp +++ b/containers/linux/container_linux.cpp @@ -443,57 +443,54 @@ void container_linux::draw_borders(litehtml::uint_ptr hdc, const litehtml::borde { 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) + if(borders.radius.top_right_x && borders.radius.top_right_y) { 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); + draw_pos.right() - borders.radius.top_right_x, + draw_pos.top() + borders.radius.top_right_y, + borders.radius.top_right_x - bdr_right, + borders.radius.top_right_y - 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); + draw_pos.right() - borders.radius.top_right_x, + draw_pos.top() + borders.radius.top_right_y, + borders.radius.top_right_x, + borders.radius.top_right_y, + 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) + if(borders.radius.bottom_right_x && borders.radius.bottom_right_y) { - cairo_line_to(cr, draw_pos.right(), draw_pos.bottom() - r_bottom); + cairo_line_to(cr, draw_pos.right(), draw_pos.bottom() - borders.radius.bottom_right_y); 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); + draw_pos.right() - borders.radius.bottom_right_x, + draw_pos.bottom() - borders.radius.bottom_right_y, + borders.radius.bottom_right_x, + borders.radius.bottom_right_y, + 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); + draw_pos.right() - borders.radius.bottom_right_x, + draw_pos.bottom() - borders.radius.bottom_right_y, + borders.radius.bottom_right_x - bdr_right, + borders.radius.bottom_right_y - bdr_right + (bdr_right - bdr_bottom), + end_angle, + start_angle, true); } else { cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); @@ -508,57 +505,54 @@ void container_linux::draw_borders(litehtml::uint_ptr hdc, const litehtml::borde { 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) + if(borders.radius.bottom_left_x && borders.radius.bottom_left_y) { 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); + draw_pos.left() + borders.radius.bottom_left_x, + draw_pos.bottom() - borders.radius.bottom_left_y, + borders.radius.bottom_left_x - bdr_bottom + (bdr_bottom - bdr_left), + borders.radius.bottom_left_y - 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); + draw_pos.left() + borders.radius.bottom_left_x, + draw_pos.bottom() - borders.radius.bottom_left_y, + borders.radius.bottom_left_x, + borders.radius.bottom_left_y, + 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) + if(borders.radius.bottom_right_x && borders.radius.bottom_right_y) { - cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.bottom()); + cairo_line_to(cr, draw_pos.right() - borders.radius.bottom_right_x, 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); + draw_pos.right() - borders.radius.bottom_right_x, + draw_pos.bottom() - borders.radius.bottom_right_y, + borders.radius.bottom_right_x, + borders.radius.bottom_right_y, + 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); + draw_pos.right() - borders.radius.bottom_right_x, + draw_pos.bottom() - borders.radius.bottom_right_y, + borders.radius.bottom_right_x - bdr_bottom + (bdr_bottom - bdr_right), + borders.radius.bottom_right_y - bdr_bottom, + start_angle, + end_angle, false); } else { cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); @@ -573,57 +567,54 @@ void container_linux::draw_borders(litehtml::uint_ptr hdc, const litehtml::borde { 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) + if(borders.radius.top_left_x && borders.radius.top_left_y) { 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); + draw_pos.left() + borders.radius.top_left_x, + draw_pos.top() + borders.radius.top_left_y, + borders.radius.top_left_x, + borders.radius.top_left_y, + 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); + draw_pos.left() + borders.radius.top_left_x, + draw_pos.top() + borders.radius.top_left_y, + borders.radius.top_left_x - bdr_top + (bdr_top - bdr_left), + borders.radius.top_left_y - 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) + if(borders.radius.top_right_x && borders.radius.top_right_y) { - cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.top() + bdr_top); + cairo_line_to(cr, draw_pos.right() - borders.radius.top_right_x, 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); + draw_pos.right() - borders.radius.top_right_x, + draw_pos.top() + borders.radius.top_right_y, + borders.radius.top_right_x - bdr_top + (bdr_top - bdr_right), + borders.radius.top_right_y - 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); + draw_pos.right() - borders.radius.top_right_x, + draw_pos.top() + borders.radius.top_right_y, + borders.radius.top_right_x, + borders.radius.top_right_y, + end_angle, + start_angle, true); } else { cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); @@ -638,57 +629,54 @@ void container_linux::draw_borders(litehtml::uint_ptr hdc, const litehtml::borde { 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) + if(borders.radius.top_left_x && borders.radius.top_left_y) { 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); + draw_pos.left() + borders.radius.top_left_x, + draw_pos.top() + borders.radius.top_left_y, + borders.radius.top_left_x - bdr_left, + borders.radius.top_left_y - 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); + draw_pos.left() + borders.radius.top_left_x, + draw_pos.top() + borders.radius.top_left_y, + borders.radius.top_left_x, + borders.radius.top_left_y, + 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) + if(borders.radius.bottom_left_x && borders.radius.bottom_left_y) { - cairo_line_to(cr, draw_pos.left(), draw_pos.bottom() - r_bottom); + cairo_line_to(cr, draw_pos.left(), draw_pos.bottom() - borders.radius.bottom_left_y); 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); + draw_pos.left() + borders.radius.bottom_left_x, + draw_pos.bottom() - borders.radius.bottom_left_y, + borders.radius.bottom_left_x, + borders.radius.bottom_left_y, + 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); + draw_pos.left() + borders.radius.bottom_left_x, + draw_pos.bottom() - borders.radius.bottom_left_y, + borders.radius.bottom_left_x - bdr_left, + borders.radius.bottom_left_y - bdr_left + (bdr_left - bdr_bottom), + start_angle, + end_angle, false); } else { cairo_line_to(cr, draw_pos.left(), draw_pos.bottom()); @@ -794,9 +782,15 @@ std::shared_ptr<litehtml::element> container_linux::create_element(const char *t 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); + if(radius.top_left_x && radius.top_left_y) + { + add_path_arc(cr, + pos.left() + radius.top_left_x, + pos.top() + radius.top_left_y, + radius.top_left_x, + radius.top_left_y, + M_PI, + M_PI * 3.0 / 2.0, false); } else { cairo_move_to(cr, pos.left(), pos.top()); @@ -804,23 +798,41 @@ void container_linux::rounded_rectangle( cairo_t* cr, const litehtml::position & cairo_line_to(cr, pos.right() - radius.top_right_x, pos.top()); - if(radius.top_right_x) + if(radius.top_right_x && radius.top_right_y) { - 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); + add_path_arc(cr, + pos.right() - radius.top_right_x, + pos.top() + radius.top_right_y, + radius.top_right_x, + radius.top_right_y, + M_PI * 3.0 / 2.0, + 2.0 * M_PI, false); } cairo_line_to(cr, pos.right(), pos.bottom() - radius.bottom_right_x); - if(radius.bottom_right_x) + if(radius.bottom_right_x && radius.bottom_right_y) { - cairo_arc(cr, pos.right() - radius.bottom_right_x, pos.bottom() - radius.bottom_right_x, radius.bottom_right_x, 0, M_PI / 2.0); + add_path_arc(cr, + pos.right() - radius.bottom_right_x, + pos.bottom() - radius.bottom_right_y, + radius.bottom_right_x, + radius.bottom_right_y, + 0, + M_PI / 2.0, false); } cairo_line_to(cr, pos.left() - radius.bottom_left_x, pos.bottom()); - if(radius.bottom_left_x) + if(radius.bottom_left_x && radius.bottom_left_y) { - 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); + add_path_arc(cr, + pos.left() + radius.bottom_left_x, + pos.bottom() - radius.bottom_left_y, + radius.bottom_left_x, + radius.bottom_left_y, + M_PI / 2.0, + M_PI, false); } } diff --git a/include/litehtml/borders.h b/include/litehtml/borders.h index e690db6d..9c47abca 100644 --- a/include/litehtml/borders.h +++ b/include/litehtml/borders.h @@ -157,6 +157,35 @@ namespace litehtml if (bottom_left_x < 0) bottom_left_x = 0; if (bottom_left_y < 0) bottom_left_y = 0; } + void fix_values(int width, int height) + { + fix_values(); + int half_width = width / 2; + int half_height = height / 2; + auto fix_one = [&](int& radii_x, int& radii_y) + { + double factor = std::min((double) half_width / (double) radii_x, (double) half_height / (double) radii_y); + radii_x = (int) ((double) radii_x * factor); + radii_y = (int) ((double) radii_y * factor); + }; + + if(top_left_x > half_width || top_left_y > half_height) + { + fix_one(top_left_x, top_left_y); + } + if(top_right_x > half_width || top_right_y > half_height) + { + fix_one(top_right_x, top_right_y); + } + if(bottom_right_x > half_width || bottom_right_y > half_height) + { + fix_one(bottom_right_x, bottom_right_y); + } + if(bottom_left_x > half_width || bottom_left_y > half_height) + { + fix_one(bottom_left_x, bottom_left_y); + } + } }; struct css_border_radius @@ -213,6 +242,7 @@ namespace litehtml ret.top_right_y = top_right_y.calc_percent(height); ret.bottom_right_x = bottom_right_x.calc_percent(width); ret.bottom_right_y = bottom_right_y.calc_percent(height); + ret.fix_values(width, height); return ret; } }; |