From 81a71169ad34843c2dd34a622e114387d5cb17a3 Mon Sep 17 00:00:00 2001 From: Akira Kakuto Date: Tue, 28 Jul 2020 22:26:35 +0000 Subject: Add missing reset_xgstate. Fix CMap wmode setting. (S. Hirata) git-svn-id: svn://tug.org/texlive/trunk@55980 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/dvipdfm-x/ChangeLog | 7 + Build/source/texk/dvipdfm-x/spc_pdfm.c | 229 +++++++++++++++++---------------- Build/source/texk/dvipdfm-x/spc_xtx.c | 9 +- Build/source/texk/dvipdfm-x/tt_cmap.c | 4 +- 4 files changed, 134 insertions(+), 115 deletions(-) (limited to 'Build/source') diff --git a/Build/source/texk/dvipdfm-x/ChangeLog b/Build/source/texk/dvipdfm-x/ChangeLog index 1d14727f586..c1d1176e8db 100644 --- a/Build/source/texk/dvipdfm-x/ChangeLog +++ b/Build/source/texk/dvipdfm-x/ChangeLog @@ -1,3 +1,10 @@ +2020-07-29 Shunsaku Hirata + + * spc_pdfm.c: Improve codes in unicode conversion and + annotation rect calculation. + * spc_xtx.c: Add missing reset_xgstate(). + * tt_cmap.c: Add wmode to auto-generated CMap names. + 2020-07-28 Clerk Ma * pdfobj.c: Simple modifications for LIBDPX. diff --git a/Build/source/texk/dvipdfm-x/spc_pdfm.c b/Build/source/texk/dvipdfm-x/spc_pdfm.c index fdb2ac13d68..f13aaef9d04 100644 --- a/Build/source/texk/dvipdfm-x/spc_pdfm.c +++ b/Build/source/texk/dvipdfm-x/spc_pdfm.c @@ -427,94 +427,133 @@ spc_handler_pdfm_put (struct spc_env *spe, struct spc_arg *ap) */ #include "cmap.h" -static int -reencodestring (CMap *cmap, pdf_obj *instring) -{ -#define WBUF_SIZE 4096 - unsigned char wbuf[WBUF_SIZE]; - unsigned char *obufcur; - const unsigned char *inbufcur; - int inbufleft, obufleft; - - if (!cmap || !instring) - return 0; - - inbufleft = pdf_string_length(instring); - inbufcur = pdf_string_value (instring); - - wbuf[0] = 0xfe; - wbuf[1] = 0xff; - obufcur = wbuf + 2; - obufleft = WBUF_SIZE - 2; - - CMap_decode(cmap, - &inbufcur, &inbufleft, - &obufcur, &obufleft); - - if (inbufleft > 0) { - return -1; +static size_t +calculate_size_utf16 (const unsigned char *p, const unsigned char *endptr) +{ + size_t len = 0; + + while (p < endptr) { + unsigned char c = *p; + if (c < 0x80) { + len += 2; + p += 1; + } else if (c < 0xE0) { + len += 2; + p += 2; + } else if (c < 0xF0) { + len += 2; + p += 3; + } else if (c < 0xF8) { + len += 4; /* Surrogate */ + p += 4; + } else if (c < 0xFC) { + len += 4; /* Surrogate */ + p += 5; + } else if (c < 0xFE) { + len += 4; /* Surrogate */ + p += 6; + } } - pdf_set_string(instring, wbuf, WBUF_SIZE - obufleft); - - return 0; + return len; } static int -maybe_reencode_utf8(pdf_obj *instring) +reencode_string_from_utf8_to_utf16be (pdf_obj *instring) { - unsigned char *inbuf; - int inlen; - int non_ascii = 0; - const unsigned char *cp; - unsigned char *op; - unsigned char wbuf[WBUF_SIZE]; + int error = 0; + unsigned char *strptr; + size_t length; + int non_ascii; + const unsigned char *p, *endptr; - if (!instring) - return 0; + ASSERT(instring); + ASSERT(PDF_OBJ_STRINGTYPE(instring)); - inlen = pdf_string_length(instring); - inbuf = pdf_string_value(instring); + strptr = pdf_string_value(instring); + length = pdf_string_length(instring); /* check if the input string is strictly ASCII */ - for (cp = inbuf; cp < inbuf + inlen; ++cp) { - if (*cp > 127) { - non_ascii = 1; - } + p = strptr; + endptr = strptr + length; + non_ascii = 0; + for ( ; p < endptr; p++) { + if (*p > 127) + non_ascii++; } if (non_ascii == 0) return 0; /* no need to reencode ASCII strings */ - /* Check if the input string is valid UTF8 string - * This routine may be called against non-text strings. - * We need to re-encode string only when string is a text string - * endcoded in UTF8. - */ - if (!UC_UTF8_is_valid_string(inbuf, inbuf + inlen)) - return 0; - else if (inbuf[0] == 0xfe && inbuf[1] == 0xff && - UC_UTF16BE_is_valid_string(inbuf + 2, inbuf + inlen)) - return 0; /* no need to reencode UTF16BE with BOM */ - - cp = inbuf; - op = wbuf; - *op++ = 0xfe; - *op++ = 0xff; - while (cp < inbuf + inlen) { - int32_t usv; - int len; - - usv = UC_UTF8_decode_char((const unsigned char **)&cp, inbuf + inlen); - if (!UC_is_valid(usv)) - return -1; /* out of valid Unicode range, give up (redundant) */ - len = UC_UTF16BE_encode_char(usv, &op, wbuf + WBUF_SIZE); - if (len == 0) - return -1; + if (!UC_UTF8_is_valid_string(strptr, endptr)) { + error = -1; + } else { + unsigned char *q, *buf, *limptr; + size_t len; + + p = strptr; + /* Rough estimate of output length. */ + len = calculate_size_utf16(p, endptr) + 2; + buf = NEW(len, unsigned char); + q = buf; + limptr = buf + len; + q[0] = 0xfe; q[1] = 0xff; + q += 2; + while (p < endptr && q < limptr && !error) { + int32_t ucv; + size_t count; + + ucv = UC_UTF8_decode_char(&p, endptr); + if (!UC_is_valid(ucv)) { + error = -1; + } else { + count = UC_UTF16BE_encode_char(ucv, &q, limptr); + if (count == 0) { + error = -1; + } + } + } + if (!error) + pdf_set_string(instring, buf, q - buf); + RELEASE(buf); } - pdf_set_string(instring, wbuf, op - wbuf); + return error; +} + +static int +reencode_string (CMap *cmap, pdf_obj *instring) +{ + int error = 0; - return 0; + if (!instring || !PDF_OBJ_STRINGTYPE(instring)) + return -1; + + if (cmap) { + unsigned char *obuf; + unsigned char *obufcur; + const unsigned char *inbufcur; + int inbufleft, obufleft, obufsize; + + inbufleft = pdf_string_length(instring); + inbufcur = pdf_string_value (instring); + + obufsize = inbufleft * 4 + 2; + obuf = NEW(obufsize, unsigned char); + obuf[0] = 0xfe; + obuf[1] = 0xff; + obufcur = obuf + 2; + obufleft = obufsize - 2; + + CMap_decode(cmap, &inbufcur, &inbufleft, &obufcur, &obufleft); + + if (inbufleft > 0) + error = -1; + if (!error) + pdf_set_string(instring, obuf, obufsize - obufleft); + RELEASE(obuf); + } + + return error; } /* The purpose of this routine is to check if given string object is @@ -523,7 +562,7 @@ maybe_reencode_utf8(pdf_obj *instring) * additional dictionary entries which is considered as a text string. */ static int -needreencode (pdf_obj *kp, pdf_obj *vp, struct tounicode *cd) +need_reencode (pdf_obj *kp, pdf_obj *vp, struct tounicode *cd) { int r = 0, i; pdf_obj *tk; @@ -562,18 +601,14 @@ modstrings (pdf_obj *kp, pdf_obj *vp, void *dp) case PDF_STRING: if (cd && cd->cmap_id >= 0 && cd->taintkeys) { CMap *cmap = CMap_cache_get(cd->cmap_id); - if (needreencode(kp, vp, cd)) - r = reencodestring(cmap, vp); + if (need_reencode(kp, vp, cd)) + r = reencode_string(cmap, vp); } else if ((dpx_conf.compat_mode == dpx_mode_xdv_mode) && cd && cd->taintkeys) { - /* Please fix this... PDF string object is not always a text string. - * needreencode() is assumed to do a simple check if given string - * object is actually a text string. - */ - if (needreencode(kp, vp, cd)) - r = maybe_reencode_utf8(vp); + if (need_reencode(kp, vp, cd)) + r = reencode_string_from_utf8_to_utf16be(vp); } if (r < 0) /* error occured... */ - WARN("Failed to convert input string to UTF16..."); + WARN("Input string conversion (to UTF16BE) failed for %s...", pdf_name_value(kp)); break; case PDF_DICT: r = pdf_foreach_dict(vp, modstrings, dp); @@ -623,34 +658,10 @@ parse_pdf_dict_with_tounicode (const char **pp, const char *endptr, struct touni static void set_rect (pdf_rect *rect, pdf_coord cp1, pdf_coord cp2, pdf_coord cp3, pdf_coord cp4) { - rect->llx = cp1.x; - if (cp2.x < rect->llx) - rect->llx = cp2.x; - if (cp3.x < rect->llx) - rect->llx = cp3.x; - if (cp4.x < rect->llx) - rect->llx = cp4.x; - rect->urx = cp1.x; - if (cp2.x > rect->urx) - rect->urx = cp2.x; - if (cp3.x > rect->urx) - rect->urx = cp3.x; - if (cp4.x > rect->urx) - rect->urx = cp4.x; - rect->lly = cp1.y; - if (cp2.y < rect->lly) - rect->lly = cp2.y; - if (cp3.y < rect->lly) - rect->lly = cp3.y; - if (cp4.y < rect->lly) - rect->lly = cp4.y; - rect->ury = cp1.y; - if (cp2.y > rect->ury) - rect->ury = cp2.y; - if (cp3.y > rect->ury) - rect->ury = cp3.y; - if (cp4.y > rect->ury) - rect->ury = cp4.y; + rect->llx = min4(cp1.x, cp2.x, cp3.x, cp4.x); + rect->lly = min4(cp1.y, cp2.y, cp3.y, cp4.y); + rect->urx = max4(cp1.x, cp2.x, cp3.x, cp4.x); + rect->ury = max4(cp1.y, cp2.y, cp3.y, cp4.y); } static int diff --git a/Build/source/texk/dvipdfm-x/spc_xtx.c b/Build/source/texk/dvipdfm-x/spc_xtx.c index f80dd83eb40..12742f14155 100644 --- a/Build/source/texk/dvipdfm-x/spc_xtx.c +++ b/Build/source/texk/dvipdfm-x/spc_xtx.c @@ -1,7 +1,7 @@ /* This is xdvipdfmx, an extended version of dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2013-2019 by the dvipdfmx project team. + Copyright (C) 2013-2020 by the dvipdfmx project team. Copyright (c) 2006 SIL International Originally written by Jonathan Kew @@ -138,9 +138,9 @@ spc_handler_xtx_rotate (struct spc_env *spe, struct spc_arg *args) args->curptr = args->endptr; return spc_handler_xtx_do_transform (spe->x_user, spe->y_user, - cos(value * M_PI / 180), sin(value * M_PI / 180), - -sin(value * M_PI / 180), cos(value * M_PI / 180), - 0, 0); + cos(value * M_PI / 180), sin(value * M_PI / 180), + -sin(value * M_PI / 180), cos(value * M_PI / 180), + 0, 0); } int @@ -165,6 +165,7 @@ spc_handler_xtx_grestore (struct spc_env *spe, struct spc_arg *args) */ pdf_dev_reset_fonts(0); pdf_dev_reset_color(0); + pdf_dev_reset_xgstate(0); return 0; } diff --git a/Build/source/texk/dvipdfm-x/tt_cmap.c b/Build/source/texk/dvipdfm-x/tt_cmap.c index cff28f2b690..3e9fea7274d 100644 --- a/Build/source/texk/dvipdfm-x/tt_cmap.c +++ b/Build/source/texk/dvipdfm-x/tt_cmap.c @@ -1,6 +1,6 @@ /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2002-2019 by Jin-Hwan Cho and Shunsaku Hirata, + Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team. This program is free software; you can redistribute it and/or modify @@ -1615,7 +1615,7 @@ otf_try_load_GID_to_CID_map (const char *map_name, int ttc_index, int wmode) /* Check if already loaded */ cmap_name = NEW(strlen(map_name)+strlen("-GID")+5, char); - sprintf(cmap_name, "%s:%3d-GID", map_name, ttc_index); + sprintf(cmap_name, "%s:%d-%d-GID", map_name, ttc_index, wmode); cmap_id = CMap_cache_find(cmap_name); if (cmap_id >= 0) { RELEASE(cmap_name); -- cgit v1.2.3