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