home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / g / gs241j11.zip / ZKFSNF.C < prev    next >
C/C++ Source or Header  |  1992-06-22  |  13KB  |  574 lines

  1. /*
  2.  * zkfsnf.c --- Kanji font operator for X11R4 SNF format font file
  3.  *
  4.  * Copyright (C) 1991 Norio Katayama.
  5.  * Aug. 28, 1991 Programmed by N.Katayama (katayama@nacsis.ac.jp)
  6.  */
  7.  
  8. #include "memory_.h"
  9. #include "ghost.h"
  10. #include "oper.h"
  11. #include "errors.h"
  12. #include "gsmatrix.h"
  13. #include "state.h"
  14. #include "store.h"
  15.  
  16. #define B_X_CL    500    /* horizontal center in BuildChar */
  17. #define B_Y_CL    400    /* vertical center in BuildChar */
  18.  
  19. /* X11 headers */
  20. #undef min    /* min and max are defined in X11/misc.h */
  21. #undef max
  22.  
  23. #ifdef BSD4_2    /* circumvent the conflict between Xfuncs.h and memory_.h */
  24. #define bcopy _bcopy
  25. #define bzero _bzero
  26. #include <X11/Xfuncs.h>
  27. #undef bcopy
  28. #undef bzero
  29. #endif
  30.  
  31. #include <X11/X.h>
  32. #include <X11/Xproto.h>
  33. #include "fontstruct.h"
  34. #include "bdftosnf.h"
  35. #include "snfstruct.h"
  36.  
  37. /* DEFINITIONS BELOW ARE MACHINE DEPENDENT */
  38.  
  39. #ifdef sony
  40. #    define bitOrder        MSBFirst
  41. #    define byteOrder    MSBFirst
  42. #    define scanUnit        1
  43. #    ifdef bsd43
  44. #        define glyphPad    2
  45. #    else
  46. #        define glyphPad    1
  47. #    endif
  48. #else
  49. #    define bitOrder        DEFAULTBITORDER
  50. #    define byteOrder    DEFAULTBYTEORDER
  51. #    define scanUnit        DEFAULTSCANUNIT
  52. #    define glyphPad        DEFAULTGLPAD
  53. #endif
  54.  
  55. /* Imported procedures */
  56.  
  57. extern int kf_is_vchar(P1(int));
  58. extern int kf_vmatrix(P5(int, floatp, floatp, gs_rect *, gs_matrix *));
  59. extern int gs_imagebbox(P6(int width, int height, int bool, 
  60.                gs_matrix *pmat, byte *image, gs_rect *));
  61.  
  62. /* Forward declaration */
  63.  
  64. private int snfimage(P9(char *, int, int *, int *, byte *, int,
  65.             gs_matrix *, floatp *, floatp *));
  66.  
  67. /*
  68.  * zkfsnf
  69.  */
  70.  
  71. int
  72. zkfsnf(register os_ptr op)
  73. {
  74.     char *buffer;
  75.     int code, len, width, height, length;
  76.     int jis_code, wmode;
  77.     byte *bitmap;
  78.     floatp w0x, w0y;
  79.     gs_matrix *pmat, vmat, imat;
  80.     gs_rect bbox;
  81.  
  82.     check_type(op[-4], t_integer);        /* JIS Code */
  83.     check_type(op[-3], t_integer);        /* WMode */
  84.     if((code = write_matrix(op - 2)) < 0)    /* ImageMatrix */
  85.         return code;
  86.     check_type(op[-1], t_string);        /* ImageString */
  87.     check_type(op[0], t_string);        /* FileName */
  88.  
  89.     len = r_size(op);
  90.     if((buffer = gs_malloc(len + 1, 1, "zkfsnf")) == 0)
  91.         return e_VMerror;
  92.     memcpy(buffer, (char *)op->value.bytes, len);
  93.     buffer[len] = 0;
  94.  
  95.     jis_code = op[-4].value.intval;
  96.     wmode = op[-3].value.intval;
  97.  
  98.     bitmap = op[-1].value.bytes;
  99.     length = r_size(op - 1);
  100.     pmat = (gs_matrix *)op[-2].value.refs;
  101.  
  102.     if((code = snfimage(buffer, jis_code,
  103.                 &width, &height, bitmap, length, 
  104.                 pmat, &w0x, &w0y)) < 0)
  105.         return code;
  106.  
  107.     if((code = gs_imagebbox(width, height, 1, pmat, bitmap, &bbox)) < 0)
  108.         return code;
  109.  
  110.     if(wmode && kf_is_vchar(jis_code)) {
  111.         kf_vmatrix(jis_code, 
  112.                (floatp)B_X_CL, (floatp)B_Y_CL, &bbox, &vmat);
  113.         gs_matrix_invert(&vmat, &imat);
  114.         gs_matrix_multiply(&imat, pmat, pmat);
  115.     }
  116.  
  117.     /* Push results */
  118.     /* w0x w0y llx lly urx ury width height bool matrix bitmap */
  119.     push(6);
  120.     make_real(op - 10, w0x);
  121.     make_real(op - 9, w0y);
  122.     make_real(op - 8, bbox.p.x);
  123.     make_real(op - 7, bbox.p.y);
  124.     make_real(op - 6, bbox.q.x);
  125.     make_real(op - 5, bbox.q.y);
  126.     make_int(op - 4, width);
  127.     make_int(op - 3, height);
  128.     make_bool(op - 2 , 1);
  129.     make_tasv(op - 1, t_array, a_all, 6, refs, (ref *)pmat);
  130.     make_tasv(op, t_string, a_all, length, bytes, bitmap);
  131.     gs_free(buffer, len + 1, 1, "zkfsnf");
  132.     return 0;
  133. }
  134.  
  135. /* -------- Initialization procedure -------- */
  136.  
  137. op_def zkfsnf_op_defs[] = {
  138.     {"5kfsnf", zkfsnf},
  139.     op_def_end(0)
  140. };
  141.  
  142. /*---------- The part below is copied from input.c and modified. ---------*/
  143. /*-------- input.c is included in snftobdf written by Mark Leisher. ------*/
  144.  
  145. /*
  146.  * Copyright (C) 1990 Mark Leisher.
  147.  *
  148.  * Author: Mark Leisher (mleisher@nmsu.edu)
  149.  *
  150.  * This program is free software; you can redistribute it and/or modify
  151.  * it under the terms of the GNU General Public License as published by
  152.  * the Free Software Foundation; either version 1, or (at your option)
  153.  * any later version.
  154.  *
  155.  * This program is distributed in the hope that it will be useful,
  156.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  157.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  158.  * GNU General Public License for more details.
  159.  *
  160.  * A copy of the GNU General Public License can be obtained from this
  161.  * program's author (send electronic mail to mleisher@nmsu.edu) or from
  162.  * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
  163.  * 02139, USA.
  164.  *
  165.  */
  166.  
  167. #define ReallyNonExistent(pci) \
  168.   ((((pci).metrics.leftSideBearing + (pci).metrics.rightSideBearing) == 0) && \
  169.    (((pci).metrics.ascent + (pci).metrics.descent) == 0))
  170.  
  171. private void
  172. invertbits(unsigned char *buf, int count)
  173. {
  174.     int i, n, m;
  175.     unsigned char c, oc;
  176.  
  177.     for ( i = 0; i < count; i++ ) {
  178.         c = buf[i];
  179.         oc = 0;
  180.         for (n=0, m=7; n < 8; n++, m--) {
  181.             oc |= ((c >> n) & 1) << m;
  182.         }
  183.         buf[i] = oc;
  184.     }
  185. }
  186.  
  187. private void
  188. invert2(unsigned char *buf, int count)
  189. {
  190.     int i;
  191.     unsigned char c;
  192.  
  193.     for ( i = 0; i < count; i += 2) {
  194.         c = buf[i];
  195.         buf[i] = buf[i+1];
  196.         buf[i+1] = c;
  197.     }
  198. }
  199.  
  200. private void
  201. invert4(unsigned char *buf, int count)
  202. {
  203.     int i;
  204.     unsigned char c;
  205.  
  206.     for (i = 0; i < count; i += 4) {
  207.         c = buf[i];
  208.         buf[i] = buf[i+3];
  209.         buf[i+3] = c;
  210.         c = buf[i+1];
  211.         buf[i+1] = buf[i+2];
  212.         buf[i+2] = c;
  213.     }
  214. }
  215.  
  216. private int
  217. GetSNFInfo(char *file, TempFont **ptf)
  218. {
  219.     int fd, i, size;
  220.     char *strings;
  221.     long offset;
  222.     TempFont *tf;
  223.  
  224.     if((fd = open(file, 0)) < 0)
  225.         return e_undefinedfilename;
  226.  
  227.     if((tf = (TempFont *)malloc(sizeof(TempFont))) == 0) {
  228.         close(fd);
  229.         return e_VMerror;
  230.     }
  231.  
  232.     offset = 0;
  233.  
  234.     /* FontInfo */
  235.      
  236.     size = BYTESOFFONTINFO(tf->pFI);
  237.     if((tf->pFI = (FontInfoPtr)malloc(size)) == 0) {
  238.         close(fd);
  239.         return e_VMerror;
  240.     }
  241.  
  242.     if(read(fd, tf->pFI, size) != size) {
  243.         close(fd);
  244.         return e_ioerror;
  245.     }
  246.  
  247.     if (tf->pFI->version1 != FONT_FILE_VERSION ||
  248.         tf->pFI->version2 != FONT_FILE_VERSION)
  249.         fprintf(stderr, "Warning: %s is old style BDF\n", file);
  250.  
  251.     if(lseek(fd, offset += size, 0) < 0) {
  252.         close(fd);
  253.         return e_ioerror;
  254.     }
  255.  
  256.     /* CharInfo */
  257.  
  258.     size = BYTESOFCHARINFO(tf->pFI);
  259.     if((tf->pCI = (CharInfoPtr)malloc(size)) == 0) {
  260.         close(fd);
  261.         return e_VMerror;
  262.     }
  263.  
  264.     if(read(fd, tf->pCI, size) != size) {
  265.         close(fd);
  266.         return e_ioerror;
  267.     }
  268.  
  269.     if(lseek(fd, offset += size, 0) < 0) {
  270.         close(fd);
  271.         return e_ioerror;
  272.     }
  273.  
  274.     /* Glyphs */
  275.  
  276.     tf->pGlyphs = (unsigned char *)offset;
  277.     if(lseek(fd, offset += BYTESOFGLYPHINFO(tf->pFI), 0) < 0) {
  278.         close(fd);
  279.         return e_ioerror;
  280.     }
  281.  
  282.     /* FontProp */
  283.  
  284.     size = BYTESOFPROPINFO(tf->pFI);
  285.     if((tf->pFP = (FontPropPtr)malloc(size)) == 0) {
  286.         close(fd);
  287.         return e_VMerror;
  288.     }
  289.  
  290.     if(read(fd, tf->pFP, size) != size) {
  291.         close(fd);
  292.         return e_ioerror;
  293.     }
  294.  
  295.     if(lseek(fd, offset += size, 0) < 0) {
  296.         close(fd);
  297.         return e_ioerror;
  298.     }
  299.  
  300.     /* strings */
  301.  
  302.     size = BYTESOFSTRINGINFO(tf->pFI);
  303.     if((strings = (char *)malloc(size)) == 0) {
  304.         close(fd);
  305.         return e_VMerror;
  306.     }
  307.  
  308.     if(read(fd, strings, size) != size) {
  309.         close(fd);
  310.         return e_ioerror;
  311.     }
  312.         
  313.     if(lseek(fd, offset += size, 0) < 0) {
  314.         close(fd);
  315.         return e_ioerror;
  316.     }
  317.  
  318.     /* inkMetrics */
  319.  
  320.     if (tf->pFI->inkMetrics) {
  321.         if((tf->pInkMin = (CharInfoPtr)
  322.         malloc(3 * sizeof(CharInfoRec))) == 0) {
  323.             close(fd);
  324.             return e_VMerror;
  325.         }
  326.         
  327.         size = sizeof(CharInfoRec) * 3;
  328.         if(read(fd, tf->pInkMin, size) != size) {
  329.             close(fd);
  330.             return e_ioerror;
  331.         }
  332.         tf->pInkMax = tf->pInkMin + 1;
  333.         tf->pInkCI  = tf->pInkMax + 1;
  334.     }
  335.  
  336.     for (i = 0; i < tf->pFI->nProps; i++) {
  337.         tf->pFP[i].name += (int)strings;
  338.         if (tf->pFP[i].indirect)
  339.             tf->pFP[i].value += (int)strings;
  340.     }
  341.  
  342.     *ptf = tf;
  343.     return(fd);
  344. }
  345.  
  346. private int
  347. code2num(TempFont *tf, int code)
  348. {
  349.     int row, col, ncols;
  350.     FontInfoPtr pFI = tf->pFI;
  351.  
  352.     if((row = (code >> 8)) < pFI->firstRow ||
  353.        row > pFI->lastRow)
  354.         return -1;
  355.     if((col = (code & 0x00ff)) < pFI->firstCol ||
  356.        col > pFI->lastCol)
  357.         return -1;
  358.     ncols = pFI->lastCol - pFI->firstCol + 1;
  359.     return (row - pFI->firstRow) * ncols + col - pFI->firstCol;
  360. }
  361.  
  362. private int
  363. GetSNFBitmap(int fd, TempFont *tf, unsigned int char_code, 
  364.          int *width, int *height, byte *bmap, int length,
  365.          int *pixel_size, int *font_ascent, int *font_descent,
  366.          int *wx, int *wy, int *llx, int *lly, int *urx, int *ury)
  367. {
  368.     CharInfoPtr pCI = tf->pCI;
  369.     int charnum;
  370.     int ht, wd, gbp, wid, bytes, glyphbytes;
  371.     int i, j = 0, count = 0;
  372.     unsigned char *bitmap, *ptr;
  373.  
  374.     if((charnum = code2num(tf, char_code)) < 0) {
  375.         if((charnum = code2num(tf, tf->pFI->chDefault)) < 0)
  376.             return e_rangecheck;
  377.     }
  378.     else {
  379.         if (!pCI[charnum].exists || ReallyNonExistent(pCI[charnum]))
  380.             if((charnum = code2num(tf, tf->pFI->chDefault)) < 0)
  381.                 return e_rangecheck;
  382.     }
  383.  
  384.     ht = pCI[charnum].metrics.descent + pCI[charnum].metrics.ascent;
  385.     wd = pCI[charnum].metrics.rightSideBearing - 
  386.            pCI[charnum].metrics.leftSideBearing;
  387.     gbp = GLWIDTHBYTESPADDED(wd, glyphPad);
  388.     wid = ((wd / 8) + ((wd % 8) ? 1 : 0));
  389.     bytes = ht * wid;
  390.     glyphbytes = gbp * ht;
  391.  
  392.     if(bytes > length)
  393.         return e_rangecheck;
  394.  
  395.     /* Read Glyph */
  396.     
  397.     if((bitmap = ptr = (unsigned char *)
  398.     gs_malloc(glyphbytes, 1, "GetSNFBitmap(bitmap)")) == 0)
  399.         return e_VMerror;
  400.  
  401.     if(lseek(fd, tf->pGlyphs + pCI[charnum].byteOffset, 0) < 0)
  402.         return e_ioerror;
  403.  
  404.     if(read(fd, bitmap, glyphbytes) != glyphbytes)
  405.         return e_ioerror;
  406.  
  407.     if (bitOrder == LSBFirst)
  408.         invertbits(ptr, glyphbytes);
  409.     if (bitOrder != byteOrder) {
  410.         if (scanUnit == 2)
  411.             invert2(ptr, glyphbytes);
  412.         else if (scanUnit == 4)
  413.             invert4(ptr, glyphbytes);
  414.     }
  415.         
  416.     for (i = 0; i < ht; i++) {
  417.         for (j = 0; j < wid; j++)
  418.           bmap[count++] = *ptr++;
  419.         ptr += (gbp - wid);
  420.     }
  421.  
  422.     gs_free((char *)bitmap, glyphbytes, 1, "GetSNFBitmap(bitmap)");
  423.  
  424.     /* Retrieve size */
  425.  
  426.     *pixel_size = tf->pFI->fontAscent + tf->pFI->fontDescent;
  427.     for(i = 0; i< tf->pFI->nProps; i++) {
  428.         if(strcmp((char *)tf->pFP[i].name, "PIXEL_SIZE") == 0)
  429.             *pixel_size = tf->pFP[i].value;
  430.     }
  431.     if(*pixel_size == 0)
  432.         return e_invalidfont;
  433.  
  434.     /* Set Metrics Information */
  435.  
  436.     *font_ascent = tf->pFI->fontAscent;
  437.     *font_descent = tf->pFI->fontDescent;
  438.     *width = wd;
  439.     *height = ht;
  440.     *wx = pCI[charnum].metrics.characterWidth;
  441.     *wy = 0;
  442.     *llx = pCI[charnum].metrics.leftSideBearing;
  443.     *lly = - pCI[charnum].metrics.descent;
  444.     *urx = pCI[charnum].metrics.rightSideBearing;
  445.     *ury = pCI[charnum].metrics.ascent;
  446.  
  447.     return 0;
  448. }
  449.  
  450. /*--------------------------- end of input.c --------------------------*/
  451.  
  452. /*
  453.  * Hash Index Routines
  454.  */
  455.  
  456. typedef struct index_item_s {
  457.     struct index_item_s *next;
  458.     char *str;
  459.     int fd;
  460.     TempFont *tf;
  461. } index_item;
  462. private index_item *hash_index[256];
  463.  
  464. /* Hash function */
  465. private int
  466. hash(unsigned char *str)
  467. {
  468.         unsigned char hash;
  469.         for(hash = 0; *str != 0; str++)
  470.                 hash ^= *str;
  471.         return hash;
  472. }
  473.  
  474. /* store */
  475. private int
  476. store(char *str, int fd, TempFont *tf)
  477. {
  478.     int key = hash((unsigned char *)str);
  479.     index_item *item;
  480.     if((item = (index_item *)malloc(sizeof(index_item))) == 0)
  481.         return e_VMerror;
  482.     if((item->str = (char *)malloc(strlen(str) + 1)) == 0)
  483.         return e_VMerror;
  484.     strcpy(item->str, str);
  485.     item->next = hash_index[key];
  486.     item->fd = fd;
  487.     item->tf = tf;
  488.     hash_index[key] = item;
  489.     return 0;
  490. }
  491.  
  492. /* search */
  493. private int
  494. search(char *str, int *fd, TempFont **tf)
  495. {
  496.     int key = hash((unsigned char *)str);
  497.     index_item *item;
  498.     item = hash_index[key];
  499.     while(item != 0) {
  500.         if(strcmp(item->str, str) == 0) {
  501.             *fd = item->fd;
  502.             *tf = item->tf;
  503.             return 1;
  504.         }
  505.         item = item->next;
  506.     }
  507.     return 0;
  508. }
  509.  
  510. /*
  511.  * Open SNF Font File
  512.  */
  513.  
  514. private int
  515. OpenSNFFont(char *file, TempFont **ptf)
  516. {
  517.     int fd, code;
  518.  
  519.     if(search(file, &fd, ptf)) 
  520.         return fd;
  521.     else {
  522.         if((fd = GetSNFInfo(file, ptf)) < 0)
  523.             return fd;
  524.         if((code = store(file, fd, *ptf)) < 0)
  525.             return code;
  526.         return fd;
  527.     }
  528. }
  529.  
  530. /*
  531.  * Retrieve Font Image
  532.  */
  533.  
  534. private int
  535. snfimage(char *file, int jis_code,
  536.      int *width, int *height, byte *bitmap, int length, 
  537.      gs_matrix *pmat, floatp *wx, floatp *wy)
  538. {
  539.     int code, fd, pixel_size;
  540.     int font_ascent, font_descent;
  541.     int w_x, w_y, ll_x, ll_y, ur_x, ur_y;
  542.     floatp dx, dy, scale;
  543.     gs_matrix smat, tmat;
  544.     TempFont *tf;
  545.  
  546.     if((fd = OpenSNFFont(file, &tf)) < 0)
  547.         return fd;
  548.  
  549.     if((code = GetSNFBitmap(fd, tf, jis_code, 
  550.                 width, height, bitmap, length, 
  551.                 &pixel_size, &font_ascent, &font_descent,
  552.                 &w_x, &w_y, &ll_x, &ll_y, &ur_x, &ur_y)) < 0)
  553.         return code;
  554.  
  555.     /* Transform Image */
  556.  
  557.     gs_make_identity(pmat);
  558.  
  559.     scale = (floatp)B_Y_CL * 2.0 / (floatp)font_ascent;
  560.     gs_make_scaling(1.0 / scale, -1.0 / scale, &smat);
  561.  
  562.     dx = (floatp)pixel_size / 2.0 - (floatp)B_X_CL / scale;
  563.     dy = (floatp)font_ascent;
  564.     gs_make_translation(dx, dy, &tmat);
  565.  
  566.     gs_matrix_multiply(pmat, &smat, pmat);
  567.     gs_matrix_multiply(pmat, &tmat, pmat);
  568.  
  569.     *wx = (floatp)B_X_CL * 2.0;
  570.     *wy = 0;
  571.  
  572.     return 0;
  573. }
  574.