home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / groff / libXdvi / font.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-30  |  6.2 KB  |  351 lines

  1. /*
  2.  * font.c
  3.  *
  4.  * map dvi fonts to X fonts
  5.  */
  6.  
  7. #include <X11/Xos.h>
  8. #include <X11/IntrinsicP.h>
  9. #include <X11/StringDefs.h>
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #include "DviP.h"
  13. #include "XFontName.h"
  14.  
  15. extern char    *malloc ();
  16.  
  17. static char *
  18. savestr (s)
  19.     char    *s;
  20. {
  21.     char    *n;
  22.  
  23.     if (!s)
  24.         return 0;
  25.     n = malloc (strlen (s) + 1);
  26.     if (n)
  27.         strcpy (n, s);
  28.     return n;
  29. }
  30.  
  31. static DviFontList *
  32. LookupFontByPosition (dw, position)
  33.     DviWidget    dw;
  34.     int        position;
  35. {
  36.     DviFontList    *f;
  37.  
  38.     for (f = dw->dvi.fonts; f; f=f->next)
  39.         if (f->dvi_number == position)
  40.             break;
  41.     return f;
  42. }
  43.  
  44. static DviFontSizeList *
  45. LookupFontSizeBySize (f, size)
  46.     DviFontList    *f;
  47.     int        size;
  48. {
  49.     DviFontSizeList    *fs, *best = 0;
  50.     int        bestsize = 0;
  51.  
  52.     for (fs = f->sizes; fs; fs=fs->next) {
  53.         if (fs->size <= size && fs->size >= bestsize) {
  54.             best = fs;
  55.             bestsize = fs->size;
  56.         }
  57.     }
  58.     return best;
  59. }
  60.  
  61. static char *
  62. SkipFontNameElement (n)
  63.     char    *n;
  64. {
  65.     while (*n != '-')
  66.         if (!*++n)
  67.             return 0;
  68.     return n+1;
  69. }
  70.  
  71. # define SizePosition        8
  72. # define EncodingPosition    13
  73.  
  74. static
  75. ConvertFontNameToSize (n)
  76.     char    *n;
  77. {
  78.     int    i, size;
  79.  
  80.     for (i = 0; i < SizePosition; i++) {
  81.         n = SkipFontNameElement (n);
  82.         if (!n)
  83.             return -1;
  84.     }
  85.     size = atoi (n);
  86.     return size/10;
  87. }
  88.  
  89. static char *
  90. ConvertFontNameToEncoding (n)
  91.     char    *n;
  92. {
  93.         int i;
  94.     for (i = 0; i < EncodingPosition; i++) {
  95.         n = SkipFontNameElement (n);
  96.         if (!n)
  97.             return 0;
  98.     }
  99.     return n;
  100. }
  101.  
  102. DviFontSizeList *
  103. InstallFontSizes (dw, x_name)
  104.     DviWidget    dw;
  105.     char        *x_name;
  106. {
  107.     char    fontNameString[2048];
  108.     char    **fonts;
  109.     int    i, count;
  110.     int    size;
  111.     DviFontSizeList    *sizes, *new;
  112.     XFontName    fontName;
  113.     unsigned int    fontNameAttributes;
  114.  
  115.     if (!XParseFontName (x_name, &fontName, &fontNameAttributes))
  116.         return;
  117.     fontNameAttributes &= ~(FontNamePixelSize|FontNamePointSize);
  118.     fontNameAttributes |= FontNameResolutionX;
  119.     fontNameAttributes |= FontNameResolutionY;
  120.     fontName.ResolutionX = dw->dvi.device_resolution;
  121.     fontName.ResolutionY = dw->dvi.device_resolution;
  122.     XFormatFontName (&fontName, fontNameAttributes, fontNameString);
  123.     fonts = XListFonts (XtDisplay (dw), fontNameString, 10000000, &count);
  124.     sizes = 0;
  125.     for (i = 0; i < count; i++) {
  126.         if ((size = ConvertFontNameToSize (fonts[i])) != -1) {
  127.             new = (DviFontSizeList *) malloc (sizeof *new);
  128.             new->next = sizes;
  129.             new->size = size;
  130.             new->x_name = savestr (fonts[i]);
  131.             new->doesnt_exist = 0;
  132.             new->font = 0;
  133.             sizes = new;
  134.         }
  135.     }
  136.     XFreeFontNames (fonts);
  137.     return sizes;
  138. }
  139.  
  140. static
  141. DisposeFontSizes (fs)
  142.     DviFontSizeList    *fs;
  143. {
  144.     DviFontSizeList    *next;
  145.  
  146.     for (; fs; fs=next) {
  147.         next = fs->next;
  148.         if (fs->x_name)
  149.             free (fs->x_name);
  150.         if (fs->font)
  151.             XFree ((char *)fs->font);
  152.         free ((char *) fs);
  153.     }
  154. }
  155.  
  156. static DviFontList *
  157. InstallFont (dw, position, dvi_name, x_name)
  158.     DviWidget    dw;
  159.     int        position;
  160.     char        *dvi_name;
  161.     char        *x_name;
  162. {
  163.     DviFontList    *f;
  164.     DviFontSizeList    *sizes;
  165.     char        *encoding;
  166.  
  167.     if (f = LookupFontByPosition (dw, position)) {
  168.         /*
  169.          * ignore gratuitous font loading
  170.          */
  171.         if (!strcmp (f->dvi_name, dvi_name) &&
  172.             !strcmp (f->x_name, x_name))
  173.             return;
  174.  
  175.         sizes = InstallFontSizes (dw, x_name);
  176.         if (!sizes)
  177.             return f;
  178.  
  179.         DisposeFontSizes (f->sizes);
  180.         if (f->dvi_name)
  181.             free (f->dvi_name);
  182.         if (f->x_name)
  183.             free (f->x_name);
  184.     } else {
  185.         sizes = InstallFontSizes (dw, x_name);
  186.         if (!sizes)
  187.             return 0;
  188.         f = (DviFontList *) malloc (sizeof (*f));
  189.         f->next = dw->dvi.fonts;
  190.         dw->dvi.fonts = f;
  191.     }
  192.     f->dvi_name = savestr (dvi_name);
  193.     f->x_name = savestr (x_name);
  194.     f->dvi_number = position;
  195.     f->sizes = sizes;
  196.     if (f->x_name) {
  197.         encoding = ConvertFontNameToEncoding (f->x_name);
  198.         f->char_map = DviFindMap (encoding);
  199.     } else
  200.         f->char_map = 0;
  201.     /* 
  202.      * force requery of fonts
  203.      */
  204.     dw->dvi.font = 0;
  205.     dw->dvi.font_number = -1;
  206.     dw->dvi.cache.font = 0;
  207.     dw->dvi.cache.font_number = -1;
  208.     return f;
  209. }
  210.  
  211. static char *
  212. MapDviNameToXName (dw, dvi_name)
  213.     DviWidget    dw;
  214.     char        *dvi_name;
  215. {
  216.     DviFontMap    *fm;
  217.     
  218.     for (fm = dw->dvi.font_map; fm; fm=fm->next)
  219.         if (!strcmp (fm->dvi_name, dvi_name))
  220.             return fm->x_name;
  221.     return 0;
  222. }
  223.  
  224. static char *
  225. MapXNameToDviName (dw, x_name)
  226.     DviWidget    dw;
  227.     char        *x_name;
  228. {
  229.     DviFontMap    *fm;
  230.     
  231.     for (fm = dw->dvi.font_map; fm; fm=fm->next)
  232.         if (!strcmp (fm->x_name, x_name))
  233.             return fm->dvi_name;
  234.     return 0;
  235. }
  236.  
  237. ParseFontMap (dw)
  238.     DviWidget    dw;
  239. {
  240.     char        dvi_name[1024];
  241.     char        x_name[2048];
  242.     char        *m, *s;
  243.     char        *encoding;
  244.     DviFontMap    *fm, *new;
  245.  
  246.     if (dw->dvi.font_map)
  247.         DestroyFontMap (dw->dvi.font_map);
  248.     fm = 0;
  249.     m = dw->dvi.font_map_string;
  250.     while (*m) {
  251.         s = m;
  252.         while (*m && !isspace (*m))
  253.             ++m;
  254.         strncpy (dvi_name, s, m-s);
  255.         dvi_name[m-s] = '\0';
  256.         while (isspace (*m))
  257.             ++m;
  258.         s = m;
  259.         while (*m && *m != '\n')
  260.             ++m;
  261.         strncpy (x_name, s, m-s);
  262.         x_name[m-s] = '\0';
  263.         new = (DviFontMap *) malloc (sizeof *new);
  264.         new->x_name = savestr (x_name);
  265.         new->dvi_name = savestr (dvi_name);
  266.         new->next = fm;
  267.         fm = new;
  268.         ++m;
  269.     }
  270.     dw->dvi.font_map = fm;
  271. }
  272.  
  273. DestroyFontMap (font_map)
  274.     DviFontMap    *font_map;
  275. {
  276.     DviFontMap    *next;
  277.  
  278.     for (; font_map; font_map = next) {
  279.         next = font_map->next;
  280.         if (font_map->x_name)
  281.             free (font_map->x_name);
  282.         if (font_map->dvi_name)
  283.             free (font_map->dvi_name);
  284.         free ((char *) font_map);
  285.     }
  286. }
  287.  
  288. SetFontPosition (dw, position, dvi_name, extra)
  289.     DviWidget    dw;
  290.     int        position;
  291.     char        *dvi_name;
  292.     char        *extra;    /* unused */
  293. {
  294.     char    *x_name;
  295.  
  296.     x_name = MapDviNameToXName (dw, dvi_name);
  297.     (void) InstallFont (dw, position, dvi_name, x_name);
  298. }
  299.  
  300. XFontStruct *
  301. QueryFont (dw, position, size)
  302.     DviWidget    dw;
  303.     int        position;
  304.     int        size;
  305. {
  306.     DviFontList    *f;
  307.     DviFontSizeList    *fs;
  308.  
  309.     f = LookupFontByPosition (dw, position);
  310.     if (!f)
  311.         return dw->dvi.default_font;
  312.     fs = LookupFontSizeBySize (f, size);
  313.     if (!fs->font) {
  314.         if (fs->x_name)
  315.             fs->font = XLoadQueryFont (XtDisplay (dw), fs->x_name);
  316.         if (!fs->font)
  317.             fs->font = dw->dvi.default_font;
  318.     }
  319.     return fs->font;
  320. }
  321.  
  322. DviCharNameMap *
  323. QueryFontMap (dw, position)
  324.     DviWidget    dw;
  325.     int        position;
  326. {
  327.     DviFontList    *f;
  328.     char        *encoding;
  329.  
  330.     f = LookupFontByPosition (dw, position);
  331.     if (f)
  332.         return f->char_map;
  333.     else
  334.         return 0;
  335. }
  336.  
  337. LoadFont (dw, position, size)
  338.     DviWidget    dw;
  339.     int        position;
  340.     int        size;
  341. {
  342.     XFontStruct    *font;
  343.  
  344.     font = QueryFont (dw, position, size);
  345.     dw->dvi.font_number = position;
  346.     dw->dvi.font_size = size;
  347.     dw->dvi.font = font;
  348.     XSetFont (XtDisplay (dw), dw->dvi.normal_GC, font->fid);
  349.     return;
  350. }
  351.