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

Draw.c

/* ====================================================================
 * ===  Copyright (C) 1998-2007 Yutaka Sagiya. All rights reserved. ===
 * ====================================================================
 * 
 *    Project              : SagCAD
 *    Description          : CAD/CAM
 *    Source               : Draw.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 <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "intl.h"
#define DRAW
#include "MemoryLeak.h"
#include "List_cad.h"
#include "List_Dimension.h"
#include "List_PolyLine.h"
#include "List_Ellipse.h"
#include "List_insert.h"
#include "List_Block.h"
#include "List_Undo.h"
#include "List_Select.h"
#include "global.h"
#include "culcfunc.h"
#include "spline.h"
#include "B_spline.h"
#include "Select.h"
#include "Ellipse.h"
#include "Draw.h"
#include "Dimension.h"
#include "etc.h"





/* -------------------------------------------------------------------
 * ビューポート(デバイス座標系)の設定
 * 
 *                     (WX2,WY2)                 (SX2,SY2)
 *      ┌────────┐             ┌─────┐
 *      │   ・           │             │  ・      │
 *      │ (WXp,WYp)      │             │ (SXp,SYp)│
 *      │                │             │          │
 *      │                │             │          │
 *      └────────┘             └─────┘
 *   (WX1,WY1)                       (SX1,SY1)         
 *           ウインドウ                    ビューポート
 * 
 */
gint view_port_set(gdouble vx1, gdouble vy1, gdouble vx2, gdouble vy2)
{
//#define SET_VIEWPORT

      /* ViewPort Aspect */
      view_port_aspect = (vx2-vx1) / (vy1-vy2);

      view_port_x1 = vx1;
      view_port_y1 = vy1;
      view_port_x2 = vx2;
      view_port_y2 = vy2;

#ifdef SET_VIEWPORT
g_print("ViewPort(%f,%f)-(%f,%f)  ViewPortAspect = %f\n", SX1, SY1, SX2, SY2, ViewPortAspect);
#endif

      return 1;
}



/* -------------------------------------------------------------------
 * ウインドウ(ワールド座標系)の設定
 * 
 * ViewPort を設定してから設定する
 * 
 *                     (WX2,WY2)                 (SX2,SY2)
 *      ┌────────┐             ┌─────┐
 *      │   ・           │             │  ・      │
 *      │ (WXp,WYp)      │             │ (SXp,SYp)│
 *      │                │             │          │
 *      │                │             │          │
 *      └────────┘             └─────┘
 *   (WX1,WY1)                       (SX1,SY1)         
 *           ウインドウ                    ビューポート
 * 
 */
gint world_window_set_center(gdouble mag, gdouble mag_x, gdouble mag_y, gdouble view_x)
{
      gdouble WXlength, WYlength;

      if (mag == 0) return -1;

      WXlength = view_x / mag;
      WYlength = WXlength / view_port_aspect;

      world_window_x1 = mag_x - (WXlength / 2);
      world_window_y1 = mag_y - (WYlength / 2);
      world_window_x2 = mag_x + (WXlength / 2);
      world_window_y2 = mag_y + (WYlength / 2);


      window_left   =   world_window_x1;
      window_top    =   world_window_y2;
      window_right  =   world_window_x2;
      window_bottom =   world_window_y1;


      return 0;
}



/* ---------------------------------------------------------------------
 * 描画処理
 * 
 * この関数を直接呼ぶ関数は
 *     Draw.c : Redraw()
 *     DrawArea.c : configure_event()
 * 
 */
void Draw(GtkWidget *widget)
{
      CAD_LIST *p;
      SELECT_LIST *ps;
      DIMENSION_LIST *pd;
      POLYLINE_LIST *pld;
      ELLIPSE_LIST *pe;


      PenSet(gc, 1, sagcad_color.Back);
      gdk_draw_rectangle (pixmap, gc, TRUE, 0, 0, widget->allocation.width * 3, widget->allocation.height * 3);

      if (printer.Draw_View == DRAWING_VIEW) WakuWakuDraw(widget);


      /* -----------------------------------------------------------------
       * 図形描画 
       */
      p = cad_list_info.head;
      while(p != NULL) {
            if(Layer[p->cad->layer].draw == 1) {
                  switch (p->cad->code) {
                        case 0: /* 点のとき */
                              PointDraw(widget, p->cad->sx, p->cad->sy, p->cad->style, p->cad->color);
                              break;
                        case 1: /* 直線のとき */
                              LineDraw(widget,  
                                           p->cad->sx, p->cad->sy, p->cad->ex, p->cad->ey, 
                                           p->cad->style, p->cad->color);
                              break;
                        case 2: /* 円弧のとき */
                              ArcDraw(widget, 
                                          p->cad->cx, p->cad->cy, p->cad->r, 
                                          p->cad->sx, p->cad->sy, p->cad->ex, p->cad->ey, 
                                          p->cad->style, p->cad->color);
                              break;
                        case 4: /* 円のとき */
                              CircleDraw(widget,      
                                          p->cad->cx, p->cad->cy, p->cad->r, 
                                          p->cad->style, p->cad->color);
                              break;
                  }
            }
            p = p->next;      /* ポインタを次のデータに移す */
      }



      /* -----------------------------------------------------------------
       * 寸法描画
       */
      /* 各寸法要素 */
      pd = dimension_list_info.head;
      /* -------------------------------------------
       * 最後まで見つからない場合、 p に NULL が 
       * 入ってループを抜ける。
       */
      while(pd != NULL) {
            if(Layer[pd->dimension->Layer].draw == 1) {
                  DimensionDraw(widget, pd->dimension, SCD_ORG);
            }
            pd = pd->next;    /* ポインタを次のデータに移す */
      }



      /* -----------------------------------------------------------------
       * ポリライン描画
       */
      /* 各ポリライン要素 */
      pld = polyline_list_info.head;
      /* -------------------------------------------
       * 最後まで見つからない場合、 p に NULL が 
       * 入ってループを抜ける。
       */
      while(pld != NULL) {
            if(Layer[pld->polyline->layer].draw == 1) {
                  PolyLineDraw(widget, pld->polyline, SCD_ORG);
            }
            pld = pld->next;  /* ポインタを次のデータに移す */
      }



      /* -----------------------------------------------------------------
       * 楕円描画
       */
      pe = ellipse_list_info.head;
      while (pe != NULL) {
            if(Layer[pe->ellipse->layer].draw == 1) {
                  EllipseDraw(widget, pe->ellipse, SCD_ORG);
            }
            pe = pe->next;    /* ポインタを次のデータに移す */
      }



      /* -----------------------------------------------------------------
       * 選択図形作図
       */
      if (select_list_info.head != NULL) {
            ps = select_list_info.head;
            while (ps != NULL) {
                  SelectDraw(widget, ps->select, SCD_SELECT, UPDATE_OFF);
                  ps = ps->next;    /* ポインタを次のデータに移す */
            }
      }


      /* -----------------------------------------------------------------
       * OnlyOne Mode 
       */
      if (OnlyOne_mode == 210) OnlyOne(3);


      /* -----------------------------------------------------------------
       * Chain2_OnlyOne_mode Mode 
       */
      if (Chain2_OnlyOne_mode == 211) SelectChain2_OnlyOne(3);

//    g_print("Draw.c : Draw() : Draw_event\n");
      UpDate();

}





/* -------------------------------------------------------------------
 * CAD Data をデバイス座標(ディスプレイまたはプリンター)に変換 (X)
 *    
 *    
 * < プリンター >
 * Printer_width  : 印刷領域の横を何 mm とするか(実際の大きさではない)
 * Horzres              : 印刷領域の横の大きさ (ピクセル単位)
 * p_dpiX               : dpi
 *    
 */
int ToDeviceX(double x)
{
      gdouble up, down, ret;

      up = (x - world_window_x1) * (view_port_x2 - view_port_x1);
      down = (world_window_x2 - world_window_x1);
      if (down == 0) {
            // error
      }
      ret = (up / down) + view_port_x1;

      return (int) ret;
}





/* -------------------------------------------------------------------
 * CAD Data をディスプレイ座標またはプリンター座標に変換 (Y)
 *    
 *    
 * < プリンター >
 * Printer_height       : 印刷領域の縦を何 mm とするか(実際の大きさではない)
 * Vertres              : 印刷領域の縦の大きさ (ピクセル単位)
 * p_dpiY               : dpi
 *    
 */
int ToDeviceY(double y)
{
      gdouble up, down, ret;

      up = (y - world_window_y1) * (view_port_y1 - view_port_y2);
      down = (world_window_y2 - world_window_y1);
      if (down == 0) {
            // error
      }
      ret = view_port_y1 - (up / down);

      return (int) ret;
}





/* -------------------------------------------------------------------
 * デバイス座標(ディスプレイ)から CAD Data のスクリーン座標に変換 (X)
 *    
 *    ToViewK は window_set で設定済み
 */
double ToViewX(int x)
{
      gdouble up, down, ret;

      up = (world_window_x2 - world_window_x1) * (x - view_port_x1);
      down = (view_port_x2 - view_port_x1);
      if (down == 0) {
            // error
      }
      ret = (up / down) + world_window_x1;

      return ret;
}





/* -------------------------------------------------------------------
 * デバイス座標(ディスプレイ)から CAD Data のスクリーン座標に変換 (Y)
 *    
 *    ToViewK は window_set で設定済み
 */
double ToViewY(int y)
{
      gdouble up, down, ret;

      up = (world_window_y2 - world_window_y1) * (view_port_y1 - y);
      down = (view_port_y1 - view_port_y2);
      if (down == 0) {
            // error
      }
      ret = (up / down) + world_window_y1;

      return ret;
}





/* ------------------------------------------------------------------
 * GC 作成
 */
GdkGC *create_gc(GtkWidget *widget)
{     return gdk_gc_new(widget->window); }





/* ------------------------------------------------------------------
 * GC 開放
 */
void delete_gc(GdkGC *gc)
{     gdk_gc_destroy(gc); }





/* -------------------------------------------------------------------
 * ペンを選ぶ
 * 
 * WIN32 なら HDC
 * LINUX なら GC
 * 
 */
int PenSet(GdkGC *gc, int style, long color)
{
      GdkColor for_gdk_backgroundcolor;
      GdkColor for_gdk_foregroundcolor;


      for_gdk_foregroundcolor = color_gtk(color);
      gdk_color_alloc(gdk_colormap_get_system(), &for_gdk_foregroundcolor);
      gdk_gc_set_foreground(gc, &for_gdk_foregroundcolor);

      for_gdk_backgroundcolor = color_gtk(sagcad_color.Back);
      gdk_color_alloc(gdk_colormap_get_system(), &for_gdk_backgroundcolor);
      gdk_gc_set_background(gc, &for_gdk_backgroundcolor);

      if (DrawObject == 0) {
            gdk_gc_set_line_attributes(   gc, sagcad_line_style[style].DsplayWidth, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
      }
      return 1;
}





/* ------------------------------------------------------------------
 * GC を設定  (BackColor も設定)
 * GC Setting
 */
int PenSet_with_back(GdkGC *gc, int style, long color, long backcolor)
{
      GdkColor for_gdk_backgroundcolor;
      GdkColor for_gdk_foregroundcolor;

      gchar dash[] = { 6, 6};
      gchar dash1[] = { 20, 6, 6, 6};
      gchar dash2[] = { 20, 6, 6, 6, 6, 6};

      for_gdk_foregroundcolor = color_gtk(color);
      gdk_color_alloc(gdk_colormap_get_system(), &for_gdk_foregroundcolor);
      gdk_gc_set_foreground(gc, &for_gdk_foregroundcolor);
      
      for_gdk_backgroundcolor = color_gtk(backcolor);
      gdk_color_alloc(gdk_colormap_get_system(), &for_gdk_backgroundcolor);
      gdk_gc_set_background(gc, &for_gdk_backgroundcolor);

      if(style == 0) {
            gdk_gc_set_line_attributes(gc, 2, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
      }
      else if(style == 1) {
            gdk_gc_set_line_attributes(gc, 1, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
      }
      /* 点線 */
      else if(style == 2) {
            gdk_gc_set_line_attributes(gc, 1, GDK_LINE_DOUBLE_DASH, GDK_CAP_BUTT, GDK_JOIN_MITER);
            gdk_gc_set_dashes(gc, 0, dash, 2);
      }
      /* 1点鎖線 */
      else if(style == 3) {
            gdk_gc_set_line_attributes(gc, 1, GDK_LINE_DOUBLE_DASH, GDK_CAP_BUTT, GDK_JOIN_MITER);
            gdk_gc_set_dashes(gc, 0, dash1, 4);
      }
      /* 2点鎖線 */
      else if(style == 4) {
            gdk_gc_set_line_attributes(gc, 1, GDK_LINE_DOUBLE_DASH, GDK_CAP_BUTT, GDK_JOIN_MITER);
            gdk_gc_set_dashes(gc, 0, dash2, 6);
      }
      else {
            gdk_gc_set_line_attributes(gc, 1, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
      }
      return 1;
}





/* -------------------------------------------------------------------
 * ペンを削除
 *    
 */
int PenDelete(GdkGC *gc)
{
      return 1;
}





/* ---------------------------------------------------------------------
 * 円を描画
 */
int CircleDraw(GtkWidget *widget, double CX, double CY, double R, int Style, long color)
{
      int Ret;

      Ret = CircleCheckDraw(&CX, &CY, &R);
      if(Ret == 1) {
            CircleK(widget, CX, CY, R, 0, 360, Style, color);
      }
      return 1;
}





/* ---------------------------------------------------------------------
 * 円弧を描画
 */
int ArcDraw(GtkWidget *widget, double CX, double CY, double R, double SX, double SY, double EX, double EY, int Style, long color)
{
      int Ret;
      struct RtnDat LA;
      double SA, EA;
      
      Ret = CircleCheckDraw(&CX, &CY, &R);

      if (Ret == 1) {
            LA.sx[1] = CX; LA.sy[1] = CY; LA.ex[1] = SX; LA.ey[1] = SY;
            la(&LA);
            SA = LA.angle;

            LA.sx[1] = CX; LA.sy[1] = CY; LA.ex[1] = EX; LA.ey[1] = EY;
            la(&LA);
            EA = LA.angle;

            CircleK(widget, CX, CY, R, SA, EA, Style, color);
      }
      return 1;
}





/* ---------------------------------------------------------------------
 * 直線を描画
 */
int LineDraw(GtkWidget *widget, double SX, double SY, double EX, double EY, int Style, long color)
{
      int Ret;

      Ret = LineCheckDraw(&SX, &SY, &EX, &EY);
      if(Ret == 0) return 0;
      else if(Ret == 2 || Ret == 1) {
            LineK(widget, SX, SY, EX, EY, Style, color);
      }
      return 1;
}





/* ---------------------------------------------------------------------
 * 点を描画
 */
int PointDraw(GtkWidget *widget, double x, double y, int Style, long color)
{
      int Ret;
      int DevX, DevY;
      double orgX, orgY;

      orgX = x;
      orgY = y;
      Ret = PointCheckDraw(&orgX, &orgY);
      if(Ret == 1) {
            PenSet(gc, 1, color);
            
            DevX = ToDeviceX(orgX);
            DevY = ToDeviceY(orgY);
            
            gdk_draw_point(pixmap/*widget->window*/, gc, DevX, DevY);

            gdk_draw_point(pixmap/*widget->window*/, gc, DevX + 1, DevY + 1);
            gdk_draw_point(pixmap/*widget->window*/, gc, DevX + 2, DevY + 2);
            gdk_draw_point(pixmap/*widget->window*/, gc, DevX + 3, DevY + 3);
            gdk_draw_point(pixmap/*widget->window*/, gc, DevX - 1, DevY - 1);
            gdk_draw_point(pixmap/*widget->window*/, gc, DevX - 2, DevY - 2);
            gdk_draw_point(pixmap/*widget->window*/, gc, DevX - 3, DevY - 3);

            gdk_draw_point(pixmap/*widget->window*/, gc, DevX + 1, DevY - 1);
            gdk_draw_point(pixmap/*widget->window*/, gc, DevX + 2, DevY - 2);
            gdk_draw_point(pixmap/*widget->window*/, gc, DevX + 3, DevY - 3);
            gdk_draw_point(pixmap/*widget->window*/, gc, DevX - 1, DevY + 1);
            gdk_draw_point(pixmap/*widget->window*/, gc, DevX - 2, DevY + 2);
            gdk_draw_point(pixmap/*widget->window*/, gc, DevX - 3, DevY + 3);
            return 1;
      }
      return 0;
}





/* -------------------------------------------------------------------
 * スプライン補間
 * 
 * 開曲線
 * 
 */
int open_spline_Basic(GtkWidget *widget, int n, VERTEX *vertex, int split, int style, long color)
{
      int i, Ret;
      double pitch;
      static double old_x = 0, old_y = 0;
      double SX, SY, EX, EY;

      double u, v;
      double *x, *y, *p, *a, *b;
      double *h, *d;


      x = (double *) xmalloc( n * sizeof(double) );
      y = (double *) xmalloc( n * sizeof(double) );
      p = (double *) xmalloc( n * sizeof(double) );
      a = (double *) xmalloc( n * sizeof(double) );
      b = (double *) xmalloc( n * sizeof(double) );

      h = (double *) xmalloc( n * sizeof(double) );
      d = (double *) xmalloc( n * sizeof(double) );


      for (i = 0 ; i < n ; i++) {
            x[i] = vertex[i].x;
            y[i] = vertex[i].y;
            p[i] = 0;
            a[i] = 0;
            b[i] = 0;

            h[i] = 0;
            d[i] = 0;
      }


      open_maketable2(n, p, x, y, a, b, h, d);

      pitch = 1.0/(double)split;
      for (i = 0; i <= split ; i++) {
            open_spline2(n, pitch * i, &u, &v, p, x, y, a, b);
            if (i == 0) {
                  // pset
            }
            else {
                  SX = old_x;
                  SY = old_y;
                  EX = u;
                  EY = v;

                  Ret = LineCheckDraw(&SX, &SY, &EX, &EY);
                  if (Ret == 2 || Ret == 1) {
                        LineK(widget, SX, SY, EX, EY, style, color);
                  }
            }
            old_x = u;
            old_y = v;
      }


      xfree(x);
      xfree(y);
      xfree(p);
      xfree(a);
      xfree(b);

      xfree(h);
      xfree(d);

      return 1;
}





/* -------------------------------------------------------------------
 * スプライン補間
 * 
 * 閉曲線
 * 
 */
int close_spline_Basic(GtkWidget *widget, int n, VERTEX *vertex, int split, int style, long color)
{
      int i, Ret;
      double pitch;
      static double old_x = 0, old_y = 0;
      double SX, SY, EX, EY;

      double u, v;
      double *x, *y, *p, *a, *b;
      double *h, *d, *w;


      x = (double *) xmalloc( (n+1) * sizeof(double) );
      y = (double *) xmalloc( (n+1) * sizeof(double) );
      p = (double *) xmalloc( (n+1) * sizeof(double) );
      a = (double *) xmalloc( (n+1) * sizeof(double) );
      b = (double *) xmalloc( (n+1) * sizeof(double) );

      h = (double *) xmalloc( (n+1) * sizeof(double) );
      d = (double *) xmalloc( (n+1) * sizeof(double) );
      w = (double *) xmalloc( (n+1) * sizeof(double) );

      for (i = 0 ; i < (n+1) ; i++) {
            x[i] = vertex[i].x;
            y[i] = vertex[i].y;
            p[i] = 0;
            a[i] = 0;
            b[i] = 0;

            h[i] = 0;
            d[i] = 0;
            w[i] = 0;
      }


      close_maketable2(n, p, x, y, a, b, h, d, w);
      pitch = 1.0/(double)split;
      for (i = 0; i <= split ; i++) {
            close_spline2(n, pitch * i, &u, &v, p, x, y, a, b);
            if (i == 0) {
                  // pset
            }
            else {
                  SX = old_x;
                  SY = old_y;
                  EX = u;
                  EY = v;
                  Ret = LineCheckDraw(&SX, &SY, &EX, &EY);
                  if (Ret == 2 || Ret == 1) {
                        LineK(widget, SX, SY, EX, EY, style, color);
                  }
            }
            old_x = u;
            old_y = v;
      }


      xfree(x);
      xfree(y);
      xfree(p);
      xfree(a);
      xfree(b);

      xfree(h);
      xfree(d);
      xfree(w);

      return 1;
}





/* -------------------------------------------------------------------
 * 3次Bスプライン
 * 
 * データの数が最低7個は必要となる。
 *     データの数が3個の場合、中間点を3分割
 *     データの数が4個から6個の場合、中間点を2分割
 * 
 */
int b_spline_Basic(GtkWidget *widget, int n, VERTEX *vertex, double pitch, int style, long color)
{
      int i, j, Ret;
      double u, s1, s2, s3, s4;
      double x, y;
      double SX, SY, EX, EY;
      static double old_x = 0, old_y = 0;
      VERTEX *dummy_vertex = NULL;

      VERTEX sp = {0,0};
      VERTEX ep = {0,0};
      VERTEX ap1 = {0,0};
      VERTEX ap2 = {0,0};


      if (n == 3) {
            dummy_vertex = (VERTEX *)xmalloc( 7 * sizeof(VERTEX) );
            j = 0;
            dummy_vertex[j].x = vertex[0].x;
            dummy_vertex[j].y = vertex[0].y;
            for (i = 1 ; i < n ; i++) {
                  sp.x = vertex[i-1].x;
                  sp.y = vertex[i-1].y;
                  ep.x = vertex[i].x;
                  ep.y = vertex[i].y;
                  split3(sp, ep, &ap1, &ap2);
                  j++;
                  dummy_vertex[j].x = ap1.x;
                  dummy_vertex[j].y = ap1.y;
                  j++;
                  dummy_vertex[j].x = ap2.x;
                  dummy_vertex[j].y = ap2.y;
                  j++;
                  dummy_vertex[j].x = vertex[i].x;
                  dummy_vertex[j].y = vertex[i].y;
            }
            n = 7;
      }
      else if (n > 3 && n < 7) {
            dummy_vertex = (VERTEX *)xmalloc(((n * 2) - 1) * sizeof(VERTEX));
            j = 0;
            dummy_vertex[j].x = vertex[0].x;
            dummy_vertex[j].y = vertex[0].y;
            for (i = 1 ; i < n ; i++) {
                  sp.x = vertex[i-1].x;
                  sp.y = vertex[i-1].y;
                  ep.x = vertex[i].x;
                  ep.y = vertex[i].y;
                  split2(sp, ep, &ap1);
                  j++;
                  dummy_vertex[j].x = ap1.x;
                  dummy_vertex[j].y = ap1.y;
                  j++;
                  dummy_vertex[j].x = vertex[i].x;
                  dummy_vertex[j].y = vertex[i].y;
            }
            n = (n * 2) - 1;
      }
      else if (n > 6) {
            dummy_vertex = (VERTEX *)xmalloc( n * sizeof(VERTEX) );
            for (i = 0 ; i < n ; i++) {
                  dummy_vertex[i].x = vertex[i].x;
                  dummy_vertex[i].y = vertex[i].y;
            }
      }



      for (i = 0 ; i < n-3 ; i++) {
            for (u = 0.0 ; u <= 1.0 + pitch/2 ; u = u + pitch) {
                  /* 最初の区間 */
                  if (i == 0) {
                        spl1(u, &s1, &s2, &s3, &s4);
                  }
                  /* 2番目の区間 */
                  else if (i == 1) {
                        spl2(u, &s1, &s2, &s3, &s4);
                  }
                  /* 中間の区間 */
                  else if (i > 1 && i < n-5) {
                        spl3(u, &s1, &s2, &s3, &s4);
                  }
                  /* 最後から2番目の区間 */
                  else if (i > 1 && i == n-5) {
                        spl4(u, &s1, &s2, &s3, &s4);
                  }
                  /* 最後の区間 */
                  else if (i > 2 && i == n-4) {
                        spl5(u, &s1, &s2, &s3, &s4);
                  }
                  x = s1*dummy_vertex[i].x + s2*dummy_vertex[i+1].x + s3*dummy_vertex[i+2].x + s4*dummy_vertex[i+3].x;
                  y = s1*dummy_vertex[i].y + s2*dummy_vertex[i+1].y + s3*dummy_vertex[i+2].y + s4*dummy_vertex[i+3].y;
                  if (u == 0) {
                        //pset;
                  }
                  else {
                        SX = old_x;
                        SY = old_y;
                        EX = x;
                        EY = y;
                        Ret = LineCheckDraw(&SX, &SY, &EX, &EY);
                        if (Ret == 2 || Ret == 1) {
                              LineK(widget, SX, SY, EX, EY, style, color);
                        }
                  }
                  old_x = x;
                  old_y = y;
            }
      }

      xfree(dummy_vertex);
      return 1;
}





/* -------------------------------------------------------------------
 * ポリライン描画
 *    
 * 選択         : DrawType = 1  SCD_SELECT
 * 元の色      : DrawType = 0  SCD_ORG
 * 消            : DrawType = 2  SCD_HIDE
 */
int PolyLineDraw(GtkWidget *widget, POLYLINE *a, int frag)
{
//#define POLYLINEDRAW
      long i;
      long color = a->color;
      VERTEX_LIST *v;
      VERTEX first, old;
      VERTEX *vertex;
      int debug = 0;


#ifdef POLYLINEDRAW
      debug = 1;
#endif

      if (frag == SCD_ORG) color = a->color;
      else if (frag == SCD_HIDE) color = sagcad_color.Back;
      else if (frag == SCD_SELECT) color = sagcad_color.Select;


      if (debug > 0) g_print ("PolyLineDraw() : in\n");
      if (debug > 0) g_print ("PolyLineDraw() : code = %d\n", a->code);


      if (Layer[a->layer].draw == 1) {

            /* ポリライン(折れ線) */
            if (a->code == 8) {
                  if (debug > 0) g_print ("PolyLineDraw() : ポリライン(折れ線) in\n");
                  v = a->vertex_list_info.head;
                  i = 0;
                  while (v != NULL) {
                        if (i == 0) {
                              first = *v->vertex;
                              old = *v->vertex;
                              i++;
                        }
                        else {
                              LineDraw(   widget, 
                                                old.x, old.y, 
                                                v->vertex->x, v->vertex->y, 
                                                a->style, color);
                              old = *v->vertex;
                        }
                        v = v->next;
                  }

                  /* 閉じているとき */
                  if ((a->frag & 1) == 1) {
                        LineDraw(widget, first.x, first.y, old.x, old.y, a->style, color);
                  }
            }




            /* スプライン補間 */
            else if (a->code == 16) {
                  if (debug > 0) g_print ("PolyLineDraw() : スプライン補間 in\n");
                  if (debug > 0) g_print ("PolyLineDraw() : index = %d   frag = %d\n", a->index, a->frag);

                  if (a->index > 0) {
                        vertex = (VERTEX *) xmalloc( (a->index + 1) * sizeof(VERTEX) );

                        if (debug > 0) g_print ("PolyLineDraw() : スプライン補間 0\n");

                        v = a->vertex_list_info.head;
                        i = 0;
                        while (v != NULL) {
                              vertex[i] = *v->vertex;
                              i++;
                              v = v->next;
                        }

                        if (debug > 0) g_print ("PolyLineDraw() : スプライン補間 1\n");

                        /* 閉じているとき(閉曲線) */
                        if ((a->frag & 1) == 1) {
                              if (debug > 0) g_print ("PolyLineDraw() : スプライン補間 2\n");
                              vertex[i] = vertex[0];
                              close_spline_Basic(widget, a->index, vertex, a->index * a->split, a->style, color);
                        }
                        /* (開曲線) */
                        else {
                              if (debug > 0) g_print ("PolyLineDraw() : スプライン補間 3\n");
                              open_spline_Basic(widget, a->index, vertex, a->index * a->split, a->style, color);
                        }

                        if (debug > 0) g_print ("PolyLineDraw() : スプライン補間 4\n");

                        xfree(vertex);
                  }
            }


            /* Bスプライン曲線 */
            else if (a->code == 32) {
                  if (debug > 0) g_print ("PolyLineDraw() : Bスプライン曲線 in\n");
                  if (a->index > 0) {
                        vertex = (VERTEX *) xmalloc( a->index * sizeof(VERTEX) );

                        v = a->vertex_list_info.head;
                        i = 0;
                        while (v != NULL) {
                              vertex[i] = *v->vertex;
                              i++;
                              v = v->next;
                        }
                        b_spline_Basic(widget, a->index, vertex, a->pitch, a->style, color);
                        xfree(vertex);
                  }
            }


      }
      return 1;
}





/* -------------------------------------------------------------------
 * 楕円描画 (ELLIPSE)
 *    
 * 選択         : DrawType = 1  SCD_SELECT
 * 元の色      : DrawType = 0  SCD_ORG
 * 消            : DrawType = 2  SCD_HIDE
 */
int EllipseDraw(GtkWidget *widget, ELLIPSE *ellipse, int frag)
{
      long color = ellipse->color;


      if (frag == SCD_ORG) color = ellipse->color;
      else if (frag == SCD_HIDE) color = sagcad_color.Back;
      else if (frag == SCD_SELECT) color = sagcad_color.Select;


      if (Layer[ellipse->layer].draw == 1) {
            EllipseK(widget, *ellipse, ellipse->style, color);
/*          EllipseK(widget, 
                         ellipse->cx, ellipse->cy, 
                         get_ellipse_a(*ellipse), get_ellipse_b(*ellipse), 
                         ellipse->sa, ellipse->ea, 
                         get_ellipse_angle(*ellipse), 
                         ellipse->style, color);*/
      }
      return 1;
}





/* -------------------------------------------------------------------
 * 点を枠の中だけの座標を返す
 *    
 *    
 * 戻値 : int    0:不可視    1:可視
 *    
 */
int PointCheckDraw(double *SX, double *SY)
{
//    double left, top, right, bottom;
      int s_bit = 0;


      /* ディスプレイ */
      if (DrawObject == 0) {
//          left   =    MagX - ((sagcad_system.ViewX/Mag)/2);
//          top      =  MagY + (((sagcad_system.ViewX/Mag)/2)*sagcad_system.Aspect);
//          right  =    MagX + ((sagcad_system.ViewX/Mag)/2);
//          bottom =    MagY - (((sagcad_system.ViewX/Mag)/2)*sagcad_system.Aspect);

            if (*SY > window_top)         s_bit = s_bit + 8;
            if (*SY < window_bottom)      s_bit = s_bit + 4;
            if (*SX > window_right)       s_bit = s_bit + 2;
            if (*SX < window_left)        s_bit = s_bit + 1;
      }

#ifdef TEST
      /* プリンター */
      else if (DrawObject == 1) {
            left   =    MagX - (sagcad_printer.Printer_width/2);
            top      =  MagY + ((sagcad_printer.Printer_width/2)*sagcad_printer.Printer_Aspect);
            right  =    MagX + (sagcad_printer.Printer_width/2);
            bottom =    MagY - ((sagcad_printer.Printer_width/2)*sagcad_printer.Printer_Aspect);


            if(*SY > top)           s_bit = s_bit + 8;
            if(*SY < bottom)  s_bit = s_bit + 4;
            if(*SX > right)         s_bit = s_bit + 2;
            if(*SX < left)          s_bit = s_bit + 1;
      }
#endif


      /* 可視 */
      if(s_bit == 0) return 1;
      return 0;
}





/* -------------------------------------------------------------------
 * 円を枠の中だけの座標を返す
 *    
 *    
 * 戻値 : int    0:不可視    1:可視
 *    
 */
int CircleCheckDraw(double *CX, double *CY, double *R)
{
//    double left, top, right, bottom;
      int s_bit = 0;


      /* ディスプレイ */
      if (DrawObject == 0) {
//          left   =    (MagX - ((sagcad_system.ViewX/Mag)/2)) - *R;
//          top      =  (MagY + (((sagcad_system.ViewX/Mag)/2)*sagcad_system.Aspect)) + *R;
//          right  =    (MagX + ((sagcad_system.ViewX/Mag)/2)) + *R;
//          bottom =    (MagY - (((sagcad_system.ViewX/Mag)/2)*sagcad_system.Aspect)) - *R;

//window_set();

            if (*CY > window_top + *R)          s_bit = s_bit + 8;
            if (*CY < window_bottom - *R) s_bit = s_bit + 4;
            if (*CX > window_right + *R)  s_bit = s_bit + 2;
            if (*CX < window_left - *R)         s_bit = s_bit + 1;
      }


#ifdef TEST
      /* プリンター */
      else if (DrawObject == 1) {
            left   =    (MagX - (sagcad_printer.Printer_width/2)) - *R;
            top      =  (MagY + ((sagcad_printer.Printer_width/2)*sagcad_printer.Printer_Aspect)) + *R;
            right  =    (MagX + (sagcad_printer.Printer_width/2)) + *R;
            bottom =    (MagY - ((sagcad_printer.Printer_width/2)*sagcad_printer.Printer_Aspect)) - *R;

            if (*CY > top)          s_bit = s_bit + 8;
            if (*CY < bottom) s_bit = s_bit + 4;
            if (*CX > right)  s_bit = s_bit + 2;
            if (*CX < left)         s_bit = s_bit + 1;
      }
#endif


      /* 可視 */
      if(s_bit == 0) return 1;
      return 0;
}





/* -------------------------------------------------------------------
 * 直線を枠の中だけの座標を返す
 *    
 *    
 * 戻値 : int    0:不可視    1:変換 OK     2:変換無し可視
 *    
 */
int LineCheckDraw(double *SX,double *SY,double *EX,double *EY)
{
      double left = 0, top = 0, right = 0, bottom = 0;
      double sx, sy, ex, ey;
      struct RtnDat LLPH;
      int s_bit = 0, e_bit = 0;
      int sx_Frag = 0, ex_Frag = 0;
      int CP;


      sx = *SX;
      sy = *SY;
      ex = *EX;
      ey = *EY;

      /* ディスプレイ */
      if (DrawObject == 0) {
//          left   = MagX - ((sagcad_system.ViewX / Mag) / 2);
//          top    = MagY + (((sagcad_system.ViewX / Mag) / 2) * sagcad_system.Aspect);
//          right  = MagX + ((sagcad_system.ViewX / Mag) / 2);
//          bottom = MagY - (((sagcad_system.ViewX / Mag) / 2) * sagcad_system.Aspect);

            left   = window_left;
            top    = window_top;
            right  = window_right;
            bottom = window_bottom;
      }


#ifdef TEST
      /* プリンター */
      else if (DrawObject == 1) {
            left   = MagX - (sagcad_printer.Printer_width / 2);
            top    = MagY + ((sagcad_printer.Printer_width / 2) * sagcad_printer.Printer_Aspect);
            right  = MagX + (sagcad_printer.Printer_width / 2);
            bottom = MagY - ((sagcad_printer.Printer_width / 2) * sagcad_printer.Printer_Aspect);
      }
#endif


#ifdef Doc
0001 = 1
0010 = 2
0100 = 4
1000 = 8

1001 | 1000 | 1010
------------------
0001 | 0000 | 0010
------------------
0101 | 0100 | 0110
#endif






      /* 始点 */
      if(sy > top)      s_bit = s_bit + 8;
      if(sy < bottom) s_bit = s_bit + 4;
      if(sx > right)    s_bit = s_bit + 2;
      if(sx < left)     s_bit = s_bit + 1;

      /* 終点 */
      if(ey > top)      e_bit = e_bit + 8;
      if(ey < bottom) e_bit = e_bit + 4;
      if(ex > right)    e_bit = e_bit + 2;
      if(ex < left)     e_bit = e_bit + 1;



      /* ---------------------------------------------------------------
       * 完全に可視
       */
      if(s_bit == 0 && e_bit == 0) {
            return 2;
      }



      /* ---------------------------------------------------------------
       * 完全に不可視
       */
      if ((s_bit & e_bit) != 0) {
            return 0;
      }



      /* ---------------------------------------------------------------
       * 可視の可能性がある (1)
       */
      if ( ((s_bit && e_bit) == 0) 
             || 
             ( s_bit == 0x8 && e_bit == 0x4 )
             || 
             ( s_bit == 0x4 && e_bit == 0x8 )
             || 
             ( s_bit == 0x2 && e_bit == 0x1 )
             || 
             ( s_bit == 0x1 && e_bit == 0x2 ) ) 
      {
            /* -----------------------------------------------------------
             * 上の境界線と交点があるか
             */
            if ( (s_bit & 8) == 8 || (e_bit & 8) == 8 ) {
                  /* 直線と上の境界線との交点を求める */
                  LLPH.sx[1] = sx;  LLPH.sy[1] = sy;  LLPH.ex[1] = ex;  LLPH.ey[1] = ey;
                  LLPH.sx[2] = left;      LLPH.sy[2] = top; LLPH.ex[2] = right;     LLPH.ey[2] = top;
                  llp(&LLPH);
                  /* 交点がある */
                  if (LLPH.sx[3] > left && LLPH.sx[3] < right) {
                        if ((s_bit & 8) == 8) {
                              *SX = LLPH.sx[3];
                              *SY = LLPH.sy[3];
                              sx_Frag = 1;
                        }
                        else if ((e_bit & 8) == 8) {
                              *EX = LLPH.sx[3];
                              *EY = LLPH.sy[3];
                              ex_Frag = 1;
                        }
                  }
            }

            /* -----------------------------------------------------------
             * 下の境界線と交点があるか
             */
            if ( (s_bit & 4) == 4 || (e_bit & 4) == 4 ) {
                  /* 直線と下の境界線との交点を求める */
                  LLPH.sx[1] = sx;  LLPH.sy[1] = sy;  LLPH.ex[1] = ex;  LLPH.ey[1] = ey;
                  LLPH.sx[2] = left;      LLPH.sy[2] = bottom;    LLPH.ex[2] = right;     LLPH.ey[2] = bottom;
                  llp(&LLPH);
                  /* 交点がある */
                  if (LLPH.sx[3] > left && LLPH.sx[3] < right) {
                        if ( (s_bit & 4) == 4 ) {
                              *SX = LLPH.sx[3];
                              *SY = LLPH.sy[3];
                              sx_Frag = 1;
                        }
                        else if ( (e_bit & 4) == 4 ) {
                              *EX = LLPH.sx[3];
                              *EY = LLPH.sy[3];
                              ex_Frag = 1;
                        }
                  }
            }

            /* -----------------------------------------------------------
             * 右の境界線と交点があるか
             */
            if ( (s_bit & 2) == 2 || (e_bit & 2) == 2 ) {
                  /* 直線と右の境界線との交点を求める */
                  LLPH.sx[1] = sx;  LLPH.sy[1] = sy;  LLPH.ex[1] = ex;  LLPH.ey[1] = ey;
                  LLPH.sx[2] = right;     LLPH.sy[2] = top; LLPH.ex[2] = right;     LLPH.ey[2] = bottom;
                  llp(&LLPH);
                  /* 交点がある */
                  if (LLPH.sy[3] > bottom && LLPH.sy[3] < top) {
                        if ( ( s_bit & 2) == 2 ) {
                              *SX = LLPH.sx[3];
                              *SY = LLPH.sy[3];
                              sx_Frag = 1;
                        }
                        else if ( (e_bit & 2) == 2 ) {
                              *EX = LLPH.sx[3];
                              *EY = LLPH.sy[3];
                              ex_Frag = 1;
                        }
                  }
            }

            /* -----------------------------------------------------------
             * 左の境界線と交点があるか
             */
            if ( (s_bit & 1) == 1 || (e_bit & 1) == 1 ) {
                  /* 直線と左の境界線との交点を求める */
                  LLPH.sx[1] = sx;  LLPH.sy[1] = sy;  LLPH.ex[1] = ex;  LLPH.ey[1] = ey;
                  LLPH.sx[2] = left;      LLPH.sy[2] = top; LLPH.ex[2] = left;      LLPH.ey[2] = bottom;
                  llp(&LLPH);
                  /* 交点がある */
                  if (LLPH.sy[3] > bottom && LLPH.sy[3] < top) {
                        if ( (s_bit & 1) == 1 ) {
                              *SX = LLPH.sx[3];
                              *SY = LLPH.sy[3];
                              sx_Frag = 1;
                        }
                        else if ( (e_bit & 1) == 1 ) {
                              *EX = LLPH.sx[3];
                              *EY = LLPH.sy[3];
                              ex_Frag = 1;
                        }
                  }
            }

            /* -----------------------------------------------------------
             * 
             */
            if(sx_Frag == 1 || ex_Frag == 1) {
                  return 1;
            }
            else return 0;
      }



      /* ---------------------------------------------------------------
       * 可視の可能性がある (2)
       * 始点終点とも枠外なので、交点が2個有れば可視
       */
      if(   ( (s_bit & 8) == 8 && (e_bit & 1) == 1 ) 
            || 
            ( (s_bit & 8) == 8 && (e_bit & 2) == 2 ) 
            || 
            ( (s_bit & 4) == 4 && (e_bit & 1) == 1 ) 
            || 
            ( (s_bit & 4) == 4 && (e_bit & 2) == 2 ) 
            || 
            ( (s_bit & 1) == 1 && (e_bit & 8) == 8 ) 
            || 
            ( (s_bit & 2) == 2 && (e_bit & 8) == 8 ) 
            || 
            ( (s_bit & 1) == 1 && (e_bit & 4) == 4 ) 
            || 
            ( (s_bit & 2) == 2 && (e_bit & 4) == 4 ) )
      {
            CP = 0;

            /* -------------------------------------------------
             * 上の境界線と交点があるか
             */
            LLPH.sx[1] = sx;  LLPH.sy[1] = sy;  LLPH.ex[1] = ex;  LLPH.ey[1] = ey;
            LLPH.sx[2] = left;      LLPH.sy[2] = top; LLPH.ex[2] = right;     LLPH.ey[2] = top;
            /* 交点がある */
            if (Act_llp(&LLPH) == 1) {
                  CP++;
                  if(CP == 1) {
                        *SX = LLPH.sx[3]; *SY = LLPH.sy[3];
                  }
                  else if(CP == 2) {
                        *EX = LLPH.sx[3]; *EY = LLPH.sy[3];
                  }
            }

            /* -------------------------------------------------
             * 下の境界線と交点があるか
             */
            LLPH.sx[1] = sx;  LLPH.sy[1] = sy;  LLPH.ex[1] = ex;  LLPH.ey[1] = ey;
            LLPH.sx[2] = left;      LLPH.sy[2] = bottom;    LLPH.ex[2] = right;     LLPH.ey[2] = bottom;
            /* 交点がある */
            if (Act_llp(&LLPH) == 1) {
                  CP++;
                  if(CP == 1) {
                        *SX = LLPH.sx[3]; *SY = LLPH.sy[3];
                  }
                  else if(CP == 2) {
                        *EX = LLPH.sx[3]; *EY = LLPH.sy[3];
                  }
            }

            /* -------------------------------------------------
             * 右の境界線と交点があるか
             */
            LLPH.sx[1] = sx;  LLPH.sy[1] = sy;  LLPH.ex[1] = ex;  LLPH.ey[1] = ey;
            LLPH.sx[2] = right;     LLPH.sy[2] = top; LLPH.ex[2] = right;     LLPH.ey[2] = bottom;
            /* 交点がある */
            if (Act_llp(&LLPH) == 1) {
                  CP++;
                  if(CP == 1) {
                        *SX = LLPH.sx[3]; *SY = LLPH.sy[3];
                  }
                  else if(CP == 2) {
                        *EX = LLPH.sx[3]; *EY = LLPH.sy[3];
                  }
            }

            /* -------------------------------------------------
             * 左の境界線と交点があるか
             */
            LLPH.sx[1] = sx;  LLPH.sy[1] = sy;  LLPH.ex[1] = ex;  LLPH.ey[1] = ey;
            LLPH.sx[2] = left;      LLPH.sy[2] = top; LLPH.ex[2] = left;      LLPH.ey[2] = bottom;
            /* 交点がある */
            if (Act_llp(&LLPH) == 1) {
                  CP++;
                  if(CP == 1) {
                        *SX = LLPH.sx[3]; *SY = LLPH.sy[3];
                  }
                  else if(CP == 2) {
                        *EX = LLPH.sx[3]; *EY = LLPH.sy[3];
                  }
            }


            if (CP == 2) return 1;
      }



      return 0;
}





/* ---------------------------------------------------------------------
 * 図を上に移動
 */
void MoveUp(void)
{
      if (sagcad_system.Splits < 0) {
            MagY = MagY - sagcad_system.ScrollPitch;
      }
      else {
            MagY = MagY + sagcad_system.ScrollPitch;
      }
      SetMag(Mag);
      /* --- < 再描画処理 > --- */
//    Redraw();
}



/* ---------------------------------------------------------------------
 * 図を下に移動
 */
void MoveDown(void)
{
      if (sagcad_system.Splits < 0) {
            MagY = MagY + sagcad_system.ScrollPitch;
      }
      else {
            MagY = MagY - sagcad_system.ScrollPitch;
      }
      SetMag(Mag);
      /* --- < 再描画処理 > --- */
//    Redraw();
}



/* ---------------------------------------------------------------------
 * 図を右に移動
 */
void MoveRight(void)
{
      if (sagcad_system.Splits < 0) {
            MagX = MagX - sagcad_system.ScrollPitch;
      }
      else {
            MagX = MagX + sagcad_system.ScrollPitch;
      }
      SetMag(Mag);
      /* --- < 再描画処理 > --- */
//    Redraw();
}



/* ---------------------------------------------------------------------
 * 図を左に移動 
 */
void MoveLeft(void)
{
      if (sagcad_system.Splits < 0) {
            MagX = MagX + sagcad_system.ScrollPitch;
      }
      else {
            MagX = MagX - sagcad_system.ScrollPitch;
      }
      SetMag(Mag);
      /* --- < 再描画処理 > --- */
//    Redraw();
}



/* ---------------------------------------------------------------------
 * 再描画
 */
void Redraw(void)
{
//    GdkRectangle update_rect;
//    update_rect.x = 0;
//    update_rect.y = 0;
//    update_rect.width = sagcad_system.DeviceX;
//    update_rect.height = sagcad_system.DeviceY;

      PenSet(gc, 1, sagcad_color.Back);
      gdk_draw_rectangle (pixmap/*drawing_area->window*/, gc, TRUE, 0, 0, sagcad_system.DeviceX, sagcad_system.DeviceY);

//g_print("Draw.c : Redraw() : Draw\n");
      Draw(drawing_area);
      //g_print("Redraw Mag = %f  MagX = %f  MagY = %f\n", Mag, MagX, MagY);
      //gtk_widget_draw (drawing_area, &update_rect);
      gtk_widget_queue_draw_area (drawing_area, 0, 0, sagcad_system.DeviceX, sagcad_system.DeviceY);
      return;
}



/* ---------------------------------------------------------------------
 * 再描画
 */
void UpDate(void)
{
      gtk_widget_queue_draw_area (drawing_area, 0, 0, sagcad_system.DeviceX, sagcad_system.DeviceY);

//    g_print("Draw.c : UpDate() : UpDate\n");
}





/* ---------------------------------------------------------------------
 * 再描画
 */
void UpDate_widget(GtkWidget *widget)
{
      gtk_widget_queue_draw_area (widget, 0, 0, widget->allocation.width, widget->allocation.height);
}





/* ---------------------------------------------------------------------
 * 縮小
 */
void ZoomDown(void)
{
      double      dumy;

      dumy = Mag / sagcad_system.ZoomMag;
      SetMag((float)dumy);
      return;
}





/* ---------------------------------------------------------------------
 * 拡大
 */
void ZoomUp(void)
{
      double      dumy;

      dumy = Mag * sagcad_system.ZoomMag;
      SetMag((float)dumy);
      return;
}





/* -------------------------------------------------------------------
 * window_set
 * 
 * 
 * window_set は、
 *     ウインドウのサイズまたは、大きさの変更があったときに呼ぶ。
 *     WIN32 では WM_PAINT のとこ
 *     LINUX では expose_event のとこ
 * 
 *     SetMag()
 *     上下左右に移動
 *     拡大縮小は、SetMag を呼ぶのでいらない。
 * 
 */
void window_set(void)
{
      window_left   =   MagX - ((sagcad_system.ViewX/Mag)/2);
      window_top    =   MagY + (((sagcad_system.ViewX/Mag)/2)*sagcad_system.Aspect);
      window_right  =   MagX + ((sagcad_system.ViewX/Mag)/2);
      window_bottom =   MagY - (((sagcad_system.ViewX/Mag)/2)*sagcad_system.Aspect);

//    ToDeviceK =  sagcad_system.twipX / (sagcad_system.ViewX/Mag);

      ToDevice_X_lo = sagcad_system.ViewX/Mag;
      ToDevice_X_hi = ToDevice_X_lo / 2.;

      ToDevice_Y_lo = ToDevice_X_lo * sagcad_system.Aspect;
      ToDevice_Y_hi = ToDevice_Y_lo / 2.;

      ToViewK = sagcad_system.DeviceX / (sagcad_system.ViewX/Mag);

      return;
}





/* ---------------------------------------------------------------------
 * 倍率設定
 */
void SetMag(double MagData)
{
      char DumyStr[20], str[20];
      
      if (MagData < 0.002) MagData = (float) 0.002;
      if (MagData > 2000) MagData = 2000;
      Mag = MagData;

      world_window_set_center(Mag, 
                                          MagX, 
                                          MagY, 
                                          sagcad_system.ViewX * 3);

      DC = (double)(sagcad_system.Search / Mag);
      /* --- < 倍率 > --- */
      sagcad_system.ScrollPitch = (float)(sg((sagcad_system.ViewX/abs(sagcad_system.Splits))/Mag, 2));
      FloatOut(str, sagcad_system.ScrollPitch, 0);
      sprintf(DumyStr, "SP %s", str);
      set_label_text(scroll_pitch, DumyStr);

//    window_set();

      /* 再描画 */
      Redraw();

      /* 倍率 */
      FloatOut(str, MagData, 0);
      sprintf(DumyStr,"Mag %s",str);
      set_label_text(mag, DumyStr);

      return;
}





/* -------------------------------------------------------------------
 * 直線を style で描く
 *    
 */
int LineK(GtkWidget *widget, double SX, double SY, double EX, double EY, int style, long color)
{
      double Total_Len, Angle;
      double Now_Len = 0, Now_SX, Now_SY, Now_EX, Now_EY;
      struct RtnDat PPH, LAH, PAPH;
      double mm;
//    double mm, min = 1, mid = 3, max = 10;


      PenSet(gc, style, color);


      Now_SX = SX;
      Now_SY = SY;
      mm = 1 / Mag;

      /* 2点間の距離 */
      PPH.sx[1] = SX;
      PPH.sy[1] = SY;
      PPH.ex[1] = EX;
      PPH.ey[1] = EY;
      pp(&PPH);
      Total_Len = PPH.l;

      /* 直線の角度 */
      LAH.sx[1] = SX;
      LAH.sy[1] = SY;
      LAH.ex[1] = EX;
      LAH.ey[1] = EY;
      la(&LAH);
      Angle = LAH.angle;


      //MoveToEx(gc, ToDeviceX(SX), ToDeviceY(SY), NULL);

      /* 実線 */
      if (sagcad_line_style[style].style == 1) {
            gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(SX), ToDeviceY(SY), ToDeviceX(EX), ToDeviceY(EY));
            //LineTo(gc, ToDeviceX(EX), ToDeviceY(EY));
            return 1;
      }



      /* 点線 */
      else if (sagcad_line_style[style].style == 2) {
            while (1) {
                  PAPH.sx[1] = Now_SX;
                  PAPH.sy[1] = Now_SY;
                  PAPH.angle = Angle;
                  PAPH.l = sagcad_line_style[style].max * mm;
                  pap(&PAPH);
                  Now_EX = sg(PAPH.ex[1], calcu_digits);
                  Now_EY = sg(PAPH.ey[1], calcu_digits);
                  Now_Len = Now_Len + (sagcad_line_style[style].max * mm);
                  if (Total_Len <= Now_Len) {
                        Now_EX = EX;
                        Now_EY = EY;
                        gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //LineTo(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        return 1;
                  }
                  else {
                        gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //LineTo(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        Now_SX = Now_EX;
                        Now_SY = Now_EY;
                  }


                  PAPH.sx[1] = Now_SX;
                  PAPH.sy[1] = Now_SY;
                  PAPH.angle = Angle;
                  PAPH.l = sagcad_line_style[style].min * mm;
                  pap(&PAPH);
                  Now_EX = sg(PAPH.ex[1], calcu_digits);
                  Now_EY = sg(PAPH.ey[1], calcu_digits);
                  Now_Len = Now_Len + (sagcad_line_style[style].min * mm);
                  if (Total_Len <= Now_Len) {
                        Now_EX = EX;
                        Now_EY = EY;
                        //gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //MoveToEx(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY), NULL);
                        return 1;
                  }
                  else {
                        //gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //MoveToEx(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY), NULL);
                        Now_SX = Now_EX;
                        Now_SY = Now_EY;
                  }
            }
            return 1;
      }



      /* 1点鎖線 */
      else if (sagcad_line_style[style].style == 3) {
            while (1) {
                  PAPH.sx[1] = Now_SX;
                  PAPH.sy[1] = Now_SY;
                  PAPH.angle = Angle;
                  PAPH.l = sagcad_line_style[style].max * mm;
                  pap(&PAPH);
                  Now_EX = sg(PAPH.ex[1], calcu_digits);
                  Now_EY = sg(PAPH.ey[1], calcu_digits);
                  Now_Len = Now_Len + (sagcad_line_style[style].max * mm);
                  if (Total_Len <= Now_Len) {
                        Now_EX = EX;
                        Now_EY = EY;
                        gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //LineTo(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        return 1;
                  }
                  else {
                        gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //LineTo(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        Now_SX = Now_EX;
                        Now_SY = Now_EY;
                  }


                  PAPH.sx[1] = Now_SX;
                  PAPH.sy[1] = Now_SY;
                  PAPH.angle = Angle;
                  PAPH.l = sagcad_line_style[style].min * mm;
                  pap(&PAPH);
                  Now_EX = sg(PAPH.ex[1], calcu_digits);
                  Now_EY = sg(PAPH.ey[1], calcu_digits);
                  Now_Len = Now_Len + (sagcad_line_style[style].min * mm);
                  if (Total_Len <= Now_Len) {
                        Now_EX = EX;
                        Now_EY = EY;
                        //gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //MoveToEx(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY), NULL);
                        return 1;
                  }
                  else {
                        //gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //MoveToEx(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY), NULL);
                        Now_SX = Now_EX;
                        Now_SY = Now_EY;
                  }


                  PAPH.sx[1] = Now_SX;
                  PAPH.sy[1] = Now_SY;
                  PAPH.angle = Angle;
                  PAPH.l = sagcad_line_style[style].min * mm;
                  pap(&PAPH);
                  Now_EX = sg(PAPH.ex[1], calcu_digits);
                  Now_EY = sg(PAPH.ey[1], calcu_digits);
                  Now_Len = Now_Len + (sagcad_line_style[style].min * mm);
                  if (Total_Len <= Now_Len) {
                        Now_EX = EX;
                        Now_EY = EY;
                        gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //LineTo(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        return 1;
                  }
                  else {
                        gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //LineTo(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        Now_SX = Now_EX;
                        Now_SY = Now_EY;
                  }


                  PAPH.sx[1] = Now_SX;
                  PAPH.sy[1] = Now_SY;
                  PAPH.angle = Angle;
                  PAPH.l = sagcad_line_style[style].min * mm;
                  pap(&PAPH);
                  Now_EX = sg(PAPH.ex[1], calcu_digits);
                  Now_EY = sg(PAPH.ey[1], calcu_digits);
                  Now_Len = Now_Len + (sagcad_line_style[style].min * mm);
                  if (Total_Len <= Now_Len) {
                        Now_EX = EX;
                        Now_EY = EY;
                        //gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //MoveToEx(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY), NULL);
                        return 1;
                  }
                  else {
                        //gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //MoveToEx(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY), NULL);
                        Now_SX = Now_EX;
                        Now_SY = Now_EY;
                  }


            }
            return 1;
      }


      /* 二点鎖線 */
      else if (sagcad_line_style[style].style == 4) {
            while (1) {
                  PAPH.sx[1] = Now_SX;
                  PAPH.sy[1] = Now_SY;
                  PAPH.angle = Angle;
                  PAPH.l = sagcad_line_style[style].max * mm;
                  pap(&PAPH);
                  Now_EX = sg(PAPH.ex[1], calcu_digits);
                  Now_EY = sg(PAPH.ey[1], calcu_digits);
                  Now_Len = Now_Len + (sagcad_line_style[style].max * mm);
                  if (Total_Len <= Now_Len) {
                        Now_EX = EX;
                        Now_EY = EY;
                        gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //LineTo(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        return 1;
                  }
                  else {
                        gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //LineTo(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        Now_SX = Now_EX;
                        Now_SY = Now_EY;
                  }


                  PAPH.sx[1] = Now_SX;
                  PAPH.sy[1] = Now_SY;
                  PAPH.angle = Angle;
                  PAPH.l = sagcad_line_style[style].min * mm;
                  pap(&PAPH);
                  Now_EX = sg(PAPH.ex[1], calcu_digits);
                  Now_EY = sg(PAPH.ey[1], calcu_digits);
                  Now_Len = Now_Len + (sagcad_line_style[style].min * mm);
                  if (Total_Len <= Now_Len) {
                        Now_EX = EX;
                        Now_EY = EY;
                        //gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //MoveToEx(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY), NULL);
                        return 1;
                  }
                  else {
                        //gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //MoveToEx(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY), NULL);
                        Now_SX = Now_EX;
                        Now_SY = Now_EY;
                  }


                  PAPH.sx[1] = Now_SX;
                  PAPH.sy[1] = Now_SY;
                  PAPH.angle = Angle;
                  PAPH.l = sagcad_line_style[style].min * mm;
                  pap(&PAPH);
                  Now_EX = sg(PAPH.ex[1], calcu_digits);
                  Now_EY = sg(PAPH.ey[1], calcu_digits);
                  Now_Len = Now_Len + (sagcad_line_style[style].min * mm);
                  if (Total_Len <= Now_Len) {
                        Now_EX = EX;
                        Now_EY = EY;
                        gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //LineTo(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        return 1;
                  }
                  else {
                        gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //LineTo(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        Now_SX = Now_EX;
                        Now_SY = Now_EY;
                  }


                  PAPH.sx[1] = Now_SX;
                  PAPH.sy[1] = Now_SY;
                  PAPH.angle = Angle;
                  PAPH.l = sagcad_line_style[style].min * mm;
                  pap(&PAPH);
                  Now_EX = sg(PAPH.ex[1], calcu_digits);
                  Now_EY = sg(PAPH.ey[1], calcu_digits);
                  Now_Len = Now_Len + (sagcad_line_style[style].min * mm);
                  if (Total_Len <= Now_Len) {
                        Now_EX = EX;
                        Now_EY = EY;
                        //gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //MoveToEx(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY), NULL);
                        return 1;
                  }
                  else {
                        //gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //MoveToEx(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY), NULL);
                        Now_SX = Now_EX;
                        Now_SY = Now_EY;
                  }


                  PAPH.sx[1] = Now_SX;
                  PAPH.sy[1] = Now_SY;
                  PAPH.angle = Angle;
                  PAPH.l = sagcad_line_style[style].min * mm;
                  pap(&PAPH);
                  Now_EX = sg(PAPH.ex[1], calcu_digits);
                  Now_EY = sg(PAPH.ey[1], calcu_digits);
                  Now_Len = Now_Len + (sagcad_line_style[style].min * mm);
                  if (Total_Len <= Now_Len) {
                        Now_EX = EX;
                        Now_EY = EY;
                        gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //LineTo(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        return 1;
                  }
                  else {
                        gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //LineTo(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        Now_SX = Now_EX;
                        Now_SY = Now_EY;
                  }


                  PAPH.sx[1] = Now_SX;
                  PAPH.sy[1] = Now_SY;
                  PAPH.angle = Angle;
                  PAPH.l = sagcad_line_style[style].min * mm;
                  pap(&PAPH);
                  Now_EX = sg(PAPH.ex[1], calcu_digits);
                  Now_EY = sg(PAPH.ey[1], calcu_digits);
                  Now_Len = Now_Len + (sagcad_line_style[style].min * mm);
                  if (Total_Len <= Now_Len) {
                        Now_EX = EX;
                        Now_EY = EY;
                        //gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //MoveToEx(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY), NULL);
                        return 1;
                  }
                  else {
                        //gdk_draw_line(pixmap/*widget->window*/, gc, ToDeviceX(Now_SX), ToDeviceY(Now_SY), ToDeviceX(Now_EX), ToDeviceY(Now_EY));
                        //MoveToEx(gc, ToDeviceX(Now_EX), ToDeviceY(Now_EY), NULL);
                        Now_SX = Now_EX;
                        Now_SY = Now_EY;
                  }
            }
            return 1;
      }
      return 0;
}





/* -------------------------------------------------------------------
 * 円の表示
 * 
 */
int CircleK(GtkWidget *widget, double CX, double CY, double R, double SA, double EA, int style, long color)
{
      double mm;
      double X, Y, oX = 0, oY = 0, i, step;
      int k;

      if (R <= 0) return 0;

      mm = 1 / Mag;
      step = (mm * 360) / (2 * PI * R);

      if(SA < EA) {
            /* 実線 */
            if (sagcad_line_style[style].style == 1) {
                  for(i = SA ; i <= EA ; i = i + step) {
                        X = R * cos(degrad(i)) + CX;
                        Y = R * sin(degrad(i)) + CY;
                        if(i != SA) LineDraw(widget, oX, oY, X, Y, style, color);
                        oX = X;
                        oY = Y;
                  }
                  X = R * cos(degrad(EA)) + CX;
                  Y = R * sin(degrad(EA)) + CY;
                  LineDraw(widget, oX, oY, X, Y, style, color);
            }



            /* 点線 */
            if (sagcad_line_style[style].style == 2) {
                  k = 0;
                  for(i = SA ; i < EA ; i = i + step ) {
                        k++;
                        X = R * cos(degrad(i)) + CX;
                        Y = R * sin(degrad(i)) + CY;
                        if(i != SA && k<= sagcad_line_style[style].max) {
                              LineDraw(widget, oX, oY, X, Y, style, color);
                        }
                        else if(k < sagcad_line_style[style].max + sagcad_line_style[style].min) {
                              // 
                        }
                        else if(k == sagcad_line_style[style].max + sagcad_line_style[style].min) {
                              k = 0;
                        }
                        oX = X;
                        oY = Y;
                  }
                  X = R * cos(degrad(EA)) + CX;
                  Y = R * sin(degrad(EA)) + CY;
                  LineDraw(widget, oX, oY, X, Y, style, color);
            }



            /* 一点鎖線 */
            if (sagcad_line_style[style].style == 3) {
                  k = 0;
                  for(i = SA ; i < EA ; i = i + step ) {
                        k++;
                        X = R * cos(degrad(i)) + CX;
                        Y = R * sin(degrad(i)) + CY;
                        if(i != SA && k<= sagcad_line_style[style].max) {
                              LineDraw(widget, oX, oY, X, Y, style, color);
                        }
                        else if(k <= sagcad_line_style[style].max + sagcad_line_style[style].min) {
                              //
                        }
                        else if(k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 2)) {
                              LineDraw(widget, oX, oY, X, Y, style, color);
                        }
                        else if(k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 3)) {
                              if(k == sagcad_line_style[style].max + (sagcad_line_style[style].min * 3)) k=0;
                        }
                        oX = X;
                        oY = Y;
                  }
                  X = R * cos(degrad(EA)) + CX;
                  Y = R * sin(degrad(EA)) + CY;
                  LineDraw(widget, oX, oY, X, Y, style, color);
            }



            /* 二点鎖線 */
            if (sagcad_line_style[style].style == 4) {
                  k = 0;
                  for(i = SA ; i < EA ; i = i + step ) {
                        k++;
                        X = R * cos(degrad(i)) + CX;
                        Y = R * sin(degrad(i)) + CY;
                        /* max */
                        if(i != SA && k <= sagcad_line_style[style].max) {
                              LineDraw(widget, oX, oY, X, Y, style, color);
                        }
                        else if(k <= sagcad_line_style[style].max + sagcad_line_style[style].min) {
                              // 
                        }
                        else if(k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 2)) {
                              LineDraw(widget, oX, oY, X, Y, style, color);
                        }
                        else if(k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 3)) {
                              // 
                        }
                        else if(k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 4)) {
                              LineDraw(widget, oX, oY, X, Y, style, color);
                        }
                        else if(k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 5)) {
                              if(k == sagcad_line_style[style].max + (sagcad_line_style[style].min * 5)) k = 0;
                        }
                        oX = X;
                        oY = Y;
                  }
                  X = R * cos(degrad(EA)) + CX;
                  Y = R * sin(degrad(EA)) + CY;
                  LineDraw(widget, oX, oY, X, Y, style, color);
            }
      }



      if(SA > EA) {
            CircleK(widget, CX, CY, R, SA, 360, style, color);
            CircleK(widget, CX, CY, R, 0, EA, style, color);
      }
      return 1;
}





/* -------------------------------------------------------------------
 * 楕円の表示
 * 
 */
int EllipseK(GtkWidget *widget, ELLIPSE ellipse, int style, long color)
{

      double mm;
      double i, step;
      int k;
      SAG_POINT new_point, old_point;
      ELLIPSE ellipse_sub;


      mm = 1/Mag;
      step = (mm * 360) / (2 * PI * get_ellipse_a(ellipse));

//    g_print("sa = %f   ea = %f   step = %f\n", ellipse.sa, ellipse.ea, step);

      if (ellipse.sa < ellipse.ea) {
            /* 実線 */
            if (sagcad_line_style[style].style == 1) {
                  for (i = ellipse.sa ; i < ellipse.ea ; i = i + step) {
                        new_point.x = 0;
                        new_point.y = 0;
                        get_ellipse_point_from_angle (ellipse, i, &new_point);
                        //g_print("%f : (%f,%f)\n", i, new_point.x, new_point.y);
                        if (i != ellipse.sa) LineDraw(widget, old_point.x, old_point.y, new_point.x, new_point.y, style, color);
                        old_point.x = new_point.x;
                        old_point.y = new_point.y;
                  }
                  get_ellipse_point_from_angle (ellipse, ellipse.ea, &new_point);
                  //g_print("%f : (%f,%f)\n", ellipse.ea, new_point.x, new_point.y);
                  LineDraw(widget, old_point.x, old_point.y, new_point.x, new_point.y, style, color);
            }



            /* 点線 */
            else if (sagcad_line_style[style].style == 2) {
                  k = 0;
                  for(i = ellipse.sa ; i < ellipse.ea ; i = i + step ) {
                        k++;
                        get_ellipse_point_from_angle (ellipse, i, &new_point);
                        if (i != ellipse.sa && k <= sagcad_line_style[style].max) {
                              LineDraw(widget, old_point.x, old_point.y, new_point.x, new_point.y, style, color);
                        }
                        else if (k < sagcad_line_style[style].max + sagcad_line_style[style].min) {
                              // 
                        }
                        else if (k == sagcad_line_style[style].max + sagcad_line_style[style].min) {
                              k = 0;
                        }
                        old_point.x = new_point.x;
                        old_point.y = new_point.y;
                  }
                  get_ellipse_point_from_angle (ellipse, ellipse.ea, &new_point);
                  LineDraw(widget, old_point.x, old_point.y, new_point.x, new_point.y, style, color);
            }



            /* 一点鎖線 */
            else if (sagcad_line_style[style].style == 3) {
                  k = 0;
                  for(i = ellipse.sa ; i < ellipse.ea ; i = i + step ) {
                        k++;
                        get_ellipse_point_from_angle (ellipse, i, &new_point);
                        if (i != ellipse.sa && k <= sagcad_line_style[style].max) {
                              LineDraw(widget, old_point.x, old_point.y, new_point.x, new_point.y, style, color);
                        }
                        else if (k <= sagcad_line_style[style].max + sagcad_line_style[style].min) {
                              //
                        }
                        else if (k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 2)) {
                              LineDraw(widget, old_point.x, old_point.y, new_point.x, new_point.y, style, color);
                        }
                        else if (k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 3)) {
                              if (k == sagcad_line_style[style].max + (sagcad_line_style[style].min * 3)) k=0;
                        }
                        old_point.x = new_point.x;
                        old_point.y = new_point.y;
                  }
                  get_ellipse_point_from_angle (ellipse, ellipse.ea, &new_point);
                  LineDraw(widget, old_point.x, old_point.y, new_point.x, new_point.y, style, color);
            }



            /* 二点鎖線 */
            else if (sagcad_line_style[style].style == 4) {
                  k = 0;
                  for (i = ellipse.sa ; i < ellipse.ea ; i = i + step ) {
                        k++;
                        get_ellipse_point_from_angle (ellipse, i, &new_point);
                        /* max */
                        if (i != ellipse.sa && k <= sagcad_line_style[style].max) {
                              LineDraw(widget, old_point.x, old_point.y, new_point.x, new_point.y, style, color);
                        }
                        else if (k <= sagcad_line_style[style].max + sagcad_line_style[style].min) {
                              // 
                        }
                        else if (k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 2)) {
                              LineDraw(widget, old_point.x, old_point.y, new_point.x, new_point.y, style, color);
                        }
                        else if (k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 3)) {
                              // 
                        }
                        else if (k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 4)) {
                              LineDraw(widget, old_point.x, old_point.y, new_point.x, new_point.y, style, color);
                        }
                        else if (k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 5)) {
                              if (k == sagcad_line_style[style].max + (sagcad_line_style[style].min * 5)) k = 0;
                        }
                        old_point.x = new_point.x;
                        old_point.y = new_point.y;
                  }
                  get_ellipse_point_from_angle (ellipse, ellipse.ea, &new_point);
                  LineDraw(widget, old_point.x, old_point.y, new_point.x, new_point.y, style, color);
            }
      }



      if (ellipse.sa > ellipse.ea) {
            ellipse_sub = ellipse;
            ellipse_sub.ea = 360;
            EllipseK(widget, ellipse_sub, style, color);
            ellipse_sub = ellipse;
            ellipse_sub.sa = 0;
            EllipseK(widget, ellipse_sub, style, color);
      }
      return 1;
}




#ifdef TEST
/* -------------------------------------------------------------------
 * 楕円の表示
 * 
 */
int EllipseK(GtkWidget *widget, 
                   double cx, double cy, double a, double b, 
                   double sa, double ea, double angle , 
                   int style, long color)
{

      double mm;
      double X, Y, oX = 0, oY = 0, i, step;
      int k;
      double RAD, DX, DY;


      if (a < 0 || b < 0) return 0;

      mm = 1/Mag;
      step = (mm * 360) / (2 * PI * a);
      /* 移動ベクトル */
      RAD = degrad(angle);

      if (sa < ea) {
            /* 実線 */
            if (sagcad_line_style[style].style == 1) {
                  for (i = sa ; i <= ea ; i = i + step) {
                        X = a * cos(degrad(i)) + cx;
                        Y = b * sin(degrad(i)) + cy;
                        
                        DX = X - cx;
                        DY = Y - cy;
                        X = sg((DX * cos(RAD) - DY * sin(RAD)) + cx, calcu_digits);
                        Y = sg((DY * cos(RAD) + DX * sin(RAD)) + cy, calcu_digits);
                        
                        if (i != sa) LineDraw(widget, oX, oY, X, Y, style, color);
                        oX = X;
                        oY = Y;
                  }
                  X = a * cos(degrad(ea)) + cx;
                  Y = b * sin(degrad(ea)) + cy;
                  
                  DX = X - cx;
                  DY = Y - cy;
                  X = sg((DX * cos(RAD) - DY * sin(RAD)) + cx, calcu_digits);
                  Y = sg((DY * cos(RAD) + DX * sin(RAD)) + cy, calcu_digits);
                  LineDraw(widget, oX, oY, X, Y, style, color);
            }



            /* 点線 */
            if (sagcad_line_style[style].style == 2) {
                  k = 0;
                  for(i = sa ; i < ea ; i = i + step ) {
                        k++;
                        X = a * cos(degrad(i)) + cx;
                        Y = b * sin(degrad(i)) + cy;
                        
                        DX = X - cx;
                        DY = Y - cy;
                        X = sg((DX * cos(RAD) - DY * sin(RAD)) + cx, calcu_digits);
                        Y = sg((DY * cos(RAD) + DX * sin(RAD)) + cy, calcu_digits);

                        if (i != sa && k <= sagcad_line_style[style].max) {
                              LineDraw(widget, oX, oY, X, Y, style, color);
                        }
                        else if (k < sagcad_line_style[style].max + sagcad_line_style[style].min) {
                              // 
                        }
                        else if (k == sagcad_line_style[style].max + sagcad_line_style[style].min) {
                              k = 0;
                        }
                        oX = X;
                        oY = Y;
                  }

                  X = a * cos(degrad(ea)) + cx;
                  Y = b * sin(degrad(ea)) + cy;
                  
                  DX = X - cx;
                  DY = Y - cy;
                  X = sg((DX * cos(RAD) - DY * sin(RAD)) + cx, calcu_digits);
                  Y = sg((DY * cos(RAD) + DX * sin(RAD)) + cy, calcu_digits);
                  LineDraw(widget, oX, oY, X, Y, style, color);
            }



            /* 一点鎖線 */
            if (sagcad_line_style[style].style == 3) {
                  k = 0;
                  for(i = sa ; i < ea ; i = i + step ) {
                        k++;

                        X = a * cos(degrad(i)) + cx;
                        Y = b * sin(degrad(i)) + cy;
                        
                        DX = X - cx;
                        DY = Y - cy;
                        X = sg((DX * cos(RAD) - DY * sin(RAD)) + cx, calcu_digits);
                        Y = sg((DY * cos(RAD) + DX * sin(RAD)) + cy, calcu_digits);

                        if (i != sa && k <= sagcad_line_style[style].max) {
                              LineDraw(widget, oX, oY, X, Y, style, color);
                        }
                        else if (k <= sagcad_line_style[style].max + sagcad_line_style[style].min) {
                              //
                        }
                        else if (k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 2)) {
                              LineDraw(widget, oX, oY, X, Y, style, color);
                        }
                        else if (k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 3)) {
                              if (k == sagcad_line_style[style].max + (sagcad_line_style[style].min * 3)) k=0;
                        }
                        oX = X;
                        oY = Y;
                  }

                  X = a * cos(degrad(ea)) + cx;
                  Y = b * sin(degrad(ea)) + cy;
                  
                  DX = X - cx;
                  DY = Y - cy;
                  X = sg((DX * cos(RAD) - DY * sin(RAD)) + cx, calcu_digits);
                  Y = sg((DY * cos(RAD) + DX * sin(RAD)) + cy, calcu_digits);
                  LineDraw(widget, oX, oY, X, Y, style, color);
            }



            /* 二点鎖線 */
            if (sagcad_line_style[style].style == 4) {
                  k = 0;
                  for (i = sa ; i < ea ; i = i + step ) {
                        k++;

                        X = a * cos(degrad(i)) + cx;
                        Y = b * sin(degrad(i)) + cy;
                        
                        DX = X - cx;
                        DY = Y - cy;
                        X = sg((DX * cos(RAD) - DY * sin(RAD)) + cx, calcu_digits);
                        Y = sg((DY * cos(RAD) + DX * sin(RAD)) + cy, calcu_digits);

                        /* max */
                        if (i != sa && k <= sagcad_line_style[style].max) {
                              LineDraw(widget, oX, oY, X, Y, style, color);
                        }
                        else if (k <= sagcad_line_style[style].max + sagcad_line_style[style].min) {
                              // 
                        }
                        else if (k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 2)) {
                              LineDraw(widget, oX, oY, X, Y, style, color);
                        }
                        else if (k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 3)) {
                              // 
                        }
                        else if (k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 4)) {
                              LineDraw(widget, oX, oY, X, Y, style, color);
                        }
                        else if (k <= sagcad_line_style[style].max + (sagcad_line_style[style].min * 5)) {
                              if (k == sagcad_line_style[style].max + (sagcad_line_style[style].min * 5)) k = 0;
                        }
                        oX = X;
                        oY = Y;
                  }

                  X = a * cos(degrad(ea)) + cx;
                  Y = b * sin(degrad(ea)) + cy;
                  
                  DX = X - cx;
                  DY = Y - cy;
                  X = sg((DX * cos(RAD) - DY * sin(RAD)) + cx, calcu_digits);
                  Y = sg((DY * cos(RAD) + DX * sin(RAD)) + cy, calcu_digits);
                  LineDraw(widget, oX, oY, X, Y, style, color);
            }
      }



      if (sa > ea) {
            EllipseK(widget, cx, cy, a, b, sa, 360, angle, style, color);
            EllipseK(widget, cx, cy, a, b, 0, ea, angle, style, color);
      }
      return 1;
}
#endif




/* -------------------------------------------------------------------
 * 実寸印刷時の印刷範囲を描画
 * 
 *      Points       mm
 * A3 : 842 x 1191   297.039 x 420.159
 * A4 : 595 x  842   209.903 x 297.039
 * A5 : 420 x  595   148.167 x 209.903
 * B4 : 729 x 1032   257.175 x 364.067
 * B5 : 516 x  729   182.033 x 257.175
 */
int WakuWakuDraw(GtkWidget *widget)
{

      double PaperX = 0, PaperY = 0, left, top, right, bottom;


      switch (printer.Paper) {
            case USER_PAPER :
                  PaperX = printer.paper_right;
                  PaperY = printer.paper_top;
                  break;

            /* A3 */
            case A3_PAPER:
                  PaperX = 297.039;
                  PaperY = 420.159;
                  if (printer.Orientation == LANDSCAPE) {
                        Swap_double (&PaperX, &PaperY);
                  }
                  break;

            /* A4 */
            case A4_PAPER:
                  PaperX = 209.903;
                  PaperY = 297.039;
                  if (printer.Orientation == LANDSCAPE) {
                        Swap_double (&PaperX, &PaperY);
                  }
                  break;

            /* A5 */
            case A5_PAPER:
                  PaperX = 148.167;
                  PaperY = 209.903;
                  if (printer.Orientation == LANDSCAPE) {
                        Swap_double (&PaperX, &PaperY);
                  }
                  break;

            /* B5 */
            case B5_PAPER:
                  PaperX = 182.033;
                  PaperY = 257.175;
                  if (printer.Orientation == LANDSCAPE) {
                        Swap_double (&PaperX, &PaperY);
                  }
                  break;

            /* B4 */
            case B4_PAPER:
                  PaperX = 257.175;
                  PaperY = 364.067;
                  if (printer.Orientation == LANDSCAPE) {
                        Swap_double (&PaperX, &PaperY);
                  }
                  break;

            default:
                  g_print (_("Mistaking by the specification of the paper.[%d]\n"), printer.Paper);
                  PaperX = 209.903;
                  PaperY = 297.039;
                  break;
      }


      PenSet(gc, 2, sagcad_color.PrinterRect);

      left   = MagX - ((PaperX / 2) / printer.scale);
      top      = MagY + ((PaperY / 2) / printer.scale);
      right  = MagX + ((PaperX / 2) / printer.scale);
      bottom = MagY - ((PaperY / 2) / printer.scale);


//    left   = -1 * (PaperX / 2);
//    top      = (PaperY / 2);
//    right  = (PaperX / 2);
//    bottom = -1 * (PaperY / 2);

      LineDraw(widget, left, top, right, top, 2, sagcad_color.PrinterRect);
      LineDraw(widget, right, top, right, bottom, 2, sagcad_color.PrinterRect);
      LineDraw(widget, right, bottom, left, bottom, 2, sagcad_color.PrinterRect);
      LineDraw(widget, left, bottom, left, top, 2, sagcad_color.PrinterRect);

      PenDelete(gc);
      return 1;
}





#ifdef TEST
/* ------------------------------------------------------------------
 * GC を設定
 * GC Setting
 */
int PenSet(GdkGC *gc, int style, long color)
{
      GdkColor for_gdk_backgroundcolor;
      GdkColor for_gdk_foregroundcolor;

      gchar dash[] = { 6, 6};
      gchar dash1[] = { 20, 6, 6, 6};
      gchar dash2[] = { 20, 6, 6, 6, 6, 6};

      for_gdk_foregroundcolor = color_gtk(color);
      gdk_color_alloc(gdk_colormap_get_system(), &for_gdk_foregroundcolor);
      gdk_gc_set_foreground(gc, &for_gdk_foregroundcolor);

      for_gdk_backgroundcolor = color_gtk(Back_color);
      gdk_color_alloc(gdk_colormap_get_system(), &for_gdk_backgroundcolor);
      gdk_gc_set_background(gc, &for_gdk_backgroundcolor);


      /* 実線(太) */
      if(style == 0) {
            gdk_gc_set_line_attributes(gc, 3, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
      }
      /* 実線(細) */
      else if(style == 1) {
            gdk_gc_set_line_attributes(gc, 2, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
      }
      /* 点線 */
      else if(style == 2) {
            gdk_gc_set_line_attributes(gc, 2, GDK_LINE_DOUBLE_DASH, GDK_CAP_BUTT, GDK_JOIN_MITER);
            gdk_gc_set_dashes(gc, 0, dash, 2);
      }
      /* 1点鎖線 */
      else if(style == 3) {
            gdk_gc_set_line_attributes(gc, 2, GDK_LINE_DOUBLE_DASH, GDK_CAP_BUTT, GDK_JOIN_MITER);
            gdk_gc_set_dashes(gc, 0, dash1, 4);
      }
      /* 2点鎖線 */
      else if(style == 4) {
            gdk_gc_set_line_attributes(gc, 2, GDK_LINE_DOUBLE_DASH, GDK_CAP_BUTT, GDK_JOIN_MITER);
            gdk_gc_set_dashes(gc, 0, dash2, 6);
      }
      /* 寸法線用実線 */
      else if(style == 5) {
            gdk_gc_set_line_attributes(gc, 1, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
      }
      /* LineStyleBox & Layer_dlg リソース用実線 */
      else if(style == 10) {
            gdk_gc_set_line_attributes(gc, 1, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
      }
      else {
            gdk_gc_set_line_attributes(gc, 1, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
      }
      return 1;
}





/* ------------------------------------------------------------------
 * GC を RGB で設定
 * GC Setting RGB
 */
int PenSet_rgb(GdkGC *gc, gushort red, gushort green, gushort blue, int style)
{
      int Ret;
      GdkColor color;

      color.red = red, color.green = green, color.blue = blue;
      gdk_color_alloc(gdk_colormap_get_system(), &color);

//      Ret = PenSet(gc, style, &color);

      if(Ret == 0)
            return 0;
      else  
            return 1;
}
#endif





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

Generated by  Doxygen 1.6.0   Back to index