summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Bursa <james@netsurf-browser.org>2004-03-22 00:36:53 +0000
committerJames Bursa <james@netsurf-browser.org>2004-03-22 00:36:53 +0000
commit2c757c1e795d2dec37a55cccb5d882079a9b8cc6 (patch)
tree252cb98bd7199d0acd83f3d83fb03d177f7e4488
parent083d96493ef28b09cc739c0c8bf836a134d26d1e (diff)
downloadnetsurf-2c757c1e795d2dec37a55cccb5d882079a9b8cc6.tar.gz
netsurf-2c757c1e795d2dec37a55cccb5d882079a9b8cc6.tar.bz2
[project @ 2004-03-22 00:36:53 by bursa]
Implement most of CSS borders. svn path=/import/netsurf/; revision=650
-rw-r--r--!NetSurf/Resources/CSS,f792
-rw-r--r--css/ruleset.c454
-rw-r--r--riscos/htmlredraw.c74
3 files changed, 432 insertions, 98 deletions
diff --git a/!NetSurf/Resources/CSS,f79 b/!NetSurf/Resources/CSS,f79
index f8334363a..afeb3bc4f 100644
--- a/!NetSurf/Resources/CSS,f79
+++ b/!NetSurf/Resources/CSS,f79
@@ -47,7 +47,7 @@ center { text-align: center; }
small { font-size: smaller; }
big { font-size: larger; }
select, input { background-color: #eeb; color: #000; width: 10em; height: 1.5em;
- text-align: left;}
+ text-align: left; border: thin inset #bbb; }
textarea { background-color: #eeb; color: #000; text-align: left; }
input[type=button], input[type=image], input[type=reset], input[type=submit],
button { background-color: #ddd; color: #000; width: auto;
diff --git a/css/ruleset.c b/css/ruleset.c
index a51868d67..f38b4572d 100644
--- a/css/ruleset.c
+++ b/css/ruleset.c
@@ -46,6 +46,8 @@ static void parse_border_bottom_color(struct css_style * const s, const struct c
static void parse_border_bottom_style(struct css_style * const s, const struct css_node * v);
static void parse_border_bottom_width(struct css_style * const s, const struct css_node * v);
static void parse_border_color(struct css_style * const s, const struct css_node * v);
+static void parse_border_color_side(struct css_style * const s,
+ const struct css_node * const v, unsigned int i);
static void parse_border_left(struct css_style * const s, const struct css_node * v);
static void parse_border_left_color(struct css_style * const s, const struct css_node * v);
static void parse_border_left_style(struct css_style * const s, const struct css_node * v);
@@ -54,12 +56,18 @@ static void parse_border_right(struct css_style * const s, const struct css_node
static void parse_border_right_color(struct css_style * const s, const struct css_node * v);
static void parse_border_right_style(struct css_style * const s, const struct css_node * v);
static void parse_border_right_width(struct css_style * const s, const struct css_node * v);
+static void parse_border_side(struct css_style * const s,
+ const struct css_node *v, unsigned int i);
static void parse_border_style(struct css_style * const s, const struct css_node * v);
+static void parse_border_style_side(struct css_style * const s,
+ const struct css_node * const v, unsigned int i);
static void parse_border_top(struct css_style * const s, const struct css_node * v);
static void parse_border_top_color(struct css_style * const s, const struct css_node * v);
static void parse_border_top_style(struct css_style * const s, const struct css_node * v);
static void parse_border_top_width(struct css_style * const s, const struct css_node * v);
static void parse_border_width(struct css_style * const s, const struct css_node * v);
+static void parse_border_width_side(struct css_style * const s,
+ const struct css_node * const v, unsigned int i);
static void parse_clear(struct css_style * const s, const struct css_node * const v);
static void parse_color(struct css_style * const s, const struct css_node * const v);
static void parse_display(struct css_style * const s, const struct css_node * const v);
@@ -100,7 +108,7 @@ static css_text_decoration css_text_decoration_parse(const char * const s);
static const struct property_entry property_table[] = {
{ "background", parse_background },
{ "background-color", parse_background_color },
-/* { "border", parse_border },
+ { "border", parse_border },
{ "border-bottom", parse_border_bottom },
{ "border-bottom-color", parse_border_bottom_color },
{ "border-bottom-style", parse_border_bottom_style },
@@ -119,7 +127,7 @@ static const struct property_entry property_table[] = {
{ "border-top-color", parse_border_top_color },
{ "border-top-style", parse_border_top_style },
{ "border-top-width", parse_border_top_width },
- { "border-width", parse_border_width },*/
+ { "border-width", parse_border_width },
{ "clear", parse_clear },
{ "color", parse_color },
{ "display", parse_display },
@@ -434,6 +442,286 @@ void parse_background_color(struct css_style * const s, const struct css_node *
s->background_color = c;
}
+void parse_border_width(struct css_style * const s,
+ const struct css_node * const v)
+{
+ unsigned int count = 0;
+ const struct css_node *w;
+
+ for (w = v; w; w = w->next, count++)
+ if (!((w->type == CSS_NODE_IDENT && (
+ (strcasecmp(w->data, "inherit") == 0) ||
+ (strcasecmp(w->data, "thin") == 0) ||
+ (strcasecmp(w->data, "medium") == 0) ||
+ (strcasecmp(w->data, "thick") == 0))) ||
+ (w->type == CSS_NODE_DIMENSION) ||
+ (w->type == CSS_NODE_NUMBER)))
+ return;
+
+ w = v;
+ switch (count) {
+ case 1: /* one value: applies to all sides */
+ parse_border_width_side(s, w, TOP);
+ parse_border_width_side(s, w, RIGHT);
+ parse_border_width_side(s, w, BOTTOM);
+ parse_border_width_side(s, w, LEFT);
+ break;
+ case 2: /* (top and bottom), (left and right) */
+ parse_border_width_side(s, w, TOP);
+ parse_border_width_side(s, w, BOTTOM);
+ w = w->next;
+ parse_border_width_side(s, w, RIGHT);
+ parse_border_width_side(s, w, LEFT);
+ break;
+ case 3: /* top, (left and right), bottom */
+ parse_border_width_side(s, w, TOP);
+ w = w->next;
+ parse_border_width_side(s, w, RIGHT);
+ parse_border_width_side(s, w, LEFT);
+ w = w->next;
+ parse_border_width_side(s, w, BOTTOM);
+ break;
+ case 4: /* top, right, bottom, left */
+ parse_border_width_side(s, w, TOP);
+ w = w->next;
+ parse_border_width_side(s, w, RIGHT);
+ w = w->next;
+ parse_border_width_side(s, w, BOTTOM);
+ w = w->next;
+ parse_border_width_side(s, w, LEFT);
+ break;
+ }
+}
+
+#define PARSE_BORDER_WIDTH(side, z) \
+void parse_border_ ## side ## _width(struct css_style * const s, \
+ const struct css_node * const v) \
+{ \
+ if (v->next != 0) \
+ return; \
+ parse_border_width_side(s, v, z); \
+}
+
+PARSE_BORDER_WIDTH(top, TOP)
+PARSE_BORDER_WIDTH(right, RIGHT)
+PARSE_BORDER_WIDTH(bottom, BOTTOM)
+PARSE_BORDER_WIDTH(left, LEFT)
+
+void parse_border_width_side(struct css_style * const s,
+ const struct css_node * const v, unsigned int i)
+{
+ if (v->type == CSS_NODE_IDENT) {
+ if (strcasecmp(v->data, "inherit") == 0)
+ s->border[i].width.width = CSS_BORDER_WIDTH_INHERIT;
+ else if (strcasecmp(v->data, "thin") == 0) {
+ s->border[i].width.width = CSS_BORDER_WIDTH_LENGTH;
+ s->border[i].width.value.value = 1;
+ s->border[i].width.value.unit = CSS_UNIT_PX;
+ } else if (strcasecmp(v->data, "medium") == 0) {
+ s->border[i].width.width = CSS_BORDER_WIDTH_LENGTH;
+ s->border[i].width.value.value = 2;
+ s->border[i].width.value.unit = CSS_UNIT_PX;
+ } else if (strcasecmp(v->data, "thick") == 0) {
+ s->border[i].width.width = CSS_BORDER_WIDTH_LENGTH;
+ s->border[i].width.value.value = 4;
+ s->border[i].width.value.unit = CSS_UNIT_PX;
+ }
+ } else if ((v->type == CSS_NODE_DIMENSION ||
+ v->type == CSS_NODE_NUMBER) &&
+ parse_length(&s->border[i].width.value, v, true) == 0)
+ s->border[i].width.width = CSS_BORDER_WIDTH_LENGTH;
+}
+
+void parse_border_color(struct css_style * const s,
+ const struct css_node * const v)
+{
+ unsigned int count = 0;
+ const struct css_node *w;
+
+ for (w = v; w; w = w->next, count++)
+ if (!(w->type == CSS_NODE_HASH ||
+ w->type == CSS_NODE_FUNCTION ||
+ w->type == CSS_NODE_IDENT))
+ return;
+
+ w = v;
+ switch (count) {
+ case 1: /* one value: applies to all sides */
+ parse_border_color_side(s, w, TOP);
+ parse_border_color_side(s, w, RIGHT);
+ parse_border_color_side(s, w, BOTTOM);
+ parse_border_color_side(s, w, LEFT);
+ break;
+ case 2: /* (top and bottom), (left and right) */
+ parse_border_color_side(s, w, TOP);
+ parse_border_color_side(s, w, BOTTOM);
+ w = w->next;
+ parse_border_color_side(s, w, RIGHT);
+ parse_border_color_side(s, w, LEFT);
+ break;
+ case 3: /* top, (left and right), bottom */
+ parse_border_color_side(s, w, TOP);
+ w = w->next;
+ parse_border_color_side(s, w, RIGHT);
+ parse_border_color_side(s, w, LEFT);
+ w = w->next;
+ parse_border_color_side(s, w, BOTTOM);
+ break;
+ case 4: /* top, right, bottom, left */
+ parse_border_color_side(s, w, TOP);
+ w = w->next;
+ parse_border_color_side(s, w, RIGHT);
+ w = w->next;
+ parse_border_color_side(s, w, BOTTOM);
+ w = w->next;
+ parse_border_color_side(s, w, LEFT);
+ break;
+ }
+}
+
+#define PARSE_BORDER_COLOR(side, z) \
+void parse_border_ ## side ## _color(struct css_style * const s, \
+ const struct css_node * const v) \
+{ \
+ if (v->next != 0) \
+ return; \
+ parse_border_color_side(s, v, z); \
+}
+
+PARSE_BORDER_COLOR(top, TOP)
+PARSE_BORDER_COLOR(right, RIGHT)
+PARSE_BORDER_COLOR(bottom, BOTTOM)
+PARSE_BORDER_COLOR(left, LEFT)
+
+void parse_border_color_side(struct css_style * const s,
+ const struct css_node * const v, unsigned int i)
+{
+ colour c = parse_colour(v);
+ if (c != CSS_COLOR_NONE)
+ s->border[i].color = c;
+}
+
+void parse_border_style(struct css_style * const s,
+ const struct css_node * const v)
+{
+ unsigned int count = 0;
+ const struct css_node *w;
+
+ for (w = v; w; w = w->next, count++)
+ if (w->type != CSS_NODE_IDENT)
+ return;
+
+ w = v;
+ switch (count) {
+ case 1: /* one value: applies to all sides */
+ parse_border_style_side(s, w, TOP);
+ parse_border_style_side(s, w, RIGHT);
+ parse_border_style_side(s, w, BOTTOM);
+ parse_border_style_side(s, w, LEFT);
+ break;
+ case 2: /* (top and bottom), (left and right) */
+ parse_border_style_side(s, w, TOP);
+ parse_border_style_side(s, w, BOTTOM);
+ w = w->next;
+ parse_border_style_side(s, w, RIGHT);
+ parse_border_style_side(s, w, LEFT);
+ break;
+ case 3: /* top, (left and right), bottom */
+ parse_border_style_side(s, w, TOP);
+ w = w->next;
+ parse_border_style_side(s, w, RIGHT);
+ parse_border_style_side(s, w, LEFT);
+ w = w->next;
+ parse_border_style_side(s, w, BOTTOM);
+ break;
+ case 4: /* top, right, bottom, left */
+ parse_border_style_side(s, w, TOP);
+ w = w->next;
+ parse_border_style_side(s, w, RIGHT);
+ w = w->next;
+ parse_border_style_side(s, w, BOTTOM);
+ w = w->next;
+ parse_border_style_side(s, w, LEFT);
+ break;
+ }
+}
+
+#define PARSE_BORDER_STYLE(side, z) \
+void parse_border_ ## side ## _style(struct css_style * const s, \
+ const struct css_node * const v) \
+{ \
+ if (v->next != 0 || v->type != CSS_NODE_IDENT) \
+ return; \
+ parse_border_style_side(s, v, z); \
+}
+
+PARSE_BORDER_STYLE(top, TOP)
+PARSE_BORDER_STYLE(right, RIGHT)
+PARSE_BORDER_STYLE(bottom, BOTTOM)
+PARSE_BORDER_STYLE(left, LEFT)
+
+void parse_border_style_side(struct css_style * const s,
+ const struct css_node * const v, unsigned int i)
+{
+ css_border_style z = css_border_style_parse(v->data);
+ if (z != CSS_BORDER_STYLE_UNKNOWN)
+ s->border[i].style = z;
+}
+
+void parse_border(struct css_style * const s,
+ const struct css_node * const v)
+{
+ parse_border_side(s, v, TOP);
+ parse_border_side(s, v, RIGHT);
+ parse_border_side(s, v, BOTTOM);
+ parse_border_side(s, v, LEFT);
+}
+
+#define PARSE_BORDER(side, z) \
+void parse_border_ ## side(struct css_style * const s, \
+ const struct css_node * const v) \
+{ \
+ parse_border_side(s, v, z); \
+}
+
+PARSE_BORDER(top, TOP)
+PARSE_BORDER(right, RIGHT)
+PARSE_BORDER(bottom, BOTTOM)
+PARSE_BORDER(left, LEFT)
+
+void parse_border_side(struct css_style * const s,
+ const struct css_node *v, unsigned int i)
+{
+ colour c;
+ css_border_style z;
+
+ if (!v->next && v->type == CSS_NODE_IDENT &&
+ strcasecmp(v->data, "inherit") == 0) {
+ s->border[i].color = CSS_COLOR_INHERIT;
+ s->border[i].width.width = CSS_BORDER_WIDTH_INHERIT;
+ s->border[i].style = CSS_BORDER_STYLE_INHERIT;
+ return;
+ }
+
+ for (; v; v = v->next) {
+ c = parse_colour(v);
+ if (c != CSS_COLOR_NONE) {
+ s->border[i].color = c;
+ continue;
+ }
+
+ if (v->type == CSS_NODE_IDENT) {
+ z = css_border_style_parse(v->data);
+ if (z != CSS_BORDER_STYLE_UNKNOWN) {
+ s->border[i].style = z;
+ continue;
+ }
+ }
+
+ parse_border_width_side(s, v, i);
+ }
+}
+
void parse_clear(struct css_style * const s, const struct css_node * const v)
{
css_clear z;
@@ -649,67 +937,54 @@ void parse_margin(struct css_style * const s, const struct css_node * const v)
(w->type == CSS_NODE_NUMBER)))
return;
+ w = v;
switch (count) {
case 1: /* one value: applies to all sides */
- parse_margin_side(s, v, 0);
- parse_margin_side(s, v, 1);
- parse_margin_side(s, v, 2);
- parse_margin_side(s, v, 3);
+ parse_margin_side(s, w, TOP);
+ parse_margin_side(s, w, RIGHT);
+ parse_margin_side(s, w, BOTTOM);
+ parse_margin_side(s, w, LEFT);
break;
case 2: /* (top and bottom), (left and right) */
- parse_margin_side(s, v, 0);
- parse_margin_side(s, v, 2);
- v = v->next;
- parse_margin_side(s, v, 1);
- parse_margin_side(s, v, 3);
+ parse_margin_side(s, w, TOP);
+ parse_margin_side(s, w, BOTTOM);
+ w = w->next;
+ parse_margin_side(s, w, RIGHT);
+ parse_margin_side(s, w, LEFT);
break;
case 3: /* top, (left and right), bottom */
- parse_margin_side(s, v, 0);
- v = v->next;
- parse_margin_side(s, v, 1);
- parse_margin_side(s, v, 3);
- v = v->next;
- parse_margin_side(s, v, 2);
+ parse_margin_side(s, w, TOP);
+ w = w->next;
+ parse_margin_side(s, w, RIGHT);
+ parse_margin_side(s, w, LEFT);
+ w = w->next;
+ parse_margin_side(s, w, BOTTOM);
break;
case 4: /* top, right, bottom, left */
- parse_margin_side(s, v, 0);
- v = v->next;
- parse_margin_side(s, v, 1);
- v = v->next;
- parse_margin_side(s, v, 2);
- v = v->next;
- parse_margin_side(s, v, 3);
+ parse_margin_side(s, w, TOP);
+ w = w->next;
+ parse_margin_side(s, w, RIGHT);
+ w = w->next;
+ parse_margin_side(s, w, BOTTOM);
+ w = w->next;
+ parse_margin_side(s, w, LEFT);
break;
}
}
-void parse_margin_top(struct css_style * const s, const struct css_node * const v)
-{
- if (v->next != 0)
- return;
- parse_margin_side(s, v, 0);
-}
-
-void parse_margin_right(struct css_style * const s, const struct css_node * const v)
-{
- if (v->next != 0)
- return;
- parse_margin_side(s, v, 1);
-}
-
-void parse_margin_bottom(struct css_style * const s, const struct css_node * const v)
-{
- if (v->next != 0)
- return;
- parse_margin_side(s, v, 2);
+#define PARSE_MARGIN_(side, z) \
+void parse_margin_ ## side(struct css_style * const s, \
+ const struct css_node * const v) \
+{ \
+ if (v->next != 0) \
+ return; \
+ parse_margin_side(s, v, z); \
}
-void parse_margin_left(struct css_style * const s, const struct css_node * const v)
-{
- if (v->next != 0)
- return;
- parse_margin_side(s, v, 3);
-}
+PARSE_MARGIN_(top, TOP)
+PARSE_MARGIN_(right, RIGHT)
+PARSE_MARGIN_(bottom, BOTTOM)
+PARSE_MARGIN_(left, LEFT)
void parse_margin_side(struct css_style * const s, const struct css_node * const v,
unsigned int i)
@@ -739,67 +1014,54 @@ void parse_padding(struct css_style * const s, const struct css_node * const v)
(w->type == CSS_NODE_NUMBER)))
return;
+ w = v;
switch (count) {
case 1: /* one value: applies to all sides */
- parse_padding_side(s, v, 0);
- parse_padding_side(s, v, 1);
- parse_padding_side(s, v, 2);
- parse_padding_side(s, v, 3);
+ parse_padding_side(s, w, TOP);
+ parse_padding_side(s, w, RIGHT);
+ parse_padding_side(s, w, BOTTOM);
+ parse_padding_side(s, w, LEFT);
break;
case 2: /* (top and bottom), (left and right) */
- parse_padding_side(s, v, 0);
- parse_padding_side(s, v, 2);
- v = v->next;
- parse_padding_side(s, v, 1);
- parse_padding_side(s, v, 3);
+ parse_padding_side(s, w, TOP);
+ parse_padding_side(s, w, BOTTOM);
+ w = w->next;
+ parse_padding_side(s, w, RIGHT);
+ parse_padding_side(s, w, LEFT);
break;
case 3: /* top, (left and right), bottom */
- parse_padding_side(s, v, 0);
- v = v->next;
- parse_padding_side(s, v, 1);
- parse_padding_side(s, v, 3);
- v = v->next;
- parse_padding_side(s, v, 2);
+ parse_padding_side(s, w, TOP);
+ w = w->next;
+ parse_padding_side(s, w, RIGHT);
+ parse_padding_side(s, w, LEFT);
+ w = w->next;
+ parse_padding_side(s, w, BOTTOM);
break;
case 4: /* top, right, bottom, left */
- parse_padding_side(s, v, 0);
- v = v->next;
- parse_padding_side(s, v, 1);
- v = v->next;
- parse_padding_side(s, v, 2);
- v = v->next;
- parse_padding_side(s, v, 3);
+ parse_padding_side(s, w, TOP);
+ w = w->next;
+ parse_padding_side(s, w, RIGHT);
+ w = w->next;
+ parse_padding_side(s, w, BOTTOM);
+ w = w->next;
+ parse_padding_side(s, w, LEFT);
break;
}
}
-void parse_padding_top(struct css_style * const s, const struct css_node * const v)
-{
- if (v->next != 0)
- return;
- parse_padding_side(s, v, 0);
-}
-
-void parse_padding_right(struct css_style * const s, const struct css_node * const v)
-{
- if (v->next != 0)
- return;
- parse_padding_side(s, v, 1);
-}
-
-void parse_padding_bottom(struct css_style * const s, const struct css_node * const v)
-{
- if (v->next != 0)
- return;
- parse_padding_side(s, v, 2);
+#define PARSE_PADDING_(side, z) \
+void parse_padding_ ## side(struct css_style * const s, \
+ const struct css_node * const v) \
+{ \
+ if (v->next != 0) \
+ return; \
+ parse_padding_side(s, v, z); \
}
-void parse_padding_left(struct css_style * const s, const struct css_node * const v)
-{
- if (v->next != 0)
- return;
- parse_padding_side(s, v, 3);
-}
+PARSE_PADDING_(top, TOP)
+PARSE_PADDING_(right, RIGHT)
+PARSE_PADDING_(bottom, BOTTOM)
+PARSE_PADDING_(left, LEFT)
void parse_padding_side(struct css_style * const s, const struct css_node * const v,
unsigned int i)
diff --git a/riscos/htmlredraw.c b/riscos/htmlredraw.c
index e5d76ef4b..c552c1718 100644
--- a/riscos/htmlredraw.c
+++ b/riscos/htmlredraw.c
@@ -10,6 +10,7 @@
#include <stdbool.h>
#include <string.h>
#include "oslib/colourtrans.h"
+#include "oslib/draw.h"
#include "oslib/font.h"
#include "netsurf/css/css.h"
#include "netsurf/content/content.h"
@@ -29,8 +30,10 @@ static void html_redraw_box(struct content *content, struct box * box,
float scale);
static void html_redraw_clip(long clip_x0, long clip_y0,
long clip_x1, long clip_y1);
-void html_redraw_rectangle(int x0, int y0, int width, int height,
+static void html_redraw_rectangle(int x0, int y0, int width, int height,
os_colour colour);
+static void html_redraw_border(colour color, int width, css_border_style style,
+ int x0, int y0, int x1, int y1);
bool gui_redraw_debug = false;
@@ -119,6 +122,40 @@ void html_redraw_box(struct content *content, struct box * box,
os_COLOUR_YELLOW);
}
+ /* borders */
+ if (box->style && box->border[TOP])
+ html_redraw_border(box->style->border[TOP].color,
+ box->border[TOP] * 2,
+ box->style->border[TOP].style,
+ x - box->border[LEFT] * 2,
+ y + box->border[TOP],
+ x + width + box->border[RIGHT] * 2,
+ y + box->border[TOP]);
+ if (box->style && box->border[RIGHT])
+ html_redraw_border(box->style->border[RIGHT].color,
+ box->border[RIGHT] * 2,
+ box->style->border[RIGHT].style,
+ x + width + box->border[RIGHT],
+ y + box->border[TOP] * 2,
+ x + width + box->border[RIGHT],
+ y - height - box->border[BOTTOM] * 2);
+ if (box->style && box->border[BOTTOM])
+ html_redraw_border(box->style->border[BOTTOM].color,
+ box->border[BOTTOM] * 2,
+ box->style->border[BOTTOM].style,
+ x - box->border[LEFT] * 2,
+ y - height - box->border[BOTTOM],
+ x + width + box->border[RIGHT] * 2,
+ y - height - box->border[BOTTOM]);
+ if (box->style && box->border[LEFT])
+ html_redraw_border(box->style->border[LEFT].color,
+ box->border[LEFT] * 2,
+ box->style->border[LEFT].style,
+ x - box->border[LEFT],
+ y + box->border[TOP] * 2,
+ x - box->border[LEFT],
+ y - height - box->border[BOTTOM] * 2);
+
/* return if the box is completely outside the clip rectangle, except
* for table rows which may contain cells spanning into other rows */
if (box->type != BOX_TABLE_ROW &&
@@ -363,3 +400,38 @@ void html_redraw_rectangle(int x0, int y0, int width, int height,
os_plot(os_PLOT_DOTTED | os_PLOT_BY, -width, 0);
os_plot(os_PLOT_DOTTED | os_PLOT_BY, 0, height);
}
+
+
+static int path[] = { draw_MOVE_TO, 0, 0, draw_LINE_TO, 0, 0,
+ draw_END_PATH, 0 };
+static const draw_line_style line_style = { draw_JOIN_MITRED,
+ draw_CAP_BUTT, draw_CAP_BUTT, 0, 0x7fffffff,
+ 0, 0, 0, 0 };
+static const int dash_pattern_dotted[] = { 0, 1, 512 };
+static const int dash_pattern_dashed[] = { 0, 1, 2048 };
+
+void html_redraw_border(colour color, int width, css_border_style style,
+ int x0, int y0, int x1, int y1)
+{
+ draw_dash_pattern *dash_pattern = 0;
+ os_error *error;
+
+ if (style == CSS_BORDER_STYLE_DOTTED)
+ dash_pattern = (draw_dash_pattern *) &dash_pattern_dotted;
+ else if (style == CSS_BORDER_STYLE_DASHED)
+ dash_pattern = (draw_dash_pattern *) &dash_pattern_dashed;
+
+ path[1] = x0 * 256;
+ path[2] = y0 * 256;
+ path[4] = x1 * 256;
+ path[5] = y1 * 256;
+ error = xcolourtrans_set_gcol(color << 8, 0, os_ACTION_OVERWRITE, 0, 0);
+ if (error)
+ LOG(("xcolourtrans_set_gcol: 0x%x: %s",
+ error->errnum, error->errmess));
+ error = xdraw_stroke((draw_path *) path, 0, 0, 0, width * 256,
+ &line_style, dash_pattern);
+ if (error)
+ LOG(("xdraw_stroke: 0x%x: %s",
+ error->errnum, error->errmess));
+}