Hello community,

here is the log from the commit of package hxtools for openSUSE:Factory checked 
in at 2020-03-31 17:15:45
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/hxtools (Old)
 and      /work/SRC/openSUSE:Factory/.hxtools.new.3160 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "hxtools"

Tue Mar 31 17:15:45 2020 rev:38 rq:789916 version:20200331

Changes:
--------
--- /work/SRC/openSUSE:Factory/hxtools/hxtools.changes  2020-03-18 
12:43:22.408878058 +0100
+++ /work/SRC/openSUSE:Factory/.hxtools.new.3160/hxtools.changes        
2020-03-31 17:16:00.531656694 +0200
@@ -1,0 +2,8 @@
+Mon Mar 30 23:28:58 UTC 2020 - Jan Engelhardt <[email protected]>
+
+- Update to release 20200331
+  * vfontas: add "N2" vectorizer
+  * vfontas: new -saven2 command to use N2
+  * vfontas: moved N1 to historic status
+
+-------------------------------------------------------------------
@@ -5 +13 @@
-  * vfontas: add new N1 vectorizer
+  * vfontas: add "N1" vectorizer

Old:
----
  hxtools-20200310.tar.asc
  hxtools-20200310.tar.xz

New:
----
  hxtools-20200331.tar.asc
  hxtools-20200331.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ hxtools.spec ++++++
--- /var/tmp/diff_new_pack.qKeCqE/_old  2020-03-31 17:16:01.839657525 +0200
+++ /var/tmp/diff_new_pack.qKeCqE/_new  2020-03-31 17:16:01.839657525 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           hxtools
-Version:        20200310
+Version:        20200331
 Release:        0
 Summary:        Collection of day-to-day tools (binaries)
 License:        GPL-2.0+ and WTFPL
@@ -160,7 +160,9 @@
 %description -n vfontas
 vfontas (originally "VGA font file assembler") can transform raster
 font files in various ways - scaling, moving, row-filling, convert
-between formats (bdf/clt/pbm/psf/raw) and vector export to sfd/ttf.
+between formats (bdf/clt/pbm/psf/raw DOS font) and vector export to
+sfd (and then TrueType/OpenType/WOFF/etc. via FontForge). The vector
+export is able to smoothen the jagged edges of bitmap fonts.
 
 %prep
 %setup -q

++++++ hxtools-20200310.tar.xz -> hxtools-20200331.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hxtools-20200310/configure 
new/hxtools-20200331/configure
--- old/hxtools-20200310/configure      2020-03-10 10:30:35.462411142 +0100
+++ new/hxtools-20200331/configure      2020-03-31 01:26:20.475923272 +0200
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for hxtools 20200310.
+# Generated by GNU Autoconf 2.69 for hxtools 20200331.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -577,8 +577,8 @@
 # Identity of this package.
 PACKAGE_NAME='hxtools'
 PACKAGE_TARNAME='hxtools'
-PACKAGE_VERSION='20200310'
-PACKAGE_STRING='hxtools 20200310'
+PACKAGE_VERSION='20200331'
+PACKAGE_STRING='hxtools 20200331'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1301,7 +1301,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 hxtools 20200310 to adapt to many kinds of systems.
+\`configure' configures hxtools 20200331 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1367,7 +1367,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of hxtools 20200310:";;
+     short | recursive ) echo "Configuration of hxtools 20200331:";;
    esac
   cat <<\_ACEOF
 
@@ -1486,7 +1486,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-hxtools configure 20200310
+hxtools configure 20200331
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1946,7 +1946,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by hxtools $as_me 20200310, which was
+It was created by hxtools $as_me 20200331, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2811,7 +2811,7 @@
 
 # Define the identity of the package.
  PACKAGE='hxtools'
- VERSION='20200310'
+ VERSION='20200331'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -5897,7 +5897,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by hxtools $as_me 20200310, which was
+This file was extended by hxtools $as_me 20200331, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -5963,7 +5963,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; 
s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-hxtools config.status 20200310
+hxtools config.status 20200331
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hxtools-20200310/configure.ac 
new/hxtools-20200331/configure.ac
--- old/hxtools-20200310/configure.ac   2020-03-10 10:29:07.000000000 +0100
+++ new/hxtools-20200331/configure.ac   2020-03-31 01:25:27.000000000 +0200
@@ -1,4 +1,4 @@
-AC_INIT([hxtools], [20200310])
+AC_INIT([hxtools], [20200331])
 AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_HEADERS([config.h])
 AC_PROG_INSTALL
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hxtools-20200310/doc/NEWS.txt 
new/hxtools-20200331/doc/NEWS.txt
--- old/hxtools-20200310/doc/NEWS.txt   2020-03-10 10:29:07.000000000 +0100
+++ new/hxtools-20200331/doc/NEWS.txt   2020-03-31 01:25:27.000000000 +0200
@@ -1,12 +1,39 @@
 
+rel-20200331
+============
+* vfontas: add new N2 vectorizer
+* vfontas: new -saven2 command to use N2
+
+The N2 vectorizer is able to recognize logical 45-degree angles in
+bitmap glyphs and will output the outlines as such. Unlike N1,
+it analyzes glyph outlines rather than pixel patterns, and produces
+higher quality output due to a larger working radius.
+
+N2 can reproduce the "Nouveau IBM" font quite closely now (e.g. from
+Fontraption's VGA9.F16 file). A few differences have just become apparent (one
+can inspect in e.g. Inkscape by overlaying both fontfaces) that may be
+addressed in a later release.
+
+N2:
+* Serifs are subject to diagonalization (but maybe should become exempt).
+* Isthmuses tend to get washed out, noticable in glyphs like 'G'.
+* Sumps in the 'K', 'M', 'N' glyphs could be improved.
+  This is noticable in glyphs like 'G'.
+
+Nouveau IBM:
+* Kerning is not original: too closely spaced.
+* Node points are not at pixel or half-pixel locations.
+  'B' has a 30.78 diagonal for no apparent reason. This is bad for integral
+  scaling. Other values can be observed in 'W'.
+* Glyph 'C' is asymmetric.
+
+
 rel-20200309
 ============
-* vfontas: add new N1 vectorizer
+* vfontas: add N1 vectorizer
 * vfontas: new -saven1 command to use N1
 * vfontas: remove -xbrz
 
-The N1 vectorizer is able to recognize logical 45-degree angles in
-bitmap glyphs and will output the outlines as such.
 
 
 rel-20200124
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hxtools-20200310/doc/vfontas.1 
new/hxtools-20200331/doc/vfontas.1
--- old/hxtools-20200310/doc/vfontas.1  2020-03-10 10:29:07.000000000 +0100
+++ new/hxtools-20200331/doc/vfontas.1  2020-03-31 01:25:27.000000000 +0200
@@ -41,6 +41,8 @@
 .PP
 \fB\-saven1\fP \fInew.sfd\fP
 .PP
+\fB\-saven2\fP \fInew.sfd\fP
+.PP
 \fB\-savepbm\fP \fIoutdir/\fP
 .PP
 \fB\-savepsf\fP \fInew.psfu\fP
@@ -129,41 +131,48 @@
 Saves the current in-memory Unicode mapping table to the given file.
 .SS saven1
 .PP
+N1 was an experiment to try and model the "diagonalization idea" (cf. \-saven2)
+by analyzing the original glyph \fIbitmap\fP. Its defining characteristic is a
+lookaround window of 3x3 pixels, whose contents are mapped to a set of
+triangles. N1 has some drawbacks over the newer N2:
+.IP \(bu 4
+N1 adds diagonals on single-pixel protrusions (e.g. the left end of the
+horizontal bar in an 'f' in certain fonts). This is definitely not fixable with
+a 3x3 window and would require using 5x5.
+.IP \(bu 4
+N1 adds triangles between pixels that do not necessarily belong together, such
+as in spirals like U+0040 or jampacked glyphs like U+20A7. N2 operates on edges
+and knows their direction, and avoids making connections to "pixel islands" at
+certain angles.
+.SS saven2
+.PP
 Similar to \fB\-savesfd\fP, this produces an SFD file, but uses an alternate
-vectorizer (aptly named "N1"), which smoothens the jagged edges of a bitmap
+vectorizer (aptly named "N2"), which smoothens the jagged edges of a bitmap
 font.
 .PP
-The N1 vectorizer is able to recognize logical 45-degree angles in bitmap
-glyphs. Each 90 degree corner followed by a 270 degree corner is replaced by a
-diagonal segment. This diagonalization was originally employed by Arto Hatanpää
-(possibly in a long session of manual work) for the "Nouveau IBM" and "Nouveau
-IBM Stretch" vector font versions of the IBM VGA 9x16 ROM font.
-.PP
-In a twist, N1 does not look at the angles of the corners of the glyph
-outlines, but rather inspects source pixel patterns in a 3x3 window and emits
-triangles accordingly that implement the replacement rule.
+The N2 vectorizer is able to recognize the "stair" pattern of pixels and
+transform these sections to 45-degree angles. This diagonalization was
+originally employed by Arto Hatanpää (possibly in a long session of manual
+work) for the "Nouveau IBM" and "Nouveau IBM Stretch" vector font versions of
+the IBM VGA 9x16 ROM font.
+.PP
+The defining characteristic of N2 is that it analyzes glyph edges (similar to
+those produced by \-savesfd) using a lookaround window of 7 edge segments,
+which is used to work on areas of effectively 5x5 pixels. When a 90/270 corner
+is found, it will be transformed by adding diagonal edges.
 .PP
 In comparison to other scalers,
 .IP \(bu 4
-xBRZ erroneously round the ends of strokes (e.g. the '-' dash).
-.IP \(bu 4
-N1 adds diagonals on single-pixel protrusions (e.g. the left end of the
-horizontal bar in an 'f'). This is definitely not fixable with a 3x3 window,
-and is probably not solvable for the general case either.
-.IP \(bu 4
-N1 adds links between pixels that do not necessarily belong there (such as in
-spirals like U+0040 or jampacked glyphs like U+20A7). This is probably not
-fixable for the general case without making the vectorizer aware of expected
-shapes.
+xBRZ erroneously round the ends of strokes (e.g. the '-' dash), N1/N2 does not.
 .IP \(bu 4
 While xBRZ is a bitmap-to-bitmap procedure (also limited to 6x magnification
-as of writing), N1 converts to vector.
+as of writing), N1/N2 converts to vector.
 .IP \(bu 4
 Autotrace/Potrace just is not targeted for low resolution sources (as 8x16
 bitmap fonts are). Either it will convert the bitmap 1:1 with jagged edges,
 or turn it into three or so beziers, which is not nearly enough for '&'.
 .IP \(bu 4
-N1 is only specified for monochrome input.
+N1/N2 is only specified for monochrome input.
 .SS savepsf
 .PP
 Saves the current in-memory glyphs as a PC Screen Font PSF2.0 file, which can
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hxtools-20200310/smm/vfalib.cpp 
new/hxtools-20200331/smm/vfalib.cpp
--- old/hxtools-20200310/smm/vfalib.cpp 2020-03-10 10:29:07.000000000 +0100
+++ new/hxtools-20200331/smm/vfalib.cpp 2020-03-31 01:25:27.000000000 +0200
@@ -68,14 +68,16 @@
        public:
        std::vector<std::vector<edge>> simple(const glyph &, int descent = 0);
        std::vector<std::vector<edge>> n1(const glyph &, int descent = 0);
+       std::vector<std::vector<edge>> n2(const glyph &, int descent = 0);
        static constexpr const unsigned int scale_factor = 2;
 
        private:
        void finalize();
-       std::vector<edge> pop_poly();
+       std::vector<edge> pop_poly(unsigned int flags);
        void set(int, int);
 
        std::set<edge> emap;
+       static const unsigned int P_SIMPLIFY_LINES = 1 << 0;
 };
 
 static const char vfhex[] = "0123456789abcdef";
@@ -757,7 +759,7 @@
        }
 }
 
-std::vector<edge> vectorizer::pop_poly()
+std::vector<edge> vectorizer::pop_poly(unsigned int flags)
 {
        std::vector<edge> poly;
        if (emap.size() == 0)
@@ -815,7 +817,7 @@
                 * polygon has a vertex in the same location.)
                 */
                auto next_dir = next->trivial_dir();
-               if (next_dir == prev_dir)
+               if ((flags & P_SIMPLIFY_LINES) && next_dir == prev_dir)
                        tail_vtx = next->end_vtx;
                else
                        poly.push_back(*next);
@@ -839,7 +841,7 @@
        finalize();
        std::vector<std::vector<edge>> pmap;
        while (true) {
-               auto poly = pop_poly();
+               auto poly = pop_poly(P_SIMPLIFY_LINES);
                if (poly.size() == 0)
                        break;
                pmap.push_back(std::move(poly));
@@ -918,7 +920,7 @@
        finalize();
        std::vector<std::vector<edge>> pmap;
        while (true) {
-               auto poly = pop_poly();
+               auto poly = pop_poly(P_SIMPLIFY_LINES);
                if (poly.size() == 0)
                        break;
                pmap.push_back(std::move(poly));
@@ -926,6 +928,160 @@
        return pmap;
 }
 
+static void n2_angle(std::vector<edge> &poly)
+{
+       static const unsigned int M_HEAD = 0x20, M_TAIL = 0x02;
+       std::vector<unsigned int> flags(poly.size());
+
+       for (size_t xm3 = 0; xm3 < poly.size(); ++xm3) {
+               auto xm2 = (xm3 + 1) % poly.size();
+               auto xm1 = (xm3 + 2) % poly.size();
+               auto x00 = (xm3 + 3) % poly.size();
+               auto xp1 = (xm3 + 4) % poly.size();
+               auto xp2 = (xm3 + 5) % poly.size();
+               auto xp3 = (xm3 + 6) % poly.size();
+               auto dm3 = poly[xm3].trivial_dir(), dm2 = 
poly[xm2].trivial_dir();
+               auto dm1 = poly[xm1].trivial_dir(), d00 = 
poly[x00].trivial_dir();
+               auto dp1 = poly[xp1].trivial_dir(), dp2 = 
poly[xp2].trivial_dir();
+               auto dp3 = poly[xp3].trivial_dir();
+
+#if 0
+               printf("I%zu dm3:\e[32m%d\e[0m,dm2:\e[32m%d\e[0m,"
+                       "dm1:\e[32m%d\e[0m,d:\e[32m%d\e[0m,dp1:\e[32m%d\e[0m,"
+                       "dp2:\e[32m%d\e[0m,dp3:\e[32m%d\e[0m\n",
+                       x00, dm3, dm2, dm1, d00, dp1, dp2, dp3);
+#endif
+
+               if (d00 == dm2 && d00 == dp2) {
+                       /* _|~|_ or ~|_|~ pattern seen */
+                       if ((dm3 == d00 || dm3 == dp1) &&
+                           (dp3 == d00 || dp3 == dm1) &&
+                           dm1 == (dm2 + 270) % 360 && dp1 == (dm2 + 90) % 360)
+                               /* pimple __|~|__ ('f', '4'), retain */
+                               continue;
+
+                       if (dm1 == (dm2 + 90) % 360 && dp1 == (dm2 + 270) % 
360) {
+                               /* dimple ~~|_|~~ ('8'), sink it */
+                               if (dm3 == dm2) {
+                                       /* with left-side flat zone */
+                                       flags[xm2] |= M_TAIL;
+                                       flags[xm1]  = M_HEAD | M_TAIL;
+                                       flags[x00] |= M_HEAD;
+                               }
+                               if (dp3 == dp2) {
+                                       /* with right-side flat zone */
+                                       flags[x00] |= M_TAIL;
+                                       flags[xp1]  = M_HEAD | M_TAIL;
+                                       flags[xp2] |= M_HEAD;
+                               }
+                               continue;
+                       }
+               }
+
+               /* Test for chicane */
+               if (dm1 != dp1)
+                       continue;
+               if ((d00 + 270) % 360 != dp1 && (d00 + 90) % 360 != dp1)
+                       continue;
+
+               /*
+                * #1: single step, with or without sump,
+                * #2: bottom of stairs, with or without sump,
+                * #3: stairs midpart,
+                * #4: top of stairs (implies no sump)
+                */
+               flags[xm1] |= M_TAIL;
+               flags[x00]  = M_HEAD | M_TAIL;
+               flags[xp1] |= M_HEAD;
+
+               if (dp2 == d00) {
+                       flags[xp1] |= M_TAIL;
+                       flags[xp2] |= M_HEAD;
+               }
+               if (dm2 == d00) {
+                       flags[xm2] |= M_TAIL;
+                       flags[xm1] |= M_HEAD;
+               }
+       }
+
+       auto p_iter = poly.begin();
+       auto f_iter = flags.begin();
+       for (size_t ia = 0; ia < poly.size(); ++ia, ++p_iter, ++f_iter) {
+               auto ix = ia + 1;
+               auto ib = ix % poly.size();
+               if (!(flags[ia] & M_TAIL && flags[ib] & M_HEAD))
+                       continue;
+
+               flags[ia] &= ~M_TAIL;
+               flags[ib] &= ~M_HEAD;
+               p_iter = poly.insert(std::next(p_iter), edge{{-64, -64}, {-64, 
-64}});
+               f_iter = flags.insert(std::next(f_iter), 0);
+               ib = (ia + 2) % poly.size();
+
+               auto da = poly[ia].trivial_dir(), db = poly[ib].trivial_dir();
+               if (da == 0)
+                       --poly[ia].end_vtx.y;
+               else if (da == 90)
+                       --poly[ia].end_vtx.x;
+               else if (da == 180)
+                       ++poly[ia].end_vtx.y;
+               else if (da == 270)
+                       ++poly[ia].end_vtx.x;
+               if (db == 0)
+                       ++poly[ib].start_vtx.y;
+               else if (db == 90)
+                       ++poly[ib].start_vtx.x;
+               else if (db == 180)
+                       --poly[ib].start_vtx.y;
+               else if (db == 270)
+                       --poly[ib].start_vtx.x;
+               poly[ix].start_vtx = poly[ia].end_vtx;
+               poly[ix].end_vtx   = poly[ib].start_vtx;
+               ++ia;
+       }
+       poly.erase(std::remove_if(poly.begin(), poly.end(), [](const edge &e) {
+               return e.start_vtx == e.end_vtx;
+       }), poly.end());
+
+       p_iter = poly.begin();
+       while (p_iter != poly.cend()) {
+               auto next = std::next(p_iter);
+               if (next == poly.end())
+                       break;
+               auto d1 = p_iter->trivial_dir(), d2 = next->trivial_dir();
+               if (d1 != d2) {
+                       ++p_iter;
+                       continue;
+               }
+               p_iter->end_vtx = next->end_vtx;
+               poly.erase(next);
+       }
+}
+
+std::vector<std::vector<edge>> vectorizer::n2(const glyph &g, int desc)
+{
+       const auto &sz = g.m_size;
+       for (unsigned int y = 0; y < sz.h; ++y) {
+               int yy = sz.h - 1 - static_cast<int>(y) - desc;
+               for (unsigned int x = 0; x < sz.w; ++x) {
+                       bitpos ipos = y * sz.w + x;
+                       if (g.m_data[ipos.byte] & ipos.mask)
+                               set(x, yy);
+               }
+       }
+       finalize();
+       std::vector<std::vector<edge>> pmap;
+       while (true) {
+               /* Have all edges retian length 1 */
+               auto poly = pop_poly(0);
+               if (poly.size() == 0)
+                       break;
+               n2_angle(poly);
+               pmap.push_back(std::move(poly));
+       }
+       return pmap;
+}
+
 void font::save_sfd_glyph(FILE *fp, size_t idx, char32_t cp, int asc, int desc,
     enum vectoalg vt)
 {
@@ -944,6 +1100,8 @@
                pmap = vectorizer().simple(m_glyph[idx], desc);
        else if (vt == V_N1)
                pmap = vectorizer().n1(m_glyph[idx], desc);
+       else if (vt == V_N2)
+               pmap = vectorizer().n2(m_glyph[idx], desc);
        for (const auto &poly : pmap) {
                const auto &v1 = poly.cbegin()->start_vtx;
                fprintf(fp, "%d %d m 25\n", v1.x, v1.y);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hxtools-20200310/smm/vfalib.hpp 
new/hxtools-20200331/smm/vfalib.hpp
--- old/hxtools-20200310/smm/vfalib.hpp 2020-03-10 10:29:07.000000000 +0100
+++ new/hxtools-20200331/smm/vfalib.hpp 2020-03-31 01:25:27.000000000 +0200
@@ -80,6 +80,7 @@
 enum vectoalg {
        V_SIMPLE = 0,
        V_N1,
+       V_N2,
 };
 
 class glyph {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hxtools-20200310/smm/vfontas.cpp 
new/hxtools-20200331/smm/vfontas.cpp
--- old/hxtools-20200310/smm/vfontas.cpp        2020-03-10 10:29:07.000000000 
+0100
+++ new/hxtools-20200331/smm/vfontas.cpp        2020-03-31 01:25:27.000000000 
+0200
@@ -258,6 +258,15 @@
        return false;
 }
 
+static bool vf_saven2(font &f, char **args)
+{
+       auto ret = f.save_sfd(args[0], vectoalg::V_N2);
+       if (ret >= 0)
+               return true;
+       fprintf(stderr, "Error saving %s: %s\n", args[0], strerror(-ret));
+       return false;
+}
+
 static bool vf_setname(font &f, char **args)
 {
        f.name = args[0];
@@ -416,6 +425,7 @@
        {"savefnt", 1, vf_savefnt},
        {"savemap", 1, vf_savemap},
        {"saven1", 1, vf_saven1},
+       {"saven2", 1, vf_saven2},
        {"savepbm", 1, vf_savepbm},
        {"savepsf", 1, vf_savepsf},
        {"savesfd", 1, vf_savesfd},


Reply via email to