;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; ; File: FontMgr.a ; ; Copyright: © 1983-1993 by Apple Computer, Inc., all rights reserved. ; ; Scaling Font Manager for MacIntosh User Interface ToolBox ; ; written by Andy Hertzfeld February 5, 1983 ; ; New 128K ROM version, AJH, last week of April 1985 ; ; Here it is, the new scaling font manager which supports independent ; typeFaces and sizes. The font manager is built on top of the ; resource manager and provides a simple swapping mechanism for fonts, ; based on the resource/memory manager's purgable objects. It is passed ; an input record from QuickDraw consisting of the font face, device, style ; and scale and selects the closest font to the requested size that it can. ; It is optimized so that it is very fast if the request is the same as the ; last time. ; ; Printer support is provided via two control/status calls defined by the font . ; manager. After it figures out what everything should be, it gives the ; appropriate device a control call to let it change things. Also, it makes ; a status call to get a table of style values to aid in in figuring things out. ; ; Major changes for the new (128K) ROM include a new font addressing ; scheme using family definition records as resource type "FONT", ; which allows up to 64K different font families and tweaked fonts for ; bold, italic, etc. Fractional widths are fully supported. ; ; Change History (most recent first): ; ; 7/6/93 kc Roll in Ludwig. ; 5/21/93 KW (SM20 CSS) Update from Reality for Truetype bug fixes post 7.1: ; (74 DTY) Move ScriptPriv.a out of a non-ROM conditional area to ; get Font2RealScript. Also, for ROM builds, change a word branch ; to GetDevPix to a jsr, now that GetDevPix in Color Quickdraw is ; too far away to branch to. (73 YK) ; #PartOfWSIIFix,1053866,1053919: Double-Byte TryeType font, which ; usually has relatively large LowestPPEM value, has trouble in ; small point size on Cube-E. 1. If sfnt is the only installed ; font resource (no NFNT), always use it even if the requested ; size is smaller than the LowestPPEM. 2. When trying to find the ; closest size of NFNT reosurce, donÕt take sfnt as Zero-point ; NFNT. 3. Call the Script Manger, instead of masking a font id, ; to get the system script font. (71 DTY) Fix ; GetFONDForSizeAndStyle to use correct style when styles are ; split across multiple FONDs. ; 5/28/93 kc Change GetPixelDepth to get the base address of the screen from ; low memory instead of the QuickDraw globals. On Cyclone, the ; base address changes on depth switch, and StupidDraw doesn't ; update the QuickDraw Globals. InitGDevice should be changed to ; update the QuickDraw Globals for every running process. ; 5/27/93 CSS Roll out <71> from previously rolled in from Reality because it ; was rejected in the Cyclone code review. ; 5/21/93 CSS Update from Reality for Truetype bug fixes post 7.1: ; <74> 3/30/93 DTY Move ScriptPriv.a out of a non-ROM conditional area to get ; Font2RealScript. Also, for ROM builds, change a word branch to ; GetDevPix to a jsr, now that GetDevPix in Color Quickdraw is too ; far away to branch to. ; <73> 3/29/93 YK #PartOfWSIIFix,1053866,1053919: Double-Byte TryeType font, which ; usually has relatively large LowestPPEM value, has trouble in ; small point size on Cube-E. ; 1. If sfnt is the only installed font resource (no NFNT), always ; use it even if the requested size is smaller than the ; LowestPPEM. ; 2. When trying to find the closest size of NFNT reosurce, donÕt ; take sfnt as Zero-point NFNT. ; 3. Call the Script Manger, instead of masking a font id, to get ; the system script font. ; <71> 1/11/93 DTY Fix GetFONDForSizeAndStyle to use correct style when styles are ; split across multiple FONDs. ; 11/19/92 RB Set ROMMapInsert to MapTrue just before doing some GetResource ; calls so that we look in ROM first. ; 11/12/92 PN Get rid of ³ 020 conditionals ; 10/22/92 CSS Change some short branches to word branches. ; <70> 9/2/92 DTY Use records for the synthetic font labels. ; <69> 9/1/92 DTY Use a record for stack frame offsets. ; <68> 8/17/92 DTY #1039825 : IÕll get it right one of these daysÉ If weÕre ; remembering an alternate font and we determine that weÕve ; already picked up an alternate, donÕt bail immediately. Instead, ; branch to a point in the code which decides whether we need to ; keep looking for an exact match, or if we actually can leave. ; <67> 8/13/92 DTY #1039692 : #1039692 : The last two changes made the ; Font Manager stop looking for an exact match too soon. It ; stopped looking after it found a possible match. Make it keep ; looking until it finds an exact match, or it runs out of fonts ; to look at. ; <66> 8/7/92 DTY Need to mark the requested style as non-plain for splines as ; well. ; <65> 8/6/92 DTY #1039047: If using a styled bitmap even though plain was ; requested, change the requested style to be non-plain so that ; GetFONDForSizeAndStyle knows which register to return the 'FOND' ; from.This is another Dean is a bonehead bug. This happens only ; if you copy the application font into the destination suitcase, ; and the Finder updates some windows after the Mover progress ; dialog goes away. In the Font Manager, if a styled bitmap was ; being used as a QuickDraw plain face, GetFONDForSizeAndStyle ; would return the saved 'FOND' from the wrong register, and wind ; up nilling out the resource chain. ; <64> 7/31/92 DTY #1037497 : The last change had a bug which caused an ; infinite loop if QuickDraw wants a size that doesnÕt exist, and ; there is no other style to fall back on. Add some code which ; knows how to get out of this case. ; <63> 7/24/92 DTY #1037497 : Added code to GetBestFONDForSizeAndStyle to ; remember styled 'FOND' entries if QuickDraw is asking for a ; plain style. This is so that styled fonts can be rendered in ; their own face instead of the application font. Adding this ; code allows styled fonts to be plain versions of themselves in ; addition to being styled versions of the base font. ; <62> 7/21/92 DTY #1036674: #1036674: Test D0 after the call to ReallocHandle to ; restore the condition code after restoring the zone. ; <61> 7/20/92 DTY #1035869: Be a little more lenient about bonehead 'FOND' ; resources. Bail early in GetCandidateFONDs if the entry count in ; the font association table is negative. ; <60> 7/17/92 DTY #1036422 : Locking the candidate list while IÕm walking ; through it in RealFont would be niceÉ ; <59> 7/11/92 DTY #1035746 : In GetBestFONDForSizeAndStyle, mark the ; candidate 'FOND' non-purgeable so it doesnÕt get purged when a ; large TrueType font is loaded. ; <58> 7/8/92 DTY #1035322 : In GetBestFONDForSizeAndStyle, check to see if ; an alternate font has already been remembered before remembering ; a new alternate. ; <57> 7/2/92 DTY #1034530: ReAllocHandle will reallocate handle blocks in the ; current heap, even though the master pointer may be in a ; different heap. Make sure that the system zone is the current ; zone before calling ReAllocHandle so that the width tables are ; always in the system heap. ; <56> 6/30/92 DTY #1034346 : In GetCandidateFONDs, if the font number passed ; in is applFont, grab the real font number out of ApFontID so ; that GetResource will succeed. ; <55> 6/29/92 DTY #1031203: #1031203: Dean is brain damaged. The last change winds ; up not looping through the resource chain at all. ; <54> 6/23/92 DTY #1031203: Suitcase has a patch on GetResource that makes it ; start searching from the top of the resource chain, if Suitcase ; is the current resource map. This breaks GetCandidateFONDs, ; which doesnÕt expect to get a resource from higher up in the ; chain than the current resource map. Added a check that ; collects FOND resources to bail if the end of the resource chain ; is reached before the map containing the FOND resource is found. ; <53> 6/23/92 DTY #1031450: The previous change to RealFont added a call to ; fs_LowestPPEM to determine if TrueType can be used for a ; particular point size. The point size is kept in register D2, ; but D2 can be trashed by Toolbox calls. Like fs_LowestPPEM. ; Save and restore D2 around the call to fs_LowestPPEM. ; <52> 6/12/92 DTY #1032393 : RealFont needs to set CurMap before calling ; LoadSplineFontResource in case the current resource map is below ; the resource file that the font came from. ; <51> 6/8/92 SAH #1031825: No longer use arithmetic mode bit as a signal that we ; need to colorize (this used to be passed to MakeScaleTbl to tell ; it to colorize, but MakeScaleTbl no longer uses this bit). This ; means that synthetic fonts created with an arithmetic mode are ; now black and white, rather than black and white but marked as ; color. Also changed to create synthetic fonts for not modes. ; <50> 6/5/92 DTY #1031450: In RealFont, if weÕve got a TrueType font, donÕt ; automatically return true. Instead, call fs_LowestPPEM first to ; make sure this is a font size that TrueType will be used for. ; <49> 6/3/92 DTY #1031058: Normally, the font association table in a 'FOND' ; resource is structured such that for a given point size, the ; entry for the plain font comes before the entries for any ; stylistic variations. The candidate caching code saves ; information about the fonts in the font family, keeping a record ; of the plain font, and a record for all the styles. It assumes ; that the font assocation table followed the normal ordering. Of ; course, weÕre talking about Macintosh developers here, who are a ; breed apart and thereÕs always ONE person that doesnÕt follow ; the standard. Add a check so that if one of these screwy ; 'FOND's is encountered, the record for the styles is split ; across the record for the plain entry. What IÕm saying is that ; the cache entries used to look like: [Info for plain][Info for ; styles]. For a screwy 'FOND', it will look like: [Info for ; styles][Info for plain][Info for more styles]. ; <48> 6/2/92 DTY #1030818 : The check in FindSize for a double byte font ; assumes that all script systems after smKorean will be double ; byte. This causes Arabic and Hebrew TrueType to not work because ; the call to fs_LowestPPEM fails due to the lack of a fragment ; table. ; <47> 5/4/92 DTY #1029119: In GetFONDForSizeAndStyle, ignore the high byte of the ; style word when matching for a style, since this byte contains ; color information, and we donÕt care about that at this point. ; <46> 4/24/92 DTY Case Obj sucks. DonÕt use Case Obj for ROM builds. ; <45> 4/24/92 DTY TrueTypeª lives! Remove all the hasSplineFonts and Gaudi ; conditionals. ; <44> 3/31/92 DTY #1024665,: Change all the one deep Resource Manager calls ; back to the n deep ones since weÕre gauranteeing unique IDs for ; all font resources. ; <43> 3/27/92 DTY #1025750: In GoLoadStrike, if the code path reaches @loadFailed, ; restore d6 and d7 before branching to FindSize. ; <42> 3/20/92 DTY #1025041: Re-write GetFONDForSizeAndStyle so itÕs much easier to ; read and understand.#1025041,: Improve ; GetFONDForSizeAndStyle so itÕs easier to follow and understand. ; <41> 3/17/92 DTY GetCandidateFONDs puts a long into CurMap, smashing ResReadOnly. ; <40> 1/22/92 DTY Take out all the changes to the synthetic font code from <29>. ; WeÕre gauranteeing that font resources will always have unique ; IDs. ; <39> 1/15/92 DTY FONDMap is a long, not a word, hosehead! Get the reference ; number by dereferencing FONDMap. ; <38> 1/11/92 DTY #1019573: GetStrike now uses a stack frame, but a stack frame is ; not set up when GetStrike is called from _RealFont. Set up a ; stack frame around the call to GetStrike in _RealFont. Also, in ; GetFONDForSizeAndStyle, make sure that a 'FOND' resource that ; is being checked for the desired size and style is actually ; currently in the resource chain before trying to use it. If the ; resource map containing a 'FOND' is not in the chain, that ; 'FOND' is skipped. ; <37> 12/20/91 DTY In GetCandidateFONDs, start building the candidate list from ; TopMapHndl instead of CurMap. ; <36> 12/18/91 DTY #1018428: DonÕt assume that FindSize found the font resource. ; Check the condition codes when it returns to see if scaling will ; be necessary. ; <35> 12/13/91 DTY This is what I get for mixing old code with new code. ; GetFONDForSizeAndStyle looks at D2 at the very end to set the ; codes for whether or not to look for another font, or to try to ; scale another size. D2 should have the last size entry in the ; font association table. Errrnnk! ; <34> 12/13/91 DTY The last fix caused MakeMapOneDeep to be called twice in some ; instances, which effectively destroyed the copy of the real ; attributes in D7. Check the contents of D7 before the second ; call to determine if MakeMapOneDeep should called again. ; <33> 12/10/91 JH Fixed bug in GoLoadStrike that was causing a crash when the ; keyboard menu was pulled down. Basically if the font needed to ; draw in the menu is a spline font GoLoadStrike will call ; _sbPreFlightFontMem which loads the spline and if everything is ; OK branches to @splineOKay. The problem with this is that ; eventually the code at @splineOkay ends up branching to WeGotIt ; which always calls RestoreMapAttributes which expects d7 to ; contain the old map attributes. If the spline font was ; successfully loaded the attributes never got saved in d7 so we ; restore trash, hmmm. Fix was to call MakeMapOneDeep, which sets ; d7 correctly, before branching to splineOKay. If I was Pete I'd ; say thanks Dean, but I'm not so I won't. ; <32> 12/2/91 DTY LetÕs derefence the TrueType global handle before we use itÉ ; <31> 11/22/91 JH Rolling in Kon's changes from Sakura project. Added code to ; FindSize utility routine to check if the font is an asian font. ; If it is we check splinepreferred if that is true use the old ; Roman logic. Next check to see if requested size is bigger than ; the mimimum size allowed in LowestPPM. If requested size is less ; than we use the bitmap. Change begins at @gotSpline label and ; ends at ST WidthIsSpline(A1). ; <30> 11/19/91 DTY Another check is needed in GetFONDForSizeAndStyle to return the ; plain spline before the styled spline. Also, donÕt call ; MakeMapOneDeep in LoadSplineResource, since LoadSplineResource ; is called from other places in the code that donÕt set things up ; properly. Instead, just set up CurMap from lastFontMap and hope ; for the best. ; <29> 11/15/91 DTY Save the resource map attribute bits upon entry into GetStrike, ; since it might not fall through from LoadStrike. (This means ; restoring the bits before falling through from LoadStrike.) ; Also store the font family ID in each synthetic font record ; entry, since the synthetic fonts are tagged by font ID, but ; fonts are allowed to have duplicate IDs in the Fonts folder, so ; further differentiation is needed. ; <28> 11/9/91 DTY Delay the restoring if the real CurMap until after an attempt to ; fetch the styled font resource. ; <27> 11/3/91 DTY The FOND stored in LastFOND may be different from that FOND that ; is actually returned by GetFONDForSizeAndStyle. Jam the FOND ; that is used into LastFOND in this routine. ; <26> 10/25/91 DTY Erk. I left a _Debugger in the source. ; <25> 10/25/91 DTY Ooops again. Need to bump past the FOND ID in the candidate ; list when trying to scale a font. ; <24> 10/25/91 DTY Ooops. GetFONDForSizeAndStyle doesnÕt restore D4 and D5 if a ; font wasnÕt found. Sorry Kon. ; <23> 10/25/91 DTY GetCandidateFONDs is still looking in TopMapHndl instead of the ; current map. (Everything else was changed in the last revision, ; but I missed this case.) Also, some additional checking to ; determine whether to use the plain or styled font is needed in ; GetFONDForSizeAndStyle if a TrueType font is to be used. ; <22> 10/24/91 JSM Include ResourceMgrPriv.a for ROM builds so they keep working, ; although this isnÕt a real good solution. ; <21> 10/23/91 DTY Brian lied. The Resource Manager doesnÕt stop at SysMapHndl. ; Stop slamming TopMapHndl to get around what doesnÕt happen. ; LoadStrike now calls _GetMap to get the current resource map ; instead of peeking at TopMapHndl. ; <20> 10/22/91 DTY Make sure to use TrueType fonts if splinePreferred is set, even ; if a bitmap was found first. (But keep the bitmap around in ; case a TrueType font isnÕt found.) ; <19> 10/21/91 DTY One deep resource calls should be one deep resource calls. ; Clear the twoDeepBit in the resource map before trying to load a ; font. (DonÕt you just love how the Resource Manager and the Font ; Manager have their hands all over each other?) ; <18> 10/14/91 DTY Make GetCandidateFONDs use the application font if the requested ; font family couldnÕt be found. Make _RealFont use ; GetCandidateFONDs to determine if a size is available instead of ; patching it. (The _RealFont patch in FontFolderPatches.a is ; gone.) Also load the resource in FindSize if the font was ; purged. ; <17> 10/11/91 DTY Building the candidate FOND list takes too long. Cache two lists ; in SplineKey. Also added check for styled TrueType font in ; GetFONDForSizeAndStyle. ; <16> 10/10/91 DTY Change GetCandidateFONDs to include styles in the list it ; builds, and have GetFONDForSize consider the style thatÕs needed ; during its search as well. ; <15> 10/4/91 DTY Font resources can have duplicate IDs in the font chain. They ; may lead to the wrong font being loaded if the font type is not ; found in the current map, but is found in a lower map. Use one ; deep resource calls in LoadStrike and LoadSplineFont to avoid ; this. Fixed bug in GetCandidateFONDs which didnÕt know when to ; stop walking the resource chain, and wound up going through 0. ; Also fixed bug in LoadSplineFont which caused it to bail even if ; a spline was actually loaded. ; <14> 9/25/91 jlf Rolled in modifications from Pacific TrueType project: ; Replaced GetResource calls for 'sfnt' resources with ; a procedure call to LoadSplineFontResource. Added ; LoadSplineFontResource to not load 'sfnt' resources ; greater than 128k (Asian fonts can be as large as ; eight megabytes). Modified SetFontLock so that it ; calls LoadSplineFontResource instead of LoadResource. ; Added conditional (hasSplineFonts) or (Gaudi) code ; after DoStyle - code was loading sfnt resources and ; treating them as 'FONT'/'NFNT' resources. Solution ; is to check WidthIsSpline field in the current ; widthtable and bail to noColors if true. ; <13> 9/19/91 DTY Teach _FMSwapFont about the Fonts Folder. Change NewFontLookup ; to call a new routine which finds all occurences of a 'FOND' in ; all open font files, and gets all the sizes in those 'FOND's. ; NewFontLookup uses this information to find the right size ; instead of examining the Font Association table inside the ; 'FOND'. ; <12> 7/10/91 JSM Remove obsolete SysVers conditional. ; <11> 6/12/91 LN added #include 'SysPrivateEqu.a' ; <10> 2/22/91 CL JT: Fixing synthetic font building. Just using sethandlesize to ; make sure there is enough space instead of purgespace. ; <9> 2/13/91 KON CEL, SMC: BRC #unknown: FMSwapFont derefernces a handle and then ; calls SetHandleSize. This was causing crashes when Heap Scramble ; was turned on. Now the Handle is locked before calling ; SetHandleSize. ; <8> 2/11/91 RB [MR,CD,CC] Redereference FOND handle when walking it inside ; RealFont after loading an sfnt. Jam the width of to zero, ; inorder to make FractEnable on/off widths consistant between ; bitmaps and outlines. ; <7> 1/8/91 CL (GM) In the RealFont routineÉ Need to check in the rom for the ; sfnt. Setting ROMMapInsert to true before the getresource call. ; <6> 1/7/91 csd & gbm; Removed the conditional around the code that calls ; InitFonts if the widthTabHandle is NIL. We want this in case we ; get a volume remount (or other) dialog before the application ; has called InitFonts. ; <5> 11/28/90 CL Fixing MakeITab branch. Cannot be short. ; <4> 11/28/90 CL (RB)Must still look for extra widths for sfnts when style width ; tables are in the FOND. You can only use these for bitmap fonts. ; <3> 10/30/90 CL (MR)Adding in fs_LowestPPEM to realfont. ; <2> 10/22/90 CL (BKR) Adding fontHandle to preflight call. ; <30> 10/9/90 CL Adding call to preflight routine to make sure the loaded sfnt ; leaves enough space for the font scaler. ; <29> 10/8/90 CL Added code that when failing to load in an sfnt tries again for ; a bitmap font of that family. ; <28> 9/27/90 CL Needed to add the numer and denom fill back into the spline case. ; <27> 9/27/90 CL Backing out Bold style extra fix. Need to re-evaluate the ; consequences. ; <26> 9/26/90 CL In fractenable when using an outline font the Bold style extra ; was not being set up since the fontmgr thought it would get the ; widths out of the FOND width table. All widths always come from ; the sfnt in the outline font case. So the style extra must be ; set with the algorithmic extra that QuickDraw is using. ; <24+> 9/24/90 CL Matching up the spline caches at the end of FMSwapfont. ; <24> 9/23/90 CL Fixing conditionalized branch ; <23> 9/22/90 CL The boolean FractEnable when sent to sbFillwidthtab must have ; the value in the high byte of the word. ; <21+> 9/20/90 CL Accidently skipped some code that filled out part of the width ; table values. One important one was the fSize field which ; effected the charExtra type routines. ; <21> 9/18/90 CL Fixing a bug that jumped out of the difFont loop. Bad ; idea since we would not do the unlink. ; <20> 9/17/90 BG Fixed up log message for <19> since the CheckWindowIn CANCEL ; button doesnt work correctly yet. ; <19> 9/17/90 BG Removed <13>. 040s now work more reliably. ; <18> 8/31/90 CL The font may be purged before getting to the sb_FillWidthTable ; or sb_SearchForCache call. This should not happen since both ; routines expect the font to be there. So load the font in ; before calling these routines!!! ; <17> 8/24/90 CL The font manager did not create 16 or 32 bit fonts. Instead it ; pinned the syn fonts to 8 bit. The only problem to this is that ; it tried to use the device color table. Since it was 16 or 32 ; bit dest but the source was 8 bit the table certainly did not ; match. Now it uses the original data and its 'fctb' in 16 or 32 ; bit mode. ; <16> 8/16/90 CL Problem: A synthetic font some times would not be created ; correctly. Reason: D3 register was expected to be set up to the ; source depth. When a font that was smaller than the original ; data was not found, D3 never got set up. The font building ; created a bad syn font. Solution: We made sure we always set up ; D3 before creating the font. ; <15> 7/27/90 CL Added SetFScaleDisable and SetFractEnable back in for Black and ; White machines for the TrueTypeª build. ; <14> 7/25/90 CL When a get resource on an sfnt fails A0 may be invalid so ; setting isSpline off of A0 is not a good idea at all. Now it is ; fixed. ; <13> 7/20/90 BG Added EclipseNOPs for flakey 040s. ; <12> 7/20/90 DTY Bass: The Linked Patch. Added condition Black and White ; procedure names, added Gaudi variable to checks for SplineFonts, ; and moved in GetDevPix from BassComm_Tail. (You mean thatÕs ; it?!?) ; <11> 7/16/90 CL FMExist does not exist on the MacPlus so it canÕt be checked in ; initfonts for this cpu. ; <10> 6/29/90 CL Took out swap cache flag to make sure the sb_searchforcache ; always gets called to insure the correct font cache is loaded. ; <9> 6/22/90 CL Checking in changes for CHAZZÉ Took out cache handles ; from the width table. Only one global cache at a time. ; It is simplier. Took out run time checks for hasColor ; since the fontmgr is now compiled for either B&W or ; Color. ; <9> 6/22/90 CL Created new equate file fontPrivate.a with includes from this file and ; SplineDefines. ; <8> 5/29/90 CL Checking in changes for CHAZZÉ Took out cache handles from the ; width table. Only one global cache at a time. It is simplier. ; Took out run time checks for hasColor since the fontmgr is now ; compiled for either B&W or Color. ; <7> 4/18/90 CL Taking out special case for disk caching since the routine ; called is already conditionalized. Fixed conditionalize for ; SPLINE_FONT to be hasSplineFonts like it needs to be. ; <6> 4/16/90 HJR Change SPLINE_FONTS to hasSplineFonts ; <5> 4/10/90 CL Adding in ROM conditionals for Elsie. If the spline key is not ; set up we will never choose a spline font from the font ; association table. ; <4> 3/20/90 CL Support for tag sfnt formatÉ ; <3> 2/28/90 CL Fixed include for rom builds. Needed to replace inc.sum.a with ; StandardEqu.d. ; <2> 2/27/90 CL Added support for DrText optimizations ; <4.1> 11/28/89 CEL Justification bug in spline fonts was caused by one extra space ; adjustment. ; <4.0> 10/27/89 BAL forJP: Forgot to make InitFonts RTS to caller, silly me. ; <3.9> 10/27/89 BAL Only define Spline_Font if currently undefined. Also added the ; forJP conditional. ; <3.8> 9/25/89 CEL Took out actual face adjustment for Spline fonts. Now works the ; same as bitmaps. ; <3.7> 9/15/89 CEL Re-doing calling conventions to make them pascal. ; <3.6> 8/28/89 PKE In InitFonts, finish by jumping to Script Manager code ; <3.5> 8/28/89 CEL Fixing Bass outline font scaling values. Fixed SpExtra in ; <3.4> 8/14/89 CEL Spline Fonts does not include PatchMacs.a anymore. Added in ; <3.3> 6/28/89 GGD Fixed link problems by using BigJMP to SMgrInitFonts, ; <¥3.2> 6/10/89 CEL Moved Private.a QuickDraw Equates into proper QuickDraw ; <3.1> 5/26/89 CEL Integrated the new Font Scaler 1.0 into Spline Fonts ; <3.0> 5/5/89 CEL Fixed colorgray value for Bass patch. This does not affect ; <¥2.9> 5/5/89 CEL Moved label outside of conditionals so system would build, ; <¥2.8> 5/4/89 CEL Cleaned up conditionals for ROM ; <¥2.7> 5/3/89 CEL Bass rolled into ROM. NOTE:Spline Fonts are conditionalized ; <¥2.5> 5/1/89 cel Rolled in BassÉ ; <1.8> 4/4/89 CCH Fixed out of range branch. ; <1.7> 4/3/89 cv Rolled in several patches including all new routines in the ; <1.6> 2/28/89 PKE Restored Script Manager mod to InitFonts, which somehow ; <1.5> 2/20/89 rwh changed from machine-based to feature based conditionals. ; <1.4> 2/15/89 CCH Changed LOAD of inc.sum.d to INCLUDE of inc.sum.a. ; <¥1.3> 2/15/89 CCH Adding to EASE for 32-bit quickdraw from sources from ; 5/9/88 BAL Altered depth scaling code to use long sized pixel translation ; table. ; 5/8/88 BAL Tweek code to allow pixel sizes up to 32 bits. ; 6/4/87 CRC Sorry, Jerome, but I took your patch right out again. The ; curious comment on 20-Feb-87 allows zero sized fonts for font ; names, only. For all other font references, the font resource ; must be at least 24 bytes long. But, since GetHandleSize on an ; empty handle is a faux pas, I changed it to MaxRsrcSize. ; 6/2/87 JTC Roll in patch to bypass GetHandleSize after GetResource, as ; curiously mentioned in 20-Feb-87 above. ; 2/20/87 CRC Skip GetHandleSize check after a GetResource from GetFName, so ; that zero size fonts are allowed ; 1/31/87 CRC make FONDs nonpurgable in cache case; let condense, extend go ; multi-bit; use 1 bit font in ÒnotÓ srcBic modes, look for second ; best multibit font, donÕt color srcXor, allow font sizes > 127 ; 1/3/87 CRC if less than 3K stack, or if dest. is 1 bit, skip color cache ; 12/21/86 CRC use normal foreground/background color with arithmetic modes ; 12/4/86 CRC if fond can not be had, try old way first before substituting ; 12/4/86 CRC cache case short circuit moved so that FOutExtra is set up ; properly; initialized fWidStyle ; 12/2/86 CRC can only return FOND widths only if fractional widths are ; enabled. ; 11/24/86 CRC three bugs: register across FixMul; inval FondID; A3 ; save/restore in DifStyle ; 11/11/86 CRC large font from Professional Composer pointed out bug (missing ; .L) in synthetic font build ; 11/10/86 CRC OK, letÕs try forcing the synthetic strike list handle in the ; sysZone instead. ; 11/10/86 CRC clear FOutFontHandle in InitFonts only in fmExist false case; ; skip widths if only colors, modes, depth changed; get the depth ; from the current port, and the gDevice only if old bitmap & on ; screen ; 11/8/86 CRC force synthetic strike list handle to be allocated in the ; applZone (Turbo Pascal) ; 10/30/86 CRC save original font request less needBits rather than ; substitution record ; 10/24/86 CRC inval width table in system heap full case; made some stack ; locals conditional for Becks. ; 10/20/86 CRC fixed check LastSpExtra before CurFMFamily in DoMapFont bug ; 10/17/86 CRC moved some equates to nToolEqu; just test fgColor/bkColor in ; fast case added fmExists to allocate structures once per ; application, some code cleanup ; 10/9/86 bbm Modified to mpw aincludes. ; 9/26/86 CRC fixed MacWrite bug; called InitFonts before InitGraf ; 9/24/86 CRC code cleanup from Jerome/Donn/Erich/Andy review ; 9/17/86 CRC Color, gray scale font support ; 9/16/86 CRC Added condition for JSwapFont set up for trap table ; 9/15/86 CRC Separated screen widths from screen strikes in style selection. ; 8/22/86 CRC InitFonts uses SwapFont to get system font. made JSwapFont just ; a copy of trap table entry rolled GetResource FONT and FOND ; together. Reused GotStrike to hold fond flags rather than high ; byte of WidthListHand ; 8/12/86 CRC Revamped caching code, made family/size substitution happen ; everywhere, changed substitution algorithm. Fixed bug in style ; font selection. Backed off MyFixMul, MyFixRatio optimizations. ; 7/15/86 WRL Corrected address compare to check 24 bits only. ; 5/28/86 JTC (1) Patched GetFDefHandle to restore MemMgr bits only if master ; ptr is non-Nil. (2) Patched FontMetrics to get num/denom right. ; (3) Fix bug in height table loop for wide, tall fonts. ; 4/10/86 JTC Rolled in missed patch to GetFontName, invalidating the cache ; doubly, by setting LastSPExtra to -1. ; 2/19/86 BBM Made some modifications to work under MPW ; 1/13/86 JTC Rolled in SwapFont patches to set CurFMInput to -1 when ; FMSwapFont is and to force the WidthVFactor to be 1,1 when ; scaling is on. ; 11/6/85 DLD Took out the hack to remember a font's size in case it purged ; (Resources tell me). ; 11/6/85 DLD Conditionally check for a non-screen device when computing Extra ; before MakeWTab. ; 11/6/85 DLD Added a bit in the FOND to allow use of Family Extra with ; FractEnable False (MakeWTab). ; 10/30/85 DLD DoWTable does FScale to the missing width characters. ; 10/28/85 DLD InitFonts clears FScaleDisable and FractEnable ; 10/24/85 DLD Added code to fix the bug with switcher. Invalwidths puts -1 ; into LastSPExtra to keep us from matching in the short case. ; 10/22/85 DLD Fixed disk switched font bug - CurFMFamily set to -2 to disable ; WidthTabHandle when we call ourselves via GetResource and disk ; switched hook. ; 10/18/85 DLD Now check if someone wants to invalidate the width cache ; (CurFMInput = -1 to invalidate). ; 10/18/85 DLD Changed NewEQU to put WidthTabHandle in a non-switched location. ; 10/17/85 DLD Changed ComputeFractExtra to use WidthASize - actual font size ; for "style extra". ; 10/17/85 DLD Now I mask off the high byte of WidthListHandle before checking ; if it's nil. ; 10/16/85 DLD Moved the Move.L #WidTabSize,D0 outside the loop in DoMapFont. ; 10/16/85 DLD Put a redundancy check on the font handle into DeRefResource ; 10/10/85 DLD Changed InitFonts to Call GetTrapAddress to pick up a custom ; SwapFont routine. ; 10/10/85 DLD Changed BuildCharTable to not special case RomFont0, since it ; may be custom. ; 10/10/85 DLD Changed InitFonts to check if it couldn't get a system font, and ; use Chicago. ; 10/10/85 DLD Cut down the number of extra width tables to 12. ; 10/10/85 DLD Changed InitFonts to not set or clear FScaleDisable or ; FractEnable. ; 9/27/85 DLD Added DEF to FMSwapFont, since it was removed with QuickGlue ; recently. ; 9/25/85 DLD Fixed a bug in DoMapFont (@3) where I derefed LastFOND even if ; it was Nil. ; 9/24/85 DLD Changed MapScale to loop on 2X and .5X scaling, so 4X, 8X will ; work ; 9/24/85 DLD Changed SetScaleDisable to invalidate all width tables. ; 9/24/85 DLD Rewrote FontMetrics to use fonts info, and compensate for scale ; and style. ; 9/24/85 DLD Fixed a bug in GetFontName, calling GetFDefHandle with MapFalse ; didn't load the FOND so it would return EQ. Now I invalidate ; LastFOND, FONDID. ; 9/24/85 DLD Changed SetFontLock to make the FOND purgable and non-purgable ; too. ; 9/20/85 DLD Changed the extra for Italic to 0, because old ROMs patch it to ; 0. ; 9/12/85 DLD Fixed a bug printing in hires with FOND's. We use actual size in ; GotXWidth2. ; 9/11/85 DLD Changed CheckPurged to handle the case of a released (disposed) ; font. ; 9/10/85 DLD Added logic to find FOND neighbors when all members of a family ; are gone. ; 9/3/85 DLD Extended the format of a width table (in memory) ; 9/3/85 DLD Added logic to maintain 2 width tables, when there's room. ; 8/20/85 DLD Added MyFixMul and MyFixRatio to skip trivial operations ; 8/20/85 DLD Coded an in-line FixRound, since it's easy. ; 8/19/85 DLD Made GetFDefHandle cache FondID even when no FOND found ; 7/9/85 EHB Added setup of ROMMapInsert for ROM resources ; 7/3/85 AJH Fixed RealFont "only one" bug Larry found ; 7/1/85 AJH look for NFNT then FONT, use scale factor in Metrics ; 6/28/85 AJH new fields in header for Bayles; NFNT -> FONT, more res in ; famWid tables, skip 2X for FScaleDisable, added UsedFWidths ; 6/24/85 AJH Got rid of bold extra, added italic extra (1 pixel) ; 5/30/85 AJH Made it not call FixMul unless it has to ; 5/21/85 SC Made font scaling disabled as default ; 5/14/85 SC Made FScaleDisable search down first and then up for old fonts ; and then stop search(if found) on new fonts ; 5/14/85 SC Fixed D3 bug in GetFNum that Ernie found ; 5/10/85 AJH Added FScaleDisable width correction; widMax to metrics ; NewFontLookUp search order changed; SetScaleDisable ; 5/10/85 SC Added FScaleDisable vertical correction ; 5/9/85 AJH added font->NFNT; new FOND format; family widths FractEnable and ; FontMetrics. ; 5/8/85 AJH SwapFont must rebuild WidthPtr each call; removed "numer low ; bits mask" fudge ; 5/8/85 AJH SpaceExtra changing should block "short-circuit" ; 5/7/85 AJH Fixed bugs in width table "adjust" cases ; 5/6/85 AJH Added width table support; saved FOND purged state ; 5/2/85 AJH Added checks for font IDs >= 512 ; 4/30/85 AJH Added single-element FOND cache; optimized initial compare; ; removed RightMask table ; 4/22/85 AJH New ROM overhaul. ; 8/31/83 AJH fixed scaling bug Owen found (introduced 15-Aug) ; 8/29/83 AJH changed MOVEM to MOVE at SwapDone ; 8/29/83 AJH used "IOQElSize" for control and status calls ; 8/15/83 AJH Speed-optimized most common case by saving less registers some ; minor code crunching, too ; 8/13/83 AJH Fixed bug introduced by yesterday's changes (ReturnNilString) ; 8/12/83 AJH Saved code in GetFontName per Jerome's suggestions ; 7/13/83 SC Fixed bugs in lockfont ; 6/11/83 AJH made it prefer 2X and .5X scaling ; 5/11/83 AJH made GetFNum turn resource loading back on ; 4/28/83 AJH made it test resErr and substitute system font if error ; 4/6/83 AJH made GetFontName substitute for font 1 ; 4/4/83 AJH made it use parameter RAM to init default font ; 4/3/83 AJH 7 bits for size instead of 6 ; 3/17/83 AJH changed gotStrike to FF instead of 01 cause of Bill A. ; 3/7/83 AJH excluded font 0 in RealFont; added ScaleDisable ; 3/6/83 AJH Added support for strike-less FWID resource ; 3/5/83 AJH Changed way numer/denom is computed to avoid overflow ; 2/27/83 AJH Fixed bug making font 1 not work ; 2/25/83 AJH Made GetFID divide result by 64 ; 2/16/83 AJH Got rid of the ROM-based font, added RealFont function ; ; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ BLANKS ON STRING ASIS ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; Check DefinesÉ ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IF (&TYPE('HAS_COLOR') = 'UNDEFINED') THEN HAS_COLOR EQU hasCQD ENDIF IF (&TYPE('forJP') = 'UNDEFINED') THEN forJP EQU 0 ENDIF ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IF (forROM) THEN ;<2.7-4april89-CEL> debugging EQU 0 MACRO Check &ea,&dReg IF debugging THEN CHK &ea,&dReg ENDIF ENDM MACRO _Debug IF debugging THEN DC.W $A9FF ENDIF ENDM MACHINE MC68020 ELSE CASE OBJ PrNonPortable EQU 1 ; Needed for patches MACHINE MC68020 ENDIF ; <2.7-4april89-CEL> IF (&TYPE('fmOutCurStyle') = 'UNDEFINED') THEN PRINT OFF IF (NOT forROM) THEN ; Using private includes for now until checked into the system <2.7-4april89-CEL> INCLUDE 'Quickequ.a' INCLUDE 'ColorEqu.a' INCLUDE 'sysequ.a' INCLUDE 'Traps.a' INCLUDE 'ToolEqu.a' INCLUDE 'SplineDefines.a' INCLUDE 'ScriptEqu.a' ; <3.6> INCLUDE 'SysPrivateEqu.a' include 'Private.a' ; <19> ELSE LOAD 'StandardEqu.d' ; <1.4> INCLUDE 'ColorEqu.a' ENDIF INCLUDE 'fontPrivate.a' INCLUDE 'qdhooks.a' include 'ResourceMgrPriv.a' ; <22> INCLUDE 'Scriptpriv.a' ; <3.6> PRINT ON ENDIF ; Here are the external definitions that let the font manager communicate ; with the rest of the world. IF forROM or HAS_COLOR THEN FontManager PROC EXPORT EXPORT InitFonts EXPORT SetFontLock EXPORT GetFontName EXPORT GetFNum EXPORT FMSwapFont EXPORT RealFont EXPORT FontMetrics IF forROM THEN EXPORT SetFScaleDisable EXPORT SetFractEnable IMPORT GetDevPix ; GetDevPix is with CQD routines in ROM ELSE EXPORT GetDevPix ; If not ROM build, GetDevPix in Font manager ENDIF EXPORT FMgrEnd EXPORT FPointOne ; (so that first reference will be seen.) ELSE BWFontManager PROC EXPORT EXPORT BWInitFonts EXPORT BWSetFontLock EXPORT BWGetFontName EXPORT BWGetFNum EXPORT BWGetDevPix EXPORT BWFMSwapFont EXPORT BWRealFont EXPORT BWFontMetrics EXPORT BWFMgrEnd EXPORT BWFPointOne ; (so that first reference will be seen.) EXPORT BWSetFScaleDisable EXPORT BWSetFractEnable ENDIF IF NOT (&TYPE('testVersion') = 'UNDEFINED') THEN INCLUDE 'FontMgrInstall' ENDIF ; With Color and gray scale font support, the Font flags, FOND style word in the property association ; table, and the width table get expanded as shown: ; Font flags: ; 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ; 1 intl m/p 1 0 0 colr syn fctb 0 0 pixel-width wid height @@@@ ; ; m/p indicates whether the font is monospaced or proportional, same as always. ; intl is set if the font is an international font which should not be expanded (Kanji, for instance). ; colr is set if the font contains colors other than black and white. ; syn is set only when the font is synthetic and created on the fly with the requested bit depth. ; (should always be clear for disk fonts) ; fctb is set if the font has a color table in a resource of type fctb with the same ID as the font. ; bits 2 - 4 represent the bit depth of the describing a range of 1 to 8 bits per pixel. (0 = 1, 1 = 2, 2 = 4, 3 = 8, etc) ; wid is set if the font has a fixed-point width table. ; height is set if the font has a character height/length table appended to the end. ; style word in FOND property association table: ; 15 14 13 12 11 10 9 8 | 7 6 5 4 3 2 1 0 ; 0 0 0 0 0 pixel-width | ÑÑÑÑnormal QuickDraw style byteÑÑÑ @@@@ ; ; bits 8 - 10 represent the bit depth of the (0 based) describing a range of 1 to 32 bits per pixel. (0 = 1, 1 = 2, 2 = 4, 3 = 8, etc) ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; PROCEDURE InitFonts -- initialize the font manager data structures ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ if forROM or HAS_COLOR then InitFonts else BWInitFonts endif IF HAS_COLOR THEN ; FMExist does not exist on the MacPlus!!! TST.B FMExist ; has the font manager been initialized? BEQ @skipRest ; if flag clear, then yes ENDIF MOVEQ #-1,D2 ; get some ones CLR.W FOutError ; clear once at init time BSR SetScreenDevice ; make the screen the default device CLR.W CurFMDevice ; make the device 0 CLR.B FScaleDisable ; enable font scaling CLR.B FractEnable ; for now, turn off fractWidths ST FontFlag ; set to note that a call is not re-entrant MOVE.W SPFont,ApFontID ; set up default font ID ADDQ.W #1,ApFontID ; bump it by 1 MOVE.B #12,FMDefaultSize ; set up FMDefault Size ; allocate and initialize the width table in the system heap, if we haven't already MOVE.L WidthTabHandle,D0 ; already got it? BNE.S @doneAlloc ; Check for spline ready MOVE.L #WidTabSize,D0 ; size of table _NewHandle ,SYS ; new handle in sysHeap BNE.S CantAllocMem ; if an error, skip MOVE.L A0,WidthTabHandle ; remember it ; allocate a width table list if there is room for them. (part of PM298 removes the next three lines) MOVE.L #WidListSize,D0 ; size of table _NewHandle ,SYS,CLEAR ; new handle in sysHeap, cleared BNE.S @doneAlloc ; Check for spline ready MOVE.L A0,WidthListHand ; remember it @doneAlloc BCLR #preserveGlyph, HiliteMode ; Do not always blit everything unless set BCLR #splinePreferred, HiliteMode ; Set to bitmap preferred ; Invalidate all of the extra width tables, if they exist. ; set up swapFont jump table entry (part of PM298) IF forROM THEN ; determine if in ROM code of if patched MOVE.L $1204,JSwapFont ; set up the jump vector ELSE ; if patch MOVE #$101,D0 ; _GetTrapAddress ; MOVE.L A0,JSwapFont ; ENDIF MOVEQ #SyntheticStrikeTable.synEntry,D0 ; size of 1 entry version MOVE.L SynListHandle,D1 ; already got it? BLE.S @createSynList ; if zero or -1, create one ; mark all entries as nothing MOVE.L D1,A0 ; existing list handle _SetHandleSize ; restore to single entry version BRA.S @inval1stRecord @createSynList _NewHandle ,SYS ; create synthetic font list with one entry BNE.S CantAllocMem ; real trouble if no memory in application zone MOVE.L A0,SynListHandle @inval1stRecord MOVE.L (A0),A0 MOVE.L D2,SyntheticStrikeTable.synNFNT(A0) ; mark first entry as invalid @makeSysFont TST.B fmExist BPL.S @skipRest CLR.B fmExist CLR.L FOutFontHandle ; may point to non-existent font, so clear CLR.L LastFOND BSR.S InValWidths ; invalidate all of the width tables. ; new system font logic to handle non-12 point, or non-Chicago system font. MOVE.L OneOne,-(SP) ; scale factor denominator MOVE.L OneOne,-(SP) ; scale factor numerator CLR.L -(SP) ; clear face, need bits, device CLR.L -(SP) ; pass system family, size SUBQ #4,SP ; room for function result PEA 4(SP) ; pass the address of the input record _FMSwapFont ADD #20,SP ; toss function result & input record MOVE.L FOutFontHandle,RomFont0 ; salt away system font for backwards compat. @skipRest IF (NOT forROM) THEN ; With SMgrRecord ; Script Manager call out from initfonts GetSMgrCore a0 ; move.l sVectSMgrInitFonts(a0),a0 ; jmp (a0) ; EndWith ; ELSE IF (NOT forJP) THEN ; 32-Bit QuickDraw build? IMPORT SMgrInitFonts ; (in file SMgrPatch.a) BigJMP SMgrInitFonts,A0 ; Script Mgr sets sys & app fonts ELSE ; RTS ENDIF ; ENDIF ; ; we couldn't allocate the width table so issue the out-of-memory deepShit alert ; >> note that since there is no system font yet, this will flash the box repeatedly until the stack ; >> runs into something important. There must be a better way! CantAllocMem ; MOVEQ #25,D0 ; out of mem code _SysError ; self-destruct... ; Invalidate all of the extra width tables, if they exist. InValWidths ; * restore purge state of old FOND first MOVE.L LastFOND,A0 MOVE.B FONDstate,D0 CMP.B #$FF,D0 ; check to see if -1 BEQ.S @skipUnintialized ; if it is don't set state _HSetState ; @skipUnintialized ; ; _HSetState ; wasn't testing for -1 MOVEQ #-1,D2 ; get some ones MOVE.L D2,LastSPExtra ; flag that we can't get a match next time MOVE.W D2,FONDID ; init FOND cache (bug fix: not specific to color) IF (HAS_COLOR) THEN ; ; DIspose of all synthetic entries inside the synthetic strike list. MOVE.L SynListHandle,A0 _GetHandleSize MOVE.L (A0),A1 MOVE.L D0,D1 ; size of handle DIVU #SyntheticStrikeTable.synEntry,D1 ; number of entries SUBQ #1,D1 ; zero base for DBRA @topOfLoop MOVE.L (A1)+,A0 ; handle to strike CMP.L (A1),D2 ; is the ID invalid? BEQ.S @nextEntry ; if so, nothing else to do _DisposHandle ; throw away the strike MOVE.L D2,(A1) ; mark the entry as invalid @nextEntry ADD #SyntheticStrikeTable.synEntry-SyntheticStrikeTable.synNFNT,A1 ; advance past ID, colors DBRA D1,@topOfLoop MOVE.L SynListHandle,A0 ; get handle to list MOVEQ #SyntheticStrikeTable.synEntry,D0 ; size of 1 entry version _SetHandleSize ; restore to single entry version ENDIF MOVE.L WidthListHand,D0 BEQ.S InvalWidthTab MOVE.L D0,A1 MOVE.L A1, A0 ; Get handle in A0 for trap <9-CEL,KON,SMC> _HGetState ; Save state for restore <9-CEL,KON,SMC> MOVE.B D0, -(SP) ; _HLock ; lock for sethandlesize below <9-CEL,KON,SMC> MOVE.L (A1),A1 ; handle->pointer MOVEQ #NumTables-1,D1 @5 MOVE.L (A1)+,D0 ; get a handle from the table BEQ.S @66 ; end of table. <9-CEL,KON,SMC> MOVE.L D0,A0 MOVE.L (A0),D0 ; was this handle purged? BEQ.S @55 MOVE.L #WidTabSize,D0 ; size of new width tablesize _SetHandleSize ; resize the handle since it started out smaller beq.s @getNewSize BNE.S CantAllocMem ; We're dead, don't bother cleaning up stack @getNewSize MOVE.L (A0),A0 MOVE.L D2,WidTabFont(A0) ; invalidate it MOVE.W D2,WidthFID(A0) ; and invalidate requested font ID. SF WidthIsSpline(A0) ; Set width table to bitmap ST WidthLoadSpline(A0) ; try loading spline sf KeepSplineOnDisk(a0) ; try loading it into memory (assume it's less than 128k) @55 DBRA D1,@5 ; until end of table. @66 MOVE.L WidthListHand,A0 ; Get the handle for resetting <9-CEL,KON,SMC> MOVE.B (SP)+, D0 ; restore state in D0 <9-CEL,KON,SMC> _HSetState ; restore the state of handle <9-CEL,KON,SMC> ; Invalidate the width table. InvalWidthTab MOVEQ #-1,D2 ; set up invalid value MOVE.L WidthTabHandle,A0 ; Get Width table Handle in A0 MOVE.L #WidTabSize,D0 ; size of new width tablesize _SetHandleSize ; resize the handle since it started out smaller beq.s @getNewSize1 BNE CantAllocMem ; We're dead, don't bother cleaning up stack @getNewSize1 BSR.S DerefWidthTab MOVE.L D2,WidTabFont(A0) ; invalidate it MOVE.W D2,WidthFID(A0) ; and invalidate requested font ID. MOVE D2,CurFMFamily ; and avoid simple match SF WidthIsSpline(A0) ; Set width table as bitmap ST WidthLoadSpline(A0) ; try loading spline sf KeepSplineOnDisk(a0) ; try loading spline into memory (assume it's less than 128k) @skipSetHandle RTS ; common dereference DerefWidthTab MOVE.L WidthTabHandle,A0 MOVE.L (A0),A0 ; handle->pointer RTS ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; FamSizeInD0 returns both the family and the high word and the size in the low word. FamSizeInD0 MOVEQ #0,D1 ; zero high byte of size MOVE (A3),D0 ; get the family BNE.S @notSystem ; only system if it is zero MOVE SysFontFam,D0 ; set up system family (could be zero, OK) MOVE SysFontSize,D1 ; set up system size (less OK if zero) BNE.S @sysSizeOK ; if nonzero, keep it @notSystem MOVE.B FMDefaultSize,D1 ; get default font size BNE.S @sizeNonZero MOVEQ #12,D1 ; if low memory is no help, hard code to 12 @sizeNonZero CMP #1,D0 ; is the font the application font? BNE.S @sysSizeOK ; if not, donÕt change it MOVE ApFontID,D0 ; change family to application family @sysSizeOK SWAP D0 ; save the family MOVE fmInSize(A3),D0 ; get current size BNE.S @notSizeZero ; if nonzero, leave alone MOVE D1,D0 ; else use either SysFontSize or FMDefaultSize @notSizeZero RTS if not(forROM) then ; GetDevPix is in CQD in ROM builds ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; Moved in from BassCommTail (now part of BassPatches) ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ if HAS_COLOR then GetDevPix else BWGetDevPix endif ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; ; UTILITY GetDevPix; ; ; Returns a pointer to theGDevice's pixMap in A0 ; MOVE.L theGDevice,A0 ; GET A HANDLE TO THE GRAFDEVICE MOVE.L (A0),A0 ; GET A POINTER TO THE GRAFDEVICE MOVE.L GDPMAP(A0),A0 ; GET HANDLE TO THE DEVICE'S PIXMAP SHARE MOVE.L (A0),A0 ; GET PIXMAP POINTER RTS endif ; not forROM case ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ SwapFontStackFrame Record 0,Decr copyInput ds.b 16 ; A copy of CurFMInput styleID ds.l 1 ; Saved style and ID from current FOND. (Set up in GoLoadStrike) paramBlk ds.b ioQElSize ; Parameter block used to give the current device a chance to mess with the output record saveMap ds.w 1 ; The applicationÕs resource map in case we need to switch resource maps fwidStyle ds.w 1 ; Style of the best width tabel found in the FOND if HAS_COLOR then fPixMap ds.b pmRec ; Passed to MakeScaleTbl to return color map foreBack ds.b 12 ; Space for current foreground/background colors curTxMode ds.w 1 ; Current text mode, used when deciding proper fore/back colors endif stackFrame equ * EndR ; ; FUNCTION FMSwapFont(inRec:FontInputRecord):^FontOutputRecord ; ; FMSwapFont is the heart of the font manager. It receives an input record ; from QuickDraw specifying the font, face, device and scale of the requested ; font and figures out the best set of bits to load and return in the output ; record. It is optimized so that if the request is the same as the previous ; one, it returns as fast as it can. ; Some init conditions are rolled in from patches... ; ; To (try to) understand FontFlag, see the comments at SubFont, far, far below. ; if forROM or HAS_COLOR then FMSwapFont else BWFMSwapFont endif ; If no width table, initialise Font Manager for Gaudi. With SwapFontStackFrame tst.l widthTabHandle bne.s @hasWidthTable movem.l a0-a2/d0-d3,-(sp) _InitFonts movem.l (sp)+,a0-a2/d0-d3 @hasWidthTable ; Check FontFlag to see if we got here through SysError first. ; Need to save the family id of the last swapfont call since the FontMgr ; sets CurFMFamily to -1 when a widthtable is purged. The family id is used ; in the BassCache code to determine which script the current font is mapped ; to. The script is then used to lookup the correct cmap, etc. move.l expandMem,a0 ; get low memory global move.l ExpandMemRec.emSplineKey(a0),a0 ; get handle to splinekey move.l (a0),a0 ; get pointer to spline key move.l 4(sp),a1 ; get input record address move.w fmInFamily(a1),splineKeyRec.fLastSwapFontFamilyID(a0) ; save family id for BassCache code. LEA FMgrOutRec,A0 ; get pointer to our output record MOVE.L A0,8(SP) ; return it as the result MOVEQ #-1,D2 ; common constant to invalidate globals CMP.L LastSpExtra,D2 BEQ GoDifFont ADDQ.B #1,FontFlag ; if not a re-entrant call, this sets to zero BEQ.S @notReentrant _Debug BSR InvalWidthTab ; donÕt use the current cache; may be incomplete ; Here we know that the call to LoadResource failed, the disk switch hook is trying to go up, or a real ; SysError occured. CMP.B #9,FontFlag ; are all substitutions exhausted ? BEQ GoTryChicago ; if so, go straight for the ROM font BGT FMSwapDone ; if that didnÕt work, this just return the last record MOVE.B #8,FontFlag ; set to next re-entrant range. @notReentrant ; the most important thing to do is to see if the input record is the same ; as it was last time, as fast as we can MOVE.L 4(SP),A0 ; keep input record pointer in A3 LEA CurFMInput,A1 ; point at last request CMPM.L (A0)+,(A1)+ ; the same? BEQ.S @okFamSize ; if so, skip MOVE.L A3,-(SP) ; maybe just substitution MOVE.L 8(SP),A3 ; set up input record for utility BSR FamSizeInD0 ; returns family, size MOVE.L D0,D2 ; save input record, substituted LEA CurFMInput,A3 ; maybe actuals need subbing as well BSR FamSizeInD0 ; get last family, size MOVE.L (SP)+,A3 ; restore CMP.L D2,D0 ; the same? IF (HAS_COLOR) THEN ; <2.7-4april89-CEL> BNE DifFont ELSE BNE.S GoDifFont ENDIF MOVE.L -4(A0),-4(A1) ; jam original so next time is fast @okFamSize CMPM.L (A0)+,(A1)+ ; face, needbits, device the same? BEQ.S @okFaceBitsDev ; if so, fine, continue fast case ; ! assume for now that I can get away without matching needBits MOVE.L -(A0),D0 ; get the request face, needBits, device MOVE.L -(A1),D1 ; check that against the last accessed face, bits, dev. EOR.L D0,D1 ; set the bits that are different AND.L #$FF00FFFF,D1 ; clear the needBits part BNE.S GoDifFont ; if more is different, go handle it MOVE.L (A0)+,(A1)+ ; make fast for next time, continue fast case @okFaceBitsDev CMPM.L (A0)+,(A1)+ ; numer the same? BNE.S GoDifFont ; if not, skip CMPM.L (A0)+,(A1)+ ; denom the same? BNE.S GoDifFont ; if so, we're cool! ; ugh -- now we have to pull SpExtra out of the port to see if ; that changed. If not, we're cool. ; Believe it or not, it is possible that QuickDraw is not around at all, so test first. TST.B QDExist ; is QuickDraw around BMI.S StraightLineCP MOVE.L grafGlobals(A5),A0 ; get grafGlobals MOVE.L thePort(A0),D0 ; get thePort BEQ.S StraightLineCP ; if no port, donÕt check space extra MOVE.L D0,A0 IF (HAS_COLOR) THEN ; <2.7-4april89-CEL> MOVE txMode(A0),D1 CMP LastMode,D1 BNE.S GoDifStyle ; I also need to check to see if the foreground or background color has changed ! LEA fgColor(A0),A1 LEA LastFore,A0 CMPM.L (A0)+,(A1)+ BNE.S GoDifStyle CMPM.L (A0)+,(A1)+ BNE.S GoDifStyle MOVE.L D0,A0 ; check the bit depth of the port BSR GetPixDepth CMP LastDepth,D0 GoDifStyle BNE DifStyle MOVE.L ([grafGlobals,A5],thePort),A0 ; re-set up thePort ENDIF @checkLastSp MOVE.L LastSpExtra,D0 ; get spaceExtra CMP.L SpExtra(A0),D0 ; did it change? BEQ.S StraightLineCP ; if not, skip ; spaceExtra changing is not such a big deal; we don't have to recalculate ; everything. Dive in at the right spot... LINK A6,#stackFrame CLR saveMap(A6) ; in case substitution must switch res. maps CLR fwidStyle(A6) ; just in case, remember no styled widths have been found MOVEM.L D3-D7/A2-A4,-(SP) ; save work registers MOVE.L 8(A6),A3 ; get input pointer SUBQ.B #2,FontFlag ; set up substitution position to try again. BRA AdjustSpace ; dive in... ; the request is different from the last one, so do things the slow way GoDifFont BRA DifFont ; go handle it ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; Hurray! the font was the same as last time so we can return right away. The ; only thing left to do is to make sure the font wasn't purged. The master pointer can only contain ; a real live font or NIL. No need to check to see if the resource bits are set or if the master pointer ; is part of the free chain or if the handle has been reused since any calls to OpenResFile, CloseResFile ; and ReleaseResource have invalidated any cached handle state. ; A large scale change made here is to branch to DifFont if the font can not be loaded. This allows the ; same substitution to be used by all. Before, the system font was loaded instead, using the CurFMInput ; record. The new code is possibly disasterous since CheckPurged is called at the tail end of DifFont, so ; the space extra only special case can use the same code as the long way around. I need to make sure ; that DifFont only gets this far if the font has been successfully loaded, and no further purging sort of ; operations have occurred. StraightLineCP SUBQ.B #2,FontFlag ; set up substitution position to try again. CheckPurged MOVE.L FOutFontHandle,A0 ; get the font handle. TST.L (A0) BNE.S FMSwapDone MOVE.L WidthTabHandle, A1 MOVE.L (A1), A1 ; Width table ptr TST.B WidthIsSpline(A1) ; Get flag stating if spline <14-jlf> beq.s @DoNormalPurgeCheck ; do normal stuff if not a spline <14-jlf> tst.b KeepSplineOnDisk(a1) ; should we do the load? <14-jlf> bne.s @skipBuildTable ; no, skip it <14-jlf> move.w WidthStrikeID(a1),d0 ; setup sfnt resource id parameter <14-jlf> jsr LoadSplineFontResource ; load the spline font resource <14-jlf> bsr DerefWidthTab ; get the widthtablepointer in a0 <14-jlf> move.l a0,a1 ; save widthPointer <14-jlf> move.l d0,a0 ; move splineHandle <14-jlf> tst.l (a0) ; was the spline loaded? <14-jlf> seq KeepSplineOnDisk(a1) ; no, don't try to load it again. <14-jlf> bra.s @skipBuildTable ; Do not build height table if spline <14-jlf> @DoNormalPurgeCheck MOVE.L A0,-(SP) ; push it MOVE.W #MapTrue,ROMMapInsert ; get it from ROM if possible <10 Jul 85> _LoadResource ; make sure its loaded CMP.B #-1,FontFlag ; hit disk-switch? BEQ.S GoDifFont ; other data is inconsistent so start over. TST.L (A0) ; still NIL? BEQ.S GoDifFont ; if so, in trouble BSR BuildCharTable ; need to rebuild character table @skipBuildTable ; all done with FMSwapFont so restore registers and return to our caller FMSwapDone BSR DerefWidthTab ; get pointer to width table in A0 TST.B WidthIsSpline(A0) ; Test if spline BEQ.S @skipSpline ; not a spline MOVEM.L A0-A1/D0-D2,-(SP) ; Save regs SUBQ #4,SP ; make room for result MOVE.L WidthTabHandle, -(SP) ; 1) Push the Width Table Handle onto the stack _sbSearchForCache ; Call the routine via SplineDispatch TST.L (SP)+ ; check for errors MOVEM.L (SP)+, A0-A1/D0-D2 ; Restore regs BNE.S @skipSpline ; bail MOVE.L expandMem, A0 ; get low mem expand MOVE.L ExpandMemRec.emSplineKey(A0), A0 ; get handle to splineKey MOVE.L (A0), A0 ; pointer to splinekey MOVE.L splineKeyRec.cacheHand(A0), A0 ; is there a cache MOVE.L (A0), A0 ; pointer to the cache LEA cache.fmAscent(A0), A0 LEA FOutAscent, A1 ; MOVE.B (A0)+,(A1)+ ; copy ascent MOVE.B (A0)+,(A1)+ ; copy descent MOVE.B (A0)+,(A1)+ ; copy widMax MOVE.B (A0),(A1)+ ; copy leading ADDQ #1, A1 ; bump to numer passed unused MOVE.L #$01000100, (A1)+ ; fill in numer for splines always 1,1 MOVE.L #$01000100, (A1) ; fill in denom for splines always 1,1 @skipSpline ; we must re-establish widthPtr each time we are called, as the heap might ; have been compacted. Note that this is for backwards compatability only. @cleanUp MOVE.L WidthTabHandle,A0 MOVE.L (A0),WidthPtr ; assume color QD needs this no more. ST FontFlag ; no more worry about re-entrancy ; If returning to previous font manager call (via LoadResource, GetResource, etc.), will need to check ; FontFlag to see if it is -1; if so, start substitution all over since state is no good. MOVE.L (SP)+,A0 ; get return address ADDQ #4,SP ; strip parameter JMP (A0) ; return to caller ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; Utility called by DoMapFont when the correct widths were found in the width cache. It is called twice ; to set up FOutNumer h & v, FScaleVFact & FScaleHFact. A1 first points to widthVOutput in the FOND. ; D1 is either 0 (for v) or 2 (for h). ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ SetUpScale LEA fmOutNumer+FOutRec,A0 ; set up the scale factor in the output record. MOVE.W (A1)+,0(A0,D1) ; save @ FOutNumer. (FOutDenom is always 256.) LEA FScaleVFact,A0 ; also set up scale factor in low memory. MOVEQ #0,D0 ; clear high word (unsigned?) MOVE.W 2(A1),D0 ; widthVFactor or widthHFactor ASL.L #8,D0 ; adjust 8.8 number to 16.16 ADD D1,D1 ; double to 0 or 4. NEG.W D1 ; make 0 or -4. (Low memory is h, v; table is v, h) MOVE.L D0,0(A0,D1) ; save @ FScaleVFact, then FScaleHFact RTS ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; Given a handle to a FONT, NFNT or FOND in A0, DeRefResource loads it if it has been purged (skipping ; the trap call if it is already in memory.) A0 is set on output to point to the resource, or equals NIL ; if the call to LoadResource fails. The Z flag is set if the call to load resource failed. ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ DeRefResource TST.L (A0) ; see if it is already loaded. BNE.S alreadyLoaded ; if so, do nothing. MOVE.L A0,-(SP) ; push it MOVE.W #MapTrue,ROMMapInsert ; get it from ROM if possible <10 Jul 85> _LoadResource ; make sure its loaded CMP.B #-1,FontFlag ; hit disk-switch? BEQ.S badLoad ; other data is inconsistent so start over. TST.L (A0) ; still NIL? BEQ.S badLoad ; if so, in trouble alreadyLoaded MOVE.L (A0),A0 ; handle -> pointer RTS badLoad BRA Pop4SubFont ; start substituting (throw away return address) IF (HAS_COLOR) THEN ; <2.7-4april89-CEL> ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ PurgeOnTheFly ; see if last font supplied was synthesized font. if so, make it purgable CMP #-1,FONDID BEQ.S @nothingToDo MOVE.L FOutFontHandle,D0 ; does it exist at all? BEQ.S @nothingToDo ; wonÕt exist at InitFonts time MOVE.L D0,A0 ; pointer to font MOVE.L (A0),D0 ; did it purge? BEQ.S @nothingToDo MOVE.L D0,A1 BTST #0,(A1) ; is it an on-the-fly font? BEQ.S @nothingToDo _HPurge ; make it purgable @nothingToDo RTS ENDIF ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; DifFont - handle a font or style change. ; ; We reach this point when the family, size, scale or device has been changed, which usually means that ; we have to load in some new bits. The first thing to do is see if the device changed and, if it has, ask it ; for a new style table and dots/inch values. ; ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ DifFont LINK A6,#stackFrame ; might as well use locals as locals. CLR saveMap(A6) ; in case substitution must switch res. maps. CLR fwidStyle(A6) ; just in case, remember no styled widths have been found MOVEM.L D3-D7/A2-A4,-(SP) ; save work registers MoreDifFont IF (HAS_COLOR) THEN ; <2.7-4april89-CEL> BSR.S PurgeOnTheFly ENDIF MOVE.L 8(A6),A0 ; pick up request pointer LEA copyInput(A6),A1 MOVEQ #$10,D0 _BlockMove ; make copy of request MOVE.L A1,A3 MOVE.B fmInFace(A3),FOutCurStyle ; set up desired style MOVE.W fmInDevice(A3),D0 ; get device in request CMP.W CurFMDevice,D0 ; did it change? BEQ.S @sameDevice ; if not, we're cool BSR SetNewDevice ; otherwise, read in the new stuff @sameDevice ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; ; The TryAgain entry point is used if no size/style variant of the requested font was found. SubFont has ; changed the family field and restored the size field from the original input record before entering here. ; ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ TryAgain BSR FamSizeInD0 MOVE.L D0,(A3) ; save the size, family ; remember that copy has needBits cleared, but spline code (??) should check A6 input record !!! CLR.B fmInNeedBits(A3) LEA FontFlag,A4 ; we save a word here. CMP.B #6,(A4) ; did we just substitute the ROM font? BLT.S @skipROMFamily ; if not, all is well CLR (A3) ; zero family, but leave substituted size @skipROMFamily ; if we got here from the shortcut exact match or space extra only change, and LoadResource of ; the font failed, then FontFlag is set to -2. TST.B (A4) ; test FontFlag for -2 BPL.S DoMapFont ; if 0 or greater, no problem BSR InvalWidthTab ; invalidate WidthTabHandle CLR.B (A4) ; advance to real substitution ; Use the info from the old width table if it applies. ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; DoMapFont searches handles pointed to by the width list for a table of widths matching the font ; requested by the input pointer. ; ; Registers used: ; D0 = size of width table, scratch ; D1 = scratch ; D2 = last purged handle entry offset ; D3 = last invalidated entry offset ; D4 = table full flag ; D5 = offset into entry list ; D6 = call MapFont flag ; D7 = last nonpurged offset ; A0 = scratch ; A1 = scratch ; A2 = ; A3 = input pointer ; A4 = width list handle, pointer ; ; Significant changes made since the Macintosh + ROM: ; ; 12-Aug-86 CRC Details, detailsÉ ; The algorithm for determining which entry to use was: ; Check list until match, or entry = 0, or entry has been purged, or the end of the list is reached. ; If an entry was purged, reallocate it and use it. ; If entry = 0, allocate it and use it. ; ; The algorithm is now: ; Check list until match or entry = 0 or the end of the list is reached. ; if no match, use the last invalidated entry in the list. ; if memory is not full: ; if no invalidated entry, reallocate the last purged entry in the list. ; if no purged entry, and the last entry = 0, allocate a new entry at the end of the list. ; if memory is full or the list is full: ; reuse the last nonpurged entry in the list. ; if there isnÕt a nonpurged entry then weÕre out of luck; donÕt use cache. ; if a memory allocation call fails, then the system heap is in bad shape; donÕt use cache. ; ; The actual size and font are stored in the width table instead of 0 or applFont. ; ; NewHandle, ReallocHandle recover if an error is returned. ; ; Entries in queue are rotated so that list is ordered most recently accessed to least recently ; accessed. If the system heap has room for all twelve elements, the least recently accessed is ; reused first. Otherwise, the Memory Manager roving purge pointer spins the wheel of fortune to ; decide who is purged (but only if some other process allocates heap space, or if the system heap ; is sufficiently fragmented.) ; ; Just for grins, all local branches are forward except for branches to the tops of loops. ; ; Any newly allocated or reused width table has the font handle and family ID fields invalidated to ; allow optimization of the remainder of the table fill-in code. ; ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ DoMapFont MOVE.L WidthListHand,D0 ; do we have any spare width tables? BEQ.S @shortSkip ; if not, then skip this nonsense. ; Check if the width-table cache is still valid. <18-Oct-85> MOVEQ #-1,D2 ; handy invalidation constant CMP.L LastSpExtra,D2 ; invalidated through normal means or switcher? BEQ.S @invalAll CMP CurFMFamily,D2 ; just reuse WidthTabHandle? BNE.S @notInvalid BRA.S @shortSkip @invalAll BSR InvalWidths ; invalidate all of the width tables. @shortSkip BRA @skipCache ; ; We know that there has been some change. Search the list of width tables for a match. @notInvalid MOVE.L D0,A4 ; get the width list handle. MOVE.L (A4),A4 MOVEQ #-1,D2 ; no purged handles found so far. MOVEQ #-1,D3 ; no invalidated entries found so far. SF D4 ; assume that table is not full. MOVEQ #-4,D5 ; list entry counter is incremented at the top of loop. SF D6 ; do call MapFont MOVEQ #-1,D7 ; no nonpurged handles found so far. ; Check each list entry to see if it has been allocated, or if the table has purged. @loopTop ADDQ #4,D5 ; advance to next entry in width table handle MOVE.L (A4),D1 ; get a possible width table handle. BEQ @outOfLoop ; if none, create a new entry. MOVE.L D1,A0 MOVE.L (A0),D0 ; get the master pointer. BEQ @rememberPurge ; skip if it has been purged. MOVE D5,D7 ; remember that this one was not purged. MOVE.L D0,A1 ; we are pointing at the table now. ; We know that the device and scales match. But does the old table match the requested style? MOVEQ #3,D1 ; number of longs to check - 1 MOVE.L A3,A0 ; copy the input pointer LEA WidthFID(A1),A1 ; point to old width's info. CMP #-1,(A1) ; check to see if it is valid. BNE.S @valid ; skip if valid. MOVE D5,D3 ; remember offset to invalid entry @valid CMPM.L (A0)+,(A1)+ ; does family, size; face, needbits, device; DBNE D1,@valid ; numer; denom match? BNE.S @loopBottom ; ; We already have the font handle (from the old width table), so skip most of MapFont. ST D6 ; donÕt call MapFont MOVE (A1),D0 ; get new font family ID CMP FONDID,D0 ; different from old one? BEQ.S @sameFOND ; if not, fond globals are already set up MOVE.B FONDState,D0 ; get old FOND state MOVE.L LastFOND,A0 ; maybe zero; if so, HSetState will reject _HSetState ; restore purge state MOVE.L (A4), A0 ; Get the Width Table handle <1.7/22mar89> _HNoPurge ; Make the Width Table non-purgeable <1.7/22mar89> MOVE (A1)+,D0 ; get new FOND ID MOVE D0,FONDID ; save it MOVE.L (A1)+,A0 ; get new FOND handle MOVE.L A0,LastFOND ; save it BEQ.S @noFOND BSR DerefResource ; load it if it has purged MOVE.B (A0),SaveFondFlags ; save the high byte of the FOND flags. MOVE.L LastFOND,A0 _HGetState ; get the purge state MOVE.B D0,FONDState ; preserve it until the next change _HNoPurge ; and make the font nonpurgable MOVE.L WidthListHand, A4 ; Get the list handle of Width Tables <1.7/22mar89> MOVE.L (A4), A4 ; Pointer to Width Table Handles <1.7/22mar89> ADD D5, A4 ; Add Offset of current Width Table <1.7/22mar89> MOVE.L (A4), A1 ; Handle to Width Table <1.7/22mar89> MOVE.L (A1), A1 ; Width Table ptr <1.7/22mar89> LEA WidthUsedFam(A1),A1 ; Load the address of the WidthUsedFam <1.7/22mar89> BRA.S @noFOND ; skip skip @sameFOND ADDQ #6,A1 ; skip over FOND ID, handle @noFOND MOVE.B (A1)+,UsedFWidths ; remember if we used family widths. ; We are changing back to an old style, so set up FOutFontHandle from our width. MOVE.B (A1)+,FOutCurStyle ; set up real style (computed along with width table). MOVEQ #0,D1 BSR SetUpScale ; set up the vertical scale factor and output. MOVEQ #2,D1 BSR SetUpScale ; set up the horizontal scale factor and output. ; If we really want an expanded version, see if it already exists. MOVE.L (A4),A0 ; get width handle. MOVE.L (A0),A1 ; pointer to width table. MOVE.L WidTabFont(A1),A1 ; corresponding font handle. MOVE.L A1,FOutFontHandle ; get the font handle. BRA.S @toSkipNew ; insert width handle in list. ; This entry did not match the request, so go on to the next one. @rememberPurge MOVE D5,D2 ; remember that this one was purged. @loopBottom ; ADDQ #4,A4 ; bump the list pointer. CMP.W #(NumTables-1)*4,D5 ; done with the table yet? BLO @loopTop ; try for a match on the next one in the list. ; end of loop ST D4 ; remember that the table was full. SUBQ #4,A4 ; point back at the one we want to use. @outOfLoop ; if no exact match was found, check the existing WidthTabHandle to see if it is already invalid. MOVE.L WidthTabHandle,A1 ; get address of handle MOVE.L (A1),A1 ; get master pointer CMP.W #-1,WidthFID(A1) ; has it been marked invalid? BEQ.S @skipCache ; it is all ready to use. EXG D3,D5 ; set up invalid position, preserve end of table. TST D5 ; was an invalid table found? BPL.S @reuseIt ; if so, skip purge check. MOVE.L #WidTabSize,D1 ; get size of a table, in case we must allocate it. _MaxBlock ,SYS ; better than FreeMem; unfortunately, didnÕt know for Aladdin ROM CMP.L D1,D0 ; is there enough room? BLE.S @useNonpurged ; if not, use the last nonpurged entry in the list. MOVE.L D1,D0 ; set up size to allocate. MOVE D2,D5 ; was a purged handle found (to be missing)? BPL.S @reuseIt ; if so, since we have enough memory, reuse it. TST.B D4 ; is the table full? BNE.S @useNonpurged ; if so, re-use nonpurged entry. ; We are beyond all list entries, so create a new one. MOVE D3,D5 ; restore end of table position. _NewHandle ,SYS ;_NewHandle in system heap. BNE.S @skipCache ; use it only if allocation successful. BRA.S @reuseIt ; reset width list pointer since it may have moved. @useNonpurged MOVE D7,D5 ; last nonpurged entry. BMI.S @skipCache ; if not one, all out of options. @reuseIt MOVE.L WidthListHand,A4 ; get the width list handle again. MOVE.L (A4),A4 ; since it may have moved. LEA 0(A4,D5),A4 ; determine list entry address. MOVE.L (A4),D1 ; get the master pointer. BEQ.S @newWidthTable ; if zero, just created; skip purge test. MOVE.L D1,A0 ; get the master pointer. TST.L (A0) ; has it been purged? BNE.S @newWidthTable ; if non-purged, mark as invalid. ; We found a purged list entry, so let's re-allocate it. ; <57> The width table should always be allocated in the system heap. However, ReAllocHandle ; is stupid, and will allocate the memory in the current heap, so set the current zone ; to be the system zone to ensure system heap allocation. move.l TheZone,-(sp) ; <57> Save the current zone move.l SysZone,TheZone ; <57> Make the system zone the current zone _ReAllocHandle ; so that the memory for the width table will always be move.l (sp)+,TheZone ; <57> allocated in the system heap. tst.w d0 ; <62> Refresh the result code. BNE.S @skipCache ; it failed, so nothing can be cached. BRA.S @reuseIt ; reset width list pointer since it may have moved. ; If ReallocHandle or NewHandle fail, then there is no room to cache anything (since all other cache ; members would have purged to allow ReallocHandle or NewHandle to succeed). ; At this point and at the entry point skipNew, A0 is the handle to be ; installed at the front of the table, A4 points to the entry position being reused, and D5 is the offset ; from the front of the table to the reused position. @newWidthTable @toSkipNew BRA.S @skipNew ; dive in. @skipNext MOVE.L -(A4),4(A4) ; move previous entry to this one. @skipNew SUBQ #4,D5 ; see if this is the first entry. BPL.S @skipNext ; if so, nothing to do. @swapHandles MOVE.L WidthTabHandle,D1 ; save current handle - it's old now. MOVE.L A0,WidthTabHandle ; save it in widthTabHandle. _HNoPurge ; the current handle can't purge. MOVE.L D1,(A4) ; save old handle in the front of the list. MOVE.L D1,A0 _HPurge ; now it can purge if it wants. ; check to see if font is already figured out and installed TST.B D6 ; call MapFont? BNE.S GotFontHandle ; donÕt bother if the widths were found ; call MapFont to do all the hard work, installing a font in the output record @skipCache ; Invalidate the new table entry. BSR InvalWidthTab BSR MapFont ; figure out font and install it ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ GotFontHandle MOVE.L WidthTabHandle, A1 MOVE.L (A1), A1 ; get Width Table pointer <14-jlf> TST.B WidthIsSpline(A1) ; is this a spline width table? <14-jlf> beq.s @SkipSplineLoad ; no, do non-spline cases <14-jlf> tst.b KeepSplineOnDisk(a1) ; should we load the spline? <14-jlf> bne NoColors ; no, skip the load <14-jlf> move.w WidthStrikeID(a1),d0 ; setup sfnt resource id parameter <14-jlf> jsr LoadSplineFontResource ; load the spline font resource <14-jlf> bsr DerefWidthTab ; get widthPointer in a0 <14-jlf> move.l a0,a1 ; save widthPointer <14-jlf> move.l d0,a0 ; load spline handle into a0 <14-jlf> tst.l (a0) ; was the spline loaded? <14-jlf> seq KeepSplineOnDisk(a1) ; no, don't try to load it next time <14-jlf> bra NoColors ; Splines do not expand whole strike on the fly <14-jlf> @SkipSplineLoad MOVE.L FOutFontHandle,A0 ; get the current font handle <14-jlf> BSR DeRefResource ; load resource who's handle is in A0. <14-jlf> ; set up ascent, descent, etc... TST.B FScaleDisable ; if scaling disabled, do new way BNE.S newSetupHeight LEA FOutAscent,A1 ; point to the info section MOVE.B FAscent+1(A0),(A1)+ ; copy ascent MOVE.B FDescent+1(A0),(A1)+ ; copy descent MOVE.B FWidMax+1(A0),(A1)+ ; copy max width MOVE.B FLeading+1(A0),(A1) ; copy leading BRA DoStyle ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; ByteScale, ByteHScale are utility routines used to figure the font metrics for this font. ; FScaleVFact contains the nice factor to allow scaling to be disabled so that QD can do no or easy bitmap ; scaling. The value to be scaled is passed in D0, and scaled by the value in D1. ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ByteScale MOVE.L FScaleVFact,D1 ByteHScale EXT D0 ; fix-ize the byte in D0 SWAP D0 CLR D0 ; clear fract MOVEM.L D0-D3/A0-A1,-(SP) ; D0, D1are operands; D2, D3 make room for results, ; preserves A0, A1. _FixMul ; _FixRound MOVE (SP)+,D0 ; get result in low byte ADDQ #2,SP ; throw away the other half of D3 MOVEM.L (SP)+,A0-A1 ; restore registers MOVE.B D0,(A1)+ ; save it in FMgrOutRec RTS newSetupHeight LEA FOutAscent,A1 ; point to the info section MOVE.B FAscent+1(A0),D0 BSR.S ByteScale ; copy integer ascent MOVE.B FDescent+1(A0),D0 BSR.S ByteScale ; copy descent MOVE.B FWidMax+1(A0),D0 ; maxwidth needs a horizontal factor adjustment. MOVE.L FScaleHFact,D1 BSR.S ByteHScale ; copy max width MOVE.B FLeading+1(A0),D0 BSR.S ByteScale ; copy leading ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; At this point, we have the proper bits but the style parameters are wrong. ; Fill out the style record using a table supplied by the current device IF (HAS_COLOR) THEN ; <2.7-4april89-CEL> BRA.S DoStyle ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; GetPixelDepth returns the size in bits of a destination pixel in D0. ; GetPixDepth is an alternate entry used by the start of FMSwapFont to see if the destination depth has changed. ; uses D0, A0, A1 ; GetPixelDepth TST.B QDExist ; is QuickDraw around BMI.S useDefault GetPixDepth MOVE.L grafGlobals(A5),A1 MOVE.L thePort(A1),D0 BEQ.S useDefault ; no port after InitGraf until at least InitWindows (and InitFonts in between!) MOVE.L D0,A0 ; This code used to dig ScrnBase out of the QuickDraw Globals. ; This doesn't work so well because Cyclone changes ScrnBase on depth switch ; without updating the QuickDraw Globals. A "More Correct" fix would be to ; have the process manager update the QuickDraw Globals of all running processes. MOVE.L ScrnBase,D0 ; get pointer to screen base address TST portBits+rowBytes(A0) ; IS SRC A PIXMAP? BPL.S @doBits ; =>NO, IT'S A BITMAP MOVE.L ([portBits+baseAddr,A0]),A0 ; GET POINTER TO PORT'S PIXMAP CMP.L pBaseAddr(A0),D0 ; does pixelmap point to the screen? BEQ.S @useDevDepth ; if so, use the gDevice depth BRA.S @usePixDepth ; if not, use the pixel map depth @doBits CMP.L portBits+baseAddr(A0),D0 ; IS BITMAP BASEADDR SAME ? BNE.S useDefault ; if offscreen and old port must be 1 deep @useDevDepth bsr.l GetDevPix ; bitmap points to screen, so get screen depth @@@@ @usePixDepth MOVEQ #0,D0 ; zero high word MOVE pixelSize(A0),D0 ; get the bit depth (zero flag clear) RTS useDefault MOVEQ #1,D0 ; assume old style bit maps are always 1 deep (zero flag clear) RTS ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ DifStyle LINK A6,#stackFrame CLR saveMap(A6) ; in case substitution must switch res. maps CLR fwidStyle(A6) ; just in case, remember no styled widths have been found MOVEM.L D3-D7/A2-A4,-(SP) ; save work registers MOVE.L 8(A6),A3 ; get input pointer SUBQ.B #2,FontFlag ; set up substitution position to try again. BSR PurgeOnTheFly BSR DerefWidthTab ; pointer to width table. MOVE.L WidTabFont(A0),A0 ; corresponding font handle. MOVE.L A0,FOutFontHandle ; set the font handle to the original 1 bit guy for expansion ENDIF ; END colorgrayness DoStyle IF (HAS_COLOR) THEN ; <2.7-4april89-CEL> ; If the destination depth is 1, or if QuickDraw must algorithmically add a style, or if there is less than 3K of stack left, ; or if the international bit is set in the font, donÕt look for a color font. BSR.S GetPixelDepth ; the depth of the destination bitmap MOVE.L D0,D6 ; the device pixel size CMP #1,D6 ; 1 bit? BEQ.S @noColors MOVE.B FOutCurStyle,D0 AND.B #$9F,D0 ; turn off condense, extend BNE.S @noColors ; are there algorithmic additions? _StackSpace CMP.L #$0C00,D0 ; at least 3K of stack? BLT.S @noColors ; if not, use 1 bit font bsr DerefWidthTab ; dereference the width table <14-jlf> tst.b WidthIsSpline(a0) ; is this a spline font? <14-jlf> bne NoColors ; yes, skip this color madness <14-jlf> MOVE.L FOutFontHandle,A0 BSR DeRefResource ; make sure it is loadable BTST #6,(A0) ; test international bit BEQ.S LookForColor ; if clear, it is OK to expand @noColors toNoColors ; label referenced below BRA NoColors ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; LookForColor scans the table of synthesized color fonts looking for a match. It is passed the resource ; ID of the strike to find, and a hint of where the last one was found. ; It sets the Z condition flag if a match is found. ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ LookForColor BFFFO D6{$1A,6},D6 ; turns 32, 16, 8, 4, 2, 1 into $1A, $1B, $1C, $1D, $1E, $1F @@@@ NOT D6 ; $FFE5 ÉÊ$FFE0 AND #7,D6 ; 5, 4, 3, 2, 1, 0 (amount to shift to multiply by bit depth) @@@@ ; get the foreground and background colors, if needed MOVE #1,curTxMode(A6) ; assume text mode is srcOr LEA foreBack(A6),A1 ; set foreground to default of black CLR.L (A1)+ ; clear the foreground r, g CLR.W (A1)+ ; clear the foreground b MOVEQ #-1,D0 ; full intensity MOVE.L D0,(A1)+ ; set the background r, g MOVE.W D0,(A1) ; set the background b ; Believe it or not, it is possible that QuickDraw is not around at all, so test first. TST.B QDExist ; is QuickDraw around? BMI.S @useDefault MOVE.L ([grafGlobals,A5],thePort),D0 ; get the port BEQ.S @useDefault ; no port after InitGraf until at least InitWindows (and InitFonts in between!) MOVE.L D0,A0 MOVE txMode(A0),D0 AND #$FFF7,D0 ; clear the pattern bit, in case it was set by the user by mistake MOVE D0,curTxMode(A6) CMP #$32,D0 ; hilite? BEQ.S toNoColors ; if so, return 1 bit font BCLR #5,D0 ; arithmetic mode? BNE.S @arithMode ; if not, use black and white BCLR #2,D0 ; a ÒnotÓ mode? (we ignore these now and create synth font) <5JUNE92 SAH> SUBQ #srcBic,D0 ; srcBic? BEQ.S toNoColors ; if so, return 1 bit font BRA.S @useDefault ; multibit font, but black/white @arithMode ; <5JUNE92 SAH> ; Here is Shannon's changes to text to make it draw faster! ; The code currently uses the arithmetic mode bit (bit 5) to mean color font. It passes this ; to MakeScaleTbl to get it to colorize. The only problem is that MakeScaleTbl uses bit 3 ; to determine if it needs to colorize, so no colorizing happens. When creating a synthetic ; font, this code checks bit 5. If it's set, it marks the font as color (because MakeScaleTbl should ; have colorized it). When calling stretch, it passes multColor to be true if the font is color. ; This means that when a synthetic font is created and an arithmetic transfer mode is set, multColor is set ; to true in StretchBits, even though the source is entirely black and white. It also means that color ; fonts are not colorized. ; It is stupid to use bit 5 for colorizing as it doesn't do this. ; It is also stupid to mark synthetic fonts as color when they're not. ; for now, I'm going to clear bit 5 in the curTxMode (here) and create a B&W font. This means ; that we can change the meaning of multColor in stretch to be a bit field, where bit 0 means ; that the source is entirely black and white. Therefore, we can take BitBlt rather than ; ScaleBlt. BCLR #5,curTxMode + 1(A6) ; clear arithmetic mode <5JUNE92 SAH> bra.s @useDefault ; <5JUNE92 SAH> @useColor ; multibit font, fg/bg colors PEA foreBack(A6) _GetForeColor PEA foreBack+6(A6) ; for srcCopy use normal forground, background _GetBackColor @useDefault MOVE.L A3,-(SP) ; preserve register move.w CurMap,-(sp) ; <29> Save current resource map, outside of some major spaghetti code ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; look for a multibit font, if it is around MOVEQ #0,D3 ; assume no multibit font on disk MOVEQ #0,D5 ; assume no second best match MOVE D6,D7 ; if we do find a multibit font, assume it is an exact (depth) match MOVE D6,D0 ASL #8,D0 ; shift to high byte OR.B fmInFace(A3),D0 ; add in actual style requested MOVE.B FOutCurStyle,D1 ; could be condense, extend EOR.B D1,D0 ; if so, turn them off BSR DerefWidthTab MOVE widthASize(A0),D2 ; actual size font returned ; scan through FOND looking for matching size and style MOVE.L LastFOND,D1 ; is there a FOND? BEQ @noEntry ; if not, no preexpanded fonts move.l ExpandMem,a0 ; <29> move.l ExpandMemRec.emSplineKey(a0),a0 ; <29> Get pointer to TrueType variables move.l (a0),a0 ; <32> move.w splineKeyRec.lastFontMap(a0),CurMap ; <29> Set up resource map that last font was fetched from MOVE.L D1,A0 ; if so, check it for fast fonts MOVE.L (A0),A0 LEA FontFamilyRecord.FONDAssoc(A0),A0 ; skip header MOVE.W (A0)+,D1 ; fetch # of entries @FTSLoop CMP.W (A0)+,D2 ; search for matching size BLT.S @secondBest ; sizes must be in ascending order BNE.S @skipStyle ; if the style is too small, donÕt check the style CMP.W (A0),D0 ; is the style high-byte (bit depth) equal to the request? BEQ.S @foundEntry ; also look for a smaller bit depth than the one requested if an exact match is not found. Keep it around just in case ; donÕt worry about 1 bit; it has already been found. And it canÕt be 8 bit (depth = 3), since that would already be an ; exact match. ; FONDs containing more than 1 font in different depths should order the entries in bitdepth ascending order so that the ; second guess will be the deepest font. As an example, if a FOND contained a 2 bit font followed by a 4 bit font, ; the 4 bit font is chosen if the destination is 8 bits. (Of course, the 1 bit font would be chosen in the 1 bit destination case, ; the 2 in the 2 bit dest. case, and the 4 in the 4 bit dest. case.) MOVE.W (A0),D4 ; get the style word CMP #$0100,D4 ; is it 1 bit? BLT.S @skipStyle @bumpStyle CMP #$0500,D4 ; is it 32 bit? @@@@ used to be 0300 BGE.S @skipStyle ADD #$0100,D4 ; bump the bit depth CMP D4,D0 ; does the bumped depth match the request? BNE.S @bumpStyle MOVE.L A0,D5 ; save the second best @skipStyle ADDQ #FAssocSiz-2,A0 DBRA D1,@FTSLoop @secondBest TST.L D5 ; a less precision multi-bit font around? BEQ.S @noEntry MOVE.L D5,A0 ; if so, point to it MOVE.B (A0),D7 ; and set up the depth @foundEntry MOVE 2(A0),D0 ; get strike ID MOVE D0,D5 ; save a copy for later BSR LoadNoROM ; try to load it from system first BNE.S @gotOne ; only look in ROM if FOutFontHandle is also in ROM MOVE.L FOutFontHandle,A0 ; could be a 1 bit ROM font BSR DerefResource ; get a pointer to it MOVE.L A0,D0 _StripAddress ; but only look at the valid part of the address MOVE.L D0,A0 MOVE.L ROMBase,D0 ; do the same to the ROM base pointer _StripAddress CMP.L D0,A0 ; is it below the ROM? BLT.S @noEntry ; if so, skip looking for a expanded font in the ROM MOVE D5,D0 BSR LoadNewStrike ; then look in ROM BEQ.S @noEntry @gotOne MOVE.L A0,FOutFontHandle ; install the font handle MOVE.L A0,A2 ; set up font handle for adding to syn list BSR BuildCharTable ; make the character (height) table MOVE.L (A2),A0 ; get pointer to font data CMP D6,D7 ; exact match or second best? BNE.S @expand ; if not exact match, must map into correct depth BTST #1,(A0) ; if colr bit is clear, install directly in the color table BEQ SaveFont @expand ; font can contain color, so set up the colors for makescaletbl BCLR #5,curTxMode+1(A6) ; start out with the bit clear CMP #srcXor,curTxMode(A6) ; is it srcXor? BEQ.S @skipColor ; if so, donÕt color it PEA foreBack(A6) _GetForeColor PEA foreBack+6(A6) ; for srcCopy use normal forground, background _GetBackColor BSET #5,curTxMode+1(A6) ; set bit so that MakeScaleTbl will use fg, bg colors @skipColor @noEntry ; search through the synthesized strike table for matching colors and depth ; determine the original ID from the width table BSR DerefWidthTab MOVE.L widthNFNT(A0),D5 ; the strike ID @noFontFamily MOVE.L SynListHandle,A0 _GetHandleSize DIVU #SyntheticStrikeTable.synEntry,D0 SUBQ #1,D0 ; number of entries, zero based MOVE.L (A0),A0 @nextCEntry MOVE.L (A0)+,A2 ; get the strike handle MOVE.L (A0)+,D2 ; and the strike ID & FONT/NFNT flag CMP.L D5,D2 ; see if it matches BNE.S @skipToNext TST.L (A2) ; has it been purged? BEQ.S @skipToNext MOVE.L (A2),A3 ; dereference MOVE (A3),D2 ; get font flags LSR #2,D2 ; toss height and width table bits AND #$7,D2 ; look at only depth bits @@@@ used to be #3 CMP D6,D2 ; same as screen depth? BNE.S @skipToNext MOVE.L A0,A3 LEA foreBack(A6),A1 MOVEQ #(RGBColor/2)-1,D4 ; number of longs of color, zero based @checkNext CMPM.L (A3)+,(A1)+ DBNE D4,@checkNext BNE.S @skipToNext ; if it is a synthetic font, donÕt let it purge, since it can not be reloaded with LoadResource MOVE.L (A2),A0 BTST #0,(A0) ; synthetic? BEQ.S @skipNoPurge MOVE.L A2,A0 _HNoPurge @skipNoPurge BRA saveFont ; take short branch out of here. @skipToNext ADD #SyntheticStrikeTable.synEntry-SyntheticStrikeTable.synFGColor,A0 ; skip 12 bytes color DBRA D0,@nextCEntry ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; Registers used by color strike part: ; D0 = scratch D1 = scratch D2 = scratch D3 = input pixel size ; D4 = D5 = color table handle D6 = output pixel size D7 = font purge state, scratch ; A0 = scratch A1 = scratch A2 = new font A3 = save stack ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; Here either the source or destination bitmap or both are not one deep. ; If either the screen depth or font depth is greater than 1, then let PatConvert expand, compress, or map ; the strike. Make the font strike nonpurgable for QD routine. Then, see if the font has a color table: MOVE.L FOutFontHandle,A0 ; get handle again _HGetState ; need to preserve current purgability MOVE D0,D7 ; save old state _HNoPurge ; make nonpurgable for QD patConvert MOVE.L (A0),A0 ; deref. it MOVEQ #0,D5 ; assume that no color table exists TST.B 1(A0) ; test the color table bit BPL.S @relativeColor ; derive color table from foreground/background ; If one exists, get the resource ID from the current width table. (The resource ID of the FCLR is the same ; as the ID of the strike.) Note that only NFNTs can be color, since both a FONT and an NFNT could have the ; same ID. BSR DerefWidthTab ; get pointer to width table in A0 MOVE.L widthNFNT(A0),D0 ; get resource ID in low word, NFNT bit in high word BPL.S @relativeColor ; if FONT, skip trying for color table SUBQ #4,SP ; make space for function result MOVE.L #'fctb',-(SP) ; pass resource type MOVE D0,-(SP) ; pass resource ID MOVE.W #MapTrue,RomMapInsert ; look in ROM first rb _GetResource ; only uses D0,A0 MOVE.L (SP)+,D5 ; if it fails, then no color table to pass to MakeScaleTbl @relativeColor MOVE.L D5,fPixMap+pmTable(A6) ; set up color table, if any ; save the stack so we know how much to pop after MakeScaleTbl has done its thing MOVE.L SP,A3 ; save stack pointer MOVE.L FOutFontHandle,A0 ; source strike ; Calc total size of the dst and set the size of patXData MOVE.L (A0),A1 ; Ptr to font MOVE.W fFontType(A1),D0 ; Need source bit depth <10-CEL> MOVE.W D0, D3 ; make a copy, for D3 setup <10-CEL> LSR #2,D3 ; toss bottom two bits AND #$7,D3 ; 0 É 5 (bit depth of 1 É 32) cmp #3,d6 ; is output depth <= 8 bits/pixel? ble.s @depthOK ; use the original font tst D3 ; is the input depth only 1-bit? <10-CEL> BEQ giveup1 ; dont scale to 16 or 32 bit. <10-CEL> BTST #9,D0 ; does the strike contain color? <10-CEL> BEQ giveup1 ; no, just ignore it. <10-CEL> MOVE.W #3, D6 ; pin at 8 bit/pixel <10-CEL> @depthOK _GetHandleSize ; size of the original handle MOVE.L (A0),A1 ; dereference handle MOVE fRowWords(A1),D1 ; loc table is just after strike " ADD D1,D1 ; strike width in bytes is rowWords * 2 MULU fFRectHeight(A1),D1 ; figure size of original strike MOVE.L D1,D5 ; remember size of strike in pixels ASL.L D3,D1 ; scale up for bit depth MOVE.L D1,D4 ; remember source strike size SUB.L D1,D0 ; difference of original strike and rest of font MOVE.L D0,D2 ; remember size of post-strike table + header LSL.L D6,D5 ; size of destination strike in bits ADD.L D5,D0 ; size of new font MOVE.L FOutFontHandle,A0 ; source strike " move.l d0,a2 ; save requested size in a2 <10-CEL> move.l d2,-(sp) ; save d2 across call _HandToHand move.l (sp)+,d2 ; restore for later TST D0 BNE giveUp1 move.l a2,d0 add.l #$1000, d0 ; add for slop then shrink later <10-CEL> _SetHandleSize BNE giveUp move.l a2,d0 ; shrink to real size <10-CEL> _SetHandleSize ; <10-CEL> BNE giveUp ; <10-CEL> MOVE.L A0,A2 ; save handle to new font <10-CEL> MOVE.L FOutFontHandle,A0 MOVE D7,D0 _HSetState ; restore purgability of original strike MOVE.L (A2),A1 ; dereference new handle ; fix up the flag words MOVE D6,D0 ; get the bit depth (0 É 3) ASL #2,D0 ; make room for the height and width bits BSET #8,D0 ; set synthetic font bit MOVE curTxMode(A6),D1 ; get mode word AND #$20,D1 ; isolate arithmetic mode bit LSL #4,D1 ; move to bit 9 (set if font contains color) OR D1,D0 ; combine with depth AND #$FFe3,(A1) ; clear existing depth bits used to be fff3 OR D0,(A1) ; and save it in the font. ; There are two methods of finding the location table, either by looking just past the strike or just before the ; offset/width table. So, it is not enough to just scale owTLoc; the locTable length may not be an even multiple ; of the scale factor. To find the offset/width table, the high word of owTLoc is stored in nDescent, a field ; left over from Xerox days that doesnÕt appear to be in use. Assuming that fNDescent always has a negative ; value from its old use, there is no confusing it with the actual fNDescent. MOVE fNDescent(A1),D0 ; if the original font is bigger than 128K, get the high word SWAP D0 ; put it in its place BPL.S @skipZero MOVEQ #0,D0 ; zero high word @skipZero MOVE fOWTLoc(A1),D0 ; get the original offset ADD.L D0,D0 ; make it bytes SUB.L D4,D0 ; remove original strike size ADD.L D5,D0 ; add in new strike size ASR.L #1,D0 ; make back into words MOVE D0,fOWTLoc(A1) ; save low word in original location in bytes SWAP D0 MOVE D0,fNDescent(A1) ; save high word in new strike as well. MOVEQ #$1A,D0 ; size of header MOVE.L (A0),A0 ; pointer to original font ADD.L D4,A0 ; size of original strike ADD.L D0,A0 ; plus header to point to post-strike table ADD.L D5,A1 ; offset to end of new strike ADD.L D0,A1 ; donÕt forget header size SUB.L D0,D2 ; take out header from size of post-strike tables MOVE.L D2,D0 _BlockMove ; move tables after the strike ; put pixel size in stack record for MakeScaleTbl MOVEQ #1,D4 LSL D3,D4 ; turn 0 É 5 into 1 É 32 @@@@ MOVE D4,fPixMap+pixelSize(A6) ; set up bit depth PEA fPixMap(A6) ; pass pointer to colors, or 0 if none MOVE curTxMode(A6),-(SP) ; pass text mode _MakeScaleTbl ; For each pixel, translate and write out MOVE.L FOutFontHandle,A0 ; point to the source font BSR DerefResource ; get the data handle (and re-load it if it purged) MOVE fRowWords(A0),D2 ; nonscaled pixel width of font in words MULU fFRectHeight(A0),D2 ; get strike height, let that be rectangle bottom ASL.L #4,D2 ; convert words to bits ADD #$1A,A0 ; advance past header MOVE.L (A2),A1 ; point to the dest data ADD #$1A,A1 ; move past header in a font MOVEQ #1,D5 LSL D6,D5 ; translate into destination depth (1 É 32) @@@@ MOVEQ #0,D6 ; position to start of src scan MOVEQ #0,D3 ; position to start of dst IF (NOT forROM) THEN ; <2.7-4april89-CEL> BSR getIs32Bit ; 32-bit QuickDraw around? BNE.S @nxtPixel ; if so work with longs @nxtPixel2 BFEXTU (A0){D6:D4},D0 ; extract a source pixel MOVE 0(SP,D0*2),D0 ; translate it BFINS D0,(A1){D3:D5} ; and put to dst ADD.L D4,D6 ; bump to next src pixel ADD.L D5,D3 ; bump to next dst pixel SUBQ.L #1,D2 BHI.S @nxtPixel2 BRA.S @afterPixelLoop ENDIF @nxtPixel BFEXTU (A0){D6:D4},D0 ; extract a source pixel move.l 0(SP,D0*4),D0 ; translate it @@@@ BFINS D0,(A1){D3:D5} ; and put to dst ADD.L D4,D6 ; bump to next src pixel ADD.L D5,D3 ; bump to next dst pixel SUBQ.L #1,D2 BHI.S @nxtPixel IF (NOT forROM) THEN ; <2.7-4april89-CEL> @afterPixelLoop ENDIF MOVE.L A3,SP ; restore stack ; Almost made it. Now, install this brand new font in the synthetic strike cache and in low memory: ; if canÕt grow cache, just reuse old element AddToSynList MOVE.L SynListHandle,A0 _GetHandleSize MOVE.L D0,D1 DIVU #SyntheticStrikeTable.synEntry,D1 SUBQ #1,D1 ; make zero based MOVE.L (A0),A1 MOVEQ #-1,D2 ; for compare BRA.S @skipAdvance ; skip advance first time through @nextOne ADD #SyntheticStrikeTable.synEntry,A1 ; advance to next entry @skipAdvance MOVE.L (A1),A3 ; last entry CMP.L 4(A1),D2 ; check ID field BEQ.S @neverUsed ; if minus one, there is no handle TST.L (A3) ; purged? DBEQ D1,@nextOne ; either a purged one was found or ran out of list BEQ.S @entryPurged ; if a purged one, reuse it ; ran out of entries, so try to grow list MOVE D0,D3 ; save old size ADD #SyntheticStrikeTable.synEntry,D0 ;(never could grow over 64K?) _SetHandleSize BNE.S @entryPurged ; couldnÕt grow, so reuse one (practically never happen) MOVE.L (A0),A1 ADD D3,A1 ; figure where new entry is BRA.S @neverUsed ; fill in new entry @entryPurged MOVE.L (A1),A0 ; throw away old purged master pointer _DisposHandle @neverUsed MOVE.L A2,(A1)+ ; save the newly created font BSR DerefWidthTab ; get pointer to width table in A0 MOVE.L widthNFNT(A0),(A1)+ ; save the font ID, NFNT flag LEA foreBack(A6),A0 MOVEQ #rgbColor*2,D0 ; size of foreground, background colors _BlockMove ; move foreground, background ; new font should only be made purgable at next DifFont time ; this means FontMgr needs to know that it was a ÒsyntheticÓ font via font flag ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; putting the new strike in FOutFontHandle is enough to set it up SaveFont MOVE.L A2,FOutFontHandle BRA.S restoreRegs ; all done ; the call to SetHandleSize failed, so throw away the new handle giveUp _DisposHandle ; the call to HandToHand failed, but make the original font purgable giveUp1 MOVE.L FOutFontHandle,A0 MOVE D7,D0 _HSetState ; restore purgability of the strike (could be multibit) BSR DerefWidthTab ; pointer to width table. MOVE.L WidTabFont(A0),A0 ; corresponding font handle. MOVE.L A0,FOutFontHandle ; set the font handle to the original 1 bit guy restoreRegs AlreadyCached move.w (sp)+,CurMap ; <29> Restore current resource map MOVE.L (SP)+,A3 ; restore pointer to input frame ENDIF ; END ColorGrayNess NoColors MOVE.B FOutCurStyle,D1 ; get style byte LEA FOutBold,A0 ; point at style part of output record CLR.L (A0)+ ; set everything to 0 CLR.W (A0)+ ; clear some more CLR.B (A0)+ ; clear seven bytes total ; special case the most common case -- plain text (ie, style byte is 0) TST.B D1 ; plain? BEQ.S CheckWTable ; if so, skip the loop ; we must fill out the style record the hard way, by looping through the ; driver-supplied style definition table MOVEQ #0,D2 ; clear high part for indexing LEA FMStyleTab,A1 ; point to the style table MOVEQ #6,D0 ; consider 7 bits worth LEA FOutBold,A0 ; point to style params @fmStyloop MOVE.B (A1)+,D2 ; get index MOVE.B (A1)+,D3 ; get field increment MOVE.B (A1)+,D4 ; get extra increment LSR #1,D1 ; examine next style bit BCC.S @nextSBit ; if its off, don't bother ADD.B D3,0(A0,D2) ; increment proper style param ADD.B D4,FOutExtra ; also increment extra @nextSBit DBRA D0,@fmStyloop ; loop till done ; special case underlining since it doesn't fit into our model BTST #ULineBit,FOutCurStyle ; underlining on? BEQ.S CheckWTable ; if not, skip LEA FOutULOffset,A0 ; point to underline parameters MOVE.B (A1)+,(A0)+ ; copy the three underline parameters MOVE.B (A1)+,(A0)+ ; copy second byte MOVE.B (A1)+,(A0)+ ; copy third byte ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; Now the style is all set up so its time to make sure the width table is cool. First check to see if the ; widths were already cached, so we can skip the most time-consuming part of the work. CheckWTable ; These tests decide to use either the integral style extra provided by the Font Manager, or the ; fractional style extra in the FOND. MOVE.L LastFond,D0 ; check if there is a last FOND. BEQ MakeITab ; if not, style extra canÕt be fractional. TST.B FDevDisable ; set if the device would prefer the FOND style extra. BNE.S @skipDevice TST.B fmInDevice(A3) ; if the device is not the screen, it can supply itÕs BNE MakeITab ; own style widths, so skip looking at the FOND widths. @skipDevice BTST #5,saveFondFlags ; set if fractional style extra is never from FOND. BNE MakeITab BTST #4,saveFondFlags ; set if fractional style extra is always from FOND. BNE.S @computeFractExtra ; <06Nov85> TST.B FractEnable ; set if application allows fractional spacing BEQ.S MakeITab ; if not, donÕt figure fractional style extra from FOND. <06Nov85> @computeFractExtra ; ; We can only get this far if the FOND has valid style extra entries (part of the FOND flags)? ; Next, compute the fixed point extra into D6 when we do have a family definition record present. MOVE.L D0,A0 ; get the last fond. BSR DeRefResource ; load resource who's handle is in A0. ; But wait, maybe this FOND is an empty FOND created by Font/DA Mover. If so, the FONDLast field ; will contain a zero. TST FontFamilyRecord.FONDLast(A0) ; see if last character is zero. BEQ.S MakeITab ; if so, do not calculate style here. LEA FontFamilyRecord.FONDProperty(A0),A0 ; point to start of table MOVE.W (A0)+,D6 ; get plain extra EXT.L D6 ; If the FOND has a width table with a style already calculated in it, it is not necessary to figure out the ; style extra for the styles already contained in the widths. Earlier, in GotEntry, a style with the correct ; widths found was saved in a local. MOVE.B FOutCurStyle,D1 ; get style byte BEQ.S @gotFractExtra ; if plain, skip the loop BTST #6,saveFondFlags ; does this FOND have width tables at all? BNE.S @noStyleInWidths ; if set (like for Courier) there are no width tables in FOND MOVE.L WidthTabHandle,A1 MOVE.L (A1),A1 TST.B WidthIsSpline(A1) ; is it a spline font BNE.S @noStyleInWidths ; if so ignore width tables in fond and use fond property table. MOVE fwidStyle(A6),D0 ; get style of widths already found NOT D0 ; use as mask, AND D0,D1 ; to turn off any style attributes already in widths @noStyleInWidths ; we must fill out the style record the hard way, by looping through the ; driver-supplied style definition table MOVEQ #7,D0 ; consider 8 bits worth @exStyloop MOVE.W (A0)+,D2 ; get extra value LSR #1,D1 ; examine next style bit BCC.S @nextExBit ; if its off, don't bother ; >> here we can add Adobe fix to look for funny sign bit sort of negative number CMP #$8FFF,D2 ; is it -7.001 or smaller? BGT.S @doNormalAdd BCLR #15,D2 ; throw away sign bit NEG D2 ; make into a normal twoÕs complement number @doNormalAdd EXT.L D2 ADD.L D2,D6 ; add it in @nextExBit DBRA D0,@exStyloop ; loop till done @gotFractExtra ASL.L #4,D6 ; adjust 4.12 to 16.16 fixed point SUBQ #6,SP ; space for FixMul, FixRound results CLR.W -(SP) ; fraction part zero. BSR DerefWidthTab ; get pointer to width table in A0 MOVE.W WidthASize(A0),-(SP) ; get the actual size. MOVE.L D6,-(SP) ; compute floating extra times pointsize _FixMul MOVE.L (SP),D6 ; get fixed point answer _FixRound ; round in case fractions are disabled MOVE (SP)+,D0 ; pop the answer ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ TST.B FractEnable ; fractional widths? <06Nov85> BNE.S MakeWTab ; yes, then donÕt use the rounded result. MOVE.B D0,FOutExtra ; and save the byte-sized result MakeITab ; <06Nov85> MOVEQ #0,D6 ; clear out D6 MOVE.B FOutExtra,D6 ; get extra value EXT.W D6 ; sign extend it SWAP D6 ; make it fixed point MakeWTab ; the font changed so we have to make the table from scratch. First ; init the meta fields in the new table. BSR DerefWidthTab ; get a pointer to the width table in A0 CMP #-1,widthFID(A0) ; is it a new one? BNE AdjustSpace ; just take care of space extra LEA WidthSExtra(A0),A1 ; point just past widths CLR.L (A1)+ ; set lastSpExtra to 0 MOVE.L D6,(A1) ; set lastStyExtra to value ADD.W #WidthAFID-WidthStyle,A1 MOVE.W FONDID,(A1)+ MOVE.L LastFOND,(A1) TST.B WidthIsSpline(A0) ; Get flag stating if spline <2.7-4april89-CEL> BNE AdjustSpace ; Go to adjust space and fill width function is called ; there are two cases for building the width table, depending on whether ; the font comes with a fixed-point table or not. Point A1 at either ; the offset/width table or the fixed-point width table ; better load it if it purged MOVE.L FOutFontHandle,A0 ; get the current font handle, prepare for deref. later BSR DeRefResource ; load resource who's handle is in A0. ; D2 holds the flags word, D3 has firstChar and D4 has lastChar. Compute ; the size of the tables in D5. MOVEM.W (A0),D2-D4 ; get flags, first, last MOVE D4,D5 ; copy lastChar SUB.W D3,D5 ; compute lastChar-firstChar MOVE D5,D1 ; keep # in D1 ADDQ #3,D5 ; # of chars, including missing ADD.W D5,D5 ; compute size of table EXT.L D5 ; make it a longWord ; compute address of offset/width table into A1 MOVE.W fNDescent(A0),D0 ; possibly the high word of owTLoc SWAP D0 ; put it in the high word BPL.S @notNegative MOVEQ #0,D0 @notNegative MOVE.W fOWTLoc(A0),D0 ; get size till owTable ADD.L D0,D0 ; double for bytes LEA fOWTLoc(A0,D0.L),A1 ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; case out on the font format, pointing A1 at the right table and getting ; the width of the missing character in long format in D7 MOVEQ #0,D7 ; clear out D7 TST.B FractEnable ; use expanded widths? BEQ.S @noExWidth ; if not, skip BTST #1,D2 ; expanded width table present? BNE.S @gotExWidth ; if so, skip BTST #6,saveFondFlags ; set if FOND fractional widths are not (to be) used. BNE.S @noExWidth ; if not, compute integral values from the font. ; See if we have a family width table for this font. A4 contains an offset to it if there is one ; (set up by MapFont) or is NIL. MOVE.L A4,D0 ; got family width table? BEQ.S @noExWidth ; if not, skip ; handle case of figuring out missing character width for family width table MOVE.L LastFOND,A1 ; get famDef record MOVE.L (A1),A1 ; handle -> pointer ADD.L A4,A1 ; compute width tab ptr BSR DerefWidthTab ; get pointer to width table in A0 MOVE.W WidthASize(A0),D0 ; get size in D0 MOVE.W -4(A1,D5),D7 ; get fixed point width MULS D0,D7 ; scale it up ASL.L #4,D7 ; convert to 32 bits <28Jun AJH> BRA.S DoWTable ; back to common code ; this font doesn't have an expanded width table, so A1 is cool. Fetch ; the width of the missing character. @noExWidth MOVE.B -3(A1,D5),D7 ; get byte width SWAP D7 ; convert to fixed point BRA.S DoWTable ; go make the table ; the font does have an expanded width table, so adjust A1 and fetch the ; width of the missing character @gotExWidth ADD.L D5,A1 ; bump to expanded table MOVE.W -4(A1,D5),D7 ; get fixed point width ASL.L #8,D7 ; convert to 32 bits ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; build the width table DoWTable ; set up D5 with a boolean that specifies whether we have to call FixMul ; to do the scale-disable scaling CMP.L #$10000,FScaleHFact ; scale factor = 1 SNE D5 ; if = 1, make it 0 <10-30-85> AND.B FScaleDisable,D5 ; FScaleDisable must be on, too ; OK, start making the width table by filling in the missing characters ; for "minChar" characters MOVE.L D7,D0 ; <10-30-85> BSR.S AddD6ScaleD0 ; add extra to missing width, scale by FScaleHFactor. MOVE.L D0,D7 ; <10-30-85> BSR DerefWidthTab ; get pointer to width table in A0 BRA.S @minCharSkip ; WHILE, not REPEAT @minCharLoop MOVE.L D7,(A0)+ ; stuff in missing width @minCharSkip DBRA D3,@minCharLoop ; repeat till done ; now we case out to two separate loops for filling out the body of the ; width table, depending on if we have an expanded table. CLR.B UsedFWidths ; assume we don't use them TST.B FractEnable ; fraction widths enabled? BEQ CalcOldWLoop ; if not, skip BTST #1,D2 ; which format? (check for width table in font) BEQ.S CheckFracWidths ; if not expanded, see if there is a FOND. @gotXWid1 MOVEQ #0,D0 ; clear out D0 MOVE.W (A1)+,D3 ; get 8.8 character width CMP.W #-1,D3 ; is it missing? BNE.S @notMissing ; if not, go handle MOVE.L D7,D0 ; use missing width BRA.S @stuffWidth ; go stuff it @notMissing MOVE.W D3,D0 ; get width ASL.L #8,D0 ; make it 16.16 fixed-point BSR.S AddD6ScaleD0 ; add extra, and scale if enabled @stuffWidth ; MOVE.L D0,(A0)+ ; stuff it DBRA D1,@gotXWid1 ; loop for # of chars ST UsedFWidths ; we used them BRA.S FillTheRest ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; we might have a family width table -- if we do, use a different loop CheckFracWidths BTST #6,saveFondFlags ; set if no fractional family widths BNE.S CalcOldWLoop ; if set, compute integral values from the font. MOVE.L A4,D0 ; got a family one? BEQ.S CalcOldWLoop ; if not, must be old way. ; use family widths to figure sizes MOVE.L WidthTabHandle,A4 MOVE.L (A4),A4 MOVE.W WidthASize(A4),-(SP) ; get the actual size, keep on stack. MOVE.L D0,A4 ; restore index to family widths @fxWidLoop MOVEQ #0,D0 ; clear out D0 MOVE.W (A1)+,D3 ; get 4.12 1-point width CMP.W #-1,D3 ; is it missing? BNE.S @0 ; if not, go handle MOVE.L D7,D0 ; use missing width BRA.S @1 ; go stuff it @0 MOVE.W D3,D0 ; get width MULU (SP),D0 ; scale it up ASL.L #4,D0 ; adjust to 16.16 fixed point BSR.S AddD6ScaleD0 ; add extra, and scale if enabled @1 ; <10-30-85> MOVE.L D0,(A0)+ ; stuff it DBRA D1,@fxWidLoop ; loop for # of chars ADDQ #2,SP ; pop off point size ST UsedFWidths ; we used them BRA.S FillTheRest ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; common utility routine ; AddD6ScaleD0 adds in the style extra in D6, then multiplies the value in D0 by the ; FScaleDisable scale factor. AddD6ScaleD0 TST.L D0 ; is it zero? BEQ.S @0 ; if it has no width, do nothing ADD.L D6,D0 ; add in style extra first TST.B D5 ; need to scale it? BEQ.S @0 MOVEM.L A1/A0/D1,-(SP) ; save registers used by FixMul (D1, A0, A1) SUBQ #4,SP ; make room for result MOVE.L D0,-(SP) ; pass param D0 MOVE.L FScaleHFact,-(SP) _FixMul ; MOVEM.L (SP)+,D0-D1/A0-A1 ; function result (D0), restore registers (D1, A0, A1) @0 RTS ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ CalcOldWLoop ; its the old format, so walk down the o/w table, computing the fixed point ; widths and stuffing them into the table. MOVEQ #0,D0 ; clear out D0 MOVE.W (A1)+,D3 ; get offset/width CMP #-1,D3 ; is it missing? BNE.S @skipMiss ; if non-missing, skip MOVE.L D7,D0 ; use missing width BRA.S @stuffIt ; go stuff it @skipMiss MOVE.B D3,D0 ; get width SWAP D0 ; make it fixed-point BSR.S AddD6ScaleD0 ; nop if not scale disabled @stuffIt ; MOVE.L D0,(A0)+ ; stuff it DBRA D1,CalcOldWLoop ; loop for # of chars ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; OK, now fill out the end of the table with the missing character width FillTheRest MOVE #255,D0 SUB.W D4,D0 ; how many left? BRA.S @whileStart ; let DBRA decrement first @maxCharLoop MOVE.L D7,(A0)+ ; stuff the width @whileStart DBRA D0,@maxCharLoop ; repeat till done ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; Short cut space extra check at the beginning of SwapFont jumps to here. Also, cached widths case jumps ; here. AdjustSpace BSR DerefWidthTab ; get pointer to width table in A0 LEA widthSExtra(A0),A1 ; figure where space is ; Believe it or not, it is possible that QuickDraw is not around at all, so test first. MOVE.L (A1),D7 TST.B QDExist ; is QuickDraw around BMI.S @noQuickDraw MOVE.L grafGlobals(A5),A0 ; get grafGlobals MOVE.L thePort(A0),D0 ; get thePort BEQ.S @noQuickDraw MOVE.L D0,A0 MOVE.L spExtra(A0),D7 ; get current space extra IF (HAS_COLOR) THEN ; <2.7-4april89-CEL> MOVE txMode(A0),lastMode LEA fgColor(A0),A0 LEA lastFore,A2 MOVE.L (A0)+,(A2)+ ; saving the foreground/background colors for next time MOVE.L (A0),(A2) MOVE.L A1,-(SP) BSR GetPixelDepth MOVE.L (SP)+,A1 MOVE D0,lastDepth ENDIF ; END Color GrayNess @noQuickDraw CLR.L D4 ; Zero out D1 for splines spExtra MOVE.L D7,LastSpExtra ; and remember it for next time. SUB.L (A1),D7 ; subtract old with current BEQ.S @checkDevice ; if same, nothing to do ; D7 has the difference in the value of spaceExtra. The only problem is spaceExtra is given in screen ; coordinates but we must return stuff in font coordinate space. Thus we must scale spaceExtra before ; adding it in. FMInNumer.h FOutDenom.h ; width = ÑÑÑÑÑÑÑÑ * ÑÑÑÑÑÑÑÑ * spExtra ; FMInDenom.h FOutNumer.h ADD.L D7,(A1) ; remember new value SUB.W #12,SP ; make space on stack MOVE.W FMInNumer+2(A3),-(SP) ; push x input numer MOVE.W FMInDenom+2(A3),-(SP) ; push x input denom _FixRatio ; compute ratio SUBQ #4,SP ; make space for result MOVE.W FOutDenom+2,-(SP) ; push x output denom MOVE.W FOutNumer+2,-(SP) ; push x output numer _FixRatio ; compute ratio _FixMul ; calculate scale factor MOVE.L D7,-(SP) ; push space extra _FixMul ; scale it ; we have the adjustment factor on the stack, so add it into the table BSR DerefWidthTab ; get pointer to width table in A0 MOVE.L (SP)+,D0 ; get scaled delta ADD.L D0,4*' '(A0) ; adjust space width MOVE.L D0, D4 ; SAVE Space adjustment in D1 for spline space adjustment ; Now that we finally have everything the way we want it, let the current ; device have a crack at changing things if it wants to. @checkDevice MOVEQ #-1,D0 ; get lots of ones MOVE.B FMInDevice(A3),D0 ; get the device number BEQ.S @doneStyle ; if its the screen, we're done ; call the driver to give it a chance to change the output record LEA paramBlk(A6),A0 ; point A0 at OS block MOVE.W D0,IORefNum(A0) ; set up the refNum MOVE.W #FMgrCtl1,CSCode(A0) ; set up the control code MOVE.L A3,CSParam(A0) ; pass the input record as a parameter MOVE.W FMInDevice(A3),CSParam+4(A0) ; pass subclass, too _Control ; All done now so copy the input record into the current record for the next time. @doneStyle MOVE.L 8(A6),A3 ; point to original input record MOVE.L A3,A0 LEA CurFMInput,A1 ; point to current record MOVE.L (A0)+,(A1)+ ; copy first 4 bytes MOVE.L (A0)+,(A1)+ ; copy next 4 bytes MOVE.L (A0)+,(A1)+ ; copy next 4 bytes MOVE.L (A0)+,(A1)+ ; copy last 4 bytes BSR DerefWidthTab ; get pointer to width table in A0 CMP #-1,widthFID(A0) ; already filled out? (cache case) BNE.S @skipFill ; MOVE.B UsedFWidths,WidthUsedFam(A0) ; update UsedFam. MOVE.B FOutCurStyle,WidthAFace(A0) ; update Actual Face. LEA widthFID(A0),A1 ; point to request info (Font ID etc) in width. BSR FamSizeInD0 MOVE.L D0,(A1)+ ; update requested Font ID and Size. ADDQ #4,A3 MOVE.L (A3)+,(A1)+ ; update requested face and device. CLR.B -3(A1) ; but clear the needBits field MOVE.L (A3)+,(A1)+ ; update numer, denom MOVE.L (A3),(A1) ; of the scale factors. TST.B WidthIsSpline(A0) ; Test if spline BEQ.S @skipFill ; do not do spline things CLR.B WidthUsedFam(A0) ; Splines never used FOND widths. tst.b KeepSplineOnDisk(a0) ; should we load the spline? <14-jlf> bne.s @fontOkay ; no, skip the load. <14-jlf> move.w WidthStrikeID(a0),d0 ; push the sfnt resource id <14-jlf> jsr LoadSplineFontResource ; load the spline resource <14-jlf> bsr DerefWidthTab ; get widthpointer in a0 <14-jlf> exg d0,a0 ; swap splineHandle with widthTable <14-jlf> tst.l (a0) ; was spline loaded into memory? <14-jlf> exg d0,a0 ; restore register positions <14-jlf> seq KeepSplineOnDisk(a0) ; if not loaded, set flag for next time <14-jlf> ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; _sbFillWidthTab() ; <2.7-4april89-CEL> @fontOkay MOVEM.L A0-A1/D0-D2,-(SP) ; Save off all registers before JSR SUBQ #4,SP ; make room for result MOVE.L WidthTabHandle, -(SP) ; Push the WidthTable for updating SUBQ #2, SP ; Make room for fractEnable MOVE.B fractEnable, (SP) ; Get fractEnable flag _sbFillWidthTab ; Call the routine via SplineDispatch ADDQ #4, SP ; to late for errors <18-CEL> MOVEM.L (SP)+, A0-A1/D0-D2 ; Restore all registers on return BSR DerefWidthTab ; get pointer to width table in A0 ADD.L D4, 4*' '(A0) ; adjust space width @skipFill BSR DerefWidthTab ; get pointer to width table in A0 <8-CEL> CLR.L 4*13(A0) ; jam carriage return to zero <8-CEL> MOVEM.L (SP)+,D3-D7/A2-A4 ; restore work registers. MOVE saveMap(A6),D0 ; saved resource map or 0 BEQ.S @skipSave MOVE D0,curMap @skipSave UNLK A6 BRA CheckPurged ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; MapFont does all the hard work in FMSwapFont. Given a pointer to the ; font input record in A3, it normalizes the scale, finds the best set ; of bits it can and installs them into the output record. ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ MapFont SUB.L A4,A4 ; no family widths yet! MOVE.W fmInSize(A3),D5 ; get the size in D5 MOVE.W fmInFamily(A3),D3 ; get the family ; OK, now D3 has the family we want. Now scale the size based on the current ; DotsPerInch and numer/denom and build the resource ID of the font we want ; (even though we might not have it) CalcRealSize SUB #14,SP ; make space for function results MOVE.W FMDotsPerInch+2,-(SP) ; push horizontal dots/inch MOVE.W #80,-(SP) ; push nominal dots/inch _FixRatio ; turn into fixed point SUBQ #4,SP ; make some room MOVE.W fmInNumer+2(A3),-(SP) ; push horizontal numerator MOVE.W fmInDenom+2(A3),-(SP) ; push horizontal denominator _FixRatio ; make that a fixed point, too _FixMul ; multiply them together. CLR.W -(SP) ; fraction part is 0 MOVE.W D5,-(SP) ; push the size _FixMul ; scale the size. _FixRound ; round it off ; At this point the desired family is in D3 and the desired size is on the top of the stack. See if we have a ; family definition record for this family; if so, handle it the new way. Try to get a record of type ; into D0. Since this is sometimes speed critical, we implement a cache to skip the difficult ; resource search if we can. The FOND in the first element of the cache, WidthTabHandle, is always ; unpurgable. TryForFond CMP.W FondID,D3 ; same as last time BEQ.S @sameFDef ; if so, short-circuit MOVE.L LastFOND,A0 ; get old one (if zero, _HSetState will reject) MOVE.B FondState,D0 _HSetState ; restore purge state MOVE D3,D1 MOVE.W #MapTRUE,ROMMapInsert ; get from ROM if possible <10 Jul 85> BSR GetFOND ; use common utility below (GetFontName) BEQ.S @doneFDEFGet ; if no FOND, skip caching ; OK, we're changing the state of the cache so restore the purge state of ; the old one (if any), and make the new one unpurgable MOVE.L (A0),A1 ; get a byte of FOND flag word and save it in low mem. MOVE.B (A1),saveFondFlags ; bit 6 will be used to disable fractional junk. _HGetState MOVE.B D0,FondState ; save the old state _HNoPurge ; make it non-purgable @doneFDEFGet ; Check disk switch status here; better late than neverÉ CMP.B #-1,FontFlag BEQ Pop6SubFont ; if so, go start over. MOVE.W D3,FONDID ; moved these two lines from above MOVE.L A0,LastFOND ; so we will cache when no FOND. ; the cache worked, so fetch it from low memory @sameFDef MOVE.L LastFOND,D0 BNE NewFontLookUp ; if so, go look up size CMP #512,D3 ; if greater than 511, must have FOND BLO.S OldFontLookUp ; if in old range, use old method BRA Pop6SubFont ; if not, start up the great substitution engine ; utility subroutine to save code -- or in the size OrInSize AND #$FF80,D3 ; use high nine bits from that OR D0,D3 ; combine family and size BSR GetFontHandle ; got it? return to caller BVS Pop8SubFont ; go start over if disk switch hook came up. RTS ; after all that work, the desired size is on the top of the stack. Now we'll ; use it to build the resource ID of the desired font in D3 OldFontLookUp MOVE.W (SP)+,D0 ; get the desired size BNE.S @notZero ; this calculated if zero, should be made 1. MOVEQ #1,D0 @notZero AND #$007F,D0 ; use only low 7 bits ASL #7,D3 ; make room for size field OR D0,D3 ; add in the size bits MOVE D0,D7 ; save target size ; At this point, D3 has the resource ID of the font we want. See if its there. BSR GetFontHandle ; get the font, if we can BVS Pop4SubFont ; go start over if disk switch hook came up. BNE.S GotTheFont ; if we got it, stop searching ; we couldn't find the one we wanted so try for 2X and .5X for the general ; search. MOVE.W D3,D4 ; remember where we started MOVE D7,D0 ; get target size CMP #64,D0 ; is it > 64? BGE.S SkipDouble ; if so, forget about doubling ADD D0,D0 ; compute doubled size BSR.S OrInSize ; or in the size BNE.S GotTheFont ; if so, use it ; well, 2X didn't work so try .5X SkipDouble MOVE D7,D0 ; get target size LSR #1,D0 ; divide by 2 BCS.S SkipHalf ; if odd, we're out of luck BSR.S OrInSize ; or in the size BNE.S GotTheFont ; if so, go use it ; we couldn't find a 2X or 1/2X match so start scanning up. If that doesn't ; work, scan down. SkipHalf MOVE D4,D3 ; retreive starting place MOVEQ #1,D6 ; search up first TST.B FScaleDisable ; scaling disabled? BEQ.S scanFontLoop MOVEQ #-1,D6 ; search down then ScanFontLoop ADD D6,D3 ; bump to the next size AND #$007F,D3 ; only the low 7 bits are significant BEQ ScanDone ; if we reach zero, done direction MOVE D4,D0 ; get the original AND #$FF80,D0 ; mask off size OR D0,D3 ; build new one ; see if we have this one BSR GetFontHandle ; get the font handle if we can BVS Pop4SubFont ; go start over if disk switch hook came up. BEQ.S ScanFontLoop ; if we couldn't, loop again ; we found a font so install it and compute the appropriate numer/denom ; ; Numer' := Numer * requested size * DotsPerInch ; ----------------------------------------------- ; Denom' := Denom * actual size * 80 ; ; Font handle in A0, size in D3. GotTheFont MOVE.L A0,FOutFontHandle ; install the font handle MOVE.L WidthTabHandle, A1 MOVE.L (A1), A1 ; Width table ptr TST.B WidthIsSpline(A1) ; Get flag stating if spline BEQ.S @notSpline ; If spline skip height and size check SUBQ #4,SP ; make room for result MOVE fmInSize(A3),-(SP) ; push desired size MOVE D3,-(SP) ; push actual size AND #$7FFF,(SP) ; make sure it is not negative - 32,768 BRA.S @contScale @notSpline BSR BuildCharTable ; make the character (height) table SUBQ #4,SP ; make room for result MOVE fmInSize(A3),-(SP) ; push desired size MOVE D3,-(SP) ; push actual size AND #$007F,(SP) ; use only low 7 bits @contScale _FixRatio ; make it a fixed point number. MOVE.L (SP)+,D6 ; keep size scale in D6 BSR DerefWidthTab ; get pointer to width table in A0 MOVE.W D3,WidthASize(A0) ; save actual size in width table. MOVE.L FOutFontHandle,WidTabFont(A0) MOVEQ #0,D5 ; first do the vertical BSR.S MapScale ; calculate numer.v/denom.v MOVEQ #2,D5 ; now do the horizontal ; compute the new numer/demon as a fixed point number, then rationalize it ; and stick it where it belongs MapScale SUB #12,SP ; make some space for results *** was 12 *** MOVE.W fmInNumer(A3,D5),-(SP) ; push the numer MOVE.W fmInDenom(A3,D5),-(SP) ; push the denom _FixRatio ; compute the ratio. SUBQ #4,SP ; make room for result LEA FMDotsPerInch,A0 ; point to the dots/inch factor MOVE.W 0(A0,D5),-(SP) ; push the dots/inch MOVE.W #80,-(SP) ; the screen is 80 dots/inch _FixRatio ; make it a rational number. _FixMul ; multiply them together. MOVE.L D6,-(SP) ; push the size scale _FixMul ; multiply that in, too. LEA FOutNumer,A0 ; point to the place to stuff result MOVE.L (SP)+,D0 ; get the fixed point result ADD.L #$80,D0 ; *** round it up LSR.L #8,D0 ; take the middle 16 bits MOVE.W D0,0(A0,D5) ; store the numerator MOVE.W #256,4(A0,D5) ; the denom is 256 if forROM or HAS_COLOR then MOVE.L FPointOne,D1 ; set up FScaleHFact, FScaleVFact when disabled else move.l BWFPointOne,d1 ; <12> DTY endif TST.B FScaleDisable ; scaling disabled? BEQ.S GoScaleLess ; if not, skip MOVEQ #0,D1 ; zero top half of scale factor MOVE.W D0,D1 ; remember it MOVE #256,D0 ; start value for numerator @2 CMP #512,D1 ; scale up > 2 x BLO.S @4 ASL #1,D0 ; multiply numer by two ASR #1,D1 ; divide scale factor by two BRA.S @2 @4 CMP #192,D1 ; scale down < .75? BHS.S @6 ASR #1,D0 ; multiply by 1/2 ASL #1,D1 ; divide by 1/2 BRA.S @4 @6 CMP #256,D1 ; scale down between 1x and 2x BHS.S @doneScale MOVE D0,D2 ; * 3 ADD D0,D0 ADD D2,D0 ASR #2,D0 ; multiply by 3/4ths ASL #2,D1 ; divide by 3/4ths DIVU #3,D1 EXT.L D1 @doneScale MOVE.W D0,0(A0,D5) ; stuff numer ASL.L #8,D1 ; fixate scale factor ; scaling is disabled so calculate the width factor adjustment GoScaleLess TST D5 ; horizontal? BEQ.S @didVChange ; if not, skip MOVE.L D1,FScaleHFact ; save new scale factor BRA.S @scaleless ; compute vertical scaling factor too @didVChange MOVE.L D1,FScaleVFact ; record new V factor @scaleless MOVE.L WidthTabHandle,A1 MOVE.L (A1),A1 ; and remember it in the width table too. LEA WidthVOutput(A1),A1 MOVE.W D0,0(A1,D5) ASR.L #8,D1 ; shift scale factor back to a word. MOVE.W D1,WidthVFactor-WidthVOutput(A1,D5) RTS ; second time through, this ends MapFont ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; At this point, we've scanned all we can in one direction. If scaling is not allowed, then we started ; scanning down so now we must scan up; the opposite is true if scaling is allowed. If we have scanned ; in both directions, then start up the great font substitution machine. ScanDone TST.B FScaleDisable ; scaling disabled? BEQ.S @0 NEG D6 ; negate the direction BMI.S Pop4SubFont ; if negative now, we must substitute BRA.S @1 ; go on @0 NEG D6 ; negate the direction BPL.S Pop4SubFont ; if positive now, we must substitute @1 MOVE D4,D3 ; start with the target again BRA ScanFontLoop ; try our luck scanning down ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; A word or two about font substitution: ; ; FontFlag is set to the current substitution level. If we get to SubFont, then the font requested is not ; available, or the disk switch hook drew in the system font while loading the requested FOND, FONT or ; NFNT. The value in FontFlag indicates what just happened, and what should be substituted next: ; -2 = The LoadResource failed at CheckPurged, although the font is the same one returned the last ; time SwapFont was called. (Maybe the user filled up memory, purging a large font.) Try for ; the same font again, so that a family-related substitute will be returned. ; -1 = The code was re-entered by the SysError (either a real problem or the disk switch hook.) The ; requested FOND, NFNT, or FONT may have been loaded, but the cache & low memory is no good. ; Try for the same font again. ; 0 = The requested font is not available, nor any reasonable family-related substitute. Try the ; ApFontID, if it is in the same neighborhood. ; 2 = The ApFontID family is not available. Try the base of the neighborhood. ; 4 = The base of the neighborhood is not available (Geneva, for the Roman neighborhood). Try the ; SysFontFam if it is in the same neighborhood. ; 6 = The SysFontFam family is not available. Try Font 0, setting curMap to the system map. ; 8 = (Disk switch only.) Give Chicago 12 a shot (same as 6). ; we have to substitute; use either the application or system font. ; Substitution order is: ; if the apFontID is in the same neighborhood as the requested font, use it. ; if not, or not available, use the base of the neighborhood (Geneva if the neighborhood is Roman.) ; if not available, use the sysFontFam, but only if it is in the same neighborhood as the request. ; if not, or not available, use the ROM font (hard coded to family 0, Chicago.) Pop8SubFont ADDQ #2,SP ; entry for throwing 2 return addresses away Pop6SubFont ADDQ #2,SP ; entry for throwing away scaled size, return address Pop4SubFont ADDQ #4,SP ; throw away return address for next time through SubFont ; determine which to go to next MOVE (A3),D3 ; set up font family MOVEQ #0,D0 MOVE.B FontFlag,D0 BPL.S @noDiskSwitch _Debug BSR InvalWidthTab ; otherwise, toss first cache entry CLR.B FontFlag ; set up to 0 to start all over BRA.S @skipDispatch @noDiskSwitch ADDQ.B #2,FontFlag Check #12,D0 ; debugging aid MOVE SubJump(D0),D0 JSR SubJump(D0) @skipDispatch MOVE.L 8(A6),A1 ; get pointer to original input record MOVE D3,fmInFamily(A3) ; set up new substitute family MOVE fmInSize(A1),fmInSize(A3) ; copy size since may have to map to system font. BRA TryAgain SubJump DC.W tryApFontID-SubJump ; 0 DC.W tryNeighborhoodBase-SubJump ; 2 DC.W trySysFontFam-SubJump ; 4 DC.W tryChicago-SubJump ; 6 DC.W tryChicago-SubJump ; 8 ; Use apFontID if it is in the same neighborhood. tryApFontID MOVE ApFontID,D1 checkNeighborhood ; common entry point for system family as well. MOVEQ #9,D2 ; convenient constant LSR D2,D1 SUB #31,D1 BPL.S @apForiegn MOVEQ #0,D1 @apForiegn MOVE D3,D0 ; copy family LSR D2,D0 ; divide by 512 (unsigned) SUB #31,D0 ; first $4000 is Roman, rest are neighborhoods BPL.S @notRoman MOVEQ #0,D0 ; Roman is 0, first neighborhood 1, etc. @notRoman CMP D0,D1 ; is apFontID in the same neighborhood as D3? BNE.S Pop4SubFont ; if not, use next substitution method MOVE ApFontID,D3 RTS ; Use the base of the neighborhood. tryNeighborhoodBase CMP #$4000,D3 BLO.S @mustBeRoman ;; AND #$FE00,D3 ; base is neighborhood & ~512 subq #6,SP ; <73> 2 for Font2RealScript, 4 for GetScript move.w D3,-(SP) ; <73> push current font id _Font2RealScript ; <73> convert it to script code move.w #smScriptSysFond,-(SP) _GetScript ; <73> get system font id for the script move.l (SP)+,D3 ; <73> try the script system font RTS @mustBeRoman MOVEQ #3,D3 ; hard code to Geneva RTS ; Use the SysFontFam if it is in the same neighborhood. trySysFontFam MOVE SysFontFam,D1 BRA.S checkNeighborhood ; This entry point is called from the top of SwapFont if from within SysError we failed. GoTryChicago LINK A6,#stackFrame MOVEM.L D3-D7/A2-A4,-(SP) ; save work registers MOVE.L 8(A6),A3 ; get input pointer BSR.S tryChicago BRA MoreDifFont ; Use the ROM font. ; have to be very careful here that D3 is not later substituted tryChicago MOVE CurMap,saveMap(A6) ; save the current map MOVE SysMap,CurMap ; hard code to the system map MOVEQ #0,D3 ; hard code to Chicago RTS ; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; SetNewDevice is called when we notice that the device has changed. ; If the device is 0 (the screen), fill out the info ourselves, ; otherwise make a status call to the driver to get it. Called only in DifFont after noting that the device ; has changed. SetNewDevice TST D0 ; is it the screen? BEQ.S SetScreenDevice ; if so, no need to call the driver MOVEQ #-1,D0 ; get some ones MOVE.B fmInDevice(A3),D0 ; build the refNum MOVEQ #IOQElSize,D1 ; get size of pBlock SUB.L D1,SP ; make space for control record LEA IORefNum(SP),A0 ; point A0 at OS block MOVE.W D0,(A0)+ ; set up the refNum MOVE.W #FMgrCtl1,(A0)+ ; set up the control code LEA FMDotsPerInch,A1 ; get place to stash info MOVE.L A1,(A0)+ ; tell the driver about it MOVE.W fmInDevice(A3),(A0)+ ; pass subclass, too MOVE.L SP,A0 ; point A0 at pBlock _Status ; ask the driver ADD.L D1,SP ; pop off parameter block RTS ; Set up parameters for the screen SetScreenDevice LEA FMDotsPerInch,A1 ; get place to stash info LEA ScreenStyleTab,A0 ; point to the info MOVEQ #28,D0 ; 28 bytes of info to move _BlockMove ; move it in RTS ; ------------------------------------------------------------------------------------- ; ; Routine: splineHandle = LoadSplineFontResource( splineResourceID ) ; ; Input: d0.w spline font resource id ; ; Output: d0.l spline font handle ; ; Purpose: Load a spline resource. If the spline resource is greater than 128k ; we load an empty resource handle into the system heap. Otherwise, ; the entire resource is loaded into the current heap. The TrueType ; scaler uses the PartialFont mechanism for fonts that are not loaded ; into memory; loading a spline into memory is for Roman performance ; improvements. ; ; Warning: None ; ; Frame: None LoadSplineFontResourceFrame: Record {oldA6},decrement returnAddress: ds.l 1 oldA6: ds.l 1 resourceID: ds.w 1 resourceHandle: ds.l 1 frameSize: equ * EndR ; ------------------------------------------------------------------------------------- LoadSplineFontResource With LoadSplineFontResourceFrame link a6,#frameSize ; create local space movem.l d1-d2/a0-a1,-(sp) ; save registers move.w d0,resourceID(a6) ; save resourceID for later move.w ResLoad,-(sp) ; <15> Save current ResLoad move.w #0,-(sp) _SetResLoad ; <15> DonÕt load the spline move.w #MapFALSE,ROMMapInsert ; don't load sfnt into memory subq #4,sp ; reserve space for function result move.l #'sfnt',-(sp) ; push resource type move.w d0,-(sp) ; push the resource id _GetResource ; grab the resource handle move.l (sp)+,d0 ; <15> Set the condition code properly @foundSpline move.l d0,resourceHandle(a6) ; pop the spline handle beq.s @Exit ; bail if it was nil move.l d0,a0 ; grab the resource handle tst.l (a0) ; is the handle already loaded into memory? bne.s @Exit ; yes, return immediately ; at this point the empty resource handle is: ; ; 1) newly created empty handle in the current heap. ; 2) a purged sfnt <= 128K in the system or one of several application heaps ; 3) a purged sfnt > 128K in the system heap, which means that the KeepSplineOnDisk ; flag failed and this routine shouldn't have been called. subq #4,sp ; reserve space for function result move.l a0,-(sp) ; push the empty resource handle _SizeRsrc ; get the size of the resource move.l (sp)+,d0 ; pop the resource size cmp.l #128*1024,d0 ; is the spline size greater than 128k? bgt.s @LoadEmptySplineIntoSystemHeap ; yes, load an empty spline into the system heap move.l resourceHandle(a6),-(sp) ; push empty resource handle _LoadResource ; load the resource into memory bra.s @Exit ; return ; The spline font is bigger than 128K, so donÕt load it into memory, but create an empty ; handle for it in itÕs resource reference entry. We can probably get rid of the call to ; ReleaseResource and the zone mucking, since itÕs pretty unlikely for a font to be loaded ; in the application heap these days. For example, fonts from the system and the Fonts ; folder automatically load in the system heap. Fonts will go in the application heap ; if the application is carrying the font around. But at this point in the code, the ; 'sfnt' is larger than 128K, and itÕs unlikely that applications will be carrying around ; fonts of this size. But IÕm too chicken to get rid of these lines at this point in ; 7.1Õs schedule. @LoadEmptySplineIntoSystemHeap move.l resourceHandle(a6),-(sp) ; push resource handle _ReleaseResource ; get rid of empty spline from some application heap move.w #MapFALSE,ROMMapInsert ; don't load sfnt into memory move.l TheZone,-(sp) ; save the current zone move.l SysZone,TheZone ; make the system heap current subq #4,sp ; reserve space for function result move.l #'sfnt',-(sp) ; push resource type move.w resourceID(a6),-(sp) ; push the resource id _GetResource ; grab the resource handle move.l (sp)+,resourceHandle(a6) ; pop the spline handle move.l (sp)+,TheZone ; restore the saved heap zone @Exit _SetResLoad ; <15> Old ResLoad is still on the stack. Restore it before we leave. movem.l (sp)+,d1-d2/a0-a1 ; restore registers move.l resourceHandle(a6),d0 ; set function result unlk a6 ; destroy local space rts ; return to caller EndWith ; we found it, but better make sure we can load it ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; ; Four ways to get a font handle: ; ; GetStrike: returns handle to unloaded FONT to get resource attributes of ID passed in D1. ; GetFontHandle: returns handle to loaded FONT passed in D3. ; GoLoadStrike: returns handle to loaded FONT or NFNT inside FOND offset in A0. ; LoadNewStrike: returns handle to loaded FONT or NFNT passed in D0. ; ; All routines return the font handle in A0 and D0, with the Z-flag set to reflect if it is nil. ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ GoLoadStrike MOVE.L (A0),D0 ; get style/ID words from FOND MOVE.L D0,styleID(A6) ; remember for later LoadNewStrike MOVE.W #MapTRUE,ROMMapInsert ; ResLoad True for GetResource <10 july 85> LoadNoROM MOVE D0,-(SP) ; preserve ID BSR DerefWidthTab ; get pointer to widthtable TST.B WidthIsSpline(A0) ; Could not load Spline so it is not Spline BEQ.S @skipSpline ; not a spline ; d0 must contain the splinefont resource id. <14-jlf> jsr LoadSplineFontResource ; load the spline resource handle - but, not the data <14-jlf> tst.l d0 ; was there an error? <14-jlf> bz.s @loadFailed ; yes, load failed so bail and try other font <14-jlf> bsr DerefWidthTab ; get widthPointer in a0 <14-jlf> exg d0,a0 ; swap splineHandle with widthPointer <14-jlf> tst.l (a0) ; was the spline handle loaded into memory? <14-jlf> exg d0,a0 ; restore register positions <14-jlf> seq KeepSplineOnDisk(a0) ; if not loaded, set flag for next time <14-jlf> @SkipSplineLoad MOVEM.L A0-A1/D0-D2,-(SP) ; Save off all registers before JSR SUBQ #4,SP ; make room for result MOVE.L WidthTabHandle, -(SP) ; Push the WidthTable for updating MOVE.L D0, -(SP) ; Push the fontHandle MOVE.W #12, -(SP) ; Scan lines MOVE.W D3, -(SP) ; ppem _sbPreFlightFontMem ; Call the routine via SplineDispatch TST.L (SP)+ ; Check the errors MOVEM.L (SP)+, A0-A1/D0-D2 ; Restore all registers on return beq.s @splineOkay ; The TrueType font couldnÕt be loaded for some reason. Mark width table so that the ; spline will not be loaded next time, then go find a bitmap size to use. @loadFailed BSR DerefWidthTab ; get pointer to widthtable SF WidthIsSpline(A0) ; Could not load Spline so it is not Spline SF WidthLoadSpline(A0) ; Do not try to load spline next time <29> ADD #2,SP ; get rid of strike id BRA FindSize ; try for the size again <29> ; Use a bitmap font instead of a TrueType font. @skipSpline SUBQ #4,SP ; <14-jlf> MOVE.L #'NFNT',-(SP) ; push NFNT MOVE.W D0,-(SP) MOVE.W #MapTrue,RomMapInsert ; look in ROM first rb _GetResource MOVE.L (SP)+,D0 ; got it? bz.s fontOnlyLoad ; if not, look for FONT @splineOkay ; <2.7-4april89-CEL> BSR DerefWidthTab ; get pointer to width table in A0 MOVE #$8000,widthNFNT(A0) ; remember that we found a NFNT MOVE (SP)+,widthStrikeID(A0) TST.L D0 ; clear z flag ; <3.1-16May89-CEL> BRA.S weGotIt ; return z clear, handle in D0. ; we couldn't find the NFNT, so look for a FONT GetStrike MOVE.W #MapFALSE,ROMMapInsert ; don't load the font <10 July 85> MOVE D1,-(SP) ; pass font family BRA.S fontOnlyNoLoad ; use common code ; This is the entry point used by OldFontLookup to get a font resource that uses the ; old numbering scheme. D3 should have the font ID on entry. GetFontHandle MOVE D3,-(SP) ; Save the font ID ; Load the font, looking in ROM for the font resource as well. fontOnlyLoad MOVE.W #MapTRUE,ROMMapInsert ; get FONT from ROM if possible <10july 85> MOVEQ #0,D0 MOVE (SP),D0 ; Get font ID BSR DerefWidthTab ; get pointer to width table in A0 MOVE.L D0,widthNFNT(A0) ; remember that we tried to find a FONT ; Load the font, but donÕt look in ROM for the resource. fontOnlyNoLoad MOVE (SP)+,D0 ; recover ID SUBQ #4,SP ; make space for function result MOVE.L #'FONT',-(SP) ; 'FONT' is resType MOVE.W D0,-(SP) ; push ID _GetResource MOVE.L (SP)+,D0 ; sets Z flag bz.s @weDidntGetIt ; if missing, skip checking size ; But wait! What if we didnÕt get a font at all? @gotFONT MOVE.L D0,-(SP) ; protect handle from resource manager call SUBQ #4,SP ; make room for function result MOVE.L D0,-(SP) _MaxSizeRsrc ; <1July87> ; A font with a single character has a $1A header, at least a 1 word strike, 2 word loc table, 2 entry o/w table, thus: CMP.L #$24,(SP)+ ; is it smaller than the minimal size SLO D0 ; set D0 if it is too small to be useful MOVE.L (SP)+,A0 ; restore handle to font BRA.S setZBit @weDidntGetIt weGotIt MOVE.L D0,A0 ; return it in A0 SEQ D0 ; save Z flag setZBit AND #4,D0 ; set only Z bit CMP.B #-1,FontFlag ; was there a disk switch? BNE.S @noDskSwitch ; if not, leave V flag clear BSET #1,D0 ; set V bit @noDskSwitch MOVE D0,CCR ; return V set if switch, Z set if no resource RTS ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; FindSize is a utility that scans the font family data structure for the ; size that's passed in D3. It uses the famDef handle in A2. ; >> rather than implied return for GoLoadStrike, may need to check FontFlag for -1. ; ; Registers on Entry: ; A2 = Family Def Handle ; D3 = Requested Size ; ; Registers used: ; A1 = Width Table Ptr ; D0 = Keeps spot of spline ; D1 = Number of font entries ; D2 = last found size in FAT ; ; Registers returned: ; A0 = Font ID ; ; CLOBBERS: É ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ FindSize tst.l (a2) ; See if itÕs been purged first bne.s @noReload move.l a2,-(sp) _LoadResource ; The FOND has been purged. Reload it. @noReload MOVE.L (A2),A0 ; handle->pointer LEA FontFamilyRecord.FONDAssoc(A0),A0 ; bump past header MOVE.W (A0)+,D1 ; get the # of entries MOVE.L WidthTabHandle, A1 ; MOVE.L (A1), A1 ; Dereference WidthTable SF WidthIsSpline(A1) ; Mark WidthTab not spline MOVEQ #0, D0 ; Assume no spline font MOVEQ #0, D2 ; set size check to zero TST.B WidthLoadSpline(A1) ; should we load the spline??? <29> BEQ.S @fSizeLoop ; do not load spline <29> MOVE.L A0, -(SP) ; save A0 MOVE.L expandMem, A0 ; Get low mem expand TST.L ExpandMemRec.emSplineKey(A0) ; SplineKey is invalid? MOVE.L (SP)+, A0 ; restore A0 BEQ.S @fSizeLoop ; yes -> cannot use spline fonts TST.W (A0) ; First entry is spline font? BNE.S @fSizeLoop ; no -> do normal stuff ADDQ #2, A0 ; Increment A0 past zero size MOVE.L A0, D0 ; save off handle of sfnt TST.W D1 ; Any more fonts left? BLE.S @gotSpline ; no -> done so use spline BTST #splinePreferred,HiliteMode ; Test to see if we prefer splines BNE.S @gotSpline ; Try for spline BRA.S @contLoop ; Increment for next entry @fSizeLoop MOVE.W (A0)+, D2 ; FAT entry size CMP.W D2, D3 ; this the one? BEQ @getStrike ; if so, go load it (code above) BLT.S @trySpline ; if too big, too late @contLoop ADDQ #FAssocSiz-2,A0 ; bump to next entry DBRA D1,@fSizeLoop ; check them all out @trySpline TST D0 ; check if Spline was found BEQ @cantFind @gotSpline ; ; if Roman font, do as before ; movem.l a1/d0-d2,-(sp) ; Save everything clr.w -(sp) _FontScript ; check if it's Kanji move.w (sp)+,d0 ; get result into D0 beq.s @GoNonAsian ; moved a 0, means we are Roman font so GoNonAsian cmp.w #smJapanese,d0 ; Japanese? beq.s @CheckSplinePreferred ; yes, now check if spline preferred cmp.w #smTradChinese,d0 ; not Japanese, how about traditional Chinese beq.s @CheckSplinePreferred ; yes, check spline preferred cmp.w #smKorean,d0 ; is it Korean beq.s @CheckSplinePreferred ; <48> yes so check spline preferred cmp.w #smSimpChinese,d0 ; Is it Simplified Chinese beq.s @CheckSplinePreferred ; last time, go check spline preferred @GoNonAsian movem.l (sp)+, a1/d0-d2 ; Restore it all bra.s @DoRomanLogic ; ; Use spline if spline preferred is true ; @CheckSplinePreferred movem.l (sp)+, a1/d0-d2 ; Restore it all MOVE.L (A2),A0 ; <73> handle->pointer LEA FontFamilyRecord.FONDAssoc(A0),A0 ; <73> bump past header tst.w (A0) ; <73> only sfnt is installed? beq.s @DoRomanLogic ; <73> then use it. btst.b #splinePreferred,HiliteMode ; bit flag set in HiliteMode? bne.s @DoRomanLogic ; yes, force spline ; ; check if point size is big enough to use a spline for this font. ; if so, fall through and use spline. ; if not, do checkMore which uses bitmap ; move.l d0,a0 ; get ptr to style/ID word from FOND movem.l d0-d2,-(sp) ; Save relevent stuff move.w #MapFALSE,ROMMapInsert ; don't load sfnt into memory subq #6,sp ; reserve space for function result ... move.l #'sfnt',-(sp) ; ... for GetResource and fs_LowestPPEM move.w 2(a0),-(sp) ; push the resource id _GetResource ; grab the resource handle ; ; leave resource handle on stack and space for result already allocated on stack ; _fsLowestPPEM ; LOOKOUT: MOVES MEMORY! cmp.w (sp)+, d5 ; is desired size bigger than minimum movem.l (sp)+, d0-d2 ; Restore relevent stuff move.l WidthTabHandle, A1 ; move.l (A1), A1 ; Dereference WidthTable again since memory moved blt.s @checkMore ; size is smaller than minimum spline size, branch @DoRomanLogic ST WidthIsSpline(A1) ; Mark width table spline MOVE.L D0, A0 ; increment to get id MOVE.L (A0),D0 ; get style/ID words from FOND MOVE.B Widthface(A1), WidthAFace(A1) ; Act as if plain and get requested style BRA.S @getStrike ; Get the sfnt strike @cantFind TST.W D2 ; greater size than zero??? BNE.S @checkMore ; check for more bitmap sizes ORI #2, CCR ; set V for no resource match in FOND RTS @checkMore MOVEQ #0,D0 ; z-flag set, return NIL RTS @getStrike BRA GoLoadStrike ; Get the sfnt strike ; ; Candidate cache offsets ; sizeInFOND equ 0 ; Point size described by this entry entryStyles equ 2 ; Styles described by this entry FONDHandle equ 4 ; 'FOND' handle containing this size and style FONDMap equ 8 ; Resource map 'FOND' came from kFONDListSize equ 12 ; Candidate cache entry size ;_________________________________________________________________________________________ ; ; GetFONDForSizeAndStyle searches the candidate list passed in A3 for a FOND ; with the requested size and style. If the correct size and style is found, ; return a handle to the FOND in A0, and CurMap is set up to get the font out ; of the right resource file. The low word of D3 contains the desired size, ; and the high word contains the desired style on entry. ; ; GetFONDForSizeAndStyle returns a TrueType font if one is available if the requested ; size (and style) isnÕt available. It returns the plain style of the requested size ; if the desired style isnÕt available. ; ; Register Input: ; A3 -> Handle to candidate list ; D3 -> Requested Style/Requested size ; ; Register Output: ; A0 <- Best 'FOND' handle for requested size and style. ; D0 <- Non zero if candidate was found was found. ; Zero if candidate was not found. ; ; Internal register usage: ; A1 - Pointer to cache entry to use ; A4 - Current cache entry ; D2 - Size/Style comparisons ; D4 - Pointer to cache entry for styled spline ; D5 - Pointer to cache entry for styled bitmap ; D6 - Pointer to cache entry for plain bitmap ; D7 - Pointer to cache entry for plain spline ; GetFONDForSizeAndStyle movem.l d2-d7/a4,-(sp) move.l (a3),a4 ; Get pointer to candidate list addq #2,a4 ; Bump past FOND ID move.w (a4)+,d1 ; get the # of entries in candidate list bmi @sizeAndStyleNotFound ; <61> DonÕt do anything if this is an empty candidate list. moveq #0,d2 ; Initialize size moveq #0,d4 ; Assume no styled spline font moveq #0,d5 ; Assume no styled bitmap moveq #0,d6 ; Assume no plain style, either moveq #0,d7 ; Assume no plain spline. ; For each entry in the FOND candidate list, make sure that the resource map that each ; FOND comes from is presently in the resource chain. If itÕs not, skip the entry, and ; try another one. @fSizeLoop move.l d1,-(sp) ; Need to save D1 around _GetMap subq #4,sp move.l FONDMap(a4),a1 move.l (a1),a1 move.w mRefNum(a1),-(sp) ; Make sure the map that this FOND came from is in the resource chain _GetMap ; Get the map handle from the reference number tst.l (sp)+ ; If nil is returned, the map is not in the chain bnz.s @FONDMapInChain move.l (sp)+,d1 ; Restore D1 add.w #kFONDListSize,a4 ; The map isnÕt in the chain. Try the next candidate dbra d1,@fSizeLoop bra @CheckAlternates ; No more candidates. See if we can use something else instead. ; The resource map containing this 'FOND' is in the resource chain. Look at the font ; association table in this 'FOND' to see if it contains references to the desired ; size and style. @FONDMapInChain move.l (sp)+,d1 ; Restore D1 move.w (a4)+,d2 ; Get a size bnz.s @notSpline ; This entry is not a TrueType font. ; We got a TrueType entry. Rememeber it in case a bitmap for the desired size canÕt be ; located. swap d3 move.w d3,d2 ; Get the style we want swap d3 move.w (a4)+,d0 ; Get the styles this 'FOND' describes andi.w #$0F,d0 ; Mask off color bits bnz.s @styledSplineEntry ; ItÕs not plain tst.l d7 ; <58> See if weÕve already remembered a plain TrueType font bnz.s @gotPlainSpline ; <58> WeÕve already got one, so donÕt remember this new one move.l a4,d7 ; ItÕs plain. Remember this cache entry in case the right bitmap size isnÕt found. @gotPlainSpline tst.w d2 ; Did we want plain? bne.s @keepLooking ; Nope. Keep looking bra.s @checkSplinePreferred ; Yes. See if itÕs ok to return a TrueType font. @styledSplineEntry cmp.w d2,d0 ; <71> See if style is exactly the same bne.s @testForStyle ; <71> No. See if this candidate has the style we want move.l a4,d4 ; <71> This 'FOND' has the style we want bra.s @gotStyledSpline ; <71> @testForStyle and.w d2,d0 ; See if this 'FOND' describes the desired style bnz.s @savePotentialStyleMatch ; It does indeed. Prepare to load it in. move.l d3,d0 ; <63> This 'FOND' doesnÕt have the desired style. swap d0 ; <63> Check the desired style to see if weÕre trying to get plain tst.w d0 ; <63> If weÕre not looking for plain, try the next candidate. Otherwise, bnz.s @keepLooking ; <63> QuickDraw wants to use this style as plain, so remember it. @savePotentialStyleMatch tst.l d4 ; <58> See if we already have an alternate style bnz.s @gotStyledSpline ; <58> <68> WeÕve got an alternate style already move.l a4,d4 ; This 'FOND' has the style we want. See if we can return the TrueType font. @gotStyledSpline tst.w d0 ; <67> This code is used for getting a styled font. If QuickDraw really bz.s @keepLooking ; <67> wanted a plain font, keep looking for plain. ; If splinePreferred is set, leave early if we got the right style. @checkSplinePreferred btst #splinePreferred,HiliteMode ; If this bit is set, it means use a TrueType font whenever possible. bz.s @keepLooking ; ItÕs not set. Keep looking for a bitmap of the right size. ; We want to use the TrueType font. Determine whether to return the plain or the style tst.w d2 ; D2 still the desired style bnz.s @passBackStyledSpline ; Return the styled variation move.l d7,a1 ; Pass the pointer to the plain cache entry to our exit code. bra @setupForLoad ; Go to the code which sets up the resource chain to load in the font. @passBackStyledSpline move.l d4,a1 ; Pass the pointer to the styled cache entry bra @setupForLoad ; Go set up for loading the font. ; This entry in the cache is for a bitmap size. See if it matches the desired size. @notSpline cmp.w d2,d3 ; Correct size? bne.s @sizeDoesntMatch ; No. Try the next entry. swap d3 move.w d3,d2 ; Get the desired style swap d3 move.w (a4)+,d0 ; The size is right. Check the style. bnz.s @styledBitMapEntry tst.l d6 ; <58> See if weÕve got an alternate plain bitmap bnz.s @gotPlainBitmap ; <58> If we do, donÕt save this new one. move.l a4,d6 ; Remember this cache entry as the plain base in case the desired style isnÕt found. @gotPlainBitmap tst.w d2 ; Did we want plain? bne.s @keepLooking ; Nope. Keep looking bra.s @checkIfBitMapIsGoodEnough ; This entry has a style. See if itÕs the style we want. @styledBitMapEntry and.w d2,d0 ; See if this FOND can deal with the style we want bnz.s @gotDesiredStyledBitMap ; It does indeed. Prepare to load it in. move.l d3,d0 ; <63> This 'FOND' doesnÕt have the desired style. swap d0 ; <63> Check the desired style to see if weÕre trying to get plain tst.w d0 ; <63> If weÕre not looking for plain, try the next candidate. Otherwise, bnz.s @keepLooking ; <63> QuickDraw wants to use this style as plain, so remember it. @gotDesiredStyledBitMap tst.l d5 ; <58> See if we already have a styled bitmap bnz.s @gotStyledBitMap ; <58> <68> If we do, donÕt remember the new one. move.l a4,d5 ; It has the right style. Remember this cache entry @gotStyledBitMap tst.w d0 ; <67> This code is used for getting a styled font. If QuickDraw really bz.s @keepLooking ; <67> wanted a plain font, keep looking for plain. ; A bitmap of the right size and style was found. However, if splinePreferred is set, keep ; looking for a TrueType font. @checkIfBitMapIsGoodEnough btst #splinePreferred,HiliteMode ; See if TrueType fonts are preferred. bnz.s @keepLooking ; Yes. Continue with the search. ; Using the bitmap font is ok. Determine which font to return (styled or plain) tst.w d2 ; Check the desired style bnz.s @passBackStyledBitMap ; Return styled variation move.l d6,a1 ; Otherwise, we can return this 'FOND'. bra.s @setupForLoad @passBackStyledBitMap move.l d5,a1 ; Pass pointer to styled cache entry bra.s @setupForLoad ; At this point, either the size, style, or font type doesnÕt match with what we want. ; Try the next entry. @sizeDoesntMatch addq #2,a4 ; Skip over the style @keepLooking add.w #kFONDListSize-4,a4 ; bump to next entry dbra d1,@fSizeLoop ; check them all out ; ; The entire FOND list was checked without finding a real match. See if anything else ; was picked up that can be used instead. ; @CheckAlternates btst #splinePreferred,HiliteMode ; <71> See if TrueType fonts are preferred bz.s @useBitMapAlternates ; <71> No. Get a bitmapped font tst.l d4 ; <71> See if we have styled spline candidate bnz.s @tryForSpline ; <71> We do. Use it. tst.l d7 ; <71> See if we have plain spline candidate bnz.s @tryForSpline ; <71> We do. Use it. @useBitMapAlternates tst.l d6 ; See if plain variation was found bz.s @tryForStyledAlternate ; <67> If there is a plain, return it. move.l d6,a1 ; The plain variant was found bra.s @setupForLoad ; Rejoin the rest of the code @tryForStyledAlternate tst.l d5 ; <67> There was no plain, see if we have a style alternate bz.s @tryForSpline ; <67> No styled bit map either. See if we have a spline. move.l d5,a1 ; <67> WeÕve got a style alternate. Return that. bra.s @setupForLoad ; <67> Return the styled bitmap. ; The plain bitmap wasnÕt found (either). See if a TrueType font was picked up along ; the way. @tryForSpline move.l d3,d0 ; Get desired style/size swap d0 ; Get desired style in low word tst.w d0 ; Plain or styled? bz.s @tryForPlainSpline ; A plain font was desired @tryForStyledSpline tst.l d4 ; See if a styled spline was picked up. bz.s @tryForPlainSpline ; <71> It wasnÕt. Try plain. move.l d4,a1 ; <71> Use styled spline bra.s @setupForLoad ; <71> @tryForPlainSpline tst.l d7 ; See if a plain TrueType font was picked up. bnz.s @passBackPlainSpline ; WeÕve got a TrueType version. Go use it. ; A plain spline couldnÕt be found. Before we go back to try subsituting, go back and ; look for a styled spline if QuickDraw was asking for a plain font, in case the font ; is styled. move.l d3,d0 ; <63> swap d0 ; <63> tst.w d0 ; <63> Check the style that QuickDraw wanted bnz.s @sizeAndStyleNotFound ; <64> If QuickDraw wanted a style, we didnÕt find it, so go subsitute ; QuickDraw was asking for a plain font. Before we go look at the a styled alternate, change ; the requested style to be non-plain so we donÕt infinite loop if there is no styled alternate ; either. swap d3 ; <64> move.w #1,d3 ; <64> Pretend weÕre looking for a style so we donÕt inifinite loop swap d3 ; <64> bra.s @tryForStyledSpline ; <64> Go see if a styled spline was picked up along the way @passBackPlainSpline move.l d7,a1 ; Point to the plain cache entry ; WeÕve got a pointer to the cache entry for the best match we could find in A1. ; Set up the resource chain for the load from this 'FOND'. @setupForLoad movem.l (sp)+,d2-d7/a4 move.l LastFOND,a0 ; <59> move.b FONDState,d0 ; <59> Restore the handle state of the previously cached FOND _HSetState ; <59> move.l (a1)+,a0 ; Get FOND handle from list move.l a0,LastFOND ; <27> Keep the two handles synchronized. _HGetState ; <59> Get the current state of the 'FOND' handle move.b d0,FONDState ; <59> Save the state of the handle _HNoPurge ; <59> DonÕt let it get purged while weÕre using it. move.l (a1),a1 ; Get handle to resource map that contains this FOND move.l (a1),a1 move.w 20(a1),d0 ; Remember this resource mapÕs refNum. move.l ExpandMem,a1 move.l ExpandMemRec.emSplineKey(a1),a1 move.l (a1),a1 move.w d0,splineKeyRec.lastFontMap(a1) ; Save map this font was fetched from move.w d0,CurMap ; Set up the map to fetch from move.l a0,d0 ; Move the 'FOND' into D0 to set up condition code rts ; ; If we got here, we couldnÕt find a good enough match for the desired size and style. ; Set the condition codes to go back and try scaling another size. ; @sizeAndStyleNotFound movem.l (sp)+,d2-d7/a4 ; <24> Restore these buggers. moveq #0,d0 ; Tell NewFontLookup to try scaling. rts ;_________________________________________________________________________________________ ; ; A new FOND list has been created. Cache it. Always move the second cache entry into ; the first one, and store the new FOND list in the second cache entry. A2 contains the ; handle to cache on entry. ; CacheFONDList movem.l a0-a1/d0,-(sp) move.L expandMem, a1 ; Get low mem expand move.l ExpandMemRec.emSplineKey(a1),d0 ; Get TrueType globals beq.s @noSplineRec ; Get out if no globals move.l d0,a1 move.l (a1),a1 lea splineKeyRec.fondCache(a1),a1 ; Get address of cached FOND list move.l (a1),d0 beq.s @noHandleInCache move.l d0,a0 _DisposeHandle ; Get rid of the first list @noHandleInCache move.l 4(a1),(a1)+ ; Move second entry up move.l a2,(a1) ; Store the new list @noSplineRec movem.l (sp)+,a0-a1/d0 rts ;_________________________________________________________________________________________ ; ; Look for a FOND list from the cache in SplineKey. Returns a handle in A2 if a list is ; found. D7 holds the FOND ID on entry. ; TryForListFromCache move.L expandMem, A0 ; Get low mem expand move.l ExpandMemRec.emSplineKey(A0),d0 ; Get TrueType globals beq.s @noSplineRecord ; Oops! No cache! move.l d0,a0 move.l (a0),a0 lea splineKeyRec.fondCache(a0),a0 ; Get address of cached FOND list moveq #1,d1 @checkCache move.l (a0)+,d0 ; See if thereÕs a FOND list beq.s @checkNextCacheEntry ; If not, try the other one move.l d0,a2 move.l (a2),a2 cmp.w (a2),d7 ; Right FOND? beq.s @foundListInFOND ; Yep. moveq #0,d0 ; Clear out D0 in case we fall through. @checkNextCacheEntry dbra d1,@checkCache @foundListInFOND move.l d0,a2 tst.l d0 @noSplineRecord rts ;_________________________________________________________________________________________ ; ; Search the font chain for all FOND resource with the correct family ID. Build a list of ; sizes and styles referenced by each family record. ; GetCandidateFONDs FindFONDFrame Record {A6Link},Decr sizeList ds.l 1 paramBegin equ * fontNum ds.w 1 useApplFont ds.w 1 paramSize equ paramBegin - * retAddr ds.l 1 A6Link ds.l 1 oldCurMap ds.w 1 localSize equ * EndR With FindFONDFrame link a6,#localSize movem.l a2-a4/d1/d5-d7,-(sp) move.w fontNum(a6),d7 ; Get FOND ID cmpi.w #applFont,d7 ; <56> Did applFont get passed in for some reason? bne.s @notApplicationFont ; <56> No move.w ApFontID,d7 ; <56> If so, subsitute in real font ID for application font. @notApplicationFont move.w CurMap,oldCurMap(a6) ; Everybody remember where we parked! move.l TopMapHndl,a3 ; <37> Start searching from the top resource map move.l (a3),a0 ; <37> move.w mRefNum(a0),CurMap ; <37> <41> Start looking for fonts from the top bsr.s TryForListFromCache ; Try to get a FOND list from the cache bne @exitFindFONDS ; If got something from the cache, get out. ; ; First do a quick check to see if the requested font is available. If not, use the ; application font. ; subq #4,sp move.l #'FOND',-(sp) ; Look for a font family record move.w d7,-(sp) ; Font family move.w #MapTrue,ROMMapInsert ; Look in ROM, too. _GetResource ; Try to get it. move.l (sp)+,d0 bne.s @fontFamilyAvailable ; Go on if this font family exists. tst.w useApplFont(a6) ; Use application font if fontNum doesnÕt exist? bne.s @useApplicationFont ; Yep. Assume that application font is always available. moveq #0,a2 ; Return nothing bra @exitFindFONDs @useApplicationFont move.w ApFontID,d7 ; If not, use the application font. @fontFamilyAvailable moveq #4,d0 _NewHandle ,Sys,Clear move.l a0,a2 ; Handle for size list bsr CacheFONDList ; Place the handle in the cache. move.l (a0),a0 move.w d7,(a0) move.w #-1,2(a0) ; Start at -1, so entry count will be zero based ; ; Find all 'FOND' resources of ID fontNum, and build a list of font sizes these resources contain ; @findFONDLoop subq #4,sp move.l #'FOND',-(sp) move.w d7,-(sp) ; Low word of D7 has font family number move.w #MapTrue,ROMMapInsert ; Search the ROM for FONDs too. _GetResource move.l (sp)+,d0 ; See if we got anything beq @exitFindFONDs ; If not, get out. ; ; Figure out which resource map this resource came from. ; move.l d0,a4 subq #2,sp move.l a4,-(sp) _HomeResFile ; See where the resource came from move.w (sp)+,d0 ; Get the file reference number cmpi.w #0,d0 ; Special case for System file bne.s @findMapLoop moveq #2,d0 @findMapLoop move.l a3,a0 ; Remember this map. move.l a3,d5 ; Keep another copy for putting in our little table move.l (a0),a0 move.l 16(a0),a3 ; Save next map cmp.w 20(a0),d0 ; Is it the the right map? beq.s @parseFOND ; <54> WeÕve found the right map. Now check out the font assocation table entries. move.l a3,d1 ; <54> See if weÕve hit the bottom of the chain without finding the map the font came from bz.s @exitFindFONDs ; <54> If this is the case, just exit. bra.s @findMapLoop ; <55> Loop back to find the right map. ; ; Parse the FOND for the sizes it contains ; @parseFOND move.l (a4),a1 lea FontFamilyRecord.FONDAssoc(a1),a1 ; Get FOND association table move.w (a1)+,d6 ; Get number of entries bmi.s @exitFindFONDs ; <61> If the entry count is less than 0, bail @addEntryLoop move.l a2,a0 _GetHandleSize move.l d0,d1 ; Save a copy of the size add.w #kFONDListSize,d0 _SetHandleSize ; Increase list size by another entry bne.s @exitFindFONDS ; Bail out if the list couldnÕt be expanded move.l (a0),a0 add.w #1,2(a0) ; Increment the count of entries in list add.l d1,a0 ; Add entry to the end move.w (a1),d0 ; Size to look for styles of move.w d0,(a0)+ ; Remember this font size ; ; Given a font size, and a handle to a FOND resource, determine all the styles that ; this FOND describes for this size, and form a bitmap of these styles. The bitmap ; is a merger of all the style codes for this font size in the FOND. ; ; <49> Normally, the font association table in a 'FOND' resource is structured such that ; for a given point size, the entry for the plain font comes before the entries for any ; stylistic variations. The following code saves information about the fonts in the ; font family, keeping a record of the plain font, and a record for all the styles. It ; assumes that the font assocation table followed the normal ordering. Of course, weÕre ; talking about Macintosh developers here, who are a breed apart and thereÕs always ONE ; person that doesnÕt follow the standard. Add a check so that if one of these screwy ; 'FOND's is encountered, the record for the styles is split across the record for the ; plain entry. What IÕm saying is that the cache entries used to look like: ; [Info for plain][Info for styles]. For a screwy 'FOND', it will look like: ; [Info for styles][Info for plain][Info for more styles]. ; moveq #0,d1 ; Assume only plain style first tst.b 3(a1) ; Keep the plain font separate since there are no bits to signify plain bne.s @getStylesLoop addq #FAssocSiz,a1 ; Point to next entry bra.s @putStyleInfoInList @getStylesLoop cmp.w (a1),d0 ; Is the the right size? blt.s @gotAllStyles ; If the size in the association table is larger than what we want, weÕre done tst.b 3(a1) ; <49> Check in case we have a FOND that doesnÕt have the plain style first bz.s @gotAllStyles ; <49> If this entry is plain, save off the styles we have so far, and start a new entry for the plain style or.b 3(a1),d1 ; Merge in the styles in this entry @tryNextEntry addq #FAssocSiz,a1 ; Try next entry dbra d6,@getStylesLoop ; Or until there are no more entries @gotAllStyles addq #1,d6 ; Add one so we can fall through properly at the dbra @putStyleInfoInList move.w d1,(a0)+ ; Remember which styles this FOND contains move.l a4,(a0)+ ; And this FOND resource move.l d5,(a0)+ ; And which resource map it was in dbra d6,@addEntryLoop ; ; ; All the sizes have been sucked out of this FOND. Set up the font chain to point ; to the file below the one that this FOND was found in, and try from there. At this ; point, A3 still contains a handle to that next resource map. ; @gotSizeForLastFont move.l a3,d0 ; Check to see if weÕre at bottom beq.s @exitFindFONDs ; If so, get out of here. move.l a3,a0 move.l (a0),a0 move.w 20(a0),CurMap ; And set the file reference number bra @findFONDLoop ; Try with this map @exitFindFONDS move.w oldCurMap(a6),CurMap move.l a2,sizeList(a6) ; Return handle to caller movem.l (sp)+,a2-a4/d1/d5-d7 unlk a6 move.l (sp)+,a0 addq #paramSize,sp ; Pop parameters jmp (a0) ; Return to caller EndWith ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; NewFontLookUp is passed the family definition record in D0 and the ; desired size on the top of the stack. It decides on the best strike ; to use, then uses common code to finish up. ; ; Upon entry, the desired font size is on the top of the stack, and ; the desired font family ID is in D3. ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ NewFontLookUp move.w (sp)+,d5 ; get desired size swap d3 clr.w d3 move.b fmInFace(a3),d3 ; and style we want swap d3 ; Keep style in high word move.l d0,a2 ; Get family record move.w CurMap,-(sp) ; <28> Switch the order of A3 and CurMap on move.l a3,-(sp) ; <28> the stack so A3 can be restored first. subq #4,sp move.w d3,-(sp) ; Pass in the family ID move.w #1,-(sp) ; Use application font if desired font cannot be found. bsr GetCandidateFONDs ; Search font chain for all FONDs of this ID. move.l (sp)+,a3 ; List of sizes ; first go for an exact match move.w D5,D3 bsr GetFONDForSizeAndStyle ; Find the resource handle of the FOND with the right size bz.s @tryScaling move.l a0,a2 ; Then call the old FindSize to load it bsr FindSize bvs NewFailedRestore ; <36> CouldnÕt find one. Restore the resource chain and leave. beq.s @tryScaling ; <36> bra.s FoundTheSize ; Now deal with styles ; if FScaleDisable is on, don't bother to look for 2X and .5X first @tryScaling TST.B FScaleDisable BNE.S FindClosest ; now try for the one that's twice the size ADD.W D3,D3 bsr GetFONDForSizeAndStyle ; Find the resource handle of the FOND with the right size beq.s @tryHalfSize move.l a0,a2 bsr FindSize ; And load it if the right size was found bvs NewFailedRestore ; <36> CouldnÕt find one. Restore the resource chain and leave. bz.s @tryHalfSize ; <36> bra.s FoundTheSize ; try for the half-size one @tryHalfSize move.w D5,D3 lsr.w #1,D3 bcs.s FindClosest ; skip if the original size is odd. bsr GetFONDForSizeAndStyle ; Try to find a FOND for this size bz.s FindClosest ; or try scaling with the closest size move.l a0,a2 bsr FindSize ; If a FOND was found, load it up bvs.s NewFailedRestore ; <36> If one couldnÕt be found, panic beq.s FindClosest ; <36> or try scaling with the closest size bra.s FoundTheSize ; now worry about points for style ; oh, well, beggars can't be choosers. Scan to find the closest one ; in size FindClosest MOVE.L (A3),A0 ; point to size list addq #2,a0 ; <25> Skip FOND ID. MOVE.W (A0)+,D4 ; get # of entries-1 MOVEQ #0,D1 ; no font yet MOVE #$7FFF,D2 ; closest delta so far tst.w (A0) ; <73> donÕt take sfnt as the closest NFNT beq.s NxtSizeLoop ; <73> assuming sfnt is the first entry Scan4SizeLoop MOVE.W D5,D0 ; get one we want SUB.W (A0),D0 ; compute delta BPL.S @2 TST.B FScaleDisable ; scaling disabled? BEQ.S @1 ; if so, see if we've got one lower TST D1 ; if so, skip town BNE.S sizeFound ; because we want to scale up @1 NEG.W D0 ; absolute value @2 CMP D2,D0 ; closest one yet BGT.S NxtSizeLoop ; if not, skip move.w D0,D2 ; remember the size difference move.w (A0),D1 ; remember font size, too NxtSizeLoop add.w #kFONDListSize,A0 ; bump to next entry DBRA D4,Scan4SizeLoop ; search them all sizeFound move.w D1,D3 ; get best alternative BSR GetFONDForSizeAndStyle ; Try to find a FOND for this size beq.s NewFailedRestore move.l a0,a2 bsr FindSize ; If a FOND was found, load it up BVS.S NewFailedRestore ; <36> If we STILL canÕt find a font, then beq.s NewFailedRestore ; <36> weÕre REALLY hosed! ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; OK, we found the size so now worry about the style. The Font handle is ; saved in D0. FoundTheSize move.l (sp)+,a3 ; Restore A3 MOVE.L A0,D0 ; save the font handle in D0 MOVE.L (A2),A0 ; handle->pointer LEA FontFamilyRecord.FONDAssoc(A0),A0 ; skip header MOVE.W (A0)+,D1 ; fetch # of entries MOVE.L WidthTabHandle, A1 ; Get the Width Table Handle MOVE.L (A1), A1 ; Get pointer to Width Table TST.B WidthIsSpline(A1) ; Did a spline match BNE.S GotEntry ; Is spline so branch FTSLoop CMP.W (A0),D3 ; search for matching size BEQ.S GotEntry ADDQ #FAssocSiz,A0 DBRA D1,FTSLoop _Debug ; when could this ever fall through? bra.s NewFailed NewFailedRestore ; we can't find any in the family FOND record so try the old way move.l (sp)+,a3 ; Restore A3 NewFailed move.w (sp)+,CurMap ; <28> Pop CurMap in NewFailed in case weÕre coming from FoundTheSize MOVE D5,-(SP) ; put size on stack MOVE (A3),D3 ; get the requested family BRA OldFontLookUp ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; Modification history: ; 13-Aug-86 CRC Fixed bugs with uninitialized FOND entry pointer, looking at data past end of FOND. ; 2.8 CEL Added Spline Font Style selection. Plus needed spline font width table initialization. ; ; A0 points to the first entry of this size in the FOND, but maybe the FOND contains a stylized font that ; is better. Loop through to pick up the best qualifying one. The first font in the actual ; size pointed to by the FOND has already been successfully loaded, and is pointed to by D0. ; Both this routine and the earlier call to FindSize only make one call to GetResource; if that call fails, ; then other styles in the same size are not tried before going on to other methods of font substitution. ; A major reorganization of the code should include a thorough family search, retrying after failure until ; the family has been exhausted. ; >>> Styleweights needs to be driver supplied, at least for alternate display devices? ; StyleWeights is a table of weights for the font style bits, to determine which strike to display on ; the screen. Styles not provided by the strike returned are generated by QuickDraw. ; ; ; Registers on Entry: ; A0 = FOND data pointer ; A2 = FOND handle ; A3 = input record ; D0 = font handle ; D1 = left in assoc. table ; D3 = actual size ; ; Registers used: ; A1 = best style entry ; A4 = offset to width table in FOND ; D2 = user style descriptor, scratch ; D4 = best style weight, temp. ; D6 = FOND style descriptor ; ; CLOBBERS: ; D5 = scratch ; D7 = scratch ; ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ StyleWeights DC.B 4 ; weight for bold DC.B 8 ; weight for italic DC.B 1 ; weight for underline DC.B 3 ; weight for outline DC.B 3 ; weight for shadow DC.B 2 ; weight for condensed DC.B 1 ; weight for extended DC.B 0 ; bit 7 unused GotEntry MOVEQ #0,D2 ; zero high byte of style ADDQ #2,A0 ; point to style field MOVEQ #-2,D4 ; init best metric MOVE.B fmInFace(A3),D2 ; get style we want @selectStyleLoop MOVE.W (A0),D6 ; get style descriptor (want low byte only) CMP D6,D2 ; do they match? BNE.S @noStyleMatch MOVE.L A0,A1 ; if so, we've got it! BRA.S @foundMatch0 @noStyleMatch MOVEQ #-1,D5 ; take the first entry for starters MOVE D2,D7 NOT D7 AND D6,D7 ; can we use it? BNE.S @nextStyle ; if not, skip ; it qualifies, so determine its weighting MOVEQ #0,D5 ; initial weight is 0 MOVEQ #7,D7 ; start with bit 8 AND D2,D6 ; only bits set in both request & available @styMagLoop ASL.B #1,D6 ; bit set? BCC.S @nextStyMag ; if not, skip ADD.B StyleWeights(D7),D5 ; add in weight @nextStyMag DBRA D7,@styMagLoop ; loop for 8 bits ; OK, now see if the resulting weight (in D1) is the biggest so far @nextStyle CMP D5,D4 ; best so far? BGE.S @loopBottom ; if not, forget it! ; its the biggest so far, so remember it MOVE D5,D4 ; remember metric value MOVE.L A0,A1 ; remember entry ; if we have more to consider, go handle them @loopBottom ADDQ #FAssocSiz-2,A0 ; bump to next entry MOVE.L A0, -(SP) ; save off regs for now BSR DerefWidthTab ; get pointer to widthtable TST.B WidthIsSpline(A0) ; is it spline BEQ.S @notSpline ; not a spline MOVE.L (SP)+, A0 ; restore A0 TST.W (A0)+ ; Spline always 0 BEQ.S @checkBranch ; test for looping BRA.S @foundMatch0 ; pass up loop @notSpline MOVE.L (SP)+, A0 ; restore A0 CMP.W (A0)+,D3 ; next one same size? @checkBranch ; <2.7-4april89-CEL> DBNE D1,@selectStyleLoop ; if not, or if out of entries, decide the style ; no more of this size so the winner is the one pointed to by A1. If the ; ID is the same as the one we already got, we don't have to get it ; again @foundMatch0 MOVE.W (A1)+,D6 ; get the style of winner MOVE.W styleID+2(A6),D1 ; get resID of one in D0 CMP.W (A1),D1 ; do we already have it? MOVE.L D0,A0 ; keep fontHandle from now on in addr. reg. BEQ.S @foundItAll ; if so, don't have to load ; it changed, so we have to get it again MOVE.L A0,D4 ; remember old fontHandle MOVE.W (A1),D0 ; get ID BSR LoadNewStrike ; << this is the only call to this subroutine, ; << but it is inside goLoadStrike (which is ; << also called only once.) ; << Clobbers only A0, D0 BVS.S NewFailed ; disk switch, oh no. BNE.S @foundItAll @noTweakedFont ; we couldn't load it, so stick with the old one MOVE.L D4,A0 ; recover fontHandle MOVE.W styleID(A6),D6 ; recover style ; OK, the fontHandle is in D0 and its style is in D6. Set up FOutCurStyle ; with the proper value, and dive back in to the font manager proper. @foundItAll move.w (sp)+,CurMap ; <28> Restore the resource map now NOT D6 ; invert mask of what we got AND.B D6,FOutCurStyle ; turn off built-in properties ; at this point D6 has the inverse of the style we actually got. A2 has ; the family definition record handle. Look for a matching width table; ; if we got one, return its offset in A4. MOVE.L (A2),A1 ; point to famDef MOVE.W FontFamilyRecord.FONDLast(A1),D1 ; get lastChar BEQ.S @noFamWidths ; if zero, must be a ÒnullÓ FOND set up by Font/DA Mover SUB.W FontFamilyRecord.FONDFirst(A1),D1 ; compute # of chars-1 ADDQ #4,D1 ; compute word size of wTab (include style wd.) ADD.W D1,D1 ; compute size of table MOVE.L FontFamilyRecord.FONDWTabOff(A1),D0 ; get offset to widthTabs BEQ.S @noFamWidths ; if none, skip ADD.L D0,A1 ; point to the width tables MOVE.W (A1)+,D2 ; get # of tables-1 BMI.S @noFamWidths ; drskip if none ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; here's the loop where we search for the appropriate family width table ; >> Adobe pointed out a bug here. If the FOND has a style width table, but the style screen font is not ; >> around, the plain width table will be used incorrectly. The right solution is for the styles to be ; >> searched and compared on a weighted basis just like the screen styles, except for the weights are ; >> different. Bold first, Condensed next, and Italic third? What about the idea of masking out ; >> underline, outline, shadow, and always forcing stylistic extras to be used, unless an exact match ; >> is found? ; >> Certainly, if a style width has styles outside of the requested style, it can not be used. ; ; >> Although this code is very similar to the screen font code above, I canÕt see any trivial way of ; >> rolling them together. For one, all registers are used. ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; bug fix, implemented as a patch on Aladdin - the problem is that FOND widths will only be used ; if FractEnable is true; otherwise, the widths will be gotten from the strike. ; probably can skip this whole mess if FractEnable is false --- @srchFamWTab MOVEQ #-1,D4 ; best match found so far TST.B FractEnable ; are fractions allowed? BNE.S @useBestStyle ; if so, use the best width table around NOT D6 ; reverse strike style once more MOVE D6,-(SP) ; use width table equivalent to strike BRA.S @nextFamWTab @useBestStyle MOVEQ #0,D0 ; zero high word MOVE.B fmInFace(A3),D0 ; get original requested style MOVE D0,-(SP) ; push it @nextFamWTab MOVE (SP),D0 ; get the style word CMP (A1),D0 ; exact match? BEQ.S @figureWidthPos ; donÕt worry no more NOT D0 ; set all cleared bits AND (A1),D0 ; nonzero if style in width is not in request BNE.S @wrongFamWidths ; donÕt consider widths with too much info. MOVEQ #0,D5 ; accumulated weight MOVE (SP),D0 ; bits in requested style AND (A1),D0 ; and in available bits MOVEQ #7,D7 ; number of bits in style byte @nextBit ASL.B #1,D0 ; BCC.S @skipWeight ; ADD.B widthWeights(D7),D5 @skipWeight DBRA D7,@nextBit ; if no carry and not zero, go to next bit CMP D5,D4 BGE.S @wrongFamWidths MOVE D5,D4 ; save best MOVE.L A1,D6 ; location of best width found so far @wrongFamWidths ADD D1,A1 ; advance to next table entry DBRA D2,@nextFamWTab TST D4 BMI.S @tossStackSpace MOVE.L D6,A1 @figureWidthPos MOVE (A1)+,fwidStyle(A6) ; keep best found style SUB.L (A2),A1 MOVE.L A1,A4 @tossStackSpace ADDQ #2,SP @noFamWidths BRA GotTheFont ; dive back in ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; output registers: (double dashes indicate registers are written before read) ; D0 = -- D1 = -- D2 = -- ; D3 = actual size (input) D4 = -- D5 = -- ; D6 = -- D7 = -- A0 = handle to font (input) ; A1 = -- A2 = -- A3 = input record ; A4 = offset to width table in FOND ; end of GotEntry ; WidthWeights are used to determine which width table in the FOND is the best approximation of the ; requested style widths. Styles not provided by the FOND width table are added in from the FOND values ; in style extra. ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ WidthWeights DC.B 1 ; weight for bold DC.B 3 ; weight for italic DC.B 5 ; weight for underline DC.B 4 ; weight for outline DC.B 4 ; weight for shadow DC.B 2 ; weight for condensed DC.B 2 ; weight for extended DC.B 0 ; bit 7 unused if forROM or HAS_COLOR then FPointOne else BWFPointOne endif DC.W 1 DC.W 0 ; StyleTable for the Screen -- note this is changed from old ROM; no ; more extra for bold and italic. ScreenStyleTab DC.W 80,80 ; dots/inch DC.B 0,1,1 ; bold DC.B 1,8,0 ; italic DC.B 0,0,0 ; underline (stub) DC.B 5,1,1 ; outline DC.B 5,2,2 ; shadow DC.B 0,0,$FF ; condensed DC.B 0,0,1 ; extended DC.B 1,1,1 ; underline (for real) Theft DC.B $00,$77,$7A,$3B,$C9,$35,$30,$19 DC.B $80,$AF,$30,$18,$7A,$60,$18,$09 DC.B $00,$60,$31,$98,$09,$72,$7B,$BA DC.B $49,$BF,$E0,$9D,$01,$02,$20,$BF DC.B $40,$88,$01,$F1,$FE,$02,$0A,$81 DC.B $BC,$04,$07,$03,$9A,$08,$04,$0F DC.B $80,$99,$1F,$C0,$37,$60,$B9,$0F DC.B $04,$03,$DF,$0F,$98,$08,$37,$60 DC.B $1F,$C1,$A8,$04,$0F,$80,$02,$02 DC.B $9A,$01,$04,$87,$08,$18 EndWith ; PROCEDURE GetFontName(familyID: INTEGER; VAR theName: Str255); ; ; Get the name of the font, given the family ID if forROM or HAS_COLOR then GetFontName else BWGetFontName endif ; first check if we have a family definition record MOVE.L (SP)+,A1 ; save return address MOVE.L (SP)+,D2 ; save pointer to string MOVE.W (SP)+,D1 ; get the requested family ID MOVE.W #MapFALSE,ROMMapInsert ; set ResLoading False <10 Jul 85> BSR.S GetFONDMap ; is there a FOND for this family? BNE.S @askForName ; if so, skip ; make sure the ID is in range CMP.W #512,D1 ; ID in range? BCC.S @returnNilString ; if not, skip ; no luck, so try it the old way ASL #7,D1 ; set size field to 0 MOVE.W #MapFALSE,ROMMapInsert ; don't load the font SUBQ #4,SP ; make space for function result MOVE.L #'FONT',-(SP) ;'FONT' is resType MOVE.W D1,-(SP) ; push ID _GetResource ; get the named resource handle MOVE.L (SP)+,D0 MOVE.L D0,A0 BEQ.S @returnNilString ; if NIL, return empty string @askForName MOVE.L A0,-(SP) ; push the resource handle CLR.L -(SP) ; no place for ID (don't care) CLR.L -(SP) ; no place for type (don't care) MOVE.L D2,-(SP) ; place for name (where app wants) MOVE.W #MapFALSE,ROMMapInsert ; get from ROM if possible <10 Jul 85> _GetResInfo ; get it! BRA.S @doneGetFName ; all done @returnNilString MOVE.L D2,A0 ; get the string pointer CLR.B (A0) ; make it NIL @doneGetFName JMP (A1) ; return to caller ; Common code used by GetFontName and RealFont. GetFOND entry point is used by TryFOND. ; ; Need to map D1 into proper ID if 0 or 1 GetFONDMap TST D1 BNE.S @notSysFont MOVE SysFontFam,D1 BRA.S GetFOND @notSysFont CMP #1,D1 ; is it the same as the apFontID? BNE.S GetFOND MOVE ApFontID,D1 GetFOND SUBQ #4,SP MOVE.L #'FOND',-(SP) ; push type "FOND" MOVE.W D1,-(SP) ; push the ID MOVE.W #MapTrue,RomMapInsert ; look in ROM first rb _GetResource ; look for it MOVE.L (SP)+,D0 MOVE.L D0,A0 RTS ; FUNCTION RealFont(famID: INTEGER; size: INTEGER): BOOLEAN; ; ; RealFont is a boolean function that returns true if we have a real bitmap ; (as opposed to a stretched one) for the requested font ; ; Modification History: ; ; 26-Aug-86 CRC Use same substitution scheme as SwapFont. Do not play with cache state ; anymore. if forROM or HAS_COLOR then RealFont else BWRealFont endif With SwapFontStackFrame MOVE.L (SP)+,A1 ; save return address MOVE.W (SP)+,D2 ; get size BNE.S @notSizeZero ; if nonzero, no prob with Bob TST (SP) ; sysFontFam? BNE.S @notSysFont ; if not, use FMDefaultSize MOVE SysFontSize,D2 ; must be 0,0 BNE.S @notSizeZero ; if non zero, it is fine @notSysFont MOVEQ #0,D2 ; zero high order byte MOVE.B FMDefaultSize,D2 ; pick up preset default BNE.S @notSizeZero ; take it as long as it is not zero. MOVEQ #12,D2 ; hardcode to 12 if low memory is no help @notSizeZero MOVE.W (SP)+,D1 ; get the font family clr.w (sp) ; Assume not real move.l a1,-(sp) ; Save A1 since GetCandidateFONDs doesnÕt. subq #4,sp move.w d1,-(sp) clr.w -(sp) ; DonÕt use the application font if font family isnÕt found bsr GetCandidateFONDs ; Use candidate list move.l (sp)+,d0 move.l (sp)+,a1 ; Restore A1 move.l d0,-(sp) ; <60> Save the candidate list beq.s @oldKindOfFont ; GetCandidateFONDs returns a list of available sizes for this font family. Scan this ; list for the requested size. move.l d0,a0 _HLock ; <60> Lock the candidate list MOVE.L (A0),A0 ; handle->pointer addq #2,a0 ; Skip past family ID MOVE.W (A0)+,D0 ; pick up the count BMI @notReal ; if none, skip <14-jlf> @nrfLoop tst.w (a0) ; Size 0 means itÕs a spline font. bz.s @checkPPEM ; <50> Check the lowest size TrueType is used for. cmp.w (a0),d2 ; got it? beq @itsReal ; if so, its real @nextCandidate add.w #kFONDListSize,A0 ; skip to next entry DBRA D0,@nrfLoop ; check em all out BRA.S @notReal ; it must not be real... ; <50> WeÕve got an entry for a TrueType font. Instead of automatically ; returning true, call fs_LowestPPEM to see if the TrueType font will be ; used to draw this point size. If it is, go ahead and return true. If ; it wonÕt, go back into the loop and look for a bitmapped size. @checkPPEM movem.l d0/a0-a2,-(sp) ; <50> move.w CurMap,-(sp) ; <52> Save the current resource map. move.l FONDMap(a0),a2 ; <52> Get the resource map handle move.l (a2),a2 ; <52> move.w mRefNum(a2),CurMap ; <52> Make this map the current resource map move.l FONDHandle(a0),a2 ; <50> Get handle to FOND containing spline entry tst.l (a2) ; <50> bnz.s @fondIsLoaded ; <50> move.l a2,-(sp) ; <50> _LoadResource ; <50> Make sure itÕs loaded @fondIsLoaded move.l (a2),a2 ; <50> lea FontFamilyRecord.FONDAssoc+2(a2),a2 ; <50> Point to font association table (after entry count) ; The TrueType entry in the font association table should always be first, but ; do a loop just in case. This loop assumes that the entry in the candidate entry ; is correct, and that a spline font will eventually be found in this font association ; table. @findSplineEntry tst.w (a2) ; <50> Is this the spline entry? bz.s @gotSplineEntry ; <50> If the size is 0, then it is addq #fAssocSiz,a2 ; <50> Otherwise, point to the next entry bra.s @findSplineEntry ; <50> ; Found the entry in the font association table for the TrueType version of this font. ; Load the spline resource, then call LowestPPEM to find out the lowest point size that ; TrueType will be used for. If the requested size is larger than this size, then ; return true. If the requested size is smaller than this size, then continue searching ; the candidate list for a bit map. @gotSplineEntry move.w 4(a2),d0 ; <50> Pass the ID of the 'sfnt' resource bsr LoadSplineFontResource ; <50> Go get it. move.w d2,-(sp) ; <53> Save the size weÕre looking for. subq #2,sp ; <50> move.l d0,-(sp) ; <50> Pass TrueType font handle to fsLowestPPEM _fsLowestPPEM ; <50> Find out the lowest size TrueType will be used for move.w (sp)+,d0 ; <53> Get the lowest size TrueType should be used for move.w (sp)+,d2 ; <53> Restore the requested size. cmp.w d0,d2 ; <50> Compare against the requested size blt.s @tryForBitMap ; <50> If the requested size is less, look for an actual bitmap size move.w (sp)+,CurMap ; <52> Restore the current resource map. movem.l (sp)+,d0/a0-a2 ; <50> bra.s @itsReal ; <50> If TrueType will be used for this size, this should be considered an available size. @tryForBitMap move.w (sp)+,CurMap ; <52> Restore the current resource map. movem.l (sp)+,d0/a0-a2 ; <50> bra.s @nextCandidate @oldKindOfFont ; make sure the ID is in range for an old-style font CMP.W #512,D1 ; ID in range? BCC.S @notReal ; if not, return false ; there's no family definition record so do it the old way ASL #7,D1 ; shift FamID into place AND.W #$007F,D2 ; only use low 7 bits of size OR D2,D1 ; compute resource ID link a6,#stackFrame ; <38> GetStrike uses the FMSwapFont stack frame now move.w d1,styleID+2(a6) ; <38> Save the resource ID here BSR GetStrike ; do we have it unlk a6 ; <38> Done with the stack frame BEQ.S @notReal ; good! (branch if we couldn't find it) @itsReal ADDQ.B #1,4(SP) ; return TRUE <60> The candidate handle is still on the stack @notReal move.l (sp)+,a0 ; <60> Get the candidate handle _HUnlock ; <60> Let it float JMP (A1) ; return to caller ; ; Utility called by GetFNum TryForName SUBQ #4,SP ; make room for function result ; MOVE.L D1,-(SP) ; push the resource class ; MOVE.L 12(SP),-(SP) ; push the name pointer MOVE.L D0,-(SP) ; push the resource class MOVE.L D1,-(SP) ; push the name pointer MOVE.W #MapFALSE,ROMMapInsert ; do with ResLoad false <10 Jul 85> _GetNamedResource ; get the resource MOVE.L (SP)+,D0 ; did it get it? RTS EndWith ; PROCEDURE GetFNum(familyName: Str255; VAR theID: INTEGER); ; ; Get the family ID of the font, given the name ; ; Modification History: ; ; 26-Aug-86 CRC Take advantage of new Resource Manager + code crunching ; 29-Aug-86 CRC A preliminary version of MacAuthor depends on D2 being preserved. if forROM or HAS_COLOR then GetFNum else BWGetFNum endif MOVE.L 8(SP),D1 ; move string address to register MOVE.L (SP)+,4(SP) ; place return address at top of frame MOVE.L (SP)+,A1 ; get pointer to ID. MOVE.L #'FOND',D0 ; resource type BSR.S TryForName BNE.S @gotFondFID MOVE.L #'FONT',D0 ; resource type BSR.S TryForName BNE.S @gotFontFID CLR.W (A1) ; make it NIL BRA.S @doneGFID ; all done ; we got it, so look up the ID @gotFondFID ST D1 BRA.S @gotFID @gotFontFID SF D1 @gotFID MOVE.L D0,-(SP) ; push the resource handle MOVE.L A1,-(SP) ; place for ID CLR.L -(SP) ; no type CLR.L -(SP) ; no name MOVE.W #MapFALSE,ROMMapInsert ; get from ROM if possible <10 Jul 85> _GetResInfo ; get it! ; CMP.L #'FOND',D1 ; new way? (old way!) TST.B D1 ; got FOND? BNE.S @doneGFID ; if so, already done MOVE.W (A1),D0 ; get the ID LSR #7,D0 ; divide by 128 MOVE.W D0,(A1) ; return the ID ; all done so restore registers and return to caller @doneGFID ; MOVE.L D2,(SP) ; overwrite location of string with return address RTS ; PROCEDURE SetFontLock(lockFlag:Boolean) -- makes the current font purgable ; or unpurgable. if forROM or HAS_COLOR then SetFontLock else BWSetFontLock endif MOVE.L (SP)+,A1 ; get return address TST.B (SP)+ ; set or clear lock? BEQ.S @unlockFont ; if set, go lock it down ; we want to lock the font down so make sure its loaded and make it unpurgable move.l FOutFontHandle,a0 ; get the current font handle <14-jlf> tst.l (a0) ; is it purged? <14-jlf> bne.s @NoPurgeFont ; no, skip the resource load stuff <14-jlf> move.l WidthTabHandle,a0 ; get current width table <14-jlf> move.l (a0),a0 ; get master pointer <14-jlf> tst.b WidthIsSpline(a0) ; is this a spline font? <14-jlf> beq.s @DoNormalFontLock ; no, do normal stuff <14-jlf> tst.b KeepSplineOnDisk(a0) ; should the spline be loaded into memory? <14-jlf> bne.s @doneSFL ; no, bail out of routine <14-jlf> move.w WidthStrikeID(a0),d0 ; setup sfnt resource id parameter <14-jlf> jsr LoadSplineFontResource ; call the load routine <14-jlf> bsr DerefWidthTab ; get widthPointer in a0 <14-jlf> exg d0,a0 ; exchange splineHandle with widthTable <14-jlf> tst.l (a0) ; was the spline loaded into memory? <14-jlf> exg d0,a0 ; swap the registers back <14-jlf> seq KeepSplineOnDisk(a0) ; don't try to load next time if not loaded <14-jlf> beq.s @doneSFL ; skip the nopurge if it wasn't loaded <14-jlf> bra.s @NoPurgeFont ; make it non-purgeable <14-jlf> @DoNormalFontLock MOVE.L FOutFontHandle,A0 ; get the font handle <14-jlf> MOVE.L A0,-(SP) ; push font handle for release/load MOVE.W #MapTrue,ROMMapInsert ; get it from ROM if possible <10 Jul 85> _LoadResource ; load it in @NoPurgeFont ; <14-jlf> _HNoPurge ; turn off purge bit BCLR #purge,FondState BRA.S @doneSFL ; we no longer need the font so make it purgable @unlockFont MOVE.L FOutFontHandle,A0 ; get the font handle _HPurge ; make it purgable BSET #purge,FondState @doneSFL JMP (A1) ; return to caller IF forROM OR NOT HAS_COLOR THEN ; PROCEDURE SetFScaleDisable(scaleDis:BOOLEAN); ; ; Set to turn ScaleDisable on and off, invalidating the width cache. if forROM or HAS_COLOR then SetFScaleDisable else BWSetFScaleDisable endif MOVE.L (SP)+,A0 MOVE.B (SP)+,FScaleDisable setFScaleTail MOVE.L MinusOne,LastSpExtra ; note that widths are invalid JMP (A0) ; PROCEDURE SetFractEnable(fractEnable:BOOLEAN); ; ; Set to turn FractEnable on and off, invalidating the width cache. if forROM or HAS_COLOR then SetFractEnable else BWSetFractEnable endif MOVE.L (SP)+,A0 ; return address MOVE.B (SP)+,FractEnable BRA.S setFScaleTail ENDIF ; PROCEDURE FontMetrics(VAR theMetrics:FontMetricRec); ; ; FontMetrics returns fractional information about the current font ; as specified in thePort. It returns a Font Metric Record whose format ; is: ; ; ascent: Fixed; ; descent: Fixed; ; leading: Fixed; ; widMax: Fixed; ; WTabHandle: Handle; ; ; first use CharWidth to force a SwapFont if forROM or HAS_COLOR then FontMetrics else BWFontMetrics endif SUBQ #2,SP ; make room for result MOVE #' ',-(SP) ; push ASCII for blank _CharWidth ; run through SwapFont ADDQ #2,SP ; we don't really care about result ; get the parameter pointer MOVE.L A2,-(SP) ; save work register MOVE.L 8(SP),A2 ; point to result record ; always derive things from the font itself MOVE.L FOutFontHandle,A1 ; get font handle MOVE.L (A1),A1 ; handle->pointer BSR DerefWidthTab ; Get pointer to width table TST.B WidthIsSpline(A0) ; Get is spline flag BEQ.S @notSpline ; not a spline MOVE.L expandMem, A0 ; get low mem expand MOVE.L ExpandMemRec.emSplineKey(A0), A0 ; Handle to splineKey MOVE.L (A0), A0 ; pointer to splinekey MOVE.L splineKeyRec.cacheHand(A0), D0 ; is there a cache BEQ.S @bailForZeros MOVE.L D0, A0 ; get Handle in addr reg TST.L (A0) ; Is it purged BEQ.S @bailForZeros ; bail since we have no cache MOVE.L (A0), A0 ; pointer to the cache WITH cache ; <8> MOVE.L ascent(A0), (A2)+ ; Get Ascent out of cache MOVE.L descent(A0), (A2)+ ; Get Descent out of cache MOVE.L leading(A0), (A2)+ ; Get Leading out of cache MOVE.L widMax(A0), (A2)+ ; Get Widmax out of cache ENDWITH BRA.S @finishSplines ; Fill in the rest of the Width Table @bailForZeros CLR.L (A2)+ ; Zero Ascent CLR.L (A2)+ ; Zero Descent CLR.L (A2)+ ; Zero Leading CLR.L (A2)+ ; Zero Widmax BRA.S @finishSplines ; Fill in the rest of the Width Table @notSpline LEA FAscent(A1),A0 ; point to ascent field PEA FWidMax(A1) ; save pointer to FWidMax for later BSR.S ScaleVFVal ; process ascent BSR.S ScaleVFVal ; process descent BSR.S ScaleVFVal ; process leading MOVE.L (SP)+,A0 MOVE.L FScaleHFact,D1 LEA fmOutNumer+FOutRec+2,A1 ; point to horizontal numerator. BSR.S ScaleFVal ; process widMax ; stuff the width table handle @finishSplines MOVE.L WidthTabHandle,A0 MOVE.L A0,(A2) ; remember width handle ; now adjust the results to compensate for style MOVE.L 8(SP),A2 ; get result pointer back. MOVEQ #0,D0 MOVE.B fmOutShadow+FOutRec,D0 ; get shadow count BEQ.S @noShadow ; skip if zero ADD.W #1,(A2) ; adjust ascent ADD.W D0,4(A2) ; adjust descent @noShadow MOVE.L (A0),A0 ; pointer to widths MOVE.L WidthStyle(A0),D0 ; get the style extra. ADD.L D0,12(A2) ; add it in to the WidMax field. ; now we're done MOVE.L (SP)+,A2 ; restore work register MOVE.L (SP)+,(SP) ; strip parameter RTS ; ScaleFVal is a code saving utility that fetches the value pointed ; to by A0, multiplies it by the scale factor and scale disable adjustment, ; and stuffs the normalized long result where A2 points ScaleVFVal MOVE.L FScaleVFact,D1 LEA fmOutNumer+FOutRec,A1 ; point to vertical numerator. ScaleFVal MOVE.W (A0)+,D0 ; get ascent MOVE.L A0,-(SP) TST.B FScaleDisable ; use 1.0 if scaling is enabled. BNE.S @2 if forROM or HAS_COLOR then MOVE.L FPointOne,D1 else move.l BWFPointOne,d1 ; <12> DTY endif @2 SUBQ #4,SP ; make space for result MOVE.L D1,-(SP) ; FScale adjustment for FixMul SUBQ #4,SP CLR.W -(SP) ; push the font's info as a fixed point value. MOVE.W D0,-(SP) SUBQ #4,SP ; reversed next 2 lines <28May86> MOVE.W (A1),-(SP) ; push V output numer MOVE.W 4(A1),-(SP) ; push V output denom _FixRatio ; compute ratio. ; multiply by the appropriate FScaleDisable factor in D1 _FixMul ; compute FScaleExtra*Value _FixMul ; compute FScaleExtra*Value*ScaleFactor MOVE.L (SP)+,(A2)+ ; remember it MOVE.L (SP)+,A0 RTS ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; BuildCharTable operates on the font passed in A0. It makes room for ; a character height table at the end of the font and then loops from ; FirstChar to LastChar+1, computing it. ; ; Registers used: ; ; D0 = scratch D1 = scratch D2 = scratch D3 = character height ; D4 = constant (16) D5 = table size D6 = next entry, width D7 = locTable entry ; A0 = fontHandle (input) A1 = strike pointer A2 = fontPtr, locTable A3 = fontHandle ; A4 = character height A5 = mask table RightMask EQU $0 ; position of right masks in QuickDrawÕs table. LeftMask EQU $20 ; position of left masks in QuickDrawÕs table. IF (HAS_COLOR) THEN ; <2.7-4april89-CEL> hBitDepth EQU -4 locStack EQU hBitDepth ENDIF BuildCharTable IF (HAS_COLOR) THEN ; <2.7-4april89-CEL> LINK A6,#locStack ENDIF ; END colorgrayness MOVEM.L D3-D7/A2-A5,-(SP) ; save registers MOVE.L A0,A3 ; keep fontHandle in A3 _GetMaskTable MOVE.L A0,A5 ; keep pointer to left masks around MOVE.L (A3),A1 ; point to the font MOVE.W (A1)+,D0 ; get format word? LSR #1,D0 ; already got table? BCS.S DoneBCT ; if so, we're done ; get firstChar, lastChar and compute size of table MOVE.W (A1)+,D0 ; get firstChar MOVEQ #0,D5 ; zero high word MOVE.W (A1),D5 ; get lastChar SUB.W D0,D5 ; compute lastChar-firstChar ADDQ #3,D5 ; # of chars, including missing ADD.W D5,D5 ; compute size of table ; compute total new size of font: position of OWTable + 2 * D5 MOVE.L (A3),A1 ; point to font IF (HAS_COLOR) THEN ; <2.7-4april89-CEL> MOVE (A1),D0 ; get font flags ASR #2,D0 ; strip height, width bits AND #$7,D0 ; get bit depth of font @@@@ used to be 3 MOVE D0,hBitDepth(A6) ENDIF ; END Color Gray Ness MOVE.W fNDescent(A1),D0 ; possibly the high word of owTLoc SWAP D0 ; put it in the high word BPL.S @notNegative MOVEQ #0,D0 @notNegative MOVE.W fOWTLoc(A1),D0 ; get size till owTable ADDQ.L #8,D0 ; 8 header words in front ADD.L D0,D0 ; double for bytes MOVE.L D0,D1 ; remember in D1 SUB.L D5,D1 ; compute offset to LocTable ADD.L D5,D0 ; add in owTable MOVE.L D0,D2 ; remember offset to height table for later ADD.L D5,D0 ; add in newTable ; if the font has a built-in width table, make sure we take that into ; account BTST #1,1(A1) ; built in width table? BEQ.S @growTheFont ; if not, skip ADD.L D5,D0 ; increase new size ADD.L D5,D2 ; bump where heights go, too ; grow it to include the table @growTheFont MOVE.L A3,A0 ; get the font handle _SetHandleSize ; try to grow it BEQ.S MakeCTable ; if we can, good ; we couldn't grow the handle so give up. DoneBCT MOVEM.L (SP)+,D3-D7/A2-A5 IF (HAS_COLOR) THEN ; <2.7-4april89-CEL> UNLK A6 ENDIF ; End color grayness RTS ; OK, D2 has the offset to the beginning of the character offset table, ; D1 has offset to locTable, D3 has firstChar and D4 has lastChar. Loop ; for the # of characters, walking down both tables, using locTable to ; build the mask, counting the rows and filling out the charTable. MakeCTable MOVE.L (A3),A2 ; point to font OR #1,(A2) ; turn on mode bit MOVE.W fFRectHeight(A2),D3 ; hold total height ADD.L D1,A2 ; A2 points to locTable MOVE.L (A3),A4 ; point to font ADD.L D2,A4 ; point to charTable ; here's the start of the loop. D5 has the number of entries *2 to ; process. From the words that A2 points to, make a mask/offset combo ; in A1/D0. SUBQ #2,D5 ; don't need extra bounds CTabLoop0 MOVE #$FF00,(A4) ; init top to FF, bot to 0 MOVE.W (A2)+,D7 ; get locTable entry MOVE.W (A2),D6 ; get next entry, too SUB.W D7,D6 ; compute length in pixels IF (HAS_COLOR) THEN ; <2.7-4april89-CEL> BEQ EmptyChar MOVE hBitDepth(A6),D0 LSL D0,D7 ; scale up pixel start LSL D0,D6 ; scale up remaining width ELSE BEQ.S EmptyChar ; if zero, its easy ENDIF ; End Color Gray Ness ; Here's where we re-enter the loop for wide characters. Make A1 point ; into word of font, and start building the mask in D0. CTab1Loop MOVE.W D7,D2 ; remember start MOVE.W D7,D0 ; get start in D0 LSR.W #4,D0 ; divide by 16 ADD.W D0,D0 ; double for byte offset MOVE.L (A3),A1 ; get font pointer ADD.W #FRowWords+2,A1 ; point to strike ADD.W D0,A1 ; point to proper word ; now build the leftMask based on the remainder AND #15,D2 ; compute start mod 16 MOVE D2,D1 ; copy it ADD.W D1,D1 ; double for word index MOVEQ #0,D0 ; clear high part of D0 MOVE.W LeftMask(A5,D1),D0 ; get leftMask SWAP D0 ; keep in high word ; now compute how many pixels were used up in the first word, and decrement ; the width value MOVEQ #16,D4 ; useful constant! MOVE D4,D1 ; at most 16 used SUB.W D2,D1 ; compute number used ADD.W D1,D7 ; bump left index SUB.W D1,D6 ; compute number left BEQ.S MaskBuilt ; if none, done building mask BPL.S @moreMask ; if >0, turn on more bits ; the width remaining is < 0, so we must turn off bits in the mask MOVE D6,D1 ; get the delta ADD.W D4,D1 ; compute 16-delta ADD.W D1,D1 ; double for word index MOVE.L RightMask(A5,D1),D2 ; get inverse mask in high word AND.L D2,D0 ; turn off right bits BRA.S MaskBuilt ; OK, we got it ; here we handle the case where there's more in the next word to process, ; so extend the mask into the low word. @moreMask MOVE.W D6,D1 ; get remaining count CMP.W D4,D1 ; bigger than 16? BLE.S @notTopEnd ; if not, skip MOVE.W D4,D1 ; if so, max out at 16 @notTopEnd ADD.W D1,D1 ; double for word index MOVE.W RightMask(A5,D1),D2 ; get mask OR D2,D0 ; extend the mask SUB.W D4,D6 ; decrement remaining width ADD.W D4,D7 ; bump index to next word ; at this point, A1 points to the top long in the character and D0 has ; the mask. D3 has the number of scan lines. Loop, fetching a long ; and masking to find top of character. MaskBuilt MOVE.L A1,-(SP) ; remember first pointer MOVE D3,D1 ; init height counter SUBQ #1,D1 ; bias for DBRA MOVE.L (A3),A0 ; get font pointer IF (HAS_COLOR) THEN ; <2.7-4april89-CEL> MOVE fRowWords(A0),D4 MOVE hBitDepth(A6),D2 LSL D2,D4 ; scale up ADD D4,D4 ; compute rowBytes MOVE D4,A0 ; leave in A0 BRA.S @doneBitDepth MOVE.W fRowWords(A0),A0 ; get rowWords in A0 ADD.W A0,A0 ; compute rowBytes @doneBitDepth ELSE MOVE.W fRowWords(A0),A0 ; get rowWords in A0 ADD.W A0,A0 ; compute rowBytes ENDIF MOVEQ #0,D4 ; D4 is current top TopMaskLoop MOVE.L (A1),D2 ; get the bits AND.L D0,D2 ; any relevant one on? BNE.S MergeInTop ; if on, done with top ADDQ #1,D4 ; bump top ADD.W A0,A1 ; add in RowBytes DBRA D1,TopMaskLoop ; loop for all height ; all blank so set up as (0,0) ADDQ.L #4,SP ; strip saved A1 MOVEQ #0,D6 EmptyChar CLR.W (A4)+ ; stick 0,0 in table BRA.S NextChar ; go process next char ; OK, so top is in D4. Merge it into the table. ; (A4) starts at $FF, so any other value is smaller by unsigned <28May86> ; compare; we're looking for the lowest value possible. <28May86> MergeInTop CMP.B (A4),D4 ; is it smaller? BHS.S @0 ; if not, skip MOVE.B D4,(A4) ; update top ; now try the bottom up @0 MOVE.L (SP)+,A1 ; recover character ptr MOVE D3,D2 ; get height SUBQ #1,D2 ; compute height-1 MOVE A0,D4 ; get rowBytes MULU D4,D2 ; compute offset to bottom ADD.L D2,A1 ; start with bottom word MOVE D3,D4 ; start with height MOVE D3,D1 ; get # of lines SUBQ #1,D1 ; bias for DBRA BotMaskLoop MOVE.L (A1),D2 ; get the long AND.L D0,D2 ; any relevant bits on? BNE.S MergeInBot SUBQ #1,D4 ; one less high SUB.W A0,A1 ; back up a scan line DBRA D1,BotMaskLoop BRA.S EmptyChar ; impossible to get here... ; compute the height of the character and merge it in ; Herein lies the bug: until now the delta was computed along the <28May86> ; way, so information could be lost about characters that slanted <28May86> ; from lower left to upper right. Nowadays, keep the low point in the <28May86> ; second byte until the character is finished; then compute the delta <28May86> ; into the second byte. MergeInBot ADDQ.L #1,A4 ; skip top offset <28May86> CMP.B (A4)+,D4 ; compare with last height BCS.S NextChar ; <28May86> MOVE.B D4,-1(A4) ; its bigger, so use it ; we're finally done with this band of the character (at least!) so see ; if we're really done with it NextChar SUBQ.L #2,A4 ; back up TST D6 ; done with this character? BGT CTab1Loop ; if not, dive in again ; Get here when finished with a char. Have high and low pts in (A4), <28May86> ; so must compute low-high in 1(A4) as incrementing. <28May86> MOVE.B (A4)+,D0 ; high pt <28May86> SUB.B D0,(A4)+ ; low-high <28May86> SUBQ #2,D5 ; more to do? BGT CTabLoop0 ; if so, go do it BRA DoneBCT ; if not, we're done IF (NOT forROM) THEN ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ ; getIs32Bit - load the is32Bit flag from the splineKey globals. ;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ getIs32Bit MOVE.L A0,-(SP) ; save a register. MOVE.L expandMem,A0 ; get low memory expand pointer. MOVE.L ExpandMemRec.emSplineKey(A0),A0 ; get handle to splineKey globals. MOVE.L (A0), A0 ; get pointer to splineKey globals. TST.B splineKeyRec.is32bit(A0) ; get 32 bit CQD flag in CCR. MOVE.L (SP)+,A0 ; restore a register. RTS ; return to the caller. ENDIF if forROM or HAS_COLOR then FMgrEnd else BWFMgrEnd endif ; END ; <3.3> ;******************************************************************* ;******************************************************************* ;*******************************************************************