home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / g / gs241j11.zip / ZKFSONY.C < prev    next >
C/C++ Source or Header  |  1992-05-26  |  9KB  |  450 lines

  1. /*
  2.  * zkfsony.c --- Kanji font operator for Sony format outline font
  3.  *
  4.  * Copyright (C) 1991 Norio Katayama.
  5.  * Aug.5, 1991 Programmed by N.Katayama (katayama@nacsis.ac.jp)
  6.  */
  7.  
  8. #include <ctype.h>
  9. #include "math_.h"
  10. #include "memory_.h"
  11. #include "ghost.h"
  12. #include "oper.h"
  13. #include "errors.h"
  14. #include "gspath.h"
  15. #include "state.h"
  16. #include "FS.h"
  17.  
  18. #undef  DEBUG
  19.  
  20. #define D_X_CL    (D_SIZE / 2 + D_OFFSET)        /* horizontal center of data */
  21. #define D_Y_CL    (D_SIZE / 2 + D_OFFSET)        /* vertical center of data */
  22. #define    D_Y_BL    (D_SIZE * 0.9 + D_OFFSET)    /* base line of data */
  23.  
  24. #define B_X_CL    500    /* horizontal center in BuildChar */
  25. #define B_Y_CL    400    /* vertical center in BuildChar */
  26. #define B_Y_BL    0    /* base line in BuildChar */
  27.  
  28. /* Forward declaration */
  29.  
  30. private floatp map_x(P1(double));
  31. private floatp map_y(P1(double));
  32. private int hash(P1(unsigned char *));
  33. private int draw_font(P3(char *, int, int));
  34.  
  35. /*
  36.  * zkfsony
  37.  */
  38.  
  39. int
  40. zkfsony(register os_ptr op)
  41. {
  42.     char *buffer;
  43.     int code, len, jis_code, wmode;
  44.  
  45.     check_type(op[-2], t_integer);        /* JIS Code */
  46.     check_type(op[-1], t_integer);        /* WMode */
  47.     check_type(op[0], t_string);        /* File Name */    
  48.  
  49.     len = r_size(op);
  50.     if((buffer = gs_malloc(len + 1, 1, "zkfsony")) == 0)
  51.         return e_VMerror;
  52.     memcpy(buffer, (char *)op->value.bytes, len);
  53.     buffer[len] = 0;
  54.  
  55.     jis_code = op[-2].value.intval;
  56.     wmode = op[-1].value.intval;
  57.  
  58.     if((code = draw_font(buffer, jis_code, wmode)) != 0)
  59.         return code;
  60.  
  61.     pop(3);
  62.     gs_free(buffer, len + 1, 1, "zkfsony");
  63.     return 0;
  64. }
  65.  
  66. /* -------- Initialization procedure -------- */
  67.  
  68. op_def zkfsony_op_defs[] = {
  69.     {"3kfsony", zkfsony},
  70.     op_def_end(0)
  71. };
  72.  
  73. /* -------- Internal routines -------- */
  74.  
  75. /*
  76.  * Mapping to coordinates in BuildChar
  77.  */
  78.  
  79. private floatp
  80. map_x(double x)
  81. {
  82.     static double factor = 
  83.         (double)(B_Y_CL - B_Y_BL) / (double)(D_Y_CL - D_Y_BL);
  84.  
  85.     return B_X_CL + (x - D_X_CL) * (factor > 0 ? factor : - factor);
  86. }
  87.  
  88. private floatp
  89. map_y(double y)
  90. {
  91.     static double factor = 
  92.         (double)(B_Y_CL - B_Y_BL) / (double)(D_Y_CL - D_Y_BL);
  93.  
  94.     return B_Y_CL + (y - D_Y_CL) * factor;
  95. }
  96.  
  97. /*
  98.  * Convert JIS code into serial code
  99.  */
  100.  
  101. private unsigned int 
  102. vchars[] = {
  103.         0x2122, 0x2123, 0x2131, 0x2132, 0x213c, 0x213d, 0x213e, 0x2141,
  104.         0x2142, 0x2143, 0x2144, 0x2145, 0x214a, 0x214b, 0x214c, 0x214d,
  105.         0x214e, 0x214f, 0x2150, 0x2151, 0x2152, 0x2153, 0x2154, 0x2155,
  106.         0x2156, 0x2157, 0x2158, 0x2159, 0x215a, 0x215b, 0x222e, 0x2421,
  107.         0x2423, 0x2425, 0x2427, 0x2429, 0x2443, 0x2463, 0x2465, 0x2467,
  108.         0x246e,
  109.                                                                 0x2521,
  110.         0x2523, 0x2525, 0x2527, 0x2529, 0x2543, 0x2563, 0x2565, 0x2567,
  111.         0x256e, 0x2575, 0x2576
  112. };
  113.  
  114. private int
  115. jtoc(int jis, int wmode)
  116. {
  117.     int i, num_vchars = sizeof(vchars)/sizeof(*vchars);
  118.     if(wmode == 1 && jis <= vchars[num_vchars-1]) {
  119. #ifdef DEBUG
  120.         fprintf(stderr, "WMode: %04X\n", jis);
  121. #endif
  122.         for(i=0; i<num_vchars; i++) {
  123.             if(jis == vchars[i]) {
  124.                 jis = i + 0x7521;
  125.                 break;
  126.             }
  127.         }
  128.     }
  129.     return (( jis >> 8) - 0x21) * 94 + (jis & 0xff) - 0x21;
  130. }
  131.  
  132. /*
  133.  * Hash Index
  134.  */
  135.  
  136. typedef struct index_item_s {
  137.     struct index_item_s *next;
  138.     char *str;
  139.     int fd;
  140. } index_item;
  141. private index_item *hash_index[256];
  142.  
  143. /* store */
  144.  
  145. private int
  146. store(char *str, int fd)
  147. {
  148.     int key = hash((unsigned char *)str);
  149.     index_item *item;
  150.     if((item = (index_item *)malloc(sizeof(index_item))) == 0)
  151.         return e_VMerror;
  152.     if((item->str = (char *)malloc(strlen(str) + 1)) == 0)
  153.         return e_VMerror;
  154.     strcpy(item->str, str);
  155.     item->next = hash_index[key];
  156.     item->fd = fd;
  157.     hash_index[key] = item;
  158.     return 0;
  159. }
  160.  
  161. /* search */
  162.  
  163. private int
  164. search(char *str, int *fd)
  165. {
  166.     int key = hash((unsigned char *)str);
  167.     index_item *item;
  168.     item = hash_index[key];
  169.     while(item != 0) {
  170.         if(strcmp(item->str, str) == 0) {
  171.             *fd = item->fd;
  172.             return 1;
  173.         }
  174.         item = item->next;
  175.     }
  176.     return 0;
  177. }
  178.  
  179. /*
  180.  * Hash function
  181.  */
  182.  
  183. private int 
  184. hash(unsigned char *str)
  185. {
  186.     unsigned char hash;
  187.  
  188.     for(hash = 0; *str != 0; str++)
  189.         hash ^= *str;
  190.  
  191.     return hash;
  192. }
  193.         
  194. /*
  195.  * Open font 
  196.  */
  197.  
  198. private int 
  199. open_font(char *file)
  200.  
  201. {
  202.     int code, fd;
  203.  
  204.     if(search(file, &fd))
  205.         return fd;
  206.     else {
  207.         if((fd = FS_open_font(file)) < 0) {
  208.             fprintf(stderr, "FS_open_font: error code = %d\n", fd);
  209.             return fd;
  210.         }
  211.         if((code = store(file, fd)) < 0)
  212.             return code;
  213.         return fd;
  214.     }
  215. }
  216.  
  217. /*
  218.  * moveto
  219.  */
  220.  
  221. #define moveto(x, y)    gs_moveto(igs, map_x(x), map_y(y))
  222.  
  223. /*
  224.  * lineto
  225.  */
  226.  
  227. #define lineto(x, y)    gs_lineto(igs, map_x(x), map_y(y))
  228.  
  229. /*
  230.  * atan360
  231.  */
  232.  
  233. private double
  234. atan360(double y, double x)
  235. {
  236.     double ang;
  237.     static double factor = -1.0;
  238.  
  239. #ifdef M_PI
  240.     if(factor < 0.0)
  241.         factor = 180.0 / M_PI;
  242. #else
  243.         factor = 45.0 / atan(1.0);
  244. #endif
  245.  
  246.     if((ang = atan2(y, x) * factor) < 0)
  247.         ang += 360.0;
  248.     return ang;
  249. }
  250.  
  251. /*
  252.  * darc3
  253.  */
  254.  
  255. private int
  256. darc3(floatp x1, floatp y1, floatp x2, floatp y2, floatp x3, floatp y3)
  257. {
  258.     int code;
  259.     floatp dx1, dy1, dx3, dy3, cx, cy, z, r, ang1, ang2, ang3, ang;
  260.  
  261.     x1 = map_x(x1);        y1 = map_y(y1);
  262.     x2 = map_x(x2);        y2 = map_y(y2);
  263.     x3 = map_x(x3);        y3 = map_y(y3);
  264.  
  265.     dx1 = x1 - x2;        dy1 = y1 - y2;
  266.     dx3 = x3 - x2;        dy3 = y3 - y2;
  267.  
  268.     if((z = dx1*dy3 - dx3*dy1) == 0) {
  269.         if((dx1 == dx3) && (dy1 == dy3)) {
  270.             cx = dx1 / 2.0;
  271.             cy = dy1 / 2.0;
  272.             r = sqrt(cx*cx + cy*cy);
  273.             ang = atan360(dy1 - cy, dx1 - cx);
  274.             return gs_arc(igs, cx + x2, cy + y2, r, ang, ang+360);
  275.         }
  276.         else {
  277.             if((code = gs_lineto(igs, x1, y1)) < 0)
  278.                 return code;
  279.             return gs_lineto(igs, x3, y3);
  280.         }
  281.     }
  282.  
  283.     cx = ((dx1*dx1 + dy1*dy1)*dy3 - (dx3*dx3 + dy3*dy3)*dy1) / z / 2.0;
  284.     cy = - ((dx1*dx1 + dy1*dy1)*dx3 - (dx3*dx3 + dy3*dy3)*dx1) / z / 2.0;
  285.     r = sqrt(cx*cx + cy*cy);
  286.  
  287.     ang1 = atan360(dy1 - cy, dx1 - cx);
  288.     ang2 = atan360(-cy, -cx);
  289.     ang3 = atan360(dy3 - cy, dx3 - cx);
  290.  
  291.     if(ang1 == ang3)
  292.         return gs_arc(igs, cx + x2, cy + y2, r, 0.0, 360.0);
  293.     else if(ang1 < ang3) {
  294.         if(ang1 <= ang2 && ang2 <= ang3)
  295.             return gs_arc(igs, cx + x2, cy + y2, r, ang1, ang3);
  296.         else
  297.             return gs_arcn(igs, cx + x2, cy + y2, r, ang1, ang3);
  298.     }
  299.     else {
  300.         if(ang3 <= ang2 && ang2 <= ang1)
  301.             return gs_arcn(igs, cx + x2, cy + y2, r, ang1, ang3);
  302.         else
  303.             return gs_arc(igs, cx + x2, cy + y2, r, ang1, ang3);
  304.     }
  305. }
  306.  
  307. /*
  308.  * curveto
  309.  */
  310.  
  311. #define curveto(x1, y1, x2, y2, x3, y3)    \
  312.     gs_curveto(igs, map_x(x1), map_y(y1), \
  313.            map_x(x2), map_y(y2), map_x(x3), map_y(y3))
  314.  
  315. /*
  316.  * Draw Font
  317.  */
  318.  
  319. #define FS_XY(ptr, x, y)    \
  320.     if(is_bos(*ptr)) return e_undefinedresult; \
  321.     x = (*ptr >> X_SHIFT) & XY_MASK; \
  322.     y = *ptr & XY_MASK;
  323.  
  324. #define GMASK    (LINE | ARC | BEZIER)
  325.  
  326. private int 
  327. draw_font(char *font_name, int jis, int wmode)
  328. {
  329.     long *ptr, token, next_token;
  330.     int font_fd, code;
  331.     int x, y, x0, y0, x1, y1, x2, y2, x3, y3;
  332.  
  333.     if((font_fd = open_font(font_name)) <0)
  334.         return e_undefinedfilename;
  335.     
  336.     if((code = FS_get_outline(jtoc(jis, wmode), font_fd, &ptr)) < 0) {
  337.         switch(code) {
  338. #ifdef FS_GET_OUTLINE_ERR_5
  339.         case FS_GET_OUTLINE_ERR_5:
  340.             /* undefined font */
  341.             return 0;
  342. #endif
  343.         default:
  344.             fprintf(stderr, "FS_get_outline: error code = %d\n",
  345.                 code);
  346.             return e_ioerror;
  347.         }
  348.     }
  349.  
  350.     while(*ptr != 0) {
  351.  
  352.         /* The beginning of segment */
  353.  
  354.         if(!is_bos(*ptr))
  355.             return e_undefinedresult;
  356.         token = *ptr ++;
  357.  
  358.         FS_XY(ptr, x, y);
  359.         ptr ++;
  360.         x0 = x;
  361.         y0 = y;
  362.         moveto((floatp)x0, (floatp)y0);
  363.  
  364.         switch(token & GMASK) {
  365.         case LINE:
  366.             break;
  367.         case ARC:
  368.             x1 = x;
  369.             y1 = y;
  370.             FS_XY(ptr, x2, y2);
  371.             ptr ++;
  372.             break;
  373.         case BEZIER:
  374.             FS_XY(ptr, x2, y2);
  375.             ptr ++;
  376.             FS_XY(ptr, x3, y3);
  377.             ptr ++;
  378.             break;
  379.         default:
  380.             return e_undefinedresult;
  381.         }
  382.  
  383.         while(!is_bos(*ptr) && *ptr != 0) {
  384.             if(is_token(*ptr))
  385.                 next_token = *ptr++;
  386.             else
  387.                 next_token = token;
  388.             FS_XY(ptr, x, y);
  389.             ptr ++;
  390.  
  391.             switch(token & GMASK) {
  392.             case LINE:
  393.                 lineto((floatp)x, (floatp)y);
  394.                 break;
  395.             case ARC:
  396.                 darc3((floatp)x1, (floatp)y1, 
  397.                       (floatp)x2, (floatp)y2, 
  398.                       (floatp)x,  (floatp)y);
  399.                 break;
  400.             case BEZIER:
  401.                 curveto((floatp)x2, (floatp)y2,
  402.                     (floatp)x3, (floatp)y3,
  403.                     (floatp)x,  (floatp)y);
  404.                 break;
  405.             default:
  406.                 return e_undefinedresult;
  407.             }
  408.  
  409.             token = next_token;
  410.             switch(token & GMASK) {
  411.             case LINE:
  412.                 break;
  413.             case ARC:
  414.                 x1 = x;
  415.                 y1 = y;
  416.                 FS_XY(ptr, x2, y2);
  417.                 ptr ++;
  418.                 break;
  419.             case BEZIER:
  420.                 FS_XY(ptr, x2, y2);
  421.                 ptr ++;
  422.                 FS_XY(ptr, x3, y3);
  423.                 ptr ++;
  424.                 break;
  425.             default:
  426.                 return e_undefinedresult;
  427.             }
  428.         }
  429.  
  430.         switch(token & GMASK) {
  431.         case LINE:
  432.             lineto((floatp)x0, (floatp)y0);
  433.             break;
  434.         case ARC:
  435.             darc3((floatp)x1, (floatp)y1, 
  436.                   (floatp)x2, (floatp)y2,
  437.                   (floatp)x0, (floatp)y0);
  438.             break;
  439.         case BEZIER:
  440.             curveto((floatp)x2, (floatp)y2,
  441.                 (floatp)x3, (floatp)y3,
  442.                 (floatp)x0, (floatp)y0);
  443.             break;
  444.         default:
  445.             return e_undefinedresult;
  446.         }
  447.     }
  448.     return 0;
  449. }
  450.