rect.c

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|