home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / lyx-0.13.2.tar.gz / lyx-0.13.2.tar / lyx-0.13.2 / src / FontLoader.C < prev    next >
C/C++ Source or Header  |  1998-04-23  |  6KB  |  251 lines

  1. // -*- C++ -*-
  2. /* This file is part of
  3.  * ======================================================
  4.  * 
  5.  *           LyX, The Document Processor
  6.  *      
  7.  *        Copyright (C) 1997 Asger Alstrup
  8.  *           and the LyX Team.
  9.  *
  10.  *======================================================*/
  11.  
  12. #include <config.h>
  13. #include <math.h>    // fabs()
  14. #include <stdlib.h>    // atoi()
  15.  
  16. #ifdef __GNUG__
  17. #pragma implementation "FontLoader.h"
  18. #endif
  19.  
  20. #include "gettext.h"
  21. #include "FontLoader.h"
  22. #include "FontInfo.h"
  23. #include "error.h"
  24. #include "lyxrc.h"    // lyxrc.font_*
  25. extern LyXRC * lyxrc;
  26. #include "minibuffer.h"
  27. extern MiniBuffer *minibuffer;
  28.  
  29. // Initialize font loader
  30. FontLoader::FontLoader()
  31. {
  32.     reset();
  33. }
  34.  
  35. // Destroy font loader
  36. FontLoader::~FontLoader()
  37. {
  38.     unload();
  39. }
  40.  
  41. // Update fonts after zoom, dpi, font names, or norm change
  42. // For now, we just ditch all fonts we have. Later, we should
  43. // reuse the ones that are already loaded.
  44. void FontLoader::update()
  45. {
  46.     unload();
  47. }
  48.  
  49. // Reset font loader
  50. void FontLoader::reset()
  51. {
  52.     // Clear font infos, font structs and font metrics
  53.     for (int i1=0; i1<4; i1++)
  54.         for (int i2=0; i2<2; i2++)
  55.             for (int i3=0; i3<4; i3++) {
  56.                 fontinfo[i1][i2][i3] = 0;
  57.                 for (int i4=0; i4<10; i4++) {
  58.                     fontstruct[i1][i2][i3][i4] = 0;
  59.                 }
  60.             }
  61. }
  62.  
  63. // Unload all fonts
  64. void FontLoader::unload() 
  65. {
  66.     // Unload all fonts
  67.     for (int i1=0; i1<4; i1++)
  68.         for (int i2=0; i2<2; i2++)
  69.             for (int i3=0; i3<4; i3++) {
  70.                 if (fontinfo[i1][i2][i3]) {
  71.                     delete fontinfo[i1][i2][i3];
  72.                     fontinfo[i1][i2][i3] = 0;
  73.                 }
  74.                 for (int i4=0; i4<10; i4++) {
  75.                     if (fontstruct[i1][i2][i3][i4]) {
  76.                         XFreeFont(fl_display, fontstruct[i1][i2][i3][i4]);
  77.                         fontstruct[i1][i2][i3][i4] = 0;
  78.                     }
  79.                 }
  80.             }
  81. }
  82.  
  83. // Get font info
  84. /* Takes care of finding which font that can match the given request. Tries
  85. different alternatives. */
  86. void FontLoader::getFontinfo(LyXFont::FONT_FAMILY family, 
  87.                  LyXFont::FONT_SERIES series, 
  88.                  LyXFont::FONT_SHAPE shape)
  89. {
  90.     // Do we have the font info already?
  91.     if (fontinfo[family][series][shape] != 0)
  92.         return;
  93.  
  94.     // Special code for the symbol family
  95.     if (family == LyXFont::SYMBOL_FAMILY){
  96.         fontinfo[family][series][shape] = new FontInfo("-*-symbol-*");
  97.         return;
  98.     }
  99.  
  100.     // Normal font. Let's search for an existing name that matches.
  101.     LString ffamily;
  102.     LString fseries;
  103.     LString fshape;
  104.     LString norm = lyxrc->font_norm;
  105.     LString fontname;
  106.  
  107.     FontInfo * fi = new FontInfo();
  108.     fontinfo[family][series][shape] = fi;
  109.  
  110.     for (int cfam=0; cfam < 2; cfam++) {
  111.         // Determine family name
  112.         switch (family) {
  113.         case LyXFont::ROMAN_FAMILY:
  114.             switch (cfam) {
  115.             case 0: ffamily = lyxrc->roman_font_name; break;
  116.             case 1: ffamily = "-*-times";
  117.             default: cfam = 100;
  118.             }
  119.             break;
  120.         case LyXFont::SANS_FAMILY:
  121.             switch (cfam) {
  122.             case 0: ffamily = lyxrc->sans_font_name; break;
  123.             case 1: ffamily = "-*-helvetica";
  124.             default: cfam = 100;
  125.             }
  126.             break;
  127.         case LyXFont::TYPEWRITER_FAMILY:
  128.             switch (cfam) {
  129.             case 0: ffamily = lyxrc->typewriter_font_name; break;
  130.             case 1: ffamily = "-*-courier";
  131.             default: cfam = 100;
  132.             }
  133.             break;
  134.         default: ;
  135.         }
  136.  
  137.         for (int cser=0; cser < 4; cser++) {
  138.             // Determine series name
  139.             switch (series) {
  140.             case LyXFont::MEDIUM_SERIES:
  141.                 switch (cser) {
  142.                 case 0: fseries = "-medium"; break;
  143.                 case 1: fseries = "-book"; break;
  144.                 case 2: fseries = "-light";
  145.                 default: cser = 100;
  146.                 }
  147.                 break;
  148.             case LyXFont::BOLD_SERIES:
  149.                 switch (cser) {
  150.                 case 0: fseries = "-bold"; break;
  151.                 case 1: fseries = "-black"; break;
  152.                 case 2: fseries = "-demi"; break;
  153.                 case 3: fseries = "-demibold";
  154.                 default: cser = 100;
  155.                 }
  156.                 break;
  157.             default: ;
  158.             }
  159.  
  160.             for (int csha=0; csha < 2; csha++) {
  161.                 // Determine shape name
  162.                 switch (shape) {
  163.                 case LyXFont::UP_SHAPE:
  164.                 case LyXFont::SMALLCAPS_SHAPE:
  165.                     switch (csha) {
  166.                     case 0: fshape = "-r";
  167.                     default: csha = 100;
  168.                     }
  169.                     break;
  170.                 case LyXFont::ITALIC_SHAPE:
  171.                     switch (csha) {
  172.                     case 0: fshape = "-i"; break;
  173.                     case 1: fshape = "-o";
  174.                     default: csha = 100;
  175.                     }
  176.                     break;
  177.                 case LyXFont::SLANTED_SHAPE:
  178.                     switch (csha) {
  179.                     case 0: fshape = "-o"; break;
  180.                     case 1: fshape = "-i";
  181.                     default: csha = 100;
  182.                     }
  183.                     break;
  184.                 default: ;
  185.                 }
  186.                 //
  187.                 fontname = ffamily + fseries + fshape +
  188.                        "-normal-*-*-*-*-*-*-*-" + norm;
  189.                 fi->setPattern(fontname);
  190.                 if (fi->exist()) {
  191.                     return;
  192.                 }
  193.             }
  194.         }
  195.     }
  196. }
  197.  
  198. /// Do load font
  199. XFontStruct* FontLoader::doLoad(LyXFont::FONT_FAMILY family, 
  200.                 LyXFont::FONT_SERIES series, 
  201.                 LyXFont::FONT_SHAPE shape, 
  202.                 LyXFont::FONT_SIZE size)
  203. {
  204.     getFontinfo(family,series,shape);
  205.     int fsize = (int) ( (lyxrc->font_sizes[size] * lyxrc->dpi * 
  206.                 (lyxrc->zoom/100.0) ) / 72.27 + 0.5 );
  207.  
  208.     LString font = fontinfo[family][series][shape]->getFontname(fsize);
  209.  
  210.     if (font.empty()) {
  211.         lyxerr.print("No font matches request. Using 'fixed'.");
  212.         lyxerr.print("Start LyX as 'lyx -dbg 515' to get more information.");
  213.         font = "fixed";
  214.     }
  215.  
  216.     minibuffer->Store();
  217.     minibuffer->Set(_("Loading font into X-Server..."));
  218.  
  219.     XFontStruct* fs = XLoadQueryFont(fl_display, font.c_str());
  220.  
  221.     if (fs == 0) {
  222.         if (font=="fixed") {
  223.             lyxerr.print("We're doomed. Can't get 'fixed' font.");
  224.         } else {
  225.             lyxerr.print("Could not get font. Using 'fixed'.");
  226.             fs = XLoadQueryFont(fl_display, "fixed");
  227.         }
  228.     } else {
  229.         if (lyxerr.debugging(Error::FONT)) {
  230.             // Tell user the font matching
  231.             LyXFont f;
  232.             f.setFamily(family);
  233.             f.setSeries(series);
  234.             f.setShape(shape);
  235.             f.setSize(size);
  236.             // The rest of the attributes are not interesting
  237.             f.setEmph(LyXFont::INHERIT);
  238.             f.setUnderbar(LyXFont::INHERIT);
  239.             f.setNoun(LyXFont::INHERIT);
  240.             f.setLatex(LyXFont::INHERIT);
  241.             f.setColor(LyXFont::INHERIT_COLOR);
  242.             lyxerr.print(LString("Font '") + f.stateText() 
  243.                       + "' matched by\n" + font + '\n');
  244.         }
  245.     }
  246.     minibuffer->Reset();
  247.  
  248.     fontstruct[family][series][shape][size] = fs;
  249.     return fs;
  250. }
  251.