home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d182 / setfont.lha / SetFont / SetFont.cp < prev    next >
Text File  |  1989-02-25  |  9KB  |  277 lines

  1. // =======================================================================
  2.  
  3. /* SetFont 2.5 - by Dave Haynie
  4.  
  5.             BIX:    hazy
  6.             Usenet:    {uunet|rutgers}!cbmvax!daveh
  7.             PLINK:    D-Dave H
  8.              Drink:    Guinness
  9.  
  10.    BUSINESS:
  11.  
  12.     This program is complete, real, and true public domain software.
  13.    Do with it what you will as long as you don't remove my name from it.
  14.    Feel free to enhance this as you see fit.  I may eventually make one
  15.    that's better....
  16.    
  17.    ABOUT IT:
  18.  
  19.         SetFont V2.5 cleans up all known bugs in SetFont V2.0, and it's
  20.    the first C++ version.  The code is GREATLY cleaned up and simplified
  21.    from SetFont V2.0.  I no longer free any fonts that were previously
  22.    set.  V2.0 did too much freeing, but even with that, it is possible
  23.    that another program could get a pointer to the font or font descriptor
  24.    in a window or screen and choke if that's freed.  That may not be good
  25.    behavior, but this way's safer.  A future version will probably track
  26.    fonts opened and closed by SetFont itsself so that it can reclaim some
  27.    of it's resources and still be reasonably safe.  Right now I have no
  28.    way of knowing if the font or descriptor I see is even really owned by
  29.    SetFont.
  30.  
  31.    CONFLICTS:
  32.  
  33.     There are a few potential problems the general notion of SetFont in 
  34.    the Amiga system.  First of all, many programs are written to support only
  35.    the topaz 8 (80 column) font (sloppy, I know, but that's life).  If you're
  36.    a 60 column user, you've probably experienced this before.  It's not a 
  37.    problem with the Amiga as a whole, since most of the system will adjust 
  38.    itself.  But it may be a problem with programs that have a fixed idea of 
  39.    what a font should look like.  Most 80 column fonts work with most 
  40.    applications, and an 80 column 8x8 font will work just about everywhere.  
  41.    Some programs, like CLI for instance, have trouble with proportionally-
  42.    spaced fonts.  The best thing to do is try out the font you like.  One 
  43.    final problem is that some applications ask the WorkBench screen to close 
  44.    when they start up.  It'll close if there's nothing else open on it, but 
  45.    when it re-opens, it'll restart with the Preferences-selected font, not 
  46.    the SetFont selected font.  Of course, preferences doesn't support 
  47.    arbitrary fonts (which is why this program is even necessary).  Oh well, 
  48.    maybe day.  
  49. */
  50.  
  51. #include <exec/types.h>
  52. #include <exec/io.h>
  53. #include <exec/ports.h>
  54. #include <exec/memory.h>
  55. #include <graphics/gfxbase.h>
  56. #include <graphics/text.h>
  57. #include <graphics/rastport.h>
  58. #include <libraries/dos.h>
  59. #include <libraries/dosextens.h>
  60. #include <intuition/intuition.h>
  61. #include <string.h>
  62. #include <ctype.h>
  63. #include <stdio.h>
  64. #include <stdlib.h>
  65.  
  66. // =========================================================================
  67.  
  68. // Miscellaneous stuff.
  69.  
  70. extern TextFont *OpenDiskFont(const TextAttr *);
  71.  
  72. inline BPTR CADDR(APTR cptr) { return BPTR(ULONG(cptr) >> 2); }
  73.  
  74. inline void fail(char *a, char *b = NULL) { printf(a,b); exit(10); }
  75.  
  76. inline MsgPort *contask(MsgPort *port) {
  77.    return (MsgPort *) ((port->mp_SigTask->ln_Type == NT_PROCESS)
  78.           ? ((Process *)port->mp_SigTask)->pr_ConsoleTask 
  79.           : NULL);
  80. }
  81.  
  82. // =========================================================================
  83.  
  84. // This is the "smart" font class.  SmartFont items stay around after the 
  85. // program exits if they appear to have been used.
  86.  
  87. class SmartFont {
  88.    private:
  89.       static BOOL aok;            // Font checks out    
  90.       TextAttr      sfattr;        // Font descriptor
  91.       
  92.    public:
  93.       SmartFont(char *n, UWORD s);
  94.  
  95.       TextFont *font() {
  96.          TextFont *f = OpenDiskFont(&sfattr);
  97.  
  98.          if (!f) f = OpenFont(&sfattr);
  99.          if (!f) fail("Font \"%s\" not found\n",sfattr.ta_Name);
  100.          return f;
  101.       }
  102.       TextAttr *attr() {
  103.          TextAttr *a = (TextAttr *)AllocMem(sizeof(TextAttr),MEMF_PUBLIC|MEMF_CLEAR);
  104.          a->ta_Name = (char *)AllocMem(strlen(sfattr.ta_Name)+1,MEMF_PUBLIC|MEMF_CLEAR);
  105.          strcpy(a->ta_Name,sfattr.ta_Name);
  106.          a->ta_YSize = sfattr.ta_YSize;
  107.          return a;
  108.       }
  109.       char *name() { return sfattr.ta_Name; }
  110.       UWORD size() { return sfattr.ta_YSize; }
  111. };
  112.  
  113. SmartFont::SmartFont(char *n, UWORD s = 8) {
  114.    strcat(strcpy(sfattr.ta_Name = new char[strlen(n)+6],n),".font");
  115.    sfattr.ta_YSize = (s>2)?s:8;
  116.    sfattr.ta_Style = sfattr.ta_Flags = 0;
  117.  
  118.    if (!aok) {
  119.       TextFont *f = font();
  120.       CloseFont(f);
  121.       aok = TRUE;
  122.    }
  123. }
  124.  
  125. // =========================================================================
  126.  
  127. // These classes manage the places that fonts are hidden.
  128.  
  129. // This is the basic place node
  130.  
  131. class PlaceNode : public Node {
  132.    private:
  133.       static Window *pwin;
  134.       static Screen *pscr;
  135.  
  136.    public:
  137.       PlaceNode();      
  138.       PlaceNode *next() { return (PlaceNode *)Node::next(); }
  139.  
  140.       void testwindow() { if (!pwin) fail("Window not found\n"); }
  141.       void testscreen() { if (!pscr) fail("Screen not found\n"); }
  142.  
  143.       Window *window()  { return pwin; }
  144.       Screen *screen()  { return pscr; }
  145.  
  146.       virtual void set(SmartFont *f) {
  147.          testwindow();
  148.          SetFont(window()->graphic(),f->font());
  149.          printf("\033c");              // Re-init window's conunit
  150.          (void)flushall();
  151.       }
  152. };
  153.  
  154. // Initialize the static stuff, once.
  155.  
  156. PlaceNode::PlaceNode() {
  157.    if (pwin) return;
  158.  
  159.    StandardPacket *packet = new StandardPacket;
  160.    InfoData *info = new InfoData;   
  161.    MsgPort *port = new StdPort;
  162.  
  163.   // Find the window
  164.    if (contask(port)) {
  165.       packet->sendio(contask(port),port,ACTION_DISK_INFO,CADDR(info));
  166.       (void)port->wait();
  167.       pwin = (Window *)info->id_VolumeNode;
  168.    } else 
  169.       pwin = NULL;
  170.    delete port;
  171.    delete info;
  172.    delete packet;
  173.  
  174.   // Find the screen
  175.    pscr = (pwin) ? pwin->screen() : NULL;
  176. }
  177.  
  178. // These are the derived special nodes, one for each "place".
  179.  
  180. #define WindowNode    PlaceNode
  181.  
  182. class ScreenNode : public PlaceNode {
  183.    public:
  184.       void set(SmartFont *f) {
  185.          testscreen();
  186.          if (strcmp(screen()->Font->ta_Name,f->name()) == 0)
  187.             screen()->Font->ta_YSize = f->size();
  188.          else
  189.             screen()->Font = f->attr();
  190.       }
  191. };
  192.  
  193. class TitleNode : public PlaceNode {
  194.    public:
  195.       void set(SmartFont *f) {
  196.          testscreen();
  197.          SetFont(screen()->graphic(),f->font());
  198.       }
  199. };
  200.  
  201. class BarNode : public PlaceNode {
  202.    public:
  203.       void set(SmartFont *f) {
  204.          testscreen();
  205.          SetFont(screen()->BarLayer->rp,f->font());
  206.       }
  207. };
  208.  
  209. // This is the place list, which links a number of place nodes, and also
  210. // manages to go work like finding windows, etc.
  211.  
  212. class PlaceList : public List {
  213.    public:
  214.       PlaceList(int argc, char **argv);   
  215.       PlaceNode *first() { return (PlaceNode *)List::first(); }
  216. };
  217.  
  218. // The PlaceList constructor does a great deal of the work.  It looks up
  219. // the window data, then parses the command line to build the place
  220. // list.
  221.  
  222. PlaceList::PlaceList(int argc, char **argv) {
  223.   // Parse our input arguments
  224.    for (short i = 0; i < argc; ++i)
  225.       switch (toupper(argv[i][0])) {
  226.          case 'B': add(new BarNode);        break;
  227.          case 'S': add(new ScreenNode);        break;
  228.          case 'T': add(new TitleNode);        break;
  229.          case 'W': add(new WindowNode);        break;
  230.          default :                break;
  231.       }
  232.    if (is_empty()) {
  233.       add(new BarNode);
  234.       add(new ScreenNode);
  235.       add(new TitleNode);
  236.       add(new WindowNode);
  237.    }
  238. }
  239.  
  240. // =========================================================================
  241.  
  242. // Prints help notice
  243.  
  244. void PrintNotice() {
  245.    printf("SetFont 2.5 by Dave Haynie\n\n");
  246.    printf("Usage: SetFont [fontname [point [place]]]\n");
  247.    printf("  where:\n");
  248.    printf("  \2331mfontname\2330m  is the font's name (e.g. \"topaz\")\n");
  249.    printf("  \2331mpoint\2330m     is the point size (default is 8)\n");
  250.    printf("  \2331mplace\2330m     pick the place, one or more of:\n");
  251.    printf("    \2331mBAR\2330m       set the barlayer font only\n");
  252.    printf("    \2331mSCREEN\2330m    set the screen font only\n");
  253.    printf("    \2331mTITLES\2330m    set the screen titles only\n");
  254.    printf("    \2331mWINDOW\2330m    set the window's font only\n\n");
  255.    printf("If no \2331mplace\2330m switch is given, everything is set.\n\n");
  256.    exit(0);
  257. }
  258.  
  259. // The main function
  260.  
  261. void main(int argc, char *argv[]) {
  262.   // Automatic help command
  263.    if (argc < 2 || argv[1][0] == '?') PrintNotice();
  264.  
  265.   // Process the command-line arguments, AmigaDOS style.
  266.    PlaceList *plist = new PlaceList(argc-2,&argv[3]);
  267.  
  268.   // Get the font if it's there.
  269.    SmartFont *font = new SmartFont(argv[1],atoi(argv[2]));
  270.    
  271.   // Here we apply all the requested changes.
  272.    for (PlaceNode *n = plist->first(); n->next(); n = n->next()) n->set(font);
  273.  
  274.   // And we're done!
  275.    exit(0);
  276. }
  277.