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