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