Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7643 views
1
#include "mupdf/html.h"
2
3
enum { T, R, B, L };
4
5
typedef struct html_document_s html_document;
6
typedef struct html_page_s html_page;
7
8
struct html_document_s
9
{
10
fz_document super;
11
fz_archive *zip;
12
fz_html_font_set *set;
13
float page_w, page_h, em;
14
float page_margin[4];
15
fz_html *box;
16
};
17
18
struct html_page_s
19
{
20
fz_page super;
21
html_document *doc;
22
int number;
23
};
24
25
static void
26
htdoc_close_document(fz_context *ctx, fz_document *doc_)
27
{
28
html_document *doc = (html_document*)doc_;
29
fz_drop_archive(ctx, doc->zip);
30
fz_drop_html(ctx, doc->box);
31
fz_drop_html_font_set(ctx, doc->set);
32
fz_free(ctx, doc);
33
}
34
35
static int
36
htdoc_count_pages(fz_context *ctx, fz_document *doc_)
37
{
38
html_document *doc = (html_document*)doc_;
39
int count = ceilf(doc->box->h / doc->page_h);
40
return count;
41
}
42
43
static void
44
htdoc_layout(fz_context *ctx, fz_document *doc_, float w, float h, float em)
45
{
46
html_document *doc = (html_document*)doc_;
47
doc->page_margin[T] = em;
48
doc->page_margin[B] = em;
49
doc->page_margin[L] = 0;
50
doc->page_margin[R] = 0;
51
doc->page_w = w - doc->page_margin[L] - doc->page_margin[R];
52
doc->page_h = h - doc->page_margin[T] - doc->page_margin[B];
53
doc->em = em;
54
fz_layout_html(ctx, doc->box, doc->page_w, doc->page_h, doc->em);
55
}
56
57
static void
58
htdoc_drop_page_imp(fz_context *ctx, fz_page *page_)
59
{
60
}
61
62
static fz_rect *
63
htdoc_bound_page(fz_context *ctx, fz_page *page_, fz_rect *bbox)
64
{
65
html_page *page = (html_page*)page_;
66
html_document *doc = page->doc;
67
bbox->x0 = 0;
68
bbox->y0 = 0;
69
bbox->x1 = doc->page_w + doc->page_margin[L] + doc->page_margin[R];
70
bbox->y1 = doc->page_h + doc->page_margin[T] + doc->page_margin[B];
71
return bbox;
72
}
73
74
static void
75
htdoc_run_page(fz_context *ctx, fz_page *page_, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie)
76
{
77
html_page *page = (html_page*)page_;
78
html_document *doc = page->doc;
79
fz_matrix local_ctm = *ctm;
80
int n = page->number;
81
82
fz_pre_translate(&local_ctm, doc->page_margin[L], doc->page_margin[T]);
83
84
fz_draw_html(ctx, doc->box, n * doc->page_h, (n+1) * doc->page_h, dev, &local_ctm);
85
}
86
87
static fz_page *
88
htdoc_load_page(fz_context *ctx, fz_document *doc_, int number)
89
{
90
html_document *doc = (html_document*)doc_;
91
html_page *page = fz_new_page(ctx, sizeof *page);
92
page->super.bound_page = htdoc_bound_page;
93
page->super.run_page_contents = htdoc_run_page;
94
page->super.drop_page_imp = htdoc_drop_page_imp;
95
page->doc = doc;
96
page->number = number;
97
return (fz_page*)page;
98
}
99
100
static fz_document *
101
htdoc_open_document_with_stream(fz_context *ctx, fz_stream *file)
102
{
103
html_document *doc;
104
fz_buffer *buf;
105
106
doc = fz_malloc_struct(ctx, html_document);
107
doc->super.close = htdoc_close_document;
108
doc->super.layout = htdoc_layout;
109
doc->super.count_pages = htdoc_count_pages;
110
doc->super.load_page = htdoc_load_page;
111
112
doc->zip = fz_open_directory(ctx, ".");
113
doc->set = fz_new_html_font_set(ctx);
114
115
buf = fz_read_all(ctx, file, 0);
116
fz_write_buffer_byte(ctx, buf, 0);
117
doc->box = fz_parse_html(ctx, doc->set, doc->zip, ".", buf, NULL);
118
fz_drop_buffer(ctx, buf);
119
120
return (fz_document*)doc;
121
}
122
123
static fz_document *
124
htdoc_open_document(fz_context *ctx, const char *filename)
125
{
126
char dirname[2048];
127
fz_buffer *buf;
128
html_document *doc;
129
130
fz_dirname(dirname, filename, sizeof dirname);
131
132
doc = fz_malloc_struct(ctx, html_document);
133
doc->super.close = htdoc_close_document;
134
doc->super.layout = htdoc_layout;
135
doc->super.count_pages = htdoc_count_pages;
136
doc->super.load_page = htdoc_load_page;
137
138
doc->zip = fz_open_directory(ctx, dirname);
139
doc->set = fz_new_html_font_set(ctx);
140
141
buf = fz_read_file(ctx, filename);
142
fz_write_buffer_byte(ctx, buf, 0);
143
doc->box = fz_parse_html(ctx, doc->set, doc->zip, ".", buf, NULL);
144
fz_drop_buffer(ctx, buf);
145
146
return (fz_document*)doc;
147
}
148
149
static int
150
htdoc_recognize(fz_context *doc, const char *magic)
151
{
152
char *ext = strrchr(magic, '.');
153
154
if (ext)
155
{
156
if (!fz_strcasecmp(ext, ".xml") || !fz_strcasecmp(ext, ".xhtml") || !fz_strcasecmp(ext, ".html"))
157
return 100;
158
}
159
if (!strcmp(magic, "application/html+xml") || !strcmp(magic, "application/xml") || !strcmp(magic, "text/xml"))
160
return 100;
161
162
return 0;
163
}
164
165
fz_document_handler html_document_handler =
166
{
167
&htdoc_recognize,
168
&htdoc_open_document,
169
&htdoc_open_document_with_stream
170
};
171
172