C:\home\SVGCats_src\src\rect.c
1|/*********************************************************************** 2| 1. <<< 矩形 (Rect) >>> 3|************************************************************************/ 4| 5|#include "mixer_precomp.h" /* Auto precompiled header, Look at mixer-... folder */ 6|// #pragma hdrstop 7| 8|#if defined(USES_MXP_AUTOINC) 9| #include "rect.ah" /* Auto include header, Look at mixer-... folder */ 10|#endif 11| 12|/*-------------------------------------------------------------------------*/ 13|/* 2. <<<< ◆(Rect) 矩形(幅・高さ指定) >>>> */ 14|/*-------------------------------------------------------------------------*/ 15| 16|/*********************************************************************** 17| 2-1. <<< [Rect_init] 初期化する >>> 18|************************************************************************/ 19|void Rect_init( Rect* m, int x, int y, int w, int h ) 20|{ 21| m->x = x; m->y = y; 22| m->w = w; m->h = h; 23|} 24| 25| 26| 27|/*********************************************************************** 28| 2-2. <<< [Rect_isEqual] 同じ矩形領域かどうか判定する >>> 29|************************************************************************/ 30|bool Rect_isEqual( Rect* a, Rect* b ) 31|{ 32| return memcmp( a, b, sizeof(Rect) ) == 0; 33|} 34| 35| 36| 37|/*********************************************************************** 38| 2-3. <<< [Rect_toAnd] 共通部分の矩形にする >>> 39|【機能】 40|・矩形 a と矩形 b の共通部分を ans とする。 41|・共通部分がないときは、ans->w または ans->h が0かマイナスになります。 42|************************************************************************/ 43|void Rect_toAnd( Rect* ans, Rect* a, Rect* b ) 44|{ 45| #define MAX(x,y) ((x)<(y) ? (y) : (x) ) 46| #define MIN(x,y) ((x)<(y) ? (x) : (y) ) 47| 48| ans->x = MAX( a->x, b->x ); 49| ans->y = MAX( a->y, b->y ); 50| 51| ans->w = MIN( a->x + a->w, b->x + b->w ) - ans->x; 52| ans->h = MIN( a->y + a->h, b->y + b->h ) - ans->y; 53| 54| #undef MAX 55| #undef MIN 56|} 57| 58| 59| 60|/*********************************************************************** 61| 2-4. <<< [Rect_print] デバッグ表示する >>> 62|【引数】 63| ・char* title; 行頭に加えるメッセージ 64|************************************************************************/ 65|#ifdef USES_ERRORS 66|#ifndef ERRORS_CUT_DEBUG_TOOL 67|void Rect_print( Rect* m, const char* title ) 68|{ 69| Errors_printf( "%s:Rect(%p): (x,y)-(w,h) = (%d, %d) - (%d, %d)", 70| title, m, m->x, m->y, m->w, m->h ); 71|} 72|#endif /* not ERRORS_CUT_DEBUG_TOOL */ 73|#endif 74| 75| 76| 77|/*********************************************************************** 78| 2-5. <<< [Rect_isPointIn] 矩形の内部に点があるかどうかを返す(端も含む) >>> 79|【引数】 80| ・Rect* rect; 矩形 81| ・int x,y; 点 82| ・bool 返り値; 矩形の内部に点があるかどうか(端も含む) 83|************************************************************************/ 84|bool Rect_isPointIn( Rect* rect, int x, int y ) 85|{ 86| const int x1 = rect->x; 87| const int y1 = rect->y; 88| const int x2 = rect->x + rect->w - 1; 89| const int y2 = rect->y + rect->h - 1; 90| 91| return ( x1 <= x && x <= x2 && y1 <= y && y <= y2 ); 92|} 93| 94| 95| 96|/*********************************************************************** 97| 2-6. <<< [Rect_getPointPos] 矩形と点の位置関係を返す >>> 98|【引数】 99| ・Rect* rect; 矩形 100| ・int x,y; 点 101| ・int 返り値; RECT_X_LT 等の、X, Y に関する論理和 102|************************************************************************/ 103|int Rect_getPointPos( Rect* rect, int x, int y ) 104|{ 105| int f; 106| 107| if ( x < rect->x ) f = RECT_X_LT; 108| else if ( x == rect->x ) f = RECT_X_LE; 109| else if ( x < rect->x + rect->w ) f = RECT_X_E; 110| else if ( x == rect->x + rect->w ) f = RECT_X_GE; 111| else f = RECT_X_GT; 112| 113| if ( y < rect->y ) f |= RECT_Y_LT; 114| else if ( y == rect->y ) f |= RECT_Y_LE; 115| else if ( y < rect->y + rect->h ) f |= RECT_Y_E; 116| else if ( y == rect->y + rect->h ) f |= RECT_Y_GE; 117| else f |= RECT_Y_GT; 118| 119| return f; 120|} 121| 122| 123| 124|/*********************************************************************** 125| 2-7. <<< [Rect_getHitHandleNum] CadPrim::GetHitHandleNum の実装部 >>> 126|【補足】 127|・ハンドル番号は、左上が1、上が2、右上が3、左が4、右が5、左下が6、 128| 下が7、右下が8です。 129|・ハンドルの数は、Rect_nHandle です。 130|************************************************************************/ 131|int Rect_getHitHandleNum( Rect* m, int x, int y, int zoom, 132| int* dx, int* dy, int* arrow ) 133|{ 134| int dx1, dy1, dx2, dy2, dx3, dy3; 135| int diff = 8; 136| int diff2 = 2; 137| int minDiff = 2 * diff + 1; 138| int d; 139| int ret; 140| 141| diff = 8 * 100 / zoom; if ( diff < 1 ) diff = 1; 142| diff2 = 2 * 100 / zoom; if ( diff2 < 1 ) diff2 = 1; 143| 144| dx1 = x - m->x; 145| dy1 = y - m->y; 146| dx2 = x - ( m->x + (m->w + 1) / 2 ); 147| dy2 = y - ( m->y + (m->h + 1) / 2 ); 148| dx3 = x - ( m->x + m->w + 1 ); 149| dy3 = y - ( m->y + m->h + 1 ); 150| 151| *dx = 0; *dy = 0; ret = 0; 152| 153| if ( m->w < diff && m->h < diff ) { 154| if ( dx3 >= -diff2 && dx3 <= diff && dy3 >= -diff2 && dy3 <= diff ) 155| { *arrow = CadPrim_RightDownArrow; return 8; } 156| else 157| { *arrow = CadPrim_NormalArrow; return 0; } 158| } 159| else { 160| if ( dx3 >= -diff2 && dx3 <= diff && dy2 >= -diff && dy2 <= diff ) { 161| d = abs(dx3) + abs(dy2); 162| if ( d < minDiff ) 163| { *arrow = CadPrim_HorizontalArrow; minDiff = d; ret = 5; } 164| } 165| if ( dx2 >= -diff && dx2 <= diff && dy3 >= -diff2 && dy3 <= diff ) { 166| d = abs(dx2) + abs(dy3); 167| if ( d < minDiff ) 168| { *arrow = CadPrim_VerticalArrow; minDiff = d; ret = 7; } 169| } 170| if ( dx1 >= -diff && dx1 <= diff2 && dy2 >= -diff && dy2 <= diff ) { 171| d = abs(dx1) + abs(dy2); 172| if ( d < minDiff ) 173| { *arrow = CadPrim_HorizontalArrow; minDiff = d; ret = 4; } 174| } 175| if ( dx2 >= -diff && dx2 <= diff && dy1 >= -diff && dy1 <= diff2 ) { 176| d = abs(dx2) + abs(dy1); 177| if ( d < minDiff ) 178| { *arrow = CadPrim_VerticalArrow; minDiff = d; ret = 2; } 179| } 180| if ( dx3 >= -diff2 && dx3 <= diff && dy3 >= -diff2 && dy3 <= diff ) { 181| d = abs(dx3) + abs(dy3); 182| if ( d < minDiff ) 183| { *arrow = CadPrim_RightDownArrow; minDiff = d; ret = 8; } 184| } 185| if ( dx1 >= -diff && dx1 <= diff2 && dy1 >= -diff && dy1 <= diff2 ) { 186| d = abs(dx1) + abs(dy1); 187| if ( d < minDiff ) 188| { *arrow = CadPrim_RightDownArrow; minDiff = d; ret = 1; } 189| } 190| if ( dx3 >= -diff2 && dx3 <= diff && dy1 >= -diff && dy1 <= diff2 ) { 191| d = abs(dx3) + abs(dy1); 192| if ( d < minDiff ) 193| { *arrow = CadPrim_RightUpArrow; minDiff = d; ret = 3; } 194| } 195| if ( dx1 >= -diff && dx1 <= diff2 && dy3 >= -diff2 && dy3 <= diff ) { 196| d = abs(dx1) + abs(dy3); 197| if ( d < minDiff ) 198| { *arrow = CadPrim_RightUpArrow; minDiff = d; ret = 6; } 199| } 200| 201| if ( ret != 0 ) { 202| return ret; 203| } 204| else if ( m->x <= x && x <= m->x + m->w && m->y <= y && y <= m->y + m->h ) { 205| *dx = m->x - x; *dy = m->y - y; 206| *arrow = CadPrim_MovableArrow; 207| return -1; 208| } 209| else { 210| *arrow = CadPrim_NormalArrow; 211| return 0; 212| } 213| } 214|} 215| 216| 217|/*********************************************************************** 218| 2-8. <<< [Rect_moveByHandle] CadPrim::MoveByHandle の実装部 >>> 219|************************************************************************/ 220|void Rect_moveByHandle( Rect* m, int iHandle, int x, int y, bool bShift ) 221|{ 222| int dx, dy, xx, yy; 223| 224| if ( bShift ) { 225| switch ( iHandle ) { 226| case 1: 227| dx = x - m->x; yy = m->y + m->h; 228| m->x = x; m->w -= dx; 229| if ( m->w < 1 ) { m->x -= -m->w + 1; m->w = 1; } 230| m->y = yy - m->w; m->h = m->w; 231| break; 232| 233| case 2: 234| dy = y - m->y; 235| m->y = y; 236| m->h -= dy; 237| if ( m->h < 1 ) { m->y -= -m->h + 1; m->h = 1; } 238| xx = m->x + m->w / 2; 239| m->x = xx - m->h / 2; m->w = m->h; 240| break; 241| 242| case 3: 243| yy = m->y + m->h; 244| m->w = x - m->x + 1; 245| if ( m->w < 1 ) { m->w = 1; } 246| m->y = yy - m->w; 247| m->h = m->w; 248| break; 249| 250| case 4: 251| dx = x - m->x; 252| m->x = x; 253| m->w -= dx; 254| if ( m->w < 1 ) { m->x -= -m->w + 1; m->w = 1; } 255| yy = m->y + m->h / 2; 256| m->y = yy - m->w / 2; m->h = m->w; 257| break; 258| 259| case 5: 260| m->w = x - m->x + 1; 261| if ( m->w < 1 ) { m->w = 1; } 262| yy = m->y + m->h / 2; 263| m->y = yy - m->w / 2; m->h = m->w; 264| break; 265| 266| case 6: 267| dx = x - m->x; 268| m->x = x; 269| m->w -= dx; 270| if ( m->w < 1 ) { m->x -= -m->w + 1; m->w = 1; } 271| m->h = m->w; 272| break; 273| 274| case 7: 275| m->h = y - m->y + 1; 276| if ( m->h < 1 ) { m->h = 1; } 277| xx = m->x + m->w / 2; 278| m->x = xx - m->h / 2; m->w = m->h; 279| break; 280| 281| case 8: 282| m->w = x - m->x + 1; 283| if ( m->w < 1 ) { m->w = 1; } 284| m->h = m->w; 285| break; 286| 287| case -1: 288| m->x = x; m->y = y; 289| break; 290| } 291| } 292| else { 293| switch ( iHandle ) { 294| case 1: 295| dx = x - m->x; dy = y - m->y; 296| m->x = x; m->y = y; 297| m->w -= dx; m->h -= dy; 298| if ( m->w < 1 ) { m->x -= -m->w + 1; m->w = 1; } 299| if ( m->h < 1 ) { m->y -= -m->h + 1; m->h = 1; } 300| break; 301| 302| case 2: 303| dy = y - m->y; 304| m->y = y; 305| m->h -= dy; 306| if ( m->h < 1 ) { m->y -= -m->h + 1; m->h = 1; } 307| break; 308| 309| case 3: 310| dy = y - m->y; 311| m->y = y; 312| m->w = x - m->x; m->h -= dy; 313| if ( m->w < 1 ) { m->w = 1; } 314| if ( m->h < 1 ) { m->y -= -m->h + 1; m->h = 1; } 315| break; 316| 317| case 4: 318| dx = x - m->x; 319| m->x = x; 320| m->w -= dx; 321| if ( m->w < 1 ) { m->x -= -m->w + 1; m->w = 1; } 322| break; 323| 324| case 5: 325| m->w = x - m->x; 326| if ( m->w < 1 ) { m->w = 1; } 327| break; 328| 329| case 6: 330| dx = x - m->x; 331| m->x = x; 332| m->w -= dx; m->h = y - m->y; 333| if ( m->w < 1 ) { m->x -= -m->w + 1; m->w = 1; } 334| if ( m->h < 1 ) { m->h = 1; } 335| break; 336| 337| case 7: 338| m->h = y - m->y; 339| if ( m->h < 1 ) { m->h = 1; } 340| break; 341| 342| case 8: 343| m->w = x - m->x; m->h = y - m->y; 344| if ( m->w < 1 ) { m->w = 1; } 345| if ( m->h < 1 ) { m->h = 1; } 346| break; 347| 348| case -1: 349| m->x = x; m->y = y; 350| break; 351| } 352| } 353|} 354| 355| 356|/*********************************************************************** 357| 2-9. <<< [Rect_getCenterOfHandle] ハンドルの中心座標を取得する >>> 358|【引数】 359| ・Rect* rect; 矩形 360| ・int iHandle; ハンドル番号(1〜Rect_nHandle) 361| ・int* x,y; 座標を格納する領域のアドレス 362|【補足】 363|・ハンドルについては、Rect_getHitHandleNum を参照。 364|************************************************************************/ 365|void Rect_getCenterOfHandle( Rect* m, int iHandle, int* x, int* y ) 366|{ 367|#if 0 /* 幅がピクセル数と一致するとき */ 368| switch ( iHandle ) { 369| case 1: 370| *x = m->x; *y = m->y; 371| break; 372| 373| case 2: 374| *x = m->x + (m->w - 1) / 2; *y = m->y; 375| break; 376| 377| case 3: 378| *x = m->x + m->w - 1; *y = m->y; 379| break; 380| 381| case 4: 382| *x = m->x; *y = m->y + (m->h - 1) / 2; 383| break; 384| 385| case 5: 386| *x = m->x + m->w - 1; *y = m->y + (m->h - 1) / 2; 387| break; 388| 389| case 6: 390| *x = m->x; *y = m->y + m->h - 1; 391| break; 392| 393| case 7: 394| *x = m->x + (m->w - 1) / 2; *y = m->y + m->h - 1; 395| break; 396| 397| case 8: 398| *x = m->x + m->w - 1; *y = m->y + m->h - 1; 399| break; 400| } 401|#endif 402| 403|#if 0 /* 幅が右端から左端の差のとき */ 404| switch ( iHandle ) { 405| case 1: 406| *x = m->x; *y = m->y; 407| break; 408| 409| case 2: 410| *x = m->x + m->w / 2; *y = m->y; 411| break; 412| 413| case 3: 414| *x = m->x + m->w; *y = m->y; 415| break; 416| 417| case 4: 418| *x = m->x; *y = m->y + m->h / 2; 419| break; 420| 421| case 5: 422| *x = m->x + m->w; *y = m->y + m->h / 2; 423| break; 424| 425| case 6: 426| *x = m->x; *y = m->y + m->h; 427| break; 428| 429| case 7: 430| *x = m->x + m->w / 2; *y = m->y + m->h; 431| break; 432| 433| case 8: 434| *x = m->x + m->w; *y = m->y + m->h; 435| break; 436| } 437|#endif 438| 439|#if 1 /* for SVG */ 440| switch ( iHandle ) { 441| case 1: 442| *x = m->x; *y = m->y; 443| break; 444| 445| case 2: 446| *x = m->x + (m->w + 1) / 2; *y = m->y; 447| break; 448| 449| case 3: 450| *x = m->x + m->w + 1; *y = m->y; 451| break; 452| 453| case 4: 454| *x = m->x; *y = m->y + (m->h + 1) / 2; 455| break; 456| 457| case 5: 458| *x = m->x + m->w + 1; *y = m->y + (m->h + 1) / 2; 459| break; 460| 461| case 6: 462| *x = m->x; *y = m->y + m->h + 1; 463| break; 464| 465| case 7: 466| *x = m->x + (m->w + 1) / 2; *y = m->y + m->h + 1; 467| break; 468| 469| case 8: 470| *x = m->x + m->w + 1; *y = m->y + m->h + 1; 471| break; 472| } 473|#endif 474|} 475| 476| 477|/*-------------------------------------------------------------------------*/ 478|/* 3. <<<< ◆ (Rect_2XY) 矩形(2点指定)>>>> */ 479|/*-------------------------------------------------------------------------*/ 480| 481|/*********************************************************************** 482| 3-1. <<< [Rect_2XY_setInDesktop] ウィンドウが外に出ないようにデスクトップの中に入れる >>> 483|【引数】 484| ・Rect_2XY* wnd; ウィンドウの位置(入出力) 485| ・Rect_2XY* desktop; デスクトップのサイズ 486|【補足】 487|・デスクトップの大きさは、GetDesktopWindow と GetWindowRect で取得できます。 488|・ウィンドウの移動は、MoveWindow です。 489|************************************************************************/ 490|void Rect_2XY_setInDesktop( Rect_2XY* wnd, Rect_2XY* desktop ) 491|{ 492| if ( wnd->x2 > desktop->x2 ) { 493| wnd->x1 -= wnd->x2 - desktop->x2; 494| wnd->x2 = desktop->x2; 495| if ( wnd->x1 < 0 ) wnd->x1 = 0; 496| } 497| if ( wnd->y2 > desktop->y2 ) { 498| wnd->y1 -= wnd->y2 - desktop->y2; 499| wnd->y2 = desktop->y2; 500| if ( wnd->y1 < 0 ) wnd->y1 = 0; 501| } 502|} 503| 504|