diff --git a/dvipdfm-x/mfileio.c b/dvipdfm-x/mfileio.c
index 56b58fe..ee3a73d 100644
--- a/dvipdfm-x/mfileio.c
+++ b/dvipdfm-x/mfileio.c
@@ -45,16 +45,24 @@ static void io_debug_init(void)
 }
 #endif
 
+FILE *unxz_popen(const char *name, const char *mode)
+{
+  FILE *tmp;
+  char *cmd;
+  cmd = malloc(strlen(name) + 12);
+  strcpy(cmd, "xz -d -c ");
+  strcat(cmd, name);
+  tmp = popen (cmd, "r");
+  free(cmd);
+  return tmp;
+}
+
 #ifdef IODEBUG
 FILE *mfopen(const char *name, const char *mode, const char *function, int line)
 {
   FILE *tmp;
   io_debug_init();
-#if defined(WIN32)
-  tmp = fsyscp_fopen (name, mode);
-#else
   tmp = fopen (name, mode);
-#endif
   event += 1;
   fprintf(iodebug_file, "%p %07ld [fopen] %s:%d\n", tmp, event,
 	  function, line);
@@ -68,6 +76,24 @@ int mfclose(FILE *file, const char *function, int line)
 	  function, line);
   return fclose(file);
 }
+FILE *mpopen(const char *name, const char *mode, const char *function, int line)
+{
+  FILE *tmp;
+  io_debug_init();
+  tmp = unxz_popen (name, mode);
+  event += 1;
+  fprintf(iodebug_file, "%p %07ld [popen] %s:%d\n", tmp, event,
+	  function, line);
+  return tmp;
+}
+int mpclose(FILE *file, const char *function, int line) 
+{
+  io_debug_init();
+  event += 1;
+  fprintf(iodebug_file, "%p %07ld [pclose] %s:%d\n", file, event,
+	  function, line);
+  return pclose(file);
+}
 #endif
 
 static void os_error(void)
diff --git a/dvipdfm-x/mfileio.h b/dvipdfm-x/mfileio.h
index 70afb15..e6011f4 100644
--- a/dvipdfm-x/mfileio.h
+++ b/dvipdfm-x/mfileio.h
@@ -26,21 +26,34 @@
 #include <stdio.h>
 #include "numbers.h"
 
+#if defined(WIN32)
+#undef fopen
+#undef popen
+#define fopen fsyscp_fopen
+#define popen fsyscp_popen
+#endif
+
+FILE *unxz_popen (const char *name, const char *mode);
 #ifdef IODEBUG
 FILE *mfopen (const char *name, const char *mode,
 	      const char *function, int line);
 int mfclose (FILE *file, const char *function, int line);
+FILE *mpopen (const char *name, const char *mode,
+	      const char *function, int line);
+int mpclose (FILE *file, const char *function, int line);
 #define MFOPEN(name,mode) \
    mfopen((name),(mode),__FUNCTION__,__LINE__)
 #define MFCLOSE(file) \
    mfclose((file),__FUNCTION__,__LINE__)
-#else
-#if defined(WIN32)
-#define MFOPEN(name,mode) fsyscp_fopen((name),(mode))
+#define MPOPEN(name,mode) \
+   mpopen((name),(mode),__FUNCTION__,__LINE__)
+#define MPCLOSE(file) \
+   mpclose((file),__FUNCTION__,__LINE__)
 #else
 #define MFOPEN(name,mode) fopen((name),(mode))
-#endif
 #define MFCLOSE(file) fclose(file)
+#define MPOPEN(name,mode) unxz_popen((name),(mode))
+#define MPCLOSE(file) pclose(file)
 #endif
 
 extern UNSIGNED_BYTE read_byte (FILE *);
diff --git a/dvipdfm-x/vf.c b/dvipdfm-x/vf.c
index 151f8ed..cf92e4f 100644
--- a/dvipdfm-x/vf.c
+++ b/dvipdfm-x/vf.c
@@ -269,7 +269,7 @@ static void process_vf_file (FILE *vf_file, int thisfont)
 /* Global variables such as num_vf_fonts require careful attention */
 int vf_locate_font (const char *tex_name, spt_t ptsize)
 {
-  int thisfont = -1, i;
+  int thisfont = -1, i, is_compressed;
   char *full_vf_file_name;
   FILE *vf_file;
   /* Has this name and ptsize already been loaded as a VF? */
@@ -281,6 +281,7 @@ int vf_locate_font (const char *tex_name, spt_t ptsize)
   if (i != num_vf_fonts) {
     thisfont = i;
   } else {
+    is_compressed = 0;
     /* It's hasn't already been loaded as a VF, so try to load it */
     full_vf_file_name = kpse_find_file (tex_name, 
 					kpse_vf_format,
@@ -290,8 +291,15 @@ int vf_locate_font (const char *tex_name, spt_t ptsize)
 					  kpse_ovf_format,
 					  1);
     }
+    if (!full_vf_file_name) {
+      full_vf_file_name = kpse_find_file (tex_name, 
+					  kpse_ovfxz_format,
+					  1);
+      is_compressed = 1;
+    }
     if (full_vf_file_name &&
-	(vf_file = MFOPEN (full_vf_file_name, FOPEN_RBIN_MODE)) != NULL) {
+	(vf_file = (is_compressed ? MPOPEN (full_vf_file_name, FOPEN_RBIN_MODE)
+		    : MFOPEN (full_vf_file_name, FOPEN_RBIN_MODE))) != NULL) {
       if (verbose == 1)
 	fprintf (stderr, "(VF:%s", tex_name);
       if (verbose > 1)
@@ -312,7 +320,7 @@ int vf_locate_font (const char *tex_name, spt_t ptsize)
       process_vf_file (vf_file, thisfont);
       if (verbose)
 	fprintf (stderr, ")");
-      MFCLOSE (vf_file);
+      is_compressed ? MPCLOSE (vf_file) : MFCLOSE (vf_file);
     }
     if (full_vf_file_name)
       RELEASE(full_vf_file_name);
diff --git a/dvipsk/config.h b/dvipsk/config.h
index f4889b1..33044ce 100644
--- a/dvipsk/config.h
+++ b/dvipsk/config.h
@@ -29,6 +29,7 @@
 #define ovfpath kpse_ovf_format
 #define ofmpath kpse_ofm_format
 #define vfpath kpse_vf_format
+#define ovfxzpath kpse_ovfxz_format
 #define configpath kpse_dvips_config_format
 #define headerpath kpse_tex_ps_header_format
 #define type1path kpse_type1_format
diff --git a/dvipsk/search.c b/dvipsk/search.c
index d3f10c6..76f54c0 100644
--- a/dvipsk/search.c
+++ b/dvipsk/search.c
@@ -32,6 +32,9 @@
 #ifndef GUNZIP
 #define GUNZIP          "gzip -d"
 #endif
+#ifndef UNXZ
+#define UNXZ            "xz -d"
+#endif
 
 int to_close;  /* use fclose or pclose? */
 char *realnameoffile;
@@ -159,16 +162,17 @@ search(kpse_file_format_type format, const char *file, const char *mode)
   /* Most file looked for through here must exist -- the exception is
      VF's. Bitmap fonts go through pksearch. */
   found_name = kpse_find_file (file, format,
-                               format != vfpath && format != ofmpath);
+                               format != vfpath && format != ofmpath && format != ovfxzpath);
   if (found_name) {
     unsigned len = strlen (found_name);
-    if ((format == figpath || format == headerpath)
+    if ((format == figpath || format == headerpath || format == ovfxzpath)
         && ((len > 2 && FILESTRCASEEQ (found_name + len - 2, ".Z"))
-            || (len > 3 && FILESTRCASEEQ (found_name + len - 3, ".gz")))) {
+            || (len > 3 && FILESTRCASEEQ (found_name + len - 3, ".gz"))
+            || (len > 3 && FILESTRCASEEQ (found_name + len - 3, ".xz")))) {
       /* automatically but safely decompress.  */
       char *quoted_name = quote_name (found_name);
       char *cmd;
-      char *prog = selfautoloc_prog (GUNZIP);
+      char *prog = selfautoloc_prog (FILESTRCASEEQ(found_name+len-3,".xz") ? UNXZ : GUNZIP);
       cmd = concat3 (prog, " -c ", quoted_name);
       ret = popen (cmd, "r");
       if (dd(D_FILES)) {
diff --git a/dvipsk/virtualfont.c b/dvipsk/virtualfont.c
index f412a4d..93b7df6 100644
--- a/dvipsk/virtualfont.c
+++ b/dvipsk/virtualfont.c
@@ -90,7 +90,8 @@ vfopen(register fontdesctype *fd)
       return(1);
    if (!noomega)
 #ifdef KPATHSEA
-      if (0 != (vffile=search(ovfpath, n, READBIN)))
+      if (0 != (vffile=search(ovfpath, n, READBIN))
+          || 0 != (vffile=search(ovfxzpath, n, READBIN)))
 #else
       if (0 != (vffile=search(d, n, READBIN)))
 #endif
@@ -296,7 +297,11 @@ virtualfont(register fontdesctype *curfnt)
    } while (cmd < 243);
    if (cmd != 248)
       badvf("missing postamble");
+#ifdef KPATHSEA
+   close_file(vffile);
+#else
    fclose(vffile);
+#endif
    curfnt->loaded = 2;
    if (maxcc+1<no_of_chars) {
       curfnt->chardesc = (chardesctype *)
diff --git a/kpathsea/tex-file.c b/kpathsea/tex-file.c
index 4dcade9..e14c256 100644
--- a/kpathsea/tex-file.c
+++ b/kpathsea/tex-file.c
@@ -654,6 +654,13 @@ kpathsea_init_format_return_varlist(kpathsea kpse,kpse_file_format_type format)
       ALT_SUFFIXES (".vpl");
       FMT_INFO.suffix_search_only = true;
       break;
+    case kpse_ovfxz_format:
+      INIT_FORMAT ("ovf.xz", DEFAULT_OVFFONTS, OVF_ENVS);
+#define OVFXZ_SUFFIXES ".ovf.xz", ".vf.xz"
+      SUFFIXES (OVFXZ_SUFFIXES);
+      FMT_INFO.suffix_search_only = true;
+      FMT_INFO.binmode = true;
+      break;
     case kpse_pict_format:
       INIT_FORMAT ("graphic/figure", DEFAULT_TEXINPUTS, PICT_ENVS);
 #define ALT_PICT_SUFFIXES ".eps", ".epsi"
diff --git a/kpathsea/tex-file.h b/kpathsea/tex-file.h
index 1796bc6..0c2cc65 100644
--- a/kpathsea/tex-file.h
+++ b/kpathsea/tex-file.h
@@ -136,6 +136,7 @@ extern KPSEDLL boolean kpse_out_name_ok (const_string fname);
    VF translators, such as vftovp.  */
 #define kpse_find_vf(name) kpse_find_file (name, kpse_vf_format, false)
 #define kpse_find_ovf(name) kpse_find_file (name, kpse_ovf_format, false)
+#define kpse_find_ovfxz(name) kpse_find_file (name, kpse_ovfxz_format, false)
 
 extern KPSEDLL FILE *kpse_open_file (const_string, kpse_file_format_type);
 
diff --git a/kpathsea/types.h b/kpathsea/types.h
index 54fd59c..2c7d101 100644
--- a/kpathsea/types.h
+++ b/kpathsea/types.h
@@ -122,6 +122,7 @@ typedef enum
   kpse_otp_format,
   kpse_ovf_format,
   kpse_ovp_format,
+  kpse_ovfxz_format,
   kpse_pict_format,
   kpse_tex_format,
   kpse_texdoc_format,
