Logo Search packages:      
Sourcecode: sagcad version File versions  Download package

List_cad.c

/* ====================================================================
 * ===  Copyright (C) 1998-2007 Yutaka Sagiya. All rights reserved. ===
 * ====================================================================
 * 
 *    Project              : SagCAD
 *    Description          : CAD/CAM
 *    Source               : List_cad.c
 * 
 *    ----------------------------------
 * 
 *    License              : GNU General Public License (GPL)
 *    Copyright            : (C) 1998-2007 by Yutaka Sagiya
 *    email                : kappa@a6s.highway.ne.jp
 *                         : yutaka@sagiya.com
 *    Begin                : 2001/01/16
 *    Last                 : 2007/11/08
 * ====================================================================
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include "MemoryLeak.h"
#include "types.h"
#include "List_Undo.h"
#define _LIST_CAD_
#include "List_cad.h"





int init_cad(CAD *cad)
{
      /* CAD Data の初期化 */
      cad->layer = 0;
      cad->style = 1;
      cad->color = 0xffffff;
      cad->code = 0;
      cad->sx = 0;
      cad->sy = 0;
      cad->ex = 0;
      cad->ey = 0;
      cad->cx = 0;
      cad->cy = 0;
      cad->r  = 0;
      cad->OnScreen = 0;
      return 1;
}





/* -------------------------------------------------------------------
 * 領域確保済みの CAD Data をリストの最初に追加
 * 
 */
CAD_LIST *r_cad_list_add_first(CAD *add_cad, CAD_LIST_INFO *p_cad_list_info)
{
      CAD_LIST *p;

      /* データ (LIST) を書き込むための領域を確保する */
      p_cad_list = (CAD_LIST *)xmalloc(sizeof(CAD_LIST));



#ifdef TEST
      char str[256];
      sprintf(str, "List_cad.c : r_cad_list_add_first() : New CAD_LIST (0x%x)\n", p_cad_list);
      OneShotLog(str);
      sprintf(str, "    0x%x : (%f,%f)-(%f,%f) (%f,%f),R%f\n", 
                        p_cad_list->cad, 
                        add_cad->sx, add_cad->sy, add_cad->ex, add_cad->ey, 
                        add_cad->cx, add_cad->cy, add_cad->r
                        );
      OneShotLog(str);
#endif


      /* 確保した領域にデータ (cad) を書き込む */
      p_cad_list->cad = add_cad;
      p_cad_list->next = NULL;


      /* -----------------------------------------------------
       * head & tail の両方が NULL のときは、1個もデータがない 
       */
      if (p_cad_list_info->head == NULL && p_cad_list_info->tail == NULL) {
            p_cad_list_info->head = p_cad_list;
            p_cad_list_info->tail = p_cad_list;
      }

      /* -----------------------------------------------------
       * データが1個以上ある
       */
      else {
            p = p_cad_list_info->head;
            p_cad_list_info->head = p_cad_list;
            p_cad_list->next = p;
      }

      return p_cad_list_info->head;
}





/* -------------------------------------------------------------------
 * CAD Data をリストの最初に追加
 * 
 */
CAD_LIST *cad_list_add_first(CAD *add_cad, CAD_LIST_INFO *p_cad_list_info)
{
      CAD_LIST *p;

      /* データ (LIST) を書き込むための領域を確保する */
      p_cad_list = (CAD_LIST *)xmalloc(sizeof(CAD_LIST));


#ifdef TEST
      g_print("List_cad.c : cad_list_add_first() : New CAD_LIST (0x%x)\n", (int)p_cad_list);
      g_print("    0x%x : (%f,%f)-(%f,%f) (%f,%f),R%f\n", 
                        (int)p_cad_list->cad, 
                        add_cad->sx, add_cad->sy, add_cad->ex, add_cad->ey, 
                        add_cad->cx, add_cad->cy, add_cad->r);
#endif


      /* データ (cad) を書き込むための領域を確保する */
      p_cad_list->cad = (CAD *)xmalloc(sizeof(CAD));

      /* 確保した領域にデータ (cad) を書き込む */
      *p_cad_list->cad = *add_cad;
      p_cad_list->next = NULL;

//    g_print("List_cad.c : cad_list_add_first() : (%f,%f)-(%f,%f) (%f,%f),R%f\n", 
//                      p_cad_list->cad->sx, p_cad_list->cad->sy, p_cad_list->cad->ex, p_cad_list->cad->ey, 
//                      p_cad_list->cad->cx, p_cad_list->cad->cy, p_cad_list->cad->r);

      /* -----------------------------------------------------
       * head & tail の両方が NULL のときは、1個もデータがない 
       */
      if (p_cad_list_info->head == NULL && p_cad_list_info->tail == NULL) {
//          g_print("List Non Data\n");
            p_cad_list_info->head = p_cad_list;
            p_cad_list_info->tail = p_cad_list;
      }

      /* -----------------------------------------------------
       * データが1個以上ある
       */
      else {
//          g_print("List over 1 Data\n");
            p = p_cad_list_info->head;
            p_cad_list_info->head = p_cad_list;
            p_cad_list->next = p;
      }

      return p_cad_list_info->head;
}





/* -------------------------------------------------------------------
 * CAD Data をリストの最初に追加して、 Undo Baffer に書込む
 *    
 */
CAD_LIST *cad_list_add_first_with_undo(CAD *add_cad, CAD_LIST_INFO *p_cad_list_info)
{
      CAD_LIST *p;
      CAD cad = {0,0,0,0,0,0,0,0,0,0,0,0};

      DIAGRAM diagram;
      LPDIAGRAM lpdiagram;


      /* データ (LIST) を書き込むための領域を確保する */
      p_cad_list = (CAD_LIST *)xmalloc(sizeof(CAD_LIST));

      /* データ (cad) を書き込むための領域を確保する */
      p_cad_list->cad = (CAD *)xmalloc(sizeof(CAD));

      /* 確保した領域にデータ (cad) を書き込む */
      *p_cad_list->cad = *add_cad;
      p_cad_list->next = NULL;


      /* -----------------------------------------------------
       * head & tail の両方が NULL のときは、1個もデータがない 
       */
      if (p_cad_list_info->head == NULL && p_cad_list_info->tail == NULL) {
            p_cad_list_info->head = p_cad_list;
            p_cad_list_info->tail = p_cad_list;
      }

      /* -----------------------------------------------------
       * データが1個以上ある
       */
      else {
            p = p_cad_list_info->head;
            p_cad_list_info->head = p_cad_list;
            p_cad_list->next = p;
      }


      lpdiagram.cad_point = p_cad_list_info->head->cad;
      diagram.cad = cad;

      /* Undo Buffa Write */
      undo_list_add_first(CAD_NEW, lpdiagram, diagram);
      return p_cad_list_info->head;
}





/* -------------------------------------------------------------------
 * CAD Data をリストの最後に追加
 * 
 */
CAD_LIST *cad_list_add_last(CAD *add_cad, CAD_LIST_INFO *p_cad_list_info)
{
      CAD_LIST *p;


      /* データ (LIST) を書き込むための領域を確保する */
      p_cad_list = (CAD_LIST *)xmalloc(sizeof(CAD_LIST));

      /* データ (cad) を書き込むための領域を確保する */
      p_cad_list->cad = (CAD *)xmalloc(sizeof(CAD));

      /* 確保した領域にデータ (cad) を書き込む */
      *p_cad_list->cad = *add_cad;
      p_cad_list->next = NULL;


      /* -----------------------------------------------------
       * head & tail の両方が NULL のときは、1個もデータがない 
       */
      if (p_cad_list_info->head == NULL && p_cad_list_info->tail == NULL) {
            p_cad_list_info->head = p_cad_list;
            p_cad_list_info->tail = p_cad_list;
      }

      /* -----------------------------------------------------
       * head = tail で NULL ではないときは、1個だけデータがある
       */
      else if (p_cad_list_info->head != NULL 
                        && p_cad_list_info->tail != NULL 
                              && p_cad_list_info->head == p_cad_list_info->tail) {
            p_cad_list_info->head->next = p_cad_list;
            p_cad_list_info->tail = p_cad_list;
      }

      /* -----------------------------------------------------
       * データが2個以上ある
       */
      else {
            p = p_cad_list_info->tail;
            p_cad_list_info->tail = p_cad_list;
            p->next = p_cad_list_info->tail;
      }

      /* アンドゥバッファに書込む */
//    undo_list_add_first(11, p_cad_list_info->tail, NULL);
      return p_cad_list_info->tail;
}





/* -------------------------------------------------------------------
 * CAD Data をリストの最後に追加、 Undo Baffer に書込む
 *    
 */
CAD_LIST *cad_list_add_last_with_undo(CAD *add_cad, CAD_LIST_INFO *p_cad_list_info)
{
      CAD_LIST *p;
      CAD cad = {0,0,0,0,0,0,0,0,0,0,0,0};

      DIAGRAM diagram;
      LPDIAGRAM lpdiagram;


      /* データ (LIST) を書き込むための領域を確保する */
      p_cad_list = (CAD_LIST *)xmalloc(sizeof(CAD_LIST));

      /* データ (cad) を書き込むための領域を確保する */
      p_cad_list->cad = (CAD *)xmalloc(sizeof(CAD));

      /* 確保した領域にデータ (cad) を書き込む */
      *p_cad_list->cad = *add_cad;
      p_cad_list->next = NULL;


      /* -----------------------------------------------------
       * head & tail の両方が NULL のときは、1個もデータがない 
       */
      if (p_cad_list_info->head == NULL && p_cad_list_info->tail == NULL) {
            p_cad_list_info->head = p_cad_list;
            p_cad_list_info->tail = p_cad_list;
      }

      /* -----------------------------------------------------
       * head = tail で NULL ではないときは、1個だけデータがある
       */
      else if (p_cad_list_info->head != NULL 
                        && p_cad_list_info->tail != NULL 
                              && p_cad_list_info->head == p_cad_list_info->tail) {
            p_cad_list_info->head->next = p_cad_list;
            p_cad_list_info->tail = p_cad_list;
      }

      /* -----------------------------------------------------
       * データが2個以上ある
       */
      else {
            p = p_cad_list_info->tail;
            p_cad_list_info->tail = p_cad_list;
            p->next = p_cad_list_info->tail;
      }

      lpdiagram.cad_point = p_cad_list_info->tail->cad;
      diagram.cad = cad;

      /* Undo Buffa Write */
      undo_list_add_first(CAD_NEW, lpdiagram, diagram);
      return p_cad_list_info->tail;
}





/* -------------------------------------------------------------------
 * CAD Data の削除機能 (メモリの削除ではない)
 * 
 */
int cad_list_delete(CAD_LIST *del_List, CAD_LIST_INFO *p_cad_list_info)
{
      CAD_LIST *p = NULL;
      CAD_LIST *pb = NULL;


      /* データが先頭で1個だけ  */
      if (del_List == p_cad_list_info->head && del_List->next == NULL) {
            p_cad_list_info->head = NULL;
            p_cad_list_info->tail = NULL;
      }
      /* データが先頭で2個以上  */
      else if (del_List == p_cad_list_info->head && del_List->next != NULL) {
            p_cad_list_info->head = p_cad_list_info->head->next;
      }
      else {
            /* -------------------------------------------
             * 削除するポインタの前のデータを知りたいので、
             * head (リストの先頭) から削除するポインタが
             * 見つかるまで繰り返し、前のデータを探す。
             */
            p = p_cad_list_info->head;
            /* -------------------------------------------
             * 最後まで見つからない場合、 p に NULL が 
             * 入ってループを抜ける。
             */
            while(p != NULL && p != del_List) {
                  pb = p;                 /* 前のデータのポインタとして保存しておく */
                  p = p->next;      /* ポインタを次のデータに移す */
            }


            if(p != NULL){
                  /* 最後のデータ */
                  if (del_List == p_cad_list_info->tail) {
                        pb->next = NULL;
                        p_cad_list_info->tail = pb;
                  }
                  /* 中間のデータ */
                  else if (del_List != p_cad_list_info->head && del_List != p_cad_list_info->tail) {
                        pb->next = p->next;
                  }
            }
            else {
                  g_print("List_cad.c : cad_list_delete() : There is not data of structure data CAD.\n");
                  return 0;
            }
      }
      xfree(del_List);
//    StartData = p_cad_list_info->head;
      return 1;
}





/* -------------------------------------------------------------------
 * CAD Data の削除機能 (メモリの削除ではなく、Undo Buffer へ移す)
 * 
 */
int cad_list_delete_Undo(CAD_LIST *del_List, CAD_LIST_INFO *p_cad_list_info)
{
      CAD_LIST *p = NULL;
      CAD_LIST *pb = NULL;

      DIAGRAM diagram;
      LPDIAGRAM lpdiagram;


      /* データが先頭で1個だけ  */
      if (del_List == p_cad_list_info->head && del_List->next == NULL) {
            p_cad_list_info->head = NULL;
            p_cad_list_info->tail = NULL;
      }
      /* データが先頭で2個以上  */
      else if (del_List == p_cad_list_info->head && del_List->next != NULL) {
            p_cad_list_info->head = p_cad_list_info->head->next;
      }
      else {
            /* -------------------------------------------
             * 削除するポインタの前のデータを知りたいので、
             * head (リストの先頭) から削除するポインタが
             * 見つかるまで繰り返し、前のデータを探す。
             */
            p = p_cad_list_info->head;
            /* -------------------------------------------
             * 最後まで見つからない場合、 p に NULL が 
             * 入ってループを抜ける。
             */
            while(p != NULL && p != del_List) {
                  pb = p;                 /* 前のデータのポインタとして保存しておく */
                  p = p->next;      /* ポインタを次のデータに移す */
            }


            if(p != NULL){
                  /* 最後のデータ */
                  if (del_List == p_cad_list_info->tail) {
                        pb->next = NULL;
                        p_cad_list_info->tail = pb;
                  }
                  /* 中間のデータ */
                  else if (del_List != p_cad_list_info->head && del_List != p_cad_list_info->tail) {
                        pb->next = p->next;
                  }
            }
            else {
                  g_print("List_cad.c : cad_list_delete() : There is not data of structure data CAD.\n");
                  return 0;
            }
      }

      lpdiagram.cad_point = del_List->cad;
      diagram.cad = *del_List->cad;

      undo_list_add_first(CAD_DEL, lpdiagram, diagram);
      xfree(del_List);
//    StartData = p_cad_list_info->head;
      return 1;
}





/* -------------------------------------------------------------------
 * CAD のポインタのデータを Undo バッファ(編集)に入れて、
 * その場所に新しいデータを入れる。
 *    
 * 戻り値 元のデータのアドレス
 */
CAD_LIST *cad_list_edit(CAD_LIST *point, CAD *change_cad, CAD_LIST_INFO *p_cad_list_info)
{
      /* データ (LIST) を書き込むための領域を確保する */
      p_cad_list = (CAD_LIST *)xmalloc(sizeof(CAD_LIST));

      /* データ (cad) を書き込むための領域を確保する */
      p_cad_list->cad = (CAD *)xmalloc(sizeof(CAD));

      /* 確保した領域に変更前のデータ (cad) を書き込む */
      *p_cad_list->cad = *point->cad;
      p_cad_list->next = point;

      /* 変更データを書き込む */
      *point->cad = *change_cad;

//    undo_list_add_first(13, p_cad_list, NULL);
      return p_cad_list;
}





/* -------------------------------------------------------------------
 * CAD のポインタのデータを Undo バッファ(編集)に入れて、
 * その場所に新しいデータを入れ、Undo Baffer に書込む
 *    
 * 戻り値 元のデータのアドレス
 */
CAD_LIST *cad_list_edit_with_undo(CAD_LIST *point, CAD *change_cad, CAD_LIST_INFO *p_cad_list_info)
{
      CAD cad = {0,0,0,0,0,0,0,0,0,0,0,0};

      DIAGRAM diagram;
      LPDIAGRAM lpdiagram;


      /* 確保した領域に変更前のデータ (CAD) を書き込む */
      cad = *point->cad;

      /* 変更データを書き込む */
      *point->cad = *change_cad;


      lpdiagram.cad_point = point->cad;
      diagram.cad = cad;

      undo_list_add_first(CAD_EDIT, lpdiagram, diagram);
      return point;
}





/* -------------------------------------------------------------------
 *    リストの総数を調べる
 */
long cad_list_num(CAD_LIST_INFO *p_cad_list_info)
{
      CAD_LIST *p;
      long i;

      p = p_cad_list_info->head;
      i = 0;
      /* -------------------------------------------
       * 最後まで見つからない場合、 p に NULL が 
       * 入ってループを抜ける。
       */
      while(p != NULL) {
            i++;
            p = p->next;      /* ポインタを次のデータに移す */
      }
      return i;
}





/* -------------------------------------------------------------------
 * n 番目のデータの検索
 * 
 */
CAD_LIST *cad_search_num(long search_number, CAD_LIST_INFO *p_cad_list_info)
{
      CAD_LIST *p;
      long i;

      p = p_cad_list_info->head;
      i = 1;
      /*    */
      while( p != NULL && i != search_number) {
            i++;
            p = p->next;
      }

      /* n 番目のデータのアドレスを返す */
      if (p != NULL) {
            return p;
      }
      /* そこまでデータがない */
      else {
            return NULL;
      }
}





/* -------------------------------------------------------------------
 * CAD のデータの検索
 * 
 * 戻値  CAD_LIST
 */
CAD_LIST *cad_search_cad(CAD *p_cad, CAD_LIST_INFO *p_cad_list_info)
{
      CAD_LIST *p;

      p = p_cad_list_info->head;
      /*    */
      while( p != NULL && p->cad != p_cad) {
            p = p->next;
      }

      /* p_cad のデータのアドレスを返す */
      if (p != NULL) {
            return p;
      }
      /* そこまでデータがない */
      else {
            return NULL;
      }
}





/* -------------------------------------------------------------------
 * CAD のデータの検索
 * 
 * 戻値  long
 */
long cad_search_cad_to_num(CAD *p_cad, CAD_LIST_INFO *p_cad_list_info)
{
      CAD_LIST *p;
      long i;

      i = 1;
      p = p_cad_list_info->head;
      /*    */
      while( p != NULL && p->cad != p_cad) {
            p = p->next;
            i++;
      }

      /* p_cad のデータのアドレスを返す */
      if (p != NULL) {
            return i;
      }
      /* そこまでデータがない */
      else {
            return 0;
      }
}





/* -------------------------------------------------------------------
 *    CAD Data をリストから削除
 */
int cad_list_free(CAD_LIST *del_List, CAD_LIST_INFO *p_cad_list_info)
{
      CAD_LIST *p = NULL;
      CAD_LIST *pb = NULL;


      if (del_List == StartData) {
            StartData = NULL;
            //g_print ("List_cad.c : cad_list_free() : del_List = StartData\n");
      }

      /* データが先頭で1個だけ  */
      if (del_List == p_cad_list_info->head && del_List->next == NULL) {
            p_cad_list_info->head = NULL;
            p_cad_list_info->tail = NULL;
      }
      /* データが先頭で2個以上  */
      else if (del_List == p_cad_list_info->head && del_List->next != NULL) {
            p_cad_list_info->head = p_cad_list_info->head->next;
      }
      else {
            /* -------------------------------------------
             * 削除するポインタの前のデータを知りたいので、
             * head (リストの先頭) から削除するポインタが
             * 見つかるまで繰り返し、前のデータを探す。
             */
            p = p_cad_list_info->head;
            /* -------------------------------------------
             * 最後まで見つからない場合、 p に NULL が 
             * 入ってループを抜ける。
             */
            while(p != NULL && p != del_List) {
                  pb = p;                 /* 前のデータのポインタとして保存しておく */
                  p = p->next;      /* ポインタを次のデータに移す */
            }


            if(p != NULL){
                  /* 最後のデータ */
                  if (del_List == p_cad_list_info->tail) {
                        pb->next = NULL;
                        p_cad_list_info->tail = pb;
                  }
                  /* 中間のデータ */
                  else if (del_List != p_cad_list_info->head && del_List != p_cad_list_info->tail) {
                        pb->next = p->next;
                  }
            }
            else {
                  g_print("List_cad.c : cad_list_free() : There is not data of structure data CAD.\n");
                  return 0;
            }
      }
      xfree(del_List->cad);
      xfree(del_List);
      return 1;
}





/* -------------------------------------------------------------------
 *    全リストを削除
 */
void cad_list_all_free(CAD_LIST_INFO *p_cad_list_info)
{
      while(p_cad_list_info->head != NULL) {
            if (cad_list_free(p_cad_list_info->head, p_cad_list_info) == 0) {
                  g_print("List_cad.c : cad_list_all_free() : Error on cad_list_free()\n");
            }
      }
}





void cad_list_print(CAD_LIST_INFO *p_cad_list_info)
{
      CAD_LIST *p;
      int i = 0;

      g_print("----- CAD リストを表示 -----\n");
      p = p_cad_list_info->head;
      while (p != NULL) {
            i++;
            g_print("%d(0x%x) : code[%d] : style[%d] : color[0x%x] : (%f,%f)-(%f,%f) (%f,%f),R%f\n", 
                              i, (int)p->cad, p->cad->code, p->cad->style, (int)p->cad->color, 
                              p->cad->sx, p->cad->sy, p->cad->ex, p->cad->ey, 
                              p->cad->cx, p->cad->cy, p->cad->r);
            p = p->next;
      }
      g_print("-----------------------------\n");
}





/* ====================================================================
 * ===  Copyright (C) 1998-2007 Yutaka Sagiya. All rights reserved. ===
 * ====================================================================
 *    Project              : SagCAD
 *    Source               : List_cad.c
 * ====================================================================
 */

Generated by  Doxygen 1.6.0   Back to index