Пример #1
0
static void   draw(void)
{ 
   int      yl, yyl; 
   int     l; 

   if ((tpc == 2) && (se != 0) && (se1 != 0)) tpc = 3; 

   ku = 0; 

   if ((tpc == 2) && (kl == 3)) yyl = y[7];  else yyl = y[8];

   if (((tpc == 3) && (kl == elongl(0) + 3))) yl = y[8];
   else
   if (((tpc < 3) || ((kt > 0) && (ks == 0))) &&
       ((kn[0].ty == 0) || ((kn[0].e2 < 0) &&
       (kn[0].e3 < 0)) || ((tpc == 2) &&
       (kn[0].e2 < 0) && (kn[-(kn[0].e2)].ty == 0)))) 
      { yl = y[5]; ku = 1; }
   else yl = y[7]; 


   if ((tpc == 2) && (kl == 4) && (kk == 1))  { yyl = y[6]; yl = y[5]; } 

   if ((tpc == 2)) 
      if (((tpc == 2) && (kl == 4) && (kk == 1)) || 
          (kn[0].e2 < 0) && (kn[0].e3 < 0)) 
         { 
            mline(x[0],y[7],x[2],yl,0,kn[0].pt,0);
            mline(x[0],y[3],x[2],yl,0,kn[0].e1,0);
            knot1(0,&yl,&yyl); 
         }
      else
         {
            mline(x[0],yl - yh,x[1],yl,0,kn[0].pt,0);
            mline(x[0],yl + yh,x[1],yl,0,kn[0].e1,0);
            l = kn[0].e2;
            if (l < 0)
            { 
               if(ku == 1) mline(x[1],yl,x[2],yl,3,kn[-l].pt,0);
               else        mline(x[1],yl,x[2],yl,1,kn[-l].pt,0);
               knot1(l,&yl,&yyl);
            } 
            else knot2(&yl,&yyl); 
         } 
   else 
   if (((tpc == 3) && ((kt == 0) || (ks != 0)) &&
       (kl != elongl(0) + 3)) || (tpc == 1) && 
       (kn[0].e2 < 0) && (kn[-(kn[0].e2)].ty == 0)) 
      {
         mline(x[0],yl,x[1],yl,0,kn[0].pt,0);
         knot2(&yl,&yyl); 
      }
   else
      {
         mline(x[0],yl,x[2],yl,0,kn[0].pt,0);
         knot1(0,&yl,&yyl);
      }
}
Пример #2
0
//*******************************************************************************************************/
//* FileName:		clPlot.cpp
//*
//* Contents:		Implementation of clPlot, axis, legend, serie and timeaxis
//*
//* NOTE 1:			Only a minimum of parameter validation is implemented to save time since this plot is 
//*					time critical.
//*
//* NOTE 2:			All functionality is not fully implemented.
//*
//* Author:			Jan Vidar Berger
//*******************************************************************************************************/
//* 12.feb.98	Jan Vidar Berger	Implemented flicker free drawing. Thanks to John Kim for providing 
//*									the CGridMemDC and to Keith Rule, the author of CMemDC.
//*******************************************************************************************************/

#include "stdafx.h"
#include "clPlot.h"
#include "GridMemDC.h"

#include "malloc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

long	clPlot::m_lMaxDataPrSerie;	// max allowed data pr. serie.
long	clPlot::m_lMaxDataTotal;	// max allowed data total.

//*******************************************************************************************************/
//* time axis threshold. contains grid and label intervals to be used within specified
//* seconds pr. pixels thresholds. The array is terminated by a 'bIAmInUse'=FALSE.
//*******************************************************************************************************/
struct{
	BOOL	bIAmInUse;					// indicate valid entry, last=FALSE
	long	lgridinterval;				// grid line interval in seconds
	long	llabelinterval;				// time label interval in seconds
	long	lmodethreshold;				// mode threshold in seconds pr. pixel
}gridsetting[]={
	TRUE, 1, 4,	0,						// 0: pr. second

	FALSE, 1, 1,0,						// last entry in table
};

//*******************************************************************************************************/
//* Function:		serie::serie
//*******************************************************************************************************/
serie::serie()
{
	m_bIAmInUse		= FALSE;
	m_color			= RGB(0,0,0);
	m_iLineStyle	= PS_SOLID;
	m_bRightAxisAlign	= FALSE;
	m_lNoValues		= 0;
	m_lbegin		= 0;
	m_lend			= 0;
	m_pvalues		= NULL;

}

//*******************************************************************************************************/
//* Function:		serie::~serie
//*******************************************************************************************************/
serie::~serie()
{
	if(m_pvalues !=NULL)
		free(m_pvalues);
}

//*******************************************************************************************************/
//* Function:		serie::AddPoint
//*
//* Description:	AddPoint add new data to the end of a data serie. It will simply append the data,
//*					update the list index and get out. 
//*
//*					This function will also call realloc or malloc to re-size or create the plot array as
//*					needed.
//*
//*					The nice thing about circular lists is that they are multi thread enabled as is. You
//*					must however implement a syncronization mechanism if more than one thread is supposed
//*					to enter data into the plot.
//*
//* Parameters:		valuetime		Time (x value).
//*					y				y value
//*
//* Return Value:	-none-
//*
//* Author:			Jan Vidar Berger
//*******************************************************************************************************/
void serie::AddPoint(CTime &valuetime , double &y)
{
	if(m_lNoValues > 0)
		m_pvalues = (value*)realloc(m_pvalues, (m_lNoValues+1)*sizeof(value));
	else
		m_pvalues = (value*)malloc((m_lNoValues+1)*sizeof(value));

	m_pvalues[m_lend].ValueTime = valuetime;
	m_pvalues[m_lend].dValue	= y;
	m_lNoValues++;
	m_lend++;
	if(m_lend >= clPlot::m_lMaxDataPrSerie)
		m_lend=0;
	if(m_lbegin == m_lend){
		m_lbegin++;
		if(m_lbegin >= clPlot::m_lMaxDataPrSerie)
			m_lbegin=0;
	}
}

//*******************************************************************************************************/
//* Function:		serie::Reset
//*
//* Description:	Reset the serie. Remove data and reset indexes and pointers.
//*
//* Parameters:		-none-
//*
//* Return Value:	-none-
//*
//* Author:			Jan Vidar Berger
//*******************************************************************************************************/
void serie::Reset()
{
	m_lNoValues=0;

	if(m_pvalues !=NULL)
		free(m_pvalues);

	m_pvalues = NULL;

	m_lbegin		= 0;
	m_lend			= 0;
}

//*******************************************************************************************************/
//*******************************************************************************************************/
clPlot::clPlot()
{
	m_ctlBkColor		= RGB(255,255,255);
	m_plotBkColor		= RGB(255,255,255);
	m_legendBkColor		= RGB(255,255,255);
	m_gridColor			= RGB(127,127,127);
	m_bctlBorder		= TRUE;
	m_bplotBorder		= TRUE;
	m_blegendBorder		= TRUE;
	m_bPrimaryLegend	= FALSE;
	m_bSecondaryLegend	= FALSE;
	m_bAxisLY			= TRUE;
	m_bAxisRY			= TRUE;
	m_bAxisBX			= TRUE;
	m_bAutoScrollX		= FALSE;
	m_bSimMode			= FALSE;

	m_lMaxDataPrSerie	= 10000;
	m_lMaxDataTotal		= 100000;
	m_dNoData			= 0.0;

	m_dzoom				= 1.0;
	
	lArraySize			= 1000;			// only points with differebt x,y will be put into the array

	pLineArray			= new CPoint[lArraySize];
	SetBXRange(CTime::GetCurrentTime()-CTimeSpan(60),CTime::GetCurrentTime());

	m_logFont.lfHeight			= -13;
	m_logFont.lfWidth			= 0;
	m_logFont.lfEscapement		= 0;
	m_logFont.lfOrientation		= 0;
	m_logFont.lfWeight			= 400;
	m_logFont.lfItalic			= FALSE;
	m_logFont.lfUnderline		= FALSE;
	m_logFont.lfStrikeOut		= FALSE;
	m_logFont.lfCharSet			= ANSI_CHARSET;
	m_logFont.lfOutPrecision	= OUT_DEFAULT_PRECIS;
	m_logFont.lfClipPrecision	= CLIP_DEFAULT_PRECIS;
	m_logFont.lfQuality			= PROOF_QUALITY;
	m_logFont.lfPitchAndFamily	= DEFAULT_PITCH;
	wcscpy(m_logFont.lfFaceName,_T("Ariel"));

	m_zoomFont.lfHeight			= -13;
	m_zoomFont.lfWidth			= 0;
	m_zoomFont.lfEscapement		= 0;
	m_zoomFont.lfOrientation		= 0;
	m_zoomFont.lfWeight			= 400;
	m_zoomFont.lfItalic			= FALSE;
	m_zoomFont.lfUnderline		= FALSE;
	m_zoomFont.lfStrikeOut		= FALSE;
	m_zoomFont.lfCharSet			= ANSI_CHARSET;
	m_zoomFont.lfOutPrecision	= OUT_DEFAULT_PRECIS;
	m_zoomFont.lfClipPrecision	= CLIP_DEFAULT_PRECIS;
	m_zoomFont.lfQuality			= PROOF_QUALITY;
	m_zoomFont.lfPitchAndFamily	= DEFAULT_PITCH;
	wcscpy(m_zoomFont.lfFaceName,_T("Ariel"));

	m_font.CreateFontIndirect(&m_zoomFont);
}

//*******************************************************************************************************/
//*******************************************************************************************************/
clPlot::~clPlot()
{
	delete [] pLineArray;
}


//*******************************************************************************************************/
//*******************************************************************************************************/
BEGIN_MESSAGE_MAP(clPlot, CWnd)
	//{{AFX_MSG_MAP(clPlot)
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//*******************************************************************************************************/
//*******************************************************************************************************/
BOOL clPlot::Create(DWORD dwstyle, CRect &rect, CWnd *pParent, UINT id)
{
	DWORD style = dwstyle & (~WS_BORDER);
	if(dwstyle & WS_BORDER)
		m_bctlBorder=TRUE;
	else
		m_bctlBorder=FALSE;

	if(!CWnd::Create(NULL, _T(""), style, rect, pParent, id, NULL))
		return FALSE;

	
	m_ctlRect = rect;
	pParent->ClientToScreen(m_ctlRect);
	ScreenToClient(m_ctlRect);

	ComputeRects(TRUE);
	return TRUE;
}

//*******************************************************************************************************/
//* Function        : clPlot::ComputeRects
//*
//* Description	    : Compute rects used for internal possitioning of different objects. This function is 
//*					  called when the plot is created or sized.
//*
//* Return type	    : void 
//*
//* Parameter(s)    : bInitialization		indicate wherever parameters that can be changed abu the user
//*											also should be computed.
//*
//* Author          : Jan Vidar Berger
//*******************************************************************************************************/
void clPlot::ComputeRects(BOOL bInitialization)
{
	// adjust the client rect for borders

	//GetClientRect(m_ctlRect);
	CClientDC dc(this);
	int w = 0;
	int n=0;
	CSize z=dc.GetTextExtent(CString("A"));
//	m_TextHeight = z.cy;

	m_dzoom = ((double)m_ctlRect.Height()/(double)z.cy) / 25.0;

	m_zoomFont.lfWidth = (int)(m_logFont.lfWidth * m_dzoom);
	m_zoomFont.lfHeight = (int)(m_logFont.lfHeight * m_dzoom);
	m_font.Detach();
	m_font.CreateFontIndirect(&m_zoomFont);
	CFont *oFont = dc.SelectObject(&m_font);
//	SetFont(&m_font);
	z=dc.GetTextExtent(CString("A"));
	m_TextHeight = z.cy;
	if(m_bctlBorder){
		m_clientRect.left = m_ctlRect.left+2;
		m_clientRect.right = m_ctlRect.right-2;
		m_clientRect.top = m_ctlRect.top+2;
		m_clientRect.bottom = m_ctlRect.bottom-2;
	}else{
		m_clientRect = m_ctlRect;
	}

	if(bInitialization)
	{
		m_iMtop = m_iMbottom = m_clientRect.Height()/10;
		m_iMleft = m_iMright = m_clientRect.Width()/10;
	}

	// compute plot rect.
	m_plotRect.left = m_clientRect.left + m_iMleft;
	m_plotRect.right = m_clientRect.right - m_iMright;
	m_plotRect.top = m_clientRect.top + m_iMtop;
	m_plotRect.bottom = m_clientRect.bottom - m_iMbottom;

	// compute default legend possition

	if(bInitialization)
	{
		m_legendRect.left = m_plotRect.left + (m_iMleft/5);
		m_legendRect.right = m_plotRect.left + (m_plotRect.Width()/5);
		m_legendRect.top = m_plotRect.top - (m_iMtop/2);
		m_legendRect.bottom = m_plotRect.top + (m_iMtop);
		int w = 0;
		int n=0;
		for(int x = 0; x< MAXLEGENDS;x++){
			if(m_primarylegends[x].m_bIAmInUse){
				n++;
				z=dc.GetTextExtent(CString(m_primarylegends[x].m_szTitle));
				if(z.cx > w )
					w=z.cx;
//				m_TextHeight = z.cy;
			}
		}

		m_legendRect.right = m_legendRect.left + 40 + w;
		m_legendRect.bottom = m_legendRect.top + 10 + (m_TextHeight*n);
	}

	// compute left axis area
	m_axisLYRect.left = m_clientRect.left + (m_iMleft/5);
	m_axisLYRect.right = m_plotRect.left;
	m_axisLYRect.top = m_plotRect.top;
	m_axisLYRect.bottom = m_plotRect.bottom;

	// compute right axis area
	m_axisRYRect.left =  m_plotRect.left;
	m_axisRYRect.right = m_clientRect.right - (m_iMright/5);
	m_axisRYRect.top = m_plotRect.top;
	m_axisRYRect.bottom = m_plotRect.bottom;

	// compute bottom axis area
	m_axisBXRect.left = m_plotRect.left;
	m_axisBXRect.right = m_plotRect.right;
	m_axisBXRect.top = m_plotRect.bottom;
	m_axisBXRect.bottom = m_clientRect.bottom - (m_iMbottom/5);

//	if(bInitialization)
//	{
		m_timeaxis.m_dSecondsPrPixel = ((double)(m_timeaxis.m_maxtime.GetTime() - m_timeaxis.m_mintime.GetTime())) / (double)m_plotRect.Width();
		m_leftaxis.m_dValuePrPixel   = ((double)(m_leftaxis.maxrange- m_leftaxis.minrange) / (double)m_plotRect.Height());
		m_rightaxis.m_dValuePrPixel   = ((double)(m_rightaxis.maxrange- m_rightaxis.minrange) / (double)m_plotRect.Height());
//	}
	dc.SelectObject(oFont);
}

//*******************************************************************************************************/
//* Function:		clPlot::OnPaint
//*
//* Description:	This function will create a memory image, call Draw to draw the plot on it, and when
//*					copy the image into memory.
//*
//*					This is fast and provides flicker free plot update.
//*
//* Author:			Jan Vidar Berger
//*******************************************************************************************************/
void clPlot::OnPaint() 
{
        CPaintDC dc(this); // device context for painting
        CGridMemDC  pdc(&dc);  // non flickering painting

        Draw(&pdc);
		
		// Do not call CWnd::OnPaint() for painting messages
}

BOOL clPlot::OnEraseBkgnd(CDC* pDC) 
{
		return FALSE;
}

//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::Draw(CDC * dc)
{
	CFont *oFont = dc->SelectObject(&m_font);
	DrawBasic(dc);
	DrawGrid(dc);
	DrawPlot(dc);
	DrawLegend(dc);
	dc->SelectObject(oFont);
}

//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::DrawBasic(CDC * dc)
{
	CBrush brushctlBkColor(m_ctlBkColor);
	dc->FillRect(m_ctlRect,&brushctlBkColor);
	if(m_bctlBorder)
	{
		dc->DrawEdge(m_ctlRect,BDR_SUNKENINNER|BDR_SUNKENOUTER, BF_RECT); 
	}
	dc->Rectangle(m_plotRect);
	DrawLegendShadow(dc);
}

//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::DrawPlot(CDC * dc)
{
	for(int s=0;s<MAXSERIES;s++)
	{
		if(m_series[s].m_bIAmInUse)
		{
			DrawSerie(dc, s);
		}
	}
}

//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::DrawSerie(CDC *dc,int s)
{
	BOOL bMore=TRUE;
	BOOL bDraw;
	CPoint p;
	int ly;
	// lets get some serie parameters now and save the time of indexing during the loop
	long y = m_series[s].m_lbegin;
	long m = m_series[s].m_lend;
	long a = m_series[s].m_lNoValues;
	BOOL bRightAxis = m_series[s].m_bRightAxisAlign;
	CPen pen(m_series[s].m_iLineStyle, 1, m_series[s].m_color);
	CPen *old = dc->SelectObject(&pen);
	while(bMore){
		bDraw=FALSE;
		bMore=FALSE;
		ly=0;
		while(y != m && !bDraw){
			if(m_series[s].m_pvalues[y].dValue == m_dNoData)
			{
				bDraw = TRUE;
				bMore = TRUE;
			}else{
//				Scaling. We do scaling inline to save some time
				time_t valuetime = m_series[s].m_pvalues[y].ValueTime.GetTime();
				p.x = (int)(m_plotRect.left + ((valuetime-m_timeaxis.m_mintime.GetTime())/m_timeaxis.m_dSecondsPrPixel));
				
				if(bRightAxis){
					p.y = (int)(m_plotRect.bottom - ((m_series[s].m_pvalues[y].dValue-m_rightaxis.minrange)/m_rightaxis.m_dValuePrPixel));
				}else{
					p.y = (int)(m_plotRect.bottom - ((m_series[s].m_pvalues[y].dValue-m_leftaxis.minrange)/m_leftaxis.m_dValuePrPixel));
				}

				if((ly == 0 || p.x != pLineArray[ly].x || p.y != pLineArray[ly].y)
					&& (p.x >= m_plotRect.left && p.x <= m_plotRect.right))
				{
					pLineArray[ly].x = p.x;
					pLineArray[ly].y = p.y;
					ly++;
				}
			}
			y++;
			if(y > a)	// wrap list index ?
				y=0;
		}
		if(ly > 0){
			dc->Polyline(pLineArray, ly);
		}
	}
	dc->SelectObject(old);
}

//*******************************************************************************************************/
//*
//*******************************************************************************************************/
void clPlot::DrawGrid(CDC * dc)
{
	DrawXAxisGrid(dc);
	DrawYAxisGrid(dc);
}

//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::DrawYAxisGrid(CDC * dc)
{
	double yGrid = m_leftaxis.minrange;
	double delta = 25.0 + (long)(((m_leftaxis.m_dValuePrPixel)))*25;
	if((long)delta%50 != 0 && delta > 20.0)
		delta +=25;
	double d10 = delta / 5.0;
	// todo: delta switch
	long diff = ((long)yGrid)%((long)delta);
	yGrid = yGrid - diff;
	CPen *old, pen(PS_SOLID, 1, m_gridColor);
	CPen stick(PS_SOLID,0,RGB(0,0,0));
	CPen mline(PS_SOLID,0,RGB(192,192,192));

	for( long sy = (long)((long)(m_leftaxis.minrange) - diff); sy < m_leftaxis.maxrange; sy+=(long)d10)
	{
		int off=3;
		if((long)sy%(long)delta == 0){
			off=5;
		}
		if(sy > m_leftaxis.minrange){
			int y = (int)(m_plotRect.bottom - ((sy-m_leftaxis.minrange)/m_leftaxis.m_dValuePrPixel));
			old = dc->SelectObject(&stick); 
			dc->MoveTo(CPoint(m_plotRect.left,y));
			dc->LineTo(CPoint(m_plotRect.left-off,y));
			dc->MoveTo(CPoint(m_plotRect.right,y));
			dc->LineTo(CPoint(m_plotRect.right+off,y));
			dc->SelectObject(old);

			old = dc->SelectObject(&mline);
			dc->MoveTo(CPoint(m_plotRect.left+1,y));
			dc->LineTo(CPoint(m_plotRect.right-1,y));
			dc->SelectObject(old);
		}
	}

	old = dc->SelectObject(&pen);
	while(yGrid <= m_leftaxis.maxrange)
	{
		double yy = m_plotRect.bottom - ((yGrid-m_leftaxis.minrange)/m_leftaxis.m_dValuePrPixel);
		int y = (int)yy;
		if(yGrid > m_leftaxis.minrange && yGrid<m_leftaxis.maxrange){
			dc->MoveTo(CPoint(m_plotRect.left+1,y));
			dc->LineTo(CPoint(m_plotRect.right-1,y));
		}

		TCHAR b[100];
		swprintf(b, _T("%.0f"), yGrid);
		dc->DrawText(b, CRect(m_clientRect.left, y-m_TextHeight/2,m_plotRect.left-5,y+m_TextHeight/2), DT_RIGHT|DT_BOTTOM);

		double yr = (m_plotRect.bottom - yy) * m_rightaxis.m_dValuePrPixel + m_rightaxis.minrange;
		swprintf(b, _T("%.0f"), yr);
		dc->DrawText(b, CRect(m_plotRect.right+5, y-m_TextHeight/2,m_clientRect.right,y+m_TextHeight/2), DT_LEFT|DT_BOTTOM);

		yGrid += delta;
	}
	dc->SelectObject(old);
}
Пример #3
0
void bouncer::draw()
{
  int i;

  for (i=0; i < 12; i++){
    lin[i].line3D = lines[i];
    mline(&lin[i]);
  }
}
Пример #4
0
//*******************************************************************************************************/
//* FileName:		clPlot.cpp
//*
//* Contents:		Implementation of clPlot, axis, legend, serie and timeaxis
//*
//* NOTE 1:			Only a minimum of parameter validation is implemented to save time since this plot is 
//*					time critical.
//*
//* NOTE 2:			All functionality is not fully implemented.
//*
//* Author:			Jan Vidar Berger
//*******************************************************************************************************/
//* 12.feb.98	Jan Vidar Berger	Implemented flicker free drawing. Thanks to John Kim for providing 
//*									the CGridMemDC and to Keith Rule, the author of CMemDC.
//*******************************************************************************************************/

#include "stdafx.h"
#include "clPlot.h"
#include "GridMemDC.h"

#include "malloc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

long	clPlot::m_lMaxDataPrSerie;	// max allowed data pr. serie.
long	clPlot::m_lMaxDataTotal;	// max allowed data total.

//*******************************************************************************************************/
//* time axis threshold. contains grid and label intervals to be used within specified
//* seconds pr. pixels thresholds. The array is terminated by a 'bIAmInUse'=FALSE.
//*******************************************************************************************************/
struct{
	BOOL	bIAmInUse;					// indicate valid entry, last=FALSE
	long	lgridinterval;				// grid line interval in seconds
	long	llabelinterval;				// time label interval in seconds
	long	lmodethreshold;				// mode threshold in seconds pr. pixel
}gridsetting[]={
	TRUE, 1, 4,	0,						// 0: pr. second

	FALSE, 1, 1,0,						// last entry in table
};

//*******************************************************************************************************/
//* Function:		serie::serie
//*******************************************************************************************************/
serie::serie()
{
	m_bIAmInUse		= FALSE;
	m_color			= RGB(0,0,0);
	m_iLineStyle	= PS_SOLID;
	m_bRightAxisAlign	= FALSE;
	m_lNoValues		= 0;
	m_lbegin		= 0;
	m_lend			= 0;
	m_pvalues		= NULL;

}

//*******************************************************************************************************/
//* Function:		serie::~serie
//*******************************************************************************************************/
serie::~serie()
{
	if(m_pvalues !=NULL)
		free(m_pvalues);
}

//*******************************************************************************************************/
//* Function:		serie::AddPoint
//*
//* Description:	AddPoint add new data to the end of a data serie. It will simply append the data,
//*					update the list index and get out. 
//*
//*					This function will also call realloc or malloc to re-size or create the plot array as
//*					needed.
//*
//*					The nice thing about circular lists is that they are multi thread enabled as is. You
//*					must however implement a syncronization mechanism if more than one thread is supposed
//*					to enter data into the plot.
//*
//* Parameters:		valuetime		Time (x value).
//*					y				y value
//*
//* Return Value:	-none-
//*
//* Author:			Jan Vidar Berger
//*******************************************************************************************************/
void serie::AddPoint(CTime &valuetime , double &y)
{
	if(m_lNoValues > 0)
		m_pvalues = (value*)realloc(m_pvalues, (m_lNoValues+1)*sizeof(value));
	else
		m_pvalues = (value*)malloc((m_lNoValues+1)*sizeof(value));

	m_pvalues[m_lend].ValueTime = valuetime;
	m_pvalues[m_lend].dValue	= y;
	m_lNoValues++;
	m_lend++;
	if(m_lend >= clPlot::m_lMaxDataPrSerie)
		m_lend=0;
	if(m_lbegin == m_lend){
		m_lbegin++;
		if(m_lbegin >= clPlot::m_lMaxDataPrSerie)
			m_lbegin=0;
	}
}

//*******************************************************************************************************/
//* Function:		serie::Reset
//*
//* Description:	Reset the serie. Remove data and reset indexes and pointers.
//*
//* Parameters:		-none-
//*
//* Return Value:	-none-
//*
//* Author:			Jan Vidar Berger
//*******************************************************************************************************/
void serie::Reset()
{
	m_lNoValues=0;

	if(m_pvalues !=NULL)
		free(m_pvalues);

	m_pvalues = NULL;

	m_lbegin		= 0;
	m_lend			= 0;
}

//*******************************************************************************************************/
//*******************************************************************************************************/
clPlot::clPlot()
{
	m_ctlBkColor		= RGB(255,255,255);
	m_plotBkColor		= RGB(255,255,255);
	m_legendBkColor		= RGB(255,255,255);
	m_gridColor			= RGB(127,127,127);
	m_bctlBorder		= TRUE;
	m_bplotBorder		= TRUE;
	m_blegendBorder		= TRUE;
	m_bPrimaryLegend	= FALSE;
	m_bSecondaryLegend	= FALSE;
	m_bAxisLY			= TRUE;
	m_bAxisRY			= TRUE;
	m_bAxisBX			= TRUE;
	m_bAutoScrollX		= FALSE;
	m_bSimMode			= FALSE;

	m_lMaxDataPrSerie	= 10000;
	m_lMaxDataTotal		= 100000;
	m_dNoData			= 0.0;

	m_dzoom				= 1.0;
	
	lArraySize			= 1000;			// only points with differebt x,y will be put into the array

	pLineArray			= new CPoint[lArraySize];
	SetBXRange(CTime::GetCurrentTime()-CTimeSpan(60),CTime::GetCurrentTime());

	m_logFont.lfHeight			= -13;
	m_logFont.lfWidth			= 0;
	m_logFont.lfEscapement		= 0;
	m_logFont.lfOrientation		= 0;
	m_logFont.lfWeight			= 400;
	m_logFont.lfItalic			= FALSE;
	m_logFont.lfUnderline		= FALSE;
	m_logFont.lfStrikeOut		= FALSE;
	m_logFont.lfCharSet			= ANSI_CHARSET;
	m_logFont.lfOutPrecision	= OUT_DEFAULT_PRECIS;
	m_logFont.lfClipPrecision	= CLIP_DEFAULT_PRECIS;
	m_logFont.lfQuality			= PROOF_QUALITY;
	m_logFont.lfPitchAndFamily	= DEFAULT_PITCH;
	wcscpy(m_logFont.lfFaceName,_T("Ariel"));

	m_zoomFont.lfHeight			= -13;
	m_zoomFont.lfWidth			= 0;
	m_zoomFont.lfEscapement		= 0;
	m_zoomFont.lfOrientation		= 0;
	m_zoomFont.lfWeight			= 400;
	m_zoomFont.lfItalic			= FALSE;
	m_zoomFont.lfUnderline		= FALSE;
	m_zoomFont.lfStrikeOut		= FALSE;
	m_zoomFont.lfCharSet			= ANSI_CHARSET;
	m_zoomFont.lfOutPrecision	= OUT_DEFAULT_PRECIS;
	m_zoomFont.lfClipPrecision	= CLIP_DEFAULT_PRECIS;
	m_zoomFont.lfQuality			= PROOF_QUALITY;
	m_zoomFont.lfPitchAndFamily	= DEFAULT_PITCH;
	wcscpy(m_zoomFont.lfFaceName,_T("Ariel"));

	m_font.CreateFontIndirect(&m_zoomFont);
}

//*******************************************************************************************************/
//*******************************************************************************************************/
clPlot::~clPlot()
{
	delete [] pLineArray;
}


//*******************************************************************************************************/
//*******************************************************************************************************/
BEGIN_MESSAGE_MAP(clPlot, CWnd)
	//{{AFX_MSG_MAP(clPlot)
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//*******************************************************************************************************/
//*******************************************************************************************************/
BOOL clPlot::Create(DWORD dwstyle, CRect &rect, CWnd *pParent, UINT id)
{
	DWORD style = dwstyle & (~WS_BORDER);
	if(dwstyle & WS_BORDER)
		m_bctlBorder=TRUE;
	else
		m_bctlBorder=FALSE;

	if(!CWnd::Create(NULL, _T(""), style, rect, pParent, id, NULL))
		return FALSE;

	
	m_ctlRect = rect;
	pParent->ClientToScreen(m_ctlRect);
	ScreenToClient(m_ctlRect);

	ComputeRects(TRUE);
	return TRUE;
}

//*******************************************************************************************************/
//* Function        : clPlot::ComputeRects
//*
//* Description	    : Compute rects used for internal possitioning of different objects. This function is 
//*					  called when the plot is created or sized.
//*
//* Return type	    : void 
//*
//* Parameter(s)    : bInitialization		indicate wherever parameters that can be changed abu the user
//*											also should be computed.
//*
//* Author          : Jan Vidar Berger
//*******************************************************************************************************/
void clPlot::ComputeRects(BOOL bInitialization)
{
	// adjust the client rect for borders

	//GetClientRect(m_ctlRect);
	CClientDC dc(this);
	int w = 0;
	int n=0;
	CSize z=dc.GetTextExtent(CString("A"));
//	m_TextHeight = z.cy;

	m_dzoom = ((double)m_ctlRect.Height()/(double)z.cy) / 25.0;

	m_zoomFont.lfWidth = (int)(m_logFont.lfWidth * m_dzoom);
	m_zoomFont.lfHeight = (int)(m_logFont.lfHeight * m_dzoom);
	m_font.Detach();
	m_font.CreateFontIndirect(&m_zoomFont);
	CFont *oFont = dc.SelectObject(&m_font);
//	SetFont(&m_font);
	z=dc.GetTextExtent(CString("A"));
	m_TextHeight = z.cy;
	if(m_bctlBorder){
		m_clientRect.left = m_ctlRect.left+2;
		m_clientRect.right = m_ctlRect.right-2;
		m_clientRect.top = m_ctlRect.top+2;
		m_clientRect.bottom = m_ctlRect.bottom-2;
	}else{
		m_clientRect = m_ctlRect;
	}

	if(bInitialization)
	{
		m_iMtop = m_iMbottom = m_clientRect.Height()/10;
		m_iMleft = m_iMright = m_clientRect.Width()/10;
	}

	// compute plot rect.
	m_plotRect.left = m_clientRect.left + m_iMleft;
	m_plotRect.right = m_clientRect.right - m_iMright;
	m_plotRect.top = m_clientRect.top + m_iMtop;
	m_plotRect.bottom = m_clientRect.bottom - m_iMbottom;

	// compute default legend possition

	if(bInitialization)
	{
		m_legendRect.left = m_plotRect.left + (m_iMleft/5);
		m_legendRect.right = m_plotRect.left + (m_plotRect.Width()/5);
		m_legendRect.top = m_plotRect.top - (m_iMtop/2);
		m_legendRect.bottom = m_plotRect.top + (m_iMtop);
		int w = 0;
		int n=0;
		for(int x = 0; x< MAXLEGENDS;x++){
			if(m_primarylegends[x].m_bIAmInUse){
				n++;
				z=dc.GetTextExtent(CString(m_primarylegends[x].m_szTitle));
				if(z.cx > w )
					w=z.cx;
//				m_TextHeight = z.cy;
			}
		}

		m_legendRect.right = m_legendRect.left + 40 + w;
		m_legendRect.bottom = m_legendRect.top + 10 + (m_TextHeight*n);
	}

	// compute left axis area
	m_axisLYRect.left = m_clientRect.left + (m_iMleft/5);
	m_axisLYRect.right = m_plotRect.left;
	m_axisLYRect.top = m_plotRect.top;
	m_axisLYRect.bottom = m_plotRect.bottom;

	// compute right axis area
	m_axisRYRect.left =  m_plotRect.left;
	m_axisRYRect.right = m_clientRect.right - (m_iMright/5);
	m_axisRYRect.top = m_plotRect.top;
	m_axisRYRect.bottom = m_plotRect.bottom;

	// compute bottom axis area
	m_axisBXRect.left = m_plotRect.left;
	m_axisBXRect.right = m_plotRect.right;
	m_axisBXRect.top = m_plotRect.bottom;
	m_axisBXRect.bottom = m_clientRect.bottom - (m_iMbottom/5);

//	if(bInitialization)
//	{
		m_timeaxis.m_dSecondsPrPixel = ((double)(m_timeaxis.m_maxtime.GetTime() - m_timeaxis.m_mintime.GetTime())) / (double)m_plotRect.Width();
		m_leftaxis.m_dValuePrPixel   = ((double)(m_leftaxis.maxrange- m_leftaxis.minrange) / (double)m_plotRect.Height());
		m_rightaxis.m_dValuePrPixel   = ((double)(m_rightaxis.maxrange- m_rightaxis.minrange) / (double)m_plotRect.Height());
//	}
	dc.SelectObject(oFont);
}

//*******************************************************************************************************/
//* Function:		clPlot::OnPaint
//*
//* Description:	This function will create a memory image, call Draw to draw the plot on it, and when
//*					copy the image into memory.
//*
//*					This is fast and provides flicker free plot update.
//*
//* Author:			Jan Vidar Berger
//*******************************************************************************************************/
void clPlot::OnPaint() 
{
        CPaintDC dc(this); // device context for painting
        CGridMemDC  pdc(&dc);  // non flickering painting

        Draw(&pdc);
		
		// Do not call CWnd::OnPaint() for painting messages
}

BOOL clPlot::OnEraseBkgnd(CDC* pDC) 
{
		return FALSE;
}

//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::Draw(CDC * dc)
{
	CFont *oFont = dc->SelectObject(&m_font);
	DrawBasic(dc);
	DrawGrid(dc);
	DrawPlot(dc);
	DrawLegend(dc);
	dc->SelectObject(oFont);
}

//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::DrawBasic(CDC * dc)
{
	CBrush brushctlBkColor(m_ctlBkColor);
	dc->FillRect(m_ctlRect,&brushctlBkColor);
	if(m_bctlBorder)
	{
		dc->DrawEdge(m_ctlRect,BDR_SUNKENINNER|BDR_SUNKENOUTER, BF_RECT); 
	}
	dc->Rectangle(m_plotRect);
	DrawLegendShadow(dc);
}

//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::DrawPlot(CDC * dc)
{
	for(int s=0;s<MAXSERIES;s++)
	{
		if(m_series[s].m_bIAmInUse)
		{
			DrawSerie(dc, s);
		}
	}
}

//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::DrawSerie(CDC *dc,int s)
{
	BOOL bMore=TRUE;
	BOOL bDraw;
	CPoint p;
	int ly;
	// lets get some serie parameters now and save the time of indexing during the loop
	long y = m_series[s].m_lbegin;
	long m = m_series[s].m_lend;
	long a = m_series[s].m_lNoValues;
	BOOL bRightAxis = m_series[s].m_bRightAxisAlign;
	CPen pen(m_series[s].m_iLineStyle, 1, m_series[s].m_color);
	CPen *old = dc->SelectObject(&pen);
	while(bMore){
		bDraw=FALSE;
		bMore=FALSE;
		ly=0;
		while(y != m && !bDraw){
			if(m_series[s].m_pvalues[y].dValue == m_dNoData)
			{
				bDraw = TRUE;
				bMore = TRUE;
			}else{
//				Scaling. We do scaling inline to save some time
				time_t valuetime = m_series[s].m_pvalues[y].ValueTime.GetTime();
				p.x = (int)(m_plotRect.left + ((valuetime-m_timeaxis.m_mintime.GetTime())/m_timeaxis.m_dSecondsPrPixel));
				
				if(bRightAxis){
					p.y = (int)(m_plotRect.bottom - ((m_series[s].m_pvalues[y].dValue-m_rightaxis.minrange)/m_rightaxis.m_dValuePrPixel));
				}else{
					p.y = (int)(m_plotRect.bottom - ((m_series[s].m_pvalues[y].dValue-m_leftaxis.minrange)/m_leftaxis.m_dValuePrPixel));
				}

				if((ly == 0 || p.x != pLineArray[ly].x || p.y != pLineArray[ly].y)
					&& (p.x >= m_plotRect.left && p.x <= m_plotRect.right))
				{
					pLineArray[ly].x = p.x;
					pLineArray[ly].y = p.y;
					ly++;
				}
			}
			y++;
			if(y > a)	// wrap list index ?
				y=0;
		}
		if(ly > 0){
			dc->Polyline(pLineArray, ly);
		}
	}
	dc->SelectObject(old);
}

//*******************************************************************************************************/
//*
//*******************************************************************************************************/
void clPlot::DrawGrid(CDC * dc)
{
	DrawXAxisGrid(dc);
	DrawYAxisGrid(dc);
}

//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::DrawYAxisGrid(CDC * dc)
{
	double yGrid = m_leftaxis.minrange;
	double delta = 25.0 + (long)(((m_leftaxis.m_dValuePrPixel)))*25;
	if((long)delta%50 != 0 && delta > 20.0)
		delta +=25;
	double d10 = delta / 5.0;
	// todo: delta switch
	long diff = ((long)yGrid)%((long)delta);
	yGrid = yGrid - diff;
	CPen *old, pen(PS_SOLID, 1, m_gridColor);
	CPen stick(PS_SOLID,0,RGB(0,0,0));
	CPen mline(PS_SOLID,0,RGB(192,192,192));

	for( long sy = (long)((long)(m_leftaxis.minrange) - diff); sy < m_leftaxis.maxrange; sy+=(long)d10)
	{
		int off=3;
		if((long)sy%(long)delta == 0){
			off=5;
		}
		if(sy > m_leftaxis.minrange){
			int y = (int)(m_plotRect.bottom - ((sy-m_leftaxis.minrange)/m_leftaxis.m_dValuePrPixel));
			old = dc->SelectObject(&stick); 
			dc->MoveTo(CPoint(m_plotRect.left,y));
			dc->LineTo(CPoint(m_plotRect.left-off,y));
			dc->MoveTo(CPoint(m_plotRect.right,y));
			dc->LineTo(CPoint(m_plotRect.right+off,y));
			dc->SelectObject(old);

			old = dc->SelectObject(&mline);
			dc->MoveTo(CPoint(m_plotRect.left+1,y));
			dc->LineTo(CPoint(m_plotRect.right-1,y));
			dc->SelectObject(old);
		}
	}

	old = dc->SelectObject(&pen);
	while(yGrid <= m_leftaxis.maxrange)
	{
		double yy = m_plotRect.bottom - ((yGrid-m_leftaxis.minrange)/m_leftaxis.m_dValuePrPixel);
		int y = (int)yy;
		if(yGrid > m_leftaxis.minrange && yGrid<m_leftaxis.maxrange){
			dc->MoveTo(CPoint(m_plotRect.left+1,y));
			dc->LineTo(CPoint(m_plotRect.right-1,y));
		}

		TCHAR b[100];
		swprintf(b, _T("%.0f"), yGrid);
		dc->DrawText(b, CRect(m_clientRect.left, y-m_TextHeight/2,m_plotRect.left-5,y+m_TextHeight/2), DT_RIGHT|DT_BOTTOM);

		double yr = (m_plotRect.bottom - yy) * m_rightaxis.m_dValuePrPixel + m_rightaxis.minrange;
		swprintf(b, _T("%.0f"), yr);
		dc->DrawText(b, CRect(m_plotRect.right+5, y-m_TextHeight/2,m_clientRect.right,y+m_TextHeight/2), DT_LEFT|DT_BOTTOM);

		yGrid += delta;
	}
	dc->SelectObject(old);
}

//*******************************************************************************************************/
//*******************************************************************************************************/
void clPlot::DrawXAxisGrid(CDC * dc)
{
	long yGrid = m_timeaxis.m_mintime.GetTime();
	long delta = (long)(10.0 + (long)(((m_timeaxis.m_dSecondsPrPixel)))*10);
	long d10 = (long)(delta / 10.0);
	// todo: delta switch
	long diff = ((long)yGrid)%((long)delta);
	yGrid = yGrid - diff;
	CPen *old, pen(PS_SOLID, 1, m_gridColor);
	CPen stick(PS_SOLID,0,RGB(0,0,0));
	CPen mline(PS_SOLID,0,RGB(192,192,192));

	for( long sx = m_timeaxis.m_mintime.GetTime() - diff; sx < m_timeaxis.m_maxtime.GetTime(); sx+=d10)
	{
		int off=3;
		if((long)sx%(long)delta == 0){
			off=5;
		}
		if(sx > m_timeaxis.m_mintime.GetTime()){
			int x = (int)(m_plotRect.left + ((sx-m_timeaxis.m_mintime.GetTime())/m_timeaxis.m_dSecondsPrPixel));
//			int x = m_plotRect.right - ((sx-m_timeaxis.m_mintime.GetTime())/m_timeaxis.m_lSecondsPrPixel);
			old = dc->SelectObject(&stick); 
			dc->MoveTo(CPoint(x,m_plotRect.bottom));
			dc->LineTo(CPoint(x+off,m_plotRect.bottom));
			dc->SelectObject(old);

			old = dc->SelectObject(&mline);
			dc->MoveTo(CPoint(x,m_plotRect.bottom-1));
			dc->LineTo(CPoint(x,m_plotRect.top+1));
			dc->SelectObject(old);
		}
	}

	old = dc->SelectObject(&pen);
	while(yGrid <= m_timeaxis.m_maxtime.GetTime())
	{
		int x = (int)(m_plotRect.left + ((yGrid-m_timeaxis.m_mintime.GetTime())/m_timeaxis.m_dSecondsPrPixel));

		if(yGrid > m_timeaxis.m_mintime.GetTime() && yGrid<m_timeaxis.m_maxtime.GetTime()){
			dc->MoveTo(CPoint(x,m_plotRect.bottom-1));
			dc->LineTo(CPoint(x,m_plotRect.top+1));
		}

//		char b[100];
//		sprintf(b, "%.0f", yGrid);
//		dc->DrawText(b, CRect(m_clientRect.left, y-m_TextHeight/2,m_plotRect.left-5,y+m_TextHeight/2), DT_RIGHT|DT_BOTTOM);

		yGrid += delta;
	}
	dc->SelectObject(old);
}
Пример #5
0
static void  knot2(int* yl,int* yyl)
{ int     l, m, m1, m2, p1, p2;
  int      yz;

   l = 0;
   yz = *yl;
   { knot *with1 = &kn[-l];
      if (tpc == 2) { m1 = with1->e2; m2 = with1->e3;
                      p1 = with1->n2; p2 = with1->n3; } 
      else { m1 = with1->e1; m2 = with1->e2;
             p1 = with1->n1; p2 = with1->n2; } 
   }

aa: if (tpc == 3) 
      if ((m1 < 0) && (m2 < 0) && (elongl(-m1) < elongl(-m2))) 
         { m = m1; m1 = m2; m2 = m; }

   if ((tpc == 3) && ((l == -se) || (l == -se1))) 
      {
         mline(x[0],*yl,x[1],*yl,0,m1,0);
         m1 = m2; m2 = 0; p1 = p2; 
      } 

   if (m1 > 0) mline(x[1],yz,x[2],*yl,-1,m1,0);
   else mline(x[1],yz,x[2],yz,1,kn[-m1].pt,0);
   pext = p1;
   knot1(m1,&yz,yyl);

   if (m2 == 0) return;

   l = m2;
   yz += ys; 
   if ((yz + ys < *yyl) || ((yz < *yyl) && ((tpc == 1) ||
       (((l == -se) || (l == -se1)) && (kn[-l].e2 < 0))))) 
      yz += ys; 
   { knot *with1 = &kn[-l];
      
         if ((tpc < 3) && (with1->e2 > 0)) 
              mline(x[1],*yl,x[1],yz,-1,with1->pt,0);
         else mline(x[1],*yl,x[1],yz,0,with1->pt,0);
         *yl = yz; 
         m1 = with1->e1; p1 = with1->n1; 
         m2 = with1->e2; p2 = with1->n2; 
         if ((tpc < 3) && (m2 > 0))
            {  mline(x[1],yz,x[2],yz,1,with1->pt,0);
               knot1(l,yl,yyl);
               return;
            }
   }

   goto aa;
}
Пример #6
0
// Creates a SDP body from transport address and list of media descriptors
// Use own list if given media list is 0
MimeSdpBody* SDPSession::createSDP(const char* addr, ObjList* mediaList)
{
    DDebug(m_parser,DebugAll,"SDPSession::createSDP('%s',%p) [%p]",addr,mediaList,this);
    if (!mediaList)
	mediaList = m_rtpMedia;
    // if we got no media descriptors we simply create no SDP
    if (!mediaList)
	return 0;
    if (m_sdpSession)
	++m_sdpVersion;
    else
	m_sdpVersion = m_sdpSession = Time::secNow();

    // no address means on hold or muted
    String origin;
    origin << "yate " << m_sdpSession << " " << m_sdpVersion;
    origin << " IN IP4 " << (addr ? addr : m_host.safe());
    String conn;
    conn << "IN IP4 " << (addr ? addr : "0.0.0.0");

    MimeSdpBody* sdp = new MimeSdpBody;
    sdp->addLine("v","0");
    sdp->addLine("o",origin);
    sdp->addLine("s",m_parser->m_sessionName);
    sdp->addLine("c",conn);
    sdp->addLine("t","0 0");

    Lock lock(m_parser);
    bool defcodecs = m_parser->m_codecs.getBoolValue("default",true);
    for (ObjList* ml = mediaList->skipNull(); ml; ml = ml->skipNext()) {
	SDPMedia* m = static_cast<SDPMedia*>(ml->get());
	String mline(m->fmtList());
	ObjList* l = mline.split(',',false);
	mline = *m;
	mline << " " << (m->localPort() ? m->localPort().c_str() : "0") << " " << m->transport();
	ObjList* map = m->mappings().split(',',false);
	ObjList rtpmap;
	String frm;
	int ptime = 0;
	ObjList* f = l;
	for (; f; f = f->next()) {
	    String* s = static_cast<String*>(f->get());
	    if (s) {
		int mode = 0;
		if (*s == "ilbc20")
		    ptime = mode = 20;
		else if (*s == "ilbc30")
		    ptime = mode = 30;
		else if (*s == "g729b")
		    continue;
		int payload = s->toInteger(SDPParser::s_payloads,-1);
		int defcode = payload;
		String tmp = *s;
		tmp << "=";
		for (ObjList* pl = map; pl; pl = pl->next()) {
		    String* mapping = static_cast<String*>(pl->get());
		    if (!mapping)
			continue;
		    if (mapping->startsWith(tmp)) {
			payload = -1;
			tmp = *mapping;
			tmp >> "=" >> payload;
			XDebug(m_parser,DebugAll,"RTP mapped payload %d for '%s' [%p]",
			    payload,s->c_str(),this);
			break;
		    }
		}
		if (payload >= 0) {
		    if (defcode < 0)
			defcode = payload;
		    const char* map = lookup(defcode,SDPParser::s_rtpmap);
		    if (map && m_parser->m_codecs.getBoolValue(*s,defcodecs && DataTranslator::canConvert(*s))) {
			frm << " " << payload;
			String* temp = new String("rtpmap:");
			*temp << payload << " " << map;
			rtpmap.append(temp);
			if (mode) {
			    temp = new String("fmtp:");
			    *temp << payload << " mode=" << mode;
			    rtpmap.append(temp);
			}
			if (*s == "g729") {
			    temp = new String("fmtp:");
			    *temp << payload << " annexb=" <<
				((0 != l->find("g729b")) ? "yes" : "no");
			    rtpmap.append(temp);
			}
			else if (*s == "amr") {
			    temp = new String("fmtp:");
			    *temp << payload << " octet-align=0";
			    rtpmap.append(temp);
			}
			else if (*s == "amr-o") {
			    temp = new String("fmtp:");
			    *temp << payload << " octet-align=1";
			    rtpmap.append(temp);
			}

			if(s->length()) {
			    String key("fmtp-");
			    key << *s;
			    for(unsigned int i = 0; i < m->length(); ++i) {
				const NamedString *ns = m->getParam(i);
				if(ns && ns->name() == key) {
				    temp = new String("fmtp:");
				    *temp << payload << " " << *ns;
				    rtpmap.append(temp);
				}
			    }
			}
		    }
		}
	    }
	}
	TelEngine::destruct(l);
	TelEngine::destruct(map);

	if ((m_rfc2833 >= 0) && frm && m->isAudio()) {
	    int rfc2833 = m->rfc2833().toInteger(m_rfc2833);
	    if (rfc2833 < 96 || rfc2833 > 127)
		rfc2833 = 101;
	    // claim to support telephone events
	    frm << " " << rfc2833;
	    String* s = new String;
	    *s << "rtpmap:" << rfc2833 << " telephone-event/8000";
	    rtpmap.append(s);
	}

	if (frm.null()) {
	    if (m->isAudio() || !m->fmtList()) {
		Debug(m_parser,DebugMild,"No formats for '%s', excluding from SDP [%p]",
		    m->c_str(),this);
		continue;
	    }
	    Debug(m_parser,DebugInfo,"Assuming formats '%s' for media '%s' [%p]",
		m->fmtList(),m->c_str(),this);
	    frm << " " << m->fmtList();
	    // brutal but effective
	    for (char* p = const_cast<char*>(frm.c_str()); *p; p++) {
		if (*p == ',')
		    *p = ' ';
	    }
	}

	if (ptime) {
	    String* temp = new String("ptime:");
	    *temp << ptime;
	    rtpmap.append(temp);
	}

	sdp->addLine("m",mline + frm);
	bool enc = false;
	if (m->isModified()) {
	    unsigned int n = m->length();
	    for (unsigned int i = 0; i < n; i++) {
		const NamedString* param = m->getParam(i);
		if (param) {
		    String tmp = param->name();
		    if (tmp.startsWith("fmtp-"))
			continue;
		    if (*param)
			tmp << ":" << *param;
		    sdp->addLine("a",tmp);
		    enc = enc || (param->name() == "encryption");
		}
	    }
	}
	for (f = rtpmap.skipNull(); f; f = f->skipNext()) {
	    String* s = static_cast<String*>(f->get());
	    if (s)
		sdp->addLine("a",*s);
	}
	if (addr && m->localCrypto()) {
	    sdp->addLine("a","crypto:" + m->localCrypto());
	    if (!enc)
		sdp->addLine("a","encryption:optional");
	}
    }
Пример #7
0
// Creates a SDP body from transport address and list of media descriptors
// Use own list if given media list is 0
MimeSdpBody* SDPSession::createSDP(const char* addr, ObjList* mediaList)
{
    DDebug(m_enabler,DebugAll,"SDPSession::createSDP('%s',%p) [%p]",addr,mediaList,m_ptr);
    if (!mediaList)
        mediaList = m_rtpMedia;
    // if we got no media descriptors we simply create no SDP
    if (!mediaList)
        return 0;
    if (m_sdpSession)
        ++m_sdpVersion;
    else
        m_sdpVersion = m_sdpSession = Time::secNow();

    // override the address with the externally advertised if needed
    if (addr && m_rtpNatAddr)
        addr = m_rtpNatAddr;
    if (!m_originAddr)
        m_originAddr = addr ? addr : m_host.safe();
    // no address means on hold or muted
    String origin;
    origin << "yate " << m_sdpSession << " " << m_sdpVersion;
    origin << " ";
    int f = addIP(origin,m_originAddr);
    String conn;
    addIP(conn,addr,f);

    MimeSdpBody* sdp = new MimeSdpBody;
    sdp->addLine("v","0");
    sdp->addLine("o",origin);
    sdp->addLine("s",m_parser->m_sessionName);
    sdp->addLine("c",conn);
    sdp->addLine("t","0 0");

    Lock lock(m_parser);
    bool defcodecs = m_parser->m_codecs.getBoolValue("default",true);
    for (ObjList* ml = mediaList->skipNull(); ml; ml = ml->skipNext()) {
        SDPMedia* m = static_cast<SDPMedia*>(ml->get());
        int rfc2833 = 0;
        if ((m_rfc2833 >= 0) && m->isAudio()) {
            if (!m_rtpForward) {
                rfc2833 = m->rfc2833().toInteger(m_rfc2833);
                if (rfc2833 < 96 || rfc2833 > 127)
                    rfc2833 = 101;
            }
            else if (m->rfc2833().toBoolean(true)) {
                rfc2833 = m->rfc2833().toInteger();
                if (rfc2833 < 96 || rfc2833 > 127)
                    rfc2833 = 0;
            }
        }
        String mline(m->fmtList());
        ObjList* l = mline.split(',',false);
        mline = *m;
        mline << " " << (m->localPort() ? m->localPort().c_str() : "0") << " " << m->transport();
        ObjList* map = m->mappings().split(',',false);
        ObjList rtpmap;
        ObjList* dest = &rtpmap;
        String frm;
        int ptime = 0;
        ObjList* f = l;
        for (; f; f = f->next()) {
            const String* s = static_cast<const String*>(f->get());
            if (s) {
                int mode = 0;
                if (*s == "g729b")
                    continue;
                int payload = s->toInteger(SDPParser::s_payloads,-1);
                int defcode = payload;
                String tmp = *s;
                tmp << "=";
                bool found = false;
                for (ObjList* pl = map; pl; pl = pl->next()) {
                    const String* mapping = static_cast<const String*>(pl->get());
                    if (!mapping)
                        continue;
                    if (mapping->startsWith(tmp)) {
                        payload = -1;
                        tmp = *mapping;
                        tmp >> "=" >> payload;
                        found = true;
                        XDebug(m_enabler,DebugAll,"RTP mapped payload %d for '%s' [%p]",
                               payload,s->c_str(),m_ptr);
                        break;
                    }
                    String tmp2 = *mapping;
                    int pload;
                    tmp2 >> "=" >> pload;
                    if (payload == pload) {
                        XDebug(m_enabler,DebugAll,"RTP conflict for payload %d, allocating new [%p]",
                               payload,m_ptr);
                        payload = -1;
                        u_int32_t bmap = 0;
                        for (ObjList* sl = map; sl; sl = sl->next()) {
                            mapping = static_cast<const String*>(sl->get());
                            if (!mapping)
                                continue;
                            tmp2 = *mapping;
                            pload = 0;
                            tmp2 >> "=" >> pload;
                            if (pload >= 96 && pload < 127)
                                bmap |= 1 << (pload - 96);
                        }
                        // allocate free and non-standard is possible
                        for (pload = 96; pload < 127; pload++) {
                            if (pload == rfc2833)
                                continue;
                            if (lookup(pload,SDPParser::s_rtpmap))
                                continue;
                            if ((bmap & (1 << (pload - 96))) == 0) {
                                payload = pload;
                                break;
                            }
                        }
                        if (payload >= 0)
                            break;
                        // none free, allocate from "standard" ones too
                        for (pload = 96; pload < 127; pload++) {
                            if (pload == rfc2833)
                                continue;
                            if ((bmap & (1 << (pload - 96))) == 0) {
                                payload = pload;
                                break;
                            }
                        }
                        break;
                    }
                }
                if (payload >= 0) {
                    if (!found) {
                        tmp = *s;
                        tmp << "=" << payload;
                        map->append(new String(tmp));
                    }
                    if (defcode < 0)
                        defcode = payload;
                    const char* map = lookup(defcode,SDPParser::s_rtpmap);
                    if (map && m_parser->m_codecs.getBoolValue(*s,defcodecs && DataTranslator::canConvert(*s))) {
                        if (*s == "ilbc20")
                            ptime = mode = 20;
                        else if (*s == "ilbc30")
                            ptime = mode = 30;
                        frm << " " << payload;
                        String* temp = new String("rtpmap:");
                        *temp << payload << " " << map;
                        dest = dest->append(temp);
                        if (mode) {
                            temp = new String("fmtp:");
                            *temp << payload << " mode=" << mode;
                            dest = dest->append(temp);
                        }
                        if (*s == "g729") {
                            temp = new String("fmtp:");
                            *temp << payload << " annexb=" <<
                                  ((0 != l->find("g729b")) ? "yes" : "no");
                            dest = dest->append(temp);
                        }
                        else if (*s == "amr") {
                            temp = new String("fmtp:");
                            *temp << payload << " octet-align=0";
                            dest = dest->append(temp);
                        }
                        else if (*s == "amr-o") {
                            temp = new String("fmtp:");
                            *temp << payload << " octet-align=1";
                            dest = dest->append(temp);
                        }
                    }
                }
            }
        }
Пример #8
0
static void  knot1(int l,int* yl,int* yyl)
{ int     m, m1, m2, m3, p, p1, p2, p3;
  int      z;

   if (l > 0) { m1 = l; m2 = 0; m3 = 0; p1 = pext; goto bb; }

aa:{ knot *with1 = &kn[-l];
      if ((tpc > 1) && ((l == -se) || (l == -se1)))
      {
         if (tpc == 3) mline(x[0],*yl,x[2],*yl,0,with1->e1,0);
         m1 = with1->e2; m2 = with1->e3; m3 = 0;
         p1 = with1->n2; p2 = with1->n3; 
      } 
      else 
      {  m1 = with1->e1; m2 = with1->e2; m3 = with1->e3; 
         p1 = with1->n1; p2 = with1->n2; p3 = with1->n3;
      } 
   } 
   if (ku == 1)
      {  ku = 0; 
         if (m1 < 0) { m = m1; m1 = m2; p = p1; p1 = p2; } 
         else        { m = m2; p = p2; }
         m2 = m3;
         p2 = p3; 
         if (m1 < 0) m3 = m1;
         if ((tpc == 3) && (elongl(-m3) > elongl(-m)))
            {
               if (m1 < 0) { m1 = m; p1 = p; }
               else        { m2 = m; p2 = p; }
               m = m3;
               p = p3; 
            }
         m3 = 0;

         { knot *with1 = &kn[-m]; 

               mline(x[2],*yl,x[2],*yl - ys,0,with1->pt,0);
               mline(x[2],*yl - ys,x[3],*yyl,2,with1->e1,with1->n1);
               *yyl += ys; 
               mline(x[2],*yl - ys,x[3],*yyl,2,with1->e2,with1->n2);
               *yyl += ys; 
         } 
      }


bb: if ((m1 > 0))
      {
         mline(x[2],*yl,x[3],*yyl,2,m1,p1);
         *yyl += ys;
         l = m2;
      }
   else l = m1; 

   if ((m2 > 0)) 
      { 
         mline(x[2],*yl,x[3],*yyl,2,m2,p2);
         *yyl += ys; 
         l = m3; 
      } 

   if ((m3 > 0)) 
         { 
            mline(x[2],*yl,x[3],*yyl,2,m3,p3);
            *yyl += ys;
         }

   if ((l >= 0)) return;

   { knot *with1 = &kn[-l];

         z = *yl + ys;
         if (tpc == 3 && (l == -se || l == -se1))  m = with1->ty - 1; 
         else m = with1->ty;
         if ((m > 1) && (z < *yyl)) z += ys; 
         mline(x[2],*yl,x[2],z,0,with1->pt,0);
         *yl = z;
   } 
      
   goto aa;
} 
Пример #9
0
static void painter(int xc,int yc,int ivr,int slt,int hor)
{int    tp, l, xcnt, ycnt, xx, yy, hh, 
         ylo, yhi, start, ks, kk, pp; 
 int flag; 
/*
char buff[10];
for(l=0;l<deep;l++) buff[l]=' ';
buff[l]=0; deep++;

printf("New vertex vrt=%d slt=%d \n",ivr,slt);
*/
   flag = 0; 
   start = 2; 
   xcnt = xc; 
   ycnt = yc; 
   tp = howin(ivr); 
   ks = wherein(ivr); 
   kk = ks == diag.valence[ivr-1] ?  
        diag.valence[ivr-1] - 1   : 
        diag.valence[ivr-1]       ; 
   lot(&ylo,&yhi,ivr,kk,hor); 
   
//printf("%s vert=%d  kk=%d hor=%d ylo=%d yhi=%d\n",buff,ivr,kk,hor,ylo,yhi);
   
   pp = ks == kk - 1 ? kk - 2 : kk - 1; 
   if (tp == 2) 
   { 
      if (ylo < 2) 
         ycnt += ystep; 
      else 
      {  ycnt += ylo * ystep; 
         yc += (ylo - 1) * ystep;
      } 
      mline(xstart,yc,xcnt,ycnt,ivr,slt,1); 
      mline(xstart,ycnt,xcnt,ycnt,ivr,ks,1); 
   } 
   else 
      if (tp == 1) 
      { 
         if (yc == ystart) ycnt += ylo * ystep; 
         if (hor && diag.valence[ivr-1] == 4) 
         { 
            lot(&hh,&yy,ivr,pp,hor); 
//printf("%s tp=1, ivr=%d pp=%d hh=%d yy=%d\n",buff, ivr,pp,hh,yy);            
            ycnt += (yhi + hh + 1) * ystep; 
            start = 1; 
         } 
         mline(xstart,ycnt,xcnt,ycnt,ivr,ks,1); 
      } 
      else 
         if (diag.valence[ivr-1] == 4) 
         { 
            start = 1; 
            if (!hor) cr(1,xcnt++,ycnt,ivr,slt); 
         } 
         else 
            if (hor && (OUT_PRTCL&diag.vertlist[ivr-1][1].prop) 
                    && (OUT_PRTCL&diag.vertlist[ivr-1][2].prop)) 
               start = 1; 

//printf("%s first start=%d\n",buff,start);

   res->scr[xcnt-1][ycnt-1] = vertsign; 
   if (xcnt > res->mhor) 
      res->mhor = xcnt; 
   for (l = kk; l >= 2; l--) 
   {edgeinvert *with1 = &diag.vertlist[ivr-1][l-1]; 
      if (!(IN_PRTCL & with1->prop)) 
      { 
         if (flag) 
{
//            lot(&ylo,&yhi,ivr,l,start != 3); 

             
                         lot(&ylo,&yhi,ivr,l,start==2);
//printf("%s start=%d  vrt=%d l=%d   hor=%d ylo=%d yhi=%d\n",buff, start, ivr,l, start==2, ylo,yhi);  
}          
         else 
            flag = 1; 
         xx = (OUT_PRTCL&with1->prop) ? xend : 
              start == 3 ? xcnt : xcnt + xstep; 
         {vertlink *with2 = &with1->nextvert; 
            if (start == 1) 
            { 
               
//               lot(&hh,&yy,ivr,pp,1); 
                 lot(&hh,&yy,ivr,l-1,1);
//printf("%s statr1 vrt=%d l-1=%d hh=%d yy=%d\n",buff, ivr, l-1,hh,yy);
               yy = ycnt - (hh +1) * ystep;
               mline(xcnt,ycnt,xx,yy,with2->vno,with2->edno,0); 
               if (!(OUT_PRTCL & with1->prop))  painter(xx,yy,with2->vno,with2->edno,1); 
            } 
            else 
               if (start == 2) 
               { 
                  lot(&hh,&yhi,ivr,l,1);
                  mline(xcnt,ycnt,xx,ycnt,with2->vno,with2->edno,1); 
                  if (!(OUT_PRTCL&with1->prop)) painter(xx,ycnt,with2->vno,with2->edno,1); 
                  yy = yhi;
//                  yy=ylo; 
               } 
               else 
               { 
//printf("%s start=? %d yy=%d  ylo=%d\n",buff,start,yy,ylo);
                  yy += ylo + 1;
//                    yy+=yhi+1;
//printf("%s down %d\n",buff,yy);
                  yy = ycnt + yy * ystep; 
                  
                  mline(xcnt,ycnt,xx,yy,with2->vno,with2->edno,0); 
                  if (!(OUT_PRTCL&with1->prop)) painter(xx,yy,with2->vno,with2->edno,0); 
               } 
         } 
         ++(start); 
      } 
   } 
}   /* The end of Painter's body */