[project @ 2002-12-30 02:06:03 by monkeyson]

Started support for img tag - doesn't attempt to fetch/render images yet.
Combo boxes in forms.

svn path=/import/netsurf/; revision=72
This commit is contained in:
Phil Mellor 2002-12-30 02:06:03 +00:00
parent 50fc20c2d4
commit 33a91eb2fe
5 changed files with 266 additions and 22 deletions

View File

@ -19,7 +19,7 @@ col { display: table-column }
colgroup { display: table-column-group }
td, th { display: table-cell }
caption { display: table-caption }
img { display:none}
img { display:inline}
h1 { font-size: xx-large; font-weight: bold; }
h2 { font-size: x-large; }

View File

@ -1,5 +1,5 @@
/**
* $Id: box.c,v 1.23 2002/12/29 22:27:35 monkeyson Exp $
* $Id: box.c,v 1.24 2002/12/30 02:06:03 monkeyson Exp $
*/
#include <assert.h>
@ -29,7 +29,8 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
struct css_stylesheet * stylesheet,
struct css_selector ** selector, unsigned int depth,
struct box * parent, struct box * inline_container,
const char *href, struct font_set *fonts);
const char *href, struct font_set *fonts,
struct gui_gadget* current_select, struct formoption* current_option);
struct css_style * box_get_style(struct css_stylesheet * stylesheet, struct css_style * parent_style,
xmlNode * n, struct css_selector * selector, unsigned int depth);
void box_normalise_block(struct box *block);
@ -80,6 +81,7 @@ struct box * box_create(xmlNode * node, box_type type, struct css_style * style,
box->col = 0;
box->font = 0;
box->gadget = 0;
box->img = 0;
return box;
}
@ -126,21 +128,28 @@ void xml_to_box(xmlNode * n, struct css_style * parent_style,
struct css_stylesheet * stylesheet,
struct css_selector ** selector, unsigned int depth,
struct box * parent, struct box * inline_container,
const char *href, struct font_set *fonts)
const char *href, struct font_set *fonts,
struct gui_gadget* current_select, struct formoption* current_option)
{
LOG(("node %p", n));
convert_xml_to_box(n, parent_style, stylesheet,
selector, depth, parent, inline_container, href, fonts);
selector, depth, parent, inline_container, href, fonts, current_select, current_option);
LOG(("normalising"));
box_normalise_block(parent->children);
}
void LOG2(char* log)
{
fprintf(stderr, "%s\n", log);
}
struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
struct css_stylesheet * stylesheet,
struct css_selector ** selector, unsigned int depth,
struct box * parent, struct box * inline_container,
const char *href, struct font_set *fonts)
const char *href, struct font_set *fonts,
struct gui_gadget* current_select, struct formoption* current_option)
{
struct box * box;
struct box * inline_container_c;
@ -177,6 +186,9 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
if (n->type == XML_TEXT_NODE ||
(n->type == XML_ELEMENT_NODE && (strcmp((const char *) n->name, "input") == 0)) ||
(n->type == XML_ELEMENT_NODE && (strcmp((const char *) n->name, "select") == 0)) ||
(n->type == XML_ELEMENT_NODE && (strcmp((const char *) n->name, "option") == 0)) ||
(n->type == XML_ELEMENT_NODE && (strcmp((const char *) n->name, "img") == 0)) ||
(n->type == XML_ELEMENT_NODE && (style->float_ == CSS_FLOAT_LEFT ||
style->float_ == CSS_FLOAT_RIGHT))) {
/* text nodes are converted to inline boxes, wrapped in an inline container block */
@ -186,7 +198,18 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
box_add_child(parent, inline_container);
}
if (n->type == XML_TEXT_NODE) {
LOG(("text node"));
LOG2("TEXT NODE");
if (current_option != 0)
{
char* thistext = squash_whitespace(tolat1(n->content));
LOG2("adding to option");
option_addtext(current_option, thistext);
LOG2("freeing thistext");
LOG2("arse");
}
else
{
LOG2(("text node"));
box = box_create(n, BOX_INLINE, parent_style, href);
box->text = squash_whitespace(tolat1(n->content));
box->length = strlen(box->text);
@ -198,13 +221,30 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
}
box->font = font_open(fonts, box->style);
box_add_child(inline_container, box);
}
} else if (strcmp((const char *) n->name, "img") == 0) {
LOG2(("image"));
box = box_image(n, parent_style);
if (box != NULL)
box_add_child(inline_container, box);
} else if (strcmp((const char *) n->name, "select") == 0) {
LOG2(("select"));
box = box_select(n, parent_style);
if (box != NULL)
{
box_add_child(inline_container, box);
current_select = box->gadget;
}
} else if (strcmp((const char *) n->name, "option") == 0) {
LOG2(("option"));
current_option = box_option(n, parent_style, current_select);
} else if (strcmp((const char *) n->name, "input") == 0) {
LOG(("input"));
LOG2(("input"));
box = box_gui_gadget(n, parent_style);
if (box != NULL)
box_add_child(inline_container, box);
} else {
LOG(("float"));
LOG2(("float"));
box = box_create(0, BOX_FLOAT_LEFT, 0, href);
if (style->float_ == CSS_FLOAT_RIGHT) box->type = BOX_FLOAT_RIGHT;
box_add_child(inline_container, box);
@ -224,14 +264,14 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
for (c = n->children; c != 0; c = c->next)
inline_container_c = convert_xml_to_box(c, style, stylesheet,
selector, depth + 1, box, inline_container_c,
href, fonts);
href, fonts, current_select, current_option);
inline_container = 0;
break;
case CSS_DISPLAY_INLINE: /* inline elements get no box, but their children do */
for (c = n->children; c != 0; c = c->next)
inline_container = convert_xml_to_box(c, style, stylesheet,
selector, depth + 1, parent, inline_container,
href, fonts);
href, fonts, current_select, current_option);
break;
case CSS_DISPLAY_TABLE:
box = box_create(n, BOX_TABLE, style, href);
@ -239,7 +279,7 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
for (c = n->children; c != 0; c = c->next)
convert_xml_to_box(c, style, stylesheet,
selector, depth + 1, box, 0,
href, fonts);
href, fonts, current_select, current_option);
inline_container = 0;
break;
case CSS_DISPLAY_TABLE_ROW_GROUP:
@ -251,7 +291,7 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
for (c = n->children; c != 0; c = c->next)
inline_container_c = convert_xml_to_box(c, style, stylesheet,
selector, depth + 1, box, inline_container_c,
href, fonts);
href, fonts, current_select, current_option);
inline_container = 0;
break;
case CSS_DISPLAY_TABLE_ROW:
@ -260,7 +300,7 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
for (c = n->children; c != 0; c = c->next)
convert_xml_to_box(c, style, stylesheet,
selector, depth + 1, box, 0,
href, fonts);
href, fonts, current_select, current_option);
inline_container = 0;
break;
case CSS_DISPLAY_TABLE_CELL:
@ -275,7 +315,7 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
for (c = n->children; c != 0; c = c->next)
inline_container_c = convert_xml_to_box(c, style, stylesheet,
selector, depth + 1, box, inline_container_c,
href, fonts);
href, fonts, current_select, current_option);
inline_container = 0;
break;
default:
@ -717,6 +757,11 @@ void box_free(struct box *box)
/* gadget_free(box->gadget); */
free((void*)box->gadget);
}
if (box->img != 0)
{
free((void*)box->img);
}
if (box->text != 0)
free((void*)box->text);
@ -730,6 +775,118 @@ void box_free(struct box *box)
}
}
struct box* box_image(xmlNode * n, struct css_style* style)
{
struct box* box = 0;
char* s;
box = box_create(n, BOX_INLINE, style, NULL);
box->img = xcalloc(1, sizeof(struct img));
box->text = 0;
box->length = 0;
box->font = 0;
if ((s = (char *) xmlGetProp(n, (xmlChar *) "width")))
{
box->img->width = atoi(s);
free(s);
}
else
box->img->width = 24;
if ((s = (char *) xmlGetProp(n, (xmlChar *) "height")))
{
box->img->height = atoi(s);
free(s);
}
else
box->img->height = 24;
if ((s = (char *) xmlGetProp(n, (xmlChar *) "alt")))
{
box->img->alt = s;
}
return box;
}
struct box* box_select(xmlNode * n, struct css_style* style)
{
struct box* box = 0;
char* s;
LOG2("creating box");
box = box_create(n, BOX_INLINE, style, NULL);
LOG2("creating gadget");
box->gadget = xcalloc(1, sizeof(struct gui_gadget));
box->gadget->type = GADGET_SELECT;
box->text = 0;
box->length = 0;
box->font = 0;
if ((s = (char *) xmlGetProp(n, (xmlChar *) "size")))
{
box->gadget->data.select.size = atoi(s);
free(s);
}
else
box->gadget->data.select.size = 1;
box->gadget->data.select.items = NULL;
box->gadget->data.select.numitems = 0;
/* to do: multiple, name */
LOG2("returning from select");
return box;
}
struct formoption* box_option(xmlNode* n, struct css_style* style, struct gui_gadget* current_select)
{
struct formoption* option;
assert(current_select != 0);
LOG2("realloc option");
if (current_select->data.select.items == 0)
{
option = xcalloc(1, sizeof(struct formoption));
current_select->data.select.items = option;
}
else
{
struct formoption* current;
option = xcalloc(1, sizeof(struct formoption));
current = current_select->data.select.items;
while (current->next != 0)
current = current->next;
current->next = option;
}
/* TO DO: set selected / value here */
LOG2("returning");
return option;
}
void option_addtext(struct formoption* option, char* text)
{
assert(option != 0);
assert(text != 0);
if (option->text == 0)
{
LOG2("option->text is 0");
option->text = strdup(text);
}
else
{
LOG2("option->text is realloced");
option->text = xrealloc(option->text, strlen(option->text) + strlen(text) + 1);
strcat(option->text, text);
}
LOG2("returning");
return;
}
struct box* box_gui_gadget(xmlNode * n, struct css_style* style)
{
struct box* box = 0;

View File

@ -1,5 +1,5 @@
/**
* $Id: box.h,v 1.13 2002/12/29 22:27:35 monkeyson Exp $
* $Id: box.h,v 1.14 2002/12/30 02:06:03 monkeyson Exp $
*/
#ifndef _NETSURF_RENDER_BOX_H_
@ -27,9 +27,16 @@ struct column {
unsigned long min, max, width;
};
struct formoption {
int selected;
char* value;
char* text;
struct formoption* next;
};
struct gui_gadget {
enum { GADGET_HIDDEN = 0, GADGET_TEXTBOX, GADGET_RADIO, GADGET_OPTION,
GADGET_COMBO, GADGET_LIST, GADGET_TEXTAREA, GADGET_ACTIONBUTTON } type;
GADGET_SELECT, GADGET_TEXTAREA, GADGET_ACTIONBUTTON } type;
union {
struct {
int maxlength;
@ -39,9 +46,22 @@ struct gui_gadget {
struct {
char* label;
} actionbutt;
struct {
int numitems;
struct formoption* items;
int size;
int multiple;
} select;
} data;
};
struct img {
int width;
int height;
char* alt;
char* src;
};
struct box {
box_type type;
xmlNode * node;
@ -62,6 +82,7 @@ struct box {
struct column *col;
struct font_data *font;
struct gui_gadget* gadget;
struct img* img;
};
#define UNKNOWN_WIDTH ULONG_MAX
@ -74,7 +95,8 @@ struct box {
void xml_to_box(xmlNode * n, struct css_style * parent_style, struct css_stylesheet * stylesheet,
struct css_selector ** selector, unsigned int depth,
struct box * parent, struct box * inline_container,
const char *href, struct font_set *fonts);
const char *href, struct font_set *fonts,
struct gui_gadget* current_select, struct formoption* current_option);
void box_dump(struct box * box, unsigned int depth);
void box_free(struct box *box);

View File

@ -1,5 +1,5 @@
/**
* $Id: layout.c,v 1.28 2002/12/29 22:27:35 monkeyson Exp $
* $Id: layout.c,v 1.29 2002/12/30 02:06:03 monkeyson Exp $
*/
#include <assert.h>
@ -109,14 +109,38 @@ void layout_node(struct box * box, unsigned long width, struct box * cont,
int img_width(struct img* img)
{
return img->width;
}
int img_height(struct img* img)
{
return img->height;
}
int gadget_width(struct gui_gadget* gadget)
{
struct formoption* current;
int max;
/* should use wimp_textop via a gui wraper for these */
switch (gadget->type)
{
case GADGET_TEXTBOX:
return gadget->data.textbox.size * 8;
case GADGET_ACTIONBUTTON:
return strlen(gadget->data.actionbutt.label) * 8 + 16;
case GADGET_SELECT:
current = gadget->data.select.items;
max = 32;
while (current != NULL)
{
if (strlen(current->text) * 8 + 16 > max)
max = strlen(current->text) * 8 + 16;
current = current->next;
}
return max;
default:
assert(0);
}
@ -131,6 +155,8 @@ int gadget_height(struct gui_gadget* gadget)
return 28;
case GADGET_ACTIONBUTTON:
return 28;
case GADGET_SELECT:
return 28;
default:
assert(0);
}
@ -331,6 +357,8 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long
/* get minimum line height from containing block */
if (first->text != 0)
height = line_height(first->parent->parent->style);
else if (first->img != 0)
height = img_height(first->img);
else if (first->gadget != 0)
height = gadget_height(first->gadget);
@ -340,6 +368,8 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long
if (b->type == BOX_INLINE) {
if (b->text != 0)
h = line_height(b->style ? b->style : b->parent->parent->style);
else if (b->img != 0)
h = img_height(b->img);
else if (b->gadget != 0)
h = gadget_height(b->gadget);
@ -347,12 +377,14 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long
if (h > height) height = h;
if (b->width == UNKNOWN_WIDTH && b->font != 0)
b->width = font_width(b->font, b->text, b->length);
else if (b->width == UNKNOWN_WIDTH && b->img != 0)
b->width = img_width(b->img);
else if (b->width == UNKNOWN_WIDTH && b->gadget != 0)
b->width = gadget_width(b->gadget);
if (b->font != 0)
x += b->width + b->space ? b->font->space_width : 0;
else if (b->gadget != 0)
else if (b->gadget != 0 || b->img != 0)
x += b->width;
}
}
@ -425,6 +457,8 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long
w = c->width;
else if (c->font != 0)
w = font_width(c->font, c->text, space - c->text);
else if (c->img != 0)
w = img_width(c->img);
else if (c->gadget != 0)
w = gadget_width(c->gadget);
@ -733,6 +767,13 @@ void calculate_inline_container_widths(struct box *box)
width = font_width(child->font, word, strlen(word));
if (min < width) min = width;
}
else if (child->img != 0)
{
child->width = img_width(child->img);
max += child->width;
if (min < child->width)
min = child->width;
}
else if (child->gadget != 0)
{
child->width = gadget_width(child->gadget);
@ -777,6 +818,10 @@ void calculate_table_widths(struct box *table)
#define WIDTH_FIXED ULONG_MAX
if (table->children == 0)
return;
if (table->children->children == 0)
return;
assert(table->children != 0 && table->children->children != 0);
for (row_group = table->children; row_group != 0; row_group = row_group->next) {
assert(row_group->type == BOX_TABLE_ROW_GROUP);

View File

@ -1,5 +1,5 @@
/**
* $Id: gui.c,v 1.10 2002/12/29 22:27:35 monkeyson Exp $
* $Id: gui.c,v 1.11 2002/12/30 02:06:03 monkeyson Exp $
*/
#include "netsurf/riscos/font.h"
@ -506,7 +506,13 @@ void ro_gui_window_redraw_box(gui_window* g, struct box * box, signed long x, si
current_background_color = box->style->background_color;
}
if (box->gadget != 0)
if (box->img != 0)
{
colourtrans_set_gcol(os_COLOUR_LIGHT_GREY, 0, os_ACTION_OVERWRITE, 0);
os_plot(os_MOVE_TO, x + box->x * 2, y - box->y * 2);
os_plot(os_PLOT_RECTANGLE | os_PLOT_BY, box->width * 2, -box->height * 2);
}
else if (box->gadget != 0)
{
wimp_icon icon;
fprintf(stderr, "writing GADGET\n");
@ -543,6 +549,20 @@ void ro_gui_window_redraw_box(gui_window* g, struct box * box, signed long x, si
fprintf(stderr, "writing GADGET ACTION\n");
wimp_plot_icon(&icon);
break;
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);
icon.data.indirected_text.text = box->gadget->data.select.items->text;
icon.data.indirected_text.size = strlen(box->gadget->data.select.items->text);
icon.data.indirected_text.validation = "R2";
fprintf(stderr, "writing GADGET ACTION\n");
wimp_plot_icon(&icon);
break;
}
}