From owner-svn-ports-head@freebsd.org Thu Jan 11 14:21:24 2018 Return-Path: Delivered-To: svn-ports-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 8C382E658C3; Thu, 11 Jan 2018 14:21:24 +0000 (UTC) (envelope-from tobik@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 964FF73407; Thu, 11 Jan 2018 14:21:23 +0000 (UTC) (envelope-from tobik@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 6BB3816049; Thu, 11 Jan 2018 14:21:22 +0000 (UTC) (envelope-from tobik@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w0BELMqC056868; Thu, 11 Jan 2018 14:21:22 GMT (envelope-from tobik@FreeBSD.org) Received: (from tobik@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w0BELMAr056866; Thu, 11 Jan 2018 14:21:22 GMT (envelope-from tobik@FreeBSD.org) Message-Id: <201801111421.w0BELMAr056866@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: tobik set sender to tobik@FreeBSD.org using -f From: Tobias Kortkamp Date: Thu, 11 Jan 2018 14:21:22 +0000 (UTC) To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r458743 - in head/graphics/llpp: . files X-SVN-Group: ports-head X-SVN-Commit-Author: tobik X-SVN-Commit-Paths: in head/graphics/llpp: . files X-SVN-Commit-Revision: 458743 X-SVN-Commit-Repository: ports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-ports-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the ports tree for head List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 11 Jan 2018 14:21:24 -0000 Author: tobik Date: Thu Jan 11 14:21:22 2018 New Revision: 458743 URL: https://svnweb.freebsd.org/changeset/ports/458743 Log: graphics/llpp: Fix build with MuPDF 1.12.0 llpp > 25 supports MuPDF 1.12.0 out of the box however we currently lack Ocaml 4.04 in the ports tree. llpp 25 is the last version that supports Ocaml 4.02, so backport some changes instead. PR: 224712 Modified: head/graphics/llpp/Makefile head/graphics/llpp/files/patch-link.c Modified: head/graphics/llpp/Makefile ============================================================================== --- head/graphics/llpp/Makefile Thu Jan 11 14:20:38 2018 (r458742) +++ head/graphics/llpp/Makefile Thu Jan 11 14:21:22 2018 (r458743) @@ -3,7 +3,7 @@ PORTNAME= llpp PORTVERSION= 25 -PORTREVISION= 3 +PORTREVISION= 4 CATEGORIES= graphics MASTER_SITES= http://repo.or.cz/llpp.git/snapshot/ DISTNAME= v${PORTVERSION} Modified: head/graphics/llpp/files/patch-link.c ============================================================================== --- head/graphics/llpp/files/patch-link.c Thu Jan 11 14:20:38 2018 (r458742) +++ head/graphics/llpp/files/patch-link.c Thu Jan 11 14:21:22 2018 (r458743) @@ -1,6 +1,91 @@ +Fix build with MuPDF 1.12.0 + +Based on upstream commit 50a80d2fe92b52c0b50915bc194edf556b10aa49 + --- link.c.orig 2016-11-29 15:11:31 UTC +++ link.c -@@ -511,8 +511,8 @@ static void pdfinfo (void) +@@ -8,12 +8,18 @@ + #include + #include + #include ++ ++#include + #include ++#include ++#include + + #include + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -29,7 +35,15 @@ + #include + #include + ++#ifdef __COCOA__ ++#include ++#endif ++ ++#ifdef __APPLE__ ++#include ++#else + #include ++#endif + + #include + #include +@@ -48,10 +62,6 @@ + #include + #include FT_FREETYPE_H + +-#ifdef USE_FONTCONFIG +-#include +-#endif +- + #define PIGGYBACK + #define CACHE_PAGEREFS + +@@ -191,16 +201,15 @@ struct page { + int pageno; + int pdimno; + fz_stext_page *text; +- fz_stext_sheet *sheet; + fz_page *fzpage; + fz_display_list *dlist; ++ fz_link *links; + int slinkcount; + struct slink *slinks; + int annotcount; + struct annot *annots; + struct mark { +- int i; +- fz_stext_span *span; ++ fz_stext_char *ch; + } fmark, lmark; + }; + +@@ -270,6 +279,7 @@ struct { + pdf_document *pdf; + } pdflut; + #endif ++ int utf8cs; + } state; + + struct bo { +@@ -396,6 +406,7 @@ static int readlen (int fd) + { + /* Type punned unions here. Why? Less code (Adjusted by more comments). + https://en.wikipedia.org/wiki/Type_punning */ ++ /* Then again https://bugs.llvm.org/show_bug.cgi?id=31928 - hmm */ + union { uint32_t len; char raw[4]; } buf; + readdata (fd, buf.raw, 4); + return buf.len; +@@ -511,8 +522,8 @@ static void pdfinfo (void) { "info:Producer", "Producer" }, { "info:CreationDate", "Creation date" }, }; @@ -11,7 +96,7 @@ for (size_t i = 0; i < sizeof (metatbl) / sizeof (metatbl[1]); ++i) { int need; -@@ -524,9 +524,9 @@ static void pdfinfo (void) +@@ -524,9 +535,9 @@ static void pdfinfo (void) printd ("info %s\t%s", metatbl[i].name, buf); } else { @@ -19,20 +104,1292 @@ - if (!buf) err (1, "realloc %d", need); - len = need; + buf = realloc (buf, need + 1); -+ if (!buf) err (1, "realloc %d", need + 1); ++ if (!buf) err (1, "pdfinfo realloc %d", need + 1); + len = need + 1; goto again; } } -@@ -1670,7 +1670,6 @@ static void * mainloop (void UNUSED_ATTR +@@ -555,9 +566,6 @@ static void freepage (struct page *page) + if (page->text) { + fz_drop_stext_page (state.ctx, page->text); + } +- if (page->sheet) { +- fz_drop_stext_sheet (state.ctx, page->sheet); +- } + if (page->slinks) { + free (page->slinks); + } +@@ -772,12 +780,13 @@ static struct tile *rendertile (struct page *page, int + if (pbo) { + tile->pixmap = + fz_new_pixmap_with_bbox_and_data (state.ctx, state.colorspace, +- &bbox, 1, pbo->ptr); ++ &bbox, NULL, 1, pbo->ptr); + tile->pbo = pbo; + } + else { + tile->pixmap = +- fz_new_pixmap_with_bbox (state.ctx, state.colorspace, &bbox, 1); ++ fz_new_pixmap_with_bbox (state.ctx, state.colorspace, &bbox, ++ NULL, 1); + } + } + +@@ -817,7 +826,7 @@ pdf_collect_pages(pdf_document *doc, pdf_obj *node) + fz_throw (ctx, FZ_ERROR_GENERIC, "cycle in page tree"); + for (int i = 0; i < len; i++) { + pdf_obj *kid = pdf_array_get (ctx, kids, i); +- char *type = pdf_to_name (ctx, pdf_dict_gets (ctx, kid, "Type")); ++ const char *type = pdf_to_name (ctx, pdf_dict_gets (ctx, kid, "Type")); + if (*type + ? !strcmp (type, "Pages") + : pdf_dict_gets (ctx, kid, "Kids") +@@ -930,7 +939,6 @@ static void initpdims (int wthack) + fz_matrix ctm, page_ctm; + + dev = fz_new_bbox_device (ctx, &rect); +- dev->hints |= FZ_IGNORE_SHADE; + pdf_page_transform (ctx, page, &mediabox, &page_ctm); + fz_invert_matrix (&ctm, &page_ctm); + pdf_run_page (ctx, page, dev, &fz_identity, NULL); +@@ -1034,7 +1042,6 @@ static void initpdims (int wthack) + fz_device *dev; + + dev = fz_new_bbox_device (ctx, &rect); +- dev->hints |= FZ_IGNORE_SHADE; + fz_run_page (ctx, page, dev, &fz_identity, NULL); + fz_close_device (ctx, dev); + fz_drop_device (ctx, dev); +@@ -1291,7 +1298,7 @@ static void process_outline (void) + } + } + +-static char *strofspan (fz_stext_span *span) ++static char *strofline (fz_stext_line *line) + { + char *p; + char utf8[10]; +@@ -1301,7 +1308,7 @@ static char *strofspan (fz_stext_span *span) + p = malloc (cap + 1); + if (!p) return NULL; + +- for (ch = span->text; ch < span->text + span->len; ++ch) { ++ for (ch = line->first_char; ch; ch = ch->next) { + int n = fz_runetochar (utf8, ch->c); + if (size + n > cap) { + cap *= 2; +@@ -1316,17 +1323,14 @@ static char *strofspan (fz_stext_span *span) + return p; + } + +-static int matchspan (regex_t *re, fz_stext_span *span, ++static int matchline (regex_t *re, fz_stext_line *line, + int stop, int pageno, double start) + { + int ret; + char *p; + regmatch_t rm; +- int a, b, c; +- fz_rect sb, eb; +- fz_point p1, p2, p3, p4; + +- p = strofspan (span); ++ p = strofline (line); + if (!p) return -1; + + ret = regexec (re, p, 1, &rm, 0); +@@ -1343,31 +1347,33 @@ static int matchspan (regex_t *re, fz_stext_span *span + return 0; + } + else { +- int l = span->len; ++ fz_point p1, p2, p3, p4; ++ fz_rect s = {0,0,0,0}, e; ++ fz_stext_char *ch; ++ int o = 0; + +- for (a = 0, c = 0; c < rm.rm_so && a < l; a++) { +- c += fz_runelen (span->text[a].c); ++ for (ch = line->first_char; ch; ch = ch->next) { ++ o += fz_runelen (ch->c); ++ if (o > rm.rm_so) { ++ s = ch->bbox; ++ break; ++ } + } +- for (b = a; c < rm.rm_eo - 1 && b < l; b++) { +- c += fz_runelen (span->text[b].c); ++ for (;ch; ch = ch->next) { ++ o += fz_runelen (ch->c); ++ if (o > rm.rm_eo) break; + } ++ e = ch->bbox; + +- if (fz_runelen (span->text[b].c) > 1) { +- b = fz_maxi (0, b-1); +- } ++ p1.x = s.x0; ++ p1.y = s.y0; ++ p2.x = e.x1; ++ p2.y = s.y0; ++ p3.x = e.x1; ++ p3.y = e.y1; ++ p4.x = s.x0; ++ p4.y = e.y1; + +- fz_stext_char_bbox (state.ctx, &sb, span, a); +- fz_stext_char_bbox (state.ctx, &eb, span, b); +- +- p1.x = sb.x0; +- p1.y = sb.y0; +- p2.x = eb.x1; +- p2.y = sb.y0; +- p3.x = eb.x1; +- p3.y = eb.y1; +- p4.x = sb.x0; +- p4.y = eb.y1; +- + if (!stop) { + printd ("firstmatch %d %d %f %f %f %f %f %f %f %f", + pageno, 1, +@@ -1393,24 +1399,16 @@ static int matchspan (regex_t *re, fz_stext_span *span + } + } + +-static int compareblocks (const void *l, const void *r) +-{ +- fz_stext_block const *ls = l; +- fz_stext_block const *rs = r; +- return ls->bbox.y0 - rs->bbox.y0; +-} +- + /* wishful thinking function */ + static void search (regex_t *re, int pageno, int y, int forward) + { +- int j; + fz_device *tdev; + fz_stext_page *text; +- fz_stext_sheet *sheet; + struct pagedim *pdim; + int stop = 0, niters = 0; + double start, end; + fz_page *page; ++ fz_stext_block *block; + + start = now (); + while (pageno >= 0 && pageno < state.pagecount && !stop) { +@@ -1428,9 +1426,8 @@ static void search (regex_t *re, int pageno, int y, in } + } + pdim = pdimofpageno (pageno); +- sheet = fz_new_stext_sheet (state.ctx); + text = fz_new_stext_page (state.ctx, &pdim->mediabox); +- tdev = fz_new_stext_device (state.ctx, sheet, text, 0); ++ tdev = fz_new_stext_device (state.ctx, text, 0); - lock ("open"); -- fz_set_use_document_css (state.ctx, usedoccss); - fz_try (state.ctx) { - ok = openxref (filename, password); + page = fz_load_page (state.ctx, state.doc, pageno); + { +@@ -1438,34 +1435,34 @@ static void search (regex_t *re, int pageno, int y, in + fz_run_page (state.ctx, page, tdev, &ctm, NULL); + } + +- qsort (text->blocks, text->len, sizeof (*text->blocks), compareblocks); + fz_close_device (state.ctx, tdev); + fz_drop_device (state.ctx, tdev); + +- for (j = 0; j < text->len; ++j) { +- int k; +- fz_page_block *pb; +- fz_stext_block *block; ++ if (forward) { ++ for (block = text->first_block; block; block = block->next) { ++ fz_stext_line *line; + +- pb = &text->blocks[forward ? j : text->len - 1 - j]; +- if (pb->type != FZ_PAGE_BLOCK_TEXT) continue; +- block = pb->u.text; ++ if (block->type != FZ_STEXT_BLOCK_TEXT) continue; ++ for (line = block->u.t.first_line; line; line = line->next) { ++ if (line->bbox.y0 < y + 1) continue; + +- for (k = 0; k < block->len; ++k) { ++ switch (matchline (re, line, stop, pageno, start)) { ++ case 0: break; ++ case 1: stop = 1; break; ++ case -1: stop = 1; goto endloop; ++ } ++ } ++ } ++ } ++ else { ++ for (block = text->last_block; block; block = block->prev) { + fz_stext_line *line; +- fz_stext_span *span; + +- if (forward) { +- line = &block->lines[k]; ++ if (block->type != FZ_STEXT_BLOCK_TEXT) continue; ++ for (line = block->u.t.last_line; line; line = line->prev) { + if (line->bbox.y0 < y + 1) continue; +- } +- else { +- line = &block->lines[block->len - 1 - k]; +- if (line->bbox.y0 > y - 1) continue; +- } + +- for (span = line->first_span; span; span = span->next) { +- switch (matchspan (re, span, stop, pageno, start)) { ++ switch (matchline (re, line, stop, pageno, start)) { + case 0: break; + case 1: stop = 1; break; + case -1: stop = 1; goto endloop; +@@ -1473,6 +1470,7 @@ static void search (regex_t *re, int pageno, int y, in + } } -@@ -4008,8 +4007,7 @@ CAMLprim value ml_platform (value unit_v + } ++ + if (forward) { + pageno += 1; + y = 0; +@@ -1483,7 +1481,6 @@ static void search (regex_t *re, int pageno, int y, in + } + endloop: + fz_drop_stext_page (state.ctx, text); +- fz_drop_stext_sheet (state.ctx, sheet); + fz_drop_page (state.ctx, page); + } + end = now (); +@@ -1537,17 +1534,13 @@ static void realloctexts (int texcount) + state.texids + texcount); + } + +- size = texcount * sizeof (*state.texids); ++ size = texcount * (sizeof (*state.texids) + sizeof (*state.texowners)); + state.texids = realloc (state.texids, size); + if (!state.texids) { +- err (1, "realloc texids %" FMT_s, size); ++ err (1, "realloc texs %" FMT_s, size); + } + +- size = texcount * sizeof (*state.texowners); +- state.texowners = realloc (state.texowners, size); +- if (!state.texowners) { +- err (1, "realloc texowners %" FMT_s, size); +- } ++ state.texowners = (void *) (state.texids + texcount); + if (texcount > state.texcount) { + glGenTextures (texcount - state.texcount, + state.texids + state.texcount); +@@ -1566,23 +1559,32 @@ static char *mbtoutf8 (char *s) + wchar_t *tmp; + size_t i, ret, len; + ++ if (state.utf8cs) { ++ return s; ++ } ++ + len = mbstowcs (NULL, s, strlen (s)); + if (len == 0) { + return s; + } + else { + if (len == (size_t) -1) { ++ printd ("emsg mbtoutf8: mbstowcs %d:%s\n", errno, strerror (errno)); + return s; + } + } + +- tmp = malloc (len * sizeof (wchar_t)); ++ tmp = calloc (len, sizeof (wchar_t)); + if (!tmp) { ++ printd ("emsg mbtoutf8: calloc(%zu, %zu) %d:%s", ++ len, sizeof (wchar_t), errno, strerror (errno)); + return s; + } + + ret = mbstowcs (tmp, s, len); + if (ret == (size_t) -1) { ++ printd ("emsg mbtoutf8: mbswcs %zu characters failed %d:%s\n", ++ len, errno, strerror (errno)); + free (tmp); + return s; + } +@@ -1594,6 +1596,7 @@ static char *mbtoutf8 (char *s) + + p = r = malloc (len + 1); + if (!r) { ++ printd ("emsg mbtoutf8: malloc(%zu)", len); + free (tmp); + return s; + } +@@ -1988,87 +1991,45 @@ static void recti (int x0, int y0, int x1, int y1) + + static void showsel (struct page *page, int ox, int oy) + { +- int seen = 0; + fz_irect bbox; + fz_rect rect; +- fz_stext_line *line; +- fz_page_block *pageb; + fz_stext_block *block; +- struct mark first, last; ++ int seen = 0; + unsigned char selcolor[] = {15,15,15,140}; + +- first = page->fmark; +- last = page->lmark; ++ if (!page->fmark.ch || !page->lmark.ch) return; + +- if (!first.span || !last.span) return; +- + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_SRC_ALPHA); + glColor4ubv (selcolor); + + ox += state.pagedims[page->pdimno].bounds.x0; + oy += state.pagedims[page->pdimno].bounds.y0; +- for (pageb = page->text->blocks; +- pageb < page->text->blocks + page->text->len; +- ++pageb) { +- if (pageb->type != FZ_PAGE_BLOCK_TEXT) continue; +- block = pageb->u.text; + +- for (line = block->lines; +- line < block->lines + block->len; +- ++line) { +- fz_stext_span *span; +- rect = fz_empty_rect; ++ for (block = page->text->first_block; block; block = block->next) { ++ fz_stext_line *line; + +- for (span = line->first_span; span; span = span->next) { +- int i, j, k; +- bbox.x0 = bbox.y0 = bbox.x1 = bbox.y1 = 0; ++ if (block->type != FZ_STEXT_BLOCK_TEXT) continue; ++ for (line = block->u.t.first_line; line; line = line->next) { ++ fz_stext_char *ch; + +- j = 0; +- k = span->len - 1; +- +- if (span == page->fmark.span && span == page->lmark.span) { +- seen = 1; +- j = fz_mini (first.i, last.i); +- k = fz_maxi (first.i, last.i); +- } +- else { +- if (span == first.span) { +- seen = 1; +- j = first.i; +- } +- else if (span == last.span) { +- seen = 1; +- k = last.i; +- } +- } +- +- if (seen) { +- for (i = j; i <= k; ++i) { +- fz_rect bbox1; +- fz_union_rect (&rect, +- fz_stext_char_bbox (state.ctx, &bbox1, +- span, i)); +- } ++ rect = fz_empty_rect; ++ for (ch = line->first_char; ch; ch = ch->next) { ++ if (ch == page->fmark.ch) seen = 1; ++ if (seen) fz_union_rect (&rect, &ch->bbox); ++ if (ch == page->lmark.ch) { + fz_round_rect (&bbox, &rect); +- lprintf ("%d %d %d %d oy=%d ox=%d\n", +- bbox.x0, +- bbox.y0, +- bbox.x1, +- bbox.y1, +- oy, ox); +- + recti (bbox.x0 + ox, bbox.y0 + oy, + bbox.x1 + ox, bbox.y1 + oy); +- if (span == last.span) { +- goto done; +- } +- rect = fz_empty_rect; ++ goto done; + } + } ++ fz_round_rect (&bbox, &rect); ++ recti (bbox.x0 + ox, bbox.y0 + oy, ++ bbox.x1 + ox, bbox.y1 + oy); + } + } +- done: ++done: + glDisable (GL_BLEND); + } + +@@ -2131,14 +2092,20 @@ static void solidrect (fz_matrix *m, + glDrawArrays (GL_TRIANGLE_FAN, 0, 4); + } + ++static void ensurelinks (struct page *page) ++{ ++ if (!page->links) ++ page->links = fz_load_links (state.ctx, page->fzpage); ++} ++ + static void highlightlinks (struct page *page, int xoff, int yoff) + { + fz_matrix ctm, tm, pm; +- fz_link *link, *links; ++ fz_link *link; + GLfloat *texcoords = state.texcoords; + GLfloat *vertices = state.vertices; + +- links = fz_load_links (state.ctx, page->fzpage); ++ ensurelinks (page); + + glEnable (GL_TEXTURE_1D); + glEnable (GL_BLEND); +@@ -2154,7 +2121,7 @@ static void highlightlinks (struct page *page, int xof + glTexCoordPointer (1, GL_FLOAT, 0, texcoords); + glVertexPointer (2, GL_FLOAT, 0, vertices); + +- for (link = links; link; link = link->next) { ++ for (link = page->links; link; link = link->next) { + fz_point p1, p2, p3, p4; + + p1.x = link->rect.x0; +@@ -2214,16 +2181,10 @@ static void droptext (struct page *page) + { + if (page->text) { + fz_drop_stext_page (state.ctx, page->text); +- page->fmark.i = -1; +- page->lmark.i = -1; +- page->fmark.span = NULL; +- page->lmark.span = NULL; ++ page->fmark.ch = NULL; ++ page->lmark.ch = NULL; + page->text = NULL; + } +- if (page->sheet) { +- fz_drop_stext_sheet (state.ctx, page->sheet); +- page->sheet = NULL; +- } + } + + static void dropannots (struct page *page) +@@ -2279,6 +2240,10 @@ static void dropslinks (struct page *page) + page->slinks = NULL; + page->slinkcount = 0; + } ++ if (page->links) { ++ fz_drop_link (state.ctx, page->links); ++ page->links = NULL; ++ } + } + + static void ensureslinks (struct page *page) +@@ -2286,7 +2251,7 @@ static void ensureslinks (struct page *page) + fz_matrix ctm; + int i, count; + size_t slinksize = sizeof (*page->slinks); +- fz_link *link, *links; ++ fz_link *link; + + ensureannots (page); + if (state.gen != page->sgen) { +@@ -2295,11 +2260,11 @@ static void ensureslinks (struct page *page) + } + if (page->slinks) return; + +- links = fz_load_links (state.ctx, page->fzpage); ++ ensurelinks (page); + ctm = pagectm (page); + + count = page->annotcount; +- for (link = links; link; link = link->next) { ++ for (link = page->links; link; link = link->next) { + count++; + } + if (count > 0) { +@@ -2311,7 +2276,7 @@ static void ensureslinks (struct page *page) + err (1, "calloc slinks %d", count); + } + +- for (i = 0, link = links; link; ++i, link = link->next) { ++ for (i = 0, link = page->links; link; ++i, link = link->next) { + fz_rect rect; + + rect = link->rect; +@@ -2467,20 +2432,20 @@ static void uploadslice (struct tile *tile, struct sli + } + } + +-CAMLprim value ml_begintiles (value unit_v) ++CAMLprim void ml_begintiles (value unit_v) + { + CAMLparam1 (unit_v); + glEnable (TEXT_TYPE); + glTexCoordPointer (2, GL_FLOAT, 0, state.texcoords); + glVertexPointer (2, GL_FLOAT, 0, state.vertices); +- CAMLreturn (unit_v); ++ CAMLreturn0; + } + +-CAMLprim value ml_endtiles (value unit_v) ++CAMLprim void ml_endtiles (value unit_v) + { + CAMLparam1 (unit_v); + glDisable (TEXT_TYPE); +- CAMLreturn (unit_v); ++ CAMLreturn0; + } + + CAMLprim void ml_drawtile (value args_v, value ptr_v) +@@ -2664,9 +2629,9 @@ static fz_link *getlink (struct page *page, int x, int + { + fz_point p; + fz_matrix ctm; +- fz_link *link, *links; ++ fz_link *link; + +- links = fz_load_links (state.ctx, page->fzpage); ++ ensureslinks (page); + + p.x = x; + p.y = y; +@@ -2675,7 +2640,7 @@ static fz_link *getlink (struct page *page, int x, int + fz_invert_matrix (&ctm, &ctm); + fz_transform_point (&p, &ctm); + +- for (link = links; link; link = link->next) { ++ for (link = page->links; link; link = link->next) { + if (p.x >= link->rect.x0 && p.x <= link->rect.x1) { + if (p.y >= link->rect.y0 && p.y <= link->rect.y1) { + return link; +@@ -2697,13 +2662,10 @@ static void ensuretext (struct page *page) + + page->text = fz_new_stext_page (state.ctx, + &state.pagedims[page->pdimno].mediabox); +- page->sheet = fz_new_stext_sheet (state.ctx); +- tdev = fz_new_stext_device (state.ctx, page->sheet, page->text, 0); ++ tdev = fz_new_stext_device (state.ctx, page->text, 0); + ctm = pagectm (page); + fz_run_display_list (state.ctx, page->dlist, + tdev, &ctm, &fz_infinite_rect, NULL); +- qsort (page->text->blocks, page->text->len, +- sizeof (*page->text->blocks), compareblocks); + fz_close_device (state.ctx, tdev); + fz_drop_device (state.ctx, tdev); + } +@@ -2743,7 +2705,9 @@ CAMLprim value ml_find_page_with_links (value start_pa + } + else { + fz_page *page = fz_load_page (state.ctx, state.doc, i); +- found = !!fz_load_links (state.ctx, page); ++ fz_link *link = fz_load_links (state.ctx, page); ++ found = !!link; ++ fz_drop_link (state.ctx, link); + fz_drop_page (state.ctx, page); + } + +@@ -2917,8 +2881,9 @@ CAMLprim value ml_getlink (value ptr_v, value n_v) + CAMLprim value ml_getannotcontents (value ptr_v, value n_v) + { + CAMLparam2 (ptr_v, n_v); ++ CAMLlocal1 (ret_v); + pdf_document *pdf; +- const char *contents = ""; ++ char *contents = NULL; + + lock (__func__); + pdf = pdf_specifics (state.ctx, state.doc); +@@ -2929,11 +2894,18 @@ CAMLprim value ml_getannotcontents (value ptr_v, value + + page = parse_pointer (__func__, s); + slink = &page->slinks[Int_val (n_v)]; +- contents = pdf_annot_contents (state.ctx, +- (pdf_annot *) slink->u.annot); ++ contents = pdf_copy_annot_contents (state.ctx, ++ (pdf_annot *) slink->u.annot); + } + unlock (__func__); +- CAMLreturn (caml_copy_string (contents)); ++ if (contents) { ++ ret_v = caml_copy_string (contents); ++ fz_free (state.ctx, contents); ++ } ++ else { ++ ret_v = caml_copy_string (""); ++ } ++ CAMLreturn (ret_v); + } + + CAMLprim value ml_getlinkcount (value ptr_v) +@@ -3019,85 +2991,67 @@ CAMLprim value ml_whatsunder (value ptr_v, value x_v, + } + else { + fz_rect *b; +- fz_page_block *pageb; + fz_stext_block *block; + + ensuretext (page); +- for (pageb = page->text->blocks; +- pageb < page->text->blocks + page->text->len; +- ++pageb) { ++ ++ for (block = page->text->first_block; block; block = block->next) { + fz_stext_line *line; +- if (pageb->type != FZ_PAGE_BLOCK_TEXT) continue; +- block = pageb->u.text; + ++ if (block->type != FZ_STEXT_BLOCK_TEXT) continue; + b = &block->bbox; + if (!(x >= b->x0 && x <= b->x1 && y >= b->y0 && y <= b->y1)) + continue; + +- for (line = block->lines; +- line < block->lines + block->len; +- ++line) { +- fz_stext_span *span; ++ for (line = block->u.t.first_line; line; line = line->next) { ++ fz_stext_char *ch; + + b = &line->bbox; + if (!(x >= b->x0 && x <= b->x1 && y >= b->y0 && y <= b->y1)) + continue; + +- for (span = line->first_span; span; span = span->next) { +- int charnum; ++ for (ch = line->first_char; ch; ch = ch->next) { ++ b = &ch->bbox; + +- b = &span->bbox; +- if (!(x >= b->x0 && x <= b->x1 && y >= b->y0 && y <= b->y1)) +- continue; ++ if (x >= b->x0 && x <= b->x1 && y >= b->y0 && y <= b->y1) { ++ const char *n2 = fz_font_name (state.ctx, ch->font); ++ FT_FaceRec *face = fz_font_ft_face (state.ctx, ++ ch->font); + +- for (charnum = 0; charnum < span->len; ++charnum) { +- fz_rect bbox; +- fz_stext_char_bbox (state.ctx, &bbox, span, charnum); +- b = &bbox; ++ if (!n2) n2 = ""; + +- if (x >= b->x0 && x <= b->x1 +- && y >= b->y0 && y <= b->y1) { +- fz_stext_style *style = span->text->style; +- const char *n2 = +- style->font +- ? fz_font_name (state.ctx, style->font) +- : "Span has no font name" +- ; +- FT_FaceRec *face = fz_font_ft_face (state.ctx, +- style->font); +- if (face && face->family_name) { +- char *s; +- char *n1 = face->family_name; +- size_t l1 = strlen (n1); +- size_t l2 = strlen (n2); ++ if (face && face->family_name) { ++ char *s; ++ char *n1 = face->family_name; ++ size_t l1 = strlen (n1); ++ size_t l2 = strlen (n2); + +- if (l1 != l2 || memcmp (n1, n2, l1)) { +- s = malloc (l1 + l2 + 2); +- if (s) { +- memcpy (s, n2, l2); +- s[l2] = '='; +- memcpy (s + l2 + 1, n1, l1 + 1); +- str_v = caml_copy_string (s); +- free (s); +- } ++ if (l1 != l2 || memcmp (n1, n2, l1)) { ++ s = malloc (l1 + l2 + 2); ++ if (s) { ++ memcpy (s, n2, l2); ++ s[l2] = '='; ++ memcpy (s + l2 + 1, n1, l1 + 1); ++ str_v = caml_copy_string (s); ++ free (s); + } + } +- if (str_v == Val_unit) { +- str_v = caml_copy_string (n2); +- } +- ret_v = caml_alloc_small (1, utext); +- Field (ret_v, 0) = str_v; +- goto unlock; + } ++ if (str_v == Val_unit) { ++ str_v = caml_copy_string (n2); ++ } ++ ret_v = caml_alloc_small (1, utext); ++ Field (ret_v, 0) = str_v; ++ goto unlock; + } + } + } + } + } +- unlock: ++unlock: + unlock (__func__); + +- done: ++done: + CAMLreturn (ret_v); + } + +@@ -3120,10 +3074,8 @@ CAMLprim void ml_clearmark (value ptr_v) + } + + page = parse_pointer (__func__, s); +- page->fmark.span = NULL; +- page->lmark.span = NULL; +- page->fmark.i = 0; +- page->lmark.i = 0; ++ page->fmark.ch = NULL; ++ page->lmark.ch = NULL; + + unlock (__func__); + done: +@@ -3137,7 +3089,6 @@ CAMLprim value ml_markunder (value ptr_v, value x_v, v + fz_rect *b; + struct page *page; + fz_stext_line *line; +- fz_page_block *pageb; + fz_stext_block *block; + struct pagedim *pdim; + int mark = Int_val (mark_v); +@@ -3155,34 +3106,8 @@ CAMLprim value ml_markunder (value ptr_v, value x_v, v + ensuretext (page); + + if (mark == mark_page) { +- int i; +- fz_page_block *pb1 = NULL, *pb2 = NULL; +- +- for (i = 0; i < page->text->len; ++i) { +- if (page->text->blocks[i].type == FZ_PAGE_BLOCK_TEXT) { +- pb1 = &page->text->blocks[i]; +- break; +- } +- } +- if (!pb1) goto unlock; +- +- for (i = page->text->len - 1; i >= 0; --i) { +- if (page->text->blocks[i].type == FZ_PAGE_BLOCK_TEXT) { +- pb2 = &page->text->blocks[i]; +- break; +- } +- } +- if (!pb2) goto unlock; +- +- block = pb1->u.text; +- +- page->fmark.i = 0; +- page->fmark.span = block->lines->first_span; +- +- block = pb2->u.text; +- line = &block->lines[block->len - 1]; +- page->lmark.i = line->last_span->len - 1; +- page->lmark.span = line->last_span; ++ page->fmark.ch = page->text->first_block->u.t.first_line->first_char; ++ page->lmark.ch = page->text->last_block->u.t.last_line->last_char; + ret_v = Val_bool (1); + goto unlock; + } +@@ -3190,102 +3115,62 @@ CAMLprim value ml_markunder (value ptr_v, value x_v, v + x += pdim->bounds.x0; + y += pdim->bounds.y0; + +- for (pageb = page->text->blocks; +- pageb < page->text->blocks + page->text->len; +- ++pageb) { +- if (pageb->type != FZ_PAGE_BLOCK_TEXT) continue; +- block = pageb->u.text; +- ++ for (block = page->text->first_block; block; block = block->next) { ++ if (block->type != FZ_STEXT_BLOCK_TEXT) continue; + b = &block->bbox; + if (!(x >= b->x0 && x <= b->x1 && y >= b->y0 && y <= b->y1)) + continue; + + if (mark == mark_block) { +- page->fmark.i = 0; +- page->fmark.span = block->lines->first_span; +- +- line = &block->lines[block->len - 1]; +- page->lmark.i = line->last_span->len - 1; +- page->lmark.span = line->last_span; ++ page->fmark.ch = block->u.t.first_line->first_char; ++ page->lmark.ch = block->u.t.last_line->last_char; + ret_v = Val_bool (1); + goto unlock; + } + +- for (line = block->lines; +- line < block->lines + block->len; +- ++line) { +- fz_stext_span *span; ++ for (line = block->u.t.first_line; line; line = line->next) { ++ fz_stext_char *ch; + + b = &line->bbox; + if (!(x >= b->x0 && x <= b->x1 && y >= b->y0 && y <= b->y1)) + continue; + + if (mark == mark_line) { +- page->fmark.i = 0; +- page->fmark.span = line->first_span; +- +- page->lmark.i = line->last_span->len - 1; +- page->lmark.span = line->last_span; ++ page->fmark.ch = line->first_char; ++ page->lmark.ch = line->last_char; + ret_v = Val_bool (1); + goto unlock; + } + +- for (span = line->first_span; span; span = span->next) { +- int charnum; +- +- b = &span->bbox; +- if (!(x >= b->x0 && x <= b->x1 && y >= b->y0 && y <= b->y1)) +- continue; +- +- for (charnum = 0; charnum < span->len; ++charnum) { +- fz_rect bbox; +- fz_stext_char_bbox (state.ctx, &bbox, span, charnum); +- b = &bbox; +- +- if (x >= b->x0 && x <= b->x1 && y >= b->y0 && y <= b->y1) { +- /* unicode ftw */ +- int charnum2, charnum3 = -1, charnum4 = -1; +- +- if (uninteresting (span->text[charnum].c)) goto unlock; +- +- for (charnum2 = charnum; charnum2 >= 0; --charnum2) { +- if (uninteresting (span->text[charnum2].c)) { +- charnum3 = charnum2 + 1; +- break; +- } *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***