summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Mellor <phil@monkeyson.info>2002-12-30 02:06:03 +0000
committerPhil Mellor <phil@monkeyson.info>2002-12-30 02:06:03 +0000
commit33a91eb2febbc2e28581a17207d01a972c898504 (patch)
treec11e52273bc16d0988f41c1483bf9da502a01933
parent50fc20c2d4883b399fcee8c7a2905605304d9e40 (diff)
downloadnetsurf-33a91eb2febbc2e28581a17207d01a972c898504.tar.gz
netsurf-33a91eb2febbc2e28581a17207d01a972c898504.tar.bz2
[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
-rw-r--r--!NetSurf/Resources/CSS2
-rw-r--r--render/box.c185
-rw-r--r--render/box.h28
-rw-r--r--render/layout.c49
-rw-r--r--riscos/gui.c24
5 files changed, 266 insertions, 22 deletions
diff --git a/!NetSurf/Resources/CSS b/!NetSurf/Resources/CSS
index 7fb109565..4909b92e3 100644
--- a/!NetSurf/Resources/CSS
+++ b/!NetSurf/Resources/CSS
@@ -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; }
diff --git a/render/box.c b/render/box.c
index 5fc1aa355..e6726b02b 100644
--- a/render/box.c
+++ b/render/box.c
@@ -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;
diff --git a/render/box.h b/render/box.h
index 05f7ffeb8..e978662ad 100644
--- a/render/box.h
+++ b/render/box.h
@@ -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);
diff --git a/render/layout.c b/render/layout.c
index 62cb25f0e..db1432c78 100644
--- a/render/layout.c
+++ b/render/layout.c
@@ -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);
diff --git a/riscos/gui.c b/riscos/gui.c
index 04b6e10d1..552388701 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -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;
+
}
}