;============================================================ ; 2008/--/-- ; Artlet2D demo ; AlphaPaint ; ;============================================================ ; ; サンプルペイントソフトです。 ; ;============================================================ #include "a2d.hsp" ;----------------------------------------------------------- ; config #define IMG_CANVAS 0 #define IMG_BUFS 5 ; canvas + undo buffers #define IMG_CONS 100 #define IMG_CMARK 110 #define IMG_RMARK 120 #define IMG_AMARK 130 #define IMG_PMARK 140 #define IMG_TEX 200 frmx = 640 frmy = 480 mgn = 8 winx = frmx + 100 winy = frmy + 75 sizex = 512 sizey = 384 ;----------------------------------------------------------- ; startup screen 0, winx, winy title "AlphaPaint" redraw 0 ; Create Image repeat IMG_BUFS alCreateImage cnt, frmx, frmy if stat = -1 { dialog "GDI+ を初期化できませんでした。" end } loop ; Create Console Image alCreateImage IMG_CONS, winx, winy ; frame alSyscolor 15 : alFillRect alSyscolor 20 : alFillRect 0, 0, frmx+1, frmy+1 alSyscolor 12 : alFillRect 0, 0, frmx, frmy ; Logo alFont "Arial", 35, 3 stri = "AlphaPaint" alTransModeOffsetRotateZoom 5, frmy, 8, 1.2, 1 alColor 255, 255, 255, 128 : alDrawText stri, 0, 0 alColor 0, 0, 0, 100 : alDrawText stri, 2, 2 alGradientColor 0, 0, 0, 50, 0xffffffff, 0xffaaaaaa : alDrawText stri, 1, 1 alResetTransMode ; alpha bar alpha_x = frmx + 12 alpha_y = 340 alpha_w = 32 alpha_h = 128 alGradientColor 0, alpha_y, 0, alpha_y+alpha_h, 0xff000000, 0x00000000 alFillRect alpha_x+alpha_w/2-4, alpha_y, 8, alpha_h ; pen-size bar psize_x = frmx + 56 psize_y = alpha_y psize_w = alpha_w psize_h = alpha_h alColor 0, 0, 128, 96 p = psize_x+psize_w/2-10, psize_y, psize_x+psize_w/2+10, psize_y, psize_x+psize_w/2, psize_y+psize_h alFillPoly p, 3 ; print alFont "MS UI Gothic", 14 alColor 0, 0, 0 alTransModeOffsetRotateZoom frmx+10, alpha_y - 40 alDrawText "ペン設定", 0, 0, 80, 20, 1, 1 alDrawText "濃度", 0, 20, 40, 20, 1, 1 alDrawText "太さ", 40, 20, 40, 20, 1, 1 alResetTransMode ; color bar color_w = 192 / 2 * 4 color_h = winy - frmy - mgn * 2 color_x = frmx - color_w color_y = frmy + mgn alColor 128, 128, 128 : alFillRect color_x-1, color_y-1, color_w+1, color_h+1 alColor 255, 255, 255 : alFillRect color_x, color_y, color_w+1, color_h+1 repeat color_w x = cnt h = cnt * 2 vf = limit((x-96) * 255 / 192, 0, 255) repeat color_h y = cnt s = (color_h-1-y) * 255 / (color_h-1) v = y * vf / (color_h-1) + (color_h-1-y) * 255 / (color_h-1) hsvcolor h, s, v alSetPixel color_x + x, color_y + y, RGBA(ginfo_r, ginfo_g, ginfo_b) loop loop ; Color Marker alCreateImage IMG_CMARK, 32, 32 ; ReSize Marker alCreateImage IMG_RMARK, 40, 40 ; Alpha Marker alCreateImage IMG_AMARK, 32, 32 ; PSize Marker alCreateImage IMG_PMARK, 32, 32 ; Create Background (HSP buffer 1) buffer 1, frmx, frmy color 222, 222, 222 div = 8 repeat frmy / div + 1 y = cnt repeat frmx / 2 / div + 1 boxf cnt*div*2 + (y&1)*div, y*div, cnt*div*2 + (y&1)*div + div-1, y*div + div-1 loop loop ; Window Objects gsel 0 objsize winx - frmx - mgn * 2, 21 pos frmx + mgn, mgn : button gosub "● 丸ブラシ", *select_stamp : btnx.stat = ginfo_cx : btny.stat = ginfo_cy pos , ginfo_cy + 3 : button gosub "■ 角ブラシ", *select_stamp : btnx.stat = ginfo_cx : btny.stat = ginfo_cy pos , ginfo_cy + 3 : button gosub "○ 消しゴム", *select_stamp : btnx.stat = ginfo_cx : btny.stat = ginfo_cy pos , ginfo_cy + 3 : button gosub "┼ スポイト", *select_stamp : btnx.stat = ginfo_cx : btny.stat = ginfo_cy pos , ginfo_cy + 13 : button gosub "全消去", *image_reset pos , ginfo_cy + 3 : button gosub "選択色消去", *image_colorkey pos , ginfo_cy + 13 : button gosub "元に戻す", *undo_pop pos , ginfo_cy + 13 : button gosub "テクスチャ読込", *texture_load pos , ginfo_cy + 13 : button gosub "ファイル読込", *image_load pos , ginfo_cy + 3 : button gosub "αpng 保存", *image_save ;----------------------------------------------------------- ; init stamp_r = 8 cur_a = 85 cur_r = 0 cur_g = 0 cur_b = 0 cur_t = 0 cur_x = 0 cur_y = -100 gosub *update_cons gosub *update_cmark gosub *update_rmark gosub *update_amark gosub *update_pmark gosub *update_screen ;----------------------------------------------------------- ; mainloop #uselib "user32" #func ScreenToClient "ScreenToClient" int, int #define STAMP_MAX 24 #define DM_VOID -1 #define DM_DRAW 1 #define DM_RESIZE 3 #define DM_COLOR 2 #define DM_PIPET 4 #define DM_ALPHA 5 #define DM_PSIZE 6 repeat bk = moux^mouy if drawmode { await } else { wait 1 } ; get mouse status getkey k, 1 : k *= (ginfo_act = 0) p = ginfo_mx, ginfo_my ScreenToClient hwnd, varptr(p) moux = p.0 mouy = p.1 ; set drawmode if k * (drawmode = 0) { if (moux >= color_x) & (mouy >= color_y) & (moux < color_x+color_w) & (mouy < color_y+color_h) { ; 色選択領域 drawmode = DM_COLOR } else:if sqrt((sizex-moux)*(sizex-moux)+(sizey-mouy)*(sizey-mouy)) <= 16 { ; リサイズ drawmode = DM_RESIZE } else:if (moux >= alpha_x) & (mouy >= alpha_y-10) & (moux < alpha_x+alpha_w) & (mouy < alpha_y+alpha_h+10) { ; アルファ選択 drawmode = DM_ALPHA } else:if (moux >= psize_x) & (mouy >= psize_y-10) & (moux < psize_x+psize_w) & (mouy < psize_y+psize_h+10) { ; ペンサイズ選択 drawmode = DM_PSIZE } else:if (moux < sizex) & (mouy < sizey) { if type_stamp = 3 { ; スポイト drawmode = DM_PIPET } else { ; 描画 drawmode = DM_DRAW gosub *undo_push alSelectImage IMG_CANVAS if type_stamp = 2 { alEraserBrush } else { if cur_t { alTextureImage IMG_TEX } else { alColor cur_r, cur_g, cur_b, cur_a*2/3 } } } } else { ; 無効ドラッグモード drawmode = DM_VOID } ; スポイトモード 解除 if (drawmode ! DM_PIPET) & (drawmode ! DM_VOID) : gosub *pipet_off bk = 0 } ; reset drawmode if (k = 0) * drawmode { drawmode = 0 gosub *update_screen } ; mousemove : if moux^mouy^bk { ; color if drawmode = DM_COLOR { cur_x = limit(moux, color_x, color_x+color_w-1) cur_y = limit(mouy, color_y, color_y+color_h-1) cur_t = 0 ; テクスチャタイプ -> 0 (solid) alSelectImage IMG_CONS cur_r = ARGB_R( alGetPixel(cur_x, cur_y) ) cur_g = ARGB_G( alGetPixel(cur_x, cur_y) ) cur_b = ARGB_B( alGetPixel(cur_x, cur_y) ) gosub *update_cons gosub *update_cmark gosub *update_screen } ; resize if drawmode = DM_RESIZE { sizex = limit(moux, 16, frmx) & 0xfffe sizey = limit(mouy, 16, frmy) & 0xfffe gosub *update_rmark gosub *update_screen } ; alpha if drawmode = DM_ALPHA { cur_a = limit((alpha_y+alpha_h-mouy) * 255 / alpha_h, 0, 255) gosub *update_amark gosub *update_screen } ; psize if drawmode = DM_PSIZE { stamp_r = limit((psize_y+psize_h-mouy) * STAMP_MAX / psize_h, 0, STAMP_MAX) gosub *update_pmark gosub *update_screen } ; pipet if drawmode = DM_PIPET { cur_x = limit(moux, 0, sizex-1) cur_y = limit(mouy, 0, sizey-1) cur_t = 0 ; テクスチャタイプ -> 0 (solid) alSelectImage IMG_CANVAS cur_a = ARGB_A( alGetPixel(cur_x, cur_y) ) cur_r = ARGB_R( alGetPixel(cur_x, cur_y) ) cur_g = ARGB_G( alGetPixel(cur_x, cur_y) ) cur_b = ARGB_B( alGetPixel(cur_x, cur_y) ) gosub *update_cons gosub *update_cmark gosub *update_amark gosub *update_screen } ; draw if drawmode = DM_DRAW { x = moux - stamp_r y = mouy - stamp_r w = stamp_r * 2 h = stamp_r * 2 if type_stamp = 0 { repeat stamp_r alFillEllip x+cnt, y+cnt, w-cnt*2, h-cnt*2 loop } else:if type_stamp = 1 { repeat stamp_r alFillRect x+cnt, y+cnt, w-cnt*2, h-cnt*2 loop } else:if type_stamp = 2 { alFillEllip x, y, w, h ; 消しゴム } gosub *update_canvas_xywh } } loop ;----------------------------------------------------------- ; subroutines *update_screen ; HSP screen 0 へ各 Image, buffer の画像を合成 redraw 0 ; BG Console alCopyImageToScreen IMG_CONS, 0 ; Canvas pos 0, 0 : gcopy 1, 0, 0, sizex, sizey alCopyImageToScreen IMG_CANVAS, 0, 0, 0, sizex, sizey ; ReSize Marker alCopyImageToScreen IMG_RMARK, 0, sizex-20, sizey-20, 40, 40 ; PSize Marker alCopyImageToScreen IMG_PMARK, 0, psize_x+psize_w/2-16, psize_y+psize_h-(stamp_r * psize_h / STAMP_MAX)-16 ; Alpha Marker if cur_t = 0 : alCopyImageToScreen IMG_AMARK, 0, alpha_x+alpha_w/2-16, alpha_y+alpha_h-(cur_a * alpha_h / 255)-16 ; Color Marker alCopyImageToScreen IMG_CMARK, 0, cur_x-16, cur_y-16, 32, 32 redraw 1 return *update_canvas_xywh ; キャンバスのみ更新 (高速) ; 変数 x, y, w, h の矩形領域 をアップデート redraw 0 pos x, y : gcopy 1, x, y, limit(w, 0, limit(sizex-x, 0, 9999)), limit(h, 0, limit(sizey-y, 0, 9999)) alCopyImageToScreen IMG_CANVAS, 0, x, y, limit(w, 0, limit(sizex-x, 0, 9999)), limit(h, 0, limit(sizey-y, 0, 9999)), x, y redraw 1, x, y, w, h return *update_cons ; コンソールイメージ更新 alSelectImage IMG_CONS alSyscolor 15 alFillRect frmx+1, 0, 999, 200 alFillRect frmx+1, frmy+1 alColor 255, 255, 255 : alFillRect btnx.type_stamp-0, btny.type_stamp-21, 86, 23 alColor 128, 128, 128 : alFillRect btnx.type_stamp-2, btny.type_stamp-23, 86, 23 alColor 255, 0, 0, 96 : alFillRect btnx.type_stamp-1, btny.type_stamp-22, 86, 23 x1 = frmx + mgn y1 = frmy + mgn w1 = winx - frmx - mgn * 2 h1 = winy - frmy - mgn * 2 if type_stamp = 0 | type_stamp = 3 { alColor 128, 128, 128 : alFillEllip x1-1, y1-1, w1, h1 alColor 255, 255, 255 : alFillEllip x1+1, y1+1, w1, h1 if cur_t { alTextureImage IMG_TEX } else { alColor cur_r, cur_g, cur_b } alFillEllip x1, y1, w1, h1 } if type_stamp = 1 { alColor 128, 128, 128 : alFillRect x1-1, y1-1, w1, h1 alColor 255, 255, 255 : alFillRect x1+1, y1+1, w1, h1 if cur_t { alTextureImage IMG_TEX } else { alColor cur_r, cur_g, cur_b } alFillRect x1, y1, w1, h1 } return *update_cmark ; カラーマーカーイメージ更新 alSelectImage IMG_CMARK alErase alPenWidth 4 alColor 0, 0, 0, 128 alDrawEllip 4, 4, 26, 26 alColor 255, 255, 255, 128 alDrawEllip 2, 2, 26, 26 alColor cur_r, cur_g, cur_b alDrawEllip 3, 3, 26, 26 return *update_rmark ; size マーカーイメージ更新 alSelectImage IMG_RMARK alErase alTransModeOffsetRotateZoom 20, 20, -45, 0.9, 1.2 alColor 255, 255, 128, limit(128+sizey-frmy, 32, 255) alFillRect -25, -5, 50, 10 alColor 0, 0, 255, 192 alFont "Arial", 9 alDrawText ""+sizex+" "+sizey, -30, -4, 60, 10, 1, 1 alResetTransMode alEraserBrush alFillRect 1, 1, 20, 20 alFillRect 19, 19, 20, 20 alColor 0, 0, 255, 128 alFillRect 19, 10, 2, 20 alFillRect 10, 19, 20, 2 return *update_amark if cur_a < 5 : cur_a = 5 ; lower limit ; Alpha マーカーイメージ更新 alSelectImage IMG_AMARK gosub *nyoro alFont "Arial", 10 + cur_a*5/255 alDrawText ""+cur_a, 0, 1, 32, 32, 1, 1 return *update_pmark ; Pen-size マーカーイメージ更新 alSelectImage IMG_PMARK gosub *nyoro alFont "Arial", 10 + stamp_r*5/STAMP_MAX alDrawText ""+stamp_r, 0, 1, 32, 32, 1, 1 return *nyoro alErase alGradientColor 0, 24, 0, 28, 0x44000000, 0x00000000 alFillRect 0, 24, 32, 4 alColor 128, 128, 128 : alFillRect 0, 8, 32, 16 alColor 255, 255, 255 : alFillRect 0, 8, 31, 15 alSyscolor 15 : alFillRect 1, 9, 30, 14 alGradientColor 0, 8, 0, 24, 0x11000000, 0x77ffffff alFillRect 1, 9, 30, 14 alColor 0, 0, 0 return ;----------------------------------------------------------- *pipet_off ; スポイトモード off if type_stamp = 3 { type_stamp = 0 cur_x = 0 cur_y = -100 gosub *update_cons } return *select_stamp st = stat gosub *pipet_off ; スタンプタイプ 変更 type_stamp = st gosub *update_cons gosub *update_screen return *texture_load gosub *pipet_off dialog "bmp;*.png;*.jpg;*.jpeg;*.tif;*.tiff;*.ico;*.gif", 16, "Image" if stat { alCreateImageByFile IMG_TEX, refstr if stat = -1 { dialog "読み込み失敗" } else { cur_t = 1 ; テクスチャタイプ -> 1 (texture) } } gosub *update_cons gosub *update_screen wait 10 ; ミスクリック対策 return ;----------------------------------------------------------- *undo_push repeat IMG_BUFS-1 alSelectImage IMG_BUFS-cnt-1 alErase alCopyImageToImage (IMG_BUFS-cnt-2), (IMG_BUFS-cnt-1) loop return *undo_pop repeat IMG_BUFS-1 alSelectImage cnt alErase alCopyImageToImage (cnt+1), (cnt) loop gosub *update_screen return ;----------------------------------------------------------- *image_reset gosub *undo_push alSelectImage alErase gosub *update_screen return *image_colorkey ; 選択色を透明化 gosub *undo_push alSelectImage alErase s = 16 alCopyModeColorKey RGBA(limit(cur_r-s,0,255), limit(cur_g-s,0,255), limit(cur_b-s,0,255)), RGBA(limit(cur_r+s,0,255), limit(cur_g+s,0,255), limit(cur_b+s,0,255)) alCopyImageToImage 1, 0 alResetCopyMode gosub *update_screen return *image_load dialog "bmp;*.png;*.jpg;*.jpeg;*.tif;*.tiff;*.ico;*.gif", 16, "Image" if stat { alGetFileWidth refstr, sizex, sizey if stat = -1 { dialog "読み込み失敗" } else { if type_stamp = 3 { ; スポイトモード patch cur_x = 0 cur_y = -100 } sizex = limit(sizex, 1, frmx) sizey = limit(sizey, 1, frmy) gosub *update_rmark gosub *undo_push alSelectImage IMG_CANVAS alErase alLoadFile refstr gosub *update_screen } } wait 10 ; ミスクリック対策 return *image_save dialog "png", 17, "png Image" if stat { astr = refstr if strmid(astr, strlen(astr)-4, 4) != ".png" : astr += ".png" alSelectImage IMG_CANVAS alSaveFile astr, "image/png", 0, 0, sizex, sizey if stat : dialog "保存失敗" } wait 10 ; ミスクリック対策 return