summaryrefslogtreecommitdiff
path: root/source/html/epub-doc.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2016-10-07 19:56:00 +0100
committerRobin Watts <robin.watts@artifex.com>2016-10-10 15:57:46 +0100
commitf22be2b82fe1afe733dd0e6c3ab9d26a39acd39b (patch)
treea56e46b0dc3d44f844e82ba03d6aba9dac1319c7 /source/html/epub-doc.c
parentb2a895f639c3f98925a0ad1913bf81dc44fe221f (diff)
downloadmupdf-f22be2b82fe1afe733dd0e6c3ab9d26a39acd39b.tar.xz
Bug 697123: epub: Adjust anchor positions using fragments.
Diffstat (limited to 'source/html/epub-doc.c')
-rw-r--r--source/html/epub-doc.c51
1 files changed, 44 insertions, 7 deletions
diff --git a/source/html/epub-doc.c b/source/html/epub-doc.c
index 19b8c0a8..fbcc1a86 100644
--- a/source/html/epub-doc.c
+++ b/source/html/epub-doc.c
@@ -34,6 +34,35 @@ struct epub_page_s
int number;
};
+static int
+find_anchor_flow(fz_html_flow *flow, const char *anchor, float page_h, int *page)
+{
+ while (flow)
+ {
+ if (flow->type == FLOW_ANCHOR && !strcmp(anchor, flow->content.text))
+ {
+ *page += (int)(flow->y / page_h);
+ return 1;
+ }
+ flow = flow->next;
+ }
+ return 0;
+}
+
+static int
+find_anchor(fz_html *box, const char *anchor, float page_h, int *page)
+{
+ while (box)
+ {
+ if (box->flow_head && find_anchor_flow(box->flow_head, anchor, page_h, page))
+ return 1;
+ if (box->down && find_anchor(box->down, anchor, page_h, page))
+ return 1;
+ box = box->next;
+ }
+ return 0;
+}
+
static void
epub_update_link_dests(fz_context *ctx, epub_document *doc, fz_outline *node)
{
@@ -43,13 +72,24 @@ epub_update_link_dests(fz_context *ctx, epub_document *doc, fz_outline *node)
{
if (node->dest.kind == FZ_LINK_GOTO)
{
+ const char *dest = node->dest.ld.gotor.dest;
+ const char *s = strchr(dest, '#');
+ int n = s ? s - dest : strlen(dest);
+ if (s && s[1] == 0)
+ s = NULL;
+
for (ch = doc->spine; ch; ch = ch->next)
{
- if (!strcmp(ch->path, node->dest.ld.gotor.dest))
+ if (strncmp(ch->path, dest, n) || ch->path[n] != 0)
+ continue;
+ node->dest.ld.gotor.page = ch->start;
+ if (s)
{
- node->dest.ld.gotor.page = ch->start;
- break;
+ /* Search for a matching fragment */
+ if (find_anchor(ch->box, s+1, ch->page_h, &node->dest.ld.gotor.page))
+ continue;
}
+ break;
}
}
epub_update_link_dests(ctx, doc, node->down);
@@ -240,7 +280,7 @@ epub_parse_chapter(fz_context *ctx, epub_document *doc, const char *path)
static fz_outline *
epub_parse_ncx_imp(fz_context *ctx, epub_document *doc, fz_xml *node, char *base_uri)
{
- char path[2048], *s;
+ char path[2048];
fz_outline *outline, *head, **tailp;
head = NULL;
@@ -258,9 +298,6 @@ epub_parse_ncx_imp(fz_context *ctx, epub_document *doc, fz_xml *node, char *base
fz_strlcat(path, content, sizeof path);
fz_urldecode(path);
fz_cleanname(path);
- s = strchr(path, '#');
- if (s)
- *s = 0;
*tailp = outline = fz_new_outline(ctx);
tailp = &(*tailp)->next;