home *** CD-ROM | disk | FTP | other *** search
/ Phoenix Heaven Sunny 2 / APPARE2.BIN / oh_towns / art2 / src.lzh / IMAGEWIN.C < prev    next >
C/C++ Source or Header  |  1995-06-19  |  21KB  |  775 lines

  1. /*====================================================
  2.                       ARTemis
  3.                    (version 1.3)
  4.              FM-TOWNS 用ペイントツール
  5.  
  6.                  by 松内 良介 1994
  7. ====================================================*/
  8. #if 0
  9.   // モジュール初期化
  10.     int imagewin_init(void);
  11.  
  12.   // 生成・消滅
  13.     IMWIN *imagewin_new(int pixelsize,int width, int height);
  14.     void imagewin_destroy(IMWIN *win);
  15.  
  16.   // リンク関連
  17.     IMWIN *imagewin_getfirst(void);
  18.     IMWIN *imagewin_getnext(void);
  19.     void imagewin_link(IMWIN *win);
  20.     void imagewin_unlink(IMWIN *win);
  21.     void imagewin_show(IMWIN *win);
  22.     IMWIN *imagewin_getWinFromPart(int objId);
  23.         // オブジェクトIDからウィンドウを検索する
  24.     IMWIN *imagewin_getCurrentWin(void);
  25.     void imagewin_setCurrentWin(IMWIN *win);
  26.  
  27.   // 座標変換
  28.     void imagewin_getScrFrame(IMWIN *win, FRAME *frPic, FRAME *frBitmap);
  29.         // PIC領域(x,y,wid,ht)から、SCRBITMAP領域(x,y,wid,ht)へと変換
  30.     void imagewin_getDispFrame(IMWIN *win,FRAME* frPic);
  31.         // ウィンドウのユーザー領域を、表示画像の PIC 領域(x,y,wid,ht)に変換
  32.     void imagewin_getPosFromMos(IMWIN *win, POINT *mos, POINT *pos);
  33.         // 画面上のマウス座標から、画像内での位置を得る
  34.     BOOL imagewin_PtInPic(IMWIN* win, POINT* pt);
  35.         // 画面座標 pt がウィンドウ内の画像領域にあるかどうか
  36.  
  37.   // 表示内容更新
  38.     void imagewin_updateBuf(IMWIN *win);
  39.         // PIC内容から、SCRBITMAP全体を再生成する
  40.     void imagewin_updateScr(IMWIN *win);
  41.         // SCRBITMAPの内容を画面に表示。同時にラバー描画も行う
  42.     void imagewin_updateScrPart(IMWIN *win, FRAME *updatefr);
  43.         // PIC領域 updatefr に対応する SCRBITMAP / 画面を更新する
  44.  
  45.   // ラバー制御
  46.     void imagewin_setBoxRubber(IMWIN* win, FRAME *fr);
  47.         // fr : PIC領域(x,y,wid,ht)
  48.     void imagewin_setBoxRubber2(IMWIN* win, FRAME *fr);
  49.     void imagewin_clearBoxRubber(IMWIN* win);
  50.     void imagewin_clearBoxRubber2(IMWIN* win);
  51.     void imagewin_resetLineRubber(IMWIN* win);
  52.     void imagewin_addLineRubber(IMWIN* win,POINT* p1,POINT* p2);
  53.         // p1,p2 : PIC 座標   p2 が NULL のとき、リストの最初の点とむすぶ
  54.     int imagewin_nLineRubber(IMWIN* win);
  55.     void imagewin_clearLineRubber(IMWIN* win);
  56.     void imagewin_resetLineRubber2(IMWIN* win);
  57.     void imagewin_addLineRubber2(IMWIN* win,POINT* p1,POINT* p2);
  58.         // p1,p2 : PIC 座標   p2 が NULL のとき、リストの最初の点とむすぶ
  59.     int imagewin_nLineRubber2(IMWIN* win);
  60.     void imagewin_clearLineRubber2(IMWIN* win);
  61.  
  62.   // リサイズ、表示倍率変更など
  63.     void imagewin_setFileName(IMWIN *win, char *fname, BOOL fShow);
  64.     void imagewin_updateTitle(IMWIN *win, BOOL fShow);
  65.     int imagewin_resize(IMWIN *win, BOOL fRedraw);
  66.         // 子ウィンドウの再配置
  67.     void imagewin_setZoom(IMWIN *win, int zoom);
  68.  
  69.   // 画像編集
  70.     void imagewin_storeUndo(IMWIN* win);
  71.     void imagewin_recoverUndo(void)
  72.     void imagewin_copy(IMWIN* srcwin,FRAME* frSrc,
  73.                        IMWIN* destwin,POINT *ptDest);
  74.         // frSrc:PIC領域(x,y,wid,ht)
  75.         // ptDest:PIC座標
  76.     void imagewin_copyarea(IMWIN* srcwin,AREA areaSrc,
  77.                            IMWIN* destwin,POINT *ptDest);
  78. #endif
  79.  
  80. #define    MODULE_IMWIN
  81.  
  82. #include <stdio.h>
  83. #include <stdlib.h>
  84. #include <string.h>
  85. #include <winb.h>
  86. #include <te.h>
  87. #include <fntb.h>
  88. #include <gui.h>
  89. #include <egb.h>
  90. #include <wgb.h>
  91. #include <msdos.cf>
  92.  
  93. #include "art.h"
  94. #include "guisub.h"
  95. #include "wgbmac.H"
  96. #include "alert.h"
  97. #include "subgrp.h"
  98.  
  99. #include "imagewin.h"
  100. #include "imgwin.h"
  101. #include "desktop.h"
  102.  
  103. #define    PIXELSIZE    2
  104.  
  105. BOOL art_IntersectRect(FRAME* frdest, FRAME* fr1, FRAME* fr2)
  106.     // (x,y,wid,ht) で表された FRAME の intersect を得る
  107. {
  108.     FRAME fr;
  109.     fr.X = _max(fr1->X, fr2->X);
  110.     fr.Y = _max(fr1->Y, fr2->Y);
  111.     fr.X2 = _min(fr1->X+fr1->WID, fr2->X+fr2->WID);
  112.     fr.Y2 = _min(fr1->Y+fr1->HT, fr2->Y+fr2->HT);
  113.     fr.WID = fr.X2 - fr.X;
  114.     fr.HT  = fr.Y2 - fr.Y;
  115.     if (fr.WID <= 0 || fr.HT <= 0)
  116.         return FALSE;
  117.     else
  118.     {
  119.         if (frdest != NULL)
  120.             *frdest = fr;
  121.         return TRUE;
  122.     }
  123. }
  124.  
  125. /*--------------------------------------------------------*/
  126. /*                 モジュール内データ構造                 */
  127. /*--------------------------------------------------------*/
  128.  
  129. IMWIN *winlist = NULL;
  130. IMWIN *curptr;
  131.  
  132. /*--------------------------------------------------------*/
  133. /*                   モジュールの初期化                   */
  134. /*--------------------------------------------------------*/
  135.  
  136. int imagewin_init(void)
  137. {
  138.     winlist = NULL;
  139.     return NOERR;
  140. }
  141.  
  142. /*--------------------------------------------------------*/
  143. /*                       生成・消滅                       */
  144. /*--------------------------------------------------------*/
  145.  
  146. IMWIN *imagewin_new(int pixelsize,int width, int height)
  147. {
  148.     IMWIN *w ;
  149.     if ((w = TL_calloc(1, sizeof(IMWIN))) == NULL)
  150.         return NULL;
  151.   // PIC 部品の生成
  152.     if ((w->pic = pic_new(pixelsize,width,height)) == NULL)
  153.         { TL_free(w);  return NULL; }
  154.   // データ構造の初期化
  155.     w->fBoxRubber = FALSE;
  156.     w->fBoxRubber2 = FALSE;
  157.     w->zoom = 1;
  158.   /* ひな型部品の複製をつくる */
  159.     w->win      = MMI_SendMessage( idImageWin, MM_NEW, 0 ) ;
  160.     w->sbar_h   = MMI_SendMessage( idImageHSBar, MM_NEW, 0 ) ;
  161.     w->sbar_v   = MMI_SendMessage( idImageVSBar, MM_NEW, 0 ) ;
  162.     w->titlebar = MMI_SendMessage( idImageTitleDBtn, MM_NEW, 0 );
  163.     w->titlemsg = MMI_SendMessage( idImageTitleMsg, MM_NEW, 0 );
  164.     w->erasebtn = MMI_SendMessage( idImageEraseDBtn, MM_NEW, 0 );
  165.   /* それぞれの部品をくっつける */
  166.     MMI_SendMessage( w->sbar_h,   MM_ATTACH, 1, w->win ) ;
  167.     MMI_SendMessage( w->sbar_v,   MM_ATTACH, 1, w->win ) ;
  168.     MMI_SendMessage( w->titlebar, MM_ATTACH, 1, w->win ) ;
  169.     MMI_SendMessage( w->titlemsg, MM_ATTACH, 1, w->win ) ;
  170.     MMI_SendMessage( w->erasebtn, MM_ATTACH, 1, w->win ) ;
  171.   // ウィンドウのタイトルを作成
  172.     imagewin_updateTitle(w, FALSE);
  173.   // 各部品の配置(画面バッファも同時に確保)
  174.     if (imagewin_resize(w, FALSE) != NOERR)
  175.     {
  176.         imagewin_destroy(w);
  177.         return NULL;
  178.     }
  179.   // おわり
  180.     return w;
  181. }
  182.  
  183. void imagewin_destroy(IMWIN *win)
  184. {
  185.     MMI_SendMessage( win->win, MM_DESTROY, 0 );
  186.     if (win->bm != NULL)
  187.         scrbitmap_delete(win->bm);
  188.     if (win->pic != NULL)
  189.         pic_destroy(win->pic);
  190.     TL_free(win);
  191. }
  192.  
  193. /*--------------------------------------------------------*/
  194. /*                       リンク関連                       */
  195. /*--------------------------------------------------------*/
  196.  
  197. IMWIN    *imagewin_getfirst(void)
  198. {
  199.     curptr = winlist;
  200.     return curptr;
  201. }
  202.  
  203. IMWIN    *imagewin_getnext(void)
  204. {
  205.     if (curptr == NULL)
  206.         return NULL;
  207.     curptr = curptr->next;
  208.     return curptr;
  209. }
  210.  
  211. void imagewin_link(IMWIN *win)
  212. {
  213.     win->next = winlist;
  214.     winlist = win;
  215.     MMI_SendMessage(win->win, MM_ATTACH, 1, idDesktopWinAttachHyper);
  216.     MMI_SendMessage(win->win, MM_WAKE, 0 );
  217. }
  218.  
  219. void imagewin_show(IMWIN *win)
  220. {
  221.     WINCLIP *clipStack;
  222.     WIN_beginUpDateObj(win->win, &clipStack);
  223.     MMI_SendMessage(win->win, MM_SHOW, 0);
  224.     WIN_endUpDateObj(clipStack);
  225. }
  226.  
  227. void imagewin_unlink(IMWIN *win)
  228. {
  229.     IMWIN *w,*prev;
  230.     for (w=winlist,prev=NULL; w!=NULL; prev=w,w=w->next)
  231.     {
  232.         if (w == win)
  233.         {
  234.             if (prev==NULL)
  235.                 winlist = w->next;
  236.             else
  237.                 prev->next = w->next;
  238.         }
  239.     }
  240.     MMI_SendMessage(win->win, MM_ERASE, 0);
  241.     MMI_SendMessage(win->win, MM_DETACH, 0);
  242. }
  243.  
  244. IMWIN *imagewin_getWinFromPart(int objId)
  245. /* 部品IDからどの IMWIN であるかを得る */
  246. {
  247.     IMWIN *win;
  248.     for (win=imagewin_getfirst(); win!=NULL; win=imagewin_getnext())
  249.     {
  250.         if (    win->win == objId      || win->sbar_h == objId   ||
  251.                 win->sbar_v == objId   || /* win->btn == objId      || */
  252.                 win->erasebtn == objId || win->titlebar == objId ||
  253.                 win->titlemsg == objId        )
  254.             return win;
  255.     }
  256.     return NULL;
  257. }
  258.  
  259. static IMWIN *curwin = NULL;
  260.  
  261. IMWIN *imagewin_getCurrentWin(void)
  262. {
  263.     return curwin;
  264. }
  265.  
  266. void imagewin_setCurrentWin(IMWIN *win)
  267. {
  268.     curwin = win;
  269. }
  270.  
  271. /*--------------------------------------------------------*/
  272. /*                        座標変換                        */
  273. /*--------------------------------------------------------*/
  274.  
  275. void imagewin_getDispFrame(IMWIN *win, FRAME *fr)
  276. // ウィンドウのユーザー領域を、表示画像の PIC 領域(x,y,wid,ht)に変換
  277. {
  278.     FRAME frUser, ret;
  279.     RM_getWinUserFrame(win->win, &frUser);
  280.     ret.X = RM_getScrollPos(win->sbar_h);
  281.     ret.Y = RM_getScrollPos(win->sbar_v);
  282.     ret.WID = (frUser.X2 - frUser.X + 1 + win->zoom-1) / win->zoom;
  283.     ret.HT = (frUser.Y2 - frUser.Y + 1 + win->zoom-1) / win->zoom;
  284.     if (fr!=NULL)
  285.         *fr = ret;
  286. }
  287.  
  288. void imagewin_getScrFrame(IMWIN *win, FRAME *picfr, FRAME *scrfr)
  289. // PIC領域(x,y,wid,ht)から、SCRBITMAP領域(x,y,wid,ht)へと変換
  290. {
  291.     FRAME ret, pfr;
  292.     imagewin_getDispFrame(win, &pfr);
  293.     ret.X = (picfr->X - pfr.X) * win->zoom;
  294.     ret.Y = (picfr->Y - pfr.Y) * win->zoom;
  295.     ret.WID = picfr->WID * win->zoom;
  296.     ret.HT = picfr->HT * win->zoom;
  297.     *scrfr = ret;
  298. }
  299.  
  300. void imagewin_getPosFromMos(IMWIN *win, POINT *mos, POINT *pos)
  301. /* マウスカーソル位置が画像内のどこであるかを得る */
  302. /*
  303. [引数]
  304.     win : 画像ウィンドウ
  305.     mos : マウス座標
  306. [結果]
  307.     pos : 画像内での座標
  308. */
  309. {
  310.     FRAME frUser;
  311.     RM_getWinUserFrame(win->win, &frUser);
  312.     FRAME frDisp;
  313.     imagewin_getDispFrame(win, &frDisp);
  314.     pos->x = frDisp.X + (mos->x - frUser.X) / win->zoom;
  315.     pos->y = frDisp.Y + (mos->y - frUser.Y) / win->zoom;
  316. }
  317.  
  318. BOOL imagewin_PtInPic(IMWIN* win, POINT* pt)
  319. // pt :画面座標
  320. {
  321.     FRAME frUser;
  322.     RM_getWinUserFrame(win->win, &frUser);
  323.     if (PtInRect((Rect*)&frUser,(Point*)pt))
  324.         return TRUE;
  325.     else
  326.         return FALSE;
  327. }
  328.  
  329. /*--------------------------------------------------------*/
  330. /*                 SCRBITMAP / 画面の更新                 */
  331. /*--------------------------------------------------------*/
  332.  
  333. void imagewin_updateBuf(IMWIN *win)
  334. /* 画像内容の変更があった場合に、ユーザー領域バッファの内容を更新 */
  335. {
  336.     FRAME frDisp;
  337.     imagewin_getDispFrame(win, &frDisp);
  338.     if (win->pic != NULL && win->bm != NULL)
  339.         pic_getScrBitmap(win->pic, win->bm, 0,0, &frDisp, win->zoom);
  340. }
  341.  
  342. void imagewin_updateScr(IMWIN *win)
  343. {
  344.     BEGINPAINT(win->win)
  345.     FRAME frUser;
  346.     RM_getWinUserFrame(win->win, &frUser);
  347.     if (win->bm != NULL)
  348.         scrbitmap_draw(win->bm, frUser.X, frUser.Y);
  349.   // ラバーを上書きする
  350.     FRAME frDisp;
  351.     imagewin_getDispFrame(win, &frDisp);
  352.   // ボックスラバー描画関数
  353.     void boxrubber(FRAME* fr)
  354.      // fr:PIC領域(x,y,wid,ht)
  355.     {
  356.         if (win->zoom == 1)
  357.         {
  358.             WGB_RBOXLINE(guiEgbPtr,
  359.                          frUser.X + (fr->X - frDisp.X),
  360.                          frUser.Y + (fr->Y - frDisp.Y),
  361.                          fr->WID, fr->HT, RMcol(WHITE), 4);
  362.         }
  363.         else
  364.         {
  365.             FRAME frBitmap;
  366.             void draw(void)
  367.             {
  368.                 WGB_RBOXFILL(guiEgbPtr,
  369.                              frUser.X + frBitmap.X,
  370.                              frUser.Y + frBitmap.Y,
  371.                              frBitmap.WID, frBitmap.HT, RMcol(WHITE),4);
  372.             }
  373.             { FRAME frPic = {fr->X,fr->Y,fr->WID,1};
  374.               imagewin_getScrFrame(win, &frPic, &frBitmap); }
  375.             draw();
  376.             if (fr->HT >= 2)
  377.             {
  378.                 { FRAME frPic = {fr->X,fr->Y+fr->HT-1,fr->WID,1};
  379.                   imagewin_getScrFrame(win, &frPic, &frBitmap); }
  380.                 draw();
  381.             }
  382.             if (fr->HT >= 3)
  383.             {
  384.                 { FRAME frPic = {fr->X,fr->Y+1,1,fr->HT-2};
  385.                   imagewin_getScrFrame(win, &frPic, &frBitmap); }
  386.                 draw();
  387.                 if (fr->WID >= 2)
  388.                 {
  389.                     { FRAME frPic = {fr->X+fr->WID-1,fr->Y+1,1,fr->HT-2};
  390.                       imagewin_getScrFrame(win, &frPic, &frBitmap); }
  391.                     draw();
  392.                 }
  393.             }
  394.         }
  395.     }
  396.     if (win->fBoxRubber)
  397.         boxrubber(&win->frBoxRubber);
  398.     if (win->fBoxRubber2)
  399.         boxrubber(&win->frBoxRubber2);
  400.   // 直線ラバー描画関数
  401.     void linerubber(LIST* list)
  402.     {
  403.         for (list_top(list); !list_isOut(list); list_next(list))
  404.         {
  405.             FRAME fr;
  406.             list_getData(list, &fr);
  407.             if (win->zoom == 1)
  408.             {
  409.                 WGB_LINE(guiEgbPtr,
  410.                     frUser.X + (fr.X - frDisp.X),
  411.                     frUser.Y + (fr.Y - frDisp.Y),
  412.                     frUser.X + (fr.X2 - frDisp.X),
  413.                     frUser.Y + (fr.Y2 - frDisp.Y), RMcol(WHITE), 4);
  414.             }
  415.             else
  416.             {
  417.                 void putpixel(int x,int y)
  418.                 {
  419.                     if (frDisp.X <= x && x < frDisp.X + frDisp.WID &&
  420.                         frDisp.Y <= y && y < frDisp.Y + frDisp.HT)
  421.                     {
  422.                         int tx = frUser.X + (x - frDisp.X) * win->zoom;
  423.                         int ty = frUser.Y + (y - frDisp.Y) * win->zoom;
  424.                         WGB_RBOXFILL(guiEgbPtr, tx,ty,win->zoom,win->zoom,
  425.                                      RMcol(WHITE), 4);
  426.                     }
  427.                 }
  428.                 do_line(fr.X,fr.Y,fr.X2,fr.Y2,putpixel);
  429.             }
  430.         }
  431.     }
  432.     if (win->fLineRubber)
  433.         linerubber(win->listLineRubber);
  434.     if (win->fLineRubber2)
  435.         linerubber(win->listLineRubber2);
  436.     ENDPAINT
  437. }
  438.  
  439. void imagewin_updateScrPart(IMWIN *win, FRAME *updatefr)
  440. // PIC領域updatefr(x,y,wid,ht) に対応する SCRBITMAP と画面を更新
  441. {
  442.   // 更新の必要な PIC 領域を得る
  443.     FRAME frDisp;   // 画面に表示されている PIC 領域
  444.     FRAME frUpdate; // 更新の必要な PIC 領域
  445.     imagewin_getDispFrame(win, &frDisp);
  446.     if (!art_IntersectRect(&frUpdate, &frDisp, updatefr))
  447.         return;
  448.   // その PIC 領域に対応した SCRBITMAP 領域を更新する
  449.     FRAME frDraw; // 更新の必要な SCRBITMAP 領域
  450.     imagewin_getScrFrame(win, &frUpdate, &frDraw);
  451.     if (win->pic != NULL && win->bm != NULL)
  452.         pic_getScrBitmap(win->pic,win->bm,frDraw.X,frDraw.Y,&frUpdate,
  453.             win->zoom);
  454.   // 画面に描画
  455.     BEGINPAINT(win->win)
  456.     FRAME frUser; RM_getWinUserFrame(win->win, &frUser);
  457.     if (win->bm != NULL)
  458.         scrbitmap_drawPart(win->bm, &frDraw, frUser.X, frUser.Y);
  459.     ENDPAINT
  460. }
  461.  
  462. /*--------------------------------------------------------*/
  463. /*                       ラバー制御                       */
  464. /*--------------------------------------------------------*/
  465.  
  466. void imagewin_setBoxRubber(IMWIN* win, FRAME *fr)
  467.     // fr : PIC領域(x,y,wid,ht)
  468. {
  469.     win->fBoxRubber = TRUE;
  470.     win->frBoxRubber = *fr;
  471.     imagewin_updateScr(win);
  472. }
  473.  
  474. void imagewin_setBoxRubber2(IMWIN* win, FRAME *fr)
  475.     // fr : PIC領域(x,y,wid,ht)
  476. {
  477.     win->fBoxRubber2 = TRUE;
  478.     win->frBoxRubber2 = *fr;
  479.     imagewin_updateScr(win);
  480. }
  481.  
  482. void imagewin_clearBoxRubber(IMWIN* win)
  483. {
  484.     win->fBoxRubber = FALSE;
  485.     imagewin_updateScr(win);
  486. }
  487.  
  488. void imagewin_clearBoxRubber2(IMWIN* win)
  489. {
  490.     win->fBoxRubber2 = FALSE;
  491.     imagewin_updateScr(win);
  492. }
  493.  
  494. void imagewin_resetLineRubber(IMWIN* win)
  495. {
  496.     if (!win->fLineRubber)
  497.         return;
  498.     LIST* list = win->listLineRubber;
  499.     while (!list_isEmpty(list))
  500.       { list_top(list); list_deleteData(list); }
  501. }
  502.  
  503. void imagewin_addLineRubber(IMWIN* win,POINT* p1,POINT* p2)
  504. {
  505.     if (!win->fLineRubber)
  506.     {
  507.         win->fLineRubber = TRUE;
  508.         win->listLineRubber = list_new(sizeof(FRAME));
  509.     }
  510.     LIST* list = win->listLineRubber;
  511.     FRAME fr;
  512.     if (p2 == NULL)
  513.     {
  514.         list_top(list);  FRAME frTop;  list_getData(list,&frTop);
  515.         fr.X2 = frTop.X;
  516.         fr.Y2 = frTop.Y;
  517.     }
  518.     else
  519.         fr.X2 = p2->x, fr.Y2 = p2->y;
  520.     fr.X = p1->x, fr.Y = p1->y;
  521.     list_moveTo(list, list_getDataNum(list));
  522.     list_insertData(list,&fr);
  523.     imagewin_updateScr(win);
  524. }
  525.  
  526. int imagewin_nLineRubber(IMWIN* win)
  527. {
  528.     if (!win->fLineRubber)
  529.         return 0;
  530.     else
  531.         return list_getDataNum(win->listLineRubber);
  532. }
  533.  
  534. void imagewin_clearLineRubber(IMWIN* win)
  535. {
  536.     if (win->fLineRubber)
  537.     {
  538.         list_destroy(win->listLineRubber);
  539.         win->listLineRubber = NULL;
  540.         win->fLineRubber = FALSE;
  541.     }
  542.     imagewin_updateScr(win);
  543. }
  544.  
  545. void imagewin_resetLineRubber2(IMWIN* win)
  546. {
  547.     if (!win->fLineRubber2)
  548.         return;
  549.     LIST* list = win->listLineRubber2;
  550.     while (!list_isEmpty(list))
  551.       { list_top(list); list_deleteData(list); }
  552. }
  553.  
  554. void imagewin_addLineRubber2(IMWIN* win,POINT* p1,POINT* p2)
  555. {
  556.     if (!win->fLineRubber2)
  557.     {
  558.         win->fLineRubber2 = TRUE;
  559.         win->listLineRubber2 = list_new(sizeof(FRAME));
  560.     }
  561.     LIST* list = win->listLineRubber2;
  562.     FRAME fr;
  563.     if (p2 == NULL)
  564.     {
  565.         list_top(list);  FRAME frTop;  list_getData(list,&frTop);
  566.         fr.X2 = frTop.X;
  567.         fr.Y2 = frTop.Y;
  568.     }
  569.     else
  570.         fr.X2 = p2->x, fr.Y2 = p2->y;
  571.     fr.X = p1->x, fr.Y = p1->y;
  572.     list_moveTo(list, list_getDataNum(list));
  573.     list_insertData(list,&fr);
  574.     imagewin_updateScr(win);
  575. }
  576.  
  577. int imagewin_nLineRubber2(IMWIN* win)
  578. {
  579.     if (!win->fLineRubber2)
  580.         return 0;
  581.     else
  582.         return list_getDataNum(win->listLineRubber2);
  583. }
  584.  
  585. void imagewin_clearLineRubber2(IMWIN* win)
  586. {
  587.     if (win->fLineRubber2)
  588.     {
  589.         list_destroy(win->listLineRubber2);
  590.         win->listLineRubber2 = NULL;
  591.         win->fLineRubber2 = FALSE;
  592.     }
  593.     imagewin_updateScr(win);
  594. }
  595.  
  596. /*--------------------------------------------------------*/
  597. /*                        リサイズ                        */
  598. /*--------------------------------------------------------*/
  599.  
  600. int imagewin_resize(IMWIN *win, BOOL fRedraw)
  601. // NOERR, -1(メモリ不足)
  602. {
  603.     #define XADD    ((2+2) + (BAR_SIZE+2))        /* usr.wid + XADD = win.wid */
  604.     #define YADD    ((16+2) + (BAR_SIZE+2))        /* usr.ht + YADD = win.ht */
  605.     static FRAME frAdj[] =
  606.     {
  607.         { 2+2,16+2,-BAR_SIZE-1-2,-BAR_SIZE-1-2 },    // user 領域
  608.         { 1,1,-2,15 },        // タイトルバー
  609.         { 0, -BAR_SIZE, -BAR_SIZE, -1 },    // HSBAR
  610.         { -BAR_SIZE, 16, -1, -BAR_SIZE },    // VSBAR
  611.         { 0,0,0,0 }
  612.     };
  613.   // pic の大きさにあわせてウィンドウの大きさを制限
  614.     if (win->pic != NULL)
  615.     {
  616.         FRAME fr;
  617.         RM_getFrame(win->win, &fr);
  618.         int maxwid = win->pic->wid * win->zoom + XADD;
  619.         int maxht = win->pic->ht * win->zoom + YADD;
  620.         if (fr.X2-fr.X+1 > maxwid)
  621.             fr.X2 = fr.X + maxwid - 1;
  622.         if (fr.Y2-fr.Y+1 > maxht)
  623.             fr.Y2 = fr.Y + maxht - 1;
  624.         MMI_SendMessage(win->win, MM_MOVE, 1, &fr);
  625.     }
  626.   // 各部品を配置
  627.     RM_adjustWinUser(win->win, &frAdj[0]);
  628.     RM_adjustFrame(win->titlebar, win->win, &frAdj[1]);
  629.     RM_adjustFrame(win->sbar_h, win->win, &frAdj[2]);
  630.     RM_adjustFrame(win->sbar_v, win->win, &frAdj[3]);
  631.   // スクロールバーの更新
  632.     FRAME frDisp;
  633.     imagewin_getDispFrame(win, &frDisp);
  634.     int ofsx,ofsy;
  635.     ofsx = RM_getScrollPos(win->sbar_h);
  636.     ofsy = RM_getScrollPos(win->sbar_v);
  637.     RM_setScrollRange(win->sbar_h, frDisp.WID, win->pic->wid, FALSE);
  638.     RM_setScrollRange(win->sbar_v, frDisp.HT, win->pic->ht, FALSE);
  639.     ofsx = _min(ofsx, win->pic->wid - frDisp.WID);
  640.     ofsy = _min(ofsy, win->pic->ht - frDisp.HT);
  641.     RM_setScrollPos(win->sbar_h, ofsx, fRedraw);
  642.     RM_setScrollPos(win->sbar_v, ofsy, fRedraw);
  643.     if (!fRedraw)
  644.     {
  645.         // スクロールバーの表示フラグをクリア
  646.         MMI_SendMessage(win->sbar_h, MM_ERASE, 0);
  647.         MMI_SendMessage(win->sbar_v, MM_ERASE, 0);
  648.     }
  649.   // 画面出力バッファの再確保★
  650.     if (win->bm != NULL)
  651.         scrbitmap_delete(win->bm);
  652.     FRAME frUser;
  653.     RM_getWinUserFrame(win->win, &frUser);
  654.     win->bm = scrbitmap_new(frUser.X2-frUser.X+1, frUser.Y2-frUser.Y+1);
  655.     if (win->bm == NULL)
  656.         return -1;
  657.     imagewin_updateBuf(win);
  658.     return NOERR;
  659. }
  660.  
  661. void imagewin_setZoom(IMWIN *win, int zoom)
  662. {
  663.     win->zoom = zoom;
  664.     WINCLIP* clip;
  665.     WIN_beginUpDateObj(win->win, &clip);
  666.     imagewin_resize(win, FALSE);
  667.     MMI_SendMessage(idBackDialog, MM_SHOW, 0);
  668.     MMI_SendMessage(win->win, MM_SHOW, 0);
  669.     WIN_endUpDateObj(clip);
  670. }
  671.  
  672. void imagewin_updateTitle(IMWIN *win, BOOL fShow)
  673. // ウィンドウタイトルを更新表示する
  674. {
  675.     if (win->fname[0] == 0)
  676.     {
  677.         strcpy(win->title, "<名称未定>");
  678.     }
  679.     else
  680.     {
  681.         char drive[_MAX_DRIVE],dir[_MAX_DIR];
  682.         char basename[_MAX_FNAME],ext[_MAX_EXT];
  683.         _splitpath(win->fname, drive, dir, basename, ext);
  684.         sprintf(win->title, "%s%s%s",drive,basename,ext);
  685.         _strupr(win->title);
  686.     }
  687.     char buf[40];
  688.     sprintf(buf, " (%d×%d, %s colors) 倍率:×%d",
  689.             win->pic->wid, win->pic->ht, 
  690.             (win->pic->pixelsize == 16 ? "32K" : "16M"),
  691.             win->zoom);
  692.     strcat(win->title, buf);
  693.     if (fShow)
  694.     {
  695.         WINCLIP *clip;
  696.         WIN_beginUpDateObj(win->titlebar, &clip);
  697.         MMI_SendMessage(win->titlemsg, MM_ERASE, 0);
  698.         MMI_SendMessage(win->titlebar, MM_SHOW, 0);
  699.         MMI_SendMessage(win->erasebtn, MM_SHOW, 0);
  700.         MMI_SendMessage(win->titlemsg, MM_SETMSG, 1, win->title);
  701.         MMI_SendMessage(win->titlemsg, MM_SHOW, 0);
  702.         WIN_endUpDateObj(clip);
  703.     }
  704.     else
  705.     {
  706.         MMI_SendMessage(win->titlemsg, MM_SETMSG, 1, win->title);
  707.     }
  708. }
  709.  
  710. void imagewin_setFileName(IMWIN *win, char *fname, BOOL fShow)
  711. {
  712.     if (fname == NULL)
  713.         win->fname[0] = 0;
  714.     else
  715.         strncpy(win->fname, fname, _MAX_PATH-1);
  716.     imagewin_updateTitle(win, fShow);
  717. }
  718.  
  719. /*--------------------------------------------------------*/
  720. /*                        画像編集                        */
  721. /*--------------------------------------------------------*/
  722.  
  723. static PIC* picUndo = NULL;
  724. static IMWIN* undo_win = NULL;
  725.  
  726. void imagewin_storeUndo(IMWIN* win)
  727. {
  728.     if (picUndo != NULL)
  729.         pic_destroy(picUndo);
  730.     undo_win = win;
  731.     if ((picUndo = pic_dup(win->pic)) == NULL)
  732.     {
  733.     #if 0
  734.         dispAlertMessage("メモリが足りません",
  735.             "メモリ不足のため、この描画コマンドはアンドゥすることが"
  736.             "できません。ご注意ください");
  737.     #endif
  738.     }
  739. }
  740.  
  741. void imagewin_recoverUndo(void)
  742. {
  743.     if (undo_win == NULL)
  744.         return;
  745.     if (picUndo == NULL)
  746.         return;
  747.     PIC* pic = undo_win->pic;
  748.     undo_win->pic = picUndo;
  749.     pic_destroy(pic);
  750.     picUndo = NULL;
  751.     imagewin_updateBuf(undo_win);
  752.     imagewin_updateScr(undo_win);
  753.     undo_win = NULL;
  754. }
  755.  
  756. void imagewin_copy(IMWIN* srcwin, FRAME* frSrc, IMWIN* destwin, POINT *ptDest)
  757. {
  758.     FRAME frUpdate;
  759.     imagewin_storeUndo(destwin);
  760.     pic_beginUpDate(destwin->pic);
  761.     pic_copy(srcwin->pic, frSrc, destwin->pic, ptDest);
  762.     pic_endUpDate(destwin->pic, &frUpdate);
  763.     imagewin_updateScrPart(destwin, &frUpdate);
  764. }
  765.  
  766. void imagewin_copyarea(IMWIN* srcwin,AREA areaSrc,IMWIN* destwin,POINT *ptDest)
  767. {
  768.     FRAME frUpdate;
  769.     imagewin_storeUndo(destwin);
  770.     pic_beginUpDate(destwin->pic);
  771.     pic_copyarea(srcwin->pic, areaSrc, destwin->pic, ptDest);
  772.     pic_endUpDate(destwin->pic, &frUpdate);
  773.     imagewin_updateScrPart(destwin, &frUpdate);
  774. }
  775.