summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/html.h4
-rw-r--r--source/html/css-apply.c33
-rw-r--r--source/html/layout.c167
3 files changed, 102 insertions, 102 deletions
diff --git a/include/mupdf/html.h b/include/mupdf/html.h
index 2add60ee..419fa0a3 100644
--- a/include/mupdf/html.h
+++ b/include/mupdf/html.h
@@ -65,12 +65,12 @@ struct property
struct style
{
struct style *up;
+ int count;
struct {
const char *name;
struct value *value;
int spec;
} prop[64];
- int count;
};
struct value
@@ -87,6 +87,7 @@ struct condition *new_condition(int type, const char *key, const char *val);
struct property *new_property(const char *name, struct value *value, int spec);
struct value *new_value(int type, const char *value);
+int get_style_property_display(struct style *node);
struct rule *fz_parse_css(fz_context *ctx, struct rule *old, const char *source);
struct property *fz_parse_css_properties(fz_context *ctx, const char *source);
@@ -101,7 +102,6 @@ struct color
struct computed_style
{
- int display;
int position;
float top, right, bottom, left;
float margin[4];
diff --git a/source/html/css-apply.c b/source/html/css-apply.c
index 53a46f50..1a93e3e4 100644
--- a/source/html/css-apply.c
+++ b/source/html/css-apply.c
@@ -699,6 +699,24 @@ get_style_property_string(struct style *node, const char *name, const char *init
return value->data;
}
+int
+get_style_property_display(struct style *node)
+{
+ struct value *value = get_style_property(node, "display");
+ if (value)
+ {
+ if (!strcmp(value->data, "none"))
+ return NONE;
+ if (!strcmp(value->data, "inline"))
+ return INLINE;
+ if (!strcmp(value->data, "block"))
+ return BLOCK;
+ if (!strcmp(value->data, "list-item"))
+ return LIST_ITEM;
+ }
+ return INLINE;
+}
+
static float
compute_number(struct value *value, float em, float hundred, float scale, float initial)
{
@@ -751,24 +769,10 @@ compute_style(struct computed_style *style, struct style *node)
memset(style, 0, sizeof *style);
- style->display = INLINE;
style->position = STATIC;
style->text_align = LEFT;
style->font_size = 12;
- value = get_style_property(node, "display");
- if (value)
- {
- if (!strcmp(value->data, "none"))
- style->display = NONE;
- if (!strcmp(value->data, "inline"))
- style->display = INLINE;
- if (!strcmp(value->data, "block"))
- style->display = BLOCK;
- if (!strcmp(value->data, "list-item"))
- style->display = LIST_ITEM;
- }
-
value = get_style_property(node, "position");
if (value)
{
@@ -871,7 +875,6 @@ void
print_style(struct computed_style *style)
{
printf("style {\n");
- printf("\tdisplay = %d;\n", style->display);
printf("\tposition = %d;\n", style->position);
printf("\ttext-align = %d;\n", style->text_align);
printf("\tfont-family = %s;\n", style->font_family);
diff --git a/source/html/layout.c b/source/html/layout.c
index c8ba17e2..1d92b502 100644
--- a/source/html/layout.c
+++ b/source/html/layout.c
@@ -40,159 +40,156 @@ enum
struct box
{
int type;
-
float x, y, w, h;
- float padding[4];
- float border[4];
- float margin[4];
-
- int bold, italic;
-
- fz_xml *node;
- const char *text;
-
struct box *up, *down, *last, *next;
+ fz_xml *node;
+ struct style style;
};
-struct box *new_box(fz_context *ctx, struct box *root, int type, struct computed_style *cstyle, fz_xml *node)
+struct box *new_box(fz_context *ctx, fz_xml *node, struct style *up_style)
{
struct box *box;
- int i;
box = fz_malloc_struct(ctx, struct box);
- box->type = type;
+
+ box->type = BOX_BLOCK;
box->x = box->y = 0;
box->w = box->h = 0;
- for (i = 0; i < 4; ++i)
- {
- box->padding[i] = cstyle->padding[i];
- box->margin[i] = cstyle->margin[i];
- box->border[i] = cstyle->border_width[i];
- box->bold = cstyle->bold;
- box->italic = cstyle->italic;
- }
-
- box->node = node;
-
- box->up = root;
+ box->up = NULL;
box->last = NULL;
box->down = NULL;
box->next = NULL;
- if (root)
+ box->node = node;
+
+ box->style.up = up_style;
+ box->style.count = 0;
+
+ return box;
+}
+
+void insert_box(fz_context *ctx, struct box *box, int type, struct box *top)
+{
+ box->type = type;
+
+ box->up = top;
+
+ if (top)
{
- if (!root->last)
+ if (!top->last)
{
- root->down = root->last = box;
+ top->down = top->last = box;
}
else
{
- root->last->next = box;
- root->last = box;
+ top->last->next = box;
+ top->last = box;
}
}
-
- return box;
}
-static struct box *new_block_box(fz_context *ctx, struct box **topp, struct computed_style *cstyle, fz_xml *node)
+static struct box *insert_block_box(fz_context *ctx, struct box *box, struct box *top)
{
- struct box *top = *topp;
- struct box *box;
-
if (top->type == BOX_BLOCK)
{
- box = new_box(ctx, top, BOX_BLOCK, cstyle, node);
+ insert_box(ctx, box, BOX_BLOCK, top);
}
else if (top->type == BOX_ANONYMOUS)
{
while (top->type != BOX_BLOCK)
top = top->up;
- *topp = top;
- box = new_box(ctx, top, BOX_BLOCK, cstyle, node);
+ insert_box(ctx, box, BOX_BLOCK, top);
}
else if (top->type == BOX_INLINE)
{
while (top->type != BOX_BLOCK)
top = top->up;
- *topp = top;
- box = new_box(ctx, top, BOX_BLOCK, cstyle, node);
+ insert_box(ctx, box, BOX_BLOCK, top);
}
- return box;
+ return top;
}
-static struct box *new_inline_box(fz_context *ctx, struct box *box, struct computed_style *cstyle, fz_xml *node)
+static void insert_inline_box(fz_context *ctx, struct box *box, struct box *top)
{
- if (box->type == BOX_BLOCK)
+ if (top->type == BOX_BLOCK)
{
- if (box->last && box->last->type == BOX_ANONYMOUS)
- box = box->last;
+ if (top->last && top->last->type == BOX_ANONYMOUS)
+ {
+ insert_box(ctx, box, BOX_INLINE, top->last);
+ }
else
- box = new_box(ctx, box, BOX_ANONYMOUS, cstyle, NULL);
- box = new_box(ctx, box, BOX_INLINE, cstyle, node);
+ {
+ struct box *anon = new_box(ctx, NULL, &top->style);
+ insert_box(ctx, anon, BOX_ANONYMOUS, top);
+ insert_box(ctx, box, BOX_INLINE, anon);
+ }
}
else if (box->type == BOX_ANONYMOUS)
{
- box = new_box(ctx, box, BOX_INLINE, cstyle, node);
+ insert_box(ctx, box, BOX_INLINE, top);
}
else if (box->type == BOX_INLINE)
{
- box = new_box(ctx, box, BOX_INLINE, cstyle, node);
+ insert_box(ctx, box, BOX_INLINE, top);
}
- return box;
}
-static void layout_tree(fz_context *ctx, fz_xml *node, struct box *top, struct style *up_style, struct rule *rule)
+static void generate_boxes(fz_context *ctx, fz_xml *node, struct box *top, struct rule *rule)
{
- struct style style;
- struct computed_style cstyle;
+ struct style *up_style;
struct box *box;
+ int display;
+
+ /* link styles separately because splitting inline blocks breaks the style/box tree symmetry */
+ up_style = &top->style;
while (node)
{
- style.up = up_style;
- style.count = 0;
+ box = new_box(ctx, node, up_style);
if (fz_xml_tag(node))
{
- apply_styles(ctx, &style, rule, node);
- compute_style(&cstyle, &style);
- // print_style(&cstyle);
+ apply_styles(ctx, &box->style, rule, node);
+
+ display = get_style_property_display(&box->style);
// TOOD: <br>
// TODO: <img>
- if (cstyle.display != NONE)
+ if (display != NONE)
{
- if (cstyle.display == BLOCK)
+ if (display == BLOCK)
{
- box = new_block_box(ctx, &top, &cstyle, node);
+ top = insert_block_box(ctx, box, top);
}
- else if (cstyle.display == INLINE)
+ else if (display == INLINE)
{
- box = new_inline_box(ctx, top, &cstyle, node);
+ insert_inline_box(ctx, box, top);
}
else
{
fz_warn(ctx, "unknown box display type");
- box = new_box(ctx, top, BOX_BLOCK, &cstyle, node);
+ insert_box(ctx, box, BOX_BLOCK, top);
}
if (fz_xml_down(node))
- layout_tree(ctx, fz_xml_down(node), box, &style, rule);
+ generate_boxes(ctx, fz_xml_down(node), box, rule);
}
}
else
{
- compute_style(&cstyle, &style);
- new_inline_box(ctx, top, &cstyle, node);
+ insert_inline_box(ctx, box, top);
}
node = fz_xml_next(node);
}
}
+static void layout_boxes(fz_context *ctx, struct box *top, float w, float h)
+{
+}
+
static void indent(int level)
{
while (level--) printf(" ");
@@ -209,13 +206,12 @@ static void print_box(fz_context *ctx, struct box *box, int level)
case BOX_ANONYMOUS: printf("anonymous"); break;
case BOX_INLINE: printf("inline"); break;
}
- if (box->node) {
+ if (box->node)
+ {
const char *tag = fz_xml_tag(box->node);
const char *text = fz_xml_text(box->node);
if (tag) printf(" <%s>", tag);
if (text) printf(" \"%s\"", text);
- if (box->bold) printf(" bold");
- if (box->italic) printf(" italic");
}
printf("\n");
if (box->down)
@@ -238,7 +234,8 @@ static char *concat_text(fz_context *ctx, fz_xml *root)
for (node = fz_xml_down(root); node; node = fz_xml_next(node))
{
const char *text = fz_xml_text(node);
- if (text) {
+ if (text)
+ {
n = strlen(text);
memcpy(s+i, text, n);
i += n;
@@ -251,14 +248,18 @@ static char *concat_text(fz_context *ctx, fz_xml *root)
static struct rule *load_css(fz_context *ctx, struct rule *css, fz_xml *root)
{
fz_xml *node;
- for (node = root; node; node = fz_xml_next(node)) {
+ for (node = root; node; node = fz_xml_next(node))
+ {
const char *tag = fz_xml_tag(node);
#if 0
- if (tag && !strcmp(tag, "link")) {
+ if (tag && !strcmp(tag, "link"))
+ {
char *rel = fz_xml_att(node, "rel");
- if (rel && !strcasecmp(rel, "stylesheet")) {
+ if (rel && !strcasecmp(rel, "stylesheet"))
+ {
char *type = fz_xml_att(node, "type");
- if ((type && !strcmp(type, "text/css")) || !type) {
+ if ((type && !strcmp(type, "text/css")) || !type)
+ {
char *href = fz_xml_att(node, "href");
strcpy(filename, dirname);
strcat(filename, href);
@@ -267,7 +268,8 @@ static struct rule *load_css(fz_context *ctx, struct rule *css, fz_xml *root)
}
}
#endif
- if (tag && !strcmp(tag, "style")) {
+ if (tag && !strcmp(tag, "style"))
+ {
char *s = concat_text(ctx, node);
css = fz_parse_css(ctx, css, s);
fz_free(ctx, s);
@@ -283,8 +285,6 @@ html_layout_document(html_document *doc, float w, float h)
{
struct rule *css = NULL;
struct box *root_box;
- struct style style;
- struct computed_style cstyle;
#if 0
strcpy(dirname, argv[i]);
@@ -299,11 +299,8 @@ html_layout_document(html_document *doc, float w, float h)
// print_rules(css);
- style.up = NULL;
- style.count = 0;
- compute_style(&cstyle, &style);
- root_box = new_box(doc->ctx, NULL, BOX_BLOCK, &cstyle, NULL);
-
- layout_tree(doc->ctx, doc->root, root_box, NULL, css);
+ root_box = new_box(doc->ctx, NULL, NULL);
+ generate_boxes(doc->ctx, doc->root, root_box, css);
+ layout_boxes(doc->ctx, root_box, w, h);
print_box(doc->ctx, root_box, 0);
}