home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / opus / v5 / opussdk / examples / viewfont / viewfont.c < prev    next >
C/C++ Source or Header  |  1977-12-31  |  20KB  |  1,055 lines

  1. #include "viewfont.h"
  2.  
  3. void main(int argc,char **argv)
  4. {
  5.     font_data *data;
  6.  
  7.     // Need dopus library
  8.     if (!(DOpusBase=OpenLibrary("dopus5:libs/dopus5.library",55)))
  9.         exit(10);
  10.  
  11.     // Allocate data
  12.     if (!(data=AllocMemH(0,sizeof(font_data))))
  13.     {
  14.         font_free(0);
  15.         exit(5);
  16.     }
  17.  
  18.     // Parse arguments
  19.     data->args=
  20.         ReadArgs(
  21.             "FONT,SIZE/N,B=BOLD/S,I=ITALIC/S,U=ULINE/S,PUBSCREEN/K",
  22.             (long *)data->arg_array,
  23.             0);
  24.  
  25.     // Default to topaz 8
  26.     strcpy(data->font_name,"topaz.font");
  27.     data->font_size=8;
  28.  
  29.     // Got font name?
  30.     if (data->arg_array[ARG_FONT])
  31.         font_get_name(data,(char *)data->arg_array[ARG_FONT]);
  32.  
  33.     // Got a font size?
  34.     if (data->arg_array[ARG_SIZE] && *((long *)data->arg_array[ARG_SIZE]))
  35.     {
  36.         data->font_size=*((long *)data->arg_array[ARG_SIZE]);
  37.         data->first=1;
  38.     }
  39.  
  40.     // Initialise locale
  41.     init_locale_data(&data->locale);
  42.  
  43.     // Got locale library?
  44.     if (LocaleBase)
  45.     {
  46.         BPTR lock;
  47.  
  48.         // Change PROGDIR: to dopus5:
  49.         if (lock=Lock("dopus5:",ACCESS_READ))
  50.             UnLock(SetProgramDir(lock));
  51.  
  52.         // Initialise
  53.         data->locale.li_LocaleBase=LocaleBase;
  54.         data->locale.li_Catalog=OpenCatalogA(0,"viewfont.catalog",0);
  55.         data->locale.li_Locale=OpenLocale(0);
  56.     }
  57.  
  58.     // Create message port
  59.     data->appport=CreateMsgPort();
  60.  
  61.     // Open window
  62.     if (!(font_open(data)))
  63.     {
  64.         font_free(data);
  65.         exit(5);
  66.     }
  67.  
  68.     // Initial gadget settings
  69.     if (data->arg_array[ARG_BOLD]) SetGadgetValue(data->list,GAD_FONT_BOLD,1);
  70.     if (data->arg_array[ARG_ITALIC]) SetGadgetValue(data->list,GAD_FONT_ITALIC,1);
  71.     if (data->arg_array[ARG_ULINE]) SetGadgetValue(data->list,GAD_FONT_ULINE,1);
  72.  
  73.     // Show font
  74.     font_show_font(data,0);
  75.  
  76.     // Initialise refresh hook
  77.     data->refresh_hook.h_Entry=(ULONG (*)())font_refresh;
  78.     data->refresh_hook.h_Data=data;
  79.  
  80.     // Event loop
  81.     FOREVER
  82.     {
  83.         struct IntuiMessage *msg;
  84.         BOOL quit_flag=0;
  85.  
  86.         // AppWindow?
  87.         if (data->appwindow)
  88.         {
  89.             struct AppMessage *amsg;
  90.  
  91.             // Get messages
  92.             while (amsg=(struct AppMessage *)GetMsg(data->appport))
  93.             {
  94.                 // Got file?
  95.                 if (amsg->am_NumArgs>0)
  96.                 {
  97.                     char buf[256];
  98.  
  99.                     // Get name
  100.                     DevNameFromLock(amsg->am_ArgList[0].wa_Lock,buf,256);
  101.                     if (amsg->am_ArgList[0].wa_Name && *amsg->am_ArgList[0].wa_Name)
  102.                         AddPart(buf,amsg->am_ArgList[0].wa_Name,256);
  103.  
  104.                     // Get font name
  105.                     font_get_name(data,buf);
  106.  
  107.                     // Get new font
  108.                     font_get_font(data);
  109.                     font_show_font(data,0);
  110.                 }
  111.  
  112.                 // Reply to message
  113.                 ReplyMsg((struct Message *)amsg);
  114.             }
  115.         }
  116.  
  117.         // Requester?
  118.         if (data->about)
  119.         {
  120.             // Handle requester
  121.             if (SysReqHandler(data->about,0,0)>=0)
  122.             {
  123.                 // Close requester
  124.                 FreeSysRequest(data->about);
  125.                 data->about=0;
  126.             }
  127.         }
  128.  
  129.         // Intuition messages
  130.         if (data->window)
  131.         {
  132.             while (msg=GetWindowMsg(data->window->UserPort))
  133.             {
  134.                 struct IntuiMessage msg_copy;
  135.                 USHORT id;
  136.  
  137.                 // Copy message and reply
  138.                 msg_copy=*msg;
  139.                 ReplyWindowMsg(msg);
  140.  
  141.                 // Get gadget ID
  142.                 if (msg_copy.Class==IDCMP_GADGETUP)
  143.                     id=((struct Gadget *)msg_copy.IAddress)->GadgetID;
  144.  
  145.                 // Look at message
  146.                 switch (msg_copy.Class)
  147.                 {
  148.                     // Close window
  149.                     case IDCMP_CLOSEWINDOW:
  150.                         quit_flag=1;
  151.                         break;
  152.  
  153.  
  154.                     // New size
  155.                     case IDCMP_NEWSIZE:
  156.  
  157.                         // Redraw font
  158.                         font_show_font(data,0);
  159.  
  160.                         // Set flag to say we resized
  161.                         data->resized=1;
  162.                         break;
  163.  
  164.  
  165.                     // Menu
  166.                     case IDCMP_MENUPICK:
  167.                         {
  168.                             struct MenuItem *item;
  169.  
  170.                             // Get item
  171.                             if (!(item=ItemAddress(data->window->MenuStrip,msg_copy.Code)))
  172.                                 break;
  173.  
  174.                             // Get ID
  175.                             id=(USHORT)GTMENUITEM_USERDATA(item);
  176.  
  177.                             // Fall through
  178.                         }
  179.  
  180.                     // Gadget
  181.                     case IDCMP_GADGETUP:
  182.                         switch (id)
  183.                         {
  184.                             // Show requester
  185.                             case GAD_FONT_FONT_POPUP:
  186.                             case MENU_OPEN_FONT:
  187.  
  188.                                 // Ask for name
  189.                                 font_ask_name(data);
  190.                                 break;
  191.  
  192.  
  193.                             // Font name typed
  194.                             case GAD_FONT_FONT:
  195.  
  196.                                 // Get name
  197.                                 font_get_name(data,(char *)GetGadgetValue(data->list,GAD_FONT_FONT));
  198.  
  199.                                 // Get new font
  200.                                 font_get_font(data);
  201.                                 font_show_font(data,0);
  202.                                 break;
  203.  
  204.  
  205.                             // Font size up/down
  206.                             case GAD_FONT_UP:
  207.                             case GAD_FONT_DOWN:
  208.                                 {
  209.                                     short size;
  210.  
  211.                                     // Get next size
  212.                                     size=font_get_size(data,(id==GAD_FONT_UP)?1:-1);
  213.  
  214.                                     // No change?
  215.                                     if (size==data->font_size) break;
  216.  
  217.                                     // Use this size
  218.                                     data->font_size=size;
  219.                                     SetGadgetValue(data->list,GAD_FONT_SIZE,size);
  220.                                 }
  221.  
  222.                             // Font size given
  223.                             case GAD_FONT_CYCLE:
  224.  
  225.                                 // Check id
  226.                                 if (id==GAD_FONT_CYCLE)
  227.                                 {
  228.                                     short size;
  229.  
  230.                                     // Get size
  231.                                     if (!(size=atoi(data->size_labels[msg_copy.Code])))
  232.                                         break;
  233.  
  234.                                     // Refresh gadget
  235.                                     data->font_size=size;
  236.                                     SetGadgetValue(data->list,GAD_FONT_SIZE,data->font_size);
  237.                                 }
  238.  
  239.                             // Font size
  240.                             case GAD_FONT_SIZE:
  241.  
  242.                                 // Entered size
  243.                                 if (id==GAD_FONT_SIZE)
  244.                                 {
  245.                                     // Bounds check gadget
  246.                                     data->font_size=
  247.                                         BoundsCheckGadget(
  248.                                             data->list,
  249.                                             GAD_FONT_SIZE,
  250.                                             4,
  251.                                             255);
  252.                                 }
  253.  
  254.                                 // Get new font
  255.                                 font_get_font(data);
  256.                                 font_show_font(data,0);
  257.                                 break;
  258.  
  259.                             // Styles changed
  260.                             case GAD_FONT_BOLD:
  261.                             case GAD_FONT_ITALIC:
  262.                             case GAD_FONT_ULINE:
  263.  
  264.                                 // Redraw font
  265.                                 font_show_font(data,0);
  266.                                 break;
  267.  
  268.  
  269.                             // Save settings
  270.                             case MENU_SAVE_SETTINGS:
  271.                                 font_save_settings(data);
  272.                                 break;
  273.  
  274.  
  275.                             // Quit
  276.                             case MENU_QUIT:
  277.                                 quit_flag=1;
  278.                                 break;
  279.  
  280.  
  281.                             // About
  282.                             case MENU_ABOUT:
  283.                                 font_show_about(data);
  284.                                 break;
  285.                         }
  286.                         break;
  287.  
  288.  
  289.                     // Rawkey
  290.                     case IDCMP_RAWKEY:
  291.  
  292.                         // Help?
  293.                         if (msg_copy.Code==0x5f)
  294.                             font_show_about(data);
  295.  
  296.                     // Key
  297.                     case IDCMP_VANILLAKEY:
  298.  
  299.                         // Escape does quit
  300.                         if (msg_copy.Code==0x1b) quit_flag=1;
  301.                         break;
  302.  
  303.  
  304.                     // Refresh
  305.                     case IDCMP_REFRESHWINDOW:
  306.  
  307.                         // Have we just resized?
  308.                         if (data->resized)
  309.                         {
  310.                             // Don't need to refresh
  311.                             BeginRefresh(data->window);
  312.                             EndRefresh(data->window,TRUE);
  313.                             data->resized=0;
  314.                             break;
  315.                         }
  316.  
  317.                         // Refresh font display
  318.                         font_show_font(data,1);
  319.                         break;
  320.                 }
  321.  
  322.                 // Check window is still valid
  323.                 if (!data->window) break;
  324.             }
  325.         }
  326.  
  327.         if (quit_flag) break;
  328.  
  329.         // Wait for signal (ctrl-c breaks)
  330.         if ((Wait(SIGBREAKF_CTRL_C|
  331.                     ((data->window)?(1<<data->window->UserPort->mp_SigBit):0)|
  332.                     ((data->about)?(1<<data->about->UserPort->mp_SigBit):0)|
  333.                     ((data->appwindow)?(1<<data->appport->mp_SigBit):0)))&SIGBREAKF_CTRL_C) break;
  334.     }
  335.  
  336.     // Free stuff
  337.     font_free(data);
  338.     exit(0);
  339. }
  340.  
  341.  
  342. // Open font window
  343. BOOL font_open(font_data *data)
  344. {
  345.     struct Screen *screen=0;
  346.  
  347.     // Screen supplied?
  348.     if (data->arg_array[ARG_SCREEN])
  349.         screen=LockPubScreen((char *)data->arg_array[ARG_SCREEN]);    
  350.  
  351.     // Fill out new window
  352.     data->new_win.nw_Parent=screen;
  353.     data->new_win.nw_Dims=&data->win_dims;
  354.     data->new_win.nw_Title=DOpusGetString(&data->locale,MSG_FONT_TITLE);
  355.     data->new_win.nw_Locale=&data->locale;
  356.     data->new_win.nw_Flags=WINDOW_SCREEN_PARENT|WINDOW_VISITOR|WINDOW_AUTO_KEYS|WINDOW_SIZE_BOTTOM|WINDOW_SIMPLE;
  357.  
  358.     // Default dimensions
  359.     data->win_dims=font_window;
  360.  
  361.     // Read settings
  362.     font_read_settings(data);
  363.  
  364.     // Open window
  365.     if (data->window=OpenConfigWindow(&data->new_win))
  366.         data->list=AddObjectList(data->window,font_objects);
  367.  
  368.     // Unlock screen
  369.     UnlockPubScreen(0,screen);
  370.  
  371.     // Failed to open?
  372.     if (!data->list) return 0;
  373.  
  374.     // Fix sizing limits
  375.     WindowLimits(data->window,
  376.         (font_window.cw_CharDims.Width*data->window->RPort->TxWidth)+font_window.cw_FineDims.Width,
  377.         (font_window.cw_CharDims.Height*data->window->RPort->TxHeight)+font_window.cw_FineDims.Height,
  378.         ~0,~0);
  379.  
  380.     // Add menus
  381.     AddWindowMenus(data->window,font_menus);
  382.  
  383.     // Add AppWindow
  384.     if (data->appport)
  385.         data->appwindow=AddAppWindowA(0,0,data->window,data->appport,0);
  386.  
  387.     // Get the font
  388.     font_get_font(data);
  389.     return 1;
  390. }
  391.  
  392.  
  393. // Close font display
  394. void font_close(font_data *data)
  395. {
  396.     // Window open?
  397.     if (data->window)
  398.     {
  399.         // Remove AppWindow
  400.         RemoveAppWindow(data->appwindow);
  401.         data->appwindow=0;
  402.  
  403.         // Close requester
  404.         FreeSysRequest(data->about);
  405.         data->about=0;
  406.  
  407.         // Close window
  408.         CloseConfigWindow(data->window);
  409.         data->window=0;
  410.     }
  411. }
  412.  
  413.  
  414. // Free font data
  415. void font_free(font_data *data)
  416. {
  417.     if (data)
  418.     {
  419.         // Close stuff
  420.         font_close(data);
  421.  
  422.         // Free font
  423.         if (data->font) CloseFont(data->font);
  424.  
  425.         // Free port
  426.         DeleteMsgPort(data->appport);
  427.  
  428.         // Close locale stuff
  429.         if (data->locale.li_Locale)
  430.         {
  431.             CloseLocale(data->locale.li_Locale);
  432.             CloseCatalog(data->locale.li_Catalog);
  433.         }
  434.  
  435.         // Free args
  436.         FreeArgs(data->args);
  437.  
  438.         // Free labels
  439.         FreeMemH(data->size_labels);
  440.  
  441.         // Free data
  442.         FreeMemH(data);
  443.     }
  444.  
  445.     // Close library
  446.     CloseLibrary(DOpusBase);
  447. }
  448.  
  449.  
  450. // Get font
  451. void font_get_font(font_data *data)
  452. {
  453.     // Make window busy
  454.     SetWindowBusy(data->window);
  455.  
  456.     // Existing font?
  457.     if (data->font)
  458.     {
  459.         // Free font
  460.         CloseFont(data->font);
  461.         data->font=0;
  462.     }
  463.  
  464.     // Has the font name changed?
  465.     if (stricmp(data->font_name,data->last_font_name))
  466.     {
  467.         struct FontContentsHeader *fch;
  468.         BPTR lock;
  469.  
  470.         // Empty labels
  471.         font_build_labels(data,0);
  472.  
  473.         // Is the name a full path?
  474.         if (strchr(data->font_name,'/') || strchr(data->font_name,':'))
  475.         {
  476.             // Lock font
  477.             if (lock=Lock(data->font_name,ACCESS_READ))
  478.             {
  479.                 BPTR parent;
  480.  
  481.                 // Get lock on parent
  482.                 parent=ParentDir(lock);
  483.  
  484.                 // Unlock lock on file
  485.                 UnLock(lock);
  486.                 lock=parent;
  487.             }
  488.         }
  489.  
  490.         // Lock fonts: directory
  491.         else lock=Lock("fonts:",ACCESS_READ);
  492.  
  493.         // Got lock?
  494.         if (lock)
  495.         {
  496.             // Get font contents
  497.             if (fch=NewFontContents(lock,FilePart(data->font_name)))
  498.             {
  499.                 // Build labels
  500.                 font_build_labels(data,fch);
  501.  
  502.                 // Free contents
  503.                 DisposeFontContents(fch);
  504.             }
  505.  
  506.             // Unlock drawer
  507.             UnLock(lock);
  508.         }
  509.     }
  510.  
  511.     // Fill out TextAttr
  512.     data->attr.ta_Name=data->font_name;
  513.     data->attr.ta_YSize=data->font_size;
  514.     data->attr.ta_Style=0;
  515.     data->attr.ta_Flags=0;
  516.  
  517.     // Open font
  518.     data->font=OpenDiskFont(&data->attr);
  519.  
  520.     // Show font name and size
  521.     SetGadgetValue(data->list,GAD_FONT_FONT,(ULONG)FilePart(data->font_name));
  522.     SetGadgetValue(data->list,GAD_FONT_SIZE,data->font_size);
  523.  
  524.     // Got font?
  525.     if (data->font)
  526.     {
  527.         short ch,pos,hi;
  528.  
  529.         // First character
  530.         ch=data->font->tf_LoChar;
  531.         if (ch<33) ch=33;
  532.  
  533.         // Hi character
  534.         hi=data->font->tf_HiChar;
  535.         if (hi>126 && ch<127) hi=127;
  536.  
  537.         // Build display text
  538.         for (pos=0;ch<hi;ch++,pos++)
  539.             data->font_text[pos]=ch;
  540.         data->font_text[pos]=0;
  541.  
  542.         // Got labels?
  543.         if (data->size_labels)
  544.         {
  545.             // Find label corresponding to this size
  546.             for (pos=0;data->size_labels[pos];pos++)
  547.             {
  548.                 if (atoi(data->size_labels[pos])==data->font_size)
  549.                 {
  550.                     // Set cycle gadget
  551.                     SetGadgetValue(data->list,GAD_FONT_CYCLE,pos);
  552.                     break;
  553.                 }
  554.             }
  555.         }
  556.     }
  557.  
  558.     // Empty labels
  559.     else font_build_labels(data,0);
  560.  
  561.     // Copy name
  562.     strcpy(data->last_font_name,data->font_name);
  563.  
  564.     // Clear 'first' flag
  565.     data->first=0;
  566.  
  567.     // Clear window busy
  568.     ClearWindowBusy(data->window);
  569. }
  570.  
  571.  
  572. // Show font example
  573. void font_show_font(font_data *data,BOOL refresh)
  574. {
  575.     struct Rectangle rect;
  576.     struct Region *region;
  577.     struct RastPort rp;
  578.  
  579.     // Get display rectangle
  580.     GetObjectRect(data->list,GAD_FONT_DISPLAY,&rect);
  581.  
  582.     // Move rectangle in
  583.     rect.MinX+=3;
  584.     rect.MinY+=3;
  585.     rect.MaxX-=3;
  586.     rect.MaxY-=3;
  587.  
  588.     // Copy rastport
  589.     rp=*data->window->RPort;
  590.  
  591.     // Refresh?
  592.     if (refresh)
  593.     {
  594.         LockLayerInfo(&data->window->WScreen->LayerInfo);
  595.         BeginRefresh(data->window);
  596.     }
  597.  
  598.     // Clear background
  599.     SetAPen(&rp,DRAWINFO(data->window)->dri_Pens[SHINEPEN]);
  600.     RectFill(&rp,rect.MinX-1,rect.MinY-1,rect.MaxX+1,rect.MaxY+1);
  601.  
  602.     // Refreshing?
  603.     if (refresh) EndRefresh(data->window,FALSE);
  604.  
  605.     // Create region
  606.     if (region=NewRegion())
  607.     {
  608.         // Set rectangle
  609.         OrRectRegion(region,&rect);
  610.  
  611.         // Install region
  612.         InstallClipRegion(data->window->WLayer,region);
  613.     }
  614.  
  615.     // Refreshing?
  616.     if (refresh) BeginRefresh(data->window);
  617.  
  618.     // Got a font?
  619.     if (data->font)
  620.     {
  621.         ULONG flags;
  622.         short y;
  623.         struct TextExtent extent;
  624.         char *ptr,*end;
  625.  
  626.         // Set pen and font
  627.         SetAPen(&rp,DRAWINFO(data->window)->dri_Pens[TEXTPEN]);
  628.         SetDrMd(&rp,JAM1);
  629.         SetFont(&rp,data->font);
  630.  
  631.         // Get style flags
  632.         flags=0;
  633.         if (GetGadgetValue(data->list,GAD_FONT_BOLD)) flags|=FSF_BOLD;
  634.         if (GetGadgetValue(data->list,GAD_FONT_ITALIC)) flags|=FSF_ITALIC;
  635.         if (GetGadgetValue(data->list,GAD_FONT_ULINE)) flags|=FSF_UNDERLINED;
  636.  
  637.         // Set styles
  638.         SetSoftStyle(&rp,flags,FSF_BOLD|FSF_ITALIC|FSF_UNDERLINED);
  639.  
  640.         // Valid font to draw?
  641.         if (data->font_text[0])
  642.         {
  643.             // Get end of the string
  644.             end=data->font_text+strlen(data->font_text);
  645.  
  646.             // Initial coordinates
  647.             y=rect.MinY;
  648.  
  649.             // Initialise position
  650.             if (!(ptr=strchr(data->font_text,'A')))
  651.                 ptr=data->font_text;
  652.             Move(&rp,rect.MinX,y+rp.TxBaseline);
  653.  
  654.             // Draw until we reach the bottom
  655.             while (y<rect.MaxY)
  656.             {
  657.                 // New line
  658.                 if (rp.cp_x>rect.MaxX)
  659.                 {
  660.                     // Bump position
  661.                     y+=rp.TxHeight+1;
  662.                     Move(&rp,rect.MinX,y+rp.TxBaseline);
  663.                 }
  664.  
  665.                 // Otherwise
  666.                 else
  667.                 {
  668.                     short len,maxlen;
  669.  
  670.                     // Get text that will fit
  671.                     len=
  672.                         TextFit(
  673.                             &rp,
  674.                             ptr,
  675.                             (maxlen=strlen(ptr)),
  676.                             &extent,
  677.                             0,1,
  678.                             rect.MaxX-rp.cp_x+1,
  679.                             rp.TxHeight);
  680.  
  681.                     // Check against length, add extra character if ok
  682.                     if (len<maxlen) ++len;
  683.  
  684.                     // Draw text
  685.                     Text(&rp,ptr,len);
  686.  
  687.                     // Bump text position
  688.                     ptr+=len;
  689.  
  690.                     // End of the string?
  691.                     if (ptr>=end) ptr=data->font_text;
  692.                 }
  693.             }
  694.         }
  695.     }
  696.  
  697.     // Finished refreshing?
  698.     if (refresh) EndRefresh(data->window,TRUE);
  699.  
  700.     // Remove region
  701.     if (region)
  702.     {
  703.         InstallClipRegion(data->window->WLayer,0);
  704.         DisposeRegion(region);
  705.     }
  706.  
  707.     // Unlock layers if we refreshed
  708.     if (refresh) UnlockLayerInfo(&data->window->WScreen->LayerInfo);
  709. }
  710.  
  711.  
  712. // Get font name from string
  713. void font_get_name(font_data *data,char *name)
  714. {
  715.     short len;
  716.  
  717.     // .font suffix?
  718.     if ((len=strlen(name))>5 &&
  719.         stricmp(name+len-5,".font")==0)
  720.     {
  721.         // Use name as given
  722.         strcpy(data->font_name,name);
  723.     }
  724.  
  725.     // Numeric name?
  726.     else
  727.     if (len=atoi(FilePart(name)))
  728.     {
  729.         // Strip filename
  730.         *(PathPart(name))=0;
  731.  
  732.         // Store name
  733.         strcpy(data->font_name,name);
  734.         strcat(data->font_name,".font");
  735.  
  736.         // Store size
  737.         data->font_size=len;
  738.         data->first=1;
  739.     }
  740.  
  741.     // Name specified without .font
  742.     else
  743.     {
  744.         // Store name
  745.         strcpy(data->font_name,name);
  746.         strcat(data->font_name,".font");
  747.     }
  748. }
  749.  
  750.  
  751. // Ask for font name
  752. void font_ask_name(font_data *data)
  753. {
  754.     char file[40],path[256],*fileptr;
  755.  
  756.     // Copy path
  757.     strcpy(path,data->font_name);
  758.  
  759.     // Split filename
  760.     if (fileptr=FilePart(path))
  761.     {
  762.         strcpy(file,fileptr);
  763.         *fileptr=0;
  764.     }
  765.     else file[0]=0;
  766.  
  767.     // Empty path?
  768.     if (!path[0]) strcpy(path,"fonts:");
  769.  
  770.     // Busy window
  771.     SetWindowBusy(data->window);
  772.  
  773.     // Display requester
  774.     if (AslRequestTags(((WindowData *)data->window->UserData)->request,
  775.         ASLFR_Window,data->window,
  776.         ASLFR_TitleText,DOpusGetString(&data->locale,MSG_FONT_SELECT),
  777.         ASLFR_InitialFile,file,
  778.         ASLFR_InitialDrawer,path,
  779.         ASLFR_IntuiMsgFunc,&data->refresh_hook,
  780.         TAG_END))
  781.     {
  782.         // Get pathname
  783.         strcpy(path,((WindowData *)data->window->UserData)->request->fr_Drawer);
  784.         AddPart(path,((WindowData *)data->window->UserData)->request->fr_File,256);
  785.  
  786.         // Get font name
  787.         font_get_name(data,path);
  788.  
  789.         // Get new font
  790.         font_get_font(data);
  791.         font_show_font(data,0);
  792.     }
  793.  
  794.     // Unbusy window
  795.     else ClearWindowBusy(data->window);
  796. }
  797.  
  798.  
  799. // varargs AslRequestTags
  800. BOOL __stdargs AslRequestTags(
  801.     APTR req,
  802.     Tag tag1,...)
  803. {
  804.     return AslRequest(req,(struct TagItem *)&tag1);
  805. }
  806.  
  807.  
  808. // Refresh hook
  809. ULONG __asm __saveds font_refresh(
  810.     register __a0 struct Hook *hook,
  811.     register __a1 struct IntuiMessage *msg)
  812. {
  813.     font_data *data=(font_data *)hook->h_Data;
  814.  
  815.     // Refresh message?
  816.     if (msg->Class==IDCMP_REFRESHWINDOW)
  817.     {
  818.         // Do the refresh
  819.         font_show_font(data,1);
  820.     }
  821.  
  822.     // New size?
  823.     else
  824.     if (msg->Class==IDCMP_NEWSIZE)
  825.     {
  826.         // Handle resize
  827.         LayoutResize(data->window);
  828.  
  829.         // Redraw font
  830.         font_show_font(data,0);
  831.  
  832.         // Set flag to say we resized
  833.         data->resized=1;
  834.     }
  835.  
  836.     return (ULONG)msg;
  837. }
  838.  
  839.  
  840. // Get next font size
  841. short font_get_size(font_data *data,short dir)
  842. {
  843.     short size;
  844.  
  845.     // Current size
  846.     size=data->font_size;
  847.  
  848.     // Increment it
  849.     size+=dir;
  850.  
  851.     // Bounds check
  852.     if (size<2) size=2;
  853.     else
  854.     if (size>254) size=254;
  855.  
  856.     return size;
  857. }
  858.  
  859.  
  860. // Build size labels
  861. void font_build_labels(font_data *data,struct FontContentsHeader *fch)
  862. {
  863.     char **labels,*ptr;
  864.     short num=0,a,smallest=0;
  865.     struct FontContents *fc=0;
  866.     BOOL topaz=0;
  867.  
  868.     // Get number
  869.     if (fch) num=fch->fch_NumEntries;
  870.     if (num<1)
  871.     {
  872.         num=1;
  873.         fch=0;
  874.     }
  875.  
  876.     // Kludge for topaz
  877.     if (fch)
  878.     {
  879.         // Get first contents pointer
  880.         fc=(struct FontContents *)(fch+1);
  881.  
  882.         // Topaz?
  883.         if (strnicmp(fc->fc_FileName,"topaz/",6)==0)
  884.         {
  885.             // Add 8 and 9
  886.             num+=2;
  887.             topaz=1;
  888.         }
  889.     }
  890.  
  891.     // Allocate array and buffer
  892.     if (!(ptr=AllocMemH(0,(sizeof(char *)+8)*(num+1))))
  893.         return;
  894.  
  895.     // Get label array, bump pointer
  896.     labels=(char **)ptr;
  897.     ptr+=sizeof(char *)*(num+1);
  898.  
  899.     // No font contents?
  900.     if (!fc)
  901.     {
  902.         // Null label
  903.         labels[0]=ptr;
  904.         labels[1]=0;
  905.     }
  906.  
  907.     // Get label pointers, build labels
  908.     else
  909.     for (a=0;a<num;a++,ptr+=8)
  910.     {
  911.         // Get pointer
  912.         labels[a]=ptr;
  913.  
  914.         // Topaz kludge?
  915.         if (topaz && a<2)
  916.         {
  917.             short val=8+a;
  918.  
  919.             // Add 8 or 9
  920.             labels[a][0]='0'+val;
  921.             labels[a][1]=0;
  922.  
  923.             // Is this the smallest?
  924.             if (!smallest || val<smallest)
  925.                 smallest=val;
  926.         }
  927.  
  928.         // Normal font
  929.         else
  930.         {
  931.             // Add size
  932.             sprintf(labels[a],"%d",fc->fc_YSize);
  933.  
  934.             // Is this the smallest?
  935.             if (!smallest || fc->fc_YSize<smallest)
  936.                 smallest=fc->fc_YSize;
  937.  
  938.             // Bump contents pointer
  939.             fc++;
  940.         }
  941.     }
  942.  
  943.     // Use smallest as first size to show
  944.     if (!data->first && smallest) data->font_size=smallest;
  945.  
  946.     // Use new labels
  947.     SetGadgetChoices(data->list,GAD_FONT_CYCLE,labels);
  948.  
  949.     // Disable if no labels
  950.     DisableObject(data->list,GAD_FONT_CYCLE,(BOOL)!labels[1]);
  951.  
  952.     // Free old labels, store pointer
  953.     FreeMemH(data->size_labels);
  954.     data->size_labels=labels;
  955. }
  956.  
  957.  
  958. // Show about requester
  959. void font_show_about(font_data *data)
  960. {
  961.     struct EasyStruct easy;
  962.  
  963.     // Window open?
  964.     if (data->about)
  965.     {
  966.         WindowToFront(data->about);
  967.         ActivateWindow(data->about);
  968.         return;
  969.     }
  970.  
  971.     // Fill out easy struct
  972.     easy.es_StructSize=sizeof(easy);
  973.     easy.es_Flags=0;
  974.     easy.es_Title=0;
  975.     easy.es_TextFormat="Directory Opus 5 Font Viewer\nv55.0 (01.08.96)\n\n© 1996 Jonathan Potter";
  976.     easy.es_GadgetFormat=DOpusGetString(&data->locale,MSG_OK);
  977.  
  978.     // Open requester
  979.     data->about=BuildEasyRequest(data->window,&easy,0,0);
  980. }
  981.  
  982.  
  983. // Save settings
  984. void font_save_settings(font_data *data)
  985. {
  986.     char buf[80];
  987.  
  988.     // Set busy pointer
  989.     SetWindowBusy(data->window);
  990.  
  991.     // Build settings string
  992.     sprintf(buf,"%d/%d/%d/%d\n",
  993.         data->window->LeftEdge,
  994.         data->window->TopEdge,
  995.         data->window->GZZWidth,
  996.         data->window->Height-data->window->BorderTop-2);
  997.  
  998.     // Set variable
  999.     if (SetVar("dopus/Font Viewer",buf,-1,GVF_GLOBAL_ONLY))
  1000.     {
  1001.         // Copy to ENVARC:
  1002.         SystemTagList("copy \"env:dopus/Font Viewer\" envarc:dopus",0);
  1003.     }
  1004.  
  1005.     // Clear busy pointer
  1006.     ClearWindowBusy(data->window);
  1007. }
  1008.  
  1009.  
  1010. // Read settings
  1011. void font_read_settings(font_data *data)
  1012. {
  1013.     char buf[80],*ptr;
  1014.     struct IBox dims;
  1015.  
  1016.     // Get environment variable
  1017.     if (GetVar("dopus/Font Viewer",buf,sizeof(buf),GVF_GLOBAL_ONLY)<=0)
  1018.         return;
  1019.  
  1020.     // Get pointer to buffer
  1021.     ptr=buf;
  1022.  
  1023.     // Parse settings
  1024.     read_parse_set(&ptr,(USHORT *)&dims.Left);
  1025.     read_parse_set(&ptr,(USHORT *)&dims.Top);
  1026.     read_parse_set(&ptr,(USHORT *)&dims.Width);
  1027.     read_parse_set(&ptr,(USHORT *)&dims.Height);
  1028.  
  1029.     // Got valid size?
  1030.     if (dims.Height>0)
  1031.     {
  1032.         // Clear character coordinates
  1033.         data->win_dims.cw_CharDims.Top=0;
  1034.         data->win_dims.cw_CharDims.Left=0;
  1035.         data->win_dims.cw_CharDims.Width=0;
  1036.         data->win_dims.cw_CharDims.Height=0;
  1037.  
  1038.         // Set absolute coordinates
  1039.         data->win_dims.cw_FineDims=dims;
  1040.     }
  1041. }
  1042.  
  1043.  
  1044. // Parse number out of string, leave pointer at one character after end of number
  1045. void read_parse_set(char **ptr,unsigned short *val)
  1046. {
  1047.     // Digit?
  1048.     if (isdigit(*(*ptr)))
  1049.     {
  1050.         *val=atoi(*ptr);
  1051.         while (*(*ptr) && isdigit(*(*ptr))) ++*ptr;
  1052.         ++*ptr;
  1053.     }
  1054. }
  1055.