summaryrefslogtreecommitdiff
path: root/source/html/handler.c
blob: cbce9409228f0c6e741a0e1232bc8386e17ba0c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "mupdf/html.h"

#define DEFW (450)
#define DEFH (600)

void
html_close_document(html_document *doc)
{
	fz_context *ctx = doc->ctx;
	fz_free(ctx, doc);
}

int
html_count_pages(html_document *doc)
{
	int count;

	if (!doc->box) html_layout_document(doc, DEFW, DEFH);

	count = ceilf(doc->box->h / doc->page_h);
printf("count pages! %g / %g = %d\n", doc->box->h, doc->page_h, count);
	return count;
}

html_page *
html_load_page(html_document *doc, int number)
{
printf("load page %d\n", number);
	if (!doc->box) html_layout_document(doc, DEFW, DEFH);
	return (void*)((intptr_t)number + 1);
}

void
html_free_page(html_document *doc, html_page *page)
{
}

fz_rect *
html_bound_page(html_document *doc, html_page *page, fz_rect *bbox)
{
	if (!doc->box) html_layout_document(doc, DEFW, DEFH);
	printf("html: bound page\n");
	bbox->x0 = bbox->y0 = 0;
	bbox->x1 = doc->page_w;
	bbox->y1 = doc->page_h;
	return bbox;
}

void
html_run_page(html_document *doc, html_page *page, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie)
{
	int n = ((intptr_t)page) - 1;
	printf("html: run page %d\n", n);
	html_run_box(doc->ctx, doc->box, n * doc->page_h, (n+1) * doc->page_h, dev, ctm);
}

html_document *
html_open_document_with_stream(fz_context *ctx, fz_stream *file)
{
	html_document *doc;
	fz_buffer *buf;
	fz_xml *xml;

	buf = fz_read_all(file, 0);
	fz_write_buffer_byte(ctx, buf, 0);

printf("html: parsing XHTML.\n");
	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->dirname = NULL;

	doc->super.close = (void*)html_close_document;
	doc->super.count_pages = (void*)html_count_pages;
	doc->super.load_page = (void*)html_load_page;
	doc->super.bound_page = (void*)html_bound_page;
	doc->super.run_page_contents = (void*)html_run_page;
	doc->super.free_page = (void*)html_free_page;

	doc->xml = xml;
	doc->box = NULL;

	return doc;
}

html_document *
html_open_document(fz_context *ctx, const char *filename)
{
	fz_stream *file;
	html_document *doc;
	char *s;

	file = fz_open_file(ctx, filename);
	if (!file)
		fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open file '%s': %s", filename, strerror(errno));

	fz_try(ctx)
	{
		doc = html_open_document_with_stream(ctx, file);
	}
	fz_always(ctx)
	{
		fz_close(file);
	}
	fz_catch(ctx)
	{
		fz_rethrow(ctx);
	}

	doc->dirname = fz_strdup(ctx, filename);
	s = strrchr(doc->dirname, '/');
	if (!s) s = strrchr(doc->dirname, '\\');
	if (s) s[1] = 0;
	else doc->dirname[0] = 0;

	return doc;
}

static int
html_recognize(fz_context *doc, const char *magic)
{
	char *ext = strrchr(magic, '.');

	if (ext)
	{
		if (!fz_strcasecmp(ext, ".xhtml") || !fz_strcasecmp(ext, ".html"))
			return 100;
	}
	if (!strcmp(magic, "application/html+xml") || !strcmp(magic, "application/xml") || !strcmp(magic, "text/xml"))
		return 100;

	return 0;
}

fz_document_handler html_document_handler =
{
	(fz_document_recognize_fn *)&html_recognize,
	(fz_document_open_fn *)&html_open_document,
	(fz_document_open_with_stream_fn *)&html_open_document_with_stream
};