summaryrefslogtreecommitdiff
path: root/source/html
diff options
context:
space:
mode:
Diffstat (limited to 'source/html')
-rw-r--r--source/html/css-apply.c151
-rw-r--r--source/html/handler.c15
-rw-r--r--source/html/layout.c92
3 files changed, 147 insertions, 111 deletions
diff --git a/source/html/css-apply.c b/source/html/css-apply.c
index a99eed2b..8526f7b9 100644
--- a/source/html/css-apply.c
+++ b/source/html/css-apply.c
@@ -717,60 +717,84 @@ get_style_property_display(struct style *node)
return DIS_INLINE;
}
-static float
-compute_number(struct value *value, float em, float hundred, float scale, float initial)
+static struct number
+make_number(float v, int u)
+{
+ struct number n;
+ n.value = v;
+ n.unit = u;
+ return n;
+}
+
+static struct number
+number_from_value(struct value *value, float initial, int initial_unit)
{
char *p;
if (!value)
- return initial;
+ return make_number(initial, initial_unit);
if (value->type == CSS_PERCENT)
- return strtof(value->data, &p) * hundred / 100;
+ return make_number(strtof(value->data, NULL), N_PERCENT);
if (value->type == CSS_NUMBER)
- return strtof(value->data, &p) * scale;
+ return make_number(strtof(value->data, NULL), N_NUMBER);
if (value->type == CSS_LENGTH)
{
float x = strtof(value->data, &p);
if (p[0] == 'e' && p[1] == 'm')
- return x * em;
+ return make_number(x, N_SCALE);
if (p[0] == 'e' && p[1] == 'x')
- return x * em / 2;
+ return make_number(x / 2, N_SCALE);
if (p[0] == 'i' && p[1] == 'n')
- return x * 72;
+ return make_number(x * 72, N_NUMBER);
if (p[0] == 'c' && p[1] == 'm')
- return x * 7200 / 254;
+ return make_number(x * 7200 / 254, N_NUMBER);
if (p[0] == 'm' && p[1] == 'm')
- return x * 720 / 254;
+ return make_number(x * 720 / 254, N_NUMBER);
if (p[0] == 'p' && p[1] == 'c')
- return x * 12;
+ return make_number(x * 12, N_NUMBER);
if (p[0] == 'p' && p[1] == 't')
- return x;
+ return make_number(x, N_NUMBER);
if (p[0] == 'p' && p[1] == 'x')
- return x;
+ return make_number(x, N_NUMBER);
- return x;
+ return make_number(x, N_NUMBER);
}
- return initial;
+ return make_number(initial, initial_unit);
+}
+
+static struct number number_from_property(struct style *node, const char *property, float initial, int initial_unit)
+{
+ return number_from_value(get_style_property(node, property), initial, initial_unit);
+}
+
+float
+from_number(struct number number, float em, float width)
+{
+ switch (number.unit) {
+ default:
+ case N_NUMBER: return number.value;
+ case N_SCALE: return number.value * em;
+ case N_PERCENT: return number.value * width;
+ }
}
void
-compute_style(struct computed_style *style, struct style *node, float width)
+compute_style(struct computed_style *style, struct style *node)
{
struct value *value;
- float em = 12;
memset(style, 0, sizeof *style);
style->position = POS_STATIC;
style->text_align = TA_LEFT;
- style->font_size = 12;
+ style->font_size = make_number(1, N_SCALE);
value = get_style_property(node, "position");
if (value)
@@ -808,45 +832,37 @@ compute_style(struct computed_style *style, struct style *node, float width)
}
value = get_style_property(node, "font-size");
- if (value) {
- if (!strcmp(value->data, "xx-large")) style->font_size = 20;
- else if (!strcmp(value->data, "x-large")) style->font_size = 16;
- else if (!strcmp(value->data, "large")) style->font_size = 14;
- else if (!strcmp(value->data, "medium")) style->font_size = 12;
- else if (!strcmp(value->data, "small")) style->font_size = 10;
- else if (!strcmp(value->data, "x-small")) style->font_size = 8;
- else if (!strcmp(value->data, "xx-small")) style->font_size = 6;
- else if (!strcmp(value->data, "larger")) style->font_size = em + 2;
- else if (!strcmp(value->data, "smaller")) style->font_size = em - 2;
- else style->font_size = compute_number(value, em, em, 1, 12);
- } else {
- style->font_size = 12;
- }
- em = style->font_size;
-
- value = get_style_property(node, "line-height");
- style->line_height = compute_number(value, em, em, em, 1.2 * em);
-
- value = get_style_property(node, "text-indent");
- style->text_indent = compute_number(value, em, width, 1, 0);
-
- value = get_style_property(node, "margin-top");
- style->margin[0] = compute_number(value, em, width, 1, 0);
- value = get_style_property(node, "margin-right");
- style->margin[1] = compute_number(value, em, width, 1, 0);
- value = get_style_property(node, "margin-bottom");
- style->margin[2] = compute_number(value, em, width, 1, 0);
- value = get_style_property(node, "margin-left");
- style->margin[3] = compute_number(value, em, width, 1, 0);
-
- value = get_style_property(node, "padding-top");
- style->padding[0] = compute_number(value, em, width, 1, 0);
- value = get_style_property(node, "padding-right");
- style->padding[1] = compute_number(value, em, width, 1, 0);
- value = get_style_property(node, "padding-bottom");
- style->padding[2] = compute_number(value, em, width, 1, 0);
- value = get_style_property(node, "padding-left");
- style->padding[3] = compute_number(value, em, width, 1, 0);
+ if (value)
+ {
+ if (!strcmp(value->data, "xx-large")) style->font_size = make_number(20, N_NUMBER);
+ else if (!strcmp(value->data, "x-large")) style->font_size = make_number(16, N_NUMBER);
+ else if (!strcmp(value->data, "large")) style->font_size = make_number(14, N_NUMBER);
+ else if (!strcmp(value->data, "medium")) style->font_size = make_number(12, N_NUMBER);
+ else if (!strcmp(value->data, "small")) style->font_size = make_number(10, N_NUMBER);
+ else if (!strcmp(value->data, "x-small")) style->font_size = make_number(8, N_NUMBER);
+ else if (!strcmp(value->data, "xx-small")) style->font_size = make_number(6, N_NUMBER);
+ else if (!strcmp(value->data, "larger")) style->font_size = make_number(1.25f, N_SCALE);
+ else if (!strcmp(value->data, "smaller")) style->font_size = make_number(0.8f, N_SCALE);
+ else style->font_size = number_from_value(value, 12, N_NUMBER);
+ }
+ else
+ {
+ style->font_size = make_number(1, N_SCALE);
+ }
+
+ style->line_height = number_from_property(node, "line-height", 1.2, N_SCALE);
+
+ style->text_indent = number_from_property(node, "text-indent", 0, N_NUMBER);
+
+ style->margin[0] = number_from_property(node, "margin-top", 0, N_NUMBER);
+ style->margin[1] = number_from_property(node, "margin-right", 0, N_NUMBER);
+ style->margin[2] = number_from_property(node, "margin-bottom", 0, N_NUMBER);
+ style->margin[3] = number_from_property(node, "margin-left", 0, N_NUMBER);
+
+ style->padding[0] = number_from_property(node, "padding-top", 0, N_NUMBER);
+ style->padding[1] = number_from_property(node, "padding-right", 0, N_NUMBER);
+ style->padding[2] = number_from_property(node, "padding-bottom", 0, N_NUMBER);
+ style->padding[3] = number_from_property(node, "padding-left", 0, N_NUMBER);
{
const char *font_family = get_style_property_string(node, "font-family", "serif");
@@ -880,13 +896,20 @@ print_style(struct computed_style *style)
printf("\tfont-weight = %s;\n", style->bold ? "bold" : "normal");
printf("\tfont-style = %s;\n", style->italic ? "italic" : "normal");
printf("\tfont-variant = %s;\n", style->smallcaps ? "small-caps" : "normal");
- printf("\tfont-size = %g;\n", style->font_size);
- printf("\tline-height = %g;\n", style->line_height);
- printf("\ttext-indent = %g;\n", style->text_indent);
+
+ printf("\tfont-size = %g%c;\n", style->font_size.value, style->font_size.unit);
+ printf("\tline-height = %g%c;\n", style->line_height.value, style->line_height.unit);
+ printf("\ttext-indent = %g%c;\n", style->text_indent.value, style->text_indent.unit);
printf("\tvertical-align = %d;\n", style->vertical_align);
- printf("\tmargin = %g %g %g %g;\n",
- style->margin[0], style->margin[1], style->margin[2], style->margin[3]);
- printf("\tpadding = %g %g %g %g;\n",
- style->padding[0], style->padding[1], style->padding[2], style->padding[3]);
+ printf("\tmargin = %g%c %g%c %g%c %g%c;\n",
+ style->margin[0].value, style->margin[0].unit,
+ style->margin[1].value, style->margin[1].unit,
+ style->margin[2].value, style->margin[2].unit,
+ style->margin[3].value, style->margin[3].unit);
+ printf("\tpadding = %g%c %g%c %g%c %g%c;\n",
+ style->padding[0].value, style->padding[0].unit,
+ style->padding[1].value, style->padding[1].unit,
+ style->padding[2].value, style->padding[2].unit,
+ style->padding[3].value, style->padding[3].unit);
printf("}\n");
}
diff --git a/source/html/handler.c b/source/html/handler.c
index f5002437..859721c8 100644
--- a/source/html/handler.c
+++ b/source/html/handler.c
@@ -1,9 +1,5 @@
#include "mupdf/html.h"
-struct html_page_s
-{
-};
-
void
html_close_document(html_document *doc)
{
@@ -21,7 +17,7 @@ html_page *
html_load_page(html_document *doc, int number)
{
printf("html: load page %d\n", number);
- return (html_page*)"nothing";
+ return doc->box;
}
void
@@ -43,6 +39,7 @@ void
html_run_page(html_document *doc, html_page *page, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie)
{
printf("html: run page\n");
+ html_run_box(doc->ctx, page, dev, ctm);
}
html_document *
@@ -50,15 +47,14 @@ html_open_document_with_stream(fz_context *ctx, fz_stream *file)
{
html_document *doc;
fz_buffer *buf;
- fz_xml *root;
+ fz_xml *xml;
buf = fz_read_all(file, 0);
- root = fz_parse_xml(ctx, buf->data, buf->len, 1);
+ xml = fz_parse_xml(ctx, buf->data, buf->len, 1);
fz_drop_buffer(ctx, buf);
doc = fz_malloc_struct(ctx, html_document);
doc->ctx = ctx;
- doc->root = root;
doc->super.close = (void*)html_close_document;
doc->super.count_pages = (void*)html_count_pages;
@@ -67,6 +63,9 @@ html_open_document_with_stream(fz_context *ctx, fz_stream *file)
doc->super.run_page_contents = (void*)html_run_page;
doc->super.free_page = (void*)html_free_page;
+ doc->xml = xml;
+ doc->box = NULL;
+
html_layout_document(doc, 400, 600);
return doc;
diff --git a/source/html/layout.c b/source/html/layout.c
index 8079213d..898e0eb7 100644
--- a/source/html/layout.c
+++ b/source/html/layout.c
@@ -43,10 +43,10 @@ struct box
float x, y, w, h;
struct box *up, *down, *last, *next;
fz_xml *node;
- struct style style;
+ struct computed_style style;
};
-struct box *new_box(fz_context *ctx, fz_xml *node, struct style *up_style)
+struct box *new_box(fz_context *ctx, fz_xml *node)
{
struct box *box;
@@ -63,9 +63,6 @@ struct box *new_box(fz_context *ctx, fz_xml *node, struct style *up_style)
box->node = node;
- box->style.up = up_style;
- box->style.count = 0;
-
return box;
}
@@ -120,7 +117,7 @@ static void insert_inline_box(fz_context *ctx, struct box *box, struct box *top)
}
else
{
- struct box *flow = new_box(ctx, NULL, &top->style);
+ struct box *flow = new_box(ctx, NULL);
insert_box(ctx, flow, BOX_FLOW, top);
insert_box(ctx, box, BOX_INLINE, flow);
}
@@ -135,24 +132,24 @@ static void insert_inline_box(fz_context *ctx, struct box *box, struct box *top)
}
}
-static void generate_boxes(fz_context *ctx, fz_xml *node, struct box *top, struct rule *rule)
+static void generate_boxes(fz_context *ctx, fz_xml *node, struct box *top, struct rule *rule, struct style *up_style)
{
- struct style *up_style;
+ struct style 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)
{
- box = new_box(ctx, node, up_style);
+ style.up = up_style;
+ style.count = 0;
+
+ box = new_box(ctx, node);
if (fz_xml_tag(node))
{
- apply_styles(ctx, &box->style, rule, node);
+ apply_styles(ctx, &style, rule, node);
- display = get_style_property_display(&box->style);
+ display = get_style_property_display(&style);
// TOOD: <br>
// TODO: <img>
@@ -174,7 +171,7 @@ static void generate_boxes(fz_context *ctx, fz_xml *node, struct box *top, struc
}
if (fz_xml_down(node))
- generate_boxes(ctx, fz_xml_down(node), box, rule);
+ generate_boxes(ctx, fz_xml_down(node), box, rule, &style);
}
}
else
@@ -182,44 +179,44 @@ static void generate_boxes(fz_context *ctx, fz_xml *node, struct box *top, struc
insert_inline_box(ctx, box, top);
}
+ compute_style(&box->style, &style);
+
node = fz_xml_next(node);
}
}
-static void layout_inline(fz_context *ctx, struct box *box, struct box *top)
+static void layout_inline(fz_context *ctx, struct box *box, struct box *top, float em)
{
- struct computed_style style;
struct box *child;
const char *s;
- compute_style(&style, &box->style, top->w);
+ em = from_number(box->style.font_size, em, em);
box->x = top->x + top->w;
box->y = top->y;
- box->h = style.font_size;
+ box->h = em;
box->w = 0;
s = fz_xml_text(box->node);
if (s)
{
- box->w += strlen(s) * 0.5 * style.font_size;
+ box->w += strlen(s) * 0.5 * em;
}
for (child = box->down; child; child = child->next)
{
- layout_inline(ctx, child, top);
+ layout_inline(ctx, child, top, em);
if (child->h > box->h)
box->h = child->h;
top->w += child->w;
}
}
-static void layout_flow(fz_context *ctx, struct box *box, struct box *top)
+static void layout_flow(fz_context *ctx, struct box *box, struct box *top, float em)
{
- struct computed_style style;
struct box *child;
- compute_style(&style, &box->style, top->w);
+ em = from_number(box->style.font_size, em, em);
box->x = top->x;
box->y = top->y + top->h;
@@ -228,35 +225,40 @@ static void layout_flow(fz_context *ctx, struct box *box, struct box *top)
for (child = box->down; child; child = child->next)
{
- layout_inline(ctx, child, box);
+ layout_inline(ctx, child, box, em);
if (child->h > box->h)
box->h = child->h;
box->w += child->w;
}
}
-static void layout_block(fz_context *ctx, struct box *box, struct box *top)
+static void layout_block(fz_context *ctx, struct box *box, struct box *top, float em)
{
- struct computed_style style;
struct box *child;
+ float margin[4];
- compute_style(&style, &box->style, top->w);
+ em = from_number(box->style.font_size, em, em);
- box->x = top->x + style.margin[LEFT];
- box->y = top->y + top->h + style.margin[TOP];
- box->w = top->w - (style.margin[LEFT] + style.margin[RIGHT]);
+ margin[0] = from_number(box->style.margin[0], em, top->w);
+ margin[1] = from_number(box->style.margin[1], em, top->w);
+ margin[2] = from_number(box->style.margin[2], em, top->w);
+ margin[3] = from_number(box->style.margin[3], em, top->w);
+
+ box->x = top->x + margin[LEFT];
+ box->y = top->y + top->h + margin[TOP];
+ box->w = top->w - (margin[LEFT] + margin[RIGHT]);
box->h = 0;
for (child = box->down; child; child = child->next)
{
if (child->type == BOX_BLOCK)
- layout_block(ctx, child, box);
+ layout_block(ctx, child, box, em);
else if (child->type == BOX_FLOW)
- layout_flow(ctx, child, box);
+ layout_flow(ctx, child, box, em);
box->h += child->h;
}
- box->h += style.margin[BOTTOM];
+ box->h += margin[BOTTOM];
}
static void indent(int level)
@@ -290,6 +292,12 @@ static void print_box(fz_context *ctx, struct box *box, int level)
}
}
+void
+html_run_box(fz_context *ctx, struct box *box, fz_device *dev, const fz_matrix *ctm)
+{
+
+}
+
static char *concat_text(fz_context *ctx, fz_xml *root)
{
fz_xml *node;
@@ -356,6 +364,7 @@ html_layout_document(html_document *doc, float w, float h)
struct rule *css = NULL;
struct box *root_box;
struct box *win_box;
+ struct style style;
#if 0
strcpy(dirname, argv[i]);
@@ -366,18 +375,23 @@ html_layout_document(html_document *doc, float w, float h)
#endif
css = fz_parse_css(doc->ctx, NULL, default_css);
- css = load_css(doc->ctx, css, doc->root);
+ css = load_css(doc->ctx, css, doc->xml);
print_rules(css);
- root_box = new_box(doc->ctx, NULL, NULL);
- generate_boxes(doc->ctx, doc->root, root_box, css);
+ style.up = NULL;
+ style.count = 0;
+ root_box = new_box(doc->ctx, NULL);
- win_box = new_box(doc->ctx, NULL, NULL);
+ generate_boxes(doc->ctx, doc->xml, root_box, css, &style);
+
+ win_box = new_box(doc->ctx, NULL);
win_box->w = w;
win_box->h = 0;
- layout_block(doc->ctx, root_box, win_box);
+ layout_block(doc->ctx, root_box, win_box, 12);
print_box(doc->ctx, root_box, 0);
+
+ doc->box = root_box;
}