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

List_font.c

/* ====================================================================
 * ===  Copyright (C) 1998-2007 Yutaka Sagiya. All rights reserved. ===
 * ====================================================================
 * 
 *    Project              : SagCAD
 *    Description          : CAD/CAM
 *    Source               : List_font.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 <unistd.h>
//#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
//#include <langinfo.h>

#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "intl.h"

#include "MemoryLeak.h"
#include "List_cad.h"
#include "List_Dimension.h"
#include "List_PolyLine.h"
#include "List_Block.h"
#include "List_Undo.h"
#include "List_Select.h"
#include "culcfunc.h"
#include "etc.h"
#define _LIST_FONT_
#include "List_font.h"





/* ---------------------------------------------------------
 * SAG_FONT Data をリストの最後に追加
 * 
 * 
 */
SAG_FONT_LIST *font_list_add_last(SAG_FONT *add_font)
{
      SAG_FONT_LIST *p;

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

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

      /* ここでは領域を確保する必要はない。フォントを読み込んだときに確保したから。 */
      /* データ (font_data) を書き込むための領域を確保する */
//    p_font_list->font->font_data = (SAG_FONT_DATA *)xmalloc(add_font->index * sizeof(SAG_FONT_DATA));

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


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

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

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

      /* アンドゥバッファに書込む */
      return font_list_info.tail;
}





/* ---------------------------------------------------------
 * SAG_FONT Data をリストから削除
 * 
 */
int font_list_free(SAG_FONT_LIST *del_List)
{
      SAG_FONT_LIST *p = NULL;
      SAG_FONT_LIST *pb = NULL;


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


            if(p != NULL){
                  /* 最後のデータ */
                  if (del_List == font_list_info.tail) {
                        //g_print("最後のデータ\n");
                        pb->next = NULL;
                        font_list_info.tail = pb;
                  }
                  /* 中間のデータ */
                  else if (del_List != font_list_info.head && del_List != font_list_info.tail) {
                        //g_print("中間のデータ\n");
                        pb->next = p->next;
                  }
            }
            else {
                  //g_print("リストの SAG_FONT データではない\n");
                  return 0;
            }
      }
      if (del_List->font->index > 0) {
            xfree(del_List->font->font_data);
      }
      xfree(del_List->font);
      xfree(del_List);
      return 1;
}





/* ---------------------------------------------------------
 * 全リストを削除
 * 
 */
void font_list_all_free(void)
{
      while(font_list_info.head != NULL) {
            font_list_free(font_list_info.head);
      }
}





/* -------------------------------------------------------------------
 * SagCAD Font Type (sft File) のデータを読み込む
 */
int sft_file_read(FILE *stream)
{
      char str[256];


      while(1) {
            if (LineRead(stream, str) == 0) return 0;

            /* "eof" の文字で終了 */
            if (strstr(str, "eof") != NULL ) break;
            /* "EOF" の文字で終了 */
            else if (strstr(str, "EOF") != NULL ) break;

            else if(strstr(str, "s_") != NULL ) {
                  sft_char_read(stream, str);
            }
      }
      return 1;
}



int ScalingFont(SAG_FONT_DATA *font_data, double x, double y, double k)
{
      /* 点のとき */
      if (font_data->code == 0) {
            font_data->sx = sg((k * font_data->sx) + x * (1 - k), calcu_digits);
            font_data->sy = sg((k * font_data->sy) + y * (1 - k), calcu_digits);
      }
      /* 線のとき */
      else if (font_data->code == 1) {
            font_data->sx = sg((k * font_data->sx) + x * (1 - k), calcu_digits);
            font_data->sy = sg((k * font_data->sy) + y * (1 - k), calcu_digits);
            font_data->ex = sg((k * font_data->ex) + x * (1 - k), calcu_digits);
            font_data->ey = sg((k * font_data->ey) + y * (1 - k), calcu_digits);
      }
      /* 円弧のとき */
      else if (font_data->code == 2) {
            font_data->cx = sg((k * font_data->cx) + x * (1 - k), calcu_digits);
            font_data->cy = sg((k * font_data->cy) + y * (1 - k), calcu_digits);
            font_data->sx = sg((k * font_data->sx) + x * (1 - k), calcu_digits);
            font_data->sy = sg((k * font_data->sy) + y * (1 - k), calcu_digits);
            font_data->ex = sg((k * font_data->ex) + x * (1 - k), calcu_digits);
            font_data->ey = sg((k * font_data->ey) + y * (1 - k), calcu_digits);
            font_data->r = sg(k * font_data->r, calcu_digits);
      }
      /* 円のとき */
      else if (font_data->code == 4) {
            font_data->cx = sg((k * font_data->cx) + x * (1 - k), calcu_digits);
            font_data->cy = sg((k * font_data->cy) + y * (1 - k), calcu_digits);
            font_data->r = sg(k * font_data->r, calcu_digits);
      }
      return 1;
}



/* -------------------------------------------------------------------
 * SagCAD Font Type (sft File) のデータを読み込む
 */
SAG_FONT *sft_char_read(FILE *stream, char *str)
{
      SAG_FONT_LIST *font_list = NULL;
      SAG_FONT font;
      SAG_FONT_DATA *font_data = NULL;
      char ret[256];
      int i;
      double scale;


      /* 定義文字 */
      strcpy (font.moji, &str[2]);
      /* width */
      if (LineRead(stream, str) == 0) return NULL;
      font.width = (float) atof(str);
      /* height */
      if (LineRead(stream, str) == 0) return NULL;
      font.height = (float) atof(str);

      scale = 9 / font.height;
      font.height = font.height*scale;
      font.width = font.width*scale;

      /* index */
      if (LineRead(stream, str) == 0) return NULL;
      font.index = atoi(str);
      if (font.index > 0) {
            /* データ (font_data) を書き込むための領域を確保する */
            font_data = (SAG_FONT_DATA *)xmalloc(font.index * sizeof(SAG_FONT_DATA));
            font.font_data = font_data;
      }
      else {
            font.font_data = NULL;
      }
      /* SAG_FONT Data をリストの最後に追加 */
      font_list = font_list_add_last(&font);




      if (font.index > 0) {
            for (i = 0 ; i < font.index ; i++) {
                  /* 1行読みこみ */
                  if (LineRead(stream, str) == 0) return NULL;
                  /* code */
                  LineDataSplit(str, ',', 1, ret);
                  font_data[i].code = atoi(ret);
                  /* SX */
                  LineDataSplit(str, ',', 2, ret);
                  font_data[i].sx = (float) atof(ret);
                  /* SY */
                  LineDataSplit(str, ',', 3, ret);
                  font_data[i].sy = (float) atof(ret);
                  /* EX */
                  LineDataSplit(str, ',', 4, ret);
                  font_data[i].ex = (float) atof(ret);
                  /* EY */
                  LineDataSplit(str, ',', 5, ret);
                  font_data[i].ey = (float) atof(ret);
                  /* CX */
                  LineDataSplit(str, ',', 6, ret);
                  font_data[i].cx = (float) atof(ret);
                  /* CY */
                  LineDataSplit(str, ',', 7, ret);
                  font_data[i].cy = (float) atof(ret);
                  /*    R */
                  LineDataSplit(str, ',', 8, ret);
                  font_data[i].r = (float) atof(ret);

                  ScalingFont(&font_data[i], 0, 0, scale);
            }
      }

      return font_list->font;
}





/* -------------------------------------------------------------------
 * QCad Font Type (cxf File) のデータを読み込む
 */
int cxf_file_read(FILE *stream)
{
      char str[256];


      while(1) {
            if (LineRead(stream, str) == 0) {
                  g_print ("LineRead End\n");
                  return 0;
            }

            /* "eof" の文字で終了 */
            if (strstr(str, "eof") != NULL ) {
                  break;
            }
            /* "EOF" の文字で終了 */
            else if (strstr(str, "#EOF") != NULL ) {
                  break;
            }

            else if (strstr(str, "[") != NULL && strstr(str, "]") != NULL) {
                  cxf_char_read(stream, str);
            }
      }
      return 1;
}



/* -------------------------------------------------------------------
 * QCad Font Type (cxf File) のデータを読み込む
 */
SAG_FONT *cxf_char_read(FILE *stream, char *str)
{
      SAG_FONT_LIST *font_list = NULL;
      SAG_FONT font;
      SAG_FONT_DATA *font_data = NULL;
      char ret[256], *index_start;
      int i;
      double angle = 0, sa = 0, ea = 0, max = 0;
      char ret_str[256];
      int bite = 0;


      strcpy(ret_str, &str[1]);
      bite = utf8_bite_num(ret_str[0]);
      /* 1 bite */
      if (bite == 1) {
            font.moji[0] = ret_str[0];
            font.moji[1] = '\0';

//          g_print ("%hhx [%s]\n", font.moji[0], str);
      }
      /* 2 bite */
      else if (bite == 2) {
            font.moji[0] = ret_str[0];
            font.moji[1] = ret_str[1];
            font.moji[2] = '\0';

//          g_print ("%hhx %hhx [%s]\n", font.moji[0], font.moji[1], str);
      }
      /* 3 bite */
      else if (bite == 3) {
            font.moji[0] = ret_str[0];
            font.moji[1] = ret_str[1];
            font.moji[2] = ret_str[2];
            font.moji[3] = '\0';

//          g_print ("%hhx %hhx %hhx [%s]\n", font.moji[0], font.moji[1], font.moji[2], str);
      }
      /* 4 bite */
      else if (bite == 4) {
            font.moji[0] = ret_str[0];
            font.moji[1] = ret_str[1];
            font.moji[2] = ret_str[2];
            font.moji[3] = ret_str[3];
            font.moji[4] = '\0';
      }
      else {
            font.moji[0] = ret_str[0];
            font.moji[1] = '\0';
//          g_print("sag_iconv warning [%c] %d %x\n", ret_str[0] & 0xff, bite, ret_str[0] & 0xff);
      }


      /* width */
      font.width = (float) 9.;
      /* height */
      font.height = (float) 9.;

      /* index */
      index_start = strstr(str, "]") + 1;
      font.index = atoi(index_start);
      if (font.index > 0) {
            /* データ (font_data) を書き込むための領域を確保する */
            font_data = (SAG_FONT_DATA *)xmalloc(font.index * sizeof(SAG_FONT_DATA));
            font.font_data = font_data;
      }
      else {
            font.font_data = NULL;
      }



      if (font.index > 0) {
            /* 文字の要素を取り込む */
            for (i = 0 ; i < font.index ; i++) {
                  /* 1行読みこみ */
                  if (LineRead(stream, str) == 0) return NULL;


                  index_start = str + 2;
                  if (str[0] == 'L' && str[1] == ' ') {
                        /* code */
                        font_data[i].code = 1;
                        /* SX */
                        LineDataSplit(index_start, ',', 1, ret);
                        font_data[i].sx = (float) atof(ret);
                        if (max < font_data[i].sx) max = font_data[i].sx;

                        /* SY */
                        LineDataSplit(index_start, ',', 2, ret);
                        font_data[i].sy = (float) atof(ret);
                        /* EX */
                        LineDataSplit(index_start, ',', 3, ret);
                        font_data[i].ex = (float) atof(ret);
                        if (max < font_data[i].ex) max = font_data[i].ex;

                        /* EY */
                        LineDataSplit(index_start, ',', 4, ret);
                        font_data[i].ey = (float) atof(ret);
                  }
                  else if (str[0] == 'A') {
                        /* code */
                        font_data[i].code = 2;
                        /* CX */
                        LineDataSplit(index_start, ',', 1, ret);
                        font_data[i].cx = (float) atof(ret);
                        //if (max < font_data[i].cx) max = font_data[i].cx;

                        /* CY */
                        LineDataSplit(index_start, ',', 2, ret);
                        font_data[i].cy = (float) atof(ret);
                        /* R */
                        LineDataSplit(index_start, ',', 3, ret);
                        font_data[i].r = (float) atof(ret);
                        if (str[1] == ' ') {
                              /* SA */
                              LineDataSplit(index_start, ',', 4, ret);
                              sa = atof(ret);
                              /* EA */
                              LineDataSplit(index_start, ',', 5, ret);
                              ea = atof(ret);
                        }
                        else if (str[1] == 'R') {
                              /* SA */
                              LineDataSplit(index_start, ',', 5, ret);
                              sa = atof(ret);
                              /* EA */
                              LineDataSplit(index_start, ',', 4, ret);
                              ea = atof(ret);
                        }
                        
                        angle = sa * (3.14159265358979 / 180.0);
                        font_data[i].sx = font_data[i].cx + (font_data[i].r * cos(angle));
                        font_data[i].sy = font_data[i].cy + (font_data[i].r * sin(angle));
                        if (max < font_data[i].sx) max = font_data[i].sx;

                        angle = ea * (3.14159265358979 / 180.0);
                        font_data[i].ex = font_data[i].cx + (font_data[i].r * cos(angle));
                        font_data[i].ey = font_data[i].cy + (font_data[i].r * sin(angle));
                        if (max < font_data[i].ex) max = font_data[i].ex;

                  }
            } // for
            /* width */
            font.width = max;

      }
      /* SAG_FONT Data をリストの最後に追加 */
      font_list = font_list_add_last(&font);

      return font_list->font;
}





/* -------------------------------------------------------------------
 * 文字のフォントデータを読みこむ (静的)
 * 
 * CADの起動時にメモリに読みこむフォント
 * フォントファイル [ font_file ]
 * 
 */
int font_open(char *font_file)
{
      FILE *stream;
      char str[256], *file_name;


      /* フォントファイルを探して開く */

      /* 設定パス */
      sprintf(str, "%s", font_file);
      if( (stream  = fopen( str, "r" )) == NULL ) {
            //g_print("フォントファイル [ %s ] がない。\n", str);


            /* ファイル名を取り出す */
            file_name = getFileName(font_file);


            /* /usr/local/sagcad/font/ (普通にインストールしたとき) */
            strcpy(str, FONTDIR);
            strcat(str, "/");
            strcat(str, file_name);
            if( (stream  = fopen( str, "r" )) == NULL ) {
                  //g_print("      [ %s ] にもない。\n", str);

                  /* ./font/ (インストールしないとき用) */
                  sprintf(str, "./font/%s", file_name);
                  if( (stream  = fopen( str, "r" )) == NULL ) {
                        //g_print("  [ %s ] にもない。\n", str);

                        /* カレント */
                        sprintf(str, "%s", file_name);
                        if( (stream  = fopen( str, "r" )) == NULL ){
                              //g_print("フォントファイル [ %s ] がない。\n", str);

                              g_print( _("File Not Found. [%s]\n") , file_name);
                              not_find_font("?");
                              return 0;
                        }
                  }
            }
      }
#ifdef TEST
      g_print("font_file [ %s ] OK !\n", str);
#endif

      if (strstr(font_file, "sft") != NULL || strstr(font_file, "SFT") != NULL) {
            sft_file_read(stream);
      }
      if (strstr(font_file, "cxf") != NULL || strstr(font_file, "CXF") != NULL) {
            cxf_file_read(stream);
      }
      else {
            sft_file_read(stream);
      }

      fclose(stream);
      return 1;
}





/* -------------------------------------------------------------------
 * 文字のフォントデータを読みこむ (動的)
 * 
 * CAD実行中に必要なフォントだけをロードする
 * フォントファイル [ font_file2 ]
 * 
 */
SAG_FONT *font_search_open(char *moji, char *font_file2)
{
//#define FONT_SEARCH_OPEN
      SAG_FONT *font;

      FILE *stream;
      char str[256], *file_name;
      int bite = 0;


      /* フォントファイルを探して開く */
      /* 設定パス */
      sprintf(str, "%s", font_file2);
      if( (stream  = fopen( str, "r" )) == NULL ) {
            g_print("font not search 1 [ %s ]\n", str);


            /* ファイル名を取り出す */
            file_name = getFileName(font_file2);


            /* /usr/local/sagcad/font/ (普通にインストールしたとき) */
            //sprintf(str, "/usr/local/sagcad/font/%s", file_name);
            strcpy(str, FONTDIR);
            strcat(str, "/");
            strcat(str, file_name);
            if( (stream  = fopen( str, "r" )) == NULL ) {
                  g_print("font not search 2 [ %s ]\n", str);
                  
                  /* ./font/ (インストールしないとき用) */
                  sprintf(str, "../../font/%s", file_name);
                  if( (stream  = fopen( str, "r" )) == NULL ) {
                        g_print("font not search 3 [ %s ]\n", str);
                        
                        /* カレント */
                        sprintf(str, "%s", file_name);
                        if( (stream  = fopen( str, "r" )) == NULL ){
                              g_print("font not search 4 [ %s ] がない。\n", str);
                              
                              g_print( _("File Not Found. [%s]\n") , file_name);
                              not_find_font("?");
                              return 0;
                        }
                  }
            }
      }
#ifdef FONT_SEARCH_OPEN
      g_print("font_file2 [ %s ] OK !\n", str);
#endif



      bite = utf8_bite_num(moji[0]);
      while(1) {
            if (LineRead(stream, str) == 0) {
                  return NULL;
            }

            /* "eof" の文字で終了 */
            if(strstr(str, "eof") != NULL ) {
                  break;
            }

            else if (strstr(str, "[") != NULL && strstr(str, "]") != NULL) {
                  /* 1バイト文字 */
                  if (bite == 1) {
                        if (moji[0] == str[1]) {
                              font = cxf_char_read(stream, str);
                              fclose(stream);
                              return font;
                        }
                  }
                  /* 2バイト文字 */
                  else if (bite == 2) {
                        if (moji[0] == str[1] && moji[1] == str[2]) {
                              font = cxf_char_read(stream, str);
                              fclose(stream);
                              return font;
                        }
                  }
                  /* 3バイト文字 */
                  else if (bite == 3) {
                        if (moji[0] == str[1] && moji[1] == str[2] && moji[2] == str[3]) {
                              font = cxf_char_read(stream, str);
                              fclose(stream);
                              return font;
                        }
                  }
                  /* 4バイト文字 */
                  else if (bite == 4) {
                        if (moji[0] == str[1] && moji[1] == str[2] && moji[2] == str[3] && moji[3] == str[4]) {
                              font = cxf_char_read(stream, str);
                              fclose(stream);
                              return font;
                        }
                  }
            }
      }
      fclose(stream);
      return NULL;
}



/* -------------------------------------------------------------------
 * 文字のデータを探す
 *    
 * char *moji                        : 探す文字
 * struct sag_font *FontData : 見つけたデータを入れる構造体
 *    
 *    
 */
SAG_FONT *font_search(char *moji, char *font_file2)
{
//#define FONT_SEARCH
#ifdef FONT_SEARCH
      char ret[256];
#endif

      SAG_FONT_LIST *p_list;
      SAG_FONT *p_font;
      int bite = 0;


      bite = utf8_bite_num(moji[0] & 0xff);

//g_print ("search moji = %c (%hhx) bite = %d\n", moji[0], moji[0], bite);

      p_list = font_list_info.head;
      while (p_list != NULL) {
            if (bite == 1) {
                  if ((p_list->font->moji[0] & 0xff) == (moji[0] & 0xff)) {
                        //g_print ("[%s] はメモリにあった[%s]\n", moji, p_list->font->moji);
                        return p_list->font;
                  }
            }
            else if (bite == 2) {
                  if ((p_list->font->moji[0] & 0xff) == (moji[0] & 0xff) && 
                              (p_list->font->moji[1] & 0xff) == (moji[1] & 0xff)) {
                        //g_print ("charset = [%d]   [%s : %x%x] はメモリにあった[%s : %x%x]\n", 
                        return p_list->font;
                  }
            }
            else if (bite == 3) {
                  if ((p_list->font->moji[0] & 0xff) == (moji[0] & 0xff) && 
                              (p_list->font->moji[1] & 0xff) == (moji[1] & 0xff) && 
                              (p_list->font->moji[2] & 0xff) == (moji[2] & 0xff)) {
                        //g_print ("charset = [%d]   [%s : %x%x] はメモリにあった[%s : %x%x]\n", 
                        return p_list->font;
                  }
            }
            else if (bite == 4) {
                  if ((p_list->font->moji[0] & 0xff) == (moji[0] & 0xff) && 
                              (p_list->font->moji[1] & 0xff) == (moji[1] & 0xff) && 
                              (p_list->font->moji[2] & 0xff) == (moji[2] & 0xff) && 
                              (p_list->font->moji[3] & 0xff) == (moji[3] & 0xff)) {
                        //g_print ("charset = [%d]   [%s : %x%x] はメモリにあった[%s : %x%x]\n", 
                        return p_list->font;
                  }
            }

            else {
//                g_print ("charset = [%d]   [%s : %x%x] はメモリにない[%s : %x%x]\n", 
//                                  charset, moji, moji[0], moji[1], p_list->font->moji, p_list->font->moji[0], p_list->font->moji[1]);
            }
            p_list = p_list->next;
      }

//    g_print ("charset = [%d]   [%s : %x%x] はメモリにない\n", 
//                      charset, moji, (moji[0] & 0xff), (moji[1] & 0xff));



      /* -----------------------------------------------------
       * 次に、フォントファイル2から必要なベクトルフォントをひとつ探し
       * メモリに読みこみ、ポインタの構造体に入れて返す。
       */
      p_font = font_search_open(moji, font_file2);
      if (p_font != NULL) {
            //g_print ("[%s] はメモリになかったが font_file2 にあった\n", moji);
            return p_font;
      }


      /* -----------------------------------------------------
       * それでも見つからなかったら "?" 
       */
      p_font = not_find_font(moji);
      if (p_font != NULL) {
            //g_print ("[%s] はなかったから「?」\n", moji);
            return p_font;
      }
      //g_print ("[%s] はなかったから「NULL」\n", moji);
      return NULL;
}





/* -------------------------------------------------------------------
 * moji を?として表示するように登録
 * 
 * 毎回ファイルから探していたら表示が遅いので、
 * メモリに登録する。表示は?
 * 
 */
SAG_FONT *not_find_font(char *moji)
{
      int i;
      SAG_FONT_LIST *font_list;
      SAG_FONT font;
      SAG_FONT_DATA *font_data;
      SAG_FONT_DATA data[15] = {
            {1,2.4,1.2,3,0.6,0,0,0},
            {1,3,0.6,2.4,0,0,0,0},
            {1,2.4,0,1.8,0.6,0,0,0},
            {1,1.8,0.6,2.4,1.2,0,0,0},
            {1,2.4,2.4,2.4,4.2,0,0,0},
            {1,2.4,4.2,3,4.8,0,0,0},
            {1,3,4.8,4.2,5.4,0,0,0},
            {1,4.2,5.4,4.8,6,0,0,0},
            {1,4.8,6,4.8,7.8,0,0,0},
            {1,4.8,7.8,4.2,8.4,0,0,0},
            {1,4.2,8.4,3,9,0,0,0},
            {1,3,9,1.8,9,0,0,0},
            {1,1.8,9,0.6,8.4,0,0,0},
            {1,0.6,8.4,0,7.8,0,0,0},
            {1,0,7.8,0,6.6,0,0,0}
      };
      int bite = 0;


      /* SJIS も euc も UTF-8 もスペースは 0x20 */
      if (moji[0] == ' ') {
            font.moji[0] = ' ';
            font.moji[1] = '\0';
            font.width = 0.6;
            font.height = 9;
            font.index = 0;
            font_data = NULL;
            /* SAG_FONT Data をリストの最後に追加 */
            font_list = font_list_add_last(&font);
            return font_list->font;
      }

      bite = utf8_bite_num(moji[0]);
      if (bite == 1) {
            font.moji[0] = moji[0];
            font.moji[1] = '\0';
      }
      else if (bite == 2) {
            font.moji[0] = moji[0];
            font.moji[1] = moji[1];
            font.moji[2] = '\0';
      }
      else if (bite == 3) {
            font.moji[0] = moji[0];
            font.moji[1] = moji[1];
            font.moji[2] = moji[2];
            font.moji[3] = '\0';
      }
      else if (bite == 4) {
            font.moji[0] = moji[0];
            font.moji[1] = moji[1];
            font.moji[2] = moji[2];
            font.moji[3] = moji[3];
            font.moji[4] = '\0';
      }

      font.width = 4.8;
      font.height = 9;
      font.index = 15;
      font_data = (SAG_FONT_DATA *)xmalloc(font.index * sizeof(SAG_FONT_DATA));
      font.font_data = font_data;
      for (i = 0 ; i < font.index ; i++) {
            font_data[i].code = data[i].code;
            font_data[i].sx   = data[i].sx;
            font_data[i].sy   = data[i].sy;
            font_data[i].ex   = data[i].ex;
            font_data[i].ey   = data[i].ey;
            font_data[i].cx   = data[i].cx;
            font_data[i].cy   = data[i].cy;
            font_data[i].r      = data[i].r;
      }
      /* SAG_FONT Data をリストの最後に追加 */
      font_list = font_list_add_last(&font);
      //font_list_print();

      return font_list->font;
}





/* -------------------------------------------------------------------
 * 文字コードの種別を判定する
 *    
 * 関数値 
 * 漢字の種別を表す値
 * ・引数strの先頭文字が半角カナの場合、関数値は1
 * ・引数strの先頭2文字がシフトJISコードの場合、関数値は2
 * ・引数strの先頭2文字がEUC半角カナコードの場合、関数値は4
 * ・引数strの先頭2文字がEUC全角コードの場合、関数値は8
 * ・引数strの先頭3文字が新JIS(X0208-1983)シフトコードの場合、
 *  関数値は16
 * ・引数strの先頭3文字が旧JIS(X0208-1978)シフトコードの場合、
 *  関数値は32
 * ・引数strの先頭3文字がJISローマ字(X0201)シフトコードの場合、
 *  関数値は64
 * ・引数strの先頭3文字がASCII シフトコードの場合、関数値は128
 * ・上のケースが複数個同時に起きる場合は、関数値はそれらの論理和
 * ・上のいずれでもない場合は、関数値は0
 *    
 *    
 * 注意事項 
 *    
 * 用例(whatKanji-test.c)
 * whatKanji("漢字");
 *    
 *    
 * 説明 
 *     半角カナコードは 0xa0 - 0xdf の間を使う。
 *     シフトJISコードは第1バイトとして 0x81 - 0x9f までと 0xe0 - 0xfc まで、第2バイトと
 * して 0x40 - 0xfc まで(0x7fを除く)を使う。このため、シフトJISは上記の半角コード
 * と混在できる。しかし、制御文字として使われる \(バックスラッシュまたは円記号)な
 * どが第2バイトの領域に入っているために問題が生じることがある。
 *     EUCコードは第1、第2バイトとも 0xa1 - 0xfe までであるが、半角のカナ文字については、
 * 0x8e を半角カナ文字の前につけ、2バイトで表現する。
 *     一方、JISコードは7ビット系漢字コードであるため、つぎのようなシフトコードを使って、
 * 文字セットの切り替えを行い、かな漢字を表現する。
 *    
 *    シフトコード一覧
 * 文字セット  シフトコード  
 * 新JIS X0208-1983  ESC $ B  
 * 旧JIS X0208-1978  ESC $ @  
 * JISローマ字 X0201  ESC ( J   
 * ASCII  ESC ( B 
 *    
 */
int whatKanji_sjis(/* unsigned */ char *str)
{
//0x81~0x9F   0xE0~0xEF 
      int val = 0;
      unsigned char b1, b2, b3;

      b1 = (unsigned char) *str++;
      b2 = (unsigned char) *str++;
      b3 = (unsigned char) *str;

      if ((b1 >= 0x81 && b1 <= 0x9f) || (b1 >= 0xe0 && b1 <= 0xef)) {
            val = 2;
//          return 2;
      }

      return val;
}



int whatKanji_euc(/*unsigned */ char *str)
{
      int val = 0;
      unsigned char b1, b2, b3;

      b1 = (unsigned char) *str++;
      b2 = (unsigned char) *str++;
      b3 = (unsigned char) *str;

      if (b1 == 0x8e && (b2 >= 0xa0 && b2 <= 0xdf)) val = 8/*4*/; 
      if (b1 >= 0xa1 && b1 <= 0xfe) val = 8;

      return val;


#ifdef TEST
EUC 漢字コード 

UNIX で漢字を表現するために用いられた方式。漢字 IN/OUT を 使わずに制御文字、
ASCII コード文字と混在できるが、SHIFT-JIS 方式と 同じく 8ビット幅でないと表現でき
ない、文字化けの危険性があるなどの 欠点がある。表示アルゴリズムは SHIFT-JIS と似
ており、次のように なっている。 

1バイト目が 0x00 ~ 0x7F だったら、それを single-byte 文字として そのまま表示する。 
1バイト目が 0x8E だったら、そのあとに続く文字を半角カナとして 表示する (このとき
の 2バイト目は SHIFT-JIS における半角カナ文字を 表すコードと同じものが使われる)。
 1バイト目が 0xA1 ~ 0xFE だったら、それは漢字の 1バイト目とみなし、 次の 1バイト
と合わせて漢字を表示する。 

      int val = 0;
      unsigned char b1, b2, b3;

      b1 = (unsigned char) *str++;
      b2 = (unsigned char) *str++;
      b3 = (unsigned char) *str;
      if (b1 == 0x8e && (b2 >= 0xa0 && b2 <= 0xdf)) {
            val |= 4;
//          return 2;
      }
      if ((b1 >= 0xa1 && b1 <= 0xfe) && (b2 >= 0xa1 && b1 <= 0xfe)) {
            val |= 8;
//          return 2;
      }

      return val;
#endif
}




/* ====================================================================
 * ===        Copyright (C) 2001 Yutaka Sagiya. All rights reserved.    ===
 * ====================================================================
 *      Project                  : SagCAD
 *      Source                   : font.c
 * ====================================================================
 */



void font_list_print(void)
{
      SAG_FONT_LIST *p;
      int i, j;
      char str[256];


      p = font_list_info.head;
      if (p == NULL) {
            OneShotLog("font Data は、ありません。\n");
            return;
      }

      i = 0;
      while(p != NULL) {
            i++;
            sprintf(str, "#%d : \"%s\"\n", i, p->font->moji);
            OneShotLog(str);

//#ifdef TEST
            sprintf(str, "[%s] %d\n", p->font->moji, p->font->index);
            OneShotLog(str);

            for (j = 0; j < p->font->index; j++) {
                  if (p->font->font_data[j].code == 1) {
                        sprintf(str, "L %f,%f,%f,%f\n", 
                                                p->font->font_data[j].sx, 
                                                p->font->font_data[j].sy, 
                                                p->font->font_data[j].ex, 
                                                p->font->font_data[j].ey);
                        OneShotLog(str);
                  }
                  else if (p->font->font_data[j].code == 2) {
                        sprintf(str, "A %f,%f,%f,%f\n", 
                                                p->font->font_data[j].cx, 
                                                p->font->font_data[j].cy, 
                                                p->font->font_data[j].r, 
                                                p->font->font_data[j].sx);
                        OneShotLog(str);
                  }
            }
//#endif
            p = p->next;
      }
      return;
}



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

Generated by  Doxygen 1.6.0   Back to index