home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format 74 / af074a.adf / archives / af74a3.lzx / Typeface / Source / typeface.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-09  |  58.1 KB  |  2,296 lines

  1. /***********************/
  2. /*               */
  3. /* Typeface v1.0       */
  4. /* © 1995 David Kinder */
  5. /*               */
  6. /***********************/
  7.  
  8. #include "Typeface.h"
  9.  
  10. extern struct IntuitionBase *IntuitionBase;
  11. struct Library *AslBase, *BGUIBase, *DiskfontBase;
  12. struct Screen *Screen;
  13. struct Window *FontWnd, *OldWindowPtr;
  14. struct DrawInfo *ScrDrawInfo;
  15. struct List *CharWndList;
  16. struct MsgPort *WndMsgPort;
  17. struct Image *SizeImage, *LeftImage, *RightImage, *UpImage, *DownImage;
  18. struct TextFont *NewFont;
  19. struct FontRequester *FontReq;
  20. struct ScreenModeRequester *ScrReq;
  21. struct Character CharBuffer[257];
  22. struct Character ClipChar;
  23. struct IBox CharSize;
  24. struct NameInfo ModeIDName;
  25. Object *FontWndObj, *CharObj, *ScrollObj;
  26. Class *CharClass, *EditClass, *SlideClass;
  27. WORD SpaceTable[257], KernTable[257];
  28. ULONG FirstChar, LastChar;
  29. char WinTitle[256], FontPath[256], SavePath[256], FontName[256];
  30. BOOL CustomScreen = TRUE, ChangeScreen = FALSE, NewCustom, UseTable;
  31.  
  32. struct Preferences Prefs =
  33.   { 1,PREFS_CUSTOMSCREEN|PREFS_PIXELBORDER,0,2,11,20,20,0 };
  34. struct NewMenu menus[] = { PROJECT_MENU,End };
  35. char Version[] = "$VER:"NAME" 1.0 (29.5.95)";
  36.  
  37. struct Window *ParamWnd;
  38. Object *ParamWndObj, *PropCycle, *HeightInt, *WidthInt, *BaseInt, *SmearInt;
  39. Object *NormalCheck, *BoldCheck, *ItalicCheck, *UnderCheck;
  40. Object *ExtCheck, *RevCheck, *AspectCycle, *BlankButton;
  41. ULONG Proportional, Normal, Bold, Italic, ULine, Extended, Reversed;
  42. ULONG Height, Width, Baseline, Smear, Aspect;
  43.  
  44. struct Window *PrefsWnd;
  45. Object *PrefsWndObj;
  46. Object *CustButton, *ChooseButton, *ModeInfo;
  47. Object *VecInt, *PixelXInt, *PixelYInt, *PixelCheck;
  48. Object *SaveCycle;
  49. ULONG PrefScrModeID,PrefScrDepth;
  50. extern ULONG PixelBorder;
  51.  
  52. struct Window *AssignWnd;
  53. Object *AssignWndObj, *FontDirStr, *DirReqObj, *SaveReqObj;
  54.  
  55. struct Window *WidthWnd;
  56. struct Character *WidthChar;
  57. struct CharNode *WidthNode;
  58. Object *WidthWndObj, *ChrWidthScroll, *ChrWidthInt, *LeftInd, *RightInd;
  59. char WidthTitle[256];
  60.  
  61. struct Window *KernWnd;
  62. struct Character *KernChar;
  63. struct CharNode *KernNode;
  64. Object *KernWndObj, *SpaceObj, *KernObj;
  65. char KernTitle[256];
  66.  
  67. struct Window *SaveWnd;
  68. Object *SaveWndObj, *SaveDirStr, *FontNameStr, *SizeInfo;
  69. Object *FirstNum, *LastNum, *TableCheck;
  70.  
  71. main()
  72. {
  73.   Setup();
  74.   MsgLoop();
  75.   Quit();
  76. }
  77.  
  78. wbmain()
  79. {
  80.   main();
  81. }
  82.  
  83. void Setup(void)
  84. {
  85. struct Screen *defscr;
  86. static struct TextAttr topaz8 = { "topaz.font",8,FS_NORMAL,FPF_ROMFONT };
  87. BPTR lock;
  88.  
  89.   if (IntuitionBase->LibNode.lib_Version < 37) Quit();
  90.   if ((AslBase = OpenLibrary("asl.library",37)) == NULL)
  91.     Error("Cannot open asl.library v37+.");
  92.   if ((BGUIBase = OpenLibrary("bgui.library",38)) == NULL)
  93.   {
  94.     if ((BGUIBase = OpenLibrary("PROGDIR:libs/bgui.library",38)) == NULL)
  95.       Error("Cannot open bgui.library v38+.");
  96.   }
  97.   if ((DiskfontBase = OpenLibrary("diskfont.library",36)) == NULL)
  98.     Error("Cannot open diskfont.library v36+.");
  99.   if ((FontReq = AllocAslRequestTags(ASL_FontRequest,
  100.     ASLFO_TitleText,"Open Font",
  101.     ASLFO_MaxHeight,1000,TAG_DONE)) == NULL) Quit();
  102.   if (AslBase->lib_Version > 37)
  103.   {
  104.     if ((ScrReq = AllocAslRequestTags(ASL_ScreenModeRequest,
  105.       ASLSM_TitleText,"Change Screen Mode",
  106.       ASLSM_DoDepth,TRUE,TAG_DONE)) == NULL) Quit();
  107.   }
  108.   if ((CharClass = InitCharGadgClass()) == NULL) Quit();
  109.   if ((EditClass = InitEditGadgClass()) == NULL) Quit();
  110.   if ((SlideClass = InitSlideGadgClass()) == NULL) Quit();
  111.   if (GetNewList(&CharWndList) == NULL) Quit();
  112.   if ((WndMsgPort = CreateMsgPort()) == NULL) Quit();
  113.  
  114.   if ((defscr = LockPubScreen(NULL)) == NULL) Quit();
  115.   Prefs.ScrModeID = GetVPModeID(&defscr->ViewPort);
  116.   UnlockPubScreen(NULL,defscr);
  117.   LoadPrefs();
  118.   SetupScreen();
  119.   strcpy(FontPath,"FONTS:");
  120.   if (lock = Lock("FONTS:",ACCESS_READ))
  121.   {
  122.     NameFromLock(lock,FontPath,256);
  123.     UnLock(lock);
  124.   }
  125.   strcpy(SavePath,FontPath);
  126.   LoadFont(&topaz8);
  127. }
  128.  
  129. void SetupScreen(void)
  130. {
  131. UWORD pens[] = { ~0 };
  132. struct IBox box = { 0,0,0,0 };
  133.  
  134.   if (CustomScreen)
  135.   {
  136.     if ((Screen = OpenScreenTags(NULL,
  137.       SA_Depth,Prefs.ScrDepth,
  138.       SA_DisplayID,Prefs.ScrModeID,
  139.       SA_Pens,pens,
  140.       SA_Title,NAME,
  141.       SA_PubName,NAME,
  142.       SA_AutoScroll,TRUE,
  143.       SA_SysFont,TRUE,
  144.       TAG_DONE)) == NULL) Quit();
  145.   }
  146.   else
  147.   {
  148.     if ((Screen = LockPubScreen(NULL)) == NULL) Quit();
  149.   }
  150.   if ((ScrDrawInfo = GetScreenDrawInfo(Screen)) == NULL) Quit();
  151.   SizeImage = CreateSysImage(SIZEIMAGE,ScrDrawInfo);
  152.   LeftImage = CreateSysImage(LEFTIMAGE,ScrDrawInfo);
  153.   RightImage = CreateSysImage(RIGHTIMAGE,ScrDrawInfo);
  154.   UpImage = CreateSysImage(UPIMAGE,ScrDrawInfo);
  155.   DownImage = CreateSysImage(DOWNIMAGE,ScrDrawInfo);
  156.  
  157.   box.Top = Screen->BarHeight+1;
  158.   FontWndObj = WindowObject,
  159.     WINDOW_Screen,Screen,
  160.     WINDOW_SharedPort,WndMsgPort,
  161.     WINDOW_MenuStrip,menus,
  162.     WINDOW_Bounds,&box,
  163.     WINDOW_HelpFile,NAME".guide",
  164.     WINDOW_SmartRefresh,TRUE,
  165.     WINDOW_NoBufferRP,TRUE,
  166.     WINDOW_SizeGadget,FALSE,
  167.     WINDOW_MasterGroup,
  168.       HGroupObject,
  169.     HOffset(4),VOffset(2),Spacing(2),
  170.     StartMember,
  171.       CharObj = ExternalObject,
  172.         EXT_MinWidth,GetCharGadgWidth()-2,
  173.         EXT_MinHeight,GetCharGadgHeight()-2,
  174.         EXT_Class,CharClass,
  175.         EXT_NoRebuild,TRUE,
  176.         GA_ID,ID_CHARS,
  177.       EndObject,
  178.     EndMember,
  179.     StartMember,
  180.       ScrollObj = PropObject,
  181.         PGA_Top,0,
  182.         PGA_Total,4,
  183.         PGA_Visible,1,
  184.         PGA_Arrows,TRUE,
  185.         GA_ID,ID_CHARSCROLL,
  186.       EndObject,
  187.     EndMember,
  188.       EndObject,
  189.     EndObject;
  190.   if (FontWndObj == NULL) Quit();
  191.   if ((FontWnd = WindowOpen(FontWndObj)) == NULL)
  192.     Error("Cannot open window.");
  193.   OldWindowPtr = ((struct Process *)FindTask(NULL))->pr_WindowPtr;
  194.   ((struct Process *)FindTask(NULL))->pr_WindowPtr = FontWnd;
  195.  
  196.   GetAttr(WINDOW_Bounds,FontWndObj,&CharSize);
  197.   CharSize.Left += (CharSize.Width + Screen->RastPort.Font->tf_YSize);
  198.   CharSize.Width = Screen->Width - CharSize.Left;
  199.   CharSize.Height = Screen->Height - CharSize.Top;
  200. }
  201.  
  202. void Quit(void)
  203. {
  204.   QuitScreen();
  205.   RemoveList(&CharWndList,TRUE,NULL);
  206.   ClearCurrentFont();
  207.   if (ClipChar.chr_Data) FreeVec(ClipChar.chr_Data);
  208.   if (NewFont) CloseFont(NewFont);
  209.   if (WndMsgPort) DeleteMsgPort(WndMsgPort);
  210.   if (SlideClass) FreeEditGadgClass(SlideClass);
  211.   if (EditClass) FreeEditGadgClass(EditClass);
  212.   if (CharClass) FreeCharGadgClass(CharClass);
  213.   if (ScrReq) FreeAslRequest(ScrReq);
  214.   if (FontReq) FreeAslRequest(FontReq);
  215.   if (DiskfontBase) CloseLibrary(DiskfontBase);
  216.   if (BGUIBase) CloseLibrary(BGUIBase);
  217.   if (AslBase) CloseLibrary(AslBase);
  218.   exit(0);
  219. }
  220.  
  221. void QuitScreen(void)
  222. {
  223.   WakeWindows();
  224.   RemoveList(&CharWndList,FALSE,&CloseCharWin);
  225.   if (FontWnd)
  226.     ((struct Process *)FindTask(NULL))->pr_WindowPtr = OldWindowPtr;
  227.   ClrWindowClose(&FontWndObj,&FontWnd);
  228.   ClrDisposeObject(&FontWndObj);
  229.   CloseEditFontWnd(TRUE);
  230.   ClosePrefsWnd(TRUE);
  231.   CloseAssignWnd(TRUE);
  232.   CloseWidthWnd(TRUE);
  233.   CloseKernWnd(TRUE);
  234.   CloseSaveWnd(TRUE);
  235.   ClrDisposeObject(&DirReqObj);
  236.   ClrDisposeObject(&SaveReqObj);
  237.   ClrDisposeObject(&SizeImage);
  238.   ClrDisposeObject(&LeftImage);
  239.   ClrDisposeObject(&RightImage);
  240.   ClrDisposeObject(&UpImage);
  241.   ClrDisposeObject(&DownImage);
  242.   if (ScrDrawInfo)
  243.   {
  244.     FreeScreenDrawInfo(Screen,ScrDrawInfo);
  245.     ScrDrawInfo = NULL;
  246.   }
  247.   if (Screen)
  248.   {
  249.     if (CustomScreen)
  250.       CloseScreen(Screen);
  251.     else
  252.       UnlockPubScreen(NULL,Screen);
  253.     Screen = NULL;
  254.   }
  255. }
  256.  
  257. void MsgLoop(void)
  258. {
  259. ULONG signal,winsig,code,scroll_pos,pressed,old_height,left,first,last;
  260. LONG temp,normal;
  261. BOOL free_node,redraw = FALSE;
  262. struct CharNode *node,*oldnode;
  263. Object *charobj;
  264. char *fontstr;
  265. BPTR lock;
  266.  
  267.   GetAttr(WINDOW_SigMask,FontWndObj,&winsig);
  268.   GetAttr(EXT_Object,CharObj,&charobj);
  269.   while (TRUE)
  270.   {
  271.     signal = Wait(winsig|SIGBREAKF_CTRL_C);
  272.     if (signal & SIGBREAKF_CTRL_C) Quit();
  273.     if (signal & winsig)
  274.     {
  275.       while ((code = CheckObjMsg(FontWnd,FontWndObj)) != WMHI_NOMORE)
  276.       {
  277.     switch (code)
  278.     {
  279.       case WMHI_CLOSEWINDOW:
  280.         Quit();
  281.         break;
  282.       case ID_CHARSCROLL:
  283.         GetAttr(PGA_TOP,ScrollObj,&scroll_pos);
  284.         SetGadgetAttrs(charobj,FontWnd,NULL,CG_Pos,scroll_pos,TAG_DONE);
  285.         break;
  286.       case ID_CHARS:
  287.         GetAttr(CG_Pressed,charobj,&pressed);
  288.         SetGadgetAttrs(charobj,FontWnd,NULL,CG_Pressed,~0,TAG_DONE);
  289.         if (pressed != ~0) CheckOpenCharWin(pressed);
  290.         break;
  291.       default:
  292.         SharedMsgs(code,NULL);
  293.         break;
  294.     }
  295.       }
  296.       while ((code = CheckObjMsg(ParamWnd,ParamWndObj)) != WMHI_NOMORE)
  297.       {
  298.     switch (code)
  299.     {
  300.       case WMHI_CLOSEWINDOW:
  301.       case ID_CANCEL:
  302.         CloseEditFontWnd(FALSE);
  303.         break;
  304.       case ID_BOLD:
  305.       case ID_ITALIC:
  306.       case ID_ULINE:
  307.       case ID_EXTEND:
  308.         GetAttr(GA_Selected,BoldCheck,&normal);
  309.         GetAttr(GA_Selected,ItalicCheck,&temp);
  310.         normal |= temp;
  311.         GetAttr(GA_Selected,UnderCheck,&temp);
  312.         normal |= temp;
  313.         GetAttr(GA_Selected,ExtCheck,&temp);
  314.         normal |= temp;
  315.         SetGadgetAttrs(NormalCheck,ParamWnd,NULL,
  316.           GA_Selected,normal == 0,TAG_DONE);
  317.         break;
  318.       case ID_NORMAL:
  319.         SetGadgetAttrs(BoldCheck,ParamWnd,NULL,
  320.           GA_Selected,FALSE,TAG_DONE);
  321.         SetGadgetAttrs(ItalicCheck,ParamWnd,NULL,
  322.           GA_Selected,FALSE,TAG_DONE);
  323.         SetGadgetAttrs(UnderCheck,ParamWnd,NULL,
  324.           GA_Selected,FALSE,TAG_DONE);
  325.         SetGadgetAttrs(ExtCheck,ParamWnd,NULL,
  326.           GA_Selected,FALSE,TAG_DONE);
  327.         break;
  328.       case ID_BLANK:
  329.         CheckOpenCharWin(256);
  330.         break;
  331.       case ID_ACCEPT:
  332.         GetAttr(GA_Selected,NormalCheck,&Normal);
  333.         GetAttr(GA_Selected,BoldCheck,&Bold);
  334.         GetAttr(GA_Selected,ItalicCheck,&Italic);
  335.         GetAttr(GA_Selected,UnderCheck,&ULine);
  336.         GetAttr(GA_Selected,ExtCheck,&Extended);
  337.         GetAttr(GA_Selected,RevCheck,&Reversed);
  338.         GetAttr(CYC_Active,AspectCycle,&Aspect);
  339.  
  340.         GetAttr(STRINGA_LongVal,SmearInt,&temp);
  341.         PutPositive(ParamWnd,"bold smear",temp,0,&Smear);
  342.  
  343.         GetAttr(STRINGA_LongVal,HeightInt,&temp);
  344.         old_height = Height;
  345.         PutPositive(ParamWnd,"font height",temp,1,&Height);
  346.         if (old_height != Height)
  347.         {
  348.           redraw = TRUE;
  349.           NewHeights();
  350.         }
  351.  
  352.         GetAttr(STRINGA_LongVal,BaseInt,&temp);
  353.         if (temp >= (LONG)Height)
  354.         {
  355.           if (redraw)
  356.         Baseline = Height-1;
  357.           else
  358.         ShowReq("The font baseline must be\n"
  359.           "less than the font height.","Continue");
  360.         }
  361.         else PutPositive(ParamWnd,"font baseline",temp,0,&Baseline);
  362.  
  363.         GetAttr(CYC_Active,PropCycle,&temp);
  364.         if (temp != Proportional)
  365.         {
  366.           if ((Proportional = temp) == FALSE)
  367.           {
  368.         redraw = TRUE;
  369.         NewWidths();
  370.           }
  371.         }
  372.  
  373.         GetAttr(STRINGA_LongVal,WidthInt,&temp);
  374.         if (temp >= 0)
  375.         {
  376.           if (temp != Width)
  377.           {
  378.         Width = temp;
  379.         if (Proportional == FALSE)
  380.         {
  381.           redraw = TRUE;
  382.           NewWidths();
  383.         }
  384.           }
  385.         }
  386.         else ShowReq("The font width must be positive.","Continue");
  387.  
  388.         CloseEditFontWnd(FALSE);
  389.         if (redraw == TRUE)
  390.         {
  391.           node = CharWndList->lh_Head;
  392.           while (node->chln_Node.ln_Succ)
  393.           {
  394.         RedrawEdit(node);
  395.         node = node->chln_Node.ln_Succ;
  396.           }
  397.           redraw = FALSE;
  398.         }
  399.         break;
  400.       default:
  401.         SharedMsgs(code,NULL);
  402.         break;
  403.     }
  404.       }
  405.       while ((code = CheckObjMsg(PrefsWnd,PrefsWndObj)) != WMHI_NOMORE)
  406.       {
  407.     switch (code)
  408.     {
  409.       case WMHI_CLOSEWINDOW:
  410.       case ID_CANCEL:
  411.         ClosePrefsWnd(FALSE);
  412.         break;
  413.       case ID_CUSTOM:
  414.         GetAttr(GA_Selected,CustButton,&temp);
  415.         SetGadgetAttrs(ChooseButton,PrefsWnd,NULL,
  416.           GA_Disabled,(temp == TRUE) ? FALSE : TRUE,TAG_DONE);
  417.         break;
  418.       case ID_CHOOSE:
  419.         SleepWindows();
  420.         if (AslBase->lib_Version > 37)
  421.         {
  422.           if (AslRequestTags(ScrReq,
  423.         ASLSM_Window,FontWnd,
  424.         ASLSM_InitialDisplayID,PrefScrModeID,
  425.         ASLSM_InitialDisplayDepth,PrefScrDepth,TAG_DONE))
  426.           {
  427.         PrefScrModeID = ScrReq->sm_DisplayID;
  428.         PrefScrDepth = ScrReq->sm_DisplayDepth;
  429.         GetDisplayInfoData(NULL,&ModeIDName,
  430.           sizeof(struct NameInfo),DTAG_NAME,PrefScrModeID);
  431.         SetGadgetAttrs(ModeInfo,PrefsWnd,NULL,
  432.           INFO_TextFormat,ModeIDName.Name,TAG_DONE);
  433.           }
  434.         }
  435.         else ShowReq("asl.library v38 or higher required.","Cancel");
  436.         WakeWindows();
  437.         break;
  438.       case ID_ACCEPT:
  439.       case ID_USE:
  440.         NewCustom = CustomScreen;
  441.         GetAttr(GA_Selected,CustButton,&temp);
  442.         if (temp != CustomScreen)
  443.         {
  444.           ChangeScreen = TRUE;
  445.           NewCustom = (CustomScreen == TRUE) ? FALSE : TRUE;
  446.         }
  447.         if (temp == TRUE)
  448.         {
  449.           if ((PrefScrModeID != Prefs.ScrModeID) ||
  450.         (PrefScrDepth != Prefs.ScrDepth))
  451.           {
  452.         ChangeScreen = TRUE;
  453.         NewCustom = TRUE;
  454.           }
  455.         }
  456.         Prefs.ScrModeID = PrefScrModeID;
  457.         Prefs.ScrDepth = PrefScrDepth;
  458.  
  459.         GetAttr(STRINGA_LongVal,VecInt,&temp);
  460.         PutPositive(PrefsWnd,"tool bar height",temp,10,
  461.           &(Prefs.VecHeight));
  462.         GetAttr(STRINGA_LongVal,PixelXInt,&temp);
  463.         PutPositive(PrefsWnd,"pixel width",temp,1,&(Prefs.PixelX));
  464.         GetAttr(STRINGA_LongVal,PixelYInt,&temp);
  465.         PutPositive(PrefsWnd,"pixel height",temp,1,&(Prefs.PixelY));
  466.         GetAttr(GA_Selected,PixelCheck,&PixelBorder);
  467.  
  468.         GetAttr(CYC_Active,SaveCycle,&(Prefs.SaveTo));
  469.         if (code == ID_ACCEPT)
  470.         {
  471.           if (Prefs.SaveTo == 0)
  472.           {
  473.         SavePrefs("ENV:"NAME".prefs");
  474.         SavePrefs("ENVARC:"NAME".prefs");
  475.           }
  476.           else SavePrefs("PROGDIR:"NAME".prefs");
  477.         }
  478.         ClosePrefsWnd(FALSE);
  479.         break;
  480.       default:
  481.         SharedMsgs(code,NULL);
  482.         break;
  483.     }
  484.       }
  485.       while ((code = CheckObjMsg(AssignWnd,AssignWndObj)) != WMHI_NOMORE)
  486.       {
  487.     switch (code)
  488.     {
  489.       case WMHI_CLOSEWINDOW:
  490.       case ID_CANCEL:
  491.         CloseAssignWnd(FALSE);
  492.         break;
  493.       case ID_ASSIGN:
  494.       case ID_ASSIGNADD:
  495.         GetAttr(STRINGA_TextVal,FontDirStr,&fontstr);
  496.         strcpy(FontPath,fontstr);
  497.         SleepWindows();
  498.         if ((lock = Lock(FontPath,ACCESS_READ)) != 0)
  499.         {
  500.           if (code == ID_ASSIGNADD)
  501.         AssignAdd("FONTS",lock);
  502.           else
  503.         AssignLock("FONTS",lock);
  504.           strcpy(SavePath,FontPath);
  505.           FlushAllFonts();
  506.         }
  507.         else ShowReq("Cannot find directory\n\"%s\"","Cancel",FontPath);
  508.         WakeWindows();
  509.         CloseAssignWnd(FALSE);
  510.         break;
  511.       case ID_ASSIGNPATH:
  512.         SleepWindows();
  513.         GetAttr(STRINGA_TextVal,FontDirStr,&fontstr);
  514.         SetAttrs(DirReqObj,ASLFR_InitialDrawer,fontstr,TAG_DONE);
  515.         if (DoRequest(DirReqObj) == FRQ_OK)
  516.         {
  517.           GetAttr(FRQ_Drawer,DirReqObj,&fontstr);
  518.           SetGadgetAttrs(FontDirStr,AssignWnd,NULL,
  519.         STRINGA_TextVal,fontstr,TAG_DONE);
  520.         }
  521.         WakeWindows();
  522.         break;
  523.       default:
  524.         SharedMsgs(code,NULL);
  525.         break;
  526.     }
  527.       }
  528.       while ((code = CheckObjMsg(WidthWnd,WidthWndObj)) != WMHI_NOMORE)
  529.       {
  530.     switch (code)
  531.     {
  532.       case WMHI_CLOSEWINDOW:
  533.       case ID_CANCEL:
  534.         CloseWidthWnd(FALSE);
  535.         break;
  536.       case ID_ACCEPT:
  537.         GetAttr(STRINGA_LongVal,ChrWidthInt,&temp);
  538.         GetAttr(PGA_Top,ChrWidthScroll,&left);
  539.         if (temp >= 0)
  540.         {
  541.           if (temp > WidthChar->chr_Width)
  542.         ChangeCharWidth(WidthChar,temp,left,0);
  543.           else
  544.         ChangeCharWidth(WidthChar,temp,0,left);
  545.           RedrawEdit(WidthNode);
  546.         }
  547.         else ShowReq("The font width must be positive.","Continue");
  548.         CloseWidthWnd(FALSE);
  549.         break;
  550.       case ID_CHARWIDTH:
  551.         GetAttr(STRINGA_LongVal,ChrWidthInt,&temp);
  552.         if (temp >= 0)
  553.         {
  554.           SetGadgetAttrs(ChrWidthScroll,WidthWnd,NULL,
  555.         PGA_Total,MAX(WidthChar->chr_Width,temp),
  556.         PGA_Visible,MIN(WidthChar->chr_Width,temp),TAG_DONE);
  557.         }
  558.         else
  559.         {
  560.           ShowReq("The font width must be positive.","Continue");
  561.           SetGadgetAttrs(ChrWidthInt,WidthWnd,NULL,
  562.         STRINGA_LongVal,WidthChar->chr_Width,TAG_DONE);
  563.         }
  564.         break;
  565.       default:
  566.         SharedMsgs(code,WidthNode);
  567.         break;
  568.     }
  569.       }
  570.       while ((code = CheckObjMsg(KernWnd,KernWndObj)) != WMHI_NOMORE)
  571.       {
  572.     switch (code)
  573.     {
  574.       case WMHI_CLOSEWINDOW:
  575.       case ID_CANCEL:
  576.         CloseKernWnd(FALSE);
  577.         break;
  578.       case ID_ACCEPT:
  579.         GetAttr(STRINGA_LongVal,SpaceObj,&temp);
  580.         SpaceTable[KernNode->chln_Number] = temp;
  581.         GetAttr(STRINGA_LongVal,KernObj,&temp);
  582.         KernTable[KernNode->chln_Number] = temp;
  583.         CloseKernWnd(FALSE);
  584.         break;
  585.       default:
  586.         SharedMsgs(code,KernNode);
  587.         break;
  588.     }
  589.       }
  590.       while ((code = CheckObjMsg(SaveWnd,SaveWndObj)) != WMHI_NOMORE)
  591.       {
  592.     switch (code)
  593.     {
  594.       case WMHI_CLOSEWINDOW:
  595.       case ID_CANCEL:
  596.         CloseSaveWnd(FALSE);
  597.         break;
  598.       case ID_ACCEPT:
  599.         GetAttr(STRINGA_LongVal,FirstNum,&first);
  600.         if ((first < 0) || (first > 255)) SaveShowReq("The first "
  601.           "character must be between 0 and 255.","Cancel");
  602.         else
  603.         {
  604.           GetAttr(STRINGA_LongVal,LastNum,&last);
  605.           if ((last < 0) || (last > 255)) SaveShowReq("The first "
  606.         "character must be between 0 and 255.","Cancel");
  607.           else
  608.           {
  609.         if (first > last) SaveShowReq("The first character "
  610.           "cannot be greater than the last.","Cancel");
  611.         else
  612.         {
  613.           FirstChar = first;
  614.           LastChar = last;
  615.           GetAttr(STRINGA_TextVal,SaveDirStr,&fontstr);
  616.           strcpy(SavePath,fontstr);
  617.           GetAttr(STRINGA_TextVal,FontNameStr,&fontstr);
  618.           strcpy(FontName,fontstr);
  619.           GetAttr(GA_Selected,TableCheck,&temp);
  620.           SaveFont(temp);
  621.           sprintf(WinTitle,"%s/%ld",FontName,Height);
  622.           SetAttrs(FontWndObj,WINDOW_Title,WinTitle,TAG_DONE);
  623.         }
  624.           }
  625.         }
  626.         CloseSaveWnd(FALSE);
  627.         break;
  628.       case ID_GETSAVEDIR:
  629.         GetAttr(STRINGA_TextVal,SaveDirStr,&fontstr);
  630.         SetAttrs(SaveReqObj,
  631.           ASLFR_Window,SaveWnd,
  632.           ASLFR_InitialDrawer,fontstr,TAG_DONE);
  633.         WindowBusy(SaveWndObj);
  634.         if (DoRequest(SaveReqObj) == FRQ_OK)
  635.         {
  636.           GetAttr(FRQ_Drawer,SaveReqObj,&fontstr);
  637.           SetGadgetAttrs(SaveDirStr,SaveWnd,NULL,
  638.         STRINGA_TextVal,fontstr,TAG_DONE);
  639.         }
  640.         WindowReady(SaveWndObj);
  641.         break;
  642.     }
  643.       }
  644.       node = CharWndList->lh_Head;
  645.       while (node->chln_Node.ln_Succ)
  646.       {
  647.     free_node = FALSE;
  648.     while ((code =
  649.       CheckObjMsg(node->chln_Window,node->chln_Object)) != WMHI_NOMORE)
  650.     {
  651.       switch (code)
  652.       {
  653.         case WMHI_CLOSEWINDOW:
  654.           CloseCharWin(node);
  655.           free_node = TRUE;
  656.           break;
  657.         default:
  658.           SharedMsgs(code,node);
  659.           break;
  660.       }
  661.     }
  662.     oldnode = node;
  663.     node = node->chln_Node.ln_Succ;
  664.     if (free_node)
  665.     {
  666.       Remove(oldnode);
  667.       FreeVec(oldnode);
  668.     }
  669.       }
  670.     }
  671.     if (ChangeScreen)
  672.     {
  673.       QuitScreen();
  674.       CustomScreen = NewCustom;
  675.       SetupScreen();
  676.       SetAttrs(FontWndObj,WINDOW_Title,WinTitle,TAG_DONE);
  677.       GetAttr(WINDOW_SigMask,FontWndObj,&winsig);
  678.       GetAttr(EXT_Object,CharObj,&charobj);
  679.       ChangeScreen = FALSE;
  680.     }
  681.   }
  682. }
  683.  
  684. ULONG CheckObjMsg(struct Window *wnd, Object *obj)
  685. {
  686.   return ((wnd != NULL) ? HandleEvent(obj) : WMHI_NOMORE);
  687. }
  688.  
  689. void CheckOpenCharWin(ULONG pressed)
  690. {
  691. struct CharNode *node;
  692. BOOL open = FALSE;
  693.  
  694.   node = CharWndList->lh_Head;
  695.   while (node->chln_Node.ln_Succ)
  696.   {
  697.     if (pressed == node->chln_Number)
  698.     {
  699.       open = TRUE;
  700.       WindowToFront(node->chln_Window);
  701.       ActivateWindow(node->chln_Window);
  702.     }
  703.     node = node->chln_Node.ln_Succ;
  704.   }
  705.   if (open == FALSE) OpenCharWin(pressed,CharSize);
  706. }
  707.  
  708. void SharedMsgs(ULONG code,struct CharNode *node)
  709. {
  710.   switch (code)
  711.   {
  712.     case ID_OPEN:
  713.       SleepWindows();
  714.       if (AslRequestTags(FontReq,ASLFO_Window,FontWnd,TAG_DONE))
  715.       {
  716.     LoadFont(&FontReq->fo_Attr);
  717.     WakeWindows();
  718.     if (ParamWnd)
  719.     {
  720.       SetGadgetAttrs(PropCycle,ParamWnd,NULL,
  721.         CYC_Active,Proportional,TAG_DONE);
  722.       SetGadgetAttrs(HeightInt,ParamWnd,NULL,
  723.         STRINGA_LongVal,Height,TAG_DONE);
  724.       SetGadgetAttrs(WidthInt,ParamWnd,NULL,
  725.         STRINGA_LongVal,Width,TAG_DONE);
  726.       SetGadgetAttrs(BaseInt,ParamWnd,NULL,
  727.         STRINGA_LongVal,Baseline,TAG_DONE);
  728.       SetGadgetAttrs(SmearInt,ParamWnd,NULL,
  729.         STRINGA_LongVal,Smear,TAG_DONE);
  730.       SetGadgetAttrs(NormalCheck,ParamWnd,NULL,
  731.         GA_Selected,Normal,TAG_DONE);
  732.       SetGadgetAttrs(BoldCheck,ParamWnd,NULL,
  733.         GA_Selected,Bold,TAG_DONE);
  734.       SetGadgetAttrs(ItalicCheck,ParamWnd,NULL,
  735.         GA_Selected,Italic,TAG_DONE);
  736.       SetGadgetAttrs(UnderCheck,ParamWnd,NULL,
  737.         GA_Selected,ULine,TAG_DONE);
  738.       SetGadgetAttrs(ExtCheck,ParamWnd,NULL,
  739.         GA_Selected,Extended,TAG_DONE);
  740.       SetGadgetAttrs(RevCheck,ParamWnd,NULL,
  741.         GA_Selected,Reversed,TAG_DONE);
  742.       SetGadgetAttrs(AspectCycle,ParamWnd,NULL,
  743.         CYC_Active,Aspect,TAG_DONE);
  744.     }
  745.     node = CharWndList->lh_Head;
  746.     while (node->chln_Node.ln_Succ)
  747.     {
  748.       RedrawEdit(node);
  749.       CheckWidthKern(node->chln_Character);
  750.       node = node->chln_Node.ln_Succ;
  751.     }
  752.       }
  753.       else WakeWindows();
  754.       break;
  755.     case ID_SAVE:
  756.       OpenSaveWnd();
  757.       break;
  758.     case ID_CHANGEDIR:
  759.       OpenAssignWnd();
  760.       break;
  761.     case ID_EDITFONT:
  762.       OpenEditFontWnd();
  763.       break;
  764.     case ID_PREFS:
  765.       OpenPrefsWnd();
  766.       break;
  767.     case ID_ABOUT:
  768.       ShowReq(NAME" v1.0\n© 1995 David Kinder","Continue");
  769.       break;
  770.     case ID_QUIT:
  771.       Quit();
  772.       break;
  773.     case ID_WIDTHL:
  774.       if (node)
  775.       {
  776.     if (node->chln_Character->chr_Width > 0)
  777.     {
  778.       ChangeCharWidth(node->chln_Character,
  779.         node->chln_Character->chr_Width-1,0,0);
  780.       RedrawEdit(node);
  781.     }
  782.       }
  783.       break;
  784.     case ID_WIDTHR:
  785.       if (node)
  786.       {
  787.     ChangeCharWidth(node->chln_Character,
  788.       node->chln_Character->chr_Width+1,0,0);
  789.       RedrawEdit(node);
  790.       }
  791.       break;
  792.     case ID_WIDTHC:
  793.       if (node) OpenWidthWnd(node);
  794.       break;
  795.     case ID_KERNING:
  796.       if (node) OpenKernWnd(node);
  797.       break;
  798.     case ID_MOVEL:
  799.       if (node) MoveLeft(node);
  800.       break;
  801.     case ID_MOVER:
  802.       if (node) MoveRight(node);
  803.       break;
  804.     case ID_MOVEU:
  805.       if (node) MoveUp(node);
  806.       break;
  807.     case ID_MOVED:
  808.       if (node) MoveDown(node);
  809.       break;
  810.     case ID_COPY:
  811.       if (node) CopyChar(node);
  812.       break;
  813.     case ID_PASTE:
  814.       if (node) PasteChar(node);
  815.       break;
  816.   }
  817. }
  818.  
  819. void Error(char *message)
  820. {
  821.   ShowReq(message,"Cancel");
  822.   Quit();
  823. }
  824.  
  825. void ShowReq(char *text,char *gadgets,...)
  826. {
  827. va_list va;
  828. struct EasyStruct req =
  829.   { sizeof(struct EasyStruct),0,NAME,NULL,NULL };
  830.  
  831.   SleepWindows();
  832.   req.es_TextFormat = text;
  833.   req.es_GadgetFormat = gadgets;
  834.   va_start(va,gadgets);
  835.   EasyRequestArgs(FontWnd,&req,NULL,va);
  836.   va_end(va);
  837.   WakeWindows();
  838. }
  839.  
  840. void ClrDisposeObject(Object **obj)
  841. {
  842.   if (*obj)
  843.   {
  844.     DisposeObject(*obj);
  845.     *obj = NULL;
  846.   }
  847. }
  848.  
  849. void ClrWindowClose(Object **obj,struct Window **wnd)
  850. {
  851.   if (*wnd)
  852.   {
  853.     WindowClose(*obj);
  854.     *wnd = NULL;
  855.   }
  856. }
  857.  
  858. void SleepWindows(void)
  859. {
  860. struct CharNode *node;
  861.  
  862.   if (FontWnd)
  863.   {
  864.     WindowBusy(FontWndObj);
  865.     if (ParamWnd) WindowBusy(ParamWndObj);
  866.     if (PrefsWnd) WindowBusy(PrefsWndObj);
  867.     if (AssignWnd) WindowBusy(AssignWndObj);
  868.     if (WidthWnd) WindowBusy(WidthWndObj);
  869.     if (KernWnd) WindowBusy(KernWndObj);
  870.     node = CharWndList->lh_Head;
  871.     while (node->chln_Node.ln_Succ)
  872.     {
  873.       WindowBusy(node->chln_Object);
  874.       node = node->chln_Node.ln_Succ;
  875.     }
  876.   }
  877. }
  878.  
  879. void WakeWindows(void)
  880. {
  881. struct CharNode *node;
  882.  
  883.   if (FontWnd)
  884.   {
  885.     WindowReady(FontWndObj);
  886.     if (ParamWnd) WindowReady(ParamWndObj);
  887.     if (PrefsWnd) WindowReady(PrefsWndObj);
  888.     if (AssignWnd) WindowReady(AssignWndObj);
  889.     if (WidthWnd) WindowReady(WidthWndObj);
  890.     if (KernWnd) WindowReady(KernWndObj);
  891.     node = CharWndList->lh_Head;
  892.     while (node->chln_Node.ln_Succ)
  893.     {
  894.       WindowReady(node->chln_Object);
  895.       node = node->chln_Node.ln_Succ;
  896.     }
  897.   }
  898. }
  899.  
  900. void LoadFont(struct TextAttr *font)
  901. {
  902. ULONG i;
  903. char *endptr;
  904.  
  905.   strcpy(FontName,font->ta_Name);
  906.   if (endptr = strstr(FontName,".font")) *endptr = 0;
  907.   if ((NewFont = OpenFont(font)) == NULL)
  908.   {
  909.     if ((NewFont = OpenDiskFont(font)) == NULL)
  910.     {
  911.       ShowReq("Cannot open %s.","Continue",FontName,(ULONG)font->ta_YSize);
  912.       return;
  913.     }
  914.   }
  915.   ClearCurrentFont();
  916.   Height = NewFont->tf_YSize;
  917.   Width = NewFont->tf_XSize;
  918.   Baseline = NewFont->tf_Baseline;
  919.   Smear = NewFont->tf_BoldSmear;
  920.   FirstChar = NewFont->tf_LoChar;
  921.   LastChar = NewFont->tf_HiChar;
  922.   Proportional = ((NewFont->tf_Flags & FPF_PROPORTIONAL) != 0);
  923.   Bold = ((NewFont->tf_Style & FSF_BOLD) != 0);
  924.   Italic = ((NewFont->tf_Style & FSF_ITALIC) != 0);
  925.   ULine = ((NewFont->tf_Style & FSF_UNDERLINED) != 0);
  926.   Extended = ((NewFont->tf_Style & FSF_EXTENDED) != 0);
  927.   Normal = ((Bold | Italic | ULine | Extended) == 0);
  928.   Reversed = ((NewFont->tf_Flags & FPF_REVPATH) != 0);
  929.   Aspect = 0;
  930.   if (NewFont->tf_Flags & FPF_TALLDOT) Aspect = 1;
  931.   if (NewFont->tf_Flags & FPF_WIDEDOT) Aspect = 2;
  932.  
  933.   for (i = 0; i < 257; i++)
  934.   {
  935.     (CharBuffer+i)->chr_Width = NewFont->tf_XSize;
  936.     (CharBuffer+i)->chr_Height = NewFont->tf_YSize;
  937.     SpaceTable[i] = NewFont->tf_XSize;
  938.     KernTable[i] = 0;
  939.   }
  940.   for (i = 0; i < LastChar-FirstChar+1; i++)
  941.   {
  942.     if (!UnpackChar(CharBuffer+FirstChar+i,NewFont,i)) Quit();
  943.     KernTables(FirstChar+i,i);
  944.   }
  945.   UnpackChar(CharBuffer+256,NewFont,LastChar-FirstChar+1);
  946.   KernTables(256,LastChar-FirstChar+1);
  947.   sprintf(WinTitle,"%s/%ld",FontName,(ULONG)font->ta_YSize);
  948.   SetAttrs(FontWndObj,WINDOW_Title,WinTitle,TAG_DONE);
  949.   CloseFont(NewFont); NewFont = NULL;
  950. }
  951.  
  952. BOOL UnpackChar(struct Character *chr,struct TextFont *font,ULONG i)
  953. {
  954. struct charDef *def;
  955. ULONG j,k,mod,off,width,modj,widthj;
  956. UBYTE *data;
  957.  
  958.   mod = font->tf_Modulo;
  959.   data = (UBYTE *)font->tf_CharData;
  960.   def = ((struct charDef *)(font->tf_CharLoc))+i;
  961.   off = def->charOffset;
  962.   chr->chr_Width = def->charBitWidth;
  963.   if ((width = chr->chr_Width) > 0)
  964.   {
  965.     if ((chr->chr_Data = AllocVec(chr->chr_Width*chr->chr_Height,MEMF_ANY))
  966.       == NULL) return (FALSE);
  967.     for (j = 0; j < chr->chr_Height; j++)
  968.     {
  969.       modj = mod*j;
  970.       widthj = width*j;
  971.       for (k = 0; k < width; k++)
  972.         *(chr->chr_Data+widthj+k) = GETBIT(data+modj,off+k);
  973.     }
  974.   }
  975.   return (TRUE);
  976. }
  977.  
  978. void KernTables(ULONG to, ULONG from)
  979. {
  980.   if (NewFont->tf_CharSpace)
  981.     SpaceTable[to] = *((WORD *)(NewFont->tf_CharSpace)+from);
  982.   if (NewFont->tf_CharKern)
  983.     KernTable[to] = *((WORD *)(NewFont->tf_CharKern)+from);
  984.   if ((NewFont->tf_CharSpace) || (NewFont->tf_CharKern))
  985.     UseTable = TRUE;
  986.   else
  987.     UseTable = FALSE;
  988. }
  989.  
  990. void ClearCurrentFont(void)
  991. {
  992. struct Character *chr;
  993.  
  994.   for (chr = CharBuffer; chr < CharBuffer+257; chr++)
  995.   {
  996.     if (chr->chr_Data) FreeVec(chr->chr_Data);
  997.     chr->chr_Data = NULL;
  998.   }
  999. }
  1000.  
  1001. void OpenEditFontWnd(void)
  1002. {
  1003. static STRPTR prop_labels[] = { "Fixed Width","Proportional",NULL };
  1004. static STRPTR aspect_labels[] = { "Normal","Thin","Wide",NULL };
  1005. Object *accept, *cancel;
  1006.  
  1007.   if (ParamWnd)
  1008.   {
  1009.     WindowToFront(ParamWnd);
  1010.     ActivateWindow(ParamWnd);
  1011.   }
  1012.   else
  1013.   {
  1014.     if (ParamWndObj == NULL)
  1015.     {
  1016.       ParamWndObj = WindowObject,
  1017.     WINDOW_Screen,Screen,
  1018.     WINDOW_SharedPort,WndMsgPort,
  1019.     WINDOW_MenuStrip,menus,
  1020.     WINDOW_Title,"Edit Font Parameters",
  1021.     WINDOW_HelpFile,NAME".guide",
  1022.     WINDOW_HelpNode,"params",
  1023.     WINDOW_SmartRefresh,TRUE,
  1024.     WINDOW_SizeGadget,FALSE,
  1025.     WINDOW_MasterGroup,
  1026.       VGroupObject,
  1027.         HOffset(8),VOffset(4),Spacing(4),
  1028.         GROUP_BackFill,SHINE_RASTER,
  1029.         StartMember,
  1030.           VGroupObject,
  1031.         HOffset(8),VOffset(4),Spacing(2),
  1032.         ButtonFrame,
  1033.         FRM_Recessed,TRUE,
  1034.         StartMember,
  1035.           PropCycle =
  1036.             KeyCycle("_Font Type",prop_labels,Proportional,ID_PROP),
  1037.         EndMember,
  1038.         StartMember,
  1039.           HGroupObject,
  1040.             Spacing(8),
  1041.             StartMember,
  1042.               VGroupObject,
  1043.               Spacing(2),
  1044.             StartMember,
  1045.               HeightInt = TabKeyInteger("_Height",Height,
  1046.                 3,ID_HEIGHT),
  1047.             EndMember,
  1048.             StartMember,
  1049.               BaseInt = TabKeyInteger("_Baseline",Baseline,
  1050.                 3,ID_BASELINE),
  1051.             EndMember,
  1052.               EndObject,
  1053.             EndMember,
  1054.             StartMember,
  1055.               VGroupObject,
  1056.             Spacing(2),
  1057.             StartMember,
  1058.               WidthInt = TabKeyInteger("_Width",Width,
  1059.                 3,ID_WIDTH),
  1060.             EndMember,
  1061.             StartMember,
  1062.               SmearInt = TabKeyInteger("Bold _Smear",Smear,
  1063.                 3,ID_SMEAR),
  1064.             EndMember,
  1065.               EndObject,
  1066.             EndMember,
  1067.           EndObject,
  1068.         EndMember,
  1069.           EndObject,
  1070.         EndMember,
  1071.         StartMember,
  1072.           VGroupObject,
  1073.         HOffset(8),VOffset(4),Spacing(2),
  1074.         ButtonFrame,
  1075.         FRM_Recessed,TRUE,
  1076.         StartMember,
  1077.           HGroupObject,
  1078.             Spacing(8),
  1079.             StartMember,
  1080.               VGroupObject,
  1081.             Spacing(2),
  1082.             StartMember,
  1083.               NormalCheck =
  1084.                 KeyCheckBox("_Normal",Normal,ID_NORMAL),
  1085.             EndMember,
  1086.             StartMember,
  1087.               ItalicCheck =
  1088.                 KeyCheckBox("_Italic",Italic,ID_ITALIC),
  1089.             EndMember,
  1090.               EndObject,
  1091.             EndMember,
  1092.             StartMember,
  1093.               VGroupObject,
  1094.             Spacing(2),
  1095.             StartMember,
  1096.               BoldCheck = KeyCheckBox("B_old",Bold,ID_BOLD),
  1097.             EndMember,
  1098.             StartMember,
  1099.               UnderCheck =
  1100.                 KeyCheckBox("_Underline",ULine,ID_ULINE),
  1101.             EndMember,
  1102.               EndObject,
  1103.             EndMember,
  1104.             StartMember,
  1105.               VGroupObject,
  1106.             Spacing(2),
  1107.             StartMember,
  1108.               ExtCheck =
  1109.                 KeyCheckBox("_Extended",Extended,ID_EXTEND),
  1110.             EndMember,
  1111.             StartMember,
  1112.               RevCheck =
  1113.                 KeyCheckBox("_Reversed",Reversed,ID_REVERSE),
  1114.             EndMember,
  1115.               EndObject,
  1116.             EndMember,
  1117.           EndObject,
  1118.         EndMember,
  1119.         StartMember,
  1120.           HGroupObject,
  1121.             Spacing(8),
  1122.             StartMember,
  1123.               AspectCycle = KeyPopCycle("As_pect",
  1124.             aspect_labels,Aspect,ID_ASPECT),
  1125.             EndMember,
  1126.             StartMember,
  1127.               BlankButton = KeyButton("B_lank",ID_BLANK),
  1128.               Weight(20),
  1129.             EndMember,
  1130.           EndObject,
  1131.         EndMember,
  1132.           EndObject,
  1133.         EndMember,
  1134.         StartMember,
  1135.           HGroupObject,
  1136.         Spacing(8),
  1137.         EqualWidth,
  1138.         StartMember,
  1139.           accept = KeyButton("_Accept",ID_ACCEPT),
  1140.         EndMember,
  1141.             StartMember,
  1142.           cancel = KeyButton("_Cancel",ID_CANCEL),
  1143.         EndMember,
  1144.           EndObject,
  1145.           FixMinHeight,
  1146.         EndMember,
  1147.       EndObject,
  1148.     EndObject;
  1149.       if (ParamWndObj == NULL) Quit();
  1150.       GadgetKey(ParamWndObj,accept,"a");
  1151.       GadgetKey(ParamWndObj,cancel,"c");
  1152.       GadgetKey(ParamWndObj,PropCycle,"f");
  1153.       GadgetKey(ParamWndObj,HeightInt,"h");
  1154.       GadgetKey(ParamWndObj,WidthInt,"w");
  1155.       GadgetKey(ParamWndObj,BaseInt,"b");
  1156.       GadgetKey(ParamWndObj,SmearInt,"s");
  1157.       GadgetKey(ParamWndObj,NormalCheck,"n");
  1158.       GadgetKey(ParamWndObj,BoldCheck,"o");
  1159.       GadgetKey(ParamWndObj,ItalicCheck,"i");
  1160.       GadgetKey(ParamWndObj,UnderCheck,"u");
  1161.       GadgetKey(ParamWndObj,ExtCheck,"e");
  1162.       GadgetKey(ParamWndObj,RevCheck,"r");
  1163.       GadgetKey(ParamWndObj,AspectCycle,"p");
  1164.       GadgetKey(ParamWndObj,BlankButton,"l");
  1165.       DoMethod(ParamWndObj,WM_TABCYCLE_ORDER,
  1166.     HeightInt,WidthInt,BaseInt,SmearInt,NULL);
  1167.     }
  1168.  
  1169.     SetAttrs(PropCycle,CYC_Active,Proportional,TAG_DONE);
  1170.     SetAttrs(HeightInt,STRINGA_LongVal,Height,TAG_DONE);
  1171.     SetAttrs(BaseInt,STRINGA_LongVal,Baseline,TAG_DONE);
  1172.     SetAttrs(WidthInt,STRINGA_LongVal,Width,TAG_DONE);
  1173.     SetAttrs(SmearInt,STRINGA_LongVal,Smear,TAG_DONE);
  1174.     SetAttrs(NormalCheck,GA_Selected,Normal,TAG_DONE);
  1175.     SetAttrs(ItalicCheck,GA_Selected,Italic,TAG_DONE);
  1176.     SetAttrs(BoldCheck,GA_Selected,Bold,TAG_DONE);
  1177.     SetAttrs(UnderCheck,GA_Selected,ULine,TAG_DONE);
  1178.     SetAttrs(ExtCheck,GA_Selected,Extended,TAG_DONE);
  1179.     SetAttrs(RevCheck,GA_Selected,Reversed,TAG_DONE);
  1180.     SetAttrs(AspectCycle,CYC_Active,Aspect,TAG_DONE);
  1181.     if ((ParamWnd = WindowOpen(ParamWndObj)) == NULL) Quit();
  1182.   }
  1183. }
  1184.  
  1185. void CloseEditFontWnd(BOOL obj)
  1186. {
  1187.   ClrWindowClose(&ParamWndObj,&ParamWnd);
  1188.   if (obj) ClrDisposeObject(&ParamWndObj);
  1189. }
  1190.  
  1191. void OpenPrefsWnd(void)
  1192. {
  1193. Object *save, *use, *cancel, *select, *page;
  1194. static UBYTE *pages[] = { "Screen","Edit","Misc",NULL };
  1195. static UBYTE *save_labels[] = { "ENV:","PROGDIR:",NULL };
  1196. static ULONG map[] = { MX_Active,PAGE_Active,TAG_END };
  1197.  
  1198.   if (PrefsWnd)
  1199.   {
  1200.     WindowToFront(PrefsWnd);
  1201.     ActivateWindow(PrefsWnd);
  1202.   }
  1203.   else
  1204.   {
  1205.     if (PrefsWndObj == NULL)
  1206.     {
  1207.       PrefsWndObj = WindowObject,
  1208.     WINDOW_Screen,Screen,
  1209.     WINDOW_SharedPort,WndMsgPort,
  1210.     WINDOW_MenuStrip,menus,
  1211.     WINDOW_Title,"Preferences",
  1212.     WINDOW_HelpFile,NAME".guide",
  1213.     WINDOW_HelpNode,"prefs",
  1214.     WINDOW_ScaleWidth,15,
  1215.     WINDOW_SmartRefresh,TRUE,
  1216.     WINDOW_SizeGadget,FALSE,
  1217.     WINDOW_MasterGroup,
  1218.       VGroupObject,
  1219.         HOffset(8),VOffset(4),
  1220.         GROUP_BackFill,SHINE_RASTER,
  1221.             StartMember,
  1222.           select = MxObject,
  1223.         MX_TabsObject,TRUE,
  1224.         MX_Labels,pages,
  1225.           EndObject,
  1226.           FixMinHeight,
  1227.         EndMember,
  1228.         StartMember,
  1229.           page = PageObject,
  1230.  
  1231.         PageMember,
  1232.           VGroupObject,
  1233.             HOffset(8),VOffset(4),
  1234.             ButtonFrame,
  1235.             FRM_Recessed,TRUE,
  1236.             VarSpace(50),
  1237.             StartMember,
  1238.               HGroupObject,
  1239.             VarSpace(50),
  1240.             StartMember,
  1241.               CustButton = KeyCheckBox("Cus_tom Screen",
  1242.                 CustomScreen,ID_CUSTOM),
  1243.             EndMember,
  1244.             VarSpace(50),
  1245.               EndObject,
  1246.             EndMember,
  1247.             StartMember,
  1248.               HGroupObject,
  1249.             TOffset(6),
  1250.             VarSpace(50),
  1251.             StartMember,
  1252.               InfoObject,
  1253.                 INFO_TextFormat,"Screen Type",
  1254.                 INFO_MinLines,1,
  1255.                 INFO_HorizOffset,0,
  1256.                 INFO_VertOffset,2,
  1257.                 INFO_FixTextWidth,TRUE,
  1258.               EndObject,
  1259.             EndMember,
  1260.             VarSpace(50),
  1261.               EndObject,
  1262.             EndMember,
  1263.             StartMember,
  1264.               HGroupObject,
  1265.             FixMinHeight,
  1266.             EqualHeight,
  1267.             StartMember,
  1268.               ModeInfo = InfoObject,
  1269.                 ButtonFrame,
  1270.                 FRM_Flags,FRF_RECESSED,
  1271.                 INFO_MinLines,1,
  1272.                 INFO_HorizOffset,6,
  1273.                 INFO_VertOffset,3,
  1274.               EndObject,
  1275.               Weight(70),
  1276.             EndMember,
  1277.             StartMember,
  1278.               ChooseButton = ButtonObject,
  1279.                 Label("Choose"),
  1280.                 ButtonFrame,
  1281.                 GA_ID,ID_CHOOSE,
  1282.               EndObject,
  1283.               Weight(30),
  1284.             EndMember,
  1285.               EndObject,
  1286.             EndMember,
  1287.             VarSpace(50),
  1288.           EndObject,
  1289.  
  1290.         PageMember,
  1291.           HGroupObject,
  1292.             HOffset(8),VOffset(4),
  1293.             ButtonFrame,
  1294.             FRM_Recessed,TRUE,
  1295.             VarSpace(5),
  1296.             StartMember,
  1297.               VGroupObject,
  1298.             Spacing(2),
  1299.             StartMember,
  1300.               PixelXInt = TabKeyInteger("Pixel _Width",
  1301.                 Prefs.PixelX,3,ID_PIXELWIDTH),
  1302.             EndMember,
  1303.             StartMember,
  1304.               PixelYInt = TabKeyInteger("Pixel _Height",
  1305.                 Prefs.PixelY,3,ID_PIXELHEIGHT),
  1306.             EndMember,
  1307.             StartMember,
  1308.               VecInt = TabKeyInteger("_Tool Bar Height",
  1309.                 Prefs.VecHeight,3,ID_VECHEIGHT),
  1310.             EndMember,
  1311.             StartMember,
  1312.               PixelCheck = KeyCheckBox("Pixel _Border",
  1313.                 PixelBorder,ID_PIXELBORDER),
  1314.             EndMember,
  1315.               EndObject,
  1316.             EndMember,
  1317.             VarSpace(5),
  1318.           EndObject,
  1319.  
  1320.         PageMember,
  1321.           VGroupObject,
  1322.             HOffset(8),VOffset(4),Spacing(2),
  1323.             ButtonFrame,
  1324.             FRM_Recessed,TRUE,
  1325.             VarSpace(50),
  1326.             StartMember,
  1327.               SaveCycle = CycleObject,
  1328.             UScoreLabel("Sa_ve preferences file to",'_'),
  1329.             Place(PLACE_ABOVE),
  1330.             ButtonFrame,
  1331.             CYC_Labels,save_labels,
  1332.             CYC_Active,Prefs.SaveTo,
  1333.             CYC_Popup,TRUE,
  1334.             GA_ID,ID_SAVETO,
  1335.               EndObject,
  1336.             EndMember,
  1337.             VarSpace(50),
  1338.           EndObject,
  1339.  
  1340.           EndObject,
  1341.         EndMember,
  1342.         StartMember,
  1343.           HGroupObject,
  1344.         TOffset(4),Spacing(8),
  1345.         EqualWidth,
  1346.         StartMember,
  1347.           save = KeyButton("_Save",ID_ACCEPT),
  1348.         EndMember,
  1349.         StartMember,
  1350.           use = KeyButton("_Use",ID_USE),
  1351.         EndMember,
  1352.             StartMember,
  1353.           cancel = KeyButton("_Cancel",ID_CANCEL),
  1354.         EndMember,
  1355.           EndObject,
  1356.           FixMinHeight,
  1357.         EndMember,
  1358.       EndObject,
  1359.     EndObject;
  1360.       if (PrefsWndObj == NULL) Quit();
  1361.       GadgetKey(PrefsWndObj,save,"s");
  1362.       GadgetKey(PrefsWndObj,use,"u");
  1363.       GadgetKey(PrefsWndObj,cancel,"c");
  1364.       GadgetKey(PrefsWndObj,VecInt,"t");
  1365.       GadgetKey(PrefsWndObj,PixelXInt,"w");
  1366.       GadgetKey(PrefsWndObj,PixelYInt,"h");
  1367.       GadgetKey(PrefsWndObj,PixelCheck,"b");
  1368.       GadgetKey(PrefsWndObj,CustButton,"t");
  1369.       GadgetKey(PrefsWndObj,SaveCycle,"v");
  1370.       AddMap(select,page,map);
  1371.       DoMethod(PrefsWndObj,WM_TABCYCLE_ORDER,
  1372.     VecInt,PixelXInt,PixelYInt,NULL);
  1373.     }
  1374.  
  1375.     SetAttrs(CustButton,GA_Selected,CustomScreen,TAG_DONE);
  1376.     SetAttrs(ChooseButton,
  1377.       GA_Disabled,(CustomScreen == TRUE) ? FALSE : TRUE,TAG_DONE);
  1378.     PrefScrModeID = Prefs.ScrModeID;
  1379.     PrefScrDepth = Prefs.ScrDepth;
  1380.     GetDisplayInfoData(NULL,&ModeIDName,sizeof(struct NameInfo),
  1381.       DTAG_NAME,PrefScrModeID);
  1382.     SetAttrs(ModeInfo,INFO_TextFormat,ModeIDName.Name,TAG_DONE);
  1383.  
  1384.     SetAttrs(VecInt,STRINGA_LongVal,Prefs.VecHeight,TAG_DONE);
  1385.     SetAttrs(PixelXInt,STRINGA_LongVal,Prefs.PixelX,TAG_DONE);
  1386.     SetAttrs(PixelYInt,STRINGA_LongVal,Prefs.PixelY,TAG_DONE);
  1387.     SetAttrs(PixelCheck,GA_Selected,PixelBorder,TAG_DONE);
  1388.  
  1389.     SetAttrs(SaveCycle,CYC_Active,Prefs.SaveTo,TAG_DONE);
  1390.     if ((PrefsWnd = WindowOpen(PrefsWndObj)) == NULL) Quit();
  1391.   }
  1392. }
  1393.  
  1394. void ClosePrefsWnd(BOOL obj)
  1395. {
  1396.   ClrWindowClose(&PrefsWndObj,&PrefsWnd);
  1397.   if (obj) ClrDisposeObject(&PrefsWndObj);
  1398. }
  1399.  
  1400. void OpenAssignWnd(void)
  1401. {
  1402. Object *assign, *assignadd, *cancel;
  1403.  
  1404.   if (AssignWnd)
  1405.   {
  1406.     WindowToFront(AssignWnd);
  1407.     ActivateWindow(AssignWnd);
  1408.   }
  1409.   else
  1410.   {
  1411.     if (AssignWndObj == NULL)
  1412.     {
  1413.       AssignWndObj = WindowObject,
  1414.     WINDOW_Screen,Screen,
  1415.     WINDOW_SharedPort,WndMsgPort,
  1416.     WINDOW_MenuStrip,menus,
  1417.     WINDOW_Title,"Change Font Directory",
  1418.     WINDOW_HelpFile,NAME".guide",
  1419.     WINDOW_HelpNode,"dir",
  1420.     WINDOW_ScaleWidth,26,
  1421.     WINDOW_SmartRefresh,TRUE,
  1422.     WINDOW_SizeGadget,FALSE,
  1423.     WINDOW_MasterGroup,
  1424.       VGroupObject,
  1425.         HOffset(8),VOffset(4),Spacing(4),
  1426.         GROUP_BackFill,SHINE_RASTER,
  1427.         StartMember,
  1428.           HGroupObject,
  1429.         HOffset(8),VOffset(4),
  1430.         EqualHeight,
  1431.         ButtonFrame,
  1432.         FRM_Recessed,TRUE,
  1433.         StartMember,
  1434.           FontDirStr = StringObject,
  1435.             RidgeFrame,
  1436.             STRINGA_TextVal,FontPath,
  1437.             STRINGA_MaxChars,255,
  1438.             GA_ID,ID_ASSIGNSTR,
  1439.           EndObject,
  1440.         EndMember,
  1441.         StartMember,
  1442.           ButtonObject,
  1443.             GetPath,
  1444.             ButtonFrame,
  1445.             GA_ID,ID_ASSIGNPATH,
  1446.           EndObject,
  1447.           FixMinWidth,
  1448.         EndMember,
  1449.           EndObject,
  1450.         EndMember,
  1451.         StartMember,
  1452.           HGroupObject,
  1453.         Spacing(8),
  1454.         StartMember,
  1455.           assign = KeyButton("_Assign",ID_ASSIGN),
  1456.         EndMember,
  1457.             StartMember,
  1458.           assignadd = KeyButton("Assign A_dd",ID_ASSIGNADD),
  1459.         EndMember,
  1460.             StartMember,
  1461.           cancel = KeyButton("_Cancel",ID_CANCEL),
  1462.         EndMember,
  1463.           EndObject,
  1464.           FixMinHeight,
  1465.         EndMember,
  1466.       EndObject,
  1467.     EndObject;
  1468.       if (AssignWndObj == NULL) Quit();
  1469.       GadgetKey(AssignWndObj,assign,"a");
  1470.       GadgetKey(AssignWndObj,assignadd,"d");
  1471.       GadgetKey(AssignWndObj,cancel,"c");
  1472.  
  1473.       DirReqObj = FileReqObject,
  1474.     ASLFR_TitleText,"Change Font Directory",
  1475.     ASLFR_DrawersOnly,TRUE,
  1476.     ASLFR_Window,FontWnd,
  1477.       EndObject;
  1478.       if (DirReqObj == NULL) Quit();
  1479.     }
  1480.  
  1481.     SetAttrs(FontDirStr,STRINGA_TextVal,FontPath,TAG_DONE);
  1482.     if ((AssignWnd = WindowOpen(AssignWndObj)) == NULL) Quit();
  1483.   }
  1484. }
  1485.  
  1486. void CloseAssignWnd(BOOL obj)
  1487. {
  1488.   ClrWindowClose(&AssignWndObj,&AssignWnd);
  1489.   if (obj) ClrDisposeObject(&AssignWndObj);
  1490. }
  1491.  
  1492. void OpenWidthWnd(struct CharNode *node)
  1493. {
  1494. Object *accept, *cancel;
  1495. static struct NewMenu menus[] = { PROJECT_MENU,CHARACTER_MENU,End };
  1496. static ULONG lmap[] = { PGA_Top,INDIC_Level,TAG_END };
  1497. static ULONG rmap[] = { SCRL_Right,INDIC_Level,TAG_END };
  1498.  
  1499.   if (node->chln_Number < 256)
  1500.     sprintf(WidthTitle,"Change Width of %lu (from %d)",
  1501.       node->chln_Number,node->chln_Character->chr_Width);
  1502.   else
  1503.     sprintf(WidthTitle,"Change Width of blank (from %d)",
  1504.       node->chln_Character->chr_Width);
  1505.   WidthNode = node;
  1506.   WidthChar = node->chln_Character;
  1507.  
  1508.   if (WidthWnd)
  1509.   {
  1510.     SetGadgetAttrs(ChrWidthScroll,WidthWnd,NULL,
  1511.       PGA_Top,0,
  1512.       PGA_Total,1,
  1513.       PGA_Visible,1,TAG_DONE);
  1514.     SetGadgetAttrs(ChrWidthInt,WidthWnd,NULL,
  1515.       STRINGA_LongVal,WidthChar->chr_Width,TAG_DONE);
  1516.     SetAttrs(WidthWndObj,WINDOW_Title,WidthTitle,TAG_DONE);
  1517.     WindowToFront(WidthWnd);
  1518.     ActivateWindow(WidthWnd);
  1519.   }
  1520.   else
  1521.   {
  1522.     if (WidthWndObj == NULL)
  1523.     {
  1524.       WidthWndObj = WindowObject,
  1525.     WINDOW_Screen,Screen,
  1526.     WINDOW_SharedPort,WndMsgPort,
  1527.     WINDOW_MenuStrip,menus,
  1528.     WINDOW_HelpFile,NAME".guide",
  1529.     WINDOW_HelpNode,"width",
  1530.     WINDOW_SmartRefresh,TRUE,
  1531.     WINDOW_SizeGadget,FALSE,
  1532.     WINDOW_MasterGroup,
  1533.       VGroupObject,
  1534.         HOffset(8),VOffset(4),Spacing(4),
  1535.         GROUP_BackFill,SHINE_RASTER,
  1536.         StartMember,
  1537.           VGroupObject,
  1538.         HOffset(8),VOffset(4),Spacing(2),
  1539.         ButtonFrame,
  1540.         FRM_Recessed,TRUE,
  1541.         StartMember,
  1542.           ChrWidthInt = KeyInteger("New _Width",
  1543.             WidthChar->chr_Width,3,ID_CHARWIDTH),
  1544.         EndMember,
  1545.         StartMember,
  1546.           HGroupObject,
  1547.             Spacing(8),
  1548.             StartMember,
  1549.               LeftInd = IndicatorObject,
  1550.             INDIC_Min,0,
  1551.             INDIC_Max,999,
  1552.             INDIC_FormatString,"Left Offset: %ld",
  1553.               EndObject,
  1554.             EndMember,
  1555.             StartMember,
  1556.               RightInd = IndicatorObject,
  1557.             INDIC_Min,0,
  1558.             INDIC_Max,999,
  1559.             INDIC_FormatString,"Right Offset: %ld",
  1560.               EndObject,
  1561.             EndMember,
  1562.           EndObject,
  1563.         EndMember,
  1564.         StartMember,
  1565.           ChrWidthScroll = NewObject(SlideClass,NULL,
  1566.             PGA_Freedom,FREEHORIZ,
  1567.             PGA_Arrows,FALSE,
  1568.             GA_ID,ID_WIDTHPOS,
  1569.           EndObject,
  1570.         EndMember,
  1571.           EndObject,
  1572.         EndMember,
  1573.         StartMember,
  1574.           HGroupObject,
  1575.         Spacing(8),
  1576.         StartMember,
  1577.           accept = KeyButton("_Accept",ID_ACCEPT),
  1578.         EndMember,
  1579.             StartMember,
  1580.           cancel = KeyButton("_Cancel",ID_CANCEL),
  1581.         EndMember,
  1582.           EndObject,
  1583.           FixMinHeight,
  1584.         EndMember,
  1585.       EndObject,
  1586.     EndObject;
  1587.       if (WidthWndObj == NULL) Quit();
  1588.       GadgetKey(WidthWndObj,accept,"a");
  1589.       GadgetKey(WidthWndObj,cancel,"c");
  1590.       GadgetKey(WidthWndObj,ChrWidthInt,"w");
  1591.       AddMap(ChrWidthScroll,LeftInd,lmap);
  1592.       AddMap(ChrWidthScroll,RightInd,rmap);
  1593.     }
  1594.  
  1595.     SetAttrs(ChrWidthScroll,
  1596.       PGA_Top,0,
  1597.       PGA_Total,1,
  1598.       PGA_Visible,1,TAG_DONE);
  1599.     SetAttrs(ChrWidthInt,STRINGA_LongVal,WidthChar->chr_Width,TAG_DONE);
  1600.     SetAttrs(WidthWndObj,WINDOW_Title,WidthTitle,TAG_DONE);
  1601.     if ((WidthWnd = WindowOpen(WidthWndObj)) == NULL) Quit();
  1602.   }
  1603. }
  1604.  
  1605. void CloseWidthWnd(BOOL obj)
  1606. {
  1607.   ClrWindowClose(&WidthWndObj,&WidthWnd);
  1608.   if (obj) ClrDisposeObject(&WidthWndObj);
  1609.   WidthNode = NULL; WidthChar = NULL;
  1610. }
  1611.  
  1612. void OpenKernWnd(struct CharNode *node)
  1613. {
  1614. Object *accept, *cancel;
  1615. static struct NewMenu menus[] = { PROJECT_MENU,CHARACTER_MENU,End };
  1616.  
  1617.   if (node->chln_Number < 256)
  1618.     sprintf(KernTitle,"Kerning for %lu",node->chln_Number);
  1619.   else
  1620.     sprintf(KernTitle,"Kerning for blank");
  1621.   KernNode = node;
  1622.   KernChar = node->chln_Character;
  1623.  
  1624.   if (KernWnd)
  1625.   {
  1626.     SetAttrs(KernWndObj,WINDOW_Title,KernTitle,TAG_DONE);
  1627.     SetGadgetAttrs(SpaceObj,KernWnd,NULL,
  1628.       STRINGA_LongVal,SpaceTable[node->chln_Number],TAG_DONE);
  1629.     SetGadgetAttrs(KernObj,KernWnd,NULL,
  1630.       STRINGA_LongVal,KernTable[node->chln_Number],TAG_DONE);
  1631.     WindowToFront(KernWnd);
  1632.     ActivateWindow(KernWnd);
  1633.   }
  1634.   else
  1635.   {
  1636.     if (KernWndObj == NULL)
  1637.     {
  1638.       KernWndObj = WindowObject,
  1639.     WINDOW_Screen,Screen,
  1640.     WINDOW_SharedPort,WndMsgPort,
  1641.     WINDOW_MenuStrip,menus,
  1642.     WINDOW_HelpFile,NAME".guide",
  1643.     WINDOW_HelpNode,"kern",
  1644.     WINDOW_ScaleWidth,11,
  1645.     WINDOW_SmartRefresh,TRUE,
  1646.     WINDOW_SizeGadget,FALSE,
  1647.     WINDOW_MasterGroup,
  1648.       VGroupObject,
  1649.         HOffset(8),VOffset(4),Spacing(4),
  1650.         GROUP_BackFill,SHINE_RASTER,
  1651.         StartMember,
  1652.           VGroupObject,
  1653.         HOffset(8),VOffset(4),Spacing(2),
  1654.         ButtonFrame,
  1655.         FRM_Recessed,TRUE,
  1656.         StartMember,
  1657.           SpaceObj = TabKeyInteger("_Spacing",0,3,ID_SPACE),
  1658.         EndMember,
  1659.         StartMember,
  1660.           KernObj = TabKeyInteger("_Kerning",0,3,ID_KERN),
  1661.         EndMember,
  1662.           EndObject,
  1663.         EndMember,
  1664.         StartMember,
  1665.           HGroupObject,
  1666.         Spacing(8),
  1667.         StartMember,
  1668.           accept = KeyButton("_Accept",ID_ACCEPT),
  1669.         EndMember,
  1670.             StartMember,
  1671.           cancel = KeyButton("_Cancel",ID_CANCEL),
  1672.         EndMember,
  1673.           EndObject,
  1674.           FixMinHeight,
  1675.         EndMember,
  1676.       EndObject,
  1677.     EndObject;
  1678.       if (KernWndObj == NULL) Quit();
  1679.       GadgetKey(KernWndObj,accept,"a");
  1680.       GadgetKey(KernWndObj,cancel,"c");
  1681.       GadgetKey(KernWndObj,SpaceObj,"s");
  1682.       GadgetKey(KernWndObj,KernObj,"k");
  1683.       DoMethod(KernWndObj,WM_TABCYCLE_ORDER,SpaceObj,KernObj,NULL);
  1684.     }
  1685.  
  1686.     SetAttrs(KernWndObj,WINDOW_Title,KernTitle,TAG_DONE);
  1687.     SetAttrs(SpaceObj,
  1688.       STRINGA_LongVal,SpaceTable[node->chln_Number],TAG_DONE);
  1689.     SetAttrs(KernObj,STRINGA_LongVal,KernTable[node->chln_Number],TAG_DONE);
  1690.     if ((KernWnd = WindowOpen(KernWndObj)) == NULL) Quit();
  1691.   }
  1692. }
  1693.  
  1694. void CloseKernWnd(BOOL obj)
  1695. {
  1696.   ClrWindowClose(&KernWndObj,&KernWnd);
  1697.   if (obj) ClrDisposeObject(&KernWndObj);
  1698.   KernNode = NULL; KernChar = NULL;
  1699. }
  1700.  
  1701. void OpenSaveWnd(void)
  1702. {
  1703. Object *save, *cancel;
  1704. ULONG satan = 666;
  1705.  
  1706.   if (SaveWnd)
  1707.   {
  1708.     WindowToFront(SaveWnd);
  1709.     ActivateWindow(SaveWnd);
  1710.   }
  1711.   else
  1712.   {
  1713.     if (SaveWndObj == NULL)
  1714.     {
  1715.       SaveWndObj = WindowObject,
  1716.     WINDOW_Screen,Screen,
  1717.     WINDOW_SharedPort,WndMsgPort,
  1718.     WINDOW_Title,"Save Font",
  1719.     WINDOW_HelpFile,NAME".guide",
  1720.     WINDOW_HelpNode,"save",
  1721.     WINDOW_SmartRefresh,TRUE,
  1722.     WINDOW_SizeGadget,FALSE,
  1723.     WINDOW_RMBTrap,TRUE,
  1724.     WINDOW_MasterGroup,
  1725.       VGroupObject,
  1726.         HOffset(8),VOffset(4),Spacing(4),
  1727.         GROUP_BackFill,SHINE_RASTER,
  1728.         StartMember,
  1729.           VGroupObject,
  1730.         HOffset(8),VOffset(4),Spacing(2),
  1731.         ButtonFrame,
  1732.         FRM_Recessed,TRUE,
  1733.         StartMember,
  1734.           HGroupObject,
  1735.             StartMember,
  1736.               SaveDirStr = StringObject,
  1737.             RidgeFrame,
  1738.             UScoreLabel("Font _Directory",'_'),
  1739.             STRINGA_MaxChars,255,
  1740.             GA_TabCycle,TRUE,
  1741.             GA_ID,ID_SAVEDIR,
  1742.               EndObject,
  1743.             EndMember,
  1744.             StartMember,
  1745.               ButtonObject,
  1746.             GetPath,
  1747.             ButtonFrame,
  1748.             GA_ID,ID_GETSAVEDIR,
  1749.               EndObject,
  1750.               FixMinWidth,
  1751.             EndMember,
  1752.           EndObject,
  1753.           NoAlign,
  1754.         EndMember,
  1755.         StartMember,
  1756.           HGroupObject,
  1757.             Spacing(8),
  1758.             StartMember,
  1759.               FontNameStr = StringObject,
  1760.             RidgeFrame,
  1761.             UScoreLabel("_Font",'_'),
  1762.             STRINGA_MaxChars,255,
  1763.             GA_TabCycle,TRUE,
  1764.             GA_ID,ID_FONTNAME,
  1765.               EndObject,
  1766.             EndMember,
  1767.             StartMember,
  1768.               SizeInfo = InfoObject,
  1769.             ButtonFrame,
  1770.             FRM_Flags,FRF_RECESSED,
  1771.             Label("Size"),
  1772.             INFO_TextFormat,"\33c%ld",
  1773.             INFO_Args,&satan,
  1774.             INFO_MinLines,1,
  1775.             INFO_HorizOffset,6,
  1776.             INFO_VertOffset,3,
  1777.             INFO_FixTextWidth,TRUE,
  1778.               EndObject,
  1779.               Weight(10),
  1780.             EndMember,
  1781.           EndObject,
  1782.         EndMember,
  1783.         StartMember,
  1784.           HGroupObject,
  1785.             Spacing(8),
  1786.             StartMember,
  1787.               FirstNum = TabKeyInteger("F_irst",0,3,ID_FIRST),
  1788.             EndMember,
  1789.             StartMember,
  1790.               LastNum = TabKeyInteger("_Last",0,3,ID_LAST),
  1791.             EndMember,
  1792.             StartMember,
  1793.               VGroupObject,
  1794.             VarSpace(60),
  1795.             StartMember,
  1796.               TableCheck = KeyCheckBox("_Kern Info",0,
  1797.                 ID_KERNTABLE),
  1798.             EndMember,
  1799.             VarSpace(50),
  1800.               EndObject,
  1801.             EndMember,
  1802.           EndObject,
  1803.         EndMember,
  1804.           EndObject,
  1805.         EndMember,
  1806.         StartMember,
  1807.           HGroupObject,
  1808.         Spacing(8),
  1809.         StartMember,
  1810.           save = KeyButton("_Save",ID_ACCEPT),
  1811.         EndMember,
  1812.             StartMember,
  1813.           cancel = KeyButton("_Cancel",ID_CANCEL),
  1814.         EndMember,
  1815.           EndObject,
  1816.           FixMinHeight,
  1817.         EndMember,
  1818.       EndObject,
  1819.     EndObject;
  1820.       if (SaveWndObj == NULL) Quit();
  1821.       GadgetKey(SaveWndObj,save,"s");
  1822.       GadgetKey(SaveWndObj,cancel,"c");
  1823.       GadgetKey(SaveWndObj,SaveDirStr,"d");
  1824.       GadgetKey(SaveWndObj,FontNameStr,"f");
  1825.       GadgetKey(SaveWndObj,FirstNum,"i");
  1826.       GadgetKey(SaveWndObj,LastNum,"l");
  1827.       GadgetKey(SaveWndObj,TableCheck,"k");
  1828.       DoMethod(SaveWndObj,WM_TABCYCLE_ORDER,
  1829.     SaveDirStr,FontNameStr,FirstNum,LastNum,NULL);
  1830.  
  1831.       SaveReqObj = FileReqObject,
  1832.     ASLFR_TitleText,"Change Font Directory",
  1833.     ASLFR_DrawersOnly,TRUE,
  1834.       EndObject;
  1835.       if (SaveReqObj == NULL) Quit();
  1836.     }
  1837.  
  1838.     SleepWindows();
  1839.     SetAttrs(SaveDirStr,STRINGA_TextVal,SavePath,TAG_DONE);
  1840.     SetAttrs(FontNameStr,STRINGA_TextVal,FontName,TAG_DONE);
  1841.     SetAttrs(FirstNum,STRINGA_LongVal,FirstChar,TAG_DONE);
  1842.     SetAttrs(LastNum,STRINGA_LongVal,LastChar,TAG_DONE);
  1843.     SetAttrs(SizeInfo,INFO_Args,&Height,TAG_DONE);
  1844.     SetAttrs(TableCheck,
  1845.       GA_Disabled,Proportional == TRUE,
  1846.       GA_Selected,(Proportional == TRUE) || (UseTable == TRUE),TAG_DONE);
  1847.     if ((SaveWnd = WindowOpen(SaveWndObj)) == NULL) Quit();
  1848.   }
  1849. }
  1850.  
  1851. void CloseSaveWnd(BOOL obj)
  1852. {
  1853.   WakeWindows();
  1854.   ClrWindowClose(&SaveWndObj,&SaveWnd);
  1855.   if (obj) ClrDisposeObject(&SaveWndObj);
  1856. }
  1857.  
  1858. void PutPositive(struct Window *wnd, char *name, LONG value, LONG min,
  1859.   LONG *dest)
  1860. {
  1861.   if (value > min)
  1862.     *dest = value;
  1863.   else
  1864.     ShowReq("The %s must be greater than %ld.","Continue",name,min);
  1865. }
  1866.  
  1867. void NewHeights(void)
  1868. {
  1869. struct Character *chr;
  1870. ULONG i;
  1871. UBYTE *new_char;
  1872.  
  1873.   for (i = 0; i < 256; i++)
  1874.   {
  1875.     chr = CharBuffer+i;
  1876.     if (chr->chr_Data)
  1877.     {
  1878.       if ((new_char = AllocVec(chr->chr_Width*Height,MEMF_CLEAR)) == NULL)
  1879.     Quit();
  1880.       CopyMem(chr->chr_Data,new_char,
  1881.     MIN(chr->chr_Height,Height)*chr->chr_Width);
  1882.       FreeVec(chr->chr_Data);
  1883.       chr->chr_Data = new_char;
  1884.     }
  1885.     chr->chr_Height = Height;
  1886.   }
  1887.   sprintf(WinTitle,"%s/%ld",FontName,Height);
  1888.   SetAttrs(FontWndObj,WINDOW_Title,WinTitle,TAG_DONE);
  1889. }
  1890.  
  1891. void NewWidths(void)
  1892. {
  1893. struct Character *chr;
  1894. ULONG i;
  1895.  
  1896.   for (i = 0; i < 256; i++)
  1897.   {
  1898.     chr = CharBuffer+i;
  1899.     if (chr->chr_Data) ChangeCharWidth(chr,Width,0,0);
  1900.     chr->chr_Width = Width;
  1901.   }
  1902. }
  1903.  
  1904. void ChangeCharWidth(struct Character *chr, ULONG width, ULONG newoffset,
  1905.   ULONG oldoffset)
  1906. {
  1907. ULONG j;
  1908. UBYTE *data = NULL;
  1909.  
  1910.   if ((width > 0) && (chr->chr_Data))
  1911.   {
  1912.     if ((data = AllocVec(width*Height,MEMF_CLEAR)) == NULL) Quit();
  1913.     for (j = 0; j < Height; j++)
  1914.       CopyMem(chr->chr_Data+(j*chr->chr_Width)+oldoffset,
  1915.       data+(j*width)+newoffset,MIN(chr->chr_Width,width));
  1916.   }
  1917.   if (chr->chr_Data) FreeVec(chr->chr_Data);
  1918.   if (Reversed == FALSE)
  1919.     SpaceTable[chr-CharBuffer] += (width-chr->chr_Width);
  1920.   chr->chr_Data = data;
  1921.   chr->chr_Width = width;
  1922.   CheckWidthKern(chr);
  1923. }
  1924.  
  1925. void CheckWidthKern(struct Character *chr)
  1926. {
  1927.   if (chr == WidthChar)
  1928.   {
  1929.     if (WidthNode->chln_Number < 256)
  1930.       sprintf(WidthTitle,"Change Width of %lu (from %d)",
  1931.         WidthNode->chln_Number,WidthChar->chr_Width);
  1932.     else
  1933.       sprintf(WidthTitle,"Change Width of blank (from %d)",
  1934.     WidthChar->chr_Width);
  1935.     SetGadgetAttrs(ChrWidthScroll,WidthWnd,NULL,
  1936.       PGA_Top,0,
  1937.       PGA_Total,1,
  1938.       PGA_Visible,1,TAG_DONE);
  1939.     SetGadgetAttrs(ChrWidthInt,WidthWnd,NULL,
  1940.       STRINGA_LongVal,WidthChar->chr_Width,TAG_DONE);
  1941.     SetAttrs(WidthWndObj,WINDOW_Title,WidthTitle,TAG_DONE);
  1942.   }
  1943.   if (chr == KernChar)
  1944.     SetGadgetAttrs(SpaceObj,KernWnd,NULL,
  1945.       STRINGA_LongVal,SpaceTable[KernNode->chln_Number],TAG_DONE);
  1946. }
  1947.  
  1948. void SavePrefs(char *filename)
  1949. {
  1950. BPTR file;
  1951.  
  1952.   SleepWindows();
  1953.   Prefs.Flags = 0;
  1954.   if (NewCustom) Prefs.Flags |= PREFS_CUSTOMSCREEN;
  1955.   if (PixelBorder) Prefs.Flags |= PREFS_PIXELBORDER;
  1956.   if (file = Open(filename,MODE_NEWFILE))
  1957.   {
  1958.     Write(file,&Prefs,sizeof(struct Preferences));
  1959.     Close(file);
  1960.   }
  1961.   else ShowReq("Cannot save preferences to\n\"%s\"","Continue",filename);
  1962.   WakeWindows();
  1963. }
  1964.  
  1965. void LoadPrefs(void)
  1966. {
  1967. BPTR file;
  1968.  
  1969.   if ((file = Open("ENV:"NAME".prefs",MODE_OLDFILE)) == 0)
  1970.     file = Open("PROGDIR:"NAME".prefs",MODE_OLDFILE);
  1971.   if (file)
  1972.   {
  1973.     Read(file,&Prefs,sizeof(struct Preferences));
  1974.     Close(file);
  1975.     CustomScreen = (Prefs.Flags & PREFS_CUSTOMSCREEN) ? TRUE : FALSE;
  1976.     PixelBorder = (Prefs.Flags & PREFS_PIXELBORDER) ? TRUE : FALSE;
  1977.   }
  1978. }
  1979.  
  1980. void CopyChar(struct CharNode *node)
  1981. {
  1982. struct Character *chr;
  1983.  
  1984.   chr = node->chln_Character;
  1985.   if ((chr->chr_Width > 0) && (chr->chr_Data))
  1986.   {
  1987.     if (ClipChar.chr_Data) FreeVec(ClipChar.chr_Data);
  1988.     ClipChar.chr_Data = NULL;
  1989.     ClipChar.chr_Width = chr->chr_Width;
  1990.     ClipChar.chr_Height = chr->chr_Height;
  1991.     if ((ClipChar.chr_Data = AllocVec(chr->chr_Width*chr->chr_Height,
  1992.       MEMF_CLEAR)) == NULL) Quit();
  1993.     CopyMem(chr->chr_Data,ClipChar.chr_Data,chr->chr_Width*chr->chr_Height);
  1994.   }
  1995. }
  1996.  
  1997. void PasteChar(struct CharNode *node)
  1998. {
  1999. struct Character *chr;
  2000. ULONG i;
  2001.  
  2002.   chr = node->chln_Character;
  2003.   if (ClipChar.chr_Data)
  2004.   {
  2005.     if (chr->chr_Data) FreeVec(chr->chr_Data);
  2006.     chr->chr_Data = NULL;
  2007.     if (Proportional) chr->chr_Width = ClipChar.chr_Width;
  2008.     if (chr->chr_Width > 0)
  2009.     {
  2010.       if ((chr->chr_Data = AllocVec(chr->chr_Width*chr->chr_Height,
  2011.     MEMF_CLEAR)) == NULL) Quit();
  2012.       for (i = 0; i < MIN(chr->chr_Height,ClipChar.chr_Height); i++)
  2013.     CopyMem(ClipChar.chr_Data+(i*ClipChar.chr_Width),
  2014.     chr->chr_Data+(i*chr->chr_Width),
  2015.     MIN(chr->chr_Width,ClipChar.chr_Width));
  2016.     }
  2017.     RedrawEdit(node);
  2018.   }
  2019. }
  2020.  
  2021. void SaveFont(BOOL tables)
  2022. {
  2023. char fontpath[256], filename[256], datestr[LEN_DATSTRING];
  2024. ULONG filesize = 0, numchars, bitwidth = 0, i, offbit, hunkstart;
  2025. struct DateTime dt;
  2026. struct DiskFontHeader *dfh;
  2027. struct TextFont *tfh;
  2028. struct FontContentsHeader *fch;
  2029. ULONG *longptr, *relocstart;
  2030. UBYTE *buffer, *mptr, *fontdataptr;
  2031. struct charDef *fontlocptr;
  2032. WORD *fontkernptr;
  2033. BPTR fontfile, contfile, lock;
  2034.  
  2035.   strcpy(fontpath,SavePath);
  2036.   AddPart(fontpath,FontName,256);
  2037.   sprintf(filename,"%s/%ld",fontpath,Height);
  2038.  
  2039.   DateStamp(&(dt.dat_Stamp));
  2040.   dt.dat_Format = FORMAT_CDN;
  2041.   dt.dat_Flags = 0;
  2042.   dt.dat_StrDay = NULL;
  2043.   dt.dat_StrDate = datestr;
  2044.   dt.dat_StrTime = NULL;
  2045.   DateToStr(&dt);
  2046.   while ((mptr = strchr(datestr,'-')) != NULL) *mptr = '.';
  2047.  
  2048.   numchars = LastChar-FirstChar+2;
  2049.   filesize += 14*4;            /* Hunk structure */
  2050.   filesize += sizeof(struct DiskFontHeader);
  2051.   filesize += 4*4;            /* Relocatable addresses */
  2052.   for (i = FirstChar; i < LastChar+1; i++)
  2053.     bitwidth += (CharBuffer+i)->chr_Width;
  2054.   bitwidth += (CharBuffer+256)->chr_Width;
  2055.   if (bitwidth % 16 > 0) bitwidth = ((bitwidth/16)+1)*16;
  2056.   filesize += (bitwidth/8)*Height;    /* Character data */
  2057.   filesize += numchars*sizeof(struct charDef);
  2058.   if (tables)
  2059.   {
  2060.     filesize += numchars*4;        /* Space and kern tables */
  2061.     filesize += 2*4;            /* Table relocs */
  2062.   }
  2063.   if (filesize % 4 > 0) filesize = ((filesize/4)+1)*4;
  2064.   if ((buffer = AllocVec(filesize,MEMF_CLEAR)) != NULL)
  2065.   {
  2066.     longptr = buffer;
  2067.     *longptr++ = 0x000003F3;        /* Hunk structure */
  2068.     *longptr++ = 0x00000000;
  2069.     *longptr++ = 0x00000001;
  2070.     *longptr++ = 0x00000000;
  2071.     *longptr++ = 0x00000000;
  2072.     *longptr++ = (filesize - ((tables ? 19 : 17)*4))/4;
  2073.     *longptr++ = 0x000003E9;        /* Hunk size (twice) */
  2074.     *longptr++ = (filesize - ((tables ? 19 : 17)*4))/4;
  2075.     hunkstart = longptr;        /* All relocs relative to here */
  2076.     *longptr++ = 0x70FF4E75;        /* MOVEQ #-1,D0 RTS */
  2077.     relocstart = buffer+filesize-((9+(tables ? 2 : 0))*4);
  2078.  
  2079.     dfh = longptr;
  2080.     dfh->dfh_DF.ln_Type = NT_FONT;
  2081.     dfh->dfh_DF.ln_Name = (UBYTE *)((ULONG)dfh->dfh_Name-hunkstart);
  2082.     dfh->dfh_FileID = DFH_ID;
  2083.     sprintf(dfh->dfh_Name,"$VER: %s%d 39.0 (%s)",FontName,Height,datestr);
  2084.  
  2085.     fontdataptr = ((UBYTE *)dfh)+sizeof(struct DiskFontHeader);
  2086.     fontlocptr = fontdataptr+((bitwidth/8)*Height);
  2087.     if ((ULONG)fontlocptr % 2 > 0)
  2088.       fontlocptr = (struct charDef *)((((ULONG)fontlocptr/2)+1)*2);
  2089.     fontkernptr = (UBYTE *)fontlocptr + numchars*sizeof(struct charDef);
  2090.  
  2091.     tfh = &(dfh->dfh_TF);
  2092.     tfh->tf_Message.mn_Node.ln_Type = NT_FONT;
  2093.     tfh->tf_Message.mn_Node.ln_Name = dfh->dfh_DF.ln_Name;
  2094.     tfh->tf_YSize = Height;
  2095.     if (Normal == FALSE)
  2096.     {
  2097.       if (Bold) tfh->tf_Style |= FSF_BOLD;
  2098.       if (Italic) tfh->tf_Style |= FSF_ITALIC;
  2099.       if (ULine) tfh->tf_Style |= FSF_UNDERLINED;
  2100.       if (Extended) tfh->tf_Style |= FSF_EXTENDED;
  2101.     }
  2102.     else tfh->tf_Style = FS_NORMAL;
  2103.     tfh->tf_Flags = FPF_DESIGNED|FPF_DISKFONT;
  2104.     if (Proportional) tfh->tf_Flags |= FPF_PROPORTIONAL;
  2105.     if (Reversed) tfh->tf_Flags |= FPF_REVPATH;
  2106.     switch (Aspect)
  2107.     {
  2108.       case 1:
  2109.     tfh->tf_Flags |= FPF_TALLDOT;
  2110.     break;
  2111.       case 2:
  2112.     tfh->tf_Flags |= FPF_WIDEDOT;
  2113.     break;
  2114.     }
  2115.     tfh->tf_XSize = Width;
  2116.     tfh->tf_Baseline = Baseline;
  2117.     tfh->tf_BoldSmear = Smear;
  2118.     tfh->tf_LoChar = FirstChar;
  2119.     tfh->tf_HiChar = LastChar;
  2120.     tfh->tf_CharData = (UBYTE *)((ULONG)fontdataptr-hunkstart);
  2121.     tfh->tf_Modulo = bitwidth/8;
  2122.     tfh->tf_CharLoc = (UBYTE *)((ULONG)fontlocptr-hunkstart);
  2123.     if (tables)
  2124.     {
  2125.       tfh->tf_CharSpace = (UBYTE *)((ULONG)fontkernptr-hunkstart);
  2126.       tfh->tf_CharKern =
  2127.     (UBYTE *)((ULONG)fontkernptr+(numchars*2)-hunkstart);
  2128.     }
  2129.     for (i = FirstChar, offbit = 0; i < LastChar+1; i++)
  2130.     {
  2131.       WriteCharData(fontlocptr,fontdataptr,i-FirstChar,i,&offbit,bitwidth/8);
  2132.       if (tables)
  2133.       {
  2134.     *(fontkernptr+(i-FirstChar)) = SpaceTable[i];
  2135.     *(fontkernptr+(i-FirstChar+numchars)) = KernTable[i];
  2136.       }
  2137.     }
  2138.     WriteCharData(fontlocptr,fontdataptr,numchars-1,256,&offbit,bitwidth/8);
  2139.     if (tables)
  2140.     {
  2141.       *(fontkernptr+(numchars-1)) = SpaceTable[256];
  2142.       *(fontkernptr+(numchars-1+numchars)) = KernTable[256];
  2143.     }
  2144.  
  2145.     *relocstart++ = 0x000003EC;        /* Reloc structure */
  2146.     *relocstart++ = 4 + (tables ? 2 : 0);
  2147.     *relocstart++ = 0x00000000;
  2148.     if (tables)
  2149.     {
  2150.       *relocstart++ = (ULONG)(&(tfh->tf_CharKern))-hunkstart;
  2151.       *relocstart++ = (ULONG)(&(tfh->tf_CharSpace))-hunkstart;
  2152.     }
  2153.     *relocstart++ = (ULONG)(&(tfh->tf_CharLoc))-hunkstart;
  2154.     *relocstart++ = (ULONG)(&(tfh->tf_CharData))-hunkstart;
  2155.     *relocstart++ = (ULONG)(&(tfh->tf_Message.mn_Node.ln_Name))-hunkstart;
  2156.     *relocstart++ = (ULONG)(&(dfh->dfh_DF.ln_Name))-hunkstart;
  2157.     *relocstart++ = 0x00000000;
  2158.     *relocstart++ = 0x000003F2;
  2159.  
  2160.     WindowBusy(SaveWndObj);
  2161.     lock = Lock(fontpath,ACCESS_READ);
  2162.     WindowReady(SaveWndObj);
  2163.     if (lock == 0)
  2164.     {
  2165.       if (SaveShowReq("Directory \"%s\"\ndoes not exist.","Create|Cancel",
  2166.     fontpath))
  2167.       {
  2168.         WindowBusy(SaveWndObj);
  2169.         lock = CreateDir(fontpath);
  2170.         WindowReady(SaveWndObj);
  2171.     if (lock == 0)
  2172.     {
  2173.       SaveShowReq("Cannot create directory\n\"%s\".","Cancel",fontpath);
  2174.       if (buffer) FreeVec(buffer);
  2175.       return;
  2176.     }
  2177.     else UnLock(lock);
  2178.       }
  2179.       else
  2180.       {
  2181.     if (buffer) FreeVec(buffer);
  2182.     return;
  2183.       }
  2184.     }
  2185.     else UnLock(lock);
  2186.  
  2187.     WindowBusy(SaveWndObj);
  2188.     lock = Lock(filename,ACCESS_READ);
  2189.     WindowReady(SaveWndObj);
  2190.     if (lock)
  2191.     {
  2192.       UnLock(lock);
  2193.       if (!SaveShowReq("File \"%s\" exists.","Overwrite|Cancel",filename))
  2194.       {
  2195.     if (buffer) FreeVec(buffer);
  2196.     return;
  2197.       }
  2198.     }
  2199.  
  2200.     WindowBusy(SaveWndObj);
  2201.     fontfile = Open(filename,MODE_NEWFILE);
  2202.     WindowReady(SaveWndObj);
  2203.     if (fontfile)
  2204.     {
  2205.       WindowBusy(SaveWndObj);
  2206.       Write(fontfile,buffer,filesize);
  2207.       Close(fontfile);
  2208.  
  2209.       lock = Lock(SavePath,ACCESS_READ);
  2210.       WindowReady(SaveWndObj);
  2211.       if (lock != 0)
  2212.       {
  2213.     sprintf(filename,"%s.font",fontpath);
  2214.     WindowBusy(SaveWndObj);
  2215.     fch = NewFontContents(lock,FilePart(filename));
  2216.     WindowReady(SaveWndObj);
  2217.     if (fch != NULL)
  2218.     {
  2219.       WindowBusy(SaveWndObj);
  2220.       contfile = Open(filename,MODE_NEWFILE);
  2221.       WindowReady(SaveWndObj);
  2222.       if (contfile != 0)
  2223.       {
  2224.         WindowBusy(SaveWndObj);
  2225.         Write(contfile,fch,sizeof(struct FontContentsHeader)+
  2226.           (fch->fch_NumEntries*sizeof(struct FontContents)));
  2227.         Close(contfile);
  2228.         WindowReady(SaveWndObj);
  2229.       }
  2230.       else SaveShowReq("Cannot write font header to \n\"%s\".","Cancel",
  2231.         filename);
  2232.       DisposeFontContents(fch);
  2233.     }
  2234.     else ShowReq("Cannot create font header.","Cancel");
  2235.     UnLock(lock);
  2236.       }
  2237.     }
  2238.     else SaveShowReq("Cannot write font data to \n\"%s\".","Cancel",
  2239.       filename);
  2240.   }
  2241.   else SaveShowReq("Not enough memory.","Cancel");
  2242.   if (buffer) FreeVec(buffer);
  2243.   FlushAllFonts();
  2244. }
  2245.  
  2246. ULONG SaveShowReq(char *text,char *gadgets,...)
  2247. {
  2248. va_list va;
  2249. struct EasyStruct req =
  2250.   { sizeof(struct EasyStruct),0,NAME,NULL,NULL };
  2251. ULONG retcode;
  2252.  
  2253.   if (SaveWnd) WindowBusy(SaveWndObj);
  2254.   req.es_TextFormat = text;
  2255.   req.es_GadgetFormat = gadgets;
  2256.   va_start(va,gadgets);
  2257.   retcode = EasyRequestArgs(SaveWnd,&req,NULL,va);
  2258.   va_end(va);
  2259.   if (SaveWnd) WindowReady(SaveWndObj);
  2260.   return (retcode);
  2261. }
  2262.  
  2263. void WriteCharData(struct charDef *cd, UBYTE *fontdataptr, ULONG dest,
  2264.   ULONG src, ULONG *off, ULONG mod)
  2265. {
  2266. struct Character *chr;
  2267. UBYTE *data;
  2268. ULONG i,j,width,widthi,modi,offset;
  2269.  
  2270.   chr = CharBuffer+src;
  2271.   data = chr->chr_Data;
  2272.   width = chr->chr_Width;
  2273.   offset = *off;
  2274.   for (i = 0; i < chr->chr_Height; i++)
  2275.   {
  2276.     modi = mod*i;
  2277.     widthi = width*i;
  2278.     for (j = 0; j < width; j++)
  2279.     {
  2280.       if (*(data+widthi+j) == 1)
  2281.     *(fontdataptr+modi+((offset+j)>>3)) |= 128>>((offset+j)&7);
  2282.     }
  2283.   }
  2284.   (cd+dest)->charOffset = offset;
  2285.   (cd+dest)->charBitWidth = width;
  2286.   *off += width;
  2287.  
  2288. }
  2289.  
  2290. void FlushAllFonts(void)
  2291. {
  2292. UBYTE *free;
  2293.  
  2294.   if ((free = AllocMem(~0,MEMF_ANY)) != NULL) FreeMem(free,~0);
  2295. }
  2296.