texlive[56121] Build/source/texk/dvipdfm-x: Fix various inconsistent

commits+kakuto at tug.org commits+kakuto at tug.org
Sun Aug 16 10:10:47 CEST 2020


Revision: 56121
          http://tug.org/svn/texlive?view=revision&revision=56121
Author:   kakuto
Date:     2020-08-16 10:10:47 +0200 (Sun, 16 Aug 2020)
Log Message:
-----------
Fix various inconsistent behaviors observed in pdf:bcontent/econtent
specials. Revise PSTricks clip support (S. Hirata)

Modified Paths:
--------------
    trunk/Build/source/texk/dvipdfm-x/ChangeLog
    trunk/Build/source/texk/dvipdfm-x/configure
    trunk/Build/source/texk/dvipdfm-x/configure.ac
    trunk/Build/source/texk/dvipdfm-x/dpxutil.c
    trunk/Build/source/texk/dvipdfm-x/dpxutil.h
    trunk/Build/source/texk/dvipdfm-x/dvi.c
    trunk/Build/source/texk/dvipdfm-x/dvi.h
    trunk/Build/source/texk/dvipdfm-x/epdf.c
    trunk/Build/source/texk/dvipdfm-x/epdf.h
    trunk/Build/source/texk/dvipdfm-x/mpost.c
    trunk/Build/source/texk/dvipdfm-x/mpost.h
    trunk/Build/source/texk/dvipdfm-x/pdfdev.c
    trunk/Build/source/texk/dvipdfm-x/pdfdev.h
    trunk/Build/source/texk/dvipdfm-x/pdfdoc.c
    trunk/Build/source/texk/dvipdfm-x/pdfdoc.h
    trunk/Build/source/texk/dvipdfm-x/pdfdraw.c
    trunk/Build/source/texk/dvipdfm-x/pdfdraw.h
    trunk/Build/source/texk/dvipdfm-x/spc_dvips.c
    trunk/Build/source/texk/dvipdfm-x/spc_dvips.h
    trunk/Build/source/texk/dvipdfm-x/spc_html.c
    trunk/Build/source/texk/dvipdfm-x/spc_html.h
    trunk/Build/source/texk/dvipdfm-x/spc_misc.c
    trunk/Build/source/texk/dvipdfm-x/spc_misc.h
    trunk/Build/source/texk/dvipdfm-x/spc_pdfm.c
    trunk/Build/source/texk/dvipdfm-x/spc_pdfm.h
    trunk/Build/source/texk/dvipdfm-x/spc_xtx.c
    trunk/Build/source/texk/dvipdfm-x/spc_xtx.h
    trunk/Build/source/texk/dvipdfm-x/specials.c
    trunk/Build/source/texk/dvipdfm-x/specials.h

Modified: trunk/Build/source/texk/dvipdfm-x/ChangeLog
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/ChangeLog	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/ChangeLog	2020-08-16 08:10:47 UTC (rev 56121)
@@ -1,3 +1,20 @@
+2020-08-16  Shunsaku Hirata  <shunsaku.hirata74 at gmail.com>
+
+	* dpxutil.[ch]: Add stack operation.
+	* epdf.[ch], pdfdraw.[ch]: Revise Clip path support for PSTricks.
+	Revert changes related to "rectadd" introduced in rev.31262
+	and rev.31302 which cause non-conforming behavior in "clip"
+	operatation.
+	* dvi.[c], mpost.c, pdfdev.[ch], pdfdoc.[ch], pdfdraw.[ch],
+	spc_html.c, spc_misc.c. spc_pdfm.c, spc_xtx.c, specials.[ch]:
+	Revise bcontent support. Try to resolve various inconsistent
+	behaviors when special commnads are used within pdf:bcontent
+	and pdf:econtent. dev_coords and pt_fixee are removed from pdf
+	module and moved to specials.c.
+	* mpost.h, spc_html.h, spc_misc.h, spc_pdfm.h, spc_xtx.h:
+	Update copyright years.
+	* configure.ac: Version 20200816.
+
 2020-08-08  Shunsaku Hirata  <shunsaku.hirata74 at gmail.com>
 
 	* fontmap.[ch], pdffont.[ch], tt_aux.[ch], tt_cmap.[ch]:

Modified: trunk/Build/source/texk/dvipdfm-x/configure
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/configure	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/configure	2020-08-16 08:10:47 UTC (rev 56121)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for dvipdfm-x (TeX Live) 20200726.
+# Generated by GNU Autoconf 2.69 for dvipdfm-x (TeX Live) 20200816.
 #
 # Report bugs to <dvipdfmx at tug.org>.
 #
@@ -590,8 +590,8 @@
 # Identity of this package.
 PACKAGE_NAME='dvipdfm-x (TeX Live)'
 PACKAGE_TARNAME='dvipdfm-x--tex-live-'
-PACKAGE_VERSION='20200726'
-PACKAGE_STRING='dvipdfm-x (TeX Live) 20200726'
+PACKAGE_VERSION='20200816'
+PACKAGE_STRING='dvipdfm-x (TeX Live) 20200816'
 PACKAGE_BUGREPORT='dvipdfmx at tug.org'
 PACKAGE_URL=''
 
@@ -1350,7 +1350,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures dvipdfm-x (TeX Live) 20200726 to adapt to many kinds of systems.
+\`configure' configures dvipdfm-x (TeX Live) 20200816 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1421,7 +1421,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of dvipdfm-x (TeX Live) 20200726:";;
+     short | recursive ) echo "Configuration of dvipdfm-x (TeX Live) 20200816:";;
    esac
   cat <<\_ACEOF
 
@@ -1551,7 +1551,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-dvipdfm-x (TeX Live) configure 20200726
+dvipdfm-x (TeX Live) configure 20200816
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2390,7 +2390,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by dvipdfm-x (TeX Live) $as_me 20200726, which was
+It was created by dvipdfm-x (TeX Live) $as_me 20200816, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -8077,7 +8077,7 @@
 
 # Define the identity of the package.
  PACKAGE='dvipdfm-x--tex-live-'
- VERSION='20200726'
+ VERSION='20200816'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -14746,7 +14746,7 @@
 Report bugs to <bug-libtool at gnu.org>."
 
 lt_cl_version="\
-dvipdfm-x (TeX Live) config.lt 20200726
+dvipdfm-x (TeX Live) config.lt 20200816
 configured by $0, generated by GNU Autoconf 2.69.
 
 Copyright (C) 2011 Free Software Foundation, Inc.
@@ -16636,7 +16636,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by dvipdfm-x (TeX Live) $as_me 20200726, which was
+This file was extended by dvipdfm-x (TeX Live) $as_me 20200816, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -16706,7 +16706,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-dvipdfm-x (TeX Live) config.status 20200726
+dvipdfm-x (TeX Live) config.status 20200816
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 

Modified: trunk/Build/source/texk/dvipdfm-x/configure.ac
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/configure.ac	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/configure.ac	2020-08-16 08:10:47 UTC (rev 56121)
@@ -8,7 +8,7 @@
 dnl   gives unlimited permission to copy and/or distribute it,
 dnl   with or without modifications, as long as this notice is preserved.
 dnl
-AC_INIT([dvipdfm-x (TeX Live)], [20200726], [dvipdfmx at tug.org])
+AC_INIT([dvipdfm-x (TeX Live)], [20200816], [dvipdfmx at tug.org])
 AC_PREREQ([2.65])
 AC_CONFIG_SRCDIR([agl.c])
 AC_CONFIG_AUX_DIR([../../build-aux])

Modified: trunk/Build/source/texk/dvipdfm-x/dpxutil.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/dpxutil.c	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/dpxutil.c	2020-08-16 08:10:47 UTC (rev 56121)
@@ -277,6 +277,123 @@
 }
 
 void
+dpx_stack_init (dpx_stack *stack)
+{
+  stack->size   = 0;
+  stack->top    = NULL;
+  stack->bottom = NULL;
+}
+
+void
+dpx_stack_push (dpx_stack *stack, void *data)
+{
+  stack_elem  *elem;
+
+  ASSERT(stack);
+
+  elem = NEW(1, stack_elem);
+  elem->prev = stack->top;
+  elem->data = data;
+
+  stack->top = elem;
+  if (stack->size == 0)
+    stack->bottom = elem;
+
+  stack->size++;
+
+  return;
+}
+
+void *
+dpx_stack_pop (dpx_stack *stack)
+{
+  stack_elem *elem;
+  void       *data;
+
+  ASSERT(stack);
+
+  if (stack->size == 0)
+    return NULL;
+
+  data = stack->top->data;
+  elem = stack->top;
+  stack->top = elem->prev;
+  if (stack->size == 1)
+    stack->bottom = NULL;
+  RELEASE(elem);
+
+  stack->size--;
+
+  return data;
+}
+
+void *
+dpx_stack_top (dpx_stack *stack)
+{
+  void  *data;
+
+  ASSERT(stack);
+
+  if (stack->size == 0)
+    return NULL;
+
+  data = stack->top->data;
+
+  return data;
+}
+
+void *
+dpx_stack_at (dpx_stack *stack, int pos)
+{
+  void       *data = NULL;
+  stack_elem *elem;
+
+  if (stack->size == 0)
+    return NULL;
+
+  elem = stack->top;
+  while (pos > 0) {
+    elem = elem->prev;
+    pos--;
+  }
+  if (elem)
+    data = elem->data;
+  
+  return data;
+}
+
+void
+dpx_stack_roll (dpx_stack *stack, int n, int j)
+{
+  if (n > stack->size)
+    return;
+  if (n == 1)
+    return;
+  j = j % n;
+  while (j-- > 0) {
+    int         m = n;
+    stack_elem *elem, *prev, *top;
+
+    elem = top = stack->top;
+    while (--m > 0) {
+      elem = elem->prev;
+    }
+    prev = elem->prev;
+    stack->top = top->prev;
+    elem->prev = top;
+    top->prev  = prev;
+  }
+}
+
+int
+dpx_stack_depth (dpx_stack *stack)
+{
+  ASSERT(stack);
+
+  return stack->size;
+}
+
+void
 ht_init_table (struct ht_table *ht, hval_free_func hval_free_fn)
 {
   int  i;

Modified: trunk/Build/source/texk/dvipdfm-x/dpxutil.h
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/dpxutil.h	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/dpxutil.h	2020-08-16 08:10:47 UTC (rev 56121)
@@ -58,6 +58,28 @@
 extern void skip_white_spaces (unsigned char **s, unsigned char *endptr);
 extern int  xtoi     (char c);
 
+typedef struct stack_elem
+{
+  void              *data;
+  struct stack_elem *prev;
+} stack_elem;
+
+typedef struct dpx_stack
+{
+  int         size;
+  stack_elem *top;
+  stack_elem *bottom;
+} dpx_stack;
+
+extern void       dpx_stack_init   (dpx_stack *st);
+extern void      *dpx_stack_pop    (dpx_stack *st);
+extern void       dpx_stack_push   (dpx_stack *st, void *data);
+extern int        dpx_stack_depth  (dpx_stack *st);
+extern void      *dpx_stack_top    (dpx_stack *st);
+extern void      *dpx_stack_at     (dpx_stack *st, int pos);
+extern void       dpx_stack_roll   (dpx_stack *st, int n, int j);
+
+
 #define HASH_TABLE_SIZE 503
 
 struct ht_entry {

Modified: trunk/Build/source/texk/dvipdfm-x/dvi.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/dvi.c	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/dvi.c	2020-08-16 08:10:47 UTC (rev 56121)
@@ -806,11 +806,62 @@
   catch_phantom  = 2;
 }
 
+/* All those things related to "compensation" is intruduced due to
+ * bcontent/econtent specials. They are originally implemented with
+ * modification to very important part of pdfdev functions such as
+ * pdf_dev_set_string(), and it made things very unclear.
+ *
+ * It is not good idea to modify the core part of PDF output routines
+ * just for implementing DVI "special" command. They do not make sense
+ * and just look odd when PDF output routines are separated from dvipdfmx.
+ */
+static struct spt_coord {
+  spt_t x, y;
+} compensation = { 0, 0 };
+
+void dvi_set_compensation (double x, double y)
+{
+  compensation.x = (spt_t) round(x / dvi2pts);
+  compensation.y = (spt_t) round(y / dvi2pts);
+}
+
+static void
+set_string (spt_t       xpos,
+            spt_t       ypos,
+            const void *instr_ptr,
+            int         instr_len,
+            spt_t       width,
+            int         font_id,
+            int         ctype)
+{
+  xpos -= compensation.x;
+  ypos -= compensation.y;
+  pdf_dev_set_string(xpos, ypos, instr_ptr, instr_len, width, font_id, ctype);
+}
+
+static void
+set_rule (spt_t xpos, spt_t ypos, spt_t width, spt_t height)
+{
+  xpos -= compensation.x;
+  ypos -= compensation.y;
+  pdf_dev_set_rule(xpos, ypos, width, height);
+}
+
+static void
+calc_rect (pdf_rect *r, spt_t xpos, spt_t ypos, spt_t width, spt_t height, spt_t depth)
+{
+  xpos -= compensation.x;
+  ypos -= compensation.y;
+  pdf_dev_set_rect(r, xpos, ypos, width, height, depth);
+}
+
 void
 dvi_do_special (const void *buffer, int32_t size)
 {
-  double x_user, y_user, mag;
+  double      x_user, y_user, mag;
   const char *p;
+  int         is_drawable = 0;
+  pdf_rect    rect = {0.0, 0.0, 0.0, 0.0};
 
   graphics_mode();
 
@@ -820,12 +871,17 @@
   y_user = -dvi_state.v * dvi2pts;
   mag    =  dvi_tell_mag();
 
-  if (spc_exec_special(p, size, x_user, y_user, mag) < 0) {
+  if (spc_exec_special(p, size, x_user, y_user, mag, &is_drawable, &rect) < 0) {
     if (dpx_conf.verbose_level > 0) {
       dump(p, p + size);
     }
+    return;
   }
 
+  if (dvi_is_tracking_boxes() && is_drawable) {
+    pdf_doc_expand_box(&rect);
+  }
+
   return;
 }
 
@@ -1174,7 +1230,7 @@
     default:
       width = dvi_state.h - save_h;
     }
-    pdf_dev_set_rect  (&rect, save_h, -save_v, width, height, depth);
+    calc_rect(&rect, save_h, -save_v, width, height, depth);
     pdf_doc_expand_box(&rect);
   }
 }
@@ -1235,23 +1291,19 @@
       wbuf[1] =  UTF32toUTF16HS(ch)       & 0xff;
       wbuf[2] = (UTF32toUTF16LS(ch) >> 8) & 0xff;
       wbuf[3] =  UTF32toUTF16LS(ch)       & 0xff;
-      pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 4,
-                         width, font->font_id, 2);
+      set_string(dvi_state.h, -dvi_state.v, wbuf, 4, width, font->font_id, 2);
     } else if (ch > 255) { /* _FIXME_ */
       wbuf[0] = (ch >> 8) & 0xff;
       wbuf[1] =  ch & 0xff;
-      pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2,
-                         width, font->font_id, 2);
+      set_string(dvi_state.h, -dvi_state.v, wbuf, 2, width, font->font_id, 2);
     } else if (font->subfont_id >= 0) {
       unsigned short uch = lookup_sfd_record(font->subfont_id, (unsigned char) ch);
       wbuf[0] = (uch >> 8) & 0xff;
       wbuf[1] =  uch & 0xff;
-      pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2,
-                         width, font->font_id, 2);
+      set_string(dvi_state.h, -dvi_state.v, wbuf, 2, width, font->font_id, 2);
     } else {
       wbuf[0] = (unsigned char) ch;
-      pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 1,
-                         width, font->font_id, 1);
+      set_string(dvi_state.h, -dvi_state.v, wbuf, 1, width, font->font_id, 1);
     }
     if (dvi_is_tracking_boxes()) {
       pdf_rect rect;
@@ -1261,8 +1313,7 @@
       height = sqxfw(font->size, height);
       depth  = sqxfw(font->size, depth);
 
-      pdf_dev_set_rect  (&rect, dvi_state.h, -dvi_state.v,
-                         width, height, depth);
+      calc_rect(&rect, dvi_state.h, -dvi_state.v, width, height, depth);
       pdf_doc_expand_box(&rect);
     }
     break;
@@ -1302,18 +1353,17 @@
     /* Treat a single character as a one byte string and use the
      * string routine.
      */
-    if (ch > 65535) { /* _FIXME_ */
+    if (ch > 65535) {
+      /* FIXME: This is a private extension made by someone... */
       wbuf[0] = (UTF32toUTF16HS(ch) >> 8) & 0xff;
       wbuf[1] =  UTF32toUTF16HS(ch)       & 0xff;
       wbuf[2] = (UTF32toUTF16LS(ch) >> 8) & 0xff;
       wbuf[3] =  UTF32toUTF16LS(ch)       & 0xff;
-      pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 4,
-                         width, font->font_id, 2);
+      set_string(dvi_state.h, -dvi_state.v, wbuf, 4, width, font->font_id, 2);
     } else if (ch > 255) { /* _FIXME_ */
       wbuf[0] = (ch >> 8) & 0xff;
       wbuf[1] =  ch & 0xff;
-      pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2,
-                         width, font->font_id, 2);
+      set_string(dvi_state.h, -dvi_state.v, wbuf, 2, width, font->font_id, 2);
     } else if (font->subfont_id >= 0) {
       unsigned int uch;
 
@@ -1320,12 +1370,10 @@
       uch = lookup_sfd_record(font->subfont_id, (unsigned char) ch);
       wbuf[0] = (uch >> 8) & 0xff;
       wbuf[1] =  uch & 0xff;
-      pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2,
-                         width, font->font_id, 2);
+      set_string(dvi_state.h, -dvi_state.v, wbuf, 2, width, font->font_id, 2);
     } else {
       wbuf[0] = (unsigned char) ch;
-      pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 1,
-                         width, font->font_id, 1);
+      set_string(dvi_state.h, -dvi_state.v, wbuf, 1, width, font->font_id, 1);
     }
     if (dvi_is_tracking_boxes()) {
       pdf_rect rect;
@@ -1335,8 +1383,7 @@
       height = sqxfw(font->size, height);
       depth  = sqxfw(font->size, depth);
 
-      pdf_dev_set_rect  (&rect, dvi_state.h, -dvi_state.v,
-                         width, height, depth);
+      calc_rect(&rect, dvi_state.h, -dvi_state.v, width, height, depth);
       pdf_doc_expand_box(&rect);
     }
     break;
@@ -1362,13 +1409,13 @@
 
     switch (dvi_state.d) {
     case 0:
-      pdf_dev_set_rule(dvi_state.h, -dvi_state.v,  width, height);
+      set_rule(dvi_state.h, -dvi_state.v,  width, height);
       break;
     case 1:
-      pdf_dev_set_rule(dvi_state.h, -dvi_state.v - width, height, width);
+      set_rule(dvi_state.h, -dvi_state.v - width, height, width);
       break;
     case 3: 
-      pdf_dev_set_rule(dvi_state.h - height, -dvi_state.v , height, width);
+      set_rule(dvi_state.h - height, -dvi_state.v , height, width);
       break;
     }
   }
@@ -1843,7 +1890,7 @@
         pdf_rect rect;
         height = (double)font->size * ascent / (double)font->unitsPerEm;
         depth  = (double)font->size * -descent / (double)font->unitsPerEm;
-        pdf_dev_set_rect(&rect, dvi_state.h + xloc[i], -dvi_state.v - yloc[i], glyph_width, height, depth);
+        calc_rect(&rect, dvi_state.h + xloc[i], -dvi_state.v - yloc[i], glyph_width, height, depth);
         pdf_doc_expand_box(&rect);
       }
     }
@@ -1850,8 +1897,7 @@
 
     wbuf[0] = glyph_id >> 8;
     wbuf[1] = glyph_id & 0xff;
-    pdf_dev_set_string(dvi_state.h + xloc[i], -dvi_state.v - yloc[i], wbuf, 2,
-                       glyph_width, font->font_id, -1);
+    set_string(dvi_state.h + xloc[i], -dvi_state.v - yloc[i], wbuf, 2, glyph_width, font->font_id, -1);
   }
 
   if (font->rgba_used == 1) {

Modified: trunk/Build/source/texk/dvipdfm-x/dvi.h
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/dvi.h	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/dvi.h	2020-08-16 08:10:47 UTC (rev 56121)
@@ -106,4 +106,6 @@
 /* allow other modules (pdfdev) to ask whether we're collecting box areas */
 extern int dvi_is_tracking_boxes(void);
 
+extern void  dvi_set_compensation (double x, double y);
+
 #endif /* _DVI_H_ */

Modified: trunk/Build/source/texk/dvipdfm-x/epdf.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/epdf.c	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/epdf.c	2020-08-16 08:10:47 UTC (rev 56121)
@@ -1,6 +1,6 @@
 /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
 
-    Copyright (C) 2007-2018 by Jin-Hwan Cho and Shunsaku Hirata,
+    Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
     the dvipdfmx project team.
     
     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks at kettering.edu>
@@ -217,84 +217,84 @@
   return -1;
 }
 
-typedef enum {
-  OP_SETCOLOR		= 1,
-  OP_CLOSEandCLIP	= 2,
-  OP_CLIP		= 3,
-  OP_CONCATMATRIX	= 4,
-  OP_SETCOLORSPACE	= 5,
-  OP_RECTANGLE		= 6,
-  OP_CURVETO		= 7,
-  OP_CLOSEPATH		= 8,
-  OP_LINETO		= 9,
-  OP_MOVETO		= 10,
-  OP_NOOP		= 11,
-  OP_GSAVE		= 12,
-  OP_GRESTORE		= 13,
-  OP_CURVETO1		= 14,
-  OP_CURVETO2		= 15,
-  OP_UNKNOWN		= 16
-} pdf_opcode;
+enum action {
+  action_unknown,
+  action_discard,
+  action_path,
+  action_rect,
+  action_trans,
+  action_clip,
+  action_save,
+  action_restore
+};
 
 static struct operator
 {
   const char *token;
-  int         opcode;
-} pdf_operators[] = {
-  {"SCN",	OP_SETCOLOR},
-  {"b*",	OP_CLOSEandCLIP},
-  {"B*",	OP_CLIP},
-  {"cm",	OP_CONCATMATRIX},
-  {"CS",	OP_SETCOLORSPACE},
-  {"f*",	0},
-  {"gs",	-1},
-  {"re",	OP_RECTANGLE},
-  {"rg",	-3},
-  {"RG",	-3},
-  {"sc",	OP_SETCOLOR},
-  {"SC",	OP_SETCOLOR},
-  {"W*",	OP_CLIP},
-  {"b",		OP_CLOSEandCLIP},
-  {"B",		OP_CLIP},
-  {"c",		OP_CURVETO},
-  {"d",		-2},
-  {"f",		0},
-  {"F",		0},
-  {"g",		-1},
-  {"G",		-1},
-  {"h",		OP_CLOSEPATH},
-  {"i",		-1},
-  {"j",		-1},
-  {"J",		-1},
-  {"k",		-4},
-  {"K",		-4},
-  {"l",		OP_LINETO},
-  {"m",		OP_MOVETO},
-  {"M",		-1},
-  {"n",		OP_NOOP},
-  {"q",		OP_GSAVE},
-  {"Q",		OP_GRESTORE},
-  {"s",		OP_CLOSEandCLIP},
-  {"S",		OP_CLIP},
-  {"v",		OP_CURVETO1},
-  {"w",		-1},
-  {"W",		OP_CLIP},
-  {"y",		OP_CURVETO2}
+  enum action action;
+  int         n_args;
+} operators[] = {
+  {"b*", action_clip, 0},
+  {"B*", action_clip, 0},
+  {"cm", action_trans, 6},
+  {"f*", action_clip, 0},
+  {"re", action_rect, 4},
+  {"W*", action_path, 0},
+  {"b",  action_clip, 0},
+  {"B",  action_clip, 0},
+  {"c",  action_path, 6},
+  {"f",  action_clip, 0},
+  {"F",  action_clip, 0},
+  {"h",  action_path, 0},
+  {"l",  action_path, 2},
+  {"m",  action_path, 2},
+  {"n",  action_path, 0},
+  {"q",  action_save, 0},
+  {"Q",  action_restore, 0},
+  {"s",  action_clip, 0},
+  {"S",  action_clip, 0},
+  {"v",  action_path, 4},
+  {"W",  action_path, 0},
+  {"y",  action_path, 4}
 };
 
+#include "dpxutil.h"
 
+static int
+get_numbers_from_stack (dpx_stack *stack, double *v, int n)
+{
+  int error = 0;
+  int i;
+
+  for (i = 0; i < n; i++) {
+    pdf_obj *obj;
+    obj = dpx_stack_pop(stack);
+    if (!obj) {
+      error = -1;
+      break;
+    } else if (!PDF_OBJ_NUMBERTYPE(obj)) {
+      pdf_release_obj(obj);
+      error = -1;
+      break;
+    }
+    v[n-i-1] = pdf_number_value(obj);
+    pdf_release_obj(obj);       
+  }
+  return error;
+}
+
 int
 pdf_copy_clip (FILE *image_file, int pageNo, double x_user, double y_user)
 {
   pdf_obj     *page_tree, *contents;
-  int          depth = 0, top = -1;
-  const char  *clip_path, *end_path;
-  char        *save_path, *temp;
+  int          depth = 0;
+  const char  *p, *endptr;
   pdf_tmatrix  M;
-  double       stack[6];
   pdf_rect     bbox;
   pdf_tmatrix  mtrx;
   pdf_file    *pf;
+  dpx_stack    stack;
+  int          error = 0;
   
   pf = pdf_open(NULL, image_file);
   if (!pf)
@@ -309,6 +309,7 @@
     pdf_close(pf);
     return -1;
   }
+
   contents = get_page_content(pf, page_tree);
   pdf_release_obj(page_tree);
   if (!contents) {
@@ -318,215 +319,200 @@
 
   pdf_doc_add_page_content(" ", 1);
 
-  save_path = NEW(pdf_stream_length(contents) + 1, char);
-  strncpy(save_path, (const char *) pdf_stream_dataptr(contents),  pdf_stream_length(contents));
-  clip_path = save_path;
-  end_path = clip_path + pdf_stream_length(contents);
-  depth = 0;
+  p      = pdf_stream_dataptr(contents);
+  endptr = p + pdf_stream_length(contents);
+  depth  = 0;
+  dpx_stack_init(&stack);
 
-  for (; clip_path < end_path; clip_path++) {
-    int color_dimen = 0;	/* silence uninitialized warning */
-    char *token;
-    skip_white(&clip_path, end_path);
-    if (clip_path == end_path)
-      break;
+  skip_white(&p, endptr);
+  while (p < endptr && !error) {
+    enum action  action = action_discard;
+    char        *token  = NULL;
+    pdf_obj     *obj    = NULL;
+    int          n_args = 0;
+    char         buf[1024];
+    size_t       len = 0;
+
     if (depth > 1) {
-      if (*clip_path == 'q')
+      if (*p == 'q')
         depth++;
-      if (*clip_path == 'Q')
-	depth--;
-      parse_ident(&clip_path, end_path);
+      if (*p == 'Q')
+        depth--;
+      token = parse_ident(&p, endptr);
+      skip_white(&p, endptr);
+      RELEASE(token);
       continue;
-    } else if (*clip_path == '-'
-	    || *clip_path == '+'
-	    || *clip_path == '.'
-	    || isdigit((unsigned char)*clip_path)) {
-      stack[++top] = strtod(clip_path, &temp);
-      clip_path = temp;
-    } else if (*clip_path == '[') {
-      /* Ignore, but put a dummy value on the stack (in case of d operator) */
-      parse_pdf_array(&clip_path, end_path, pf);
-      stack[++top] = 0;
-    } else if (*clip_path == '/') {
-      if  (strncmp("/DeviceGray",	clip_path, 11) == 0
-	|| strncmp("/Indexed",		clip_path, 8)  == 0
-	|| strncmp("/CalGray",		clip_path, 8)  == 0) {
-	color_dimen = 1;
-	continue;
+    }
+
+    switch (*p) {
+    case '-': case '+': case'.':
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
+      obj = parse_pdf_number(&p, endptr);
+      break;
+    case '[':
+      obj = parse_pdf_array(&p, endptr, NULL); /* No indirect reference allowed here */
+      break;
+    case '/':
+      obj = parse_pdf_name(&p, endptr);
+      break;
+    case '(':
+      obj = parse_pdf_string(&p, endptr);
+      break;
+    case '<':
+      if (p < endptr - 1 && p[1] == '<') {
+        obj = parse_pdf_dict(&p, endptr, NULL);
+      } else {
+        obj = parse_pdf_string(&p, endptr);
       }
-      else if  (strncmp("/DeviceRGB",	clip_path, 10) == 0
-	|| strncmp("/CalRGB",		clip_path, 7)  == 0
-	|| strncmp("/Lab",		clip_path, 4)  == 0) {
-	color_dimen = 3;
-	continue;
+      break;
+    }
+    if (obj) {
+      skip_white(&p, endptr);
+      dpx_stack_push(&stack, obj);
+      continue;
+    }
+
+    /* operator */
+    token = parse_ident(&p, endptr);
+    skip_white(&p, endptr);
+    if (!token) {
+      break;
+    } else {
+      int i;
+      for (i = 0; i < sizeof(operators) / sizeof(operators[0]); i++) {
+        if (!strcmp(token, operators[i].token)) {
+          action = operators[i].action;
+          n_args = operators[i].n_args;
+          break;
+        }
       }
-      else if  (strncmp("/DeviceCMYK",	clip_path, 11) == 0) {
-	color_dimen = 4;
-	continue;
+    }
+    switch (action) {
+    case action_rect:
+      {
+        double v[4];
+
+        error = get_numbers_from_stack(&stack, v, n_args); /* n_args = 4 */
+        if (!error) {
+          /* Not sure if this switch is required */
+          if (M.b == 0.0 && M.c == 0.0) {
+            /* Use "re" operator */
+            pdf_coord p0;
+            double    w, h;
+
+            p0.x = v[0]; p0.y = v[1];
+            w = M.a * v[2]; h = M.d * v[3];
+            pdf_dev_transform(&p0, &M);
+            buf[len++] = ' ';
+            len += pdf_sprint_coord(buf+len, &p0);
+            buf[len++] = ' ';
+            len += pdf_sprint_length(buf+len, w);
+            buf[len++] = ' ';
+            len += pdf_sprint_length(buf+len, h);
+            len += sprintf(buf+len, " re");
+          } else {
+            /* Converted to lineto */
+            pdf_coord p0, p1, p2, p3;
+            double    w, h;
+
+            w = v[2]; h = v[3];
+            p0.x = v[0]; p0.y = v[1];
+            p1.x = p0.x + w; p1.y = p0.y;
+            p2.x = p1.x; p2.y = p1.y + h;
+            p3.x = p0.x; p3.y = p2.y;
+            pdf_dev_transform(&p0, &M);
+            pdf_dev_transform(&p1, &M);
+            pdf_dev_transform(&p2, &M);
+            pdf_dev_transform(&p3, &M);
+            buf[len++] = ' ';
+            len += pdf_sprint_coord(buf+len, &p0);
+            len += sprintf(buf+len, " m");
+            buf[len++] = ' ';
+            len += pdf_sprint_coord(buf+len, &p1);
+            len += sprintf(buf+len, " l");
+            buf[len++] = ' ';
+            len += pdf_sprint_coord(buf+len, &p2);
+            len += sprintf(buf+len, " l");
+            buf[len++] = ' ';
+            len += pdf_sprint_coord(buf+len, &p3);
+            len += sprintf(buf+len, " l h");
+          }
+          pdf_doc_add_page_content(buf, len);
+        }
       }
-      else {
-        clip_path++;
-        parse_ident(&clip_path, end_path);
-	skip_white(&clip_path, end_path);
-	token = parse_ident(&clip_path, end_path);
-        if (strcmp(token, "gs") == 0) {
-	  continue;
-	}
-        return -1;
-      }
-    } else {
-      int j;
-      pdf_tmatrix T;
-      pdf_coord  p0, p1, p2, p3;
+      break;
+    case action_path:
+      {
+        double    v[6];
+        pdf_coord pt;
+        int       i;
 
-      token = parse_ident(&clip_path, end_path);
-      for (j = 0; j < sizeof(pdf_operators) / sizeof(pdf_operators[0]); j++)
-        if (strcmp(token, pdf_operators[j].token) == 0)
-	  break;
-      if (j == sizeof(pdf_operators) / sizeof(pdf_operators[0])) {
-        return -1;
+        error = get_numbers_from_stack(&stack, v, n_args);
+        if (!error) {
+          for (i = 0; i < n_args/2; i++) {
+            pt.x = v[2*i];
+            pt.y = v[2*i+1];
+            pdf_dev_transform(&pt, &M);
+            buf[len++] = ' ';
+            len += pdf_sprint_coord(buf+len, &pt);
+          }
+          len += sprintf(buf+len, " %s", token);
+          pdf_doc_add_page_content(buf, len);
+        }
       }
-      switch (pdf_operators[j].opcode) {
-	case  0:
-	case -1:
-	case -2:
-	case -3:
-	case -4:
-	  /* Just pop the stack and do nothing. */
-	  top += pdf_operators[j].opcode;
-	  if (top < -1)
-	    return -1;
-	  break;
-	case OP_SETCOLOR:
-	  top -= color_dimen;
-	  if (top < -1)
-	    return -1;
-	  break;
-	case OP_CLOSEandCLIP:
-	  pdf_dev_closepath();
-	case OP_CLIP:
-#if 0
-	  pdf_dev_clip();
-#else
-	  pdf_dev_flushpath('W', PDF_FILL_RULE_NONZERO);
-#endif
-	  break;
-	case OP_CONCATMATRIX:
-	  if (top < 5)
-	    return -1;
-	  T.f = stack[top--];
-	  T.e = stack[top--];
-	  T.d = stack[top--];
-	  T.c = stack[top--];
-	  T.b = stack[top--];
-	  T.a = stack[top--];
-	  pdf_concatmatrix(&M, &T);
-	  break;
-	case OP_SETCOLORSPACE:
-	  /* Do nothing. */
-	  break;
-	case OP_RECTANGLE:
-	  if (top < 3)
-	    return -1;
-	  p1.y = stack[top--];
-	  p1.x = stack[top--];
-	  p0.y = stack[top--];
-	  p0.x = stack[top--];
-	  if (M.b == 0 && M.c == 0) {
-	    pdf_tmatrix M0;
-	    M0.a = M.a; M0.b = M.b; M0.c = M.c; M0.d = M.d;
-	    M0.e = 0; M0.f = 0;
-	    pdf_dev_transform(&p0, &M);
-	    pdf_dev_transform(&p1, &M0);
-	    pdf_dev_rectadd(p0.x, p0.y, p1.x, p1.y);
-	  } else {
-	    p2.x = p0.x + p1.x; p2.y = p0.y + p1.y;
-	    p3.x = p0.x; p3.y = p0.y + p1.y;
-	    p1.x += p0.x; p1.y = p0.y;
-	    pdf_dev_transform(&p0, &M);
-	    pdf_dev_transform(&p1, &M);
-	    pdf_dev_transform(&p2, &M);
-	    pdf_dev_transform(&p3, &M);
-	    pdf_dev_moveto(p0.x, p0.y);
-	    pdf_dev_lineto(p1.x, p1.y);
-	    pdf_dev_lineto(p2.x, p2.y);
-	    pdf_dev_lineto(p3.x, p3.y);
-	    pdf_dev_closepath();
-	  }
-	  break;
-	case OP_CURVETO:
-	  if (top < 5)
-	    return -1;
-	  p0.y = stack[top--];
-	  p0.x = stack[top--];
-	  pdf_dev_transform(&p0, &M);
-	  p1.y = stack[top--];
-	  p1.x = stack[top--];
-	  pdf_dev_transform(&p1, &M);
-	  p2.y = stack[top--];
-	  p2.x = stack[top--];
-	  pdf_dev_transform(&p2, &M);
-	  pdf_dev_curveto(p2.x, p2.y, p1.x, p1.y, p0.x, p0.y);
-	  break;
-	case OP_CLOSEPATH:
-	  pdf_dev_closepath();
-	  break;
-	case OP_LINETO:
-	  if (top < 1)
-	    return -1;
-	  p0.y = stack[top--];
-	  p0.x = stack[top--];
-	  pdf_dev_transform(&p0, &M);
-	  pdf_dev_lineto(p0.x, p0.y);
-	  break;
-	case OP_MOVETO:
-	  if (top < 1)
-	    return -1;
-	  p0.y = stack[top--];
-	  p0.x = stack[top--];
-	  pdf_dev_transform(&p0, &M);
-	  pdf_dev_moveto(p0.x, p0.y);
-	  break;
-	case OP_NOOP:
-	  pdf_doc_add_page_content(" n", 2);
-	  break;
-	case OP_GSAVE:
-	  depth++;
-	  break;
-	case OP_GRESTORE:
-	  depth--;
-	  break;
-	case OP_CURVETO1:
-	  if (top < 3)
-	    return -1;
-	  p0.y = stack[top--];
-	  p0.x = stack[top--];
-	  pdf_dev_transform(&p0, &M);
-	  p1.y = stack[top--];
-	  p1.x = stack[top--];
-	  pdf_dev_transform(&p1, &M);
-	  pdf_dev_vcurveto(p1.x, p1.y, p0.x, p0.y);
-	  break;
-	case OP_CURVETO2:
-	  if (top < 3)
-	    return -1;
-	  p0.y = stack[top--];
-	  p0.x = stack[top--];
-	  pdf_dev_transform(&p0, &M);
-	  p1.y = stack[top--];
-	  p1.x = stack[top--];
-	  pdf_dev_transform(&p1, &M);
-	  pdf_dev_ycurveto(p1.x, p1.y, p0.x, p0.y);
-	  break;
-	default:
-	  return -1;
+      break;
+    case action_trans:
+      {
+        double      v[6];
+        pdf_tmatrix T;
+        error = get_numbers_from_stack(&stack, v, n_args);
+        if (!error) {
+          T.a = v[0]; T.b = v[1]; T.c = v[2]; T.d = v[3];
+          T.e = v[4]; T.f = v[5];
+          pdf_concatmatrix(&M, &T);
+        }
       }
+      break;
+    case action_clip:
+      if (token[0] >= 'a' && token[0] <= 'z') {
+        /* close path */
+        len += sprintf(buf+len, " h");
+      }
+      if (strlen(token) >= 2 && token[1] == '*') {
+        len += sprintf(buf+len, " W* n");
+      } else {
+        len += sprintf(buf+len, " W n");
+      }
+      pdf_doc_add_page_content(buf, len);
+      break;
+    case action_save:
+      depth++;
+      break;
+    case action_restore:
+      depth--;
+      break;
+    case action_discard:
+      /* stack clearing behavior */
+      while ((obj = dpx_stack_pop(&stack)) != NULL) {
+        pdf_release_obj(obj);
+      }
+      break;
+    case action_unknown:
+      error = -1;
+      break;
     }
+    RELEASE(token);
   }
-  RELEASE(save_path);
-
+  {
+    pdf_obj *obj;
+  
+    while ((obj = dpx_stack_pop(&stack)) != NULL) {
+      pdf_release_obj(obj);
+    }
+  }
   pdf_release_obj(contents);
   pdf_close(pf);
 
-  return 0;
+  return error;
 }

Modified: trunk/Build/source/texk/dvipdfm-x/epdf.h
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/epdf.h	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/epdf.h	2020-08-16 08:10:47 UTC (rev 56121)
@@ -1,6 +1,6 @@
 /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
 
-    Copyright (C) 2002-2016 by Jin-Hwan Cho and Shunsaku Hirata,
+    Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
     the dvipdfmx project team.
     
     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks at kettering.edu>

Modified: trunk/Build/source/texk/dvipdfm-x/mpost.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/mpost.c	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/mpost.c	2020-08-16 08:10:47 UTC (rev 56121)
@@ -1,6 +1,6 @@
 /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
 
-    Copyright (C) 2007-2018 by Jin-Hwan Cho and Shunsaku Hirata,
+    Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
     the dvipdfmx project team.
 
     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks at kettering.edu>
@@ -901,8 +901,7 @@
       fig_p.flags   |= INFO_HAS_USER_BBOX;
 
       sprintf(resname, "__tf%d__", count);
-      xobj_id = pdf_doc_begin_grabbing(resname,
-				       fig_p.bbox.llx, fig_p.bbox.ury, &fig_p.bbox);
+      xobj_id = pdf_doc_begin_grabbing(resname, fig_p.bbox.llx, fig_p.bbox.ury, &fig_p.bbox);
       
       in_tfig = 1;
       count++;
@@ -913,7 +912,7 @@
       ERROR("endTexFig without valid startTexFig!.");
 
     pdf_doc_end_grabbing(NULL);
-    pdf_dev_put_image(xobj_id, &fig_p, x_user, y_user);
+    pdf_dev_put_image(xobj_id, &fig_p, x_user, y_user, NULL); /* FIXME */
     in_tfig = 0;
     break;
   default:

Modified: trunk/Build/source/texk/dvipdfm-x/mpost.h
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/mpost.h	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/mpost.h	2020-08-16 08:10:47 UTC (rev 56121)
@@ -1,6 +1,6 @@
 /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
 
-    Copyright (C) 2002-2018 by Jin-Hwan Cho and Shunsaku Hirata,
+    Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
     the dvipdfmx project team.
     
     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks at kettering.edu>

Modified: trunk/Build/source/texk/dvipdfm-x/pdfdev.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/pdfdev.c	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/pdfdev.c	2020-08-16 08:10:47 UTC (rev 56121)
@@ -49,8 +49,6 @@
 
 #include "pdflimits.h"
 
-#include "dvi.h"
-
 #include "pdfdev.h"
 
 struct dev_param
@@ -259,13 +257,6 @@
   int               max_dev_fonts;
   int               num_phys_fonts;
   char              format_buffer[FORMAT_BUF_SIZE+1];
-
-  /* Just to support pdf:bcontent special...
-   * Text position adjustment inside the pdf:bcontent and pdf:econtent.
-   */
-  pdf_coord        *dev_coords;
-  int               num_dev_coords;
-  int               max_dev_coords;
 };
 
 /*
@@ -1116,11 +1107,6 @@
     }
   }
 
-  if (p->num_dev_coords > 0) {
-    xpos -= bpt2spt(p, p->dev_coords[p->num_dev_coords-1].x);
-    ypos -= bpt2spt(p, p->dev_coords[p->num_dev_coords-1].y);
-  }
-
   /*
    * Kern is in units of character units, i.e., 1000 = 1 em.
    *
@@ -1261,9 +1247,6 @@
 
   p->num_dev_fonts  = p->max_dev_fonts = 0;
   p->fonts          = NULL;
-  p->num_dev_coords = 0;
-  p->max_dev_coords = 0;
-  p->dev_coords     = NULL;
 
   return;
 }
@@ -1287,9 +1270,6 @@
     RELEASE(p->fonts);
     p->fonts = NULL;
   }
-  if (p->dev_coords)
-    RELEASE(p->dev_coords);
-  p->dev_coords = NULL;
   pdf_dev_clear_gstates();
 }
 
@@ -1569,11 +1549,6 @@
   int      len = 0;
   double   width_in_bp;
 
-  if (p->num_dev_coords > 0) {
-    xpos -= bpt2spt(p, p->dev_coords[p->num_dev_coords-1].x);
-    ypos -= bpt2spt(p, p->dev_coords[p->num_dev_coords-1].y);
-  }
-
   pdf_dev_graphics_mode(p);
 
   p->format_buffer[len++] = ' ';
@@ -1791,11 +1766,9 @@
 }
 
 
+/* rect returned */
 int
-pdf_dev_put_image (int             id,
-                   transform_info *ti,
-                   double          ref_x,
-                   double          ref_y)
+pdf_dev_put_image (int id, transform_info *ti, double ref_x, double ref_y, pdf_rect *rect)
 {
   pdf_dev     *p = current_device();
   char        *res_name;
@@ -1803,11 +1776,6 @@
   pdf_rect     r;
   int          len = 0;
 
-  if (p->num_dev_coords > 0) {
-    ref_x -= p->dev_coords[p->num_dev_coords-1].x;
-    ref_y -= p->dev_coords[p->num_dev_coords-1].y;
-  }
-
   pdf_copymatrix(&M, &(ti->matrix));
   M.e += ref_x; M.f += ref_y;
   /* Just rotate by -90, but not tested yet. Any problem if M has scaling? */
@@ -1839,7 +1807,17 @@
     dev_out(p, buf, len);  /* op: Do */
     RELEASE(buf);
   }
+  if (rect) {
+    pdf_rect  r1;
 
+    /* Sorry for ugly code. */
+    pdf_dev_set_rect(&r1,
+                     bpt2spt(p, r.llx), bpt2spt(p, r.lly),
+                     bpt2spt(p, r.urx - r.llx), bpt2spt(p, r.ury - r.lly), 0);
+    rect->llx = r1.llx; rect->lly = r1.lly;
+    rect->urx = r1.urx; rect->ury = r1.ury;
+  }
+
   pdf_dev_grestore();
 
   pdf_doc_add_page_resource("XObject",
@@ -1846,47 +1824,6 @@
                             res_name,
                             pdf_ximage_get_reference(id));
 
-  if (dvi_is_tracking_boxes()) {
-    pdf_tmatrix P;
-    int         i;
-    pdf_rect    rect;
-    pdf_coord   corner[4];
-
-    pdf_dev_set_rect(&rect, 65536 * ref_x, 65536 * ref_y,
-                     65536 * (r.urx - r.llx), 65536 * (r.ury - r.lly), 0);
-
-    corner[0].x = rect.llx; corner[0].y = rect.lly;
-    corner[1].x = rect.llx; corner[1].y = rect.ury;
-    corner[2].x = rect.urx; corner[2].y = rect.ury;
-    corner[3].x = rect.urx; corner[3].y = rect.lly;
-
-    pdf_copymatrix(&P, &(ti->matrix));
-    for (i = 0; i < 4; ++i) {
-      corner[i].x -= rect.llx;
-      corner[i].y -= rect.lly;
-      pdf_dev_transform(&(corner[i]), &P);
-      corner[i].x += rect.llx;
-      corner[i].y += rect.lly;
-    }
-
-    rect.llx = corner[0].x;
-    rect.lly = corner[0].y;
-    rect.urx = corner[0].x;
-    rect.ury = corner[0].y;
-    for (i = 0; i < 4; ++i) {
-      if (corner[i].x < rect.llx)
-        rect.llx = corner[i].x;
-      if (corner[i].x > rect.urx)
-        rect.urx = corner[i].x;
-      if (corner[i].y < rect.lly)
-        rect.lly = corner[i].y;
-      if (corner[i].y > rect.ury)
-        rect.ury = corner[i].y;
-    }
-
-    pdf_doc_expand_box(&rect);
-  }
-
   return 0;
 }
 
@@ -2028,40 +1965,3 @@
 
   return 0;
 }
-
-/* Saved text position compensation */
-void
-pdf_dev_get_coord (double *xpos, double *ypos)
-{
-  pdf_dev *p = current_device();
-
-  if (p->num_dev_coords > 0) {
-    *xpos = p->dev_coords[p->num_dev_coords-1].x;
-    *ypos = p->dev_coords[p->num_dev_coords-1].y;
-  } else {
-    *xpos = *ypos = 0.0;
-  }
-}
-
-void
-pdf_dev_push_coord (double xpos, double ypos)
-{
-  pdf_dev *p = current_device();
-
-  if (p->num_dev_coords >= p->max_dev_coords) {
-    p->max_dev_coords += 4;
-    p->dev_coords = RENEW(p->dev_coords, p->max_dev_coords, pdf_coord);
-  }
-  p->dev_coords[p->num_dev_coords].x = xpos;
-  p->dev_coords[p->num_dev_coords].y = ypos;
-  p->num_dev_coords++;
-}
-
-void
-pdf_dev_pop_coord (void)
-{
-  pdf_dev *p = current_device();
-
-  if (p->num_dev_coords > 0)
-    p->num_dev_coords--;
-}

Modified: trunk/Build/source/texk/dvipdfm-x/pdfdev.h
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/pdfdev.h	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/pdfdev.h	2020-08-16 08:10:47 UTC (rev 56121)
@@ -107,8 +107,8 @@
                                   spt_t text_width, int font_id, int ctype);
 extern void   pdf_dev_set_rule   (spt_t xpos, spt_t ypos, spt_t width, spt_t height);
 
-/* Place XObject */
-extern int    pdf_dev_put_image  (int xobj_id, transform_info *p, double ref_x, double ref_y);
+/* Place XObject: rect returned */
+extern int    pdf_dev_put_image  (int xobj_id, transform_info *p, double ref_x, double ref_y, pdf_rect *rect);
 
 /* The design_size and ptsize required by PK font support...
  */
@@ -171,10 +171,6 @@
  */
 extern void   graphics_mode (void);
 
-extern void   pdf_dev_get_coord  (double *xpos, double *ypos);
-extern void   pdf_dev_push_coord (double xpos, double ypos);
-extern void   pdf_dev_pop_coord  (void);
-
 extern void   pdf_dev_begin_actualtext (uint16_t *unicodes, int len);
 extern void   pdf_dev_end_actualtext   (void);
 

Modified: trunk/Build/source/texk/dvipdfm-x/pdfdoc.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/pdfdoc.c	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/pdfdoc.c	2020-08-16 08:10:47 UTC (rev 56121)
@@ -1,6 +1,6 @@
 /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
 
-    Copyright (C) 2008-2020 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata,
+    Copyright (C) 2002-2020 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata,
     the dvipdfmx project team.
     
     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks at kettering.edu>
@@ -1772,8 +1772,6 @@
   pdf_doc  *p = &pdoc;
   pdf_page *page;
   pdf_obj  *rect_array;
-  double    xpos, ypos;
-  pdf_rect  annbox;
 
   page = doc_get_page_entry(p, page_no);
   if (!page->annots)
@@ -1783,30 +1781,26 @@
     pdf_rect  mediabox;
 
     pdf_doc_get_mediabox(page_no, &mediabox);
-    pdf_dev_get_coord(&xpos, &ypos);
-    annbox.llx = rect->llx - xpos; annbox.lly = rect->lly - ypos;
-    annbox.urx = rect->urx - xpos; annbox.ury = rect->ury - ypos;
-
-    if (annbox.llx < mediabox.llx || annbox.urx > mediabox.urx ||
-        annbox.lly < mediabox.lly || annbox.ury > mediabox.ury) {
+    if (rect->llx < mediabox.llx || rect->urx > mediabox.urx ||
+        rect->lly < mediabox.lly || rect->ury > mediabox.ury) {
       WARN("Annotation out of page boundary.");
       WARN("Current page's MediaBox: [%g %g %g %g]",
            mediabox.llx, mediabox.lly, mediabox.urx, mediabox.ury);
       WARN("Annotation: [%g %g %g %g]",
-           annbox.llx, annbox.lly, annbox.urx, annbox.ury);
+           rect->llx, rect->lly, rect->urx, rect->ury);
       WARN("Maybe incorrect paper size specified.");
     }
-    if (annbox.llx > annbox.urx || annbox.lly > annbox.ury) {
+    if (rect->llx > rect->urx || rect->lly > rect->ury) {
       WARN("Rectangle with negative width/height: [%g %g %g %g]",
-           annbox.llx, annbox.lly, annbox.urx, annbox.ury);
+           rect->llx, rect->lly, rect->urx, rect->ury);
     }
   }
 
   rect_array = pdf_new_array();
-  pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.llx, 0.001)));
-  pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.lly, 0.001)));
-  pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.urx, 0.001)));
-  pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.ury, 0.001)));
+  pdf_add_array(rect_array, pdf_new_number(ROUND(rect->llx, 0.001)));
+  pdf_add_array(rect_array, pdf_new_number(ROUND(rect->lly, 0.001)));
+  pdf_add_array(rect_array, pdf_new_number(ROUND(rect->urx, 0.001)));
+  pdf_add_array(rect_array, pdf_new_number(ROUND(rect->ury, 0.001)));
   pdf_add_dict (annot_dict, pdf_new_name("Rect"), rect_array);
 
   pdf_add_array(page->annots, pdf_ref_obj(annot_dict));

Modified: trunk/Build/source/texk/dvipdfm-x/pdfdoc.h
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/pdfdoc.h	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/pdfdoc.h	2020-08-16 08:10:47 UTC (rev 56121)
@@ -1,6 +1,6 @@
 /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
 
-    Copyright (C) 2007-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+    Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
     the dvipdfmx project team.
     
     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks at kettering.edu>

Modified: trunk/Build/source/texk/dvipdfm-x/pdfdraw.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/pdfdraw.c	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/pdfdraw.c	2020-08-16 08:10:47 UTC (rev 56121)
@@ -710,7 +710,7 @@
  (c) == 'f' || (c) == 'F' || \
  (c) == 's' || (c) == 'S' || \
  (c) == 'b' || (c) == 'B' || \
- (c) == 'W' || (c) == ' ' \
+ (c) == 'W' \
 )
 
 static /* __inline__ */ int
@@ -727,8 +727,7 @@
 
 /* rectfill, rectstroke, rectclip, recteoclip
  *
- * Draw isolated rectangle without actually doing
- * gsave/grestore operation.
+ * Draw isolated rectangle without actually doing gsave/grestore operation.
  * 
  * TODO:
  *  linestyle, fill-opacity, stroke-opacity,....
@@ -751,7 +750,7 @@
 
   ASSERT(r && PT_OP_VALID(opchr));
 
-  isclip = (opchr == 'W' || opchr == ' ') ? 1 : 0;
+  isclip = (opchr == 'W') ? 1 : 0;
 
   /* disallow matrix for clipping.
    * q ... clip Q does nothing and
@@ -763,18 +762,13 @@
 
   graphics_mode();
 
-  buf[len++] = ' ';
   if (!isclip) {
-    buf[len++] = 'q';
-    if (M) {
-      buf[len++] = ' ';
-      len += pdf_sprint_matrix(buf + len, M);
-      buf[len++] = ' ';
-      buf[len++] = 'c'; buf[len++] = 'm';
-    }
-    buf[len++] = ' ';
+    pdf_dev_gsave();
   }
-  buf[len++] = 'n';
+  pdf_dev_newpath();
+  if (!isclip && M) {
+    pdf_dev_concat(M);
+  }
 
   p.x = r->llx; p.y = r->lly;
   wd  = r->urx - r->llx;
@@ -788,21 +782,20 @@
   buf[len++] = ' ';
   buf[len++] = 'r'; buf[len++] = 'e';
 
-  if (opchr != ' ') {
-    buf[len++] = ' ';
-    buf[len++] = opchr;
+  buf[len++] = ' ';
+  buf[len++] = opchr;
 
-    buf[len++] = ' ';
-    buf[len++] = isclip ? 'n' : 'Q';
+  pdf_doc_add_page_content(buf, len);
+
+  if (isclip) {
+    pdf_dev_newpath();
+  } else {
+    pdf_dev_grestore();
   }
 
-  pdf_doc_add_page_content(buf, len);  /* op: q cm n re Q */
-
   return 0;
 }
 
-static int path_added = 0;
-
 /* FIXME */
 static int
 pdf_dev__flushpath (pdf_path  *pa,
@@ -817,17 +810,13 @@
   pdf_coord *pt;
   int        n_pts, n_seg;
   int        len = 0;
-  int        isclip = 0;
   int        isrect, i, j;
 
   ASSERT(pa && PT_OP_VALID(opchr));
 
-  isclip = (opchr == 'W') ? 1 : 0;
-
-  if (PA_LENGTH(pa) <= 0 && path_added == 0)
+  if (PA_LENGTH(pa) <= 0)
     return 0;
 
-  path_added = 0;
   graphics_mode();
   isrect = pdf_path__isarect(pa, ignore_rule); 
   if (isrect) {
@@ -860,7 +849,7 @@
       b[len++] = PE_OPCHR(pe);
       if (len + 128 > b_len) {
         pdf_doc_add_page_content(b, len);  /* op: m l c v y h */
-	len = 0;
+        len = 0;
       }
     }
     if (len > 0) {
@@ -873,9 +862,6 @@
   b[len++] = opchr;
   if (rule == PDF_FILL_RULE_EVENODD)
     b[len++] = '*';
-  if (isclip) {
-    b[len++] = ' '; b[len++] = 'n';
-  }
 
   pdf_doc_add_page_content(b, len);  /* op: f F s S b B W f* F* s* S* b* B* W* */
 
@@ -882,95 +868,9 @@
   return 0;
 }
 
-/* Stack operation */
-typedef struct m_stack_elem
-{
-  void                *data;
-  struct m_stack_elem *prev;
-} m_stack_elem;
-
-typedef struct m_stack
-{
-  int           size;
-  m_stack_elem *top;
-  m_stack_elem *bottom;
-} m_stack;
-
-static void
-m_stack_init (m_stack *stack)
-{
-  ASSERT(stack);
-
-  stack->size   = 0;
-  stack->top    = NULL;
-  stack->bottom = NULL;
-
-  return;
-}
-
-static void
-m_stack_push (m_stack *stack, void *data)
-{
-  m_stack_elem  *elem;
-
-  ASSERT(stack);
-
-  elem = NEW(1, m_stack_elem);
-  elem->prev = stack->top;
-  elem->data = data;
-
-  stack->top = elem;
-  if (stack->size == 0)
-    stack->bottom = elem;
-
-  stack->size++;
-
-  return;
-}
-
-static void *
-m_stack_pop (m_stack *stack)
-{
-  m_stack_elem *elem;
-  void         *data;
-
-  ASSERT(stack);
-
-  if (stack->size == 0)
-    return NULL;
-
-  data = stack->top->data;
-  elem = stack->top;
-  stack->top = elem->prev;
-  if (stack->size == 1)
-    stack->bottom = NULL;
-  RELEASE(elem);
-
-  stack->size--;
-
-  return data;
-}
-
-static void *
-m_stack_top (m_stack *stack)
-{
-  void  *data;
-
-  ASSERT(stack);
-
-  if (stack->size == 0)
-    return NULL;
-
-  data = stack->top->data;
-
-  return data;
-}
-
-#define m_stack_depth(s)    ((s)->size)
-
 /* ExtGState stack */
-static m_stack xgs_stack;
-static int     xgs_count = 0;
+static dpx_stack xgs_stack;
+static int       xgs_count = 0;
 
 struct xgs_res {
   pdf_obj *object;
@@ -988,7 +888,7 @@
 static void
 init_xgstate (void)
 {
-  m_stack_init(&xgs_stack);
+  dpx_stack_init(&xgs_stack);
   xgs_count = 0;
 
   return;
@@ -999,7 +899,7 @@
 {
   struct xgs_res *xgs;
 
-  while ((xgs = m_stack_pop(&xgs_stack)) != NULL) {
+  while ((xgs = dpx_stack_pop(&xgs_stack)) != NULL) {
     pdf_release_obj(xgs->object);
     pdf_release_obj(xgs->accumlated);
     RELEASE(xgs);
@@ -1036,12 +936,11 @@
   /* internal */
   pdf_path  path;
   int       flags;
-  /* bookkeeping the origin of the last transform applied */
-  pdf_coord pt_fixee;
+
   pdf_obj  *extgstate;
 } pdf_gstate;
 
-static m_stack gs_stack;
+static dpx_stack gs_stack;
 
 static void
 init_a_gstate (pdf_gstate *gs)
@@ -1066,8 +965,6 @@
   /* Internal variables */
   gs->flags = 0;
   init_a_path(&gs->path);
-  gs->pt_fixee.x = 0;
-  gs->pt_fixee.y = 0;
 
   gs->extgstate  = NULL;
 
@@ -1118,8 +1015,6 @@
 
   pdf_color_copycolor(&gs1->fillcolor  , &gs2->fillcolor);
   pdf_color_copycolor(&gs1->strokecolor, &gs2->strokecolor);
-  gs1->pt_fixee.x = gs2->pt_fixee.x;
-  gs1->pt_fixee.y = gs2->pt_fixee.y;
 
   gs1->extgstate  = gs2->extgstate ? pdf_link_obj(gs2->extgstate) : NULL;
 
@@ -1129,8 +1024,8 @@
 static int
 pdf_dev_set_xgstate (pdf_obj *diff, pdf_obj *accumlated)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   char        buf[64], res_name[16];
   int         len = 0, id;
 
@@ -1151,14 +1046,14 @@
 int
 pdf_dev_reset_xgstate (int force)
 {
-  m_stack        *gss = &gs_stack;
+  dpx_stack      *gss = &gs_stack;
   pdf_gstate     *gs;
   pdf_obj        *current, *target, *keys, *diff;
   struct xgs_res *xgs;
   int             i, need_reset = 0;
 
-  gs  = m_stack_top(gss);
-  xgs = m_stack_top(&xgs_stack);
+  gs  = dpx_stack_top(gss);
+  xgs = dpx_stack_top(&xgs_stack);
   if (xgs) {
     target  = pdf_link_obj(xgs->accumlated);
   } else {
@@ -1212,7 +1107,7 @@
 
   target = NEW(1, struct xgs_res);
   target->object = object;
-  current = m_stack_top(&xgs_stack);
+  current = dpx_stack_top(&xgs_stack);
   if (!current) {
     const char *ptr, *endptr;
     ptr    = default_xgs;
@@ -1224,7 +1119,7 @@
   }
   pdf_merge_dict(accumlated, object);
   target->accumlated = accumlated;
-  m_stack_push(&xgs_stack, target);
+  dpx_stack_push(&xgs_stack, target);
 
   pdf_dev_set_xgstate(target->object, target->accumlated);
 
@@ -1238,8 +1133,8 @@
   pdf_obj        *accumlated, *revert, *keys;
   int             i;
 
-  current = m_stack_pop(&xgs_stack);
-  target  = m_stack_top(&xgs_stack); 
+  current = dpx_stack_pop(&xgs_stack);
+  target  = dpx_stack_top(&xgs_stack); 
   if (!current) {
     WARN("Too many pop operation for ExtGState!");
     return;
@@ -1281,12 +1176,12 @@
 {
   pdf_gstate *gs;
 
-  m_stack_init(&gs_stack);
+  dpx_stack_init(&gs_stack);
 
   gs = NEW(1, pdf_gstate);
   init_a_gstate(gs);
 
-  m_stack_push(&gs_stack, gs); /* Initial state */
+  dpx_stack_push(&gs_stack, gs); /* Initial state */
   init_xgstate();
 
   return;
@@ -1297,10 +1192,10 @@
 {
   pdf_gstate *gs;
 
-  if (m_stack_depth(&gs_stack) > 1) /* at least 1 elem. */
+  if (dpx_stack_depth(&gs_stack) > 1) /* at least 1 elem. */
     WARN("GS stack depth is not zero at the end of the document.");
 
-  while ((gs = m_stack_pop(&gs_stack)) != NULL) {
+  while ((gs = dpx_stack_pop(&gs_stack)) != NULL) {
     clear_a_gstate(gs);
     RELEASE(gs);
   }
@@ -1315,11 +1210,11 @@
 {
   pdf_gstate *gs0, *gs1;
 
-  gs0 = m_stack_top(&gs_stack);
+  gs0 = dpx_stack_top(&gs_stack);
   gs1 = NEW(1, pdf_gstate);
   init_a_gstate(gs1);
   copy_a_gstate(gs1, gs0);
-  m_stack_push(&gs_stack, gs1);
+  dpx_stack_push(&gs_stack, gs1);
 
   pdf_doc_add_page_content(" q", 2);  /* op: q */
 
@@ -1331,12 +1226,12 @@
 {
   pdf_gstate *gs;
 
-  if (m_stack_depth(&gs_stack) <= 1) { /* Initial state at bottom */
+  if (dpx_stack_depth(&gs_stack) <= 1) { /* Initial state at bottom */
     WARN("Too many grestores.");
     return  -1;
   }
 
-  gs = m_stack_pop(&gs_stack);
+  gs = dpx_stack_pop(&gs_stack);
   clear_a_gstate(gs);
   RELEASE(gs);
 
@@ -1351,7 +1246,7 @@
 int
 pdf_dev_push_gstate (void)
 {
-  m_stack    *gss = &gs_stack;
+  dpx_stack  *gss = &gs_stack;
   pdf_gstate *gs0;
 
   gs0 = NEW(1, pdf_gstate);
@@ -1358,7 +1253,7 @@
 
   init_a_gstate(gs0);
 
-  m_stack_push(gss, gs0);
+  dpx_stack_push(gss, gs0);
 
   return 0;
 }
@@ -1367,15 +1262,15 @@
 int
 pdf_dev_pop_gstate (void)
 {
-  m_stack    *gss = &gs_stack;
+  dpx_stack  *gss = &gs_stack;
   pdf_gstate *gs;
 
-  if (m_stack_depth(gss) <= 1) { /* Initial state at bottom */
+  if (dpx_stack_depth(gss) <= 1) { /* Initial state at bottom */
     WARN("Too many grestores.");
     return  -1;
   }
 
-  gs = m_stack_pop(gss);
+  gs = dpx_stack_pop(gss);
   clear_a_gstate(gs);
   RELEASE(gs);
 
@@ -1386,24 +1281,24 @@
 int
 pdf_dev_current_depth (void)
 {
-  return (m_stack_depth(&gs_stack) - 1); /* 0 means initial state */
+  return (dpx_stack_depth(&gs_stack) - 1); /* 0 means initial state */
 }
 
 void
 pdf_dev_grestore_to (int depth)
 {
-  m_stack    *gss = &gs_stack;
+  dpx_stack  *gss = &gs_stack;
   pdf_gstate *gs;
 
   ASSERT(depth >= 0);
 
-  if (m_stack_depth(gss) > depth + 1) {
+  if (dpx_stack_depth(gss) > depth + 1) {
     WARN("Closing pending transformations at end of page/XObject.");
   }
 
-  while (m_stack_depth(gss) > depth + 1) {
+  while (dpx_stack_depth(gss) > depth + 1) {
     pdf_doc_add_page_content(" Q", 2);  /* op: Q */
-    gs = m_stack_pop(gss);
+    gs = dpx_stack_pop(gss);
     clear_a_gstate(gs);
     RELEASE(gs);
   }
@@ -1415,8 +1310,8 @@
 int
 pdf_dev_currentpoint (pdf_coord *p)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   pdf_coord  *cpt = &gs->cp;
 
   ASSERT(p);
@@ -1429,8 +1324,8 @@
 int
 pdf_dev_currentmatrix (pdf_tmatrix *M)
 {
-  m_stack     *gss = &gs_stack;
-  pdf_gstate  *gs  = m_stack_top(gss);
+  dpx_stack   *gss = &gs_stack;
+  pdf_gstate  *gs  = dpx_stack_top(gss);
   pdf_tmatrix *CTM = &gs->matrix;
 
   ASSERT(M);
@@ -1444,8 +1339,8 @@
 int
 pdf_dev_currentcolor (pdf_color *color, int is_fill)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   pdf_color  *fcl = &gs->fillcolor;
   pdf_color  *scl = &gs->strokecolor;
 
@@ -1469,7 +1364,7 @@
 {
   int len;
 
-  pdf_gstate *gs  = m_stack_top(&gs_stack);
+  pdf_gstate *gs  = dpx_stack_top(&gs_stack);
   pdf_color *current = mask ? &gs->fillcolor : &gs->strokecolor;
 
   if (!(pdf_dev_get_param(PDF_DEV_PARAM_COLORMODE) &&
@@ -1488,8 +1383,8 @@
 int
 pdf_dev_concat (const pdf_tmatrix *M)
 {
-  m_stack     *gss = &gs_stack;
-  pdf_gstate  *gs  = m_stack_top(gss);
+  dpx_stack   *gss = &gs_stack;
+  pdf_gstate  *gs  = dpx_stack_top(gss);
   pdf_path    *cpa = &gs->path;
   pdf_coord   *cpt = &gs->cp;
   pdf_tmatrix *CTM = &gs->matrix;
@@ -1542,8 +1437,8 @@
 int
 pdf_dev_setmiterlimit (double mlimit)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   int         len = 0;
   char       *buf = fmt_buf;
 
@@ -1562,8 +1457,8 @@
 int
 pdf_dev_setlinecap (int capstyle)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   int         len = 0;
   char       *buf = fmt_buf;
 
@@ -1579,8 +1474,8 @@
 int
 pdf_dev_setlinejoin (int joinstyle)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   int         len = 0;
   char       *buf = fmt_buf;
 
@@ -1596,8 +1491,8 @@
 int
 pdf_dev_setlinewidth (double width)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);  
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);  
   int         len = 0;
   char       *buf = fmt_buf;
 
@@ -1616,8 +1511,8 @@
 int
 pdf_dev_setdash (int count, double *pattern, double offset)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   int         len = 0;
   char       *buf = fmt_buf;
   int         i;
@@ -1643,8 +1538,8 @@
 int
 pdf_dev_setflat (int flatness)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   int         len = 0;
   char       *buf = fmt_buf;
 
@@ -1665,8 +1560,8 @@
 int
 pdf_dev_clip (void)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   pdf_path   *cpa = &gs->path;
 
   return pdf_dev__flushpath(cpa, 'W', PDF_FILL_RULE_NONZERO, 0);
@@ -1675,8 +1570,8 @@
 int
 pdf_dev_eoclip (void)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   pdf_path   *cpa = &gs->path;
 
   return pdf_dev__flushpath(cpa, 'W', PDF_FILL_RULE_EVENODD, 0);
@@ -1685,8 +1580,8 @@
 int
 pdf_dev_flushpath (char p_op, int fill_rule)
 {
-  m_stack    *gss   = &gs_stack;
-  pdf_gstate *gs    = m_stack_top(gss);
+  dpx_stack  *gss   = &gs_stack;
+  pdf_gstate *gs    = dpx_stack_top(gss);
   pdf_path   *cpa   = &gs->path;
   int         error = 0;
 
@@ -1705,8 +1600,8 @@
 int
 pdf_dev_newpath (void)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   pdf_path   *p   = &gs->path;
 
   if (PA_LENGTH(p) > 0) {
@@ -1721,8 +1616,8 @@
 int
 pdf_dev_moveto (double x, double y)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   pdf_path   *cpa = &gs->path;
   pdf_coord  *cpt = &gs->cp;
   pdf_coord   p;
@@ -1734,8 +1629,8 @@
 int
 pdf_dev_rmoveto (double x, double y)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   pdf_path   *cpa = &gs->path;
   pdf_coord  *cpt = &gs->cp;
   pdf_coord   p;
@@ -1748,8 +1643,8 @@
 int
 pdf_dev_lineto (double x, double y)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   pdf_path   *cpa = &gs->path;
   pdf_coord  *cpt = &gs->cp;
   pdf_coord   p0;
@@ -1762,8 +1657,8 @@
 int
 pdf_dev_rlineto (double x, double y)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   pdf_path   *cpa = &gs->path;
   pdf_coord  *cpt = &gs->cp;
   pdf_coord   p0;
@@ -1778,8 +1673,8 @@
                  double x1, double y1,
                  double x2, double y2)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   pdf_path   *cpa = &gs->path;
   pdf_coord  *cpt = &gs->cp;
   pdf_coord   p0, p1, p2;
@@ -1792,44 +1687,12 @@
 }
 
 int
-pdf_dev_vcurveto (double x0, double y0,
-                  double x1, double y1)
-{
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
-  pdf_path   *cpa = &gs->path;
-  pdf_coord  *cpt = &gs->cp;
-  pdf_coord   p0, p1;
-
-  p0.x = x0; p0.y = y0;
-  p1.x = x1; p1.y = y1;
-
-  return pdf_path__curveto(cpa, cpt, cpt, &p0, &p1);
-}
-
-int
-pdf_dev_ycurveto (double x0, double y0,
-                  double x1, double y1)
-{
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
-  pdf_path   *cpa = &gs->path;
-  pdf_coord  *cpt = &gs->cp;
-  pdf_coord   p0, p1;
-
-  p0.x = x0; p0.y = y0;
-  p1.x = x1; p1.y = y1;
-
-  return pdf_path__curveto(cpa, cpt, &p0, &p1, &p1);
-}
-
-int
 pdf_dev_rcurveto (double x0, double y0,
                   double x1, double y1,
                   double x2, double y2)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   pdf_path   *cpa = &gs->path;
   pdf_coord  *cpt = &gs->cp;
   pdf_coord   p0, p1, p2;
@@ -1845,8 +1708,8 @@
 int
 pdf_dev_closepath (void)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   pdf_coord  *cpt = &gs->cp;
   pdf_path   *cpa = &gs->path;
 
@@ -1857,8 +1720,8 @@
 void
 pdf_dev_dtransform (pdf_coord *p, const pdf_tmatrix *M)
 {
-  m_stack     *gss = &gs_stack;
-  pdf_gstate  *gs  = m_stack_top(gss);
+  dpx_stack   *gss = &gs_stack;
+  pdf_gstate  *gs  = dpx_stack_top(gss);
   pdf_tmatrix *CTM = &gs->matrix;
 
   ASSERT(p);
@@ -1871,8 +1734,8 @@
 void
 pdf_dev_idtransform (pdf_coord *p, const pdf_tmatrix *M)
 {
-  m_stack     *gss = &gs_stack;
-  pdf_gstate  *gs  = m_stack_top(gss);
+  dpx_stack   *gss = &gs_stack;
+  pdf_gstate  *gs  = dpx_stack_top(gss);
   pdf_tmatrix *CTM = &gs->matrix;
 
   ASSERT(p);
@@ -1885,8 +1748,8 @@
 void
 pdf_dev_transform (pdf_coord *p, const pdf_tmatrix *M)
 {
-  m_stack     *gss = &gs_stack;
-  pdf_gstate  *gs  = m_stack_top(gss);
+  dpx_stack   *gss = &gs_stack;
+  pdf_gstate  *gs  = dpx_stack_top(gss);
   pdf_tmatrix *CTM = &gs->matrix;
 
   ASSERT(p);
@@ -1900,8 +1763,8 @@
 void
 pdf_dev_itransform (pdf_coord *p, const pdf_tmatrix *M)
 {
-  m_stack     *gss = &gs_stack;
-  pdf_gstate  *gs  = m_stack_top(gss);
+  dpx_stack   *gss = &gs_stack;
+  pdf_gstate  *gs  = dpx_stack_top(gss);
   pdf_tmatrix *CTM = &gs->matrix;
 
   ASSERT(p);
@@ -1916,8 +1779,8 @@
 pdf_dev_arc  (double c_x , double c_y, double r,
               double a_0 , double a_1)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   pdf_path   *cpa = &gs->path;
   pdf_coord  *cpt = &gs->cp;
   pdf_coord   c;
@@ -1932,8 +1795,8 @@
 pdf_dev_arcn (double c_x , double c_y, double r,
               double a_0 , double a_1)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   pdf_path   *cpa = &gs->path;
   pdf_coord  *cpt = &gs->cp;
   pdf_coord   c;
@@ -1950,8 +1813,8 @@
               int    a_d ,
               double xar)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   pdf_path   *cpa = &gs->path;
   pdf_coord  *cpt = &gs->cp;
   pdf_coord   c;
@@ -1966,8 +1829,8 @@
 pdf_dev_bspline (double x0, double y0,
                  double x1, double y1, double x2, double y2)
 {
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
+  dpx_stack  *gss = &gs_stack;
+  pdf_gstate *gs  = dpx_stack_top(gss);
   pdf_path   *cpa = &gs->path;
   pdf_coord  *cpt = &gs->cp;  
   pdf_coord   p1, p2, p3;
@@ -1982,7 +1845,6 @@
   return  pdf_path__curveto(cpa, cpt, &p1, &p2, &p3);
 }
 
-#if 0
 int
 pdf_dev_rectstroke (double x, double y,
                     double w, double h,
@@ -1998,7 +1860,6 @@
 
   return  pdf_dev__rectshape(&r, M, 'S');
 }
-#endif
 
 int
 pdf_dev_rectfill  (double x, double y,
@@ -2027,36 +1888,3 @@
   
   return  pdf_dev__rectshape(&r, NULL, 'W');
 }
-
-int
-pdf_dev_rectadd (double x, double y,
-                  double w, double h)
-{
-  pdf_rect r;
-
-  r.llx = x;
-  r.lly = y;
-  r.urx = x + w;
-  r.ury = y + h;
-  path_added = 1;
-
-  return  pdf_dev__rectshape(&r, NULL, ' ');
-}
-
-void
-pdf_dev_set_fixed_point (double x, double y)
-{
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
-  gs->pt_fixee.x = x;
-  gs->pt_fixee.y = y;
-}
-
-void
-pdf_dev_get_fixed_point (pdf_coord *p)
-{
-  m_stack    *gss = &gs_stack;
-  pdf_gstate *gs  = m_stack_top(gss);
-  p->x = gs->pt_fixee.x;
-  p->y = gs->pt_fixee.y;
-}

Modified: trunk/Build/source/texk/dvipdfm-x/pdfdraw.h
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/pdfdraw.h	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/pdfdraw.h	2020-08-16 08:10:47 UTC (rev 56121)
@@ -83,10 +83,6 @@
 extern int    pdf_dev_curveto       (double x0 , double y0,
                                      double x1 , double y1,
                                      double x2 , double y2);
-extern int    pdf_dev_vcurveto      (double x0 , double y0,
-                                     double x1 , double y1);
-extern int    pdf_dev_ycurveto      (double x0 , double y0,
-                                     double x1 , double y1);
 extern int    pdf_dev_rcurveto      (double x0 , double y0,
                                      double x1 , double y1,
                                      double x2 , double y2);
@@ -104,16 +100,13 @@
 extern int    pdf_dev_clip          (void);
 extern int    pdf_dev_eoclip        (void);
 
-#if 0
+
 extern int    pdf_dev_rectstroke    (double x, double y,
                                      double w, double h,
                                      const pdf_tmatrix *M  /* optional */
                                     );
-#endif
-
 extern int    pdf_dev_rectfill      (double x, double y, double w, double h);
 extern int    pdf_dev_rectclip      (double x, double y, double w, double h);
-extern int    pdf_dev_rectadd       (double x, double y, double w, double h);
  
 extern int    pdf_dev_flushpath     (char p_op, int fill_rule);
 

Modified: trunk/Build/source/texk/dvipdfm-x/spc_dvips.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/spc_dvips.c	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/spc_dvips.c	2020-08-16 08:10:47 UTC (rev 56121)
@@ -172,7 +172,7 @@
   }
   RELEASE(filename);
 
-  pdf_dev_put_image(form_id, &ti, spe->x_user, spe->y_user);
+  spc_put_image(spe, form_id, &ti, spe->x_user, spe->y_user);
 
   return  0;
 }
@@ -211,7 +211,7 @@
 		      block_pending ? pending_x : spe->x_user,
 		      block_pending ? pending_y : spe->y_user);
 #endif
-    pdf_dev_put_image(form_id, &p, 0, 0);
+    spc_put_image(spe, form_id, &p, 0, 0);
   }
   RELEASE(filename);
 
@@ -221,22 +221,22 @@
 static int
 spc_handler_ps_literal (struct spc_env *spe, struct spc_arg *args)
 {
-  int     error = 0;
-  int     st_depth, gs_depth;
-  double  x_user, y_user;
+  int       error = 0;
+  int       st_depth, gs_depth;
+  double    x_user, y_user;
+  pdf_coord cp;
 
-  ASSERT(spe && args && args->curptr <= args->endptr);
-
+  spc_get_current_point(spe, &cp);
   if (args->curptr + strlen(":[begin]") <= args->endptr &&
       !strncmp(args->curptr, ":[begin]", strlen(":[begin]"))) {
     block_pending++;
     position_set = 1;
 
-    x_user = pending_x = spe->x_user;
-    y_user = pending_y = spe->y_user;
+    x_user = pending_x = cp.x;
+    y_user = pending_y = cp.y;
     args->curptr += strlen(":[begin]");
   } else if (args->curptr + strlen(":[end]") <= args->endptr &&
-	     !strncmp(args->curptr, ":[end]", strlen(":[end]"))) {
+             !strncmp(args->curptr, ":[end]", strlen(":[end]"))) {
     if (block_pending <= 0) {
       spc_warn(spe, "No corresponding ::[begin] found.");
       return -1;
@@ -248,15 +248,14 @@
     x_user = pending_x;
     y_user = pending_y;
     args->curptr += strlen(":[end]");
-  } else if (args->curptr < args->endptr &&
-	     args->curptr[0] == ':') {
-    x_user = position_set ? pending_x : spe->x_user;
-    y_user = position_set ? pending_y : spe->y_user;
+  } else if (args->curptr < args->endptr && args->curptr[0] == ':') {
+    x_user = position_set ? pending_x : cp.x;
+    y_user = position_set ? pending_y : cp.y;
     args->curptr++;
   } else {
     position_set = 1;
-    x_user = pending_x = spe->x_user;
-    y_user = pending_y = spe->y_user;
+    x_user = pending_x = cp.x;
+    y_user = pending_y = cp.y;
   }
 
   skip_white(&args->curptr, args->endptr);
@@ -265,9 +264,7 @@
     st_depth = mps_stack_depth();
     gs_depth = pdf_dev_current_depth();
 
-    error = mps_exec_inline(&args->curptr,
-			    args->endptr,
-			    x_user, y_user);
+    error = mps_exec_inline(&args->curptr, args->endptr, x_user, y_user);
     if (error) {
       spc_warn(spe, "Interpreting PS code failed!!! Output might be broken!!!");
       pdf_dev_grestore_to(gs_depth);
@@ -313,7 +310,7 @@
   pdf_coord pt;
 
   pdf_dev_currentmatrix(&M);
-  pdf_dev_get_fixed_point(&pt);
+  spc_get_fixed_point(spe, &pt.x, &pt.y);
   T.e = pt.x;
   T.f = pt.y;
   pdf_concatmatrix(&M, &T);
@@ -456,10 +453,10 @@
     return -1;
   RAngles[RAngleCount] = value;
 
-  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);
+  return  spc_handler_xtx_do_transform (spe, 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);
 }
 
 static int
@@ -467,10 +464,10 @@
 {
   double value = RAngles[RAngleCount--];
 
-  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);
+  return  spc_handler_xtx_do_transform (spe, 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);
 }
 
 static int
@@ -495,7 +492,7 @@
       return -1;
     if (spc_handler_xtx_gsave (0, 0) != 0)
       return -1;
-    return spc_handler_xtx_do_transform (spe->x_user, spe->y_user, d1, d2, d3, d4, d5, d6);
+    return spc_handler_xtx_do_transform (spe, spe->x_user, spe->y_user, d1, d2, d3, d4, d5, d6);
   }
   return  spc_handler_xtx_grestore (0, 0);
 }
@@ -717,7 +714,7 @@
       RELEASE(gs_out);
       return  -1;
     }
-    pdf_dev_put_image(form_id, &p, 0, 0);
+    spc_put_image(spe, form_id, &p, 0, 0);
 
     dpx_delete_temp_file(gs_out, true);
     dpx_delete_temp_file(gs_in, true);
@@ -843,12 +840,13 @@
 
   {
     pdf_tmatrix M;
-    M.a = M.d = 1.0; M.b = M.c = 0.0; M.e = spe->x_user; M.f = spe->y_user;
+    pdf_coord   cp;
+
+    spc_get_current_point(spe, &cp);
+    M.a = M.d = 1.0; M.b = M.c = 0.0; M.e = cp.x; M.f = cp.y;
     pdf_dev_concat(&M);
-  error = mps_exec_inline(&args->curptr,
-			  args->endptr,
-			  spe->x_user, spe->y_user);
-    M.e = -spe->x_user; M.f = -spe->y_user;
+    error = mps_exec_inline(&args->curptr, args->endptr, cp.x, cp.y);
+    M.e = -cp.x; M.f = -cp.y;
     pdf_dev_concat(&M);
   }
   if (error)

Modified: trunk/Build/source/texk/dvipdfm-x/spc_dvips.h
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/spc_dvips.h	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/spc_dvips.h	2020-08-16 08:10:47 UTC (rev 56121)
@@ -1,6 +1,6 @@
 /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
 
-    Copyright (C) 2002-2016 by Jin-Hwan Cho and Shunsaku Hirata,
+    Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
     the dvipdfmx project team.
     
     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks at kettering.edu>

Modified: trunk/Build/source/texk/dvipdfm-x/spc_html.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/spc_html.c	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/spc_html.c	2020-08-16 08:10:47 UTC (rev 56121)
@@ -534,43 +534,16 @@
 #ifdef  ENABLE_HTML_SVG_OPACITY
 /* Replicated from spc_tpic */
 static pdf_obj *
-create_xgstate (double a /* alpha */, int f_ais /* alpha is shape */)
+create_xgstate (double a)
 {
   pdf_obj  *dict;
 
   dict = pdf_new_dict();
-  pdf_add_dict(dict,
-               pdf_new_name("Type"),
-               pdf_new_name("ExtGState"));
-  if (f_ais) {
-    pdf_add_dict(dict,
-                 pdf_new_name("AIS"),
-                 pdf_new_boolean(1));
-  }
-  pdf_add_dict(dict,
-               pdf_new_name("ca"),
-               pdf_new_number(a));
+  pdf_add_dict(dict, pdf_new_name("Type"), pdf_new_name("ExtGState"));
+  pdf_add_dict(dict, pdf_new_name("ca"), pdf_new_number(a));
 
   return  dict;
 }
-
-static int
-check_resourcestatus (const char *category, const char *resname)
-{
-  pdf_obj  *dict1, *dict2;
-
-  dict1 = pdf_doc_current_page_resources();
-  if (!dict1)
-    return  0;
-
-  dict2 = pdf_lookup_dict(dict1, category);
-  if (dict2 &&
-      pdf_obj_typeof(dict2) == PDF_DICT) {
-    if (pdf_lookup_dict(dict2, resname))
-      return  1;
-  }
-  return  0;
-}
 #endif /* ENABLE_HTML_SVG_OPACITY */
 
 static int
@@ -583,12 +556,7 @@
 #ifdef  ENABLE_HTML_SVG_OPACITY
   double         alpha = 1.0; /* meaning fully opaque */
 #endif /* ENABLE_HTML_SVG_OPACITY */
-#ifdef  ENABLE_HTML_SVG_TRANSFORM
-  pdf_tmatrix    M, M1;
 
-  pdf_setmatrix(&M, 1.0, 0.0, 0.0, 1.0, spe->x_user, spe->y_user);
-#endif /* ENABLE_HTML_SVG_TRANSFORM */
-
   spc_warn(spe, "html \"img\" tag found (not completed, plese don't use!).");
 
   src = pdf_lookup_dict(attr, "src");
@@ -631,7 +599,7 @@
       error = cvt_a_to_tmatrix(&N, p, &p);
       if (!error) {
         N.f = -N.f;
-        pdf_concatmatrix(&M, &N);
+        pdf_concatmatrix(&ti.matrix, &N);
         for ( ; *p && isspace((unsigned char)*p); p++);
         if (*p == ',')
           for (++p; *p && isspace((unsigned char)*p); p++);
@@ -650,56 +618,19 @@
     spc_warn(spe, "Could not find/load image: %s", pdf_string_value(src)); 
     error = -1;
   } else {
-#if defined(ENABLE_HTML_SVG_TRANSFORM) || defined(ENABLE_HTML_SVG_OPACITY)
-    {
-      char     *res_name;
-      pdf_rect  r;
-
-      graphics_mode();
-
-      pdf_dev_gsave();
-
-#ifdef  ENABLE_HTML_SVG_OPACITY
-      {
-        pdf_obj *dict;
-        int      a = round(100.0 * alpha);
-        if (a != 0) {
-          res_name = NEW(strlen("_Tps_a100_") + 1, char);
-          sprintf(res_name, "_Tps_a%03d_", a); /* Not Tps prefix but... */
-          if (!check_resourcestatus("ExtGState", res_name)) {
-            dict = create_xgstate(round_at(0.01 * a, 0.01), 0);
-            pdf_doc_add_page_resource("ExtGState",
-                                      res_name, pdf_ref_obj(dict));
-            pdf_release_obj(dict);
-          }
-          pdf_doc_add_page_content(" /", 2);  /* op: */
-          pdf_doc_add_page_content(res_name, strlen(res_name));  /* op: */
-          pdf_doc_add_page_content(" gs", 3);  /* op: gs */
-          RELEASE(res_name);
-        }
-      }
-#endif /* ENABLE_HTML_SVG_OPACITY */
-
-      pdf_ximage_scale_image(id, &M1, &r, &ti);
-      pdf_concatmatrix(&M, &M1);
-      pdf_dev_concat(&M);
-
-      pdf_dev_rectclip(r.llx, r.lly, r.urx - r.llx, r.ury - r.lly);
-
-      res_name = pdf_ximage_get_resname(id);
-      pdf_doc_add_page_content(" /", 2);  /* op: */
-      pdf_doc_add_page_content(res_name, strlen(res_name));  /* op: */
-      pdf_doc_add_page_content(" Do", 3);  /* op: Do */
-
-      pdf_dev_grestore();
-
-      pdf_doc_add_page_resource("XObject",
-                                res_name,
-                                pdf_ximage_get_reference(id));
+#ifdef ENABLE_HTML_SVG_OPACITY
+    if (alpha != 0.0) {
+      pdf_obj *dict;
+      dict = create_xgstate(alpha);
+      pdf_dev_xgstate_push(dict);
     }
-#else
-    pdf_dev_put_image(id, &ti, spe->x_user, spe->y_user);
-#endif /* ENABLE_HTML_SVG_XXX */
+#endif
+    spc_put_image(spe, id, &ti, spe->x_user, spe->y_user);
+#ifdef ENABLE_HTML_SVG_OPACITY
+    if (alpha != 0.0) {
+      pdf_dev_xgstate_pop();
+    }
+#endif
   }
 
   return  error;

Modified: trunk/Build/source/texk/dvipdfm-x/spc_html.h
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/spc_html.h	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/spc_html.h	2020-08-16 08:10:47 UTC (rev 56121)
@@ -1,6 +1,6 @@
 /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
 
-    Copyright (C) 2002-2016 by Jin-Hwan Cho and Shunsaku Hirata,
+    Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
     the dvipdfmx project team.
     
     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks at kettering.edu>

Modified: trunk/Build/source/texk/dvipdfm-x/spc_misc.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/spc_misc.c	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/spc_misc.c	2020-08-16 08:10:47 UTC (rev 56121)
@@ -116,7 +116,7 @@
     return  -1;
   }
 
-  pdf_dev_put_image(form_id, &ti, spe->x_user, spe->y_user);
+  spc_put_image(spe, form_id, &ti, spe->x_user, spe->y_user);
 
   return  0;
 }

Modified: trunk/Build/source/texk/dvipdfm-x/spc_misc.h
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/spc_misc.h	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/spc_misc.h	2020-08-16 08:10:47 UTC (rev 56121)
@@ -1,6 +1,6 @@
 /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
 
-    Copyright (C) 2002-2016 by Jin-Hwan Cho and Shunsaku Hirata,
+    Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
     the dvipdfmx project team.
     
     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks at kettering.edu>

Modified: trunk/Build/source/texk/dvipdfm-x/spc_pdfm.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/spc_pdfm.c	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/spc_pdfm.c	2020-08-16 08:10:47 UTC (rev 56121)
@@ -1,6 +1,6 @@
 /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
 
-    Copyright (C) 2007-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+    Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
     the dvipdfmx project team.
     
     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks at kettering.edu>
@@ -669,8 +669,35 @@
 }
 
 static void
-set_rect (pdf_rect *rect, pdf_coord cp1, pdf_coord cp2, pdf_coord cp3, pdf_coord cp4)
+set_rect_for_annot (struct spc_env *spe, pdf_rect *rect, transform_info ti)
 {
+  pdf_coord cp, cp1, cp2, cp3, cp4;
+
+  spc_get_current_point(spe, &cp);
+
+  if (ti.flags & INFO_HAS_USER_BBOX) {
+    cp1.x = cp.x + ti.bbox.llx;
+    cp1.y = cp.y + ti.bbox.lly;
+    cp2.x = cp.x + ti.bbox.urx;
+    cp2.y = cp.y + ti.bbox.lly;
+    cp3.x = cp.x + ti.bbox.urx;
+    cp3.y = cp.y + ti.bbox.ury;
+    cp4.x = cp.x + ti.bbox.llx;
+    cp4.y = cp.y + ti.bbox.ury;
+  } else {
+    cp1.x = cp.x;
+    cp1.y = cp.y - spe->mag * ti.depth;
+    cp2.x = cp.x + spe->mag * ti.width;
+    cp2.y = cp.y - spe->mag * ti.depth;
+    cp3.x = cp.x + spe->mag * ti.width;
+    cp3.y = cp.y + spe->mag * ti.height;
+    cp4.x = cp.x;
+    cp4.y = cp.y + spe->mag * ti.height;
+  }
+  pdf_dev_transform(&cp1, NULL);
+  pdf_dev_transform(&cp2, NULL);
+  pdf_dev_transform(&cp3, NULL);
+  pdf_dev_transform(&cp4, NULL);
   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);
@@ -721,78 +748,16 @@
     return  -1;
   }
 
-#ifdef SPC_PDFM_SUPPORT_ANNOT_TRANS
-  {
-    pdf_coord cp1, cp2, cp3, cp4;
-    /* QuadPoints not working? */
-#ifdef USE_QUADPOINTS
-    pdf_obj  *qpoints;
-#endif
-    if (ti.flags & INFO_HAS_USER_BBOX) {
-      cp1.x = spe->x_user + ti.bbox.llx;
-      cp1.y = spe->y_user + ti.bbox.lly;
-      cp2.x = spe->x_user + ti.bbox.urx;
-      cp2.y = spe->y_user + ti.bbox.lly;
-      cp3.x = spe->x_user + ti.bbox.urx;
-      cp3.y = spe->y_user + ti.bbox.ury;
-      cp4.x = spe->x_user + ti.bbox.llx;
-      cp4.y = spe->y_user + ti.bbox.ury;
-    } else {
-      cp1.x = spe->x_user;
-      cp1.y = spe->y_user - spe->mag * ti.depth;
-      cp2.x = spe->x_user + spe->mag * ti.width;
-      cp2.y = spe->y_user - spe->mag * ti.depth;
-      cp3.x = spe->x_user + spe->mag * ti.width;
-      cp3.y = spe->y_user + spe->mag * ti.height;
-      cp4.x = spe->x_user;
-      cp4.y = spe->y_user + spe->mag * ti.height;
-    }
-    pdf_dev_transform(&cp1, NULL);
-    pdf_dev_transform(&cp2, NULL);
-    pdf_dev_transform(&cp3, NULL);
-    pdf_dev_transform(&cp4, NULL);    
-    set_rect(&rect, cp1, cp2, cp3, cp4);
-#ifdef USE_QUADPOINTS
-    qpoints = pdf_new_array();
-    pdf_add_array(qpoints, pdf_new_number(ROUND(cp1.x, 0.01)));
-    pdf_add_array(qpoints, pdf_new_number(ROUND(cp1.y, 0.01)));
-    pdf_add_array(qpoints, pdf_new_number(ROUND(cp2.x, 0.01)));
-    pdf_add_array(qpoints, pdf_new_number(ROUND(cp2.y, 0.01)));
-    pdf_add_array(qpoints, pdf_new_number(ROUND(cp3.x, 0.01)));
-    pdf_add_array(qpoints, pdf_new_number(ROUND(cp3.y, 0.01)));
-    pdf_add_array(qpoints, pdf_new_number(ROUND(cp4.x, 0.01)));
-    pdf_add_array(qpoints, pdf_new_number(ROUND(cp4.y, 0.01)));
-    pdf_add_dict(annot_dict, pdf_new_name("QuadPoints"), qpoints);
-#endif    
-  }
-#else
-  {
-    pdf_coord cp;
+  set_rect_for_annot(spe, &rect, ti);
 
-    cp.x = spe->x_user; cp.y = spe->y_user;
-    pdf_dev_transform(&cp, NULL);
-    if (ti.flags & INFO_HAS_USER_BBOX) {
-      rect.llx = ti.bbox.llx + cp.x;
-      rect.lly = ti.bbox.lly + cp.y;
-      rect.urx = ti.bbox.urx + cp.x;
-      rect.ury = ti.bbox.ury + cp.y;
-    } else {
-      rect.llx = cp.x;
-      rect.lly = cp.y - spe->mag * ti.depth;
-      rect.urx = cp.x + spe->mag * ti.width;
-      rect.ury = cp.y + spe->mag * ti.height;
-    }
-  }
-#endif
-
   /* Order is important... */
   if (ident)
-    spc_push_object(ident, pdf_link_obj(annot_dict));
+    spc_push_object(spe, ident, pdf_link_obj(annot_dict));
   /* Add this reference. */
   pdf_doc_add_annot(pdf_doc_current_page_number(), &rect, annot_dict, 1);
 
   if (ident) {
-    spc_flush_object(ident);
+    spc_flush_object(spe, ident);
     RELEASE(ident);
   }
   pdf_release_obj(annot_dict);
@@ -839,7 +804,7 @@
 
   error = spc_begin_annot(spe, pdf_link_obj(sd->annot_dict));
   if (ident) {
-    spc_push_object(ident, pdf_link_obj(sd->annot_dict));
+    spc_push_object(spe, ident, pdf_link_obj(sd->annot_dict));
     RELEASE(ident);
   }
 
@@ -903,54 +868,7 @@
     return  -1;
   }
 
-#ifdef SPC_PDFM_SUPPORT_ANNOT_TRANS
-  {
-    pdf_coord cp1, cp2, cp3, cp4;
-
-    if (ti.flags & INFO_HAS_USER_BBOX) {
-      cp1.x = spe->x_user + ti.bbox.llx;
-      cp1.y = spe->y_user + ti.bbox.lly;
-      cp2.x = spe->x_user + ti.bbox.urx;
-      cp2.y = spe->y_user + ti.bbox.lly;
-      cp3.x = spe->x_user + ti.bbox.urx;
-      cp3.y = spe->y_user + ti.bbox.ury;
-      cp4.x = spe->x_user + ti.bbox.llx;
-      cp4.y = spe->y_user + ti.bbox.ury;
-    } else {
-      cp1.x = spe->x_user;
-      cp1.y = spe->y_user - spe->mag * ti.depth;
-      cp2.x = spe->x_user + spe->mag * ti.width;
-      cp2.y = spe->y_user - spe->mag * ti.depth;
-      cp3.x = spe->x_user + spe->mag * ti.width;
-      cp3.y = spe->y_user + spe->mag * ti.height;
-      cp4.x = spe->x_user;
-      cp4.y = spe->y_user + spe->mag * ti.height;
-    }
-    pdf_dev_transform(&cp1, NULL);
-    pdf_dev_transform(&cp2, NULL);
-    pdf_dev_transform(&cp3, NULL);
-    pdf_dev_transform(&cp4, NULL);    
-    set_rect(&rect, cp1, cp2, cp3, cp4);
-  }
-#else
-  {
-    pdf_coord cp;
-
-    cp.x = spe->x_user; cp.y = spe->y_user;
-    pdf_dev_transform(&cp, NULL);
-    if (ti.flags & INFO_HAS_USER_BBOX) {
-      rect.llx = ti.bbox.llx + cp.x;
-      rect.lly = ti.bbox.lly + cp.y;
-      rect.urx = ti.bbox.urx + cp.x;
-      rect.ury = ti.bbox.ury + cp.y;
-    } else {
-      rect.llx = cp.x;
-      rect.lly = cp.y - spe->mag * ti.depth;
-      rect.urx = cp.x + spe->mag * ti.width;
-      rect.ury = cp.y + spe->mag * ti.height;
-    }
-  }
-#endif
+  set_rect_for_annot(spe, &rect, ti);
   pdf_doc_expand_box(&rect);
 
   return 0;
@@ -1024,7 +942,7 @@
 spc_handler_pdfm_btrans (struct spc_env *spe, struct spc_arg *args)
 {
   pdf_tmatrix     M;
-  double          x_user, y_user, xpos, ypos;
+  pdf_coord       cp;
   transform_info  ti;
 
   transform_info_clear(&ti);
@@ -1035,13 +953,11 @@
   /* btrans inside bcontent-econtent bug fix.
    * I don't know if this is the only place needs to be fixed...
    */
-  pdf_dev_get_coord(&xpos, &ypos);
-  x_user = spe->x_user - xpos;
-  y_user = spe->y_user - ypos;
+  spc_get_current_point(spe, &cp);
   /* Create transformation matrix */
   pdf_copymatrix(&M, &(ti.matrix));
-  M.e += ((1.0 - M.a) * x_user - M.c * y_user);
-  M.f += ((1.0 - M.d) * y_user - M.b * x_user);
+  M.e += ((1.0 - M.a) * cp.x - M.c * cp.y);
+  M.f += ((1.0 - M.d) * cp.y - M.b * cp.x);
 
   pdf_dev_gsave();
   pdf_dev_concat(&M);
@@ -1165,7 +1081,7 @@
   }
 
   pdf_doc_begin_article(ident, pdf_link_obj(info_dict));
-  spc_push_object(ident, info_dict);
+  spc_push_object(spe, ident, info_dict);
   RELEASE(ident);
 
   return 0;
@@ -1181,7 +1097,6 @@
   pdf_rect         rect;
   int              page_no;
   transform_info   ti;
-  pdf_coord        cp;
 
   skip_white(&args->curptr, args->endptr);
 
@@ -1210,20 +1125,6 @@
     return -1;
   }
 
-  cp.x = spe->x_user; cp.y = spe->y_user;
-  pdf_dev_transform(&cp, NULL);
-  if (ti.flags & INFO_HAS_USER_BBOX) {
-    rect.llx = ti.bbox.llx + cp.x;
-    rect.lly = ti.bbox.lly + cp.y;
-    rect.urx = ti.bbox.urx + cp.x;
-    rect.ury = ti.bbox.ury + cp.y;
-  } else {
-    rect.llx = cp.x;
-    rect.lly = cp.y - spe->mag * ti.depth;
-    rect.urx = cp.x + spe->mag * ti.width;
-    rect.ury = cp.y + spe->mag * ti.height;
-  }
-
   skip_white(&args->curptr, args->endptr);
   if (args->curptr[0] != '<') {
     article_info = pdf_new_dict();
@@ -1243,9 +1144,10 @@
     pdf_release_obj(article_info);
   } else {
     pdf_doc_begin_article(article_name, pdf_link_obj(article_info));
-    spc_push_object(article_name, article_info);
+    spc_push_object(spe, article_name, article_info);
   }
   page_no = pdf_doc_current_page_number();
+  set_rect_for_annot(spe, &rect, ti);
   pdf_doc_add_bead(article_name, NULL, page_no, &rect);
 
   RELEASE(article_name);
@@ -1311,8 +1213,9 @@
     return  -1;
   }
 
-  if (!(ti.flags & INFO_DO_HIDE))
-    pdf_dev_put_image(xobj_id, &ti, spe->x_user, spe->y_user);
+  if (!(ti.flags & INFO_DO_HIDE)) {
+    spc_put_image(spe, xobj_id, &ti, spe->x_user, spe->y_user);
+  }
 
   if (ident) {
     if ((dpx_conf.compat_mode == dpx_mode_compat_mode) &&
@@ -1503,11 +1406,11 @@
   skip_white(&args->curptr, args->endptr);
   ident = parse_opt_ident(&args->curptr, args->endptr);
   if (ident) {
-    spc_flush_object(ident);
+    spc_flush_object(spe, ident);
     RELEASE(ident);
   } else { /* Close all? */
     spc_warn(spe, "pdf:close without an argument no longer supported!");
-    spc_clear_objects();
+    spc_clear_objects(spe);
   }
 
   return 0;
@@ -1532,7 +1435,7 @@
     RELEASE(ident);
     return  -1;
   } else {
-    spc_push_object(ident, object);
+    spc_push_object(spe, ident, object);
   }
   RELEASE(ident);
 
@@ -1547,8 +1450,10 @@
   skip_white(&args->curptr, args->endptr);
   if (args->curptr < args->endptr) {
     pdf_tmatrix M;
+    pdf_coord   cp;
 
-    pdf_setmatrix(&M, 1.0, 0.0, 0.0, 1.0, spe->x_user, spe->y_user);
+    spc_get_current_point(spe, &cp);
+    pdf_setmatrix(&M, 1.0, 0.0, 0.0, 1.0, cp.x, cp.y);
     work_buffer[len++] = ' ';
     work_buffer[len++] = 'q';
     work_buffer[len++] = ' ';
@@ -1591,15 +1496,18 @@
 
   if (args->curptr < args->endptr) {
     pdf_tmatrix M;
+    pdf_coord   cp;
+
+    spc_get_current_point(spe, &cp);
     if (!direct) {
       M.a = M.d = 1.0; M.b = M.c = 0.0;
-      M.e = spe->x_user; M.f = spe->y_user;
+      M.e = cp.x; M.f = cp.y;
       pdf_dev_concat(&M);
     }
     pdf_doc_add_page_content(" ", 1);  /* op: */
     pdf_doc_add_page_content(args->curptr, (int) (args->endptr - args->curptr));  /* op: ANY */
     if (!direct) {
-      M.e = -spe->x_user; M.f = -spe->y_user;
+      M.e = -cp.x; M.f = -cp.y;
       pdf_dev_concat(&M);
     }
   }
@@ -1613,13 +1521,14 @@
 spc_handler_pdfm_bcontent (struct spc_env *spe, struct spc_arg *args)
 {
   pdf_tmatrix M;
-  double xpos, ypos;
+  double      xpos, ypos;
 
   pdf_dev_gsave();
-  pdf_dev_get_coord(&xpos, &ypos);
+  spc_get_coord(spe, &xpos, &ypos);
   pdf_setmatrix(&M, 1.0, 0.0, 0.0, 1.0, spe->x_user - xpos, spe->y_user - ypos);
   pdf_dev_concat(&M);
-  pdf_dev_push_coord(spe->x_user, spe->y_user);
+  spc_push_coord(spe, spe->x_user, spe->y_user);
+
   return 0;
 }
 
@@ -1626,7 +1535,7 @@
 static int
 spc_handler_pdfm_econtent (struct spc_env *spe, struct spc_arg *args)
 {
-  pdf_dev_pop_coord();
+  spc_pop_coord(spe);
   pdf_dev_grestore();
   pdf_dev_reset_color(0);
   pdf_dev_reset_xgstate(0);
@@ -1767,7 +1676,7 @@
   }
 
   /* Users should explicitly close this. */
-  spc_push_object(ident, fstream);
+  spc_push_object(spe, ident, fstream);
   RELEASE(ident);
 
   return 0;
@@ -1817,6 +1726,7 @@
   int             xobj_id;
   char           *ident;
   pdf_rect        cropbox;
+  pdf_coord       cp;
   transform_info  ti;
 
   skip_white(&args->curptr, args->endptr);
@@ -1862,7 +1772,8 @@
     cropbox.ury = ti.height;
   }
 
-  xobj_id = pdf_doc_begin_grabbing(ident, spe->x_user, spe->y_user, &cropbox);
+  spc_get_current_point(spe, &cp);
+  xobj_id = pdf_doc_begin_grabbing(ident, cp.x, cp.y, &cropbox);
 
   if (xobj_id < 0) {
     RELEASE(ident);
@@ -1952,7 +1863,7 @@
     xobj_id = pdf_ximage_reserve(ident);
   }
 
-  pdf_dev_put_image(xobj_id, &ti, spe->x_user, spe->y_user);
+  spc_put_image(spe, xobj_id, &ti, spe->x_user, spe->y_user);
   RELEASE(ident);
 
   return 0;

Modified: trunk/Build/source/texk/dvipdfm-x/spc_pdfm.h
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/spc_pdfm.h	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/spc_pdfm.h	2020-08-16 08:10:47 UTC (rev 56121)
@@ -1,6 +1,6 @@
 /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
 
-    Copyright (C) 2002-2018 by Jin-Hwan Cho and Shunsaku Hirata,
+    Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
     the dvipdfmx project team.
     
     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks at kettering.edu>

Modified: trunk/Build/source/texk/dvipdfm-x/spc_xtx.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/spc_xtx.c	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/spc_xtx.c	2020-08-16 08:10:47 UTC (rev 56121)
@@ -60,7 +60,7 @@
 
 
 int
-spc_handler_xtx_do_transform (double x_user, double y_user, double a, double b, double c, double d, double e, double f)
+spc_handler_xtx_do_transform (struct spc_env *spe, double x_user, double y_user, double a, double b, double c, double d, double e, double f)
 {
   pdf_tmatrix     M = { 0, 0, 0, 0, 0, 0 };
   pdf_coord       pt;
@@ -74,8 +74,8 @@
   M.f = ((1.0 - M.d) * y_user - M.b * x_user) + f;
 
   pdf_dev_concat(&M);
-  pdf_dev_get_fixed_point(&pt);
-  pdf_dev_set_fixed_point(x_user - pt.x, y_user - pt.y);
+  spc_get_fixed_point(spe, &pt.x, &pt.y);
+  spc_set_fixed_point(spe, x_user - pt.x, y_user - pt.y);
 
   return  0;
 }
@@ -90,7 +90,7 @@
   }
   args->curptr = args->endptr;
 
-  return spc_handler_xtx_do_transform(spe->x_user, spe->y_user, values[0], 0, 0, values[1], 0, 0);
+  return spc_handler_xtx_do_transform(spe, spe->x_user, spe->y_user, values[0], 0, 0, values[1], 0, 0);
 }
 
 /* Scaling without gsave/grestore. */
@@ -114,7 +114,7 @@
   scaleFactors[scaleFactorCount].y = 1 / values[1];
   args->curptr = args->endptr;
 
-  return  spc_handler_xtx_do_transform (spe->x_user, spe->y_user, values[0], 0, 0, values[1], 0, 0);
+  return  spc_handler_xtx_do_transform (spe, spe->x_user, spe->y_user, values[0], 0, 0, values[1], 0, 0);
 }
 
 static int
@@ -124,7 +124,7 @@
 
   args->curptr = args->endptr;
 
-  return  spc_handler_xtx_do_transform (spe->x_user, spe->y_user, factor.x, 0, 0, factor.y, 0, 0);
+  return  spc_handler_xtx_do_transform (spe, spe->x_user, spe->y_user, factor.x, 0, 0, factor.y, 0, 0);
 }
 
 static int
@@ -137,7 +137,7 @@
   }
   args->curptr = args->endptr;
 
-  return  spc_handler_xtx_do_transform (spe->x_user, spe->y_user,
+  return  spc_handler_xtx_do_transform (spe, 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);
@@ -147,6 +147,7 @@
 spc_handler_xtx_gsave (struct spc_env *spe, struct spc_arg *args)
 {
   pdf_dev_gsave();
+  spc_dup_fixed_point(spe);
 
   return  0;
 }
@@ -155,6 +156,7 @@
 spc_handler_xtx_grestore (struct spc_env *spe, struct spc_arg *args)
 {
   pdf_dev_grestore();
+  spc_pop_fixed_point(spe);
 
   /*
    * Unfortunately, the following line is necessary in case

Modified: trunk/Build/source/texk/dvipdfm-x/spc_xtx.h
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/spc_xtx.h	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/spc_xtx.h	2020-08-16 08:10:47 UTC (rev 56121)
@@ -1,7 +1,7 @@
 /*  This is xdvipdfmx, an extended version of dvipdfmx,
     an eXtended version of dvipdfm by Mark A. Wicks.
 
-    Copyright (C) 2013-2016 by the dvipdfmx project team.
+    Copyright (C) 2013-2020 by the dvipdfmx project team.
 
     Copyright (c) 2006 SIL International
     Originally written by Jonathan Kew
@@ -34,7 +34,7 @@
 extern int  spc_xtx_check_special (const char *buffer, int size);
 extern int  spc_xtx_setup_handler (struct spc_handler *handle,
 				    struct spc_env *spe, struct spc_arg *args);
-extern int spc_handler_xtx_do_transform (double x_user, double y_user, double a, double b, double c, double d, double e, double f);
+extern int spc_handler_xtx_do_transform (struct spc_env *spe, double x_user, double y_user, double a, double b, double c, double d, double e, double f);
 extern int spc_handler_xtx_gsave (struct spc_env *spe, struct spc_arg *args);
 extern int spc_handler_xtx_grestore (struct spc_env *spe, struct spc_arg *args);
 

Modified: trunk/Build/source/texk/dvipdfm-x/specials.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/specials.c	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/specials.c	2020-08-16 08:10:47 UTC (rev 56121)
@@ -287,7 +287,7 @@
 }
 
 void
-spc_push_object (const char *key, pdf_obj *value)
+spc_push_object (struct spc_env *spe, const char *key, pdf_obj *value)
 {
   if (!key || !value)
     return;
@@ -296,21 +296,178 @@
 }
 
 void
-spc_flush_object (const char *key)
+spc_flush_object (struct spc_env *spe, const char *key)
 {
   pdf_names_close_object(global_names, key, strlen(key));
 }
 
 void
-spc_clear_objects (void)
+spc_clear_objects (struct spc_env *spe)
 {
   /* Do nothing... */
 }
 
+/* Migrated form pdf_dev.c
+ * No need to palce this into pdfdev.c at all.
+ */
+static dpx_stack coords;
 
+void
+spc_get_coord (struct spc_env *spe, double *x, double *y)
+{
+  ASSERT(x && y );
+
+  if (dpx_stack_depth(&coords) > 0) {
+    pdf_coord *p = dpx_stack_top(&coords);
+    *x = p->x;
+    *y = p->y;
+  } else {
+    *x = *y = 0.0;
+  }
+}
+
+void
+spc_push_coord (struct spc_env *spe, double x, double y)
+{
+  pdf_coord *p;
+
+  p = NEW(1, pdf_coord);
+  p->x = x; p->y = y;
+  dpx_stack_push(&coords, p);
+  dvi_set_compensation(x, y);
+}
+
+void
+spc_pop_coord (struct spc_env *spe)
+{
+  double     x, y;
+  pdf_coord *p;
+
+  p = dpx_stack_pop(&coords);
+  if (p)
+    RELEASE(p);
+
+  spc_get_coord(spe, &x, &y);
+  dvi_set_compensation(x, y);
+}
+
+/* Migrated from pdfdraw.c.
+ *
+ * pt_fixee is obviously not a PDF graphics state parameter.
+ *
+ */
+
+static dpx_stack pt_fixee;
+
+void
+spc_set_fixed_point (struct spc_env *spe, double x, double y)
+{
+  pdf_coord *p;
+
+  p = dpx_stack_top(&pt_fixee);
+  if (p) {
+    p->x = x;
+    p->y = y;
+  } else {
+    p = NEW(1, pdf_coord);
+    p->x = x;
+    p->y = y;
+    dpx_stack_push(&pt_fixee, p);
+  }
+}
+
+void
+spc_get_fixed_point (struct spc_env *spe, double *x, double *y)
+{
+  pdf_coord *p;
+
+  ASSERT(x && y);
+
+  p = dpx_stack_top(&pt_fixee);
+  if (p) {
+    *x = p->x;
+    *y = p->y;
+  } else {
+    *x = 0.0;
+    *y = 0.0;
+  }
+}
+
+void
+spc_put_fixed_point (struct spc_env *spe, double x, double y)
+{
+  pdf_coord *p;
+
+  p = NEW(1, pdf_coord);
+  p->x = x;
+  p->y = y;
+  dpx_stack_push(&pt_fixee, p);
+}
+
+void
+spc_dup_fixed_point (struct spc_env *spe)
+{
+  pdf_coord *p1, *p2;
+
+  p1 = dpx_stack_top(&pt_fixee);
+  p2 = NEW(1, pdf_coord);
+  if (p1) {
+    p2->x = p1->x; p2->y = p1->y;
+  } else {
+    p2->x = 0.0; p2->y = 0.0;
+  }
+  dpx_stack_push(&pt_fixee, p2);
+}
+
+void
+spc_pop_fixed_point (struct spc_env *spe)
+{
+  pdf_coord *p;
+  p = dpx_stack_pop(&pt_fixee);
+  if (p)
+    RELEASE(p);
+}
+
+void
+spc_clear_fixed_point (struct spc_env *spe)
+{
+  pdf_coord *p;
+
+  for (;;) {
+    p = dpx_stack_pop(&pt_fixee);
+    if (!p)
+      break;
+    else
+      RELEASE(p);
+  }
+}
+
+void
+spc_get_current_point (struct spc_env *spe, pdf_coord *cp)
+{
+  double xoff, yoff;
+
+  if (!spe || !cp)
+    return;
+
+  spc_get_coord(spe, &xoff, &yoff);
+  cp->x = spe->x_user - xoff;
+  cp->y = spe->y_user - yoff;
+}
+
+void
+spc_put_image (struct spc_env *spe, int res_id, transform_info *ti, double xpos, double ypos)
+{
+  double xoff, yoff;
+
+  spc_get_coord(spe, &xoff, &yoff);
+  pdf_dev_put_image(res_id, ti, xpos - xoff, ypos - yoff, &spe->info.rect);
+  spe->info.is_drawable = 1;
+}
+
+
 static int
-spc_handler_unknown (struct spc_env *spe,
-                     struct spc_arg *args)
+spc_handler_unknown (struct spc_env *spe, struct spc_arg *args)
 {
   ASSERT(spe && args);
 
@@ -334,6 +491,11 @@
   spe->y_user = y_user;
   spe->mag    = mag;
   spe->pg     = pdf_doc_current_page_number(); /* _FIXME_ */
+  spe->info.is_drawable = 0;
+  spe->info.rect.llx    = 0.0;
+  spe->info.rect.lly    = 0.0;
+  spe->info.rect.urx    = 0.0;
+  spe->info.rect.ury    = 0.0;
 
   args->curptr = p;
   args->endptr = args->curptr + size;
@@ -486,6 +648,9 @@
       error = known_specials[i].bodhk_func();
     }
   }
+  
+  dpx_stack_init(&coords);
+  dpx_stack_init(&pt_fixee);
 
   return error;
 }
@@ -493,8 +658,9 @@
 int
 spc_exec_at_end_document (void)
 {
-  int  error = 0;
-  int  i;
+  int        error = 0;
+  int        i;
+  pdf_coord *p;
 
   for (i = 0; known_specials[i].key != NULL; i++) {
     if (known_specials[i].eodhk_func) {
@@ -502,6 +668,13 @@
     }
   }
 
+  while ((p = dpx_stack_pop(&coords)) != NULL) {  
+    RELEASE(p);
+  }
+  while ((p = dpx_stack_pop(&pt_fixee)) != NULL) {  
+    RELEASE(p);
+  }
+
   return error;
 }
 
@@ -558,7 +731,8 @@
 
 int
 spc_exec_special (const char *buffer, int32_t size,
-		  double x_user, double y_user, double mag)
+                  double x_user, double y_user, double mag,
+                  int *is_drawable, pdf_rect *rect)
 {
   int    error = -1;
   int    i, found;
@@ -578,10 +752,19 @@
     if (found) {
       error = known_specials[i].setup_func(&special, &spe, &args);
       if (!error) {
-	error = special.exec(&spe, &args);
+        error = special.exec(&spe, &args);
       }
       if (error) {
-	print_error(known_specials[i].key, &spe, &args);
+        print_error(known_specials[i].key, &spe, &args);
+      } else {
+        if (is_drawable)
+          *is_drawable = spe.info.is_drawable;
+        if (rect) {
+          rect->llx    = spe.info.rect.llx;
+          rect->lly    = spe.info.rect.lly;
+          rect->urx    = spe.info.rect.urx;
+          rect->ury    = spe.info.rect.ury;
+        }
       }
       break;
     }

Modified: trunk/Build/source/texk/dvipdfm-x/specials.h
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/specials.h	2020-08-15 23:47:32 UTC (rev 56120)
+++ trunk/Build/source/texk/dvipdfm-x/specials.h	2020-08-16 08:10:47 UTC (rev 56121)
@@ -1,6 +1,6 @@
 /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
 
-    Copyright (C) 2007-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+    Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
     the dvipdfmx project team.
     
     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks at kettering.edu>
@@ -23,10 +23,17 @@
 #ifndef _SPECIALS_H_
 #define _SPECIALS_H_
 
+#include "pdfobj.h"
+#include "pdfdev.h"
+
 struct spc_env {
   double x_user, y_user;
   double mag;
   int    pg;  /* current page in PDF */
+  struct {
+    int      is_drawable;
+    pdf_rect rect;
+  } info;
 };
 
 struct spc_arg {
@@ -48,9 +55,6 @@
 #include <stdarg.h>
 extern void    spc_warn (struct spc_env *spe, const char *fmt, ...);
 
-#include "pdfobj.h"
-/* PDF parser shouldn't depend on this...
- */
 extern pdf_obj *spc_lookup_reference (const char *ident);
 extern pdf_obj *spc_lookup_object    (const char *ident);
 
@@ -66,16 +70,31 @@
 /* set default height of phantom texts */
 extern void     spc_set_phantom  (struct spc_env *spe, double height, double depth);
 
-extern void     spc_push_object   (const char *key, pdf_obj *value);
-extern void     spc_flush_object  (const char *key);
-extern void     spc_clear_objects (void);
+extern void     spc_push_object   (struct spc_env *spe, const char *key, pdf_obj *value);
+extern void     spc_flush_object  (struct spc_env *spe, const char *key);
+extern void     spc_clear_objects (struct spc_env *spe);
 
+extern void     spc_put_image     (struct spc_env *spe, int res_id, transform_info *ti, double xpos, double ypos);
+
+extern void     spc_get_current_point (struct spc_env *spe, pdf_coord *cp);
+
+/* dvipdfmx pdf: special */
+extern void     spc_get_coord  (struct spc_env *spe, double *x, double *y);
+extern void     spc_push_coord (struct spc_env *spe, double  x, double  y);
+extern void     spc_pop_coord  (struct spc_env *spe);
+/* XeTeX */
+extern void     spc_set_fixed_point   (struct spc_env *spe, double  x, double  y);
+extern void     spc_get_fixed_point   (struct spc_env *spe, double *x, double *y);
+extern void     spc_put_fixed_point   (struct spc_env *spe, double  x, double  y);
+extern void     spc_dup_fixed_point   (struct spc_env *spe);
+extern void     spc_pop_fixed_point   (struct spc_env *spe);
+extern void     spc_clear_fixed_point (struct spc_env *spe);
+
 extern int      spc_exec_at_begin_page     (void);
 extern int      spc_exec_at_end_page       (void);
 extern int      spc_exec_at_begin_document (void);
 extern int      spc_exec_at_end_document   (void);
 
-extern int      spc_exec_special (const char *p, int32_t size,
-				  double x_user, double y_user, double mag);
+extern int      spc_exec_special (const char *p, int32_t size, double x_user, double y_user, double mag, int *is_drawable, pdf_rect *rect);
 
 #endif /* _SPECIALS_H_ */



More information about the tex-live-commits mailing list.