mirror of
https://github.com/netsurf-browser/netsurf
synced 2025-01-03 17:54:33 +03:00
[project @ 2004-02-02 00:22:59 by bursa]
Start at margin / padding / border support. svn path=/import/netsurf/; revision=529
This commit is contained in:
parent
dbda424e61
commit
b0c5b74987
106
css/css.c
106
css/css.c
@ -38,6 +38,14 @@ static bool css_match_rule(struct css_node *rule, xmlNode *element);
|
||||
|
||||
const struct css_style css_base_style = {
|
||||
0xffffff,
|
||||
{ { 0x000000, { CSS_BORDER_WIDTH_LENGTH,
|
||||
{ 2, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE },
|
||||
{ 0x000000, { CSS_BORDER_WIDTH_LENGTH,
|
||||
{ 2, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE },
|
||||
{ 0x000000, { CSS_BORDER_WIDTH_LENGTH,
|
||||
{ 2, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE },
|
||||
{ 0x000000, { CSS_BORDER_WIDTH_LENGTH,
|
||||
{ 2, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE } },
|
||||
CSS_CLEAR_NONE,
|
||||
0x000000,
|
||||
CSS_DISPLAY_BLOCK,
|
||||
@ -49,6 +57,14 @@ const struct css_style css_base_style = {
|
||||
CSS_FONT_VARIANT_NORMAL,
|
||||
{ CSS_HEIGHT_AUTO, { 1, CSS_UNIT_EM } },
|
||||
{ CSS_LINE_HEIGHT_ABSOLUTE, { 1.3 } },
|
||||
{ { CSS_MARGIN_LENGTH, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_MARGIN_LENGTH, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_MARGIN_LENGTH, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_MARGIN_LENGTH, { { 0, CSS_UNIT_PX } } } },
|
||||
{ { CSS_PADDING_LENGTH, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_PADDING_LENGTH, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_PADDING_LENGTH, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_PADDING_LENGTH, { { 0, CSS_UNIT_PX } } } },
|
||||
CSS_TEXT_ALIGN_LEFT,
|
||||
CSS_TEXT_DECORATION_NONE,
|
||||
{ CSS_TEXT_INDENT_LENGTH, { { 0, CSS_UNIT_EM } } },
|
||||
@ -60,6 +76,14 @@ const struct css_style css_base_style = {
|
||||
|
||||
const struct css_style css_empty_style = {
|
||||
CSS_COLOR_INHERIT,
|
||||
{ { CSS_COLOR_INHERIT, { CSS_BORDER_WIDTH_INHERIT,
|
||||
{ 0, CSS_UNIT_PX } }, CSS_BORDER_STYLE_INHERIT },
|
||||
{ CSS_COLOR_INHERIT, { CSS_BORDER_WIDTH_INHERIT,
|
||||
{ 0, CSS_UNIT_PX } }, CSS_BORDER_STYLE_INHERIT },
|
||||
{ CSS_COLOR_INHERIT, { CSS_BORDER_WIDTH_INHERIT,
|
||||
{ 0, CSS_UNIT_PX } }, CSS_BORDER_STYLE_INHERIT },
|
||||
{ CSS_COLOR_INHERIT, { CSS_BORDER_WIDTH_INHERIT,
|
||||
{ 0, CSS_UNIT_PX } }, CSS_BORDER_STYLE_INHERIT } },
|
||||
CSS_CLEAR_INHERIT,
|
||||
CSS_COLOR_INHERIT,
|
||||
CSS_DISPLAY_INHERIT,
|
||||
@ -71,6 +95,14 @@ const struct css_style css_empty_style = {
|
||||
CSS_FONT_VARIANT_INHERIT,
|
||||
{ CSS_HEIGHT_INHERIT, { 1, CSS_UNIT_EM } },
|
||||
{ CSS_LINE_HEIGHT_INHERIT, { 1.3 } },
|
||||
{ { CSS_MARGIN_INHERIT, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_MARGIN_INHERIT, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_MARGIN_INHERIT, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_MARGIN_INHERIT, { { 0, CSS_UNIT_PX } } } },
|
||||
{ { CSS_PADDING_INHERIT, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_PADDING_INHERIT, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_PADDING_INHERIT, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_PADDING_INHERIT, { { 0, CSS_UNIT_PX } } } },
|
||||
CSS_TEXT_ALIGN_INHERIT,
|
||||
CSS_TEXT_DECORATION_INHERIT,
|
||||
{ CSS_TEXT_INDENT_INHERIT, { { 0, CSS_UNIT_EM } } },
|
||||
@ -82,6 +114,14 @@ const struct css_style css_empty_style = {
|
||||
|
||||
const struct css_style css_blank_style = {
|
||||
TRANSPARENT,
|
||||
{ { 0x000000, { CSS_BORDER_WIDTH_LENGTH,
|
||||
{ 2, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE },
|
||||
{ 0x000000, { CSS_BORDER_WIDTH_LENGTH,
|
||||
{ 2, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE },
|
||||
{ 0x000000, { CSS_BORDER_WIDTH_LENGTH,
|
||||
{ 2, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE },
|
||||
{ 0x000000, { CSS_BORDER_WIDTH_LENGTH,
|
||||
{ 2, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE } },
|
||||
CSS_CLEAR_NONE,
|
||||
CSS_COLOR_INHERIT,
|
||||
CSS_DISPLAY_INLINE,
|
||||
@ -93,6 +133,14 @@ const struct css_style css_blank_style = {
|
||||
CSS_FONT_VARIANT_INHERIT,
|
||||
{ CSS_HEIGHT_AUTO, { 1, CSS_UNIT_EM } },
|
||||
{ CSS_LINE_HEIGHT_INHERIT, { 1.3 } },
|
||||
{ { CSS_MARGIN_LENGTH, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_MARGIN_LENGTH, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_MARGIN_LENGTH, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_MARGIN_LENGTH, { { 0, CSS_UNIT_PX } } } },
|
||||
{ { CSS_PADDING_LENGTH, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_PADDING_LENGTH, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_PADDING_LENGTH, { { 0, CSS_UNIT_PX } } },
|
||||
{ CSS_PADDING_LENGTH, { { 0, CSS_UNIT_PX } } } },
|
||||
CSS_TEXT_ALIGN_INHERIT,
|
||||
CSS_TEXT_DECORATION_INHERIT,
|
||||
{ CSS_TEXT_INDENT_INHERIT, { { 0, CSS_UNIT_EM } } },
|
||||
@ -643,6 +691,7 @@ static void dump_length(const struct css_length * const length)
|
||||
|
||||
void css_dump_style(const struct css_style * const style)
|
||||
{
|
||||
unsigned int i;
|
||||
fprintf(stderr, "{ ");
|
||||
fprintf(stderr, "background-color: #%lx; ", style->background_color);
|
||||
fprintf(stderr, "clear: %s; ", css_clear_name[style->clear]);
|
||||
@ -676,6 +725,29 @@ void css_dump_style(const struct css_style * const style)
|
||||
default: fprintf(stderr, "UNKNOWN"); break;
|
||||
}
|
||||
fprintf(stderr, "; ");
|
||||
fprintf(stderr, "margin:");
|
||||
for (i = 0; i != 4; i++) {
|
||||
switch (style->margin[i].margin) {
|
||||
case CSS_MARGIN_INHERIT: fprintf(stderr, " inherit"); break;
|
||||
case CSS_MARGIN_LENGTH: fprintf(stderr, " ");
|
||||
dump_length(&style->margin[i].value.length); break;
|
||||
case CSS_MARGIN_PERCENT: fprintf(stderr, " %g%%", style->margin[i].value.percent);
|
||||
case CSS_MARGIN_AUTO: fprintf(stderr, " auto"); break;
|
||||
default: fprintf(stderr, "UNKNOWN"); break;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "; ");
|
||||
fprintf(stderr, "padding:");
|
||||
for (i = 0; i != 4; i++) {
|
||||
switch (style->padding[i].padding) {
|
||||
case CSS_PADDING_INHERIT: fprintf(stderr, " inherit"); break;
|
||||
case CSS_PADDING_LENGTH: fprintf(stderr, " ");
|
||||
dump_length(&style->padding[i].value.length); break;
|
||||
case CSS_PADDING_PERCENT: fprintf(stderr, " %g%%", style->padding[i].value.percent);
|
||||
default: fprintf(stderr, "UNKNOWN"); break;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "; ");
|
||||
fprintf(stderr, "text-align: %s; ", css_text_align_name[style->text_align]);
|
||||
fprintf(stderr, "text-decoration:");
|
||||
switch (style->text_decoration) {
|
||||
@ -704,6 +776,7 @@ void css_dump_style(const struct css_style * const style)
|
||||
fprintf(stderr, "visibility: %s; ", css_visibility_name[style->visibility]);
|
||||
fprintf(stderr, "width: ");
|
||||
switch (style->width.width) {
|
||||
case CSS_WIDTH_INHERIT: fprintf(stderr, "inherit"); break;
|
||||
case CSS_WIDTH_AUTO: fprintf(stderr, "auto"); break;
|
||||
case CSS_WIDTH_LENGTH: dump_length(&style->width.value.length); break;
|
||||
case CSS_WIDTH_PERCENT: fprintf(stderr, "%g%%", style->width.value.percent); break;
|
||||
@ -753,6 +826,7 @@ void css_dump_stylesheet(const struct css_stylesheet * stylesheet)
|
||||
|
||||
void css_cascade(struct css_style * const style, const struct css_style * const apply)
|
||||
{
|
||||
unsigned int i;
|
||||
float f;
|
||||
|
||||
/* text-decoration: approximate CSS 2.1 by inheriting into inline elements */
|
||||
@ -833,11 +907,28 @@ void css_cascade(struct css_style * const style, const struct css_style * const
|
||||
default: /* leave unchanged */
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i != 4; i++) {
|
||||
if (apply->border[i].color != CSS_COLOR_INHERIT)
|
||||
style->border[i].color = apply->border[i].color;
|
||||
if (apply->border[i].width.width != CSS_BORDER_WIDTH_INHERIT)
|
||||
style->border[i].width = apply->border[i].width;
|
||||
if (apply->border[i].style != CSS_BORDER_STYLE_INHERIT)
|
||||
style->border[i].style = apply->border[i].style;
|
||||
|
||||
if (apply->margin[i].margin != CSS_MARGIN_INHERIT)
|
||||
style->margin[i] = apply->margin[i];
|
||||
|
||||
if (apply->padding[i].padding != CSS_PADDING_INHERIT)
|
||||
style->padding[i] = apply->padding[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void css_merge(struct css_style * const style, const struct css_style * const apply)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (apply->background_color != CSS_COLOR_INHERIT)
|
||||
style->background_color = apply->background_color;
|
||||
if (apply->clear != CSS_CLEAR_INHERIT)
|
||||
@ -876,6 +967,21 @@ void css_merge(struct css_style * const style, const struct css_style * const ap
|
||||
style->width = apply->width;
|
||||
if (apply->white_space != CSS_WHITE_SPACE_INHERIT)
|
||||
style->white_space = apply->white_space;
|
||||
|
||||
for (i = 0; i != 4; i++) {
|
||||
if (apply->border[i].color != CSS_COLOR_INHERIT)
|
||||
style->border[i].color = apply->border[i].color;
|
||||
if (apply->border[i].width.width != CSS_BORDER_WIDTH_INHERIT)
|
||||
style->border[i].width = apply->border[i].width;
|
||||
if (apply->border[i].style != CSS_BORDER_STYLE_INHERIT)
|
||||
style->border[i].style = apply->border[i].style;
|
||||
|
||||
if (apply->margin[i].margin != CSS_MARGIN_INHERIT)
|
||||
style->margin[i] = apply->margin[i];
|
||||
|
||||
if (apply->padding[i].padding != CSS_PADDING_INHERIT)
|
||||
style->padding[i] = apply->padding[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
36
css/css.h
36
css/css.h
@ -35,6 +35,10 @@ typedef unsigned long colour; /* 0xbbggrr */
|
||||
#define TRANSPARENT 0x1000000
|
||||
#define CSS_COLOR_INHERIT 0x2000000
|
||||
#define CSS_COLOR_NONE 0x3000000
|
||||
#define TOP 0
|
||||
#define RIGHT 1
|
||||
#define BOTTOM 2
|
||||
#define LEFT 3
|
||||
|
||||
/** Representation of a CSS 2 length. */
|
||||
struct css_length {
|
||||
@ -55,6 +59,17 @@ typedef enum {
|
||||
/** Representation of a complete CSS 2 style. */
|
||||
struct css_style {
|
||||
colour background_color;
|
||||
|
||||
struct {
|
||||
colour color;
|
||||
struct {
|
||||
enum { CSS_BORDER_WIDTH_INHERIT,
|
||||
CSS_BORDER_WIDTH_LENGTH } width;
|
||||
struct css_length value;
|
||||
} width;
|
||||
css_border_style style;
|
||||
} border[4]; /**< top, right, bottom, left */
|
||||
|
||||
css_clear clear;
|
||||
colour color;
|
||||
css_display display;
|
||||
@ -96,6 +111,27 @@ struct css_style {
|
||||
} value;
|
||||
} line_height;
|
||||
|
||||
struct {
|
||||
enum { CSS_MARGIN_INHERIT,
|
||||
CSS_MARGIN_LENGTH,
|
||||
CSS_MARGIN_PERCENT,
|
||||
CSS_MARGIN_AUTO } margin;
|
||||
union {
|
||||
struct css_length length;
|
||||
float percent;
|
||||
} value;
|
||||
} margin[4]; /**< top, right, bottom, left */
|
||||
|
||||
struct {
|
||||
enum { CSS_PADDING_INHERIT,
|
||||
CSS_PADDING_LENGTH,
|
||||
CSS_PADDING_PERCENT } padding;
|
||||
union {
|
||||
struct css_length length;
|
||||
float percent;
|
||||
} value;
|
||||
} padding[4]; /**< top, right, bottom, left */
|
||||
|
||||
css_text_align text_align;
|
||||
css_text_decoration text_decoration;
|
||||
struct {
|
||||
|
@ -2,8 +2,7 @@ css_unit em ex px in cm mm pt pc
|
||||
css_background_attachment inherit fixed scroll
|
||||
css_background_position inherit top center bottom left right length percent
|
||||
css_background_repeat inherit repeat repeat_x repeat_y no_repeat
|
||||
css_border_width inherit medium thin thick length
|
||||
css_border_style inherit none dashed dotted double groove inset outset ridge solid
|
||||
css_border_style inherit none hidden dotted dashed solid double groove ridge inset outset
|
||||
css_clear inherit none both left right
|
||||
css_display inherit inline block list-item run-in inline-block table inline-table table-row-group table-header-group table-footer-group table-row table-column-group table-column table-cell table-caption none
|
||||
css_float inherit none left right
|
||||
@ -14,7 +13,6 @@ css_font_weight inherit normal bold bolder lighter 100 200 300 400 500 600 700 8
|
||||
css_letter_spacing normal length
|
||||
css_list_style_position outside inside
|
||||
css_list_style_type disc circle square decimal lower_alpha lower_roman upper_alpha upper_roman none
|
||||
css_margin auto length percent
|
||||
css_text_align inherit left right center justify
|
||||
css_text_transform inherit none capitalize lowercase uppercase
|
||||
css_vertical_align baseline bottom middle sub super text_bottom text_top top percent
|
||||
|
257
css/ruleset.c
257
css/ruleset.c
@ -39,6 +39,26 @@ static int parse_length(struct css_length * const length,
|
||||
static colour parse_colour(const struct css_node * const v);
|
||||
static void parse_background(struct css_style * const s, const struct css_node * v);
|
||||
static void parse_background_color(struct css_style * const s, const struct css_node * const v);
|
||||
static void parse_border(struct css_style * const s, const struct css_node * v);
|
||||
static void parse_border_bottom(struct css_style * const s, const struct css_node * v);
|
||||
static void parse_border_bottom_color(struct css_style * const s, const struct css_node * v);
|
||||
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_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);
|
||||
static void parse_border_left_width(struct css_style * const s, const struct css_node * v);
|
||||
static void parse_border_right(struct css_style * const s, const struct css_node * v);
|
||||
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_style(struct css_style * const s, const struct css_node * v);
|
||||
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_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);
|
||||
@ -51,6 +71,20 @@ static void parse_font_variant(struct css_style * const s, const struct css_node
|
||||
static void parse_font_weight(struct css_style * const s, const struct css_node * const v);
|
||||
static void parse_height(struct css_style * const s, const struct css_node * const v);
|
||||
static void parse_line_height(struct css_style * const s, const struct css_node * const v);
|
||||
static void parse_margin(struct css_style * const s, const struct css_node * const v);
|
||||
static void parse_margin_bottom(struct css_style * const s, const struct css_node * const v);
|
||||
static void parse_margin_left(struct css_style * const s, const struct css_node * const v);
|
||||
static void parse_margin_right(struct css_style * const s, const struct css_node * const v);
|
||||
static void parse_margin_top(struct css_style * const s, const struct css_node * const v);
|
||||
static void parse_margin_side(struct css_style * const s, const struct css_node * const v,
|
||||
unsigned int i);
|
||||
static void parse_padding(struct css_style * const s, const struct css_node * const v);
|
||||
static void parse_padding_bottom(struct css_style * const s, const struct css_node * const v);
|
||||
static void parse_padding_left(struct css_style * const s, const struct css_node * const v);
|
||||
static void parse_padding_right(struct css_style * const s, const struct css_node * const v);
|
||||
static void parse_padding_top(struct css_style * const s, const struct css_node * const v);
|
||||
static void parse_padding_side(struct css_style * const s, const struct css_node * const v,
|
||||
unsigned int i);
|
||||
static void parse_text_align(struct css_style * const s, const struct css_node * const v);
|
||||
static void parse_text_decoration(struct css_style * const s, const struct css_node * const v);
|
||||
static void parse_text_indent(struct css_style * const s, const struct css_node * const v);
|
||||
@ -65,6 +99,26 @@ 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-bottom", parse_border_bottom },
|
||||
{ "border-bottom-color", parse_border_bottom_color },
|
||||
{ "border-bottom-style", parse_border_bottom_style },
|
||||
{ "border-bottom-width", parse_border_bottom_width },
|
||||
{ "border-color", parse_border_color },
|
||||
{ "border-left", parse_border_left },
|
||||
{ "border-left-color", parse_border_left_color },
|
||||
{ "border-left-style", parse_border_left_style },
|
||||
{ "border-left-width", parse_border_left_width },
|
||||
{ "border-right", parse_border_right },
|
||||
{ "border-right-color", parse_border_right_color },
|
||||
{ "border-right-style", parse_border_right_style },
|
||||
{ "border-right-width", parse_border_right_width },
|
||||
{ "border-style", parse_border_style },
|
||||
{ "border-top", parse_border_top },
|
||||
{ "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 },*/
|
||||
{ "clear", parse_clear },
|
||||
{ "color", parse_color },
|
||||
{ "display", parse_display },
|
||||
@ -77,6 +131,16 @@ static const struct property_entry property_table[] = {
|
||||
{ "font-weight", parse_font_weight },
|
||||
{ "height", parse_height },
|
||||
{ "line-height", parse_line_height },
|
||||
{ "margin", parse_margin },
|
||||
{ "margin-bottom", parse_margin_bottom },
|
||||
{ "margin-left", parse_margin_left },
|
||||
{ "margin-right", parse_margin_right },
|
||||
{ "margin-top", parse_margin_top },
|
||||
{ "padding", parse_padding },
|
||||
{ "padding-bottom", parse_padding_bottom },
|
||||
{ "padding-left", parse_padding_left },
|
||||
{ "padding-right", parse_padding_right },
|
||||
{ "padding-top", parse_padding_top },
|
||||
{ "text-align", parse_text_align },
|
||||
{ "text-decoration", parse_text_decoration },
|
||||
{ "text-indent", parse_text_indent },
|
||||
@ -274,6 +338,11 @@ int parse_length(struct css_length * const length,
|
||||
{
|
||||
css_unit u;
|
||||
float value;
|
||||
if (v->type == CSS_NODE_NUMBER && atof(v->data) == 0) {
|
||||
length->unit = CSS_UNIT_EM;
|
||||
length->value = 0;
|
||||
return 0;
|
||||
}
|
||||
if (v->type != CSS_NODE_DIMENSION)
|
||||
return 1;
|
||||
u = css_unit_parse(v->data + strspn(v->data, "0123456789+-."));
|
||||
@ -542,7 +611,8 @@ void parse_height(struct css_style * const s, const struct css_node * const v)
|
||||
{
|
||||
if (v->type == CSS_NODE_IDENT && strcasecmp(v->data, "auto") == 0)
|
||||
s->height.height = CSS_HEIGHT_AUTO;
|
||||
else if (v->type == CSS_NODE_DIMENSION && parse_length(&s->height.length, v, true) == 0)
|
||||
else if ((v->type == CSS_NODE_DIMENSION || v->type == CSS_NODE_NUMBER) &&
|
||||
parse_length(&s->height.length, v, true) == 0)
|
||||
s->height.height = CSS_HEIGHT_LENGTH;
|
||||
}
|
||||
|
||||
@ -563,6 +633,186 @@ void parse_line_height(struct css_style * const s, const struct css_node * const
|
||||
}
|
||||
}
|
||||
|
||||
void parse_margin(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, "auto") == 0))) ||
|
||||
(w->type == CSS_NODE_PERCENTAGE) ||
|
||||
(w->type == CSS_NODE_DIMENSION) ||
|
||||
(w->type == CSS_NODE_NUMBER)))
|
||||
return;
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void parse_margin_side(struct css_style * const s, const struct css_node * const v,
|
||||
unsigned int i)
|
||||
{
|
||||
if (v->type == CSS_NODE_IDENT && strcasecmp(v->data, "inherit") == 0)
|
||||
s->margin[i].margin = CSS_MARGIN_INHERIT;
|
||||
else if (v->type == CSS_NODE_IDENT && strcasecmp(v->data, "auto") == 0)
|
||||
s->margin[i].margin = CSS_MARGIN_AUTO;
|
||||
else if (v->type == CSS_NODE_PERCENTAGE) {
|
||||
s->margin[i].margin = CSS_MARGIN_PERCENT;
|
||||
s->margin[i].value.percent = atof(v->data);
|
||||
} else if ((v->type == CSS_NODE_DIMENSION || v->type == CSS_NODE_NUMBER) &&
|
||||
parse_length(&s->margin[i].value.length, v, false) == 0) {
|
||||
s->margin[i].margin = CSS_MARGIN_LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
void parse_padding(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) ||
|
||||
(w->type == CSS_NODE_PERCENTAGE) ||
|
||||
(w->type == CSS_NODE_DIMENSION) ||
|
||||
(w->type == CSS_NODE_NUMBER)))
|
||||
return;
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void parse_padding_side(struct css_style * const s, const struct css_node * const v,
|
||||
unsigned int i)
|
||||
{
|
||||
if (v->type == CSS_NODE_IDENT && strcasecmp(v->data, "inherit") == 0)
|
||||
s->padding[i].padding = CSS_PADDING_INHERIT;
|
||||
else if (v->type == CSS_NODE_PERCENTAGE) {
|
||||
s->padding[i].padding = CSS_PADDING_PERCENT;
|
||||
s->padding[i].value.percent = atof(v->data);
|
||||
} else if ((v->type == CSS_NODE_DIMENSION || v->type == CSS_NODE_NUMBER) &&
|
||||
parse_length(&s->padding[i].value.length, v, true) == 0) {
|
||||
s->padding[i].padding = CSS_PADDING_LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
void parse_text_align(struct css_style * const s, const struct css_node * const v)
|
||||
{
|
||||
css_text_align z;
|
||||
@ -580,7 +830,8 @@ void parse_text_indent(struct css_style * const s, const struct css_node * const
|
||||
} else if (v->type == CSS_NODE_PERCENTAGE) {
|
||||
s->text_indent.size = CSS_TEXT_INDENT_PERCENT;
|
||||
s->text_indent.value.percent = atof(v->data);
|
||||
} else if (v->type == CSS_NODE_DIMENSION && parse_length(&s->text_indent.value.length, v, true) == 0) {
|
||||
} else if ((v->type == CSS_NODE_DIMENSION || v->type == CSS_NODE_NUMBER) &&
|
||||
parse_length(&s->text_indent.value.length, v, true) == 0) {
|
||||
s->text_indent.size = CSS_TEXT_INDENT_LENGTH;
|
||||
}
|
||||
}
|
||||
@ -633,7 +884,7 @@ void parse_width(struct css_style * const s, const struct css_node * const v)
|
||||
else if (v->type == CSS_NODE_PERCENTAGE) {
|
||||
s->width.width = CSS_WIDTH_PERCENT;
|
||||
s->width.value.percent = atof(v->data);
|
||||
} else if (v->type == CSS_NODE_DIMENSION &&
|
||||
} else if ((v->type == CSS_NODE_DIMENSION || v->type == CSS_NODE_NUMBER) &&
|
||||
parse_length(&s->width.value.length, v, true) == 0)
|
||||
s->width.width = CSS_WIDTH_LENGTH;
|
||||
}
|
||||
|
@ -162,6 +162,7 @@ void box_add_child(struct box * parent, struct box * child)
|
||||
struct box * box_create(struct css_style * style,
|
||||
char *href, char *title, pool box_pool)
|
||||
{
|
||||
unsigned int i;
|
||||
struct box *box = pool_alloc(box_pool, sizeof (struct box));
|
||||
assert(box);
|
||||
box->type = BOX_INLINE;
|
||||
@ -195,6 +196,8 @@ struct box * box_create(struct css_style * style,
|
||||
#endif
|
||||
box->x = box->y = 0;
|
||||
box->height = 0;
|
||||
for (i = 0; i != 4; i++)
|
||||
box->margin[i] = box->padding[i] = box->border[i] = 0;
|
||||
return box;
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,11 @@ struct plugin_params {};
|
||||
struct box {
|
||||
box_type type;
|
||||
struct css_style * style;
|
||||
long x, y, width, height;
|
||||
int x; /**< Coordinate of left padding edge relative to parent box. */
|
||||
int y; /**< Coordinate of top padding edge relative to parent box. */
|
||||
int width; /**< Width of content box (excluding padding etc.). */
|
||||
int height; /**< Height of content box (excluding padding etc.). */
|
||||
int margin[4], padding[4], border[4];
|
||||
long min_width, max_width;
|
||||
char * text;
|
||||
unsigned int space : 1; /* 1 <=> followed by a space */
|
||||
|
202
render/layout.c
202
render/layout.c
@ -26,13 +26,16 @@
|
||||
#include "netsurf/utils/log.h"
|
||||
#include "netsurf/utils/utils.h"
|
||||
|
||||
/**
|
||||
* internal functions
|
||||
*/
|
||||
|
||||
#define AUTO INT_MIN
|
||||
|
||||
|
||||
static void layout_node(struct box * box, unsigned long width, struct box * cont,
|
||||
unsigned long cx, unsigned long cy);
|
||||
static unsigned long layout_block_children(struct box * box, unsigned long width, struct box * cont,
|
||||
static int layout_block_find_dimensions(unsigned long available_width,
|
||||
struct css_style *style,
|
||||
int margin[4], int padding[4], int border[4]);
|
||||
static void layout_block_children(struct box *box, struct box *cont,
|
||||
unsigned long cx, unsigned long cy);
|
||||
static void find_sides(struct box * fl, unsigned long y0, unsigned long y1,
|
||||
unsigned long * x0, unsigned long * x1, struct box ** left, struct box ** right);
|
||||
@ -50,20 +53,17 @@ static void calculate_table_widths(struct box *table);
|
||||
|
||||
|
||||
/**
|
||||
* layout algorithm
|
||||
*/
|
||||
|
||||
/**
|
||||
* layout_document -- calculate positions of boxes in a document
|
||||
* Calculate positions of boxes in a document.
|
||||
*
|
||||
* doc root of document box tree
|
||||
* width page width
|
||||
* \param doc root of document box tree
|
||||
* \param width page width
|
||||
*/
|
||||
|
||||
void layout_document(struct box * doc, unsigned long width)
|
||||
{
|
||||
struct box *box;
|
||||
doc->float_children = 0;
|
||||
doc->x = doc->y = 0;
|
||||
layout_node(doc, width, doc, 0, 0);
|
||||
for (box = doc->float_children; box != 0; box = box->next_float)
|
||||
if (doc->height < box->y + box->height)
|
||||
@ -71,6 +71,16 @@ void layout_document(struct box * doc, unsigned long width)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Layout the children of a box.
|
||||
*
|
||||
* \param box box to layout
|
||||
* \param width horizontal space available
|
||||
* \param cont ancestor box which defines horizontal space, for inlines
|
||||
* \param cx box position relative to cont
|
||||
* \param cy box position relative to cont
|
||||
*/
|
||||
|
||||
void layout_node(struct box * box, unsigned long width, struct box * cont,
|
||||
unsigned long cx, unsigned long cy)
|
||||
{
|
||||
@ -78,6 +88,13 @@ void layout_node(struct box * box, unsigned long width, struct box * cont,
|
||||
|
||||
gui_multitask();
|
||||
|
||||
if (box->style) {
|
||||
box->width = layout_block_find_dimensions(width, box->style,
|
||||
box->margin, box->padding, box->border);
|
||||
box->x += box->margin[LEFT] + box->border[LEFT];
|
||||
box->y += box->margin[TOP] + box->border[TOP];
|
||||
}
|
||||
|
||||
switch (box->type) {
|
||||
case BOX_BLOCK:
|
||||
case BOX_INLINE_BLOCK:
|
||||
@ -96,12 +113,13 @@ void layout_node(struct box * box, unsigned long width, struct box * cont,
|
||||
|
||||
|
||||
/**
|
||||
* layout_block -- position block and recursively layout children
|
||||
* Layout the children of a block box.
|
||||
*
|
||||
* box block box to layout
|
||||
* width horizontal space available
|
||||
* cont ancestor box which defines horizontal space, for inlines
|
||||
* cx, cy box position relative to cont
|
||||
* \param box block box to layout
|
||||
* \param width horizontal space available
|
||||
* \param cont ancestor box which defines horizontal space, for inlines
|
||||
* \param cx box position relative to cont
|
||||
* \param cy box position relative to cont
|
||||
*/
|
||||
|
||||
void layout_block(struct box * box, unsigned long width, struct box * cont,
|
||||
@ -114,20 +132,7 @@ void layout_block(struct box * box, unsigned long width, struct box * cont,
|
||||
|
||||
LOG(("box %p, width %lu, cont %p, cx %lu, cy %lu", box, width, cont, cx, cy));
|
||||
|
||||
switch (style->width.width) {
|
||||
case CSS_WIDTH_LENGTH:
|
||||
box->width = len(&style->width.value.length, style);
|
||||
break;
|
||||
case CSS_WIDTH_PERCENT:
|
||||
box->width = width * style->width.value.percent / 100;
|
||||
break;
|
||||
case CSS_WIDTH_AUTO:
|
||||
default:
|
||||
/* take all available width */
|
||||
box->width = width;
|
||||
break;
|
||||
}
|
||||
box->height = layout_block_children(box, (unsigned int)box->width, cont, cx, cy);
|
||||
layout_block_children(box, cont, cx, cy);
|
||||
switch (style->height.height) {
|
||||
case CSS_HEIGHT_LENGTH:
|
||||
box->height = len(&style->height.length, style);
|
||||
@ -141,16 +146,118 @@ void layout_block(struct box * box, unsigned long width, struct box * cont,
|
||||
|
||||
|
||||
/**
|
||||
* layout_block_children -- recursively layout block children
|
||||
*
|
||||
* (as above)
|
||||
* Compute dimensions of box, margins, paddings, and borders for a block box.
|
||||
*/
|
||||
|
||||
unsigned long layout_block_children(struct box * box, unsigned long width, struct box * cont,
|
||||
int layout_block_find_dimensions(unsigned long available_width,
|
||||
struct css_style *style,
|
||||
int margin[4], int padding[4], int border[4])
|
||||
{
|
||||
unsigned int i;
|
||||
int width;
|
||||
|
||||
/* calculate box width */
|
||||
switch (style->width.width) {
|
||||
case CSS_WIDTH_LENGTH:
|
||||
width = len(&style->width.value.length, style);
|
||||
break;
|
||||
case CSS_WIDTH_PERCENT:
|
||||
width = available_width * style->width.value.percent / 100;
|
||||
break;
|
||||
case CSS_WIDTH_AUTO:
|
||||
default:
|
||||
width = AUTO;
|
||||
break;
|
||||
}
|
||||
|
||||
/* calculate size of margins, paddings, and borders */
|
||||
for (i = 0; i != 4; i++) {
|
||||
switch (style->margin[i].margin) {
|
||||
case CSS_MARGIN_LENGTH:
|
||||
margin[i] = len(&style->margin[i].value.length, style);
|
||||
break;
|
||||
case CSS_MARGIN_PERCENT:
|
||||
margin[i] = available_width *
|
||||
style->margin[i].value.percent / 100;
|
||||
break;
|
||||
case CSS_MARGIN_AUTO:
|
||||
default:
|
||||
margin[i] = AUTO;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (style->padding[i].padding) {
|
||||
case CSS_MARGIN_PERCENT:
|
||||
padding[i] = available_width *
|
||||
style->padding[i].value.percent / 100;
|
||||
break;
|
||||
case CSS_PADDING_LENGTH:
|
||||
default:
|
||||
padding[i] = len(&style->padding[i].value.length, style);
|
||||
break;
|
||||
}
|
||||
|
||||
if (style->border[i].style == CSS_BORDER_STYLE_NONE ||
|
||||
style->border[i].style == CSS_BORDER_STYLE_HIDDEN)
|
||||
/* spec unclear: following Mozilla */
|
||||
border[i] = 0;
|
||||
else
|
||||
border[i] = len(&style->border[i].width.value, style);
|
||||
}
|
||||
|
||||
/* solve the width constraint as given in CSS 2.1 section 10.3.3 */
|
||||
if (width == AUTO) {
|
||||
/* any other 'auto' become 0 */
|
||||
if (margin[LEFT] == AUTO)
|
||||
margin[LEFT] = 0;
|
||||
if (margin[RIGHT] == AUTO)
|
||||
margin[RIGHT] = 0;
|
||||
width = available_width -
|
||||
(margin[LEFT] + border[LEFT] + padding[LEFT] +
|
||||
padding[RIGHT] + border[RIGHT] + margin[RIGHT]);
|
||||
} else if (margin[LEFT] == AUTO && margin[RIGHT] == AUTO) {
|
||||
/* make the margins equal, centering the element */
|
||||
margin[LEFT] = margin[RIGHT] = (available_width -
|
||||
(border[LEFT] + padding[LEFT] + width +
|
||||
padding[RIGHT] + border[RIGHT])) / 2;
|
||||
} else if (margin[LEFT] == AUTO) {
|
||||
margin[LEFT] = available_width -
|
||||
(border[LEFT] + padding[LEFT] + width +
|
||||
padding[RIGHT] + border[RIGHT] + margin[RIGHT]);
|
||||
} else {
|
||||
/* margin-right auto or "over-constained" */
|
||||
margin[RIGHT] = available_width -
|
||||
(margin[LEFT] + border[LEFT] + padding[LEFT] +
|
||||
width + padding[RIGHT] + border[RIGHT]);
|
||||
}
|
||||
|
||||
if (margin[TOP] == AUTO)
|
||||
margin[TOP] = 0;
|
||||
if (margin[BOTTOM] == AUTO)
|
||||
margin[BOTTOM] = 0;
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recursively layout block children.
|
||||
*
|
||||
* \param box block box to layout
|
||||
* \param cont ancestor box which defines horizontal space, for inlines
|
||||
* \param cx box position relative to cont
|
||||
* \param cy box position relative to cont
|
||||
*
|
||||
* box->width, box->margin, box->padding and box->border must be valid.
|
||||
* box->height is filled in.
|
||||
*/
|
||||
|
||||
void layout_block_children(struct box *box, struct box *cont,
|
||||
unsigned long cx, unsigned long cy)
|
||||
{
|
||||
struct box * c;
|
||||
unsigned long y = 0;
|
||||
struct box *c;
|
||||
int width = box->width;
|
||||
int y = box->padding[TOP];
|
||||
|
||||
assert(box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK ||
|
||||
box->type == BOX_FLOAT_LEFT || box->type == BOX_FLOAT_RIGHT ||
|
||||
@ -179,14 +286,15 @@ unsigned long layout_block_children(struct box * box, unsigned long width, struc
|
||||
(c->style->clear == CSS_CLEAR_BOTH && (left != 0 || right != 0)));
|
||||
}
|
||||
|
||||
c->x = 0;
|
||||
c->x = box->padding[LEFT];
|
||||
c->y = y;
|
||||
layout_node(c, width, cont, cx, cy + y);
|
||||
y = c->y + c->height;
|
||||
y = c->y + c->height + c->padding[TOP] + c->padding[BOTTOM] +
|
||||
c->border[BOTTOM] + c->margin[BOTTOM];
|
||||
if (box->width < c->width)
|
||||
box->width = c->width;
|
||||
}
|
||||
return y;
|
||||
box->height = y - box->padding[TOP];
|
||||
}
|
||||
|
||||
|
||||
@ -593,19 +701,7 @@ void layout_table(struct box * table, unsigned long width, struct box * cont,
|
||||
calculate_table_widths(table);
|
||||
memcpy(col, table->col, sizeof(col[0]) * columns);
|
||||
|
||||
/* find table width */
|
||||
switch (table->style->width.width) {
|
||||
case CSS_WIDTH_LENGTH:
|
||||
table_width = len(&table->style->width.value.length, table->style);
|
||||
break;
|
||||
case CSS_WIDTH_PERCENT:
|
||||
table_width = width * table->style->width.value.percent / 100;
|
||||
break;
|
||||
case CSS_WIDTH_AUTO:
|
||||
default:
|
||||
table_width = width;
|
||||
break;
|
||||
}
|
||||
table_width = table->width;
|
||||
|
||||
LOG(("width %lu, min %lu, max %lu", table_width, table->min_width, table->max_width));
|
||||
|
||||
@ -710,7 +806,7 @@ void layout_table(struct box * table, unsigned long width, struct box * cont,
|
||||
assert(c->style != 0);
|
||||
c->width = xs[c->start_column + c->columns] - xs[c->start_column];
|
||||
c->float_children = 0;
|
||||
c->height = layout_block_children(c, (unsigned long)c->width, c, 0, 0);
|
||||
layout_block_children(c, c, 0, 0);
|
||||
if (c->style->height.height == CSS_HEIGHT_LENGTH) {
|
||||
/* some sites use height="1" or similar to attempt
|
||||
* to make cells as small as possible, so treat
|
||||
|
@ -28,6 +28,7 @@ extern int current_menu_x, current_menu_y, iconbar_menu_height;
|
||||
extern struct form_control *current_gadget;
|
||||
extern gui_window *window_list;
|
||||
extern bool gui_reformat_pending;
|
||||
extern bool gui_redraw_debug;
|
||||
|
||||
struct gui_window
|
||||
{
|
||||
|
@ -28,6 +28,10 @@ static void html_redraw_box(struct content *content, struct box * box,
|
||||
long clip_x0, long clip_y0, long clip_x1, long clip_y1);
|
||||
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,
|
||||
os_colour colour);
|
||||
|
||||
bool gui_redraw_debug = false;
|
||||
|
||||
|
||||
void html_redraw(struct content *c, long x, long y,
|
||||
@ -57,13 +61,9 @@ void html_redraw(struct content *c, long x, long y,
|
||||
|
||||
|
||||
/* validation strings can't be const */
|
||||
static char validation_select[] = "R2";
|
||||
static char validation_checkbox_selected[] = "Sopton";
|
||||
static char validation_checkbox_unselected[] = "Soptoff";
|
||||
|
||||
static char select_text_multiple[] = "<Multiple>"; /* TODO: read from messages */
|
||||
static char select_text_none[] = "<None>";
|
||||
|
||||
static char empty_text[] = "";
|
||||
|
||||
void html_redraw_box(struct content *content, struct box * box,
|
||||
@ -74,30 +74,40 @@ void html_redraw_box(struct content *content, struct box * box,
|
||||
long clip_x0, long clip_y0, long clip_x1, long clip_y1)
|
||||
{
|
||||
struct box *c;
|
||||
char *select_text;
|
||||
struct form_option *opt;
|
||||
int width, height, x0, y0, x1, y1, colour;
|
||||
|
||||
x += box->x * 2;
|
||||
y -= box->y * 2;
|
||||
width = box->width * 2;
|
||||
height = box->height * 2;
|
||||
width = (box->padding[LEFT] + box->width + box->padding[RIGHT]) * 2;
|
||||
height = (box->padding[TOP] + box->height + box->padding[BOTTOM]) * 2;
|
||||
|
||||
x0 = x;
|
||||
y1 = y - 1;
|
||||
x1 = x0 + width - 1;
|
||||
y0 = y1 - height + 1;
|
||||
|
||||
/* return if visibility is hidden or inherited visibility is hidden
|
||||
*/
|
||||
/* if visibility is hidden render children only */
|
||||
if (box->style->visibility == CSS_VISIBILITY_HIDDEN) {
|
||||
for (c=box->children;c!=0;c=c->next)
|
||||
for (c = box->children; c; c = c->next)
|
||||
html_redraw_box(content, c, x, y, current_background_color,
|
||||
gadget_subtract_x, gadget_subtract_y, select_on,
|
||||
x0, y0, x1, y1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gui_redraw_debug) {
|
||||
html_redraw_rectangle(x, y, width, height, os_COLOUR_MAGENTA);
|
||||
html_redraw_rectangle(x + box->padding[LEFT] * 2, y - box->padding[TOP] * 2,
|
||||
box->width * 2, box->height * 2, os_COLOUR_CYAN);
|
||||
html_redraw_rectangle(x - (box->border[LEFT] + box->margin[LEFT]) * 2,
|
||||
y + (box->border[TOP] + box->margin[TOP]) * 2,
|
||||
width + (box->border[LEFT] + box->margin[LEFT] +
|
||||
box->border[RIGHT] + box->margin[RIGHT]) * 2,
|
||||
height + (box->border[TOP] + box->margin[TOP] +
|
||||
box->border[BOTTOM] + box->margin[BOTTOM]) * 2,
|
||||
os_COLOUR_YELLOW);
|
||||
}
|
||||
|
||||
/* 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 &&
|
||||
@ -124,13 +134,14 @@ void html_redraw_box(struct content *content, struct box * box,
|
||||
|
||||
/* background colour */
|
||||
if (box->style != 0 && box->style->background_color != TRANSPARENT) {
|
||||
colourtrans_set_gcol(box->style->background_color << 8, colourtrans_USE_ECFS, os_ACTION_OVERWRITE, 0);
|
||||
colourtrans_set_gcol(box->style->background_color << 8,
|
||||
colourtrans_USE_ECFS, os_ACTION_OVERWRITE, 0);
|
||||
os_plot(os_MOVE_TO, x, y);
|
||||
os_plot(os_PLOT_RECTANGLE | os_PLOT_BY, width, -height);
|
||||
current_background_color = box->style->background_color;
|
||||
}
|
||||
|
||||
if (box->object /*&& box->object->type != CONTENT_HTML*/) {
|
||||
if (box->object) {
|
||||
content_redraw(box->object, x, y, (unsigned int)width,
|
||||
(unsigned int)height, x0, y0, x1, y1);
|
||||
|
||||
@ -145,66 +156,6 @@ void html_redraw_box(struct content *content, struct box * box,
|
||||
icon.extent.y1 = -gadget_subtract_y + y;
|
||||
|
||||
switch (box->gadget->type) {
|
||||
case GADGET_SELECT:
|
||||
icon.flags = wimp_ICON_TEXT | wimp_ICON_BORDER |
|
||||
wimp_ICON_VCENTRED | wimp_ICON_FILLED |
|
||||
wimp_ICON_INDIRECTED | wimp_ICON_HCENTRED |
|
||||
(wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) |
|
||||
(wimp_COLOUR_VERY_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT);
|
||||
select_text = 0;
|
||||
opt = box->gadget->data.select.items;
|
||||
// if (box->gadget->data.select.size == 1) {
|
||||
while (opt != NULL)
|
||||
{
|
||||
if (opt->selected)
|
||||
{
|
||||
if (select_text == 0)
|
||||
select_text = opt->text;
|
||||
else
|
||||
select_text = select_text_multiple;
|
||||
}
|
||||
opt = opt->next;
|
||||
}
|
||||
if (select_text == 0)
|
||||
select_text = select_text_none;
|
||||
/* }
|
||||
else {
|
||||
while (opt != NULL)
|
||||
{
|
||||
if (opt->selected)
|
||||
{
|
||||
select_text = opt->text;
|
||||
opt = opt->next;
|
||||
break;
|
||||
}
|
||||
opt = opt->next;
|
||||
}
|
||||
if (select_text == 0) {
|
||||
// display the first n options
|
||||
opt = box->gadget->data.select.items;
|
||||
select_text = opt->text;
|
||||
opt = opt->next;
|
||||
for(i = box->gadget->data.select.size-1;
|
||||
i != 0; i--, opt=opt->next) {
|
||||
strcat(select_text, "\n");
|
||||
strcat(select_text, opt->text);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(i = box->gadget->data.select.size-1;
|
||||
i != 0; i--, opt=opt->next) {
|
||||
strcat(select_text, "\n");
|
||||
strcat(select_text, opt->text);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/ icon.data.indirected_text.text = select_text;
|
||||
icon.data.indirected_text.size = strlen(icon.data.indirected_text.text);
|
||||
icon.data.indirected_text.validation = validation_select;
|
||||
LOG(("writing GADGET ACTION"));
|
||||
wimp_plot_icon(&icon);
|
||||
break;
|
||||
|
||||
case GADGET_CHECKBOX:
|
||||
icon.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE |
|
||||
wimp_ICON_VCENTRED | wimp_ICON_HCENTRED | wimp_ICON_INDIRECTED;
|
||||
@ -380,3 +331,14 @@ void html_redraw_clip(long clip_x0, long clip_y0,
|
||||
os_writec((char) (clip_y1 & 0xff)); os_writec((char) (clip_y1 >> 8));
|
||||
}
|
||||
|
||||
|
||||
void html_redraw_rectangle(int x0, int y0, int width, int height,
|
||||
os_colour colour)
|
||||
{
|
||||
colourtrans_set_gcol(colour, 0, os_ACTION_OVERWRITE, 0);
|
||||
os_plot(os_MOVE_TO, x0, y0);
|
||||
os_plot(os_PLOT_DOTTED | os_PLOT_BY, width, 0);
|
||||
os_plot(os_PLOT_DOTTED | os_PLOT_BY, 0, -height);
|
||||
os_plot(os_PLOT_DOTTED | os_PLOT_BY, -width, 0);
|
||||
os_plot(os_PLOT_DOTTED | os_PLOT_BY, 0, height);
|
||||
}
|
||||
|
@ -726,6 +726,11 @@ bool ro_gui_window_keypress(gui_window *g, int key, bool toolbar)
|
||||
cache_dump();
|
||||
return true;
|
||||
|
||||
case wimp_KEY_F11: /* Toggle display of box outlines. */
|
||||
gui_redraw_debug = !gui_redraw_debug;
|
||||
gui_window_redraw_window(g);
|
||||
return true;
|
||||
|
||||
case wimp_KEY_CONTROL + wimp_KEY_F2: /* Close window. */
|
||||
browser_window_destroy(g->data.browser.bw
|
||||
#ifdef WITH_FRAMES
|
||||
|
Loading…
Reference in New Issue
Block a user