Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "texception.h"
Toshihiro Shimizu 890ddd
#include "toonz/autoclose.h"
Toshihiro Shimizu 890ddd
#include "trastercm.h"
Toshihiro Shimizu 890ddd
#include "skeletonlut.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define AUT_SPOT_SAMPLES 10
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace SkeletonLut;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TAutocloser::Imp {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  struct Seed {
Shinya Kitaoka 120a6e
    UCHAR *m_ptr;
Shinya Kitaoka 120a6e
    UCHAR m_preseed;
Shinya Kitaoka 120a6e
    Seed(UCHAR *ptr, UCHAR preseed) : m_ptr(ptr), m_preseed(preseed) {}
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int m_closingDistance;
Shinya Kitaoka 120a6e
  double m_spotAngle;
Shinya Kitaoka 120a6e
  int m_inkIndex;
Shinya Kitaoka 120a6e
  int m_opacity;
Shinya Kitaoka 120a6e
  TRasterP m_raster;
Shinya Kitaoka 120a6e
  TRasterGR8P m_bRaster;
Shinya Kitaoka 120a6e
  UCHAR *m_br;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int m_bWrap;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int m_displaceVector[8];
Shinya Kitaoka 120a6e
  TPointD m_displAverage;
Shinya Kitaoka 120a6e
  int m_visited;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double m_csp, m_snp, m_csm, m_snm, m_csa, m_sna, m_csb, m_snb;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Imp(const TRasterP &r, int distance = 10, double angle = M_PI_2,
Shinya Kitaoka 120a6e
      int index = 0, int opacity = 0)
Shinya Kitaoka 120a6e
      : m_raster(r)
Shinya Kitaoka 120a6e
      , m_spotAngle(angle)
Shinya Kitaoka 120a6e
      , m_closingDistance(distance)
Shinya Kitaoka 120a6e
      , m_inkIndex(index)
Shinya Kitaoka 120a6e
      , m_opacity(opacity) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~Imp() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool inline isInk(UCHAR *br) { return (*br) & 0x1; }
Shinya Kitaoka 120a6e
  inline void eraseInk(UCHAR *br) { *(br) &= 0xfe; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UCHAR inline ePix(UCHAR *br) { return (*(br + 1)); }
Shinya Kitaoka 120a6e
  UCHAR inline wPix(UCHAR *br) { return (*(br - 1)); }
Shinya Kitaoka 120a6e
  UCHAR inline nPix(UCHAR *br) { return (*(br + m_bWrap)); }
Shinya Kitaoka 120a6e
  UCHAR inline sPix(UCHAR *br) { return (*(br - m_bWrap)); }
Shinya Kitaoka 120a6e
  UCHAR inline swPix(UCHAR *br) { return (*(br - m_bWrap - 1)); }
Shinya Kitaoka 120a6e
  UCHAR inline nwPix(UCHAR *br) { return (*(br + m_bWrap - 1)); }
Shinya Kitaoka 120a6e
  UCHAR inline nePix(UCHAR *br) { return (*(br + m_bWrap + 1)); }
Shinya Kitaoka 120a6e
  UCHAR inline sePix(UCHAR *br) { return (*(br - m_bWrap + 1)); }
Shinya Kitaoka 120a6e
  UCHAR inline neighboursCode(UCHAR *seed) {
Shinya Kitaoka 120a6e
    return ((swPix(seed) & 0x1) | ((sPix(seed) & 0x1) << 1) |
Shinya Kitaoka 120a6e
            ((sePix(seed) & 0x1) << 2) | ((wPix(seed) & 0x1) << 3) |
Shinya Kitaoka 120a6e
            ((ePix(seed) & 0x1) << 4) | ((nwPix(seed) & 0x1) << 5) |
Shinya Kitaoka 120a6e
            ((nPix(seed) & 0x1) << 6) | ((nePix(seed) & 0x1) << 7));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //.......................
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  inline bool notMarkedBorderInk(UCHAR *br) {
Shinya Kitaoka 120a6e
    return ((((*br) & 0x5) == 1) &&
Shinya Kitaoka 120a6e
            (ePix(br) == 0 || wPix(br) == 0 || nPix(br) == 0 || sPix(br) == 0));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //.......................
Shinya Kitaoka 120a6e
  UCHAR *getPtr(int x, int y) { return m_br + m_bWrap * y + x; }
Shinya Kitaoka 120a6e
  UCHAR *getPtr(const TPoint &p) { return m_br + m_bWrap * p.y + p.x; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPoint getCoordinates(UCHAR *br) {
Shinya Kitaoka 120a6e
    TPoint p;
Shinya Kitaoka 120a6e
    int pixelCount = br - m_bRaster->getRawData();
Shinya Kitaoka 120a6e
    p.y            = pixelCount / m_bWrap;
Shinya Kitaoka 120a6e
    p.x            = pixelCount - p.y * m_bWrap;
Shinya Kitaoka 120a6e
    return p;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //.......................
Shinya Kitaoka 120a6e
  void compute(std::vector<segment> &closingSegmentArray);</segment>
Shinya Kitaoka 120a6e
  void draw(const std::vector<segment> &closingSegmentArray);</segment>
Shinya Kitaoka 120a6e
  void skeletonize(std::vector<tpoint> &endpoints);</tpoint>
Shinya Kitaoka 120a6e
  void findSeeds(std::vector<seed> &seeds, std::vector<tpoint> &endpoints);</tpoint></seed>
Shinya Kitaoka 120a6e
  void erase(std::vector<seed> &seeds, std::vector<tpoint> &endpoints);</tpoint></seed>
Shinya Kitaoka 120a6e
  void circuitAndMark(UCHAR *seed, UCHAR preseed);
Shinya Kitaoka 120a6e
  bool circuitAndCancel(UCHAR *seed, UCHAR preseed,
Shinya Kitaoka 120a6e
                        std::vector<tpoint> &endpoints);</tpoint>
Shinya Kitaoka 120a6e
  void findMeetingPoints(std::vector<tpoint> &endpoints,</tpoint>
Shinya Kitaoka 120a6e
                         std::vector<segment> &closingSegments);</segment>
Shinya Kitaoka 120a6e
  void calculateWeightAndDirection(std::vector<segment> &orientedEndpoints);</segment>
Shinya Kitaoka 120a6e
  bool spotResearchTwoPoints(std::vector<segment> &endpoints,</segment>
Shinya Kitaoka 120a6e
                             std::vector<segment> &closingSegments);</segment>
Shinya Kitaoka 120a6e
  bool spotResearchOnePoint(std::vector<segment> &endpoints,</segment>
Shinya Kitaoka 120a6e
                            std::vector<segment> &closingSegments);</segment>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void copy(const TRasterGR8P &braux, TRaster32P &raux);
Shinya Kitaoka 120a6e
  int exploreTwoSpots(const TAutocloser::Segment &s0,
Shinya Kitaoka 120a6e
                      const TAutocloser::Segment &s1);
Shinya Kitaoka 120a6e
  int notInsidePath(const TPoint &p, const TPoint &q);
Shinya Kitaoka 120a6e
  void drawInByteRaster(const TPoint &p0, const TPoint &p1);
Shinya Kitaoka 120a6e
  TPoint visitEndpoint(UCHAR *br);
Shinya Kitaoka 120a6e
  bool exploreSpot(const Segment &s, TPoint &p);
Shinya Kitaoka 120a6e
  bool exploreRay(UCHAR *br, Segment s, TPoint &p);
Shinya Kitaoka 120a6e
  void visitPix(UCHAR *br, int toVisit, const TPoint &dis);
Shinya Kitaoka 120a6e
  void cancelMarks(UCHAR *br);
Shinya Kitaoka 120a6e
  void cancelFromArray(std::vector<segment> &array, TPoint p, int &count);</segment>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#define DRAW_SEGMENT(a, b, da, db, istr1, istr2, block)                        \
Shinya Kitaoka 120a6e
  {                                                                            \
Shinya Kitaoka 120a6e
    d      = 2 * db - da;                                                      \
Shinya Kitaoka 120a6e
    incr_1 = 2 * db;                                                           \
Shinya Kitaoka 120a6e
    incr_2 = 2 * (db - da);                                                    \
Shinya Kitaoka 120a6e
    while (a < da) {                                                           \
Shinya Kitaoka 120a6e
      if (d <= 0) {                                                            \
Shinya Kitaoka 120a6e
        d += incr_1;                                                           \
Shinya Kitaoka 120a6e
        a++;                                                                   \
Shinya Kitaoka 120a6e
        istr1;                                                                 \
Shinya Kitaoka 120a6e
      } else {                                                                 \
Shinya Kitaoka 120a6e
        d += incr_2;                                                           \
Shinya Kitaoka 120a6e
        a++;                                                                   \
Shinya Kitaoka 120a6e
        b++;                                                                   \
Shinya Kitaoka 120a6e
        istr2;                                                                 \
Shinya Kitaoka 120a6e
      }                                                                        \
Shinya Kitaoka 120a6e
      block;                                                                   \
Shinya Kitaoka 120a6e
    }                                                                          \
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#define EXPLORE_RAY_ISTR(istr)                                                 \
Shinya Kitaoka 120a6e
  if (!inside_ink) {                                                           \
Shinya Kitaoka 120a6e
    if (((*br) & 0x1) && !((*br) & 0x80)) {                                    \
Shinya Kitaoka 120a6e
      p.x = istr;                                                              \
Shinya Kitaoka 120a6e
      p.y = (s.first.y < s.second.y) ? s.first.y + y : s.first.y - y;          \
Shinya Kitaoka 120a6e
      return true;                                                             \
Shinya Kitaoka 120a6e
    }                                                                          \
Shinya Kitaoka 120a6e
  } else if (inside_ink && !((*br) & 0x1))                                     \
Shinya Kitaoka 120a6e
    inside_ink = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline bool isInk(const TPixel32 &pix) { return pix.r < 80; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRasterGR8P fillByteRaster(const TRasterCM32P &r, TRasterGR8P &bRaster) {
Shinya Kitaoka 120a6e
  int i, j;
Shinya Kitaoka 120a6e
  int lx = r->getLx();
Shinya Kitaoka 120a6e
  int ly = r->getLy();
Shinya Kitaoka 120a6e
  // bRaster->create(lx+4, ly+4);
Shinya Kitaoka 120a6e
  UCHAR *br = bRaster->getRawData();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < lx + 4; i++) *(br++) = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < lx + 4; i++) *(br++) = 131;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < ly; i++) {
Shinya Kitaoka 120a6e
    *(br++)         = 0;
Shinya Kitaoka 120a6e
    *(br++)         = 131;
Shinya Kitaoka 120a6e
    TPixelCM32 *pix = r->pixels(i);
Shinya Kitaoka 120a6e
    for (j = 0; j < lx; j++, pix++) {
Shinya Kitaoka 120a6e
      if (pix->getTone() != pix->getMaxTone())
Shinya Kitaoka 120a6e
        *(br++) = 3;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        *(br++) = 0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    *(br++) = 131;
Shinya Kitaoka 120a6e
    *(br++) = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < lx + 4; i++) *(br++) = 131;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < lx + 4; i++) *(br++) = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return bRaster;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#define SET_INK                                                                \
Shinya Kitaoka 120a6e
  if (buf->getTone() == buf->getMaxTone())                                     \
Shinya Kitaoka 120a6e
    *buf = TPixelCM32(inkIndex, 0, 255 - opacity);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void drawSegment(TRasterCM32P &r, const TAutocloser::Segment &s,
Shinya Kitaoka 120a6e
                 USHORT inkIndex, USHORT opacity) {
Shinya Kitaoka 120a6e
  int wrap        = r->getWrap();
Shinya Kitaoka 120a6e
  TPixelCM32 *buf = r->pixels();
Shinya Kitaoka 120a6e
  /*
Toshihiro Shimizu 890ddd
int i, j;
Toshihiro Shimizu 890ddd
for (i=0; i<r->getLy();i++)</r->
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
  for (j=0; j<r->getLx();j++, buf++)</r->
Shinya Kitaoka 120a6e
*buf = (1<<4)|0xf;
Shinya Kitaoka 120a6e
buf += wrap-r->getLx();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
return;
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int x, y, dx, dy, d, incr_1, incr_2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int x1 = s.first.x;
Shinya Kitaoka 120a6e
  int y1 = s.first.y;
Shinya Kitaoka 120a6e
  int x2 = s.second.x;
Shinya Kitaoka 120a6e
  int y2 = s.second.y;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (x1 > x2) {
Shinya Kitaoka 120a6e
    tswap(x1, x2);
Shinya Kitaoka 120a6e
    tswap(y1, y2);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  buf += y1 * wrap + x1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  dx = x2 - x1;
Shinya Kitaoka 120a6e
  dy = y2 - y1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  x = y = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (dy >= 0) {
Shinya Kitaoka 120a6e
    if (dy <= dx)
Shinya Kitaoka 120a6e
      DRAW_SEGMENT(x, y, dx, dy, (buf++), (buf += wrap + 1), SET_INK)
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      DRAW_SEGMENT(y, x, dy, dx, (buf += wrap), (buf += wrap + 1), SET_INK)
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    dy = -dy;
Shinya Kitaoka 120a6e
    if (dy <= dx)
Shinya Kitaoka 120a6e
      DRAW_SEGMENT(x, y, dx, dy, (buf++), (buf -= (wrap - 1)), SET_INK)
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      DRAW_SEGMENT(y, x, dy, dx, (buf -= wrap), (buf -= (wrap - 1)), SET_INK)
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TAutocloser::Imp::compute(std::vector<segment> &closingSegmentArray) {</segment>
Shinya Kitaoka 120a6e
  std::vector<tpoint> endpoints;</tpoint>
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    assert(closingSegmentArray.empty());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TRasterCM32P raux;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (!(raux = (TRasterCM32P)m_raster))
Shinya Kitaoka 120a6e
      throw TException("Unable to autoclose a not CM32 image.");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (m_raster->getLx() == 0 || m_raster->getLy() == 0)
Shinya Kitaoka 120a6e
      throw TException("Autoclose error: bad image size");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // Lx = r->lx;
Shinya Kitaoka 120a6e
    // Ly = r->ly;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TRasterGR8P braux(raux->getLx() + 4, raux->getLy() + 4);
Shinya Kitaoka 120a6e
    braux->lock();
Shinya Kitaoka 120a6e
    fillByteRaster(raux, braux);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TRect r(2, 2, braux->getLx() - 3, braux->getLy() - 3);
Shinya Kitaoka 120a6e
    m_bRaster = braux->extract(r);
Shinya Kitaoka 120a6e
    m_br      = m_bRaster->getRawData();
Shinya Kitaoka 120a6e
    m_bWrap   = m_bRaster->getWrap();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_displaceVector[0] = -m_bWrap - 1;
Shinya Kitaoka 120a6e
    m_displaceVector[1] = -m_bWrap;
Shinya Kitaoka 120a6e
    m_displaceVector[2] = -m_bWrap + 1;
Shinya Kitaoka 120a6e
    m_displaceVector[3] = -1;
Shinya Kitaoka 120a6e
    m_displaceVector[4] = +1;
Shinya Kitaoka 120a6e
    m_displaceVector[5] = m_bWrap - 1;
Shinya Kitaoka 120a6e
    m_displaceVector[6] = m_bWrap;
Shinya Kitaoka 120a6e
    m_displaceVector[7] = m_bWrap + 1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    skeletonize(endpoints);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    findMeetingPoints(endpoints, closingSegmentArray);
Shinya Kitaoka 120a6e
    // copy(m_bRaster, raux);
Shinya Kitaoka 120a6e
    braux->unlock();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  catch (TException &e) {
Shinya Kitaoka 120a6e
    throw e;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TAutocloser::Imp::draw(const std::vector<segment> &closingSegmentArray) {</segment>
Shinya Kitaoka 120a6e
  TRasterCM32P raux;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!(raux = (TRasterCM32P)m_raster))
Shinya Kitaoka 120a6e
    throw TException("Unable to autoclose a not CM32 image.");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_raster->getLx() == 0 || m_raster->getLy() == 0)
Shinya Kitaoka 120a6e
    throw TException("Autoclose error: bad image size");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int i = 0; i < (int)closingSegmentArray.size(); i++)
Shinya Kitaoka 120a6e
    drawSegment(raux, closingSegmentArray[i], m_inkIndex, m_opacity);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TAutocloser::Imp::copy(const TRasterGR8P &br, TRaster32P &r) {
Shinya Kitaoka 120a6e
  assert(r->getLx() == br->getLx() && r->getLy() == br->getLy());
Shinya Kitaoka 120a6e
  int i, j;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int lx = r->getLx();
Shinya Kitaoka 120a6e
  int ly = r->getLy();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UCHAR *bbuf = br->getRawData();
Shinya Kitaoka 120a6e
  TPixel *buf = (TPixel *)r->getRawData();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < ly; i++) {
Shinya Kitaoka 120a6e
    for (j = 0; j < lx; j++, buf++, bbuf++) {
Shinya Kitaoka 120a6e
      buf->m = 255;
Shinya Kitaoka 120a6e
      if ((*bbuf) & 0x40)
Shinya Kitaoka 120a6e
        buf->r = 255, buf->g = buf->b = 0;
Shinya Kitaoka 120a6e
      else if (isInk(bbuf))
Shinya Kitaoka 120a6e
        buf->r = buf->g = buf->b = 0;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        buf->r = buf->g = buf->b = 255;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    buf += r->getWrap() - lx;
Shinya Kitaoka 120a6e
    bbuf += br->getWrap() - lx;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*=============================================================================*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int intersect_segment(int x1, int y1, int x2, int y2, int i, double *ris) {
Shinya Kitaoka 120a6e
  if ((i < std::min(y1, y2)) || (i > std::max(y1, y2)) || (y1 == y2)) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  *ris = ((double)((x1 - x2) * (i - y2)) / (double)(y1 - y2) + x2);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*=============================================================================*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline int distance2(const TPoint p0, const TPoint p1) {
Shinya Kitaoka 120a6e
  return (p0.x - p1.x) * (p0.x - p1.x) + (p0.y - p1.y) * (p0.y - p1.y);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*=============================================================================*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int closerPoint(const std::vector<tautocloser::segment> &points,</tautocloser::segment>
Shinya Kitaoka 120a6e
                std::vector<bool> &marks, int index) {</bool>
Shinya Kitaoka 120a6e
  assert(points.size() == marks.size());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int min, curr;
Shinya Kitaoka 120a6e
  int minval = (std::numeric_limits<int>::max)();</int>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  min = index + 1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (curr = index + 1; curr < (int)points.size(); curr++)
Shinya Kitaoka 120a6e
    if (!(marks[curr])) {
Shinya Kitaoka 120a6e
      int distance = distance2(points[index].first, points[curr].first);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (distance < minval) {
Shinya Kitaoka 120a6e
        minval = distance;
Shinya Kitaoka 120a6e
        min    = curr;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  marks[min] = true;
Shinya Kitaoka 120a6e
  return min;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int intersect_triangle(int x1a, int y1a, int x2a, int y2a, int x3a, int y3a,
Shinya Kitaoka 120a6e
                       int x1b, int y1b, int x2b, int y2b, int x3b, int y3b) {
Shinya Kitaoka 120a6e
  int minx, maxx, miny, maxy, i;
Shinya Kitaoka 120a6e
  double xamin, xamax, xbmin, xbmax, val;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  miny = std::max(std::min({y1a, y2a, y3a}), std::min({y1b, y2b, y3b}));
Shinya Kitaoka 120a6e
  maxy = std::min(std::max({y1a, y2a, y3a}), std::max({y1b, y2b, y3b}));
Shinya Kitaoka 120a6e
  if (maxy < miny) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  minx = std::max(std::min({x1a, x2a, x3a}), std::min({x1b, x2b, x3b}));
Shinya Kitaoka 120a6e
  maxx = std::min(std::max({x1a, x2a, x3a}), std::max({x1b, x2b, x3b}));
Shinya Kitaoka 120a6e
  if (maxx < minx) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = miny; i <= maxy; i++) {
Shinya Kitaoka 120a6e
    xamin = xamax = xbmin = xbmax = 0.0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    intersect_segment(x1a, y1a, x2a, y2a, i, &xamin);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (intersect_segment(x1a, y1a, x3a, y3a, i, &val))
Shinya Kitaoka 120a6e
      if (xamin)
Shinya Kitaoka 120a6e
        xamax = val;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        xamin = val;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (!xamax) intersect_segment(x2a, y2a, x3a, y3a, i, &xamax);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (xamax < xamin) {
Shinya Kitaoka 120a6e
      val = xamin, xamin = xamax, xamax = val;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    intersect_segment(x1b, y1b, x2b, y2b, i, &xbmin);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (intersect_segment(x1b, y1b, x3b, y3b, i, &val))
Shinya Kitaoka 120a6e
      if (xbmin)
Shinya Kitaoka 120a6e
        xbmax = val;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        xbmin = val;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (!xbmax) intersect_segment(x2b, y2b, x3b, y3b, i, &xbmax);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (xbmax < xbmin) {
Shinya Kitaoka 120a6e
      val = xbmin, xbmin = xbmax, xbmax = val;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (!((tceil(xamax) < tfloor(xbmin)) || (tceil(xbmax) < tfloor(xamin))))
Shinya Kitaoka 120a6e
      return 1;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TAutocloser::Imp::notInsidePath(const TPoint &p, const TPoint &q) {
Shinya Kitaoka 120a6e
  int tmp, x, y, dx, dy, d, incr_1, incr_2;
Shinya Kitaoka 120a6e
  int x1, y1, x2, y2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  x1 = p.x;
Shinya Kitaoka 120a6e
  y1 = p.y;
Shinya Kitaoka 120a6e
  x2 = q.x;
Shinya Kitaoka 120a6e
  y2 = q.y;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (x1 > x2) {
Shinya Kitaoka 120a6e
    tmp = x1, x1 = x2, x2 = tmp;
Shinya Kitaoka 120a6e
    tmp = y1, y1 = y2, y2 = tmp;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  UCHAR *br = getPtr(x1, y1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  dx = x2 - x1;
Shinya Kitaoka 120a6e
  dy = y2 - y1;
Shinya Kitaoka 120a6e
  x = y = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (dy >= 0) {
Shinya Kitaoka 120a6e
    if (dy <= dx)
Shinya Kitaoka 120a6e
      DRAW_SEGMENT(x, y, dx, dy, (br++), (br += m_bWrap + 1),
Shinya Kitaoka 120a6e
                   if (!((*br) & 0x2)) return true)
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      DRAW_SEGMENT(y, x, dy, dx, (br += m_bWrap), (br += m_bWrap + 1),
Shinya Kitaoka 120a6e
                   if (!((*br) & 0x2)) return true)
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    dy = -dy;
Shinya Kitaoka 120a6e
    if (dy <= dx)
Shinya Kitaoka 120a6e
      DRAW_SEGMENT(x, y, dx, dy, (br++), (br -= m_bWrap - 1),
Shinya Kitaoka 120a6e
                   if (!((*br) & 0x2)) return true)
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      DRAW_SEGMENT(y, x, dy, dx, (br -= m_bWrap), (br -= m_bWrap - 1),
Shinya Kitaoka 120a6e
                   if (!((*br) & 0x2)) return true)
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TAutocloser::Imp::exploreTwoSpots(const TAutocloser::Segment &s0,
Shinya Kitaoka 120a6e
                                      const TAutocloser::Segment &s1) {
Shinya Kitaoka 120a6e
  int x1a, y1a, x2a, y2a, x3a, y3a, x1b, y1b, x2b, y2b, x3b, y3b;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  x1a = s0.first.x;
Shinya Kitaoka 120a6e
  y1a = s0.first.y;
Shinya Kitaoka 120a6e
  x1b = s1.first.x;
Shinya Kitaoka 120a6e
  y1b = s1.first.y;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPoint p0aux = s0.second;
Shinya Kitaoka 120a6e
  TPoint p1aux = s1.second;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (x1a == p0aux.x && y1a == p0aux.y) return 0;
Shinya Kitaoka 120a6e
  if (x1b == p1aux.x && y1b == p1aux.y) return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  x2a = tround(x1a + (p0aux.x - x1a) * m_csp - (p0aux.y - y1a) * m_snp);
Shinya Kitaoka 120a6e
  y2a = tround(y1a + (p0aux.x - x1a) * m_snp + (p0aux.y - y1a) * m_csp);
Shinya Kitaoka 120a6e
  x3a = tround(x1a + (p0aux.x - x1a) * m_csm - (p0aux.y - y1a) * m_snm);
Shinya Kitaoka 120a6e
  y3a = tround(y1a + (p0aux.x - x1a) * m_snm + (p0aux.y - y1a) * m_csm);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  x2b = tround(x1b + (p1aux.x - x1b) * m_csp - (p1aux.y - y1b) * m_snp);
Shinya Kitaoka 120a6e
  y2b = tround(y1b + (p1aux.x - x1b) * m_snp + (p1aux.y - y1b) * m_csp);
Shinya Kitaoka 120a6e
  x3b = tround(x1b + (p1aux.x - x1b) * m_csm - (p1aux.y - y1b) * m_snm);
Shinya Kitaoka 120a6e
  y3b = tround(y1b + (p1aux.x - x1b) * m_snm + (p1aux.y - y1b) * m_csm);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return (intersect_triangle(x1a, y1a, p0aux.x, p0aux.y, x2a, y2a, x1b, y1b,
Shinya Kitaoka 120a6e
                             p1aux.x, p1aux.y, x2b, y2b) ||
Shinya Kitaoka 120a6e
          intersect_triangle(x1a, y1a, p0aux.x, p0aux.y, x3a, y3a, x1b, y1b,
Shinya Kitaoka 120a6e
                             p1aux.x, p1aux.y, x2b, y2b) ||
Shinya Kitaoka 120a6e
          intersect_triangle(x1a, y1a, p0aux.x, p0aux.y, x2a, y2a, x1b, y1b,
Shinya Kitaoka 120a6e
                             p1aux.x, p1aux.y, x3b, y3b) ||
Shinya Kitaoka 120a6e
          intersect_triangle(x1a, y1a, p0aux.x, p0aux.y, x3a, y3a, x1b, y1b,
Shinya Kitaoka 120a6e
                             p1aux.x, p1aux.y, x3b, y3b));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TAutocloser::Imp::findMeetingPoints(
Shinya Kitaoka 120a6e
    std::vector<tpoint> &endpoints, std::vector<segment> &closingSegments) {</segment></tpoint>
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  double alfa;
Shinya Kitaoka 120a6e
  alfa  = m_spotAngle / AUT_SPOT_SAMPLES;
Shinya Kitaoka 120a6e
  m_csp = cos(m_spotAngle / 5);
Shinya Kitaoka 120a6e
  m_snp = sin(m_spotAngle / 5);
Shinya Kitaoka 120a6e
  m_csm = cos(-m_spotAngle / 5);
Shinya Kitaoka 120a6e
  m_snm = sin(-m_spotAngle / 5);
Shinya Kitaoka 120a6e
  m_csa = cos(alfa);
Shinya Kitaoka 120a6e
  m_sna = sin(alfa);
Shinya Kitaoka 120a6e
  m_csb = cos(-alfa);
Shinya Kitaoka 120a6e
  m_snb = sin(-alfa);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<segment> orientedEndpoints(endpoints.size());</segment>
Shinya Kitaoka 120a6e
  for (i                       = 0; i < (int)endpoints.size(); i++)
Shinya Kitaoka 120a6e
    orientedEndpoints[i].first = endpoints[i];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int size = -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while ((int)closingSegments.size() > size && !orientedEndpoints.empty()) {
Shinya Kitaoka 120a6e
    size = closingSegments.size();
Shinya Kitaoka 120a6e
    do
Shinya Kitaoka 120a6e
      calculateWeightAndDirection(orientedEndpoints);
Shinya Kitaoka 120a6e
    while (spotResearchTwoPoints(orientedEndpoints, closingSegments));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    do
Shinya Kitaoka 120a6e
      calculateWeightAndDirection(orientedEndpoints);
Shinya Kitaoka 120a6e
    while (spotResearchOnePoint(orientedEndpoints, closingSegments));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Campbell Barton b3bd84
static bool allMarked(const std::vector<bool> &marks, int index) {</bool>
Shinya Kitaoka 120a6e
  int i;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = index + 1; i < (int)marks.size(); i++)
Shinya Kitaoka 120a6e
    if (!marks[i]) return false;
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TAutocloser::Imp::spotResearchTwoPoints(
Shinya Kitaoka 120a6e
    std::vector<segment> &endpoints, std::vector<segment> &closingSegments) {</segment></segment>
Shinya Kitaoka 120a6e
  int i, distance, current = 0, closerIndex;
Shinya Kitaoka 120a6e
  int sqrDistance = m_closingDistance * m_closingDistance;
Shinya Kitaoka 120a6e
  bool found      = 0;
Shinya Kitaoka 120a6e
  std::vector<bool> marks(endpoints.size());</bool>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (current < (int)endpoints.size() - 1) {
Shinya Kitaoka 120a6e
    found = 0;
Shinya Kitaoka 120a6e
    for (i = current + 1; i < (int)marks.size(); i++) marks[i] = false;
Shinya Kitaoka 120a6e
    distance                                                   = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    while (!found && (distance <= sqrDistance) && !allMarked(marks, current)) {
Shinya Kitaoka 120a6e
      closerIndex = closerPoint(endpoints, marks, current);
Shinya Kitaoka 120a6e
      if (exploreTwoSpots(endpoints[current], endpoints[closerIndex]) &&
Shinya Kitaoka 120a6e
          notInsidePath(endpoints[current].first,
Shinya Kitaoka 120a6e
                        endpoints[closerIndex].first)) {
Shinya Kitaoka 120a6e
        drawInByteRaster(endpoints[current].first,
Shinya Kitaoka 120a6e
                         endpoints[closerIndex].first);
Shinya Kitaoka 120a6e
        closingSegments.push_back(
Shinya Kitaoka 120a6e
            Segment(endpoints[current].first, endpoints[closerIndex].first));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (!EndpointTable[neighboursCode(
Shinya Kitaoka 120a6e
                getPtr(endpoints[closerIndex].first))]) {
Shinya Kitaoka 120a6e
          std::vector<segment>::iterator it = endpoints.begin();</segment>
Shinya Kitaoka 120a6e
          std::advance(it, closerIndex);
Shinya Kitaoka 120a6e
          endpoints.erase(it);
Shinya Kitaoka 120a6e
          std::vector<bool>::iterator it1 = marks.begin();</bool>
Shinya Kitaoka 120a6e
          std::advance(it1, closerIndex);
Shinya Kitaoka 120a6e
          marks.erase(it1);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        found = true;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (found) {
Shinya Kitaoka 120a6e
      std::vector<segment>::iterator it = endpoints.begin();</segment>
Shinya Kitaoka 120a6e
      std::advance(it, current);
Shinya Kitaoka 120a6e
      endpoints.erase(it);
Shinya Kitaoka 120a6e
      std::vector<bool>::iterator it1 = marks.begin();</bool>
Shinya Kitaoka 120a6e
      std::advance(it1, current);
Shinya Kitaoka 120a6e
      marks.erase(it1);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      current++;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return found;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
static void clear_marks(POINT *p)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
while (p)
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
  p->mark = 0;
Toshihiro Shimizu 890ddd
  p = p->next;
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int there_are_unmarked(POINT *p)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
while (p)
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
  if (!p->mark) return 1;
Toshihiro Shimizu 890ddd
  p = p->next;
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TAutocloser::Imp::calculateWeightAndDirection(
Shinya Kitaoka 120a6e
    std::vector<segment> &orientedEndpoints) {</segment>
Shinya Kitaoka 120a6e
  // UCHAR *br;
Shinya Kitaoka 120a6e
  int lx = m_raster->getLx();
Shinya Kitaoka 120a6e
  int ly = m_raster->getLy();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<segment>::iterator it = orientedEndpoints.begin();</segment>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (it != orientedEndpoints.end()) {
Shinya Kitaoka 120a6e
    TPoint p0  = it->first;
Shinya Kitaoka 120a6e
    TPoint &p1 = it->second;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // br = (UCHAR *)m_bRaster->pixels(p0.y)+p0.x;
Shinya Kitaoka 120a6e
    // code = neighboursCode(br);
Shinya Kitaoka 120a6e
    /*if (!EndpointTable[code])
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
it = orientedEndpoints.erase(it);
Shinya Kitaoka 120a6e
continue;
Shinya Kitaoka 120a6e
}*/
Shinya Kitaoka 120a6e
    TPoint displAverage = visitEndpoint(getPtr(p0));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    p1 = p0 - displAverage;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*if ((point->x2<0 && point->y2<0) || (point->x2>Lx && point->y2>Ly))
Shinya Kitaoka 120a6e
     * printf("che palle!!!!!!\n");*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (p1.x < 0) {
Shinya Kitaoka 120a6e
      p1.y = tround(p0.y - (float)((p0.y - p1.y) * p0.x) / (p0.x - p1.x));
Shinya Kitaoka 120a6e
      p1.x = 0;
Shinya Kitaoka 120a6e
    } else if (p1.x > lx) {
Shinya Kitaoka 120a6e
      p1.y =
Shinya Kitaoka 120a6e
          tround(p0.y - (float)((p0.y - p1.y) * (p0.x - lx)) / (p0.x - p1.x));
Shinya Kitaoka 120a6e
      p1.x = lx;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (p1.y < 0) {
Shinya Kitaoka 120a6e
      p1.x = tround(p0.x - (float)((p0.x - p1.x) * p0.y) / (p0.y - p1.y));
Shinya Kitaoka 120a6e
      p1.y = 0;
Shinya Kitaoka 120a6e
    } else if (p1.y > ly) {
Shinya Kitaoka 120a6e
      p1.x =
Shinya Kitaoka 120a6e
          tround(p0.x - (float)((p0.x - p1.x) * (p0.y - ly)) / (p0.y - p1.y));
Shinya Kitaoka 120a6e
      p1.y = ly;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    it++;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TAutocloser::Imp::spotResearchOnePoint(
Shinya Kitaoka 120a6e
    std::vector<segment> &endpoints, std::vector<segment> &closingSegments) {</segment></segment>
Shinya Kitaoka 120a6e
  int count = 0;
Shinya Kitaoka 120a6e
  bool ret  = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (count < (int)endpoints.size()) {
Shinya Kitaoka 120a6e
    TPoint p;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (exploreSpot(endpoints[count], p)) {
Shinya Kitaoka 120a6e
      Segment segment(endpoints[count].first, p);
Shinya Kitaoka 120a6e
      std::vector<segment>::iterator it =</segment>
Shinya Kitaoka 120a6e
          std::find(closingSegments.begin(), closingSegments.end(), segment);
Shinya Kitaoka 120a6e
      if (it == closingSegments.end()) {
Shinya Kitaoka 120a6e
        ret = true;
Shinya Kitaoka 120a6e
        drawInByteRaster(endpoints[count].first, p);
Shinya Kitaoka 120a6e
        closingSegments.push_back(Segment(endpoints[count].first, p));
Shinya Kitaoka 120a6e
        cancelFromArray(endpoints, p, count);
Shinya Kitaoka 120a6e
        if (!EndpointTable[neighboursCode(getPtr(endpoints[count].first))]) {
Shinya Kitaoka 120a6e
          std::vector<segment>::iterator it = endpoints.begin();</segment>
Shinya Kitaoka 120a6e
          std::advance(it, count);
Shinya Kitaoka 120a6e
          endpoints.erase(it);
Shinya Kitaoka 120a6e
          continue;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    count++;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TAutocloser::Imp::exploreSpot(const Segment &s, TPoint &p) {
Shinya Kitaoka 120a6e
  int x1, y1, x2, y2, x3, y3, i;
Shinya Kitaoka 120a6e
  double x2a, y2a, x2b, y2b, xnewa, ynewa, xnewb, ynewb;
Shinya Kitaoka 120a6e
  int lx = m_raster->getLx();
Shinya Kitaoka 120a6e
  int ly = m_raster->getLy();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  x1 = s.first.x;
Shinya Kitaoka 120a6e
  y1 = s.first.y;
Shinya Kitaoka 120a6e
  x2 = s.second.x;
Shinya Kitaoka 120a6e
  y2 = s.second.y;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (x1 == x2 && y1 == y2) return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (exploreRay(getPtr(x1, y1), s, p)) return true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  x2a = x2b = (double)x2;
Shinya Kitaoka 120a6e
  y2a = y2b = (double)y2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < AUT_SPOT_SAMPLES; i++) {
Shinya Kitaoka 120a6e
    xnewa = x1 + (x2a - x1) * m_csa - (y2a - y1) * m_sna;
Shinya Kitaoka 120a6e
    ynewa = y1 + (y2a - y1) * m_csa + (x2a - x1) * m_sna;
Shinya Kitaoka 120a6e
    x3    = tround(xnewa);
Shinya Kitaoka 120a6e
    y3    = tround(ynewa);
Shinya Kitaoka 120a6e
    if ((x3 != tround(x2a) || y3 != tround(y2a)) && x3 > 0 && x3 < lx &&
Shinya Kitaoka 120a6e
        y3 > 0 && y3 < ly &&
Shinya Kitaoka 120a6e
        exploreRay(
Shinya Kitaoka 120a6e
            getPtr(x1, y1),
Shinya Kitaoka 120a6e
            Segment(TPoint(x1, y1), TPoint(tround(xnewa), tround(ynewa))), p))
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    x2a = xnewa;
Shinya Kitaoka 120a6e
    y2a = ynewa;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    xnewb = x1 + (x2b - x1) * m_csb - (y2b - y1) * m_snb;
Shinya Kitaoka 120a6e
    ynewb = y1 + (y2b - y1) * m_csb + (x2b - x1) * m_snb;
Shinya Kitaoka 120a6e
    x3    = tround(xnewb);
Shinya Kitaoka 120a6e
    y3    = tround(ynewb);
Shinya Kitaoka 120a6e
    if ((x3 != tround(x2b) || y3 != tround(y2b)) && x3 > 0 && x3 < lx &&
Shinya Kitaoka 120a6e
        y3 > 0 && y3 < ly &&
Shinya Kitaoka 120a6e
        exploreRay(
Shinya Kitaoka 120a6e
            getPtr(x1, y1),
Shinya Kitaoka 120a6e
            Segment(TPoint(x1, y1), TPoint(tround(xnewb), tround(ynewb))), p))
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    x2b = xnewb;
Shinya Kitaoka 120a6e
    y2b = ynewb;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TAutocloser::Imp::exploreRay(UCHAR *br, Segment s, TPoint &p) {
Shinya Kitaoka 120a6e
  int x, y, dx, dy, d, incr_1, incr_2, inside_ink;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  inside_ink = 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  x = 0;
Shinya Kitaoka 120a6e
  y = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (s.first.x < s.second.x) {
Shinya Kitaoka 120a6e
    dx = s.second.x - s.first.x;
Shinya Kitaoka 120a6e
    dy = s.second.y - s.first.y;
Shinya Kitaoka 120a6e
    if (dy >= 0)
Shinya Kitaoka 120a6e
      if (dy <= dx)
Shinya Kitaoka 120a6e
        DRAW_SEGMENT(x, y, dx, dy, (br++), (br += m_bWrap + 1),
Shinya Kitaoka 120a6e
                     EXPLORE_RAY_ISTR((s.first.x + x)))
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        DRAW_SEGMENT(y, x, dy, dx, (br += m_bWrap), (br += m_bWrap + 1),
Shinya Kitaoka 120a6e
                     EXPLORE_RAY_ISTR((s.first.x + x)))
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      dy = -dy;
Shinya Kitaoka 120a6e
      if (dy <= dx)
Shinya Kitaoka 120a6e
        DRAW_SEGMENT(x, y, dx, dy, (br++), (br -= m_bWrap - 1),
Shinya Kitaoka 120a6e
                     EXPLORE_RAY_ISTR((s.first.x + x)))
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        DRAW_SEGMENT(y, x, dy, dx, (br -= m_bWrap), (br -= m_bWrap - 1),
Shinya Kitaoka 120a6e
                     EXPLORE_RAY_ISTR((s.first.x + x)))
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    dx = s.first.x - s.second.x;
Shinya Kitaoka 120a6e
    dy = s.second.y - s.first.y;
Shinya Kitaoka 120a6e
    if (dy >= 0)
Shinya Kitaoka 120a6e
      if (dy <= dx)
Shinya Kitaoka 120a6e
        DRAW_SEGMENT(x, y, dx, dy, (br--), (br += m_bWrap - 1),
Shinya Kitaoka 120a6e
                     EXPLORE_RAY_ISTR((s.first.x - x)))
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        DRAW_SEGMENT(y, x, dy, dx, (br += m_bWrap), (br += m_bWrap - 1),
Shinya Kitaoka 120a6e
                     EXPLORE_RAY_ISTR((s.first.x - x)))
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      dy = -dy;
Shinya Kitaoka 120a6e
      if (dy <= dx)
Shinya Kitaoka 120a6e
        DRAW_SEGMENT(x, y, dx, dy, (br--), (br -= m_bWrap + 1),
Shinya Kitaoka 120a6e
                     EXPLORE_RAY_ISTR((s.first.x - x)))
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        DRAW_SEGMENT(y, x, dy, dx, (br -= m_bWrap), (br -= m_bWrap + 1),
Shinya Kitaoka 120a6e
                     EXPLORE_RAY_ISTR((s.first.x - x)))
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TAutocloser::Imp::drawInByteRaster(const TPoint &p0, const TPoint &p1) {
Shinya Kitaoka 120a6e
  int x, y, dx, dy, d, incr_1, incr_2;
Shinya Kitaoka 120a6e
  UCHAR *br;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (p0.x > p1.x) {
Shinya Kitaoka 120a6e
    br = getPtr(p1);
Shinya Kitaoka 120a6e
    dx = p0.x - p1.x;
Shinya Kitaoka 120a6e
    dy = p0.y - p1.y;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    br = getPtr(p0);
Shinya Kitaoka 120a6e
    dx = p1.x - p0.x;
Shinya Kitaoka 120a6e
    dy = p1.y - p0.y;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  x = y = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (dy >= 0) {
Shinya Kitaoka 120a6e
    if (dy <= dx)
Shinya Kitaoka 120a6e
      DRAW_SEGMENT(x, y, dx, dy, (br++), (br += m_bWrap + 1), ((*br) |= 0x41))
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      DRAW_SEGMENT(y, x, dy, dx, (br += m_bWrap), (br += m_bWrap + 1),
Shinya Kitaoka 120a6e
                   ((*br) |= 0x41))
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    dy = -dy;
Shinya Kitaoka 120a6e
    if (dy <= dx)
Shinya Kitaoka 120a6e
      DRAW_SEGMENT(x, y, dx, dy, (br++), (br -= m_bWrap - 1), ((*br) |= 0x41))
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      DRAW_SEGMENT(y, x, dy, dx, (br -= m_bWrap), (br -= m_bWrap - 1),
Shinya Kitaoka 120a6e
                   ((*br) |= 0x41))
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPoint TAutocloser::Imp::visitEndpoint(UCHAR *br)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  m_displAverage = TPointD();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_visited = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  visitPix(br, m_closingDistance, TPoint());
Shinya Kitaoka 120a6e
  cancelMarks(br);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return TPoint(convert((1.0 / m_visited) * m_displAverage));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TAutocloser::Imp::visitPix(UCHAR *br, int toVisit, const TPoint &dis) {
Shinya Kitaoka 120a6e
  UCHAR b = 0;
Shinya Kitaoka 120a6e
  int i, pixToVisit = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  *br |= 0x10;
Shinya Kitaoka 120a6e
  m_visited++;
Shinya Kitaoka 120a6e
  m_displAverage.x += dis.x;
Shinya Kitaoka 120a6e
  m_displAverage.y += dis.y;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  toVisit--;
Shinya Kitaoka 120a6e
  if (toVisit == 0) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = 0; i < 8; i++) {
Shinya Kitaoka 120a6e
    UCHAR *v = br + m_displaceVector[i];
Shinya Kitaoka 120a6e
    if (isInk(v) && !((*v) & 0x10)) {
Shinya Kitaoka 120a6e
      b |= (1 << i);
Shinya Kitaoka 120a6e
      pixToVisit++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (pixToVisit == 0) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (pixToVisit <= 4) toVisit = troundp(toVisit / (double)pixToVisit);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (toVisit == 0) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int x[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
Shinya Kitaoka 120a6e
  int y[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = 0; i < 8; i++)
Shinya Kitaoka 120a6e
    if (b & (1 << i))
Shinya Kitaoka 120a6e
      visitPix(br + m_displaceVector[i], toVisit, dis + TPoint(x[i], y[i]));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TAutocloser::Imp::cancelMarks(UCHAR *br) {
Shinya Kitaoka 120a6e
  *br &= 0xef;
Shinya Kitaoka 120a6e
  int i;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = 0; i < 8; i++) {
Shinya Kitaoka 120a6e
    UCHAR *v = br + m_displaceVector[i];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (isInk(v) && (*v) & 0x10) cancelMarks(v);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*=============================================================================*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*=============================================================================*/
Toshihiro Shimizu 890ddd
/*=============================================================================*/
Toshihiro Shimizu 890ddd
/*=============================================================================*/
Toshihiro Shimizu 890ddd
/*=============================================================================*/
Toshihiro Shimizu 890ddd
/*=============================================================================*/
Toshihiro Shimizu 890ddd
/*=============================================================================*/
Toshihiro Shimizu 890ddd
/*=============================================================================*/
Toshihiro Shimizu 890ddd
/*=============================================================================*/
Toshihiro Shimizu 890ddd
/*=============================================================================*/
Toshihiro Shimizu 890ddd
/*=============================================================================*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*=============================================================================*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TAutocloser::Imp::skeletonize(std::vector<tpoint> &endpoints) {</tpoint>
Shinya Kitaoka 120a6e
  std::vector<seed> seeds;</seed>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  findSeeds(seeds, endpoints);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  erase(seeds, endpoints);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TAutocloser::Imp::findSeeds(std::vector<seed> &seeds,</seed>
Shinya Kitaoka 120a6e
                                 std::vector<tpoint> &endpoints) {</tpoint>
Shinya Kitaoka 120a6e
  int i, j;
Shinya Kitaoka 120a6e
  UCHAR preseed;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UCHAR *br = m_br;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < m_bRaster->getLy(); i++) {
Shinya Kitaoka 120a6e
    for (j = 0; j < m_bRaster->getLx(); j++, br++) {
Shinya Kitaoka 120a6e
      if (notMarkedBorderInk(br)) {
Shinya Kitaoka 120a6e
        preseed = FirstPreseedTable[neighboursCode(br)];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (preseed != 8) /*non e' un pixel isolato*/
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          seeds.push_back(Seed(br, preseed));
Shinya Kitaoka 120a6e
          circuitAndMark(br, preseed);
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          (*br) |= 0x8;
Shinya Kitaoka 120a6e
          endpoints.push_back(getCoordinates(br));
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    br += m_bWrap - m_bRaster->getLx();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TAutocloser::Imp::circuitAndMark(UCHAR *seed, UCHAR preseed) {
Shinya Kitaoka 120a6e
  UCHAR *walker;
Shinya Kitaoka 120a6e
  UCHAR displ, prewalker;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  *seed |= 0x4;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  displ = NextPointTable[(neighboursCode(seed) << 3) | preseed];
Shinya Kitaoka 120a6e
  // assert(displ>=0 && displ<8);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  walker    = seed + m_displaceVector[displ];
Shinya Kitaoka 120a6e
  prewalker = displ ^ 0x7;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  while ((walker != seed) || (preseed != prewalker)) {
Shinya Kitaoka 120a6e
    *walker |= 0x4; /* metto la marca di passaggio */
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    displ = NextPointTable[(neighboursCode(walker) << 3) | prewalker];
Shinya Kitaoka 120a6e
    //  assert(displ>=0 && displ<8);
Shinya Kitaoka 120a6e
    walker += m_displaceVector[displ];
Shinya Kitaoka 120a6e
    prewalker = displ ^ 0x7;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TAutocloser::Imp::erase(std::vector<seed> &seeds,</seed>
Shinya Kitaoka 120a6e
                             std::vector<tpoint> &endpoints) {</tpoint>
Shinya Kitaoka 120a6e
  int i, size = 0, oldSize;
Shinya Kitaoka 120a6e
  UCHAR *seed, preseed, code, displ;
Shinya Kitaoka 120a6e
  oldSize = seeds.size();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (oldSize != size) {
Shinya Kitaoka 120a6e
    oldSize = size;
Shinya Kitaoka 120a6e
    size    = seeds.size();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (i = oldSize; i < size; i++) {
Shinya Kitaoka 120a6e
      seed    = seeds[i].m_ptr;
Shinya Kitaoka 120a6e
      preseed = seeds[i].m_preseed;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (!isInk(seed)) {
Shinya Kitaoka 120a6e
        code = NextSeedTable[neighboursCode(seed)];
Shinya Kitaoka 120a6e
        seed += m_displaceVector[code & 0x7];
Shinya Kitaoka 120a6e
        preseed = (code & 0x38) >> 3;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (circuitAndCancel(seed, preseed, endpoints)) {
Shinya Kitaoka 120a6e
        if (isInk(seed)) {
Shinya Kitaoka 120a6e
          displ = NextPointTable[(neighboursCode(seed) << 3) | preseed];
Shinya Kitaoka 120a6e
          //				assert(displ>=0 && displ<8);
Shinya Kitaoka 120a6e
          seeds.push_back(Seed(seed + m_displaceVector[displ], displ ^ 0x7));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        } else /* il seed e' stato cancellato */
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          code = NextSeedTable[neighboursCode(seed)];
Shinya Kitaoka 120a6e
          seeds.push_back(
Shinya Kitaoka 120a6e
              Seed(seed + m_displaceVector[code & 0x7], (code & 0x38) >> 3));
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TAutocloser::Imp::circuitAndCancel(UCHAR *seed, UCHAR preseed,
Shinya Kitaoka 120a6e
                                        std::vector<tpoint> &endpoints) {</tpoint>
Shinya Kitaoka 120a6e
  UCHAR *walker, *previous;
Shinya Kitaoka 120a6e
  UCHAR displ, prewalker;
Shinya Kitaoka 120a6e
  bool ret = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  displ = NextPointTable[(neighboursCode(seed) << 3) | preseed];
Shinya Kitaoka 120a6e
  // assert(displ>=0 && displ<8);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if ((displ == preseed) && !((*seed) & 0x8)) {
Shinya Kitaoka 120a6e
    endpoints.push_back(getCoordinates(seed));
Shinya Kitaoka 120a6e
    *seed |= 0x8;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  walker    = seed + m_displaceVector[displ];
Shinya Kitaoka 120a6e
  prewalker = displ ^ 0x7;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while ((walker != seed) || (preseed != prewalker)) {
Shinya Kitaoka 120a6e
    //	assert(prewalker>=0 && prewalker<8);
Shinya Kitaoka 120a6e
    displ = NextPointTable[(neighboursCode(walker) << 3) | prewalker];
Shinya Kitaoka 120a6e
    //  assert(displ>=0 && displ<8);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if ((displ == prewalker) && !((*walker) & 0x8)) {
Shinya Kitaoka 120a6e
      endpoints.push_back(getCoordinates(walker));
Shinya Kitaoka 120a6e
      *walker |= 0x8;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    previous = walker + m_displaceVector[prewalker];
Shinya Kitaoka 120a6e
    if (ConnectionTable[neighboursCode(previous)]) {
Shinya Kitaoka 120a6e
      ret = true;
Shinya Kitaoka 120a6e
      if (previous != seed) eraseInk(previous);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    walker += m_displaceVector[displ];
Shinya Kitaoka 120a6e
    prewalker = displ ^ 0x7;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  displ = NextPointTable[(neighboursCode(walker) << 3) | prewalker];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if ((displ == preseed) && !((*seed) & 0x8)) {
Shinya Kitaoka 120a6e
    endpoints.push_back(getCoordinates(seed));
Shinya Kitaoka 120a6e
    *seed |= 0x8;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (ConnectionTable[neighboursCode(seed + m_displaceVector[preseed])]) {
Shinya Kitaoka 120a6e
    ret = true;
Shinya Kitaoka 120a6e
    eraseInk(seed + m_displaceVector[preseed]);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (ConnectionTable[neighboursCode(seed)]) {
Shinya Kitaoka 120a6e
    ret = true;
Shinya Kitaoka 120a6e
    eraseInk(seed);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*=============================================================================*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TAutocloser::Imp::cancelFromArray(std::vector<segment> &array, TPoint p,</segment>
Shinya Kitaoka 120a6e
                                       int &count) {
Shinya Kitaoka 120a6e
  std::vector<segment>::iterator it = array.begin();</segment>
Shinya Kitaoka 120a6e
  int i                             = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (; it != array.end(); ++it, i++)
Shinya Kitaoka 120a6e
    if (it->first == p) {
Shinya Kitaoka 120a6e
      if (!EndpointTable[neighboursCode(getPtr(p))]) {
Shinya Kitaoka 120a6e
        assert(i != count);
Shinya Kitaoka 120a6e
        if (i < count) count--;
Shinya Kitaoka 120a6e
        array.erase(it);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
int is_in_list(LIST list, UCHAR *br)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
POINT *aux;
Toshihiro Shimizu 890ddd
aux = list.head;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
while(aux)
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
  if (aux->p == br) return 1;
Toshihiro Shimizu 890ddd
  aux = aux->next;
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*=============================================================================*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TAutocloser::TAutocloser(const TRasterP &r, int distance, double angle,
Shinya Kitaoka 120a6e
                         int index, int opacity)
Shinya Kitaoka 120a6e
    : m_imp(new Imp(r, distance, angle, index, opacity)) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//...............................
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TAutocloser::exec() {
Shinya Kitaoka 120a6e
  std::vector<tautocloser::segment> segments;</tautocloser::segment>
Shinya Kitaoka 120a6e
  compute(segments);
Shinya Kitaoka 120a6e
  draw(segments);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//...............................
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TAutocloser::~TAutocloser() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TAutocloser::compute(std::vector<segment> &closingSegmentArray) {</segment>
Shinya Kitaoka 120a6e
  m_imp->compute(closingSegmentArray);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TAutocloser::draw(const std::vector<segment> &closingSegmentArray) {</segment>
Shinya Kitaoka 120a6e
  m_imp->draw(closingSegmentArray);
Toshihiro Shimizu 890ddd
}