svn commit: r458743 - in head/graphics/llpp: . files

Tobias Kortkamp tobik at FreeBSD.org
Thu Jan 11 14:21:24 UTC 2018


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 <string.h>
+ #include <stdlib.h>
+ #include <signal.h>
++
++#include <math.h>
+ #include <wchar.h>
++#include <locale.h>
++#include <langinfo.h>
+ 
+ #include <unistd.h>
+ #include <pthread.h>
+ #include <sys/uio.h>
+ #include <sys/time.h>
++#include <sys/stat.h>
++#include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/ioctl.h>
+ #include <sys/utsname.h>
+@@ -29,7 +35,15 @@
+ #include <limits.h>
+ #include <inttypes.h>
+ 
++#ifdef __COCOA__
++#include <CoreFoundation/CoreFoundation.h>
++#endif
++
++#ifdef __APPLE__
++#include <OpenGL/gl.h>
++#else
+ #include <GL/gl.h>
++#endif
+ 
+ #include <caml/fail.h>
+ #include <caml/alloc.h>
+@@ -48,10 +62,6 @@
+ #include <ft2build.h>
+ #include FT_FREETYPE_H
+ 
+-#ifdef USE_FONTCONFIG
+-#include <fontconfig/fontconfig.h>
+-#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 = "<unknown font>";
+ 
+-                        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 ***


More information about the svn-ports-all mailing list