texlive[55804] Build/source/texk/dvipdfm-x: Introduce ExtGState stack

commits+kakuto at tug.org commits+kakuto at tug.org
Sat Jul 11 00:35:48 CEST 2020


Revision: 55804
          http://tug.org/svn/texlive?view=revision&revision=55804
Author:   kakuto
Date:     2020-07-11 00:35:48 +0200 (Sat, 11 Jul 2020)
Log Message:
-----------
Introduce ExtGState stack and pdf:[be]xgstate special. (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/pdfdev.c
    trunk/Build/source/texk/dvipdfm-x/pdfdoc.c
    trunk/Build/source/texk/dvipdfm-x/pdfdraw.c
    trunk/Build/source/texk/dvipdfm-x/pdfdraw.h
    trunk/Build/source/texk/dvipdfm-x/pdfobj.c
    trunk/Build/source/texk/dvipdfm-x/pdfobj.h
    trunk/Build/source/texk/dvipdfm-x/spc_pdfm.c

Modified: trunk/Build/source/texk/dvipdfm-x/ChangeLog
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/ChangeLog	2020-07-10 21:34:37 UTC (rev 55803)
+++ trunk/Build/source/texk/dvipdfm-x/ChangeLog	2020-07-10 22:35:48 UTC (rev 55804)
@@ -1,3 +1,11 @@
+2020-07-11  Shunsaku Hirata  <shunsaku.hirata74 at gmail.com>
+
+	* pdfdev.c, pdfdoc.c, pdfdraw.[ch], pdfobj.[ch], spc_pdfm.c:
+	ExtGState can be manipulated with a dedicated stack.
+	Add new specials pdf:bxgstate and pdf:exgstate to push/pop
+	ExtGState into/from the stack.
+	* configure.ac: Version 20200711.
+
 2020-07-04  Shunsaku Hirata  <shunsaku.hirata74 at gmail.com>
 
 	* pdfcolor.c, spc_util.c: Fix a bug in pdfcolor.c.

Modified: trunk/Build/source/texk/dvipdfm-x/configure
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/configure	2020-07-10 21:34:37 UTC (rev 55803)
+++ trunk/Build/source/texk/dvipdfm-x/configure	2020-07-10 22:35:48 UTC (rev 55804)
@@ -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) 20200704.
+# Generated by GNU Autoconf 2.69 for dvipdfm-x (TeX Live) 20200711.
 #
 # 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='20200704'
-PACKAGE_STRING='dvipdfm-x (TeX Live) 20200704'
+PACKAGE_VERSION='20200711'
+PACKAGE_STRING='dvipdfm-x (TeX Live) 20200711'
 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) 20200704 to adapt to many kinds of systems.
+\`configure' configures dvipdfm-x (TeX Live) 20200711 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) 20200704:";;
+     short | recursive ) echo "Configuration of dvipdfm-x (TeX Live) 20200711:";;
    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 20200704
+dvipdfm-x (TeX Live) configure 20200711
 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 20200704, which was
+It was created by dvipdfm-x (TeX Live) $as_me 20200711, 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='20200704'
+ VERSION='20200711'
 
 
 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 20200704
+dvipdfm-x (TeX Live) config.lt 20200711
 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 20200704, which was
+This file was extended by dvipdfm-x (TeX Live) $as_me 20200711, 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 20200704
+dvipdfm-x (TeX Live) config.status 20200711
 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-07-10 21:34:37 UTC (rev 55803)
+++ trunk/Build/source/texk/dvipdfm-x/configure.ac	2020-07-10 22:35:48 UTC (rev 55804)
@@ -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)], [20200704], [dvipdfmx at tug.org])
+AC_INIT([dvipdfm-x (TeX Live)], [20200711], [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/pdfdev.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/pdfdev.c	2020-07-10 21:34:37 UTC (rev 55803)
+++ trunk/Build/source/texk/dvipdfm-x/pdfdev.c	2020-07-10 22:35:48 UTC (rev 55804)
@@ -1,6 +1,6 @@
 /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
 
-    Copyright (C) 2002-2019 by Jin-Hwan Cho and Shunsaku Hirata,
+    Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
     the dvipdfmx project team.
     
     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks at kettering.edu>
@@ -1364,6 +1364,7 @@
 
   pdf_dev_reset_fonts(1);
   pdf_dev_reset_color(0);
+  pdf_dev_reset_xgstate(0);
 }
 
 void

Modified: trunk/Build/source/texk/dvipdfm-x/pdfdoc.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/pdfdoc.c	2020-07-10 21:34:37 UTC (rev 55803)
+++ trunk/Build/source/texk/dvipdfm-x/pdfdoc.c	2020-07-10 22:35:48 UTC (rev 55804)
@@ -2717,6 +2717,7 @@
    */
   pdf_dev_reset_fonts(1);
   pdf_dev_reset_color(1);  /* force color operators to be added to stream */
+  pdf_dev_reset_xgstate(1);
 
   return xobj_id;
 }
@@ -2763,6 +2764,7 @@
 
   pdf_dev_reset_fonts(1);
   pdf_dev_reset_color(0);
+  pdf_dev_reset_xgstate(0);
 
   RELEASE(fnode);
 

Modified: trunk/Build/source/texk/dvipdfm-x/pdfdraw.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/pdfdraw.c	2020-07-10 21:34:37 UTC (rev 55803)
+++ trunk/Build/source/texk/dvipdfm-x/pdfdraw.c	2020-07-10 22:35:48 UTC (rev 55804)
@@ -37,6 +37,8 @@
 #include "pdfdoc.h"
 #include "pdfdev.h"
 #include "pdfcolor.h"
+#include "pdfparse.h"
+#include "pdfobj.h"
 
 #include "pdfdraw.h"
 
@@ -880,40 +882,7 @@
   return 0;
 }
 
-
-/* Graphics State */
-typedef struct pdf_gstate_
-{
-  pdf_coord   cp;
-
-  pdf_tmatrix matrix;   /* cm,  - */
-
-  pdf_color   strokecolor;
-  pdf_color   fillcolor;
-  /* colorspace here */
-
-  struct {
-    int     num_dash;
-    double  pattern[PDF_DASH_SIZE_MAX];
-    double  offset;
-  } linedash;           /* d,  D  */
-
-  double    linewidth;  /* w,  LW */
-
-  int       linecap;    /* J,  LC */
-  int       linejoin;   /* j,  LJ */
-  double    miterlimit; /* M,  ML */
-
-  int       flatness;   /* i,  FL, 0 to 100 (0 for use device-default) */
-
-  /* internal */
-  pdf_path  path;
-  int       flags;
-  /* bookkeeping the origin of the last transform applied */
-  pdf_coord pt_fixee;
-} pdf_gstate;
-
-
+/* Stack operation */
 typedef struct m_stack_elem
 {
   void                *data;
@@ -999,6 +968,79 @@
 
 #define m_stack_depth(s)    ((s)->size)
 
+/* ExtGState stack */
+static m_stack xgs_stack;
+static int     xgs_count = 0;
+
+struct xgs_res {
+  pdf_obj *object;
+  pdf_obj *accumlated;
+};
+
+static const char default_xgs[] = "\
+<< /Type /ExtGState\
+   /LW 1 /LC 0 /LJ 0 /ML 10 /D [[] 0]\
+   /RI /RelativeColorimetric /SA false /BM /Normal /SMask /None\
+   /AIS false /TK false /CA 1 /ca 1\
+   /OP false /op false /OPM 0 /FL 1\
+>>";
+
+static void
+init_xgstate (void)
+{
+  m_stack_init(&xgs_stack);
+  xgs_count = 0;
+
+  return;
+}
+
+static void
+clear_xgstate (void)
+{
+  struct xgs_res *xgs;
+
+  while ((xgs = m_stack_pop(&xgs_stack)) != NULL) {
+    pdf_release_obj(xgs->object);
+    pdf_release_obj(xgs->accumlated);
+    RELEASE(xgs);
+  }
+
+  return;  
+}
+
+/* Graphics State */
+typedef struct pdf_gstate_
+{
+  pdf_coord   cp;
+
+  pdf_tmatrix matrix;   /* cm,  - */
+
+  pdf_color   strokecolor;
+  pdf_color   fillcolor;
+  /* colorspace here */
+
+  struct {
+    int     num_dash;
+    double  pattern[PDF_DASH_SIZE_MAX];
+    double  offset;
+  } linedash;           /* d,  D  */
+
+  double    linewidth;  /* w,  LW */
+
+  int       linecap;    /* J,  LC */
+  int       linejoin;   /* j,  LJ */
+  double    miterlimit; /* M,  ML */
+
+  int       flatness;   /* i,  FL, 0 to 100 (0 for use device-default) */
+
+  /* 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 void
@@ -1027,6 +1069,8 @@
   gs->pt_fixee.x = 0;
   gs->pt_fixee.y = 0;
 
+  gs->extgstate  = NULL;
+
   return;
 }
 
@@ -1034,6 +1078,8 @@
 clear_a_gstate (pdf_gstate *gs)
 {
   clear_a_path(&gs->path);
+  if (gs->extgstate)
+    pdf_release_obj(gs->extgstate);
   memset(gs, 0, sizeof(pdf_gstate));
 
   return;
@@ -1075,8 +1121,158 @@
   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;
+
   return;
 }
+
+static int
+pdf_dev_set_xgstate (pdf_obj *diff, pdf_obj *accumlated)
+{
+  m_stack    *gss = &gs_stack;
+  pdf_gstate *gs  = m_stack_top(gss);
+  char        buf[64], res_name[16];
+  int         len = 0, id;
+
+  id = xgs_count;
+  snprintf(res_name, 16, "DPX_GS%d", id);
+  res_name[15] = '\0';
+  len += snprintf(buf, 64, " /%s gs", res_name);
+  pdf_doc_add_page_content(buf, len);
+  pdf_doc_add_page_resource("ExtGState", res_name, pdf_link_obj(diff));
+  if (gs->extgstate)
+    pdf_release_obj(gs->extgstate);
+  gs->extgstate = pdf_link_obj(accumlated);
+  xgs_count++;
+
+  return 0;
+}
+
+int
+pdf_dev_reset_xgstate (int force)
+{
+  m_stack        *gss = &gs_stack;
+  pdf_gstate     *gs;
+  pdf_obj        *current, *target, *keys, *diff;
+  struct xgs_res *xgs;
+  int             i;
+
+  gs  = m_stack_top(gss);
+  xgs = m_stack_top(&xgs_stack);
+  if (xgs) {
+    target  = pdf_link_obj(xgs->accumlated);
+  } else {
+    const char *ptr, *endptr;
+
+    if (!gs->extgstate && !force)
+      return 0;
+    ptr     = default_xgs;
+    endptr  = ptr + strlen(ptr);
+    target  = parse_pdf_dict(&ptr, endptr, NULL);
+  }
+  if (gs->extgstate) {
+    current = pdf_link_obj(gs->extgstate);
+  } else {
+    const char *ptr, *endptr;
+    ptr     = default_xgs;
+    endptr  = ptr + strlen(ptr);
+    current = parse_pdf_dict(&ptr, endptr, NULL);
+  }
+
+  diff = pdf_new_dict();
+  keys = pdf_dict_keys(target);
+  for (i = 0; i < pdf_array_length(keys); i++) {
+    pdf_obj *key, *value1, *value2;
+    int      is_diff = 0;
+
+    key     = pdf_get_array(keys, i);
+    value1  = pdf_lookup_dict(target,  pdf_name_value(key));
+    value2  = pdf_lookup_dict(current, pdf_name_value(key));
+    is_diff = pdf_compare_object(value1, value2);
+    if (is_diff) {
+      pdf_add_dict(diff, pdf_link_obj(key), pdf_link_obj(value1));
+    }
+  }
+  pdf_release_obj(keys);
+  pdf_dev_set_xgstate(diff, target);
+  pdf_release_obj(diff);
+  pdf_release_obj(current);
+  pdf_release_obj(target);
+
+  return 0;
+}
+
+void
+pdf_dev_xgstate_push (pdf_obj *object)
+{
+  struct xgs_res *target, *current;
+  pdf_obj        *accumlated;
+
+  target = NEW(1, struct xgs_res);
+  target->object = object;
+  current = m_stack_top(&xgs_stack);
+  if (!current) {
+    const char *ptr, *endptr;
+    ptr    = default_xgs;
+    endptr = ptr + strlen(default_xgs);
+    accumlated = parse_pdf_dict(&ptr, endptr, NULL);
+  } else {
+    accumlated = pdf_new_dict();
+    pdf_merge_dict(accumlated, current->accumlated);    
+  }
+  pdf_merge_dict(accumlated, object);
+  target->accumlated = accumlated;
+  m_stack_push(&xgs_stack, target);
+
+  pdf_dev_set_xgstate(target->object, target->accumlated);
+
+  return;
+}
+
+void
+pdf_dev_xgstate_pop (void)
+{
+  struct xgs_res *current, *target;
+  pdf_obj        *accumlated, *revert, *keys;
+  int             i;
+
+  current = m_stack_pop(&xgs_stack);
+  target  = m_stack_top(&xgs_stack); 
+  if (!current) {
+    WARN("Too many pop operation for ExtGState!");
+    return;
+  }
+  if (!target) {
+    const char *ptr, *endptr;
+    ptr    = default_xgs;
+    endptr = ptr + strlen(default_xgs);
+    accumlated = parse_pdf_dict(&ptr, endptr, NULL);
+  } else {
+    accumlated = pdf_link_obj(target->accumlated);
+  }
+  keys   = pdf_dict_keys(current->object);  
+  revert = pdf_new_dict();
+  for (i = 0; i < pdf_array_length(keys); i++) {
+    pdf_obj *key, *value;
+    key   = pdf_get_array(keys, i);
+    value = pdf_lookup_dict(accumlated, pdf_name_value(key));
+    if (!value) {
+      WARN("No previous ExtGState entry known for \"%s\", ignoring...", pdf_name_value(key));
+    } else {
+      pdf_add_dict(revert, pdf_link_obj(key), pdf_link_obj(value));
+    }
+  }
+  pdf_dev_set_xgstate(revert, accumlated);
+  pdf_release_obj(revert);
+  pdf_release_obj(keys);
+  pdf_release_obj(accumlated);
+
+  pdf_release_obj(current->object);
+  pdf_release_obj(current->accumlated);
+  RELEASE(current);
+
+  return;
+}
     
 void
 pdf_dev_init_gstates (void)
@@ -1089,6 +1285,7 @@
   init_a_gstate(gs);
 
   m_stack_push(&gs_stack, gs); /* Initial state */
+  init_xgstate();
 
   return;
 }
@@ -1105,6 +1302,9 @@
     clear_a_gstate(gs);
     RELEASE(gs);
   }
+
+  clear_xgstate();
+
   return;
 }
 

Modified: trunk/Build/source/texk/dvipdfm-x/pdfdraw.h
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/pdfdraw.h	2020-07-10 21:34:37 UTC (rev 55803)
+++ trunk/Build/source/texk/dvipdfm-x/pdfdraw.h	2020-07-10 22:35:48 UTC (rev 55804)
@@ -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>
@@ -167,4 +167,8 @@
 #define pdf_dev_set_strokingcolor(c)     pdf_dev_set_color(c,    0, 0);
 #define pdf_dev_set_nonstrokingcolor(c)  pdf_dev_set_color(c, 0x20, 0);
 
+extern void pdf_dev_xgstate_push  (pdf_obj *object);
+extern void pdf_dev_xgstate_pop   (void);
+extern int  pdf_dev_reset_xgstate (int force);
+
 #endif /* _PDF_DRAW_H_ */

Modified: trunk/Build/source/texk/dvipdfm-x/pdfobj.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/pdfobj.c	2020-07-10 21:34:37 UTC (rev 55803)
+++ trunk/Build/source/texk/dvipdfm-x/pdfobj.c	2020-07-10 22:35:48 UTC (rev 55804)
@@ -4262,3 +4262,106 @@
   return data1->pf != data2->pf || data1->label != data2->label
     || data1->generation != data2->generation;
 }
+
+int
+pdf_compare_object (pdf_obj *obj1, pdf_obj *obj2)
+{
+  int r = 0;
+
+  if (!obj1 && obj2) {
+    return 1;
+  } else if (obj1 && !obj2) {
+    return 1;
+  } else if (pdf_obj_typeof(obj1) != pdf_obj_typeof(obj2)) {
+    return 1;
+  }
+
+  switch (pdf_obj_typeof(obj1)) {
+  case PDF_BOOLEAN:
+    r = pdf_boolean_value(obj1) - pdf_boolean_value(obj2);
+    break;
+  case PDF_NUMBER:
+    if (pdf_number_value(obj1) < pdf_number_value(obj2)) {
+      r = -1;
+    } else if (pdf_number_value(obj1) > pdf_number_value(obj2)) {
+      r = 1;
+    } else {
+      r = 0;
+    }
+    break;
+  case PDF_STRING:
+    if (pdf_string_length(obj1) < pdf_string_length(obj2)) {
+      r = -1;
+    } else if (pdf_string_length(obj1) > pdf_string_length(obj2)) {
+      r = 1;
+    } else {
+      r = memcmp(pdf_string_value(obj1), pdf_string_value(obj2), pdf_string_length(obj1));
+    }
+    break;
+  case PDF_NAME:
+    r = strcmp(pdf_name_value(obj1), pdf_name_value(obj2));
+    break;
+  case PDF_NULL:
+    /* Always same */
+    r = 0;
+    break;
+  case PDF_INDIRECT:
+    r = pdf_compare_reference(obj1, obj2);
+    break;
+  case PDF_ARRAY:
+    if (pdf_array_length(obj1) < pdf_array_length(obj2)) {
+      r = -1;
+    } else if (pdf_array_length(obj1) > pdf_array_length(obj2)) {
+      r = 1;
+    } else {
+      int i;
+      for (i = 0; r == 0 && i < pdf_array_length(obj1); i++) {
+        pdf_obj *v1, *v2;
+        v1 = pdf_get_array(obj1, i);
+        v2 = pdf_get_array(obj2, i);
+        r  = pdf_compare_object(v1, v2); 
+      }
+    }
+    break;
+  case PDF_DICT:
+    {
+      pdf_obj *keys1, *keys2;
+      keys1 = pdf_dict_keys(obj1);
+      keys2 = pdf_dict_keys(obj2);
+      r = pdf_compare_object(keys1, keys2);
+      if (r == 0) {
+        int i;
+        for (i = 0; r == 0 && i < pdf_array_length(keys1); i++) {
+          pdf_obj *key, *v1, *v2;
+          key = pdf_get_array(keys1, i);
+          v1  = pdf_lookup_dict(obj1, pdf_name_value(key));
+          v2  = pdf_lookup_dict(obj2, pdf_name_value(key));
+          r   = pdf_compare_object(v1, v2);
+        }
+      }
+      pdf_release_obj(keys1);
+      pdf_release_obj(keys2);
+    }
+    break;
+  case PDF_STREAM:
+    /* Not seriously testing... */
+    r = pdf_compare_object(pdf_stream_dict(obj1), pdf_stream_dict(obj2));
+    if (r == 0) {
+      size_t len1, len2;
+      len1 = pdf_stream_length(obj1);
+      len2 = pdf_stream_length(obj2);
+      if (len1 < len2) {
+        r = -1;
+      } else if (len1 > len2) {
+        r = 1;
+      } else {
+        r = 0;
+      }
+    }
+    break;
+  default:
+    r = 1;
+  }
+
+  return r;
+}

Modified: trunk/Build/source/texk/dvipdfm-x/pdfobj.h
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/pdfobj.h	2020-07-10 21:34:37 UTC (rev 55803)
+++ trunk/Build/source/texk/dvipdfm-x/pdfobj.h	2020-07-10 22:35:48 UTC (rev 55804)
@@ -1,6 +1,6 @@
 /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
 
-    Copyright (C) 2007-2019 by Jin-Hwan Cho and Shunsaku Hirata,
+    Copyright (C) 2007-2020 by Jin-Hwan Cho and Shunsaku Hirata,
     the dvipdfmx project team.
     
     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks at kettering.edu>
@@ -164,9 +164,10 @@
                                              int predictor, int32_t columns,
                                              int bpc, int colors);
 
-/* Compare label of two indirect reference object.
- */
+/* Compare labels of two indirect reference object. */
 extern int         pdf_compare_reference (pdf_obj *ref1, pdf_obj *ref2);
+/* Compare objects. */
+extern int         pdf_compare_object    (pdf_obj *obj1, pdf_obj *obj2);
 
 /* The following routines are not appropriate for pdfobj.
  */

Modified: trunk/Build/source/texk/dvipdfm-x/spc_pdfm.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/spc_pdfm.c	2020-07-10 21:34:37 UTC (rev 55803)
+++ trunk/Build/source/texk/dvipdfm-x/spc_pdfm.c	2020-07-10 22:35:48 UTC (rev 55804)
@@ -1061,6 +1061,7 @@
    * starting a new page.
    */
   pdf_dev_reset_color(0);
+  pdf_dev_reset_xgstate(0);
 
   return 0;
 }
@@ -1632,6 +1633,7 @@
   pdf_dev_pop_coord();
   pdf_dev_grestore();
   pdf_dev_reset_color(0);
+  pdf_dev_reset_xgstate(0);
 
   return 0;
 }
@@ -2212,6 +2214,36 @@
 }
 
 static int
+spc_handler_pdfm_bxgstate (struct spc_env *spe, struct spc_arg *args)
+{
+  pdf_obj *object;
+
+  skip_white(&args->curptr, args->endptr);
+  object = parse_pdf_object(&args->curptr, args->endptr, NULL);
+  if (!object) {
+    spc_warn(spe, "Could not find an object definition.");
+    return -1;
+  } else if (!PDF_OBJ_DICTTYPE(object)) {
+    spc_warn(spe, "Parsed object for ExtGState not a dictionary object!");
+    pdf_release_obj(object);
+    return -1;
+  }
+  pdf_dev_xgstate_push(object);
+
+  skip_white(&args->curptr, args->endptr);
+
+  return 0;
+}
+
+static int
+spc_handler_pdfm_exgstate (struct spc_env *spe, struct spc_arg *args)
+{
+  pdf_dev_xgstate_pop();
+  skip_white(&args->curptr, args->endptr);
+  return 0;
+}
+
+static int
 spc_handler_pdft_compat_page (struct spc_env *spe, struct spc_arg *args)
 {
   skip_white(&args->curptr, args->endptr);
@@ -2342,6 +2374,9 @@
   {"xannot",      spc_handler_pdfm_xann},
   {"extendann",   spc_handler_pdfm_xann},
   {"xann",        spc_handler_pdfm_xann}, 
+
+  {"bxgstate",    spc_handler_pdfm_bxgstate},
+  {"exgstate",    spc_handler_pdfm_exgstate},
 };
 
 static struct spc_handler pdft_compat_handlers[] = {



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