#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 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;
}