[project @ 2003-01-06 23:53:39 by bursa]

Changes to integrate images and forms.

svn path=/import/netsurf/; revision=86
This commit is contained in:
James Bursa 2003-01-06 23:53:40 +00:00
parent 59a1594f21
commit 3af4ad82a8
4 changed files with 210 additions and 211 deletions

View File

@ -1,5 +1,5 @@
/**
* $Id: browser.c,v 1.19 2002/12/30 22:56:30 monkeyson Exp $
* $Id: browser.c,v 1.20 2003/01/06 23:53:39 bursa Exp $
*/
#include "netsurf/riscos/font.h"
@ -11,6 +11,7 @@
#include "netsurf/desktop/cache.h"
#include "netsurf/utils/log.h"
#include "libxml/uri.h"
#include "libxml/debugXML.h"
#include <string.h>
#include <stdlib.h>
#include <assert.h>
@ -127,6 +128,7 @@ void content_html_reformat(struct content* c, int width)
LOG(("Setting document to myDoc"));
c->data.html.document = c->data.html.parser->myDoc;
xmlDebugDumpDocument(stderr, c->data.html.parser->myDoc);
/* skip to start of html */
LOG(("Skipping to html"));
@ -174,8 +176,10 @@ void content_html_reformat(struct content* c, int width)
LOG(("XML to box"));
xml_to_box(c->data.html.markup, c->data.html.style, c->data.html.stylesheet, &selector, 0, c->data.html.layout, 0, 0, c->data.html.fonts, 0, 0, 0, 0, &c->data.html.elements);
box_dump(c->data.html.layout->children, 0);
LOG(("Layout document"));
layout_document(c->data.html.layout->children, (unsigned long)width);
box_dump(c->data.html.layout->children, 0);
/* can tidy up memory here? */

View File

@ -1,5 +1,5 @@
/**
* $Id: box.c,v 1.27 2003/01/03 22:19:39 bursa Exp $
* $Id: box.c,v 1.28 2003/01/06 23:53:39 bursa Exp $
*/
#include <assert.h>
@ -147,12 +147,6 @@ void xml_to_box(xmlNode * n, struct css_style * parent_style,
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,
@ -162,11 +156,12 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
struct gui_gadget* current_textarea, struct form* current_form,
struct page_elements* elements)
{
struct box * box;
struct box * box = 0;
struct box * inline_container_c;
struct css_style * style;
xmlNode * c;
char * s;
char * text = 0;
assert(n != 0 && parent_style != 0 && stylesheet != 0 && selector != 0 &&
parent != 0 && fonts != 0);
@ -187,69 +182,84 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
if (style->display == CSS_DISPLAY_NONE)
return inline_container;
/* special elements */
if (strcmp((const char *) n->name, "a") == 0) {
if ((s = (char *) xmlGetProp(n, (xmlChar *) "href"))) {
href = strdup(s);
free(s);
}
}
}
if ((s = (char *) xmlGetProp(n, (xmlChar *) "href")))
href = s;
if (n->type == XML_ELEMENT_NODE && (strcmp((const char *) n->name, "form") == 0))
{
struct form* form = box_form(n);
if (form != NULL)
{
} else if (strcmp((const char *) n->name, "form") == 0) {
struct form* form = box_form(n);
current_form = form;
add_form_element(elements, form);
}
}
else 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, "textarea") == 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))) {
char * text = 0;
int ignore;
if (n->type == XML_TEXT_NODE)
text = squash_whitespace(tolat1(n->content));
ignore = n->type == XML_TEXT_NODE && text[0] == ' ' && text[1] == 0;
} else if (strcmp((const char *) n->name, "img") == 0) {
LOG(("image"));
box = box_image(n, style, href);
add_img_element(elements, box->img);
} else if (strcmp((const char *) n->name, "textarea") == 0) {
char * content = xmlNodeGetContent(n);
char * thistext = squash_whitespace(tolat1(content)); /* squash ? */
LOG(("textarea"));
box = box_textarea(n, style, current_form);
current_textarea = box->gadget;
add_gadget_element(elements, box->gadget);
textarea_addtext(current_textarea, thistext);
free(content);
} else if (strcmp((const char *) n->name, "select") == 0) {
LOG(("select"));
box = box_select(n, style, current_form);
current_select = box->gadget;
add_gadget_element(elements, box->gadget);
} else if (strcmp((const char *) n->name, "option") == 0) {
char * content = xmlNodeGetContent(n);
char * thistext = tolat1(content);
LOG(("option"));
current_option = box_option(n, style, current_select);
LOG(("adding to option"));
option_addtext(current_option, thistext);
LOG(("freeing thistext"));
LOG(("arse"));
free(content);
} else if (strcmp((const char *) n->name, "input") == 0) {
LOG(("input"));
box = box_input(n, style, current_form, elements);
/* text nodes are converted to inline boxes, wrapped in an inline container block */
if (inline_container == 0 && !ignore) {
/* this is the first inline node: make a container */
inline_container = xcalloc(1, sizeof(struct box));
inline_container->type = BOX_INLINE_CONTAINER;
box_add_child(parent, inline_container);
}
if (ignore) {
/* special elements must be inline or block */
if (box != 0 && style->display != CSS_DISPLAY_INLINE)
style->display = CSS_DISPLAY_BLOCK;
} else if (n->type == XML_TEXT_NODE) {
text = squash_whitespace(tolat1(n->content));
if (text[0] == ' ' && text[1] == 0) {
if (inline_container != 0) {
assert(inline_container->last != 0);
inline_container->last->space = 1;
}
xfree(text);
} else if (n->type == XML_TEXT_NODE) {
LOG2("TEXT NODE");
if (current_textarea != 0)
{
char* thistext = squash_whitespace(tolat1(n->content));
textarea_addtext(current_textarea, thistext);
}
else if (current_option != 0)
{
char* thistext = (tolat1(n->content));
LOG2("adding to option");
option_addtext(current_option, thistext);
LOG2("freeing thistext");
LOG2("arse");
}
else
{
LOG2(("text node"));
return inline_container;
}
}
if (n->type == XML_TEXT_NODE ||
(box != 0 && style->display == CSS_DISPLAY_INLINE) ||
(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 */
if (inline_container == 0) {
/* this is the first inline node: make a container */
inline_container = xcalloc(1, sizeof(struct box));
inline_container->type = BOX_INLINE_CONTAINER;
box_add_child(parent, inline_container);
}
if (n->type == XML_TEXT_NODE) {
LOG(("text node"));
box = box_create(n, BOX_INLINE, parent_style, href);
box_add_child(inline_container, box);
box->length = strlen(text);
@ -267,60 +277,30 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
}
box->text = text;
box->font = font_open(fonts, box->style);
}
} else if (strcmp((const char *) n->name, "img") == 0) {
LOG2(("image"));
box = box_image(n, parent_style, href);
if (box != NULL)
{
box_add_child(inline_container, box);
add_img_element(elements, box->img);
}
} else if (strcmp((const char *) n->name, "textarea") == 0) {
LOG2(("textarea"));
box = box_textarea(n, parent_style, current_form);
if (box != NULL)
{
box_add_child(inline_container, box);
current_textarea = box->gadget;
add_gadget_element(elements, box->gadget);
}
} else if (strcmp((const char *) n->name, "select") == 0) {
LOG2(("select"));
box = box_select(n, parent_style, current_form);
if (box != NULL)
{
box_add_child(inline_container, box);
current_select = box->gadget;
add_gadget_element(elements, 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) {
LOG2(("input"));
box = box_input(n, parent_style, current_form, elements);
if (box != NULL)
{
box_add_child(inline_container, box);
add_gadget_element(elements, box->gadget);
}
} else {
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);
} else if (style->float_ == CSS_FLOAT_LEFT || style->float_ == CSS_FLOAT_RIGHT) {
LOG(("float"));
parent = box_create(0, BOX_FLOAT_LEFT, 0, href);
if (style->float_ == CSS_FLOAT_RIGHT) parent->type = BOX_FLOAT_RIGHT;
box_add_child(inline_container, parent);
style->float_ = CSS_FLOAT_NONE;
parent = box;
if (style->display == CSS_DISPLAY_INLINE)
style->display = CSS_DISPLAY_BLOCK;
} else {
assert(box != 0);
box_add_child(inline_container, box);
return inline_container;
}
}
if (n->type == XML_ELEMENT_NODE) {
switch (style->display) {
case CSS_DISPLAY_BLOCK: /* blocks get a node in the box tree */
box = box_create(n, BOX_BLOCK, style, href);
if (box == 0)
box = box_create(n, BOX_BLOCK, style, href);
else
box->type = BOX_BLOCK;
box_add_child(parent, box);
inline_container_c = 0;
for (c = n->children; c != 0; c = c->next)
@ -331,6 +311,8 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
inline_container = 0;
break;
case CSS_DISPLAY_INLINE: /* inline elements get no box, but their children do */
assert(box == 0); /* special inline elements have already been
added to the inline container above */
for (c = n->children; c != 0; c = c->next)
inline_container = convert_xml_to_box(c, style, stylesheet,
selector, depth + 1, parent, inline_container,
@ -412,12 +394,12 @@ struct css_style * box_get_style(struct css_stylesheet * stylesheet, struct css_
if ((s = (char *) xmlGetProp(n, (xmlChar *) "align"))) {
if (strcmp((const char *) n->name, "table") == 0 ||
strcmp((const char *) n->name, "img") == 0) {
if (strcmp(s, "left") == 0) style->float_ = CSS_FLOAT_LEFT;
else if (strcmp(s, "right") == 0) style->float_ = CSS_FLOAT_RIGHT;
if (stricmp(s, "left") == 0) style->float_ = CSS_FLOAT_LEFT;
else if (stricmp(s, "right") == 0) style->float_ = CSS_FLOAT_RIGHT;
} else {
if (strcmp(s, "left") == 0) style->text_align = CSS_TEXT_ALIGN_LEFT;
else if (strcmp(s, "center") == 0) style->text_align = CSS_TEXT_ALIGN_CENTER;
else if (strcmp(s, "right") == 0) style->text_align = CSS_TEXT_ALIGN_RIGHT;
if (stricmp(s, "left") == 0) style->text_align = CSS_TEXT_ALIGN_LEFT;
else if (stricmp(s, "center") == 0) style->text_align = CSS_TEXT_ALIGN_CENTER;
else if (stricmp(s, "right") == 0) style->text_align = CSS_TEXT_ALIGN_RIGHT;
}
free(s);
}
@ -429,9 +411,9 @@ struct css_style * box_get_style(struct css_stylesheet * stylesheet, struct css_
}
if ((s = (char *) xmlGetProp(n, (xmlChar *) "clear"))) {
if (strcmp(s, "all") == 0) style->clear = CSS_CLEAR_BOTH;
else if (strcmp(s, "left") == 0) style->clear = CSS_CLEAR_LEFT;
else if (strcmp(s, "right") == 0) style->clear = CSS_CLEAR_RIGHT;
if (stricmp(s, "all") == 0) style->clear = CSS_CLEAR_BOTH;
else if (stricmp(s, "left") == 0) style->clear = CSS_CLEAR_LEFT;
else if (stricmp(s, "right") == 0) style->clear = CSS_CLEAR_RIGHT;
}
if ((s = (char *) xmlGetProp(n, (xmlChar *) "color"))) {
@ -440,6 +422,13 @@ struct css_style * box_get_style(struct css_stylesheet * stylesheet, struct css_
style->color = (b << 16) | (g << 8) | r;
}
if ((s = (char *) xmlGetProp(n, (xmlChar *) "height"))) {
style->height.height = CSS_HEIGHT_LENGTH;
style->height.length.unit = CSS_UNIT_PX;
style->height.length.value = atof(s);
free(s);
}
if ((s = (char *) xmlGetProp(n, (xmlChar *) "width"))) {
if (strrchr(s, '%')) {
style->width.width = CSS_WIDTH_PERCENT;
@ -484,8 +473,12 @@ void box_dump(struct box * box, unsigned int depth)
switch (box->type) {
case BOX_BLOCK: fprintf(stderr, "BOX_BLOCK "); break;
case BOX_INLINE_CONTAINER: fprintf(stderr, "BOX_INLINE_CONTAINER "); break;
case BOX_INLINE: fprintf(stderr, "BOX_INLINE '%.*s' ",
(int) box->length, box->text); break;
case BOX_INLINE: if (box->text != 0)
fprintf(stderr, "BOX_INLINE '%.*s' ",
(int) box->length, box->text);
else
fprintf(stderr, "BOX_INLINE (special) ");
break;
case BOX_TABLE: fprintf(stderr, "BOX_TABLE "); break;
case BOX_TABLE_ROW: fprintf(stderr, "BOX_TABLE_ROW "); break;
case BOX_TABLE_CELL: fprintf(stderr, "BOX_TABLE_CELL [columns %i] ",
@ -966,21 +959,19 @@ struct box* box_image(xmlNode * n, struct css_style* style, char* href)
box->length = 0;
box->font = 0;
if ((s = (char *) xmlGetProp(n, (xmlChar *) "width")))
{
box->img->width = atoi(s);
free(s);
if (style->width.width == CSS_WIDTH_AUTO) {
/* should find the real image width */
style->width.width = CSS_WIDTH_LENGTH;
style->width.value.length.unit = CSS_UNIT_PX;
style->width.value.length.value = 24;
}
else
box->img->width = 24;
if ((s = (char *) xmlGetProp(n, (xmlChar *) "height")))
{
box->img->height = atoi(s);
free(s);
if (style->height.height == CSS_HEIGHT_AUTO) {
/* should find the real image height */
style->height.height = CSS_HEIGHT_LENGTH;
style->height.length.unit = CSS_UNIT_PX;
style->height.length.value = 24;
}
else
box->img->height = 24;
if ((s = (char *) xmlGetProp(n, (xmlChar *) "alt")))
{
@ -995,9 +986,9 @@ struct box* box_textarea(xmlNode* n, struct css_style* style, struct form* curre
struct box* box = 0;
char* s;
LOG2("creating box");
LOG(("creating box"));
box = box_create(n, BOX_INLINE, style, NULL);
LOG2("creating gadget");
LOG(("creating gadget"));
box->gadget = xcalloc(1, sizeof(struct gui_gadget));
box->gadget->type = GADGET_TEXTAREA;
box->gadget->form = current_form;
@ -1035,9 +1026,9 @@ struct box* box_select(xmlNode * n, struct css_style* style, struct form* curren
struct box* box = 0;
char* s;
LOG2("creating box");
LOG(("creating box"));
box = box_create(n, BOX_INLINE, style, NULL);
LOG2("creating gadget");
LOG(("creating gadget"));
box->gadget = xcalloc(1, sizeof(struct gui_gadget));
box->gadget->type = GADGET_SELECT;
box->gadget->form = current_form;
@ -1065,7 +1056,7 @@ struct box* box_select(xmlNode * n, struct css_style* style, struct form* curren
box->gadget->data.select.items = NULL;
box->gadget->data.select.numitems = 0;
/* to do: multiple, name */
LOG2("returning from select");
LOG(("returning from select"));
return box;
}
@ -1075,7 +1066,7 @@ struct formoption* box_option(xmlNode* n, struct css_style* style, struct gui_ga
char* s;
assert(current_select != 0);
LOG2("realloc option");
LOG(("realloc option"));
if (current_select->data.select.items == 0)
{
option = xcalloc(1, sizeof(struct formoption));
@ -1101,7 +1092,7 @@ struct formoption* box_option(xmlNode* n, struct css_style* style, struct gui_ga
option->value = s;
}
LOG2("returning");
LOG(("returning"));
return option;
}
@ -1128,16 +1119,16 @@ void option_addtext(struct formoption* option, char* text)
if (option->text == 0)
{
LOG2("option->text is 0");
LOG(("option->text is 0"));
option->text = strdup(text);
}
else
{
LOG2("option->text is realloced");
LOG(("option->text is realloced"));
option->text = xrealloc(option->text, strlen(option->text) + strlen(text) + 1);
strcat(option->text, text);
}
LOG2("returning");
LOG(("returning"));
return;
}
@ -1149,7 +1140,7 @@ struct box* box_input(xmlNode * n, struct css_style* style, struct form* current
if ((type = (char *) xmlGetProp(n, (xmlChar *) "type")))
{
if (strcmp(type, "hidden") == 0)
if (stricmp(type, "hidden") == 0)
{
struct gui_gadget* g = xcalloc(1, sizeof(struct gui_gadget));
g->type = GADGET_HIDDEN;
@ -1162,8 +1153,9 @@ struct box* box_input(xmlNode * n, struct css_style* style, struct form* current
if ((s = (char *) xmlGetProp(n, (xmlChar *) "name"))) {
g->name = s;
}
add_gadget_element(elements, g);
}
if (strcmp(type, "checkbox") == 0 || strcmp(type, "radio") == 0)
if (stricmp(type, "checkbox") == 0 || stricmp(type, "radio") == 0)
{
box = box_create(n, BOX_INLINE, style, NULL);
box->gadget = xcalloc(1, sizeof(struct gui_gadget));
@ -1195,8 +1187,9 @@ struct box* box_input(xmlNode * n, struct css_style* style, struct form* current
if ((s = (char *) xmlGetProp(n, (xmlChar *) "name"))) {
box->gadget->name = s;
}
add_gadget_element(elements, box->gadget);
}
if (strcmp(type, "submit") == 0 || strcmp(type, "reset") == 0)
if (stricmp(type, "submit") == 0 || stricmp(type, "reset") == 0)
{
//style->display = CSS_DISPLAY_BLOCK;
@ -1221,8 +1214,9 @@ struct box* box_input(xmlNode * n, struct css_style* style, struct form* current
if ((s = (char *) xmlGetProp(n, (xmlChar *) "name"))) {
box->gadget->name = s;
}
add_gadget_element(elements, box->gadget);
}
if (strcmp(type, "text") == 0 || strcmp(type, "password") == 0)
if (stricmp(type, "text") == 0 || stricmp(type, "password") == 0)
{
//style->display = CSS_DISPLAY_BLOCK;
@ -1258,6 +1252,7 @@ struct box* box_input(xmlNode * n, struct css_style* style, struct form* current
if ((s = (char *) xmlGetProp(n, (xmlChar *) "name"))) {
box->gadget->name = s;
}
add_gadget_element(elements, box->gadget);
}
free(type);
}
@ -1275,11 +1270,10 @@ struct form* box_form(xmlNode* n)
form->action = s;
}
form->method = method_GET;
if ((s = (char *) xmlGetProp(n, (xmlChar *) "method"))) {
if (strcmp(s, "get") == 0)
form->action = method_GET;
else if (strcmp(s, "post") == 0)
form->action = method_POST;
if (stricmp(s, "post") == 0)
form->method = method_POST;
xfree(s);
}

View File

@ -1,5 +1,5 @@
/**
* $Id: box.h,v 1.16 2003/01/02 13:26:43 bursa Exp $
* $Id: box.h,v 1.17 2003/01/06 23:53:40 bursa Exp $
*/
#ifndef _NETSURF_RENDER_BOX_H_
@ -75,8 +75,6 @@ struct gui_gadget {
};
struct img {
int width;
int height;
char* alt;
char* src;
};
@ -88,7 +86,7 @@ struct box {
unsigned long x, y, width, height;
unsigned long min_width, max_width;
const char * text;
int space; /* 1 <=> followed by a space */
unsigned int space : 1; /* 1 <=> followed by a space */
const char * href;
unsigned int length;
unsigned int columns;
@ -134,7 +132,7 @@ void xml_to_box(xmlNode * n, struct css_style * parent_style, struct css_stylesh
struct box * parent, struct box * inline_container,
const char *href, struct font_set *fonts,
struct gui_gadget* current_select, struct formoption* current_option,
struct gui_gadget* current_textarea, struct form* current_form,
struct gui_gadget* current_textarea, struct form* current_form,
struct page_elements* elements);
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.31 2003/01/03 22:19:39 bursa Exp $
* $Id: layout.c,v 1.32 2003/01/06 23:53:40 bursa Exp $
*/
#include <assert.h>
@ -105,17 +105,6 @@ 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;
@ -353,12 +342,7 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long
find_sides(cont->float_children, cy, cy, &x0, &x1, &left, &right);
/* 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);
height = line_height(first->parent->parent->style);
/* pass 1: find height of line assuming sides at top of line */
for (x = 0, b = first; x < x1 - x0 && b != 0; b = b->next) {
@ -366,23 +350,38 @@ 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);
else {
assert(b->style != 0);
assert(b->style->height.height == CSS_HEIGHT_LENGTH);
h = len(&b->style->height.length, b->style);
}
b->height = h;
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)
if (h > height) height = h;
if (b->width == UNKNOWN_WIDTH) {
if (b->text != 0)
b->width = font_width(b->font, b->text, b->length);
else if (b->gadget != 0)
b->width = gadget_width(b->gadget);
else {
assert(b->style != 0);
assert(b->style->width.width == CSS_WIDTH_LENGTH ||
b->style->width.width == CSS_WIDTH_PERCENT);
if (b->style->width.width == CSS_WIDTH_LENGTH)
b->width = len(&b->style->width.value.length,
b->style);
else
b->width = width * b->style->width.value.percent
/ 100;
}
}
if (b->text != 0)
x += b->width + b->space ? b->font->space_width : 0;
else if (b->gadget != 0 || b->img != 0)
else
x += b->width;
}
}
@ -400,7 +399,7 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long
b->x = x;
x += b->width;
space_before = space_after;
if (b->font != 0)
if (b->text != 0)
space_after = b->space ? b->font->space_width : 0;
else
space_after = 0;
@ -441,29 +440,29 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long
if (x1 - x0 < x) {
/* the last box went over the end */
char * space = strchr(c->text, ' ');
char * space = 0;
unsigned long w;
struct box * c2;
x = x_previous;
if (c->text != 0)
space = strchr(c->text, ' ');
if (space != 0 && c->length <= space - c->text)
/* space after end of string */
space = 0;
/* space != 0 implies c->text != 0 */
if (space == 0)
w = c->width;
else if (c->font != 0)
else
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);
if (x1 - x0 < x + space_before + w && left == 0 && right == 0 && c == first) {
/* first word doesn't fit, but no floats and first on line so force in */
if (space == 0) {
/* only one word in this box */
/* only one word in this box or not text */
b = c->next;
} else {
/* cut off first word for this line */
@ -484,7 +483,7 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long
/* first word doesn't fit, but full width not available so leave for later */
b = c;
/* fprintf(stderr, "layout_line: overflow, leaving\n"); */
} else if (c->text != 0) {
} else {
/* fit as many words as possible */
assert(space != 0);
space = font_split(c->font, c->text, c->length,
@ -745,30 +744,26 @@ void calculate_inline_container_widths(struct box *box)
for (child = box->children; child != 0; child = child->next) {
switch (child->type) {
case BOX_INLINE:
/* max = all one line */
if (child->font != 0)
if (child->text != 0)
{
child->width = font_width(child->font,
child->text, child->length);
max += child->width;
/* min = widest word */
for (word = child->text, space = strchr(child->text, ' ');
space != 0;
word = space + 1, space = strchr(word, ' ')) {
width = font_width(child->font, word, space - word);
if (min < width) min = width;
}
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 = all one line */
child->width = font_width(child->font,
child->text, child->length);
max += child->width;
if (min < child->width)
min = child->width;
/* TODO: add spaces */
/* min = widest word */
for (word = child->text,
space = strchr(child->text, ' ');
space != 0;
word = space + 1,
space = strchr(word, ' ')) {
width = font_width(child->font, word,
space - word);
if (min < width) min = width;
}
width = font_width(child->font, word, strlen(word));
if (min < width) min = width;
}
else if (child->gadget != 0)
{
@ -777,6 +772,14 @@ void calculate_inline_container_widths(struct box *box)
if (min < child->width)
min = child->width;
}
else if (child->style->width.width == CSS_WIDTH_LENGTH)
{
child->width = len(&child->style->width.value.length,
child->style);
max += child->width;
if (min < child->width)
min = child->width;
}
break;
case BOX_FLOAT_LEFT: