#help_index "Graphics/Sprite;Sprites"

#define SPBM_EXIT 				0
#define SPBM_MAIN_MENU			1
#define SPBM_COLOR				2
#define SPBM_DITHER_COLOR 		3
#define SPBM_WIDTH				4
#define SPBM_PT 				5
#define SPBM_LINE 				6
#define SPBM_ARROW				7
#define SPBM_RECT 				8
#define SPBM_CIRCLE 			9
#define SPBM_TEXT 				10
#define SPBM_TEXT_BOX 			11
#define SPBM_TEXT_DIAMOND 		12
#define SPBM_FLOOD_FILL 		13
#define SPBM_FLOOD_FILL_NOT 	14
#define SPBM_POLYLINE 			15
#define SPBM_POLYPT 			16
#define SPBM_COPY 				17
#define SPBM_DELETE 			18
#define SPBM_PASTE				19
#define SPBM_PASTE_TRANSPARENT	20
#define SPBM_FIND_AND_REPLACE 	21
#define SPBM_TRIM_TO_EXTENTS	22
#define SPBM_ADD_OUTLINE		23
#define SPBM_ETCH 				24
#define SPBM_UNDO 				25
#define SPBM_SAVE_GR			26

U0 GrInit4()
{
	DefineListLoad("ST_SPRITE_BITMAP_MENU", 

						"Exit\0"
						"Main Menu\0"
						"Color\0"
						"Dither Color\0"
						"Width\0"
						"Point\0"
						"Line\0"
						"Arrow\0"
						"Rect\0"
						"Circle\0"
						"Text\0"
						"Text Box\0"
						"Text Diamond\0"
						"Flood Fill\0"
						"Flood Fill Not Color\0"
						"PolyLine\0"
						"PolyPoint\0"
						"Copy\0"
						"Delete\0"
						"Paste\0"
						"Paste Transparent\0"
						"Find and Replace\0"
						"Trim to Extents\0"
						"Add Outline\0"
						"Etch\0"
						"Undo\0"
						"Save GR\0");
}
GrInit4;

I64 PopUpSpriteBitMap(CColorROPU32 color,  I64 width)
{
	I64   res;
	U8	 *st1,  *st2,  buf[STR_LEN];
	CDoc *doc = DocNew;

	Color2Str(buf, color);
	if (color & ROPF_DITHER)
	{
		st1 = "";
		st2 = buf;
	}
	else
	{
		st1 = buf;
		st2 = "";
	}
	DocPrint(doc,
				"$$PURPLE$$$$TX+CX,\"Sprite BitMap Menu\"$$\n"
				"$$LK+PU+CX,\"Click for Help\",A=\"FI:::/Doc/SpriteBitMap.DD\"$$\n"
				"\n$$LTBLUE$$$$MU-UL,\"Color        %s\",LE=SPBM_COLOR$$\n"
				"$$MU-UL,\"Dither Color %s\",LE=SPBM_DITHER_COLOR$$\n"
				"$$MU-UL,\"Width        %d\",LE=SPBM_WIDTH$$\n"
				"$$MU-UL,\"Find & Replace Color\",LE=SPBM_FIND_AND_REPLACE$$\n"
				"$$MU-UL,\"Trim to Extents\",LE=SPBM_TRIM_TO_EXTENTS$$\n"
				"$$MU-UL,\"Add Outline\",LE=SPBM_ADD_OUTLINE$$\n"
				"$$MU-UL,\"Etch\",LE=SPBM_ETCH$$\n"
				"\n$$MU-UL,\"Point\",LE=SPBM_PT$$\n"
				"$$MU-UL,\"Line\",LE=SPBM_LINE$$\n"
				"$$MU-UL,\"Arrow\",LE=SPBM_ARROW$$\n"
				"$$MU-UL,\"Rect\",LE=SPBM_RECT$$\n"
				"$$MU-UL,\"Circle\",LE=SPBM_CIRCLE$$\n"
				"$$MU-UL,\"Text\",LE=SPBM_TEXT$$\n"
				"$$MU-UL,\"Text Box\",LE=SPBM_TEXT_BOX$$\n"
				"$$MU-UL,\"Text Diamond\",LE=SPBM_TEXT_DIAMOND$$\n"
				"$$MU-UL,\"Flood Fill\",LE=SPBM_FLOOD_FILL$$\n"
				"$$MU-UL,\"Flood Fill Not Color\",LE=SPBM_FLOOD_FILL_NOT$$\n"
				"$$MU-UL,\"PolyLine\",LE=SPBM_POLYLINE$$\n"
				"$$MU-UL,\"PolyPoint\",LE=SPBM_POLYPT$$\n"
				"\n$$MU-UL,\"Copy to Clip\",LE=SPBM_COPY$$\n"
				"$$MU-UL,\"Delete to Clip\",LE=SPBM_DELETE$$\n"
				"$$MU-UL,\"Paste Clip\",LE=SPBM_PASTE$$\n"
				"$$MU-UL,\"Paste Transparent Clip\",LE=SPBM_PASTE_TRANSPARENT$$\n"
				"\n$$MU-UL,\"Save GR File\",LE=SPBM_SAVE_GR$$\n"
				"\n$$MU-UL,\"Undo\",LE=SPBM_UNDO$$\n"
				"\n$$PURPLE$$$$MU-UL,\"+] Sprite Main Menu\",LE=SPBM_MAIN_MENU$$$$LTBLUE$$\n"
				"$$MU-UL,\"Exit  Sprite\",LE=SPBM_EXIT$$\n"
				"$$MU-UL,\"Abort Sprite\",LE=DOCM_CANCEL$$\n"
				"\nRight-Click to get back to this menu.", st1, st2, width);
	res = PopUpMenu(doc);
	DocDel(doc);

	return res;
}

U0 GrBitMapEdPrepPersistentDC(CDC *dc, I64 xx1, I64 yy1, CDC *img)
{
	DCFill(dc);
	GrBlot(dc, xx1, yy1, img);
}

U0 GrBitMapEdTrimToExtents(CDC **_img, I64 *_xx1, I64 *_yy1, I64 *_xx2, I64 *_yy2, CColorROPU32 bkcolor)
{
	CDC *img = *_img;
	I64  i, c, x1 = 0, y1 = 0, x2 = img->width - 1, y2 = img->height - 1; //inclusive

	while (y1 < y2)
	{
		for (i = x1; i <= x2; i++)
		{
			c = GrPeek(img, i, y1);
			if (c != bkcolor && c != TRANSPARENT)
				goto tr_y2;
		}
		y1++;
	}

	tr_y2:
	while (y1 < y2)
	{
		for (i = x1; i <= x2; i++)
		{
			c = GrPeek(img, i, y2);
			if (c != bkcolor && c != TRANSPARENT)
				goto tr_x1;
		}
		y2--;
	}

	tr_x1:
	while (x1 < x2)
	{
		for (i = y1; i <= y2; i++)
		{
			c = GrPeek(img, x1, i);
			if (c != bkcolor && c != TRANSPARENT)
				goto tr_x2;
		}
		x1++;
	}

	tr_x2:
	while (x1 < x2)
	{
		for (i = y1; i <= y2; i++)
		{
			c = GrPeek(img, x2, i);
			if (c != bkcolor && c != TRANSPARENT)
				goto tr_done;
		}
		x2--;
	}

	tr_done:
	*_img = DCExt(img, x1, y1, x2, y2);
	*_xx1 += x1;
	*_yy1 += y1;
	*_xx2 += x2 - (img->width - 1);
	*_yy2 += y2 - (img->height - 1); //not inclusive
	DCDel(img);
}

U0 GrBitMapEdAddOutline(CDC *img, I64 width, CColorROPU32 color, CColorROPU32 bkcolor)
{
	I64				 i, j, k, c;
	CColorROPU32	 old_color;
	CDC				*src;

	if (img->width && img->height)
	{
		old_color = img->color;
		img->color = color;
		while (width-- > 0)
		{
			src = DCExt(img, 0, 0, img->width - 1, img->height - 1);
			for (i = 0; i < img->height; i++)
				for (j = 0; j < img->width; j++)
					if (GrPeek(src, j, i) == bkcolor)
						for (k = 0; k < 8; k++)
						{
							c = GrPeek(src, j + gr_x_offsets[k], i + gr_y_offsets[k]);
							if (c >= 0 && c != bkcolor)
							{
								GrPlot(img, j, i);
								break;
							}
						}
			DCDel(src);
		}
		img->color = old_color;
	}
}

U0 GrBitMapEdEtch(CDC *img, I64 width, CColorROPU32 bkcolor)
{
	I64				 i, j, k, c;
	CColorROPU32	 old_color;
	CDC				*src;

	if (img->width && img->height)
	{
		old_color = img->color;
		img->color = bkcolor;
		while (width-- > 0)
		{
			src = DCExt(img, 0, 0, img->width - 1, img->height - 1);
			for (i = 0; i < img->height; i++)
				for (j = 0; j < img->width; j++)
					if (GrPeek(src, j, i) != bkcolor)
						for (k = 0; k < 8; k++)
						{
							c = GrPeek(src, j + gr_x_offsets[k], i + gr_y_offsets[k]);
							if (c < 0 || c == bkcolor)
							{
								GrPlot(img, j, i);
								break;
							}
						}
			DCDel(src);
		}
		img->color = old_color;
	}
}

I64 SpriteBitMapEd(CDoc *, CDocEntry *doc_e, CDC *dc, I64 *_xx1, I64 *_yy1, I64 *_xx2, I64 *_yy2,
				   CDC **_img, CColorROPU32 bkcolor)
{
	I64			 i, j, mode = SPBM_LINE, color = BLACK, width = 1, message_code, arg1, arg2, x1, y1, x11, y11, 
				x22, y22, res, xx1 = *_xx1, yy1 = *_yy1, xx2 = *_xx2, yy2 = *_yy2, old_de_flags = doc_e->de_flags;
	Bool		 down = FALSE;
	U8			*st = NULL;
	CEdFileName	 filename;
	CDC			*img = *_img, *clip = NULL, *undo = NULL, *dc2;

	SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$

	doc_e->de_flags |= DOCEF_DONT_DRAW;
	goto bm_menu;

	while (TRUE)
	{
		if (kbd.scan_code & SCF_CTRL)//grab scroll update?
			GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);

		dc->color = ROPF_DITHER + WHITE << 16 + BLACK;
		dc->thick = 1;
		GrBorder(dc, xx1 - 1, yy1 - 1, xx2, yy2);//This is done little bit too often.

		while (message_code = MessageScan(&arg1, &arg2, 1 << MESSAGE_MS_L_DOWN | 1 << MESSAGE_MS_L_UP |
														1 << MESSAGE_MS_R_DOWN | 1 << MESSAGE_MS_MOVE |
														1 << MESSAGE_KEY_DOWN))
		{
			switch (message_code)
			{
				case MESSAGE_KEY_DOWN:
					switch (arg1)
					{
						case CH_SHIFT_ESC:
							res = SPE_ABORT;
							goto bm_key_up_done;

						case CH_ESC:
							res = SPE_CONT;
							goto bm_key_up_done;

						case 'c': //eye-dropper
							dc2 = DCScreenCapture(FALSE);
							color = GrPeek(dc2, mouse.pos.x, mouse.pos.y) ^ 15;//Mouse cursor is XORed.
							DCDel(dc2);
							break;

						case 't': //Set to transparent color
							color = TRANSPARENT;
							break;
					}
					break;

				case MESSAGE_MS_R_DOWN:
bm_menu:
					DCFill(dc);
					StrCopy(Fs->task_title, "Sprite BitMap Menu");
					i = PopUpSpriteBitMap(color, width);
					if (i >= 0)
						StrCopy(Fs->task_title, DefineSub(i, "ST_SPRITE_BITMAP_MENU"));
					switch (i)
					{
						case DOCM_CANCEL:
							res = SPE_ABORT;
							goto bm_done;

						case SPBM_EXIT:
							res = SPE_EXIT;
							goto bm_done;

						case SPBM_MAIN_MENU:
							res = SPE_CONT;
							goto bm_done;

						case SPBM_COLOR:
							i = PopUpColor(,, FALSE);
							if (i >= 0)
								color = i;
							goto bm_menu;

						case SPBM_FIND_AND_REPLACE:
							i = PopUpColor("Find Color\n",, FALSE);
							if (i >= 0)
							{
								j = PopUpColor("Replace Color\n",, FALSE);
								if (j >= 0)
								{
									DCColorChange(img, i, j);
									GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
								}
							}
							goto bm_menu;

						case SPBM_TRIM_TO_EXTENTS:
							GrBitMapEdTrimToExtents(&img, &xx1, &yy1, &xx2, &yy2, bkcolor);
							GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							goto bm_menu;

						case SPBM_ADD_OUTLINE:
							i = PopUpRangeI64(1, 16, 1, "Outline Width\n");
							if (i >= 0)
							{
								GrBitMapEdAddOutline(img, i, color, bkcolor);
								GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							}
							goto bm_menu;

						case SPBM_ETCH:
							i = PopUpRangeI64(1, 16, 1, "Etch Width\n");
							if (i >= 0)
							{
								GrBitMapEdEtch(img, i, bkcolor);
								GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							}
							goto bm_menu;

						case SPBM_SAVE_GR:
							*filename.name = 0;
							if (DocForm(&filename) && *filename.name)
								GRWrite(filename.name, img, DCSF_PALETTE_GET);
							goto bm_menu;

						case SPBM_DITHER_COLOR:
							i = PopUpColorDither;
							if (i >= 0)
								color = i;
							goto bm_menu;

						case SPBM_WIDTH:
							i = PopUpRangeI64(1, 16, 1, "Thick\n");
							if (i >= 0)
								width = i;
							goto bm_menu;

						case SPBM_UNDO:
							if (undo)
							{
								DCFill(img, bkcolor);
								img->color = ROP_EQU;
								GrBlot(img, 0, 0, undo);
								DCDel(undo);
								undo = NULL;
							}
							goto bm_menu;

						case SPBM_PT:
						case SPBM_LINE:
						case SPBM_ARROW:
						case SPBM_RECT:
						case SPBM_CIRCLE:
						case SPBM_FLOOD_FILL:
						case SPBM_FLOOD_FILL_NOT:
						case SPBM_POLYPT:
						case SPBM_POLYLINE:
						case SPBM_COPY:
						case SPBM_DELETE:
						case SPBM_PASTE:
						case SPBM_PASTE_TRANSPARENT:
							mode = i;
							break;

						case SPBM_TEXT:
						case SPBM_TEXT_BOX:
						case SPBM_TEXT_DIAMOND:
							Free(st);
							st = PopUpGetStr("Enter text and press <ESC>.\n");
							if (st && *st)
								mode = i;
							else
								goto bm_menu;
							break;
					}
					DCDel(undo);
					undo = DCExt(img, 0, 0, img->width - 1, img->height - 1);
					undo->bkcolor=bkcolor;
					Refresh(2, TRUE);	//Let popup close
					GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
					down = FALSE;
					break;

				case MESSAGE_MS_L_DOWN:
					switch (mode)
					{
						case SPBM_PT:
							img->color = color;
							img->thick = width;
							GrPlot3(img, arg1 - xx1, arg2 - yy1, 0);
							GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							break;
						start:
							if (down)
								GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							x1 = arg1;
							y1 = arg2;
							down = TRUE;
							dc->color = color;
							dc->thick = width;
							case SPBM_LINE:
								GrLine3(dc, x1, y1, 0, arg1, arg2, 0);
								break;

							case SPBM_ARROW:
								GrArrow3(dc, x1, y1, 0, arg1, arg2, 0);
								break;

							case SPBM_RECT:
								GrRect(dc, x1, y1, 1, 1);
								break;

							case SPBM_CIRCLE:
								GrCircle3(dc, x1, y1, 0, 1);
								break;

							case SPBM_COPY:
							case SPBM_DELETE:
								dc->color = ROPF_DITHER + WHITE << 16 + BLACK;
								dc->thick = 1;
								GrBorder(dc, x1, y1, x1, y1);
								break;
						end:
							break;

						case SPBM_PASTE:
						case SPBM_PASTE_TRANSPARENT:
							if (clip)
							{
								GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
								if (mode == SPBM_PASTE)
								{
									clip->flags |= DCF_NO_TRANSPARENTS;
									GrBlot(dc, arg1, arg2, clip);
									clip->flags&=~DCF_NO_TRANSPARENTS;
								}
								else
								{
									dc2 = DCCopy(clip);
									DCColorChange(dc2, bkcolor);
									GrBlot(dc, arg1, arg2, dc2);
									DCDel(dc2);
								}
							}
							break;

						case SPBM_TEXT:
							GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							dc->color = color;
							GrPrint(dc, arg1, arg2, "%s", st);
							break;

						case SPBM_TEXT_BOX:
							GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							dc->color = color;
							GrTextBox3(dc, arg1, arg2, 0, st);
							break;

						case SPBM_TEXT_DIAMOND:
							GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							dc->color = color;
							GrTextDiamond3(dc, arg1, arg2, 0, st);
							break;

						case SPBM_FLOOD_FILL:
							img->color = color;
							GrFloodFill(img, arg1 - xx1, arg2 - yy1);
							GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							break;

						case SPBM_FLOOD_FILL_NOT:
							img->color = color;
							GrFloodFill(img, arg1 - xx1, arg2 - yy1, TRUE);
							GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							break;

						case SPBM_POLYLINE:
							if (!down)
							{
								x1 = arg1;
								y1 = arg2;
								down = TRUE;
								dc->color = color;
								dc->thick = width;
								GrLine3(dc, x1, y1, 0, arg1, arg2, 0);
							}
							break;

						case SPBM_POLYPT:
							x1 = arg1;
							y1 = arg2;
							down = TRUE;
							img->color = color;
							img->thick = width;
							GrLine3(img, x1 - xx1, y1 - yy1, 0, arg1 - xx1, arg2 - yy1, 0);
							GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							break;
					}
					break;

				case MESSAGE_MS_MOVE:
					switch (mode)
					{
						case SPBM_LINE:
						case SPBM_ARROW:
						case SPBM_POLYLINE:
							if (down)
							{
								GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
								dc->color = color;
								dc->thick = width;
								if (mode == SPBM_ARROW)
									GrArrow3(dc, x1, y1, 0, arg1, arg2, 0);
								else
									GrLine3(dc, x1, y1, 0, arg1, arg2, 0);
							}
							break;

						case SPBM_RECT:
							if (down)
							{
								GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
								if (x1 < arg1)
								{
									x11 = x1;
									x22 = arg1;
								}
								else
								{
									x11 = arg1;
									x22 = x1;
								}
								if (y1 < arg2)
								{
									y11 = y1;
									y22 = arg2;
								}
								else
								{
									y11 = arg2;
									y22 = y1;
								}
								dc->color = color;
								GrRect(dc, x11, y11, x22 - x11 + 1, y22 - y11 + 1);
							}
							break;

						case SPBM_COPY:
						case SPBM_DELETE:
							if (down)
							{
								GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
								if (x1 < arg1)
								{
									x11 = x1;
									x22 = arg1;
								}
								else
								{
									x11 = arg1;
									x22 = x1;
								}
								if (y1 < arg2)
								{
									y11 = y1;
									y22 = arg2;
								}
								else
								{
									y11 = arg2;
									y22 = y1;
								}
								dc->color = ROPF_DITHER + WHITE << 16 + BLACK;
								dc->thick = 1;
								GrBorder(dc, x11, y11, x22, y22);
							}
							break;

						case SPBM_CIRCLE:
							if (down)
							{
								GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
								dc->color = color;
								dc->thick = width;
								GrCircle3(dc, x1, y1, 0, Sqrt(SqrI64(arg1 - x1) + SqrI64(arg2 - y1)));
							}
							break;

						case SPBM_PASTE:
						case SPBM_PASTE_TRANSPARENT:
							if (clip)
							{
								GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
								if (mode == SPBM_PASTE)
								{
									clip->flags |= DCF_NO_TRANSPARENTS;
									GrBlot(dc, arg1, arg2, clip);
									clip->flags &= ~DCF_NO_TRANSPARENTS;
								}
								else
								{
									dc2 = DCCopy(clip);
									DCColorChange(dc2, bkcolor);
									GrBlot(dc, arg1, arg2, dc2);
									DCDel(dc2);
								}
							}
							break;

						case SPBM_TEXT:
							GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							dc->color = color;
							GrPrint(dc, arg1, arg2, "%s", st);
							break;

						case SPBM_TEXT_BOX:
							GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							dc->color = color;
							GrTextBox3(dc, arg1, arg2, 0, st);
							break;

						case SPBM_TEXT_DIAMOND:
							GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							dc->color = color;
							GrTextDiamond3(dc, arg1, arg2, 0, st);
							break;

						case SPBM_POLYPT:
							if (down)
							{
								img->color = color;
								img->thick = width;
								GrLine3(img, x1 - xx1, y1 - yy1, 0, arg1 - xx1, arg2 - yy1, 0);
								GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
								x1 = arg1;
								y1 = arg2;
							}
							break;
					}
					break;

				case MESSAGE_MS_L_UP:
					switch (mode)
					{
						case SPBM_LINE:
						case SPBM_ARROW:
						case SPBM_POLYPT:
						case SPBM_POLYLINE:
							img->color = color;
							img->thick = width;
							if (mode == SPBM_ARROW)
								GrArrow3(img, x1 - xx1, y1 - yy1, 0, arg1 - xx1, arg2 - yy1, 0);
							else
								GrLine3(img, x1 - xx1, y1 - yy1, 0, arg1 - xx1, arg2 - yy1, 0);
							GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							if (mode == SPBM_POLYLINE)
							{
								x1 = arg1;
								y1 = arg2;
							}
							else
								down = FALSE;
							break;

						case SPBM_RECT:
							img->color = color;
							if (x1 < arg1)
							{
								x11 = x1;
								x22 = arg1;
							}
							else
							{
								x11 = arg1;
								x22 = x1;
							}
							if (y1 < arg2)
							{
								y11 = y1;
								y22 = arg2;
							}
							else
							{
								y11 = arg2;
								y22 = y1;
							}
							GrRect(img, x11 - xx1, y11 - yy1, x22 - x11 + 1, y22 - y11 + 1);
							down = FALSE;
							GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							break;

						case SPBM_COPY:
						case SPBM_DELETE:
							if (x1 < arg1)
							{
								x11 = x1;
								x22 = arg1;
							}
							else
							{
								x11 = arg1;
								x22 = x1;
							}
							if (y1 < arg2)
							{
								y11 = y1;
								y22 = arg2;
							}
							else
							{
								y11 = arg2;
								y22 = y1;
							}
							DCDel(clip);
							clip = DCExt(img, x11 - xx1, y11 - yy1, x22 - xx1, y22 - yy1);
							clip->bkcolor = bkcolor;
							if (mode == SPBM_DELETE)
							{
								img->color = bkcolor;
								GrRect(img, x11 - xx1, y11 - yy1, x22 - x11 + 1, y22 - y11 + 1);
							}
							goto bm_menu;

						case SPBM_CIRCLE:
							img->color = color;
							img->thick = width;
							GrCircle3(img, x1 - xx1, y1 - yy1, 0, Sqrt(SqrI64(arg1 - x1) + SqrI64(arg2 - y1)));
							down = FALSE;
							GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							break;

						case SPBM_PASTE:
						case SPBM_PASTE_TRANSPARENT:
							if (clip)
							{
								GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
								if (mode == SPBM_PASTE)
								{
									clip->flags |= DCF_NO_TRANSPARENTS;
									GrBlot(img, arg1 - xx1, arg2 - yy1, clip);
									clip->flags &= ~DCF_NO_TRANSPARENTS;
								}
								else
								{
									dc2 = DCCopy(clip);
									DCColorChange(dc2, bkcolor);
									GrBlot(img, arg1 - xx1, arg2 - yy1, dc2);
									DCDel(dc2);
								}
								GrBitMapEdPrepPersistentDC(dc, xx1, yy1, img);
							}
							break;

						case SPBM_TEXT:
							img->color = color;
							GrPrint(img, arg1 - xx1, arg2 - yy1, "%s", st);
							goto bm_menu;

						case SPBM_TEXT_BOX:
							img->color = color;
							GrTextBox3(img, arg1 - xx1, arg2 - yy1, 0, st);
							goto bm_menu;

						case SPBM_TEXT_DIAMOND:
							img->color = color;
							GrTextDiamond3(img, arg1 - xx1, arg2 - yy1, 0, st);
							goto bm_menu;
					}
					break;
			}
		}
		Refresh;
	}
bm_key_up_done:
	MessageGet(,, 1 << MESSAGE_KEY_UP);
bm_done:
	DCDel(clip);
	DCDel(undo);
	Free(st);
	DCFill(dc);
	SettingsPop;
	doc_e->de_flags = old_de_flags;
	*_img = img;
	*_xx1 = xx1, *_yy1 = yy1, *_xx2 = xx2, *_yy2 = yy2;

	return res;
}
