draw_borders now accept litehtml::borders as parameter.

updated cairo_container for new draw_borders parameters and some fixes with the borders appearance.
This commit is contained in:
Yuri Kobets 2015-04-26 23:03:33 +03:00
parent aa020ebccd
commit 5f8874dacd
6 changed files with 287 additions and 152 deletions

View File

@ -319,11 +319,10 @@ void cairo_container::draw_background( litehtml::uint_ptr hdc, const litehtml::b
cairo_restore(cr);
}
void cairo_container::add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg)
bool cairo_container::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);
@ -339,13 +338,12 @@ void cairo_container::add_path_arc(cairo_t* cr, double x, double y, double rx, d
}
cairo_restore(cr);
} else
{
cairo_move_to(cr, x, y);
return true;
}
return false;
}
void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::css_borders& borders, const litehtml::position& draw_pos, bool root )
void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root )
{
cairo_t* cr = (cairo_t*) hdc;
cairo_save(cr);
@ -358,51 +356,57 @@ void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::css_
int bdr_left = 0;
int bdr_right = 0;
if(borders.top.width.val() != 0 && borders.top.style > litehtml::border_style_hidden)
if(borders.top.width != 0 && borders.top.style > litehtml::border_style_hidden)
{
bdr_top = (int) borders.top.width.val();
bdr_top = (int) borders.top.width;
}
if(borders.bottom.width.val() != 0 && borders.bottom.style > litehtml::border_style_hidden)
if(borders.bottom.width != 0 && borders.bottom.style > litehtml::border_style_hidden)
{
bdr_bottom = (int) borders.bottom.width.val();
bdr_bottom = (int) borders.bottom.width;
}
if(borders.left.width.val() != 0 && borders.left.style > litehtml::border_style_hidden)
if(borders.left.width != 0 && borders.left.style > litehtml::border_style_hidden)
{
bdr_left = (int) borders.left.width.val();
bdr_left = (int) borders.left.width;
}
if(borders.right.width.val() != 0 && borders.right.style > litehtml::border_style_hidden)
if(borders.right.width != 0 && borders.right.style > litehtml::border_style_hidden)
{
bdr_right = (int) borders.right.width.val();
bdr_right = (int) borders.right.width;
}
// draw right border
if(bdr_right)
if (bdr_right)
{
set_color(cr, borders.right.color);
double r_top = borders.radius.top_right_x.val();
double r_bottom = borders.radius.bottom_right_x.val();
double r_top = (double) borders.radius.top_right_x;
double r_bottom = (double) 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);
double end_angle = 2.0 * M_PI;
double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_top / (double) bdr_right + 0.5);
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);
if (!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))
{
cairo_move_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top);
}
add_path_arc(cr,
draw_pos.right() - r_top,
draw_pos.top() + r_top,
r_top,
r_top,
start_angle,
end_angle, false);
if (!add_path_arc(cr,
draw_pos.right() - r_top,
draw_pos.top() + r_top,
r_top,
r_top,
start_angle,
end_angle, false))
{
cairo_line_to(cr, draw_pos.right(), draw_pos.top());
}
} else
{
cairo_move_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top);
@ -414,23 +418,29 @@ void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::css_
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);
double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_bottom / (double) bdr_right + 0.5);
add_path_arc(cr,
draw_pos.right() - r_bottom,
draw_pos.bottom() - r_bottom,
r_bottom,
r_bottom,
start_angle,
end_angle, false);
if (!add_path_arc(cr,
draw_pos.right() - r_bottom,
draw_pos.bottom() - r_bottom,
r_bottom,
r_bottom,
start_angle,
end_angle, false))
{
cairo_line_to(cr, draw_pos.right(), draw_pos.bottom());
}
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);
if (!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))
{
cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom);
}
} else
{
cairo_line_to(cr, draw_pos.right(), draw_pos.bottom());
@ -445,29 +455,35 @@ void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::css_
{
set_color(cr, borders.bottom.color);
double r_left = borders.radius.bottom_left_x.val();
double r_right = borders.radius.bottom_right_x.val();
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);
double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_left / (double) bdr_bottom + 0.5);
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);
if (!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))
{
cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom);
}
add_path_arc(cr,
draw_pos.left() + r_left,
draw_pos.bottom() - r_left,
r_left,
r_left,
end_angle,
start_angle, true);
if (!add_path_arc(cr,
draw_pos.left() + r_left,
draw_pos.bottom() - r_left,
r_left,
r_left,
end_angle,
start_angle, true))
{
cairo_line_to(cr, draw_pos.left(), draw_pos.bottom());
}
} else
{
cairo_move_to(cr, draw_pos.left(), draw_pos.bottom());
@ -479,23 +495,29 @@ void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::css_
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);
double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_right / (double) bdr_bottom + 0.5);
add_path_arc(cr,
draw_pos.right() - r_right,
draw_pos.bottom() - r_right,
r_right,
r_right,
end_angle,
start_angle, true);
if (!add_path_arc(cr,
draw_pos.right() - r_right,
draw_pos.bottom() - r_right,
r_right,
r_right,
end_angle,
start_angle, true))
{
cairo_line_to(cr, draw_pos.right(), draw_pos.bottom());
}
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,
if (!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);
end_angle, false))
{
cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom);
}
} else
{
cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom);
@ -510,29 +532,35 @@ void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::css_
{
set_color(cr, borders.top.color);
double r_left = borders.radius.top_left_x.val();
double r_right = borders.radius.top_right_x.val();
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);
double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_left / (double) bdr_top + 0.5);
add_path_arc(cr,
draw_pos.left() + r_left,
draw_pos.top() + r_left,
r_left,
r_left,
end_angle,
start_angle, true);
if (!add_path_arc(cr,
draw_pos.left() + r_left,
draw_pos.top() + r_left,
r_left,
r_left,
end_angle,
start_angle, true))
{
cairo_move_to(cr, draw_pos.left(), draw_pos.top());
}
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);
if (!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))
{
cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top);
}
} else
{
cairo_move_to(cr, draw_pos.left(), draw_pos.top());
@ -544,23 +572,29 @@ void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::css_
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);
double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_right / (double) bdr_top + 0.5);
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);
if (!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))
{
cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top);
}
add_path_arc(cr,
draw_pos.right() - r_right,
draw_pos.top() + r_right,
r_right,
r_right,
if (!add_path_arc(cr,
draw_pos.right() - r_right,
draw_pos.top() + r_right,
r_right,
r_right,
end_angle,
start_angle, true);
start_angle, true))
{
cairo_line_to(cr, draw_pos.right(), draw_pos.top());
}
} else
{
cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top);
@ -571,33 +605,39 @@ void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::css_
}
// draw left border
if(bdr_left)
if (bdr_left)
{
set_color(cr, borders.left.color);
double r_top = borders.radius.top_left_x.val();
double r_bottom = borders.radius.bottom_left_x.val();
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);
double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_top / (double) bdr_left + 0.5);
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);
if (!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))
{
cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top);
}
add_path_arc(cr,
draw_pos.left() + r_top,
draw_pos.top() + r_top,
r_top,
r_top,
end_angle,
start_angle, true);
if (!add_path_arc(cr,
draw_pos.left() + r_top,
draw_pos.top() + r_top,
r_top,
r_top,
end_angle,
start_angle, true))
{
cairo_line_to(cr, draw_pos.left(), draw_pos.top());
}
} else
{
cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top);
@ -609,23 +649,29 @@ void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::css_
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);
double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_bottom / (double) bdr_left + 0.5);
add_path_arc(cr,
draw_pos.left() + r_bottom,
draw_pos.bottom() - r_bottom,
r_bottom,
r_bottom,
end_angle,
start_angle, true);
if (!add_path_arc(cr,
draw_pos.left() + r_bottom,
draw_pos.bottom() - r_bottom,
r_bottom,
r_bottom,
end_angle,
start_angle, true))
{
cairo_line_to(cr, draw_pos.left(), draw_pos.bottom());
}
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);
if (!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))
{
cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom);
}
} else
{
cairo_line_to(cr, draw_pos.left(), draw_pos.bottom());

View File

@ -74,7 +74,7 @@ public:
virtual void get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz);
virtual void draw_image(litehtml::uint_ptr hdc, const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, const litehtml::position& pos);
virtual void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg);
virtual void draw_borders(litehtml::uint_ptr hdc, const litehtml::css_borders& borders, const litehtml::position& draw_pos, bool root);
virtual void draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root);
virtual void transform_text(litehtml::tstring& text, litehtml::text_transform tt);
virtual void set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y);
@ -99,7 +99,7 @@ protected:
private:
simpledib::dib* get_dib(litehtml::uint_ptr hdc) { return (simpledib::dib*) hdc; }
void apply_clip(cairo_t* cr);
void add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg);
bool add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg);
void draw_txdib(cairo_t* cr, CTxDIB* bmp, int x, int y, int cx, int cy);
void lock_images_cache();

View File

@ -31,6 +31,44 @@ namespace litehtml
}
};
struct border
{
int width;
border_style style;
web_color color;
border()
{
width = 0;
}
border(const border& val)
{
width = val.width;
style = val.style;
color = val.color;
}
border(const css_border& val)
{
width = (int) val.width.val();
style = val.style;
color = val.color;
}
border& operator=(const border& val)
{
width = val.width;
style = val.style;
color = val.color;
return *this;
}
border& operator=(const css_border& val)
{
width = (int) val.width.val();
style = val.style;
color = val.color;
return *this;
}
};
struct border_radiuses
{
int top_left_x;
@ -205,4 +243,54 @@ namespace litehtml
return *this;
}
};
struct borders
{
border left;
border top;
border right;
border bottom;
border_radiuses radius;
borders()
{
}
borders(const borders& val)
{
left = val.left;
right = val.right;
top = val.top;
bottom = val.bottom;
radius = val.radius;
}
borders(const css_borders& val)
{
left = val.left;
right = val.right;
top = val.top;
bottom = val.bottom;
}
borders& operator=(const borders& val)
{
left = val.left;
right = val.right;
top = val.top;
bottom = val.bottom;
radius = val.radius;
return *this;
}
borders& operator=(const css_borders& val)
{
left = val.left;
right = val.right;
top = val.top;
bottom = val.bottom;
return *this;
}
};
}

View File

@ -229,8 +229,8 @@ void litehtml::el_image::draw( uint_ptr hdc, int x, int y, const position* clip
border_box += m_padding;
border_box += m_borders;
css_borders bdr = m_css_borders;
bdr.radius.calc_percents(border_box.width, border_box.height);
borders bdr = m_css_borders;
bdr.radius = m_css_borders.radius.calc_percents(border_box.width, border_box.height);
m_doc->container()->draw_borders(hdc, bdr, border_box, parent() ? false : true);
}

View File

@ -42,7 +42,7 @@ namespace litehtml
virtual void load_image(const tchar_t* src, const tchar_t* baseurl, bool redraw_on_ready) = 0;
virtual void get_image_size(const tchar_t* src, const tchar_t* baseurl, litehtml::size& sz) = 0;
virtual void draw_background(uint_ptr hdc, const litehtml::background_paint& bg) = 0;
virtual void draw_borders(uint_ptr hdc, const css_borders& borders, const litehtml::position& draw_pos, bool root) = 0;
virtual void draw_borders(uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) = 0;
virtual void set_caption(const tchar_t* caption) = 0;
virtual void set_base_url(const tchar_t* base_url) = 0;

View File

@ -1921,8 +1921,8 @@ void litehtml::html_tag::draw_background( uint_ptr hdc, int x, int y, const posi
border_box += m_padding;
border_box += m_borders;
css_borders bdr = m_css_borders;
bdr.radius.calc_percents(border_box.width, border_box.height);
borders bdr = m_css_borders;
bdr.radius = m_css_borders.radius.calc_percents(border_box.width, border_box.height);
m_doc->container()->draw_borders(hdc, bdr, border_box, parent() ? false : true);
}
@ -1990,8 +1990,9 @@ void litehtml::html_tag::draw_background( uint_ptr hdc, int x, int y, const posi
bg_paint.border_radius = bdr.radius.calc_percents(bg_paint.border_box.width, bg_paint.border_box.width);
m_doc->container()->draw_background(hdc, bg_paint);
}
m_doc->container()->draw_borders(hdc, bdr, *box, false);
borders b = bdr;
b.radius = bdr.radius.calc_percents(box->width, box->height);
m_doc->container()->draw_borders(hdc, b, *box, false);
}
}
}