home *** CD-ROM | disk | FTP | other *** search
/ Aminet 10 / aminetcdnumber101996.iso / Aminet / util / gnu / groff_src.lha / groff-1.10src / xditview / font.c < prev    next >
C/C++ Source or Header  |  1992-12-12  |  9KB  |  472 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. static DisposeFontSizes();
  16.  
  17. static char *
  18. savestr (s)
  19.     char    *s;
  20. {
  21.     char    *n;
  22.  
  23.     if (!s)
  24.         return 0;
  25.     n = XtMalloc (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. int
  45. MaxFontPosition (dw)
  46.     DviWidget dw;
  47. {
  48.     DviFontList    *f;
  49.     int n = -1;
  50.  
  51.     for (f = dw->dvi.fonts; f; f = f->next)
  52.         if (f->dvi_number > n)
  53.             n = f->dvi_number;
  54.     return n;
  55. }
  56.  
  57. static DviFontSizeList *
  58. LookupFontSizeBySize (dw, f, size)
  59.     DviWidget    dw;
  60.     DviFontList    *f;
  61.     int        size;
  62. {
  63.     DviFontSizeList    *fs, *best = 0, *smallest = 0;
  64.     int        bestsize = 0;
  65.     XFontName    fontName;
  66.     unsigned int    fontNameAttributes;
  67.     char            fontNameString[2048];
  68.     int        decipointsize;
  69.     
  70.     if (f->scalable) {
  71.         decipointsize = (10*size)/dw->dvi.sizescale;
  72.         for (best = f->sizes; best; best = best->next)
  73.             if (best->size == decipointsize)
  74.                 return best;
  75.         best = (DviFontSizeList *) XtMalloc(sizeof *best);
  76.         best->next = f->sizes;
  77.         best->size = decipointsize;
  78.         f->sizes = best;
  79.         XParseFontName (f->x_name, &fontName, &fontNameAttributes);
  80.         fontNameAttributes &= ~(FontNamePixelSize|FontNameAverageWidth);
  81.         fontNameAttributes |= FontNameResolutionX;
  82.         fontNameAttributes |= FontNameResolutionY;
  83.         fontNameAttributes |= FontNamePointSize;
  84.         fontName.ResolutionX = dw->dvi.display_resolution;
  85.         fontName.ResolutionY = dw->dvi.display_resolution;
  86.         fontName.PointSize = decipointsize;
  87.         XFormatFontName (&fontName, fontNameAttributes, fontNameString);
  88.         best->x_name = savestr (fontNameString);
  89.         best->doesnt_exist = 0;
  90.         best->font = 0;
  91.         return best;
  92.     }
  93.     for (fs = f->sizes; fs; fs=fs->next) {
  94.         if (dw->dvi.sizescale*fs->size <= 10*size
  95.             && fs->size >= bestsize) {
  96.             best = fs;
  97.             bestsize = fs->size;
  98.         }
  99.         if (smallest == 0 || fs->size < smallest->size)
  100.             smallest = fs;
  101.     }
  102.     return best ? best : smallest;
  103. }
  104.  
  105. static char *
  106. SkipFontNameElement (n)
  107.     char    *n;
  108. {
  109.     while (*n != '-')
  110.         if (!*++n)
  111.             return 0;
  112.     return n+1;
  113. }
  114.  
  115. # define SizePosition        8
  116. # define EncodingPosition    13
  117.  
  118. static
  119. ConvertFontNameToSize (n)
  120.     char    *n;
  121. {
  122.     int    i, size;
  123.  
  124.     for (i = 0; i < SizePosition; i++) {
  125.         n = SkipFontNameElement (n);
  126.         if (!n)
  127.             return -1;
  128.     }
  129.     size = atoi (n);
  130.     return size;
  131. }
  132.  
  133. static char *
  134. ConvertFontNameToEncoding (n)
  135.     char    *n;
  136. {
  137.         int i;
  138.     for (i = 0; i < EncodingPosition; i++) {
  139.         n = SkipFontNameElement (n);
  140.         if (!n)
  141.             return 0;
  142.     }
  143.     return n;
  144. }
  145.  
  146. DviFontSizeList *
  147. InstallFontSizes (dw, x_name, scalablep)
  148.     DviWidget    dw;
  149.     char        *x_name;
  150.     Boolean        *scalablep;
  151. {
  152.     char    fontNameString[2048];
  153.     char    **fonts;
  154.     int    i, count;
  155.     int    size;
  156.     DviFontSizeList    *sizes, *new;
  157.     XFontName    fontName;
  158.     unsigned int    fontNameAttributes;
  159.  
  160.     *scalablep = FALSE;
  161.     if (!XParseFontName (x_name, &fontName, &fontNameAttributes))
  162.         return 0;
  163.     fontNameAttributes &= ~(FontNamePixelSize|FontNamePointSize
  164.                 |FontNameAverageWidth);
  165.     fontNameAttributes |= FontNameResolutionX;
  166.     fontNameAttributes |= FontNameResolutionY;
  167.     fontName.ResolutionX = dw->dvi.display_resolution;
  168.     fontName.ResolutionY = dw->dvi.display_resolution;
  169.     XFormatFontName (&fontName, fontNameAttributes, fontNameString);
  170.     fonts = XListFonts (XtDisplay (dw), fontNameString, 10000000, &count);
  171.     sizes = 0;
  172.     for (i = 0; i < count; i++) {
  173.         size = ConvertFontNameToSize (fonts[i]);
  174.         if (size == 0) {
  175.             DisposeFontSizes (dw, sizes);
  176.             sizes = 0;
  177.             *scalablep = TRUE;
  178.             break;
  179.         }
  180.         if (size != -1) {
  181.             new = (DviFontSizeList *) XtMalloc (sizeof *new);
  182.             new->next = sizes;
  183.             new->size = size;
  184.             new->x_name = savestr (fonts[i]);
  185.             new->doesnt_exist = 0;
  186.             new->font = 0;
  187.             sizes = new;
  188.         }
  189.     }
  190.     XFreeFontNames (fonts);
  191.     return sizes;
  192. }
  193.  
  194. static
  195. DisposeFontSizes (dw, fs)
  196.     DviWidget    dw;
  197.     DviFontSizeList    *fs;
  198. {
  199.     DviFontSizeList    *next;
  200.  
  201.     for (; fs; fs=next) {
  202.         next = fs->next;
  203.         if (fs->x_name)
  204.             XtFree (fs->x_name);
  205.         if (fs->font) {
  206.             XUnloadFont (XtDisplay (dw), fs->font->fid);
  207.             XFree ((char *)fs->font);
  208.         }
  209.         XtFree ((char *) fs);
  210.     }
  211. }
  212.  
  213. static DviFontList *
  214. InstallFont (dw, position, dvi_name, x_name)
  215.     DviWidget    dw;
  216.     int        position;
  217.     char        *dvi_name;
  218.     char        *x_name;
  219. {
  220.     DviFontList    *f;
  221.     char        *encoding;
  222.  
  223.     if ((f = LookupFontByPosition (dw, position)) != NULL) {
  224.         /*
  225.          * ignore gratuitous font loading
  226.          */
  227.         if (!strcmp (f->dvi_name, dvi_name) &&
  228.             !strcmp (f->x_name, x_name))
  229.             return f;
  230.  
  231.         DisposeFontSizes (dw, f->sizes);
  232.         if (f->dvi_name)
  233.             XtFree (f->dvi_name);
  234.         if (f->x_name)
  235.             XtFree (f->x_name);
  236.         f->device_font = 0;
  237.     } else {
  238.         f = (DviFontList *) XtMalloc (sizeof (*f));
  239.         f->next = dw->dvi.fonts;
  240.         dw->dvi.fonts = f;
  241.     }
  242.     f->initialized = FALSE;
  243.     f->dvi_name = savestr (dvi_name);
  244.     f->device_font = device_find_font (dw->dvi.device, dvi_name);
  245.     f->x_name = savestr (x_name);
  246.     f->dvi_number = position;
  247.     f->sizes = 0;
  248.     f->scalable = FALSE;
  249.     if (f->x_name) {
  250.         encoding = ConvertFontNameToEncoding (f->x_name);
  251.         f->char_map = DviFindMap (encoding);
  252.     } else
  253.         f->char_map = 0;
  254.     /* 
  255.      * force requery of fonts
  256.      */
  257.     dw->dvi.font = 0;
  258.     dw->dvi.font_number = -1;
  259.     dw->dvi.cache.font = 0;
  260.     dw->dvi.cache.font_number = -1;
  261.     dw->dvi.device_font = 0;
  262.     dw->dvi.device_font_number = -1;
  263.     return f;
  264. }
  265.  
  266. ForgetFonts (dw)
  267.     DviWidget dw;
  268. {
  269.     DviFontList *f = dw->dvi.fonts;
  270.     
  271.     while (f) {
  272.         DviFontList *tem = f;
  273.  
  274.         if (f->sizes)
  275.             DisposeFontSizes (dw, f->sizes);
  276.         if (f->dvi_name)
  277.             XtFree (f->dvi_name);
  278.         if (f->x_name)
  279.             XtFree (f->x_name);
  280.         f = f->next;
  281.         XtFree ((char *) tem);
  282.     }
  283.     
  284.     /* 
  285.      * force requery of fonts
  286.      */
  287.     dw->dvi.font = 0;
  288.     dw->dvi.font_number = -1;
  289.     dw->dvi.cache.font = 0;
  290.     dw->dvi.cache.font_number = -1;
  291.     dw->dvi.device_font = 0;
  292.     dw->dvi.device_font_number = -1;
  293.     dw->dvi.fonts = 0;
  294. }
  295.  
  296.  
  297. static char *
  298. MapDviNameToXName (dw, dvi_name)
  299.     DviWidget    dw;
  300.     char        *dvi_name;
  301. {
  302.     DviFontMap    *fm;
  303.     
  304.     for (fm = dw->dvi.font_map; fm; fm=fm->next)
  305.         if (!strcmp (fm->dvi_name, dvi_name))
  306.             return fm->x_name;
  307.     return 0;
  308. }
  309.  
  310. #if 0
  311. static char *
  312. MapXNameToDviName (dw, x_name)
  313.     DviWidget    dw;
  314.     char        *x_name;
  315. {
  316.     DviFontMap    *fm;
  317.     
  318.     for (fm = dw->dvi.font_map; fm; fm=fm->next)
  319.         if (!strcmp (fm->x_name, x_name))
  320.             return fm->dvi_name;
  321.     return 0;
  322. }
  323. #endif
  324.  
  325. ParseFontMap (dw)
  326.     DviWidget    dw;
  327. {
  328.     char        dvi_name[1024];
  329.     char        x_name[2048];
  330.     char        *m, *s;
  331.     DviFontMap    *fm, *new;
  332.  
  333.     if (dw->dvi.font_map)
  334.         DestroyFontMap (dw->dvi.font_map);
  335.     fm = 0;
  336.     m = dw->dvi.font_map_string;
  337.     while (*m) {
  338.         s = m;
  339.         while (*m && !isspace (*m))
  340.             ++m;
  341.         strncpy (dvi_name, s, m-s);
  342.         dvi_name[m-s] = '\0';
  343.         while (isspace (*m))
  344.             ++m;
  345.         s = m;
  346.         while (*m && *m != '\n')
  347.             ++m;
  348.         strncpy (x_name, s, m-s);
  349.         x_name[m-s] = '\0';
  350.         new = (DviFontMap *) XtMalloc (sizeof *new);
  351.         new->x_name = savestr (x_name);
  352.         new->dvi_name = savestr (dvi_name);
  353.         new->next = fm;
  354.         fm = new;
  355.         ++m;
  356.     }
  357.     dw->dvi.font_map = fm;
  358. }
  359.  
  360. DestroyFontMap (font_map)
  361.     DviFontMap    *font_map;
  362. {
  363.     DviFontMap    *next;
  364.  
  365.     for (; font_map; font_map = next) {
  366.         next = font_map->next;
  367.         if (font_map->x_name)
  368.             XtFree (font_map->x_name);
  369.         if (font_map->dvi_name)
  370.             XtFree (font_map->dvi_name);
  371.         XtFree ((char *) font_map);
  372.     }
  373. }
  374.  
  375. /* ARGSUSED */
  376.  
  377. SetFontPosition (dw, position, dvi_name, extra)
  378.     DviWidget    dw;
  379.     int        position;
  380.     char        *dvi_name;
  381.     char        *extra;    /* unused */
  382. {
  383.     char    *x_name;
  384.  
  385.     x_name = MapDviNameToXName (dw, dvi_name);
  386.     if (x_name)
  387.         (void) InstallFont (dw, position, dvi_name, x_name);
  388. }
  389.  
  390. XFontStruct *
  391. QueryFont (dw, position, size)
  392.     DviWidget    dw;
  393.     int        position;
  394.     int        size;
  395. {
  396.     DviFontList    *f;
  397.     DviFontSizeList    *fs;
  398.  
  399.     f = LookupFontByPosition (dw, position);
  400.     if (!f)
  401.         return dw->dvi.default_font;
  402.     if (!f->initialized) {
  403.         f->sizes = InstallFontSizes (dw, f->x_name, &f->scalable);
  404.         f->initialized = TRUE;
  405.     }
  406.     fs = LookupFontSizeBySize (dw, f, size);
  407.     if (!fs)
  408.         return dw->dvi.default_font;
  409.     if (!fs->font) {
  410.         if (fs->x_name)
  411.             fs->font = XLoadQueryFont (XtDisplay (dw), fs->x_name);
  412.         if (!fs->font)
  413.             fs->font = dw->dvi.default_font;
  414.     }
  415.     return fs->font;
  416. }
  417.  
  418. DeviceFont *
  419. QueryDeviceFont (dw, position)
  420.     DviWidget    dw;
  421.     int        position;
  422. {
  423.     DviFontList    *f;
  424.  
  425.     f = LookupFontByPosition (dw, position);
  426.     if (!f)
  427.         return 0;
  428.     return f->device_font;
  429. }
  430.  
  431. DviCharNameMap *
  432. QueryFontMap (dw, position)
  433.     DviWidget    dw;
  434.     int        position;
  435. {
  436.     DviFontList    *f;
  437.  
  438.     f = LookupFontByPosition (dw, position);
  439.     if (f)
  440.         return f->char_map;
  441.     else
  442.         return 0;
  443. }
  444.  
  445. #if 0
  446. LoadFont (dw, position, size)
  447.     DviWidget    dw;
  448.     int        position;
  449.     int        size;
  450. {
  451.     XFontStruct    *font;
  452.  
  453.     font = QueryFont (dw, position, size);
  454.     dw->dvi.font_number = position;
  455.     dw->dvi.font_size = size;
  456.     dw->dvi.font = font;
  457.     XSetFont (XtDisplay (dw), dw->dvi.normal_GC, font->fid);
  458.     return;
  459. }
  460. #endif
  461.  
  462. /*
  463. Local Variables:
  464. c-indent-level: 8
  465. c-continued-statement-offset: 8
  466. c-brace-offset: -8
  467. c-argdecl-indent: 8
  468. c-label-offset: -8
  469. c-tab-always-indent: nil
  470. End:
  471. */
  472.