Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "drawutil.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tmathutil.h"
Toshihiro Shimizu 890ddd
//#include "tregion.h"
Toshihiro Shimizu 890ddd
#include "tcurveutil.h"
Toshihiro Shimizu 890ddd
#include "tcurves.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
void drawQuadraticCenterline(const TQuadratic &inQuad,
Toshihiro Shimizu 890ddd
							 double pixelSize,
Toshihiro Shimizu 890ddd
							 double from,
Toshihiro Shimizu 890ddd
							 double to)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(0.0 <= from &&
Toshihiro Shimizu 890ddd
		   from <= to &&
Toshihiro Shimizu 890ddd
		   to <= 1.0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	to = (std::max)(0.0, (std::min)(to, 1.0));
Toshihiro Shimizu 890ddd
	from = (std::max)(0.0, (std::min)(from, to));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TQuadratic
Toshihiro Shimizu 890ddd
		tmp(inQuad),
Toshihiro Shimizu 890ddd
		s1,
Toshihiro Shimizu 890ddd
		s2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TQuadratic
Toshihiro Shimizu 890ddd
		*quad = &tmp;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double
Toshihiro Shimizu 890ddd
		newFrom = from;
Toshihiro Shimizu 890ddd
	if (to != 1.0) {
Toshihiro Shimizu 890ddd
		tmp.split(to, s1, s2);
Toshihiro Shimizu 890ddd
		quad = &s1;
Toshihiro Shimizu 890ddd
		newFrom = from / to;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (from != 0.0) {
Toshihiro Shimizu 890ddd
		tmp = *quad;
Toshihiro Shimizu 890ddd
		tmp.split(newFrom, s1, s2);
Toshihiro Shimizu 890ddd
		quad = &s2;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//glColor( TPixel32::Black );
Toshihiro Shimizu 890ddd
	double step = computeStep(*quad, pixelSize);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// It draws the curve as a linear piecewise approximation
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double invSqrtScale = 1.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// First of all, it computes the control circles of the curve in screen coordinates
Toshihiro Shimizu 890ddd
	TPointD scP0 = quad->getP0();
Toshihiro Shimizu 890ddd
	TPointD scP1 = quad->getP1();
Toshihiro Shimizu 890ddd
	TPointD scP2 = quad->getP2();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD A = scP0 - 2 * scP1 + scP2;
Toshihiro Shimizu 890ddd
	TPointD B = scP0 - scP1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double h;
Toshihiro Shimizu 890ddd
	h = invSqrtScale * step;
Toshihiro Shimizu 890ddd
	double h2 = h * h;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD P = scP0, D2 = 2 * h2 * A, D1 = A * h2 - 2 * B * h;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (h < 0 || isAlmostZero(h))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//    if ( h < from )
Toshihiro Shimizu 890ddd
	//      h = from;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// It draws the whole curve, using forward differencing
Toshihiro Shimizu 890ddd
	glBegin(GL_LINE_STRIP); // The curve starts from scP0
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//scP0 = quad.getPoint(from);
Toshihiro Shimizu 890ddd
	glVertex2d(scP0.x, scP0.y);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (double t = from + h; t < to; t = t + h) {
Toshihiro Shimizu 890ddd
		P = P + D1;
Toshihiro Shimizu 890ddd
		D1 = D1 + D2;
Toshihiro Shimizu 890ddd
		glVertex2d(P.x, P.y);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//scP2 = quad.getPoint(to);
Toshihiro Shimizu 890ddd
	glVertex2d(scP2.x, scP2.y); // The curve ends in scP2
Toshihiro Shimizu 890ddd
	glEnd();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
void stroke2polyline(std::vector<tpointd> &pnts, const TStroke &stroke,</tpointd>
Toshihiro Shimizu 890ddd
					 double pixelSize, double w0, double w1, bool lastRepeatable)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TPointD p;
Toshihiro Shimizu 890ddd
	double step;
Toshihiro Shimizu 890ddd
	int i, index0, index1;
Toshihiro Shimizu 890ddd
	double t0, t1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (isAlmostZero(w0))
Toshihiro Shimizu 890ddd
		w0 = 0.0;
Toshihiro Shimizu 890ddd
	if (isAlmostZero(w1))
Toshihiro Shimizu 890ddd
		w1 = 0.0;
Toshihiro Shimizu 890ddd
	if (isAlmostZero(1 - w0))
Toshihiro Shimizu 890ddd
		w0 = 1.0;
Toshihiro Shimizu 890ddd
	if (isAlmostZero(1 - w1))
Toshihiro Shimizu 890ddd
		w1 = 1.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(w0 >= 0.0);
Toshihiro Shimizu 890ddd
	assert(w0 <= 1.0);
Toshihiro Shimizu 890ddd
	assert(w1 >= 0.0);
Toshihiro Shimizu 890ddd
	assert(w1 <= 1.0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	stroke.getChunkAndT(w0, index0, t0);
Toshihiro Shimizu 890ddd
	stroke.getChunkAndT(w1, index1, t1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double t;
Toshihiro Shimizu 890ddd
	double endT;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (index1 < index0 || (index1 == index0 && t1 < t0)) {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (i = index0; i >= index1; i--) {
Toshihiro Shimizu 890ddd
			step = computeStep(*(stroke.getChunk(i)), pixelSize);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (step < TConsts::epsilon)
Toshihiro Shimizu 890ddd
				step = TConsts::epsilon;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			p = stroke.getChunk(i)->getPoint(t0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (pnts.empty() || pnts.back() != p)
Toshihiro Shimizu 890ddd
				pnts.push_back(p);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			endT = (i == index1) ? t1 : 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			pnts.reserve((UINT)((t0 - endT) / step) + 1 + pnts.size());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			for (t = t0 - step; t >= endT; t -= step)
Toshihiro Shimizu 890ddd
				pnts.push_back(stroke.getChunk(i)->getPoint(t));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			t0 = 1;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (i = index0; i <= index1; i++) {
Toshihiro Shimizu 890ddd
			step = computeStep(*(stroke.getChunk(i)), pixelSize);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			assert(step);
Toshihiro Shimizu 890ddd
			if (!step)
Toshihiro Shimizu 890ddd
				step = TConsts::epsilon; //non dovrebbe accadere mai!!!
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			p = stroke.getChunk(i)->getPoint(t0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (pnts.empty() || pnts.back() != p)
Toshihiro Shimizu 890ddd
				pnts.push_back(p);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			endT = (i == index1) ? t1 : 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			pnts.reserve((UINT)((endT - t0) / step) + 1 + pnts.size());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			for (t = t0 + step; t <= endT; t += step)
Toshihiro Shimizu 890ddd
				pnts.push_back(stroke.getChunk(i)->getPoint(t));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			t0 = 0;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	p = stroke.getPoint(w1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (pnts.empty() || (p != pnts.back() && (p != pnts.front() || lastRepeatable)))
Toshihiro Shimizu 890ddd
		pnts.push_back(p);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
void  region2polyline(vector<t3dpointd>& pnts,</t3dpointd>
Toshihiro Shimizu 890ddd
                      const TRegion* reg, 
Toshihiro Shimizu 890ddd
                      double pixelSize )
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
assert( reg );
Toshihiro Shimizu 890ddd
if(!reg) return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TStroke* stroke;
Toshihiro Shimizu 890ddd
double w0;
Toshihiro Shimizu 890ddd
double w1;
Toshihiro Shimizu 890ddd
TPointD lastPnt;
Toshihiro Shimizu 890ddd
for(UINT i=0; i<reg->getEdgeCount(); i++)</reg->
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
  TRegion::edge* edge = reg->getEdge(i);
Toshihiro Shimizu 890ddd
  stroke = edge->m_stroke;
Toshihiro Shimizu 890ddd
  assert(stroke);
Toshihiro Shimizu 890ddd
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
    stroke->getNearestChunk(edge->m_p0, t, index, dummy);
Toshihiro Shimizu 890ddd
    edge->m_w0 = getWfromChunkAndT(stroke, index, t);
Toshihiro Shimizu 890ddd
     
Toshihiro Shimizu 890ddd
    stroke->getNearestChunk(edge->m_p1, t, index, dummy);
Toshihiro Shimizu 890ddd
    edge->m_w1 = getWfromChunkAndT(stroke, index, t);
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  w0 = edge->m_w0;
Toshihiro Shimizu 890ddd
  w1 = edge->m_w1;
Toshihiro Shimizu 890ddd
    
Toshihiro Shimizu 890ddd
  assert( 0 <= w0 && w0 <= 1.0 );
Toshihiro Shimizu 890ddd
  assert( 0 <= w1 && w1 <= 1.0 );
Toshihiro Shimizu 890ddd
   
Toshihiro Shimizu 890ddd
  double step = computeStep( *stroke, pixelSize );
Toshihiro Shimizu 890ddd
    
Toshihiro Shimizu 890ddd
    // assert( step != 2 && step != 0.0 );
Toshihiro Shimizu 890ddd
    
Toshihiro Shimizu 890ddd
  if( isAlmostZero( step ) ) 
Toshihiro Shimizu 890ddd
    step = 1.0;
Toshihiro Shimizu 890ddd
   
Toshihiro Shimizu 890ddd
  step/= stroke->getChunkCount(); 
Toshihiro Shimizu 890ddd
    
Toshihiro Shimizu 890ddd
  double direction = 1;
Toshihiro Shimizu 890ddd
    
Toshihiro Shimizu 890ddd
  if( w0 > w1 ) 
Toshihiro Shimizu 890ddd
    direction *=-1;
Toshihiro Shimizu 890ddd
    
Toshihiro Shimizu 890ddd
  T3DPointD pnt;
Toshihiro Shimizu 890ddd
    
Toshihiro Shimizu 890ddd
  double incr = direction*step;
Toshihiro Shimizu 890ddd
    
Toshihiro Shimizu 890ddd
  pnt = T3DPointD( stroke->getPoint( w0 ), 0 );
Toshihiro Shimizu 890ddd
    
Toshihiro Shimizu 890ddd
  if ( pnts.empty() || pnt != pnts.back() )
Toshihiro Shimizu 890ddd
    pnts.push_back( pnt );
Toshihiro Shimizu 890ddd
    
Toshihiro Shimizu 890ddd
  for( double w = w0 + incr; direction*w < direction*w1; w+= incr)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
    pnt = T3DPointD( stroke->getPoint( w ), 0 );    
Toshihiro Shimizu 890ddd
      if ( pnt != pnts.back() )
Toshihiro Shimizu 890ddd
        pnts.push_back( pnt );
Toshihiro Shimizu 890ddd
    }	           
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if defined(MACOSX)
Toshihiro Shimizu 890ddd
void lefttRotateBits(UCHAR *buf, int bufferSize)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UINT *buffer = (UINT *)buf;
Shinya Kitaoka 4c5bd5
	UINT app;
Toshihiro Shimizu 890ddd
	for (int i = 0; i < bufferSize; i++, buffer++) {
Toshihiro Shimizu 890ddd
		app = *buffer;
Toshihiro Shimizu 890ddd
		*buffer = app << 8 | app >> 24;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double computeStep(const TStroke &s, double pixelSize)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double minVal = (std::numeric_limits<double>::max)();</double>
Toshihiro Shimizu 890ddd
	double tempVal;
Toshihiro Shimizu 890ddd
	for (int i = 0; i < s.getChunkCount(); ++i)
Toshihiro Shimizu 890ddd
		if ((tempVal = computeStep(*s.getChunk(i), pixelSize)) < minVal)
Toshihiro Shimizu 890ddd
			minVal = tempVal;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return minVal;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
TRasterP prepareTexture(const TRasterP &ras, TextureInfoForGL &texinfo)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TDimension size = ras->getSize();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	texinfo.width = size.lx;
Toshihiro Shimizu 890ddd
	texinfo.height = size.ly;
Toshihiro Shimizu 890ddd
	texinfo.internalformat = ras->getPixelSize();
Toshihiro Shimizu 890ddd
	texinfo.format = GL_UNSIGNED_BYTE;
Toshihiro Shimizu 890ddd
	texinfo.pixels = ras->getRawData();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	switch (texinfo.internalformat) {
Toshihiro Shimizu 890ddd
	case 1:
Toshihiro Shimizu 890ddd
		texinfo.type = GL_LUMINANCE;
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	case 2:
Toshihiro Shimizu 890ddd
		texinfo.type = GL_LUMINANCE_ALPHA;
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (texinfo.internalformat > 2) {
Toshihiro Shimizu 890ddd
		switch (texinfo.internalformat) {
Toshihiro Shimizu 890ddd
		case 3:
Toshihiro Shimizu 890ddd
			texinfo.type = GL_RGB;
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
		case 4:
Toshihiro Shimizu 890ddd
			texinfo.type = GL_RGBA;
Toshihiro Shimizu 890ddd
			break; // GL_RGBA;  break;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef TNZ_MACHINE_CHANNEL_ORDER_BGRM // under win32 pixel are in reverse order
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef GL_EXT_bgra // if extension exists...
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// and it's  present at run time all okay
Toshihiro Shimizu 890ddd
		// if(TGLArea::isBGRASupported())
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			switch (texinfo.internalformat) {
Toshihiro Shimizu 890ddd
			case 3:
Toshihiro Shimizu 890ddd
				texinfo.type = GL_BGR_EXT;
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			case 4:
Toshihiro Shimizu 890ddd
				texinfo.type = GL_BGRA_EXT;
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			return ras;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TDimension size = ras->getSize();
Toshihiro Shimizu 890ddd
		TRasterP outRas = ras->clone();
Toshihiro Shimizu 890ddd
		outRas->lock();
Toshihiro Shimizu 890ddd
		int pixelSize = ras->getPixelSize();
Toshihiro Shimizu 890ddd
		texinfo.pixels = outRas->getRawData();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		UCHAR *p1, *p2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (int i = 0; i < size.lx; ++i)
Toshihiro Shimizu 890ddd
			for (int j = 0; j < size.ly; ++j) {
Toshihiro Shimizu 890ddd
				p1 = outRas->getRawData(i, j);
Toshihiro Shimizu 890ddd
				p2 = p1 + 2;
Toshihiro Shimizu 890ddd
				std::swap(*p1, *p2);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		outRas->unlock();
Toshihiro Shimizu 890ddd
		return outRas;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#elif defined(TNZ_MACHINE_CHANNEL_ORDER_MRGB)
Toshihiro Shimizu 890ddd
//mrgb
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#warning "ottimizzare in qualche modo"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TDimension size = ras->getSize();
Toshihiro Shimizu 890ddd
		TRasterP outRas = ras->clone();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		texinfo.pixels = outRas->getRawData();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		lefttRotateBits((UCHAR *)texinfo.pixels, size.lx * size.ly);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		return outRas;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	texinfo.pixels = ras->getRawData();
Toshihiro Shimizu 890ddd
	return ras;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void drawStrokeCenterline(const TStroke &stroke,
Toshihiro Shimizu 890ddd
						  double pixelSize,
Toshihiro Shimizu 890ddd
						  double from,
Toshihiro Shimizu 890ddd
						  double to)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int
Toshihiro Shimizu 890ddd
		c1 = 0,
Toshihiro Shimizu 890ddd
		c2 = 0;
Toshihiro Shimizu 890ddd
	double
Toshihiro Shimizu 890ddd
		t1 = 1.0,
Toshihiro Shimizu 890ddd
		t2 = 0.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (stroke.getChunkCount() == 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	stroke.getChunkAndT(from, c1, t1);
Toshihiro Shimizu 890ddd
	stroke.getChunkAndT(to, c2, t2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (c1 == c2) {
Toshihiro Shimizu 890ddd
		if (from == to)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		drawQuadraticCenterline(*stroke.getChunk(c1),
Toshihiro Shimizu 890ddd
								pixelSize,
Toshihiro Shimizu 890ddd
								t1,
Toshihiro Shimizu 890ddd
								t2);
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		// partial first chunk
Toshihiro Shimizu 890ddd
		drawQuadraticCenterline(*stroke.getChunk(c1),
Toshihiro Shimizu 890ddd
								pixelSize,
Toshihiro Shimizu 890ddd
								t1,
Toshihiro Shimizu 890ddd
								1.0);
Toshihiro Shimizu 890ddd
		// next chunk
Toshihiro Shimizu 890ddd
		++c1;
Toshihiro Shimizu 890ddd
		if (c1 < c2) {
Toshihiro Shimizu 890ddd
			for (int i = c1;
Toshihiro Shimizu 890ddd
				 i < c2;
Toshihiro Shimizu 890ddd
				 ++i)
Toshihiro Shimizu 890ddd
				drawQuadraticCenterline(*stroke.getChunk(i),
Toshihiro Shimizu 890ddd
										pixelSize,
Toshihiro Shimizu 890ddd
										0.0,
Toshihiro Shimizu 890ddd
										1.0);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// partial last chunk
Toshihiro Shimizu 890ddd
		drawQuadraticCenterline(*stroke.getChunk(c2),
Toshihiro Shimizu 890ddd
								pixelSize,
Toshihiro Shimizu 890ddd
								0.0,
Toshihiro Shimizu 890ddd
								t2);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI TStroke *makeEllipticStroke(double thick, TPointD center, double radiusX, double radiusY)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::vector<tthickpoint> points(17);</tthickpoint>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double xmin = center.x - radiusX; // x coordinate of the upper left corner of the bounding rectangle
Toshihiro Shimizu 890ddd
	double ymin = center.y - radiusY; // y coordinate of the upper left corner of the bounding rectangle
Toshihiro Shimizu 890ddd
	double xmax = center.x + radiusX; // x coordinate of the bottom right corner of the bounding rectangle
Toshihiro Shimizu 890ddd
	double ymax = center.y + radiusY; // y coordinate of the bottom right corner of the bounding rectangle
Toshihiro Shimizu 890ddd
	const double C1 = 0.1465;		  // magic number for coefficient1
Toshihiro Shimizu 890ddd
	const double C2 = 0.2070;		  // magic number for coefficient2
Toshihiro Shimizu 890ddd
	double dx = xmax - xmin;		  // dx is width diameter
Toshihiro Shimizu 890ddd
	double dy = ymax - ymin;		  // dy is height diameter
Toshihiro Shimizu 890ddd
	const double begin = 0.8535;	  // starting position to draw (bounding square is 1x1)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double c1dx = (double)(C1 * dx);
Toshihiro Shimizu 890ddd
	double c1dy = (double)(C1 * dy);
Toshihiro Shimizu 890ddd
	double c2dx = (double)(C2 * dx);
Toshihiro Shimizu 890ddd
	double c2dy = (double)(C2 * dy);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	points[0] = TThickPoint(xmin + begin * dx, ymin + begin * dy, thick);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	points[1] = points[0] + TThickPoint(-c1dx, c1dy, 0);  //
Toshihiro Shimizu 890ddd
	points[2] = points[1] + TThickPoint(-c2dx, 0, 0);	 //
Toshihiro Shimizu 890ddd
	points[3] = points[2] + TThickPoint(-c2dx, 0, 0);	 //
Toshihiro Shimizu 890ddd
	points[4] = points[3] + TThickPoint(-c1dx, -c1dy, 0); //
Toshihiro Shimizu 890ddd
	points[5] = points[4] + TThickPoint(-c1dx, -c1dy, 0); //
Toshihiro Shimizu 890ddd
	points[6] = points[5] + TThickPoint(0, -c2dy, 0);	 //
Toshihiro Shimizu 890ddd
	points[7] = points[6] + TThickPoint(0, -c2dy, 0);	 //
Toshihiro Shimizu 890ddd
	points[8] = points[7] + TThickPoint(c1dx, -c1dy, 0);  //
Toshihiro Shimizu 890ddd
	points[9] = points[8] + TThickPoint(c1dx, -c1dy, 0);  //
Toshihiro Shimizu 890ddd
	points[10] = points[9] + TThickPoint(c2dx, 0, 0);	 //
Toshihiro Shimizu 890ddd
	points[11] = points[10] + TThickPoint(c2dx, 0, 0);	//
Toshihiro Shimizu 890ddd
	points[12] = points[11] + TThickPoint(c1dx, c1dy, 0); //
Toshihiro Shimizu 890ddd
	points[13] = points[12] + TThickPoint(c1dx, c1dy, 0); //
Toshihiro Shimizu 890ddd
	points[14] = points[13] + TThickPoint(0, c2dy, 0);	//
Toshihiro Shimizu 890ddd
	points[15] = points[14] + TThickPoint(0, c2dy, 0);	//
Toshihiro Shimizu 890ddd
	points[16] = points[0];								  // need to be closed!!!
Toshihiro Shimizu 890ddd
														  //points[15]+TThickPoint(-c1dx,  c1dy,0);//
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStroke *stroke = new TStroke(points);
Toshihiro Shimizu 890ddd
	stroke->setSelfLoop();
Toshihiro Shimizu 890ddd
	return stroke;
Toshihiro Shimizu 890ddd
}