From 53635480521030761f8aa0488752853eab6d9f87 Mon Sep 17 00:00:00 2001 From: James Bursa Date: Sun, 21 Sep 2003 22:47:08 +0000 Subject: [project @ 2003-09-21 22:47:08 by bursa] Implement display: inline-block and work on textarea. svn path=/import/netsurf/; revision=307 --- !NetSurf/Resources/CSS,f79 | 2 +- css/css_enums | 2 +- render/box.c | 101 +++++++++++++++++++++++++++++++++------------ render/box.h | 3 +- render/layout.c | 36 ++++++++++------ riscos/htmlredraw.c | 2 +- 6 files changed, 102 insertions(+), 44 deletions(-) diff --git a/!NetSurf/Resources/CSS,f79 b/!NetSurf/Resources/CSS,f79 index 1c271c439..614546221 100644 --- a/!NetSurf/Resources/CSS,f79 +++ b/!NetSurf/Resources/CSS,f79 @@ -39,4 +39,4 @@ center { text-align: center; } small { font-size: smaller; } big { font-size: larger; } input, select { width: 10em; height: 2em; background-color: #eeeebb; } -textarea { width: 20em; height: 4em; background-color: #eeeebb; } +textarea { display: inline-block; width: 20em; height: 4em; background-color: #eeeebb; } diff --git a/css/css_enums b/css/css_enums index 1d12aea74..56f5c63ab 100644 --- a/css/css_enums +++ b/css/css_enums @@ -5,7 +5,7 @@ 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_clear inherit none both left right -css_display inherit inline block list-item run-in compact marker 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_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 css_font_style inherit normal italic oblique css_font_variant normal smallcaps diff --git a/render/box.c b/render/box.c index 789b49356..c8c435179 100644 --- a/render/box.c +++ b/render/box.c @@ -228,8 +228,7 @@ static box_type box_map[] = { BOX_BLOCK, /*CSS_DISPLAY_BLOCK,*/ BOX_BLOCK, /*CSS_DISPLAY_LIST_ITEM,*/ BOX_INLINE, /*CSS_DISPLAY_RUN_IN,*/ - BOX_INLINE, /*CSS_DISPLAY_COMPACT,*/ - BOX_INLINE, /*CSS_DISPLAY_MARKER,*/ + BOX_INLINE_BLOCK, /*CSS_DISPLAY_INLINE_BLOCK,*/ BOX_TABLE, /*CSS_DISPLAY_TABLE,*/ BOX_TABLE, /*CSS_DISPLAY_INLINE_TABLE,*/ BOX_TABLE_ROW_GROUP, /*CSS_DISPLAY_TABLE_ROW_GROUP,*/ @@ -353,6 +352,7 @@ struct box * convert_xml_to_box(xmlNode * n, struct content *content, if (text != 0 || box->type == BOX_INLINE || + box->type == BOX_INLINE_BLOCK || style->float_ == CSS_FLOAT_LEFT || style->float_ == CSS_FLOAT_RIGHT) { /* this is an inline box */ @@ -374,7 +374,7 @@ struct box * convert_xml_to_box(xmlNode * n, struct content *content, } LOG(("depth %i, node %p, node type %i END", depth, n, n->type)); goto end; - } else if (style->float_ == CSS_FLOAT_NONE) { + } else if (box->type == BOX_INLINE) { /* inline box: add to tree and recurse */ box_add_child(inline_container, box); if (convert_children) { @@ -385,6 +385,18 @@ struct box * convert_xml_to_box(xmlNode * n, struct content *content, } LOG(("depth %i, node %p, node type %i END", depth, n, n->type)); goto end; + } else if (box->type == BOX_INLINE_BLOCK) { + /* inline block box: add to tree and recurse */ + box_add_child(inline_container, box); + if (convert_children) { + inline_container_c = 0; + for (c = n->children; c != 0; c = c->next) + inline_container_c = convert_xml_to_box(c, content, style, + selector, depth + 1, box, inline_container_c, + status); + } + LOG(("depth %i, node %p, node type %i END", depth, n, n->type)); + goto end; } else { /* float: insert a float box between the parent and current node */ assert(style->float_ == CSS_FLOAT_LEFT || style->float_ == CSS_FLOAT_RIGHT); @@ -395,7 +407,7 @@ struct box * convert_xml_to_box(xmlNode * n, struct content *content, else parent->type = BOX_FLOAT_RIGHT; box_add_child(inline_container, parent); - if (box->type == BOX_INLINE) + if (box->type == BOX_INLINE || box->type == BOX_INLINE_BLOCK) box->type = BOX_BLOCK; } } @@ -571,6 +583,27 @@ struct css_style * box_get_style(struct content ** stylesheet, xmlFree(s); } + if (strcmp((const char *) n->name, "textarea") == 0) { + if ((s = (char *) xmlGetProp(n, (const xmlChar *) "rows"))) { + int value = atoi(s); + if (0 < value) { + style->height.height = CSS_HEIGHT_LENGTH; + style->height.length.unit = CSS_UNIT_EM; + style->height.length.value = value; + } + xmlFree(s); + } + if ((s = (char *) xmlGetProp(n, (const xmlChar *) "cols"))) { + int value = atoi(s); + if (0 < value) { + style->width.width = CSS_WIDTH_LENGTH; + style->width.value.length.unit = CSS_UNIT_EX; + style->width.value.length.value = value; + } + xmlFree(s); + } + } + if ((s = (char *) xmlGetProp(n, (const xmlChar *) "style"))) { struct css_style * astyle = xcalloc(1, sizeof(struct css_style)); memcpy(astyle, &css_empty_style, sizeof(struct css_style)); @@ -664,8 +697,8 @@ struct result box_form(xmlNode *n, struct status *status, struct result box_textarea(xmlNode *n, struct status *status, struct css_style *style) { - xmlChar *content; - struct box* box = 0; + xmlChar *content, *current; + struct box *box, *inline_container, *inline_box; char* s; box = box_create(style, NULL, 0); @@ -673,25 +706,29 @@ struct result box_textarea(xmlNode *n, struct status *status, box->gadget->type = GADGET_TEXTAREA; box->gadget->form = status->current_form; - content = xmlNodeGetContent(n); - box->gadget->data.textarea.text = squash_tolat1(content); /* squash ? */ - xmlFree(content); - - if ((s = (char *) xmlGetProp(n, (const xmlChar *) "cols"))) - { - box->gadget->data.textarea.cols = atoi(s); - xmlFree(s); + /* split the content at newlines and make an inline container with an + * inline box for each line */ + current = content = xmlNodeGetContent(n); + current += strspn(current, "\r\n"); /* skip any initial CR, LF */ + while (*current) { + size_t len = strcspn(current, "\r\n"); + char old = current[len]; + current[len] = 0; + inline_container = box_create(0, 0, 0); + inline_container->type = BOX_INLINE_CONTAINER; + inline_box = box_create(style, 0, 0); + inline_box->type = BOX_INLINE; + inline_box->style_clone = 1; + inline_box->text = tolat1(current); + inline_box->length = strlen(inline_box->text); + inline_box->font = font_open(status->content->data.html.fonts, style); + box_add_child(inline_container, inline_box); + box_add_child(box, inline_container); + current[len] = old; + current += len; + current += strspn(current, "\r\n"); } - else - box->gadget->data.textarea.cols = 40; - - if ((s = (char *) xmlGetProp(n, (const xmlChar *) "rows"))) - { - box->gadget->data.textarea.rows = atoi(s); - xmlFree(s); - } - else - box->gadget->data.textarea.rows = 16; + xmlFree(content); if ((s = (char *) xmlGetProp(n, (const xmlChar *) "name"))) { @@ -957,6 +994,7 @@ void box_dump(struct box * box, unsigned int depth) 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 "); break; + case BOX_INLINE_BLOCK: fprintf(stderr, "BOX_INLINE_BLOCK "); 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] ", @@ -987,8 +1025,8 @@ void box_dump(struct box * box, unsigned int depth) * ensure the box tree is correctly nested * * parent permitted child nodes - * BLOCK BLOCK, INLINE_CONTAINER, TABLE - * INLINE_CONTAINER INLINE, FLOAT_LEFT, FLOAT_RIGHT + * BLOCK, INLINE_BLOCK BLOCK, INLINE_CONTAINER, TABLE + * INLINE_CONTAINER INLINE, INLINE_BLOCK, FLOAT_LEFT, FLOAT_RIGHT * INLINE none * TABLE at least 1 TABLE_ROW_GROUP * TABLE_ROW_GROUP at least 1 TABLE_ROW @@ -1005,7 +1043,8 @@ void box_normalise_block(struct box *block) struct css_style *style; assert(block != 0); - assert(block->type == BOX_BLOCK || block->type == BOX_TABLE_CELL); + assert(block->type == BOX_BLOCK || block->type == BOX_INLINE_BLOCK || + block->type == BOX_TABLE_CELL); LOG(("block %p, block->type %u", block, block->type)); gui_multitask(); @@ -1024,6 +1063,7 @@ void box_normalise_block(struct box *block) box_normalise_table(child); break; case BOX_INLINE: + case BOX_INLINE_BLOCK: case BOX_FLOAT_LEFT: case BOX_FLOAT_RIGHT: /* should have been wrapped in inline @@ -1118,6 +1158,7 @@ void box_normalise_table(struct box *table) &table_columns); break; case BOX_INLINE: + case BOX_INLINE_BLOCK: case BOX_FLOAT_LEFT: case BOX_FLOAT_RIGHT: /* should have been wrapped in inline @@ -1198,6 +1239,7 @@ void box_normalise_table_row_group(struct box *row_group, box_normalise_table_row(row, row_span, table_columns); break; case BOX_INLINE: + case BOX_INLINE_BLOCK: case BOX_FLOAT_LEFT: case BOX_FLOAT_RIGHT: /* should have been wrapped in inline @@ -1276,6 +1318,7 @@ void box_normalise_table_row(struct box *row, box_normalise_block(cell); break; case BOX_INLINE: + case BOX_INLINE_BLOCK: case BOX_FLOAT_LEFT: case BOX_FLOAT_RIGHT: /* should have been wrapped in inline @@ -1336,6 +1379,10 @@ void box_normalise_inline_container(struct box *cont) case BOX_INLINE: /* ok */ break; + case BOX_INLINE_BLOCK: + /* ok */ + box_normalise_block(child); + break; case BOX_FLOAT_LEFT: case BOX_FLOAT_RIGHT: /* ok */ diff --git a/render/box.h b/render/box.h index 1d61696c3..2422f2032 100644 --- a/render/box.h +++ b/render/box.h @@ -22,7 +22,8 @@ typedef enum { BOX_BLOCK, BOX_INLINE_CONTAINER, BOX_INLINE, BOX_TABLE, BOX_TABLE_ROW, BOX_TABLE_CELL, BOX_TABLE_ROW_GROUP, - BOX_FLOAT_LEFT, BOX_FLOAT_RIGHT + BOX_FLOAT_LEFT, BOX_FLOAT_RIGHT, + BOX_INLINE_BLOCK } box_type; struct column { diff --git a/render/layout.c b/render/layout.c index 0adc2e85e..a759caf72 100644 --- a/render/layout.c +++ b/render/layout.c @@ -81,6 +81,7 @@ void layout_node(struct box * box, unsigned long width, struct box * cont, switch (box->type) { case BOX_BLOCK: + case BOX_INLINE_BLOCK: layout_block(box, width, cont, cx, cy); break; case BOX_INLINE_CONTAINER: @@ -109,7 +110,7 @@ void layout_block(struct box * box, unsigned long width, struct box * cont, { struct css_style * style = box->style; - assert(box->type == BOX_BLOCK); + assert(box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK); assert(style != 0); LOG(("box %p, width %lu, cont %p, cx %lu, cy %lu", box, width, cont, cx, cy)); @@ -152,8 +153,9 @@ unsigned long layout_block_children(struct box * box, unsigned long width, struc struct box * c; unsigned long y = 0; - assert(box->type == BOX_BLOCK || box->type == BOX_FLOAT_LEFT || - box->type == BOX_FLOAT_RIGHT || box->type == BOX_TABLE_CELL); + assert(box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK || + box->type == BOX_FLOAT_LEFT || box->type == BOX_FLOAT_RIGHT || + box->type == BOX_TABLE_CELL); LOG(("box %p, width %lu, cont %p, cx %lu, cy %lu", box, width, cont, cx, cy)); @@ -266,7 +268,7 @@ signed long line_height(struct css_style * style) struct box * layout_line(struct box * first, unsigned long width, unsigned long * y, unsigned long cy, struct box * cont) { - unsigned long height; + unsigned long height, used_height; unsigned long x0 = 0; unsigned long x1 = width; unsigned long x, h, x_previous; @@ -285,18 +287,17 @@ 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 */ - height = line_height(first->parent->parent->style); + used_height = 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) { - assert(b->type == BOX_INLINE || b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT); + assert(b->type == BOX_INLINE || b->type == BOX_INLINE_BLOCK || + b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT); if (b->type == BOX_INLINE) { if ((b->object || b->gadget) && b->style && b->style->height.height == CSS_HEIGHT_LENGTH) h = len(&b->style->height.length, b->style); - else if (b->text) - h = line_height(b->style ? b->style : b->parent->parent->style); else - h = 0; + h = line_height(b->style ? b->style : b->parent->parent->style); b->height = h; if (h > height) height = h; @@ -315,6 +316,12 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long x += b->width + b->space ? b->font->space_width : 0; else x += b->width; + + } else if (b->type == BOX_INLINE_BLOCK) { + layout_block(b, width, b, 0, 0); + if (height < b->height) + height = b->height; + x += b->width; } } @@ -325,7 +332,7 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long /* pass 2: place boxes in line */ for (x = x_previous = 0, b = first; x <= x1 - x0 && b != 0; b = b->next) { - if (b->type == BOX_INLINE) { + if (b->type == BOX_INLINE || b->type == BOX_INLINE_BLOCK) { x_previous = x; x += space_after; b->x = x; @@ -465,13 +472,15 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long default: break; /* leave on left */ } for (d = first; d != b; d = d->next) { - if (d->type == BOX_INLINE) { + if (d->type == BOX_INLINE || d->type == BOX_INLINE_BLOCK) { d->x += x0; d->y = *y; + if (used_height < d->height) + used_height = d->height; } } - if (move_y) *y += height + 1; + if (move_y) *y += used_height + 1; return b; } @@ -765,7 +774,7 @@ void calculate_widths(struct box *box) unsigned long min = 0, max = 0, width; assert(box->type == BOX_TABLE_CELL || - box->type == BOX_BLOCK || + box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK || box->type == BOX_FLOAT_LEFT || box->type == BOX_FLOAT_RIGHT); /* check if the widths have already been calculated */ @@ -846,6 +855,7 @@ void calculate_inline_container_widths(struct box *box) } break; + case BOX_INLINE_BLOCK: case BOX_FLOAT_LEFT: case BOX_FLOAT_RIGHT: if (child->style != 0 && diff --git a/riscos/htmlredraw.c b/riscos/htmlredraw.c index 3259c095c..731a24ac4 100644 --- a/riscos/htmlredraw.c +++ b/riscos/htmlredraw.c @@ -108,7 +108,7 @@ void html_redraw_box(struct content *content, struct box * box, x0, y0, x1, y1); html_redraw_unclip(clip_x0, clip_y0, clip_x1, clip_y1); - } else if (box->gadget) { + } else if (box->gadget && box->gadget->type != GADGET_TEXTAREA) { wimp_icon icon; LOG(("writing GADGET")); -- cgit v1.2.3