Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tcurves.h"
Toshihiro Shimizu 890ddd
//#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "tvectorimageP.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
//#include "tgl.h"
Toshihiro Shimizu 890ddd
#include "tvectorrenderdata.h"
Toshihiro Shimizu 890ddd
#include "tmathutil.h"
Toshihiro Shimizu 890ddd
//#include "tdebugmessage.h"
Toshihiro Shimizu 890ddd
#include "tofflinegl.h"
Toshihiro Shimizu 890ddd
//#include "tcolorstyles.h"
Toshihiro Shimizu 890ddd
#include "tpaletteutil.h"
Toshihiro Shimizu 890ddd
#include "tthreadmessage.h"
Toshihiro Shimizu 890ddd
#include "tsimplecolorstyles.h"
Campbell Barton 8c6c57
#include "tcomputeregions.h"
Campbell Barton 40cabe
Campbell Barton 40cabe
#include <memory></memory>
Campbell Barton 40cabe
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
typedef TVectorImage::IntersectionBranch IntersectionBranch;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef std::set<int> DisabledStrokeStyles;</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// uso getDisabledStrokeStyleSet() invece che accedere direttamente alla
Toshihiro Shimizu 890ddd
// variabile per assicurarmi che il tutto funzioni anche quando viene
Toshihiro Shimizu 890ddd
// usato PRIMA del main (per iniziativa di un costruttore di una variabile
Toshihiro Shimizu 890ddd
// globale, p.es.).
Shinya Kitaoka 120a6e
// per l'idioma: cfr. Modern C++ design, Andrei Alexandrescu, Addison Wesley
Shinya Kitaoka 120a6e
// 2001, p.133
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline DisabledStrokeStyles &getDisabledStrokeStyleSet() {
Shinya Kitaoka 120a6e
  static DisabledStrokeStyles disabledStokeStyles;
Shinya Kitaoka 120a6e
  return disabledStokeStyles;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline bool isStrokeStyleEnabled__(int index) {
Shinya Kitaoka 120a6e
  DisabledStrokeStyles &disabledSet = getDisabledStrokeStyleSet();
Shinya Kitaoka 120a6e
  return disabledSet.find(index) == disabledSet.end();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
Permette di copiare effettuare delle copie delle curve
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
/*
Shinya Kitaoka 120a6e
template <class container=""></class>
Toshihiro Shimizu 890ddd
class StrokeArrayInsertIterator
Shinya Kitaoka 120a6e
{
Toshihiro Shimizu 890ddd
  Container& container;
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
  explicit    StrokeArrayInsertIterator(Container& Line)
Toshihiro Shimizu 890ddd
    :container(Line)
Toshihiro Shimizu 890ddd
  {};
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  StrokeArrayInsertIterator& operator=(const VIStroke* value )
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
    TStroke *stroke = new TStroke(*(value->m_s));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
    stroke->setId(value->m_s->getId());
Toshihiro Shimizu 890ddd
    container.push_back(new VIStroke(stroke));
Toshihiro Shimizu 890ddd
    return *this;
Toshihiro Shimizu 890ddd
  };
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  StrokeArrayInsertIterator&  operator*()       { return *this; }
Toshihiro Shimizu 890ddd
  StrokeArrayInsertIterator&  operator++()       { return *this; }
Toshihiro Shimizu 890ddd
  StrokeArrayInsertIterator   operator++(int val){ return *this; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
TVectorImage::Imp: implementation of TVectorImage class
Toshihiro Shimizu 890ddd
\relates  TVectorImage
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TVectorImage::Imp::Imp(TVectorImage *vi)
Shinya Kitaoka 120a6e
    : m_areValidRegions(false)
Shinya Kitaoka 120a6e
    , m_notIntersectingStrokes(false)
Shinya Kitaoka 120a6e
    , m_computeRegions(true)
Shinya Kitaoka 120a6e
    , m_autocloseTolerance(c_newAutocloseTolerance)
Shinya Kitaoka 120a6e
    , m_maxGroupId(1)
Shinya Kitaoka 120a6e
    , m_maxGhostGroupId(1)
Shinya Kitaoka 120a6e
    , m_mutex(new TThread::Mutex())
Shinya Kitaoka 120a6e
    , m_vi(vi)
Shinya Kitaoka 120a6e
    , m_intersectionData(0)
Shinya Kitaoka 120a6e
    , m_computedAlmostOnce(false)
Shinya Kitaoka 120a6e
    , m_justLoaded(false)
Shinya Kitaoka 120a6e
    , m_insideGroup(TGroupId())
Shinya Kitaoka 120a6e
    , m_minimizeEdges(true)
Shinya Kitaoka 6f0974
#ifdef NEW_REGION_FILL
Shinya Kitaoka 120a6e
    , m_regionFinder(0)
Shinya Kitaoka 6f0974
#endif
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 6f0974
#ifdef NEW_REGION_FILL
Shinya Kitaoka 120a6e
  resetRegionFinder();
Shinya Kitaoka 6f0974
#endif
Shinya Kitaoka 120a6e
  initRegionsData();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TVectorImage::Imp::~Imp() {
Shinya Kitaoka 120a6e
  // delete m_regionFinder;
Shinya Kitaoka 120a6e
  deleteRegionsData();
Shinya Kitaoka 120a6e
  delete m_mutex;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TVectorImage::TVectorImage(bool loaded) : m_imp(new TVectorImage::Imp(this)) {
Shinya Kitaoka 120a6e
  if (loaded) m_imp->m_justLoaded = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TVectorImage::~TVectorImage() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::isInsideGroup() const {
Shinya Kitaoka 120a6e
  return m_imp->m_insideGroup.getDepth();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::addStrokeToGroup(TStroke *stroke, int strokeIndex) {
Shinya Kitaoka 120a6e
  if (!m_imp->m_strokes[strokeIndex]->m_groupId.isGrouped())
Shinya Kitaoka 120a6e
    return addStroke(stroke, true);
Shinya Kitaoka 120a6e
  for (int i = m_imp->m_strokes.size() - 1; i >= 0; i--)
Shinya Kitaoka 120a6e
    if (m_imp->m_strokes[i]->m_groupId ==
Shinya Kitaoka 120a6e
        m_imp->m_strokes[strokeIndex]->m_groupId) {
Shinya Kitaoka 120a6e
      m_imp->insertStrokeAt(
Shinya Kitaoka 120a6e
          new VIStroke(stroke, m_imp->m_strokes[i]->m_groupId), i + 1);
Shinya Kitaoka 120a6e
      return i + 1;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  assert(false);
Shinya Kitaoka 120a6e
  return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::addStroke(TStroke *stroke, bool discardPoints) {
Shinya Kitaoka 120a6e
  if (discardPoints) {
Shinya Kitaoka 120a6e
    TRectD bBox = stroke->getBBox();
Shinya Kitaoka 120a6e
    if (bBox.x0 == bBox.x1 && bBox.y0 == bBox.y1)  // empty stroke: discard
Shinya Kitaoka 120a6e
      return -1;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_imp->m_insideGroup != TGroupId()) {
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = m_imp->m_strokes.size() - 1; i >= 0; i--)
Shinya Kitaoka 120a6e
      if (m_imp->m_insideGroup.isParentOf(m_imp->m_strokes[i]->m_groupId)) {
Shinya Kitaoka 120a6e
        m_imp->insertStrokeAt(
Shinya Kitaoka 120a6e
            new VIStroke(stroke, m_imp->m_strokes[i]->m_groupId), i + 1);
Shinya Kitaoka 120a6e
        return i + 1;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TGroupId gid;
Shinya Kitaoka 120a6e
  if (m_imp->m_strokes.empty() ||
Shinya Kitaoka 120a6e
      m_imp->m_strokes.back()->m_groupId.isGrouped() != 0)
Shinya Kitaoka 120a6e
    gid = TGroupId(this, true);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    gid = m_imp->m_strokes.back()->m_groupId;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->m_strokes.push_back(new VIStroke(stroke, gid));
Shinya Kitaoka 120a6e
  m_imp->m_areValidRegions = false;
Shinya Kitaoka 120a6e
  return m_imp->m_strokes.size() - 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::moveStrokes(int fromIndex, int count, int moveBefore) {
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
  m_imp->checkGroups();
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  m_imp->moveStrokes(fromIndex, count, moveBefore, true);
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
  m_imp->checkGroups();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::Imp::moveStrokes(int fromIndex, int count, int moveBefore,
Shinya Kitaoka 120a6e
                                    bool regroup) {
Shinya Kitaoka 120a6e
  assert(fromIndex >= 0 && fromIndex < (int)m_strokes.size());
Shinya Kitaoka 120a6e
  assert(moveBefore >= 0 && moveBefore <= (int)m_strokes.size());
Shinya Kitaoka 120a6e
  assert(count > 0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(fromIndex != moveBefore);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int i = 0; i < count; i++)
Shinya Kitaoka 120a6e
    if (fromIndex < moveBefore)
Shinya Kitaoka 120a6e
      moveStroke(fromIndex, moveBefore);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      moveStroke(fromIndex + i, moveBefore + i);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<int> changedStrokes;</int>
Shinya Kitaoka 120a6e
  if (regroup) regroupGhosts(changedStrokes);
Shinya Kitaoka 120a6e
  if (!changedStrokes.empty())
Shinya Kitaoka 120a6e
    notifyChangedStrokes(changedStrokes, std::vector<tstroke *="">(), false);</tstroke>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::insertStrokeAt(VIStroke *vs, int strokeIndex,
Shinya Kitaoka 120a6e
                                  bool recomputeRegions) {
Shinya Kitaoka 120a6e
  m_imp->insertStrokeAt(vs, strokeIndex, recomputeRegions);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Shinya Kitaoka 120a6e
void TVectorImage::insertStrokeAt(TStroke *stroke, int strokeIndex, const
Shinya Kitaoka 120a6e
TGroupId& id)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
VIStroke* vs;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
vs = new VIStroke(stroke, id);
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
m_imp->insertStrokeAt(vs, strokeIndex);
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Shinya Kitaoka 3bfa54
TRectD TVectorImage::addStroke(const std::vector<tthickpoint> &points)</tthickpoint>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
//  era:  TStroke *stroke = makeTStroke(points);
Toshihiro Shimizu 890ddd
  TStroke *stroke = TStroke::interpolate(points, 5.0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  m_imp->m_strokes.push_back(new VIStroke( stroke) );
Toshihiro Shimizu 890ddd
  m_imp->m_areValidRegions = false;
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  return stroke->getBBox();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Campbell Barton 8c6c57
static bool isRegionWithStroke(TRegion *region, TStroke *s) {
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < region->getEdgeCount(); i++)
Shinya Kitaoka 120a6e
    if (region->getEdge(i)->m_s == s) return true;
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Campbell Barton 8c6c57
static void deleteSubRegionWithStroke(TRegion *region, TStroke *s) {
Shinya Kitaoka 120a6e
  for (int i = 0; i < (int)region->getSubregionCount(); i++) {
Shinya Kitaoka 120a6e
    deleteSubRegionWithStroke(region->getSubregion(i), s);
Shinya Kitaoka 120a6e
    if (isRegionWithStroke(region->getSubregion(i), s)) {
Shinya Kitaoka 120a6e
      TRegion *r = region->getSubregion(i);
Shinya Kitaoka 120a6e
      r->moveSubregionsTo(region);
Shinya Kitaoka 120a6e
      assert(r->getSubregionCount() == 0);
Shinya Kitaoka 120a6e
      region->deleteSubregion(i);
Shinya Kitaoka 120a6e
      delete r;
Shinya Kitaoka 120a6e
      i--;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStroke *TVectorImage::removeStroke(int index, bool doComputeRegions) {
Shinya Kitaoka 120a6e
  return m_imp->removeStroke(index, doComputeRegions);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStroke *TVectorImage::Imp::removeStroke(int index, bool doComputeRegions) {
Shinya Kitaoka 120a6e
  assert(index >= 0 && index < (int)m_strokes.size());
Shinya Kitaoka 120a6e
  QMutexLocker sl(m_mutex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  VIStroke *stroke = m_strokes[index];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  eraseIntersection(index);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_strokes.erase(m_strokes.begin() + index);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_computedAlmostOnce) {
Shinya Kitaoka 120a6e
    reindexEdges(index);
Shinya Kitaoka 120a6e
    if (doComputeRegions) computeRegions();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return stroke->m_s;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::removeStrokes(const std::vector<int> &toBeRemoved,</int>
Shinya Kitaoka 120a6e
                                 bool deleteThem, bool recomputeRegions) {
Shinya Kitaoka 120a6e
  m_imp->removeStrokes(toBeRemoved, deleteThem, recomputeRegions);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::Imp::removeStrokes(const std::vector<int> &toBeRemoved,</int>
Shinya Kitaoka 120a6e
                                      bool deleteThem, bool recomputeRegions) {
Shinya Kitaoka 120a6e
  QMutexLocker sl(m_mutex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int i = toBeRemoved.size() - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
    assert(i == 0 || toBeRemoved[i - 1] < toBeRemoved[i]);
Shinya Kitaoka 120a6e
    UINT index = toBeRemoved[i];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    eraseIntersection(index);
Shinya Kitaoka 120a6e
    if (deleteThem) delete m_strokes[index];
Shinya Kitaoka 120a6e
    m_strokes.erase(m_strokes.begin() + index);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_computedAlmostOnce && !toBeRemoved.empty()) {
Shinya Kitaoka 120a6e
    reindexEdges(toBeRemoved, false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (recomputeRegions)
Shinya Kitaoka 120a6e
      computeRegions();
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      m_areValidRegions = false;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::deleteStroke(int index) {
Shinya Kitaoka 120a6e
  TStroke *stroke = removeStroke(index);
Shinya Kitaoka 120a6e
  delete stroke;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::deleteStroke(VIStroke *stroke) {
Shinya Kitaoka 120a6e
  UINT index = 0;
Shinya Kitaoka 120a6e
  for (; index < m_imp->m_strokes.size(); index++)
Shinya Kitaoka 120a6e
    if (m_imp->m_strokes[index] == stroke) {
Shinya Kitaoka 120a6e
      deleteStroke(index);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
void TVectorImage::validateRegionEdges(TStroke* stroke, bool invalidate)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
if (invalidate)
Toshihiro Shimizu 890ddd
  for (UINT i=0; i
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
    TRegion *r = getRegion(i);
Toshihiro Shimizu 890ddd
//  if ((*cit)->getBBox().contains(stroke->getBBox()))
Toshihiro Shimizu 890ddd
    for (UINT j=0; j<r->getEdgeCount(); j++)</r->
Toshihiro Shimizu 890ddd
      {
Toshihiro Shimizu 890ddd
      TEdge* edge = r->getEdge(j);
Toshihiro Shimizu 890ddd
      if (edge->m_s == stroke)
Toshihiro Shimizu 890ddd
        edge->m_w0 = edge->m_w1 = -1;
Toshihiro Shimizu 890ddd
      }
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
else
Toshihiro Shimizu 890ddd
 for (UINT i=0; i
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
    TRegion *r = getRegion(i);
Toshihiro Shimizu 890ddd
//  if ((*cit)->getBBox().contains(stroke->getBBox()))
Toshihiro Shimizu 890ddd
    for (UINT j=0; j<r->getEdgeCount(); j++)</r->
Toshihiro Shimizu 890ddd
      {
Toshihiro Shimizu 890ddd
      TEdge* edge = r->getEdge(j);
Toshihiro Shimizu 890ddd
      if (edge->m_w0==-1)
Toshihiro Shimizu 890ddd
        {
Toshihiro Shimizu 890ddd
        int index;
Toshihiro Shimizu 890ddd
        double t, dummy;
Toshihiro Shimizu 890ddd
        edge->m_s->getNearestChunk(edge->m_p0, t, index, dummy);
Toshihiro Shimizu 890ddd
        edge->m_w0 = getWfromChunkAndT(edge->m_s, index, t);
Toshihiro Shimizu 890ddd
        edge->m_s->getNearestChunk(edge->m_p1, t, index, dummy);
Toshihiro Shimizu 890ddd
        edge->m_w1 = getWfromChunkAndT(edge->m_s, index, t);
Toshihiro Shimizu 890ddd
        }
Toshihiro Shimizu 890ddd
      }
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UINT TVectorImage::getStrokeCount() const { return m_imp->m_strokes.size(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
void  TVectorImage::addSeed(const TPointD& p, const TPixel& color)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
m_imp->m_seeds.push_back(TFillSeed(color, p, NULL));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UINT TVectorImage::getRegionCount() const {
Shinya Kitaoka 120a6e
  //  assert( m_imp->m_areValidRegions || m_imp->m_regions.empty());
Shinya Kitaoka 120a6e
  return m_imp->m_regions.size();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRegion *TVectorImage::getRegion(UINT index) const {
Shinya Kitaoka 120a6e
  assert(index < m_imp->m_regions.size());
Shinya Kitaoka 120a6e
  //  assert( m_imp->m_areValidRegions );
Shinya Kitaoka 120a6e
  return m_imp->m_regions[index];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRegion *TVectorImage::getRegion(TRegionId regId) const {
Shinya Kitaoka 120a6e
  int index = getStrokeIndexById(regId.m_strokeId);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(m_imp->m_areValidRegions);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRegion *reg = m_imp->getRegion(regId, index);
Shinya Kitaoka 120a6e
  // assert( reg );
Shinya Kitaoka 120a6e
  return reg;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRegion *TVectorImage::Imp::getRegion(TRegionId regId, int index) const {
Shinya Kitaoka 120a6e
  assert(index != -1);
Shinya Kitaoka 120a6e
  if (index == -1) return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(index < (int)m_strokes.size());
Shinya Kitaoka 120a6e
  if (index >= (int)m_strokes.size()) return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::list<tedge *=""> &edgeList = m_strokes[index]->m_edgeList;</tedge>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::list<tedge *="">::iterator endList = edgeList.end();</tedge>
Shinya Kitaoka 120a6e
  double w0;
Shinya Kitaoka 120a6e
  double w1;
Shinya Kitaoka 120a6e
  for (std::list<tedge *="">::iterator it = edgeList.begin(); it != endList;</tedge>
Shinya Kitaoka 120a6e
       ++it) {
Shinya Kitaoka 120a6e
    w0 = (*it)->m_w0;
Shinya Kitaoka 120a6e
    w1 = (*it)->m_w1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (w0 < w1) {
Shinya Kitaoka 120a6e
      if (w0 < regId.m_midW && regId.m_midW < w1 && regId.m_direction)
Shinya Kitaoka 120a6e
        return (*it)->m_r;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      if (w1 < regId.m_midW && regId.m_midW < w0 && !regId.m_direction)
Shinya Kitaoka 120a6e
        return (*it)->m_r;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
  TPointD cp1 = m_strokes[index]->m_s->getControlPoint(0);
Shinya Kitaoka 120a6e
  TPointD cp2 = m_strokes[index]->m_s->getControlPoint(
Shinya Kitaoka 120a6e
      m_strokes[index]->m_s->getControlPointCount() - 1);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
TRegion* TVectorImage::getRegion(TRegionId regId) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  int index = getStrokeIndexById(regId.m_strokeId);
Toshihiro Shimizu 890ddd
  assert(index!=-1);
Toshihiro Shimizu 890ddd
  if( index == -1 )
Toshihiro Shimizu 890ddd
    return 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  assert( index < (int)m_imp->m_strokes.size() );
Toshihiro Shimizu 890ddd
  if( index >= (int)m_imp->m_strokes.size() )
Toshihiro Shimizu 890ddd
    return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
  std::list<tedge*> &edgeList = m_imp->m_strokes[index]->m_edgeList;</tedge*>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
  std::list<tedge*>::iterator endList = edgeList.end();</tedge*>
Toshihiro Shimizu 890ddd
  double w0;
Toshihiro Shimizu 890ddd
  double w1;
Toshihiro Shimizu 890ddd
  for(list<tedge*>::iterator it= edgeList.begin(); it!=endList; ++it)</tedge*>
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
    w0 = (*it)->m_w0;
Toshihiro Shimizu 890ddd
    w1 = (*it)->m_w1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
    if(w0
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
      if( w0 < regId.m_midW && regId.m_midW < w1 && regId.m_direction )
Toshihiro Shimizu 890ddd
        return (*it)->m_r;
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
    else
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
      if( w1 < regId.m_midW && regId.m_midW < w0 && !regId.m_direction )
Toshihiro Shimizu 890ddd
        return (*it)->m_r;
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::setEdgeColors(int strokeIndex, int leftColorIndex,
Shinya Kitaoka 120a6e
                                 int rightColorIndex) {
Shinya Kitaoka 120a6e
  std::list<tedge *=""> &ll = m_imp->m_strokes[strokeIndex]->m_edgeList;</tedge>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::list<tedge *="">::const_iterator l   = ll.begin();</tedge>
Shinya Kitaoka 120a6e
  std::list<tedge *="">::const_iterator l_e = ll.end();</tedge>
Shinya Kitaoka 120a6e
  for (; l != l_e; ++l) {
Shinya Kitaoka 120a6e
    // double w0 = (*l)->m_w0, w1 = (*l)->m_w1;
Shinya Kitaoka 120a6e
    if ((*l)->m_w0 > (*l)->m_w1) {
Shinya Kitaoka 120a6e
      if (leftColorIndex != -1)
Shinya Kitaoka 120a6e
        (*l)->m_styleId = leftColorIndex;
Shinya Kitaoka 120a6e
      else if (rightColorIndex != -1)
Shinya Kitaoka 120a6e
        (*l)->m_styleId = rightColorIndex;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      if (rightColorIndex != -1)
Shinya Kitaoka 120a6e
        (*l)->m_styleId = rightColorIndex;
Shinya Kitaoka 120a6e
      else if (leftColorIndex != -1)
Shinya Kitaoka 120a6e
        (*l)->m_styleId = leftColorIndex;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStroke *TVectorImage::getStroke(UINT index) const {
Shinya Kitaoka 120a6e
  assert(index < m_imp->m_strokes.size());
Shinya Kitaoka 120a6e
  return m_imp->m_strokes[index]->m_s;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
VIStroke *TVectorImage::getVIStroke(UINT index) const {
Shinya Kitaoka 120a6e
  assert(index < m_imp->m_strokes.size());
Shinya Kitaoka 120a6e
  return m_imp->m_strokes[index];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
VIStroke *TVectorImage::getStrokeById(int id) const {
Shinya Kitaoka 120a6e
  int n = m_imp->m_strokes.size();
Shinya Kitaoka 120a6e
  for (int i = 0; i < n; i++)
Shinya Kitaoka 120a6e
    if (m_imp->m_strokes[i]->m_s->getId() == id) return m_imp->m_strokes[i];
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::getStrokeIndexById(int id) const {
Shinya Kitaoka 120a6e
  int n = m_imp->m_strokes.size();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int i = 0; i < n; i++)
Shinya Kitaoka 120a6e
    if (m_imp->m_strokes[i]->m_s->getId() == id) return i;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::getStrokeIndex(TStroke *stroke) const {
Shinya Kitaoka 120a6e
  int n = m_imp->m_strokes.size();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int i = 0; i < n; i++)
Shinya Kitaoka 120a6e
    if (m_imp->m_strokes[i]->m_s == stroke) return i;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRectD TVectorImage::getBBox() const {
Shinya Kitaoka 120a6e
  UINT strokeCount = m_imp->m_strokes.size();
Shinya Kitaoka 120a6e
  if (strokeCount == 0) return TRectD();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TPalette *plt = getPalette();
Shinya Kitaoka 120a6e
  TRectD bbox;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < strokeCount; ++i) {
Shinya Kitaoka 120a6e
    TRectD r           = m_imp->m_strokes[i]->m_s->getBBox();
Shinya Kitaoka 120a6e
    TColorStyle *style = 0;
shun-iwasawa 9bcc69
    if (plt) style = plt->getStyle(m_imp->m_strokes[i]->m_s->getStyle());
Shinya Kitaoka 120a6e
    if (dynamic_cast<trasterimagepatternstrokestyle *="">(style) ||</trasterimagepatternstrokestyle>
Shinya Kitaoka 120a6e
        dynamic_cast<tvectorimagepatternstrokestyle *="">(</tvectorimagepatternstrokestyle>
Shinya Kitaoka 120a6e
            style))  // con i pattern style, il render a volte taglia sulla bbox
Shinya Kitaoka 120a6e
                     // dello stroke....
Shinya Kitaoka 120a6e
      // aumento la bbox della meta' delle sue dimensioni:pezzaccia.
shun-iwasawa 9bcc69
      r = r.enlarge(std::max(r.getLx() * 0.25, r.getLy() * 0.25));
Shinya Kitaoka 120a6e
    bbox = ((i == 0) ? r : bbox + r);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return bbox;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TVectorImage::getNearestStroke(const TPointD &p, double &outW,
Shinya Kitaoka 120a6e
                                    UINT &strokeIndex, double &dist2,
Shinya Kitaoka 120a6e
                                    bool onlyInCurrentGroup) const {
Shinya Kitaoka 120a6e
  dist2       = (std::numeric_limits<double>::max)();</double>
Shinya Kitaoka 120a6e
  strokeIndex = getStrokeCount();
Shinya Kitaoka 120a6e
  outW        = -1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double tempdis2, tempPar;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int i = 0; i < (int)m_imp->m_strokes.size(); ++i) {
Shinya Kitaoka 120a6e
    if (onlyInCurrentGroup && !inCurrentGroup(i)) continue;
Shinya Kitaoka 120a6e
    TStroke *s = m_imp->m_strokes[i]->m_s;
Shinya Kitaoka 120a6e
    tempPar    = s->getW(p);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    tempdis2 = tdistance2(TThickPoint(p, 0), s->getThickPoint(tempPar));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (tempdis2 < dist2) {
Shinya Kitaoka 120a6e
      outW        = tempPar;
Shinya Kitaoka 120a6e
      dist2       = tempdis2;
Shinya Kitaoka 120a6e
      strokeIndex = i;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return dist2 < (std::numeric_limits<double>::max)();</double>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Rozhuk Ivan ac51ab
#if defined(LINUX) || defined(FREEBSD) || defined(MACOSX)
Shinya Kitaoka 120a6e
void TVectorImage::render(const TVectorRenderData &rd, TRaster32P &ras) {
Shinya Kitaoka 120a6e
  // hardRenderVectorImage(rd,ras,this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//#include "timage_io.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRaster32P TVectorImage::render(bool onlyStrokes) {
Shinya Kitaoka 120a6e
  TRect bBox = convert(getBBox());
Shinya Kitaoka 120a6e
  if (bBox.isEmpty()) return (TRaster32P)0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 2a7129
  std::unique_ptr<tofflinegl> offlineGlContext(new TOfflineGL(bBox.getSize()));</tofflinegl>
Shinya Kitaoka 120a6e
  offlineGlContext->clear(TPixel32(0, 0, 0, 0));
Shinya Kitaoka 120a6e
  offlineGlContext->makeCurrent();
Shinya Kitaoka 120a6e
  TVectorRenderData rd(TTranslation(-convert(bBox.getP00())),
Shinya Kitaoka 120a6e
                       TRect(bBox.getSize()), getPalette(), 0, true, true);
Shinya Kitaoka 120a6e
  rd.m_drawRegions = !onlyStrokes;
Shinya Kitaoka 120a6e
  offlineGlContext->draw(this, rd, false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return offlineGlContext->getRaster()->clone();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // hardRenderVectorImage(rd,ras,this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRegion *TVectorImage::getRegion(const TPointD &p) {
Shinya Kitaoka 6f0974
#ifndef NEW_REGION_FILL
Shinya Kitaoka 120a6e
  if (!isComputedRegionAlmostOnce()) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!m_imp->m_areValidRegions) m_imp->computeRegions();
Shinya Kitaoka 6f0974
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return m_imp->getRegion(p);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRegion *TVectorImage::Imp::getRegion(const TPointD &p) {
Shinya Kitaoka 120a6e
  int strokeIndex = (int)m_strokes.size() - 1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  while (strokeIndex >= 0) {
Shinya Kitaoka 120a6e
    for (UINT regionIndex = 0; regionIndex < m_regions.size(); regionIndex++)
Shinya Kitaoka 120a6e
      if (areDifferentGroup(strokeIndex, false, regionIndex, true) == -1 &&
Shinya Kitaoka 120a6e
          m_regions[regionIndex]->contains(p))
Shinya Kitaoka 120a6e
        return m_regions[regionIndex]->getRegion(p);
Shinya Kitaoka 120a6e
    int curr = strokeIndex;
Shinya Kitaoka 120a6e
    while (strokeIndex >= 0 &&
Shinya Kitaoka 120a6e
           areDifferentGroup(curr, false, strokeIndex, false) == -1)
Shinya Kitaoka 120a6e
      strokeIndex--;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::fillStrokes(const TPointD &p, int styleId) {
Shinya Kitaoka 120a6e
  UINT index;
Shinya Kitaoka 120a6e
  double outW, dist2;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (getNearestStroke(p, outW, index, dist2, true)) {
shun-iwasawa 9bcc69
    double thick = getStroke(index)->getThickPoint(outW).thick * 1.25;
Shinya Kitaoka 120a6e
    if (thick < 0.5) thick = 0.5;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (dist2 > thick * thick) return -1;
Shinya Kitaoka 120a6e
    assert(index >= 0 && index < m_imp->m_strokes.size());
Shinya Kitaoka 120a6e
    int ret = m_imp->m_strokes[index]->m_s->getStyle();
Shinya Kitaoka 120a6e
    m_imp->m_strokes[index]->m_s->setStyle(styleId);
Shinya Kitaoka 120a6e
    return ret;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 6f0974
//-----------------------------------------------------------------------------
Shinya Kitaoka 6f0974
Shinya Kitaoka 6f0974
#ifdef NEW_REGION_FILL
Shinya Kitaoka 6f0974
Shinya Kitaoka 120a6e
void TVectorImage::resetRegionFinder() { m_imp->resetRegionFinder(); }
Shinya Kitaoka 6f0974
#else
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::fill(const TPointD &p, int newStyleId, bool onlyEmpty) {
Shinya Kitaoka 120a6e
  TRegion *r = getRegion(p);
Shinya Kitaoka 120a6e
  if (onlyEmpty && r && r->getStyle() != 0) return -1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!m_imp->m_areValidRegions) m_imp->computeRegions();
Shinya Kitaoka 120a6e
  return m_imp->fill(p, newStyleId);
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 6f0974
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 6f0974
/*
Shinya Kitaoka 6f0974
void TVectorImage::autoFill(int styleId)
Shinya Kitaoka 6f0974
{
Shinya Kitaoka 6f0974
m_imp->autoFill(styleId, true);
Shinya Kitaoka 6f0974
}
Shinya Kitaoka 6f0974
Shinya Kitaoka 6f0974
void TVectorImage::Imp::autoFill(int styleId, bool oddLevel)
Shinya Kitaoka 6f0974
{
Shinya Kitaoka 6f0974
if (!m_areValidRegions)
Shinya Kitaoka 120a6e
  computeRegions();
Shinya Kitaoka 6f0974
for (UINT i = 0; i
Shinya Kitaoka 6f0974
  {
Shinya Kitaoka 6f0974
  if (oddLevel)
Shinya Kitaoka 6f0974
    m_regions[i]->setStyle(styleId);
Shinya Kitaoka 6f0974
  m_regions[i]->autoFill(styleId, !oddLevel);
Shinya Kitaoka 6f0974
  }
Shinya Kitaoka 6f0974
}
Shinya Kitaoka 6f0974
*/
Shinya Kitaoka 6f0974
//-----------------------------------------------------------------------------
Shinya Kitaoka 6f0974
/*
Shinya Kitaoka 6f0974
void TRegion::autoFill(int styleId, bool oddLevel)
Shinya Kitaoka 6f0974
{
Shinya Kitaoka 6f0974
for (UINT i = 0; i
Shinya Kitaoka 6f0974
  {
Shinya Kitaoka 6f0974
  TRegion* r = getSubregion(i);
Shinya Kitaoka 6f0974
  if (oddLevel)
Shinya Kitaoka 6f0974
    r->setStyle(styleId);
Shinya Kitaoka 6f0974
  r->autoFill(styleId, !oddLevel);
Shinya Kitaoka 6f0974
  }
Shinya Kitaoka 6f0974
Shinya Kitaoka 6f0974
}
Shinya Kitaoka 6f0974
*/
Shinya Kitaoka 6f0974
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::Imp::fill(const TPointD &p, int styleId) {
Shinya Kitaoka 120a6e
  int strokeIndex = (int)m_strokes.size() - 1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  while (strokeIndex >= 0) {
Shinya Kitaoka 120a6e
    if (!inCurrentGroup(strokeIndex)) {
Shinya Kitaoka 120a6e
      strokeIndex--;
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (UINT regionIndex = 0; regionIndex < m_regions.size(); regionIndex++)
Shinya Kitaoka 120a6e
      if (areDifferentGroup(strokeIndex, false, regionIndex, true) == -1 &&
Shinya Kitaoka 120a6e
          m_regions[regionIndex]->contains(p))
Shinya Kitaoka 120a6e
        return m_regions[regionIndex]->fill(p, styleId);
Shinya Kitaoka 120a6e
    int curr = strokeIndex;
Shinya Kitaoka 120a6e
    while (strokeIndex >= 0 &&
Shinya Kitaoka 120a6e
           areDifferentGroup(curr, false, strokeIndex, false) == -1)
Shinya Kitaoka 120a6e
      strokeIndex--;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TVectorImage::selectFill(const TRectD &selArea, TStroke *s, int newStyleId,
Shinya Kitaoka 120a6e
                              bool onlyUnfilled, bool fillAreas,
Shinya Kitaoka 120a6e
                              bool fillLines) {
Shinya Kitaoka 120a6e
  if (!m_imp->m_areValidRegions) m_imp->computeRegions();
Shinya Kitaoka 120a6e
  return m_imp->selectFill(selArea, s, newStyleId, onlyUnfilled, fillAreas,
Shinya Kitaoka 120a6e
                           fillLines);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TVectorImage::Imp::selectFill(const TRectD &selArea, TStroke *s,
Shinya Kitaoka 120a6e
                                   int newStyleId, bool onlyUnfilled,
Shinya Kitaoka 120a6e
                                   bool fillAreas, bool fillLines) {
Shinya Kitaoka 120a6e
  bool hitSome = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (s) {
Shinya Kitaoka 120a6e
    TVectorImage aux;
Shinya Kitaoka 120a6e
    aux.addStroke(s);
Shinya Kitaoka 120a6e
    aux.findRegions();
Shinya Kitaoka 120a6e
    for (UINT j = 0; j < aux.getRegionCount(); j++) {
Shinya Kitaoka 120a6e
      TRegion *r0 = aux.getRegion(j);
Shinya Kitaoka 120a6e
      if (fillAreas)
Shinya Kitaoka 120a6e
        for (UINT i = 0; i < m_regions.size(); i++) {
Shinya Kitaoka 120a6e
          TRegion *r1 = m_regions[i];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (m_insideGroup != TGroupId() &&
Shinya Kitaoka 120a6e
              !m_insideGroup.isParentOf(
Shinya Kitaoka 120a6e
                  m_strokes[r1->getEdge(0)->m_index]->m_groupId))
Shinya Kitaoka 120a6e
            continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if ((!onlyUnfilled || r1->getStyle() == 0) && r0->contains(*r1)) {
Shinya Kitaoka 120a6e
            r1->setStyle(newStyleId);
Shinya Kitaoka 120a6e
            hitSome = true;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      if (fillLines)
Shinya Kitaoka 120a6e
        for (UINT i = 0; i < m_strokes.size(); i++) {
Shinya Kitaoka 120a6e
          if (!inCurrentGroup(i)) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          TStroke *s1 = m_strokes[i]->m_s;
Shinya Kitaoka 120a6e
          if ((!onlyUnfilled || s1->getStyle() == 0) && r0->contains(*s1)) {
Shinya Kitaoka 120a6e
            s1->setStyle(newStyleId);
Shinya Kitaoka 120a6e
            hitSome = true;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    aux.removeStroke(0);
Shinya Kitaoka 120a6e
    return hitSome;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // rect fill
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (fillAreas)
Shinya Kitaoka 6f0974
#ifndef NEW_REGION_FILL
Shinya Kitaoka 120a6e
    for (UINT i = 0; i < m_regions.size(); i++) {
Shinya Kitaoka 120a6e
      int index, j = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      do
Shinya Kitaoka 120a6e
        index = m_regions[i]->getEdge(j++)->m_index;
Shinya Kitaoka 120a6e
      while (index < 0 && j < (int)m_regions[i]->getEdgeCount());
Shinya Kitaoka 120a6e
      // if index<0, means that the region is purely of autoclose strokes!
Shinya Kitaoka 120a6e
      if (m_insideGroup != TGroupId() && index >= 0 &&
Shinya Kitaoka 120a6e
          !m_insideGroup.isParentOf(m_strokes[index]->m_groupId))
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      if (!onlyUnfilled || m_regions[i]->getStyle() == 0)
Shinya Kitaoka 120a6e
        hitSome |= m_regions[i]->selectFill(selArea, newStyleId);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 6f0974
#else
Shinya Kitaoka 6f0974
Shinya Kitaoka 120a6e
    findRegions(selArea);
Shinya Kitaoka 6f0974
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < m_regions.size(); i++) {
Shinya Kitaoka 120a6e
    if (m_insideGroup != TGroupId() &&
Shinya Kitaoka 120a6e
        !m_insideGroup.isParentOf(
Shinya Kitaoka 120a6e
            m_strokes[m_regions[i]->getEdge(0)->m_index]->m_groupId))
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    if (!onlyUnfilled || m_regions[i]->getStyle() == 0)
Shinya Kitaoka 120a6e
      hitSome |= m_regions[i]->selectFill(selArea, newStyleId);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 6f0974
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (fillLines)
Shinya Kitaoka 120a6e
    for (UINT i = 0; i < m_strokes.size(); i++) {
Shinya Kitaoka 120a6e
      if (!inCurrentGroup(i)) continue;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      TStroke *s = m_strokes[i]->m_s;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if ((!onlyUnfilled || s->getStyle() == 0) &&
Shinya Kitaoka 120a6e
          selArea.contains(s->getBBox())) {
Shinya Kitaoka 120a6e
        s->setStyle(newStyleId);
Shinya Kitaoka 120a6e
        hitSome = true;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  return hitSome;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
void  TVectorImageImp::seedFill()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  std::vector<tfillseed>::iterator it;</tfillseed>
Toshihiro Shimizu 890ddd
  TRegion*r;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  TFillStyleP app =NULL;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  for (it=m_seeds.begin(); it!=m_seeds.end(); )
Shinya Kitaoka 120a6e
    if ((r=fill(it->m_p, new TColorStyle(it->m_fillStyle.getPointer()) ))!=NULL)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
      it->m_r = r;
Shinya Kitaoka 120a6e
      it = m_seeds.erase(it);  // i seed provengono da immagini vecchie. non
Shinya Kitaoka 120a6e
servono piu'.
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
  m_areValidRegions=true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
void  TVectorImage::seedFill()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  m_imp->seedFill();
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::notifyChangedStrokes(
Shinya Kitaoka 120a6e
    const std::vector<int> &strokeIndexArray,</int>
Shinya Kitaoka 120a6e
    const std::vector<tstroke *=""> &oldStrokeArray, bool areFlipped) {</tstroke>
Shinya Kitaoka 120a6e
  std::vector<tstroke *=""> aux;</tstroke>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /*
Toshihiro Shimizu 890ddd
if (oldStrokeArray.empty())
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
  for (int i=0; i<(int)strokeIndexArray.size(); i++)
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
          TStroke *s = getStroke(strokeIndexArray[i]);
Shinya Kitaoka 120a6e
    aux.push_back(s);
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
m_imp->notifyChangedStrokes(strokeIndexArray, aux, areFlipped);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
else*/
Shinya Kitaoka 120a6e
  m_imp->notifyChangedStrokes(strokeIndexArray, oldStrokeArray, areFlipped);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::notifyChangedStrokes(int strokeIndexArray,
Shinya Kitaoka 120a6e
                                        TStroke *oldStroke, bool isFlipped) {
Shinya Kitaoka 120a6e
  std::vector<int> app(1);</int>
Shinya Kitaoka 120a6e
  app[0] = strokeIndexArray;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<tstroke *=""> oldStrokeArray(1);</tstroke>
Shinya Kitaoka 120a6e
  oldStrokeArray[0] = oldStroke ? oldStroke : getStroke(strokeIndexArray);
Shinya Kitaoka 120a6e
  m_imp->notifyChangedStrokes(app, oldStrokeArray, isFlipped);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// ofstream of("C:\\temp\\butta.txt");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void transferColors(const std::list<tedge *=""> &oldList,</tedge>
Shinya Kitaoka 120a6e
                    const std::list<tedge *=""> &newList, bool isStrokeChanged,</tedge>
Shinya Kitaoka 120a6e
                    bool isFlipped, bool overwriteColor) {
Shinya Kitaoka 120a6e
  if (newList.empty() || oldList.empty()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::list<tedge *="">::const_iterator it;</tedge>
Toshihiro Shimizu 890ddd
// unused variable
Toshihiro Shimizu 890ddd
#if 0 
Toshihiro Shimizu 890ddd
list<tedge*>::const_iterator it1;</tedge*>
Toshihiro Shimizu 890ddd
#endif
MCCCS a0ce32
  double totLength;
MCCCS a0ce32
  if (isStrokeChanged) totLength = newList.front()->m_s->getLength();
Shinya Kitaoka 120a6e
  for (it = newList.begin(); it != newList.end(); ++it) {
Shinya Kitaoka 120a6e
    int newStyle = -1;  // ErrorStyle;
Toshihiro Shimizu 890ddd
// unused variable
Toshihiro Shimizu 890ddd
#if 0 
Toshihiro Shimizu 890ddd
  int styleId = (*it)->m_styleId;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    if (!overwriteColor && (*it)->m_styleId != 0) continue;
Shinya Kitaoka 120a6e
    bool reversed;
Shinya Kitaoka 120a6e
    double deltaMax = 0.005;
Shinya Kitaoka 120a6e
    double l0, l1;
Shinya Kitaoka 120a6e
    if ((*it)->m_w0 > (*it)->m_w1) {
Shinya Kitaoka 120a6e
      reversed = !isFlipped;
Shinya Kitaoka 120a6e
      if (isStrokeChanged) {
MCCCS a0ce32
        l0 = (*it)->m_s->getLength((*it)->m_w1) / totLength;
MCCCS a0ce32
        l1 = (*it)->m_s->getLength((*it)->m_w0) / totLength;
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        l0 = (*it)->m_w1;
Shinya Kitaoka 120a6e
        l1 = (*it)->m_w0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      reversed = isFlipped;
Shinya Kitaoka 120a6e
      if (isStrokeChanged) {
MCCCS a0ce32
        l0 = (*it)->m_s->getLength((*it)->m_w0) / totLength;
MCCCS a0ce32
        l1 = (*it)->m_s->getLength((*it)->m_w1) / totLength;
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        l0 = (*it)->m_w0;
Shinya Kitaoka 120a6e
        l1 = (*it)->m_w1;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      // w0 = (*it)->m_w0;
Shinya Kitaoka 120a6e
      // w1 = (*it)->m_w1;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::list<tedge *="">::const_iterator it1 = oldList.begin();</tedge>
Shinya Kitaoka 120a6e
    for (; it1 != oldList.end(); ++it1) {
Toshihiro Shimizu 890ddd
// unused variable
Toshihiro Shimizu 890ddd
#if 0
Toshihiro Shimizu 890ddd
      TEdge*e = *it1;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
      if (/*(*it1)->m_styleId==0 ||*/
Shinya Kitaoka 120a6e
          (reversed && (*it1)->m_w0 < (*it1)->m_w1) ||
Shinya Kitaoka 120a6e
          (!reversed && (*it1)->m_w0 > (*it1)->m_w1))
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      double _l0, _l1;
Shinya Kitaoka 120a6e
      if (isStrokeChanged) {
MCCCS a0ce32
        double totLength1 = (*it1)->m_s->getLength();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        _l0 = (*it1)->m_s->getLength(std::min((*it1)->m_w0, (*it1)->m_w1)) /
MCCCS a0ce32
              totLength1;
Shinya Kitaoka 120a6e
        _l1 = (*it1)->m_s->getLength(std::max((*it1)->m_w0, (*it1)->m_w1)) /
MCCCS a0ce32
              totLength1;
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        _l0 = std::min((*it1)->m_w0, (*it1)->m_w1);
Shinya Kitaoka 120a6e
        _l1 = std::max((*it1)->m_w0, (*it1)->m_w1);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      double delta = std::min(l1, _l1) - std::max(l0, _l0);
Shinya Kitaoka 120a6e
      if (delta > deltaMax) {
Shinya Kitaoka 120a6e
        deltaMax = delta;
Shinya Kitaoka 120a6e
        newStyle = (*it1)->m_styleId;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (newStyle >= 0)  // !=ErrorStyle)
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      if ((*it)->m_r)
Shinya Kitaoka 120a6e
        (*it)->m_r->setStyle(newStyle);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        (*it)->m_styleId = newStyle;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TVectorImage::transferStrokeColors(TVectorImageP sourceImage,
Shinya Kitaoka 120a6e
                                        int sourceStroke,
Shinya Kitaoka 120a6e
                                        TVectorImageP destinationImage,
Shinya Kitaoka 120a6e
                                        int destinationStroke) {
Shinya Kitaoka 120a6e
  std::list<tedge *=""> *sourceList =</tedge>
Shinya Kitaoka 120a6e
      &(sourceImage->m_imp->m_strokes[sourceStroke]->m_edgeList);
Shinya Kitaoka 120a6e
  std::list<tedge *=""> *destinationList =</tedge>
Shinya Kitaoka 120a6e
      &(destinationImage->m_imp->m_strokes[destinationStroke]->m_edgeList);
Shinya Kitaoka 120a6e
  transferColors(*sourceList, *destinationList, true, false, false);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
bool TVectorImage::Imp::areWholeGroups(const std::vector<int> &indexes) const {</int>
Shinya Kitaoka 120a6e
  UINT i, j;
Shinya Kitaoka 120a6e
  for (i = 0; i < indexes.size(); i++) {
Shinya Kitaoka 120a6e
    if (m_strokes[indexes[i]]->m_isNewForFill) return false;
Rozhuk Ivan 823a31
    if (!m_strokes[indexes[i]]->m_groupId.isGrouped()) return false;
Shinya Kitaoka 120a6e
    for (j = 0; j < m_strokes.size(); j++) {
Shinya Kitaoka 120a6e
      int ret = areDifferentGroup(indexes[i], false, j, false);
pojienie 4e4838
      if (ret == -1 || (ret >= 1 && find(indexes.begin(), indexes.end(), j) ==
pojienie 4e4838
                                        indexes.end()))
Shinya Kitaoka 120a6e
        return false;
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
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::Imp::notifyChangedStrokes(
Shinya Kitaoka 120a6e
    const std::vector<int> &strokeIndexArray,</int>
Shinya Kitaoka 120a6e
    const std::vector<tstroke *=""> &oldStrokeArray, bool areFlipped) {</tstroke>
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
  checkIntersections();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(oldStrokeArray.empty() ||
Shinya Kitaoka 120a6e
         strokeIndexArray.size() == oldStrokeArray.size());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_computedAlmostOnce && !m_notIntersectingStrokes) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  typedef std::list<tedge *=""> EdgeList;</tedge>
Shinya Kitaoka 120a6e
  std::vector<edgelist> oldEdgeListArray(strokeIndexArray.size());</edgelist>
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // se si sono trasformati  interi gruppi (senza deformare le stroke) non c'e'
Shinya Kitaoka 120a6e
  // bisogno di ricalcolare le regioni!
Shinya Kitaoka 120a6e
  if (oldStrokeArray.empty() && areWholeGroups(strokeIndexArray)) {
Shinya Kitaoka 120a6e
    m_areValidRegions = true;
Shinya Kitaoka 120a6e
    for (i = 0; i < (int)m_regions.size(); i++)
Shinya Kitaoka 120a6e
      invalidateRegionPropAndBBox(m_regions[i]);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QMutexLocker sl(m_mutex);
Shinya Kitaoka 120a6e
  for (i = 0; i < (int)strokeIndexArray.size(); i++)  // ATTENZIONE! non si puo'
Shinya Kitaoka 120a6e
                                                      // fare eraseIntersection
Shinya Kitaoka 120a6e
                                                      // in questo stesso ciclo
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    VIStroke *s = m_strokes[strokeIndexArray[i]];
Shinya Kitaoka 120a6e
    // if (s->m_s->isSelfLoop())
Shinya Kitaoka 120a6e
    //  assert(s->m_edgeList.size()<=1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::list<tedge *="">::iterator it = s->m_edgeList.begin();</tedge>
Shinya Kitaoka 120a6e
    for (; it != s->m_edgeList.end(); it++) {
shun-iwasawa 9bcc69
      TEdge *e = new TEdge(**it, false);
Shinya Kitaoka 120a6e
      if (!oldStrokeArray.empty()) e->m_s = oldStrokeArray[i];
Shinya Kitaoka 120a6e
      oldEdgeListArray[i].push_back(e);  // bisogna allocare nuovo edge,
Shinya Kitaoka 120a6e
                                         // perche'la eraseIntersection poi lo
Shinya Kitaoka 120a6e
                                         // cancella....
Shinya Kitaoka 120a6e
      if ((*it)->m_toBeDeleted) delete *it;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    s->m_edgeList.clear();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < (int)strokeIndexArray.size(); i++) {
Shinya Kitaoka 120a6e
    eraseIntersection(strokeIndexArray[i]);
Shinya Kitaoka 120a6e
    if (!m_notIntersectingStrokes)
Shinya Kitaoka 120a6e
      m_strokes[strokeIndexArray[i]]->m_isNewForFill = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  computeRegions();  // m_imp->m_strokes, m_imp->m_regions);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < (int)strokeIndexArray.size(); i++) {
Shinya Kitaoka 120a6e
    transferColors(oldEdgeListArray[i],
Shinya Kitaoka 120a6e
                   m_strokes[strokeIndexArray[i]]->m_edgeList, true, areFlipped,
Shinya Kitaoka 120a6e
                   false);
Shinya Kitaoka 120a6e
    clearPointerContainer(oldEdgeListArray[i]);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
  checkIntersections();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Jeremy Bullock 29ea81
void TVectorImage::findRegions() {
Shinya Kitaoka 120a6e
  // for (int i=0; i<(int)m_imp->m_strokes.size(); i++)
Shinya Kitaoka 120a6e
  //  {
Shinya Kitaoka 120a6e
  //  m_imp->eraseIntersection(i);
Shinya Kitaoka 120a6e
  //	  m_imp->m_strokes[i]->m_isNewForFill=true;
Shinya Kitaoka 120a6e
  //  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_imp->m_areValidRegions) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // m_imp->m_regions.clear();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // compute regions...
Shinya Kitaoka 120a6e
  m_imp->computeRegions();  // m_imp->m_strokes, m_imp->m_regions);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::putRegion(TRegion *region) {
Shinya Kitaoka 120a6e
  m_imp->m_regions.push_back(region);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::Imp::cloneRegions(TVectorImage::Imp &out,
Shinya Kitaoka 120a6e
                                     bool doComputeRegions) {
Shinya Kitaoka 120a6e
  std::unique_ptr<intersectionbranch[]> v;</intersectionbranch[]>
Shinya Kitaoka 120a6e
  UINT size = getFillData(v);
Shinya Kitaoka 120a6e
  out.setFillData(v, size, doComputeRegions);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TVectorImageP TVectorImage::clone() const {
Shinya Kitaoka 120a6e
  return TVectorImageP(cloneImage());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImage *TVectorImage::cloneImage() const {
Shinya Kitaoka 120a6e
  TVectorImage *out = new TVectorImage;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  out->m_imp->m_autocloseTolerance = m_imp->m_autocloseTolerance;
Shinya Kitaoka 120a6e
  out->m_imp->m_maxGroupId         = m_imp->m_maxGroupId;
Shinya Kitaoka 120a6e
  out->m_imp->m_maxGhostGroupId    = m_imp->m_maxGhostGroupId;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int i = 0; i < (int)m_imp->m_strokes.size(); i++) {
Shinya Kitaoka 120a6e
    out->m_imp->m_strokes.push_back(new VIStroke(*(m_imp->m_strokes[i])));
Shinya Kitaoka 120a6e
    out->m_imp->m_strokes.back()->m_s->setId(m_imp->m_strokes[i]->m_s->getId());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->cloneRegions(*out->m_imp);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  out->setPalette(getPalette());
Shinya Kitaoka 120a6e
  out->m_imp->m_computedAlmostOnce = m_imp->m_computedAlmostOnce;
Shinya Kitaoka 120a6e
  out->m_imp->m_justLoaded         = m_imp->m_justLoaded;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return out;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
TVectorImageP mergeAndClear(TVectorImageP v1, TVectorImageP v2 )
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  TVectorImageP out = new TVectorImage;
Shinya Kitaoka 120a6e
Shinya Kitaoka 3bfa54
  std::vector<vistroke*>::iterator it_b =  v1->m_imp->m_strokes.begin();</vistroke*>
Shinya Kitaoka 3bfa54
  std::vector<vistroke*>::iterator it_e =  v1->m_imp->m_strokes.end();</vistroke*>
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  std::copy( it_b, it_e, std::back_inserter( out->m_imp->m_strokes ) );
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  it_b =  v2->m_imp->m_strokes.begin();
Toshihiro Shimizu 890ddd
  it_e =  v2->m_imp->m_strokes.end();
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  std::copy( it_b, it_e, std::back_inserter( out->m_imp->m_strokes ) );
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  v1->m_imp->m_regions.clear();
Toshihiro Shimizu 890ddd
  v1->m_imp->m_strokes.clear();
Toshihiro Shimizu 890ddd
  v2->m_imp->m_regions.clear();
Toshihiro Shimizu 890ddd
  v2->m_imp->m_strokes.clear();
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  out->m_imp->m_areValidRegions = false;
Toshihiro Shimizu 890ddd
  return out;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
VIStroke::VIStroke(const VIStroke &s, bool sameId)
Shinya Kitaoka 120a6e
    : m_isPoint(s.m_isPoint)
Shinya Kitaoka 120a6e
    , m_isNewForFill(s.m_isNewForFill)
Shinya Kitaoka 120a6e
    , m_groupId(s.m_groupId) {
Shinya Kitaoka 120a6e
  m_s                                     = new TStroke(*s.m_s);
Shinya Kitaoka 120a6e
  std::list<tedge *="">::const_iterator it   = s.m_edgeList.begin(),</tedge>
Shinya Kitaoka 120a6e
                                     it_e = s.m_edgeList.end();
Shinya Kitaoka 120a6e
  for (; it != it_e; ++it) {
Shinya Kitaoka 120a6e
    m_edgeList.push_back(new TEdge(**it, true));
Shinya Kitaoka 120a6e
    m_edgeList.back()->m_s = m_s;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (sameId) m_s->setId(s.m_s->getId());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
pojienie 4e4838
int TVectorImage::mergeImage(const TVectorImageP &img, const TAffine &affine,
pojienie 4e4838
                             bool sameStrokeId) {
Shinya Kitaoka 120a6e
  QMutexLocker sl(m_imp->m_mutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
  checkIntersections();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TPalette *tarPlt = getPalette();
Shinya Kitaoka 120a6e
  TPalette *srcPlt = img->getPalette();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(tarPlt);
Shinya Kitaoka 120a6e
  assert(tarPlt->getPageCount() > 0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // merge della palette
Shinya Kitaoka 120a6e
  std::map<int, int=""> styleTable;</int,>
Shinya Kitaoka 120a6e
  std::set<int> usedStyles;</int>
Shinya Kitaoka 120a6e
  img->getUsedStyles(usedStyles);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // gmt, 16/10/07. Quando si copia e incolla un path su uno stroke succede
Shinya Kitaoka 120a6e
  // che la palette dell'immagine sorgente sia vuota. Non mi sembra sbagliato
Shinya Kitaoka 120a6e
  // mettere comunque un test qui
Shinya Kitaoka 120a6e
  if (srcPlt) mergePalette(tarPlt, styleTable, srcPlt, usedStyles);
Toshihiro Shimizu 890ddd
pojienie 4e4838
  return mergeImage(img, affine, styleTable, sameStrokeId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
pojienie 4e4838
int TVectorImage::mergeImage(const TVectorImageP &img, const TAffine &affine,
pojienie 4e4838
                             const std::map<int, int=""> &styleTable,</int,>
pojienie 4e4838
                             bool sameStrokeId) {
Shinya Kitaoka 120a6e
  int imageSize = img->getStrokeCount();
pojienie 4e4838
  if (imageSize == 0) return 0;
Shinya Kitaoka 120a6e
  QMutexLocker sl(m_imp->m_mutex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_imp->m_computedAlmostOnce |= img->m_imp->m_computedAlmostOnce;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<int> changedStrokeArray(imageSize);</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  img->m_imp->reindexGroups(*m_imp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  int insertAt = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_imp->m_insideGroup !=
Shinya Kitaoka 120a6e
      TGroupId())  // if is inside a group, new image is put in that group.
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    TGroupId groupId;
Rozhuk Ivan 823a31
    for (i = m_imp->m_strokes.size() - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
      if (m_imp->m_insideGroup.isParentOf(m_imp->m_strokes[i]->m_groupId)) {
Shinya Kitaoka 120a6e
        insertAt = i + 1;
Shinya Kitaoka 120a6e
        groupId  = m_imp->m_strokes[i]->m_groupId;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      }
Rozhuk Ivan 823a31
    }
Rozhuk Ivan 823a31
    if (insertAt != 0) {
Rozhuk Ivan 823a31
      for (i = 0; i < (int)img->m_imp->m_strokes.size(); i++) {
Rozhuk Ivan 823a31
        if (!img->m_imp->m_strokes[i]->m_groupId.isGrouped()) {
Shinya Kitaoka 120a6e
          img->m_imp->m_strokes[i]->m_groupId = groupId;
Rozhuk Ivan 823a31
        } else {
Shinya Kitaoka 120a6e
          img->m_imp->m_strokes[i]->m_groupId =
Shinya Kitaoka 120a6e
              TGroupId(groupId, img->m_imp->m_strokes[i]->m_groupId);
pojienie 4e4838
        }
Rozhuk Ivan 823a31
      }
Rozhuk Ivan 823a31
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // si fondono l'ultimo gruppo ghost della vecchia a e il primo della nuova
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  else if (!m_imp->m_strokes.empty() &&
Shinya Kitaoka 120a6e
           m_imp->m_strokes.back()->m_groupId.isGrouped(true) != 0 &&
Shinya Kitaoka 120a6e
           img->m_imp->m_strokes[0]->m_groupId.isGrouped(true) != 0) {
Shinya Kitaoka 120a6e
    TGroupId idNew = m_imp->m_strokes.back()->m_groupId,
Shinya Kitaoka 120a6e
             idOld = img->m_imp->m_strokes[0]->m_groupId;
Shinya Kitaoka 120a6e
    for (i = 0; i < (int)img->m_imp->m_strokes.size() &&
Shinya Kitaoka 120a6e
                img->m_imp->m_strokes[i]->m_groupId == idOld;
Shinya Kitaoka 120a6e
         i++)
Shinya Kitaoka 120a6e
      img->m_imp->m_strokes[i]->m_groupId = idNew;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // merge dell'immagine
Shinya Kitaoka 120a6e
  std::map<int, int="">::const_iterator styleTableIt;</int,>
Shinya Kitaoka 120a6e
  int oldSize = getStrokeCount();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < imageSize; i++) {
Shinya Kitaoka 120a6e
    VIStroke *srcStroke = img->m_imp->m_strokes[i];
Shinya Kitaoka 120a6e
    VIStroke *tarStroke = new VIStroke(*srcStroke, sameStrokeId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int styleId;
Shinya Kitaoka 120a6e
    // cambio i colori delle regioni
Shinya Kitaoka 120a6e
    std::list<tedge *="">::const_iterator it   = tarStroke->m_edgeList.begin(),</tedge>
Shinya Kitaoka 120a6e
                                       it_e = tarStroke->m_edgeList.end();
Shinya Kitaoka 120a6e
    for (; it != it_e; ++it) {
Shinya Kitaoka 120a6e
      int styleId  = (*it)->m_styleId;
Shinya Kitaoka 120a6e
      styleTableIt = styleTable.find(styleId);
Shinya Kitaoka 120a6e
      assert(styleTableIt != styleTable.end());
Shinya Kitaoka 120a6e
      if (styleTableIt != styleTable.end())
Shinya Kitaoka 120a6e
        (*it)->m_styleId = styleTableIt->second;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    tarStroke->m_s->transform(affine, true);
Shinya Kitaoka 120a6e
    int strokeId = srcStroke->m_s->getId();
Shinya Kitaoka 120a6e
    if (getStrokeById(strokeId) == 0) tarStroke->m_s->setId(strokeId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // cambio i colori dello stroke
Shinya Kitaoka 120a6e
    styleId      = srcStroke->m_s->getStyle();
Shinya Kitaoka 120a6e
    styleTableIt = styleTable.find(styleId);
Shinya Kitaoka 120a6e
    assert(styleTableIt != styleTable.end());
Shinya Kitaoka 120a6e
    if (styleTableIt != styleTable.end())
Shinya Kitaoka 120a6e
      tarStroke->m_s->setStyle(styleTableIt->second);
Shinya Kitaoka 120a6e
    if (insertAt == 0) {
Shinya Kitaoka 120a6e
      m_imp->m_strokes.push_back(tarStroke);
Shinya Kitaoka 120a6e
      changedStrokeArray[i] = oldSize + i;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      std::vector<vistroke *="">::iterator it = m_imp->m_strokes.begin();</vistroke>
Shinya Kitaoka 120a6e
      advance(it, insertAt + i);
Shinya Kitaoka 120a6e
      m_imp->m_strokes.insert(it, tarStroke);
Shinya Kitaoka 120a6e
      changedStrokeArray[i] = insertAt + i;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (insertAt > 0) {
Shinya Kitaoka 120a6e
    // for (i=changedStrokeArray.back()+1; i<m_imp->m_strokes.size(); i++)</m_imp->
Shinya Kitaoka 120a6e
    //  changedStrokeArray.push_back(i);
Shinya Kitaoka 120a6e
    m_imp->reindexEdges(changedStrokeArray, true);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  notifyChangedStrokes(changedStrokeArray, std::vector<tstroke *="">(), false);</tstroke>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
  checkIntersections();
Toshihiro Shimizu 890ddd
#endif
pojienie 4e4838
pojienie 4e4838
  return insertAt;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::Imp::reindexGroups(TVectorImage::Imp &img) {
Shinya Kitaoka 120a6e
  UINT i, j;
Shinya Kitaoka 120a6e
  int newMax      = img.m_maxGroupId;
Shinya Kitaoka 120a6e
  int newMaxGhost = img.m_maxGhostGroupId;
Shinya Kitaoka 120a6e
  for (i = 0; i < m_strokes.size(); i++) {
Shinya Kitaoka 120a6e
    VIStroke *s = m_strokes[i];
Shinya Kitaoka 120a6e
    if (s->m_groupId.m_id.empty()) continue;
Shinya Kitaoka 120a6e
    if (s->m_groupId.m_id[0] > 0)
Shinya Kitaoka 120a6e
      for (j = 0; j < s->m_groupId.m_id.size(); j++) {
Shinya Kitaoka 120a6e
        s->m_groupId.m_id[j] += img.m_maxGroupId;
Shinya Kitaoka 120a6e
        newMax = std::max(newMax, s->m_groupId.m_id[j]);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      for (j = 0; j < s->m_groupId.m_id.size(); j++) {
Shinya Kitaoka 120a6e
        s->m_groupId.m_id[j] -= img.m_maxGhostGroupId;
Shinya Kitaoka 120a6e
        newMaxGhost = std::max(newMaxGhost, -s->m_groupId.m_id[j]);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_maxGroupId = img.m_maxGroupId = newMax;
Shinya Kitaoka 120a6e
  m_maxGhostGroupId = img.m_maxGhostGroupId = newMaxGhost;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TVectorImage::mergeImage(const std::vector<const *="" tvectorimage=""> &images) {</const>
Shinya Kitaoka 120a6e
  UINT oldSize = getStrokeCount();
Shinya Kitaoka 120a6e
  std::vector<int> changedStrokeArray;</int>
Shinya Kitaoka 120a6e
  const TVectorImage *img;
Shinya Kitaoka 120a6e
  int index;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_imp->m_insideGroup != TGroupId()) {
Shinya Kitaoka 120a6e
    for (index = m_imp->m_strokes.size() - 1; index > -1; index--)
Shinya Kitaoka 120a6e
      if (m_imp->m_insideGroup.isParentOf(m_imp->m_strokes[index]->m_groupId))
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
    assert(index > -1);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    index = getStrokeCount() - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (UINT j = 0; j < images.size(); ++j) {
Shinya Kitaoka 120a6e
    img = images[j];
Shinya Kitaoka 120a6e
    if (img->getStrokeCount() == 0) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    img->m_imp->reindexGroups(*m_imp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int i = 0;
Shinya Kitaoka 120a6e
    /*if (!m_imp->m_strokes.empty() &&
Shinya Kitaoka 120a6e
m_imp->m_strokes[index-1]->m_groupId.isGrouped(true)!=0 &&
Shinya Kitaoka 120a6e
img->m_imp->m_strokes[0]->m_groupId.isGrouped(true)!=0)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
assert(false);
Shinya Kitaoka 120a6e
TGroupId idNew = m_imp->m_strokes[index]->m_groupId, idOld =
Shinya Kitaoka 120a6e
img->m_imp->m_strokes[0]->m_groupId;
Shinya Kitaoka 120a6e
for  (;i<(int)img->m_imp->m_strokes.size() &&
Shinya Kitaoka 120a6e
img->m_imp->m_strokes[i]->m_groupId==idOld; i++)
Shinya Kitaoka 120a6e
img->m_imp->m_strokes[i]->m_groupId==idNew;
Shinya Kitaoka 120a6e
}*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int strokeCount = img->getStrokeCount();
Shinya Kitaoka 120a6e
    m_imp->m_computedAlmostOnce |= img->m_imp->m_computedAlmostOnce;
Shinya Kitaoka 120a6e
    for (i = 0; i < strokeCount; i++) {
Shinya Kitaoka 120a6e
      VIStroke *srcStroke = img->m_imp->m_strokes[i];
Shinya Kitaoka 120a6e
      VIStroke *tarStroke = new VIStroke(*srcStroke);
Shinya Kitaoka 120a6e
      int strokeId        = srcStroke->m_s->getId();
Shinya Kitaoka 120a6e
      if (getStrokeById(strokeId) == 0) tarStroke->m_s->setId(strokeId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      index++;
Shinya Kitaoka 120a6e
      if (m_imp->m_insideGroup == TGroupId())
Shinya Kitaoka 120a6e
        m_imp->m_strokes.push_back(tarStroke);
Shinya Kitaoka 120a6e
      else  // if we are inside a group, the images must become part of that
Shinya Kitaoka 120a6e
            // group
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        tarStroke->m_groupId =
Shinya Kitaoka 120a6e
            TGroupId(m_imp->m_insideGroup, tarStroke->m_groupId);
Shinya Kitaoka 120a6e
        m_imp->insertStrokeAt(tarStroke, index);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      changedStrokeArray.push_back(index);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  notifyChangedStrokes(changedStrokeArray, std::vector<tstroke *="">(), false);</tstroke>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::recomputeRegionsIfNeeded() {
Shinya Kitaoka 120a6e
  if (!m_imp->m_justLoaded) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->m_justLoaded = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<int> v(m_imp->m_strokes.size());</int>
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < (int)m_imp->m_strokes.size(); i++) v[i] = i;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->notifyChangedStrokes(v, std::vector<tstroke *="">(), false);</tstroke>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::eraseStyleIds(const std::vector<int> styleIds) {</int>
Shinya Kitaoka 120a6e
  int j;
Shinya Kitaoka 120a6e
  for (j = 0; j < (int)styleIds.size(); j++) {
Shinya Kitaoka 120a6e
    int styleId = styleIds[j];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int strokeCount = getStrokeCount();
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = strokeCount - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
      TStroke *stroke = getStroke(i);
Shinya Kitaoka 120a6e
      if (stroke && stroke->getStyle() == styleId) removeStroke(i);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    int regionCount = getRegionCount();
Shinya Kitaoka 120a6e
    for (i = 0; i < regionCount; i++) {
Shinya Kitaoka 120a6e
      TRegion *region = getRegion(i);
Shinya Kitaoka 120a6e
      if (!region || region->getStyle() != styleId) continue;
Shinya Kitaoka 120a6e
      TPointD p;
Shinya Kitaoka 120a6e
      if (region->getInternalPoint(p)) fill(p, 0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::insertImage(const TVectorImageP &img,
Shinya Kitaoka 120a6e
                               const std::vector<int> &dstIndices) {</int>
Shinya Kitaoka 120a6e
  UINT i;
Shinya Kitaoka 120a6e
  UINT imageSize = img->getStrokeCount();
Shinya Kitaoka 120a6e
  assert(dstIndices.size() == imageSize);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // img->m_imp->reindexGroups(*m_imp);
Shinya Kitaoka 120a6e
  std::vector<int> changedStrokeArray(imageSize);</int>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<vistroke *="">::iterator it = m_imp->m_strokes.begin();</vistroke>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = 0; i < imageSize; i++) {
Shinya Kitaoka 120a6e
    assert(i == 0 || dstIndices[i] > dstIndices[i - 1]);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    VIStroke *srcStroke = img->m_imp->m_strokes[i];
Shinya Kitaoka 120a6e
    VIStroke *tarStroke = new VIStroke(*srcStroke);
Shinya Kitaoka 120a6e
    int strokeId        = srcStroke->m_s->getId();
Shinya Kitaoka 120a6e
    if (getStrokeById(strokeId) == 0) tarStroke->m_s->setId(strokeId);
Shinya Kitaoka 120a6e
    advance(it, (i == 0) ? dstIndices[i] : dstIndices[i] - dstIndices[i - 1]);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    it = m_imp->m_strokes.insert(it, tarStroke);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    changedStrokeArray[i] = dstIndices[i];
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_imp->reindexEdges(changedStrokeArray, true);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  notifyChangedStrokes(changedStrokeArray, std::vector<tstroke *="">(), false);</tstroke>
Shinya Kitaoka 120a6e
  // m_imp->computeRegions();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::enableRegionComputing(bool enabled,
Shinya Kitaoka 120a6e
                                         bool notIntersectingStrokes) {
Shinya Kitaoka 120a6e
  m_imp->m_computeRegions         = enabled;
Shinya Kitaoka 120a6e
  m_imp->m_notIntersectingStrokes = notIntersectingStrokes;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::enableMinimizeEdges(bool enabled) {
Shinya Kitaoka 120a6e
  m_imp->m_minimizeEdges = enabled;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TVectorImageP TVectorImage::splitImage(const std::vector<int> &indices,</int>
Shinya Kitaoka 120a6e
                                       bool removeFlag) {
Shinya Kitaoka 120a6e
  TVectorImageP out             = new TVectorImage;
Shinya Kitaoka 120a6e
  out->m_imp->m_maxGroupId      = m_imp->m_maxGroupId;
Shinya Kitaoka 120a6e
  out->m_imp->m_maxGhostGroupId = m_imp->m_maxGhostGroupId;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<int> toBeRemoved;</int>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TPalette *vp = getPalette();
Shinya Kitaoka 120a6e
  if (vp) out->setPalette(vp->clone());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < indices.size(); ++i) {
Shinya Kitaoka 120a6e
    VIStroke *ref = m_imp->m_strokes[indices[i]];
Shinya Kitaoka 120a6e
    assert(ref);
Shinya Kitaoka 120a6e
    VIStroke *vs       = new VIStroke(*ref);
Shinya Kitaoka 120a6e
    vs->m_isNewForFill = true;
Shinya Kitaoka 120a6e
    out->m_imp->m_strokes.push_back(vs);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (removeFlag) removeStrokes(indices, true, true);
Shinya Kitaoka 120a6e
  out->m_imp->m_areValidRegions    = false;
Shinya Kitaoka 120a6e
  out->m_imp->m_computedAlmostOnce = m_imp->m_computedAlmostOnce;
Shinya Kitaoka 120a6e
  return out;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TVectorImageP TVectorImage::splitSelected(bool removeFlag) {
Shinya Kitaoka 120a6e
  TVectorImageP out = new TVectorImage;
Shinya Kitaoka 120a6e
  std::vector<int> toBeRemoved;</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < getStrokeCount(); ++i) {
Shinya Kitaoka 120a6e
    VIStroke *ref = m_imp->m_strokes[i];
Shinya Kitaoka 120a6e
    assert(ref);
Shinya Kitaoka 120a6e
    if (ref->m_s->getFlag(TStroke::c_selected_flag)) {
Shinya Kitaoka 120a6e
      VIStroke *stroke = new VIStroke(*ref);
Shinya Kitaoka 120a6e
      out->m_imp->m_strokes.push_back(stroke);
Shinya Kitaoka 120a6e
      if (removeFlag) {
Shinya Kitaoka 120a6e
        toBeRemoved.push_back(i);
Shinya Kitaoka 120a6e
        //  	  removeStroke(i);
Shinya Kitaoka 120a6e
        //			delete ref;
Shinya Kitaoka 120a6e
        //  	  i--;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  removeStrokes(toBeRemoved, true, true);
Shinya Kitaoka 120a6e
  out->m_imp->m_areValidRegions = false;
Shinya Kitaoka 120a6e
  return out;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TVectorImage::validateRegions(bool state) {
Shinya Kitaoka 120a6e
  m_imp->m_areValidRegions = state;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
void TVectorImage::invalidateBBox()
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  for(UINT i=0; i
Toshihiro Shimizu 890ddd
    getRegion(i)->invalidateBBox();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::setFillData(std::unique_ptr<intersectionbranch[]> const &v,</intersectionbranch[]>
Shinya Kitaoka 120a6e
                               UINT branchCount, bool doComputeRegions) {
Shinya Kitaoka 120a6e
  m_imp->setFillData(v, branchCount, doComputeRegions);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UINT TVectorImage::getFillData(std::unique_ptr<intersectionbranch[]> &v) {</intersectionbranch[]>
Shinya Kitaoka 120a6e
  return m_imp->getFillData(v);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::enableStrokeStyle(int index, bool enable) {
Shinya Kitaoka 120a6e
  DisabledStrokeStyles &disabledSet = getDisabledStrokeStyleSet();
Shinya Kitaoka 120a6e
  if (enable)
Shinya Kitaoka 120a6e
    disabledSet.erase(index);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    disabledSet.insert(index);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TVectorImage::isStrokeStyleEnabled(int index) {
Shinya Kitaoka 120a6e
  return isStrokeStyleEnabled__(index);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::getUsedStyles(std::set<int> &styles) const {</int>
Shinya Kitaoka 120a6e
  UINT strokeCount = getStrokeCount();
Shinya Kitaoka 120a6e
  UINT i           = 0;
Shinya Kitaoka 120a6e
  for (; i < strokeCount; ++i) {
Shinya Kitaoka 120a6e
    VIStroke *srcStroke = m_imp->m_strokes[i];
Shinya Kitaoka 120a6e
    int styleId         = srcStroke->m_s->getStyle();
Shinya Kitaoka 120a6e
    if (styleId != 0) styles.insert(styleId);
Shinya Kitaoka 120a6e
    std::list<tedge *="">::const_iterator it = srcStroke->m_edgeList.begin();</tedge>
Shinya Kitaoka 120a6e
    for (; it != srcStroke->m_edgeList.end(); ++it) {
Shinya Kitaoka 120a6e
      styleId = (*it)->m_styleId;
Shinya Kitaoka 120a6e
      if (styleId != 0) styles.insert(styleId);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline double recomputeW1(double oldW, const TStroke &oldStroke,
Shinya Kitaoka 120a6e
                          const TStroke &newStroke, double startW) {
MCCCS a0ce32
  double oldLength = oldStroke.getLength();
MCCCS a0ce32
  double newLength = newStroke.getLength();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(startW <= oldW);
MCCCS a0ce32
  assert(newLength < oldLength);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double s = oldStroke.getLength(startW, oldW);
MCCCS a0ce32
  assert(s <= newLength || areAlmostEqual(s, newLength, 1e-5));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return newStroke.getParameterAtLength(s);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
inline double recomputeW2(double oldW, const TStroke &oldStroke,
Shinya Kitaoka 120a6e
                          const TStroke &newStroke, double length) {
Shinya Kitaoka 120a6e
  double s = oldStroke.getLength(oldW);
Shinya Kitaoka 120a6e
  return newStroke.getParameterAtLength(length + s);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline double recomputeW(double oldW, const TStroke &oldStroke,
Shinya Kitaoka 120a6e
                         const TStroke &newStroke, bool isAtBegin) {
MCCCS a0ce32
  double oldLength = oldStroke.getLength();
MCCCS a0ce32
  double newLength = newStroke.getLength();
Toshihiro Shimizu 890ddd
MCCCS a0ce32
  assert(newLength < oldLength);
Shinya Kitaoka 120a6e
  double s =
MCCCS a0ce32
      oldStroke.getLength(oldW) - ((isAtBegin) ? 0 : oldLength - newLength);
MCCCS a0ce32
  assert(s <= newLength || areAlmostEqual(s, newLength, 1e-5));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return newStroke.getParameterAtLength(s);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
void TVectorImage::checkIntersections() { m_imp->checkIntersections(); }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
void TVectorImage::reassignStyles()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  set<int> styles;</int>
Toshihiro Shimizu 890ddd
  UINT  strokeCount = getStrokeCount();
Toshihiro Shimizu 890ddd
  UINT i=0;
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  for( ; i< strokeCount; ++i)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
     int styleId = getStroke(i)->getStyle();
Toshihiro Shimizu 890ddd
     if(styleId != 0) styles.insert(styleId);
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
  UINT regionCount = getRegionCount();
Toshihiro Shimizu 890ddd
  for( i = 0; i< regionCount; ++i)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
     int styleId = getRegion(i)->getStyle();
Toshihiro Shimizu 890ddd
     if(styleId != 0) styles.insert(styleId);
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  map<int, int=""> conversionTable;</int,>
Toshihiro Shimizu 890ddd
  for(set<int>::iterator it = styles.begin(); it != styles.end(); ++it)</int>
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
     int styleId = *it;
Toshihiro Shimizu 890ddd
     conversionTable[styleId] = styleId + 13;
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  for( i = 0; i< strokeCount; ++i)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
     TStroke *stroke = getStroke(i);
Toshihiro Shimizu 890ddd
     int styleId = stroke->getStyle();
Toshihiro Shimizu 890ddd
     if(styleId != 0)
Toshihiro Shimizu 890ddd
       {
Toshihiro Shimizu 890ddd
        map<int, int="">::iterator it = conversionTable.find(styleId);</int,>
Shinya Kitaoka 120a6e
        if(it != conversionTable.end())
Toshihiro Shimizu 890ddd
          stroke->setStyle(it->second);
Toshihiro Shimizu 890ddd
       }
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  for( i = 0; i< regionCount; ++i)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
     TRegion *region = getRegion(i);
Toshihiro Shimizu 890ddd
     int styleId = region->getStyle();
Toshihiro Shimizu 890ddd
     if(styleId != 0)
Toshihiro Shimizu 890ddd
       {
Toshihiro Shimizu 890ddd
        map<int, int="">::iterator it = conversionTable.find(styleId);</int,>
Shinya Kitaoka 120a6e
        if(it != conversionTable.end())
Toshihiro Shimizu 890ddd
          region->setStyle(it->second);
Toshihiro Shimizu 890ddd
       }
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TVectorImage::isComputedRegionAlmostOnce() const {
Shinya Kitaoka 120a6e
  return m_imp->m_computedAlmostOnce;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::splitStroke(int strokeIndex,
Shinya Kitaoka 120a6e
                               const std::vector<doublepair> &sortedWRanges) {</doublepair>
Shinya Kitaoka 120a6e
  m_imp->splitStroke(strokeIndex, sortedWRanges);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::Imp::splitStroke(
Shinya Kitaoka 120a6e
    int strokeIndex, const std::vector<doublepair> &sortedWRanges) {</doublepair>
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  VIStroke *subV = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (strokeIndex >= (int)m_strokes.size() || sortedWRanges.empty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  VIStroke *vs     = m_strokes[strokeIndex];
Shinya Kitaoka 120a6e
  TGroupId groupId = vs->m_groupId;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // se e' un self loop, alla fine non lo sara', e deve stare insieme
Shinya Kitaoka 120a6e
  // alle stroke non loopate. sposto lo stroke se serve
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
if (vs->m_s->isSelfLoop())
Shinya Kitaoka 120a6e
int up = strokeIndex+1;
Shinya Kitaoka 120a6e
while (up<(int)m_strokes.size() && m_strokes[up]->m_s->isSelfLoop())
Shinya Kitaoka 120a6e
up++;
Shinya Kitaoka 120a6e
int dn = strokeIndex-1;
Shinya Kitaoka 120a6e
while (dn>=0 && m_strokes[dn]->m_s->isSelfLoop())
Shinya Kitaoka 120a6e
dn--;
Shinya Kitaoka 120a6e
if ((up == m_strokes.size() || up!=strokeIndex+1) && (dn<0 ||
Shinya Kitaoka 120a6e
dn!=strokeIndex-1))
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
if (up>=(int)m_strokes.size())
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
assert(dn>=0);
Shinya Kitaoka 120a6e
moveStroke(strokeIndex, dn+1);
Shinya Kitaoka 120a6e
strokeIndex = dn+1;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
else
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
moveStroke(strokeIndex, up-1);
Shinya Kitaoka 120a6e
strokeIndex = up-1;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  assert(vs == m_strokes[strokeIndex]);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool toBeJoined =
Shinya Kitaoka 120a6e
      (vs->m_s->isSelfLoop() && sortedWRanges.front().first == 0.0 &&
Shinya Kitaoka 120a6e
       sortedWRanges.back().second == 1.0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int styleId = vs->m_s->getStyle();
Shinya Kitaoka 120a6e
  TStroke::OutlineOptions oOptions(vs->m_s->outlineOptions());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_regions.clear();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::list<tedge *=""> origEdgeList;  // metto al pizzo la edge std::list della</tedge>
Shinya Kitaoka 120a6e
                                    // stroke, perche' la erase intersection ne
Shinya Kitaoka 120a6e
                                    // fara' scempio
Shinya Kitaoka 120a6e
  std::list<tedge *="">::iterator it   = vs->m_edgeList.begin(),</tedge>
Shinya Kitaoka 120a6e
                               it_e = vs->m_edgeList.end();
Shinya Kitaoka 120a6e
  for (; it != it_e; ++it) origEdgeList.push_back(new TEdge(**it, false));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  removeStroke(strokeIndex, false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<std::list<tedge *="">> edgeList(sortedWRanges.size());</std::list<tedge>
Shinya Kitaoka 120a6e
  strokeIndex--;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int wSize = (int)sortedWRanges.size();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = 0; i < wSize; i++) {
Shinya Kitaoka 120a6e
    assert(sortedWRanges[i].first < sortedWRanges[i].second);
Shinya Kitaoka 120a6e
    assert(i == wSize - 1 ||
Shinya Kitaoka 120a6e
           sortedWRanges[i].second <= sortedWRanges[i + 1].first);
Shinya Kitaoka 120a6e
    assert(sortedWRanges[i].first >= 0 && sortedWRanges[i].first <= 1);
Shinya Kitaoka 120a6e
    assert(sortedWRanges[i].second >= 0 && sortedWRanges[i].second <= 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    subV = new VIStroke(new TStroke(), groupId);
Shinya Kitaoka 120a6e
    TStroke s, dummy;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (areAlmostEqual(sortedWRanges[i].first, 0, 1e-4))
Shinya Kitaoka 120a6e
      s = *vs->m_s;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      vs->m_s->split(sortedWRanges[i].first, dummy, s);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    double lenAtW0 = vs->m_s->getLength(sortedWRanges[i].first);
Shinya Kitaoka 120a6e
    double lenAtW1 = vs->m_s->getLength(sortedWRanges[i].second);
Shinya Kitaoka 120a6e
    double newW1   = s.getParameterAtLength(lenAtW1 - lenAtW0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (areAlmostEqual(newW1, 1.0, 1e-4))
Shinya Kitaoka 120a6e
      *(subV->m_s) = s;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      s.split(newW1, *(subV->m_s), dummy);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    strokeIndex++;
Shinya Kitaoka 120a6e
    /*assert(m_strokes[strokeIndex]->m_edgeList.empty());
Shinya Kitaoka 120a6e
assert(m_strokes[strokeIndex-wSize+1]->m_edgeList.empty());*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::list<tedge *="">::const_iterator it   = origEdgeList.begin(),</tedge>
Shinya Kitaoka 120a6e
                                       it_e = origEdgeList.end();
Shinya Kitaoka 120a6e
    for (; it != it_e; ++it) {
Shinya Kitaoka 120a6e
      double wMin = std::min((*it)->m_w0, (*it)->m_w1);
Shinya Kitaoka 120a6e
      double wMax = std::max((*it)->m_w0, (*it)->m_w1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (wMin >= sortedWRanges[i].second || wMax <= sortedWRanges[i].first)
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      TEdge *e = new TEdge(**it, false);
Shinya Kitaoka 120a6e
      if (wMin < sortedWRanges[i].first)
Shinya Kitaoka 120a6e
        wMin = 0.0;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        wMin =
Shinya Kitaoka 120a6e
            recomputeW1(wMin, *(vs->m_s), *(subV->m_s), sortedWRanges[i].first);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (wMax > sortedWRanges[i].second)
Shinya Kitaoka 120a6e
        wMax = 1.0;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        wMax =
Shinya Kitaoka 120a6e
            recomputeW1(wMax, *(vs->m_s), *(subV->m_s), sortedWRanges[i].first);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (e->m_w0 < e->m_w1)
Shinya Kitaoka 120a6e
        e->m_w0 = wMin, e->m_w1 = wMax;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        e->m_w1 = wMin, e->m_w0 = wMax;
Shinya Kitaoka 120a6e
      e->m_r     = 0;
Shinya Kitaoka 120a6e
      e->m_s     = subV->m_s;
Shinya Kitaoka 120a6e
      e->m_index = strokeIndex;
Shinya Kitaoka 120a6e
      edgeList[i].push_back(e);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    subV->m_edgeList.clear();
Shinya Kitaoka 120a6e
    insertStrokeAt(subV, strokeIndex);
Shinya Kitaoka 120a6e
    subV->m_s->setStyle(styleId);
Shinya Kitaoka 120a6e
    subV->m_s->outlineOptions() = oOptions;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  clearPointerContainer(origEdgeList);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (toBeJoined)  // la stroke e' un loop, quindi i due choncketti iniziali e
Shinya Kitaoka 120a6e
                   // finali vanno joinati
Toshihiro Shimizu 890ddd
  {
Shinya Kitaoka 120a6e
    VIStroke *s0           = m_strokes[strokeIndex];
Shinya Kitaoka 120a6e
    VIStroke *s1           = m_strokes[strokeIndex - wSize + 1];
Shinya Kitaoka 120a6e
    std::list<tedge *=""> &l0 = edgeList.back();</tedge>
Shinya Kitaoka 120a6e
    std::list<tedge *=""> &l1 = edgeList.front();</tedge>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // assert(s0->m_edgeList.empty());
Shinya Kitaoka 120a6e
    // assert(s1->m_edgeList.empty());
Shinya Kitaoka 120a6e
    removeStroke(strokeIndex - wSize + 1, false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    strokeIndex--;
Shinya Kitaoka 120a6e
    removeStroke(strokeIndex, false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    VIStroke *s = new VIStroke(joinStrokes(s0->m_s, s1->m_s), groupId);
Shinya Kitaoka 120a6e
    insertStrokeAt(s, strokeIndex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::list<tedge *="">::iterator it = l0.begin(), it_e = l0.end();</tedge>
Shinya Kitaoka 120a6e
    for (; it != it_e; ++it) {
Shinya Kitaoka 120a6e
      (*it)->m_s     = s->m_s;
Shinya Kitaoka 120a6e
      (*it)->m_index = strokeIndex;
Shinya Kitaoka 120a6e
      (*it)->m_w0    = recomputeW2((*it)->m_w0, *(s0->m_s), *(s->m_s), 0);
Shinya Kitaoka 120a6e
      (*it)->m_w1    = recomputeW2((*it)->m_w1, *(s0->m_s), *(s->m_s), 0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    it            = l1.begin();
Shinya Kitaoka 120a6e
    double length = s0->m_s->getLength();
Shinya Kitaoka 120a6e
    while (it != l1.end()) {
Shinya Kitaoka 120a6e
      (*it)->m_s     = s->m_s;
Shinya Kitaoka 120a6e
      (*it)->m_index = strokeIndex;
Shinya Kitaoka 120a6e
      (*it)->m_w0    = recomputeW2((*it)->m_w0, *(s1->m_s), *(s->m_s), length);
Shinya Kitaoka 120a6e
      (*it)->m_w1    = recomputeW2((*it)->m_w1, *(s1->m_s), *(s->m_s), length);
Shinya Kitaoka 120a6e
      l0.push_back(*it);
Shinya Kitaoka 120a6e
      it = l1.erase(it);
Toshihiro Shimizu 890ddd
    }
Shinya Kitaoka 120a6e
    assert(l1.empty());
Shinya Kitaoka 120a6e
    edgeList.erase(edgeList.begin());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::vector<doublepair> appSortedWRanges;</doublepair>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    wSize--;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    delete s0;
Shinya Kitaoka 120a6e
    delete s1;
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // checkIntersections();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // double len  = e->m_s->getLength();
Shinya Kitaoka 120a6e
  // if (recomputeRegions)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_computedAlmostOnce) {
Shinya Kitaoka 120a6e
    computeRegions();
Shinya Kitaoka 120a6e
    assert((int)edgeList.size() == wSize);
Shinya Kitaoka 120a6e
    assert((int)m_strokes.size() > strokeIndex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    for (i = 0; i < wSize; i++)
Shinya Kitaoka 120a6e
      transferColors(edgeList[i],
Shinya Kitaoka 120a6e
                     m_strokes[strokeIndex - wSize + i + 1]->m_edgeList, false,
Shinya Kitaoka 120a6e
                     false, false);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = 0; i < wSize; i++) clearPointerContainer(edgeList[i]);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  delete vs;
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Campbell Barton 8c6c57
static void computeEdgeList(TStroke *newS, const std::list<tedge *=""> &edgeList1,</tedge>
shun-iwasawa 27b0cf
                            bool join1AtBegin,
shun-iwasawa 27b0cf
                            const std::list<tedge *=""> &edgeList2,</tedge>
Campbell Barton 8c6c57
                            bool join2AtBegin, std::list<tedge *=""> &edgeList) {</tedge>
Shinya Kitaoka 120a6e
  std::list<tedge *="">::const_iterator it;</tedge>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!edgeList1.empty()) {
Shinya Kitaoka 120a6e
    TStroke *s1    = edgeList1.front()->m_s;
MCCCS a0ce32
    double length1 = s1->getLength();
Shinya Kitaoka 120a6e
    ;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    for (it = edgeList1.begin(); it != edgeList1.end(); ++it) {
Shinya Kitaoka 120a6e
      double l0 = s1->getLength((*it)->m_w0), l1 = s1->getLength((*it)->m_w1);
MCCCS a0ce32
      if (join1AtBegin) l0 = length1 - l0, l1 = length1 - l1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      TEdge *e         = new TEdge();
Shinya Kitaoka 120a6e
      e->m_toBeDeleted = true;
Shinya Kitaoka 120a6e
      e->m_index       = -1;
Shinya Kitaoka 120a6e
      e->m_s           = newS;
Shinya Kitaoka 120a6e
      e->m_styleId     = (*it)->m_styleId;
Shinya Kitaoka 120a6e
      e->m_w0          = newS->getParameterAtLength(l0);
Shinya Kitaoka 120a6e
      e->m_w1          = newS->getParameterAtLength(l1);
Shinya Kitaoka 120a6e
      edgeList.push_back(e);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!edgeList2.empty()) {
Shinya Kitaoka 120a6e
    TStroke *s2    = edgeList2.front()->m_s;
Shinya Kitaoka 120a6e
    double offset  = newS->getLength(newS->getW(s2->getPoint(0.0)));
MCCCS a0ce32
    double length2 = s2->getLength();
Shinya Kitaoka 120a6e
    for (it = edgeList2.begin(); it != edgeList2.end(); ++it) {
Shinya Kitaoka 120a6e
      double l0 = s2->getLength((*it)->m_w0), l1 = s2->getLength((*it)->m_w1);
MCCCS a0ce32
      if (!join2AtBegin) l0 = length2 - l0, l1 = length2 - l1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      TEdge *e         = new TEdge();
Shinya Kitaoka 120a6e
      e->m_toBeDeleted = true;
Shinya Kitaoka 120a6e
      e->m_index       = -1;
Shinya Kitaoka 120a6e
      e->m_s           = newS;
Shinya Kitaoka 120a6e
      e->m_styleId     = (*it)->m_styleId;
Shinya Kitaoka 120a6e
      e->m_w0          = newS->getParameterAtLength(offset + l0);
Shinya Kitaoka 120a6e
      e->m_w1          = newS->getParameterAtLength(offset + l1);
Shinya Kitaoka 120a6e
      edgeList.push_back(e);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "tcolorstyles.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void printEdges(std::ofstream &os, char *str, TPalette *plt,
Shinya Kitaoka 120a6e
                const std::list<tedge *=""> &edges) {</tedge>
Shinya Kitaoka 120a6e
  std::list<tedge *="">::const_iterator it;</tedge>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  os << str << std::endl;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (it = edges.begin(); it != edges.end(); ++it) {
Shinya Kitaoka 120a6e
    TColorStyle *style = plt->getStyle((*it)->m_styleId);
Shinya Kitaoka 120a6e
    TPixel32 color     = style->getMainColor();
Shinya Kitaoka 120a6e
    os << "w0-w1:(" << (*it)->m_w0 << "-->" << (*it)->m_w1 << ")" << std::endl;
Shinya Kitaoka 120a6e
    os << "color=(" << color.r << "," << color.g << "," << color.b << ")"
Shinya Kitaoka 120a6e
       << std::endl;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  os << std::endl << std::endl << std::endl;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define printEdges
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
void TVectorImage::Imp::printStrokes(std::ofstream &os) {
Shinya Kitaoka 120a6e
  for (int i = 0; i < (int)m_strokes.size(); i++) {
Shinya Kitaoka 120a6e
    os << "*****stroke #" << i << " *****";
Shinya Kitaoka 120a6e
    m_strokes[i]->m_s->print(os);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStroke *TVectorImage::removeEndpoints(int strokeIndex) {
Shinya Kitaoka 120a6e
  return m_imp->removeEndpoints(strokeIndex);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::restoreEndpoints(int index, TStroke *oldStroke) {
Shinya Kitaoka 120a6e
  m_imp->restoreEndpoints(index, oldStroke);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
VIStroke *TVectorImage::Imp::extendStrokeSmoothly(int index,
Shinya Kitaoka 120a6e
                                                  const TThickPoint &pos,
Shinya Kitaoka 120a6e
                                                  int cpIndex) {
Shinya Kitaoka 120a6e
  TStroke *stroke  = m_strokes[index]->m_s;
Shinya Kitaoka 120a6e
  TGroupId groupId = m_strokes[index]->m_groupId;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int cpCount = stroke->getControlPointCount();
Shinya Kitaoka 120a6e
  int styleId = stroke->getStyle();
Shinya Kitaoka 120a6e
  const TThickQuadratic *q =
Shinya Kitaoka 120a6e
      stroke->getChunk(cpIndex == 0 ? 0 : stroke->getChunkCount() - 1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double len    = q->getLength();
Shinya Kitaoka 120a6e
  double w      = exp(-len * 0.01);
Shinya Kitaoka 120a6e
  TThickPoint m = q->getThickP1();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TThickPoint p1 =
Shinya Kitaoka 120a6e
      (cpIndex == 0 ? q->getThickP0() : q->getThickP2()) * (1 - w) + m * w;
Shinya Kitaoka 120a6e
  TThickPoint middleP = (p1 + pos) * 0.5;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double angle = fabs(cross(normalize(m - middleP), normalize(pos - middleP)));
Shinya Kitaoka 120a6e
  if (angle < 0.05) middleP = (m + pos) * 0.5;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  stroke->setControlPoint(cpIndex, middleP);
Shinya Kitaoka 120a6e
  if (isAlmostZero(len)) {
Shinya Kitaoka 120a6e
    if (cpIndex == 0)
Shinya Kitaoka 120a6e
      stroke->setControlPoint(1,
Shinya Kitaoka 120a6e
                              middleP * 0.1 + stroke->getControlPoint(2) * 0.9);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      stroke->setControlPoint(
Shinya Kitaoka 120a6e
          cpCount - 2,
Shinya Kitaoka 120a6e
          middleP * 0.1 + stroke->getControlPoint(cpCount - 3) * 0.9);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<tthickpoint> points(cpCount);</tthickpoint>
shun-iwasawa 9bcc69
  for (int i = 0; i < cpCount - 1; i++)
Shinya Kitaoka 120a6e
    points[i] = stroke->getControlPoint((cpIndex == 0) ? cpCount - i - 1 : i);
Shinya Kitaoka 120a6e
  points[cpCount - 1] = pos;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TStroke *newStroke = new TStroke(points);
Shinya Kitaoka 120a6e
  newStroke->setStyle(styleId);
Shinya Kitaoka 120a6e
  newStroke->outlineOptions() = stroke->outlineOptions();
Shinya Kitaoka 120a6e
  std::list<tedge *=""> oldEdgeList, emptyList;</tedge>
Shinya Kitaoka 120a6e
  computeEdgeList(newStroke, m_strokes[index]->m_edgeList, cpIndex == 0,
Shinya Kitaoka 120a6e
                  emptyList, 0, oldEdgeList);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<int> toBeDeleted;</int>
Shinya Kitaoka 120a6e
  toBeDeleted.push_back(index);
Shinya Kitaoka 120a6e
  removeStrokes(toBeDeleted, true, false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  insertStrokeAt(new VIStroke(newStroke, groupId), index, false);
Shinya Kitaoka 120a6e
  computeRegions();
Shinya Kitaoka 120a6e
  transferColors(oldEdgeList, m_strokes[index]->m_edgeList, true, false, true);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return m_strokes[index];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
VIStroke *TVectorImage::Imp::extendStroke(int index, const TThickPoint &p,
Shinya Kitaoka 120a6e
                                          int cpIndex) {
Shinya Kitaoka 120a6e
  TGroupId groupId = m_strokes[index]->m_groupId;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TStroke *stroke = m_strokes[index]->m_s;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TStroke *ret;
Shinya Kitaoka 120a6e
  int cpCount = stroke->getControlPointCount();
Shinya Kitaoka 120a6e
  int count   = 0;
Shinya Kitaoka 120a6e
  std::vector<tthickpoint> points(cpCount + 2);</tthickpoint>
Shinya Kitaoka 120a6e
  int i, incr = (cpIndex == 0) ? -1 : 1;
Shinya Kitaoka 120a6e
  for (i = ((cpIndex == 0) ? cpCount - 1 : 0); i != cpIndex + incr; i += incr)
Shinya Kitaoka 120a6e
    points[count++] = stroke->getControlPoint(i);
Shinya Kitaoka 120a6e
  TThickPoint tp(p, points[count - 1].thick);
Shinya Kitaoka 120a6e
  points[count++] = 0.5 * (stroke->getControlPoint(cpIndex) + tp);
Shinya Kitaoka 120a6e
  points[count++] = tp;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TStroke *newStroke = new TStroke(points);
Shinya Kitaoka 120a6e
  newStroke->setStyle(stroke->getStyle());
Shinya Kitaoka 120a6e
  newStroke->outlineOptions() = stroke->outlineOptions();
Shinya Kitaoka 120a6e
  ret                         = newStroke;
Shinya Kitaoka 120a6e
  std::list<tedge *=""> oldEdgeList, emptyList;</tedge>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_computedAlmostOnce)
Shinya Kitaoka 120a6e
    computeEdgeList(newStroke, m_strokes[index]->m_edgeList, cpIndex == 0,
Shinya Kitaoka 120a6e
                    emptyList, false, oldEdgeList);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<int> toBeDeleted;</int>
Shinya Kitaoka 120a6e
  toBeDeleted.push_back(index);
Shinya Kitaoka 120a6e
  removeStrokes(toBeDeleted, true, false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // removeStroke(index, false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  insertStrokeAt(new VIStroke(newStroke, groupId), index, false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_computedAlmostOnce) {
Shinya Kitaoka 120a6e
    computeRegions();
Shinya Kitaoka 120a6e
    transferColors(oldEdgeList, m_strokes[index]->m_edgeList, true, false,
Shinya Kitaoka 120a6e
                   true);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return m_strokes[index];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
VIStroke *TVectorImage::Imp::joinStroke(int index1, int index2, int cpIndex1,
Shinya Kitaoka 120a6e
                                        int cpIndex2) {
Shinya Kitaoka 120a6e
  assert(m_strokes[index1]->m_groupId == m_strokes[index2]->m_groupId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TGroupId groupId = m_strokes[index1]->m_groupId;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TStroke *stroke1 = m_strokes[index1]->m_s;
Shinya Kitaoka 120a6e
  TStroke *stroke2 = m_strokes[index2]->m_s;
Shinya Kitaoka 120a6e
  // TStroke* ret;
Shinya Kitaoka 120a6e
  int cpCount1 = stroke1->getControlPointCount();
Shinya Kitaoka 120a6e
  int cpCount2 = stroke2->getControlPointCount();
Shinya Kitaoka 120a6e
  int styleId  = stroke1->getStyle();
Shinya Kitaoka 120a6e
luz paz 6454c4
  // check if the both ends are at the same position
shun-iwasawa 9bcc69
  bool isSamePos = isAlmostZero(tdistance2(stroke1->getControlPoint(cpIndex1),
shun-iwasawa 9bcc69
                                           stroke2->getControlPoint(cpIndex2)));
luz paz 6454c4
  // connecting the ends in the same shape at the same position
shun-iwasawa 9bcc69
  // means just making the shape self-looped
shun-iwasawa 9bcc69
  if (isSamePos && index1 == index2) {
shun-iwasawa 9bcc69
    stroke1->setSelfLoop();
shun-iwasawa 9bcc69
    return m_strokes[index1];
shun-iwasawa 9bcc69
  }
shun-iwasawa 9bcc69
shun-iwasawa 9bcc69
  std::vector<tthickpoint> points;</tthickpoint>
Shinya Kitaoka 120a6e
  int i, incr = (cpIndex1 == 0) ? -1 : 1;
shun-iwasawa 9bcc69
  int start = ((cpIndex1 == 0) ? cpCount1 - 1 : 0);
shun-iwasawa 9bcc69
  int end   = (isSamePos) ? cpIndex1 : cpIndex1 + incr;
shun-iwasawa 9bcc69
  for (i = start; i != end; i += incr)
shun-iwasawa 9bcc69
    points.push_back(stroke1->getControlPoint(i));
shun-iwasawa 9bcc69
  points.push_back(0.5 * (stroke1->getControlPoint(cpIndex1) +
shun-iwasawa 9bcc69
                          stroke2->getControlPoint(cpIndex2)));
Shinya Kitaoka 120a6e
  if (index1 != index2) {
shun-iwasawa 9bcc69
    incr  = (cpIndex2 == 0) ? 1 : -1;
shun-iwasawa 9bcc69
    start = (isSamePos) ? cpIndex2 + incr : cpIndex2;
shun-iwasawa 9bcc69
    end   = ((cpIndex2 == 0) ? cpCount2 - 1 : 0) + incr;
shun-iwasawa 9bcc69
    for (i = start; i != end; i += incr)
shun-iwasawa 9bcc69
      points.push_back(stroke2->getControlPoint(i));
Shinya Kitaoka 120a6e
  } else
shun-iwasawa 9bcc69
    points.push_back(stroke2->getControlPoint(cpIndex2));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TStroke *newStroke = new TStroke(points);
Shinya Kitaoka 120a6e
  newStroke->setStyle(styleId);
Shinya Kitaoka 120a6e
  newStroke->outlineOptions() = stroke1->outlineOptions();
Shinya Kitaoka 120a6e
  // ret = newStroke;
Shinya Kitaoka 120a6e
  if (index1 == index2) newStroke->setSelfLoop();
Shinya Kitaoka 120a6e
  std::list<tedge *=""> oldEdgeList, emptyList;</tedge>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  computeEdgeList(
Shinya Kitaoka 120a6e
      newStroke, m_strokes[index1]->m_edgeList, cpIndex1 == 0,
Shinya Kitaoka 120a6e
      (index1 != index2) ? m_strokes[index2]->m_edgeList : emptyList,
Shinya Kitaoka 120a6e
      cpIndex2 == 0, oldEdgeList);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<int> toBeDeleted;</int>
Shinya Kitaoka 120a6e
  toBeDeleted.push_back(index1);
Shinya Kitaoka 120a6e
  if (index1 != index2) toBeDeleted.push_back(index2);
Shinya Kitaoka 120a6e
  removeStrokes(toBeDeleted, true, false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  insertStrokeAt(new VIStroke(newStroke, groupId), index1, false);
Shinya Kitaoka 120a6e
  computeRegions();
Shinya Kitaoka 120a6e
  transferColors(oldEdgeList, m_strokes[index1]->m_edgeList, true, false, true);
Shinya Kitaoka 120a6e
  return m_strokes[index1];
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
VIStroke *TVectorImage::Imp::joinStrokeSmoothly(int index1, int index2,
Shinya Kitaoka 120a6e
                                                int cpIndex1, int cpIndex2) {
Shinya Kitaoka 120a6e
  assert(m_strokes[index1]->m_groupId == m_strokes[index2]->m_groupId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TGroupId groupId = m_strokes[index1]->m_groupId;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TStroke *stroke1 = m_strokes[index1]->m_s;
Shinya Kitaoka 120a6e
  TStroke *stroke2 = m_strokes[index2]->m_s;
Shinya Kitaoka 120a6e
  TStroke *ret;
Shinya Kitaoka 120a6e
  int cpCount1 = stroke1->getControlPointCount();
Shinya Kitaoka 120a6e
  int cpCount2 = stroke2->getControlPointCount();
Shinya Kitaoka 120a6e
  int styleId  = stroke1->getStyle();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int qCount1 = stroke1->getChunkCount();
Shinya Kitaoka 120a6e
  int qCount2 = stroke2->getChunkCount();
Shinya Kitaoka 120a6e
  const TThickQuadratic *q1 =
Shinya Kitaoka 120a6e
      stroke1->getChunk(cpIndex1 == 0 ? 0 : qCount1 - 1);
Shinya Kitaoka 120a6e
  const TThickQuadratic *q2 =
Shinya Kitaoka 120a6e
      stroke2->getChunk(cpIndex2 == 0 ? 0 : qCount2 - 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double len1 = q1->getLength();
Shinya Kitaoka 120a6e
  assert(len1 >= 0);
Shinya Kitaoka 120a6e
  if (len1 <= 0) len1 = 0;
shun-iwasawa 9bcc69
  double w1 = exp(-len1 * 0.01);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double len2 = q2->getLength();
Shinya Kitaoka 120a6e
  assert(len2 >= 0);
Shinya Kitaoka 120a6e
  if (len2 <= 0) len2 = 0;
shun-iwasawa 9bcc69
  double w2 = exp(-len2 * 0.01);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TThickPoint extreme1 = cpIndex1 == 0 ? q1->getThickP0() : q1->getThickP2();
Shinya Kitaoka 120a6e
  TThickPoint extreme2 = cpIndex2 == 0 ? q2->getThickP0() : q2->getThickP2();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TThickPoint m1 = q1->getThickP1();
Shinya Kitaoka 120a6e
  TThickPoint m2 = q2->getThickP1();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TThickPoint p1 = extreme1 * (1 - w1) + m1 * w1;
Shinya Kitaoka 120a6e
  TThickPoint p2 = extreme2 * (1 - w2) + m2 * w2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TThickPoint middleP = (p1 + p2) * 0.5;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double angle = fabs(cross(normalize(m1 - middleP), normalize(m2 - middleP)));
Shinya Kitaoka 120a6e
  if (angle < 0.05) middleP = (m1 + m2) * 0.5;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  stroke1->setControlPoint(cpIndex1, middleP);
Shinya Kitaoka 120a6e
  if (isAlmostZero(len1)) {
Shinya Kitaoka 120a6e
    if (cpIndex1 == 0)
Shinya Kitaoka 120a6e
      stroke1->setControlPoint(
Shinya Kitaoka 120a6e
          1, middleP * 0.1 + stroke1->getControlPoint(2) * 0.9);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      stroke1->setControlPoint(
Shinya Kitaoka 120a6e
          cpCount1 - 2,
Shinya Kitaoka 120a6e
          middleP * 0.1 + stroke1->getControlPoint(cpCount1 - 3) * 0.9);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  stroke2->setControlPoint(cpIndex2, middleP);
Shinya Kitaoka 120a6e
  if (isAlmostZero(len2)) {
Shinya Kitaoka 120a6e
    if (cpIndex2 == 0)
Shinya Kitaoka 120a6e
      stroke2->setControlPoint(
Shinya Kitaoka 120a6e
          1, middleP * 0.1 + stroke2->getControlPoint(2) * 0.9);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      stroke2->setControlPoint(
Shinya Kitaoka 120a6e
          cpCount2 - 2,
Shinya Kitaoka 120a6e
          middleP * 0.1 + stroke2->getControlPoint(cpCount2 - 3) * 0.9);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (stroke1 == stroke2) {
Shinya Kitaoka 120a6e
    std::list<tedge *=""> oldEdgeList, emptyList;</tedge>
Shinya Kitaoka 120a6e
    computeEdgeList(stroke1, m_strokes[index1]->m_edgeList, cpIndex1 == 0,
Shinya Kitaoka 120a6e
                    emptyList, false, oldEdgeList);
Shinya Kitaoka 120a6e
    eraseIntersection(index1);
Shinya Kitaoka 120a6e
    m_strokes[index1]->m_isNewForFill = true;
Shinya Kitaoka 120a6e
    stroke1->setSelfLoop();
Shinya Kitaoka 120a6e
    computeRegions();
Shinya Kitaoka 120a6e
    transferColors(oldEdgeList, m_strokes[index1]->m_edgeList, true, false,
Shinya Kitaoka 120a6e
                   true);
Shinya Kitaoka 120a6e
    return m_strokes[index1];
Shinya Kitaoka 120a6e
    // nundo->m_newStroke=new TStroke(*stroke1);
Shinya Kitaoka 120a6e
    // nundo->m_newStrokeId=stroke1->getId();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<tthickpoint> points;</tthickpoint>
Shinya Kitaoka 120a6e
  points.reserve(cpCount1 + cpCount2 - 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int incr = (cpIndex1) ? 1 : -1;
Shinya Kitaoka 120a6e
  int stop = cpIndex1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int i = cpCount1 - 1 - cpIndex1;
Shinya Kitaoka 120a6e
  for (; i != stop; i += incr) points.push_back(stroke1->getControlPoint(i));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  incr = (cpIndex2) ? -1 : 1;
Shinya Kitaoka 120a6e
  stop = cpCount2 - 1 - cpIndex2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = cpIndex2; i != stop; i += incr)
Shinya Kitaoka 120a6e
    points.push_back(stroke2->getControlPoint(i));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  points.push_back(stroke2->getControlPoint(stop));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TStroke *newStroke = new TStroke(points);
Shinya Kitaoka 120a6e
  newStroke->setStyle(styleId);
Shinya Kitaoka 120a6e
  newStroke->outlineOptions() = stroke1->outlineOptions();
Shinya Kitaoka 120a6e
  ret                         = newStroke;
Shinya Kitaoka 120a6e
  // nundo->m_newStroke=new TStroke(*newStroke);
Shinya Kitaoka 120a6e
  // nundo->m_newStrokeId=newStroke->getId();
Shinya Kitaoka 120a6e
  std::list<tedge *=""> oldEdgeList;</tedge>
Shinya Kitaoka 120a6e
  // ofstream os("c:\\temp\\edges.txt");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // printEdges(os, "****edgelist1", getPalette(),
Shinya Kitaoka 120a6e
  // m_imp->m_strokes[index1]->m_edgeList);
Shinya Kitaoka 120a6e
  // printEdges(os, "****edgelist2", getPalette(),
Shinya Kitaoka 120a6e
  // m_imp->m_strokes[index2]->m_edgeList);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  computeEdgeList(newStroke, m_strokes[index1]->m_edgeList, cpIndex1 == 0,
Shinya Kitaoka 120a6e
                  m_strokes[index2]->m_edgeList, cpIndex2 == 0, oldEdgeList);
Shinya Kitaoka 120a6e
  // printEdges(os, "****edgelist", getPalette(), oldEdgeList);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<int> toBeDeleted;</int>
Shinya Kitaoka 120a6e
  toBeDeleted.push_back(index1);
Shinya Kitaoka 120a6e
  toBeDeleted.push_back(index2);
Shinya Kitaoka 120a6e
  removeStrokes(toBeDeleted, true, false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  insertStrokeAt(new VIStroke(newStroke, groupId), index1);
Shinya Kitaoka 120a6e
  computeRegions();
Shinya Kitaoka 120a6e
  transferColors(oldEdgeList, m_strokes[index1]->m_edgeList, true, false, true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return m_strokes[index1];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //  TUndoManager::manager()->add(nundo);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
VIStroke *TVectorImage::joinStroke(int index1, int index2, int cpIndex1,
Shinya Kitaoka 120a6e
                                   int cpIndex2, bool isSmooth) {
Shinya Kitaoka 120a6e
  int finalStyle = -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (index1 > index2) {
Shinya Kitaoka 120a6e
    finalStyle = getStroke(index1)->getStyle();
otakuto ed7dcd
    std::swap(index1, index2);
otakuto ed7dcd
    std::swap(cpIndex1, cpIndex2);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
if (index1==index2) //selfLoop!
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
if (index1>0 && index1<(int)getStrokeCount()-1 &&
Shinya Kitaoka 120a6e
  !getStroke(index1-1)->isSelfLoop() &&
Shinya Kitaoka 120a6e
  !getStroke(index1+1)->isSelfLoop())
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
for (UINT i = index1+2; i<getstrokecount() !getstroke(i)-="" &&="">isSelfLoop(); i++)</getstrokecount()>
Shinya Kitaoka 120a6e
  ;
Shinya Kitaoka 120a6e
moveStroke(index1, i-1);
Shinya Kitaoka 120a6e
index1 = index2 = i-1;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  VIStroke *ret;
Shinya Kitaoka 120a6e
  if (isSmooth)
Shinya Kitaoka 120a6e
    ret = m_imp->joinStrokeSmoothly(index1, index2, cpIndex1, cpIndex2);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    ret = m_imp->joinStroke(index1, index2, cpIndex1, cpIndex2);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (finalStyle != -1) getStroke(index1)->setStyle(finalStyle);
Shinya Kitaoka 120a6e
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
VIStroke *TVectorImage::extendStroke(int index, const TThickPoint &p,
Shinya Kitaoka 120a6e
                                     int cpIndex, bool isSmooth) {
Shinya Kitaoka 120a6e
  if (isSmooth)
Shinya Kitaoka 120a6e
    return m_imp->extendStrokeSmoothly(index, p, cpIndex);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return m_imp->extendStroke(index, p, cpIndex);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TInputStreamInterface &TInputStreamInterface::operator>>(TPixel32 &pixel) {
Shinya Kitaoka 120a6e
  return *this >> pixel.r >> pixel.g >> pixel.b >> pixel.m;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TOutputStreamInterface &TOutputStreamInterface::operator<<(
Shinya Kitaoka 120a6e
    const TPixel32 &pixel) {
Shinya Kitaoka 120a6e
  return *this << pixel.r << pixel.g << pixel.b << pixel.m;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::setAutocloseTolerance(double val) {
Shinya Kitaoka 120a6e
  m_imp->m_autocloseTolerance = val;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TVectorImage::getAutocloseTolerance() const {
Shinya Kitaoka 120a6e
  return m_imp->m_autocloseTolerance;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TThread::Mutex *TVectorImage::getMutex() const { return m_imp->m_mutex; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::areaFill(TStroke *stroke, int index, bool m_onlyUnfilled) {
Shinya Kitaoka 120a6e
  TVectorImage v;
Shinya Kitaoka 120a6e
  v.addStroke(stroke);
Shinya Kitaoka 120a6e
  v.findRegions();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < v.getRegionCount(); i++)
Shinya Kitaoka 120a6e
    for (UINT j = 0; j < getRegionCount(); j++) {
Shinya Kitaoka 120a6e
      if (m_imp->m_insideGroup != TGroupId() &&
Shinya Kitaoka 120a6e
          !m_imp->m_insideGroup.isParentOf(
Shinya Kitaoka 120a6e
              m_imp->m_strokes[getRegion(j)->getEdge(0)->m_index]->m_groupId))
Shinya Kitaoka 120a6e
        continue;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (v.getRegion(i)->contains(*getRegion(j)))
Shinya Kitaoka 120a6e
        getRegion(j)->setStyle(index);
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  v.removeStroke(0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
VIStroke *cloneVIStroke(VIStroke *vs) { return new VIStroke(*vs); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void deleteVIStroke(VIStroke *vs) {
Shinya Kitaoka 120a6e
  delete vs;
Shinya Kitaoka 120a6e
  vs = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TVectorImage::sameSubGroup(int index0, int index1) const {
Shinya Kitaoka 120a6e
  if (index0 < 0 || index1 < 0) return 0;
Shinya Kitaoka 120a6e
  return m_imp->m_strokes[index0]->m_groupId.getCommonParentDepth(
Shinya Kitaoka 120a6e
             m_imp->m_strokes[index1]->m_groupId) >
Shinya Kitaoka 120a6e
         m_imp->m_insideGroup.getDepth();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::getCommonGroupDepth(int index0, int index1) const {
Shinya Kitaoka 120a6e
  if (index0 < 0 || index1 < 0) return 0;
Shinya Kitaoka 120a6e
  return m_imp->m_strokes[index0]->m_groupId.getCommonParentDepth(
Shinya Kitaoka 120a6e
      m_imp->m_strokes[index1]->m_groupId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::ungroup(int fromIndex) {
Shinya Kitaoka 120a6e
  m_imp->m_insideGroup = TGroupId();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(m_imp->m_strokes[fromIndex]->m_groupId.isGrouped() != 0);
Shinya Kitaoka 120a6e
  std::vector<int> changedStrokes;</int>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int toIndex = fromIndex + 1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  while (toIndex < (int)m_imp->m_strokes.size() &&
Shinya Kitaoka 120a6e
         m_imp->m_strokes[fromIndex]->m_groupId.getCommonParentDepth(
Shinya Kitaoka 120a6e
             m_imp->m_strokes[toIndex]->m_groupId) >= 1)
Shinya Kitaoka 120a6e
    toIndex++;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  toIndex--;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TGroupId groupId;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (fromIndex > 0 &&
Shinya Kitaoka 120a6e
      m_imp->m_strokes[fromIndex - 1]->m_groupId.isGrouped(true) != 0)
Shinya Kitaoka 120a6e
    groupId = m_imp->m_strokes[fromIndex - 1]->m_groupId;
Shinya Kitaoka 120a6e
  else if (toIndex < (int)m_imp->m_strokes.size() - 1 &&
Shinya Kitaoka 120a6e
           m_imp->m_strokes[toIndex + 1]->m_groupId.isGrouped(true) != 0)
Shinya Kitaoka 120a6e
    groupId = m_imp->m_strokes[toIndex + 1]->m_groupId;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    groupId = TGroupId(this, true);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int i = fromIndex;
Shinya Kitaoka 120a6e
       i <= toIndex || (i < (int)m_imp->m_strokes.size() &&
Shinya Kitaoka 120a6e
                        m_imp->m_strokes[i]->m_groupId.isGrouped(true) != 0);
Shinya Kitaoka 120a6e
       i++) {
Shinya Kitaoka 120a6e
    m_imp->m_strokes[i]->m_groupId.ungroup(groupId);
Shinya Kitaoka 120a6e
    changedStrokes.push_back(i);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  notifyChangedStrokes(changedStrokes, std::vector<tstroke *="">(), false);</tstroke>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return toIndex - fromIndex + 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TVectorImage::isEnteredGroupStroke(int index) const {
Shinya Kitaoka 120a6e
  return m_imp->m_insideGroup.isParentOf(getVIStroke(index)->m_groupId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TVectorImage::enterGroup(int index) {
Shinya Kitaoka 120a6e
  VIStroke *vs = getVIStroke(index);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!vs->m_groupId.isGrouped()) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int newDepth = vs->m_groupId.getCommonParentDepth(m_imp->m_insideGroup) + 1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TGroupId newGroupId = vs->m_groupId;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  while (newGroupId.getDepth() > newDepth) newGroupId = newGroupId.getParent();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (newGroupId == m_imp->m_insideGroup) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->m_insideGroup = newGroupId;
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::exitGroup() {
Shinya Kitaoka 120a6e
  if (m_imp->m_insideGroup == TGroupId()) return -1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int i, ret = -1;
Shinya Kitaoka 120a6e
  for (i = 0; i < (int)m_imp->m_strokes.size(); i++) {
Shinya Kitaoka 120a6e
    if (m_imp->m_strokes[i]->m_groupId.getCommonParentDepth(
Shinya Kitaoka 120a6e
            m_imp->m_insideGroup) >= m_imp->m_insideGroup.getDepth()) {
Shinya Kitaoka 120a6e
      ret = i;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(i != m_imp->m_strokes.size());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->m_insideGroup = m_imp->m_insideGroup.getParent();
Shinya Kitaoka 120a6e
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::group(int fromIndex, int count) {
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  assert(count >= 0);
Shinya Kitaoka 120a6e
  std::vector<int> changedStroke;</int>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TGroupId parent = TGroupId(this, false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = 0; i < count; i++) {
Shinya Kitaoka 120a6e
    m_imp->m_strokes[fromIndex + i]->m_groupId =
Shinya Kitaoka 120a6e
        TGroupId(parent, m_imp->m_strokes[fromIndex + i]->m_groupId);
Shinya Kitaoka 120a6e
    changedStroke.push_back(fromIndex + i);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->rearrangeMultiGroup();  // see method's comment
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->regroupGhosts(changedStroke);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  notifyChangedStrokes(changedStroke, std::vector<tstroke *="">(), false);</tstroke>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
  m_imp->checkGroups();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::getGroupDepth(UINT index) const {
Shinya Kitaoka 120a6e
  assert(index < m_imp->m_strokes.size());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return m_imp->m_strokes[index]->m_groupId.isGrouped();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::areDifferentGroup(UINT index1, bool isRegion1, UINT index2,
Shinya Kitaoka 120a6e
                                    bool isRegion2) const {
Shinya Kitaoka 120a6e
  return m_imp->areDifferentGroup(index1, isRegion1, index2, isRegion2);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*this method is tricky.
Toshihiro Shimizu 890ddd
it is not allow to have not-adiacent strokes  of same group.
Shinya Kitaoka 120a6e
but it can happen when you group  some already-grouped strokes creating
Shinya Kitaoka 120a6e
sub-groups.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
example: vi made of 5 strokes, before grouping  (N=no group)
Toshihiro Shimizu 890ddd
N
Toshihiro Shimizu 890ddd
N
Toshihiro Shimizu 890ddd
1
Toshihiro Shimizu 890ddd
1
Toshihiro Shimizu 890ddd
N
Toshihiro Shimizu 890ddd
after grouping became:
Toshihiro Shimizu 890ddd
2
Toshihiro Shimizu 890ddd
2
Toshihiro Shimizu 890ddd
2-1
Toshihiro Shimizu 890ddd
2-1
Toshihiro Shimizu 890ddd
2
Toshihiro Shimizu 890ddd
not allowed!
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
this method moves strokes, so that  adiacent strokes have same group.
Toshihiro Shimizu 890ddd
so after calling rearrangeMultiGroup the vi became:
Toshihiro Shimizu 890ddd
2
Toshihiro Shimizu 890ddd
2
Toshihiro Shimizu 890ddd
2
Toshihiro Shimizu 890ddd
2-1
Toshihiro Shimizu 890ddd
2-1
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::Imp::rearrangeMultiGroup() {
Shinya Kitaoka 120a6e
  UINT i, j, k;
Shinya Kitaoka 120a6e
  if (m_strokes.size() <= 0) return;
Shinya Kitaoka 120a6e
  for (i = 0; i < m_strokes.size() - 1; i++) {
Shinya Kitaoka 120a6e
    if (m_strokes[i]->m_groupId.isGrouped() &&
Shinya Kitaoka 120a6e
        m_strokes[i + 1]->m_groupId.isGrouped() &&
Shinya Kitaoka 120a6e
        m_strokes[i]->m_groupId != m_strokes[i + 1]->m_groupId) {
Shinya Kitaoka 120a6e
      TGroupId &prevId   = m_strokes[i]->m_groupId;
Shinya Kitaoka 120a6e
      TGroupId &idToMove = m_strokes[i + 1]->m_groupId;
Shinya Kitaoka 120a6e
      for (j = i + 1;
Shinya Kitaoka 120a6e
           j < m_strokes.size() && m_strokes[j]->m_groupId == idToMove; j++)
Shinya Kitaoka 120a6e
        ;
Shinya Kitaoka 120a6e
      if (j != m_strokes.size()) {
Shinya Kitaoka 120a6e
        j--;  // now range i+1-j contains the strokes to be moved.
Shinya Kitaoka 120a6e
        // let's compute where to move them (after last
Shinya Kitaoka 120a6e
        for (k = j; k < m_strokes.size() && m_strokes[k]->m_groupId != prevId;
Shinya Kitaoka 120a6e
             k++)
Shinya Kitaoka 120a6e
          ;
Shinya Kitaoka 120a6e
        if (k < m_strokes.size()) {
Shinya Kitaoka 120a6e
          for (; k < m_strokes.size() && m_strokes[k]->m_groupId == prevId; k++)
Shinya Kitaoka 120a6e
            ;
Shinya Kitaoka 120a6e
          moveStrokes(i + 1, j - i, k, false);
Shinya Kitaoka 120a6e
          rearrangeMultiGroup();
Shinya Kitaoka 120a6e
          return;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::Imp::areDifferentGroup(UINT index1, bool isRegion1,
Shinya Kitaoka 120a6e
                                         UINT index2, bool isRegion2) const {
Shinya Kitaoka 120a6e
  TGroupId group1, group2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (isRegion1) {
Shinya Kitaoka 120a6e
    TRegion *r = m_regions[index1];
Shinya Kitaoka 120a6e
    for (UINT i = 0; i < r->getEdgeCount(); i++)
Shinya Kitaoka 120a6e
      if (r->getEdge(i)->m_index >= 0) {
Shinya Kitaoka 120a6e
        group1 = m_strokes[r->getEdge(i)->m_index]->m_groupId;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    group1 = m_strokes[index1]->m_groupId;
Shinya Kitaoka 120a6e
  if (isRegion2) {
Shinya Kitaoka 120a6e
    TRegion *r = m_regions[index2];
Shinya Kitaoka 120a6e
    for (UINT i = 0; i < r->getEdgeCount(); i++)
Shinya Kitaoka 120a6e
      if (r->getEdge(i)->m_index >= 0) {
Shinya Kitaoka 120a6e
        group2 = m_strokes[r->getEdge(i)->m_index]->m_groupId;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    group2 = m_strokes[index2]->m_groupId;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!group1 && !group2) return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (group1 == group2)
Shinya Kitaoka 120a6e
    return -1;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return group1.getCommonParentDepth(group2);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TGroupId::getCommonParentDepth(const TGroupId &id) const {
Shinya Kitaoka 120a6e
  int size1 = m_id.size();
Shinya Kitaoka 120a6e
  int size2 = id.m_id.size();
Shinya Kitaoka 120a6e
  int count;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (count = 0; count < std::min(size1, size2); count++)
Shinya Kitaoka 120a6e
    if (m_id[size1 - count - 1] != id.m_id[size2 - count - 1]) break;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return count;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TGroupId::TGroupId(const TGroupId &parent, const TGroupId &id) {
Shinya Kitaoka 120a6e
  assert(parent.m_id[0] > 0);
Shinya Kitaoka 120a6e
  assert(id.m_id.size() > 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (id.isGrouped(true) != 0)
Shinya Kitaoka 120a6e
    m_id.push_back(parent.m_id[0]);
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    m_id = id.m_id;
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 0; i < (int)parent.m_id.size(); i++)
Shinya Kitaoka 120a6e
      m_id.push_back(parent.m_id[i]);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
bool TGroupId::sameParent(const TGroupId& id) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
assert(!m_id.empty() || !id.m_id.empty());
Toshihiro Shimizu 890ddd
return m_id.back()==id.m_id.back();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TGroupId TGroupId::getParent() const {
Shinya Kitaoka 120a6e
  if (m_id.size() <= 1) return TGroupId();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TGroupId ret = *this;
Shinya Kitaoka 120a6e
  ret.m_id.erase(ret.m_id.begin());
Shinya Kitaoka 120a6e
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGroupId::ungroup(const TGroupId &id) {
Shinya Kitaoka 120a6e
  assert(id.isGrouped(true) != 0);
Shinya Kitaoka 120a6e
  assert(!m_id.empty());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_id.size() == 1)
Shinya Kitaoka 120a6e
    m_id[0] = id.m_id[0];
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_id.pop_back();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TGroupId::operator==(const TGroupId &id) const {
Shinya Kitaoka 120a6e
  if (m_id.size() != id.m_id.size()) return false;
Shinya Kitaoka 120a6e
  UINT i;
Shinya Kitaoka 120a6e
  for (i = 0; i < m_id.size(); i++)
Shinya Kitaoka 120a6e
    if (m_id[i] != id.m_id[i]) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TGroupId::operator<(const TGroupId &id) const {
Shinya Kitaoka 120a6e
  assert(!m_id.empty() && !id.m_id.empty());
Shinya Kitaoka 120a6e
  int size1 = m_id.size();
Shinya Kitaoka 120a6e
  int size2 = id.m_id.size();
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < std::min(size1, size2); i++)
Shinya Kitaoka 120a6e
    if (m_id[size1 - i - 1] != id.m_id[size2 - i - 1])
Shinya Kitaoka 120a6e
      return m_id[size1 - i - 1] < id.m_id[size2 - i - 1];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return size1 < size2;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TGroupId::isGrouped(bool implicit) const {
Shinya Kitaoka 120a6e
  assert(!m_id.empty());
Shinya Kitaoka 120a6e
  assert(m_id[0] != 0);
Shinya Kitaoka 120a6e
  if (implicit)
Shinya Kitaoka 120a6e
    return (m_id[0] < 0) ? 1 : 0;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return (m_id[0] > 0) ? m_id.size() : 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TGroupId::TGroupId(TVectorImage *vi, bool isGhost) {
Shinya Kitaoka 120a6e
  m_id.push_back((isGhost) ? -(++vi->m_imp->m_maxGhostGroupId)
Shinya Kitaoka 120a6e
                           : ++vi->m_imp->m_maxGroupId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
void TVectorImage::Imp::checkGroups() {
Shinya Kitaoka 120a6e
  TGroupId currGroupId;
Shinya Kitaoka 120a6e
  std::set<tgroupid> groupSet;</tgroupid>
Shinya Kitaoka 120a6e
  std::set<tgroupid>::iterator it;</tgroupid>
Shinya Kitaoka 120a6e
  UINT i = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (i < m_strokes.size()) {
Shinya Kitaoka 120a6e
    // assert(m_strokes[i]->m_groupId!=currGroupId);
Shinya Kitaoka 120a6e
    // assert(i==0 ||
Shinya Kitaoka 120a6e
    // m_strokes[i-1]->m_groupId.isGrouped()!=m_strokes[i]->m_groupId.isGrouped()!=0
Shinya Kitaoka 120a6e
    // ||
Shinya Kitaoka 120a6e
    //       (m_strokes[i]->m_groupId.isGrouped()!=0 &&
Shinya Kitaoka 120a6e
    //       m_strokes[i-1]->m_groupId!=m_strokes[i]->m_groupId));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    currGroupId = m_strokes[i]->m_groupId;
Shinya Kitaoka 120a6e
    it          = groupSet.find(currGroupId);
Shinya Kitaoka 120a6e
    if (it != groupSet.end())  // esisteva gia un gruppo con questo id!
Shinya Kitaoka 120a6e
      assert(!"errore: due gruppi con lo stesso id!");
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      groupSet.insert(currGroupId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    while (i < m_strokes.size() && m_strokes[i]->m_groupId == currGroupId) i++;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TVectorImage::canMoveStrokes(int strokeIndex, int count,
Shinya Kitaoka 120a6e
                                  int moveBefore) const {
Shinya Kitaoka 120a6e
  return m_imp->canMoveStrokes(strokeIndex, count, moveBefore);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// verifica se si possono spostare le stroke  da strokeindex a
Shinya Kitaoka 120a6e
// strokeindex+count-1 prima della posizione moveBefore;
Shinya Kitaoka 120a6e
// per fare questo fa un vettore in cui mette tutti i gruppi nella  posizione
Shinya Kitaoka 120a6e
// dopo lo
Shinya Kitaoka 120a6e
// spostamento e verifica che sia un configurazione di gruppi ammessa.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TVectorImage::Imp::canMoveStrokes(int strokeIndex, int count,
Shinya Kitaoka 120a6e
                                       int moveBefore) const {
Shinya Kitaoka 120a6e
  if (m_maxGroupId <= 1)  // non ci sono gruppi!
Shinya Kitaoka 120a6e
    return true;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int i, j = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<tgroupid> groupsAfterMoving(m_strokes.size());</tgroupid>
Shinya Kitaoka 120a6e
  if (strokeIndex < moveBefore) {
shun-iwasawa 9bcc69
    for (i = 0; i < strokeIndex; i++)
Shinya Kitaoka 120a6e
      groupsAfterMoving[j++] = m_strokes[i]->m_groupId;
Toshihiro Shimizu 890ddd
shun-iwasawa 9bcc69
    for (i = strokeIndex + count; i < moveBefore; i++)
Shinya Kitaoka 120a6e
      groupsAfterMoving[j++] = m_strokes[i]->m_groupId;
Toshihiro Shimizu 890ddd
shun-iwasawa 9bcc69
    for (i = strokeIndex; i < strokeIndex + count; i++)
Shinya Kitaoka 120a6e
      groupsAfterMoving[j++] = m_strokes[i]->m_groupId;
Toshihiro Shimizu 890ddd
shun-iwasawa 9bcc69
    for (i = moveBefore; i < (int)m_strokes.size(); i++)
Shinya Kitaoka 120a6e
      groupsAfterMoving[j++] = m_strokes[i]->m_groupId;
Shinya Kitaoka 120a6e
  } else {
shun-iwasawa 9bcc69
    for (i = 0; i < moveBefore; i++)
Shinya Kitaoka 120a6e
      groupsAfterMoving[j++] = m_strokes[i]->m_groupId;
Toshihiro Shimizu 890ddd
shun-iwasawa 9bcc69
    for (i = strokeIndex; i < strokeIndex + count; i++)
Shinya Kitaoka 120a6e
      groupsAfterMoving[j++] = m_strokes[i]->m_groupId;
Toshihiro Shimizu 890ddd
shun-iwasawa 9bcc69
    for (i = moveBefore; i < strokeIndex; i++)
Shinya Kitaoka 120a6e
      groupsAfterMoving[j++] = m_strokes[i]->m_groupId;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    for (i = strokeIndex + count; i < (int)m_strokes.size(); i++)
Shinya Kitaoka 120a6e
      groupsAfterMoving[j++] = m_strokes[i]->m_groupId;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(j == (int)m_strokes.size());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  i = 0;
Shinya Kitaoka 120a6e
  TGroupId currGroupId;
Shinya Kitaoka 120a6e
  std::set<tgroupid> groupSet;</tgroupid>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  while (i < (int)groupsAfterMoving.size()) {
Shinya Kitaoka 120a6e
    currGroupId = groupsAfterMoving[i];
Shinya Kitaoka 120a6e
    if (groupSet.find(currGroupId) !=
Shinya Kitaoka 120a6e
        groupSet.end())  // esisteva gia un gruppo con questo id!
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      if (!currGroupId.isGrouped(true))  // i gruppi impliciti non contano
Shinya Kitaoka 120a6e
        return false;
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      groupSet.insert(currGroupId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    while (i < (int)groupsAfterMoving.size() &&
Shinya Kitaoka 120a6e
           groupsAfterMoving[i] == currGroupId)
Shinya Kitaoka 120a6e
      i++;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TVectorImage::Imp::regroupGhosts(std::vector<int> &changedStrokes) {</int>
Shinya Kitaoka 120a6e
  TGroupId currGroupId;
Shinya Kitaoka 120a6e
  std::set<tgroupid> groupMap;</tgroupid>
Shinya Kitaoka 120a6e
  std::set<tgroupid>::iterator it;</tgroupid>
Shinya Kitaoka 120a6e
  UINT i = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (i < m_strokes.size()) {
Shinya Kitaoka 120a6e
    assert(m_strokes[i]->m_groupId != currGroupId);
Shinya Kitaoka 120a6e
    assert(i == 0 ||
Shinya Kitaoka 120a6e
           m_strokes[i - 1]->m_groupId.isGrouped() !=
Shinya Kitaoka 120a6e
               m_strokes[i]->m_groupId.isGrouped() != 0 ||
Shinya Kitaoka 120a6e
           (m_strokes[i]->m_groupId.isGrouped() != 0 &&
Shinya Kitaoka 120a6e
            m_strokes[i - 1]->m_groupId != m_strokes[i]->m_groupId));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    currGroupId = m_strokes[i]->m_groupId;
Shinya Kitaoka 120a6e
    it          = groupMap.find(currGroupId);
Shinya Kitaoka 120a6e
    if (it != groupMap.end())  // esisteva gia un gruppo con questo id!
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      if (currGroupId.isGrouped() != 0)
Shinya Kitaoka 120a6e
        assert(!"errore: due gruppi con lo stesso id!");
Shinya Kitaoka 120a6e
      else  // gruppo ghost; gli do un nuovo id
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        TGroupId newGroup(m_vi, true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        while (i < m_strokes.size() &&
Shinya Kitaoka 120a6e
               m_strokes[i]->m_groupId.isGrouped(true) != 0) {
Shinya Kitaoka 120a6e
          m_strokes[i]->m_groupId = newGroup;
Shinya Kitaoka 120a6e
          changedStrokes.push_back(i);
Shinya Kitaoka 120a6e
          i++;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      groupMap.insert(currGroupId);
Shinya Kitaoka 120a6e
      while (i < m_strokes.size() &&
Shinya Kitaoka 120a6e
             ((currGroupId.isGrouped(false) != 0 &&
Shinya Kitaoka 120a6e
               m_strokes[i]->m_groupId == currGroupId) ||
Rozhuk Ivan 823a31
              (currGroupId.isGrouped(true) != 0 &&
pojienie 4e4838
               m_strokes[i]->m_groupId.isGrouped(true) != 0))) {
Shinya Kitaoka 120a6e
        if (m_strokes[i]->m_groupId != currGroupId) {
Shinya Kitaoka 120a6e
          m_strokes[i]->m_groupId = currGroupId;
Shinya Kitaoka 120a6e
          changedStrokes.push_back(i);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        i++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TVectorImage::canEnterGroup(int strokeIndex) const {
Shinya Kitaoka 120a6e
  VIStroke *vs = m_imp->m_strokes[strokeIndex];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!vs->m_groupId.isGrouped()) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return m_imp->m_insideGroup == TGroupId() ||
Shinya Kitaoka 120a6e
         vs->m_groupId != m_imp->m_insideGroup;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TVectorImage::inCurrentGroup(int strokeIndex) const {
Shinya Kitaoka 120a6e
  return m_imp->inCurrentGroup(strokeIndex);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TVectorImage::Imp::inCurrentGroup(int strokeIndex) const {
Shinya Kitaoka 120a6e
  return m_insideGroup == TGroupId() ||
Shinya Kitaoka 120a6e
         m_insideGroup.isParentOf(m_strokes[strokeIndex]->m_groupId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TVectorImage::selectable(int strokeIndex) const {
Shinya Kitaoka 120a6e
  return (m_imp->m_insideGroup != m_imp->m_strokes[strokeIndex]->m_groupId &&
Shinya Kitaoka 120a6e
          inCurrentGroup(strokeIndex));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool containsNoSubregion(const TRegion *r, const TPointD &p) {
Shinya Kitaoka 120a6e
  if (r->contains(p)) {
Shinya Kitaoka 120a6e
    for (unsigned int i = 0; i < r->getSubregionCount(); i++)
Shinya Kitaoka 120a6e
      if (r->getSubregion(i)->contains(p)) return false;
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return false;
Toshihiro Shimizu 890ddd
}
shun-iwasawa 9bcc69
};  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::getGroupByStroke(UINT index) const {
Shinya Kitaoka 120a6e
  VIStroke *viStroke = getVIStroke(index);
Shinya Kitaoka 120a6e
  return viStroke->m_groupId.m_id.back();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::getGroupByRegion(UINT index) const {
Shinya Kitaoka 120a6e
  TRegion *r = m_imp->m_regions[index];
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < r->getEdgeCount(); i++)
Shinya Kitaoka 120a6e
    if (r->getEdge(i)->m_index >= 0) {
Shinya Kitaoka 120a6e
      return m_imp->m_strokes[r->getEdge(i)->m_index]->m_groupId.m_id.back();
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::pickGroup(const TPointD &pos, bool onEnteredGroup) const {
Shinya Kitaoka 120a6e
  if (onEnteredGroup && isInsideGroup() == 0) return -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // double maxDist2 = 50*tglGetPixelSize2();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int strokeIndex = getStrokeCount() - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (strokeIndex >=
Shinya Kitaoka 120a6e
         0)  // ogni ciclo di while esplora un gruppo; ciclo sugli stroke
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if (!isStrokeGrouped(strokeIndex)) {
Shinya Kitaoka 120a6e
      strokeIndex--;
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    bool entered = isInsideGroup() > 0 && isEnteredGroupStroke(strokeIndex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if ((onEnteredGroup || entered) && (!onEnteredGroup || !entered)) {
Shinya Kitaoka 120a6e
      strokeIndex--;
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int currStrokeIndex = strokeIndex;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    while (strokeIndex >= 0 &&
Shinya Kitaoka 120a6e
           getCommonGroupDepth(strokeIndex, currStrokeIndex) > 0) {
Shinya Kitaoka 120a6e
      TStroke *s = getStroke(strokeIndex);
Shinya Kitaoka 120a6e
      double outT;
Shinya Kitaoka 120a6e
      int chunkIndex;
Shinya Kitaoka 120a6e
      double dist2;
Shinya Kitaoka 120a6e
      bool ret = s->getNearestChunk(pos, outT, chunkIndex, dist2);
Shinya Kitaoka 120a6e
      if (ret) {
Shinya Kitaoka 120a6e
        TThickPoint p = s->getChunk(chunkIndex)->getThickPoint(outT);
Shinya Kitaoka 120a6e
        if (p.thick < 0.1) p.thick = 1;
Shinya Kitaoka 120a6e
        if (sqrt(dist2) <= 1.5 * p.thick) return strokeIndex;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*TThickPoint p = s->getThickPoint(s->getW(pos));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
double dist = tdistance( TThickPoint(pos,0), p);
Shinya Kitaoka 120a6e
if (dist<1.2*p.thick/2.0)
Shinya Kitaoka 120a6e
return strokeIndex;*/
Shinya Kitaoka 120a6e
      strokeIndex--;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  strokeIndex = getStrokeCount() - 1;
Shinya Kitaoka 120a6e
  int ret     = -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (strokeIndex >=
Shinya Kitaoka 120a6e
         0)  // ogni ciclo di while esplora un gruppo; ciclo sulle regions
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if (!isStrokeGrouped(strokeIndex)) {
Shinya Kitaoka 120a6e
      strokeIndex--;
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    bool entered = isInsideGroup() > 0 && isEnteredGroupStroke(strokeIndex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if ((onEnteredGroup || entered) && (!onEnteredGroup || !entered)) {
Shinya Kitaoka 120a6e
      strokeIndex--;
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRegion *currR = 0;
Shinya Kitaoka 120a6e
    for (UINT regionIndex = 0; regionIndex < getRegionCount(); regionIndex++) {
Shinya Kitaoka 120a6e
      TRegion *r = getRegion(regionIndex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      int i, regionStrokeIndex = -1;
Shinya Kitaoka 120a6e
      for (i = 0; i < (int)r->getEdgeCount() && regionStrokeIndex < 0; i++)
Shinya Kitaoka 120a6e
        regionStrokeIndex = r->getEdge(i)->m_index;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (regionStrokeIndex >= 0 &&
Shinya Kitaoka 120a6e
          sameSubGroup(regionStrokeIndex, strokeIndex) &&
Shinya Kitaoka 120a6e
          containsNoSubregion(r, pos)) {
Shinya Kitaoka 120a6e
        if (!currR || currR->contains(*r)) {
Shinya Kitaoka 120a6e
          currR = r;
Shinya Kitaoka 120a6e
          ret   = regionStrokeIndex;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (currR != 0) {
Shinya Kitaoka 120a6e
      assert(m_palette);
Shinya Kitaoka 120a6e
      const TSolidColorStyle *st = dynamic_cast<const *="" tsolidcolorstyle="">(</const>
Shinya Kitaoka 120a6e
          m_palette->getStyle(currR->getStyle()));
Shinya Kitaoka 120a6e
      if (!st || st->getMainColor() != TPixel::Transparent) return ret;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    while (strokeIndex > 0 &&
Shinya Kitaoka 120a6e
           getCommonGroupDepth(strokeIndex, strokeIndex - 1) > 0)
Shinya Kitaoka 120a6e
      strokeIndex--;
Shinya Kitaoka 120a6e
    strokeIndex--;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TVectorImage::pickGroup(const TPointD &pos) const {
Shinya Kitaoka 120a6e
  int index;
Shinya Kitaoka 120a6e
  if ((index = pickGroup(pos, true)) == -1) return pickGroup(pos, false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return index;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------