Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "tmachine.h"
Toshihiro Shimizu 890ddd
#include "tcurves.h"
Toshihiro Shimizu 890ddd
#include "tcommon.h"
Toshihiro Shimizu 890ddd
#include "tregion.h"
Toshihiro Shimizu 890ddd
//#include "tregionutil.h"
Toshihiro Shimizu 890ddd
#include "tstopwatch.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tstrokeutil.h"
Toshihiro Shimizu 890ddd
#include "tvectorimageP.h"
Toshihiro Shimizu 890ddd
#include "tdebugmessage.h"
Toshihiro Shimizu 890ddd
#include <vector></vector>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tcurveutil.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <algorithm></algorithm>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if !defined(TNZ_LITTLE_ENDIAN)
Toshihiro Shimizu 890ddd
TNZ_LITTLE_ENDIAN undefined !!
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef IS_DOTNET
Toshihiro Shimizu 890ddd
#define NULL_ITER list<intersectedstroke>::iterator()</intersectedstroke>
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define NULL_ITER 0
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    using namespace std;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef TVectorImage::IntersectionBranch IntersectionBranch;
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline double myRound(double x) {
Shinya Kitaoka 120a6e
  return (1.0 / REGION_COMPUTING_PRECISION) *
Shinya Kitaoka 120a6e
         ((long)(x * REGION_COMPUTING_PRECISION));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline TThickPoint myRound(const TThickPoint &p) {
Shinya Kitaoka 120a6e
  return TThickPoint(myRound(p.x), myRound(p.y), p.thick);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void print(list<intersection> &intersectionList, char *str) {</intersection>
Shinya Kitaoka 120a6e
  ofstream of(str);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  of << "***************************" << endl;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  list<intersection>::const_iterator it;</intersection>
Shinya Kitaoka 120a6e
  list<intersectedstroke>::const_iterator it1;</intersectedstroke>
Shinya Kitaoka 120a6e
  int i, j;
Shinya Kitaoka 120a6e
  for (i = 0, it = intersectionList.begin(); it != intersectionList.end();
Shinya Kitaoka 120a6e
       it++, i++) {
Shinya Kitaoka 120a6e
    of << "***************************" << endl;
Shinya Kitaoka 120a6e
    of << "Intersection#" << i << ": " << it->m_intersection
Shinya Kitaoka 120a6e
       << "numBranches: " << it->m_numInter << endl;
Shinya Kitaoka 120a6e
    of << endl;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (j = 0, it1 = it->m_strokeList.begin(); it1 != it->m_strokeList.end();
Shinya Kitaoka 120a6e
         it1++, j++) {
Shinya Kitaoka 120a6e
      of << "----Branch #" << j;
Shinya Kitaoka 120a6e
      if (it1->m_edge.m_index < 0) of << "(AUTOCLOSE)";
Shinya Kitaoka 120a6e
      of << "Intersection at " << it1->m_edge.m_w0 << ": "
Shinya Kitaoka 120a6e
         << ": " << endl;
Shinya Kitaoka 120a6e
      of << "ColorId: " << it1->m_edge.m_styleId << endl;
Shinya Kitaoka 120a6e
      /*
Shinya Kitaoka 120a6e
TColorStyle* fs = it1->m_edge.m_fillStyle;
Shinya Kitaoka 120a6e
if (fs==0)
Shinya Kitaoka 120a6e
of<<"NO color: "<< endl;
Shinya Kitaoka 120a6e
else
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
TFillStyleP fp = fs->getFillStyle();
Shinya Kitaoka 120a6e
if (fp)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
fp->
Shinya Kitaoka 120a6e
assert(false) ;
Shinya Kitaoka 120a6e
else
Shinya Kitaoka 120a6e
of<<"Color: ("<< colorStyle->getColor().r<<", "<< colorStyle->getColor().g<<",
Shinya Kitaoka 120a6e
"<< colorStyle->getColor().b<<")"<
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      of << "----Stroke " << (it1->m_gettingOut ? "OUT" : "IN") << " #"
Shinya Kitaoka 120a6e
         << it1->m_edge.m_index << ": " << endl;
Shinya Kitaoka 120a6e
      // if (it1->m_dead)
Shinya Kitaoka 120a6e
      // of<<"---- DEAD Intersection.";
Shinya Kitaoka 120a6e
      // else
Toshihiro Shimizu 890ddd
      {
Shinya Kitaoka 120a6e
        of << "---- NEXT Intersection:";
Shinya Kitaoka 120a6e
        if (it1->m_nextIntersection != intersectionList.end()) {
Shinya Kitaoka 120a6e
          int dist =
Shinya Kitaoka 120a6e
              std::distance(intersectionList.begin(), it1->m_nextIntersection);
Shinya Kitaoka 120a6e
          of << dist;
Shinya Kitaoka 120a6e
          list<intersection>::iterator iit = intersectionList.begin();</intersection>
Shinya Kitaoka 120a6e
          std::advance(iit, dist);
Shinya Kitaoka 120a6e
          of << " "
Shinya Kitaoka 120a6e
             << std::distance(iit->m_strokeList.begin(), it1->m_nextStroke);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          of << "NULL!!";
Shinya Kitaoka 120a6e
        of << "---- NEXT Stroke:";
Shinya Kitaoka 120a6e
        if (it1->m_nextIntersection != intersectionList.end())
Shinya Kitaoka 120a6e
          of << it1->m_nextStroke->m_edge.m_index;
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          of << "NULL!!";
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      of << endl << endl;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void findNearestIntersection(list<intersection> &interList,</intersection>
Shinya Kitaoka 120a6e
                             const list<intersection>::iterator &i1,</intersection>
Shinya Kitaoka 120a6e
                             const list<intersectedstroke>::iterator &i2);</intersectedstroke>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _TOLGO
Shinya Kitaoka 120a6e
void checkInterList(list<intersection> &intersectionList) {</intersection>
Shinya Kitaoka 120a6e
  list<intersection>::iterator it;</intersection>
Shinya Kitaoka 120a6e
  list<intersectedstroke>::iterator it1;</intersectedstroke>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (it = intersectionList.begin(); it != intersectionList.end(); it++) {
Shinya Kitaoka 120a6e
    int count = 0;
Shinya Kitaoka 120a6e
    for (it1 = it->m_strokeList.begin(); it1 != it->m_strokeList.end(); it1++) {
Shinya Kitaoka 120a6e
      int val;
Shinya Kitaoka 120a6e
      if (it1->m_nextIntersection != intersectionList.end()) {
Shinya Kitaoka 120a6e
        count++;
Shinya Kitaoka 120a6e
        // assert (it1->m_nextIntersection!=intersectionList.end());
Shinya Kitaoka 120a6e
        assert(it1->m_nextStroke->m_nextIntersection == it);
Shinya Kitaoka 120a6e
        assert(it1->m_nextStroke->m_nextStroke == it1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        // int k = it1->m_edge.m_index;
Shinya Kitaoka 120a6e
        val = std::distance(intersectionList.begin(), it1->m_nextIntersection);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      // else
Shinya Kitaoka 120a6e
      // assert(it1->m_nextIntersection==intersectionList.end());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    assert(count == it->m_numInter);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define checkInterList
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// void addFakeIntersection(list<intersection>& intersectionList,TStroke* s,</intersection>
Shinya Kitaoka 120a6e
// UINT ii, double w);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void addIntersections(IntersectionData &intersectionData,
Shinya Kitaoka 120a6e
                      const vector<vistroke *=""> &s, int ii, int jj,</vistroke>
Shinya Kitaoka 120a6e
                      const vector<doublepair> &intersections, int numStrokes);</doublepair>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void addIntersection(IntersectionData &intData, const vector<vistroke *=""> &s,</vistroke>
Shinya Kitaoka 120a6e
                     int ii, int jj, DoublePair intersections, int strokeSize);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool sortBBox(const TStroke *s1, const TStroke *s2) {
Shinya Kitaoka 120a6e
  return s1->getBBox().x0 < s2->getBBox().x0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void cleanIntersectionMarks(list<intersection> &interList) {</intersection>
Shinya Kitaoka 120a6e
  for (list<intersection>::iterator it1 = interList.begin();</intersection>
Shinya Kitaoka 120a6e
       it1 != interList.end(); it1++)
Shinya Kitaoka 120a6e
    for (list<intersectedstroke>::iterator it2 = (*it1).m_strokeList.begin();</intersectedstroke>
Shinya Kitaoka 120a6e
         it2 != (*it1).m_strokeList.end(); it2++) {
Shinya Kitaoka 120a6e
      it2->m_visited =
Shinya Kitaoka 120a6e
          false;  // Ogni ramo della lista viene messo nella condizione
Shinya Kitaoka 120a6e
                  // di poter essere visitato
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (it2->m_nextIntersection != interList.end()) {
Shinya Kitaoka 120a6e
        it2->m_nextIntersection =
Shinya Kitaoka 120a6e
            interList.end();  // pezza tremenda, da togliere!!!
Shinya Kitaoka 120a6e
        it1->m_numInter--;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void cleanNextIntersection(list<intersection> &interList, TStroke *s) {</intersection>
Shinya Kitaoka 120a6e
  for (list<intersection>::iterator it1 = interList.begin();</intersection>
Shinya Kitaoka 120a6e
       it1 != interList.end(); it1++)
Shinya Kitaoka 120a6e
    for (list<intersectedstroke>::iterator it2 = (*it1).m_strokeList.begin();</intersectedstroke>
Shinya Kitaoka 120a6e
         it2 != (*it1).m_strokeList.end(); it2++)
Shinya Kitaoka 120a6e
      if (it2->m_edge.m_s == s) {
Shinya Kitaoka 120a6e
        // if (it2->m_nextIntersection==NULL)
Shinya Kitaoka 120a6e
        //  return; //gia' ripulita prima
Shinya Kitaoka 120a6e
        if (it2->m_nextIntersection != interList.end()) {
Shinya Kitaoka 120a6e
          it2->m_nextIntersection = interList.end();
Shinya Kitaoka 120a6e
          it1->m_numInter--;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        it2->m_nextStroke = (*it1).m_strokeList.end();
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::Imp::eraseEdgeFromStroke(
Shinya Kitaoka 120a6e
    list<intersectedstroke>::iterator it2) {</intersectedstroke>
Shinya Kitaoka 120a6e
  if (it2->m_edge.m_index >=
Shinya Kitaoka 120a6e
      0)  // elimino il puntatore all'edge nella lista della VIStroke
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    VIStroke *s;
Shinya Kitaoka 120a6e
    s = m_strokes[it2->m_edge.m_index];
Shinya Kitaoka 120a6e
    assert(s->m_s == it2->m_edge.m_s);
Shinya Kitaoka 120a6e
    list<tedge *="">::iterator iit  = s->m_edgeList.begin(),</tedge>
Shinya Kitaoka 120a6e
                            it_e = s->m_edgeList.end();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (; iit != it_e; ++iit)
Shinya Kitaoka 120a6e
      if ((*iit)->m_w0 == it2->m_edge.m_w0 &&
Shinya Kitaoka 120a6e
          (*iit)->m_w1 == it2->m_edge.m_w1) {
Shinya Kitaoka 120a6e
        assert((*iit)->m_toBeDeleted == false);
Shinya Kitaoka 120a6e
        s->m_edgeList.erase(iit);
Shinya Kitaoka 120a6e
        return;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
list<intersectedstroke>::iterator TVectorImage::Imp::eraseBranch(</intersectedstroke>
Shinya Kitaoka 120a6e
    list<intersection>::iterator it1, list<intersectedstroke>::iterator it2) {</intersectedstroke></intersection>
Shinya Kitaoka 120a6e
  // list<intersection>::iterator iit1;</intersection>
Shinya Kitaoka 120a6e
  // list<intersectedstroke>::iterator iit2;</intersectedstroke>
Shinya Kitaoka 120a6e
  list<intersection> &intList = m_intersectionData.m_intList;</intersection>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (it2->m_nextIntersection != intList.end()) {
Shinya Kitaoka 120a6e
    list<intersection>::iterator nextInt         = it2->m_nextIntersection;</intersection>
Shinya Kitaoka 120a6e
    list<intersectedstroke>::iterator nextStroke = it2->m_nextStroke;</intersectedstroke>
Shinya Kitaoka 120a6e
    assert(nextStroke->m_nextIntersection == it1);
Shinya Kitaoka 120a6e
    assert(nextStroke->m_nextStroke == it2);
Shinya Kitaoka 120a6e
    assert(nextStroke != it2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // nextStroke->m_nextIntersection = intList.end();
Shinya Kitaoka 120a6e
    // nextStroke->m_nextStroke = nextInt->m_strokeList.end();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (nextStroke->m_nextIntersection != intList.end()) {
Shinya Kitaoka 120a6e
      nextStroke->m_nextIntersection = intList.end();
Shinya Kitaoka 120a6e
      nextInt->m_numInter--;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    // nextInt->m_strokeList.erase(nextStroke);//non posso cancellarla, puo'
Shinya Kitaoka 120a6e
    // servire in futuro!
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (it2->m_nextIntersection != intList.end()) it1->m_numInter--;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  eraseEdgeFromStroke(it2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  it2->m_edge.m_w0 = it2->m_edge.m_w1 = -3;
Shinya Kitaoka 120a6e
  it2->m_edge.m_index                 = -3;
Shinya Kitaoka 120a6e
  it2->m_edge.m_s                     = 0;
Shinya Kitaoka 120a6e
  it2->m_edge.m_styleId               = -3;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  list<intersectedstroke>::iterator ret = (*it1).m_strokeList.erase(it2);</intersectedstroke>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::Imp::eraseDeadIntersections() {
Shinya Kitaoka 120a6e
  list<intersection>::iterator it;</intersection>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (it = m_intersectionData.m_intList.begin();
Shinya Kitaoka 120a6e
       it != m_intersectionData.m_intList.end();)  // la faccio qui, e non nella
Shinya Kitaoka 120a6e
                                                   // eraseIntersection. vedi
Shinya Kitaoka 120a6e
                                                   // commento li'.
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    list<intersection> &intList = m_intersectionData.m_intList;</intersection>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (it->m_strokeList.size() == 1) {
Shinya Kitaoka 120a6e
      eraseBranch(it, (*it).m_strokeList.begin());
Shinya Kitaoka 120a6e
      assert(it->m_strokeList.empty());
Shinya Kitaoka 120a6e
      it = intList.erase(it);
Shinya Kitaoka 120a6e
    } else if (it->m_strokeList.size() == 2 &&
Shinya Kitaoka 120a6e
               ((*it).m_strokeList.front().m_edge.m_s ==
Shinya Kitaoka 120a6e
                    (*it).m_strokeList.back().m_edge.m_s &&
Shinya Kitaoka 120a6e
                (*it).m_strokeList.front().m_edge.m_w0 ==
Shinya Kitaoka 120a6e
                    (*it).m_strokeList.back().m_edge.m_w0))  // intersezione
Shinya Kitaoka 120a6e
                                                             // finta
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      list<intersectedstroke>::iterator it1 = it->m_strokeList.begin(), iit1,</intersectedstroke>
Shinya Kitaoka 120a6e
                                        iit2;
Shinya Kitaoka 120a6e
      list<intersectedstroke>::iterator it2 = it1;</intersectedstroke>
Shinya Kitaoka 120a6e
      it2++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      eraseEdgeFromStroke(it1);
Shinya Kitaoka 120a6e
      eraseEdgeFromStroke(it2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      iit1 = (it1->m_nextIntersection == intList.end()) ? NULL_ITER
Shinya Kitaoka 120a6e
                                                        : it1->m_nextStroke;
Shinya Kitaoka 120a6e
      iit2 = (it2->m_nextIntersection == intList.end()) ? NULL_ITER
Shinya Kitaoka 120a6e
                                                        : it2->m_nextStroke;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (iit1 != NULL_ITER && iit2 != NULL_ITER) {
Shinya Kitaoka 120a6e
        iit1->m_edge.m_w1 = iit2->m_edge.m_w0;
Shinya Kitaoka 120a6e
        iit2->m_edge.m_w1 = iit1->m_edge.m_w0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (iit1 != NULL_ITER) {
Shinya Kitaoka 120a6e
        iit1->m_nextStroke       = iit2;
Shinya Kitaoka 120a6e
        iit1->m_nextIntersection = it2->m_nextIntersection;
Shinya Kitaoka 120a6e
        if (iit1->m_nextIntersection == intList.end())
Shinya Kitaoka 120a6e
          it1->m_nextIntersection->m_numInter--;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (iit2 != NULL_ITER) {
Shinya Kitaoka 120a6e
        iit2->m_nextStroke       = iit1;
Shinya Kitaoka 120a6e
        iit2->m_nextIntersection = it1->m_nextIntersection;
Shinya Kitaoka 120a6e
        if (iit2->m_nextIntersection == intList.end())
Shinya Kitaoka 120a6e
          it2->m_nextIntersection->m_numInter--;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      it->m_strokeList.clear();
Shinya Kitaoka 120a6e
      it->m_numInter = 0;
Shinya Kitaoka 120a6e
      it             = intList.erase(it);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      ++it;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::Imp::doEraseIntersection(int index,
Shinya Kitaoka 120a6e
                                            vector<int> *toBeDeleted) {</int>
Shinya Kitaoka 120a6e
  list<intersection> &interList = m_intersectionData.m_intList;</intersection>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  list<intersection>::iterator it1 = interList.begin();</intersection>
Shinya Kitaoka 120a6e
  TStroke *deleteIt                = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (it1 != interList.end()) {
Shinya Kitaoka 120a6e
    bool removeAutocloses = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    list<intersectedstroke>::iterator it2 = (*it1).m_strokeList.begin();</intersectedstroke>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    while (it2 != (*it1).m_strokeList.end()) {
Shinya Kitaoka 120a6e
      IntersectedStroke &is = *it2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (is.m_edge.m_index == index) {
Shinya Kitaoka 120a6e
        if (is.m_edge.m_index >= 0)
Shinya Kitaoka 120a6e
          // if (!is.m_autoclose && (is.m_edge.m_w0==1 || is.m_edge.m_w0==0))
Shinya Kitaoka 120a6e
          removeAutocloses = true;
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          deleteIt = is.m_edge.m_s;
Shinya Kitaoka 120a6e
        it2        = eraseBranch(it1, it2);
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        ++it2;
Shinya Kitaoka 120a6e
      // checkInterList(interList);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (removeAutocloses)  // se ho tolto una stroke dall'inter corrente, tolgo
Shinya Kitaoka 120a6e
                           // tutti le stroke di autclose che partono da qui
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      assert(toBeDeleted);
Shinya Kitaoka 120a6e
      for (it2 = (*it1).m_strokeList.begin(); it2 != (*it1).m_strokeList.end();
Shinya Kitaoka 120a6e
           it2++)
Shinya Kitaoka 120a6e
        if (it2->m_edge.m_index < 0 &&
Shinya Kitaoka 120a6e
            (it2->m_edge.m_w0 == 1 || it2->m_edge.m_w0 == 0))
Shinya Kitaoka 120a6e
          toBeDeleted->push_back(it2->m_edge.m_index);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if ((*it1).m_strokeList.empty())
Shinya Kitaoka 120a6e
      it1 = interList.erase(it1);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      it1++;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (deleteIt) delete deleteIt;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UINT TVectorImage::Imp::getFillData(IntersectionBranch *&v) {
Shinya Kitaoka 120a6e
  // print(m_intersectionData.m_intList, "C:\\temp\\intersectionPrimaSave.txt");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  list<intersection> &intList = m_intersectionData.m_intList;</intersection>
Shinya Kitaoka 120a6e
  if (intList.empty()) return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  list<intersection>::iterator it1;</intersection>
Shinya Kitaoka 120a6e
  list<intersectedstroke>::iterator it2;</intersectedstroke>
Shinya Kitaoka 120a6e
  UINT currInt = 0;
Shinya Kitaoka 120a6e
  vector<uint> branchesBefore(intList.size() + 1);</uint>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  branchesBefore[0] = 0;
Shinya Kitaoka 120a6e
  UINT count = 0, size = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (it1 = intList.begin(); it1 != intList.end(); ++it1, currInt++) {
Shinya Kitaoka 120a6e
    UINT strokeListSize = it1->m_strokeList.size();
Shinya Kitaoka 120a6e
    size += strokeListSize;
Shinya Kitaoka 120a6e
    branchesBefore[currInt + 1] = branchesBefore[currInt] + strokeListSize;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  v       = new IntersectionBranch[size];
Shinya Kitaoka 120a6e
  currInt = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (it1 = intList.begin(); it1 != intList.end(); ++it1, currInt++) {
Shinya Kitaoka 120a6e
    UINT currBranch = 0;
Shinya Kitaoka 120a6e
    for (it2 = it1->m_strokeList.begin(); it2 != it1->m_strokeList.end();
Shinya Kitaoka 120a6e
         ++it2, currBranch++) {
Shinya Kitaoka 120a6e
      IntersectionBranch &b = v[count];
Shinya Kitaoka 120a6e
      b.m_currInter         = currInt;
Shinya Kitaoka 120a6e
      b.m_strokeIndex       = it2->m_edge.m_index;
Shinya Kitaoka 120a6e
      b.m_w                 = it2->m_edge.m_w0;
Shinya Kitaoka 120a6e
      b.m_style             = it2->m_edge.m_styleId;
Shinya Kitaoka 120a6e
      // assert(b.m_style<100);
Shinya Kitaoka 120a6e
      b.m_gettingOut = it2->m_gettingOut;
Shinya Kitaoka 120a6e
      if (it2->m_nextIntersection == intList.end())
Shinya Kitaoka 120a6e
        b.m_nextBranch = count;
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        UINT distInt = std::distance(intList.begin(), it2->m_nextIntersection);
Shinya Kitaoka 120a6e
        UINT distBranch = std::distance(
Shinya Kitaoka 120a6e
            it2->m_nextIntersection->m_strokeList.begin(), it2->m_nextStroke);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if ((distInt < currInt) ||
Shinya Kitaoka 120a6e
            (distInt == currInt && distBranch < currBranch)) {
Shinya Kitaoka 120a6e
          UINT posNext = branchesBefore[distInt] + distBranch;
Shinya Kitaoka 120a6e
          assert(posNext < count);
Shinya Kitaoka 120a6e
          b.m_nextBranch = posNext;
Shinya Kitaoka 120a6e
          assert(v[posNext].m_nextBranch == (std::numeric_limits<uint>::max)());</uint>
Shinya Kitaoka 120a6e
          v[posNext].m_nextBranch = count;
Shinya Kitaoka 120a6e
        } else
Shinya Kitaoka 120a6e
          b.m_nextBranch = (std::numeric_limits<uint>::max)();</uint>
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      count++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
// for (UINT i=0; i
Toshihiro Shimizu 890ddd
//  assert(v[i].m_nextBranch != std::numeric_limits<uint>::max());</uint>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Toshihiro Shimizu 890ddd
/*ofstream of("C:\\temp\\fillDataOut.txt");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
for (UINT ii=0; ii
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
  of<
Toshihiro Shimizu 890ddd
  of<<"index:"<
Toshihiro Shimizu 890ddd
  of<<"w:"<
Toshihiro Shimizu 890ddd
  of<<"curr inter:"<
Toshihiro Shimizu 890ddd
  of<<"next inter:"<
Toshihiro Shimizu 890ddd
  of<<"gettingOut:"<<((v[ii].m_gettingOut)?"TRUE":"FALSE")<
Toshihiro Shimizu 890ddd
  of<<"colorId:"<
Toshihiro Shimizu 890ddd
  }*/
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return size;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
TStroke *reconstructAutocloseStroke(list<intersection> &intList,</intersection>
Shinya Kitaoka 120a6e
                                    list<intersection>::iterator it1,</intersection>
Shinya Kitaoka 120a6e
                                    list<intersectedstroke>::iterator it2)</intersectedstroke>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  bool found                        = false;
Shinya Kitaoka 120a6e
  list<intersection>::iterator iit1 = it1;</intersection>
Shinya Kitaoka 120a6e
  list<intersectedstroke>::iterator iit2;</intersectedstroke>
Shinya Kitaoka 120a6e
  iit1++;
Shinya Kitaoka 120a6e
  // vector<tedge*> vapp;</tedge*>
Shinya Kitaoka 120a6e
  for (; !found && iit1 != intList.end(); iit1++) {
Shinya Kitaoka 120a6e
    for (iit2 = iit1->m_strokeList.begin();
Shinya Kitaoka 120a6e
         !found && iit2 != iit1->m_strokeList.end(); iit2++) {
Shinya Kitaoka 120a6e
      if (it2->m_edge.m_index == iit2->m_edge.m_index) {
Shinya Kitaoka 120a6e
        if ((iit2->m_edge.m_w0 == 1 && it2->m_edge.m_w0 == 0) ||
Shinya Kitaoka 120a6e
            (iit2->m_edge.m_w0 == 0 && it2->m_edge.m_w0 == 1)) {
Shinya Kitaoka 120a6e
          found = true;
Shinya Kitaoka 120a6e
          vector<tpointd> v;</tpointd>
Shinya Kitaoka 120a6e
          if (it2->m_edge.m_w0 == 0) {
Shinya Kitaoka 120a6e
            v.push_back(it1->m_intersection);
Shinya Kitaoka 120a6e
            v.push_back(iit1->m_intersection);
Shinya Kitaoka 120a6e
          } else {
Shinya Kitaoka 120a6e
            v.push_back(iit1->m_intersection);
Shinya Kitaoka 120a6e
            v.push_back(it1->m_intersection);
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          it2->m_edge.m_s = iit2->m_edge.m_s = new TStroke(v);
Shinya Kitaoka 120a6e
          // for (UINT ii=0; ii
Shinya Kitaoka 120a6e
          // vapp[ii]->m_s = it2->m_edge.m_s;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        // else if (iit2->m_edge.m_w0!=0 && iit2->m_edge.m_w0!=1)
Shinya Kitaoka 120a6e
        //  vapp.push_back(&(iit2->m_edge));
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  assert(found);
Shinya Kitaoka 120a6e
  if (!found) it2->m_edge.m_s = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return it2->m_edge.m_s;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::Imp::setFillData(IntersectionBranch *v, UINT branchCount) {
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Toshihiro Shimizu 890ddd
/*ofstream of("C:\\temp\\fillDataIn.txt");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
for (UINT ii=0; ii
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
  of<
Toshihiro Shimizu 890ddd
  of<<"index:"<
Toshihiro Shimizu 890ddd
  of<<"w:"<
Toshihiro Shimizu 890ddd
  of<<"curr inter:"<
Toshihiro Shimizu 890ddd
  of<<"next inter:"<
Toshihiro Shimizu 890ddd
  of<<"gettingOut:"<<((v[ii].m_gettingOut)?"TRUE":"FALSE")<
Toshihiro Shimizu 890ddd
  of<<"colorId:"<
Toshihiro Shimizu 890ddd
  }*/
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (branchCount == 0) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  list<intersection> &intList = m_intersectionData.m_intList;</intersection>
Shinya Kitaoka 120a6e
  clearPointerContainer(m_regions);
Shinya Kitaoka 120a6e
  m_regions.clear();
Shinya Kitaoka 120a6e
  intList.clear();
Shinya Kitaoka 120a6e
  list<intersection>::iterator currInt;</intersection>
Shinya Kitaoka 120a6e
  list<intersectedstroke>::iterator currBranch;</intersectedstroke>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  vector<uint> branchesBefore(v[branchCount - 1].m_currInter + 1);</uint>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UINT i = 0;
Shinya Kitaoka 120a6e
  for (; i < branchCount; i++) {
Shinya Kitaoka 120a6e
    const IntersectionBranch &b = v[i];
Shinya Kitaoka 120a6e
    if (i == 0 || v[i].m_currInter != v[i - 1].m_currInter) {
Shinya Kitaoka 120a6e
      assert(i == 0 || v[i].m_currInter == v[i - 1].m_currInter + 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      branchesBefore[v[i].m_currInter] = i;
Shinya Kitaoka 120a6e
      intList.push_back(Intersection());
Shinya Kitaoka 120a6e
      currInt = intList.begin();
Shinya Kitaoka 120a6e
      advance(currInt, intList.size() - 1);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    IntersectedStroke is;
Shinya Kitaoka 120a6e
    currInt->m_strokeList.push_back(is);
Shinya Kitaoka 120a6e
    currBranch = currInt->m_strokeList.begin();
Shinya Kitaoka 120a6e
    advance(currBranch, currInt->m_strokeList.size() - 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    currBranch->m_edge.m_styleId = b.m_style;
Shinya Kitaoka 120a6e
    // assert(b.m_style<100);
Shinya Kitaoka 120a6e
    currBranch->m_edge.m_index = b.m_strokeIndex;
Shinya Kitaoka 120a6e
    if (b.m_strokeIndex >= 0)
Shinya Kitaoka 120a6e
      currBranch->m_edge.m_s = m_strokes[b.m_strokeIndex]->m_s;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      currBranch->m_edge.m_s = 0;
Shinya Kitaoka 120a6e
    currBranch->m_gettingOut = b.m_gettingOut;
Shinya Kitaoka 120a6e
    currBranch->m_edge.m_w0  = b.m_w;
Shinya Kitaoka 120a6e
    currBranch->m_edge.m_w1  = v[b.m_nextBranch].m_w;
Shinya Kitaoka 120a6e
    assert(currBranch->m_edge.m_w0 >= -1e-8 &&
Shinya Kitaoka 120a6e
           currBranch->m_edge.m_w0 <= 1 + 1e-8);
Shinya Kitaoka 120a6e
    assert(currBranch->m_edge.m_w1 >= -1e-8 &&
Shinya Kitaoka 120a6e
           currBranch->m_edge.m_w1 <= 1 + 1e-8);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (b.m_nextBranch < i) {
Shinya Kitaoka 120a6e
      list<intersection>::iterator it1;</intersection>
Shinya Kitaoka 120a6e
      list<intersectedstroke>::iterator it2;</intersectedstroke>
Shinya Kitaoka 120a6e
      it1 = intList.begin();
Shinya Kitaoka 120a6e
      std::advance(it1, v[b.m_nextBranch].m_currInter);
Shinya Kitaoka 120a6e
      it2 = it1->m_strokeList.begin();
Shinya Kitaoka 120a6e
      assert(b.m_nextBranch - branchesBefore[v[b.m_nextBranch].m_currInter] >=
Shinya Kitaoka 120a6e
             0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      std::advance(
Shinya Kitaoka 120a6e
          it2, b.m_nextBranch - branchesBefore[v[b.m_nextBranch].m_currInter]);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      currBranch->m_nextIntersection = it1;
Shinya Kitaoka 120a6e
      currBranch->m_nextStroke       = it2;
Shinya Kitaoka 120a6e
      it2->m_nextIntersection        = currInt;
Shinya Kitaoka 120a6e
      it2->m_nextStroke              = currBranch;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // if (currBranch == currInt->m_strokeList.begin())
Shinya Kitaoka 120a6e
      //  currInt->m_intersection =
Shinya Kitaoka 120a6e
      //  currBranch->m_edge.m_s->getPoint(currBranch->m_edge.m_w0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      currInt->m_numInter++;
Shinya Kitaoka 120a6e
      it1->m_numInter++;
Shinya Kitaoka 120a6e
    } else if (b.m_nextBranch == i)
Shinya Kitaoka 120a6e
      currBranch->m_nextIntersection = intList.end();
Shinya Kitaoka 120a6e
    else if (b.m_nextBranch == (std::numeric_limits<uint>::max)()) {</uint>
Shinya Kitaoka 120a6e
      currBranch->m_nextIntersection = intList.end();
Shinya Kitaoka 120a6e
      currBranch->m_nextStroke       = currInt->m_strokeList.end();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /* {
Shinya Kitaoka 120a6e
assert(b.m_nextBranch
Shinya Kitaoka 120a6e
assert(v[b.m_nextBranch].m_nextBranch==i);
Shinya Kitaoka 120a6e
}*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (i == branchCount - 1 || v[i].m_currInter != v[i + 1].m_currInter) {
Shinya Kitaoka 120a6e
      int j = i;
Shinya Kitaoka 120a6e
      while (v[j].m_strokeIndex < 0 &&
Shinya Kitaoka 120a6e
             ((j > 0 && v[j].m_currInter == v[j - 1].m_currInter) || j == 0))
Shinya Kitaoka 120a6e
        j--;
Shinya Kitaoka 120a6e
      if (v[j].m_strokeIndex >= 0)
Shinya Kitaoka 120a6e
        currInt->m_intersection =
Shinya Kitaoka 120a6e
            m_strokes[v[j].m_strokeIndex]->m_s->getPoint(v[j].m_w);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < m_strokes.size(); i++) m_strokes[i]->m_isNewForFill = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // computeRegions();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  list<intersection>::iterator it1;</intersection>
Shinya Kitaoka 120a6e
  list<intersectedstroke>::iterator it2;</intersectedstroke>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  vector<uint> toBeDeleted;</uint>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (it1 = intList.begin(); it1 != intList.end(); it1++)
Shinya Kitaoka 120a6e
    for (it2 = it1->m_strokeList.begin(); it2 != it1->m_strokeList.end();
Shinya Kitaoka 120a6e
         ++it2) {
Shinya Kitaoka 120a6e
      if (it2->m_edge.m_index < 0 && !it2->m_edge.m_s &&
Shinya Kitaoka 120a6e
          (it2->m_edge.m_w0 == 0 || it2->m_edge.m_w0 == 1)) {
Shinya Kitaoka 120a6e
        it2->m_edge.m_s = reconstructAutocloseStroke(intList, it1, it2);
Shinya Kitaoka 120a6e
        if (it2->m_edge.m_s)
Shinya Kitaoka 120a6e
          m_intersectionData.m_autocloseMap[it2->m_edge.m_index] =
Shinya Kitaoka 120a6e
              it2->m_edge.m_s;
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          toBeDeleted.push_back(it2->m_edge.m_index);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (it1 = intList.begin(); it1 != intList.end(); it1++)
Shinya Kitaoka 120a6e
    for (it2 = it1->m_strokeList.begin(); it2 != it1->m_strokeList.end();
Shinya Kitaoka 120a6e
         ++it2) {
Shinya Kitaoka 120a6e
      if (!it2->m_edge.m_s && it2->m_edge.m_index < 0) {
Shinya Kitaoka 120a6e
        it2->m_edge.m_s =
Shinya Kitaoka 120a6e
            m_intersectionData.m_autocloseMap[it2->m_edge.m_index];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        // TEdge& e = it2->m_edge;
Shinya Kitaoka 120a6e
        if (!it2->m_edge.m_s) toBeDeleted.push_back(it2->m_edge.m_index);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < toBeDeleted.size(); i++) eraseIntersection(toBeDeleted[i]);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_areValidRegions = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  computeRegions();
Shinya Kitaoka 120a6e
  // print(m_intersectionData.m_intList, "C:\\temp\\intersectionDopoLoad.txt");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::Imp::eraseIntersection(int index) {
Shinya Kitaoka 120a6e
  vector<int> autocloseStrokes;</int>
Shinya Kitaoka 120a6e
  doEraseIntersection(index, &autocloseStrokes);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < autocloseStrokes.size(); i++) {
Shinya Kitaoka 120a6e
    doEraseIntersection(autocloseStrokes[i]);
Shinya Kitaoka 120a6e
    assert(autocloseStrokes[i] < 0);
Shinya Kitaoka 120a6e
    m_intersectionData.m_autocloseMap.erase(autocloseStrokes[i]);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void findNearestIntersection(list<intersection> &interList) {</intersection>
Shinya Kitaoka 120a6e
  list<intersection>::iterator i1;</intersection>
Shinya Kitaoka 120a6e
  list<intersectedstroke>::iterator i2;</intersectedstroke>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i1 = interList.begin(); i1 != interList.end(); i1++) {
Shinya Kitaoka 120a6e
    for (i2 = (*i1).m_strokeList.begin(); i2 != (*i1).m_strokeList.end();
Shinya Kitaoka 120a6e
         i2++) {
Shinya Kitaoka 120a6e
      if ((*i2).m_nextIntersection != interList.end())  // already set
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      int versus      = (i2->m_gettingOut) ? 1 : -1;
Shinya Kitaoka 120a6e
      double minDelta = (std::numeric_limits<double>::max)();</double>
Shinya Kitaoka 120a6e
      list<intersection>::iterator it1, it1Res;</intersection>
Shinya Kitaoka 120a6e
      list<intersectedstroke>::iterator it2, it2Res;</intersectedstroke>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      for (it1 = i1; it1 != interList.end(); ++it1) {
Shinya Kitaoka 120a6e
        if (it1 == i1)
Shinya Kitaoka 120a6e
          it2 = i2, it2++;
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          it2 = (*it1).m_strokeList.begin();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        for (; it2 != (*it1).m_strokeList.end(); ++it2) {
Shinya Kitaoka 120a6e
          if ((*it2).m_edge.m_index == i2->m_edge.m_index &&
Shinya Kitaoka 120a6e
              (*it2).m_gettingOut == !i2->m_gettingOut) {
Shinya Kitaoka 120a6e
            double delta = versus * (it2->m_edge.m_w0 - i2->m_edge.m_w0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            if (delta > 0 && delta < minDelta) {
Shinya Kitaoka 120a6e
              it1Res   = it1;
Shinya Kitaoka 120a6e
              it2Res   = it2;
Shinya Kitaoka 120a6e
              minDelta = delta;
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (minDelta != (std::numeric_limits<double>::max)()) {</double>
Shinya Kitaoka 120a6e
        (*it2Res).m_nextIntersection = i1;
Shinya Kitaoka 120a6e
        (*it2Res).m_nextStroke       = i2;
Shinya Kitaoka 120a6e
        (*it2Res).m_edge.m_w1        = i2->m_edge.m_w0;
Shinya Kitaoka 120a6e
        (*i2).m_nextIntersection     = it1Res;
Shinya Kitaoka 120a6e
        (*i2).m_nextStroke           = it2Res;
Shinya Kitaoka 120a6e
        (*i2).m_edge.m_w1            = it2Res->m_edge.m_w0;
Shinya Kitaoka 120a6e
        i1->m_numInter++;
Shinya Kitaoka 120a6e
        it1Res->m_numInter++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
void markDeadIntersections(list<intersection> &intList,</intersection>
Shinya Kitaoka 120a6e
                           list<intersection>::iterator it);</intersection>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// questa funzione "cuscinetto" serve perche crashava il compilatore in
Shinya Kitaoka 120a6e
// release!!!
Toshihiro Shimizu 890ddd
void inline markDeadIntersectionsRic(list<intersection> &intList,</intersection>
Shinya Kitaoka 120a6e
                                     list<intersection>::iterator it) {</intersection>
Shinya Kitaoka 120a6e
  markDeadIntersections(intList, it);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void markDeadIntersections(list<intersection> &intList,</intersection>
Shinya Kitaoka 120a6e
                           list<intersection>::iterator it) {</intersection>
Shinya Kitaoka 120a6e
  list<intersectedstroke>::iterator it1 = it->m_strokeList.begin();</intersectedstroke>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (it->m_numInter == 1) {
Shinya Kitaoka 120a6e
    while (it1->m_nextIntersection == intList.end()) it1++;
Shinya Kitaoka 120a6e
    assert(it1 != it->m_strokeList.end());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    list<intersection>::iterator nextInt         = it1->m_nextIntersection;</intersection>
Shinya Kitaoka 120a6e
    list<intersectedstroke>::iterator nextStroke = it1->m_nextStroke;</intersectedstroke>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    it->m_numInter          = 0;
Shinya Kitaoka 120a6e
    it1->m_nextIntersection = intList.end();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (nextInt != intList.end() /*&& !nextStroke->m_dead*/) {
Shinya Kitaoka 120a6e
      nextInt->m_numInter--;
Shinya Kitaoka 120a6e
      nextStroke->m_nextIntersection = intList.end();
Shinya Kitaoka 120a6e
      markDeadIntersectionsRic(intList, nextInt);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else if (it->m_numInter == 2)  // intersezione finta (forse)
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    while (it1 != it->m_strokeList.end() &&
Shinya Kitaoka 120a6e
           it1->m_nextIntersection == intList.end())
Shinya Kitaoka 120a6e
      it1++;
Shinya Kitaoka 120a6e
    assert(it1 != it->m_strokeList.end());
Shinya Kitaoka 120a6e
    list<intersectedstroke>::iterator it2 = it1;</intersectedstroke>
Shinya Kitaoka 120a6e
    it2++;
Shinya Kitaoka 120a6e
    while (it2 != it->m_strokeList.end() &&
Shinya Kitaoka 120a6e
           it2->m_nextIntersection == intList.end())
Shinya Kitaoka 120a6e
      it2++;
Shinya Kitaoka 120a6e
    assert(it2 != it->m_strokeList.end());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (it1->m_edge.m_s == it2->m_edge.m_s &&
Shinya Kitaoka 120a6e
        it1->m_edge.m_w0 == it2->m_edge.m_w0)  // intersezione finta
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      list<intersectedstroke>::iterator iit1, iit2;</intersectedstroke>
Shinya Kitaoka 120a6e
      assert(it1->m_nextIntersection != intList.end() &&
Shinya Kitaoka 120a6e
             it2->m_nextIntersection != intList.end());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      iit1 = it1->m_nextStroke;
Shinya Kitaoka 120a6e
      iit2 = it2->m_nextStroke;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      iit2->m_edge.m_w1 = iit1->m_edge.m_w0;
Shinya Kitaoka 120a6e
      iit1->m_edge.m_w1 = iit2->m_edge.m_w0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // if (iit1!=0)
Shinya Kitaoka 120a6e
      (*iit1).m_nextStroke = iit2;
Shinya Kitaoka 120a6e
      // if (iit2!=0)
Shinya Kitaoka 120a6e
      (*iit2).m_nextStroke = iit1;
Shinya Kitaoka 120a6e
      // if (iit1!=0)
Shinya Kitaoka 120a6e
      (*iit1).m_nextIntersection = it2->m_nextIntersection;
Shinya Kitaoka 120a6e
      // if (iit2!=0)
Shinya Kitaoka 120a6e
      (*iit2).m_nextIntersection = it1->m_nextIntersection;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      it->m_numInter          = 0;
Shinya Kitaoka 120a6e
      it1->m_nextIntersection = intList.end();
Shinya Kitaoka 120a6e
      it2->m_nextIntersection = intList.end();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// se cross val era 0, cerco di spostarmi un po' su w per vedere come sono
Shinya Kitaoka 120a6e
// orientate le tangenti agli stroke...
Shinya Kitaoka 120a6e
double nearCrossVal(TStroke *s0, double w0, TStroke *s1, double w1) {
Shinya Kitaoka 120a6e
  double ltot0 = s0->getLength();
Shinya Kitaoka 120a6e
  double ltot1 = s1->getLength();
Shinya Kitaoka 120a6e
  double dl    = tmin(ltot1, ltot0) / 1000;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double crossVal, dl0 = dl, dl1 = dl;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD p0, p1;
Shinya Kitaoka 120a6e
  int count = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (w0 == 1.0) dl0 = -dl0;
Shinya Kitaoka 120a6e
  if (w1 == 1.0) dl1 = -dl1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double l0 = s0->getLength(w0) + dl0;
Shinya Kitaoka 120a6e
  double l1 = s1->getLength(w1) + dl1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  do {
Shinya Kitaoka 120a6e
    p0       = s0->getSpeed(s0->getParameterAtLength(l0));
Shinya Kitaoka 120a6e
    p1       = s1->getSpeed(s1->getParameterAtLength(l1));
Shinya Kitaoka 120a6e
    crossVal = cross(p0, p1);
Shinya Kitaoka 120a6e
    l0 += dl0, l1 += dl1;
Shinya Kitaoka 120a6e
    count++;
Shinya Kitaoka 120a6e
  } while (areAlmostEqual(crossVal, 0.0) &&
Shinya Kitaoka 120a6e
           ((dl0 > 0 && l0 < ltot0) || (dl0 < 0 && l0 > 0)) &&
Shinya Kitaoka 120a6e
           ((dl1 > 0 && l1 < ltot1) || (dl1 < 0 && l1 > 0)));
Shinya Kitaoka 120a6e
  return crossVal;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline void insertBranch(Intersection &interList, IntersectedStroke &item,
Shinya Kitaoka 120a6e
                         bool gettingOut) {
Shinya Kitaoka 120a6e
  if (item.m_edge.m_w0 != (gettingOut ? 1.0 : 0.0)) {
Shinya Kitaoka 120a6e
    item.m_gettingOut = gettingOut;
Shinya Kitaoka 120a6e
    interList.m_strokeList.push_back(item);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double getAngle(const TPointD &p0, const TPointD &p1) {
Shinya Kitaoka 120a6e
  double angle1 = 180 * atan2(p0.x, p0.y) / TConsts::pi;
Shinya Kitaoka 120a6e
  double angle2 = 180 * atan2(p1.x, p1.y) / TConsts::pi;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (angle1 < 0) angle1 = 360 + angle1;
Shinya Kitaoka 120a6e
  if (angle2 < 0) angle2 = 360 + angle2;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return (angle2 - angle1) < 0 ? 360 + angle2 - angle1 : angle2 - angle1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
// nel caso l'angolo tra due stroke in un certo w sia nullo,
Toshihiro Shimizu 890ddd
// si va un po' avanti per vedere come sono orientate....
Shinya Kitaoka 120a6e
double getNearAngle(const TStroke *s1, double w1, bool out1, const TStroke *s2,
Shinya Kitaoka 120a6e
                    double w2, bool out2) {
Shinya Kitaoka 120a6e
  bool verse1  = (out1 && w1 < 1) || (!out1 && w1 == 0);
Shinya Kitaoka 120a6e
  bool verse2  = (out2 && w2 < 1) || (!out2 && w2 == 0);
Shinya Kitaoka 120a6e
  double ltot1 = s1->getLength();
Shinya Kitaoka 120a6e
  double ltot2 = s2->getLength();
Shinya Kitaoka 120a6e
  double l1    = s1->getLength(w1);
Shinya Kitaoka 120a6e
  double l2    = s2->getLength(w2);
Shinya Kitaoka 120a6e
  double dl    = min(ltot1, ltot2) / 1000;
Shinya Kitaoka 120a6e
  double dl1   = verse1 ? dl : -dl;
Shinya Kitaoka 120a6e
  double dl2   = verse2 ? dl : -dl;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (((verse1 && l1 < ltot1) || (!verse1 && l1 > 0)) &&
Shinya Kitaoka 120a6e
         ((verse2 && l2 < ltot2) || (!verse2 && l2 > 0))) {
Shinya Kitaoka 120a6e
    l1 += dl1;
Shinya Kitaoka 120a6e
    l2 += dl2;
Shinya Kitaoka 120a6e
    TPointD p1   = (out1 ? 1 : -1) * s1->getSpeed(s1->getParameterAtLength(l1));
Shinya Kitaoka 120a6e
    TPointD p2   = (out2 ? 1 : -1) * s2->getSpeed(s2->getParameterAtLength(l2));
Shinya Kitaoka 120a6e
    double angle = getAngle(p1, p2);
Shinya Kitaoka 120a6e
    if (!areAlmostEqual(angle, 0, 1e-9)) return angle;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool makeEdgeIntersection(Intersection &interList, IntersectedStroke &item1,
Shinya Kitaoka 120a6e
                          IntersectedStroke &item2, const TPointD &p1a,
Shinya Kitaoka 120a6e
                          const TPointD &p1b, const TPointD &p2a,
Shinya Kitaoka 120a6e
                          const TPointD &p2b) {
Shinya Kitaoka 120a6e
  double angle1 = getAngle(p1a, p1b);
Shinya Kitaoka 120a6e
  double angle2 = getAngle(p1a, p2a);
Shinya Kitaoka 120a6e
  double angle3 = getAngle(p1a, p2b);
Shinya Kitaoka 120a6e
  double angle;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool eraseP1b = false, eraseP2a = false, eraseP2b = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (areAlmostEqual(angle1, 0, 1e-9)) {
Shinya Kitaoka 120a6e
    angle1 = getNearAngle(item1.m_edge.m_s, item1.m_edge.m_w0, true,
Shinya Kitaoka 120a6e
                          item1.m_edge.m_s, item1.m_edge.m_w0, false);
Shinya Kitaoka 120a6e
    if (areAlmostEqual(angle1, 1e-9)) eraseP1b = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (areAlmostEqual(angle2, 0, 1e-9)) {
Shinya Kitaoka 120a6e
    angle2 = getNearAngle(item1.m_edge.m_s, item1.m_edge.m_w0, true,
Shinya Kitaoka 120a6e
                          item2.m_edge.m_s, item2.m_edge.m_w0, true);
Shinya Kitaoka 120a6e
    if (areAlmostEqual(angle2, 1e-9)) eraseP2a = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (areAlmostEqual(angle3, 0, 1e-9)) {
Shinya Kitaoka 120a6e
    angle3 = getNearAngle(item1.m_edge.m_s, item1.m_edge.m_w0, true,
Shinya Kitaoka 120a6e
                          item2.m_edge.m_s, item2.m_edge.m_w0, false);
Shinya Kitaoka 120a6e
    if (areAlmostEqual(angle3, 1e-9)) eraseP2b = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (areAlmostEqual(angle1, angle2, 1e-9)) {
Shinya Kitaoka 120a6e
    angle = getNearAngle(item1.m_edge.m_s, item1.m_edge.m_w0, false,
Shinya Kitaoka 120a6e
                         item2.m_edge.m_s, item2.m_edge.m_w0, true);
Shinya Kitaoka 120a6e
    if (angle != 0) {
Shinya Kitaoka 120a6e
      angle2 += angle;
Shinya Kitaoka 120a6e
      if (angle2 > 360) angle2 -= 360;
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      eraseP2a = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (areAlmostEqual(angle1, angle3, 1e-9)) {
Shinya Kitaoka 120a6e
    angle = getNearAngle(item1.m_edge.m_s, item1.m_edge.m_w0, false,
Shinya Kitaoka 120a6e
                         item2.m_edge.m_s, item2.m_edge.m_w0, false);
Shinya Kitaoka 120a6e
    if (angle != 0) {
Shinya Kitaoka 120a6e
      angle3 += angle;
Shinya Kitaoka 120a6e
      if (angle3 > 360) angle3 -= 360;
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      eraseP2b = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (areAlmostEqual(angle2, angle3, 1e-9)) {
Shinya Kitaoka 120a6e
    angle = getNearAngle(item1.m_edge.m_s, item1.m_edge.m_w0, false,
Shinya Kitaoka 120a6e
                         item2.m_edge.m_s, item2.m_edge.m_w0, true);
Shinya Kitaoka 120a6e
    if (angle != 0) {
Shinya Kitaoka 120a6e
      angle3 += angle;
Shinya Kitaoka 120a6e
      if (angle3 > 360) angle3 -= 360;
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      eraseP2b = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int fac =
Shinya Kitaoka 120a6e
      (angle1 < angle2) | ((angle1 < angle3) << 1) | ((angle2 < angle3) << 2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch (fac) {
Shinya Kitaoka 120a6e
    CASE 0 :  // p1a p2b p2a p1b
Shinya Kitaoka 120a6e
              insertBranch(interList, item1, true);
Shinya Kitaoka 120a6e
    if (!eraseP2b) insertBranch(interList, item2, false);
Shinya Kitaoka 120a6e
    if (!eraseP2a) insertBranch(interList, item2, true);
Shinya Kitaoka 120a6e
    if (!eraseP1b) insertBranch(interList, item1, false);
Shinya Kitaoka 120a6e
    CASE 1 :  // p1a p2b p1b p2a
Shinya Kitaoka 120a6e
              insertBranch(interList, item1, true);
Shinya Kitaoka 120a6e
    if (!eraseP2b) insertBranch(interList, item2, false);
Shinya Kitaoka 120a6e
    if (!eraseP1b) insertBranch(interList, item1, false);
Shinya Kitaoka 120a6e
    if (!eraseP2a) insertBranch(interList, item2, true);
Shinya Kitaoka 120a6e
    CASE 2 : assert(false);
Shinya Kitaoka 120a6e
    CASE 3 :  // p1a p1b p2b p2a
Shinya Kitaoka 120a6e
              insertBranch(interList, item1, true);
Shinya Kitaoka 120a6e
    if (!eraseP1b) insertBranch(interList, item1, false);
Shinya Kitaoka 120a6e
    if (!eraseP2b) insertBranch(interList, item2, false);
Shinya Kitaoka 120a6e
    if (!eraseP2a) insertBranch(interList, item2, true);
Shinya Kitaoka 120a6e
    CASE 4 :  // p1a p2a p2b p1b
Shinya Kitaoka 120a6e
              insertBranch(interList, item1, true);
Shinya Kitaoka 120a6e
    if (!eraseP2a) insertBranch(interList, item2, true);
Shinya Kitaoka 120a6e
    if (!eraseP2b) insertBranch(interList, item2, false);
Shinya Kitaoka 120a6e
    if (!eraseP1b) insertBranch(interList, item1, false);
Shinya Kitaoka 120a6e
    CASE 5 : assert(false);
Shinya Kitaoka 120a6e
    CASE 6 :  // p1a p2a p1b p2b
Shinya Kitaoka 120a6e
              insertBranch(interList, item1, true);
Shinya Kitaoka 120a6e
    if (!eraseP2a) insertBranch(interList, item2, true);
Shinya Kitaoka 120a6e
    if (!eraseP1b) insertBranch(interList, item1, false);
Shinya Kitaoka 120a6e
    if (!eraseP2b) insertBranch(interList, item2, false);
Shinya Kitaoka 120a6e
    CASE 7 :  // p1a p1b p2a p2b
Shinya Kitaoka 120a6e
              insertBranch(interList, item1, true);
Shinya Kitaoka 120a6e
    if (!eraseP1b) insertBranch(interList, item1, false);
Shinya Kitaoka 120a6e
    if (!eraseP2a) insertBranch(interList, item2, true);
Shinya Kitaoka 120a6e
    if (!eraseP2b) insertBranch(interList, item2, false);
Shinya Kitaoka 120a6e
  DEFAULT:
Shinya Kitaoka 120a6e
    assert(false);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool makeIntersection(IntersectionData &intData, const vector<vistroke *=""> &s,</vistroke>
Shinya Kitaoka 120a6e
                      int ii, int jj, DoublePair inter, int strokeSize,
Shinya Kitaoka 120a6e
                      Intersection &interList) {
Shinya Kitaoka 120a6e
  IntersectedStroke item1(intData.m_intList.end(), NULL_ITER),
Shinya Kitaoka 120a6e
      item2(intData.m_intList.end(), NULL_ITER);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  interList.m_intersection = s[ii]->m_s->getPoint(inter.first);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  item1.m_edge.m_w0 = inter.first;
Shinya Kitaoka 120a6e
  item2.m_edge.m_w0 = inter.second;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (ii >= 0 && ii < strokeSize) {
Shinya Kitaoka 120a6e
    item1.m_edge.m_s     = s[ii]->m_s;
Shinya Kitaoka 120a6e
    item1.m_edge.m_index = ii;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    if (ii < 0) {
Shinya Kitaoka 120a6e
      item1.m_edge.m_s     = intData.m_autocloseMap[ii];
Shinya Kitaoka 120a6e
      item1.m_edge.m_index = ii;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      item1.m_edge.m_s     = s[ii]->m_s;
Shinya Kitaoka 120a6e
      item1.m_edge.m_index = -(ii + intData.maxAutocloseId * 100000);
Shinya Kitaoka 120a6e
      intData.m_autocloseMap[item1.m_edge.m_index] = item1.m_edge.m_s;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (jj >= 0 && jj < strokeSize) {
Shinya Kitaoka 120a6e
    item2.m_edge.m_s     = s[jj]->m_s;
Shinya Kitaoka 120a6e
    item2.m_edge.m_index = jj;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    if (jj < 0) {
Shinya Kitaoka 120a6e
      item2.m_edge.m_s     = intData.m_autocloseMap[jj];
Shinya Kitaoka 120a6e
      item2.m_edge.m_index = jj;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      item2.m_edge.m_s     = s[jj]->m_s;
Shinya Kitaoka 120a6e
      item2.m_edge.m_index = -(jj + intData.maxAutocloseId * 100000);
Shinya Kitaoka 120a6e
      intData.m_autocloseMap[item2.m_edge.m_index] = item2.m_edge.m_s;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool reversed = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD p0, p0b, p1, p1b;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool ret1 = item1.m_edge.m_s->getSpeedTwoValues(item1.m_edge.m_w0, p0, p0b);
Shinya Kitaoka 120a6e
  bool ret2 = item2.m_edge.m_s->getSpeedTwoValues(item2.m_edge.m_w0, p1, p1b);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (ret1 || ret2)  // punto angoloso!!!!
Shinya Kitaoka 120a6e
    return makeEdgeIntersection(interList, item1, item2, p0, p0b, p1, p1b);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double crossVal = cross(p0, p1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // crossVal = cross(p0, p1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (areAlmostEqual(crossVal, 0.0)) {
Shinya Kitaoka 120a6e
    bool endpoint1 = (item1.m_edge.m_w0 == 0.0 || item1.m_edge.m_w0 == 1.0);
Shinya Kitaoka 120a6e
    bool endpoint2 = (item2.m_edge.m_w0 == 0.0 || item2.m_edge.m_w0 == 1.0);
Shinya Kitaoka 120a6e
    if (endpoint1 && endpoint2 && ((p0.x * p1.x >= 0 && p0.y * p1.y >= 0 &&
Shinya Kitaoka 120a6e
                                    item1.m_edge.m_w0 != item2.m_edge.m_w0) ||
Shinya Kitaoka 120a6e
                                   (p0.x * p1.x <= 0 && p0.y * p1.y <= 0 &&
Shinya Kitaoka 120a6e
                                    item1.m_edge.m_w0 == item2.m_edge.m_w0)))
Shinya Kitaoka 120a6e
    // due endpoint a 180 gradi;metto
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      item1.m_gettingOut = (item1.m_edge.m_w0 == 0.0);
Shinya Kitaoka 120a6e
      interList.m_strokeList.push_back(item1);
Shinya Kitaoka 120a6e
      item2.m_gettingOut = (item2.m_edge.m_w0 == 0.0);
Shinya Kitaoka 120a6e
      interList.m_strokeList.push_back(item2);
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    // crossVal = nearCrossVal(item1.m_edge.m_s, item1.m_edge.m_w0,
Shinya Kitaoka 120a6e
    // item2.m_edge.m_s, item2.m_edge.m_w0);
Shinya Kitaoka 120a6e
    // if (areAlmostEqual(crossVal, 0.0))
Shinya Kitaoka 120a6e
    // return false;
Shinya Kitaoka 120a6e
    return makeEdgeIntersection(interList, item1, item2, p0, p0b, p1, p1b);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (crossVal > 0)
Shinya Kitaoka 120a6e
    reversed = true;  // std::reverse(interList.m_strokeList.begin(),
Shinya Kitaoka 120a6e
                      // interList.m_strokeList.end());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (item1.m_edge.m_w0 != 1.0) {
Shinya Kitaoka 120a6e
    item1.m_gettingOut = true;
Shinya Kitaoka 120a6e
    interList.m_strokeList.push_back(item1);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (item2.m_edge.m_w0 != (reversed ? 0.0 : 1.0)) {
Shinya Kitaoka 120a6e
    item2.m_gettingOut = !reversed;
Shinya Kitaoka 120a6e
    interList.m_strokeList.push_back(item2);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (item1.m_edge.m_w0 != 0.0) {
Shinya Kitaoka 120a6e
    item1.m_gettingOut = false;
Shinya Kitaoka 120a6e
    interList.m_strokeList.push_back(item1);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (item2.m_edge.m_w0 != (reversed ? 1.0 : 0.0)) {
Shinya Kitaoka 120a6e
    item2.m_gettingOut = reversed;
Shinya Kitaoka 120a6e
    interList.m_strokeList.push_back(item2);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
void checkAuto(const vector<vistroke*>& s)</vistroke*>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
for (int i=0; i<(int)s.size(); i++)
Toshihiro Shimizu 890ddd
for (int j=i+1; j<(int)s.size(); j++)
Shinya Kitaoka 120a6e
  if (s[i]->m_s->getChunkCount()==1 && s[j]->m_s->getChunkCount()==1) //se ha
Shinya Kitaoka 120a6e
una sola quadratica, probabilmente e' un autoclose.
Shinya Kitaoka 120a6e
          {
Shinya Kitaoka 120a6e
                const TThickQuadratic*q = s[i]->m_s->getChunk(0);
Shinya Kitaoka 120a6e
                const TThickQuadratic*p = s[j]->m_s->getChunk(0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                if (areAlmostEqual(q->getP0(), p->getP0(), 1e-2) &&
Shinya Kitaoka 120a6e
areAlmostEqual(q->getP2(), p->getP2(), 1e-2))
Shinya Kitaoka 120a6e
                  assert(!"eccolo!");
Shinya Kitaoka 120a6e
                if (areAlmostEqual(q->getP0(), p->getP2(), 1e-2) &&
Shinya Kitaoka 120a6e
areAlmostEqual(q->getP2(), p->getP0(), 1e-2))
Shinya Kitaoka 120a6e
                  assert(!"eccolo!");
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool addAutocloseIntersection(IntersectionData &intData, vector<vistroke *=""> &s,</vistroke>
Shinya Kitaoka 120a6e
                              int ii, int jj, double w0, double w1,
Shinya Kitaoka 120a6e
                              int strokeSize) {
Shinya Kitaoka 120a6e
  list<intersection>::reverse_iterator rit = intData.m_intList.rbegin();</intersection>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(w0 >= 0.0 && w0 <= 1.0);
Shinya Kitaoka 120a6e
  assert(w1 >= 0.0 && w1 <= 1.0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (; rit != intData.m_intList.rend();
Shinya Kitaoka 120a6e
       rit++)  // evito di fare la connessione, se gia' ce
Shinya Kitaoka 120a6e
               // ne e' una simile tra le stesse due stroke
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if (rit->m_strokeList.size() < 2) continue;
Shinya Kitaoka 120a6e
    list<intersectedstroke>::iterator is = rit->m_strokeList.begin();</intersectedstroke>
Shinya Kitaoka 120a6e
    int s0                               = is->m_edge.m_index;
Shinya Kitaoka 120a6e
    if (s0 < 0) continue;
Shinya Kitaoka 120a6e
    double ww0 = is->m_edge.m_w0;
Shinya Kitaoka 120a6e
    is++;
Shinya Kitaoka 120a6e
    if (is->m_edge.m_index == s0 && is->m_edge.m_w0 == ww0) {
Shinya Kitaoka 120a6e
      is++;
Shinya Kitaoka 120a6e
      if (is == rit->m_strokeList.end()) continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    int s1 = is->m_edge.m_index;
Shinya Kitaoka 120a6e
    if (s1 < 0) continue;
Shinya Kitaoka 120a6e
    double ww1 = is->m_edge.m_w0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!((s0 == ii && s1 == jj) || (s0 == jj && s1 == ii))) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (s0 == ii && areAlmostEqual(w0, ww0, 0.1) &&
Shinya Kitaoka 120a6e
        areAlmostEqual(w1, ww1, 0.1))
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    else if (s1 == ii && areAlmostEqual(w0, ww1, 0.1) &&
Shinya Kitaoka 120a6e
             areAlmostEqual(w1, ww0, 0.1))
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  vector<tpointd> v;</tpointd>
Shinya Kitaoka 120a6e
  v.push_back(s[ii]->m_s->getPoint(w0));
Shinya Kitaoka 120a6e
  v.push_back(s[jj]->m_s->getPoint(w1));
Shinya Kitaoka 120a6e
  if (v[0] == v[1])  // le stroke si intersecano , ma la fottuta funzione
Shinya Kitaoka 120a6e
                     // intersect non ha trovato l'intersezione(tipicamente,
Shinya Kitaoka 120a6e
                     // questo accade agli estremi)!!!
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    addIntersection(intData, s, ii, jj, DoublePair(w0, w1), strokeSize);
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // se gia e' stato messo questo autoclose, evito
Shinya Kitaoka 120a6e
  for (int i = 0; i < (int)s.size(); i++)
Shinya Kitaoka 120a6e
    if (s[i]->m_s->getChunkCount() ==
Shinya Kitaoka 120a6e
        1)  // se ha una sola quadratica, probabilmente e' un autoclose.
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      const TThickQuadratic *q = s[i]->m_s->getChunk(0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (areAlmostEqual(q->getP0(), v[0], 1e-2) &&
Shinya Kitaoka 120a6e
              areAlmostEqual(q->getP2(), v[1], 1e-2) ||
Shinya Kitaoka 120a6e
          areAlmostEqual(q->getP0(), v[1], 1e-2) &&
Shinya Kitaoka 120a6e
              areAlmostEqual(q->getP2(), v[0], 1e-2)) {
Shinya Kitaoka 120a6e
        return true;
Shinya Kitaoka 120a6e
        addIntersection(intData, s, i, ii, DoublePair(0.0, w0), strokeSize);
Shinya Kitaoka 120a6e
        addIntersection(intData, s, i, jj, DoublePair(1.0, w1), strokeSize);
Shinya Kitaoka 120a6e
        return true;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  s.push_back(new VIStroke(new TStroke(v)));
Shinya Kitaoka 120a6e
  addIntersection(intData, s, s.size() - 1, ii, DoublePair(0.0, w0),
Shinya Kitaoka 120a6e
                  strokeSize);
Shinya Kitaoka 120a6e
  addIntersection(intData, s, s.size() - 1, jj, DoublePair(1.0, w1),
Shinya Kitaoka 120a6e
                  strokeSize);
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double g_autocloseTolerance = c_newAutocloseTolerance;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool makeEndPointConnections(vector<vistroke *=""> &s, int ii, bool isIStartPoint,</vistroke>
Shinya Kitaoka 120a6e
                             int jj, bool isJStartPoint,
Shinya Kitaoka 120a6e
                             IntersectionData &intData, int strokeSize) {
Shinya Kitaoka 120a6e
  double x0 = (isIStartPoint ? 0.0 : 1.0);
Shinya Kitaoka 120a6e
  double x1 = (isJStartPoint ? 0.0 : 1.0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TThickPoint p0 = s[ii]->m_s->getThickPoint(x0);
Shinya Kitaoka 120a6e
  TThickPoint p1 = s[jj]->m_s->getThickPoint(x1);
Shinya Kitaoka 120a6e
  double dist2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  dist2 = tdistance2(p0, p1);
Shinya Kitaoka 120a6e
  if (dist2 >= 0 &&
Shinya Kitaoka 120a6e
      dist2 <=
Shinya Kitaoka 120a6e
          tmax((g_autocloseTolerance == c_oldAutocloseTolerance) ? 9.09 : 2.0,
Shinya Kitaoka 120a6e
               g_autocloseTolerance * (p0.thick + p1.thick) *
Shinya Kitaoka 120a6e
                   (p0.thick +
Shinya Kitaoka 120a6e
                    p1.thick)))  // 0.01 tiene conto di quando thick==0
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if (ii == jj) {
Shinya Kitaoka 120a6e
      TRectD r = s[ii]->m_s->getBBox();  // se e' un autoclose su una stroke
Shinya Kitaoka 120a6e
                                         // piccolissima, creerebbe uan area
Shinya Kitaoka 120a6e
                                         // trascurabile, ignoro
Shinya Kitaoka 120a6e
      if (fabs(r.x1 - r.x0) < 2 && fabs(r.y1 - r.y0) < 2) return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return addAutocloseIntersection(intData, s, ii, jj, x0, x1, strokeSize);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
if (s[ii]==s[jj])
Toshihiro Shimizu 890ddd
  return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
dist2 = c_autocloseTolerance*tdistance2(p01, p10);
Toshihiro Shimizu 890ddd
if (dist2>0 && dist2<=(p01.thick+p10.thick)*(p01.thick+p10.thick))
Toshihiro Shimizu 890ddd
  addAutocloseIntersection(intData, s, ii, jj, 1.0, 0.0, strokeSize);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
dist2 = c_autocloseTolerance*tdistance2(p00, p10);
Toshihiro Shimizu 890ddd
if ((dist2>0 && dist2<=(p00.thick+p10.thick)*(p00.thick+p10.thick)))
Toshihiro Shimizu 890ddd
  addAutocloseIntersection(intData, s, ii, jj, 0.0, 0.0, strokeSize);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
dist2 = c_autocloseTolerance*tdistance2(p01, p11);
Toshihiro Shimizu 890ddd
if ((dist2>0 && dist2<=(p01.thick+p11.thick)*(p01.thick+p11.thick)))
Toshihiro Shimizu 890ddd
  addAutocloseIntersection(intData, s, ii, jj, 1.0, 1.0, strokeSize);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double getCurlW(TStroke *s, bool isBegin)  // trova il punto di split su una
Shinya Kitaoka 120a6e
                                           // stroke, in prossimita di un
Shinya Kitaoka 120a6e
                                           // ricciolo;
Shinya Kitaoka 120a6e
// un ricciolo c'e' se la curva ha un  min o max relativo su x seguito da uno su
Shinya Kitaoka 120a6e
// y, o viceversa.
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  int numChunks = s->getChunkCount();
Shinya Kitaoka 120a6e
  double dx2, dx1 = 0, dy2, dy1 = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int i = 0; i < numChunks; i++) {
Shinya Kitaoka 120a6e
    const TQuadratic *q = s->getChunk(isBegin ? i : numChunks - 1 - i);
Shinya Kitaoka 120a6e
    dy2                 = q->getP1().y - q->getP0().y;
Shinya Kitaoka 120a6e
    if (dy1 * dy2 < 0) break;
Shinya Kitaoka 120a6e
    dy1 = dy2;
Shinya Kitaoka 120a6e
    dy2 = q->getP2().y - q->getP1().y;
Shinya Kitaoka 120a6e
    if (dy1 * dy2 < 0) break;
Shinya Kitaoka 120a6e
    dy1 = dy2;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (i == numChunks) return -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int maxMin0 = isBegin ? i : numChunks - 1 - i;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int j = 0; j < numChunks; j++) {
Shinya Kitaoka 120a6e
    const TQuadratic *q = s->getChunk(isBegin ? j : numChunks - 1 - j);
Shinya Kitaoka 120a6e
    dx2                 = q->getP1().x - q->getP0().x;
Shinya Kitaoka 120a6e
    if (dx1 * dx2 < 0) break;
Shinya Kitaoka 120a6e
    dx1 = dx2;
Shinya Kitaoka 120a6e
    dx2 = q->getP2().x - q->getP1().x;
Shinya Kitaoka 120a6e
    if (dx1 * dx2 < 0) break;
Shinya Kitaoka 120a6e
    dx1 = dx2;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (j == numChunks) return -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int maxMin1 = isBegin ? j : numChunks - 1 - j;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return getWfromChunkAndT(
Shinya Kitaoka 120a6e
      s, isBegin ? tmax(maxMin0, maxMin1) : tmin(maxMin0, maxMin1),
Shinya Kitaoka 120a6e
      isBegin ? 1.0 : 0.0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef Levo
Toshihiro Shimizu 890ddd
bool lastIsX = false, lastIsY = false;
Toshihiro Shimizu 890ddd
for (int i = 0; i < numChunks; i++) {
Shinya Kitaoka 120a6e
  const TThickQuadratic *q = s->getChunk(isBegin ? i : numChunks - 1 - i);
Shinya Kitaoka 120a6e
  if ((q->getP0().y < q->getP1().y &&
Shinya Kitaoka 120a6e
       q->getP2().y <
Shinya Kitaoka 120a6e
           q->getP1().y) ||  // la quadratica ha un minimo o massimo relativo
Shinya Kitaoka 120a6e
      (q->getP0().y > q->getP1().y && q->getP2().y > q->getP1().y)) {
Shinya Kitaoka 120a6e
    double w = getWfromChunkAndT(s, isBegin ? i : numChunks - 1 - i,
Shinya Kitaoka 120a6e
                                 isBegin ? 1.0 : 0.0);
Shinya Kitaoka 120a6e
    if (lastIsX)  // e' il secondo min o max relativo
Shinya Kitaoka 120a6e
      return w;
Shinya Kitaoka 120a6e
    lastIsX = false;
Shinya Kitaoka 120a6e
    lastIsY = true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  } else if ((q->getP0().x < q->getP1().x &&
Shinya Kitaoka 120a6e
              q->getP2().x <
Shinya Kitaoka 120a6e
                  q->getP1()
Shinya Kitaoka 120a6e
                      .x) ||  // la quadratica ha un minimo o massimo relativo
Shinya Kitaoka 120a6e
             (q->getP0().x > q->getP1().x && q->getP2().x > q->getP1().x)) {
Shinya Kitaoka 120a6e
    double w = getWfromChunkAndT(s, isBegin ? i : numChunks - 1 - i,
Shinya Kitaoka 120a6e
                                 isBegin ? 1.0 : 0.0);
Shinya Kitaoka 120a6e
    if (lastIsY)  // e' il secondo min o max relativo
Shinya Kitaoka 120a6e
      return w;
Shinya Kitaoka 120a6e
    lastIsX = true;
Shinya Kitaoka 120a6e
    lastIsY = false;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void makeConnection(vector<vistroke *=""> &s, int ii, int jj, bool isBegin,</vistroke>
Shinya Kitaoka 120a6e
                    IntersectionData &intData, int strokeSize) {
Shinya Kitaoka 120a6e
  if (s[ii]->m_s->isSelfLoop()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double w0 = isBegin ? 0.0 : 1.0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TThickPoint p0 = s[ii]->m_s->getThickPoint(w0);
Shinya Kitaoka 120a6e
  double t, dist2;
Shinya Kitaoka 120a6e
  int index;
Shinya Kitaoka 120a6e
  TStroke sAux, *sComp;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (ii == jj)  // per trovare le intersezioni con una stroke e se stessa, si
Shinya Kitaoka 120a6e
                 // toglie il
Shinya Kitaoka 120a6e
  // pezzo di stroke di cui si cercano vicinanze fino alla prima curva
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    double w = getCurlW(s[ii]->m_s, isBegin);
Shinya Kitaoka 120a6e
    if (w == -1) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    split<tstroke>(*(s[ii]->m_s), tmin(isBegin ? 1.0 : 0.0, w),</tstroke>
Shinya Kitaoka 120a6e
                   tmax(isBegin ? 1.0 : 0.0, w), sAux);
Shinya Kitaoka 120a6e
    sComp = &sAux;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    sComp = s[jj]->m_s;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (sComp->getNearestChunk(p0, t, index, dist2) && dist2 > 0) {
Shinya Kitaoka 120a6e
    if (ii == jj) {
Shinya Kitaoka 120a6e
      double dummy;
Shinya Kitaoka 120a6e
      s[jj]->m_s->getNearestChunk(sComp->getChunk(index)->getPoint(t), t, index,
Shinya Kitaoka 120a6e
                                  dummy);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // if (areAlmostEqual(w, 0.0, 0.05) || areAlmostEqual(w, 1.0, 0.05))
Shinya Kitaoka 120a6e
    //  return; //se w e' vicino ad un estremo, rientra nell'autoclose point to
Shinya Kitaoka 120a6e
    //  point
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // if (s[jj]->m_s->getLength(w)<=s[jj]->m_s->getThickPoint(0).thick ||
Shinya Kitaoka 120a6e
    //    s[jj]->m_s->getLength(w, 1)<=s[jj]->m_s->getThickPoint(1).thick)
Shinya Kitaoka 120a6e
    //  return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TThickPoint p1 = s[jj]->m_s->getChunk(index)->getThickPoint(t);
Shinya Kitaoka 120a6e
    if (dist2 <=
Shinya Kitaoka 120a6e
        (tmax(
Shinya Kitaoka 120a6e
            (g_autocloseTolerance == c_oldAutocloseTolerance) ? 9.09 : 2.0,
Shinya Kitaoka 120a6e
            (g_autocloseTolerance + 0.7) * (p0.thick + p1.thick) *
Shinya Kitaoka 120a6e
                (p0.thick + p1.thick))))  // 0.01 tiene conto di quando thick==0
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      // if (areAlmostEqual(dist2, 0.0))
Shinya Kitaoka 120a6e
      //  return;
Shinya Kitaoka 120a6e
      double w = getWfromChunkAndT(s[jj]->m_s, index, t);
Shinya Kitaoka 120a6e
      addAutocloseIntersection(intData, s, ii, jj, w0, w, strokeSize);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void autoclose(vector<vistroke *=""> &s, int ii, int jj, IntersectionData &IntData,</vistroke>
Shinya Kitaoka 120a6e
               int strokeSize) {
Shinya Kitaoka 120a6e
  bool ret1 = false, ret2 = false, ret3 = false, ret4 = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!s[ii]->m_s->isSelfLoop() && !s[jj]->m_s->isSelfLoop()) {
Shinya Kitaoka 120a6e
    ret1 = makeEndPointConnections(s, ii, true, jj, false, IntData, strokeSize);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (ii != jj) {
Shinya Kitaoka 120a6e
      ret2 =
Shinya Kitaoka 120a6e
          makeEndPointConnections(s, ii, true, jj, true, IntData, strokeSize);
Shinya Kitaoka 120a6e
      ret3 =
Shinya Kitaoka 120a6e
          makeEndPointConnections(s, ii, false, jj, true, IntData, strokeSize);
Shinya Kitaoka 120a6e
      ret4 =
Shinya Kitaoka 120a6e
          makeEndPointConnections(s, ii, false, jj, false, IntData, strokeSize);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!ret1 && !ret2) makeConnection(s, ii, jj, true, IntData, strokeSize);
Shinya Kitaoka 120a6e
  if (!ret1 && !ret4) makeConnection(s, jj, ii, false, IntData, strokeSize);
Shinya Kitaoka 120a6e
  if (ii != jj) {
Shinya Kitaoka 120a6e
    if (!ret2 && !ret3) makeConnection(s, jj, ii, true, IntData, strokeSize);
Shinya Kitaoka 120a6e
    if (!ret3 && !ret4) makeConnection(s, ii, jj, false, IntData, strokeSize);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPointD inline getTangent(const IntersectedStroke &item) {
Shinya Kitaoka 120a6e
  return (item.m_gettingOut ? 1 : -1) *
Shinya Kitaoka 120a6e
         item.m_edge.m_s->getSpeed(item.m_edge.m_w0, item.m_gettingOut);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void addBranch(IntersectionData &intData, list<intersectedstroke> &strokeList,</intersectedstroke>
Shinya Kitaoka 120a6e
               const vector<vistroke *=""> &s, int ii, double w, int strokeSize,</vistroke>
Shinya Kitaoka 120a6e
               bool gettingOut) {
Shinya Kitaoka 120a6e
  list<intersectedstroke>::iterator it1, it2;</intersectedstroke>
Shinya Kitaoka 120a6e
  TPointD tanRef, lastTan;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  IntersectedStroke item(intData.m_intList.end(), strokeList.end());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (ii < 0) {
Shinya Kitaoka 120a6e
    item.m_edge.m_s     = intData.m_autocloseMap[ii];
Shinya Kitaoka 120a6e
    item.m_edge.m_index = ii;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    item.m_edge.m_s = s[ii]->m_s;
Shinya Kitaoka 120a6e
    if (ii < strokeSize)
Shinya Kitaoka 120a6e
      item.m_edge.m_index = ii;
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      item.m_edge.m_index = -(ii + intData.maxAutocloseId * 100000);
Shinya Kitaoka 120a6e
      intData.m_autocloseMap[item.m_edge.m_index] = item.m_edge.m_s;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  item.m_edge.m_w0  = w;
Shinya Kitaoka 120a6e
  item.m_gettingOut = gettingOut;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
if (strokeList.size()==2) //potrebbero essere orientati male; due branch possono
Shinya Kitaoka 120a6e
stare come vogliono, ma col terzo no.
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
TPointD tan2 = getTangent(strokeList.back());
Shinya Kitaoka 120a6e
TPointD aux= getTangent(*(strokeList.begin()));
Shinya Kitaoka 120a6e
double crossVal = cross(aux, tan2);
Shinya Kitaoka 120a6e
if (areAlmostEqual(aux, tan2, 1e-3))
Shinya Kitaoka 120a6e
    return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (crossVal>0)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
          std::reverse(strokeList.begin(), strokeList.end());
Shinya Kitaoka 120a6e
//tan2 = getTangent(strokeList.back());
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
if (areAlmostEqual(lastCross, 0.0) && tan1.x*tan2.x>=0 && tan1.y*tan2.y>=0)
Shinya Kitaoka 120a6e
//significa angolo tra tangenti nullo
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
          crossVal =  nearCrossVal(item.m_edge.m_s, item.m_edge.m_w0,
Shinya Kitaoka 120a6e
strokeList.back().m_edge.m_s, strokeList.back().m_edge.m_w0);
Shinya Kitaoka 120a6e
if (areAlmostEqual(crossVal, 0.0))
Shinya Kitaoka 120a6e
            return;
Shinya Kitaoka 120a6e
          if (!strokeList.back().m_gettingOut)
Shinya Kitaoka 120a6e
            crossVal = -crossVal;
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  tanRef  = getTangent(item);
Shinya Kitaoka 120a6e
  lastTan = getTangent(strokeList.back());
Shinya Kitaoka 120a6e
  /*
Toshihiro Shimizu 890ddd
for (it=strokeList.begin(); it!=strokeList.end(); ++it)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
  TPointD curTan = getTangent(*it);
Shinya Kitaoka 120a6e
double angle0 = getAngle(lastTan, curTan);
Shinya Kitaoka 120a6e
double angle1 = getAngle(lastTan, tanRef);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
if (areAlmostEqual(angle0, angle1, 1e-8))
Toshihiro Shimizu 890ddd
    {
Shinya Kitaoka 120a6e
          double angle = getNearAngle( it->m_edge.m_s,  it->m_edge.m_w0,
Shinya Kitaoka 120a6e
it->m_gettingOut,
Shinya Kitaoka 120a6e
                                      item.m_edge.m_s, item.m_edge.m_w0,
Shinya Kitaoka 120a6e
item.m_gettingOut);
Shinya Kitaoka 120a6e
angle1 += angle; if (angle1>360) angle1-=360;
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
if (angle1
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
strokeList.insert(it, item);
Shinya Kitaoka 120a6e
return;
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
  lastTan=curTan;
Shinya Kitaoka 120a6e
}*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  it2 = strokeList.end();
Shinya Kitaoka 120a6e
  it2--;
Shinya Kitaoka 120a6e
  for (it1 = strokeList.begin(); it1 != strokeList.end(); ++it1) {
Shinya Kitaoka 120a6e
    TPointD curTan = getTangent(*it1);
Shinya Kitaoka 120a6e
    double angle0  = getAngle(lastTan, curTan);
Shinya Kitaoka 120a6e
    double angle1  = getAngle(lastTan, tanRef);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (areAlmostEqual(angle1, 0, 1e-8)) {
Shinya Kitaoka 120a6e
      double angle =
Shinya Kitaoka 120a6e
          getNearAngle(it2->m_edge.m_s, it2->m_edge.m_w0, it2->m_gettingOut,
Shinya Kitaoka 120a6e
                       item.m_edge.m_s, item.m_edge.m_w0, item.m_gettingOut);
Shinya Kitaoka 120a6e
      angle1 += angle;
Shinya Kitaoka 120a6e
      if (angle1 > 360) angle1 -= 360;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (areAlmostEqual(angle0, angle1, 1e-8)) {
Shinya Kitaoka 120a6e
      double angle =
Shinya Kitaoka 120a6e
          getNearAngle(it1->m_edge.m_s, it1->m_edge.m_w0, it1->m_gettingOut,
Shinya Kitaoka 120a6e
                       item.m_edge.m_s, item.m_edge.m_w0, item.m_gettingOut);
Shinya Kitaoka 120a6e
      angle1 += angle;
Shinya Kitaoka 120a6e
      if (angle1 > 360) angle1 -= 360;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (angle1 < angle0) {
Shinya Kitaoka 120a6e
      strokeList.insert(it1, item);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    lastTan = curTan;
Shinya Kitaoka 120a6e
    it2     = it1;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // assert(!"add branch: can't find where to insert!");
Shinya Kitaoka 120a6e
  strokeList.push_back(item);
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void addBranches(IntersectionData &intData, Intersection &intersection,
Shinya Kitaoka 120a6e
                 const vector<vistroke *=""> &s, int ii, int jj,</vistroke>
Shinya Kitaoka 120a6e
                 DoublePair intersectionPair, int strokeSize) {
Shinya Kitaoka 120a6e
  bool foundS1 = false, foundS2 = false;
Shinya Kitaoka 120a6e
  list<intersectedstroke>::iterator it;</intersectedstroke>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(!intersection.m_strokeList.empty());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (it = intersection.m_strokeList.begin();
Shinya Kitaoka 120a6e
       it != intersection.m_strokeList.end(); it++) {
Shinya Kitaoka 120a6e
    if ((ii >= 0 && (*it).m_edge.m_s == s[ii]->m_s &&
Shinya Kitaoka 120a6e
         it->m_edge.m_w0 == intersectionPair.first) ||
Shinya Kitaoka 120a6e
        (ii < 0 && (*it).m_edge.m_index == ii &&
Shinya Kitaoka 120a6e
         it->m_edge.m_w0 == intersectionPair.first))
Shinya Kitaoka 120a6e
      foundS1 = true;
Shinya Kitaoka 120a6e
    if ((jj >= 0 && (*it).m_edge.m_s == s[jj]->m_s &&
Shinya Kitaoka 120a6e
         it->m_edge.m_w0 == intersectionPair.second) ||
Shinya Kitaoka 120a6e
        (jj < 0 && (*it).m_edge.m_index == jj &&
Shinya Kitaoka 120a6e
         it->m_edge.m_w0 == intersectionPair.second))
Shinya Kitaoka 120a6e
      foundS2 = true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (foundS1 && foundS2) {
Shinya Kitaoka 120a6e
    /*
Shinya Kitaoka 120a6e
//errore!(vedi commento sotto) possono essere un sacco di intersezioni
Shinya Kitaoka 120a6e
coincidenti se passano per l'estremo di una quad
Shinya Kitaoka 120a6e
//significa che ci sono due intersezioni coincidenti. cioe' due stroke tangenti.
Shinya Kitaoka 120a6e
quindi devo invertire l'ordine di due branch enlla rosa dei branch.
Shinya Kitaoka 120a6e
list<intersectedstroke>::iterator it1, it2;</intersectedstroke>
Shinya Kitaoka 120a6e
it1=intersection.m_strokeList.begin();
Shinya Kitaoka 120a6e
it2 = it1; it2++;
Shinya Kitaoka 120a6e
for (; it2!=intersection.m_strokeList.end(); ++it1, ++it2)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
if ((*it1).m_gettingOut!=(*it2).m_gettingOut &&((*it1).m_edge.m_index==jj &&
Shinya Kitaoka 120a6e
(*it2).m_edge.m_index==ii) ||
Shinya Kitaoka 120a6e
        ((*it1).m_edge.m_index==ii && (*it2).m_edge.m_index==jj))
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
            IntersectedStroke& el1 = (*it1);
Shinya Kitaoka 120a6e
            IntersectedStroke& el2 = (*it2);
Shinya Kitaoka 120a6e
IntersectedStroke app;
Shinya Kitaoka 120a6e
            app = el1;
Shinya Kitaoka 120a6e
            el1=el2;
Shinya Kitaoka 120a6e
            el2=app;
Shinya Kitaoka 120a6e
            break;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!foundS1) {
Shinya Kitaoka 120a6e
    if (intersectionPair.first != 1)
Shinya Kitaoka 120a6e
      addBranch(intData, intersection.m_strokeList, s, ii,
Shinya Kitaoka 120a6e
                intersectionPair.first, strokeSize, true);
Shinya Kitaoka 120a6e
    if (intersectionPair.first != 0)
Shinya Kitaoka 120a6e
      addBranch(intData, intersection.m_strokeList, s, ii,
Shinya Kitaoka 120a6e
                intersectionPair.first, strokeSize, false);
Shinya Kitaoka 120a6e
    // assert(intersection.m_strokeList.size()-size>0);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!foundS2) {
Shinya Kitaoka 120a6e
    if (intersectionPair.second != 1)
Shinya Kitaoka 120a6e
      addBranch(intData, intersection.m_strokeList, s, jj,
Shinya Kitaoka 120a6e
                intersectionPair.second, strokeSize, true);
Shinya Kitaoka 120a6e
    if (intersectionPair.second != 0)
Shinya Kitaoka 120a6e
      addBranch(intData, intersection.m_strokeList, s, jj,
Shinya Kitaoka 120a6e
                intersectionPair.second, strokeSize, false);
Shinya Kitaoka 120a6e
    // intersection.m_numInter+=intersection.m_strokeList.size()-size;
Shinya Kitaoka 120a6e
    // assert(intersection.m_strokeList.size()-size>0);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void addIntersections(IntersectionData &intData, const vector<vistroke *=""> &s,</vistroke>
Shinya Kitaoka 120a6e
                      int ii, int jj, vector<doublepair> &intersections,</doublepair>
Shinya Kitaoka 120a6e
                      int strokeSize) {
Shinya Kitaoka 120a6e
  for (int k = 0; k < (int)intersections.size(); k++) {
Shinya Kitaoka 120a6e
    if (ii >= strokeSize && (areAlmostEqual(intersections[k].first, 0.0) ||
Shinya Kitaoka 120a6e
                             areAlmostEqual(intersections[k].first, 1.0)))
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    if (jj >= strokeSize && (areAlmostEqual(intersections[k].second, 0.0) ||
Shinya Kitaoka 120a6e
                             areAlmostEqual(intersections[k].second, 1.0)))
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    addIntersection(intData, s, ii, jj, intersections[k], strokeSize);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline double truncate(double x) {
Shinya Kitaoka 120a6e
  x += 1.0;
Shinya Kitaoka 120a6e
  unsigned long *l = (unsigned long *)&x;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
  l[0] &= 0xFFE00000;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  l[1] &= 0xFFE00000;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return x - 1.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void addIntersection(IntersectionData &intData, const vector<vistroke *=""> &s,</vistroke>
Shinya Kitaoka 120a6e
                     int ii, int jj, DoublePair intersection, int strokeSize) {
Shinya Kitaoka 120a6e
  list<intersection>::iterator it;</intersection>
Shinya Kitaoka 120a6e
  TPointD p;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // UINT iw;
Shinya Kitaoka 120a6e
  // iw = ((UINT)(intersection.first*0x3fffffff));
Shinya Kitaoka 120a6e
  // intersection.first = truncate(intersection.first);
Shinya Kitaoka 120a6e
  // iw = (UINT)(intersection.second*0x3fffffff);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // intersection.second = truncate(intersection.second);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (areAlmostEqual(intersection.first, 0.0, 1e-8))
Shinya Kitaoka 120a6e
    intersection.first = 0.0;
Shinya Kitaoka 120a6e
  else if (areAlmostEqual(intersection.first, 1.0, 1e-8))
Shinya Kitaoka 120a6e
    intersection.first = 1.0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (areAlmostEqual(intersection.second, 0.0, 1e-8))
Shinya Kitaoka 120a6e
    intersection.second = 0.0;
Shinya Kitaoka 120a6e
  else if (areAlmostEqual(intersection.second, 1.0, 1e-8))
Shinya Kitaoka 120a6e
    intersection.second = 1.0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  p = s[ii]->m_s->getPoint(intersection.first);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (it = intData.m_intList.begin(); it != intData.m_intList.end(); it++)
Shinya Kitaoka 120a6e
    if ((*it).m_intersection ==
Shinya Kitaoka 120a6e
        p)  // devono essere rigorosamente uguali, altrimenti
Shinya Kitaoka 120a6e
    // il calcolo dell'ordine dei rami con le tangenti sballa
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      addBranches(intData, *it, s, ii, jj, intersection, strokeSize);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  intData.m_intList.push_back(Intersection());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!makeIntersection(intData, s, ii, jj, intersection, strokeSize,
Shinya Kitaoka 120a6e
                        intData.m_intList.back())) {
Shinya Kitaoka 120a6e
    list<intersection>::iterator it = intData.m_intList.begin();</intersection>
Shinya Kitaoka 120a6e
    advance(it, intData.m_intList.size() - 1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    intData.m_intList.erase(it);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::Imp::findIntersections() {
Shinya Kitaoka 120a6e
  vector<vistroke *=""> &strokeArray = m_strokes;</vistroke>
Shinya Kitaoka 120a6e
  IntersectionData &intData       = m_intersectionData;
Shinya Kitaoka 120a6e
  int strokeSize                  = (int)strokeArray.size();
Shinya Kitaoka 120a6e
  int i, j;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(intData.m_intersectedStrokeArray.empty());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  intData.maxAutocloseId++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  map<int, *="" tstroke="">::iterator it, it_b = intData.m_autocloseMap.begin();</int,>
Shinya Kitaoka 120a6e
  map<int, *="" tstroke="">::iterator it_e = intData.m_autocloseMap.end();</int,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // prima cerco le intersezioni tra nuove strokes e vecchi autoclose
Shinya Kitaoka 120a6e
  for (i = 0; i < strokeSize; i++) {
Shinya Kitaoka 120a6e
    TStroke *s1 = strokeArray[i]->m_s;
Shinya Kitaoka 120a6e
    if (!strokeArray[i]->m_isNewForFill || strokeArray[i]->m_isPoint) continue;
Shinya Kitaoka 120a6e
    TRectD bBox   = s1->getBBox();
Shinya Kitaoka 120a6e
    double thick2 = s1->getThickPoint(0).thick * 2;
Shinya Kitaoka 120a6e
    if (bBox.getLx() <= thick2 && bBox.getLy() <= thick2) {
Shinya Kitaoka 120a6e
      strokeArray[i]->m_isPoint = true;
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (int j = 0; j < (int)s1->getControlPointCount(); j++) {
Shinya Kitaoka 120a6e
      TThickPoint p = s1->getControlPoint(j);
Shinya Kitaoka 120a6e
      s1->setControlPoint(j, myRound(p));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (it = it_b; it != it_e; ++it) {
Shinya Kitaoka 120a6e
      TStroke *s2 = it->second;
Shinya Kitaoka 120a6e
      vector<doublepair> parIntersections;</doublepair>
Shinya Kitaoka 120a6e
      if (intersect(s1, s2, parIntersections, true))
Shinya Kitaoka 120a6e
        addIntersections(intData, strokeArray, i, it->first, parIntersections,
Shinya Kitaoka 120a6e
                         strokeSize);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // poi,  intersezioni tra stroke, in cui almeno uno dei due deve essere nuovo
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < strokeSize; i++) {
Shinya Kitaoka 120a6e
    TStroke *s1 = strokeArray[i]->m_s;
Shinya Kitaoka 120a6e
    if (strokeArray[i]->m_isPoint) continue;
Shinya Kitaoka 38fd86
    for (j = i; j < strokeSize /*&& (strokeArray[i]->getBBox().x1>=
Shinya Kitaoka 38fd86
                                  strokeArray[j]->getBBox().x0)*/
Shinya Kitaoka 38fd86
         ;
Shinya Kitaoka 38fd86
         j++) {
Shinya Kitaoka 120a6e
      TStroke *s2 = strokeArray[j]->m_s;
Shinya Kitaoka 120a6e
      if (strokeArray[j]->m_isPoint) continue;
Shinya Kitaoka 120a6e
      if (!(strokeArray[i]->m_isNewForFill || strokeArray[j]->m_isNewForFill))
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      vector<doublepair> parIntersections;</doublepair>
Shinya Kitaoka 120a6e
      if (s1->getBBox().overlaps(s2->getBBox())) {
Shinya Kitaoka 120a6e
        UINT size = intData.m_intList.size();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (intersect(s1, s2, parIntersections, false)) {
Shinya Kitaoka 120a6e
          // if (i==0 && j==1) parIntersections.erase(parIntersections.begin());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          addIntersections(intData, strokeArray, i, j, parIntersections,
Shinya Kitaoka 120a6e
                           strokeSize);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        // autoclose(strokeArray, i, j, intData, strokeSize);
Shinya Kitaoka 120a6e
        if (!strokeArray[i]->m_isNewForFill &&
Shinya Kitaoka 120a6e
            size != intData.m_intList.size() &&
Shinya Kitaoka 120a6e
            !strokeArray[i]->m_edgeList.empty())  // aggiunte nuove intersezioni
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          intData.m_intersectedStrokeArray.push_back(IntersectedStrokeEdges(i));
Shinya Kitaoka 120a6e
          list<tedge *=""> &_list =</tedge>
Shinya Kitaoka 120a6e
              intData.m_intersectedStrokeArray.back().m_edgeList;
Shinya Kitaoka 120a6e
          list<tedge *="">::const_iterator it;</tedge>
Shinya Kitaoka 120a6e
          for (it = strokeArray[i]->m_edgeList.begin();
Shinya Kitaoka 120a6e
               it != strokeArray[i]->m_edgeList.end(); ++it)
Shinya Kitaoka 120a6e
            _list.push_back(new TEdge(**it, false));
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    // strokeArray[i]->m_isNewForFill = false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < strokeSize; i++) {
Shinya Kitaoka 120a6e
    TStroke *s1 = strokeArray[i]->m_s;
Shinya Kitaoka 120a6e
    if (strokeArray[i]->m_isPoint) continue;
Shinya Kitaoka 120a6e
    for (j = i; j < strokeSize; j++) {
Shinya Kitaoka 120a6e
      TStroke *s2 = strokeArray[j]->m_s;
Shinya Kitaoka 120a6e
      if (strokeArray[j]->m_isPoint) continue;
Shinya Kitaoka 120a6e
      if (!(strokeArray[i]->m_isNewForFill || strokeArray[j]->m_isNewForFill))
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      if (s1->getBBox().overlaps(s2->getBBox()))
Shinya Kitaoka 120a6e
        autoclose(strokeArray, i, j, intData, strokeSize);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    strokeArray[i]->m_isNewForFill = false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < strokeSize; i++) {
Shinya Kitaoka 120a6e
    list<tedge *="">::iterator it, it_b = strokeArray[i]->m_edgeList.begin(),</tedge>
Shinya Kitaoka 120a6e
                                it_e = strokeArray[i]->m_edgeList.end();
Shinya Kitaoka 120a6e
    for (it = it_b; it != it_e; ++it)
Shinya Kitaoka 120a6e
      if ((*it)->m_toBeDeleted == 1) delete *it;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    strokeArray[i]->m_edgeList.clear();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // si devono cercare le intersezioni con i segmenti aggiunti per l'autoclose
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = strokeSize; i < (int)strokeArray.size(); ++i) {
Shinya Kitaoka 120a6e
    TStroke *s1 = strokeArray[i]->m_s;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (j = i + 1; j < (int)strokeArray.size();
Shinya Kitaoka 120a6e
         ++j)  // intersezione segmento-segmento
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      TStroke *s2 = strokeArray[j]->m_s;
Shinya Kitaoka 120a6e
      vector<doublepair> parIntersections;</doublepair>
Shinya Kitaoka 120a6e
      if (intersect(s1, s2, parIntersections, true))
Shinya Kitaoka 120a6e
        addIntersections(intData, strokeArray, i, j, parIntersections,
Shinya Kitaoka 120a6e
                         strokeSize);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (j = 0; j < strokeSize; ++j)  // intersezione segmento-curva
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      if (strokeArray[j]->m_isPoint) continue;
Shinya Kitaoka 120a6e
      TStroke *s2 = strokeArray[j]->m_s;
Shinya Kitaoka 120a6e
      vector<doublepair> parIntersections;</doublepair>
Shinya Kitaoka 120a6e
      if (intersect(s1, s2, parIntersections, true))
Shinya Kitaoka 120a6e
        addIntersections(intData, strokeArray, i, j, parIntersections,
Shinya Kitaoka 120a6e
                         strokeSize);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// la struttura delle intersezioni viene poi visitata per trovare
Toshihiro Shimizu 890ddd
// i link tra un'intersezione e la successiva
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::Imp::computeIntersections() {
Shinya Kitaoka 120a6e
  list<intersection>::iterator it1;</intersection>
Shinya Kitaoka 120a6e
  list<intersectedstroke>::iterator it2;</intersectedstroke>
Shinya Kitaoka 120a6e
  IntersectionData &intData = m_intersectionData;
Shinya Kitaoka 120a6e
  int strokeSize            = (int)m_strokes.size();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  findIntersections();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  findNearestIntersection(intData.m_intList);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // for (it1=intData.m_intList.begin(); it1!=intData.m_intList.end();) //la
Shinya Kitaoka 120a6e
  // faccio qui, e non nella eraseIntersection. vedi commento li'.
Shinya Kitaoka 120a6e
  eraseDeadIntersections();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (it1 = intData.m_intList.begin(); it1 != intData.m_intList.end(); it1++)
Shinya Kitaoka 120a6e
    markDeadIntersections(intData.m_intList, it1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // checkInterList(intData.m_intList);
Shinya Kitaoka 120a6e
  return strokeSize;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Shinya Kitaoka 120a6e
void endPointIntersect(const TStroke* s0, const TStroke* s1, vector<doublepair>&</doublepair>
Shinya Kitaoka 120a6e
parIntersections)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
TPointD p00 = s0->getPoint(0);
Toshihiro Shimizu 890ddd
TPointD p11 = s1->getPoint(1);
Toshihiro Shimizu 890ddd
if (tdistance2(p00, p11)< 2*0.06*0.06)
Toshihiro Shimizu 890ddd
  parIntersections.push_back(DoublePair(0, 1));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
if (s0==s1)
Toshihiro Shimizu 890ddd
  return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPointD p01 = s0->getPoint(1);
Toshihiro Shimizu 890ddd
TPointD p10 = s1->getPoint(0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
if (tdistance2(p00, p10)< 2*0.06*0.06)
Toshihiro Shimizu 890ddd
  parIntersections.push_back(DoublePair(0, 0));
Toshihiro Shimizu 890ddd
if (tdistance2(p01, p10)< 2*0.06*0.06)
Toshihiro Shimizu 890ddd
  parIntersections.push_back(DoublePair(1, 0));
Toshihiro Shimizu 890ddd
if (tdistance2(p01, p11)< 2*0.06*0.06)
Toshihiro Shimizu 890ddd
  parIntersections.push_back(DoublePair(1, 1));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Trova una possibile regione data una lista di punti di intersezione
Shinya Kitaoka 120a6e
TRegion *findRegion(list<intersection> &intList,</intersection>
Shinya Kitaoka 120a6e
                    list<intersection>::iterator it1,</intersection>
Shinya Kitaoka 120a6e
                    list<intersectedstroke>::iterator it2) {</intersectedstroke>
Shinya Kitaoka 120a6e
  TRegion *r    = new TRegion();
Shinya Kitaoka 120a6e
  int currStyle = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  list<intersectedstroke>::iterator itStart = it2;</intersectedstroke>
Shinya Kitaoka 120a6e
  list<intersection>::iterator nextIt1;</intersection>
Shinya Kitaoka 120a6e
  list<intersectedstroke>::iterator nextIt2;</intersectedstroke>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Cicla finche' t2 non punta ad uno stroke gia' visitato
Shinya Kitaoka 120a6e
  while (!it2->m_visited) {
Shinya Kitaoka 120a6e
    it2->m_visited = true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Ciclo finche' lo stroke puntato da it2 non ha un successivo punto di
Shinya Kitaoka 120a6e
    // intersezione
Shinya Kitaoka 120a6e
    do {
Shinya Kitaoka 120a6e
      it2++;
Shinya Kitaoka 120a6e
      if (it2 ==
Shinya Kitaoka 120a6e
          it1->m_strokeList.end())  // uso la lista come se fosse circolare
Shinya Kitaoka 120a6e
        it2 = it1->m_strokeList.begin();
Shinya Kitaoka 120a6e
    } while (it2->m_nextIntersection == intList.end());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    nextIt1 = it2->m_nextIntersection;
Shinya Kitaoka 120a6e
    nextIt2 = it2->m_nextStroke;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Viene controllato e sistemato lo stile degli stroke
Shinya Kitaoka 120a6e
    if (it2->m_edge.m_styleId != 0) {
Shinya Kitaoka 120a6e
      if (currStyle == 0)
Shinya Kitaoka 120a6e
        currStyle = it2->m_edge.m_styleId;
Shinya Kitaoka 120a6e
      else if (it2->m_edge.m_styleId != currStyle) {
Shinya Kitaoka 120a6e
        currStyle = it2->m_edge.m_styleId;
Shinya Kitaoka 120a6e
        for (UINT i                = 0; i < r->getEdgeCount(); i++)
Shinya Kitaoka 120a6e
          r->getEdge(i)->m_styleId = currStyle;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      it2->m_edge.m_styleId = currStyle;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Aggiunge lo stroke puntato da p2 alla regione
Shinya Kitaoka 120a6e
    r->addEdge(&it2->m_edge);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (nextIt2 == itStart) return r;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    it1 = nextIt1;
Shinya Kitaoka 120a6e
    it2 = nextIt2;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  delete r;
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
bool areEqualRegions(const TRegion& r1, const TRegion& r2)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
if (r1.getBBox()!=r2.getBBox())
Toshihiro Shimizu 890ddd
  return false;
Toshihiro Shimizu 890ddd
if (r1.getEdgeCount()!=r2.getEdgeCount())
Toshihiro Shimizu 890ddd
  return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
for (UINT i=0; i
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
  TEdge *e1 = r1.getEdge(i);
Toshihiro Shimizu 890ddd
  for (j=0; j
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
    TEdge *e2 = r2.getEdge(j);
Toshihiro Shimizu 890ddd
    if (e1->m_s==e2->m_s &&
Toshihiro Shimizu 890ddd
        tmin(e1->m_w0, e1->m_w1)==tmin(e2->m_w0, e2->m_w1) &&
Toshihiro Shimizu 890ddd
        tmax(e1->m_w0, e1->m_w1)==tmax(e2->m_w0, e2->m_w1))
Toshihiro Shimizu 890ddd
      {
Toshihiro Shimizu 890ddd
      if (e1->m_styleId && !e2->m_styleId)
Toshihiro Shimizu 890ddd
        e2->m_styleId=e1->m_styleId;
Toshihiro Shimizu 890ddd
      else if (e2->m_styleId && !e1->m_styleId)
Toshihiro Shimizu 890ddd
        e1->m_styleId=e2->m_styleId;
Toshihiro Shimizu 890ddd
      break;
Toshihiro Shimizu 890ddd
      }
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
  if (j==r2.getEdgeCount())  //e1 non e' uguale a nessun edge di r2
Toshihiro Shimizu 890ddd
    return false;
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
bool isMetaRegion(const TRegion& r1, const TRegion& r2)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
if (areEqualRegions(r1, r2))
Toshihiro Shimizu 890ddd
    return true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
for (UINT i=0; i
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
  if (isMetaRegion(*r1.getRegion(i), r2))
Toshihiro Shimizu 890ddd
    return true;
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool isMetaRegion(const vector<tregion*>& m_regions, const TRegion& r)</tregion*>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
for (UINT i=0; i
Toshihiro Shimizu 890ddd
  if (isMetaRegion(*(m_regions[i]), r))
Toshihiro Shimizu 890ddd
    return true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool isValidArea(const vector<tregion *=""> ®ions, const TRegion &r) {</tregion>
Shinya Kitaoka 120a6e
  double area = 0.0;
Shinya Kitaoka 120a6e
  TPointD p, pOld /*, pAux*/;
Shinya Kitaoka 120a6e
  int pointAdded = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int size = r.getEdgeCount();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (size == 0) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // if (size<2)
Shinya Kitaoka 120a6e
  //  return !isMetaRegion(regions, r);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int firstControlPoint;
Shinya Kitaoka 120a6e
  int lastControlPoint;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TEdge *e = r.getEdge(size - 1);
Shinya Kitaoka 120a6e
  pOld     = e->m_s->getPoint(e->m_w1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int i = 0; i < size; i++) {
Shinya Kitaoka 120a6e
    TEdge *e          = r.getEdge(i);
Shinya Kitaoka 120a6e
    TStroke *s        = e->m_s;
Shinya Kitaoka 120a6e
    firstControlPoint = s->getControlPointIndexAfterParameter(e->m_w0);
Shinya Kitaoka 120a6e
    lastControlPoint  = s->getControlPointIndexAfterParameter(e->m_w1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    p = s->getPoint(e->m_w0);
Shinya Kitaoka 120a6e
    area += (p.y + pOld.y) * (pOld.x - p.x);
Shinya Kitaoka 120a6e
    pOld = p;
Shinya Kitaoka 120a6e
    pointAdded++;
Shinya Kitaoka 120a6e
    if (firstControlPoint <= lastControlPoint) {
Shinya Kitaoka 120a6e
      if (firstControlPoint & 0x1) firstControlPoint++;
Shinya Kitaoka 120a6e
      if (lastControlPoint - firstControlPoint <=
Shinya Kitaoka 120a6e
          2)  /// per evitare di avere troppi pochi punti....
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        p = s->getPoint(0.333333 * e->m_w0 + 0.666666 * e->m_w1);
Shinya Kitaoka 120a6e
        area += (p.y + pOld.y) * (pOld.x - p.x);
Shinya Kitaoka 120a6e
        pOld = p;
Shinya Kitaoka 120a6e
        pointAdded++;
Shinya Kitaoka 120a6e
        p = s->getPoint(0.666666 * e->m_w0 + 0.333333 * e->m_w1);
Shinya Kitaoka 120a6e
        area += (p.y + pOld.y) * (pOld.x - p.x);
Shinya Kitaoka 120a6e
        pOld = p;
Shinya Kitaoka 120a6e
        pointAdded++;
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        for (int j = firstControlPoint; j < lastControlPoint; j += 2) {
Shinya Kitaoka 120a6e
          p = s->getControlPoint(j);
Shinya Kitaoka 120a6e
          area += (p.y + pOld.y) * (pOld.x - p.x);
Shinya Kitaoka 120a6e
          pOld = p;
Shinya Kitaoka 120a6e
          pointAdded++;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      firstControlPoint--;  // this case, getControlPointIndexBEFOREParameter
Shinya Kitaoka 120a6e
      lastControlPoint--;
Shinya Kitaoka 120a6e
      if (firstControlPoint & 0x1) firstControlPoint--;
Shinya Kitaoka 120a6e
      if (firstControlPoint - lastControlPoint <=
Shinya Kitaoka 120a6e
          2)  /// per evitare di avere troppi pochi punti....
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        p = s->getPoint(0.333333 * e->m_w0 + 0.666666 * e->m_w1);
Shinya Kitaoka 120a6e
        area += (p.y + pOld.y) * (pOld.x - p.x);
Shinya Kitaoka 120a6e
        pOld = p;
Shinya Kitaoka 120a6e
        pointAdded++;
Shinya Kitaoka 120a6e
        p = s->getPoint(0.666666 * e->m_w0 + 0.333333 * e->m_w1);
Shinya Kitaoka 120a6e
        area += (p.y + pOld.y) * (pOld.x - p.x);
Shinya Kitaoka 120a6e
        pOld = p;
Shinya Kitaoka 120a6e
        pointAdded++;
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        for (int j = firstControlPoint; j > lastControlPoint; j -= 2) {
Shinya Kitaoka 120a6e
          p = s->getControlPoint(j);
Shinya Kitaoka 120a6e
          area += (p.y + pOld.y) * (pOld.x - p.x);
Shinya Kitaoka 120a6e
          pOld = p;
Shinya Kitaoka 120a6e
          pointAdded++;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    p = s->getPoint(e->m_w1);
Shinya Kitaoka 120a6e
    area += (p.y + pOld.y) * (pOld.x - p.x);
Shinya Kitaoka 120a6e
    pOld = p;
Shinya Kitaoka 120a6e
    pointAdded++;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  assert(pointAdded >= 4);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return area > 0.5;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void transferColors(const list<tedge *=""> &oldList, const list<tedge *=""> &newList,</tedge></tedge>
Shinya Kitaoka 120a6e
                    bool isStrokeChanged, bool isFlipped, bool overwriteColor);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
void printStrokes1(vector<vistroke *=""> &v, int size) {</vistroke>
Shinya Kitaoka 120a6e
  UINT i = 0;
Shinya Kitaoka 120a6e
  ofstream of("C:\\temp\\strokes.txt");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < (UINT)size; i++) {
Shinya Kitaoka 120a6e
    TStroke *s = v[i]->m_s;
Shinya Kitaoka 120a6e
    of << "***stroke " << i << endl;
Shinya Kitaoka 120a6e
    for (UINT j = 0; j < (UINT)s->getChunkCount(); j++) {
Shinya Kitaoka 120a6e
      const TThickQuadratic *q = s->getChunk(j);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      of << "   s0 " << q->getP0() << endl;
Shinya Kitaoka 120a6e
      of << "   s1 " << q->getP1() << endl;
Shinya Kitaoka 120a6e
      of << "   s2 " << q->getP2() << endl;
Shinya Kitaoka 120a6e
      of << "****** " << endl;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    of << endl;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  for (i = size; i < v.size(); i++) {
Shinya Kitaoka 120a6e
    TStroke *s = v[i]->m_s;
Shinya Kitaoka 120a6e
    of << "***Autostroke " << i << endl;
Shinya Kitaoka 120a6e
    of << "s0 " << s->getPoint(0.0) << endl;
Shinya Kitaoka 120a6e
    of << "s1 " << s->getPoint(1.0) << endl;
Shinya Kitaoka 120a6e
    of << endl;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
static void printTime(TStopWatch &sw, string name) {
Shinya Kitaoka 120a6e
  ostringstream ss;
Shinya Kitaoka 120a6e
  ss << name << " : ";
Shinya Kitaoka 120a6e
  sw.print(ss);
Shinya Kitaoka 120a6e
  ss << '\n' << '\0';
Shinya Kitaoka 120a6e
  string s(ss.str());
Shinya Kitaoka 120a6e
  // TSystem::outputDebug(s);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
void printStrokes1(vector<vistroke *=""> &v, int size);</vistroke>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Trova le regioni in una TVectorImage
Shinya Kitaoka 120a6e
int TVectorImage::Imp::computeRegions() {
Toshihiro Shimizu 890ddd
#if defined(_DEBUG) && !defined(MACOSX)
Shinya Kitaoka 120a6e
  TStopWatch stopWatch;
Shinya Kitaoka 120a6e
  stopWatch.start(true);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!m_computeRegions) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /*if (m_intersectionData.m_computedAlmostOnce)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
UINT i,n=m_strokes.size();
Shinya Kitaoka 120a6e
  vector<int> vv(n);</int>
Shinya Kitaoka 120a6e
for( i=0; i
Shinya Kitaoka 120a6e
m_intersectionData.m_computedAlmostOnce = true;
Shinya Kitaoka 120a6e
notifyChangedStrokes(vv,vector<tstroke*>(), false);</tstroke*>
tomosu eea0ac
Shinya Kitaoka 120a6e
return true;
Shinya Kitaoka 120a6e
}*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  g_autocloseTolerance = m_autocloseTolerance;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Cancella le regioni gia' esistenti per ricalcolarle
Shinya Kitaoka 120a6e
  clearPointerContainer(m_regions);
Shinya Kitaoka 120a6e
  m_regions.clear();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Controlla che ci siano degli stroke
Shinya Kitaoka 120a6e
  if (m_strokes.empty()) {
Toshihiro Shimizu 890ddd
#if defined(_DEBUG) && !defined(MACOSX)
Shinya Kitaoka 120a6e
    stopWatch.stop();
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    return 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Inizializza la lista di intersezioni intList
Shinya Kitaoka 120a6e
  m_intersectionData.m_computedAlmostOnce = true;
Shinya Kitaoka 120a6e
  list<intersection> &intList             = m_intersectionData.m_intList;</intersection>
Shinya Kitaoka 120a6e
  cleanIntersectionMarks(intList);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // calcolo struttura delle intersezioni
Shinya Kitaoka 120a6e
  int added = 0, notAdded = 0;
Shinya Kitaoka 120a6e
  int strokeSize;
Shinya Kitaoka 120a6e
  strokeSize = computeIntersections();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  list<intersection>::iterator it1;</intersection>
Shinya Kitaoka 120a6e
  list<intersectedstroke>::iterator it2;</intersectedstroke>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (it1 = intList.begin(); it1 != intList.end(); it1++)
Shinya Kitaoka 120a6e
    for (it2 = (*it1).m_strokeList.begin(); it2 != (*it1).m_strokeList.end();
Shinya Kitaoka 120a6e
         it2++)
Shinya Kitaoka 120a6e
      it2->m_edge.m_r = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (it1 = intList.begin(); it1 != intList.end(); it1++) {
Shinya Kitaoka 120a6e
    // Controlla che il punto in questione non sia isolato
Shinya Kitaoka 120a6e
    if (it1->m_numInter == 0) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (it2 = it1->m_strokeList.begin(); it2 != it1->m_strokeList.end();
Shinya Kitaoka 120a6e
         it2++) {
Shinya Kitaoka 120a6e
      TRegion *region;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // se lo stroke non unisce due punti di intersezione
Shinya Kitaoka 120a6e
      // non lo considero e vado avanti con un altro stroke
Shinya Kitaoka 120a6e
      if (it2->m_nextIntersection == intList.end()) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Se lo stroke puntato da t2 non e' stato ancora visitato, trova una
Shinya Kitaoka 120a6e
      // regione
Shinya Kitaoka 120a6e
      if (!it2->m_visited && (region = findRegion(intList, it1, it2))) {
Shinya Kitaoka 120a6e
        // Se la regione e' valida la aggiunge al vettore delle regioni
Shinya Kitaoka 120a6e
        if (isValidArea(m_regions, *region)) {
Shinya Kitaoka 120a6e
          added++;
Shinya Kitaoka 120a6e
          addRegion(m_regions, region);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          // Lega ogni ramo della regione alla regione di appartenenza
Shinya Kitaoka 120a6e
          for (UINT i = 0; i < region->getEdgeCount(); i++) {
Shinya Kitaoka 120a6e
            TEdge *e = region->getEdge(i);
Shinya Kitaoka 120a6e
            e->m_r   = region;
Shinya Kitaoka 120a6e
            if (e->m_index >= 0) m_strokes[e->m_index]->addEdge(e);
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        } else  // Se la regione non e' valida viene scartata
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          notAdded++;
Shinya Kitaoka 120a6e
          delete region;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_notIntersectingStrokes) {
Shinya Kitaoka 120a6e
    UINT i;
Shinya Kitaoka 120a6e
    for (i = 0; i < m_intersectionData.m_intersectedStrokeArray.size(); i++) {
Shinya Kitaoka 120a6e
      if (!m_strokes[m_intersectionData.m_intersectedStrokeArray[i].m_index]
Shinya Kitaoka 120a6e
               ->m_edgeList.empty())
Shinya Kitaoka 120a6e
        transferColors(
Shinya Kitaoka 120a6e
            m_intersectionData.m_intersectedStrokeArray[i].m_edgeList,
Shinya Kitaoka 120a6e
            m_strokes[m_intersectionData.m_intersectedStrokeArray[i].m_index]
Shinya Kitaoka 120a6e
                ->m_edgeList,
Shinya Kitaoka 120a6e
            false, false, true);
Shinya Kitaoka 120a6e
      clearPointerContainer(
Shinya Kitaoka 120a6e
          m_intersectionData.m_intersectedStrokeArray[i].m_edgeList);
Shinya Kitaoka 120a6e
      m_intersectionData.m_intersectedStrokeArray[i].m_edgeList.clear();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    m_intersectionData.m_intersectedStrokeArray.clear();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(m_intersectionData.m_intersectedStrokeArray.empty());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // tolgo i segmenti aggiunti con l'autoclose
Shinya Kitaoka 120a6e
  vector<vistroke *="">::iterator it = m_strokes.begin();</vistroke>
Shinya Kitaoka 120a6e
  advance(it, strokeSize);
Shinya Kitaoka 120a6e
  m_strokes.erase(it, m_strokes.end());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_areValidRegions = true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if defined(_DEBUG) && !defined(MACOSX)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return 0;
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
class Branch
Toshihiro Shimizu 890ddd
  {
Shinya Kitaoka 120a6e
        TEdge m_edge;
Toshihiro Shimizu 890ddd
  bool m_out, m_visited;
Shinya Kitaoka 120a6e
        Branch *m_next;
Shinya Kitaoka 120a6e
        Branch *m_nextBranch;
Shinya Kitaoka 120a6e
        Intersection* m_intersection;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        public:
Shinya Kitaoka 120a6e
          Branch* next()
Shinya Kitaoka 120a6e
                  {
Shinya Kitaoka 120a6e
                        assert(m_intersection);
Shinya Kitaoka 120a6e
                        return m_next?m_next:m_intersection->m_branchList;
Shinya Kitaoka 120a6e
                        }
Shinya Kitaoka 120a6e
        }
tomosu eea0ac
tomosu eea0ac
Toshihiro Shimizu 890ddd
class Intersection
Toshihiro Shimizu 890ddd
  {
Shinya Kitaoka 120a6e
        private:
Shinya Kitaoka 120a6e
        TPointD m_intersectionPoint;
Toshihiro Shimizu 890ddd
  int m_intersectionCount;
Toshihiro Shimizu 890ddd
  Branch *m_branchList;
Shinya Kitaoka 120a6e
        Intersection* m_next;
Toshihiro Shimizu 890ddd
  list<intersectedstroke> m_strokeList;</intersectedstroke>
Shinya Kitaoka 120a6e
        public:
Toshihiro Shimizu 890ddd
  AddIntersection(int index0, int index1, DoublePair intersectionValues);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
*/