/*****************************************************************************/
/* htmldraw.cpp - 06/08/99 - By Christophe LOREK - CRYO-NETWORKS             */
/*                                                                           */
/* HTML draw functions                                                       */
/*                                                                           */
/* last modified on 30/08/99 By Christophe LOREK                             */
/*****************************************************************************/


//
// Modifications History
//
//$ LB (13/06/2002)  : changed ObjBitmap management, according to the new ObjBitmap structure
//
//$LB (20/12/2002) : 16bits to 24bits



#ifdef HTML_INCLUDE

#include "htmldraw.h"

#define HTML_SIZE1	8
#define HTML_SIZE2	10
#define HTML_SIZE3	12
#define HTML_SIZE4	14
#define HTML_SIZE5	18
#define HTML_SIZE6	24
#define HTML_SIZE7	36

#define CELLSPACING 2
#define CELLPADDING 2
#define HTML_VERTICAL_SPACING 4//7
#define HTML_BASELINE_ALIGN 5

char	*clickedurl = NULL;

#ifdef HTML_STANDALONE



OBJBITMAP_BUFFER classicBlit( OBJBITMAP_BUFFER bDest, OBJBITMAP_BUFFER bSrc,
					    int DestBPL, int SrcBPL,
					    int destX, int destY, int srcX, int srcY, int width, int height,
						int transparency)
{
    int dcx, dcy, scx, scy, color;
	unsigned char r, g, b;
	register i, j;
	register OBJBITMAP_BUFFER BufS;
	register OBJBITMAP_BUFFER BufD;

	dcy = destY * DestBPL + (destX * 3);
    scy = srcY  * SrcBPL  + (srcX * 3);

	if ( transparency == NIL ) 
	{            
	   BufS = ((OBJBITMAP_BUFFER) bSrc ) + scy ;
	   BufD = ((OBJBITMAP_BUFFER) bDest ) + dcy ;

	   for ( j = 0 ; j < height ; j ++ )
	   {                 
				memcpy( BufD, BufS, width * 3) ;
				BufD += DestBPL ;
				BufS += SrcBPL ;
	   }
	}
	else
	{
		for ( j = 0 ; j < height ; j ++ )
		{
			dcx = dcy ;
			scx = scy ;
			for ( i = 0 ; i < width ; i ++ , dcx +=3 , scx +=3 )
			{
				b = bSrc[ scx ];
				g = bSrc[ scx+1 ];
				r = bSrc[ scx+2 ];

				color = _COLOR_BGR_TO_I (b, g, r);

				if (color != transparency)
				{
					bDest[ dcx ] = b;
					bDest[ dcx+1 ] = g;
					bDest[ dcx+2 ] = r;
				}
			}
			dcy += DestBPL;
			scy += SrcBPL;
		}
	}

	return bDest;
}

#else

extern OBJBITMAP_BUFFER classicBlit( OBJBITMAP_BUFFER bDest, OBJBITMAP_BUFFER bSrc,
					    int DestBPL, int SrcBPL,
					    int destX, int destY, int srcX, int srcY, int width, int height,
						int transparency);

#endif

int DrawRectangle(PtrObjBitmap ptrBMP,int x1,int y1,int x2,int y2,int penwidth, int pencolor)
{
	HDC						dcWIN;
	HDC						dcBMP;
	HBITMAP				oldBMP;
	HPEN					currentPEN;
	HPEN					oldPEN;

	dcWIN = GetDC(ptrBMP->WHandler);
	dcBMP = CreateCompatibleDC(dcWIN);
	oldBMP = (HBITMAP) SelectObject(dcBMP,ptrBMP->DIBhandler);	

	currentPEN = CreatePen(
  PS_SOLID,    // pen style
  penwidth,    // pen width
  pencolor		 // pen color
	);
 
	oldPEN = (HPEN) SelectObject(
		dcBMP,
		currentPEN);
	
	MoveToEx(
		dcBMP,	// handle to device context
		x1,					// x-coordinate of new current position
		y1,					// y-coordinate of new current position
		NULL				// pointer to old current position
	);

	LineTo(
		dcBMP,	// device context handle
		x2,					// x-coordinate of line's ending point
		y1					// y-coordinate of line's ending point
	);

	LineTo(
		dcBMP,	// device context handle
		x2,					// x-coordinate of line's ending point
		y2					// y-coordinate of line's ending point
	);

	LineTo(
		dcBMP,	// device context handle
		x1,					// x-coordinate of line's ending point
		y2					// y-coordinate of line's ending point
	);

	LineTo(
		dcBMP,	// device context handle
		x1,					// x-coordinate of line's ending point
		y1					// y-coordinate of line's ending point
	);
	
	SelectObject(
		dcBMP,
		oldBMP);

	SelectObject(
		dcBMP,
		oldPEN);

	DeleteObject(currentPEN);
	DeleteDC(dcBMP);
	ReleaseDC(ptrBMP->WHandler,dcWIN);

	return 0;
}

int DrawFillRectangle(PtrObjBitmap ptrBMP,int x1,int y1,int x2,int y2,int r, int g, int b)
{
	HDC						dcWIN;
	HDC						dcBMP;
	HBITMAP				oldBMP;
	HPEN					currentPEN;
	HPEN					oldPEN;
	HBRUSH				currentBRUSH;
	HBRUSH				oldBRUSH;

	dcWIN = GetDC(ptrBMP->WHandler);
	dcBMP = CreateCompatibleDC(dcWIN);
	oldBMP = (HBITMAP) SelectObject(dcBMP,ptrBMP->DIBhandler);	

	currentPEN = CreatePen(
  PS_NULL,    // pen style
  0,    // pen width
  0		 // pen color
	);

	currentBRUSH = CreateSolidBrush(
		(b << 16)|(g << 8)|r   // brush color value
	);
 
	oldPEN = (HPEN) SelectObject(
		dcBMP,
		currentPEN);

	oldBRUSH = (HBRUSH) SelectObject(
		dcBMP,
		currentBRUSH);

	Rectangle(
		dcBMP,         // handle to device context
		x1,   // x-coord of bounding rectangle's upper-left corner
		y1,    // y-coord of bounding rectangle's upper-left corner
		x2,  // x-coord of bounding rectangle's lower-right corner
		y2  // y-coord of bounding rectangle's lower-right corner
	);
 	
	SelectObject(
		dcBMP,
		oldBMP);

	SelectObject(
		dcBMP,
		oldPEN);

	SelectObject(
		dcBMP,
		oldBRUSH);

	DeleteObject(currentBRUSH);
	DeleteObject(currentPEN);
	DeleteDC(dcBMP);
	ReleaseDC(ptrBMP->WHandler,dcWIN);

	return 0;
}

char *GetWord(char *string)
{
	char	*spacepos;
	
	if (string == NULL)
		return NULL;

	spacepos = strchr(string+1,' ');

	if (spacepos == NULL)
		return NULL;

	return spacepos;
}

int FormatTextLine(HDC currentDC,	RECT *boundaries,char *startline, int *cx, int *cy, int *textwidth)
{
	SIZE	stringsize;
	int		returnsize=0;
  char	*nextword;
  char	*previousword;
	int		bidon;

	previousword = nextword = startline;
	stringsize.cx = 0;
	stringsize.cy = 0;
	
	if (startline == NULL)
		return 0;

	do
	{
		previousword = nextword;
		if ((nextword = GetWord(previousword)) == NULL)
		{
			GetTextExtentPoint32(
				currentDC,					// handle to device context
				startline,					// pointer to text string
				strlen(startline),	// number of characters in string
				&stringsize);				// pointer to structure for string size
 
			if (*cx + stringsize.cx <= boundaries->right - boundaries->left)
			{
				*cx += stringsize.cx;
				*textwidth = stringsize.cx;
				return stringsize.cy + HTML_VERTICAL_SPACING;
			}
			else
			{
				*cx = 0;
				*cy += stringsize.cy;
				*textwidth = boundaries->right - boundaries->left;
				if (previousword == startline)
					return stringsize.cy + HTML_VERTICAL_SPACING;
				else
					return stringsize.cy + HTML_VERTICAL_SPACING + FormatTextLine(currentDC,boundaries,previousword+1,cx,cy,&bidon);
			}
		}
		else
		{
			GetTextExtentPoint32(
				currentDC,					// handle to device context
				startline,					// pointer to text string
				nextword - startline,// number of characters in string
				&stringsize);				// pointer to structure for string size
		}
	} while (*cx + stringsize.cx <= boundaries->right - boundaries->left);

	
	*cx = 0;
	*cy += stringsize.cy;
	*textwidth = boundaries->right - boundaries->left;
	if (previousword == startline)
		return stringsize.cy + HTML_VERTICAL_SPACING + FormatTextLine(currentDC,boundaries,nextword+1,cx,cy,&bidon);
	else
		return stringsize.cy + HTML_VERTICAL_SPACING + FormatTextLine(currentDC,boundaries,previousword+1,cx,cy,&bidon);
}

int FormatString(PtrObjBitmap	ptrBMP, HTMLTEXT *currentHTMLTEXT,HtmlBounds *bounds,int *cx, int *cy)
{
	HDC						dcWIN;
	HDC						dcBMP;
	HBITMAP				oldBMP;
	HFONT					oldfont,currentfont;
	RECT					boundaries;
	SIZE					stringsize;
	int						fontsize;
	int						oldbkmode;
	int						winalign;
	int						color;
	char					*string;
	int						textwidth = 0;
	
	currentHTMLTEXT->cx = *cx;
	currentHTMLTEXT->cy = *cy;
	currentHTMLTEXT->x = bounds->x;
	currentHTMLTEXT->y = bounds->y;
	currentHTMLTEXT->w = bounds->w;
	currentHTMLTEXT->h = 0;

	string = currentHTMLTEXT->Text();

	dcWIN = GetDC(ptrBMP->WHandler);
	dcBMP = CreateCompatibleDC(dcWIN);
	oldBMP = (HBITMAP) SelectObject(dcBMP,ptrBMP->DIBhandler);	

	boundaries.left = bounds->x;
	boundaries.right = bounds->x + bounds->w;
	boundaries.top = bounds->y;
	boundaries.bottom = bounds->y + ptrBMP->TailleH; // no lower limit

	oldbkmode = SetBkMode(
		dcBMP,						// handle of device context
		TRANSPARENT);			// flag specifying background mode

	switch(currentHTMLTEXT->Size())
	{
		case 1:
			fontsize = HTML_SIZE1;
			break;
		case 2:
			fontsize = HTML_SIZE2;
			break;						
		case 3:
			fontsize = HTML_SIZE3;
			break;					
		case 4:
			fontsize = HTML_SIZE4;
			break;						
		case 5:
			fontsize = HTML_SIZE5;
			break;						
		case 6:
			fontsize = HTML_SIZE6;
			break;
		case 7:
			fontsize = HTML_SIZE7;
			break;
		default:
			fontsize = HTML_SIZE3;
			break;
	}

	currentfont = CreateFont(
		-MulDiv(fontsize, GetDeviceCaps(dcBMP, LOGPIXELSY), 72),	// logical height of font
		0,												// logical average character width
		0,												// angle of escapement
		0,												// base-line orientation angle
		(currentHTMLTEXT->Attributes()&HTMLTEXT_ATT_BOLD)?700:0,	// font weight
		currentHTMLTEXT->Attributes()&HTMLTEXT_ATT_ITALIC,      // italic attribute flag
		currentHTMLTEXT->Attributes()&HTMLTEXT_ATT_UNDERLINED,  // underline attribute flag
		currentHTMLTEXT->Attributes()&HTMLTEXT_ATT_STRIKED,     // strikeout attribute flag
		ANSI_CHARSET,							// character set identifier
		OUT_DEFAULT_PRECIS,				// output precision
		CLIP_DEFAULT_PRECIS,			// clipping precision
		DEFAULT_QUALITY,          // output quality
		DEFAULT_PITCH|FF_DONTCARE,// pitch and family
		(currentHTMLTEXT->Font()!=NULL)?currentHTMLTEXT->Font():"Times New Roman");	// pointer to typeface name string

	oldfont = (HFONT) SelectObject(
		dcBMP,
		currentfont);

	color = (currentHTMLTEXT->Blue() << 16) +
					(currentHTMLTEXT->Green() << 8) +
					 currentHTMLTEXT->Red();

	SetTextColor(
		dcBMP,           // handle to device context
		color);   // text color

	switch(currentHTMLTEXT->Align())
	{
		case HTMLTEXT_ALIGN_LEFT:
			winalign = TA_LEFT;
			break;
		case HTMLTEXT_ALIGN_CENTER:
			winalign = TA_CENTER;
			break;
		case HTMLTEXT_ALIGN_RIGHT:
			winalign = TA_RIGHT;
			break;
		case HTMLTEXT_ALIGN_JUSTIFY:
			winalign = 0;
			break;
		case HTMLTEXT_ALIGN_CHAR:
			winalign = 0;
			break;
		default:
			winalign = 0;
			break;
	}

	SetTextAlign(
		dcBMP,								// handle to device context
//			TA_BASELINE  // text-alignment flag
			TA_BASELINE|winalign  // text-alignment flag
	);

	if (string != NULL)
		GetTextExtentPoint32(
			dcBMP,							// handle to device context
			string,							// pointer to text string
			strlen(string),			// number of characters in string
			&stringsize);				// pointer to structure for string size
	else
		GetTextExtentPoint32(
			dcBMP,							// handle to device context
			" ",						  	// pointer to text string
			1,			            // number of characters in string
			&stringsize);				// pointer to structure for string size

	if (string != NULL)
	{
	// if the string is too high to be displayed
//		if (*cy < bounds->y + stringsize.cy)
		if (*cy < stringsize.cy)
		{
			currentHTMLTEXT->cx = *cx = 0;
			currentHTMLTEXT->cy = *cy = *cy + stringsize.cy + HTML_VERTICAL_SPACING;
		}

		currentHTMLTEXT->charheight = stringsize.cy;

		currentHTMLTEXT->h = FormatTextLine(dcBMP,&boundaries,string,cx,cy,&textwidth);
//		bounds->h += currentHTMLTEXT->h;  // NON SURTOUT PAS !
		currentHTMLTEXT->textw = textwidth;
	}
  else
	{
/*		currentHTMLTEXT->cx = 0;
		currentHTMLTEXT->cy = 0;
		currentHTMLTEXT->x = 0;
		currentHTMLTEXT->y = 0;
		currentHTMLTEXT->w = 0;
		currentHTMLTEXT->h = 0;
*/		currentHTMLTEXT->charheight = stringsize.cy;
	}


//	MMechostr(MSKFOO,"HtmlTextContent (before) : (x=%i) (y=%i) (w=%i) (h=%i) %i %i %s\n",bounds->x,bounds->y,bounds->w,bounds->h,*cx,*cy,currentHTMLTEXT->Text()); 		

	SelectObject(
					dcBMP,
					oldfont);

	SetBkMode(
		dcBMP,						// handle of device context
		oldbkmode);				// flag specifying background mode

	SelectObject(
		dcBMP,
		oldBMP);

	DeleteObject(currentfont);
	DeleteDC(dcBMP);
	ReleaseDC(ptrBMP->WHandler,dcWIN);

	return 0;
}

int DrawTextLine(HDC currentDC,	RECT *boundaries,char *startline, int *cx, int *cy, int winalign)
{
	SIZE	stringsize;
	int		returnsize=0;
	char	*nextword;
	char	*previousword;
	int		xalign=0;

	previousword = nextword = startline;
	stringsize.cx = 0;
	stringsize.cy = 0;
	
	if (startline == NULL)
		return 0;

	switch(winalign)
	{
		case TA_LEFT:
			break;

		case TA_CENTER:
			xalign = (boundaries->right - boundaries->left) / 2;
			break;

		case TA_RIGHT:
			xalign = (boundaries->right - boundaries->left);
			break;

		default:
			break;
	}

	do
	{
		previousword = nextword;
		if ((nextword = GetWord(previousword)) == NULL || previousword == nextword)
		{
			GetTextExtentPoint32(
				currentDC,					// handle to device context
				startline,					// pointer to text string
				strlen(startline),	// number of characters in string
				&stringsize);				// pointer to structure for string size

			if (*cx + stringsize.cx <= boundaries->right - boundaries->left)
			{
				ExtTextOut(
					currentDC,						// handle to device context
					*cx + boundaries->left + xalign,// x-coordinate of reference point
					*cy + boundaries->top  - HTML_BASELINE_ALIGN,	// y-coordinate of reference point
					ETO_CLIPPED,					// text-output options
					boundaries,					// optional clipping and/or opaquing rectangle
					startline,						// points to string
					strlen(startline),	// number of characters in string
					NULL);								// pointer to array of intercharacter spacing values

				*cx += stringsize.cx;
				return 0;
			}
			else
			{
				if (previousword == startline)
				{
					ExtTextOut(
						currentDC,						// handle to device context
						*cx + boundaries->left + xalign,// x-coordinate of reference point
						*cy + boundaries->top  - HTML_BASELINE_ALIGN,	// y-coordinate of reference point
						ETO_CLIPPED,					// text-output options
						boundaries,					// optional clipping and/or opaquing rectangle
						startline,						// points to string
						strlen(startline),	// number of characters in string
						NULL);								// pointer to array of intercharacter spacing values

					*cx = 0;
					*cy += stringsize.cy;
				}
				else
				{
					ExtTextOut(
						currentDC,						// handle to device context
						*cx + boundaries->left + xalign,// x-coordinate of reference point
						*cy + boundaries->top - HTML_BASELINE_ALIGN,	// y-coordinate of reference point
						ETO_CLIPPED,					// text-output options
						boundaries,				  	// optional clipping and/or opaquing rectangle
						startline,						// points to string
						previousword - startline,	// number of characters in string
						NULL);								// pointer to array of intercharacter spacing values

					*cx = 0;
					*cy += stringsize.cy;
					DrawTextLine(currentDC,boundaries,previousword+1,cx,cy,winalign);
				}
				return 0;
			}
		}
		else
		GetTextExtentPoint32(
			currentDC,					// handle to device context
			startline,					// pointer to text string
			nextword - startline,// number of characters in string
			&stringsize);				// pointer to structure for string size
	} while (*cx + stringsize.cx <= boundaries->right - boundaries->left);


	if (previousword == startline)
	{
		ExtTextOut(
			currentDC,						// handle to device context
			*cx + boundaries->left + xalign,// x-coordinate of reference point
			*cy + boundaries->top  - HTML_BASELINE_ALIGN,	// y-coordinate of reference point
			ETO_CLIPPED,					// text-output options
			boundaries,					// optional clipping and/or opaquing rectangle
			startline,						// points to string
			nextword - startline,	// number of characters in string
			NULL);								// pointer to array of intercharacter spacing values

		*cx = 0;
		*cy += stringsize.cy;
		DrawTextLine(currentDC,boundaries,nextword+1,cx,cy,winalign);
	}
	else
	{
		ExtTextOut(
			currentDC,						// handle to device context
			*cx + boundaries->left + xalign,// x-coordinate of reference point
			*cy + boundaries->top - HTML_BASELINE_ALIGN,	// y-coordinate of reference point
			ETO_CLIPPED,					// text-output options
			boundaries,				  	// optional clipping and/or opaquing rectangle
			startline,						// points to string
			previousword - startline,	// number of characters in string
			NULL);								// pointer to array of intercharacter spacing values

		*cx = 0;
		*cy += stringsize.cy;
		DrawTextLine(currentDC,boundaries,previousword+1,cx,cy,winalign);
	}
	return 0;
}



int DrawString(PtrObjBitmap	ptrBMP, HTMLTEXT *currentHTMLTEXT)
{
	HDC						dcWIN;
	HDC						dcBMP;
	HBITMAP				oldBMP;
	HFONT					oldfont,currentfont;
	RECT					boundaries;
	int						fontsize;
	int						oldbkmode;
	int						winalign;
	int						color;
	char					*string;
	int						textcx;
	int						textcy;

	string = currentHTMLTEXT->Text();
	if (string != NULL) 
	{
		dcWIN = GetDC(ptrBMP->WHandler);
		dcBMP = CreateCompatibleDC(dcWIN);
		oldBMP = (HBITMAP) SelectObject(dcBMP,ptrBMP->DIBhandler);	

		textcx = currentHTMLTEXT->cx;
		textcy = currentHTMLTEXT->cy;
		boundaries.left = currentHTMLTEXT->x;
		boundaries.right = currentHTMLTEXT->x + currentHTMLTEXT->w;
		boundaries.top = currentHTMLTEXT->y;
		boundaries.bottom = currentHTMLTEXT->y + 1000000;

		oldbkmode = SetBkMode(
			dcBMP,						// handle of device context
			TRANSPARENT);			// flag specifying background mode

		switch(currentHTMLTEXT->Size())
		{
			case 1:
				fontsize = HTML_SIZE1;
				break;
			case 2:
				fontsize = HTML_SIZE2;
				break;						
			case 3:
				fontsize = HTML_SIZE3;
				break;					
			case 4:
				fontsize = HTML_SIZE4;
				break;						
			case 5:
				fontsize = HTML_SIZE5;
				break;						
			case 6:
				fontsize = HTML_SIZE6;
				break;
			case 7:
				fontsize = HTML_SIZE7;
				break;
			default:
				fontsize = HTML_SIZE3;
				break;
		}

		currentfont = CreateFont(
			-MulDiv(fontsize, GetDeviceCaps(dcBMP, LOGPIXELSY), 72),	// logical height of font
			0,												// logical average character width
			0,												// angle of escapement
			0,												// base-line orientation angle
			(currentHTMLTEXT->Attributes()&HTMLTEXT_ATT_BOLD)?700:0,	// font weight
			currentHTMLTEXT->Attributes()&HTMLTEXT_ATT_ITALIC,      // italic attribute flag
			currentHTMLTEXT->Attributes()&HTMLTEXT_ATT_UNDERLINED,  // underline attribute flag
			currentHTMLTEXT->Attributes()&HTMLTEXT_ATT_STRIKED,     // strikeout attribute flag
			ANSI_CHARSET,							// character set identifier
			OUT_DEFAULT_PRECIS,				// output precision
			CLIP_DEFAULT_PRECIS,			// clipping precision
			DEFAULT_QUALITY,          // output quality
			DEFAULT_PITCH|FF_DONTCARE,// pitch and family
			(currentHTMLTEXT->Font()!=NULL)?currentHTMLTEXT->Font():"Times New Roman");	// pointer to typeface name string

		oldfont = (HFONT) SelectObject(
			dcBMP,
			currentfont);

		color = (currentHTMLTEXT->Blue() << 16) +
						(currentHTMLTEXT->Green() << 8) +
						 currentHTMLTEXT->Red();

		SetTextColor(
			dcBMP,           // handle to device context
			color);   // text color

		switch(currentHTMLTEXT->Align())
		{
			case HTMLTEXT_ALIGN_LEFT:
				winalign = TA_LEFT;
				break;
			case HTMLTEXT_ALIGN_CENTER:
				winalign = TA_CENTER;
				break;
			case HTMLTEXT_ALIGN_RIGHT:
				winalign = TA_RIGHT;
				break;
			case HTMLTEXT_ALIGN_JUSTIFY:
				winalign = 0;
				break;
			case HTMLTEXT_ALIGN_CHAR:
				winalign = 0;
				break;
			default:
				winalign = 0;
				break;
		}

		SetTextAlign(
			dcBMP,								// handle to device context
//			TA_BASELINE  // text-alignment flag
				TA_BASELINE|winalign  // text-alignment flag
		);

		DrawTextLine(dcBMP,&boundaries,string,&textcx,&textcy,winalign);

		SelectObject(
						dcBMP,
						oldfont);

		SetBkMode(
			dcBMP,						// handle of device context
			oldbkmode);				// flag specifying background mode

		SelectObject(
			dcBMP,
			oldBMP);

		DeleteObject(currentfont);
		DeleteDC(dcBMP);
		ReleaseDC(ptrBMP->WHandler,dcWIN);
	}
	return 0;
}

char *ClickHtml(mmachine m,int htmlnode,int x, int y)
{
	HtmlBounds	bounds;

	bounds.x = 0;
	bounds.y = 0;
	bounds.w = 0;
	bounds.h = 0;

	clickedurl = NULL;
//	MMechostr(MSKFOO,"ClickHtml : start...\n");
	HtmlContent (m,htmlnode,NULL,&bounds,&x,&y,HTMLCONTENT_CLICK);
//	MMechostr(MSKFOO,"ClickHtml : end...\n");
	return clickedurl;
}

int NodeTestContent (mmachine m,HTML	*currentHTML,int node,PtrObjBitmap	ptrBMP,HtmlBounds *bounds,int *cx,int *cy,int flag)
{
	int						nodetype;

	nodetype		= MMfetch(m,node,NODE_TYPE)>>1;
	switch (nodetype)
	{
		case NODE_TYPTEXT:
			HtmlTextContent (m,currentHTML,node,ptrBMP,bounds,cx,cy,flag);
			break;

		case NODE_TYPBITMAP:
			HtmlBitmapContent (m,currentHTML,node,ptrBMP,bounds,cx,cy,flag);
			break;

		case NODE_TYPTABLE:
			HtmlTableContent (m,currentHTML,node,ptrBMP,bounds,cx,cy,flag);
			break;

		case NODE_TYPROW:
			HtmlRowContent (m,currentHTML,node,ptrBMP,bounds,cx,cy,flag);
			break;

		case NODE_TYPCELL:
			HtmlCellContent (m,currentHTML,node,ptrBMP,bounds,cx,cy,flag);
			break;

		case NODE_TYPHTML:
			break;

		default:
			break;
	}

	return 0;
}

int HtmlContent (mmachine m,int htmlnode,PtrObjBitmap	ptrBMP,HtmlBounds *bounds,int *cx,int *cy,int flag)
{
//	MMechostr(MSKFOO,"HtmlContent : (x=%i) (y=%i) (w=%i) (h=%i)\n",bounds->x,bounds->y,bounds->w,bounds->h);
	HTML	*currentHTML;
	int						nodesontab,nodebrothertab;
	int						nodetype;
	HtmlBounds		sonbounds;
	HtmlBounds		brotherbounds;

	sonbounds.x = bounds->x;
	sonbounds.y = bounds->y;
	sonbounds.w = bounds->w;
	sonbounds.h = bounds->h;
	sonbounds.nbcols = bounds->nbcols;
	brotherbounds.x = bounds->x;
	brotherbounds.y = bounds->y;
	brotherbounds.w = bounds->w;
	brotherbounds.h = bounds->h;
	brotherbounds.nbcols = bounds->nbcols;

	switch(flag)
	{
		case HTMLCONTENT_FORMAT :
			currentHTML = (HTML*) MMfetch(m,MMfetch(m,htmlnode,NODE_STRUCT)>>1,NODESTRUCT_STRUCT);
			nodesontab = MMfetch(m,htmlnode,NODE_SON)>>1;
			if (nodesontab != NIL)
			{
				nodetype		= MMfetch(m,nodesontab,NODE_TYPE)>>1;
				NodeTestContent (m,currentHTML,nodesontab,ptrBMP,&sonbounds,cx,cy,flag);
			}

			nodebrothertab = MMfetch(m,htmlnode,NODE_BROTHER)>>1;
			if (nodebrothertab != NIL)
			{
				nodetype		= MMfetch(m,nodebrothertab,NODE_TYPE)>>1;
				NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,&brotherbounds,cx,cy,flag);
			}
			break;

		case HTMLCONTENT_DRAW :
			currentHTML = (HTML*) MMfetch(m,MMfetch(m,htmlnode,NODE_STRUCT)>>1,NODESTRUCT_STRUCT);
			nodesontab = MMfetch(m,htmlnode,NODE_SON)>>1;
			if (nodesontab != NIL)
			{
				nodetype		= MMfetch(m,nodesontab,NODE_TYPE)>>1;
				NodeTestContent (m,currentHTML,nodesontab,ptrBMP,&sonbounds,cx,cy,flag);
			}

			nodebrothertab = MMfetch(m,htmlnode,NODE_BROTHER)>>1;
			if (nodebrothertab != NIL)
			{
				nodetype		= MMfetch(m,nodebrothertab,NODE_TYPE)>>1;
				NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,&brotherbounds,cx,cy,flag);
			}			break;

		case HTMLCONTENT_CLICK :
//	MMechostr(MSKFOO,"HtmlContent : HTMLCONTENT_CLICK...\n");
			currentHTML = (HTML*) MMfetch(m,MMfetch(m,htmlnode,NODE_STRUCT)>>1,NODESTRUCT_STRUCT);
			nodesontab = MMfetch(m,htmlnode,NODE_SON)>>1;
			if (nodesontab != NIL)
			{
				nodetype		= MMfetch(m,nodesontab,NODE_TYPE)>>1;
				NodeTestContent (m,currentHTML,nodesontab,ptrBMP,&sonbounds,cx,cy,flag);
			}

			nodebrothertab = MMfetch(m,htmlnode,NODE_BROTHER)>>1;
			if (nodebrothertab != NIL)
			{
				nodetype		= MMfetch(m,nodebrothertab,NODE_TYPE)>>1;
				NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,&brotherbounds,cx,cy,flag);
			}
			break;

		default:
			break;
	}
	return 0;
}

int HtmlTextContent (mmachine m,HTML	*currentHTML,int textnode,PtrObjBitmap	ptrBMP,HtmlBounds *bounds,int *cx,int *cy,int flag)
{
	HTMLTEXT			*currentHTMLTEXT;
	int						nodestructbuf;
	int						nodesontab,nodebrothertab;
	int						nodetype;
	char					*currenturl;
	HtmlBounds		sonbounds;
	int						initialcy=*cy;

	nodestructbuf = MMfetch(m,textnode,NODE_STRUCT)>>1;
	if (nodestructbuf == NIL) return 0;
	currentHTMLTEXT = (HTMLTEXT*) MMfetch(m,nodestructbuf,NODESTRUCT_STRUCT);
	if (currentHTMLTEXT == NULL) return 0;

	switch(flag)
	{
		case HTMLCONTENT_FORMAT :
			{
				sonbounds.x = bounds->x;
				sonbounds.y = bounds->y;
				sonbounds.w = bounds->w;
				sonbounds.h = 0;
				sonbounds.nbcols = bounds->nbcols;

				FormatString(ptrBMP,currentHTMLTEXT,bounds,cx,cy);

				nodesontab = MMfetch(m,textnode,NODE_SON)>>1;
				if (nodesontab != NIL)
					NodeTestContent (m,currentHTML,nodesontab,ptrBMP,&sonbounds,cx,cy,flag);

//				bounds->h += sonbounds.h;

				// if the string is a carriage return, the position must be set to the next line
				if (currentHTMLTEXT->Flags() == HTMLTEXT_FLAG_CR)
				{
					*cx = 0;
					*cy = *cy + currentHTMLTEXT->charheight + HTML_VERTICAL_SPACING;
//					bounds->h += currentHTMLTEXT->charheight + HTML_VERTICAL_SPACING;
				}

				bounds->h += *cy - initialcy;

				nodebrothertab = MMfetch(m,textnode,NODE_BROTHER)>>1;
				if (nodebrothertab != NIL)
					NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,bounds,cx,cy,flag);

				return 0;
			}
			break;

		case HTMLCONTENT_DRAW :
			{
				DrawString(ptrBMP,currentHTMLTEXT);

				nodesontab = MMfetch(m,textnode,NODE_SON)>>1;
				if (nodesontab != NIL)
					NodeTestContent (m,currentHTML,nodesontab,ptrBMP,&sonbounds,cx,cy,flag);

				nodebrothertab = MMfetch(m,textnode,NODE_BROTHER)>>1;
				if (nodebrothertab != NIL)
					NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,bounds,cx,cy,flag);
			}
			break;

		case HTMLCONTENT_CLICK :
			nodesontab = MMfetch(m,textnode,NODE_SON)>>1;
			if (nodesontab != NIL)
			{
				nodetype		= MMfetch(m,nodesontab,NODE_TYPE)>>1;
				NodeTestContent (m,currentHTML,nodesontab,ptrBMP,bounds,cx,cy,flag);
			}

			nodebrothertab = MMfetch(m,textnode,NODE_BROTHER)>>1;
			if (nodebrothertab != NIL)
			{
				nodetype		= MMfetch(m,nodebrothertab,NODE_TYPE)>>1;
				NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,bounds,cx,cy,flag);
			}
			switch(currentHTMLTEXT->Align())
			{
				case HTMLTEXT_ALIGN_RIGHT:
					if (	(*cx > (currentHTMLTEXT->x + currentHTMLTEXT->w - currentHTMLTEXT->textw)) &&
								(*cx < (currentHTMLTEXT->x + currentHTMLTEXT->w)) &&
								(*cy > (currentHTMLTEXT->cy + currentHTMLTEXT->y - currentHTMLTEXT->charheight)) &&
								(*cy < (currentHTMLTEXT->cy + currentHTMLTEXT->y + currentHTMLTEXT->h - currentHTMLTEXT->charheight))	)
					{
						currenturl = currentHTMLTEXT->Url();
						if (currenturl != NULL)
							clickedurl = currenturl;
					}
					break;

				case HTMLTEXT_ALIGN_CENTER:
					if (	(*cx > (currentHTMLTEXT->x + ((currentHTMLTEXT->w - currentHTMLTEXT->textw) / 2))) &&
								(*cx < (currentHTMLTEXT->x + ((currentHTMLTEXT->w + currentHTMLTEXT->textw) / 2))) &&
								(*cy > (currentHTMLTEXT->cy + currentHTMLTEXT->y - currentHTMLTEXT->charheight)) &&
								(*cy < (currentHTMLTEXT->cy + currentHTMLTEXT->y + currentHTMLTEXT->h - currentHTMLTEXT->charheight))	)
					{
						currenturl = currentHTMLTEXT->Url();
						if (currenturl != NULL)
							clickedurl = currenturl;
					}
					break;

				case HTMLTEXT_ALIGN_LEFT:
				default:
					if (	(*cx > currentHTMLTEXT->cx + currentHTMLTEXT->x) &&
								(*cx < (currentHTMLTEXT->cx + currentHTMLTEXT->x + currentHTMLTEXT->textw)) &&
								(*cy > (currentHTMLTEXT->cy + currentHTMLTEXT->y - currentHTMLTEXT->charheight)) &&
								(*cy < (currentHTMLTEXT->cy + currentHTMLTEXT->y + currentHTMLTEXT->h - currentHTMLTEXT->charheight))	)
					{
						currenturl = currentHTMLTEXT->Url();
						if (currenturl != NULL)
							clickedurl = currenturl;
					}
					break;

			}
			break;

		default:
			break;
	}

	return 0;
}


int HtmlTableContent (mmachine m,HTML	*currentHTML,int tablenode,PtrObjBitmap	ptrBMP,HtmlBounds *bounds,int *cx,int *cy,int flag)
{
	HTMLTABLE		*currentHTMLTABLE;
	int					nodesontab,nodebrothertab;
	int					nodestructbuf;
	int					tablecx=0;
	int					tablecy=0;
	int					oldwidth,currentwidth;
	HtmlBounds	sonbounds;

	nodestructbuf = MMfetch(m,tablenode,NODE_STRUCT)>>1;
	if (nodestructbuf == NIL)	return 0;
	currentHTMLTABLE = (HTMLTABLE*) MMfetch(m,nodestructbuf,NODESTRUCT_STRUCT);
	if (currentHTMLTABLE == NULL)	return 0;

	switch(flag)
	{
		case HTMLCONTENT_FORMAT :
			{
				currentHTMLTABLE->x = bounds->x;
				currentHTMLTABLE->y = bounds->y + *cy;
				currentHTMLTABLE->h = 0;

				oldwidth = currentwidth = bounds->w;
				if (currentHTMLTABLE->w == 0)
					currentHTMLTABLE->w = -100;		// 100% of previous width
				if (currentHTMLTABLE->w < 0)
					currentHTMLTABLE->w = (- currentHTMLTABLE->w * currentwidth) / 100;
				(currentHTMLTABLE->w<currentwidth) ? currentwidth = currentHTMLTABLE->w : currentwidth = currentwidth;

				currentHTMLTABLE->w = currentwidth;

				switch(currentHTMLTABLE->Align())
				{
					case HTMLTEXT_ALIGN_LEFT:
						break;
					case HTMLTEXT_ALIGN_CENTER:
							currentHTMLTABLE->x = bounds->x + (oldwidth - currentwidth) / 2;
						break;
					case HTMLTEXT_ALIGN_RIGHT:
							currentHTMLTABLE->x = bounds->x + (oldwidth - currentwidth);
						break;
					default:
						break;
				}

				sonbounds.x = currentHTMLTABLE->x;
				sonbounds.y = currentHTMLTABLE->y;
				sonbounds.w = currentHTMLTABLE->w;
				sonbounds.h = 0;
				sonbounds.nbcols = currentHTMLTABLE->Cols();
				
				nodesontab = MMfetch(m,tablenode,NODE_SON)>>1;
				if (nodesontab != NIL)
					NodeTestContent (m,currentHTML,nodesontab,ptrBMP,&sonbounds,&tablecx,&tablecy,flag);

				currentHTMLTABLE->h = sonbounds.h;

				*cx = 0;
				*cy += currentHTMLTABLE->h;

				nodebrothertab = MMfetch(m,tablenode,NODE_BROTHER)>>1;
				if (nodebrothertab != NIL)
					NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,bounds,cx,cy,flag);

				bounds->h += currentHTMLTABLE->h;
			}
			break;

		case HTMLCONTENT_DRAW :
			if (currentHTMLTABLE->Red() >=0 &&
					currentHTMLTABLE->Green() >=0 &&
					currentHTMLTABLE->Blue() >=0)
				DrawFillRectangle(ptrBMP,currentHTMLTABLE->x,currentHTMLTABLE->y,
											currentHTMLTABLE->x + currentHTMLTABLE->w-1,currentHTMLTABLE->y + currentHTMLTABLE->h-1,
											currentHTMLTABLE->Red(),currentHTMLTABLE->Green(),currentHTMLTABLE->Blue());

			nodesontab = MMfetch(m,tablenode,NODE_SON)>>1;
			if (nodesontab != NIL)
				NodeTestContent (m,currentHTML,nodesontab,ptrBMP,&sonbounds,&tablecx,&tablecy,flag);

			nodebrothertab = MMfetch(m,tablenode,NODE_BROTHER)>>1;
			if (nodebrothertab != NIL)
				NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,bounds,cx,cy,flag);
			break;

		case HTMLCONTENT_CLICK :
			nodesontab = MMfetch(m,tablenode,NODE_SON)>>1;
			if (nodesontab != NIL)
				NodeTestContent (m,currentHTML,nodesontab,ptrBMP,bounds,cx,cy,flag);

			nodebrothertab = MMfetch(m,tablenode,NODE_BROTHER)>>1;
			if (nodebrothertab != NIL)
				NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,bounds,cx,cy,flag);
			break;

		default:
			break;
	}
	
	return 0;
}

int HtmlRowContent (mmachine m,HTML	*currentHTML,int rownode,PtrObjBitmap	ptrBMP,HtmlBounds *bounds,int *cx,int *cy,int flag)
{
	HTMLROW			*currentHTMLROW;
	int					nodesontab,nodebrothertab;
	int					nodestructbuf;
	int					rowcx=0;
	int					rowcy=0;
	HtmlBounds	sonbounds;
	int					oldwidth,currentwidth;

//	int					cellspacing = CELLSPACING;

	nodestructbuf = MMfetch(m,rownode,NODE_STRUCT)>>1;
	if (nodestructbuf == NIL)	return 0;
	currentHTMLROW = (HTMLROW*) MMfetch(m,nodestructbuf,NODESTRUCT_STRUCT);
	if (currentHTMLROW == NULL)	return 0;

	switch(flag)
	{
		case HTMLCONTENT_FORMAT :
			{
				currentHTMLROW->x = bounds->x;
				currentHTMLROW->y = bounds->y + *cy;
				currentHTMLROW->h = 0;

				sonbounds.x = currentHTMLROW->x;
				sonbounds.y = currentHTMLROW->y;
				sonbounds.nbcols = bounds->nbcols;

				oldwidth = currentwidth = bounds->w;

				if (currentHTMLROW->w < 0)
					currentHTMLROW->w = (- currentHTMLROW->w * currentwidth) / 100;
				(currentHTMLROW->w<currentwidth) ? currentwidth = currentHTMLROW->w : currentwidth = currentwidth;

				sonbounds.w = currentHTMLROW->w = currentwidth;
				sonbounds.h = 0; // will be used by cells to determine if the previous is bigger or not

				nodesontab = MMfetch(m,rownode,NODE_SON)>>1; // FOLLOWING CELL
				if (nodesontab != NIL)
					NodeTestContent (m,currentHTML,nodesontab,ptrBMP,&sonbounds,&rowcx,&rowcy,flag);

				currentHTMLROW->h = sonbounds.h;

				*cx = 0;
				*cy += currentHTMLROW->h;

				nodebrothertab = MMfetch(m,rownode,NODE_BROTHER)>>1; //  FOLLOWING ROW
				if (nodebrothertab != NIL)
					NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,bounds,cx,cy,flag);

				bounds->h += currentHTMLROW->h;
			}
			break;

		case HTMLCONTENT_DRAW :
			{
			if (currentHTMLROW->Red() >=0 &&
					currentHTMLROW->Green() >=0 &&
					currentHTMLROW->Blue() >=0)
				DrawFillRectangle(ptrBMP,currentHTMLROW->x,currentHTMLROW->y,
											currentHTMLROW->x + currentHTMLROW->w-1,currentHTMLROW->y + currentHTMLROW->h-1,
											currentHTMLROW->Red(),currentHTMLROW->Green(),currentHTMLROW->Blue());

			nodesontab = MMfetch(m,rownode,NODE_SON)>>1;
				if (nodesontab != NIL)
					NodeTestContent (m,currentHTML,nodesontab,ptrBMP,&sonbounds,&rowcx,&rowcy,flag);

				nodebrothertab = MMfetch(m,rownode,NODE_BROTHER)>>1;
				if (nodebrothertab != NIL)
					NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,bounds,cx,cy,flag);
			}
			break;

		case HTMLCONTENT_CLICK :
			nodesontab = MMfetch(m,rownode,NODE_SON)>>1;
			if (nodesontab != NIL)
				NodeTestContent (m,currentHTML,nodesontab,ptrBMP,bounds,cx,cy,flag);

			nodebrothertab = MMfetch(m,rownode,NODE_BROTHER)>>1;
			if (nodebrothertab != NIL)
				NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,bounds,cx,cy,flag);
			break;

		default:
			break;
	}


	return 0;
}

int HtmlCellContent (mmachine m,HTML	*currentHTML,int cellnode,PtrObjBitmap	ptrBMP,HtmlBounds *bounds,int *cx,int *cy,int flag)
{
	HTMLCELL		*currentHTMLCELL;
	int					nodesontab,nodebrothertab;
	int					nodestructbuf;
	HtmlBounds	sonbounds;
	int					cellcx=0;
	int					cellcy=0;
	int					previousheight=0;
	int					charheight=0;
	int					oldwidth,currentwidth;

	int					cellspacing;
	int					cellpadding;

	nodestructbuf = MMfetch(m,cellnode,NODE_STRUCT)>>1;
	if (nodestructbuf == NIL)	return 0;
	currentHTMLCELL = (HTMLCELL*) MMfetch(m,nodestructbuf,NODESTRUCT_STRUCT);
	if (currentHTMLCELL == NULL)	return 0;

	cellspacing = currentHTMLCELL->Cellspacing();
	cellpadding = currentHTMLCELL->Cellpadding();

	switch(flag)
	{
		case HTMLCONTENT_FORMAT :
			{
				currentHTMLCELL->x = bounds->x + *cx;
				currentHTMLCELL->y = bounds->y;
				currentHTMLCELL->h = 0;
				previousheight = bounds->h;

				currentwidth = bounds->w;
				if (currentHTMLCELL->w != -100)
				{
					if (currentHTMLCELL->w < 0)
						currentHTMLCELL->w = (- currentHTMLCELL->w * currentwidth) / 100;
					(currentHTMLCELL->w<currentwidth) ? currentwidth = currentHTMLCELL->w : currentwidth = currentwidth;
				}
				else
				{
					if (bounds->nbcols > 0)
	 				oldwidth = currentwidth = currentwidth / bounds->nbcols;
				}
				currentHTMLCELL->w = currentwidth;

				sonbounds.x = currentHTMLCELL->x + cellspacing + cellpadding;
				sonbounds.y = currentHTMLCELL->y + cellspacing + cellpadding;
				sonbounds.w = currentHTMLCELL->w - cellspacing - cellpadding - cellpadding;
				sonbounds.h = cellspacing + cellpadding; // spacing/padding the top of the cell
				sonbounds.nbcols = bounds->nbcols;

				nodesontab = MMfetch(m,cellnode,NODE_SON)>>1;
				if (nodesontab != NIL)
					NodeTestContent (m,currentHTML,nodesontab,ptrBMP,&sonbounds,&cellcx,&cellcy,flag);

				currentHTMLCELL->h += sonbounds.h + cellpadding + cellpadding; // uses the current cursor pos to determine cell height
				bounds->nbcols--;

				if (currentHTMLCELL->h < previousheight)
					currentHTMLCELL->h = previousheight;

				*cy += currentHTMLCELL->h;
				*cx += currentwidth;

				bounds->h = currentHTMLCELL->h; // passing cell height to following cell

				nodebrothertab = MMfetch(m,cellnode,NODE_BROTHER)>>1;
				if (nodebrothertab != NIL)
					NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,bounds,cx,cy,flag);

				if (currentHTMLCELL->h < bounds->h)
					currentHTMLCELL->h = bounds->h;
			}
			break;

		case HTMLCONTENT_DRAW :
			{
			if (currentHTMLCELL->Red() >=0 &&
					currentHTMLCELL->Green() >=0 &&
					currentHTMLCELL->Blue() >=0)
				DrawFillRectangle(ptrBMP,currentHTMLCELL->x + cellspacing,
					currentHTMLCELL->y + cellspacing,
					currentHTMLCELL->x + currentHTMLCELL->w-1,
					currentHTMLCELL->y + currentHTMLCELL->h-1 - cellspacing,
					currentHTMLCELL->Red(),currentHTMLCELL->Green(),currentHTMLCELL->Blue());

				nodesontab = MMfetch(m,cellnode,NODE_SON)>>1;
				if (nodesontab != NIL)
					NodeTestContent (m,currentHTML,nodesontab,ptrBMP,&sonbounds,&cellcx,&cellcy,flag);

				nodebrothertab = MMfetch(m,cellnode,NODE_BROTHER)>>1;
				if (nodebrothertab != NIL)
				{
					*cy = currentHTMLCELL->h;
					NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,bounds,cx,cy,flag);
				}

				if (currentHTMLCELL->Border() > 0)
					DrawRectangle(ptrBMP,currentHTMLCELL->x + cellspacing,
						currentHTMLCELL->y + cellspacing,
						currentHTMLCELL->x + currentHTMLCELL->w-1,
						currentHTMLCELL->y + currentHTMLCELL->h-1 - cellspacing,
						currentHTMLCELL->Border(),0x00000000);
			}
			break;

		case HTMLCONTENT_CLICK :
			nodesontab = MMfetch(m,cellnode,NODE_SON)>>1;
			if (nodesontab != NIL)
				NodeTestContent (m,currentHTML,nodesontab,ptrBMP,bounds,cx,cy,flag);

			nodebrothertab = MMfetch(m,cellnode,NODE_BROTHER)>>1;
				NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,bounds,cx,cy,flag);
			break;

		default:
			break;
	}
	return 0;
}

int HtmlBitmapContent (mmachine m,HTML	*currentHTML,int bmpnode,PtrObjBitmap	ptrBMP,HtmlBounds *bounds,int *cx,int *cy,int flag)
{
	int						objvoidbuf;
	HTMLBITMAP		*currentHTMLBITMAP;
	PtrObjVoid		ptrOB;
	PtrObjBitmap	ptrBMPS;
	int						nodestructbuf;
	int						nodesontab,nodebrothertab;
	HtmlBounds		sonbounds;
	HtmlBounds		brotherbounds;
	int						xalign=0;
	int						blitW,blitH;

	nodestructbuf = MMfetch(m,bmpnode,NODE_STRUCT)>>1;
	if (nodestructbuf == NIL) return 0;
	currentHTMLBITMAP = (HTMLBITMAP*) MMfetch(m,nodestructbuf,NODESTRUCT_STRUCT);
	if (currentHTMLBITMAP == NULL) return 0;

	switch(flag)
	{
		case HTMLCONTENT_FORMAT :
			{
				sonbounds.x = bounds->x;
				sonbounds.y = bounds->y;
				sonbounds.w = bounds->w;
				sonbounds.h = 0;
				sonbounds.nbcols = bounds->nbcols;
				brotherbounds.x = bounds->x;
				brotherbounds.y = bounds->y;
				brotherbounds.w = bounds->w;
				brotherbounds.h = 0;
				brotherbounds.nbcols = bounds->nbcols;

				switch(currentHTMLBITMAP->Align())
				{
					case HTMLTEXT_ALIGN_LEFT:
						xalign = 0;
						break;
					case HTMLTEXT_ALIGN_CENTER:
						xalign = (bounds->w - currentHTMLBITMAP->w) / 2;
						break;
					case HTMLTEXT_ALIGN_RIGHT:
						xalign = bounds->w - currentHTMLBITMAP->w;
						break;
					case HTMLTEXT_ALIGN_JUSTIFY:
						xalign = 0;
						break;
					case HTMLTEXT_ALIGN_CHAR:
						xalign = 0;
						break;
					default:
						xalign = 0;
						break;
				}

				*cx += xalign;
				currentHTMLBITMAP->x = bounds->x + *cx;
				currentHTMLBITMAP->y = bounds->y + *cy;
				*cx+= currentHTMLBITMAP->w;
				*cy+= currentHTMLBITMAP->h;

				bounds->h += currentHTMLBITMAP->h;

				nodesontab = MMfetch(m,bmpnode,NODE_SON)>>1;
				if (nodesontab != NIL)
				{
					NodeTestContent (m,currentHTML,nodesontab,ptrBMP,&sonbounds,cx,cy,flag);
					bounds->h += sonbounds.h;
				}

				nodebrothertab = MMfetch(m,bmpnode,NODE_BROTHER)>>1;
				if (nodebrothertab != NIL)
				{
					NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,&brotherbounds,cx,cy,flag);
					bounds->h += brotherbounds.h;
				}
			}
			break;

		case HTMLCONTENT_DRAW :

			switch(currentHTMLBITMAP->Status())
			{
				case HTMLBITMAP_STATUS_NOOBJ :
					DrawRectangle(ptrBMP,currentHTMLBITMAP->x,currentHTMLBITMAP->y,
												currentHTMLBITMAP->x + currentHTMLBITMAP->w-1,currentHTMLBITMAP->y + currentHTMLBITMAP->h-1,
												currentHTMLBITMAP->Border(),0x000000FF);
					DrawRectangle(ptrBMP,currentHTMLBITMAP->x + 3,currentHTMLBITMAP->y + 3,
												currentHTMLBITMAP->x + currentHTMLBITMAP->w-3-1,currentHTMLBITMAP->y + currentHTMLBITMAP->h-3-1,
												currentHTMLBITMAP->Border(),0x000000FF);
					break;

				case HTMLBITMAP_STATUS_OK :
					objvoidbuf = MMfetch(m,bmpnode,NODE_OBJBITMAP)>>1;
					if (objvoidbuf == NIL)
						break;

					ptrOB = (PtrObjVoid) MMstart(m,objvoidbuf);
					if (ptrOB->Type != OBJ_TYPE_BITMAP << 1)
						break;
					ptrBMPS = (PtrObjBitmap) MMstart(m,ptrOB->Buffer >> 1);

					if (currentHTMLBITMAP->x > ptrBMP->TailleW || currentHTMLBITMAP->y > ptrBMP->TailleH)
						break;

					if (currentHTMLBITMAP->x < 0 || currentHTMLBITMAP->y < 0 || ptrBMPS->TailleW < 0 || ptrBMPS->TailleH < 0)
						break;

					if (ptrBMP->TailleW < currentHTMLBITMAP->x + ptrBMPS->TailleW)
						blitW = ptrBMP->TailleW - currentHTMLBITMAP->x;
					else
						blitW = ptrBMPS->TailleW;

					if (ptrBMP->TailleH < currentHTMLBITMAP->y + ptrBMPS->TailleH)
						blitH = ptrBMP->TailleH - currentHTMLBITMAP->y;
					else
						blitH = ptrBMPS->TailleH;

					classicBlit(ptrBMP->bits,ptrBMPS->bits,ptrBMP->BPL, ptrBMPS->BPL,currentHTMLBITMAP->x,currentHTMLBITMAP->y ,0,0,
						blitW,blitH,NIL);
					break;

				default :
					break;
			}

			nodesontab = MMfetch(m,bmpnode,NODE_SON)>>1;
			if (nodesontab != NIL)
				NodeTestContent (m,currentHTML,nodesontab,ptrBMP,&sonbounds,cx,cy,flag);

			nodebrothertab = MMfetch(m,bmpnode,NODE_BROTHER)>>1;
			if (nodebrothertab != NIL)
				NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,&brotherbounds,cx,cy,flag);

			break;

		case HTMLCONTENT_CLICK :
			nodesontab = MMfetch(m,bmpnode,NODE_SON)>>1;
			if (nodesontab != NIL)
				NodeTestContent (m,currentHTML,nodesontab,ptrBMP,bounds,cx,cy,flag);

			nodebrothertab = MMfetch(m,bmpnode,NODE_BROTHER)>>1;
			if (nodebrothertab != NIL)
				NodeTestContent (m,currentHTML,nodebrothertab,ptrBMP,bounds,cx,cy,flag);
			break;

		default:
			break;
	}

	return 0;

}

#endif