home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 188.lha / showfont.c < prev    next >
C/C++ Source or Header  |  1988-04-28  |  36KB  |  1,183 lines

  1. /********************************************/
  2. /*   ShowFont 3.1 - by Arthur Johnson Jr.   */
  3. /* ======================================== */
  4. /* Usage: ShowFont [font_name] [font_size]  */
  5. /* ======================================== */
  6. /*      Last modifications - 11/27/88       */
  7. /********************************************/
  8.  
  9. #include "intuition/intuition.h" /* this one includes heaps o' stuff */
  10. #include "exec/memory.h"
  11. #include "libraries/diskfont.h"
  12.  
  13. #define XAREA       25      /* no characters beyond (screenwidth - XAREA) */
  14. #define FONTBUFFER  1000    /* works for me */
  15. #define FONTNAMELEN 30      /* maximum font name length */
  16. #define MAXFLAGS    9       /* total of nine style flags so far */
  17.  
  18. #define MAXDISPLAY  7       /* max names, sizes, and styles to display */
  19. #define NAMELEN     13      /* maximum chars of name displayed */
  20. #define NAMEXPOS    13
  21. #define SIZEXPOS    145
  22. #define STYLXPOS    197
  23. #define TOPYPOS     7
  24.  
  25. #define BASELINE    6   /* for Topaz-8 font */
  26. #define YINCR       8
  27.  
  28. /* these are short little macro expanders to save me some typing effort */
  29. #define SIZES       fonts[namesel].sizes
  30. #define SIZESEL     fonts[namesel].sizesel
  31. #define STYLES      fonts[namesel].size[SIZESEL].styles
  32. #define STYLE       fonts[namesel].size[SIZESEL].style
  33. #define STYLESEL    fonts[namesel].size[SIZESEL].stylesel
  34.  
  35. extern struct NewScreen newscreen;
  36. extern struct Gadget W_Prop;
  37. extern struct Gadget W_Down;
  38. extern struct Gadget W_Up;
  39. extern struct MenuItem MenuItem6;
  40. extern struct Menu Menu1;
  41. extern struct NewWindow newwindow;
  42. extern struct Requester requester2;
  43. extern struct Requester requester3;
  44. extern struct Border Outline1;
  45. extern struct PropInfo W_PropSInfo;
  46. extern struct PropInfo R_FontSInfo;
  47. extern struct PropInfo R_SizeSInfo;
  48. extern struct PropInfo R_StyleSInfo;
  49. extern struct Gadget R_Font;
  50. extern struct Gadget R_Size;
  51. extern struct Gadget R_Style;
  52.  
  53. struct Screen *screen;
  54. struct Window *window;
  55. struct RastPort *rp;
  56. struct Gadget *whichgad;
  57. struct IntuiMessage *message;
  58.  
  59. struct IntuitionBase *IntuitionBase;
  60. struct GfxBase *GfxBase;
  61. struct DiskfontBase *DiskfontBase;
  62.  
  63. struct sizenode {
  64.     UWORD ysize;
  65.     int   styles;
  66.     UBYTE style[MAXFLAGS];
  67.     int   stylesel;
  68.     UBYTE flags;
  69. };
  70.  
  71. struct tempsizenode {
  72.     UWORD ysize;
  73.     int   styles;
  74.     UBYTE style[MAXFLAGS];
  75.     UBYTE flags;
  76.     struct tempsizenode *prev;
  77.     struct tempsizenode *next;
  78. };
  79.  
  80. struct fontinfo {
  81.     char    name[FONTNAMELEN + 1];
  82.     int     sizes;
  83.     struct  sizenode *size;
  84.     int     sizesel;
  85. };
  86. struct fontinfo *fonts;
  87.  
  88. struct tempfontinfo {
  89.     char    name[FONTNAMELEN + 1];
  90.     int     sizes;
  91.     struct  tempsizenode *sizedata;
  92.     struct  tempfontinfo *prev;
  93.     struct  tempfontinfo *next;
  94. };
  95. struct tempfontinfo *tempfonts;
  96.  
  97. char fontname[FONTNAMELEN + 6]; /* include space for '.font\0' */
  98. struct TextAttr myfont = { /* necessary structure for fonts */
  99.     &fontname[0],   /* default is Topaz-8 fault */
  100.     8,
  101.     FS_NORMAL,
  102.     FPF_ROMFONT };
  103. struct TextFont *font;
  104.  
  105. /* I just don't want to pass the following values around */
  106.  
  107. struct {
  108.     UBYTE *string;
  109.     int length;
  110. } fontline[256];    /* maximum of 256 lines (one char/line) */
  111.  
  112. int numfonts;
  113.  
  114. int screenwidth, screenheight;
  115.  
  116. int nameline, sizeline, styleline,
  117.     namesel,
  118.     rfontlastline, rsizelastline, rstylelastline;
  119.  
  120. USHORT fontpropsize, fontproppos, sizepropsize, sizeproppos,
  121.         stylepropsize, styleproppos;
  122.  
  123. void clearfonts()
  124. {
  125.  
  126.     register i;
  127.  
  128.     for (i = 0; i < numfonts; i++)
  129.         FreeMem(fonts[i].size, fonts[i].sizes * sizeof(struct sizenode));
  130.     FreeMem(fonts, numfonts * sizeof(struct fontinfo));
  131.  
  132.     numfonts = 0;   /* there are no fonts */
  133.  
  134. }
  135.  
  136. void clearfontlines()
  137. {
  138.  
  139.     register i;
  140.  
  141.     /* free all the string space */
  142.     i = 0;
  143.     while (fontline[i].length != 0) {
  144.         FreeMem(fontline[i].string, fontline[i].length);
  145.         fontline[i].length = 0;
  146.         ++i;
  147.     }
  148.  
  149. }
  150.  
  151. void cleanup(text)
  152. char *text;
  153. {
  154.  
  155.     clearfonts();
  156.     clearfontlines();
  157.     if (font)
  158.         CloseFont(font);
  159.     if (window) {
  160.         ClearMenuStrip(window);
  161.         CloseWindow(window);
  162.     }
  163.     if (screen)
  164.         CloseScreen(screen);
  165.     if (DiskfontBase)
  166.         CloseLibrary(DiskfontBase);
  167.     if (IntuitionBase)
  168.         CloseLibrary(IntuitionBase);
  169.     if (GfxBase)
  170.         CloseLibrary(GfxBase);
  171.  
  172.     if (text)
  173.         puts(text);
  174.  
  175.     exit();
  176.  
  177. }
  178.  
  179. void clearsizedata(font)
  180. struct tempfontinfo *font;
  181. {
  182.  
  183.     struct tempsizenode *erase;
  184.  
  185.     while (font->sizedata != NULL) {
  186.         erase = font->sizedata;
  187.         font->sizedata = font->sizedata->next;
  188.         FreeMem(erase, sizeof(struct tempsizenode));
  189.     }
  190.  
  191. }
  192.  
  193. void cleartempfonts()
  194. {
  195.  
  196.     struct tempfontinfo *erase;
  197.  
  198.     while (tempfonts != NULL) {
  199.         erase = tempfonts;
  200.         tempfonts = tempfonts->next;
  201.         clearsizedata(erase);
  202.         FreeMem(erase, sizeof(struct tempfontinfo));
  203.     }
  204.  
  205. }
  206.  
  207. void addsizenode(font, ysize, style, flags)
  208. struct tempfontinfo *font;
  209. UWORD ysize;
  210. UBYTE style;
  211. UBYTE flags;
  212. {
  213.  
  214.     struct tempsizenode *search, *prev, *newnode;
  215.  
  216.     int generic;
  217.  
  218.     prev = NULL;
  219.     search = font->sizedata;
  220.     generic = -1;
  221.     while ((search != NULL) && (generic == -1)) {
  222.         if ((search->ysize == ysize) && (search->flags == flags)) {
  223.             if (style == FS_NORMAL)
  224.                 search->style[search->styles] = 0;
  225.             if (style & FSF_UNDERLINED)
  226.                 search->style[search->styles] = 1;
  227.             if (style & FSF_BOLD)
  228.                 search->style[search->styles] = 2;
  229.             if (style & FSF_ITALIC)
  230.                 search->style[search->styles] = 4;
  231.             if (style & FSF_EXTENDED)
  232.                 search->style[search->styles] = 8;
  233.             ++(search->styles);
  234.             generic = 1;    /* found it */
  235.         }
  236.         else    if (search->ysize >= ysize)
  237.                     generic = 0;    /* should go before here */
  238.                 else {
  239.                     prev = search;
  240.                     search = search->next;
  241.                 }
  242.     }
  243.     if (generic != 1) {
  244.         newnode = (struct tempsizenode *)AllocMem(sizeof(struct tempsizenode), MEMF_CLEAR);
  245.         if (newnode == NULL)
  246.             cleanup("ShowFont: couldn't allocate enough memory!");
  247.         newnode->ysize = ysize;
  248.         newnode->styles = 0;
  249.         newnode->flags = flags;
  250.         if (style == FS_NORMAL)
  251.             newnode->style[newnode->styles] = 0;
  252.         if (style & FSF_UNDERLINED)
  253.             newnode->style[newnode->styles] = 1;
  254.         if (style & FSF_BOLD)
  255.             newnode->style[newnode->styles] = 2;
  256.         if (style & FSF_ITALIC)
  257.             newnode->style[newnode->styles] = 4;
  258.         if (style & FSF_EXTENDED)
  259.             newnode->style[newnode->styles] = 8;
  260.         ++(newnode->styles);
  261.         ++(font->sizes);
  262.         switch (generic) {
  263.             case -1: if (prev == NULL) {    /* list is empty */
  264.                         newnode->prev = NULL;
  265.                         newnode->next = NULL;
  266.                         font->sizedata = newnode;
  267.                      }
  268.                      else   /* should add at end */
  269.                         {
  270.                             prev->next = newnode;
  271.                             newnode->prev = prev;
  272.                             newnode->next = NULL;
  273.                         }
  274.                      break;
  275.             case  0: if (search->prev == NULL) { /* add at begin */
  276.                         newnode->prev = NULL;
  277.                         newnode->next = search;
  278.                         search->prev = newnode;
  279.                         font->sizedata = newnode;
  280.                      }
  281.                      else { /* add in the middle somewhere */
  282.                             search->prev->next = newnode;
  283.                             newnode->prev = search->prev;
  284.                             newnode->next = search;
  285.                             search->prev = newnode;
  286.                      }
  287.                      break;
  288.         }
  289.     }
  290.  
  291. }
  292.  
  293. void readfonts()
  294. {
  295.  
  296.     struct AvailFontsHeader *afh;
  297.     struct AvailFonts *af;
  298.  
  299.     struct tempfontinfo *search, *prev, *newnode;
  300.     struct tempsizenode *sizenode;
  301.  
  302.     int generic;
  303.  
  304.     int mem = FONTBUFFER,
  305.         moremem;
  306.  
  307.     register i, j, k;
  308.  
  309.     clearfonts();
  310.  
  311.     do {
  312.         afh = (struct AvailFontsHeader *)AllocMem(mem, MEMF_CLEAR);
  313.         if (afh == NULL)
  314.             cleanup("ShowFont: couldn't allocate enough memory!");
  315.         moremem = AvailFonts(afh, mem, 0xFF);
  316.         if (moremem != 0) {
  317.             FreeMem(afh, mem);
  318.             mem += moremem;
  319.             printf("ShowFont: allocating %d bytes of memory for the FONTS: info.\n", mem);
  320.         }
  321.     } while (moremem != 0);
  322.  
  323.     if (afh->afh_NumEntries == 0) {
  324.         FreeMem(afh, mem);
  325.         cleanup("ShowFont: couldn't find any fonts! (Is FONTS: set correctly?)");
  326.     }
  327.  
  328.     tempfonts = NULL;
  329.  
  330.     af = (struct AvailFonts *)&afh[1];
  331.     for (i = 0; i < afh->afh_NumEntries; i++) {
  332.         if (!((af->af_Attr.ta_Flags & FPF_REMOVED) ||
  333.             (af->af_Attr.ta_Flags & FPF_REVPATH) ||
  334.             ((af->af_Type & AFF_MEMORY) &&
  335.              (af->af_Attr.ta_Flags & FPF_DISKFONT)))) {
  336.  
  337.             prev = NULL;
  338.             search = tempfonts;
  339.             generic = -1;
  340.             while ((search != NULL) && (generic == -1)) {
  341.                 if (strnicmp(af->af_Attr.ta_Name, search->name, (strlen(af->af_Attr.ta_Name) - 5)) == NULL) {
  342.                     addsizenode(search, af->af_Attr.ta_YSize, af->af_Attr.ta_Style, af->af_Attr.ta_Flags);
  343.                     generic = 1;    /* found it */
  344.                 }
  345.                 else if (strnicmp(af->af_Attr.ta_Name, search->name, (strlen(af->af_Attr.ta_Name) - 5)) < NULL)
  346.                             generic = 0;    /* should go before here */
  347.                         else {
  348.                             prev = search;
  349.                             search = search->next;
  350.                         }
  351.             }
  352.             if (generic != 1) {
  353.                 newnode = (struct tempfontinfo *)AllocMem(sizeof(struct tempfontinfo), MEMF_CLEAR);
  354.                 if (newnode == NULL)
  355.                     cleanup("ShowFont: couldn't allocate enough memory!");
  356.                 stccpy(newnode->name, af->af_Attr.ta_Name, (strlen(af->af_Attr.ta_Name) - 4));
  357.                 newnode->sizes = 0;
  358.                 newnode->sizedata = NULL;
  359.                 addsizenode(newnode, af->af_Attr.ta_YSize, af->af_Attr.ta_Style, af->af_Attr.ta_Flags);
  360.                 ++numfonts;
  361.                 switch (generic) {
  362.                     case -1: if (prev == NULL) {    /* list is empty */
  363.                                 newnode->prev = NULL;
  364.                                 newnode->next = NULL;
  365.                                 tempfonts = newnode;
  366.                              }
  367.                              else   /* should add at end */
  368.                                 {
  369.                                     prev->next = newnode;
  370.                                     newnode->prev = prev;
  371.                                     newnode->next = NULL;
  372.                                 }
  373.                              break;
  374.                     case  0: if (search->prev == NULL) { /* add at begin */
  375.                                 newnode->prev = NULL;
  376.                                 newnode->next = search;
  377.                                 search->prev = newnode;
  378.                                 tempfonts = newnode;
  379.                              }
  380.                              else { /* add in the middle somewhere */
  381.                                     search->prev->next = newnode;
  382.                                     newnode->prev = search->prev;
  383.                                     newnode->next = search;
  384.                                     search->prev = newnode;
  385.                              }
  386.                              break;
  387.                 }
  388.             }
  389.         }
  390.         af++;
  391.     }
  392.  
  393.     FreeMem(afh, mem);
  394.  
  395.     if ((fonts = (struct fontinfo *)AllocMem(numfonts * sizeof(struct fontinfo), MEMF_CLEAR)) == NULL)
  396.         cleanup("ShowFont: couldn't allocate secondary memory!");
  397.  
  398.     search = tempfonts;
  399.  
  400.     for (i = 0; i < numfonts; i++) {
  401.         strcpy(fonts[i].name, search->name);
  402.         fonts[i].sizes = search->sizes;
  403.         if ((fonts[i].size = (struct sizenode *)AllocMem(fonts[i].sizes * sizeof(struct sizenode), MEMF_CLEAR)) == NULL)
  404.             cleanup("ShowFont: couldn't allocate tertiary memory!");
  405.         sizenode = search->sizedata;
  406.         for (j = 0; j < fonts[i].sizes; j++) {
  407.             fonts[i].size[j].ysize = sizenode->ysize;
  408.             fonts[i].size[j].styles = sizenode->styles;
  409.             for (k = 0; k < fonts[i].size[j].styles; k++)
  410.                 fonts[i].size[j].style[k] = sizenode->style[k];
  411.             fonts[i].size[j].stylesel = 0;
  412.             fonts[i].size[j].flags = sizenode->flags;
  413.             sizenode = sizenode->next;
  414.         }
  415.         fonts[i].sizesel = 0;
  416.         search = search->next;
  417.     }
  418.  
  419.     cleartempfonts();
  420.  
  421.     if (MenuItem6.Flags == ITEMTEXT+COMMSEQ+HIGHCOMP) {
  422.         OnMenu(window, SHIFTMENU(1) | SHIFTITEM(1));
  423.         MenuItem6.Flags |= ITEMENABLED;
  424.     }
  425.  
  426. }
  427.  
  428. void setupscreen()
  429. {
  430.  
  431.     if (window) {
  432.         ClearMenuStrip(window);
  433.         CloseWindow(window);
  434.     }
  435.     if (screen)
  436.         CloseScreen(screen);
  437.  
  438.     newscreen.Width = screenwidth;
  439.     newscreen.Height = screenheight;
  440.     if (screenwidth == 320)
  441.         if (screenheight == 200)
  442.             newscreen.ViewModes = NULL;
  443.         else
  444.             newscreen.ViewModes = LACE;
  445.     else
  446.         if (screenheight == 200)
  447.             newscreen.ViewModes = HIRES;
  448.         else
  449.             newscreen.ViewModes = HIRES | LACE;
  450.  
  451.     newwindow.Width = screenwidth;
  452.     newwindow.Height = screenheight;
  453.  
  454.     if (screenwidth == 320)
  455.         if (screenheight == 200) {
  456.             requester2.LeftEdge = 0;
  457.             requester2.TopEdge = 50;
  458.         }
  459.         else {
  460.             requester2.LeftEdge = 0;
  461.             requester2.TopEdge = 150;
  462.         }
  463.     else
  464.         if (screenheight == 200) {
  465.             requester2.LeftEdge = 160;
  466.             requester2.TopEdge = 50;
  467.         }
  468.         else {
  469.             requester2.LeftEdge = 160;
  470.             requester2.TopEdge = 150;
  471.         }
  472.  
  473.     if (screenwidth == 320)
  474.         if (screenheight == 200) {
  475.             requester3.LeftEdge = 56;
  476.             requester3.TopEdge = 50;
  477.         }
  478.         else {
  479.             requester3.LeftEdge = 56;
  480.             requester3.TopEdge = 150;
  481.         }
  482.     else
  483.         if (screenheight == 200) {
  484.             requester3.LeftEdge = 216;
  485.             requester3.TopEdge = 50;
  486.         }
  487.         else {
  488.             requester3.LeftEdge = 216;
  489.             requester3.TopEdge = 150;
  490.         }
  491.  
  492.     W_Prop.LeftEdge = screenwidth - 21;
  493.     W_Prop.Height = -29 + screenheight;
  494.     W_Down.LeftEdge = screenwidth - 21;
  495.     W_Down.TopEdge = W_Prop.TopEdge + W_Prop.Height;
  496.     W_Up.LeftEdge = screenwidth - 21;
  497.  
  498.     if ((screen = (struct Screen *)OpenScreen(&newscreen)) == NULL)
  499.         cleanup("ShowFont: couldn't open the screen.");
  500.     newwindow.Screen = screen;
  501.  
  502.     if ((window = (struct Window *)OpenWindow(&newwindow)) == NULL)
  503.         cleanup("ShowFont: couldn't open the window.");
  504.     rp = window->RPort;
  505.  
  506.     SetMenuStrip(window, &Menu1);
  507.  
  508. }
  509.  
  510. int findfont()
  511. {
  512.  
  513.     int low, mid, high;
  514.  
  515.     low = 0;
  516.     high = numfonts - 1;
  517.     while (low <= high) {
  518.         mid = (low + high) / 2;
  519.         if (strnicmp(fontname, fonts[mid].name, (strlen(fontname) - 5)) < 0)
  520.             high = mid - 1;
  521.         else
  522.             if (strnicmp(fontname, fonts[mid].name, (strlen(fontname) - 5)) > 0)
  523.                 low = mid + 1;
  524.             else
  525.                 return(mid);
  526.     }
  527.  
  528.     return(-1);
  529.  
  530. }
  531.  
  532. USHORT proppos(line, maxline)
  533. int line;
  534. int maxline;
  535. {
  536.  
  537.     if (maxline == 1)
  538.         return((USHORT)MAXBODY);
  539.     else
  540.         return((USHORT)((MAXBODY * (line - 1)) / (maxline - 1)));
  541.  
  542. }
  543.  
  544. USHORT propsize(display, maxdisplay)
  545. int display;
  546. int maxdisplay;
  547. {
  548.  
  549.     if (display >= maxdisplay)
  550.         return((USHORT)MAXPOT);
  551.     else
  552.         return((USHORT)((MAXPOT * display) / maxdisplay));
  553.  
  554. }
  555.  
  556. int propline(proppos, maxline)
  557. USHORT proppos;
  558. int maxline;
  559. {
  560.  
  561.     return((proppos * maxline) / MAXPOT);
  562.  
  563. }
  564.  
  565. void refresh1(rp)
  566. struct RastPort *rp;
  567. {
  568.  
  569.     register loop,
  570.              x, y;
  571.  
  572.     char namestring[NAMELEN + 1];
  573.  
  574.     x = NAMEXPOS;
  575.     y = TOPYPOS + BASELINE;
  576.  
  577.     SetDrMd(rp, JAM2);
  578.     SetAPen(rp, 1);
  579.  
  580.     for (loop = 0; loop < MAXDISPLAY; loop++) {
  581.         Move(rp, x, y);
  582.         SetBPen(rp, 0);
  583.         if ((nameline + loop) < numfonts) {
  584.             if ((nameline + loop) == namesel)
  585.                 SetBPen(rp, 2);
  586.             sprintf(namestring, "%-13s", fonts[nameline + loop].name);
  587.             Text(rp, namestring, NAMELEN);
  588.         }
  589.         else
  590.             Text(rp, "             ", NAMELEN);
  591.         y += YINCR;
  592.     }
  593.  
  594. }
  595.  
  596. void refresh2(rp)
  597. struct RastPort *rp;
  598. {
  599.  
  600.     register loop,
  601.              x, y;
  602.  
  603.     char sizestring[3 + 1];
  604.  
  605.     x = SIZEXPOS;
  606.     y = TOPYPOS + BASELINE;
  607.  
  608.     SetDrMd(rp, JAM2);
  609.  
  610.     for (loop = 0; loop < MAXDISPLAY; loop++) {
  611.         Move(rp, x, y);
  612.         SetBPen(rp, 0);
  613.         if ((sizeline + loop) < SIZES) {
  614.             SetAPen(rp, 1);
  615.             if (fonts[namesel].size[sizeline + loop].flags & FPF_PROPORTIONAL)
  616.                 SetAPen(rp, 3);
  617.             if ((sizeline + loop) == SIZESEL)
  618.                 SetBPen(rp, 2);
  619.             sprintf(sizestring, "%3d", fonts[namesel].size[sizeline + loop].ysize);
  620.             Text(rp, sizestring, 3);
  621.         }
  622.         else
  623.             Text(rp, "   ", 3);
  624.         y += YINCR;
  625.     }
  626.  
  627. }
  628.  
  629. void refresh3(rp)
  630. struct RastPort *rp;
  631. {
  632.  
  633.     register x, y, i;
  634.  
  635.     x = STYLXPOS;
  636.     y = TOPYPOS + BASELINE;
  637.  
  638.     SetDrMd(rp, JAM2);
  639.     SetAPen(rp, 1);
  640.  
  641.     for (i = styleline; i < STYLES; i++) {
  642.         Move(rp, x, y);
  643.         if (i == STYLESEL)
  644.             SetBPen(rp, 2);
  645.         else
  646.             SetBPen(rp, 0);
  647.         switch(STYLE[i]) {
  648.             case 0: Text(rp, "Normal      ", 12);
  649.                     break;
  650.             case 1: Text(rp, "Underlined  ", 12);
  651.                     break;
  652.             case 2: Text(rp, "Bold        ", 12);
  653.                     break;
  654.             case 4: Text(rp, "Italic      ", 12);
  655.                     break;
  656.             case 8: Text(rp, "Extended    ", 12);
  657.                     break;
  658.         }
  659.         y += YINCR;
  660.     }
  661.  
  662.     SetBPen(rp, 0);
  663.  
  664.     for (i = STYLES; i < MAXDISPLAY; i++) {
  665.         Move(rp, x, y);
  666.         Text(rp, "            ", 12);
  667.         y += YINCR;
  668.     }
  669.  
  670. }
  671.  
  672. void updateprop(prop, requester, proppos, propsize)
  673. struct Gadget *prop;
  674. struct Requester *requester;
  675. USHORT proppos;
  676. USHORT propsize;
  677. {
  678.  
  679.     ModifyProp(prop, window, requester, AUTOKNOB | FREEVERT, -1, proppos, -1, propsize);
  680.  
  681. }
  682.  
  683. /* updatetype =  1 : refresh 1      */
  684. /*                   update 2, 3    */
  685. /*                   refresh 2, 3   */
  686. /*               2 : refresh 2      */
  687. /*                   update 3       */
  688. /*                   refresh 3      */
  689. /*               3 : refresh 3      */
  690. /*              10 : moved 1, u/r 1 */
  691. /*              20 : moved 2, u/r 2 */
  692. /*              30 : moved 3, u/r 3 */
  693. void duhprop(rp, updatetype)
  694. struct RastPort *rp;
  695. int updatetype;
  696. {
  697.  
  698.     if (updatetype == 1) {
  699.         rsizelastline = (SIZES - MAXDISPLAY) + 1;
  700.         if (rsizelastline < 1)
  701.             rsizelastline = 1;
  702.         sizeline = SIZESEL;
  703.         if ((sizeline + 1) >= rsizelastline)
  704.             sizeline = rsizelastline - 1;
  705.         sizepropsize = propsize(MAXDISPLAY, SIZES);
  706.         sizeproppos = proppos((sizeline + 1), rsizelastline);
  707.     }
  708.     if (updatetype < 10) {
  709.         rstylelastline = (STYLES - MAXDISPLAY) + 1;
  710.         if (rstylelastline < 1)
  711.             rstylelastline = 1;
  712.         styleline = STYLESEL;
  713.         if ((styleline + 1) >= rstylelastline)
  714.             styleline = rstylelastline - 1;
  715.         stylepropsize = propsize(MAXDISPLAY, STYLES);
  716.         styleproppos = proppos((styleline + 1), rstylelastline);
  717.     }
  718.  
  719.     switch (updatetype) {
  720.         case 10: fontproppos = proppos((nameline + 1), rfontlastline);
  721.                  break;
  722.         case 20: sizeproppos = proppos((sizeline + 1), rsizelastline);
  723.                  break;
  724.         case 30: styleproppos = proppos((styleline + 1), rstylelastline);
  725.                  break;
  726.     }
  727.  
  728.     switch (updatetype) {
  729.         case  1: refresh1(rp);
  730.                  updateprop(&R_Size, &requester2, sizeproppos, sizepropsize);
  731.                  updateprop(&R_Style, &requester2, styleproppos, stylepropsize);
  732.                  refresh2(rp);
  733.                  refresh3(rp);
  734.                  break;
  735.         case  2: refresh2(rp);
  736.                  updateprop(&R_Style, &requester2, styleproppos, stylepropsize);
  737.                  refresh3(rp);
  738.                  break;
  739.         case  3: refresh3(rp);
  740.                  break;
  741.         case 10: updateprop(&R_Font, &requester2, fontproppos, fontpropsize);
  742.                  refresh1(rp);
  743.                  break;
  744.         case 20: updateprop(&R_Size, &requester2, sizeproppos, sizepropsize);
  745.                  refresh2(rp);
  746.                  break;
  747.         case 30: updateprop(&R_Style, &requester2, styleproppos, stylepropsize);
  748.                  refresh3(rp);
  749.                  break;
  750.     }
  751.  
  752. }
  753.  
  754. int selectfont()
  755. {
  756.  
  757.     struct RastPort *rp;
  758.  
  759.     int returnvalue,
  760.         refreshhow,
  761.         x, y;
  762.  
  763.     ULONG  class;
  764.  
  765.     Request(&requester2, window);
  766.     rp = requester2.ReqLayer->rp;
  767.  
  768.     namesel = findfont();
  769.  
  770.     rfontlastline = numfonts - MAXDISPLAY + 1;
  771.     if (rfontlastline < 1)
  772.         rfontlastline = 1;
  773.     fontpropsize = propsize(MAXDISPLAY, numfonts);
  774.  
  775.     nameline = namesel;
  776.     if ((nameline + 1) >= rfontlastline)
  777.         nameline = rfontlastline - 1;
  778.  
  779.     duhprop(rp, 1);
  780.     duhprop(rp, 10);
  781.  
  782.     DrawBorder(rp, &Outline1, 0, 0);
  783.  
  784.     refreshhow = 0;
  785.     returnvalue = 0;
  786.  
  787.     while (returnvalue == 0) {
  788.  
  789.         switch (refreshhow) {
  790.             case  0: break;
  791.             case -1: if (nameline > 0)
  792.                          --nameline;
  793.                      duhprop(rp, 10);
  794.                      break;
  795.             case 10: nameline = propline(R_FontSInfo.VertPot, rfontlastline);
  796.                      if ((nameline + 1) >= rfontlastline)
  797.                          nameline = rfontlastline - 1;
  798.                      duhprop(rp, 10);
  799.                      break;
  800.             case  1: if ((nameline + 1) < rfontlastline)
  801.                          ++nameline;
  802.                      duhprop(rp, 10);
  803.                      break;
  804.             case -2: if (sizeline > 0)
  805.                          --sizeline;
  806.                      duhprop(rp, 20);
  807.                      break;
  808.             case 20: sizeline = propline(R_SizeSInfo.VertPot, rsizelastline);
  809.                      if ((sizeline + 1) >= rsizelastline)
  810.                          sizeline = rsizelastline - 1;
  811.                      duhprop(rp, 20);
  812.                      break;
  813.             case  2: if ((sizeline + 1) < rsizelastline)
  814.                          ++sizeline;
  815.                      duhprop(rp, 20);
  816.                      break;
  817.             case -3: if (styleline > 0)
  818.                          --styleline;
  819.                      duhprop(rp, 30);
  820.                      break;
  821.             case 30: styleline = propline(R_StyleSInfo.VertPot, rstylelastline);
  822.                      if ((styleline + 1) >= rstylelastline)
  823.                          styleline = rstylelastline - 1;
  824.                      duhprop(rp, 30);
  825.                      break;
  826.             case  3: if ((styleline + 1) < rstylelastline)
  827.                          ++styleline;
  828.                      duhprop(rp, 30);
  829.                      break;
  830.         }
  831.  
  832.         message = (struct IntuiMessage *)GetMsg(window->UserPort);
  833.         if (message != 0) {
  834.             class = message->Class;
  835.             x = message->MouseX - requester2.LeftEdge;
  836.             y = message->MouseY - requester2.TopEdge;
  837.             whichgad = (struct Gadget *)message->IAddress;
  838.             ReplyMsg(message);
  839.  
  840.             if (class == GADGETDOWN) {
  841.                 switch (whichgad->GadgetID) {
  842.                     case 11: refreshhow = -1;
  843.                              break;
  844.                     case 12: refreshhow = 10;
  845.                              break;
  846.                     case 13: refreshhow = 1;
  847.                              break;
  848.                     case 21: refreshhow = -2;
  849.                              break;
  850.                     case 22: refreshhow = 20;
  851.                              break;
  852.                     case 23: refreshhow = 2;
  853.                              break;
  854.                     case 31: refreshhow = -3;
  855.                              break;
  856.                     case 32: refreshhow = 30;
  857.                              break;
  858.                     case 33: refreshhow = 3;
  859.                              break;
  860.                 }
  861.             }
  862.             if (class == GADGETUP) {
  863.                 switch (whichgad->GadgetID) {
  864.                     case 101: returnvalue = 1;
  865.                               break;
  866.                     case 102: returnvalue = -1;
  867.                               break;
  868.                 }
  869.             }
  870.             if (class == MOUSEBUTTONS) {
  871.                 refreshhow = 0;
  872.                 if ((y >= 0) && (y < 100) && (x >= 0) && (x < 320)) {
  873.                     y -= TOPYPOS;
  874.                     y = y / YINCR;
  875.                     if (y < MAXDISPLAY) {
  876.                         if ((x >= NAMEXPOS) && (x < (NAMEXPOS + NAMELEN * 8))) {
  877.                             if (namesel == (nameline + y)) {
  878.                                 returnvalue = 1;
  879.                                 EndRequest(&requester2, window);
  880.                             }
  881.                             else {
  882.                                 namesel = nameline + y;
  883.                                 if (namesel >= numfonts)
  884.                                     namesel = numfonts - 1;
  885.                                 duhprop(rp, 1);
  886.                             }
  887.                         }
  888.                         if ((x >= SIZEXPOS) && (x < (SIZEXPOS + 3 * 8))) {
  889.                             if (SIZESEL == (sizeline + y)) {
  890.                                 returnvalue = 1;
  891.                                 EndRequest(&requester2, window);
  892.                             }
  893.                             else {
  894.                                 SIZESEL = sizeline + y;
  895.                                 if (SIZESEL >= SIZES)
  896.                                     SIZESEL = SIZES - 1;
  897.                                 duhprop(rp, 2);
  898.                             }
  899.                         }
  900.                         if ((x >= STYLXPOS) && (x < (STYLXPOS + 12 * 8))) {
  901.                             if (STYLESEL == (styleline + y)) {
  902.                                 returnvalue = 1;
  903.                                 EndRequest(&requester2, window);
  904.                             }
  905.                             else {
  906.                                 STYLESEL = styleline + y;
  907.                                 if (STYLESEL >= STYLES)
  908.                                     STYLESEL = STYLES - 1;
  909.                                 duhprop(rp, 3);
  910.                             }
  911.                         }
  912.                     }
  913.                 }
  914.             }
  915.         }
  916.     }
  917.  
  918.     if (returnvalue == 1) {
  919.         strcpy(fontname, fonts[namesel].name);
  920.         strcat(fontname, ".font");
  921.         myfont.ta_YSize = fonts[namesel].size[SIZESEL].ysize;
  922.         myfont.ta_Style = STYLE[STYLESEL];
  923.         myfont.ta_Flags = fonts[namesel].size[SIZESEL].flags;
  924.     }
  925.  
  926.     return(returnvalue);
  927.  
  928. }
  929.  
  930. void mycat(s, c)
  931. char *s;
  932. char c;
  933. {
  934.  
  935.     while (*s++ != '\0') {}
  936.     *(s - 1) = c;
  937.     *s = '\0';
  938.  
  939. }
  940.  
  941. void main(argc,argv)
  942. int argc;
  943. char *argv[];
  944. {
  945.  
  946.     int cont = TRUE,
  947.         rethinkfont = TRUE;
  948.  
  949.     ULONG   class;
  950.     USHORT  code;
  951.  
  952.     int line, maxline,
  953.         yarea,
  954.         startchar,
  955.         len, pixels,
  956.         whichmenu, whichitem,
  957.         wproplastline,
  958.         refreshhow;
  959.  
  960.     char windowtitle[81];
  961.  
  962.     USHORT numy, pos, size;
  963.  
  964.     register loop, i;
  965.  
  966.     UBYTE textline[256];
  967.  
  968.     if ((argc == 2) && (*argv[1] == '?'))
  969.         cleanup("Usage: ShowFont [font_name] [font_size]");
  970.  
  971.     if ((IntuitionBase = (struct IntuitionBase *)
  972.             OpenLibrary("intuition.library", 0)) == NULL)
  973.         cleanup("ShowFont: couldn't open 'intuition.library'.");
  974.  
  975.     if ((GfxBase = (struct GfxBase *)
  976.             OpenLibrary("graphics.library", 0)) == NULL)
  977.         cleanup("ShowFont: couldn't open 'graphics.library'.");
  978.  
  979.     if ((DiskfontBase = (struct DiskfontBase *)
  980.             OpenLibrary("diskfont.library", 0)) == NULL)
  981.         cleanup("ShowFont: couldn't open 'diskfont.library'.");
  982.  
  983.     screenwidth = 640;
  984.     screenheight = 200;
  985.     setupscreen();
  986.  
  987.     fonts = NULL;
  988.  
  989.     if (argc == 1)
  990.         strcpy(fontname, "Topaz.font");
  991.     else
  992.         sprintf(fontname, "%s.font", argv[1]);
  993.     if (argc < 3) {
  994.         readfonts();
  995.         selectfont();
  996.     }
  997.     else
  998.         myfont.ta_YSize = atoi(argv[2]);
  999.  
  1000.     for (i = 0; i < 256; ++i)
  1001.         fontline[i].length = 0;
  1002.  
  1003.     while (cont) {
  1004.  
  1005.         if (rethinkfont) {
  1006.  
  1007.             if (font)
  1008.                 CloseFont(font);
  1009.  
  1010.             if ((font = (struct TextFont *)OpenDiskFont(&myfont)) == NULL)
  1011.                 cleanup("ShowFont: couldn't find the font.");
  1012.  
  1013.             if (myfont.ta_YSize > screenheight) {
  1014.                 screenheight = 400;
  1015.                 setupscreen();
  1016.             }
  1017.  
  1018.             SetFont(rp, font);
  1019.  
  1020.             clearfontlines();
  1021.  
  1022.             startchar = font->tf_LoChar;
  1023.             line = 0;
  1024.             len = 0;
  1025.  
  1026.             for (loop = font->tf_LoChar; loop <= font->tf_HiChar; ++loop) {
  1027.                 textline[len++] = loop;
  1028.                 pixels = TextLength(rp, textline, len) + window->BorderLeft;
  1029.                 if (pixels > (screenwidth - XAREA)) {
  1030.                     --len;
  1031.                     fontline[line].string = (UBYTE *)AllocMem(len, MEMF_CLEAR);
  1032.                     if (fontline[line].string == NULL)
  1033.                         cleanup("ShowFont: couldn't allocate enough memory!");
  1034.                     for (i = startchar; i < loop; ++i)
  1035.                         fontline[line].string[i - startchar] = i;
  1036.                     fontline[line].length = len;
  1037.                     startchar = loop;
  1038.                     ++line;
  1039.                     len = 0;
  1040.                     --loop; /* must go back and insert that character */
  1041.                 }
  1042.                 else
  1043.                     if (loop == font->tf_HiChar) {
  1044.                         fontline[line].string = (UBYTE *)AllocMem(len, MEMF_CLEAR);
  1045.                         if (fontline[line].string == NULL)
  1046.                             cleanup("ShowFont: couldn't allocate enough memory!");
  1047.                         for (i = startchar; i <= font->tf_HiChar; ++i)
  1048.                             fontline[line].string[i - startchar] = i;
  1049.                         fontline[line].length = len;
  1050.                         ++line;
  1051.                     }
  1052.             }
  1053.  
  1054.             maxline = line;
  1055.             line = 0;
  1056.             yarea = screenheight - (window->BorderTop + window->BorderBottom);
  1057.             numy = yarea / font->tf_YSize;
  1058.  
  1059.             wproplastline = (maxline - numy) + 1;
  1060.             if (wproplastline < 1)
  1061.                 wproplastline = 1;
  1062.  
  1063.             size = propsize(numy, maxline);
  1064.  
  1065.             stccpy(windowtitle, fontname, (strlen(fontname) - 4));
  1066.             sprintf(windowtitle + strlen(windowtitle), " - %d", myfont.ta_YSize);
  1067.             SetWindowTitles(window, windowtitle, -1);
  1068.  
  1069.             rethinkfont = FALSE;
  1070.             refreshhow = 99;    /* refresh it once only */
  1071.         }
  1072.  
  1073.         switch (refreshhow) {
  1074.             case  0: break;
  1075.             case -1: if (line > 0)
  1076.                          --line;
  1077.                      break;
  1078.             case 10: pos = W_PropSInfo.VertPot;
  1079.                      line = propline(pos, wproplastline);
  1080.                      if ((line + 1) > wproplastline)
  1081.                          line = wproplastline - 1;
  1082.                      break;
  1083.             case  1: if ((line + 1) < wproplastline)
  1084.                          ++line;
  1085.                      break;
  1086.             case 99: break;
  1087.         }
  1088.  
  1089.         if (refreshhow != 0) {
  1090.  
  1091.             pos = proppos((line + 1), wproplastline);
  1092.  
  1093.             ModifyProp(&W_Prop, window, NULL, AUTOKNOB | FREEVERT, -1, pos, -1, size);
  1094.  
  1095.             WaitTOF();  /* might just possibly reduce blinking */
  1096.             SetAPen(rp, 0); /* clear the screen */
  1097.             RectFill(rp, window->BorderLeft, window->BorderTop, (screenwidth - XAREA), (screenheight - window->BorderBottom));
  1098.  
  1099.             SetAPen(rp, 1);
  1100.             SetBPen(rp, 0);
  1101.             SetDrMd(rp, JAM2);
  1102.  
  1103.             for (i = line; i < (line + numy); ++i) {
  1104.                 Move(rp, window->BorderLeft, ((i - line) * font->tf_YSize) + window->BorderTop + font->tf_Baseline);
  1105.                 Text(rp, fontline[i].string, fontline[i].length);
  1106.             }
  1107.  
  1108.             if (refreshhow == 99)
  1109.                 refreshhow = 0; /* for initial refreshment only */
  1110.         }
  1111.  
  1112.         message = (struct IntuiMessage *)GetMsg(window->UserPort);
  1113.         if (message != 0) {
  1114.             class = message->Class;
  1115.             code  = message->Code;
  1116.             whichgad = (struct Gadget *)message->IAddress;
  1117.             ReplyMsg(message);
  1118.  
  1119.             if (class == CLOSEWINDOW)
  1120.                 cont = FALSE;
  1121.             if (class == GADGETDOWN)
  1122.                 switch (whichgad->GadgetID) {
  1123.                     case 1: refreshhow = -1;
  1124.                             break;
  1125.                     case 2: refreshhow = 10;
  1126.                             break;
  1127.                     case 3: refreshhow = 1;
  1128.                             break;
  1129.                 }
  1130.             if ((class == MOUSEBUTTONS) && (code == SELECTUP))
  1131.                 refreshhow = 0;
  1132.             if (class == MENUPICK) {
  1133.                 if (code != MENUNULL) {
  1134.                     whichmenu = MENUNUM(code);
  1135.                     whichitem = ITEMNUM(code);
  1136.                     switch (whichmenu) {
  1137.                         case 0 : switch (whichitem) {
  1138.                                     case 0: Request(&requester3, window); /* about */
  1139.                                             break;
  1140.                                     case 1: cont = FALSE; /* quit */
  1141.                                             break;
  1142.                                  }
  1143.                                  break;
  1144.                         case 1 : switch (whichitem) {
  1145.                                     case 0: readfonts(); /* read FONTS: */
  1146.                                             if (selectfont() == 1)
  1147.                                                 rethinkfont = TRUE;
  1148.                                             break;
  1149.                                     case 1: if (selectfont() == 1)
  1150.                                                 rethinkfont = TRUE;
  1151.                                             break; /* font selection */
  1152.                                  }
  1153.                                  break;
  1154.                         case 2 : switch (whichitem) {
  1155.                                     case 0: screenwidth = 320;
  1156.                                             screenheight = 200;
  1157.                                             setupscreen();
  1158.                                             break;
  1159.                                     case 1: screenwidth = 320;
  1160.                                             screenheight = 400;
  1161.                                             setupscreen();
  1162.                                             break;
  1163.                                     case 2: screenwidth = 640;
  1164.                                             screenheight = 200;
  1165.                                             setupscreen();
  1166.                                             break;
  1167.                                     case 3: screenwidth = 640;
  1168.                                             screenheight = 400;
  1169.                                             setupscreen();
  1170.                                             break;
  1171.                                  }
  1172.                                  rethinkfont = TRUE;
  1173.                                  break;
  1174.                     }
  1175.                 }
  1176.             }
  1177.         }
  1178.     }
  1179.  
  1180.     cleanup(NULL);
  1181.  
  1182. }
  1183.