home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 9 / 09.iso / l / l196 / 3.ddi / FONTB.BA$ / FONTB.bin
Encoding:
Text File  |  1990-06-24  |  51.4 KB  |  1,792 lines

  1. '*** FONTB.BAS - Font Routines for the Presentation Graphics Toolbox in
  2. '           Microsoft BASIC 7.1, Professional Development System
  3. '              Copyright (C) 1987-1990, Microsoft Corporation
  4. '
  5. '  NOTE:  This sample source code toolbox is intended to demonstrate some
  6. '  of the extended capabilities of Microsoft BASIC 7.1 Professional Development
  7. '  system that can help to leverage the professional developer's time more
  8. '  effectively.  While you are free to use, modify, or distribute the routines
  9. '  in this module in any way you find useful, it should be noted that these are
  10. '  examples only and should not be relied upon as a fully-tested "add-on"
  11. '  library.
  12. '
  13. '  PURPOSE:  These are the toolbox routines to handle graphics text using
  14. '            Windows format raster font files:
  15. '
  16. '  To create a library and QuickLib containing the font routines found
  17. '  in this file, follow these steps:
  18. '       BC /X/FS fontb.bas
  19. '       LIB fontb.lib + fontb + fontasm + qbx.lib;
  20. '       LINK /Q fontb.lib, fontb.qlb,,qbxqlb.lib;
  21. '  If you are going to use this FONTB.QLB QuickLib in conjunction with
  22. '  the charting source code (CHRTB.BAS) or the UI toobox source code
  23. '  (GENERAL.BAS, WINDOW.BAS, MENU.BAS and MOUSE.BAS), you need to
  24. '  include the assembly code routines referenced in these files.  For the
  25. '  charting routines, create FONTB.LIB as follows before you create the
  26. '  QuickLib:
  27. '       LIB fontb.lib + fontb + fontasm + chrtasm + qbx.lib;
  28. '  For the UI toolbox routines, create the library as follows:
  29. '       LIB fontb.lib + fontb + fontasm + uiasm + qbx.lib;
  30. '**************************************************************************
  31.  
  32. ' $INCLUDE: 'QBX.BI'
  33. ' $INCLUDE: 'FONTB.BI'
  34.  
  35. CONST cFALSE = 0              ' Logical False
  36. CONST cTRUE = NOT cFALSE      ' Logical True
  37.  
  38. CONST cDefaultColor = 15      ' Default character color (white in all modes)
  39. CONST cDefaultDir = 0         ' Default character direction
  40. CONST cDefaultFont = 1        ' Default font selected in LoadFont
  41.  
  42. CONST cMaxFaceName = 32       ' Maximum length of a font name
  43. CONST cMaxFileName = 66       ' Maximum length of a font file name
  44. CONST cFontResource = &H8008  ' Identifies a font resource
  45. CONST cBitMapType = 0         ' Bitmap font type
  46.  
  47. CONST cFileFont = 0           ' Font comes from file
  48. CONST cMemFont = 1            ' Font comes from memory
  49.  
  50. CONST cSizeFontHeader = 118   ' Size of Windows font header
  51.  
  52. ' *********************************************************************
  53. ' Data Types:
  54.  
  55. ' Some global variables used:
  56. TYPE GlobalParams
  57.     MaxRegistered     AS INTEGER     ' Max number of registered fonts allowed
  58.     MaxLoaded         AS INTEGER     ' Max number of loaded fonts allowed
  59.     TotalRegistered   AS INTEGER     ' Number of fonts actually registered
  60.     TotalLoaded       AS INTEGER     ' Number of fonts actually loaded
  61.  
  62.     NextDataBlock     AS INTEGER     ' Next available block in font buffer
  63.  
  64.     CurrentFont       AS INTEGER     ' Current font number in loaded fonts
  65.     CHeight           AS INTEGER     ' Character height of current font
  66.     FChar             AS INTEGER     ' First char in font
  67.     LChar             AS INTEGER     ' Last char in font
  68.     DChar             AS INTEGER     ' Default char for font
  69.     DSeg              AS INTEGER     ' Segment of current font
  70.     DOffset           AS INTEGER     ' Offset of current font
  71.     FontSource        AS INTEGER     ' Source of current font (File or Mem)
  72.  
  73.     CharColorInit     AS INTEGER     ' cFALSE (0) means color not initialized
  74.     CharColor         AS INTEGER     ' Character color
  75.     CharDirInit       AS INTEGER     ' cFALSE (0) means dir not initialized
  76.     CharDir           AS INTEGER     ' Character direction
  77.     CharSet           AS INTEGER     ' Character mappings to use
  78.  
  79.     XPixInc           AS INTEGER     ' X increment direction (0, 1, -1)
  80.     YPixInc           AS INTEGER     ' Y increment direction (0, 1, -1)
  81.  
  82.     WindowSet         AS INTEGER     ' cTRUE if GTextWindow has been called
  83.     WX1               AS SINGLE      ' Minimum WINDOW X
  84.     WY1               AS SINGLE      ' Minimum WINDOW Y
  85.     WX2               AS SINGLE      ' Maximum WINDOW X
  86.     WY2               AS SINGLE      ' Maximum WINDOW Y
  87.     WScrn             AS INTEGER     ' cTRUE means Y increases top to bottom
  88.  
  89. END TYPE
  90.  
  91. ' The following 3 types are needed to read .FON files. They are documented
  92. ' in chapter 7 of the MS Windows Programmer's Reference:
  93.  
  94. ' Windows font file header:
  95. TYPE WFHeader
  96.     dfVersion         AS INTEGER
  97.     dfSize            AS LONG
  98.     dfCopyright       AS STRING * 60
  99.     dfType            AS INTEGER
  100.     dfPoints          AS INTEGER
  101.     dfVertRes         AS INTEGER
  102.     dfHorizRes        AS INTEGER
  103.     dfAscent          AS INTEGER
  104.     dfInternalLeading AS INTEGER
  105.     dfExternalLeading AS INTEGER
  106.     dfItalic          AS STRING * 1
  107.     dfUnderline       AS STRING * 1
  108.     dfStrikeOut       AS STRING * 1
  109.     dfWeight          AS INTEGER
  110.     dfCharSet         AS STRING * 1
  111.     dfPixWidth        AS INTEGER
  112.     dfPixHeight       AS INTEGER
  113.     dfPitchAndFamily  AS STRING * 1
  114.     dfAvgWidth        AS INTEGER
  115.     dfMaxWidth        AS INTEGER
  116.     dfFirstChar       AS STRING * 1
  117.     dfLastChar        AS STRING * 1
  118.     dfDefaultChar     AS STRING * 1
  119.     dfBreakChar       AS STRING * 1
  120.     dfWidthBytes      AS INTEGER
  121.     dfDevice          AS LONG
  122.     dfFace            AS LONG
  123.     dfBitsPointer     AS LONG
  124.     dfBitsOffset      AS LONG
  125.     pad               AS STRING * 1  ' To ensure word boundry
  126. END TYPE
  127.  
  128. ' Structure for reading resource type and number from a resource
  129. ' table:
  130. TYPE ResType
  131.     TypeID            AS INTEGER
  132.     NumResource       AS INTEGER
  133.     Reserved          AS LONG
  134. END TYPE
  135.  
  136. ' Structure for reading an actual resource entry:
  137. TYPE ResEntry
  138.     AddrOffset        AS INTEGER
  139.     Length            AS INTEGER
  140.     ResourceKeywd     AS INTEGER
  141.     ResID             AS INTEGER
  142.     Reserved1         AS LONG
  143. END TYPE
  144.  
  145. ' Internal font header data type:
  146. TYPE IFontInfo
  147.     Status            AS INTEGER  ' Processing status. 0=unproc. else <>0
  148.     FontHeader        AS WFHeader ' The Windows font header
  149.     FaceName          AS STRING * cMaxFaceName   ' Font name
  150.     FileName          AS STRING * cMaxFileName   ' File name
  151.     FontSource        AS INTEGER  ' 0=file, 1=memory
  152.     FileLoc           AS LONG     ' Location in resource file of font file
  153.     DataSeg           AS INTEGER  ' FontData index or Segment address of font
  154.     DataOffset        AS INTEGER  ' Offset  address of font if in memory
  155.     BitsOffset        AS INTEGER  ' Offset from beginning of data to bitmaps
  156. END TYPE
  157.  
  158. ' Type for selecting registered fonts via LoadFont:
  159. TYPE FontSpec
  160.     FaceName    AS STRING * cMaxFaceName
  161.     Pitch       AS STRING * 1
  162.     PointSize   AS INTEGER     ' Fonts point size
  163.     HorizRes    AS INTEGER     ' Horizontal resolution of font
  164.     VertRes     AS INTEGER     ' Vertical resolution of font
  165.     ScrnMode    AS INTEGER     ' Screen mode
  166.     Height      AS INTEGER     ' Pixel height of font
  167.   
  168.     Best        AS INTEGER     ' "Best" flag (true/false)
  169.   
  170.     RegNum      AS INTEGER     ' Number of font in registered list
  171.   
  172.     InMemory    AS INTEGER     ' Whether font is in memory (true/false)
  173.     HdrSeg      AS INTEGER     ' Segment of font in memory
  174.     HdrOff      AS INTEGER     ' Offset of font in segment
  175.     DataSeg     AS INTEGER     ' Segment of data in memory
  176.     DataOff     AS INTEGER     ' Offset of data in segment
  177. END TYPE
  178.  
  179. ' *********************************************************************
  180. ' Routine Declarations:
  181.  
  182. DECLARE SUB flSetFontErr (ErrNum AS INTEGER)
  183. DECLARE SUB flClearFontErr ()
  184. DECLARE SUB flRegisterFont (FileName$, FileNum%)
  185. DECLARE SUB flReadFont (I%)
  186. DECLARE SUB flSizeFontBuffer (NFonts%)
  187. DECLARE SUB flInitSpec (Spec AS ANY)
  188. DECLARE SUB flClearFontStatus ()
  189. DECLARE SUB flGetCurrentScrnSize (XPixels%, YPixels%)
  190. DECLARE SUB flGetBASICScrnSize (ScrnMode%, XPixels%, YPixels%)
  191. DECLARE SUB flInitMask ()
  192. DECLARE SUB flPSET (X%, Y%, Colr%)
  193. DECLARE SUB flChkMax ()
  194.  
  195. DECLARE FUNCTION flGetFonts! (NFonts%)
  196. DECLARE FUNCTION flMatchFont! (FSpec AS ANY)
  197. DECLARE FUNCTION flGetNum! (Txt$, ChPos%, Default!, ErrV!)
  198. DECLARE FUNCTION flGetNextSpec! (SpecTxt$, ChPos%, Spec AS ANY)
  199. DECLARE FUNCTION flDoNextResource! (Align%, FileName$, FileNum%)
  200. DECLARE FUNCTION flOutGChar% (X%, Y%, ChVal%)
  201.  
  202. ' -- Assembly language routines
  203. DECLARE SUB flMovMem ALIAS "fl_MovMem" (SEG dest AS ANY, BYVAL SrcSeg AS INTEGER, BYVAL SrcOffset AS INTEGER, BYVAL Count AS INTEGER)
  204. DECLARE FUNCTION flANSI% ALIAS "fl_ansi" (BYVAL I%)
  205.  
  206. DECLARE SUB flSetBltDir ALIAS "fl_SetBltDir" (BYVAL XPixInc%, BYVAL YPixInc%, BYVAL XRowInc%, BYVAL YRowInc%)
  207. DECLARE SUB flSetBltColor ALIAS "fl_SetBltColor" (BYVAL CharColor%)
  208. DECLARE SUB flSetBltParams ALIAS "fl_SetBltParams" (BYVAL HdrLen%, BYVAL CharHgt%, BYVAL FirstChar%, BYVAL LastChar%, BYVAL DefaultChar%)
  209. DECLARE FUNCTION flbltchar% ALIAS "fl_BltChar" (BYVAL FASeg%, BYVAL FAOffset%, BYVAL Char%, BYVAL X%, BYVAL Y%)
  210.  
  211. ' *********************************************************************
  212. ' Variable Definitions:
  213.  
  214. ' The following arrays hold font headers and font data as fonts are
  215. ' registered and loaded. They are dynamically allocated so they can be
  216. ' changed in size to accomodate the number of fonts a program will be
  217. ' using:
  218.  
  219. ' $DYNAMIC
  220.  
  221. ' Array to hold header information for registered fonts:
  222. DIM SHARED FontHdrReg(1 TO 10)  AS IFontInfo
  223.  
  224. ' Arrays to hold header information and registered font numbers
  225. ' for loaded fonts:
  226. DIM SHARED FontHdrLoaded(1 TO 10) AS IFontInfo
  227. DIM SHARED FontLoadList(1 TO 10) AS INTEGER
  228.  
  229. ' Array to hold font data information:
  230. DIM SHARED FontData(1 TO 1) AS FontDataBlock
  231.  
  232. ' $STATIC
  233.  
  234. ' Structure holding global parameters:
  235. DIM SHARED FGP AS GlobalParams
  236.  
  237. ' Error handler for flChkMax so these arrays will be dimensioned
  238. ' to 10 by default:
  239. SetMax:
  240.     REDIM FontHdrLoaded(1 TO 10) AS IFontInfo
  241.     REDIM FontHdrReg(1 TO 10) AS IFontInfo
  242.     REDIM FontLoadList(1 TO 10) AS INTEGER
  243.     RESUME
  244.  
  245. ' Error handler for out of memory error:
  246. MemErr:
  247.     flSetFontErr cNoFontMem
  248.     RESUME NEXT
  249.  
  250. ' Error handler for unexpected errors:
  251. UnexpectedErr:
  252.     flSetFontErr cFLUnexpectedErr + ERR
  253.     RESUME NEXT
  254.  
  255. ' File not found error: RegisterFonts
  256. NoFileErr:
  257.     flSetFontErr cFileNotFound
  258.     RESUME NEXT
  259.  
  260. '=== flChkMax - Makes sure that max font settings are correct and
  261. '                enforces default of 10 for max loaded and registered
  262. '
  263. '  Arguments:
  264. '     none
  265. '
  266. '  Return Values:
  267. '     none
  268. '
  269. '=================================================================
  270. SUB flChkMax STATIC
  271. SHARED FontHdrLoaded() AS IFontInfo
  272. SHARED FontHdrReg() AS IFontInfo
  273. SHARED FGP AS GlobalParams
  274.  
  275. ' Make sure that GP.MaxLoaded and GP.MaxRegistered match array dimensions
  276. ' this will only happen if user hasn't used SetMaxFonts and allows Fontlib
  277. ' to set a default of 10 since that is what the arrays are first DIM'd
  278. ' to:
  279.  
  280. ON ERROR GOTO SetMax
  281. FGP.MaxLoaded = UBOUND(FontHdrLoaded)
  282. FGP.MaxRegistered = UBOUND(FontHdrReg)
  283. ON ERROR GOTO UnexpectedErr
  284.  
  285. END SUB
  286.  
  287. '=== flClearFontErr - Sets the FontErr variable to 0
  288. '
  289. '  Arguments:
  290. '     none
  291. '
  292. '  Return Values:
  293. '     none
  294. '
  295. '=================================================================
  296. SUB flClearFontErr STATIC
  297.  
  298.     FontErr = 0
  299.  
  300. END SUB
  301.  
  302. '=== flClearFontStatus - Clears the status field in the registered font list
  303. '
  304. '  Arguments:
  305. '     none
  306. '
  307. '=================================================================
  308. SUB flClearFontStatus STATIC
  309. SHARED FGP AS GlobalParams
  310. SHARED FontHdrReg() AS IFontInfo
  311.  
  312. FOR I% = 1 TO FGP.TotalRegistered
  313.     FontHdrReg(I%).Status = 0
  314. NEXT I%
  315.  
  316. END SUB
  317.  
  318. '=== flDoNextResource - Processes resource from resource table:
  319. '
  320. '  Arguments:
  321. '     Align%      - Alignment shift count for finding resource data
  322. '
  323. '     FileName$   - Name of font file (passed to routine that actually
  324. '                   registers resource entry)
  325. '
  326. '     FileNum%    - File number for reading
  327. '
  328. '  Return Value:
  329. '     The number of fonts actually registered
  330. '
  331. '=================================================================
  332. FUNCTION flDoNextResource (Align%, FileName$, FileNum%) STATIC
  333. DIM ResID AS ResType, Entry AS ResEntry
  334.  
  335. ' Get the first few bytes identifying the resource type and the number
  336. ' of this type:
  337. GET FileNum%, , ResID
  338.  
  339. ' If this is not the last resource then process it:
  340. IF ResID.TypeID <> 0 THEN
  341.  
  342.     ' Loop through the entries of this resource and if an entry happens to be
  343.     ' a font resource then register it. The file location must be saved
  344.     ' for each entry in the resource table since the flRegisterFont
  345.     ' routine may go to some other part of the file to read the resource:
  346.     FOR ResourceEntry = 1 TO ResID.NumResource
  347.       
  348.         GET FileNum%, , Entry
  349.         NextResLoc# = SEEK(FileNum%)
  350.         IF ResID.TypeID = cFontResource THEN
  351.              
  352.             ' Seek to font information, register it, then seek back to
  353.             ' the next resource table entry:
  354.             SEEK FileNum%, Entry.AddrOffset * 2 ^ Align% + 1
  355.             flRegisterFont FileName$, FileNum%
  356.             SEEK FileNum%, NextResLoc#
  357.             IF FontErr <> 0 THEN EXIT FUNCTION
  358.  
  359.         END IF
  360.         
  361.     NEXT ResourceEntry
  362. END IF
  363.  
  364. ' Return the current resource type so that RegisterFonts knows when the
  365. ' last resource has been read:
  366. flDoNextResource = ResID.TypeID
  367.  
  368. END FUNCTION
  369.  
  370. '=== flGetBASICScrnSize - Returns screen size for specified BASIC screen mode
  371. '
  372. '  Arguments:
  373. '
  374. '     ScrnMode%   -  BASIC screen mode
  375. '
  376. '     XPixels%    -  Number of pixels in horizontal direction
  377. '
  378. '     YPixels%    -  Number of pixels in vertical direction
  379. '
  380. '=================================================================
  381. SUB flGetBASICScrnSize (ScrnMode%, XPixels%, YPixels%) STATIC
  382.     SELECT CASE ScrnMode%
  383.         CASE 1: XPixels% = 320: YPixels% = 200
  384.         CASE 2: XPixels% = 640: YPixels% = 200
  385.         CASE 3: XPixels% = 720: YPixels% = 348
  386.         CASE 4: XPixels% = 640: YPixels% = 400
  387.         CASE 7: XPixels% = 320: YPixels% = 200
  388.         CASE 8: XPixels% = 640: YPixels% = 200
  389.         CASE 9: XPixels% = 640: YPixels% = 350
  390.         CASE 10: XPixels% = 640: YPixels% = 350
  391.         CASE 11: XPixels% = 640: YPixels% = 480
  392.         CASE 12: XPixels% = 640: YPixels% = 480
  393.         CASE 13: XPixels% = 320: YPixels% = 200
  394.         CASE ELSE: XPixels% = 0: YPixels% = 0
  395.     END SELECT
  396. END SUB
  397.  
  398. '=== flGetCurrentScrnSize - Returns screen size for current screen mode
  399. '
  400. '  Arguments:
  401. '
  402. '     XPixels%    -  Number of pixels in horizontal direction
  403. '
  404. '     YPixels%    -  Number of pixels in vertical direction
  405. '
  406. '=================================================================
  407. SUB flGetCurrentScrnSize (XPixels%, YPixels%) STATIC
  408. DIM Regs AS RegType
  409.  
  410. ' Use DOS interrupt to get current video display mode:
  411. Regs.ax = &HF00
  412. CALL INTERRUPT(&H10, Regs, Regs)
  413.  
  414. ' Set screen size based on mode:
  415. SELECT CASE Regs.ax MOD 256
  416.     CASE &H4: XPixels% = 320: YPixels% = 200
  417.     CASE &H5: XPixels% = 320: YPixels% = 200
  418.     CASE &H6: XPixels% = 640: YPixels% = 200
  419.     CASE &H7: XPixels% = 720: YPixels% = 350
  420.     CASE &H8: XPixels% = 720: YPixels% = 348     ' Hercules
  421.     CASE &HD: XPixels% = 320: YPixels% = 200
  422.     CASE &HE: XPixels% = 640: YPixels% = 200
  423.     CASE &HF: XPixels% = 640: YPixels% = 350
  424.     CASE &H10: XPixels% = 640: YPixels% = 350
  425.     CASE &H11: XPixels% = 640: YPixels% = 480
  426.     CASE &H12: XPixels% = 640: YPixels% = 480
  427.     CASE &H13: XPixels% = 320: YPixels% = 200
  428.     CASE &H40: XPixels% = 640: YPixels% = 400    ' Olivetti
  429.     CASE ELSE: XPixels% = 0: YPixels = 0
  430. END SELECT
  431. END SUB
  432.  
  433. '=== flGetFonts - Gets fonts specified in FontLoadList
  434. '
  435. '  Arguments:
  436. '     NFonts%  -  Number of fonts to load
  437. '
  438. '  Return Values:
  439. '     Number of fonts successfully loaded
  440. '
  441. '=================================================================
  442. FUNCTION flGetFonts (NFonts%) STATIC
  443. SHARED FGP AS GlobalParams
  444. SHARED FontHdrReg() AS IFontInfo
  445. SHARED FontHdrLoaded() AS IFontInfo
  446. SHARED FontLoadList() AS INTEGER
  447.  
  448. ' Re-dimension font data buffer to fit all the fonts:
  449. flSizeFontBuffer (NFonts%)
  450. IF FontErr = cNoFontMem THEN EXIT FUNCTION
  451.  
  452. ' Clear the font status variables then load the fonts (the status variable
  453. ' is used to record which ones have already been loaded so they aren't
  454. ' loaded more than once):
  455. flClearFontStatus
  456. FOR Font% = 1 TO NFonts%
  457.     FontNum% = FontLoadList(Font%)
  458.  
  459.     ' If font already loaded then just copy the already-filled-out header
  460.     ' to the new slot:
  461.     IF FontHdrReg(FontNum%).Status <> 0 THEN
  462.         FontHdrLoaded(Font%) = FontHdrLoaded(FontHdrReg(FontNum%).Status)
  463.   
  464.     ' Otherwise, read the font and update status in registered version
  465.     ' to point to the first slot it was loaded into (so we can go get
  466.     ' an already-filled-out header from there):
  467.     ELSE
  468.         FontHdrLoaded(Font%) = FontHdrReg(FontNum%)
  469.       
  470.         ' Hold any existing errors:
  471.         HoldErr% = FontErr
  472.         flClearFontErr
  473.  
  474.         flReadFont Font%
  475.       
  476.         ' If there was an error in reading font, exit. Otherwise,
  477.         ' reset the error to what it was before and continue:
  478.         IF FontErr <> 0 THEN
  479.             flGetFonts = FontNum% - 1
  480.             EXIT FUNCTION
  481.         ELSE
  482.             flSetFontErr HoldErr%
  483.         END IF
  484.  
  485.         FontHdrReg(FontNum%).Status = Font%
  486.     END IF
  487. NEXT Font%
  488.  
  489. flGetFonts = NFonts%
  490. END FUNCTION
  491.  
  492. '=== flGetNextSpec - Parses the next spec from the spec string
  493. '
  494. '  Arguments:
  495. '     SpecTxt$ -  String containing font specifications
  496. '
  497. '     ChPos%   -  Current position in string (updated in this routine)
  498. '
  499. '     Spec     -  Structure to contain parsed values
  500. '
  501. '
  502. '  Return Values:
  503. '     0    -  Spec was found
  504. '
  505. '     1    -  No spec found
  506. '
  507. '     2    -  Invalid spec found
  508. '=================================================================
  509. FUNCTION flGetNextSpec (SpecTxt$, ChPos%, Spec AS FontSpec) STATIC
  510.  
  511. ' Initialize some things:
  512. SpecErr = cFALSE
  513. SpecLen% = LEN(SpecTxt$)
  514.  
  515. ' If character pos starts past end of spec then we're done:
  516. IF ChPos% > SpecLen% THEN
  517.     flGetNextSpec = 1
  518.     EXIT FUNCTION
  519. END IF
  520.  
  521. DO UNTIL ChPos% > SpecLen%
  522.  
  523.     Param$ = UCASE$(MID$(SpecTxt$, ChPos%, 1))
  524.     ChPos% = ChPos% + 1
  525.  
  526.     SELECT CASE Param$
  527.  
  528.         ' Skip blanks:
  529.         CASE " ":
  530.  
  531.         ' Font title:
  532.         CASE "T":
  533.           
  534.             ' Scan for font title until blank or end of string:
  535.             StartPos% = ChPos%
  536.             DO UNTIL ChPos% > SpecLen%
  537.                 Char$ = MID$(SpecTxt$, ChPos%, 1)
  538.                 ChPos% = ChPos% + 1
  539.             LOOP
  540.           
  541.             ' Extract the title:
  542.             TitleLen% = ChPos% - StartPos%
  543.             IF TitleLen% <= 0 THEN
  544.                 SpecErr = cTRUE
  545.             ELSE
  546.                 Spec.FaceName = MID$(SpecTxt$, StartPos%, TitleLen%)
  547.             END IF
  548.  
  549.         ' Fixed or Proportional font:
  550.         CASE "F", "P":
  551.             Spec.Pitch = Param$
  552.  
  553.         ' Font Size (default to 12 points):
  554.         CASE "S":
  555.             Spec.PointSize = flGetNum(SpecTxt$, ChPos%, 12, SpecErr)
  556.  
  557.         ' Screen Mode:
  558.         CASE "M":
  559.             Spec.ScrnMode = flGetNum(SpecTxt$, ChPos%, -1, SpecErr)
  560.  
  561.         ' Pixel Height:
  562.         CASE "H":
  563.             Spec.Height = flGetNum(SpecTxt$, ChPos%, 0, SpecErr)
  564.  
  565.         ' Best fit:
  566.         CASE "B":
  567.             Spec.Best = cTRUE
  568.  
  569.         ' Registered font number:
  570.         CASE "N":
  571.             Spec.RegNum = flGetNum(SpecTxt$, ChPos%, 0, SpecErr)
  572.  
  573.         ' Font in memory:
  574.         CASE "R":
  575.             Spec.InMemory = cTRUE
  576.  
  577.         ' Spec separator:
  578.         CASE "/":
  579.             EXIT DO
  580.  
  581.         ' Anything else is an error:
  582.         CASE ELSE:
  583.             SpecErr = cTRUE
  584.             ChPos% = ChPos% + 1
  585.     END SELECT
  586. LOOP
  587.  
  588. ' Spec is parsed, make sure a valid screen mode has been specified and
  589. ' adjust point sizes for 320x200 screens if necessary:
  590. IF Spec.PointSize <> 0 THEN
  591.   
  592.     ' Get screen size for specified mode (with "M" param) or current
  593.     ' screen mode:
  594.     IF Spec.ScrnMode < 0 THEN
  595.         flGetCurrentScrnSize XPixels%, YPixels%
  596.     ELSE
  597.         flGetBASICScrnSize Spec.ScrnMode, XPixels%, YPixels%
  598.     END IF
  599.  
  600.     ' If this isn't a graphics mode then set an error and skip the rest:
  601.     IF XPixels% = 0 THEN
  602.         SpecErr = cTRUE
  603.         Spec.PointSize = 0
  604.  
  605.     ' If this is a 320x200 screen mode adjust point sizes to the
  606.     ' equivalent EGA font point sizes. Also set the horizontal
  607.     ' a vertical resolutions to search for in fonts (horizontal is
  608.     ' 96 for all modes, vertical varies):
  609.     ELSE
  610.       
  611.         ' Use a horizontal resolution of 96 for all screens:
  612.         Spec.HorizRes = 96
  613.  
  614.         IF XPixels% = 320 THEN
  615.             Spec.VertRes = 72
  616.           
  617.             ' In a 320x200 mode scale point sizes to their equivalent
  618.             ' EGA fonts (special case 14 and 24 point fonts to map them
  619.             ' to the closest EGA font otherwise multiply point size by
  620.             ' 2/3:
  621.             SELECT CASE Spec.PointSize
  622.                 CASE 14: Spec.PointSize = 10
  623.                 CASE 24: Spec.PointSize = 18
  624.                 CASE ELSE: Spec.PointSize = Spec.PointSize * 2 / 3
  625.             END SELECT
  626.  
  627.         ELSE
  628.           
  629.             ' Other screen modes vary only in vertical resolution:
  630.             SELECT CASE YPixels%
  631.                 CASE 200: Spec.VertRes = 48
  632.                 CASE 350: Spec.VertRes = 72
  633.                 CASE 480: Spec.VertRes = 96
  634.             END SELECT
  635.         END IF
  636.     END IF
  637. END IF
  638.  
  639. ' If an error was found somewhere then pass it on and set-up to load
  640. ' first font:
  641. IF SpecErr THEN
  642.     flGetNextSpec = 2
  643.     Spec.RegNum = 1
  644. ELSE
  645.     flGetNextSpec = 0
  646. END IF
  647.  
  648. END FUNCTION
  649.  
  650. '=== flGetNum - Parses number from string
  651. '
  652. '  Arguments:
  653. '     Txt$     -  String from which to parse number
  654. '
  655. '     ChPos%   -  Character position on which to start
  656. '
  657. '     Default  -  Default value if number not found
  658. '
  659. '     ErrV     -  Returns error as cTrue or cFalse
  660. '
  661. '  Return Values:
  662. '     Returns value found or default
  663. '
  664. '  Notes:
  665. '     Simple state machine:
  666. '        state 0: Looking for first char
  667. '        state 1: Found start (+, -, or digit)
  668. '        state 2: Done
  669. '        state 3: Error
  670. '
  671. '=================================================================
  672. FUNCTION flGetNum (Txt$, ChPos%, Default, ErrV) STATIC
  673.  
  674. ' Start in state 0
  675. State = 0
  676.  
  677. ' Loop until done
  678. DO
  679.     Char$ = MID$(Txt$, ChPos%, 1)
  680.     SELECT CASE Char$
  681.  
  682.         ' Plus and minus are only OK at the beginning:
  683.         CASE "+", "-":
  684.             SELECT CASE State
  685.                 CASE 0: Start% = ChPos%: State = 1
  686.                 CASE ELSE: State = 3
  687.             END SELECT
  688.  
  689.         ' Digits are OK at the beginning of after plus and minus:
  690.         CASE "0" TO "9":
  691.             SELECT CASE State
  692.                 CASE 0: Start% = ChPos%: State = 1
  693.                 CASE ELSE:
  694.             END SELECT
  695.  
  696.         ' Spaces are skipped:
  697.         CASE " ":
  698.  
  699.         ' Anything else is an error at the beginning or marks the end:
  700.         CASE ELSE:
  701.             SELECT CASE State
  702.                 CASE 0: State = 3
  703.                 CASE 1: State = 2
  704.             END SELECT
  705.     END SELECT
  706.  
  707.     ' Go to next character:
  708.     ChPos% = ChPos% + 1
  709. LOOP UNTIL State = 2 OR State = 3
  710.  
  711. ' Scanning is complete; adjust ChPos% to mark last character processed:
  712. ChPos% = ChPos% - 1
  713.  
  714. ' If error then set default number:
  715. IF State = 3 THEN
  716.     flGetNum = Default
  717.     ErrV = cTRUE
  718.  
  719. ' Otherwise, extract number and get its value:
  720. ELSE
  721.     EndPos% = ChPos% - 1
  722.     flGetNum = VAL(MID$(Txt$, Start%, EndPos%))
  723.     ErrV = cFALSE
  724. END IF
  725. END FUNCTION
  726.  
  727. '=== flInitSpec - Initializes font specification structure
  728. '
  729. '  Arguments:
  730. '     Spec     -  FontSpec variable to initialize
  731. '
  732. '=================================================================
  733. SUB flInitSpec (Spec AS FontSpec) STATIC
  734.  
  735.     Spec.FaceName = ""
  736.     Spec.Pitch = ""
  737.     Spec.PointSize = 0
  738.     Spec.ScrnMode = -1
  739.     Spec.Height = 0
  740.     Spec.Best = cFALSE
  741.     Spec.RegNum = 0
  742.     Spec.InMemory = cFALSE
  743.  
  744. END SUB
  745.  
  746. '=== flMatchFont - Finds first registered font that matches FontSpec
  747. '
  748. '  Arguments:
  749. '     FSpec -  FontSpec variable containing specification to match
  750. '
  751. '  Return Values:
  752. '     Number of registered font matched, -1 if no match.
  753. '
  754. '=================================================================
  755. FUNCTION flMatchFont (FSpec AS FontSpec) STATIC
  756. SHARED FGP AS GlobalParams
  757. SHARED FontHdrReg() AS IFontInfo
  758.  
  759. ' Match a specific registered font:
  760. IF FSpec.RegNum > 0 AND FSpec.RegNum <= FGP.TotalRegistered THEN
  761.     flMatchFont = FSpec.RegNum
  762.     EXIT FUNCTION
  763. END IF
  764.  
  765. ' If this is an invalid spec. then no fonts matched:
  766. IF FontErr <> 0 THEN
  767.     flMatchFont = -1
  768.     EXIT FUNCTION
  769. END IF
  770.  
  771. ' Scan font for first one that matches the rest of the specs:
  772. SelectedFont% = -1
  773. BestSizeDiff = 3.402823E+38
  774. BestFontNum% = -1
  775. FOR FontNum% = 1 TO FGP.TotalRegistered
  776.  
  777.     ' Match a font from memory:
  778.     MemOK% = cTRUE
  779.     IF FSpec.InMemory AND FontHdrReg(FontNum%).FontSource <> cMemFont THEN
  780.         MemOK% = cFALSE
  781.     END IF
  782.   
  783.     ' Match name:
  784.     IF FSpec.FaceName = FontHdrReg(FontNum%).FaceName OR LTRIM$(FSpec.FaceName) = "" THEN
  785.         NameOK% = cTRUE
  786.     ELSE
  787.         NameOK% = cFALSE
  788.     END IF
  789.  
  790.     ' Match pitch (fixed or proportional):
  791.     Pitch$ = "F"
  792.     IF FontHdrReg(FontNum%).FontHeader.dfPixWidth = 0 THEN Pitch$ = "P"
  793.     IF FSpec.Pitch = Pitch$ OR FSpec.Pitch = " " THEN
  794.         PitchOK% = cTRUE
  795.     ELSE
  796.         PitchOK% = cFALSE
  797.     END IF
  798.  
  799.     ' Match font size (if neither point or pixel size specified then
  800.     ' this font is OK):
  801.     IF FSpec.PointSize = 0 AND FSpec.Height = 0 THEN
  802.         SizeOK% = cTRUE
  803.   
  804.     ' Otherwise, if point size specified (note that point size overrides
  805.     ' the pixel height if they were both specified)...
  806.     ELSEIF FSpec.PointSize <> 0 THEN
  807.       
  808.         ' Make sure the font resolution matches the screen resolution
  809.         ' (pass over this font if not):
  810.         IF FSpec.HorizRes <> FontHdrReg(FontNum%).FontHeader.dfHorizRes THEN
  811.             SizeOK% = cFALSE
  812.         ELSEIF FSpec.VertRes <> FontHdrReg(FontNum%).FontHeader.dfVertRes THEN
  813.             SizeOK% = cFALSE
  814.       
  815.         ' Font has made it past the resolution check, now try to match size:
  816.         ELSE
  817.             SizeDiff = ABS(FSpec.PointSize - FontHdrReg(FontNum%).FontHeader.dfPoints)
  818.             IF SizeDiff = 0 THEN
  819.                 SizeOK% = cTRUE
  820.             ELSE
  821.                 SizeOK% = cFALSE
  822.             END IF
  823.         END IF
  824.  
  825.  
  826.     ' Now, the case where height was specified and not point size:
  827.     ELSEIF FSpec.Height <> 0 THEN
  828.         SizeDiff = ABS(FSpec.Height - FontHdrReg(FontNum%).FontHeader.dfPixHeight)
  829.         IF SizeDiff = 0 THEN
  830.             SizeOK% = cTRUE
  831.         ELSE
  832.             SizeOK% = cFALSE
  833.         END IF
  834.     END IF
  835.  
  836.     ' Do record keeping if best-fit was specified:
  837.     IF NOT SizeOK% AND PitchOK% AND FSpec.Best AND SizeDiff < BestSizeDiff THEN
  838.         BestSizeDiff = SizeDiff
  839.         BestFontNum% = FontNum%
  840.     END IF
  841.  
  842.     ' See if this font is OK:
  843.     IF MemOK% AND NameOK% AND PitchOK% AND SizeOK% THEN
  844.         SelectedFont% = FontNum%
  845.         EXIT FOR
  846.     END IF
  847. NEXT FontNum%
  848.  
  849. ' If no font was matched and best-fit was specified then select the
  850. ' best font:
  851. IF SelectedFont% < 0 AND FSpec.Best THEN SelectedFont% = BestFontNum%
  852.  
  853. ' Return the font matched:
  854. flMatchFont = SelectedFont%
  855.  
  856. END FUNCTION
  857.  
  858. '=== flReadFont - Reads font data and sets up font header
  859. '
  860. '  Arguments:
  861. '     I%    -  Slot in loaded fonts to process
  862. '
  863. '=================================================================
  864. SUB flReadFont (I%) STATIC
  865. SHARED FGP AS GlobalParams
  866. SHARED FontHdrLoaded() AS IFontInfo
  867. SHARED FontData() AS FontDataBlock
  868.  
  869. ON ERROR GOTO UnexpectedErr
  870.  
  871. ' If memory font then it's already in memory:
  872. IF FontHdrLoaded(I%).FontSource = cMemFont THEN
  873.     EXIT SUB
  874.  
  875. ' For a font from a file, read it in:
  876. ELSE
  877.     DataSize# = FontHdrLoaded(I%).FontHeader.dfSize - cSizeFontHeader
  878.     NumBlocks% = -INT(-DataSize# / cFontBlockSize)
  879.     FontHdrLoaded(I%).DataSeg = FGP.NextDataBlock
  880.  
  881.     ' Get next available file number and open file:
  882.     FileNum% = FREEFILE
  883.     OPEN FontHdrLoaded(I%).FileName FOR BINARY AS FileNum%
  884.  
  885.     ' Read blocks from the font file:
  886.     DataLoc# = FontHdrLoaded(I%).FileLoc + cSizeFontHeader
  887.     SEEK FileNum%, DataLoc#
  888.     FOR BlockNum% = 0 TO NumBlocks% - 1
  889.         GET FileNum%, , FontData(FGP.NextDataBlock + BlockNum%)
  890.     NEXT BlockNum%
  891.   
  892.     ' Close the file:
  893.     CLOSE FileNum%
  894.  
  895.     ' Update the next data block pointer:
  896.     FGP.NextDataBlock = FGP.NextDataBlock + NumBlocks%
  897. END IF
  898.  
  899. END SUB
  900.  
  901. '=== flRegisterFont - Actually registers a font resource:
  902. '
  903. '  Arguments:
  904. '     FileName$   - Name of font file (passed to routine that actually
  905. '                   registers resource entry)
  906. '
  907. '     FileNum%    - File number for reading
  908. '
  909. '=================================================================
  910. SUB flRegisterFont (FileName$, FileNum%) STATIC
  911. SHARED FGP AS GlobalParams
  912. SHARED FontHdrReg() AS IFontInfo
  913.  
  914. DIM Byte AS STRING * 1, FontHeader AS WFHeader
  915.  
  916. ' Read the font header:
  917. FontLoc# = SEEK(FileNum%)
  918. GET FileNum%, , FontHeader
  919.  
  920. ' Only register vector fonts:
  921. IF FontHeader.dfType AND &H1 <> cBitMapType THEN EXIT SUB
  922.  
  923. ' See that we're still within MaxRegistered limits:
  924. IF FGP.TotalRegistered >= FGP.MaxRegistered THEN
  925.     flSetFontErr cTooManyFonts
  926.     EXIT SUB
  927. END IF
  928.  
  929. ' Go to next "registered" font slot:
  930. FGP.TotalRegistered = FGP.TotalRegistered + 1
  931.  
  932. ' Set font source and save the header and file location:
  933. FontHdrReg(FGP.TotalRegistered).FontSource = cFileFont
  934. FontHdrReg(FGP.TotalRegistered).FontHeader = FontHeader
  935. FontHdrReg(FGP.TotalRegistered).FileLoc = FontLoc#
  936.  
  937. ' Get the face name (scan characters until zero byte):
  938. SEEK FileNum%, FontLoc# + FontHeader.dfFace
  939. FaceName$ = ""
  940. FOR Char% = 0 TO cMaxFaceName - 1
  941.     GET FileNum%, , Byte
  942.     IF ASC(Byte) = 0 THEN EXIT FOR
  943.     FaceName$ = FaceName$ + Byte
  944. NEXT Char%
  945. FontHdrReg(FGP.TotalRegistered).FaceName = FaceName$
  946.  
  947. ' Finally, save the file name:
  948. FontHdrReg(FGP.TotalRegistered).FileName = FileName$
  949.  
  950. END SUB
  951.  
  952. '=== flSetFontErr - Sets the FontErr variable to an error value:
  953. '
  954. '  Arguments:
  955. '     ErrNum   -  The error number to set FontErr variable to
  956. '
  957. '=================================================================
  958. SUB flSetFontErr (ErrNum AS INTEGER) STATIC
  959.  
  960.      FontErr = ErrNum
  961.  
  962. END SUB
  963.  
  964. '=== flSizeFontBuffer - Calculate the FontBuffer size required for all fonts
  965. '
  966. '  Arguments:
  967. '     NFonts%  -  Number of font to be loaded
  968. '
  969. '  Notes:
  970. '     The use of -INT(-N) in the following code rounds N to the next
  971. '     larger integer
  972. '
  973. '=================================================================
  974. SUB flSizeFontBuffer (NFonts%) STATIC
  975. SHARED FGP AS GlobalParams
  976. SHARED FontHdrReg() AS IFontInfo
  977. SHARED FontLoadList() AS INTEGER
  978. SHARED FontData() AS FontDataBlock
  979.  
  980.  
  981. ON ERROR GOTO UnexpectedErr
  982. IF NFonts% = 0 THEN EXIT SUB
  983.  
  984. ' Clear font status variables so we know what has been processed:
  985. flClearFontStatus
  986.  
  987. ' Add sizes of all unique fonts together to get total size (each font
  988. ' begins on a new font block so the size of each font is calculated in
  989. ' terms of the number of font blocks it will take up):
  990. Size = 0
  991. FOR I% = 1 TO NFonts%
  992.     FontNum% = FontLoadList(I%)
  993.     IF FontHdrReg(FontNum%).Status = 0 THEN
  994.         FontSize = FontHdrReg(FontNum%).FontHeader.dfSize - cSizeFontHeader
  995.         Size = Size - INT(-FontSize / cFontBlockSize)
  996.         FontHdrReg(FontNum%).Status = 1
  997.     END IF
  998. NEXT I%
  999.  
  1000. ' Dimension the FontData array to hold everything:
  1001. ON ERROR GOTO MemErr
  1002. REDIM FontData(1 TO Size) AS FontDataBlock
  1003. ON ERROR GOTO UnexpectedErr
  1004.  
  1005. ' Set the next font block to the start for when flReadFont begins
  1006. ' putting data in the font buffer:
  1007. FGP.NextDataBlock = 1
  1008.  
  1009. END SUB
  1010.  
  1011. '=== GetFontInfo - Returns useful information about current font
  1012. '
  1013. '  Arguments:
  1014. '     FI    -  FontInfo type variable to receive info
  1015. '
  1016. '=================================================================
  1017. SUB GetFontInfo (FI AS FontInfo) STATIC
  1018. SHARED FGP AS GlobalParams
  1019. SHARED FontHdrLoaded() AS IFontInfo
  1020.  
  1021. ON ERROR GOTO UnexpectedErr
  1022.  
  1023. ' Clear outstanding font errors:
  1024. flClearFontErr
  1025.  
  1026. ' Check that some fonts are loaded:
  1027. IF FGP.TotalLoaded <= 0 THEN
  1028.     flSetFontErr cNoFonts
  1029.     EXIT SUB
  1030. END IF
  1031.  
  1032. ' All OK, assign values from internal font header:
  1033. FI.FontNum = FGP.CurrentFont
  1034. FI.Ascent = FontHdrLoaded(FGP.CurrentFont).FontHeader.dfAscent
  1035. FI.Points = FontHdrLoaded(FGP.CurrentFont).FontHeader.dfPoints
  1036. FI.PixWidth = FontHdrLoaded(FGP.CurrentFont).FontHeader.dfPixWidth
  1037. FI.PixHeight = FontHdrLoaded(FGP.CurrentFont).FontHeader.dfPixHeight
  1038. FI.Leading = FontHdrLoaded(FGP.CurrentFont).FontHeader.dfInternalLeading
  1039. FI.MaxWidth = FontHdrLoaded(FGP.CurrentFont).FontHeader.dfMaxWidth
  1040. FI.AvgWidth = FontHdrLoaded(FGP.CurrentFont).FontHeader.dfAvgWidth
  1041. FI.FileName = FontHdrLoaded(FGP.CurrentFont).FileName
  1042. FI.FaceName = FontHdrLoaded(FGP.CurrentFont).FaceName
  1043.  
  1044. END SUB
  1045.  
  1046. '=== GetGTextLen - Returns bit length of string
  1047. '
  1048. '  Arguments:
  1049. '     Text$ -  String for which to return length
  1050. '
  1051. '  Return Values:
  1052. '     -1    -  Error (No fonts loaded, probably)
  1053. '
  1054. '     >=0   -  Length of string
  1055. '
  1056. '=================================================================
  1057. FUNCTION GetGTextLen% (Text$) STATIC
  1058. SHARED FGP AS GlobalParams
  1059. SHARED FontHdrLoaded() AS IFontInfo
  1060. SHARED FontData() AS FontDataBlock
  1061.  
  1062. ON ERROR GOTO UnexpectedErr
  1063.  
  1064. ' Clear outstanding font errors:
  1065. flClearFontErr
  1066.  
  1067. ' Make sure some fonts are loaded:
  1068. IF FGP.TotalLoaded <= 0 THEN
  1069.     flSetFontErr cNoFonts
  1070.     GetGTextLen = -1
  1071.     EXIT FUNCTION
  1072. END IF
  1073.  
  1074. ' Assume this is a memory font (may override this later):
  1075. CharTblPtr% = FontHdrLoaded(FGP.CurrentFont).DataOffset
  1076. CharTblSeg% = FontHdrLoaded(FGP.CurrentFont).DataSeg
  1077.  
  1078. ' Index into font data array:
  1079. CharTable% = FontHdrLoaded(FGP.CurrentFont).DataSeg
  1080.  
  1081. ' Add together the character lengths from the character table:
  1082. TextLen% = 0
  1083. FOR I% = 1 TO LEN(Text$)
  1084.   
  1085.     ' Get character code and translate to Ansi if IBM char set is specified:
  1086.     ChVal% = ASC(MID$(Text$, I%, 1))
  1087.     IF FGP.CharSet = cIBMChars THEN ChVal% = flANSI(ChVal%)
  1088.   
  1089.     ' Convert to default char if out of range:
  1090.     IF ChVal% < FGP.FChar OR ChVal% > FGP.LChar THEN ChVal% = FGP.DChar%
  1091.   
  1092.     ' Offset into character table for length word:
  1093.     CharOffset% = (ChVal% - FGP.FChar) * 4
  1094.  
  1095.     ' Peek the data and add it to the text length:
  1096.     IF FontHdrLoaded(FGP.CurrentFont).FontSource = cFileFont THEN
  1097.         CharTblPtr% = VARPTR(FontData(CharTable%))
  1098.         CharTblSeg% = VARSEG(FontData(CharTable%))
  1099.     END IF
  1100.     DEF SEG = CharTblSeg%
  1101.     CharLen% = PEEK(CharTblPtr% + CharOffset%) + PEEK(CharTblPtr% + CharOffset% + 1) * 256
  1102.     TextLen% = TextLen% + CharLen%
  1103. NEXT I%
  1104.  
  1105. GetGTextLen = TextLen%
  1106.  
  1107. END FUNCTION
  1108.  
  1109. '=== GetMaxFonts - Gets the maximum number of fonts that can be registered
  1110. '                  and loaded by the font library:
  1111. '
  1112. '  Arguments:
  1113. '     Registered  -  The maximum number of fonts that can be registered
  1114. '                    by the font library
  1115. '
  1116. '     Loaded      -  The maximum number of fonts that can be loaded by
  1117. '                    by the font library
  1118. '
  1119. '=================================================================
  1120. SUB GetMaxFonts (Registered AS INTEGER, Loaded AS INTEGER)
  1121. SHARED FGP AS GlobalParams
  1122.  
  1123. ON ERROR GOTO UnexpectedErr
  1124.  
  1125. ' Clear outstanding font errors:
  1126. flClearFontErr
  1127.  
  1128. ' If SetMaxFonts hasn't been called then make sure the default is
  1129. ' correct:
  1130. flChkMax
  1131.  
  1132. ' Simply return the values of the internal variables for maximum
  1133. ' fonts registered and loaded:
  1134. Registered = FGP.MaxRegistered
  1135. Loaded = FGP.MaxLoaded
  1136.  
  1137. END SUB
  1138.  
  1139. '=== GetFontInfo - Returns useful information about current font
  1140. '
  1141. '  Arguments:
  1142. '     Font  -  Font number (in list of registered fonts) on which to get
  1143. '              information
  1144. '
  1145. '     FI    -  FontInfo type variable to receive info
  1146. '
  1147. '=================================================================
  1148. SUB GetRFontInfo (Font AS INTEGER, FI AS FontInfo) STATIC
  1149. SHARED FontHdrReg() AS IFontInfo
  1150.  
  1151. ON ERROR GOTO UnexpectedErr
  1152.  
  1153. ' Clear outstanding font errors:
  1154. flClearFontErr
  1155.  
  1156. ' See that they've specified a valid font:
  1157. IF Font < 0 OR Font > FGP.TotalRegistered THEN
  1158.     flSetFontErr cBadFontNumber
  1159.     EXIT SUB
  1160. END IF
  1161.  
  1162. ' All OK, assign values from internal font header:
  1163. FI.FontNum = Font
  1164. FI.Ascent = FontHdrReg(Font).FontHeader.dfAscent
  1165. FI.Points = FontHdrReg(Font).FontHeader.dfPoints
  1166. FI.PixWidth = FontHdrReg(Font).FontHeader.dfPixWidth
  1167. FI.PixHeight = FontHdrReg(Font).FontHeader.dfPixHeight
  1168. FI.Leading = FontHdrReg(Font).FontHeader.dfInternalLeading
  1169. FI.MaxWidth = FontHdrReg(Font).FontHeader.dfMaxWidth
  1170. FI.AvgWidth = FontHdrReg(Font).FontHeader.dfAvgWidth
  1171. FI.FileName = FontHdrReg(Font).FileName
  1172. FI.FaceName = FontHdrReg(Font).FaceName
  1173.  
  1174. END SUB
  1175.  
  1176. '=== GetTotalFonts - Gets the total number of fonts that currently registered
  1177. '                    and loaded by the font library:
  1178. '
  1179. '  Arguments:
  1180. '     Registered  -  The total number of fonts registered by the font
  1181. '                    library
  1182. '
  1183. '     Loaded      -  The total number of fonts loaded by the font library
  1184. '
  1185. '=================================================================
  1186. SUB GetTotalFonts (Registered AS INTEGER, Loaded AS INTEGER)
  1187. SHARED FGP AS GlobalParams
  1188.  
  1189. ON ERROR GOTO UnexpectedErr
  1190.  
  1191. ' Clear outstanding font errors:
  1192. flClearFontErr
  1193.  
  1194. ' Simply return the values of internal variables:
  1195. Registered = FGP.TotalRegistered
  1196. Loaded = FGP.TotalLoaded
  1197.  
  1198. END SUB
  1199.  
  1200. '=== GTextWindow - Communicates the current WINDOW to fontlib
  1201. '
  1202. '  Arguments:
  1203. '     X1    -  Minimum X value
  1204. '
  1205. '     Y1    -  Minimum Y value
  1206. '
  1207. '     X2    -  Maximum X value
  1208. '
  1209. '     Y2    -  Maximum Y value
  1210. '
  1211. '     Scrn% -  cTRUE means that window Y values increase top to bottom
  1212. '
  1213. '  Remarks:
  1214. '     Calling this with X1=X2 or Y1=Y2 will clear the current
  1215. '     window.
  1216. '
  1217. '=================================================================
  1218. SUB GTextWindow (X1 AS SINGLE, Y1 AS SINGLE, X2 AS SINGLE, Y2 AS SINGLE, Scrn%)
  1219. SHARED FGP AS GlobalParams
  1220.  
  1221. ON ERROR GOTO UnexpectedErr
  1222.  
  1223. ' Clear outstanding font errors:
  1224. flClearFontErr
  1225.  
  1226. ' Save the window values in global variable:
  1227. FGP.WX1 = X1
  1228. FGP.WY1 = Y1
  1229. FGP.WX2 = X2
  1230. FGP.WY2 = Y2
  1231. FGP.WScrn = Scrn%
  1232.  
  1233. ' If window is valid then flag it as set:
  1234. FGP.WindowSet = ((X2 - X1) <> 0) AND ((Y2 - Y1) <> 0)
  1235.  
  1236. END SUB
  1237.  
  1238. '=== LoadFont - Loads one or more fonts according to specification string
  1239. '
  1240. '  Arguments:
  1241. '     SpecTxt$ -  String containing parameters specifying one or more
  1242. '                 fonts to load (see notes below)
  1243. '
  1244. '  Return Values:
  1245. '     The number of fonts loaded
  1246. '
  1247. '  Notes:
  1248. '     A spec. can contain the following parameters in any order.
  1249. '     Parameters are each one character immediately followed by a value
  1250. '     if called for. Multiple specifications may be entered separated
  1251. '     by slash (/) characters. Loadfont will search for the FIRST font in
  1252. '     the list of registered fonts that matches each spec. and load it. If
  1253. '     no font matches a specification registered font number one will be
  1254. '     used. If a given font is selected by more than one spec in the list
  1255. '     it will only be loaded once. When this routine is called all
  1256. '     previous fonts will be discarded:
  1257. '
  1258. '        T  -  followed by a blank-terminated name loads font by
  1259. '              specified name
  1260. '
  1261. '        F  -  No value. Selects only fixed pitch fonts
  1262. '
  1263. '        P  -  No value. Selects only proportional fonts
  1264. '
  1265. '        S  -  Followed by number specifies desired point size
  1266. '
  1267. '        M  -  Followed by number specifies the screen mode font will be
  1268. '              used on. This is used in conjunction with the "S" parameter
  1269. '              above to select appropriately sized font.
  1270. '
  1271. '        H  -  Followed by number specifies the pixel height of
  1272. '              font to select. "S" overrides this.
  1273. '
  1274. '        N  -  Followed by number selects specific font number
  1275. '              from the list of currently registered fonts.
  1276. '
  1277. '        R  -  Selects font stored in RAM memory
  1278. '
  1279. '=================================================================
  1280. FUNCTION LoadFont% (SpecTxt$) STATIC
  1281. SHARED FGP AS GlobalParams
  1282. DIM FSpec AS FontSpec
  1283.  
  1284. ON ERROR GOTO UnexpectedErr
  1285.  
  1286. ' Clear outstanding errors and check for valid max limits:
  1287. flClearFontErr
  1288.  
  1289. flChkMax
  1290.  
  1291. ' Make sure there's room to load a font:
  1292. IF FGP.TotalLoaded >= FGP.MaxLoaded THEN
  1293.     flSetFontErr cTooManyFonts
  1294.     EXIT FUNCTION
  1295. END IF
  1296.  
  1297. ' Make sure there are some registered fonts to look through:
  1298. IF FGP.TotalRegistered <= 0 THEN
  1299.     flSetFontErr cNoFonts
  1300.     EXIT FUNCTION
  1301. END IF
  1302.  
  1303. ' Process each spec in the spec string:
  1304. Slot% = 1
  1305. ChPos% = 1
  1306. DO UNTIL Slot% > FGP.MaxLoaded
  1307.  
  1308.     ' Initialize the spec structure:
  1309.     flInitSpec FSpec
  1310.  
  1311.     ' Get next spec from string (Found will be false if no spec found):
  1312.     SpecStatus% = flGetNextSpec(SpecTxt$, ChPos%, FSpec)
  1313.     SELECT CASE SpecStatus%
  1314.         CASE 0:
  1315.         CASE 1: EXIT DO
  1316.         CASE 2: flSetFontErr cBadFontSpec
  1317.     END SELECT
  1318.  
  1319.     ' Try to match font. Set font to one if none match:
  1320.     FontNum% = flMatchFont(FSpec)
  1321.     IF FontNum% < 1 THEN
  1322.         flSetFontErr cFontNotFound
  1323.         FontNum% = 1
  1324.     END IF
  1325.  
  1326.     ' Record font in font load list:
  1327.     FontLoadList(Slot%) = FontNum%
  1328.     Slot% = Slot% + 1
  1329. LOOP
  1330.  
  1331. ' Now actually get the fonts in the load list:
  1332. FGP.TotalLoaded = flGetFonts(Slot% - 1)
  1333. FGP.CurrentFont = 1
  1334.  
  1335. ' Select the first font by default (pass outstanding font errors around
  1336. ' it):
  1337. HoldErr% = FontErr
  1338. SelectFont cDefaultFont
  1339. IF HoldErr% <> 0 THEN flSetFontErr HoldErr%
  1340.  
  1341. LoadFont = FGP.TotalLoaded
  1342.  
  1343. END FUNCTION
  1344.  
  1345. '=== OutGText - Outputs graphics text to the screen
  1346. '
  1347. '  Arguments:
  1348. '     X        -  X location of upper left of char box
  1349. '
  1350. '     Y        -  Y location of upper left of char box
  1351. '
  1352. '     Text$    -  Text string to output
  1353. '
  1354. '  Return Values:
  1355. '     Length of text output, Values of X and Y are updated
  1356. '
  1357. '=================================================================
  1358. FUNCTION OutGText% (X AS SINGLE, Y AS SINGLE, Text$) STATIC
  1359. SHARED FGP AS GlobalParams
  1360. SHARED FontHdrLoaded() AS IFontInfo
  1361.  
  1362. ON ERROR GOTO UnexpectedErr
  1363.  
  1364. ' Clear outstanding font errors:
  1365. flClearFontErr
  1366.  
  1367. ' Make sure fonts are loaded:
  1368. IF FGP.TotalLoaded <= 0 THEN
  1369.     flSetFontErr cNoFonts
  1370.     EXIT FUNCTION
  1371. END IF
  1372.  
  1373. IF NOT FGP.CharColorInit THEN SetGTextColor cDefaultColor
  1374. IF NOT FGP.CharDirInit THEN SetGTextDir cDefaultDir
  1375.  
  1376. ' Make sure a graphic mode is set:
  1377. flGetCurrentScrnSize XP%, YP%
  1378. IF XP% = 0 THEN EXIT FUNCTION
  1379.  
  1380. ' Save input location to working variables and erase any window setting:
  1381. IX% = PMAP(X, 0)
  1382. IY% = PMAP(Y, 1)
  1383. WINDOW
  1384.  
  1385. ' Map chars to valid ones and output them adding their lengths:
  1386. TextLen% = 0
  1387. FOR Char% = 1 TO LEN(Text$)
  1388.     ChVal% = ASC(MID$(Text$, Char%, 1))
  1389.     IF FGP.CharSet = cIBMChars THEN ChVal% = flANSI(ChVal%)
  1390.   
  1391.     IF FGP.FontSource = cFileFont THEN
  1392.         BitMapPtr% = VARPTR(FontData(FGP.DSeg))
  1393.         BitMapSeg% = VARSEG(FontData(FGP.DSeg))
  1394.     ELSE
  1395.         BitMapPtr% = FGP.DOffset
  1396.         BitMapSeg% = FGP.DSeg
  1397.     END IF
  1398.  
  1399.     CharLen% = flbltchar%(BitMapSeg%, BitMapPtr%, ChVal%, IX%, IY%)
  1400.  
  1401.     IX% = IX% + FGP.XPixInc * CharLen%
  1402.     IY% = IY% + FGP.YPixInc * CharLen%
  1403.  
  1404.     TextLen% = TextLen% + CharLen%
  1405. NEXT Char%
  1406.  
  1407. ' Reset window:
  1408. IF FGP.WindowSet THEN
  1409.     IF FGP.WScrn% THEN
  1410.         WINDOW SCREEN (FGP.WX1, FGP.WY1)-(FGP.WX2, FGP.WY2)
  1411.     ELSE
  1412.         WINDOW (FGP.WX1, FGP.WY1)-(FGP.WX2, FGP.WY2)
  1413.     END IF
  1414. END IF
  1415.  
  1416. ' Update locations
  1417. X = PMAP(IX%, 2)
  1418. Y = PMAP(IY%, 3)
  1419.  
  1420. ' Return total character length:
  1421. OutGText = TextLen%
  1422.  
  1423. END FUNCTION
  1424.  
  1425. '=== RegisterFonts - Loads header information from font resources:
  1426. '
  1427. '  Arguments:
  1428. '     FileName$   -  Path name for font file to register
  1429. '
  1430. '  Return Value:
  1431. '     The number of fonts actually registered
  1432. '
  1433. '  Notes:
  1434. '     Offsets documented in Windows document assume the file's first
  1435. '     byte is byte 0 (zero) and GET assumes the first byte is byte 1 so
  1436. '     many GET locations are expressed in the following code as
  1437. '     a documented offset + 1.
  1438. '
  1439. '=================================================================
  1440. FUNCTION RegisterFonts% (FileName$) STATIC
  1441. SHARED FGP AS GlobalParams
  1442. DIM Byte AS STRING * 1
  1443.  
  1444. ON ERROR GOTO UnexpectedErr
  1445.  
  1446. ' Clear errors and make sure things are initialized:
  1447. flClearFontErr
  1448.  
  1449. flChkMax
  1450.  
  1451. ' Get next available file number:
  1452. FileNum% = FREEFILE
  1453.  
  1454. ' Try to open the file for input first to make sure the file exists. This
  1455. ' is done to avoid creating a zero length file if the file doesn't exist.
  1456. ON ERROR GOTO NoFileErr
  1457. OPEN FileName$ FOR INPUT AS FileNum%
  1458. ON ERROR GOTO UnexpectedErr
  1459. IF FontErr <> 0 THEN
  1460.     RegisterFonts = 0
  1461.     EXIT FUNCTION
  1462. END IF
  1463. CLOSE FileNum%
  1464.  
  1465. ' File seems to exist, so open it in binary mode:
  1466. OPEN FileName$ FOR BINARY ACCESS READ AS FileNum%
  1467.  
  1468. ' Get the byte that indicates whether this file has a new-style
  1469. ' header on it. If not, then error:
  1470. GET FileNum%, &H18 + 1, Byte
  1471. IF ASC(Byte) <> &H40 THEN
  1472.     flSetFontErr cBadFontFile
  1473.     CLOSE FileNum%
  1474.     EXIT FUNCTION
  1475. END IF
  1476.  
  1477. ' Save the number of fonts currently registered for use later in
  1478. ' calculating the number of fonts registered by this call:
  1479. OldTotal = FGP.TotalRegistered
  1480.  
  1481. ' Get the pointer to the new-style header:
  1482. GET FileNum%, &H3C + 1, Word%
  1483. NewHdr% = Word%
  1484.  
  1485. ' Get pointer to resource table:
  1486. GET FileNum%, Word% + &H22 + 1, Word%
  1487. ResourceEntry# = NewHdr% + Word% + 1
  1488.  
  1489. ' Get the alignment shift count from beginning of table:
  1490. GET FileNum%, ResourceEntry#, Align%
  1491.  
  1492. ' Loop, registering font resources until they have run out:
  1493. DO
  1494.     ResType% = flDoNextResource(Align%, FileName$, FileNum%)
  1495.     IF FontErr <> 0 THEN EXIT DO
  1496. LOOP UNTIL ResType% = 0
  1497.  
  1498. CLOSE FileNum%
  1499.  
  1500. ' Finally, return number of fonts actually registered:
  1501. RegisterFonts = FGP.TotalRegistered - OldTotal
  1502.  
  1503. END FUNCTION
  1504.  
  1505. '=== RegisterMemFont - Loads header information from a memory-resident font
  1506. '
  1507. '  Arguments:
  1508. '     FontSeg%    -  Segment address of font to register
  1509. '
  1510. '     FontOffset% -  Offset address of font to register
  1511. '
  1512. '  Return Value:
  1513. '     The number of fonts actually registered (0 or 1)
  1514. '
  1515. '  Notes:
  1516. '     Memory resident fonts cannot be stored in BASIC relocatable data
  1517. '     structures (like arrays or non-fixed strings).
  1518. '
  1519. '=================================================================
  1520. FUNCTION RegisterMemFont% (FontSeg AS INTEGER, FontOffset AS INTEGER) STATIC
  1521. SHARED FGP AS GlobalParams
  1522. SHARED FontHdrReg() AS IFontInfo
  1523. DIM FontHeader AS WFHeader
  1524.  
  1525. ON ERROR GOTO UnexpectedErr
  1526.  
  1527. ' Clear error and check max limits:
  1528. flClearFontErr
  1529. flChkMax
  1530.  
  1531. ' Get the font header:
  1532. flMovMem FontHeader, FontSeg, FontOffset, cSizeFontHeader
  1533.  
  1534. ' Only register vector fonts:
  1535. IF FontHeader.dfType AND &H1 <> cBitMapType THEN
  1536.     flSetFontErr cBadFontType
  1537.     RegisterMemFont = 0
  1538.     EXIT FUNCTION
  1539. END IF
  1540.  
  1541. ' See that we're still within MaxRegistered limits:
  1542. IF FGP.TotalRegistered >= FGP.MaxRegistered THEN
  1543.     flSetFontErr cTooManyFonts
  1544.     RegisterMemFont = 0
  1545.     EXIT FUNCTION
  1546. END IF
  1547.  
  1548. ' Go to next "registered" font slot:
  1549. FGP.TotalRegistered = FGP.TotalRegistered + 1
  1550.  
  1551. ' Set font source and save the header:
  1552. FontHdrReg(FGP.TotalRegistered).FontSource = cMemFont
  1553. FontHdrReg(FGP.TotalRegistered).FontHeader = FontHeader
  1554.  
  1555. ' Set font location in memory:
  1556. FontHdrReg(FGP.TotalRegistered).DataSeg = FontSeg
  1557. FontHdrReg(FGP.TotalRegistered).DataOffset = FontOffset + cSizeFontHeader
  1558.  
  1559. ' Get the face name (scan characters until zero byte):
  1560. FaceLoc% = FontOffset + FontHeader.dfFace
  1561. FaceName$ = ""
  1562. DEF SEG = FontSeg
  1563. FOR Char% = 0 TO cMaxFaceName - 1
  1564.     Byte% = PEEK(FaceLoc% + Char%)
  1565.     IF Byte% = 0 THEN EXIT FOR
  1566.     FaceName$ = FaceName$ + CHR$(Byte%)
  1567. NEXT Char%
  1568. FontHdrReg(FGP.TotalRegistered).FaceName = FaceName$
  1569.  
  1570. ' Finally, return number of fonts actually registered:
  1571. RegisterMemFont = 1
  1572.  
  1573. END FUNCTION
  1574.  
  1575. '=== SelectFont - Selects current font from among loaded fonts
  1576. '
  1577. '  Arguments:
  1578. '     FontNum% -  Font number to select
  1579. '
  1580. '=================================================================
  1581. SUB SelectFont (FontNum AS INTEGER) STATIC
  1582. SHARED FGP AS GlobalParams
  1583.  
  1584. ON ERROR GOTO UnexpectedErr
  1585.  
  1586. ' Clear outstanding font errors:
  1587. flClearFontErr
  1588.  
  1589. ' If no fonts are loaded then error:
  1590. IF FGP.TotalLoaded <= 0 THEN
  1591.     flSetFontErr cNoFonts
  1592.     EXIT SUB
  1593. END IF
  1594.  
  1595. ' Now, map the font number to an acceptable one and select it:
  1596. IF FontNum <= 0 THEN
  1597.     FGP.CurrentFont = 1
  1598. ELSE
  1599.     FGP.CurrentFont = (ABS(FontNum - 1) MOD (FGP.TotalLoaded)) + 1
  1600. END IF
  1601.  
  1602. ' Get First, Last and Default character params from header:
  1603. FGP.FChar = ASC(FontHdrLoaded(FGP.CurrentFont).FontHeader.dfFirstChar)
  1604. FGP.LChar = ASC(FontHdrLoaded(FGP.CurrentFont).FontHeader.dfLastChar)
  1605. FGP.DChar = ASC(FontHdrLoaded(FGP.CurrentFont).FontHeader.dfDefaultChar)
  1606. FGP.CHeight = FontHdrLoaded(FGP.CurrentFont).FontHeader.dfPixHeight
  1607. flSetBltParams cSizeFontHeader, FGP.CHeight, FGP.FChar, FGP.LChar, FGP.DChar
  1608.  
  1609. ' Set some other commonly used elements of font info:
  1610. FGP.DSeg = FontHdrLoaded(FGP.CurrentFont).DataSeg
  1611. FGP.DOffset = FontHdrLoaded(FGP.CurrentFont).DataOffset
  1612. FGP.FontSource = FontHdrLoaded(FGP.CurrentFont).FontSource
  1613.  
  1614. END SUB
  1615.  
  1616. '=== SetGCharset - Specifies IBM or Windows char set
  1617. '
  1618. '  Arguments:
  1619. '     Charset%    -  cIBMChars for IBM character mappings
  1620. '                    cWindowsChars for Windows character mappings
  1621. '
  1622. '=================================================================
  1623. SUB SetGCharset (CharSet AS INTEGER) STATIC
  1624. SHARED FGP AS GlobalParams
  1625.  
  1626. ON ERROR GOTO UnexpectedErr
  1627.  
  1628. ' Clear outstanding font errors:
  1629. flClearFontErr
  1630.  
  1631. IF CharSet = cWindowsChars THEN
  1632.     FGP.CharSet = cWindowsChars
  1633. ELSE
  1634.     FGP.CharSet = cIBMChars
  1635. END IF
  1636.  
  1637. END SUB
  1638.  
  1639. '=== SetGTextColor - Sets color for drawing characters
  1640. '
  1641. '  Arguments:
  1642. '     FColor   -  Color number
  1643. '
  1644. '=================================================================
  1645. SUB SetGTextColor (FColor AS INTEGER) STATIC
  1646. SHARED FGP AS GlobalParams
  1647.  
  1648. ON ERROR GOTO UnexpectedErr
  1649.  
  1650. ' Clear outstanding font errors:
  1651. flClearFontErr
  1652.   
  1653. FGP.CharColor = ABS(FColor)
  1654. flSetBltColor FGP.CharColor
  1655. FGP.CharColorInit = cTRUE
  1656.  
  1657. END SUB
  1658.  
  1659. '=== SetGTextDir - Sets character direction for OutGText
  1660. '
  1661. '  Arguments:
  1662. '     Dir   -  Character direction:
  1663. '              0 = Horizontal-Right
  1664. '              1 = Vertical-Up
  1665. '              2 = Horizontal-Left
  1666. '              3 = Vertical-Down
  1667. '
  1668. '=================================================================
  1669. SUB SetGTextDir (Dir AS INTEGER) STATIC
  1670. SHARED FGP AS GlobalParams
  1671.  
  1672. ON ERROR GOTO UnexpectedErr
  1673.  
  1674. ' Clear outstanding font errors:
  1675. flClearFontErr
  1676.  
  1677. SELECT CASE Dir
  1678.  
  1679.     ' Vertical - up
  1680.     CASE 1:  FGP.XPixInc% = 0
  1681.                 FGP.YPixInc% = -1
  1682.                 XRowInc% = 1
  1683.                 YRowInc% = 0
  1684.                 FGP.CharDir = 1
  1685.   
  1686.     ' Horizontal -left
  1687.     CASE 2:  FGP.XPixInc% = -1
  1688.                 FGP.YPixInc% = 0
  1689.                 XRowInc% = 0
  1690.                 YRowInc% = -1
  1691.                 FGP.CharDir = 2
  1692.   
  1693.     ' Vertical - down
  1694.     CASE 3:  FGP.XPixInc% = 0
  1695.                 FGP.YPixInc% = 1
  1696.                 XRowInc% = -1
  1697.                 YRowInc% = 0
  1698.                 FGP.CharDir = 3
  1699.   
  1700.     ' Horizontal - right
  1701.     CASE ELSE:  FGP.XPixInc% = 1
  1702.                     FGP.YPixInc% = 0
  1703.                     XRowInc% = 0
  1704.                     YRowInc% = 1
  1705.                     FGP.CharDir = 0
  1706.     END SELECT
  1707.  
  1708.     ' Call routine to set these increments in the char output routine
  1709.     flSetBltDir FGP.XPixInc%, FGP.YPixInc%, XRowInc%, YRowInc%
  1710.     FGP.CharDirInit = cTRUE
  1711.  
  1712. END SUB
  1713.  
  1714. '=== SetMaxFonts - Sets the maximum number of fonts that can be registered
  1715. '                  and loaded by the font library:
  1716. '
  1717. '  Arguments:
  1718. '     Registered  -  The maximum number of fonts that can be registered
  1719. '                    by the font library
  1720. '
  1721. '     Loaded      -  The maximum number of fonts that can be loaded by
  1722. '                    by the font library
  1723. '
  1724. '  Return Values:
  1725. '     Sets error if values are not positive. Adjusts MaxReg and MaxLoad
  1726. '     internal values and resets the length of FontHdrReg and FontHdrLoad
  1727. '     arrays if the new value is different from previous one
  1728. '
  1729. '=================================================================
  1730. SUB SetMaxFonts (Registered AS INTEGER, Loaded AS INTEGER) STATIC
  1731. SHARED FGP AS GlobalParams
  1732. SHARED FontHdrReg() AS IFontInfo
  1733. SHARED FontHdrLoaded() AS IFontInfo
  1734. SHARED FontLoadList() AS INTEGER
  1735. SHARED FontData() AS FontDataBlock
  1736.  
  1737. ON ERROR GOTO UnexpectedErr
  1738.  
  1739. ' Clear errors:
  1740. flClearFontErr
  1741.  
  1742. ' Check to see that values are within range:
  1743. IF Registered <= 0 OR Loaded <= 0 THEN
  1744.     flSetFontErr cBadFontLimit
  1745.     EXIT SUB
  1746. END IF
  1747.  
  1748. ' Values are ostensibly OK. Reset values and redimension arrays:
  1749. ' Reset values for registered fonts:
  1750. FGP.TotalRegistered = 0
  1751. FGP.MaxRegistered = Registered
  1752.   
  1753. ON ERROR GOTO MemErr
  1754. REDIM FontHdrReg(1 TO FGP.MaxRegistered) AS IFontInfo
  1755. ON ERROR GOTO UnexpectedErr
  1756.  
  1757. ' Reset values for loaded fonts:
  1758. FGP.TotalLoaded = 0
  1759. FGP.MaxLoaded = Loaded
  1760.   
  1761. ON ERROR GOTO MemErr
  1762. REDIM FontLoadList(1 TO FGP.MaxLoaded) AS INTEGER
  1763. REDIM FontHdrLoaded(1 TO FGP.MaxLoaded) AS IFontInfo
  1764. ON ERROR GOTO UnexpectedErr
  1765.  
  1766. ' Clear font data array:
  1767. ERASE FontData
  1768.  
  1769. END SUB
  1770.  
  1771. '=== UnRegisterFonts - Erases registered font header array and resets
  1772. '                      total registered fonts to 0:
  1773. '
  1774. '  Arguments:
  1775. '     ErrNum   -  The error number to set FontErr variable to
  1776. '
  1777. '=================================================================
  1778. SUB UnRegisterFonts STATIC
  1779. SHARED FontHdrReg() AS IFontInfo, FGP AS GlobalParams
  1780.  
  1781. ON ERROR GOTO UnexpectedErr
  1782.  
  1783. ' Clear outstanding font errors:
  1784. flClearFontErr
  1785.  
  1786. REDIM FontHdrReg(1 TO 1)  AS IFontInfo
  1787. FGP.MaxRegistered = UBOUND(FontHdrReg, 1)
  1788. FGP.TotalRegistered = 0
  1789.  
  1790. END SUB
  1791.  
  1792.