summaryrefslogtreecommitdiff
path: root/source/html/layout.c
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2014-09-08 15:49:59 +0200
committerTor Andersson <tor.andersson@artifex.com>2014-12-03 12:25:51 +0100
commit9d1482bc78d72ba330c2130170b49b4e18702623 (patch)
treee7f87a3266419e7bb238095e3fa146953dcb9e28 /source/html/layout.c
parent4b8638cfa35ecacf7418ec8933f971577652bb79 (diff)
downloadmupdf-9d1482bc78d72ba330c2130170b49b4e18702623.tar.xz
html: CSS lexer and parser.
Diffstat (limited to 'source/html/layout.c')
-rw-r--r--source/html/layout.c153
1 files changed, 153 insertions, 0 deletions
diff --git a/source/html/layout.c b/source/html/layout.c
new file mode 100644
index 00000000..91e20b9f
--- /dev/null
+++ b/source/html/layout.c
@@ -0,0 +1,153 @@
+#include "mupdf/html.h"
+
+static const char *default_css =
+"html,address,blockquote,body,dd,div,dl,dt,h1,h2,h3,h4,h5,h6,ol,p,ul,center,hr,pre{display:block}"
+"span{display:inline}"
+"li{display:list-item}"
+"head{display:none}"
+"body{margin:0px}"
+"h1{font-size:2em;margin:.67em 0}"
+"h2{font-size:1.5em;margin:.75em 0}"
+"h3{font-size:1.17em;margin:.83em 0}"
+"h4,p,blockquote,ul,ol,dl,dir,menu{margin:1.12em 0}"
+"h5{font-size:.83em;margin:1.5em 0}"
+"h6{font-size:.75em;margin:1.67em 0}"
+"h1,h2,h3,h4,h5,h6,b,strong{font-weight:bold}"
+"blockquote{margin-left:40px;margin-right:40px}"
+"i,cite,em,var,address{font-style:italic}"
+"pre,tt,code,kbd,samp{font-family:monospace}"
+"pre{white-space:pre}"
+"big{font-size:1.17em}"
+"small,sub,sup{font-size:.83em}"
+"sub{vertical-align:sub}"
+"sup{vertical-align:super}"
+"s,strike,del{text-decoration:line-through}"
+"hr{border:1pxinset}"
+"ol,ul,dir,menu,dd{margin-left:40px}"
+"ol{list-style-type:decimal}"
+"ol ul,ul ol,ul ul,ol ol{margin-top:0;margin-bottom:0}"
+"u,ins{text-decoration:underline}"
+"center{text-align:center}"
+"svg{display:none}";
+
+char dirname[2048];
+char filename[2048];
+
+static char *concat_text(fz_xml *root)
+{
+ fz_xml *node;
+ int i = 0, n = 1;
+ char *s;
+ for (node = fz_xml_down(root); node; node = fz_xml_next(node))
+ {
+ const char *text = fz_xml_text(node);
+ n += text ? strlen(text) : 0;
+ }
+ s = malloc(n);
+ for (node = fz_xml_down(root); node; node = fz_xml_next(node))
+ {
+ const char *text = fz_xml_text(node);
+ if (text) {
+ n = strlen(text);
+ memcpy(s+i, text, n);
+ i += n;
+ }
+ }
+ s[i] = 0;
+ return s;
+}
+
+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)) {
+ const char *tag = fz_xml_tag(node);
+#if 0
+ if (tag && !strcmp(tag, "link")) {
+ char *rel = fz_xml_att(node, "rel");
+ if (rel && !strcasecmp(rel, "stylesheet")) {
+ char *type = fz_xml_att(node, "type");
+ if ((type && !strcmp(type, "text/css")) || !type) {
+ char *href = fz_xml_att(node, "href");
+ strcpy(filename, dirname);
+ strcat(filename, href);
+ css = css_parse_file(css, filename);
+ }
+ }
+ }
+#endif
+ if (tag && !strcmp(tag, "style")) {
+printf("found inline style sheet!\n");
+ char *s = concat_text(node);
+printf("'%s'\n", s);
+ css = fz_parse_css(ctx, css, s);
+ }
+ if (fz_xml_down(node))
+ css = load_css(ctx, css, fz_xml_down(node));
+ }
+ return css;
+}
+
+static void layout_text(struct rule *rule, struct style *style, fz_xml *node)
+{
+ printf("%s\n", fz_xml_text(node));
+}
+
+static void layout_tree(struct rule *rule, struct style *up, fz_xml *node)
+{
+ while (node)
+ {
+ struct style style;
+ style.up = up;
+ style.count = 0;
+
+ if (fz_xml_tag(node))
+ {
+ printf("open '%s'\n", fz_xml_tag(node));
+ struct computed_style cstyle;
+ apply_styles(rule, &style, node);
+
+ // TODO: check inline style attribute!
+ //s = fz_xml_att(node, "style");
+ //if (s) {
+ // istyle = parse_declarations(s);
+ // apply_styles(istyle);
+ //}
+
+ compute_style(&cstyle, &style);
+ print_style(&cstyle);
+ }
+ else
+ layout_text(rule, &style, node);
+
+ // TOOD: <br>
+ // TODO: <img>
+
+ if (fz_xml_down(node))
+ layout_tree(rule, &style, fz_xml_down(node));
+
+ printf("end\n");
+ node = fz_xml_next(node);
+ }
+}
+
+void
+html_layout_document(html_document *doc, float w, float h)
+{
+ struct rule *css = NULL;
+
+#if 0
+ strcpy(dirname, argv[i]);
+ s = strrchr(dirname, '/');
+ if (!s) s = strrchr(dirname, '\\');
+ if (s) s[1] = 0;
+ else strcpy(dirname, "./");
+#endif
+
+ css = fz_parse_css(doc->ctx, NULL, default_css);
+ css = load_css(doc->ctx, css, doc->root);
+
+ print_rules(css);
+
+ layout_tree(css, NULL, doc->root);
+}