Hello community,

here is the log from the commit of package hxtools for openSUSE:Factory checked 
in at 2020-04-29 20:51:25
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/hxtools (Old)
 and      /work/SRC/openSUSE:Factory/.hxtools.new.2738 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "hxtools"

Wed Apr 29 20:51:25 2020 rev:39 rq:798739 version:20200428

Changes:
--------
--- /work/SRC/openSUSE:Factory/hxtools/hxtools.changes  2020-03-31 
17:16:00.531656694 +0200
+++ /work/SRC/openSUSE:Factory/.hxtools.new.2738/hxtools.changes        
2020-04-29 20:53:27.677146159 +0200
@@ -1,0 +2,10 @@
+Tue Apr 28 21:27:57 UTC 2020 - Jan Engelhardt <[email protected]>
+
+- Update to release 20200428
+  * vfontas: N2 vectorizer: cease smoothing of stub serifs
+    (concerns the topleft corner of an 'E' in some fonts)
+  * vfontas: N2 vectorizer: avoid diagonalizing "pimples" in font
+    outlines (concerns 1-pixel protrusions in the right vertical
+    edge of the '4')
+
+-------------------------------------------------------------------

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

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

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

Other differences:
------------------
++++++ hxtools.spec ++++++
--- /var/tmp/diff_new_pack.95dFXb/_old  2020-04-29 20:53:28.581148229 +0200
+++ /var/tmp/diff_new_pack.95dFXb/_new  2020-04-29 20:53:28.585148239 +0200
@@ -17,17 +17,16 @@
 
 
 Name:           hxtools
-Version:        20200331
+Version:        20200428
 Release:        0
 Summary:        Collection of day-to-day tools (binaries)
 License:        GPL-2.0+ and WTFPL
 Group:          Productivity/Other
-Url:            http://inai.de/projects/hxtools/
+Url:            https://inai.de/projects/hxtools/
 
-Source:         http://jftp.inai.de/hxtools/%name-%version.tar.xz
-Source2:        http://jftp.inai.de/hxtools/%name-%version.tar.asc
+Source:         https://inai.de/files/hxtools/%name-%version.tar.xz
+Source2:        https://inai.de/files/hxtools/%name-%version.tar.asc
 Source3:        %name.keyring
-BuildRequires:  bdftopcf
 BuildRequires:  fdupes
 BuildRequires:  gcc-c++
 BuildRequires:  libcap-devel >= 2

++++++ hxtools-20200331.tar.xz -> hxtools-20200428.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hxtools-20200331/configure 
new/hxtools-20200428/configure
--- old/hxtools-20200331/configure      2020-03-31 01:26:20.475923272 +0200
+++ new/hxtools-20200428/configure      2020-04-28 23:16:35.897024624 +0200
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for hxtools 20200331.
+# Generated by GNU Autoconf 2.69 for hxtools 20200428.
 #
 #
 # 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='20200331'
-PACKAGE_STRING='hxtools 20200331'
+PACKAGE_VERSION='20200428'
+PACKAGE_STRING='hxtools 20200428'
 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 20200331 to adapt to many kinds of systems.
+\`configure' configures hxtools 20200428 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 20200331:";;
+     short | recursive ) echo "Configuration of hxtools 20200428:";;
    esac
   cat <<\_ACEOF
 
@@ -1486,7 +1486,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-hxtools configure 20200331
+hxtools configure 20200428
 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 20200331, which was
+It was created by hxtools $as_me 20200428, 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='20200331'
+ VERSION='20200428'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -2989,6 +2989,45 @@
   fi
 fi
 
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=0;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports 
nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+       @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: 
$am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -5897,7 +5936,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 20200331, which was
+This file was extended by hxtools $as_me 20200428, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -5963,7 +6002,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 20200331
+hxtools config.status 20200428
 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-20200331/configure.ac 
new/hxtools-20200428/configure.ac
--- old/hxtools-20200331/configure.ac   2020-03-31 01:25:27.000000000 +0200
+++ new/hxtools-20200428/configure.ac   2020-04-28 22:57:45.000000000 +0200
@@ -1,8 +1,9 @@
-AC_INIT([hxtools], [20200331])
+AC_INIT([hxtools], [20200428])
 AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_HEADERS([config.h])
 AC_PROG_INSTALL
 AM_INIT_AUTOMAKE([-Wall foreign subdir-objects tar-pax no-dist-gzip dist-xz])
+m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
 AC_PROG_CC
 AM_PROG_CC_C_O
 AC_PROG_CXX
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hxtools-20200331/doc/NEWS.txt 
new/hxtools-20200428/doc/NEWS.txt
--- old/hxtools-20200331/doc/NEWS.txt   2020-03-31 01:25:27.000000000 +0200
+++ new/hxtools-20200428/doc/NEWS.txt   2020-04-28 22:57:45.000000000 +0200
@@ -1,4 +1,12 @@
 
+rel-20200428
+============
+* vfontas: N2 vectorizer: cease smoothing of stub serifs
+  (concerns the topleft corner of an 'E' in some fonts)
+* vfontas: N2 vectorizer: avoid diagonalizing "pimples" in font outlines
+  (concerns 1-pixel protrusions in the right vertical edge of the '4')
+
+
 rel-20200331
 ============
 * vfontas: add new N2 vectorizer
@@ -15,7 +23,6 @@
 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'.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hxtools-20200331/smm/vfalib.cpp 
new/hxtools-20200428/smm/vfalib.cpp
--- old/hxtools-20200331/smm/vfalib.cpp 2020-03-31 01:25:27.000000000 +0200
+++ new/hxtools-20200428/smm/vfalib.cpp 2020-04-28 22:57:45.000000000 +0200
@@ -39,11 +39,17 @@
 namespace vfalib {
 
 enum {
+       PSF1_MAGIC0 = 0x36,
+       PSF1_MAGIC1 = 0x04,
+       PSF1_MF_512 = 1 << 0,
+       PSF1_MF_TAB = 1 << 1,
+       PSF1_MF_SEQ = 1 << 2,
        PSF2_MAGIC0 = 0x72,
        PSF2_MAGIC1 = 0xB5,
        PSF2_MAGIC2 = 0x4A,
        PSF2_MAGIC3 = 0x86,
        PSF2_HAS_UNICODE_TABLE = 0x01,
+       VFA_UCS2 = 0x8000,
        PSF2_SEPARATOR = 0xFF,
        PSF2_STARTSEQ = 0xFE,
 };
@@ -66,16 +72,24 @@
 
 class vectorizer final {
        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;
+       vectorizer(const glyph &, int descent = 0);
+       std::vector<std::vector<edge>> simple();
+       std::vector<std::vector<edge>> n1();
+       std::vector<std::vector<edge>> n2(unsigned int flags = 0);
+
+       static constexpr const int scale_factor = 2;
+       static const unsigned int P_ISTHMUS = 1 << 1;
 
        private:
-       void finalize();
+       void make_squares();
+       void internal_edge_delete();
+       unsigned int neigh_edges(unsigned int dir, const vertex &, 
std::set<edge>::iterator &, std::set<edge>::iterator &) const;
+       std::set<edge>::iterator next_edge(unsigned int dir, const edge &, 
unsigned int flags) const;
        std::vector<edge> pop_poly(unsigned int flags);
        void set(int, int);
 
+       const glyph &m_glyph;
+       int m_descent = 0;
        std::set<edge> emap;
        static const unsigned int P_SIMPLIFY_LINES = 1 << 0;
 };
@@ -355,25 +369,69 @@
        return uc;
 }
 
+static char32_t nextucs2(FILE *fp)
+{
+       auto x = fgetc(fp);
+       if (x == EOF)
+               return ~0U;
+       auto y = fgetc(fp);
+       if (y == EOF)
+               return ~0U;
+       x |= y << 8;
+       return x < 0xffff ? x : ~0U;
+}
+
+static unsigned int psf_version(FILE *fp)
+{
+       uint8_t x = fgetc(fp), y = fgetc(fp);
+       if (x == PSF1_MAGIC0 && y == PSF1_MAGIC1)
+               return 1;
+       if (x != PSF2_MAGIC0 || y != PSF2_MAGIC1)
+               return 0;
+       x = fgetc(fp);
+       y = fgetc(fp);
+       return x == PSF2_MAGIC2 && y == PSF2_MAGIC3 ? 2 : 0;
+}
+
 int font::load_psf(const char *file)
 {
        std::unique_ptr<FILE, deleter> fp(fopen(file, "rb"));
        if (fp == nullptr)
                return -errno;
-       struct psf2_header hdr;
-       if (fread(&hdr, sizeof(hdr), 1, fp.get()) != 1)
-               return -errno;
-       hdr.version    = le32_to_cpu(hdr.version);
-       hdr.headersize = le32_to_cpu(hdr.headersize);
-       hdr.flags      = le32_to_cpu(hdr.flags);
-       hdr.length     = le32_to_cpu(hdr.length);
-       hdr.charsize   = le32_to_cpu(hdr.charsize);
-       hdr.height     = le32_to_cpu(hdr.height);
-       hdr.width      = le32_to_cpu(hdr.width);
-       if (hdr.magic[0] != PSF2_MAGIC0 || hdr.magic[1] != PSF2_MAGIC1 ||
-           hdr.magic[2] != PSF2_MAGIC2 || hdr.magic[3] != PSF2_MAGIC3 ||
-           hdr.version != 0)
+
+       struct psf2_header hdr{};
+       switch (psf_version(fp.get())) {
+       case 0:
                return -EINVAL;
+       case 1: {
+               auto mode = fgetc(fp.get()), charsize = fgetc(fp.get());
+               if (mode == EOF || charsize == EOF)
+                       return -EINVAL;
+               hdr.length   = (mode & PSF1_MF_512) ? 512 : 256;
+               hdr.charsize = charsize;
+               hdr.height   = charsize;
+               hdr.width    = 8;
+               hdr.flags   |= VFA_UCS2;
+               if (mode & (PSF1_MF_TAB | PSF1_MF_SEQ))
+                       hdr.flags |= PSF2_HAS_UNICODE_TABLE;
+               break;
+       }
+       case 2: {
+               if (fread(&hdr.version, sizeof(hdr) - offsetof(decltype(hdr), 
version), 1, fp.get()) != 1 ||
+                   le32_to_cpu(hdr.version) != 0)
+                       return -EINVAL;
+               hdr.version    = le32_to_cpu(hdr.version);
+               if (hdr.version != 0)
+                       return -EINVAL;
+               hdr.headersize = le32_to_cpu(hdr.headersize);
+               hdr.flags      = le32_to_cpu(hdr.flags);
+               hdr.length     = le32_to_cpu(hdr.length);
+               hdr.charsize   = le32_to_cpu(hdr.charsize);
+               hdr.height     = le32_to_cpu(hdr.height);
+               hdr.width      = le32_to_cpu(hdr.width);
+               break;
+       }
+       }
 
        std::unique_ptr<char[]> buf(new char[hdr.charsize]);
        size_t glyph_start = m_glyph.size();
@@ -386,15 +444,9 @@
        if (!(hdr.flags & PSF2_HAS_UNICODE_TABLE))
                return 0;
        m_unicode_map = std::make_shared<unicode_map>();
-       auto cd = iconv_open("UTF-32", "UTF-8");
-       if (cd == nullptr) {
-               fprintf(stderr, "iconv_open: %s\n", strerror(errno));
-               return -errno;
-       }
-       auto cdclean = make_scope_success([&]() { iconv_close(cd); });
        for (unsigned int idx = 0; idx < hdr.length; ++idx) {
                do {
-                       auto uc = nextutf8(fp.get());
+                       auto uc = hdr.flags & VFA_UCS2 ? nextucs2(fp.get()) : 
nextutf8(fp.get());
                        if (uc == ~0U)
                                break;
                        m_unicode_map->add_i2u(glyph_start + idx, uc);
@@ -721,6 +773,24 @@
        return 0;
 }
 
+static inline bool testbit_c(const glyph &g, int x, int y)
+{
+       if (x < 0 || y < 0 || x >= static_cast<int>(g.m_size.w) || y >= 
static_cast<int>(g.m_size.h))
+               return false;
+       bitpos bp = y * g.m_size.w + x;
+       return g.m_data[bp.byte] & bp.mask;
+}
+
+static inline bool testbit_u(const glyph &g, int x, int y)
+{
+       bitpos bp = y * g.m_size.w + x;
+       return g.m_data[bp.byte] & bp.mask;
+}
+
+vectorizer::vectorizer(const glyph &g, int desc) :
+       m_glyph(g), m_descent(desc)
+{}
+
 void vectorizer::set(int x, int y)
 {
        /* TTF/OTF spec wants CCW orientation */
@@ -733,7 +803,20 @@
        emap.insert(edge{{x + s, y}, {x, y}});
 }
 
-void vectorizer::finalize()
+void vectorizer::make_squares()
+{
+       const auto &sz = m_glyph.m_size;
+       for (unsigned int y = 0; y < sz.h; ++y) {
+               int yy = sz.h - 1 - static_cast<int>(y) - m_descent;
+               for (unsigned int x = 0; x < sz.w; ++x) {
+                       bitpos ipos = y * sz.w + x;
+                       if (m_glyph.m_data[ipos.byte] & ipos.mask)
+                               set(x, yy);
+               }
+       }
+}
+
+void vectorizer::internal_edge_delete()
 {
        /*
         * Remove overlaps: As enforced by set(), all the polygons are added
@@ -759,6 +842,107 @@
        }
 }
 
+/**
+ * Find the next edges (up to two) for @tail.
+ */
+unsigned int vectorizer::neigh_edges(unsigned int cur_dir, const vertex &tail,
+    std::set<edge>::iterator &inward, std::set<edge>::iterator &outward) const
+{
+       inward = emap.lower_bound({tail, {INT_MIN, INT_MIN}});
+       if (inward == emap.end() || inward->start_vtx != tail) {
+               outward = inward = emap.end();
+               return 0;
+       }
+       outward = std::next(inward); /* due to sortedness of @emap */
+       if (outward == emap.cend() || outward->start_vtx != tail) {
+               outward = emap.end();
+               return 1;
+       }
+       if (cur_dir == 0 || cur_dir == 270)
+               std::swap(inward, outward); /* order of @emap */
+       return 2;
+}
+
+std::set<edge>::iterator vectorizer::next_edge(unsigned int cur_dir,
+    const edge &cur_edge, unsigned int flags) const
+{
+       const auto &tail = cur_edge.end_vtx;
+       std::set<edge>::iterator inward, outward;
+       auto ret = neigh_edges(cur_dir, tail, inward, outward);
+       if (!(flags & P_ISTHMUS) || ret <= 1)
+               return inward;
+       /*
+        * If there are two edges with the same vertex, we have
+        * an intersection ahead (illustrative):
+        *
+        *   ##..##..  ..##..##  ####....  ....####
+        *   ..##....  ....##..  ####..##  ##..####
+        *   ##..####  ####..##  ....##..  ..##....
+        *   ....####  ####....  ..##..##  ##..##..
+        *
+        * n2_angle will work with the polygon edge we determine here, so the
+        * choice of walking direction matters.
+        *
+        * We are working with lines rather than pixels, but every edge's right
+        * side corresponds to a pixel, thereby the bitmap could be
+        * reconstructed. But since we have a reference to the bitmap anyway,
+        * it can just be checked directly.
+        *
+        * Antijoinworthy patterns:
+        *   (A1)      (A2)
+        *   ....##..  ..##....
+        *   ..##....  ####....
+        *   ##..####  ....####
+        *   ....####  ....####
+        * Joinworthy:
+        *   (J1)
+        *   ..MM....
+        *   ..MM....
+        *   ....####
+        *   ....####
+        *
+        * Right now, we are only testing for A1+A2. Might be enough...?
+        */
+       vertex bmp;
+       if (cur_dir == 0)
+               bmp = cur_edge.start_vtx;
+       else if (cur_dir == 90)
+               bmp = {cur_edge.start_vtx.x, cur_edge.start_vtx.y - 
scale_factor};
+       else if (cur_dir == 180)
+               bmp = {cur_edge.start_vtx.x - scale_factor, cur_edge.end_vtx.y};
+       else if (cur_dir == 270)
+               bmp = cur_edge.end_vtx;
+       bmp.x /= scale_factor;
+       bmp.y /= scale_factor;
+       bmp.y = m_glyph.m_size.h - bmp.y - m_descent - 1;
+
+       /* Test for pattern A1 */
+       bool up    = testbit_c(m_glyph, bmp.x, bmp.y - 2);
+       bool right = testbit_c(m_glyph, bmp.x + 2, bmp.y);
+       bool down  = testbit_c(m_glyph, bmp.x, bmp.y + 2);
+       bool left  = testbit_c(m_glyph, bmp.x - 2, bmp.y);
+       if (cur_dir == 0 && left && up)
+               return inward;
+       if (cur_dir == 90 && up && right)
+               return inward;
+       if (cur_dir == 180 && right && down)
+               return inward;
+       if (cur_dir == 270 && down && left)
+               return inward;
+
+       /* Test for pattern A2 */
+       if (cur_dir == 0 && testbit_c(m_glyph, bmp.x - 2, bmp.y - 1) && 
testbit_c(m_glyph, bmp.x - 1, bmp.y - 2))
+               return inward;
+       if (cur_dir == 90 && testbit_c(m_glyph, bmp.x + 1, bmp.y - 2) && 
testbit_c(m_glyph, bmp.x + 2, bmp.y - 1))
+               return inward;
+       if (cur_dir == 180 && testbit_c(m_glyph, bmp.x + 2, bmp.y + 1) && 
testbit_c(m_glyph, bmp.x + 1, bmp.y + 2))
+               return inward;
+       if (cur_dir == 270 && testbit_c(m_glyph, bmp.x - 2, bmp.y + 1) && 
testbit_c(m_glyph, bmp.x - 1, bmp.y + 2))
+               return inward;
+
+       return outward;
+}
+
 std::vector<edge> vectorizer::pop_poly(unsigned int flags)
 {
        std::vector<edge> poly;
@@ -774,43 +958,13 @@
                auto &tail_vtx = poly.rbegin()->end_vtx;
                if (tail_vtx == poly.cbegin()->start_vtx)
                        break;
-               auto next = emap.lower_bound({tail_vtx, {INT_MIN, INT_MIN}});
+               auto next = next_edge(prev_dir, *poly.rbegin(), flags);
                if (next == emap.cend()) {
                        fprintf(stderr, "unclosed poly wtf?!\n");
                        break;
                }
 
                /*
-                * If there are two edges from a given start vertex, prefer the
-                * edge which makes an inward curving. This makes a shape like
-                *
-                *   ######
-                *   ##  ##
-                *     ####
-                *
-                * be emitted a single polygon, rather than two (outer &
-                * enclave). The tradeoff is that fully-enclosed enclaves, e.g.
-                *
-                * ########
-                * ##  ####
-                * ####  ##
-                * ########
-                *
-                * will favor making a single polygon with self-intersection.
-                * The enclave of the number '4', when a 1-px stroke thickness
-                * is used, also ceases to be an enclave.
-                *
-                * (None of all this has an effect on rendering, just the way
-                * font editors see the outline.)
-                */
-               if (prev_dir == 0 || prev_dir == 270) {
-                       /* (Exploiting the sortedness of emap here.) */
-                       auto cand2 = std::next(next);
-                       if (cand2 != emap.cend() && cand2->start_vtx == 
tail_vtx)
-                               next = cand2;
-               }
-
-               /*
                 * Skip redundant vertices along the way to the next
                 * directional change of the outline. (Vertices are not
                 * deleted, and they are also duplicated, in case another
@@ -827,18 +981,10 @@
        return poly;
 }
 
-std::vector<std::vector<edge>> vectorizer::simple(const glyph &g, int desc)
+std::vector<std::vector<edge>> vectorizer::simple()
 {
-       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();
+       make_squares();
+       internal_edge_delete();
        std::vector<std::vector<edge>> pmap;
        while (true) {
                auto poly = pop_poly(P_SIMPLIFY_LINES);
@@ -849,25 +995,12 @@
        return pmap;
 }
 
-static inline bool testbit_c(const glyph &g, int x, int y)
-{
-       if (x < 0 || y < 0 || x >= static_cast<int>(g.m_size.w) || y >= 
static_cast<int>(g.m_size.h))
-               return false;
-       bitpos bp = y * g.m_size.w + x;
-       return g.m_data[bp.byte] & bp.mask;
-}
-
-static inline bool testbit_u(const glyph &g, int x, int y)
-{
-       bitpos bp = y * g.m_size.w + x;
-       return g.m_data[bp.byte] & bp.mask;
-}
-
-std::vector<std::vector<edge>> vectorizer::n1(const glyph &g, int desc)
+std::vector<std::vector<edge>> vectorizer::n1()
 {
+       auto &g = m_glyph;
        const auto &sz = g.m_size;
        for (unsigned int uy = 0; uy < sz.h; ++uy) {
-               int y = sz.h - 1 - static_cast<int>(uy) - desc;
+               int y = sz.h - 1 - static_cast<int>(uy) - m_descent;
                for (unsigned int ux = 0; ux < sz.w; ++ux) {
                        bitpos ipos = uy * sz.w + ux;
                        int x = ux;
@@ -917,7 +1050,7 @@
                }
        }
 
-       finalize();
+       internal_edge_delete();
        std::vector<std::vector<edge>> pmap;
        while (true) {
                auto poly = pop_poly(P_SIMPLIFY_LINES);
@@ -930,7 +1063,8 @@
 
 static void n2_angle(std::vector<edge> &poly)
 {
-       static const unsigned int M_HEAD = 0x20, M_TAIL = 0x02;
+       static const unsigned int M_HEAD = 0x20, M_TAIL = 0x02,
+               M_XHEAD = 0x10, M_XTAIL = 0x01;
        std::vector<unsigned int> flags(poly.size());
 
        for (size_t xm3 = 0; xm3 < poly.size(); ++xm3) {
@@ -956,9 +1090,15 @@
                        /* _|~|_ or ~|_|~ pattern seen */
                        if ((dm3 == d00 || dm3 == dp1) &&
                            (dp3 == d00 || dp3 == dm1) &&
-                           dm1 == (dm2 + 270) % 360 && dp1 == (dm2 + 90) % 360)
+                           dm1 == (dm2 + 270) % 360 && dp1 == (dm2 + 90) % 
360) {
                                /* pimple __|~|__ ('f', '4'), retain */
+                               flags[xm2] |= M_XTAIL;
+                               flags[xm1]  = M_XHEAD | M_XTAIL;
+                               flags[x00]  = M_XHEAD | M_XTAIL;
+                               flags[xp1]  = M_XHEAD | M_XTAIL;
+                               flags[xp2] |= M_XHEAD;
                                continue;
+                       }
 
                        if (dm1 == (dm2 + 90) % 360 && dp1 == (dm2 + 270) % 
360) {
                                /* dimple ~~|_|~~ ('8'), sink it */
@@ -984,6 +1124,15 @@
                if ((d00 + 270) % 360 != dp1 && (d00 + 90) % 360 != dp1)
                        continue;
 
+               /* #5: serif (ramp), topleft of 'E' */
+               if (dm2 == dm1 && d00 == (dm1 + 270) % 360 &&
+                   dp1 == dm1 && dp2 == (dm1 + 90) % 360 && dp3 == dp2)
+                       continue;
+               /* bottomleft 'E' */
+               if (dm3 == dm2 && dm1 == (dm2 + 90) % 360 &&
+                   d00 == (dm2 + 180) % 360 && dp1 == dm1 && dp2 == dp1)
+                       continue;
+
                /*
                 * #1: single step, with or without sump,
                 * #2: bottom of stairs, with or without sump,
@@ -1011,6 +1160,8 @@
                auto ib = ix % poly.size();
                if (!(flags[ia] & M_TAIL && flags[ib] & M_HEAD))
                        continue;
+               if ((flags[ia] & M_XTAIL) || (flags[ib] & M_XHEAD))
+                       continue;
 
                flags[ia] &= ~M_TAIL;
                flags[ib] &= ~M_HEAD;
@@ -1058,22 +1209,15 @@
        }
 }
 
-std::vector<std::vector<edge>> vectorizer::n2(const glyph &g, int desc)
+std::vector<std::vector<edge>> vectorizer::n2(unsigned int flags)
 {
-       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();
+       flags &= P_ISTHMUS;
+       make_squares();
+       internal_edge_delete();
        std::vector<std::vector<edge>> pmap;
        while (true) {
                /* Have all edges retian length 1 */
-               auto poly = pop_poly(0);
+               auto poly = pop_poly(flags);
                if (poly.size() == 0)
                        break;
                n2_angle(poly);
@@ -1097,11 +1241,13 @@
 
        std::vector<std::vector<edge>> pmap;
        if (vt == V_SIMPLE)
-               pmap = vectorizer().simple(m_glyph[idx], desc);
+               pmap = vectorizer(m_glyph[idx], desc).simple();
        else if (vt == V_N1)
-               pmap = vectorizer().n1(m_glyph[idx], desc);
+               pmap = vectorizer(m_glyph[idx], desc).n1();
        else if (vt == V_N2)
-               pmap = vectorizer().n2(m_glyph[idx], desc);
+               pmap = vectorizer(m_glyph[idx], desc).n2();
+       else if (vt == V_N2EV)
+               pmap = vectorizer(m_glyph[idx], desc).n2(vectorizer::P_ISTHMUS);
        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-20200331/smm/vfalib.hpp 
new/hxtools-20200428/smm/vfalib.hpp
--- old/hxtools-20200331/smm/vfalib.hpp 2020-03-31 01:25:27.000000000 +0200
+++ new/hxtools-20200428/smm/vfalib.hpp 2020-04-28 22:57:45.000000000 +0200
@@ -67,12 +67,14 @@
 struct vertex {
        bool operator<(const struct vertex &) const;
        bool operator==(const struct vertex &) const;
+       bool operator!=(const struct vertex &a) const { return !operator==(a); }
        int x, y;
 };
 
 struct edge {
        bool operator<(const struct edge &) const;
        bool operator==(const struct edge &) const;
+       bool operator!=(const struct edge &a) const { return !operator==(a); }
        unsigned int trivial_dir() const;
        struct vertex start_vtx, end_vtx;
 };
@@ -81,6 +83,7 @@
        V_SIMPLE = 0,
        V_N1,
        V_N2,
+       V_N2EV,
 };
 
 class glyph {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hxtools-20200331/smm/vfontas.cpp 
new/hxtools-20200428/smm/vfontas.cpp
--- old/hxtools-20200331/smm/vfontas.cpp        2020-03-31 01:25:27.000000000 
+0200
+++ new/hxtools-20200428/smm/vfontas.cpp        2020-04-28 22:57:45.000000000 
+0200
@@ -267,6 +267,15 @@
        return false;
 }
 
+static bool vf_saven2ev(font &f, char **args)
+{
+       auto ret = f.save_sfd(args[0], vectoalg::V_N2EV);
+       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];
@@ -420,12 +429,13 @@
        {"loadhex", 1, vf_loadhex},
        {"loadmap", 1, vf_loadmap},
        {"loadpsf", 1, vf_loadpsf},
-       {"savebdf", 2, vf_savebdf},
+       {"savebdf", 1, vf_savebdf},
        {"saveclt", 1, vf_saveclt},
        {"savefnt", 1, vf_savefnt},
        {"savemap", 1, vf_savemap},
        {"saven1", 1, vf_saven1},
        {"saven2", 1, vf_saven2},
+       {"saven2ev", 1, vf_saven2ev},
        {"savepbm", 1, vf_savepbm},
        {"savepsf", 1, vf_savepsf},
        {"savesfd", 1, vf_savesfd},

++++++ hxtools.keyring ++++++
--- /var/tmp/diff_new_pack.95dFXb/_old  2020-04-29 20:53:28.753148624 +0200
+++ /var/tmp/diff_new_pack.95dFXb/_new  2020-04-29 20:53:28.753148624 +0200
@@ -1,91 +1,56 @@
-pub   4096R/0xA28BDFEEB5A2B2FF 2015-05-07 [expires: 2020-08-08]
-      Key fingerprint = 2F8B FE96 D14F 8B56 0FBC  1F1D A28B DFEE B5A2 B2FF
-uid                 [ unknown] Jan Engelhardt <[email protected]>
-sub   4096R/0xB927458717B4ECED 2015-05-07 [expires: 2020-08-08]
-sub   4096R/0x6A3933DA297DFB7D 2015-05-07 [expires: 2020-08-08]
+pub   rsa4096/0xD6388181F35A0938 2020-04-28 [SC] [expires: 2025-06-01]
+      Key fingerprint = 2368 6C10 A456 91BE 7A42  5109 D638 8181 F35A 0938
+uid                   [ultimate] Jan Engelhardt <[email protected]>
 
 -----BEGIN PGP PUBLIC KEY BLOCK-----
 
-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
-cCAy
-=ePMx
+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
+NGTT6x12
+=QLsa
 -----END PGP PUBLIC KEY BLOCK-----


Reply via email to